diff --git a/src/cube_hash.h b/src/cube_hash.h
new file mode 100644
index 0000000..3477df3
--- /dev/null
+++ b/src/cube_hash.h
@@ -0,0 +1,53 @@
+
+/*
+ * This file is part of Codecrypt.
+ *
+ * Codecrypt is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Codecrypt is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Codecrypt. If not, see .
+ */
+
+#include "cubehash_impl.h"
+
+#include "hash.h"
+
+template
+class cubehash : public hash_func
+{
+public:
+ uint size() {
+ return H;
+ }
+
+ std::vector operator() (const std::vector&a) {
+ cubehash_state state;
+ size_t i;
+
+ state.init();
+
+ for (i = 0; i + B <= a.size(); i += B)
+ state.process_block (& (a[i]) );
+
+ state.process_final_incomplete_block (& (a[i]), a.size() - i);
+ std::vector result;
+ result.resize (H, 0);
+ state.get_hash (& (result[0]) );
+ return result;
+ }
+};
+
+class cube128hash : public cubehash<16, 16, 32, 32, 16> {};
+class cube192hash : public cubehash<16, 16, 32, 32, 24> {};
+class cube256hash : public cubehash<16, 16, 32, 32, 32> {};
+class cube384hash : public cubehash<16, 16, 32, 32, 48> {};
+class cube512hash : public cubehash<16, 16, 32, 32, 64> {};
+
diff --git a/src/cubehash_impl.h b/src/cubehash_impl.h
new file mode 100644
index 0000000..9e131fc
--- /dev/null
+++ b/src/cubehash_impl.h
@@ -0,0 +1,104 @@
+
+/*
+ * This file is part of Codecrypt.
+ *
+ * Codecrypt is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Codecrypt is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Codecrypt. If not, see .
+ */
+
+#ifndef _ccr_cubehash_impl_h_
+#define _ccr_cubehash_impl_h_
+
+#include "types.h"
+
+#include
+
+#if __BYTE_ORDER__!=__ORDER_LITTLE_ENDIAN__
+#error "Only for little endian now, sorry."
+#endif
+
+#define ROT(a,b,n) (((a) << (b)) | ((a) >> (n - b)))
+#define i16(cmd) for(i=0;i<16;++i) cmd;
+
+#include "iohelpers.h"
+
+template < int I, //initialization rounds
+ int R, //rounds
+ int B, //input block size, less or equal 128
+ int F, //finalization rounds
+ int H > //output hash size in *bytes*, not bits! less or equal 128.
+class cubehash_state
+{
+ uint32_t X[32]; //the state
+
+ inline void rounds (uint n) {
+ int i;
+ uint32_t T[16];
+ for (; n; --n) {
+ i16 (X[i + 16] += X[i]);
+ i16 (T[i ^ 8] = X[i]);
+ i16 (X[i] = ROT (T[i], 7, 32) );
+ i16 (X[i] ^= X[i + 16]);
+ i16 (T[i ^ 2] = X[i + 16]);
+ i16 (X[i + 16] = T[i]);
+ i16 (X[i + 16] += X[i]);
+ i16 (T[i ^ 4] = X[i]);
+ i16 (X[i] = ROT (T[i], 11, 32) );
+ i16 (X[i] ^= X[i + 16]);
+ i16 (T[i ^ 1] = X[i + 16]);
+ i16 (X[i + 16] = T[i]);
+ }
+ }
+
+public:
+ inline void init() {
+ X[0] = H;
+ X[1] = B;
+ X[2] = R;
+ for (int i = 3; i < 32; ++i) X[i] = 0;
+ rounds (I);
+ }
+
+ void process_block (const byte*data) {
+ for (int i = 0; i < B; ++i)
+ X[i / 4] ^= ( (uint32_t) (data[i]) ) << ( (i % 4) * 8);
+ rounds (R);
+ }
+
+ void process_final_incomplete_block (const byte*data, size_t n) {
+
+ byte new_block[B];
+ uint i;
+
+ for (i = 0; i < n; ++i) new_block[i] = data[i];
+
+ new_block[i++] = 0x80;
+
+ while (i < B) new_block[i++] = 0;
+
+ process_block (new_block);
+
+ //finalize
+ X[31] ^= 1;
+ rounds (F);
+ }
+
+ void get_hash (byte*out) {
+ std::cout << std::hex;
+ for (int i = 0; i < 32; ++i) out (X[i]);
+ for (int i = 0; i < H; ++i)
+ out[i] = (X[i / 4] >> ( (i % 4) * 8) ) & 0xff;
+ }
+};
+
+#endif