aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/hash
diff options
context:
space:
mode:
authorlloyd <[email protected]>2014-01-10 03:41:59 +0000
committerlloyd <[email protected]>2014-01-10 03:41:59 +0000
commit6894dca64c04936d07048c0e8cbf7e25858548c3 (patch)
tree5d572bfde9fe667dab14e3f04b5285a85d8acd95 /src/lib/hash
parent9efa3be92442afb3d0b69890a36c7f122df18eda (diff)
Move lib into src
Diffstat (limited to 'src/lib/hash')
-rw-r--r--src/lib/hash/bmw_512/bmw_512.cpp204
-rw-r--r--src/lib/hash/bmw_512/bmw_512.h38
-rw-r--r--src/lib/hash/bmw_512/info.txt5
-rw-r--r--src/lib/hash/comb4p/comb4p.cpp102
-rw-r--r--src/lib/hash/comb4p/comb4p.h61
-rw-r--r--src/lib/hash/comb4p/info.txt1
-rw-r--r--src/lib/hash/gost_3411/gost_3411.cpp242
-rw-r--r--src/lib/hash/gost_3411/gost_3411.h44
-rw-r--r--src/lib/hash/gost_3411/info.txt5
-rw-r--r--src/lib/hash/has160/has160.cpp165
-rw-r--r--src/lib/hash/has160/has160.h39
-rw-r--r--src/lib/hash/has160/info.txt5
-rw-r--r--src/lib/hash/hash.h37
-rw-r--r--src/lib/hash/info.txt3
-rw-r--r--src/lib/hash/keccak/info.txt5
-rw-r--r--src/lib/hash/keccak/keccak.cpp198
-rw-r--r--src/lib/hash/keccak/keccak.h47
-rw-r--r--src/lib/hash/md2/info.txt1
-rw-r--r--src/lib/hash/md2/md2.cpp113
-rw-r--r--src/lib/hash/md2/md2.h41
-rw-r--r--src/lib/hash/md4/info.txt5
-rw-r--r--src/lib/hash/md4/md4.cpp114
-rw-r--r--src/lib/hash/md4/md4.h46
-rw-r--r--src/lib/hash/md4_x86_32/info.txt12
-rw-r--r--src/lib/hash/md4_x86_32/md4_x86_32.cpp34
-rw-r--r--src/lib/hash/md4_x86_32/md4_x86_32.h28
-rw-r--r--src/lib/hash/md4_x86_32/md4_x86_32_imp.S137
-rw-r--r--src/lib/hash/md5/info.txt5
-rw-r--r--src/lib/hash/md5/md5.cpp136
-rw-r--r--src/lib/hash/md5/md5.h46
-rw-r--r--src/lib/hash/md5_x86_32/info.txt12
-rw-r--r--src/lib/hash/md5_x86_32/md5_x86_32.cpp31
-rw-r--r--src/lib/hash/md5_x86_32/md5_x86_32.h28
-rw-r--r--src/lib/hash/md5_x86_32/md5_x86_32_imp.S166
-rw-r--r--src/lib/hash/mdx_hash/info.txt3
-rw-r--r--src/lib/hash/mdx_hash/mdx_hash.cpp108
-rw-r--r--src/lib/hash/mdx_hash/mdx_hash.h68
-rw-r--r--src/lib/hash/par_hash/info.txt1
-rw-r--r--src/lib/hash/par_hash/par_hash.cpp100
-rw-r--r--src/lib/hash/par_hash/par_hash.h41
-rw-r--r--src/lib/hash/rmd128/info.txt5
-rw-r--r--src/lib/hash/rmd128/rmd128.cpp176
-rw-r--r--src/lib/hash/rmd128/rmd128.h38
-rw-r--r--src/lib/hash/rmd160/info.txt5
-rw-r--r--src/lib/hash/rmd160/rmd160.cpp210
-rw-r--r--src/lib/hash/rmd160/rmd160.h38
-rw-r--r--src/lib/hash/sha1/info.txt5
-rw-r--r--src/lib/hash/sha1/sha160.cpp161
-rw-r--r--src/lib/hash/sha1/sha160.h60
-rw-r--r--src/lib/hash/sha1_sse2/info.txt8
-rw-r--r--src/lib/hash/sha1_sse2/sha1_sse2.cpp335
-rw-r--r--src/lib/hash/sha1_sse2/sha1_sse2.h29
-rw-r--r--src/lib/hash/sha1_x86_32/info.txt12
-rw-r--r--src/lib/hash/sha1_x86_32/sha1_x86_32.cpp31
-rw-r--r--src/lib/hash/sha1_x86_32/sha1_x86_32.h31
-rw-r--r--src/lib/hash/sha1_x86_32/sha1_x86_32_imp.S244
-rw-r--r--src/lib/hash/sha1_x86_64/info.txt13
-rw-r--r--src/lib/hash/sha1_x86_64/sha1_x86_64.cpp31
-rw-r--r--src/lib/hash/sha1_x86_64/sha1_x86_64.h28
-rw-r--r--src/lib/hash/sha1_x86_64/sha1_x86_64_imp.S266
-rw-r--r--src/lib/hash/sha2_32/info.txt5
-rw-r--r--src/lib/hash/sha2_32/sha2_32.cpp227
-rw-r--r--src/lib/hash/sha2_32/sha2_32.h60
-rw-r--r--src/lib/hash/sha2_64/info.txt5
-rw-r--r--src/lib/hash/sha2_64/sha2_64.cpp242
-rw-r--r--src/lib/hash/sha2_64/sha2_64.h59
-rw-r--r--src/lib/hash/skein/info.txt5
-rw-r--r--src/lib/hash/skein/skein_512.cpp274
-rw-r--r--src/lib/hash/skein/skein_512.h52
-rw-r--r--src/lib/hash/tiger/info.txt5
-rw-r--r--src/lib/hash/tiger/tig_tab.cpp364
-rw-r--r--src/lib/hash/tiger/tiger.cpp187
-rw-r--r--src/lib/hash/tiger/tiger.h55
-rw-r--r--src/lib/hash/whirlpool/info.txt5
-rw-r--r--src/lib/hash/whirlpool/whrl_tab.cpp540
-rw-r--r--src/lib/hash/whirlpool/whrlpool.cpp146
-rw-r--r--src/lib/hash/whirlpool/whrlpool.h47
77 files changed, 6481 insertions, 0 deletions
diff --git a/src/lib/hash/bmw_512/bmw_512.cpp b/src/lib/hash/bmw_512/bmw_512.cpp
new file mode 100644
index 000000000..9dfa62214
--- /dev/null
+++ b/src/lib/hash/bmw_512/bmw_512.cpp
@@ -0,0 +1,204 @@
+/*
+* Blue Midnight Wish 512 (Round 2 tweaked)
+* (C) 2009 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/bmw_512.h>
+#include <botan/loadstor.h>
+#include <botan/rotate.h>
+
+namespace Botan {
+
+namespace {
+
+inline u64bit S0(u64bit X)
+ {
+ return (X >> 1) ^ (X << 3) ^ rotate_left(X, 4) ^ rotate_left(X, 37);
+ }
+
+inline u64bit S1(u64bit X)
+ {
+ return (X >> 1) ^ (X << 2) ^ rotate_left(X, 13) ^ rotate_left(X, 43);
+ }
+
+inline u64bit S2(u64bit X)
+ {
+ return (X >> 2) ^ (X << 1) ^ rotate_left(X, 19) ^ rotate_left(X, 53);
+ }
+
+inline u64bit S3(u64bit X)
+ {
+ return (X >> 2) ^ (X << 2) ^ rotate_left(X, 28) ^ rotate_left(X, 59);
+ }
+
+inline u64bit S4(u64bit X)
+ {
+ return (X >> 1) ^ X;
+ }
+
+/**
+* Blue Midnight Wish 512 compression function
+*/
+void BMW_512_compress(u64bit H[16], const u64bit M[16], u64bit Q[32])
+ {
+ const size_t EXPAND_1_ROUNDS = 2;
+
+ for(size_t i = 0; i != 16; ++i)
+ Q[i] = H[i] ^ M[i];
+
+ Q[16] = Q[ 5] - Q[ 7] + Q[10] + Q[13] + Q[14];
+ Q[17] = Q[ 6] - Q[ 8] + Q[11] + Q[14] - Q[15];
+ Q[18] = Q[ 0] + Q[ 7] + Q[ 9] - Q[12] + Q[15];
+ Q[19] = Q[ 0] - Q[ 1] + Q[ 8] - Q[10] + Q[13];
+ Q[20] = Q[ 1] + Q[ 2] + Q[ 9] - Q[11] - Q[14];
+ Q[21] = Q[ 3] - Q[ 2] + Q[10] - Q[12] + Q[15];
+ Q[22] = Q[ 4] - Q[ 0] - Q[ 3] - Q[11] + Q[13];
+ Q[23] = Q[ 1] - Q[ 4] - Q[ 5] - Q[12] - Q[14];
+ Q[24] = Q[ 2] - Q[ 5] - Q[ 6] + Q[13] - Q[15];
+ Q[25] = Q[ 0] - Q[ 3] + Q[ 6] - Q[ 7] + Q[14];
+ Q[26] = Q[ 8] - Q[ 1] - Q[ 4] - Q[ 7] + Q[15];
+ Q[27] = Q[ 8] - Q[ 0] - Q[ 2] - Q[ 5] + Q[ 9];
+ Q[28] = Q[ 1] + Q[ 3] - Q[ 6] - Q[ 9] + Q[10];
+ Q[29] = Q[ 2] + Q[ 4] + Q[ 7] + Q[10] + Q[11];
+ Q[30] = Q[ 3] - Q[ 5] + Q[ 8] - Q[11] - Q[12];
+ Q[31] = Q[12] - Q[ 4] - Q[ 6] - Q[ 9] + Q[13];
+
+ Q[ 0] = S0(Q[16]) + H[ 1];
+ Q[ 1] = S1(Q[17]) + H[ 2];
+ Q[ 2] = S2(Q[18]) + H[ 3];
+ Q[ 3] = S3(Q[19]) + H[ 4];
+ Q[ 4] = S4(Q[20]) + H[ 5];
+ Q[ 5] = S0(Q[21]) + H[ 6];
+ Q[ 6] = S1(Q[22]) + H[ 7];
+ Q[ 7] = S2(Q[23]) + H[ 8];
+ Q[ 8] = S3(Q[24]) + H[ 9];
+ Q[ 9] = S4(Q[25]) + H[10];
+ Q[10] = S0(Q[26]) + H[11];
+ Q[11] = S1(Q[27]) + H[12];
+ Q[12] = S2(Q[28]) + H[13];
+ Q[13] = S3(Q[29]) + H[14];
+ Q[14] = S4(Q[30]) + H[15];
+ Q[15] = S0(Q[31]) + H[ 0];
+
+ const u64bit EXPANSION_CONSTANT = 0x0555555555555555;
+
+ for(size_t i = 16; i != 16 + EXPAND_1_ROUNDS; ++i)
+ {
+ Q[i] = S1(Q[i-16]) + S2(Q[i-15]) + S3(Q[i-14]) + S0(Q[i-13]) +
+ S1(Q[i-12]) + S2(Q[i-11]) + S3(Q[i-10]) + S0(Q[i- 9]) +
+ S1(Q[i- 8]) + S2(Q[i- 7]) + S3(Q[i- 6]) + S0(Q[i- 5]) +
+ S1(Q[i- 4]) + S2(Q[i- 3]) + S3(Q[i- 2]) + S0(Q[i- 1]) +
+ ((rotate_left(M[(i-16) % 16], ((i-16)%16) + 1) +
+ rotate_left(M[(i-13) % 16], ((i-13)%16) + 1) -
+ rotate_left(M[(i- 6) % 16], ((i-6)%16) + 1) +
+ (EXPANSION_CONSTANT * i)) ^ H[(i-16+7)%16]);
+ }
+
+ for(size_t i = 16 + EXPAND_1_ROUNDS; i != 32; ++i)
+ {
+ Q[i] = Q[i-16] + rotate_left(Q[i-15], 5) +
+ Q[i-14] + rotate_left(Q[i-13], 11) +
+ Q[i-12] + rotate_left(Q[i-11], 27) +
+ Q[i-10] + rotate_left(Q[i- 9], 32) +
+ Q[i- 8] + rotate_left(Q[i- 7], 37) +
+ Q[i- 6] + rotate_left(Q[i- 5], 43) +
+ Q[i- 4] + rotate_left(Q[i- 3], 53) +
+ S4(Q[i - 2]) + ((Q[i-1] >> 2) ^ Q[i-1]) +
+ ((rotate_left(M[(i-16) % 16], ((i-16)%16 + 1)) +
+ rotate_left(M[(i-13) % 16], ((i-13)%16 + 1)) -
+ rotate_left(M[(i- 6) % 16], ((i-6)%16 + 1)) +
+ (EXPANSION_CONSTANT * i)) ^ H[(i-16+7)%16]);
+ }
+
+ u64bit XL = Q[16] ^ Q[17] ^ Q[18] ^ Q[19] ^
+ Q[20] ^ Q[21] ^ Q[22] ^ Q[23];
+
+ u64bit XH = Q[24] ^ Q[25] ^ Q[26] ^ Q[27] ^
+ Q[28] ^ Q[29] ^ Q[30] ^ Q[31];
+
+ XH ^= XL;
+
+ H[ 0] = ((XH << 5) ^ (Q[16] >> 5) ^ M[0]) + (XL ^ Q[24] ^ Q[0]);
+ H[ 1] = ((XH >> 7) ^ (Q[17] << 8) ^ M[1]) + (XL ^ Q[25] ^ Q[1]);
+ H[ 2] = ((XH >> 5) ^ (Q[18] << 5) ^ M[2]) + (XL ^ Q[26] ^ Q[2]);
+ H[ 3] = ((XH >> 1) ^ (Q[19] << 5) ^ M[3]) + (XL ^ Q[27] ^ Q[3]);
+ H[ 4] = ((XH >> 3) ^ (Q[20] ) ^ M[4]) + (XL ^ Q[28] ^ Q[4]);
+ H[ 5] = ((XH << 6) ^ (Q[21] >> 6) ^ M[5]) + (XL ^ Q[29] ^ Q[5]);
+ H[ 6] = ((XH >> 4) ^ (Q[22] << 6) ^ M[6]) + (XL ^ Q[30] ^ Q[6]);
+ H[ 7] = ((XH >> 11) ^ (Q[23] << 2) ^ M[7]) + (XL ^ Q[31] ^ Q[7]);
+
+ H[ 8] = rotate_left(H[4], 9) + (XH ^ Q[24] ^ M[ 8]) + ((XL << 8) ^ Q[23] ^ Q[ 8]);
+ H[ 9] = rotate_left(H[5], 10) + (XH ^ Q[25] ^ M[ 9]) + ((XL >> 6) ^ Q[16] ^ Q[ 9]);
+ H[10] = rotate_left(H[6], 11) + (XH ^ Q[26] ^ M[10]) + ((XL << 6) ^ Q[17] ^ Q[10]);
+ H[11] = rotate_left(H[7], 12) + (XH ^ Q[27] ^ M[11]) + ((XL << 4) ^ Q[18] ^ Q[11]);
+ H[12] = rotate_left(H[0], 13) + (XH ^ Q[28] ^ M[12]) + ((XL >> 3) ^ Q[19] ^ Q[12]);
+ H[13] = rotate_left(H[1], 14) + (XH ^ Q[29] ^ M[13]) + ((XL >> 4) ^ Q[20] ^ Q[13]);
+ H[14] = rotate_left(H[2], 15) + (XH ^ Q[30] ^ M[14]) + ((XL >> 7) ^ Q[21] ^ Q[14]);
+ H[15] = rotate_left(H[3], 16) + (XH ^ Q[31] ^ M[15]) + ((XL >> 2) ^ Q[22] ^ Q[15]);
+ }
+
+}
+
+void BMW_512::compress_n(const byte input[], size_t blocks)
+ {
+ for(size_t i = 0; i != blocks; ++i)
+ {
+ load_le(&M[0], input, M.size());
+
+ BMW_512_compress(&H[0], &M[0], &Q[0]);
+
+ input += hash_block_size();
+ }
+ }
+
+/*
+* Copy out the digest
+*/
+void BMW_512::copy_out(byte output[])
+ {
+ u64bit final[16] = {
+ 0xAAAAAAAAAAAAAAA0, 0xAAAAAAAAAAAAAAA1,
+ 0xAAAAAAAAAAAAAAA2, 0xAAAAAAAAAAAAAAA3,
+ 0xAAAAAAAAAAAAAAA4, 0xAAAAAAAAAAAAAAA5,
+ 0xAAAAAAAAAAAAAAA6, 0xAAAAAAAAAAAAAAA7,
+ 0xAAAAAAAAAAAAAAA8, 0xAAAAAAAAAAAAAAA9,
+ 0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAB,
+ 0xAAAAAAAAAAAAAAAC, 0xAAAAAAAAAAAAAAAD,
+ 0xAAAAAAAAAAAAAAAE, 0xAAAAAAAAAAAAAAAF };
+
+ BMW_512_compress(final, &H[0], &Q[0]);
+
+ for(size_t i = 0; i != output_length(); i += 8)
+ store_le(final[8 + i/8], output + i);
+ }
+
+/*
+* Clear memory of sensitive data
+*/
+void BMW_512::clear()
+ {
+ MDx_HashFunction::clear();
+ zeroise(M);
+ zeroise(Q);
+
+ H[ 0] = 0x8081828384858687;
+ H[ 1] = 0x88898A8B8C8D8E8F;
+ H[ 2] = 0x9091929394959697;
+ H[ 3] = 0x98999A9B9C9D9E9F;
+ H[ 4] = 0xA0A1A2A3A4A5A6A7;
+ H[ 5] = 0xA8A9AAABACADAEAF;
+ H[ 6] = 0xB0B1B2B3B4B5B6B7;
+ H[ 7] = 0xB8B9BABBBCBDBEBF;
+ H[ 8] = 0xC0C1C2C3C4C5C6C7;
+ H[ 9] = 0xC8C9CACBCCCDCECF;
+ H[10] = 0xD0D1D2D3D4D5D6D7;
+ H[11] = 0xD8D9DADBDCDDDEDF;
+ H[12] = 0xE0E1E2E3E4E5E6E7;
+ H[13] = 0xE8E9EAEBECEDEEEF;
+ H[14] = 0xF0F1F2F3F4F5F6F7;
+ H[15] = 0xF8F9FAFBFCFDFEFF;
+ }
+
+}
diff --git a/src/lib/hash/bmw_512/bmw_512.h b/src/lib/hash/bmw_512/bmw_512.h
new file mode 100644
index 000000000..b9ea63578
--- /dev/null
+++ b/src/lib/hash/bmw_512/bmw_512.h
@@ -0,0 +1,38 @@
+/*
+* Blue Midnight Wish 512 (Round 2 tweaked)
+* (C) 2009 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_BMW_512_H__
+#define BOTAN_BMW_512_H__
+
+#include <botan/mdx_hash.h>
+
+namespace Botan {
+
+/**
+* Blue Midnight Wish 512 (Round 2 tweaked version)
+*/
+class BOTAN_DLL BMW_512 : public MDx_HashFunction
+ {
+ public:
+ std::string name() const { return "BMW512"; }
+ size_t output_length() const { return 64; }
+ HashFunction* clone() const { return new BMW_512; }
+
+ void clear();
+
+ BMW_512() : MDx_HashFunction(128, false, true), H(16), M(16), Q(32)
+ { clear(); }
+ private:
+ void compress_n(const byte input[], size_t blocks);
+ void copy_out(byte output[]);
+
+ secure_vector<u64bit> H, M, Q;
+ };
+
+}
+
+#endif
diff --git a/src/lib/hash/bmw_512/info.txt b/src/lib/hash/bmw_512/info.txt
new file mode 100644
index 000000000..94dcbdd85
--- /dev/null
+++ b/src/lib/hash/bmw_512/info.txt
@@ -0,0 +1,5 @@
+define BMW_512 20131128
+
+<requires>
+mdx_hash
+</requires>
diff --git a/src/lib/hash/comb4p/comb4p.cpp b/src/lib/hash/comb4p/comb4p.cpp
new file mode 100644
index 000000000..7aec5972e
--- /dev/null
+++ b/src/lib/hash/comb4p/comb4p.cpp
@@ -0,0 +1,102 @@
+/*
+* Comb4P hash combiner
+* (C) 2010 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/comb4p.h>
+#include <botan/internal/xor_buf.h>
+#include <stdexcept>
+
+namespace Botan {
+
+namespace {
+
+void comb4p_round(secure_vector<byte>& out,
+ const secure_vector<byte>& in,
+ byte round_no,
+ HashFunction* h1,
+ HashFunction* h2)
+ {
+ h1->update(round_no);
+ h2->update(round_no);
+
+ h1->update(&in[0], in.size());
+ h2->update(&in[0], in.size());
+
+ secure_vector<byte> h_buf = h1->final();
+ xor_buf(&out[0], &h_buf[0], std::min(out.size(), h_buf.size()));
+
+ h_buf = h2->final();
+ xor_buf(&out[0], &h_buf[0], std::min(out.size(), h_buf.size()));
+ }
+
+}
+
+Comb4P::Comb4P(HashFunction* h1, HashFunction* h2) :
+ hash1(h1), hash2(h2)
+ {
+ if(hash1->name() == hash2->name())
+ throw std::invalid_argument("Comb4P: Must use two distinct hashes");
+
+ if(hash1->output_length() != hash2->output_length())
+ throw std::invalid_argument("Comb4P: Incompatible hashes " +
+ hash1->name() + " and " +
+ hash2->name());
+
+ clear();
+ }
+
+size_t Comb4P::hash_block_size() const
+ {
+ if(hash1->hash_block_size() == hash2->hash_block_size())
+ return hash1->hash_block_size();
+
+ /*
+ * Return LCM of the block sizes? This would probably be OK for
+ * HMAC, which is the main thing relying on knowing the block size.
+ */
+ return 0;
+ }
+
+void Comb4P::clear()
+ {
+ hash1->clear();
+ hash2->clear();
+
+ // Prep for processing next message, if any
+ hash1->update(0);
+ hash2->update(0);
+ }
+
+void Comb4P::add_data(const byte input[], size_t length)
+ {
+ hash1->update(input, length);
+ hash2->update(input, length);
+ }
+
+void Comb4P::final_result(byte out[])
+ {
+ secure_vector<byte> h1 = hash1->final();
+ secure_vector<byte> h2 = hash2->final();
+
+ // First round
+ xor_buf(&h1[0], &h2[0], std::min(h1.size(), h2.size()));
+
+ // Second round
+ comb4p_round(h2, h1, 1, hash1, hash2);
+
+ // Third round
+ comb4p_round(h1, h2, 2, hash1, hash2);
+
+ copy_mem(out , &h1[0], h1.size());
+ copy_mem(out + h1.size(), &h2[0], h2.size());
+
+ // Prep for processing next message, if any
+ hash1->update(0);
+ hash2->update(0);
+ }
+
+}
+
diff --git a/src/lib/hash/comb4p/comb4p.h b/src/lib/hash/comb4p/comb4p.h
new file mode 100644
index 000000000..e0cffc22b
--- /dev/null
+++ b/src/lib/hash/comb4p/comb4p.h
@@ -0,0 +1,61 @@
+/*
+* Comb4P hash combiner
+* (C) 2010 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_COMB4P_H__
+#define BOTAN_COMB4P_H__
+
+#include <botan/hash.h>
+
+namespace Botan {
+
+/**
+* Combines two hash functions using a Feistel scheme. Described in
+* "On the Security of Hash Function Combiners", Anja Lehmann
+*/
+class BOTAN_DLL Comb4P : public HashFunction
+ {
+ public:
+ /**
+ * @param h1 the first hash
+ * @param h2 the second hash
+ */
+ Comb4P(HashFunction* h1, HashFunction* h2);
+
+ Comb4P(const Comb4P&) = delete;
+ Comb4P& operator=(const Comb4P&) = delete;
+
+ ~Comb4P() { delete hash1; delete hash2; }
+
+ size_t hash_block_size() const;
+
+ size_t output_length() const
+ {
+ return hash1->output_length() + hash2->output_length();
+ }
+
+ HashFunction* clone() const
+ {
+ return new Comb4P(hash1->clone(), hash2->clone());
+ }
+
+ std::string name() const
+ {
+ return "Comb4P(" + hash1->name() + "," + hash2->name() + ")";
+ }
+
+ void clear();
+ private:
+ void add_data(const byte input[], size_t length);
+ void final_result(byte out[]);
+
+ HashFunction* hash1;
+ HashFunction* hash2;
+ };
+
+}
+
+#endif
diff --git a/src/lib/hash/comb4p/info.txt b/src/lib/hash/comb4p/info.txt
new file mode 100644
index 000000000..375895610
--- /dev/null
+++ b/src/lib/hash/comb4p/info.txt
@@ -0,0 +1 @@
+define COMB4P 20131128
diff --git a/src/lib/hash/gost_3411/gost_3411.cpp b/src/lib/hash/gost_3411/gost_3411.cpp
new file mode 100644
index 000000000..eb889c0a5
--- /dev/null
+++ b/src/lib/hash/gost_3411/gost_3411.cpp
@@ -0,0 +1,242 @@
+/*
+* GOST 34.11
+* (C) 2009 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/gost_3411.h>
+#include <botan/loadstor.h>
+#include <botan/rotate.h>
+#include <botan/internal/xor_buf.h>
+
+namespace Botan {
+
+/**
+* GOST 34.11 Constructor
+*/
+GOST_34_11::GOST_34_11() :
+ cipher(GOST_28147_89_Params("R3411_CryptoPro")),
+ buffer(32),
+ sum(32),
+ hash(32)
+ {
+ count = 0;
+ position = 0;
+ }
+
+void GOST_34_11::clear()
+ {
+ cipher.clear();
+ zeroise(sum);
+ zeroise(hash);
+ count = 0;
+ position = 0;
+ }
+
+/**
+* Hash additional inputs
+*/
+void GOST_34_11::add_data(const byte input[], size_t length)
+ {
+ count += length;
+
+ if(position)
+ {
+ buffer_insert(buffer, position, input, length);
+
+ if(position + length >= hash_block_size())
+ {
+ compress_n(&buffer[0], 1);
+ input += (hash_block_size() - position);
+ length -= (hash_block_size() - position);
+ position = 0;
+ }
+ }
+
+ const size_t full_blocks = length / hash_block_size();
+ const size_t remaining = length % hash_block_size();
+
+ if(full_blocks)
+ compress_n(input, full_blocks);
+
+ buffer_insert(buffer, position, input + full_blocks * hash_block_size(), remaining);
+ position += remaining;
+ }
+
+/**
+* The GOST 34.11 compression function
+*/
+void GOST_34_11::compress_n(const byte input[], size_t blocks)
+ {
+ for(size_t i = 0; i != blocks; ++i)
+ {
+ for(u16bit j = 0, carry = 0; j != 32; ++j)
+ {
+ u16bit s = sum[j] + input[32*i+j] + carry;
+ carry = get_byte(0, s);
+ sum[j] = get_byte(1, s);
+ }
+
+ byte S[32] = { 0 };
+
+ u64bit U[4], V[4];
+ load_be(U, &hash[0], 4);
+ load_be(V, input + 32*i, 4);
+
+ for(size_t j = 0; j != 4; ++j)
+ {
+ byte key[32] = { 0 };
+
+ // P transformation
+ for(size_t k = 0; k != 4; ++k)
+ for(size_t l = 0; l != 8; ++l)
+ key[4*l+k] = get_byte(l, U[k]) ^ get_byte(l, V[k]);
+
+ cipher.set_key(key, 32);
+ cipher.encrypt(&hash[8*j], S + 8*j);
+
+ if(j == 3)
+ break;
+
+ // A(x)
+ u64bit A_U = U[0];
+ U[0] = U[1];
+ U[1] = U[2];
+ U[2] = U[3];
+ U[3] = U[0] ^ A_U;
+
+ if(j == 1) // C_3
+ {
+ U[0] ^= 0x00FF00FF00FF00FF;
+ U[1] ^= 0xFF00FF00FF00FF00;
+ U[2] ^= 0x00FFFF00FF0000FF;
+ U[3] ^= 0xFF000000FFFF00FF;
+ }
+
+ // A(A(x))
+ u64bit AA_V_1 = V[0] ^ V[1];
+ u64bit AA_V_2 = V[1] ^ V[2];
+ V[0] = V[2];
+ V[1] = V[3];
+ V[2] = AA_V_1;
+ V[3] = AA_V_2;
+ }
+
+ byte S2[32] = { 0 };
+
+ // 12 rounds of psi
+ S2[ 0] = S[24];
+ S2[ 1] = S[25];
+ S2[ 2] = S[26];
+ S2[ 3] = S[27];
+ S2[ 4] = S[28];
+ S2[ 5] = S[29];
+ S2[ 6] = S[30];
+ S2[ 7] = S[31];
+ S2[ 8] = S[ 0] ^ S[ 2] ^ S[ 4] ^ S[ 6] ^ S[24] ^ S[30];
+ S2[ 9] = S[ 1] ^ S[ 3] ^ S[ 5] ^ S[ 7] ^ S[25] ^ S[31];
+ S2[10] = S[ 0] ^ S[ 8] ^ S[24] ^ S[26] ^ S[30];
+ S2[11] = S[ 1] ^ S[ 9] ^ S[25] ^ S[27] ^ S[31];
+ S2[12] = S[ 0] ^ S[ 4] ^ S[ 6] ^ S[10] ^ S[24] ^ S[26] ^ S[28] ^ S[30];
+ S2[13] = S[ 1] ^ S[ 5] ^ S[ 7] ^ S[11] ^ S[25] ^ S[27] ^ S[29] ^ S[31];
+ S2[14] = S[ 0] ^ S[ 4] ^ S[ 8] ^ S[12] ^ S[24] ^ S[26] ^ S[28];
+ S2[15] = S[ 1] ^ S[ 5] ^ S[ 9] ^ S[13] ^ S[25] ^ S[27] ^ S[29];
+ S2[16] = S[ 2] ^ S[ 6] ^ S[10] ^ S[14] ^ S[26] ^ S[28] ^ S[30];
+ S2[17] = S[ 3] ^ S[ 7] ^ S[11] ^ S[15] ^ S[27] ^ S[29] ^ S[31];
+ S2[18] = S[ 0] ^ S[ 2] ^ S[ 6] ^ S[ 8] ^ S[12] ^ S[16] ^ S[24] ^ S[28];
+ S2[19] = S[ 1] ^ S[ 3] ^ S[ 7] ^ S[ 9] ^ S[13] ^ S[17] ^ S[25] ^ S[29];
+ S2[20] = S[ 2] ^ S[ 4] ^ S[ 8] ^ S[10] ^ S[14] ^ S[18] ^ S[26] ^ S[30];
+ S2[21] = S[ 3] ^ S[ 5] ^ S[ 9] ^ S[11] ^ S[15] ^ S[19] ^ S[27] ^ S[31];
+ S2[22] = S[ 0] ^ S[ 2] ^ S[10] ^ S[12] ^ S[16] ^ S[20] ^ S[24] ^ S[28] ^ S[30];
+ S2[23] = S[ 1] ^ S[ 3] ^ S[11] ^ S[13] ^ S[17] ^ S[21] ^ S[25] ^ S[29] ^ S[31];
+ S2[24] = S[ 0] ^ S[ 6] ^ S[12] ^ S[14] ^ S[18] ^ S[22] ^ S[24] ^ S[26];
+ S2[25] = S[ 1] ^ S[ 7] ^ S[13] ^ S[15] ^ S[19] ^ S[23] ^ S[25] ^ S[27];
+ S2[26] = S[ 2] ^ S[ 8] ^ S[14] ^ S[16] ^ S[20] ^ S[24] ^ S[26] ^ S[28];
+ S2[27] = S[ 3] ^ S[ 9] ^ S[15] ^ S[17] ^ S[21] ^ S[25] ^ S[27] ^ S[29];
+ S2[28] = S[ 4] ^ S[10] ^ S[16] ^ S[18] ^ S[22] ^ S[26] ^ S[28] ^ S[30];
+ S2[29] = S[ 5] ^ S[11] ^ S[17] ^ S[19] ^ S[23] ^ S[27] ^ S[29] ^ S[31];
+ S2[30] = S[ 0] ^ S[ 2] ^ S[ 4] ^ S[12] ^ S[18] ^ S[20] ^ S[28];
+ S2[31] = S[ 1] ^ S[ 3] ^ S[ 5] ^ S[13] ^ S[19] ^ S[21] ^ S[29];
+
+ xor_buf(S, S2, input + 32*i, 32);
+
+ S2[0] = S[0] ^ S[2] ^ S[4] ^ S[6] ^ S[24] ^ S[30];
+ S2[1] = S[1] ^ S[3] ^ S[5] ^ S[7] ^ S[25] ^ S[31];
+
+ copy_mem(S, S+2, 30);
+ S[30] = S2[0];
+ S[31] = S2[1];
+
+ xor_buf(S, &hash[0], 32);
+
+ // 61 rounds of psi
+ S2[ 0] = S[ 2] ^ S[ 6] ^ S[14] ^ S[20] ^ S[22] ^ S[26] ^ S[28] ^ S[30];
+ S2[ 1] = S[ 3] ^ S[ 7] ^ S[15] ^ S[21] ^ S[23] ^ S[27] ^ S[29] ^ S[31];
+ S2[ 2] = S[ 0] ^ S[ 2] ^ S[ 6] ^ S[ 8] ^ S[16] ^ S[22] ^ S[28];
+ S2[ 3] = S[ 1] ^ S[ 3] ^ S[ 7] ^ S[ 9] ^ S[17] ^ S[23] ^ S[29];
+ S2[ 4] = S[ 2] ^ S[ 4] ^ S[ 8] ^ S[10] ^ S[18] ^ S[24] ^ S[30];
+ S2[ 5] = S[ 3] ^ S[ 5] ^ S[ 9] ^ S[11] ^ S[19] ^ S[25] ^ S[31];
+ S2[ 6] = S[ 0] ^ S[ 2] ^ S[10] ^ S[12] ^ S[20] ^ S[24] ^ S[26] ^ S[30];
+ S2[ 7] = S[ 1] ^ S[ 3] ^ S[11] ^ S[13] ^ S[21] ^ S[25] ^ S[27] ^ S[31];
+ S2[ 8] = S[ 0] ^ S[ 6] ^ S[12] ^ S[14] ^ S[22] ^ S[24] ^ S[26] ^ S[28] ^ S[30];
+ S2[ 9] = S[ 1] ^ S[ 7] ^ S[13] ^ S[15] ^ S[23] ^ S[25] ^ S[27] ^ S[29] ^ S[31];
+ S2[10] = S[ 0] ^ S[ 4] ^ S[ 6] ^ S[ 8] ^ S[14] ^ S[16] ^ S[26] ^ S[28];
+ S2[11] = S[ 1] ^ S[ 5] ^ S[ 7] ^ S[ 9] ^ S[15] ^ S[17] ^ S[27] ^ S[29];
+ S2[12] = S[ 2] ^ S[ 6] ^ S[ 8] ^ S[10] ^ S[16] ^ S[18] ^ S[28] ^ S[30];
+ S2[13] = S[ 3] ^ S[ 7] ^ S[ 9] ^ S[11] ^ S[17] ^ S[19] ^ S[29] ^ S[31];
+ S2[14] = S[ 0] ^ S[ 2] ^ S[ 6] ^ S[ 8] ^ S[10] ^ S[12] ^ S[18] ^ S[20] ^ S[24];
+ S2[15] = S[ 1] ^ S[ 3] ^ S[ 7] ^ S[ 9] ^ S[11] ^ S[13] ^ S[19] ^ S[21] ^ S[25];
+ S2[16] = S[ 2] ^ S[ 4] ^ S[ 8] ^ S[10] ^ S[12] ^ S[14] ^ S[20] ^ S[22] ^ S[26];
+ S2[17] = S[ 3] ^ S[ 5] ^ S[ 9] ^ S[11] ^ S[13] ^ S[15] ^ S[21] ^ S[23] ^ S[27];
+ S2[18] = S[ 4] ^ S[ 6] ^ S[10] ^ S[12] ^ S[14] ^ S[16] ^ S[22] ^ S[24] ^ S[28];
+ S2[19] = S[ 5] ^ S[ 7] ^ S[11] ^ S[13] ^ S[15] ^ S[17] ^ S[23] ^ S[25] ^ S[29];
+ S2[20] = S[ 6] ^ S[ 8] ^ S[12] ^ S[14] ^ S[16] ^ S[18] ^ S[24] ^ S[26] ^ S[30];
+ S2[21] = S[ 7] ^ S[ 9] ^ S[13] ^ S[15] ^ S[17] ^ S[19] ^ S[25] ^ S[27] ^ S[31];
+ S2[22] = S[ 0] ^ S[ 2] ^ S[ 4] ^ S[ 6] ^ S[ 8] ^ S[10] ^ S[14] ^ S[16] ^
+ S[18] ^ S[20] ^ S[24] ^ S[26] ^ S[28] ^ S[30];
+ S2[23] = S[ 1] ^ S[ 3] ^ S[ 5] ^ S[ 7] ^ S[ 9] ^ S[11] ^ S[15] ^ S[17] ^
+ S[19] ^ S[21] ^ S[25] ^ S[27] ^ S[29] ^ S[31];
+ S2[24] = S[ 0] ^ S[ 8] ^ S[10] ^ S[12] ^ S[16] ^ S[18] ^ S[20] ^ S[22] ^
+ S[24] ^ S[26] ^ S[28];
+ S2[25] = S[ 1] ^ S[ 9] ^ S[11] ^ S[13] ^ S[17] ^ S[19] ^ S[21] ^ S[23] ^
+ S[25] ^ S[27] ^ S[29];
+ S2[26] = S[ 2] ^ S[10] ^ S[12] ^ S[14] ^ S[18] ^ S[20] ^ S[22] ^ S[24] ^
+ S[26] ^ S[28] ^ S[30];
+ S2[27] = S[ 3] ^ S[11] ^ S[13] ^ S[15] ^ S[19] ^ S[21] ^ S[23] ^ S[25] ^
+ S[27] ^ S[29] ^ S[31];
+ S2[28] = S[ 0] ^ S[ 2] ^ S[ 6] ^ S[12] ^ S[14] ^ S[16] ^ S[20] ^ S[22] ^ S[26] ^ S[28];
+ S2[29] = S[ 1] ^ S[ 3] ^ S[ 7] ^ S[13] ^ S[15] ^ S[17] ^ S[21] ^ S[23] ^ S[27] ^ S[29];
+ S2[30] = S[ 2] ^ S[ 4] ^ S[ 8] ^ S[14] ^ S[16] ^ S[18] ^ S[22] ^ S[24] ^ S[28] ^ S[30];
+ S2[31] = S[ 3] ^ S[ 5] ^ S[ 9] ^ S[15] ^ S[17] ^ S[19] ^ S[23] ^ S[25] ^ S[29] ^ S[31];
+
+ copy_mem(&hash[0], &S2[0], 32);
+ }
+ }
+
+/**
+* Produce the final GOST 34.11 output
+*/
+void GOST_34_11::final_result(byte out[])
+ {
+ if(position)
+ {
+ clear_mem(&buffer[0] + position, buffer.size() - position);
+ compress_n(&buffer[0], 1);
+ }
+
+ secure_vector<byte> length_buf(32);
+ const u64bit bit_count = count * 8;
+ store_le(bit_count, &length_buf[0]);
+
+ secure_vector<byte> sum_buf = sum;
+
+ compress_n(&length_buf[0], 1);
+ compress_n(&sum_buf[0], 1);
+
+ copy_mem(out, &hash[0], 32);
+
+ clear();
+ }
+
+}
diff --git a/src/lib/hash/gost_3411/gost_3411.h b/src/lib/hash/gost_3411/gost_3411.h
new file mode 100644
index 000000000..5437ca4d8
--- /dev/null
+++ b/src/lib/hash/gost_3411/gost_3411.h
@@ -0,0 +1,44 @@
+/*
+* GOST 34.11
+* (C) 2009 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_GOST_3411_H__
+#define BOTAN_GOST_3411_H__
+
+#include <botan/hash.h>
+#include <botan/gost_28147.h>
+
+namespace Botan {
+
+/**
+* GOST 34.11
+*/
+class BOTAN_DLL GOST_34_11 : public HashFunction
+ {
+ public:
+ std::string name() const { return "GOST-R-34.11-94" ; }
+ size_t output_length() const { return 32; }
+ size_t hash_block_size() const { return 32; }
+ HashFunction* clone() const { return new GOST_34_11; }
+
+ void clear();
+
+ GOST_34_11();
+ private:
+ void compress_n(const byte input[], size_t blocks);
+
+ void add_data(const byte[], size_t);
+ void final_result(byte[]);
+
+ GOST_28147_89 cipher;
+ secure_vector<byte> buffer, sum, hash;
+ size_t position;
+ u64bit count;
+ };
+
+}
+
+#endif
diff --git a/src/lib/hash/gost_3411/info.txt b/src/lib/hash/gost_3411/info.txt
new file mode 100644
index 000000000..af8eddac6
--- /dev/null
+++ b/src/lib/hash/gost_3411/info.txt
@@ -0,0 +1,5 @@
+define GOST_34_11 20131128
+
+<requires>
+gost_28147
+</requires>
diff --git a/src/lib/hash/has160/has160.cpp b/src/lib/hash/has160/has160.cpp
new file mode 100644
index 000000000..6890ccb85
--- /dev/null
+++ b/src/lib/hash/has160/has160.cpp
@@ -0,0 +1,165 @@
+/*
+* HAS-160
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/has160.h>
+#include <botan/loadstor.h>
+#include <botan/rotate.h>
+
+namespace Botan {
+
+namespace HAS_160_F {
+
+/*
+* HAS-160 F1 Function
+*/
+inline void F1(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E,
+ u32bit msg, u32bit rot)
+ {
+ E += rotate_left(A, rot) + (D ^ (B & (C ^ D))) + msg;
+ B = rotate_left(B, 10);
+ }
+
+/*
+* HAS-160 F2 Function
+*/
+inline void F2(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E,
+ u32bit msg, u32bit rot)
+ {
+ E += rotate_left(A, rot) + (B ^ C ^ D) + msg + 0x5A827999;
+ B = rotate_left(B, 17);
+ }
+
+/*
+* HAS-160 F3 Function
+*/
+inline void F3(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E,
+ u32bit msg, u32bit rot)
+ {
+ E += rotate_left(A, rot) + (C ^ (B | ~D)) + msg + 0x6ED9EBA1;
+ B = rotate_left(B, 25);
+ }
+
+/*
+* HAS-160 F4 Function
+*/
+inline void F4(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E,
+ u32bit msg, u32bit rot)
+ {
+ E += rotate_left(A, rot) + (B ^ C ^ D) + msg + 0x8F1BBCDC;
+ B = rotate_left(B, 30);
+ }
+
+}
+
+/*
+* HAS-160 Compression Function
+*/
+void HAS_160::compress_n(const byte input[], size_t blocks)
+ {
+ using namespace HAS_160_F;
+
+ u32bit A = digest[0], B = digest[1], C = digest[2],
+ D = digest[3], E = digest[4];
+
+ for(size_t i = 0; i != blocks; ++i)
+ {
+ load_le(&X[0], input, 16);
+
+ X[16] = X[ 0] ^ X[ 1] ^ X[ 2] ^ X[ 3];
+ X[17] = X[ 4] ^ X[ 5] ^ X[ 6] ^ X[ 7];
+ X[18] = X[ 8] ^ X[ 9] ^ X[10] ^ X[11];
+ X[19] = X[12] ^ X[13] ^ X[14] ^ X[15];
+ F1(A,B,C,D,E,X[18], 5); F1(E,A,B,C,D,X[ 0],11);
+ F1(D,E,A,B,C,X[ 1], 7); F1(C,D,E,A,B,X[ 2],15);
+ F1(B,C,D,E,A,X[ 3], 6); F1(A,B,C,D,E,X[19],13);
+ F1(E,A,B,C,D,X[ 4], 8); F1(D,E,A,B,C,X[ 5],14);
+ F1(C,D,E,A,B,X[ 6], 7); F1(B,C,D,E,A,X[ 7],12);
+ F1(A,B,C,D,E,X[16], 9); F1(E,A,B,C,D,X[ 8],11);
+ F1(D,E,A,B,C,X[ 9], 8); F1(C,D,E,A,B,X[10],15);
+ F1(B,C,D,E,A,X[11], 6); F1(A,B,C,D,E,X[17],12);
+ F1(E,A,B,C,D,X[12], 9); F1(D,E,A,B,C,X[13],14);
+ F1(C,D,E,A,B,X[14], 5); F1(B,C,D,E,A,X[15],13);
+
+ X[16] = X[ 3] ^ X[ 6] ^ X[ 9] ^ X[12];
+ X[17] = X[ 2] ^ X[ 5] ^ X[ 8] ^ X[15];
+ X[18] = X[ 1] ^ X[ 4] ^ X[11] ^ X[14];
+ X[19] = X[ 0] ^ X[ 7] ^ X[10] ^ X[13];
+ F2(A,B,C,D,E,X[18], 5); F2(E,A,B,C,D,X[ 3],11);
+ F2(D,E,A,B,C,X[ 6], 7); F2(C,D,E,A,B,X[ 9],15);
+ F2(B,C,D,E,A,X[12], 6); F2(A,B,C,D,E,X[19],13);
+ F2(E,A,B,C,D,X[15], 8); F2(D,E,A,B,C,X[ 2],14);
+ F2(C,D,E,A,B,X[ 5], 7); F2(B,C,D,E,A,X[ 8],12);
+ F2(A,B,C,D,E,X[16], 9); F2(E,A,B,C,D,X[11],11);
+ F2(D,E,A,B,C,X[14], 8); F2(C,D,E,A,B,X[ 1],15);
+ F2(B,C,D,E,A,X[ 4], 6); F2(A,B,C,D,E,X[17],12);
+ F2(E,A,B,C,D,X[ 7], 9); F2(D,E,A,B,C,X[10],14);
+ F2(C,D,E,A,B,X[13], 5); F2(B,C,D,E,A,X[ 0],13);
+
+ X[16] = X[ 5] ^ X[ 7] ^ X[12] ^ X[14];
+ X[17] = X[ 0] ^ X[ 2] ^ X[ 9] ^ X[11];
+ X[18] = X[ 4] ^ X[ 6] ^ X[13] ^ X[15];
+ X[19] = X[ 1] ^ X[ 3] ^ X[ 8] ^ X[10];
+ F3(A,B,C,D,E,X[18], 5); F3(E,A,B,C,D,X[12],11);
+ F3(D,E,A,B,C,X[ 5], 7); F3(C,D,E,A,B,X[14],15);
+ F3(B,C,D,E,A,X[ 7], 6); F3(A,B,C,D,E,X[19],13);
+ F3(E,A,B,C,D,X[ 0], 8); F3(D,E,A,B,C,X[ 9],14);
+ F3(C,D,E,A,B,X[ 2], 7); F3(B,C,D,E,A,X[11],12);
+ F3(A,B,C,D,E,X[16], 9); F3(E,A,B,C,D,X[ 4],11);
+ F3(D,E,A,B,C,X[13], 8); F3(C,D,E,A,B,X[ 6],15);
+ F3(B,C,D,E,A,X[15], 6); F3(A,B,C,D,E,X[17],12);
+ F3(E,A,B,C,D,X[ 8], 9); F3(D,E,A,B,C,X[ 1],14);
+ F3(C,D,E,A,B,X[10], 5); F3(B,C,D,E,A,X[ 3],13);
+
+ X[16] = X[ 2] ^ X[ 7] ^ X[ 8] ^ X[13];
+ X[17] = X[ 3] ^ X[ 4] ^ X[ 9] ^ X[14];
+ X[18] = X[ 0] ^ X[ 5] ^ X[10] ^ X[15];
+ X[19] = X[ 1] ^ X[ 6] ^ X[11] ^ X[12];
+ F4(A,B,C,D,E,X[18], 5); F4(E,A,B,C,D,X[ 7],11);
+ F4(D,E,A,B,C,X[ 2], 7); F4(C,D,E,A,B,X[13],15);
+ F4(B,C,D,E,A,X[ 8], 6); F4(A,B,C,D,E,X[19],13);
+ F4(E,A,B,C,D,X[ 3], 8); F4(D,E,A,B,C,X[14],14);
+ F4(C,D,E,A,B,X[ 9], 7); F4(B,C,D,E,A,X[ 4],12);
+ F4(A,B,C,D,E,X[16], 9); F4(E,A,B,C,D,X[15],11);
+ F4(D,E,A,B,C,X[10], 8); F4(C,D,E,A,B,X[ 5],15);
+ F4(B,C,D,E,A,X[ 0], 6); F4(A,B,C,D,E,X[17],12);
+ F4(E,A,B,C,D,X[11], 9); F4(D,E,A,B,C,X[ 6],14);
+ F4(C,D,E,A,B,X[ 1], 5); F4(B,C,D,E,A,X[12],13);
+
+ A = (digest[0] += A);
+ B = (digest[1] += B);
+ C = (digest[2] += C);
+ D = (digest[3] += D);
+ E = (digest[4] += E);
+
+ input += hash_block_size();
+ }
+ }
+
+/*
+* Copy out the digest
+*/
+void HAS_160::copy_out(byte output[])
+ {
+ for(size_t i = 0; i != output_length(); i += 4)
+ store_le(digest[i/4], output + i);
+ }
+
+/*
+* Clear memory of sensitive data
+*/
+void HAS_160::clear()
+ {
+ MDx_HashFunction::clear();
+ zeroise(X);
+ digest[0] = 0x67452301;
+ digest[1] = 0xEFCDAB89;
+ digest[2] = 0x98BADCFE;
+ digest[3] = 0x10325476;
+ digest[4] = 0xC3D2E1F0;
+ }
+
+}
diff --git a/src/lib/hash/has160/has160.h b/src/lib/hash/has160/has160.h
new file mode 100644
index 000000000..9947d9580
--- /dev/null
+++ b/src/lib/hash/has160/has160.h
@@ -0,0 +1,39 @@
+/*
+* HAS-160
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_HAS_160_H__
+#define BOTAN_HAS_160_H__
+
+#include <botan/mdx_hash.h>
+
+namespace Botan {
+
+/**
+* HAS-160, a Korean hash function standardized in
+* TTAS.KO-12.0011/R1. Used in conjuction with KCDSA
+*/
+class BOTAN_DLL HAS_160 : public MDx_HashFunction
+ {
+ public:
+ std::string name() const { return "HAS-160"; }
+ size_t output_length() const { return 20; }
+ HashFunction* clone() const { return new HAS_160; }
+
+ void clear();
+
+ HAS_160() : MDx_HashFunction(64, false, true), X(20), digest(5)
+ { clear(); }
+ private:
+ void compress_n(const byte[], size_t blocks);
+ void copy_out(byte[]);
+
+ secure_vector<u32bit> X, digest;
+ };
+
+}
+
+#endif
diff --git a/src/lib/hash/has160/info.txt b/src/lib/hash/has160/info.txt
new file mode 100644
index 000000000..cf403dad5
--- /dev/null
+++ b/src/lib/hash/has160/info.txt
@@ -0,0 +1,5 @@
+define HAS_160 20131128
+
+<requires>
+mdx_hash
+</requires>
diff --git a/src/lib/hash/hash.h b/src/lib/hash/hash.h
new file mode 100644
index 000000000..1e4b045e2
--- /dev/null
+++ b/src/lib/hash/hash.h
@@ -0,0 +1,37 @@
+/*
+* Hash Function Base Class
+* (C) 1999-2008 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_HASH_FUNCTION_BASE_CLASS_H__
+#define BOTAN_HASH_FUNCTION_BASE_CLASS_H__
+
+#include <botan/buf_comp.h>
+#include <botan/algo_base.h>
+#include <string>
+
+namespace Botan {
+
+/**
+* This class represents hash function (message digest) objects
+*/
+class BOTAN_DLL HashFunction : public Buffered_Computation,
+ public Algorithm
+ {
+ public:
+ /**
+ * @return new object representing the same algorithm as *this
+ */
+ virtual HashFunction* clone() const = 0;
+
+ /**
+ * @return hash block size as defined for this algorithm
+ */
+ virtual size_t hash_block_size() const { return 0; }
+ };
+
+}
+
+#endif
diff --git a/src/lib/hash/info.txt b/src/lib/hash/info.txt
new file mode 100644
index 000000000..d991577f7
--- /dev/null
+++ b/src/lib/hash/info.txt
@@ -0,0 +1,3 @@
+<requires>
+algo_base
+</requires>
diff --git a/src/lib/hash/keccak/info.txt b/src/lib/hash/keccak/info.txt
new file mode 100644
index 000000000..ecdfba19c
--- /dev/null
+++ b/src/lib/hash/keccak/info.txt
@@ -0,0 +1,5 @@
+define KECCAK 20131128
+
+<requires>
+alloc
+</requires>
diff --git a/src/lib/hash/keccak/keccak.cpp b/src/lib/hash/keccak/keccak.cpp
new file mode 100644
index 000000000..e34c0fd43
--- /dev/null
+++ b/src/lib/hash/keccak/keccak.cpp
@@ -0,0 +1,198 @@
+/*
+* Keccak
+* (C) 2010 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/keccak.h>
+#include <botan/loadstor.h>
+#include <botan/parsing.h>
+#include <botan/exceptn.h>
+#include <botan/rotate.h>
+#include <botan/internal/xor_buf.h>
+
+namespace Botan {
+
+namespace {
+
+void keccak_f_1600(u64bit A[25])
+ {
+ static const u64bit RC[24] = {
+ 0x0000000000000001, 0x0000000000008082, 0x800000000000808A,
+ 0x8000000080008000, 0x000000000000808B, 0x0000000080000001,
+ 0x8000000080008081, 0x8000000000008009, 0x000000000000008A,
+ 0x0000000000000088, 0x0000000080008009, 0x000000008000000A,
+ 0x000000008000808B, 0x800000000000008B, 0x8000000000008089,
+ 0x8000000000008003, 0x8000000000008002, 0x8000000000000080,
+ 0x000000000000800A, 0x800000008000000A, 0x8000000080008081,
+ 0x8000000000008080, 0x0000000080000001, 0x8000000080008008
+ };
+
+ for(size_t i = 0; i != 24; ++i)
+ {
+ const u64bit C0 = A[0] ^ A[5] ^ A[10] ^ A[15] ^ A[20];
+ const u64bit C1 = A[1] ^ A[6] ^ A[11] ^ A[16] ^ A[21];
+ const u64bit C2 = A[2] ^ A[7] ^ A[12] ^ A[17] ^ A[22];
+ const u64bit C3 = A[3] ^ A[8] ^ A[13] ^ A[18] ^ A[23];
+ const u64bit C4 = A[4] ^ A[9] ^ A[14] ^ A[19] ^ A[24];
+
+ const u64bit D0 = rotate_left(C0, 1) ^ C3;
+ const u64bit D1 = rotate_left(C1, 1) ^ C4;
+ const u64bit D2 = rotate_left(C2, 1) ^ C0;
+ const u64bit D3 = rotate_left(C3, 1) ^ C1;
+ const u64bit D4 = rotate_left(C4, 1) ^ C2;
+
+ const u64bit B00 = A[ 0] ^ D1;
+ const u64bit B01 = rotate_left(A[ 6] ^ D2, 44);
+ const u64bit B02 = rotate_left(A[12] ^ D3, 43);
+ const u64bit B03 = rotate_left(A[18] ^ D4, 21);
+ const u64bit B04 = rotate_left(A[24] ^ D0, 14);
+ const u64bit B05 = rotate_left(A[ 3] ^ D4, 28);
+ const u64bit B06 = rotate_left(A[ 9] ^ D0, 20);
+ const u64bit B07 = rotate_left(A[10] ^ D1, 3);
+ const u64bit B08 = rotate_left(A[16] ^ D2, 45);
+ const u64bit B09 = rotate_left(A[22] ^ D3, 61);
+ const u64bit B10 = rotate_left(A[ 1] ^ D2, 1);
+ const u64bit B11 = rotate_left(A[ 7] ^ D3, 6);
+ const u64bit B12 = rotate_left(A[13] ^ D4, 25);
+ const u64bit B13 = rotate_left(A[19] ^ D0, 8);
+ const u64bit B14 = rotate_left(A[20] ^ D1, 18);
+ const u64bit B15 = rotate_left(A[ 4] ^ D0, 27);
+ const u64bit B16 = rotate_left(A[ 5] ^ D1, 36);
+ const u64bit B17 = rotate_left(A[11] ^ D2, 10);
+ const u64bit B18 = rotate_left(A[17] ^ D3, 15);
+ const u64bit B19 = rotate_left(A[23] ^ D4, 56);
+ const u64bit B20 = rotate_left(A[ 2] ^ D3, 62);
+ const u64bit B21 = rotate_left(A[ 8] ^ D4, 55);
+ const u64bit B22 = rotate_left(A[14] ^ D0, 39);
+ const u64bit B23 = rotate_left(A[15] ^ D1, 41);
+ const u64bit B24 = rotate_left(A[21] ^ D2, 2);
+
+ A[ 0] = B00 ^ (~B01 & B02);
+ A[ 1] = B01 ^ (~B02 & B03);
+ A[ 2] = B02 ^ (~B03 & B04);
+ A[ 3] = B03 ^ (~B04 & B00);
+ A[ 4] = B04 ^ (~B00 & B01);
+ A[ 5] = B05 ^ (~B06 & B07);
+ A[ 6] = B06 ^ (~B07 & B08);
+ A[ 7] = B07 ^ (~B08 & B09);
+ A[ 8] = B08 ^ (~B09 & B05);
+ A[ 9] = B09 ^ (~B05 & B06);
+ A[10] = B10 ^ (~B11 & B12);
+ A[11] = B11 ^ (~B12 & B13);
+ A[12] = B12 ^ (~B13 & B14);
+ A[13] = B13 ^ (~B14 & B10);
+ A[14] = B14 ^ (~B10 & B11);
+ A[15] = B15 ^ (~B16 & B17);
+ A[16] = B16 ^ (~B17 & B18);
+ A[17] = B17 ^ (~B18 & B19);
+ A[18] = B18 ^ (~B19 & B15);
+ A[19] = B19 ^ (~B15 & B16);
+ A[20] = B20 ^ (~B21 & B22);
+ A[21] = B21 ^ (~B22 & B23);
+ A[22] = B22 ^ (~B23 & B24);
+ A[23] = B23 ^ (~B24 & B20);
+ A[24] = B24 ^ (~B20 & B21);
+
+ A[0] ^= RC[i];
+ }
+ }
+
+}
+
+Keccak_1600::Keccak_1600(size_t output_bits) :
+ output_bits(output_bits),
+ bitrate(1600 - 2*output_bits),
+ S(25),
+ S_pos(0)
+ {
+ // We only support the parameters for the SHA-3 proposal
+
+ if(output_bits != 224 && output_bits != 256 &&
+ output_bits != 384 && output_bits != 512)
+ throw Invalid_Argument("Keccak_1600: Invalid output length " +
+ std::to_string(output_bits));
+ }
+
+std::string Keccak_1600::name() const
+ {
+ return "Keccak-1600(" + std::to_string(output_bits) + ")";
+ }
+
+HashFunction* Keccak_1600::clone() const
+ {
+ return new Keccak_1600(output_bits);
+ }
+
+void Keccak_1600::clear()
+ {
+ zeroise(S);
+ S_pos = 0;
+ }
+
+void Keccak_1600::add_data(const byte input[], size_t length)
+ {
+ if(length == 0)
+ return;
+
+ while(length)
+ {
+ size_t to_take = std::min(length, bitrate / 8 - S_pos);
+
+ length -= to_take;
+
+ while(to_take && S_pos % 8)
+ {
+ S[S_pos / 8] ^= static_cast<u64bit>(input[0]) << (8 * (S_pos % 8));
+
+ ++S_pos;
+ ++input;
+ --to_take;
+ }
+
+ while(to_take && to_take % 8 == 0)
+ {
+ S[S_pos / 8] ^= load_le<u64bit>(input, 0);
+ S_pos += 8;
+ input += 8;
+ to_take -= 8;
+ }
+
+ while(to_take)
+ {
+ S[S_pos / 8] ^= static_cast<u64bit>(input[0]) << (8 * (S_pos % 8));
+
+ ++S_pos;
+ ++input;
+ --to_take;
+ }
+
+ if(S_pos == bitrate / 8)
+ {
+ keccak_f_1600(&S[0]);
+ S_pos = 0;
+ }
+ }
+ }
+
+void Keccak_1600::final_result(byte output[])
+ {
+ std::vector<byte> padding(bitrate / 8 - S_pos);
+
+ padding[0] = 0x01;
+ padding[padding.size()-1] |= 0x80;
+
+ add_data(&padding[0], padding.size());
+
+ /*
+ * We never have to run the permutation again because we only support
+ * limited output lengths
+ */
+ for(size_t i = 0; i != output_bits/8; ++i)
+ output[i] = get_byte(7 - (i % 8), S[i/8]);
+
+ clear();
+ }
+
+}
diff --git a/src/lib/hash/keccak/keccak.h b/src/lib/hash/keccak/keccak.h
new file mode 100644
index 000000000..e91a04d32
--- /dev/null
+++ b/src/lib/hash/keccak/keccak.h
@@ -0,0 +1,47 @@
+/*
+* Keccak
+* (C) 2010 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_KECCAK_H__
+#define BOTAN_KECCAK_H__
+
+#include <botan/hash.h>
+#include <botan/secmem.h>
+#include <string>
+
+namespace Botan {
+
+/**
+* Keccak[1600], a SHA-3 candidate
+*/
+class BOTAN_DLL Keccak_1600 : public HashFunction
+ {
+ public:
+
+ /**
+ * @param output_bits the size of the hash output; must be one of
+ * 224, 256, 384, or 512
+ */
+ Keccak_1600(size_t output_bits = 512);
+
+ size_t hash_block_size() const { return bitrate / 8; }
+ size_t output_length() const { return output_bits / 8; }
+
+ HashFunction* clone() const;
+ std::string name() const;
+ void clear();
+ private:
+ void add_data(const byte input[], size_t length);
+ void final_result(byte out[]);
+
+ size_t output_bits, bitrate;
+ secure_vector<u64bit> S;
+ size_t S_pos;
+ };
+
+}
+
+#endif
diff --git a/src/lib/hash/md2/info.txt b/src/lib/hash/md2/info.txt
new file mode 100644
index 000000000..8ea7dc393
--- /dev/null
+++ b/src/lib/hash/md2/info.txt
@@ -0,0 +1 @@
+define MD2 20131128
diff --git a/src/lib/hash/md2/md2.cpp b/src/lib/hash/md2/md2.cpp
new file mode 100644
index 000000000..8f6a90208
--- /dev/null
+++ b/src/lib/hash/md2/md2.cpp
@@ -0,0 +1,113 @@
+/*
+* MD2
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/md2.h>
+#include <botan/internal/xor_buf.h>
+
+namespace Botan {
+
+/**
+* MD2 Compression Function
+*/
+void MD2::hash(const byte input[])
+ {
+ static const byte SBOX[256] = {
+ 0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36, 0x54, 0xA1,
+ 0xEC, 0xF0, 0x06, 0x13, 0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C,
+ 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA, 0x1E, 0x9B, 0x57, 0x3C,
+ 0xFD, 0xD4, 0xE0, 0x16, 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12,
+ 0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E,
+ 0xBB, 0x2F, 0xEE, 0x7A, 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F,
+ 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21, 0x80, 0x7F, 0x5D, 0x9A,
+ 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03,
+ 0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A,
+ 0xAC, 0x56, 0xAA, 0xC6, 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6,
+ 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, 0x45, 0x9D, 0x70, 0x59,
+ 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02,
+ 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69,
+ 0x34, 0x40, 0x7E, 0x0F, 0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A,
+ 0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, 0x2C, 0x53, 0x0D, 0x6E,
+ 0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52,
+ 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA, 0x24, 0xE1, 0x7B, 0x08,
+ 0x0C, 0xBD, 0xB1, 0x4A, 0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D,
+ 0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39, 0xF2, 0xEF, 0xB7, 0x0E,
+ 0x66, 0x58, 0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
+ 0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99, 0x8D, 0x33,
+ 0x9F, 0x11, 0x83, 0x14 };
+
+ buffer_insert(X, 16, input, hash_block_size());
+ xor_buf(&X[32], &X[0], &X[16], hash_block_size());
+ byte T = 0;
+
+ for(size_t i = 0; i != 18; ++i)
+ {
+ for(size_t k = 0; k != 48; k += 8)
+ {
+ T = X[k ] ^= SBOX[T]; T = X[k+1] ^= SBOX[T];
+ T = X[k+2] ^= SBOX[T]; T = X[k+3] ^= SBOX[T];
+ T = X[k+4] ^= SBOX[T]; T = X[k+5] ^= SBOX[T];
+ T = X[k+6] ^= SBOX[T]; T = X[k+7] ^= SBOX[T];
+ }
+
+ T += static_cast<byte>(i);
+ }
+
+ T = checksum[15];
+ for(size_t i = 0; i != hash_block_size(); ++i)
+ T = checksum[i] ^= SBOX[input[i] ^ T];
+ }
+
+/**
+* Update the hash
+*/
+void MD2::add_data(const byte input[], size_t length)
+ {
+ buffer_insert(buffer, position, input, length);
+
+ if(position + length >= hash_block_size())
+ {
+ hash(&buffer[0]);
+ input += (hash_block_size() - position);
+ length -= (hash_block_size() - position);
+ while(length >= hash_block_size())
+ {
+ hash(input);
+ input += hash_block_size();
+ length -= hash_block_size();
+ }
+ copy_mem(&buffer[0], input, length);
+ position = 0;
+ }
+ position += length;
+ }
+
+/**
+* Finalize a MD2 Hash
+*/
+void MD2::final_result(byte output[])
+ {
+ for(size_t i = position; i != hash_block_size(); ++i)
+ buffer[i] = static_cast<byte>(hash_block_size() - position);
+
+ hash(&buffer[0]);
+ hash(&checksum[0]);
+ copy_mem(output, &X[0], output_length());
+ clear();
+ }
+
+/**
+* Clear memory of sensitive data
+*/
+void MD2::clear()
+ {
+ zeroise(X);
+ zeroise(checksum);
+ zeroise(buffer);
+ position = 0;
+ }
+
+}
diff --git a/src/lib/hash/md2/md2.h b/src/lib/hash/md2/md2.h
new file mode 100644
index 000000000..032d8a8e0
--- /dev/null
+++ b/src/lib/hash/md2/md2.h
@@ -0,0 +1,41 @@
+/*
+* MD2
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_MD2_H__
+#define BOTAN_MD2_H__
+
+#include <botan/hash.h>
+
+namespace Botan {
+
+/**
+* MD2
+*/
+class BOTAN_DLL MD2 : public HashFunction
+ {
+ public:
+ std::string name() const { return "MD2"; }
+ size_t output_length() const { return 16; }
+ size_t hash_block_size() const { return 16; }
+ HashFunction* clone() const { return new MD2; }
+
+ void clear();
+
+ MD2() : X(48), checksum(16), buffer(16)
+ { clear(); }
+ private:
+ void add_data(const byte[], size_t);
+ void hash(const byte[]);
+ void final_result(byte[]);
+
+ secure_vector<byte> X, checksum, buffer;
+ size_t position;
+ };
+
+}
+
+#endif
diff --git a/src/lib/hash/md4/info.txt b/src/lib/hash/md4/info.txt
new file mode 100644
index 000000000..8894d4af3
--- /dev/null
+++ b/src/lib/hash/md4/info.txt
@@ -0,0 +1,5 @@
+define MD4 20131128
+
+<requires>
+mdx_hash
+</requires>
diff --git a/src/lib/hash/md4/md4.cpp b/src/lib/hash/md4/md4.cpp
new file mode 100644
index 000000000..9b9ebab36
--- /dev/null
+++ b/src/lib/hash/md4/md4.cpp
@@ -0,0 +1,114 @@
+/*
+* MD4
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/md4.h>
+#include <botan/loadstor.h>
+#include <botan/rotate.h>
+
+namespace Botan {
+
+namespace {
+
+/*
+* MD4 FF Function
+*/
+inline void FF(u32bit& A, u32bit B, u32bit C, u32bit D, u32bit M, byte S)
+ {
+ A += (D ^ (B & (C ^ D))) + M;
+ A = rotate_left(A, S);
+ }
+
+/*
+* MD4 GG Function
+*/
+inline void GG(u32bit& A, u32bit B, u32bit C, u32bit D, u32bit M, byte S)
+ {
+ A += ((B & C) | (D & (B | C))) + M + 0x5A827999;
+ A = rotate_left(A, S);
+ }
+
+/*
+* MD4 HH Function
+*/
+inline void HH(u32bit& A, u32bit B, u32bit C, u32bit D, u32bit M, byte S)
+ {
+ A += (B ^ C ^ D) + M + 0x6ED9EBA1;
+ A = rotate_left(A, S);
+ }
+
+}
+
+/*
+* MD4 Compression Function
+*/
+void MD4::compress_n(const byte input[], size_t blocks)
+ {
+ u32bit A = digest[0], B = digest[1], C = digest[2], D = digest[3];
+
+ for(size_t i = 0; i != blocks; ++i)
+ {
+ load_le(&M[0], input, M.size());
+
+ FF(A,B,C,D,M[ 0], 3); FF(D,A,B,C,M[ 1], 7);
+ FF(C,D,A,B,M[ 2],11); FF(B,C,D,A,M[ 3],19);
+ FF(A,B,C,D,M[ 4], 3); FF(D,A,B,C,M[ 5], 7);
+ FF(C,D,A,B,M[ 6],11); FF(B,C,D,A,M[ 7],19);
+ FF(A,B,C,D,M[ 8], 3); FF(D,A,B,C,M[ 9], 7);
+ FF(C,D,A,B,M[10],11); FF(B,C,D,A,M[11],19);
+ FF(A,B,C,D,M[12], 3); FF(D,A,B,C,M[13], 7);
+ FF(C,D,A,B,M[14],11); FF(B,C,D,A,M[15],19);
+
+ GG(A,B,C,D,M[ 0], 3); GG(D,A,B,C,M[ 4], 5);
+ GG(C,D,A,B,M[ 8], 9); GG(B,C,D,A,M[12],13);
+ GG(A,B,C,D,M[ 1], 3); GG(D,A,B,C,M[ 5], 5);
+ GG(C,D,A,B,M[ 9], 9); GG(B,C,D,A,M[13],13);
+ GG(A,B,C,D,M[ 2], 3); GG(D,A,B,C,M[ 6], 5);
+ GG(C,D,A,B,M[10], 9); GG(B,C,D,A,M[14],13);
+ GG(A,B,C,D,M[ 3], 3); GG(D,A,B,C,M[ 7], 5);
+ GG(C,D,A,B,M[11], 9); GG(B,C,D,A,M[15],13);
+
+ HH(A,B,C,D,M[ 0], 3); HH(D,A,B,C,M[ 8], 9);
+ HH(C,D,A,B,M[ 4],11); HH(B,C,D,A,M[12],15);
+ HH(A,B,C,D,M[ 2], 3); HH(D,A,B,C,M[10], 9);
+ HH(C,D,A,B,M[ 6],11); HH(B,C,D,A,M[14],15);
+ HH(A,B,C,D,M[ 1], 3); HH(D,A,B,C,M[ 9], 9);
+ HH(C,D,A,B,M[ 5],11); HH(B,C,D,A,M[13],15);
+ HH(A,B,C,D,M[ 3], 3); HH(D,A,B,C,M[11], 9);
+ HH(C,D,A,B,M[ 7],11); HH(B,C,D,A,M[15],15);
+
+ A = (digest[0] += A);
+ B = (digest[1] += B);
+ C = (digest[2] += C);
+ D = (digest[3] += D);
+
+ input += hash_block_size();
+ }
+ }
+
+/*
+* Copy out the digest
+*/
+void MD4::copy_out(byte output[])
+ {
+ for(size_t i = 0; i != output_length(); i += 4)
+ store_le(digest[i/4], output + i);
+ }
+
+/*
+* Clear memory of sensitive data
+*/
+void MD4::clear()
+ {
+ MDx_HashFunction::clear();
+ zeroise(M);
+ digest[0] = 0x67452301;
+ digest[1] = 0xEFCDAB89;
+ digest[2] = 0x98BADCFE;
+ digest[3] = 0x10325476;
+ }
+
+}
diff --git a/src/lib/hash/md4/md4.h b/src/lib/hash/md4/md4.h
new file mode 100644
index 000000000..750be0fe7
--- /dev/null
+++ b/src/lib/hash/md4/md4.h
@@ -0,0 +1,46 @@
+/*
+* MD4
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_MD4_H__
+#define BOTAN_MD4_H__
+
+#include <botan/mdx_hash.h>
+
+namespace Botan {
+
+/**
+* MD4
+*/
+class BOTAN_DLL MD4 : public MDx_HashFunction
+ {
+ public:
+ std::string name() const { return "MD4"; }
+ size_t output_length() const { return 16; }
+ HashFunction* clone() const { return new MD4; }
+
+ void clear();
+
+ MD4() : MDx_HashFunction(64, false, true), M(16), digest(4)
+ { clear(); }
+ protected:
+ void compress_n(const byte input[], size_t blocks);
+ void copy_out(byte[]);
+
+ /**
+ * The message buffer, exposed for use by subclasses (x86 asm)
+ */
+ secure_vector<u32bit> M;
+
+ /**
+ * The digest value, exposed for use by subclasses (x86 asm)
+ */
+ secure_vector<u32bit> digest;
+ };
+
+}
+
+#endif
diff --git a/src/lib/hash/md4_x86_32/info.txt b/src/lib/hash/md4_x86_32/info.txt
new file mode 100644
index 000000000..fa7eef6cb
--- /dev/null
+++ b/src/lib/hash/md4_x86_32/info.txt
@@ -0,0 +1,12 @@
+define MD4_X86_32 20131128
+
+load_on asm_ok
+
+<arch>
+x86_32
+</arch>
+
+<requires>
+asm_x86_32
+md4
+</requires>
diff --git a/src/lib/hash/md4_x86_32/md4_x86_32.cpp b/src/lib/hash/md4_x86_32/md4_x86_32.cpp
new file mode 100644
index 000000000..ed3f72fc9
--- /dev/null
+++ b/src/lib/hash/md4_x86_32/md4_x86_32.cpp
@@ -0,0 +1,34 @@
+/*
+* MD4 (x86-32)
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/md4_x86_32.h>
+
+namespace Botan {
+
+/**
+* MD4 compression function in x86-32 asm
+* @param digest the current digest
+* @param input the input block
+* @param M the message buffer
+*/
+extern "C" void botan_md4_x86_32_compress(u32bit digest[4],
+ const byte input[64],
+ u32bit M[16]);
+
+/*
+* MD4 Compression Function
+*/
+void MD4_X86_32::compress_n(const byte input[], size_t blocks)
+ {
+ for(size_t i = 0; i != blocks; ++i)
+ {
+ botan_md4_x86_32_compress(&digest[0], input, &M[0]);
+ input += hash_block_size();
+ }
+ }
+
+}
diff --git a/src/lib/hash/md4_x86_32/md4_x86_32.h b/src/lib/hash/md4_x86_32/md4_x86_32.h
new file mode 100644
index 000000000..a9f23e94f
--- /dev/null
+++ b/src/lib/hash/md4_x86_32/md4_x86_32.h
@@ -0,0 +1,28 @@
+/*
+* MD4 (x86-32)
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_MD4_X86_32_H__
+#define BOTAN_MD4_X86_32_H__
+
+#include <botan/md4.h>
+
+namespace Botan {
+
+/**
+* MD4 using x86 assembly
+*/
+class BOTAN_DLL MD4_X86_32 : public MD4
+ {
+ public:
+ HashFunction* clone() const { return new MD4_X86_32; }
+ private:
+ void compress_n(const byte[], size_t blocks);
+ };
+
+}
+
+#endif
diff --git a/src/lib/hash/md4_x86_32/md4_x86_32_imp.S b/src/lib/hash/md4_x86_32/md4_x86_32_imp.S
new file mode 100644
index 000000000..192751166
--- /dev/null
+++ b/src/lib/hash/md4_x86_32/md4_x86_32_imp.S
@@ -0,0 +1,137 @@
+/*
+* MD4 in x86-32 assembler
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/internal/asm_x86_32.h>
+
+START_LISTING(md4_x86_32_imp.S)
+
+START_FUNCTION(botan_md4_x86_32_compress)
+ SPILL_REGS()
+
+#define PUSHED 4
+
+ ASSIGN(EBP, ARG(2)) /* input block */
+ ASSIGN(EDI, ARG(3)) /* expanded words */
+
+ ZEROIZE(ESI)
+
+START_LOOP(.LOAD_INPUT)
+ ADD_IMM(ESI, 4)
+
+ ASSIGN(EAX, ARRAY4(EBP, 0))
+ ASSIGN(EBX, ARRAY4(EBP, 1))
+ ASSIGN(ECX, ARRAY4(EBP, 2))
+ ASSIGN(EDX, ARRAY4(EBP, 3))
+
+ ADD_IMM(EBP, 16)
+
+ ASSIGN(ARRAY4_INDIRECT(EDI,ESI,-4), EAX)
+ ASSIGN(ARRAY4_INDIRECT(EDI,ESI,-3), EBX)
+ ASSIGN(ARRAY4_INDIRECT(EDI,ESI,-2), ECX)
+ ASSIGN(ARRAY4_INDIRECT(EDI,ESI,-1), EDX)
+LOOP_UNTIL_EQ(ESI, 16, .LOAD_INPUT)
+
+ ASSIGN(EBP, ARG(1))
+ ASSIGN(EAX, ARRAY4(EBP, 0))
+ ASSIGN(EBX, ARRAY4(EBP, 1))
+ ASSIGN(ECX, ARRAY4(EBP, 2))
+ ASSIGN(EDX, ARRAY4(EBP, 3))
+
+#define MSG EDI
+#define T1 ESI
+#define T2 EBP
+
+#define FF(A, B, C, D, N, S) \
+ ASSIGN(T1, ARRAY4(MSG, N)) ; \
+ ASSIGN(T2, C) ; \
+ XOR(T2, D) ; \
+ AND(T2, B) ; \
+ XOR(T2, D) ; \
+ ADD(A, T1) ; \
+ ADD(A, T2) ; \
+ ROTL_IMM(A, S) ;
+
+#define GG(A, B, C, D, N, S) \
+ ASSIGN(T1, ARRAY4(MSG, N)) ; \
+ ASSIGN(T2, B) ; \
+ OR(T2, C) ; \
+ AND(T2, D) ; \
+ ADD3_IMM(A, T1, 0x5A827999) ; \
+ ASSIGN(T1, B) ; \
+ AND(T1, C) ; \
+ OR(T2, T1) ; \
+ ADD(A, T2) ; \
+ ROTL_IMM(A, S) ;
+
+#define HH(A, B, C, D, N, S) \
+ ASSIGN(T1, ARRAY4(MSG, N)) ; \
+ ASSIGN(T2, B) ; \
+ XOR(T2, C) ; \
+ XOR(T2, D) ; \
+ ADD3_IMM(A, T1, 0x6ED9EBA1) ; \
+ ADD(A, T2) ; \
+ ROTL_IMM(A, S) ;
+
+ FF(EAX,EBX,ECX,EDX, 0, 3);
+ FF(EDX,EAX,EBX,ECX, 1, 7);
+ FF(ECX,EDX,EAX,EBX, 2,11);
+ FF(EBX,ECX,EDX,EAX, 3,19);
+ FF(EAX,EBX,ECX,EDX, 4, 3);
+ FF(EDX,EAX,EBX,ECX, 5, 7);
+ FF(ECX,EDX,EAX,EBX, 6,11);
+ FF(EBX,ECX,EDX,EAX, 7,19);
+ FF(EAX,EBX,ECX,EDX, 8, 3);
+ FF(EDX,EAX,EBX,ECX, 9, 7);
+ FF(ECX,EDX,EAX,EBX,10,11);
+ FF(EBX,ECX,EDX,EAX,11,19);
+ FF(EAX,EBX,ECX,EDX,12, 3);
+ FF(EDX,EAX,EBX,ECX,13, 7);
+ FF(ECX,EDX,EAX,EBX,14,11);
+ FF(EBX,ECX,EDX,EAX,15,19);
+
+ GG(EAX,EBX,ECX,EDX, 0, 3);
+ GG(EDX,EAX,EBX,ECX, 4, 5);
+ GG(ECX,EDX,EAX,EBX, 8, 9);
+ GG(EBX,ECX,EDX,EAX,12,13);
+ GG(EAX,EBX,ECX,EDX, 1, 3);
+ GG(EDX,EAX,EBX,ECX, 5, 5);
+ GG(ECX,EDX,EAX,EBX, 9, 9);
+ GG(EBX,ECX,EDX,EAX,13,13);
+ GG(EAX,EBX,ECX,EDX, 2, 3);
+ GG(EDX,EAX,EBX,ECX, 6, 5);
+ GG(ECX,EDX,EAX,EBX,10, 9);
+ GG(EBX,ECX,EDX,EAX,14,13);
+ GG(EAX,EBX,ECX,EDX, 3, 3);
+ GG(EDX,EAX,EBX,ECX, 7, 5);
+ GG(ECX,EDX,EAX,EBX,11, 9);
+ GG(EBX,ECX,EDX,EAX,15,13);
+
+ HH(EAX,EBX,ECX,EDX, 0, 3);
+ HH(EDX,EAX,EBX,ECX, 8, 9);
+ HH(ECX,EDX,EAX,EBX, 4,11);
+ HH(EBX,ECX,EDX,EAX,12,15);
+ HH(EAX,EBX,ECX,EDX, 2, 3);
+ HH(EDX,EAX,EBX,ECX,10, 9);
+ HH(ECX,EDX,EAX,EBX, 6,11);
+ HH(EBX,ECX,EDX,EAX,14,15);
+ HH(EAX,EBX,ECX,EDX, 1, 3);
+ HH(EDX,EAX,EBX,ECX, 9, 9);
+ HH(ECX,EDX,EAX,EBX, 5,11);
+ HH(EBX,ECX,EDX,EAX,13,15);
+ HH(EAX,EBX,ECX,EDX, 3, 3);
+ HH(EDX,EAX,EBX,ECX,11, 9);
+ HH(ECX,EDX,EAX,EBX, 7,11);
+ HH(EBX,ECX,EDX,EAX,15,15);
+
+ ASSIGN(EBP, ARG(1))
+ ADD(ARRAY4(EBP, 0), EAX)
+ ADD(ARRAY4(EBP, 1), EBX)
+ ADD(ARRAY4(EBP, 2), ECX)
+ ADD(ARRAY4(EBP, 3), EDX)
+
+ RESTORE_REGS()
+END_FUNCTION(botan_md4_x86_32_compress)
diff --git a/src/lib/hash/md5/info.txt b/src/lib/hash/md5/info.txt
new file mode 100644
index 000000000..8bbf1c3e7
--- /dev/null
+++ b/src/lib/hash/md5/info.txt
@@ -0,0 +1,5 @@
+define MD5 20131128
+
+<requires>
+mdx_hash
+</requires>
diff --git a/src/lib/hash/md5/md5.cpp b/src/lib/hash/md5/md5.cpp
new file mode 100644
index 000000000..948f4e73b
--- /dev/null
+++ b/src/lib/hash/md5/md5.cpp
@@ -0,0 +1,136 @@
+/*
+* MD5
+* (C) 1999-2008 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/md5.h>
+#include <botan/loadstor.h>
+#include <botan/rotate.h>
+
+namespace Botan {
+
+namespace {
+
+/*
+* MD5 FF Function
+*/
+inline void FF(u32bit& A, u32bit B, u32bit C, u32bit D, u32bit msg,
+ byte S, u32bit magic)
+ {
+ A += (D ^ (B & (C ^ D))) + msg + magic;
+ A = rotate_left(A, S) + B;
+ }
+
+/*
+* MD5 GG Function
+*/
+inline void GG(u32bit& A, u32bit B, u32bit C, u32bit D, u32bit msg,
+ byte S, u32bit magic)
+ {
+ A += (C ^ (D & (B ^ C))) + msg + magic;
+ A = rotate_left(A, S) + B;
+ }
+
+/*
+* MD5 HH Function
+*/
+inline void HH(u32bit& A, u32bit B, u32bit C, u32bit D, u32bit msg,
+ byte S, u32bit magic)
+ {
+ A += (B ^ C ^ D) + msg + magic;
+ A = rotate_left(A, S) + B;
+ }
+
+/*
+* MD5 II Function
+*/
+inline void II(u32bit& A, u32bit B, u32bit C, u32bit D, u32bit msg,
+ byte S, u32bit magic)
+ {
+ A += (C ^ (B | ~D)) + msg + magic;
+ A = rotate_left(A, S) + B;
+ }
+
+}
+
+/*
+* MD5 Compression Function
+*/
+void MD5::compress_n(const byte input[], size_t blocks)
+ {
+ u32bit A = digest[0], B = digest[1], C = digest[2], D = digest[3];
+
+ for(size_t i = 0; i != blocks; ++i)
+ {
+ load_le(&M[0], input, M.size());
+
+ FF(A,B,C,D,M[ 0], 7,0xD76AA478); FF(D,A,B,C,M[ 1],12,0xE8C7B756);
+ FF(C,D,A,B,M[ 2],17,0x242070DB); FF(B,C,D,A,M[ 3],22,0xC1BDCEEE);
+ FF(A,B,C,D,M[ 4], 7,0xF57C0FAF); FF(D,A,B,C,M[ 5],12,0x4787C62A);
+ FF(C,D,A,B,M[ 6],17,0xA8304613); FF(B,C,D,A,M[ 7],22,0xFD469501);
+ FF(A,B,C,D,M[ 8], 7,0x698098D8); FF(D,A,B,C,M[ 9],12,0x8B44F7AF);
+ FF(C,D,A,B,M[10],17,0xFFFF5BB1); FF(B,C,D,A,M[11],22,0x895CD7BE);
+ FF(A,B,C,D,M[12], 7,0x6B901122); FF(D,A,B,C,M[13],12,0xFD987193);
+ FF(C,D,A,B,M[14],17,0xA679438E); FF(B,C,D,A,M[15],22,0x49B40821);
+
+ GG(A,B,C,D,M[ 1], 5,0xF61E2562); GG(D,A,B,C,M[ 6], 9,0xC040B340);
+ GG(C,D,A,B,M[11],14,0x265E5A51); GG(B,C,D,A,M[ 0],20,0xE9B6C7AA);
+ GG(A,B,C,D,M[ 5], 5,0xD62F105D); GG(D,A,B,C,M[10], 9,0x02441453);
+ GG(C,D,A,B,M[15],14,0xD8A1E681); GG(B,C,D,A,M[ 4],20,0xE7D3FBC8);
+ GG(A,B,C,D,M[ 9], 5,0x21E1CDE6); GG(D,A,B,C,M[14], 9,0xC33707D6);
+ GG(C,D,A,B,M[ 3],14,0xF4D50D87); GG(B,C,D,A,M[ 8],20,0x455A14ED);
+ GG(A,B,C,D,M[13], 5,0xA9E3E905); GG(D,A,B,C,M[ 2], 9,0xFCEFA3F8);
+ GG(C,D,A,B,M[ 7],14,0x676F02D9); GG(B,C,D,A,M[12],20,0x8D2A4C8A);
+
+ HH(A,B,C,D,M[ 5], 4,0xFFFA3942); HH(D,A,B,C,M[ 8],11,0x8771F681);
+ HH(C,D,A,B,M[11],16,0x6D9D6122); HH(B,C,D,A,M[14],23,0xFDE5380C);
+ HH(A,B,C,D,M[ 1], 4,0xA4BEEA44); HH(D,A,B,C,M[ 4],11,0x4BDECFA9);
+ HH(C,D,A,B,M[ 7],16,0xF6BB4B60); HH(B,C,D,A,M[10],23,0xBEBFBC70);
+ HH(A,B,C,D,M[13], 4,0x289B7EC6); HH(D,A,B,C,M[ 0],11,0xEAA127FA);
+ HH(C,D,A,B,M[ 3],16,0xD4EF3085); HH(B,C,D,A,M[ 6],23,0x04881D05);
+ HH(A,B,C,D,M[ 9], 4,0xD9D4D039); HH(D,A,B,C,M[12],11,0xE6DB99E5);
+ HH(C,D,A,B,M[15],16,0x1FA27CF8); HH(B,C,D,A,M[ 2],23,0xC4AC5665);
+
+ II(A,B,C,D,M[ 0], 6,0xF4292244); II(D,A,B,C,M[ 7],10,0x432AFF97);
+ II(C,D,A,B,M[14],15,0xAB9423A7); II(B,C,D,A,M[ 5],21,0xFC93A039);
+ II(A,B,C,D,M[12], 6,0x655B59C3); II(D,A,B,C,M[ 3],10,0x8F0CCC92);
+ II(C,D,A,B,M[10],15,0xFFEFF47D); II(B,C,D,A,M[ 1],21,0x85845DD1);
+ II(A,B,C,D,M[ 8], 6,0x6FA87E4F); II(D,A,B,C,M[15],10,0xFE2CE6E0);
+ II(C,D,A,B,M[ 6],15,0xA3014314); II(B,C,D,A,M[13],21,0x4E0811A1);
+ II(A,B,C,D,M[ 4], 6,0xF7537E82); II(D,A,B,C,M[11],10,0xBD3AF235);
+ II(C,D,A,B,M[ 2],15,0x2AD7D2BB); II(B,C,D,A,M[ 9],21,0xEB86D391);
+
+ A = (digest[0] += A);
+ B = (digest[1] += B);
+ C = (digest[2] += C);
+ D = (digest[3] += D);
+
+ input += hash_block_size();
+ }
+ }
+
+/*
+* Copy out the digest
+*/
+void MD5::copy_out(byte output[])
+ {
+ for(size_t i = 0; i != output_length(); i += 4)
+ store_le(digest[i/4], output + i);
+ }
+
+/*
+* Clear memory of sensitive data
+*/
+void MD5::clear()
+ {
+ MDx_HashFunction::clear();
+ zeroise(M);
+ digest[0] = 0x67452301;
+ digest[1] = 0xEFCDAB89;
+ digest[2] = 0x98BADCFE;
+ digest[3] = 0x10325476;
+ }
+
+}
diff --git a/src/lib/hash/md5/md5.h b/src/lib/hash/md5/md5.h
new file mode 100644
index 000000000..bc90df0af
--- /dev/null
+++ b/src/lib/hash/md5/md5.h
@@ -0,0 +1,46 @@
+/*
+* MD5
+* (C) 1999-2008 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_MD5_H__
+#define BOTAN_MD5_H__
+
+#include <botan/mdx_hash.h>
+
+namespace Botan {
+
+/**
+* MD5
+*/
+class BOTAN_DLL MD5 : public MDx_HashFunction
+ {
+ public:
+ std::string name() const { return "MD5"; }
+ size_t output_length() const { return 16; }
+ HashFunction* clone() const { return new MD5; }
+
+ void clear();
+
+ MD5() : MDx_HashFunction(64, false, true), M(16), digest(4)
+ { clear(); }
+ protected:
+ void compress_n(const byte[], size_t blocks);
+ void copy_out(byte[]);
+
+ /**
+ * The message buffer, exposed for use by subclasses (x86 asm)
+ */
+ secure_vector<u32bit> M;
+
+ /**
+ * The digest value, exposed for use by subclasses (x86 asm)
+ */
+ secure_vector<u32bit> digest;
+ };
+
+}
+
+#endif
diff --git a/src/lib/hash/md5_x86_32/info.txt b/src/lib/hash/md5_x86_32/info.txt
new file mode 100644
index 000000000..769ee8389
--- /dev/null
+++ b/src/lib/hash/md5_x86_32/info.txt
@@ -0,0 +1,12 @@
+define MD5_X86_32 20131128
+
+load_on asm_ok
+
+<arch>
+x86_32
+</arch>
+
+<requires>
+asm_x86_32
+md5
+</requires>
diff --git a/src/lib/hash/md5_x86_32/md5_x86_32.cpp b/src/lib/hash/md5_x86_32/md5_x86_32.cpp
new file mode 100644
index 000000000..73071ac18
--- /dev/null
+++ b/src/lib/hash/md5_x86_32/md5_x86_32.cpp
@@ -0,0 +1,31 @@
+/*
+* MD5 (x86-32)
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/md5_x86_32.h>
+
+namespace Botan {
+
+namespace {
+
+extern "C"
+void botan_md5_x86_32_compress(u32bit[4], const byte[64], u32bit[16]);
+
+}
+
+/*
+* MD5 Compression Function
+*/
+void MD5_X86_32::compress_n(const byte input[], size_t blocks)
+ {
+ for(size_t i = 0; i != blocks; ++i)
+ {
+ botan_md5_x86_32_compress(&digest[0], input, &M[0]);
+ input += hash_block_size();
+ }
+ }
+
+}
diff --git a/src/lib/hash/md5_x86_32/md5_x86_32.h b/src/lib/hash/md5_x86_32/md5_x86_32.h
new file mode 100644
index 000000000..0150249ae
--- /dev/null
+++ b/src/lib/hash/md5_x86_32/md5_x86_32.h
@@ -0,0 +1,28 @@
+/*
+* MD5 (x86-32)
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_MD5_X86_32_H__
+#define BOTAN_MD5_X86_32_H__
+
+#include <botan/md5.h>
+
+namespace Botan {
+
+/**
+* MD5 in x86 assembly
+*/
+class BOTAN_DLL MD5_X86_32 : public MD5
+ {
+ public:
+ HashFunction* clone() const { return new MD5_X86_32; }
+ private:
+ void compress_n(const byte[], size_t blocks);
+ };
+
+}
+
+#endif
diff --git a/src/lib/hash/md5_x86_32/md5_x86_32_imp.S b/src/lib/hash/md5_x86_32/md5_x86_32_imp.S
new file mode 100644
index 000000000..f41aaccbf
--- /dev/null
+++ b/src/lib/hash/md5_x86_32/md5_x86_32_imp.S
@@ -0,0 +1,166 @@
+/*
+* MD5 in x86-32 assembler
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/internal/asm_x86_32.h>
+
+START_LISTING(md5_x86_32.S)
+
+START_FUNCTION(botan_md5_x86_32_compress)
+ SPILL_REGS()
+
+#define PUSHED 4
+
+ ASSIGN(EBP, ARG(2)) /* input block */
+ ASSIGN(EDI, ARG(3)) /* expanded words */
+
+ ZEROIZE(ESI)
+
+START_LOOP(.LOAD_INPUT)
+ ADD_IMM(ESI, 4)
+
+ ASSIGN(EAX, ARRAY4(EBP, 0))
+ ASSIGN(EBX, ARRAY4(EBP, 1))
+ ASSIGN(ECX, ARRAY4(EBP, 2))
+ ASSIGN(EDX, ARRAY4(EBP, 3))
+
+ ADD_IMM(EBP, 16)
+
+ ASSIGN(ARRAY4_INDIRECT(EDI,ESI,-4), EAX)
+ ASSIGN(ARRAY4_INDIRECT(EDI,ESI,-3), EBX)
+ ASSIGN(ARRAY4_INDIRECT(EDI,ESI,-2), ECX)
+ ASSIGN(ARRAY4_INDIRECT(EDI,ESI,-1), EDX)
+LOOP_UNTIL_EQ(ESI, 16, .LOAD_INPUT)
+
+ ASSIGN(EBP, ARG(1))
+ ASSIGN(EAX, ARRAY4(EBP, 0))
+ ASSIGN(EBX, ARRAY4(EBP, 1))
+ ASSIGN(ECX, ARRAY4(EBP, 2))
+ ASSIGN(EDX, ARRAY4(EBP, 3))
+
+#define MSG EDI
+#define T1 ESI
+#define T2 EBP
+
+#define FF(A, B, C, D, N, S, MAGIC) \
+ ASSIGN(T1, ARRAY4(MSG, N)) ; \
+ ASSIGN(T2, C) ; \
+ XOR(T2, D) ; \
+ AND(T2, B) ; \
+ XOR(T2, D) ; \
+ ADD3_IMM(A, T1, MAGIC) ; \
+ ADD(A, T2) ; \
+ ROTL_IMM(A, S) ; \
+ ADD(A, B) ;
+
+#define GG(A, B, C, D, N, S, MAGIC) \
+ ASSIGN(T1, ARRAY4(MSG, N)) ; \
+ ASSIGN(T2, B) ; \
+ XOR(T2, C) ; \
+ AND(T2, D) ; \
+ XOR(T2, C) ; \
+ ADD3_IMM(A, T1, MAGIC) ; \
+ ADD(A, T2) ; \
+ ROTL_IMM(A, S) ; \
+ ADD(A, B) ;
+
+#define HH(A, B, C, D, N, S, MAGIC) \
+ ASSIGN(T1, ARRAY4(MSG, N)) ; \
+ ASSIGN(T2, B) ; \
+ XOR(T2, C) ; \
+ XOR(T2, D) ; \
+ ADD3_IMM(A, T1, MAGIC) ; \
+ ADD(A, T2) ; \
+ ROTL_IMM(A, S) ; \
+ ADD(A, B) ;
+
+#define II(A, B, C, D, N, S, MAGIC) \
+ ASSIGN(T1, ARRAY4(MSG, N)) ; \
+ ASSIGN(T2, D) ; \
+ NOT(T2) ; \
+ OR(T2, B) ; \
+ XOR(T2, C) ; \
+ ADD3_IMM(A, T1, MAGIC) ; \
+ ADD(A, T2) ; \
+ ROTL_IMM(A, S) ; \
+ ADD(A, B) ;
+
+ FF(EAX,EBX,ECX,EDX, 0, 7,0xD76AA478);
+ FF(EDX,EAX,EBX,ECX, 1,12,0xE8C7B756);
+ FF(ECX,EDX,EAX,EBX, 2,17,0x242070DB);
+ FF(EBX,ECX,EDX,EAX, 3,22,0xC1BDCEEE);
+ FF(EAX,EBX,ECX,EDX, 4, 7,0xF57C0FAF);
+ FF(EDX,EAX,EBX,ECX, 5,12,0x4787C62A);
+ FF(ECX,EDX,EAX,EBX, 6,17,0xA8304613);
+ FF(EBX,ECX,EDX,EAX, 7,22,0xFD469501);
+ FF(EAX,EBX,ECX,EDX, 8, 7,0x698098D8);
+ FF(EDX,EAX,EBX,ECX, 9,12,0x8B44F7AF);
+ FF(ECX,EDX,EAX,EBX,10,17,0xFFFF5BB1);
+ FF(EBX,ECX,EDX,EAX,11,22,0x895CD7BE);
+ FF(EAX,EBX,ECX,EDX,12, 7,0x6B901122);
+ FF(EDX,EAX,EBX,ECX,13,12,0xFD987193);
+ FF(ECX,EDX,EAX,EBX,14,17,0xA679438E);
+ FF(EBX,ECX,EDX,EAX,15,22,0x49B40821);
+
+ GG(EAX,EBX,ECX,EDX, 1, 5,0xF61E2562);
+ GG(EDX,EAX,EBX,ECX, 6, 9,0xC040B340);
+ GG(ECX,EDX,EAX,EBX,11,14,0x265E5A51);
+ GG(EBX,ECX,EDX,EAX, 0,20,0xE9B6C7AA);
+ GG(EAX,EBX,ECX,EDX, 5, 5,0xD62F105D);
+ GG(EDX,EAX,EBX,ECX,10, 9,0x02441453);
+ GG(ECX,EDX,EAX,EBX,15,14,0xD8A1E681);
+ GG(EBX,ECX,EDX,EAX, 4,20,0xE7D3FBC8);
+ GG(EAX,EBX,ECX,EDX, 9, 5,0x21E1CDE6);
+ GG(EDX,EAX,EBX,ECX,14, 9,0xC33707D6);
+ GG(ECX,EDX,EAX,EBX, 3,14,0xF4D50D87);
+ GG(EBX,ECX,EDX,EAX, 8,20,0x455A14ED);
+ GG(EAX,EBX,ECX,EDX,13, 5,0xA9E3E905);
+ GG(EDX,EAX,EBX,ECX, 2, 9,0xFCEFA3F8);
+ GG(ECX,EDX,EAX,EBX, 7,14,0x676F02D9);
+ GG(EBX,ECX,EDX,EAX,12,20,0x8D2A4C8A);
+
+ HH(EAX,EBX,ECX,EDX, 5, 4,0xFFFA3942);
+ HH(EDX,EAX,EBX,ECX, 8,11,0x8771F681);
+ HH(ECX,EDX,EAX,EBX,11,16,0x6D9D6122);
+ HH(EBX,ECX,EDX,EAX,14,23,0xFDE5380C);
+ HH(EAX,EBX,ECX,EDX, 1, 4,0xA4BEEA44);
+ HH(EDX,EAX,EBX,ECX, 4,11,0x4BDECFA9);
+ HH(ECX,EDX,EAX,EBX, 7,16,0xF6BB4B60);
+ HH(EBX,ECX,EDX,EAX,10,23,0xBEBFBC70);
+ HH(EAX,EBX,ECX,EDX,13, 4,0x289B7EC6);
+ HH(EDX,EAX,EBX,ECX, 0,11,0xEAA127FA);
+ HH(ECX,EDX,EAX,EBX, 3,16,0xD4EF3085);
+ HH(EBX,ECX,EDX,EAX, 6,23,0x04881D05);
+ HH(EAX,EBX,ECX,EDX, 9, 4,0xD9D4D039);
+ HH(EDX,EAX,EBX,ECX,12,11,0xE6DB99E5);
+ HH(ECX,EDX,EAX,EBX,15,16,0x1FA27CF8);
+ HH(EBX,ECX,EDX,EAX, 2,23,0xC4AC5665);
+
+ II(EAX,EBX,ECX,EDX, 0, 6,0xF4292244);
+ II(EDX,EAX,EBX,ECX, 7,10,0x432AFF97);
+ II(ECX,EDX,EAX,EBX,14,15,0xAB9423A7);
+ II(EBX,ECX,EDX,EAX, 5,21,0xFC93A039);
+ II(EAX,EBX,ECX,EDX,12, 6,0x655B59C3);
+ II(EDX,EAX,EBX,ECX, 3,10,0x8F0CCC92);
+ II(ECX,EDX,EAX,EBX,10,15,0xFFEFF47D);
+ II(EBX,ECX,EDX,EAX, 1,21,0x85845DD1);
+ II(EAX,EBX,ECX,EDX, 8, 6,0x6FA87E4F);
+ II(EDX,EAX,EBX,ECX,15,10,0xFE2CE6E0);
+ II(ECX,EDX,EAX,EBX, 6,15,0xA3014314);
+ II(EBX,ECX,EDX,EAX,13,21,0x4E0811A1);
+ II(EAX,EBX,ECX,EDX, 4, 6,0xF7537E82);
+ II(EDX,EAX,EBX,ECX,11,10,0xBD3AF235);
+ II(ECX,EDX,EAX,EBX, 2,15,0x2AD7D2BB);
+ II(EBX,ECX,EDX,EAX, 9,21,0xEB86D391);
+
+ ASSIGN(EBP, ARG(1))
+ ADD(ARRAY4(EBP, 0), EAX)
+ ADD(ARRAY4(EBP, 1), EBX)
+ ADD(ARRAY4(EBP, 2), ECX)
+ ADD(ARRAY4(EBP, 3), EDX)
+
+ RESTORE_REGS()
+END_FUNCTION(botan_md5_x86_32_compress)
diff --git a/src/lib/hash/mdx_hash/info.txt b/src/lib/hash/mdx_hash/info.txt
new file mode 100644
index 000000000..d9a24c621
--- /dev/null
+++ b/src/lib/hash/mdx_hash/info.txt
@@ -0,0 +1,3 @@
+define MDX_HASH_FUNCTION 20131128
+
+load_on dep
diff --git a/src/lib/hash/mdx_hash/mdx_hash.cpp b/src/lib/hash/mdx_hash/mdx_hash.cpp
new file mode 100644
index 000000000..81042c1fa
--- /dev/null
+++ b/src/lib/hash/mdx_hash/mdx_hash.cpp
@@ -0,0 +1,108 @@
+/*
+* Merkle-Damgard Hash Function
+* (C) 1999-2008 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/mdx_hash.h>
+#include <botan/exceptn.h>
+#include <botan/loadstor.h>
+
+namespace Botan {
+
+/*
+* MDx_HashFunction Constructor
+*/
+MDx_HashFunction::MDx_HashFunction(size_t block_len,
+ bool byte_end,
+ bool bit_end,
+ size_t cnt_size) :
+ buffer(block_len),
+ BIG_BYTE_ENDIAN(byte_end),
+ BIG_BIT_ENDIAN(bit_end),
+ COUNT_SIZE(cnt_size)
+ {
+ count = position = 0;
+ }
+
+/*
+* Clear memory of sensitive data
+*/
+void MDx_HashFunction::clear()
+ {
+ zeroise(buffer);
+ count = position = 0;
+ }
+
+/*
+* Update the hash
+*/
+void MDx_HashFunction::add_data(const byte input[], size_t length)
+ {
+ count += length;
+
+ if(position)
+ {
+ buffer_insert(buffer, position, input, length);
+
+ if(position + length >= buffer.size())
+ {
+ compress_n(&buffer[0], 1);
+ input += (buffer.size() - position);
+ length -= (buffer.size() - position);
+ position = 0;
+ }
+ }
+
+ const size_t full_blocks = length / buffer.size();
+ const size_t remaining = length % buffer.size();
+
+ if(full_blocks)
+ compress_n(input, full_blocks);
+
+ buffer_insert(buffer, position, input + full_blocks * buffer.size(), remaining);
+ position += remaining;
+ }
+
+/*
+* Finalize a hash
+*/
+void MDx_HashFunction::final_result(byte output[])
+ {
+ buffer[position] = (BIG_BIT_ENDIAN ? 0x80 : 0x01);
+ for(size_t i = position+1; i != buffer.size(); ++i)
+ buffer[i] = 0;
+
+ if(position >= buffer.size() - COUNT_SIZE)
+ {
+ compress_n(&buffer[0], 1);
+ zeroise(buffer);
+ }
+
+ write_count(&buffer[buffer.size() - COUNT_SIZE]);
+
+ compress_n(&buffer[0], 1);
+ copy_out(output);
+ clear();
+ }
+
+/*
+* Write the count bits to the buffer
+*/
+void MDx_HashFunction::write_count(byte out[])
+ {
+ if(COUNT_SIZE < 8)
+ throw Invalid_State("MDx_HashFunction::write_count: COUNT_SIZE < 8");
+ if(COUNT_SIZE >= output_length() || COUNT_SIZE >= hash_block_size())
+ throw Invalid_Argument("MDx_HashFunction: COUNT_SIZE is too big");
+
+ const u64bit bit_count = count * 8;
+
+ if(BIG_BYTE_ENDIAN)
+ store_be(bit_count, out + COUNT_SIZE - 8);
+ else
+ store_le(bit_count, out + COUNT_SIZE - 8);
+ }
+
+}
diff --git a/src/lib/hash/mdx_hash/mdx_hash.h b/src/lib/hash/mdx_hash/mdx_hash.h
new file mode 100644
index 000000000..14d3c27a0
--- /dev/null
+++ b/src/lib/hash/mdx_hash/mdx_hash.h
@@ -0,0 +1,68 @@
+/*
+* MDx Hash Function
+* (C) 1999-2008 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_MDX_BASE_H__
+#define BOTAN_MDX_BASE_H__
+
+#include <botan/hash.h>
+
+namespace Botan {
+
+/**
+* MDx Hash Function Base Class
+*/
+class BOTAN_DLL MDx_HashFunction : public HashFunction
+ {
+ public:
+ /**
+ * @param block_length is the number of bytes per block
+ * @param big_byte_endian specifies if the hash uses big-endian bytes
+ * @param big_bit_endian specifies if the hash uses big-endian bits
+ * @param counter_size specifies the size of the counter var in bytes
+ */
+ MDx_HashFunction(size_t block_length,
+ bool big_byte_endian,
+ bool big_bit_endian,
+ size_t counter_size = 8);
+
+ size_t hash_block_size() const { return buffer.size(); }
+ protected:
+ void add_data(const byte input[], size_t length);
+ void final_result(byte output[]);
+
+ /**
+ * Run the hash's compression function over a set of blocks
+ * @param blocks the input
+ * @param block_n the number of blocks
+ */
+ virtual void compress_n(const byte blocks[], size_t block_n) = 0;
+
+ void clear();
+
+ /**
+ * Copy the output to the buffer
+ * @param buffer to put the output into
+ */
+ virtual void copy_out(byte buffer[]) = 0;
+
+ /**
+ * Write the count, if used, to this spot
+ * @param out where to write the counter to
+ */
+ virtual void write_count(byte out[]);
+ private:
+ secure_vector<byte> buffer;
+ u64bit count;
+ size_t position;
+
+ const bool BIG_BYTE_ENDIAN, BIG_BIT_ENDIAN;
+ const size_t COUNT_SIZE;
+ };
+
+}
+
+#endif
diff --git a/src/lib/hash/par_hash/info.txt b/src/lib/hash/par_hash/info.txt
new file mode 100644
index 000000000..4f559b545
--- /dev/null
+++ b/src/lib/hash/par_hash/info.txt
@@ -0,0 +1 @@
+define PARALLEL_HASH 20131128
diff --git a/src/lib/hash/par_hash/par_hash.cpp b/src/lib/hash/par_hash/par_hash.cpp
new file mode 100644
index 000000000..df47780ef
--- /dev/null
+++ b/src/lib/hash/par_hash/par_hash.cpp
@@ -0,0 +1,100 @@
+/*
+* Parallel
+* (C) 1999-2009 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/par_hash.h>
+#include <botan/parsing.h>
+
+namespace Botan {
+
+/*
+* Update the hash
+*/
+void Parallel::add_data(const byte input[], size_t length)
+ {
+ for(auto hash : hashes)
+ hash->update(input, length);
+ }
+
+/*
+* Finalize the hash
+*/
+void Parallel::final_result(byte out[])
+ {
+ u32bit offset = 0;
+
+ for(auto hash : hashes)
+ {
+ hash->final(out + offset);
+ offset += hash->output_length();
+ }
+ }
+
+/*
+* Return output size
+*/
+size_t Parallel::output_length() const
+ {
+ size_t sum = 0;
+
+ for(auto hash : hashes)
+ sum += hash->output_length();
+ return sum;
+ }
+
+/*
+* Return the name of this type
+*/
+std::string Parallel::name() const
+ {
+ std::vector<std::string> names;
+
+ for(auto hash : hashes)
+ names.push_back(hash->name());
+
+ return "Parallel(" + string_join(names, ',') + ")";
+ }
+
+/*
+* Return a clone of this object
+*/
+HashFunction* Parallel::clone() const
+ {
+ std::vector<HashFunction*> hash_copies;
+
+ for(auto hash : hashes)
+ hash_copies.push_back(hash->clone());
+
+ return new Parallel(hash_copies);
+ }
+
+/*
+* Clear memory of sensitive data
+*/
+void Parallel::clear()
+ {
+ for(auto hash : hashes)
+ hash->clear();
+ }
+
+/*
+* Parallel Constructor
+*/
+Parallel::Parallel(const std::vector<HashFunction*>& hash_in) :
+ hashes(hash_in)
+ {
+ }
+
+/*
+* Parallel Destructor
+*/
+Parallel::~Parallel()
+ {
+ for(auto hash : hashes)
+ delete hash;
+ }
+
+}
diff --git a/src/lib/hash/par_hash/par_hash.h b/src/lib/hash/par_hash/par_hash.h
new file mode 100644
index 000000000..4f5395c23
--- /dev/null
+++ b/src/lib/hash/par_hash/par_hash.h
@@ -0,0 +1,41 @@
+/*
+* Parallel Hash
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_PARALLEL_HASH_H__
+#define BOTAN_PARALLEL_HASH_H__
+
+#include <botan/hash.h>
+#include <vector>
+
+namespace Botan {
+
+/**
+* Parallel Hashes
+*/
+class BOTAN_DLL Parallel : public HashFunction
+ {
+ public:
+ void clear();
+ std::string name() const;
+ HashFunction* clone() const;
+
+ size_t output_length() const;
+
+ /**
+ * @param hashes a set of hashes to compute in parallel
+ */
+ Parallel(const std::vector<HashFunction*>& hashes);
+ ~Parallel();
+ private:
+ void add_data(const byte[], size_t);
+ void final_result(byte[]);
+ std::vector<HashFunction*> hashes;
+ };
+
+}
+
+#endif
diff --git a/src/lib/hash/rmd128/info.txt b/src/lib/hash/rmd128/info.txt
new file mode 100644
index 000000000..7d2a4eacd
--- /dev/null
+++ b/src/lib/hash/rmd128/info.txt
@@ -0,0 +1,5 @@
+define RIPEMD_128 20131128
+
+<requires>
+mdx_hash
+</requires>
diff --git a/src/lib/hash/rmd128/rmd128.cpp b/src/lib/hash/rmd128/rmd128.cpp
new file mode 100644
index 000000000..cab4adf8b
--- /dev/null
+++ b/src/lib/hash/rmd128/rmd128.cpp
@@ -0,0 +1,176 @@
+/*
+* RIPEMD-128
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/rmd128.h>
+#include <botan/loadstor.h>
+#include <botan/rotate.h>
+
+namespace Botan {
+
+namespace RIPEMD_128_F {
+
+/*
+* RIPEMD-128 F1 Function
+*/
+inline void F1(u32bit& A, u32bit B, u32bit C, u32bit D,
+ u32bit msg, u32bit shift)
+ {
+ A += (B ^ C ^ D) + msg;
+ A = rotate_left(A, shift);
+ }
+
+/*
+* RIPEMD-128 F2 Function
+*/
+inline void F2(u32bit& A, u32bit B, u32bit C, u32bit D,
+ u32bit msg, u32bit shift, u32bit magic)
+ {
+ A += (D ^ (B & (C ^ D))) + msg + magic;
+ A = rotate_left(A, shift);
+ }
+
+/*
+* RIPEMD-128 F3 Function
+*/
+inline void F3(u32bit& A, u32bit B, u32bit C, u32bit D,
+ u32bit msg, u32bit shift, u32bit magic)
+ {
+ A += (D ^ (B | ~C)) + msg + magic;
+ A = rotate_left(A, shift);
+ }
+
+/*
+* RIPEMD-128 F4 Function
+*/
+inline void F4(u32bit& A, u32bit B, u32bit C, u32bit D,
+ u32bit msg, u32bit shift, u32bit magic)
+ {
+ A += (C ^ (D & (B ^ C))) + msg + magic;
+ A = rotate_left(A, shift);
+ }
+
+}
+
+/*
+* RIPEMD-128 Compression Function
+*/
+void RIPEMD_128::compress_n(const byte input[], size_t blocks)
+ {
+ using namespace RIPEMD_128_F;
+
+ const u32bit MAGIC2 = 0x5A827999, MAGIC3 = 0x6ED9EBA1,
+ MAGIC4 = 0x8F1BBCDC, MAGIC5 = 0x50A28BE6,
+ MAGIC6 = 0x5C4DD124, MAGIC7 = 0x6D703EF3;
+
+ for(size_t i = 0; i != blocks; ++i)
+ {
+ load_le(&M[0], input, M.size());
+
+ u32bit A1 = digest[0], A2 = A1, B1 = digest[1], B2 = B1,
+ C1 = digest[2], C2 = C1, D1 = digest[3], D2 = D1;
+
+ F1(A1,B1,C1,D1,M[ 0],11 ); F4(A2,B2,C2,D2,M[ 5], 8,MAGIC5);
+ F1(D1,A1,B1,C1,M[ 1],14 ); F4(D2,A2,B2,C2,M[14], 9,MAGIC5);
+ F1(C1,D1,A1,B1,M[ 2],15 ); F4(C2,D2,A2,B2,M[ 7], 9,MAGIC5);
+ F1(B1,C1,D1,A1,M[ 3],12 ); F4(B2,C2,D2,A2,M[ 0],11,MAGIC5);
+ F1(A1,B1,C1,D1,M[ 4], 5 ); F4(A2,B2,C2,D2,M[ 9],13,MAGIC5);
+ F1(D1,A1,B1,C1,M[ 5], 8 ); F4(D2,A2,B2,C2,M[ 2],15,MAGIC5);
+ F1(C1,D1,A1,B1,M[ 6], 7 ); F4(C2,D2,A2,B2,M[11],15,MAGIC5);
+ F1(B1,C1,D1,A1,M[ 7], 9 ); F4(B2,C2,D2,A2,M[ 4], 5,MAGIC5);
+ F1(A1,B1,C1,D1,M[ 8],11 ); F4(A2,B2,C2,D2,M[13], 7,MAGIC5);
+ F1(D1,A1,B1,C1,M[ 9],13 ); F4(D2,A2,B2,C2,M[ 6], 7,MAGIC5);
+ F1(C1,D1,A1,B1,M[10],14 ); F4(C2,D2,A2,B2,M[15], 8,MAGIC5);
+ F1(B1,C1,D1,A1,M[11],15 ); F4(B2,C2,D2,A2,M[ 8],11,MAGIC5);
+ F1(A1,B1,C1,D1,M[12], 6 ); F4(A2,B2,C2,D2,M[ 1],14,MAGIC5);
+ F1(D1,A1,B1,C1,M[13], 7 ); F4(D2,A2,B2,C2,M[10],14,MAGIC5);
+ F1(C1,D1,A1,B1,M[14], 9 ); F4(C2,D2,A2,B2,M[ 3],12,MAGIC5);
+ F1(B1,C1,D1,A1,M[15], 8 ); F4(B2,C2,D2,A2,M[12], 6,MAGIC5);
+
+ F2(A1,B1,C1,D1,M[ 7], 7,MAGIC2); F3(A2,B2,C2,D2,M[ 6], 9,MAGIC6);
+ F2(D1,A1,B1,C1,M[ 4], 6,MAGIC2); F3(D2,A2,B2,C2,M[11],13,MAGIC6);
+ F2(C1,D1,A1,B1,M[13], 8,MAGIC2); F3(C2,D2,A2,B2,M[ 3],15,MAGIC6);
+ F2(B1,C1,D1,A1,M[ 1],13,MAGIC2); F3(B2,C2,D2,A2,M[ 7], 7,MAGIC6);
+ F2(A1,B1,C1,D1,M[10],11,MAGIC2); F3(A2,B2,C2,D2,M[ 0],12,MAGIC6);
+ F2(D1,A1,B1,C1,M[ 6], 9,MAGIC2); F3(D2,A2,B2,C2,M[13], 8,MAGIC6);
+ F2(C1,D1,A1,B1,M[15], 7,MAGIC2); F3(C2,D2,A2,B2,M[ 5], 9,MAGIC6);
+ F2(B1,C1,D1,A1,M[ 3],15,MAGIC2); F3(B2,C2,D2,A2,M[10],11,MAGIC6);
+ F2(A1,B1,C1,D1,M[12], 7,MAGIC2); F3(A2,B2,C2,D2,M[14], 7,MAGIC6);
+ F2(D1,A1,B1,C1,M[ 0],12,MAGIC2); F3(D2,A2,B2,C2,M[15], 7,MAGIC6);
+ F2(C1,D1,A1,B1,M[ 9],15,MAGIC2); F3(C2,D2,A2,B2,M[ 8],12,MAGIC6);
+ F2(B1,C1,D1,A1,M[ 5], 9,MAGIC2); F3(B2,C2,D2,A2,M[12], 7,MAGIC6);
+ F2(A1,B1,C1,D1,M[ 2],11,MAGIC2); F3(A2,B2,C2,D2,M[ 4], 6,MAGIC6);
+ F2(D1,A1,B1,C1,M[14], 7,MAGIC2); F3(D2,A2,B2,C2,M[ 9],15,MAGIC6);
+ F2(C1,D1,A1,B1,M[11],13,MAGIC2); F3(C2,D2,A2,B2,M[ 1],13,MAGIC6);
+ F2(B1,C1,D1,A1,M[ 8],12,MAGIC2); F3(B2,C2,D2,A2,M[ 2],11,MAGIC6);
+
+ F3(A1,B1,C1,D1,M[ 3],11,MAGIC3); F2(A2,B2,C2,D2,M[15], 9,MAGIC7);
+ F3(D1,A1,B1,C1,M[10],13,MAGIC3); F2(D2,A2,B2,C2,M[ 5], 7,MAGIC7);
+ F3(C1,D1,A1,B1,M[14], 6,MAGIC3); F2(C2,D2,A2,B2,M[ 1],15,MAGIC7);
+ F3(B1,C1,D1,A1,M[ 4], 7,MAGIC3); F2(B2,C2,D2,A2,M[ 3],11,MAGIC7);
+ F3(A1,B1,C1,D1,M[ 9],14,MAGIC3); F2(A2,B2,C2,D2,M[ 7], 8,MAGIC7);
+ F3(D1,A1,B1,C1,M[15], 9,MAGIC3); F2(D2,A2,B2,C2,M[14], 6,MAGIC7);
+ F3(C1,D1,A1,B1,M[ 8],13,MAGIC3); F2(C2,D2,A2,B2,M[ 6], 6,MAGIC7);
+ F3(B1,C1,D1,A1,M[ 1],15,MAGIC3); F2(B2,C2,D2,A2,M[ 9],14,MAGIC7);
+ F3(A1,B1,C1,D1,M[ 2],14,MAGIC3); F2(A2,B2,C2,D2,M[11],12,MAGIC7);
+ F3(D1,A1,B1,C1,M[ 7], 8,MAGIC3); F2(D2,A2,B2,C2,M[ 8],13,MAGIC7);
+ F3(C1,D1,A1,B1,M[ 0],13,MAGIC3); F2(C2,D2,A2,B2,M[12], 5,MAGIC7);
+ F3(B1,C1,D1,A1,M[ 6], 6,MAGIC3); F2(B2,C2,D2,A2,M[ 2],14,MAGIC7);
+ F3(A1,B1,C1,D1,M[13], 5,MAGIC3); F2(A2,B2,C2,D2,M[10],13,MAGIC7);
+ F3(D1,A1,B1,C1,M[11],12,MAGIC3); F2(D2,A2,B2,C2,M[ 0],13,MAGIC7);
+ F3(C1,D1,A1,B1,M[ 5], 7,MAGIC3); F2(C2,D2,A2,B2,M[ 4], 7,MAGIC7);
+ F3(B1,C1,D1,A1,M[12], 5,MAGIC3); F2(B2,C2,D2,A2,M[13], 5,MAGIC7);
+
+ F4(A1,B1,C1,D1,M[ 1],11,MAGIC4); F1(A2,B2,C2,D2,M[ 8],15 );
+ F4(D1,A1,B1,C1,M[ 9],12,MAGIC4); F1(D2,A2,B2,C2,M[ 6], 5 );
+ F4(C1,D1,A1,B1,M[11],14,MAGIC4); F1(C2,D2,A2,B2,M[ 4], 8 );
+ F4(B1,C1,D1,A1,M[10],15,MAGIC4); F1(B2,C2,D2,A2,M[ 1],11 );
+ F4(A1,B1,C1,D1,M[ 0],14,MAGIC4); F1(A2,B2,C2,D2,M[ 3],14 );
+ F4(D1,A1,B1,C1,M[ 8],15,MAGIC4); F1(D2,A2,B2,C2,M[11],14 );
+ F4(C1,D1,A1,B1,M[12], 9,MAGIC4); F1(C2,D2,A2,B2,M[15], 6 );
+ F4(B1,C1,D1,A1,M[ 4], 8,MAGIC4); F1(B2,C2,D2,A2,M[ 0],14 );
+ F4(A1,B1,C1,D1,M[13], 9,MAGIC4); F1(A2,B2,C2,D2,M[ 5], 6 );
+ F4(D1,A1,B1,C1,M[ 3],14,MAGIC4); F1(D2,A2,B2,C2,M[12], 9 );
+ F4(C1,D1,A1,B1,M[ 7], 5,MAGIC4); F1(C2,D2,A2,B2,M[ 2],12 );
+ F4(B1,C1,D1,A1,M[15], 6,MAGIC4); F1(B2,C2,D2,A2,M[13], 9 );
+ F4(A1,B1,C1,D1,M[14], 8,MAGIC4); F1(A2,B2,C2,D2,M[ 9],12 );
+ F4(D1,A1,B1,C1,M[ 5], 6,MAGIC4); F1(D2,A2,B2,C2,M[ 7], 5 );
+ F4(C1,D1,A1,B1,M[ 6], 5,MAGIC4); F1(C2,D2,A2,B2,M[10],15 );
+ F4(B1,C1,D1,A1,M[ 2],12,MAGIC4); F1(B2,C2,D2,A2,M[14], 8 );
+
+ D2 = digest[1] + C1 + D2;
+ digest[1] = digest[2] + D1 + A2;
+ digest[2] = digest[3] + A1 + B2;
+ digest[3] = digest[0] + B1 + C2;
+ digest[0] = D2;
+
+ input += hash_block_size();
+ }
+ }
+
+/*
+* Copy out the digest
+*/
+void RIPEMD_128::copy_out(byte output[])
+ {
+ for(size_t i = 0; i != output_length(); i += 4)
+ store_le(digest[i/4], output + i);
+ }
+
+/*
+* Clear memory of sensitive data
+*/
+void RIPEMD_128::clear()
+ {
+ MDx_HashFunction::clear();
+ zeroise(M);
+ digest[0] = 0x67452301;
+ digest[1] = 0xEFCDAB89;
+ digest[2] = 0x98BADCFE;
+ digest[3] = 0x10325476;
+ }
+
+}
diff --git a/src/lib/hash/rmd128/rmd128.h b/src/lib/hash/rmd128/rmd128.h
new file mode 100644
index 000000000..e37666a27
--- /dev/null
+++ b/src/lib/hash/rmd128/rmd128.h
@@ -0,0 +1,38 @@
+/*
+* RIPEMD-128
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_RIPEMD_128_H__
+#define BOTAN_RIPEMD_128_H__
+
+#include <botan/mdx_hash.h>
+
+namespace Botan {
+
+/**
+* RIPEMD-128
+*/
+class BOTAN_DLL RIPEMD_128 : public MDx_HashFunction
+ {
+ public:
+ std::string name() const { return "RIPEMD-128"; }
+ size_t output_length() const { return 16; }
+ HashFunction* clone() const { return new RIPEMD_128; }
+
+ void clear();
+
+ RIPEMD_128() : MDx_HashFunction(64, false, true), M(16), digest(4)
+ { clear(); }
+ private:
+ void compress_n(const byte[], size_t blocks);
+ void copy_out(byte[]);
+
+ secure_vector<u32bit> M, digest;
+ };
+
+}
+
+#endif
diff --git a/src/lib/hash/rmd160/info.txt b/src/lib/hash/rmd160/info.txt
new file mode 100644
index 000000000..4e1451bb6
--- /dev/null
+++ b/src/lib/hash/rmd160/info.txt
@@ -0,0 +1,5 @@
+define RIPEMD_160 20131128
+
+<requires>
+mdx_hash
+</requires>
diff --git a/src/lib/hash/rmd160/rmd160.cpp b/src/lib/hash/rmd160/rmd160.cpp
new file mode 100644
index 000000000..ff1c1c4ec
--- /dev/null
+++ b/src/lib/hash/rmd160/rmd160.cpp
@@ -0,0 +1,210 @@
+/*
+* RIPEMD-160
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/rmd160.h>
+#include <botan/loadstor.h>
+#include <botan/rotate.h>
+
+namespace Botan {
+
+namespace {
+
+/*
+* RIPEMD-160 F1 Function
+*/
+inline void F1(u32bit& A, u32bit B, u32bit& C, u32bit D, u32bit E,
+ u32bit msg, u32bit shift)
+ {
+ A += (B ^ C ^ D) + msg;
+ A = rotate_left(A, shift) + E;
+ C = rotate_left(C, 10);
+ }
+
+/*
+* RIPEMD-160 F2 Function
+*/
+inline void F2(u32bit& A, u32bit B, u32bit& C, u32bit D, u32bit E,
+ u32bit msg, u32bit shift, u32bit magic)
+ {
+ A += (D ^ (B & (C ^ D))) + msg + magic;
+ A = rotate_left(A, shift) + E;
+ C = rotate_left(C, 10);
+ }
+
+/*
+* RIPEMD-160 F3 Function
+*/
+inline void F3(u32bit& A, u32bit B, u32bit& C, u32bit D, u32bit E,
+ u32bit msg, u32bit shift, u32bit magic)
+ {
+ A += (D ^ (B | ~C)) + msg + magic;
+ A = rotate_left(A, shift) + E;
+ C = rotate_left(C, 10);
+ }
+
+/*
+* RIPEMD-160 F4 Function
+*/
+inline void F4(u32bit& A, u32bit B, u32bit& C, u32bit D, u32bit E,
+ u32bit msg, u32bit shift, u32bit magic)
+ {
+ A += (C ^ (D & (B ^ C))) + msg + magic;
+ A = rotate_left(A, shift) + E;
+ C = rotate_left(C, 10);
+ }
+
+/*
+* RIPEMD-160 F5 Function
+*/
+inline void F5(u32bit& A, u32bit B, u32bit& C, u32bit D, u32bit E,
+ u32bit msg, u32bit shift, u32bit magic)
+ {
+ A += (B ^ (C | ~D)) + msg + magic;
+ A = rotate_left(A, shift) + E;
+ C = rotate_left(C, 10);
+ }
+
+}
+
+/*
+* RIPEMD-160 Compression Function
+*/
+void RIPEMD_160::compress_n(const byte input[], size_t blocks)
+ {
+ const u32bit MAGIC2 = 0x5A827999, MAGIC3 = 0x6ED9EBA1,
+ MAGIC4 = 0x8F1BBCDC, MAGIC5 = 0xA953FD4E,
+ MAGIC6 = 0x50A28BE6, MAGIC7 = 0x5C4DD124,
+ MAGIC8 = 0x6D703EF3, MAGIC9 = 0x7A6D76E9;
+
+ for(size_t i = 0; i != blocks; ++i)
+ {
+ load_le(&M[0], input, M.size());
+
+ u32bit A1 = digest[0], A2 = A1, B1 = digest[1], B2 = B1,
+ C1 = digest[2], C2 = C1, D1 = digest[3], D2 = D1,
+ E1 = digest[4], E2 = E1;
+
+ F1(A1,B1,C1,D1,E1,M[ 0],11 ); F5(A2,B2,C2,D2,E2,M[ 5], 8,MAGIC6);
+ F1(E1,A1,B1,C1,D1,M[ 1],14 ); F5(E2,A2,B2,C2,D2,M[14], 9,MAGIC6);
+ F1(D1,E1,A1,B1,C1,M[ 2],15 ); F5(D2,E2,A2,B2,C2,M[ 7], 9,MAGIC6);
+ F1(C1,D1,E1,A1,B1,M[ 3],12 ); F5(C2,D2,E2,A2,B2,M[ 0],11,MAGIC6);
+ F1(B1,C1,D1,E1,A1,M[ 4], 5 ); F5(B2,C2,D2,E2,A2,M[ 9],13,MAGIC6);
+ F1(A1,B1,C1,D1,E1,M[ 5], 8 ); F5(A2,B2,C2,D2,E2,M[ 2],15,MAGIC6);
+ F1(E1,A1,B1,C1,D1,M[ 6], 7 ); F5(E2,A2,B2,C2,D2,M[11],15,MAGIC6);
+ F1(D1,E1,A1,B1,C1,M[ 7], 9 ); F5(D2,E2,A2,B2,C2,M[ 4], 5,MAGIC6);
+ F1(C1,D1,E1,A1,B1,M[ 8],11 ); F5(C2,D2,E2,A2,B2,M[13], 7,MAGIC6);
+ F1(B1,C1,D1,E1,A1,M[ 9],13 ); F5(B2,C2,D2,E2,A2,M[ 6], 7,MAGIC6);
+ F1(A1,B1,C1,D1,E1,M[10],14 ); F5(A2,B2,C2,D2,E2,M[15], 8,MAGIC6);
+ F1(E1,A1,B1,C1,D1,M[11],15 ); F5(E2,A2,B2,C2,D2,M[ 8],11,MAGIC6);
+ F1(D1,E1,A1,B1,C1,M[12], 6 ); F5(D2,E2,A2,B2,C2,M[ 1],14,MAGIC6);
+ F1(C1,D1,E1,A1,B1,M[13], 7 ); F5(C2,D2,E2,A2,B2,M[10],14,MAGIC6);
+ F1(B1,C1,D1,E1,A1,M[14], 9 ); F5(B2,C2,D2,E2,A2,M[ 3],12,MAGIC6);
+ F1(A1,B1,C1,D1,E1,M[15], 8 ); F5(A2,B2,C2,D2,E2,M[12], 6,MAGIC6);
+
+ F2(E1,A1,B1,C1,D1,M[ 7], 7,MAGIC2); F4(E2,A2,B2,C2,D2,M[ 6], 9,MAGIC7);
+ F2(D1,E1,A1,B1,C1,M[ 4], 6,MAGIC2); F4(D2,E2,A2,B2,C2,M[11],13,MAGIC7);
+ F2(C1,D1,E1,A1,B1,M[13], 8,MAGIC2); F4(C2,D2,E2,A2,B2,M[ 3],15,MAGIC7);
+ F2(B1,C1,D1,E1,A1,M[ 1],13,MAGIC2); F4(B2,C2,D2,E2,A2,M[ 7], 7,MAGIC7);
+ F2(A1,B1,C1,D1,E1,M[10],11,MAGIC2); F4(A2,B2,C2,D2,E2,M[ 0],12,MAGIC7);
+ F2(E1,A1,B1,C1,D1,M[ 6], 9,MAGIC2); F4(E2,A2,B2,C2,D2,M[13], 8,MAGIC7);
+ F2(D1,E1,A1,B1,C1,M[15], 7,MAGIC2); F4(D2,E2,A2,B2,C2,M[ 5], 9,MAGIC7);
+ F2(C1,D1,E1,A1,B1,M[ 3],15,MAGIC2); F4(C2,D2,E2,A2,B2,M[10],11,MAGIC7);
+ F2(B1,C1,D1,E1,A1,M[12], 7,MAGIC2); F4(B2,C2,D2,E2,A2,M[14], 7,MAGIC7);
+ F2(A1,B1,C1,D1,E1,M[ 0],12,MAGIC2); F4(A2,B2,C2,D2,E2,M[15], 7,MAGIC7);
+ F2(E1,A1,B1,C1,D1,M[ 9],15,MAGIC2); F4(E2,A2,B2,C2,D2,M[ 8],12,MAGIC7);
+ F2(D1,E1,A1,B1,C1,M[ 5], 9,MAGIC2); F4(D2,E2,A2,B2,C2,M[12], 7,MAGIC7);
+ F2(C1,D1,E1,A1,B1,M[ 2],11,MAGIC2); F4(C2,D2,E2,A2,B2,M[ 4], 6,MAGIC7);
+ F2(B1,C1,D1,E1,A1,M[14], 7,MAGIC2); F4(B2,C2,D2,E2,A2,M[ 9],15,MAGIC7);
+ F2(A1,B1,C1,D1,E1,M[11],13,MAGIC2); F4(A2,B2,C2,D2,E2,M[ 1],13,MAGIC7);
+ F2(E1,A1,B1,C1,D1,M[ 8],12,MAGIC2); F4(E2,A2,B2,C2,D2,M[ 2],11,MAGIC7);
+
+ F3(D1,E1,A1,B1,C1,M[ 3],11,MAGIC3); F3(D2,E2,A2,B2,C2,M[15], 9,MAGIC8);
+ F3(C1,D1,E1,A1,B1,M[10],13,MAGIC3); F3(C2,D2,E2,A2,B2,M[ 5], 7,MAGIC8);
+ F3(B1,C1,D1,E1,A1,M[14], 6,MAGIC3); F3(B2,C2,D2,E2,A2,M[ 1],15,MAGIC8);
+ F3(A1,B1,C1,D1,E1,M[ 4], 7,MAGIC3); F3(A2,B2,C2,D2,E2,M[ 3],11,MAGIC8);
+ F3(E1,A1,B1,C1,D1,M[ 9],14,MAGIC3); F3(E2,A2,B2,C2,D2,M[ 7], 8,MAGIC8);
+ F3(D1,E1,A1,B1,C1,M[15], 9,MAGIC3); F3(D2,E2,A2,B2,C2,M[14], 6,MAGIC8);
+ F3(C1,D1,E1,A1,B1,M[ 8],13,MAGIC3); F3(C2,D2,E2,A2,B2,M[ 6], 6,MAGIC8);
+ F3(B1,C1,D1,E1,A1,M[ 1],15,MAGIC3); F3(B2,C2,D2,E2,A2,M[ 9],14,MAGIC8);
+ F3(A1,B1,C1,D1,E1,M[ 2],14,MAGIC3); F3(A2,B2,C2,D2,E2,M[11],12,MAGIC8);
+ F3(E1,A1,B1,C1,D1,M[ 7], 8,MAGIC3); F3(E2,A2,B2,C2,D2,M[ 8],13,MAGIC8);
+ F3(D1,E1,A1,B1,C1,M[ 0],13,MAGIC3); F3(D2,E2,A2,B2,C2,M[12], 5,MAGIC8);
+ F3(C1,D1,E1,A1,B1,M[ 6], 6,MAGIC3); F3(C2,D2,E2,A2,B2,M[ 2],14,MAGIC8);
+ F3(B1,C1,D1,E1,A1,M[13], 5,MAGIC3); F3(B2,C2,D2,E2,A2,M[10],13,MAGIC8);
+ F3(A1,B1,C1,D1,E1,M[11],12,MAGIC3); F3(A2,B2,C2,D2,E2,M[ 0],13,MAGIC8);
+ F3(E1,A1,B1,C1,D1,M[ 5], 7,MAGIC3); F3(E2,A2,B2,C2,D2,M[ 4], 7,MAGIC8);
+ F3(D1,E1,A1,B1,C1,M[12], 5,MAGIC3); F3(D2,E2,A2,B2,C2,M[13], 5,MAGIC8);
+
+ F4(C1,D1,E1,A1,B1,M[ 1],11,MAGIC4); F2(C2,D2,E2,A2,B2,M[ 8],15,MAGIC9);
+ F4(B1,C1,D1,E1,A1,M[ 9],12,MAGIC4); F2(B2,C2,D2,E2,A2,M[ 6], 5,MAGIC9);
+ F4(A1,B1,C1,D1,E1,M[11],14,MAGIC4); F2(A2,B2,C2,D2,E2,M[ 4], 8,MAGIC9);
+ F4(E1,A1,B1,C1,D1,M[10],15,MAGIC4); F2(E2,A2,B2,C2,D2,M[ 1],11,MAGIC9);
+ F4(D1,E1,A1,B1,C1,M[ 0],14,MAGIC4); F2(D2,E2,A2,B2,C2,M[ 3],14,MAGIC9);
+ F4(C1,D1,E1,A1,B1,M[ 8],15,MAGIC4); F2(C2,D2,E2,A2,B2,M[11],14,MAGIC9);
+ F4(B1,C1,D1,E1,A1,M[12], 9,MAGIC4); F2(B2,C2,D2,E2,A2,M[15], 6,MAGIC9);
+ F4(A1,B1,C1,D1,E1,M[ 4], 8,MAGIC4); F2(A2,B2,C2,D2,E2,M[ 0],14,MAGIC9);
+ F4(E1,A1,B1,C1,D1,M[13], 9,MAGIC4); F2(E2,A2,B2,C2,D2,M[ 5], 6,MAGIC9);
+ F4(D1,E1,A1,B1,C1,M[ 3],14,MAGIC4); F2(D2,E2,A2,B2,C2,M[12], 9,MAGIC9);
+ F4(C1,D1,E1,A1,B1,M[ 7], 5,MAGIC4); F2(C2,D2,E2,A2,B2,M[ 2],12,MAGIC9);
+ F4(B1,C1,D1,E1,A1,M[15], 6,MAGIC4); F2(B2,C2,D2,E2,A2,M[13], 9,MAGIC9);
+ F4(A1,B1,C1,D1,E1,M[14], 8,MAGIC4); F2(A2,B2,C2,D2,E2,M[ 9],12,MAGIC9);
+ F4(E1,A1,B1,C1,D1,M[ 5], 6,MAGIC4); F2(E2,A2,B2,C2,D2,M[ 7], 5,MAGIC9);
+ F4(D1,E1,A1,B1,C1,M[ 6], 5,MAGIC4); F2(D2,E2,A2,B2,C2,M[10],15,MAGIC9);
+ F4(C1,D1,E1,A1,B1,M[ 2],12,MAGIC4); F2(C2,D2,E2,A2,B2,M[14], 8,MAGIC9);
+
+ F5(B1,C1,D1,E1,A1,M[ 4], 9,MAGIC5); F1(B2,C2,D2,E2,A2,M[12], 8 );
+ F5(A1,B1,C1,D1,E1,M[ 0],15,MAGIC5); F1(A2,B2,C2,D2,E2,M[15], 5 );
+ F5(E1,A1,B1,C1,D1,M[ 5], 5,MAGIC5); F1(E2,A2,B2,C2,D2,M[10],12 );
+ F5(D1,E1,A1,B1,C1,M[ 9],11,MAGIC5); F1(D2,E2,A2,B2,C2,M[ 4], 9 );
+ F5(C1,D1,E1,A1,B1,M[ 7], 6,MAGIC5); F1(C2,D2,E2,A2,B2,M[ 1],12 );
+ F5(B1,C1,D1,E1,A1,M[12], 8,MAGIC5); F1(B2,C2,D2,E2,A2,M[ 5], 5 );
+ F5(A1,B1,C1,D1,E1,M[ 2],13,MAGIC5); F1(A2,B2,C2,D2,E2,M[ 8],14 );
+ F5(E1,A1,B1,C1,D1,M[10],12,MAGIC5); F1(E2,A2,B2,C2,D2,M[ 7], 6 );
+ F5(D1,E1,A1,B1,C1,M[14], 5,MAGIC5); F1(D2,E2,A2,B2,C2,M[ 6], 8 );
+ F5(C1,D1,E1,A1,B1,M[ 1],12,MAGIC5); F1(C2,D2,E2,A2,B2,M[ 2],13 );
+ F5(B1,C1,D1,E1,A1,M[ 3],13,MAGIC5); F1(B2,C2,D2,E2,A2,M[13], 6 );
+ F5(A1,B1,C1,D1,E1,M[ 8],14,MAGIC5); F1(A2,B2,C2,D2,E2,M[14], 5 );
+ F5(E1,A1,B1,C1,D1,M[11],11,MAGIC5); F1(E2,A2,B2,C2,D2,M[ 0],15 );
+ F5(D1,E1,A1,B1,C1,M[ 6], 8,MAGIC5); F1(D2,E2,A2,B2,C2,M[ 3],13 );
+ F5(C1,D1,E1,A1,B1,M[15], 5,MAGIC5); F1(C2,D2,E2,A2,B2,M[ 9],11 );
+ F5(B1,C1,D1,E1,A1,M[13], 6,MAGIC5); F1(B2,C2,D2,E2,A2,M[11],11 );
+
+ C1 = digest[1] + C1 + D2;
+ digest[1] = digest[2] + D1 + E2;
+ digest[2] = digest[3] + E1 + A2;
+ digest[3] = digest[4] + A1 + B2;
+ digest[4] = digest[0] + B1 + C2;
+ digest[0] = C1;
+
+ input += hash_block_size();
+ }
+ }
+
+/*
+* Copy out the digest
+*/
+void RIPEMD_160::copy_out(byte output[])
+ {
+ for(size_t i = 0; i != output_length(); i += 4)
+ store_le(digest[i/4], output + i);
+ }
+
+/*
+* Clear memory of sensitive data
+*/
+void RIPEMD_160::clear()
+ {
+ MDx_HashFunction::clear();
+ zeroise(M);
+ digest[0] = 0x67452301;
+ digest[1] = 0xEFCDAB89;
+ digest[2] = 0x98BADCFE;
+ digest[3] = 0x10325476;
+ digest[4] = 0xC3D2E1F0;
+ }
+
+}
diff --git a/src/lib/hash/rmd160/rmd160.h b/src/lib/hash/rmd160/rmd160.h
new file mode 100644
index 000000000..0e43fed9a
--- /dev/null
+++ b/src/lib/hash/rmd160/rmd160.h
@@ -0,0 +1,38 @@
+/*
+* RIPEMD-160
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_RIPEMD_160_H__
+#define BOTAN_RIPEMD_160_H__
+
+#include <botan/mdx_hash.h>
+
+namespace Botan {
+
+/**
+* RIPEMD-160
+*/
+class BOTAN_DLL RIPEMD_160 : public MDx_HashFunction
+ {
+ public:
+ std::string name() const { return "RIPEMD-160"; }
+ size_t output_length() const { return 20; }
+ HashFunction* clone() const { return new RIPEMD_160; }
+
+ void clear();
+
+ RIPEMD_160() : MDx_HashFunction(64, false, true), M(16), digest(5)
+ { clear(); }
+ private:
+ void compress_n(const byte[], size_t blocks);
+ void copy_out(byte[]);
+
+ secure_vector<u32bit> M, digest;
+ };
+
+}
+
+#endif
diff --git a/src/lib/hash/sha1/info.txt b/src/lib/hash/sha1/info.txt
new file mode 100644
index 000000000..fffb51275
--- /dev/null
+++ b/src/lib/hash/sha1/info.txt
@@ -0,0 +1,5 @@
+define SHA1 20131128
+
+<requires>
+mdx_hash
+</requires>
diff --git a/src/lib/hash/sha1/sha160.cpp b/src/lib/hash/sha1/sha160.cpp
new file mode 100644
index 000000000..f5daaadb2
--- /dev/null
+++ b/src/lib/hash/sha1/sha160.cpp
@@ -0,0 +1,161 @@
+/*
+* SHA-160
+* (C) 1999-2008,2011 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/sha160.h>
+#include <botan/loadstor.h>
+#include <botan/rotate.h>
+
+namespace Botan {
+
+namespace SHA1_F {
+
+namespace {
+
+/*
+* SHA-160 F1 Function
+*/
+inline void F1(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg)
+ {
+ E += (D ^ (B & (C ^ D))) + msg + 0x5A827999 + rotate_left(A, 5);
+ B = rotate_left(B, 30);
+ }
+
+/*
+* SHA-160 F2 Function
+*/
+inline void F2(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg)
+ {
+ E += (B ^ C ^ D) + msg + 0x6ED9EBA1 + rotate_left(A, 5);
+ B = rotate_left(B, 30);
+ }
+
+/*
+* SHA-160 F3 Function
+*/
+inline void F3(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg)
+ {
+ E += ((B & C) | ((B | C) & D)) + msg + 0x8F1BBCDC + rotate_left(A, 5);
+ B = rotate_left(B, 30);
+ }
+
+/*
+* SHA-160 F4 Function
+*/
+inline void F4(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg)
+ {
+ E += (B ^ C ^ D) + msg + 0xCA62C1D6 + rotate_left(A, 5);
+ B = rotate_left(B, 30);
+ }
+
+}
+
+}
+
+/*
+* SHA-160 Compression Function
+*/
+void SHA_160::compress_n(const byte input[], size_t blocks)
+ {
+ using namespace SHA1_F;
+
+ u32bit A = digest[0], B = digest[1], C = digest[2],
+ D = digest[3], E = digest[4];
+
+ for(size_t i = 0; i != blocks; ++i)
+ {
+ load_be(&W[0], input, 16);
+
+ for(size_t j = 16; j != 80; j += 8)
+ {
+ W[j ] = rotate_left((W[j-3] ^ W[j-8] ^ W[j-14] ^ W[j-16]), 1);
+ W[j+1] = rotate_left((W[j-2] ^ W[j-7] ^ W[j-13] ^ W[j-15]), 1);
+ W[j+2] = rotate_left((W[j-1] ^ W[j-6] ^ W[j-12] ^ W[j-14]), 1);
+ W[j+3] = rotate_left((W[j ] ^ W[j-5] ^ W[j-11] ^ W[j-13]), 1);
+ W[j+4] = rotate_left((W[j+1] ^ W[j-4] ^ W[j-10] ^ W[j-12]), 1);
+ W[j+5] = rotate_left((W[j+2] ^ W[j-3] ^ W[j- 9] ^ W[j-11]), 1);
+ W[j+6] = rotate_left((W[j+3] ^ W[j-2] ^ W[j- 8] ^ W[j-10]), 1);
+ W[j+7] = rotate_left((W[j+4] ^ W[j-1] ^ W[j- 7] ^ W[j- 9]), 1);
+ }
+
+ F1(A, B, C, D, E, W[ 0]); F1(E, A, B, C, D, W[ 1]);
+ F1(D, E, A, B, C, W[ 2]); F1(C, D, E, A, B, W[ 3]);
+ F1(B, C, D, E, A, W[ 4]); F1(A, B, C, D, E, W[ 5]);
+ F1(E, A, B, C, D, W[ 6]); F1(D, E, A, B, C, W[ 7]);
+ F1(C, D, E, A, B, W[ 8]); F1(B, C, D, E, A, W[ 9]);
+ F1(A, B, C, D, E, W[10]); F1(E, A, B, C, D, W[11]);
+ F1(D, E, A, B, C, W[12]); F1(C, D, E, A, B, W[13]);
+ F1(B, C, D, E, A, W[14]); F1(A, B, C, D, E, W[15]);
+ F1(E, A, B, C, D, W[16]); F1(D, E, A, B, C, W[17]);
+ F1(C, D, E, A, B, W[18]); F1(B, C, D, E, A, W[19]);
+
+ F2(A, B, C, D, E, W[20]); F2(E, A, B, C, D, W[21]);
+ F2(D, E, A, B, C, W[22]); F2(C, D, E, A, B, W[23]);
+ F2(B, C, D, E, A, W[24]); F2(A, B, C, D, E, W[25]);
+ F2(E, A, B, C, D, W[26]); F2(D, E, A, B, C, W[27]);
+ F2(C, D, E, A, B, W[28]); F2(B, C, D, E, A, W[29]);
+ F2(A, B, C, D, E, W[30]); F2(E, A, B, C, D, W[31]);
+ F2(D, E, A, B, C, W[32]); F2(C, D, E, A, B, W[33]);
+ F2(B, C, D, E, A, W[34]); F2(A, B, C, D, E, W[35]);
+ F2(E, A, B, C, D, W[36]); F2(D, E, A, B, C, W[37]);
+ F2(C, D, E, A, B, W[38]); F2(B, C, D, E, A, W[39]);
+
+ F3(A, B, C, D, E, W[40]); F3(E, A, B, C, D, W[41]);
+ F3(D, E, A, B, C, W[42]); F3(C, D, E, A, B, W[43]);
+ F3(B, C, D, E, A, W[44]); F3(A, B, C, D, E, W[45]);
+ F3(E, A, B, C, D, W[46]); F3(D, E, A, B, C, W[47]);
+ F3(C, D, E, A, B, W[48]); F3(B, C, D, E, A, W[49]);
+ F3(A, B, C, D, E, W[50]); F3(E, A, B, C, D, W[51]);
+ F3(D, E, A, B, C, W[52]); F3(C, D, E, A, B, W[53]);
+ F3(B, C, D, E, A, W[54]); F3(A, B, C, D, E, W[55]);
+ F3(E, A, B, C, D, W[56]); F3(D, E, A, B, C, W[57]);
+ F3(C, D, E, A, B, W[58]); F3(B, C, D, E, A, W[59]);
+
+ F4(A, B, C, D, E, W[60]); F4(E, A, B, C, D, W[61]);
+ F4(D, E, A, B, C, W[62]); F4(C, D, E, A, B, W[63]);
+ F4(B, C, D, E, A, W[64]); F4(A, B, C, D, E, W[65]);
+ F4(E, A, B, C, D, W[66]); F4(D, E, A, B, C, W[67]);
+ F4(C, D, E, A, B, W[68]); F4(B, C, D, E, A, W[69]);
+ F4(A, B, C, D, E, W[70]); F4(E, A, B, C, D, W[71]);
+ F4(D, E, A, B, C, W[72]); F4(C, D, E, A, B, W[73]);
+ F4(B, C, D, E, A, W[74]); F4(A, B, C, D, E, W[75]);
+ F4(E, A, B, C, D, W[76]); F4(D, E, A, B, C, W[77]);
+ F4(C, D, E, A, B, W[78]); F4(B, C, D, E, A, W[79]);
+
+ A = (digest[0] += A);
+ B = (digest[1] += B);
+ C = (digest[2] += C);
+ D = (digest[3] += D);
+ E = (digest[4] += E);
+
+ input += hash_block_size();
+ }
+ }
+
+/*
+* Copy out the digest
+*/
+void SHA_160::copy_out(byte output[])
+ {
+ for(size_t i = 0; i != output_length(); i += 4)
+ store_be(digest[i/4], output + i);
+ }
+
+/*
+* Clear memory of sensitive data
+*/
+void SHA_160::clear()
+ {
+ MDx_HashFunction::clear();
+ zeroise(W);
+ digest[0] = 0x67452301;
+ digest[1] = 0xEFCDAB89;
+ digest[2] = 0x98BADCFE;
+ digest[3] = 0x10325476;
+ digest[4] = 0xC3D2E1F0;
+ }
+
+}
diff --git a/src/lib/hash/sha1/sha160.h b/src/lib/hash/sha1/sha160.h
new file mode 100644
index 000000000..e2a81808d
--- /dev/null
+++ b/src/lib/hash/sha1/sha160.h
@@ -0,0 +1,60 @@
+/*
+* SHA-160
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_SHA_160_H__
+#define BOTAN_SHA_160_H__
+
+#include <botan/mdx_hash.h>
+
+namespace Botan {
+
+/**
+* NIST's SHA-160
+*/
+class BOTAN_DLL SHA_160 : public MDx_HashFunction
+ {
+ public:
+ std::string name() const { return "SHA-160"; }
+ size_t output_length() const { return 20; }
+ HashFunction* clone() const { return new SHA_160; }
+
+ void clear();
+
+ SHA_160() : MDx_HashFunction(64, true, true), digest(5), W(80)
+ {
+ clear();
+ }
+ protected:
+ /**
+ * Set a custom size for the W array. Normally 80, but some
+ * subclasses need slightly more for best performance/internal
+ * constraints
+ * @param W_size how big to make W
+ */
+ SHA_160(size_t W_size) :
+ MDx_HashFunction(64, true, true), digest(5), W(W_size)
+ {
+ clear();
+ }
+
+ void compress_n(const byte[], size_t blocks);
+ void copy_out(byte[]);
+
+ /**
+ * The digest value, exposed for use by subclasses (asm, SSE2)
+ */
+ secure_vector<u32bit> digest;
+
+ /**
+ * The message buffer, exposed for use by subclasses (asm, SSE2)
+ */
+ secure_vector<u32bit> W;
+ };
+
+}
+
+#endif
diff --git a/src/lib/hash/sha1_sse2/info.txt b/src/lib/hash/sha1_sse2/info.txt
new file mode 100644
index 000000000..8d4926e63
--- /dev/null
+++ b/src/lib/hash/sha1_sse2/info.txt
@@ -0,0 +1,8 @@
+define SHA1_SSE2 20131128
+
+need_isa sse2
+
+<requires>
+sha1
+simd_engine
+</requires>
diff --git a/src/lib/hash/sha1_sse2/sha1_sse2.cpp b/src/lib/hash/sha1_sse2/sha1_sse2.cpp
new file mode 100644
index 000000000..f96afd9ce
--- /dev/null
+++ b/src/lib/hash/sha1_sse2/sha1_sse2.cpp
@@ -0,0 +1,335 @@
+/*
+* SHA-1 using SSE2
+* (C) 2009-2011 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*
+* Based on public domain code by Dean Gaudet
+* (http://arctic.org/~dean/crypto/sha1.html)
+*/
+
+#include <botan/sha1_sse2.h>
+#include <botan/rotate.h>
+#include <emmintrin.h>
+
+namespace Botan {
+
+namespace SHA1_SSE2_F {
+
+namespace {
+
+/*
+* First 16 bytes just need byte swapping. Preparing just means
+* adding in the round constants.
+*/
+
+#define prep00_15(P, W) \
+ do { \
+ W = _mm_shufflehi_epi16(W, _MM_SHUFFLE(2, 3, 0, 1)); \
+ W = _mm_shufflelo_epi16(W, _MM_SHUFFLE(2, 3, 0, 1)); \
+ W = _mm_or_si128(_mm_slli_epi16(W, 8), \
+ _mm_srli_epi16(W, 8)); \
+ P.u128 = _mm_add_epi32(W, K00_19); \
+ } while(0)
+
+/*
+For each multiple of 4, t, we want to calculate this:
+
+W[t+0] = rol(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1);
+W[t+1] = rol(W[t-2] ^ W[t-7] ^ W[t-13] ^ W[t-15], 1);
+W[t+2] = rol(W[t-1] ^ W[t-6] ^ W[t-12] ^ W[t-14], 1);
+W[t+3] = rol(W[t] ^ W[t-5] ^ W[t-11] ^ W[t-13], 1);
+
+we'll actually calculate this:
+
+W[t+0] = rol(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1);
+W[t+1] = rol(W[t-2] ^ W[t-7] ^ W[t-13] ^ W[t-15], 1);
+W[t+2] = rol(W[t-1] ^ W[t-6] ^ W[t-12] ^ W[t-14], 1);
+W[t+3] = rol( 0 ^ W[t-5] ^ W[t-11] ^ W[t-13], 1);
+W[t+3] ^= rol(W[t+0], 1);
+
+the parameters are:
+
+W0 = &W[t-16];
+W1 = &W[t-12];
+W2 = &W[t- 8];
+W3 = &W[t- 4];
+
+and on output:
+prepared = W0 + K
+W0 = W[t]..W[t+3]
+*/
+
+/* note that there is a step here where i want to do a rol by 1, which
+* normally would look like this:
+*
+* r1 = psrld r0,$31
+* r0 = pslld r0,$1
+* r0 = por r0,r1
+*
+* but instead i do this:
+*
+* r1 = pcmpltd r0,zero
+* r0 = paddd r0,r0
+* r0 = psub r0,r1
+*
+* because pcmpltd and paddd are availabe in both MMX units on
+* efficeon, pentium-m, and opteron but shifts are available in
+* only one unit.
+*/
+#define prep(prep, XW0, XW1, XW2, XW3, K) \
+ do { \
+ __m128i r0, r1, r2, r3; \
+ \
+ /* load W[t-4] 16-byte aligned, and shift */ \
+ r3 = _mm_srli_si128((XW3), 4); \
+ r0 = (XW0); \
+ /* get high 64-bits of XW0 into low 64-bits */ \
+ r1 = _mm_shuffle_epi32((XW0), _MM_SHUFFLE(1,0,3,2)); \
+ /* load high 64-bits of r1 */ \
+ r1 = _mm_unpacklo_epi64(r1, (XW1)); \
+ r2 = (XW2); \
+ \
+ r0 = _mm_xor_si128(r1, r0); \
+ r2 = _mm_xor_si128(r3, r2); \
+ r0 = _mm_xor_si128(r2, r0); \
+ /* unrotated W[t]..W[t+2] in r0 ... still need W[t+3] */ \
+ \
+ r2 = _mm_slli_si128(r0, 12); \
+ r1 = _mm_cmplt_epi32(r0, _mm_setzero_si128()); \
+ r0 = _mm_add_epi32(r0, r0); /* shift left by 1 */ \
+ r0 = _mm_sub_epi32(r0, r1); /* r0 has W[t]..W[t+2] */ \
+ \
+ r3 = _mm_srli_epi32(r2, 30); \
+ r2 = _mm_slli_epi32(r2, 2); \
+ \
+ r0 = _mm_xor_si128(r0, r3); \
+ r0 = _mm_xor_si128(r0, r2); /* r0 now has W[t+3] */ \
+ \
+ (XW0) = r0; \
+ (prep).u128 = _mm_add_epi32(r0, K); \
+ } while(0)
+
+/*
+* SHA-160 F1 Function
+*/
+inline void F1(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg)
+ {
+ E += (D ^ (B & (C ^ D))) + msg + rotate_left(A, 5);
+ B = rotate_left(B, 30);
+ }
+
+/*
+* SHA-160 F2 Function
+*/
+inline void F2(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg)
+ {
+ E += (B ^ C ^ D) + msg + rotate_left(A, 5);
+ B = rotate_left(B, 30);
+ }
+
+/*
+* SHA-160 F3 Function
+*/
+inline void F3(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg)
+ {
+ E += ((B & C) | ((B | C) & D)) + msg + rotate_left(A, 5);
+ B = rotate_left(B, 30);
+ }
+
+/*
+* SHA-160 F4 Function
+*/
+inline void F4(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg)
+ {
+ E += (B ^ C ^ D) + msg + rotate_left(A, 5);
+ B = rotate_left(B, 30);
+ }
+
+}
+
+}
+
+/*
+* SHA-160 Compression Function using SSE for message expansion
+*/
+void SHA_160_SSE2::compress_n(const byte input_bytes[], size_t blocks)
+ {
+ using namespace SHA1_SSE2_F;
+
+ const __m128i K00_19 = _mm_set1_epi32(0x5A827999);
+ const __m128i K20_39 = _mm_set1_epi32(0x6ED9EBA1);
+ const __m128i K40_59 = _mm_set1_epi32(0x8F1BBCDC);
+ const __m128i K60_79 = _mm_set1_epi32(0xCA62C1D6);
+
+ u32bit A = digest[0],
+ B = digest[1],
+ C = digest[2],
+ D = digest[3],
+ E = digest[4];
+
+ const __m128i* input = reinterpret_cast<const __m128i*>(input_bytes);
+
+ for(size_t i = 0; i != blocks; ++i)
+ {
+ union v4si {
+ u32bit u32[4];
+ __m128i u128;
+ };
+
+ v4si P0, P1, P2, P3;
+
+ __m128i W0 = _mm_loadu_si128(&input[0]);
+ prep00_15(P0, W0);
+
+ __m128i W1 = _mm_loadu_si128(&input[1]);
+ prep00_15(P1, W1);
+
+ __m128i W2 = _mm_loadu_si128(&input[2]);
+ prep00_15(P2, W2);
+
+ __m128i W3 = _mm_loadu_si128(&input[3]);
+ prep00_15(P3, W3);
+
+ /*
+ Using SSE4; slower on Core2 and Nehalem
+ #define GET_P_32(P, i) _mm_extract_epi32(P.u128, i)
+
+ Much slower on all tested platforms
+ #define GET_P_32(P,i) _mm_cvtsi128_si32(_mm_srli_si128(P.u128, i*4))
+ */
+
+#define GET_P_32(P, i) P.u32[i]
+
+ F1(A, B, C, D, E, GET_P_32(P0, 0));
+ F1(E, A, B, C, D, GET_P_32(P0, 1));
+ F1(D, E, A, B, C, GET_P_32(P0, 2));
+ F1(C, D, E, A, B, GET_P_32(P0, 3));
+ prep(P0, W0, W1, W2, W3, K00_19);
+
+ F1(B, C, D, E, A, GET_P_32(P1, 0));
+ F1(A, B, C, D, E, GET_P_32(P1, 1));
+ F1(E, A, B, C, D, GET_P_32(P1, 2));
+ F1(D, E, A, B, C, GET_P_32(P1, 3));
+ prep(P1, W1, W2, W3, W0, K20_39);
+
+ F1(C, D, E, A, B, GET_P_32(P2, 0));
+ F1(B, C, D, E, A, GET_P_32(P2, 1));
+ F1(A, B, C, D, E, GET_P_32(P2, 2));
+ F1(E, A, B, C, D, GET_P_32(P2, 3));
+ prep(P2, W2, W3, W0, W1, K20_39);
+
+ F1(D, E, A, B, C, GET_P_32(P3, 0));
+ F1(C, D, E, A, B, GET_P_32(P3, 1));
+ F1(B, C, D, E, A, GET_P_32(P3, 2));
+ F1(A, B, C, D, E, GET_P_32(P3, 3));
+ prep(P3, W3, W0, W1, W2, K20_39);
+
+ F1(E, A, B, C, D, GET_P_32(P0, 0));
+ F1(D, E, A, B, C, GET_P_32(P0, 1));
+ F1(C, D, E, A, B, GET_P_32(P0, 2));
+ F1(B, C, D, E, A, GET_P_32(P0, 3));
+ prep(P0, W0, W1, W2, W3, K20_39);
+
+ F2(A, B, C, D, E, GET_P_32(P1, 0));
+ F2(E, A, B, C, D, GET_P_32(P1, 1));
+ F2(D, E, A, B, C, GET_P_32(P1, 2));
+ F2(C, D, E, A, B, GET_P_32(P1, 3));
+ prep(P1, W1, W2, W3, W0, K20_39);
+
+ F2(B, C, D, E, A, GET_P_32(P2, 0));
+ F2(A, B, C, D, E, GET_P_32(P2, 1));
+ F2(E, A, B, C, D, GET_P_32(P2, 2));
+ F2(D, E, A, B, C, GET_P_32(P2, 3));
+ prep(P2, W2, W3, W0, W1, K40_59);
+
+ F2(C, D, E, A, B, GET_P_32(P3, 0));
+ F2(B, C, D, E, A, GET_P_32(P3, 1));
+ F2(A, B, C, D, E, GET_P_32(P3, 2));
+ F2(E, A, B, C, D, GET_P_32(P3, 3));
+ prep(P3, W3, W0, W1, W2, K40_59);
+
+ F2(D, E, A, B, C, GET_P_32(P0, 0));
+ F2(C, D, E, A, B, GET_P_32(P0, 1));
+ F2(B, C, D, E, A, GET_P_32(P0, 2));
+ F2(A, B, C, D, E, GET_P_32(P0, 3));
+ prep(P0, W0, W1, W2, W3, K40_59);
+
+ F2(E, A, B, C, D, GET_P_32(P1, 0));
+ F2(D, E, A, B, C, GET_P_32(P1, 1));
+ F2(C, D, E, A, B, GET_P_32(P1, 2));
+ F2(B, C, D, E, A, GET_P_32(P1, 3));
+ prep(P1, W1, W2, W3, W0, K40_59);
+
+ F3(A, B, C, D, E, GET_P_32(P2, 0));
+ F3(E, A, B, C, D, GET_P_32(P2, 1));
+ F3(D, E, A, B, C, GET_P_32(P2, 2));
+ F3(C, D, E, A, B, GET_P_32(P2, 3));
+ prep(P2, W2, W3, W0, W1, K40_59);
+
+ F3(B, C, D, E, A, GET_P_32(P3, 0));
+ F3(A, B, C, D, E, GET_P_32(P3, 1));
+ F3(E, A, B, C, D, GET_P_32(P3, 2));
+ F3(D, E, A, B, C, GET_P_32(P3, 3));
+ prep(P3, W3, W0, W1, W2, K60_79);
+
+ F3(C, D, E, A, B, GET_P_32(P0, 0));
+ F3(B, C, D, E, A, GET_P_32(P0, 1));
+ F3(A, B, C, D, E, GET_P_32(P0, 2));
+ F3(E, A, B, C, D, GET_P_32(P0, 3));
+ prep(P0, W0, W1, W2, W3, K60_79);
+
+ F3(D, E, A, B, C, GET_P_32(P1, 0));
+ F3(C, D, E, A, B, GET_P_32(P1, 1));
+ F3(B, C, D, E, A, GET_P_32(P1, 2));
+ F3(A, B, C, D, E, GET_P_32(P1, 3));
+ prep(P1, W1, W2, W3, W0, K60_79);
+
+ F3(E, A, B, C, D, GET_P_32(P2, 0));
+ F3(D, E, A, B, C, GET_P_32(P2, 1));
+ F3(C, D, E, A, B, GET_P_32(P2, 2));
+ F3(B, C, D, E, A, GET_P_32(P2, 3));
+ prep(P2, W2, W3, W0, W1, K60_79);
+
+ F4(A, B, C, D, E, GET_P_32(P3, 0));
+ F4(E, A, B, C, D, GET_P_32(P3, 1));
+ F4(D, E, A, B, C, GET_P_32(P3, 2));
+ F4(C, D, E, A, B, GET_P_32(P3, 3));
+ prep(P3, W3, W0, W1, W2, K60_79);
+
+ F4(B, C, D, E, A, GET_P_32(P0, 0));
+ F4(A, B, C, D, E, GET_P_32(P0, 1));
+ F4(E, A, B, C, D, GET_P_32(P0, 2));
+ F4(D, E, A, B, C, GET_P_32(P0, 3));
+
+ F4(C, D, E, A, B, GET_P_32(P1, 0));
+ F4(B, C, D, E, A, GET_P_32(P1, 1));
+ F4(A, B, C, D, E, GET_P_32(P1, 2));
+ F4(E, A, B, C, D, GET_P_32(P1, 3));
+
+ F4(D, E, A, B, C, GET_P_32(P2, 0));
+ F4(C, D, E, A, B, GET_P_32(P2, 1));
+ F4(B, C, D, E, A, GET_P_32(P2, 2));
+ F4(A, B, C, D, E, GET_P_32(P2, 3));
+
+ F4(E, A, B, C, D, GET_P_32(P3, 0));
+ F4(D, E, A, B, C, GET_P_32(P3, 1));
+ F4(C, D, E, A, B, GET_P_32(P3, 2));
+ F4(B, C, D, E, A, GET_P_32(P3, 3));
+
+ A = (digest[0] += A);
+ B = (digest[1] += B);
+ C = (digest[2] += C);
+ D = (digest[3] += D);
+ E = (digest[4] += E);
+
+ input += (hash_block_size() / 16);
+ }
+
+#undef GET_P_32
+ }
+
+#undef prep00_15
+#undef prep
+
+}
diff --git a/src/lib/hash/sha1_sse2/sha1_sse2.h b/src/lib/hash/sha1_sse2/sha1_sse2.h
new file mode 100644
index 000000000..9b7b327f0
--- /dev/null
+++ b/src/lib/hash/sha1_sse2/sha1_sse2.h
@@ -0,0 +1,29 @@
+/*
+* SHA-160
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_SHA_160_SSE2_H__
+#define BOTAN_SHA_160_SSE2_H__
+
+#include <botan/sha160.h>
+
+namespace Botan {
+
+/**
+* SHA-160 using SSE2 for the message expansion
+*/
+class BOTAN_DLL SHA_160_SSE2 : public SHA_160
+ {
+ public:
+ HashFunction* clone() const { return new SHA_160_SSE2; }
+ SHA_160_SSE2() : SHA_160(0) {} // no W needed
+ private:
+ void compress_n(const byte[], size_t blocks);
+ };
+
+}
+
+#endif
diff --git a/src/lib/hash/sha1_x86_32/info.txt b/src/lib/hash/sha1_x86_32/info.txt
new file mode 100644
index 000000000..51e3f6587
--- /dev/null
+++ b/src/lib/hash/sha1_x86_32/info.txt
@@ -0,0 +1,12 @@
+define SHA1_X86_32 20131128
+
+load_on asm_ok
+
+<arch>
+x86_32
+</arch>
+
+<requires>
+asm_x86_32
+sha1
+</requires>
diff --git a/src/lib/hash/sha1_x86_32/sha1_x86_32.cpp b/src/lib/hash/sha1_x86_32/sha1_x86_32.cpp
new file mode 100644
index 000000000..6a4dc2a1d
--- /dev/null
+++ b/src/lib/hash/sha1_x86_32/sha1_x86_32.cpp
@@ -0,0 +1,31 @@
+/*
+* SHA-160 in x86-32
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/sha1_x86_32.h>
+
+namespace Botan {
+
+namespace {
+
+extern "C"
+void botan_sha160_x86_32_compress(u32bit[5], const byte[64], u32bit[81]);
+
+}
+
+/*
+* SHA-160 Compression Function
+*/
+void SHA_160_X86_32::compress_n(const byte input[], size_t blocks)
+ {
+ for(size_t i = 0; i != blocks; ++i)
+ {
+ botan_sha160_x86_32_compress(&digest[0], input, &W[0]);
+ input += hash_block_size();
+ }
+ }
+
+}
diff --git a/src/lib/hash/sha1_x86_32/sha1_x86_32.h b/src/lib/hash/sha1_x86_32/sha1_x86_32.h
new file mode 100644
index 000000000..b344d4ae2
--- /dev/null
+++ b/src/lib/hash/sha1_x86_32/sha1_x86_32.h
@@ -0,0 +1,31 @@
+/*
+* SHA-160 in x86-32 asm
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_SHA_160_X86_32_H__
+#define BOTAN_SHA_160_X86_32_H__
+
+#include <botan/sha160.h>
+
+namespace Botan {
+
+/**
+* SHA-160 in x86 assembly
+*/
+class BOTAN_DLL SHA_160_X86_32 : public SHA_160
+ {
+ public:
+ HashFunction* clone() const { return new SHA_160_X86_32; }
+
+ // Note 81 instead of normal 80: x86-32 asm needs an extra temp
+ SHA_160_X86_32() : SHA_160(81) {}
+ private:
+ void compress_n(const byte[], size_t blocks);
+ };
+
+}
+
+#endif
diff --git a/src/lib/hash/sha1_x86_32/sha1_x86_32_imp.S b/src/lib/hash/sha1_x86_32/sha1_x86_32_imp.S
new file mode 100644
index 000000000..775ef6854
--- /dev/null
+++ b/src/lib/hash/sha1_x86_32/sha1_x86_32_imp.S
@@ -0,0 +1,244 @@
+/*
+* SHA-1 in x86-32 asm
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/internal/asm_x86_32.h>
+
+START_LISTING(sha1_x86_32_imp.S)
+
+START_FUNCTION(botan_sha160_x86_32_compress)
+ SPILL_REGS()
+
+#define PUSHED 4
+
+ ASSIGN(EDI, ARG(2))
+ ASSIGN(EBP, ARG(3))
+
+ ZEROIZE(ESI)
+
+START_LOOP(.LOAD_INPUT)
+ ADD_IMM(ESI, 4)
+
+ ASSIGN(EAX, ARRAY4(EDI, 0))
+ ASSIGN(EBX, ARRAY4(EDI, 1))
+ ASSIGN(ECX, ARRAY4(EDI, 2))
+ ASSIGN(EDX, ARRAY4(EDI, 3))
+
+ ADD_IMM(EDI, 16)
+
+ BSWAP(EAX)
+ BSWAP(EBX)
+ BSWAP(ECX)
+ BSWAP(EDX)
+
+ ASSIGN(ARRAY4_INDIRECT(EBP,ESI,-4), EAX)
+ ASSIGN(ARRAY4_INDIRECT(EBP,ESI,-3), EBX)
+ ASSIGN(ARRAY4_INDIRECT(EBP,ESI,-2), ECX)
+ ASSIGN(ARRAY4_INDIRECT(EBP,ESI,-1), EDX)
+LOOP_UNTIL_EQ(ESI, 16, .LOAD_INPUT)
+
+ ADD2_IMM(EDI, EBP, 64)
+
+START_LOOP(.L_SHA_EXPANSION)
+ ADD_IMM(ESI, 4)
+
+ ZEROIZE(EAX)
+ ASSIGN(EBX, ARRAY4(EDI, -1))
+ ASSIGN(ECX, ARRAY4(EDI, -2))
+ ASSIGN(EDX, ARRAY4(EDI, -3))
+
+ XOR(EAX, ARRAY4(EDI, -5))
+ XOR(EBX, ARRAY4(EDI, -6))
+ XOR(ECX, ARRAY4(EDI, -7))
+ XOR(EDX, ARRAY4(EDI, -8))
+
+ XOR(EAX, ARRAY4(EDI, -11))
+ XOR(EBX, ARRAY4(EDI, -12))
+ XOR(ECX, ARRAY4(EDI, -13))
+ XOR(EDX, ARRAY4(EDI, -14))
+
+ XOR(EAX, ARRAY4(EDI, -13))
+ XOR(EBX, ARRAY4(EDI, -14))
+ XOR(ECX, ARRAY4(EDI, -15))
+ XOR(EDX, ARRAY4(EDI, -16))
+
+ ROTL_IMM(EDX, 1)
+ ROTL_IMM(ECX, 1)
+ ROTL_IMM(EBX, 1)
+ XOR(EAX, EDX)
+ ROTL_IMM(EAX, 1)
+
+ ASSIGN(ARRAY4(EDI, 0), EDX)
+ ASSIGN(ARRAY4(EDI, 1), ECX)
+ ASSIGN(ARRAY4(EDI, 2), EBX)
+ ASSIGN(ARRAY4(EDI, 3), EAX)
+
+ ADD_IMM(EDI, 16)
+LOOP_UNTIL_EQ(ESI, 80, .L_SHA_EXPANSION)
+
+#define MAGIC1 0x5A827999
+#define MAGIC2 0x6ED9EBA1
+#define MAGIC3 0x8F1BBCDC
+#define MAGIC4 0xCA62C1D6
+
+#define MSG ESP
+#define T2 EBP
+
+#define F1(A, B, C, D, E, F, N) \
+ ASSIGN(T2, ARRAY4(MSG, N)) ; \
+ ASSIGN(A, F) ; \
+ ROTL_IMM(F, 5) ; \
+ ADD(F, E) ; \
+ ASSIGN(E, C) ; \
+ XOR(E, D) ; \
+ ADD3_IMM(F, T2, MAGIC1) ; \
+ AND(E, B) ; \
+ XOR(E, D) ; \
+ ROTR_IMM(B, 2) ; \
+ ADD(E, F) ;
+
+#define F2_4(A, B, C, D, E, F, N, MAGIC) \
+ ASSIGN(T2, ARRAY4(MSG, N)) ; \
+ ASSIGN(A, F) ; \
+ ROTL_IMM(F, 5) ; \
+ ADD(F, E) ; \
+ ASSIGN(E, B) ; \
+ XOR(E, C) ; \
+ ADD3_IMM(F, T2, MAGIC) ; \
+ XOR(E, D) ; \
+ ROTR_IMM(B, 2) ; \
+ ADD(E, F) ;
+
+#define F3(A, B, C, D, E, F, N) \
+ ASSIGN(T2, ARRAY4(MSG, N)) ; \
+ ASSIGN(A, F) ; \
+ ROTL_IMM(F, 5) ; \
+ ADD(F, E) ; \
+ ASSIGN(E, B) ; \
+ OR(E, C) ; \
+ AND(E, D) ; \
+ ADD3_IMM(F, T2, MAGIC3) ; \
+ ASSIGN(T2, B) ; \
+ AND(T2, C) ; \
+ OR(E, T2) ; \
+ ROTR_IMM(B, 2) ; \
+ ADD(E, F) ;
+
+#define F2(A, B, C, D, E, F, MSG) \
+ F2_4(A, B, C, D, E, F, MSG, MAGIC2)
+
+#define F4(A, B, C, D, E, F, MSG) \
+ F2_4(A, B, C, D, E, F, MSG, MAGIC4)
+
+ ASSIGN(EAX, ARG(1))
+ ASSIGN(EDI, ARRAY4(EAX, 0))
+ ASSIGN(EBX, ARRAY4(EAX, 1))
+ ASSIGN(ECX, ARRAY4(EAX, 2))
+ ASSIGN(EDX, ARRAY4(EAX, 3))
+ ASSIGN(ESI, ARRAY4(EAX, 4))
+
+ ASSIGN(ARRAY4(EBP, 80), ESP)
+ ASSIGN(ESP, EBP)
+
+ /* First Round */
+ F1(EAX, EBX, ECX, EDX, ESI, EDI, 0)
+ F1(EDI, EAX, EBX, ECX, EDX, ESI, 1)
+ F1(ESI, EDI, EAX, EBX, ECX, EDX, 2)
+ F1(EDX, ESI, EDI, EAX, EBX, ECX, 3)
+ F1(ECX, EDX, ESI, EDI, EAX, EBX, 4)
+ F1(EBX, ECX, EDX, ESI, EDI, EAX, 5)
+ F1(EAX, EBX, ECX, EDX, ESI, EDI, 6)
+ F1(EDI, EAX, EBX, ECX, EDX, ESI, 7)
+ F1(ESI, EDI, EAX, EBX, ECX, EDX, 8)
+ F1(EDX, ESI, EDI, EAX, EBX, ECX, 9)
+ F1(ECX, EDX, ESI, EDI, EAX, EBX, 10)
+ F1(EBX, ECX, EDX, ESI, EDI, EAX, 11)
+ F1(EAX, EBX, ECX, EDX, ESI, EDI, 12)
+ F1(EDI, EAX, EBX, ECX, EDX, ESI, 13)
+ F1(ESI, EDI, EAX, EBX, ECX, EDX, 14)
+ F1(EDX, ESI, EDI, EAX, EBX, ECX, 15)
+ F1(ECX, EDX, ESI, EDI, EAX, EBX, 16)
+ F1(EBX, ECX, EDX, ESI, EDI, EAX, 17)
+ F1(EAX, EBX, ECX, EDX, ESI, EDI, 18)
+ F1(EDI, EAX, EBX, ECX, EDX, ESI, 19)
+
+ /* Second Round */
+ F2(ESI, EDI, EAX, EBX, ECX, EDX, 20)
+ F2(EDX, ESI, EDI, EAX, EBX, ECX, 21)
+ F2(ECX, EDX, ESI, EDI, EAX, EBX, 22)
+ F2(EBX, ECX, EDX, ESI, EDI, EAX, 23)
+ F2(EAX, EBX, ECX, EDX, ESI, EDI, 24)
+ F2(EDI, EAX, EBX, ECX, EDX, ESI, 25)
+ F2(ESI, EDI, EAX, EBX, ECX, EDX, 26)
+ F2(EDX, ESI, EDI, EAX, EBX, ECX, 27)
+ F2(ECX, EDX, ESI, EDI, EAX, EBX, 28)
+ F2(EBX, ECX, EDX, ESI, EDI, EAX, 29)
+ F2(EAX, EBX, ECX, EDX, ESI, EDI, 30)
+ F2(EDI, EAX, EBX, ECX, EDX, ESI, 31)
+ F2(ESI, EDI, EAX, EBX, ECX, EDX, 32)
+ F2(EDX, ESI, EDI, EAX, EBX, ECX, 33)
+ F2(ECX, EDX, ESI, EDI, EAX, EBX, 34)
+ F2(EBX, ECX, EDX, ESI, EDI, EAX, 35)
+ F2(EAX, EBX, ECX, EDX, ESI, EDI, 36)
+ F2(EDI, EAX, EBX, ECX, EDX, ESI, 37)
+ F2(ESI, EDI, EAX, EBX, ECX, EDX, 38)
+ F2(EDX, ESI, EDI, EAX, EBX, ECX, 39)
+
+ /* Third Round */
+ F3(ECX, EDX, ESI, EDI, EAX, EBX, 40)
+ F3(EBX, ECX, EDX, ESI, EDI, EAX, 41)
+ F3(EAX, EBX, ECX, EDX, ESI, EDI, 42)
+ F3(EDI, EAX, EBX, ECX, EDX, ESI, 43)
+ F3(ESI, EDI, EAX, EBX, ECX, EDX, 44)
+ F3(EDX, ESI, EDI, EAX, EBX, ECX, 45)
+ F3(ECX, EDX, ESI, EDI, EAX, EBX, 46)
+ F3(EBX, ECX, EDX, ESI, EDI, EAX, 47)
+ F3(EAX, EBX, ECX, EDX, ESI, EDI, 48)
+ F3(EDI, EAX, EBX, ECX, EDX, ESI, 49)
+ F3(ESI, EDI, EAX, EBX, ECX, EDX, 50)
+ F3(EDX, ESI, EDI, EAX, EBX, ECX, 51)
+ F3(ECX, EDX, ESI, EDI, EAX, EBX, 52)
+ F3(EBX, ECX, EDX, ESI, EDI, EAX, 53)
+ F3(EAX, EBX, ECX, EDX, ESI, EDI, 54)
+ F3(EDI, EAX, EBX, ECX, EDX, ESI, 55)
+ F3(ESI, EDI, EAX, EBX, ECX, EDX, 56)
+ F3(EDX, ESI, EDI, EAX, EBX, ECX, 57)
+ F3(ECX, EDX, ESI, EDI, EAX, EBX, 58)
+ F3(EBX, ECX, EDX, ESI, EDI, EAX, 59)
+
+ /* Fourth Round */
+ F4(EAX, EBX, ECX, EDX, ESI, EDI, 60)
+ F4(EDI, EAX, EBX, ECX, EDX, ESI, 61)
+ F4(ESI, EDI, EAX, EBX, ECX, EDX, 62)
+ F4(EDX, ESI, EDI, EAX, EBX, ECX, 63)
+ F4(ECX, EDX, ESI, EDI, EAX, EBX, 64)
+ F4(EBX, ECX, EDX, ESI, EDI, EAX, 65)
+ F4(EAX, EBX, ECX, EDX, ESI, EDI, 66)
+ F4(EDI, EAX, EBX, ECX, EDX, ESI, 67)
+ F4(ESI, EDI, EAX, EBX, ECX, EDX, 68)
+ F4(EDX, ESI, EDI, EAX, EBX, ECX, 69)
+ F4(ECX, EDX, ESI, EDI, EAX, EBX, 70)
+ F4(EBX, ECX, EDX, ESI, EDI, EAX, 71)
+ F4(EAX, EBX, ECX, EDX, ESI, EDI, 72)
+ F4(EDI, EAX, EBX, ECX, EDX, ESI, 73)
+ F4(ESI, EDI, EAX, EBX, ECX, EDX, 74)
+ F4(EDX, ESI, EDI, EAX, EBX, ECX, 75)
+ F4(ECX, EDX, ESI, EDI, EAX, EBX, 76)
+ F4(EBX, ECX, EDX, ESI, EDI, EAX, 77)
+ F4(EAX, EBX, ECX, EDX, ESI, EDI, 78)
+ F4(EDI, EAX, EBX, ECX, EDX, ESI, 79)
+
+ ASSIGN(ESP, ARRAY4(ESP, 80))
+
+ ASSIGN(EBP, ARG(1))
+ ADD(ARRAY4(EBP, 0), EDX)
+ ADD(ARRAY4(EBP, 1), EDI)
+ ADD(ARRAY4(EBP, 2), EAX)
+ ADD(ARRAY4(EBP, 3), EBX)
+ ADD(ARRAY4(EBP, 4), ECX)
+
+ RESTORE_REGS()
+END_FUNCTION(botan_sha160_x86_32_compress)
diff --git a/src/lib/hash/sha1_x86_64/info.txt b/src/lib/hash/sha1_x86_64/info.txt
new file mode 100644
index 000000000..54d5eefff
--- /dev/null
+++ b/src/lib/hash/sha1_x86_64/info.txt
@@ -0,0 +1,13 @@
+define SHA1_X86_64 20131128
+
+load_on asm_ok
+
+<arch>
+x86_64
+</arch>
+
+<requires>
+asm_engine
+asm_x86_64
+sha1
+</requires>
diff --git a/src/lib/hash/sha1_x86_64/sha1_x86_64.cpp b/src/lib/hash/sha1_x86_64/sha1_x86_64.cpp
new file mode 100644
index 000000000..a3e92e313
--- /dev/null
+++ b/src/lib/hash/sha1_x86_64/sha1_x86_64.cpp
@@ -0,0 +1,31 @@
+/*
+* SHA-160
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/sha1_x86_64.h>
+
+namespace Botan {
+
+namespace {
+
+extern "C"
+void botan_sha160_x86_64_compress(u32bit[5], const byte[64], u32bit[80]);
+
+}
+
+/*
+* SHA-160 Compression Function
+*/
+void SHA_160_X86_64::compress_n(const byte input[], size_t blocks)
+ {
+ for(size_t i = 0; i != blocks; ++i)
+ {
+ botan_sha160_x86_64_compress(&digest[0], input, &W[0]);
+ input += hash_block_size();
+ }
+ }
+
+}
diff --git a/src/lib/hash/sha1_x86_64/sha1_x86_64.h b/src/lib/hash/sha1_x86_64/sha1_x86_64.h
new file mode 100644
index 000000000..068a94595
--- /dev/null
+++ b/src/lib/hash/sha1_x86_64/sha1_x86_64.h
@@ -0,0 +1,28 @@
+/*
+* SHA-160 (x86-64)
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_SHA_160_X86_64_H__
+#define BOTAN_SHA_160_X86_64_H__
+
+#include <botan/sha160.h>
+
+namespace Botan {
+
+/**
+* SHA-160 in x86-64 assembly
+*/
+class BOTAN_DLL SHA_160_X86_64 : public SHA_160
+ {
+ public:
+ HashFunction* clone() const { return new SHA_160_X86_64; }
+ private:
+ void compress_n(const byte[], size_t blocks);
+ };
+
+}
+
+#endif
diff --git a/src/lib/hash/sha1_x86_64/sha1_x86_64_imp.S b/src/lib/hash/sha1_x86_64/sha1_x86_64_imp.S
new file mode 100644
index 000000000..ee35f0d85
--- /dev/null
+++ b/src/lib/hash/sha1_x86_64/sha1_x86_64_imp.S
@@ -0,0 +1,266 @@
+/*
+* SHA-1 in x86-64 assembler
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/internal/asm_x86_64.h>
+
+START_LISTING(sha1_x86_64_imp.S)
+
+START_FUNCTION(botan_sha160_x86_64_compress)
+
+#define DIGEST_ARR %rdi
+#define INPUT %rsi
+#define W %rdx
+#define LOOP_CTR %eax
+
+#define A %r8d
+#define B %r9d
+#define C %r10d
+#define D %r11d
+#define E %ecx
+
+ ZEROIZE(LOOP_CTR)
+
+ALIGN;
+.LOOP_LOAD_INPUT:
+ addl $8, %eax
+
+ movq ARRAY8(INPUT, 0), %r8
+ movq ARRAY8(INPUT, 1), %r9
+ movq ARRAY8(INPUT, 2), %r10
+ movq ARRAY8(INPUT, 3), %r11
+
+ bswap %r8
+ bswap %r9
+ bswap %r10
+ bswap %r11
+
+ rolq $32, %r8
+ rolq $32, %r9
+ rolq $32, %r10
+ rolq $32, %r11
+
+ movq %r8, ARRAY8(W, 0)
+ movq %r9, ARRAY8(W, 1)
+ movq %r10, ARRAY8(W, 2)
+ movq %r11, ARRAY8(W, 3)
+
+ addq $32, W
+ addq $32, INPUT
+
+ cmp IMM(16), LOOP_CTR
+ jne .LOOP_LOAD_INPUT
+
+/*
+#define A %r8d
+#define B %r9d
+#define C %r10d
+#define D %r11d
+#define E %ecx
+*/
+
+ALIGN;
+.LOOP_EXPANSION:
+ addl $4, LOOP_CTR
+
+ ZEROIZE(A)
+ ASSIGN(B, ARRAY4(W, -1))
+ ASSIGN(C, ARRAY4(W, -2))
+ ASSIGN(D, ARRAY4(W, -3))
+
+ XOR(A, ARRAY4(W, -5))
+ XOR(B, ARRAY4(W, -6))
+ XOR(C, ARRAY4(W, -7))
+ XOR(D, ARRAY4(W, -8))
+
+ XOR(A, ARRAY4(W, -11))
+ XOR(B, ARRAY4(W, -12))
+ XOR(C, ARRAY4(W, -13))
+ XOR(D, ARRAY4(W, -14))
+
+ XOR(A, ARRAY4(W, -13))
+ XOR(B, ARRAY4(W, -14))
+ XOR(C, ARRAY4(W, -15))
+ XOR(D, ARRAY4(W, -16))
+
+ ROTL_IMM(D, 1)
+ ROTL_IMM(C, 1)
+ ROTL_IMM(B, 1)
+ XOR(A, D)
+ ROTL_IMM(A, 1)
+
+ ASSIGN(ARRAY4(W, 0), D)
+ ASSIGN(ARRAY4(W, 1), C)
+ ASSIGN(ARRAY4(W, 2), B)
+ ASSIGN(ARRAY4(W, 3), A)
+
+ addq $16, W
+ cmp IMM(80), LOOP_CTR
+ jne .LOOP_EXPANSION
+
+ subq $320, W
+
+/*
+* Using negative values for SHA-1 constants > 2^31 to work around
+* a bug in binutils not accepting large lea displacements.
+* -0x70E44324 == 0x8F1BBCDC
+* -0x359D3E2A == 0xCA62C1D6
+*/
+#define MAGIC1 0x5A827999
+#define MAGIC2 0x6ED9EBA1
+#define MAGIC3 -0x70E44324
+#define MAGIC4 -0x359D3E2A
+
+#define T %esi
+#define T2 %eax
+
+#define F1(A, B, C, D, E, F, N) \
+ ASSIGN(T2, ARRAY4(W, N)) ; \
+ ASSIGN(A, F) ; \
+ ROTL_IMM(F, 5) ; \
+ ADD(F, E) ; \
+ ASSIGN(E, C) ; \
+ XOR(E, D) ; \
+ ADD3_IMM(F, T2, MAGIC1) ; \
+ AND(E, B) ; \
+ XOR(E, D) ; \
+ ROTR_IMM(B, 2) ; \
+ ADD(E, F) ;
+
+#define F2_4(A, B, C, D, E, F, N, MAGIC) \
+ ASSIGN(T2, ARRAY4(W, N)) ; \
+ ASSIGN(A, F) ; \
+ ROTL_IMM(F, 5) ; \
+ ADD(F, E) ; \
+ ASSIGN(E, B) ; \
+ XOR(E, C) ; \
+ ADD3_IMM(F, T2, MAGIC) ; \
+ XOR(E, D) ; \
+ ROTR_IMM(B, 2) ; \
+ ADD(E, F) ;
+
+#define F3(A, B, C, D, E, F, N) \
+ ASSIGN(T2, ARRAY4(W, N)) ; \
+ ASSIGN(A, F) ; \
+ ROTL_IMM(F, 5) ; \
+ ADD(F, E) ; \
+ ASSIGN(E, B) ; \
+ OR(E, C) ; \
+ AND(E, D) ; \
+ ADD3_IMM(F, T2, MAGIC3) ; \
+ ASSIGN(T2, B) ; \
+ AND(T2, C) ; \
+ OR(E, T2) ; \
+ ROTR_IMM(B, 2) ; \
+ ADD(E, F) ;
+
+#define F2(A, B, C, D, E, F, W) \
+ F2_4(A, B, C, D, E, F, W, MAGIC2)
+
+#define F4(A, B, C, D, E, F, W) \
+ F2_4(A, B, C, D, E, F, W, MAGIC4)
+
+ ASSIGN(T, ARRAY4(DIGEST_ARR, 0))
+ ASSIGN(B, ARRAY4(DIGEST_ARR, 1))
+ ASSIGN(C, ARRAY4(DIGEST_ARR, 2))
+ ASSIGN(D, ARRAY4(DIGEST_ARR, 3))
+ ASSIGN(E, ARRAY4(DIGEST_ARR, 4))
+
+ /* First Round */
+ F1(A, B, C, D, E, T, 0)
+ F1(T, A, B, C, D, E, 1)
+ F1(E, T, A, B, C, D, 2)
+ F1(D, E, T, A, B, C, 3)
+ F1(C, D, E, T, A, B, 4)
+ F1(B, C, D, E, T, A, 5)
+ F1(A, B, C, D, E, T, 6)
+ F1(T, A, B, C, D, E, 7)
+ F1(E, T, A, B, C, D, 8)
+ F1(D, E, T, A, B, C, 9)
+ F1(C, D, E, T, A, B, 10)
+ F1(B, C, D, E, T, A, 11)
+ F1(A, B, C, D, E, T, 12)
+ F1(T, A, B, C, D, E, 13)
+ F1(E, T, A, B, C, D, 14)
+ F1(D, E, T, A, B, C, 15)
+ F1(C, D, E, T, A, B, 16)
+ F1(B, C, D, E, T, A, 17)
+ F1(A, B, C, D, E, T, 18)
+ F1(T, A, B, C, D, E, 19)
+
+ /* Second Round */
+ F2(E, T, A, B, C, D, 20)
+ F2(D, E, T, A, B, C, 21)
+ F2(C, D, E, T, A, B, 22)
+ F2(B, C, D, E, T, A, 23)
+ F2(A, B, C, D, E, T, 24)
+ F2(T, A, B, C, D, E, 25)
+ F2(E, T, A, B, C, D, 26)
+ F2(D, E, T, A, B, C, 27)
+ F2(C, D, E, T, A, B, 28)
+ F2(B, C, D, E, T, A, 29)
+ F2(A, B, C, D, E, T, 30)
+ F2(T, A, B, C, D, E, 31)
+ F2(E, T, A, B, C, D, 32)
+ F2(D, E, T, A, B, C, 33)
+ F2(C, D, E, T, A, B, 34)
+ F2(B, C, D, E, T, A, 35)
+ F2(A, B, C, D, E, T, 36)
+ F2(T, A, B, C, D, E, 37)
+ F2(E, T, A, B, C, D, 38)
+ F2(D, E, T, A, B, C, 39)
+
+ /* Third Round */
+ F3(C, D, E, T, A, B, 40)
+ F3(B, C, D, E, T, A, 41)
+ F3(A, B, C, D, E, T, 42)
+ F3(T, A, B, C, D, E, 43)
+ F3(E, T, A, B, C, D, 44)
+ F3(D, E, T, A, B, C, 45)
+ F3(C, D, E, T, A, B, 46)
+ F3(B, C, D, E, T, A, 47)
+ F3(A, B, C, D, E, T, 48)
+ F3(T, A, B, C, D, E, 49)
+ F3(E, T, A, B, C, D, 50)
+ F3(D, E, T, A, B, C, 51)
+ F3(C, D, E, T, A, B, 52)
+ F3(B, C, D, E, T, A, 53)
+ F3(A, B, C, D, E, T, 54)
+ F3(T, A, B, C, D, E, 55)
+ F3(E, T, A, B, C, D, 56)
+ F3(D, E, T, A, B, C, 57)
+ F3(C, D, E, T, A, B, 58)
+ F3(B, C, D, E, T, A, 59)
+
+ /* Fourth Round */
+ F4(A, B, C, D, E, T, 60)
+ F4(T, A, B, C, D, E, 61)
+ F4(E, T, A, B, C, D, 62)
+ F4(D, E, T, A, B, C, 63)
+ F4(C, D, E, T, A, B, 64)
+ F4(B, C, D, E, T, A, 65)
+ F4(A, B, C, D, E, T, 66)
+ F4(T, A, B, C, D, E, 67)
+ F4(E, T, A, B, C, D, 68)
+ F4(D, E, T, A, B, C, 69)
+ F4(C, D, E, T, A, B, 70)
+ F4(B, C, D, E, T, A, 71)
+ F4(A, B, C, D, E, T, 72)
+ F4(T, A, B, C, D, E, 73)
+ F4(E, T, A, B, C, D, 74)
+ F4(D, E, T, A, B, C, 75)
+ F4(C, D, E, T, A, B, 76)
+ F4(B, C, D, E, T, A, 77)
+ F4(A, B, C, D, E, T, 78)
+ F4(T, A, B, C, D, E, 79)
+
+ ADD(ARRAY4(DIGEST_ARR, 0), D)
+ ADD(ARRAY4(DIGEST_ARR, 1), T)
+ ADD(ARRAY4(DIGEST_ARR, 2), A)
+ ADD(ARRAY4(DIGEST_ARR, 3), B)
+ ADD(ARRAY4(DIGEST_ARR, 4), C)
+
+END_FUNCTION(botan_sha160_x86_64_compress)
diff --git a/src/lib/hash/sha2_32/info.txt b/src/lib/hash/sha2_32/info.txt
new file mode 100644
index 000000000..b15db2ede
--- /dev/null
+++ b/src/lib/hash/sha2_32/info.txt
@@ -0,0 +1,5 @@
+define SHA2_32 20131128
+
+<requires>
+mdx_hash
+</requires>
diff --git a/src/lib/hash/sha2_32/sha2_32.cpp b/src/lib/hash/sha2_32/sha2_32.cpp
new file mode 100644
index 000000000..cffc8bd2a
--- /dev/null
+++ b/src/lib/hash/sha2_32/sha2_32.cpp
@@ -0,0 +1,227 @@
+/*
+* SHA-{224,256}
+* (C) 1999-2010 Jack Lloyd
+* 2007 FlexSecure GmbH
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/sha2_32.h>
+#include <botan/loadstor.h>
+#include <botan/rotate.h>
+
+namespace Botan {
+
+namespace {
+
+namespace SHA2_32 {
+
+/*
+* SHA-256 Rho Function
+*/
+inline u32bit rho(u32bit X, u32bit rot1, u32bit rot2, u32bit rot3)
+ {
+ return (rotate_right(X, rot1) ^ rotate_right(X, rot2) ^
+ rotate_right(X, rot3));
+ }
+
+/*
+* SHA-256 Sigma Function
+*/
+inline u32bit sigma(u32bit X, u32bit rot1, u32bit rot2, u32bit shift)
+ {
+ return (rotate_right(X, rot1) ^ rotate_right(X, rot2) ^ (X >> shift));
+ }
+
+/*
+* SHA-256 F1 Function
+*
+* Use a macro as many compilers won't inline a function this big,
+* even though it is much faster if inlined.
+*/
+#define SHA2_32_F(A, B, C, D, E, F, G, H, M1, M2, M3, M4, magic) \
+ do { \
+ H += magic + rho(E, 6, 11, 25) + ((E & F) ^ (~E & G)) + M1; \
+ D += H; \
+ H += rho(A, 2, 13, 22) + ((A & B) | ((A | B) & C)); \
+ M1 += sigma(M2, 17, 19, 10) + M3 + sigma(M4, 7, 18, 3); \
+ } while(0);
+
+/*
+* SHA-224 / SHA-256 compression function
+*/
+void compress(secure_vector<u32bit>& digest,
+ const byte input[], size_t blocks)
+ {
+ u32bit A = digest[0], B = digest[1], C = digest[2],
+ D = digest[3], E = digest[4], F = digest[5],
+ G = digest[6], H = digest[7];
+
+ for(size_t i = 0; i != blocks; ++i)
+ {
+ u32bit W00 = load_be<u32bit>(input, 0);
+ u32bit W01 = load_be<u32bit>(input, 1);
+ u32bit W02 = load_be<u32bit>(input, 2);
+ u32bit W03 = load_be<u32bit>(input, 3);
+ u32bit W04 = load_be<u32bit>(input, 4);
+ u32bit W05 = load_be<u32bit>(input, 5);
+ u32bit W06 = load_be<u32bit>(input, 6);
+ u32bit W07 = load_be<u32bit>(input, 7);
+ u32bit W08 = load_be<u32bit>(input, 8);
+ u32bit W09 = load_be<u32bit>(input, 9);
+ u32bit W10 = load_be<u32bit>(input, 10);
+ u32bit W11 = load_be<u32bit>(input, 11);
+ u32bit W12 = load_be<u32bit>(input, 12);
+ u32bit W13 = load_be<u32bit>(input, 13);
+ u32bit W14 = load_be<u32bit>(input, 14);
+ u32bit W15 = load_be<u32bit>(input, 15);
+
+ SHA2_32_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x428A2F98);
+ SHA2_32_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x71374491);
+ SHA2_32_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0xB5C0FBCF);
+ SHA2_32_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0xE9B5DBA5);
+ SHA2_32_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x3956C25B);
+ SHA2_32_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x59F111F1);
+ SHA2_32_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x923F82A4);
+ SHA2_32_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0xAB1C5ED5);
+ SHA2_32_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0xD807AA98);
+ SHA2_32_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x12835B01);
+ SHA2_32_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x243185BE);
+ SHA2_32_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x550C7DC3);
+ SHA2_32_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x72BE5D74);
+ SHA2_32_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0x80DEB1FE);
+ SHA2_32_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x9BDC06A7);
+ SHA2_32_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0xC19BF174);
+ SHA2_32_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0xE49B69C1);
+ SHA2_32_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0xEFBE4786);
+ SHA2_32_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x0FC19DC6);
+ SHA2_32_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x240CA1CC);
+ SHA2_32_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x2DE92C6F);
+ SHA2_32_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x4A7484AA);
+ SHA2_32_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x5CB0A9DC);
+ SHA2_32_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x76F988DA);
+ SHA2_32_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x983E5152);
+ SHA2_32_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0xA831C66D);
+ SHA2_32_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0xB00327C8);
+ SHA2_32_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0xBF597FC7);
+ SHA2_32_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0xC6E00BF3);
+ SHA2_32_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xD5A79147);
+ SHA2_32_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x06CA6351);
+ SHA2_32_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x14292967);
+ SHA2_32_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x27B70A85);
+ SHA2_32_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x2E1B2138);
+ SHA2_32_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x4D2C6DFC);
+ SHA2_32_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x53380D13);
+ SHA2_32_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x650A7354);
+ SHA2_32_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x766A0ABB);
+ SHA2_32_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x81C2C92E);
+ SHA2_32_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x92722C85);
+ SHA2_32_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0xA2BFE8A1);
+ SHA2_32_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0xA81A664B);
+ SHA2_32_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0xC24B8B70);
+ SHA2_32_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0xC76C51A3);
+ SHA2_32_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0xD192E819);
+ SHA2_32_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xD6990624);
+ SHA2_32_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0xF40E3585);
+ SHA2_32_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x106AA070);
+ SHA2_32_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x19A4C116);
+ SHA2_32_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x1E376C08);
+ SHA2_32_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x2748774C);
+ SHA2_32_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x34B0BCB5);
+ SHA2_32_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x391C0CB3);
+ SHA2_32_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x4ED8AA4A);
+ SHA2_32_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x5B9CCA4F);
+ SHA2_32_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x682E6FF3);
+ SHA2_32_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x748F82EE);
+ SHA2_32_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x78A5636F);
+ SHA2_32_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x84C87814);
+ SHA2_32_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x8CC70208);
+ SHA2_32_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x90BEFFFA);
+ SHA2_32_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xA4506CEB);
+ SHA2_32_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0xBEF9A3F7);
+ SHA2_32_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0xC67178F2);
+
+ A = (digest[0] += A);
+ B = (digest[1] += B);
+ C = (digest[2] += C);
+ D = (digest[3] += D);
+ E = (digest[4] += E);
+ F = (digest[5] += F);
+ G = (digest[6] += G);
+ H = (digest[7] += H);
+
+ input += 64;
+ }
+ }
+
+}
+
+}
+
+/*
+* SHA-224 compression function
+*/
+void SHA_224::compress_n(const byte input[], size_t blocks)
+ {
+ SHA2_32::compress(digest, input, blocks);
+ }
+
+/*
+* Copy out the digest
+*/
+void SHA_224::copy_out(byte output[])
+ {
+ for(size_t i = 0; i != output_length(); i += 4)
+ store_be(digest[i/4], output + i);
+ }
+
+/*
+* Clear memory of sensitive data
+*/
+void SHA_224::clear()
+ {
+ MDx_HashFunction::clear();
+ digest[0] = 0xC1059ED8;
+ digest[1] = 0x367CD507;
+ digest[2] = 0x3070DD17;
+ digest[3] = 0xF70E5939;
+ digest[4] = 0xFFC00B31;
+ digest[5] = 0x68581511;
+ digest[6] = 0x64F98FA7;
+ digest[7] = 0xBEFA4FA4;
+ }
+
+/*
+* SHA-256 compression function
+*/
+void SHA_256::compress_n(const byte input[], size_t blocks)
+ {
+ SHA2_32::compress(digest, input, blocks);
+ }
+
+/*
+* Copy out the digest
+*/
+void SHA_256::copy_out(byte output[])
+ {
+ for(size_t i = 0; i != output_length(); i += 4)
+ store_be(digest[i/4], output + i);
+ }
+
+/*
+* Clear memory of sensitive data
+*/
+void SHA_256::clear()
+ {
+ MDx_HashFunction::clear();
+ digest[0] = 0x6A09E667;
+ digest[1] = 0xBB67AE85;
+ digest[2] = 0x3C6EF372;
+ digest[3] = 0xA54FF53A;
+ digest[4] = 0x510E527F;
+ digest[5] = 0x9B05688C;
+ digest[6] = 0x1F83D9AB;
+ digest[7] = 0x5BE0CD19;
+ }
+
+}
diff --git a/src/lib/hash/sha2_32/sha2_32.h b/src/lib/hash/sha2_32/sha2_32.h
new file mode 100644
index 000000000..ccb8e07f2
--- /dev/null
+++ b/src/lib/hash/sha2_32/sha2_32.h
@@ -0,0 +1,60 @@
+/*
+* SHA-{224,256}
+* (C) 1999-2011 Jack Lloyd
+* 2007 FlexSecure GmbH
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_SHA_224_256_H__
+#define BOTAN_SHA_224_256_H__
+
+#include <botan/mdx_hash.h>
+
+namespace Botan {
+
+/**
+* SHA-224
+*/
+class BOTAN_DLL SHA_224 : public MDx_HashFunction
+ {
+ public:
+ std::string name() const { return "SHA-224"; }
+ size_t output_length() const { return 28; }
+ HashFunction* clone() const { return new SHA_224; }
+
+ void clear();
+
+ SHA_224() : MDx_HashFunction(64, true, true), digest(8)
+ { clear(); }
+ private:
+ void compress_n(const byte[], size_t blocks);
+ void copy_out(byte[]);
+
+ secure_vector<u32bit> digest;
+ };
+
+/**
+* SHA-256
+*/
+class BOTAN_DLL SHA_256 : public MDx_HashFunction
+ {
+ public:
+ std::string name() const { return "SHA-256"; }
+ size_t output_length() const { return 32; }
+ HashFunction* clone() const { return new SHA_256; }
+
+ void clear();
+
+ SHA_256() : MDx_HashFunction(64, true, true), digest(8)
+ { clear(); }
+ private:
+ void compress_n(const byte[], size_t blocks);
+ void copy_out(byte[]);
+
+ secure_vector<u32bit> digest;
+ };
+
+}
+
+#endif
diff --git a/src/lib/hash/sha2_64/info.txt b/src/lib/hash/sha2_64/info.txt
new file mode 100644
index 000000000..a457dffec
--- /dev/null
+++ b/src/lib/hash/sha2_64/info.txt
@@ -0,0 +1,5 @@
+define SHA2_64 20131128
+
+<requires>
+mdx_hash
+</requires>
diff --git a/src/lib/hash/sha2_64/sha2_64.cpp b/src/lib/hash/sha2_64/sha2_64.cpp
new file mode 100644
index 000000000..8dcb4684e
--- /dev/null
+++ b/src/lib/hash/sha2_64/sha2_64.cpp
@@ -0,0 +1,242 @@
+/*
+* SHA-{384,512}
+* (C) 1999-2011 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/sha2_64.h>
+#include <botan/loadstor.h>
+#include <botan/rotate.h>
+
+namespace Botan {
+
+namespace {
+
+namespace SHA2_64 {
+
+/*
+* SHA-{384,512} Rho Function
+*/
+inline u64bit rho(u64bit X, u32bit rot1, u32bit rot2, u32bit rot3)
+ {
+ return (rotate_right(X, rot1) ^ rotate_right(X, rot2) ^
+ rotate_right(X, rot3));
+ }
+
+/*
+* SHA-{384,512} Sigma Function
+*/
+inline u64bit sigma(u64bit X, u32bit rot1, u32bit rot2, u32bit shift)
+ {
+ return (rotate_right(X, rot1) ^ rotate_right(X, rot2) ^ (X >> shift));
+ }
+
+/*
+* SHA-512 F1 Function
+*
+* Use a macro as many compilers won't inline a function this big,
+* even though it is much faster if inlined.
+*/
+#define SHA2_64_F(A, B, C, D, E, F, G, H, M1, M2, M3, M4, magic) \
+ do { \
+ H += magic + rho(E, 14, 18, 41) + ((E & F) ^ (~E & G)) + M1; \
+ D += H; \
+ H += rho(A, 28, 34, 39) + ((A & B) | ((A | B) & C)); \
+ M1 += sigma(M2, 19, 61, 6) + M3 + sigma(M4, 1, 8, 7); \
+ } while(0);
+
+/*
+* SHA-{384,512} Compression Function
+*/
+void compress(secure_vector<u64bit>& digest,
+ const byte input[], size_t blocks)
+ {
+ u64bit A = digest[0], B = digest[1], C = digest[2],
+ D = digest[3], E = digest[4], F = digest[5],
+ G = digest[6], H = digest[7];
+
+ for(size_t i = 0; i != blocks; ++i)
+ {
+ u64bit W00 = load_be<u64bit>(input, 0);
+ u64bit W01 = load_be<u64bit>(input, 1);
+ u64bit W02 = load_be<u64bit>(input, 2);
+ u64bit W03 = load_be<u64bit>(input, 3);
+ u64bit W04 = load_be<u64bit>(input, 4);
+ u64bit W05 = load_be<u64bit>(input, 5);
+ u64bit W06 = load_be<u64bit>(input, 6);
+ u64bit W07 = load_be<u64bit>(input, 7);
+ u64bit W08 = load_be<u64bit>(input, 8);
+ u64bit W09 = load_be<u64bit>(input, 9);
+ u64bit W10 = load_be<u64bit>(input, 10);
+ u64bit W11 = load_be<u64bit>(input, 11);
+ u64bit W12 = load_be<u64bit>(input, 12);
+ u64bit W13 = load_be<u64bit>(input, 13);
+ u64bit W14 = load_be<u64bit>(input, 14);
+ u64bit W15 = load_be<u64bit>(input, 15);
+
+ SHA2_64_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x428A2F98D728AE22);
+ SHA2_64_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x7137449123EF65CD);
+ SHA2_64_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0xB5C0FBCFEC4D3B2F);
+ SHA2_64_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0xE9B5DBA58189DBBC);
+ SHA2_64_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x3956C25BF348B538);
+ SHA2_64_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x59F111F1B605D019);
+ SHA2_64_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x923F82A4AF194F9B);
+ SHA2_64_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0xAB1C5ED5DA6D8118);
+ SHA2_64_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0xD807AA98A3030242);
+ SHA2_64_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x12835B0145706FBE);
+ SHA2_64_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x243185BE4EE4B28C);
+ SHA2_64_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x550C7DC3D5FFB4E2);
+ SHA2_64_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x72BE5D74F27B896F);
+ SHA2_64_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0x80DEB1FE3B1696B1);
+ SHA2_64_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x9BDC06A725C71235);
+ SHA2_64_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0xC19BF174CF692694);
+ SHA2_64_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0xE49B69C19EF14AD2);
+ SHA2_64_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0xEFBE4786384F25E3);
+ SHA2_64_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x0FC19DC68B8CD5B5);
+ SHA2_64_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x240CA1CC77AC9C65);
+ SHA2_64_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x2DE92C6F592B0275);
+ SHA2_64_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x4A7484AA6EA6E483);
+ SHA2_64_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x5CB0A9DCBD41FBD4);
+ SHA2_64_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x76F988DA831153B5);
+ SHA2_64_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x983E5152EE66DFAB);
+ SHA2_64_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0xA831C66D2DB43210);
+ SHA2_64_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0xB00327C898FB213F);
+ SHA2_64_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0xBF597FC7BEEF0EE4);
+ SHA2_64_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0xC6E00BF33DA88FC2);
+ SHA2_64_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xD5A79147930AA725);
+ SHA2_64_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x06CA6351E003826F);
+ SHA2_64_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x142929670A0E6E70);
+ SHA2_64_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x27B70A8546D22FFC);
+ SHA2_64_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x2E1B21385C26C926);
+ SHA2_64_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x4D2C6DFC5AC42AED);
+ SHA2_64_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x53380D139D95B3DF);
+ SHA2_64_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x650A73548BAF63DE);
+ SHA2_64_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x766A0ABB3C77B2A8);
+ SHA2_64_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x81C2C92E47EDAEE6);
+ SHA2_64_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x92722C851482353B);
+ SHA2_64_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0xA2BFE8A14CF10364);
+ SHA2_64_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0xA81A664BBC423001);
+ SHA2_64_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0xC24B8B70D0F89791);
+ SHA2_64_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0xC76C51A30654BE30);
+ SHA2_64_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0xD192E819D6EF5218);
+ SHA2_64_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xD69906245565A910);
+ SHA2_64_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0xF40E35855771202A);
+ SHA2_64_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x106AA07032BBD1B8);
+ SHA2_64_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x19A4C116B8D2D0C8);
+ SHA2_64_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x1E376C085141AB53);
+ SHA2_64_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x2748774CDF8EEB99);
+ SHA2_64_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x34B0BCB5E19B48A8);
+ SHA2_64_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x391C0CB3C5C95A63);
+ SHA2_64_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x4ED8AA4AE3418ACB);
+ SHA2_64_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x5B9CCA4F7763E373);
+ SHA2_64_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x682E6FF3D6B2B8A3);
+ SHA2_64_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x748F82EE5DEFB2FC);
+ SHA2_64_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x78A5636F43172F60);
+ SHA2_64_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x84C87814A1F0AB72);
+ SHA2_64_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x8CC702081A6439EC);
+ SHA2_64_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x90BEFFFA23631E28);
+ SHA2_64_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xA4506CEBDE82BDE9);
+ SHA2_64_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0xBEF9A3F7B2C67915);
+ SHA2_64_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0xC67178F2E372532B);
+ SHA2_64_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0xCA273ECEEA26619C);
+ SHA2_64_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0xD186B8C721C0C207);
+ SHA2_64_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0xEADA7DD6CDE0EB1E);
+ SHA2_64_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0xF57D4F7FEE6ED178);
+ SHA2_64_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x06F067AA72176FBA);
+ SHA2_64_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x0A637DC5A2C898A6);
+ SHA2_64_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x113F9804BEF90DAE);
+ SHA2_64_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x1B710B35131C471B);
+ SHA2_64_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x28DB77F523047D84);
+ SHA2_64_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x32CAAB7B40C72493);
+ SHA2_64_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x3C9EBE0A15C9BEBC);
+ SHA2_64_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x431D67C49C100D4C);
+ SHA2_64_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x4CC5D4BECB3E42B6);
+ SHA2_64_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0x597F299CFC657E2A);
+ SHA2_64_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x5FCB6FAB3AD6FAEC);
+ SHA2_64_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x6C44198C4A475817);
+
+ A = (digest[0] += A);
+ B = (digest[1] += B);
+ C = (digest[2] += C);
+ D = (digest[3] += D);
+ E = (digest[4] += E);
+ F = (digest[5] += F);
+ G = (digest[6] += G);
+ H = (digest[7] += H);
+
+ input += 128;
+ }
+ }
+
+}
+
+}
+
+/*
+* SHA-384 compression function
+*/
+void SHA_384::compress_n(const byte input[], size_t blocks)
+ {
+ SHA2_64::compress(digest, input, blocks);
+ }
+
+/*
+* Copy out the digest
+*/
+void SHA_384::copy_out(byte output[])
+ {
+ for(size_t i = 0; i != output_length(); i += 8)
+ store_be(digest[i/8], output + i);
+ }
+
+/*
+* Clear memory of sensitive data
+*/
+void SHA_384::clear()
+ {
+ MDx_HashFunction::clear();
+ digest[0] = 0xCBBB9D5DC1059ED8;
+ digest[1] = 0x629A292A367CD507;
+ digest[2] = 0x9159015A3070DD17;
+ digest[3] = 0x152FECD8F70E5939;
+ digest[4] = 0x67332667FFC00B31;
+ digest[5] = 0x8EB44A8768581511;
+ digest[6] = 0xDB0C2E0D64F98FA7;
+ digest[7] = 0x47B5481DBEFA4FA4;
+ }
+
+/*
+* SHA-512 compression function
+*/
+void SHA_512::compress_n(const byte input[], size_t blocks)
+ {
+ SHA2_64::compress(digest, input, blocks);
+ }
+
+/*
+* Copy out the digest
+*/
+void SHA_512::copy_out(byte output[])
+ {
+ for(size_t i = 0; i != output_length(); i += 8)
+ store_be(digest[i/8], output + i);
+ }
+
+/*
+* Clear memory of sensitive data
+*/
+void SHA_512::clear()
+ {
+ MDx_HashFunction::clear();
+ digest[0] = 0x6A09E667F3BCC908;
+ digest[1] = 0xBB67AE8584CAA73B;
+ digest[2] = 0x3C6EF372FE94F82B;
+ digest[3] = 0xA54FF53A5F1D36F1;
+ digest[4] = 0x510E527FADE682D1;
+ digest[5] = 0x9B05688C2B3E6C1F;
+ digest[6] = 0x1F83D9ABFB41BD6B;
+ digest[7] = 0x5BE0CD19137E2179;
+ }
+
+}
diff --git a/src/lib/hash/sha2_64/sha2_64.h b/src/lib/hash/sha2_64/sha2_64.h
new file mode 100644
index 000000000..58b154170
--- /dev/null
+++ b/src/lib/hash/sha2_64/sha2_64.h
@@ -0,0 +1,59 @@
+/*
+* SHA-{384,512}
+* (C) 1999-2010 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_SHA_64BIT_H__
+#define BOTAN_SHA_64BIT_H__
+
+#include <botan/mdx_hash.h>
+
+namespace Botan {
+
+/**
+* SHA-384
+*/
+class BOTAN_DLL SHA_384 : public MDx_HashFunction
+ {
+ public:
+ std::string name() const { return "SHA-384"; }
+ size_t output_length() const { return 48; }
+ HashFunction* clone() const { return new SHA_384; }
+
+ void clear();
+
+ SHA_384() : MDx_HashFunction(128, true, true, 16), digest(8)
+ { clear(); }
+ private:
+ void compress_n(const byte[], size_t blocks);
+ void copy_out(byte[]);
+
+ secure_vector<u64bit> digest;
+ };
+
+/**
+* SHA-512
+*/
+class BOTAN_DLL SHA_512 : public MDx_HashFunction
+ {
+ public:
+ std::string name() const { return "SHA-512"; }
+ size_t output_length() const { return 64; }
+ HashFunction* clone() const { return new SHA_512; }
+
+ void clear();
+
+ SHA_512() : MDx_HashFunction(128, true, true, 16), digest(8)
+ { clear(); }
+ private:
+ void compress_n(const byte[], size_t blocks);
+ void copy_out(byte[]);
+
+ secure_vector<u64bit> digest;
+ };
+
+}
+
+#endif
diff --git a/src/lib/hash/skein/info.txt b/src/lib/hash/skein/info.txt
new file mode 100644
index 000000000..89443132b
--- /dev/null
+++ b/src/lib/hash/skein/info.txt
@@ -0,0 +1,5 @@
+define SKEIN_512 20131128
+
+<requires>
+alloc
+</requires>
diff --git a/src/lib/hash/skein/skein_512.cpp b/src/lib/hash/skein/skein_512.cpp
new file mode 100644
index 000000000..9aafb1616
--- /dev/null
+++ b/src/lib/hash/skein/skein_512.cpp
@@ -0,0 +1,274 @@
+/*
+* The Skein-512 hash function
+* (C) 2009-2010 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/skein_512.h>
+#include <botan/loadstor.h>
+#include <botan/parsing.h>
+#include <botan/exceptn.h>
+#include <botan/rotate.h>
+#include <algorithm>
+
+namespace Botan {
+
+namespace {
+
+enum type_code {
+ SKEIN_KEY = 0,
+ SKEIN_CONFIG = 4,
+ SKEIN_PERSONALIZATION = 8,
+ SKEIN_PUBLIC_KEY = 12,
+ SKEIN_KEY_IDENTIFIER = 16,
+ SKEIN_NONCE = 20,
+ SKEIN_MSG = 48,
+ SKEIN_OUTPUT = 63
+};
+
+void ubi_512(secure_vector<u64bit>& H,
+ secure_vector<u64bit>& T,
+ const byte msg[], size_t msg_len)
+ {
+ do
+ {
+ const size_t to_proc = std::min<size_t>(msg_len, 64);
+ T[0] += to_proc;
+
+ u64bit M[8] = { 0 };
+
+ load_le(M, msg, to_proc / 8);
+
+ if(to_proc % 8)
+ {
+ for(size_t j = 0; j != to_proc % 8; ++j)
+ M[to_proc/8] |= static_cast<u64bit>(msg[8*(to_proc/8)+j]) << (8*j);
+ }
+
+ H[8] = H[0] ^ H[1] ^ H[2] ^ H[3] ^
+ H[4] ^ H[5] ^ H[6] ^ H[7] ^ 0x1BD11BDAA9FC1A22;
+
+ T[2] = T[0] ^ T[1];
+
+ u64bit X0 = M[0] + H[0];
+ u64bit X1 = M[1] + H[1];
+ u64bit X2 = M[2] + H[2];
+ u64bit X3 = M[3] + H[3];
+ u64bit X4 = M[4] + H[4];
+ u64bit X5 = M[5] + H[5] + T[0];
+ u64bit X6 = M[6] + H[6] + T[1];
+ u64bit X7 = M[7] + H[7];
+
+#define THREEFISH_ROUND(X1,X2,X3,X4,X5,X6,X7,X8,ROT1,ROT2,ROT3,ROT4) \
+ do { \
+ X1 += X2; X2 = rotate_left(X2, ROT1) ^ X1; \
+ X3 += X4; X4 = rotate_left(X4, ROT2) ^ X3; \
+ X5 += X6; X6 = rotate_left(X6, ROT3) ^ X5; \
+ X7 += X8; X8 = rotate_left(X8, ROT4) ^ X7; \
+ } while(0);
+
+#define THREEFISH_INJECT_KEY(r) \
+ do { \
+ X0 += H[(r ) % 9]; \
+ X1 += H[(r+1) % 9]; \
+ X2 += H[(r+2) % 9]; \
+ X3 += H[(r+3) % 9]; \
+ X4 += H[(r+4) % 9]; \
+ X5 += H[(r+5) % 9] + T[(r ) % 3]; \
+ X6 += H[(r+6) % 9] + T[(r+1) % 3]; \
+ X7 += H[(r+7) % 9] + (r); \
+ } while(0);
+
+#define THREEFISH_8_ROUNDS(R1,R2) \
+ do { \
+ THREEFISH_ROUND(X0,X1,X2,X3,X4,X5,X6,X7, 46,36,19,37); \
+ THREEFISH_ROUND(X2,X1,X4,X7,X6,X5,X0,X3, 33,27,14,42); \
+ THREEFISH_ROUND(X4,X1,X6,X3,X0,X5,X2,X7, 17,49,36,39); \
+ THREEFISH_ROUND(X6,X1,X0,X7,X2,X5,X4,X3, 44, 9,54,56); \
+ \
+ THREEFISH_INJECT_KEY(R1); \
+ \
+ THREEFISH_ROUND(X0,X1,X2,X3,X4,X5,X6,X7, 39,30,34,24); \
+ THREEFISH_ROUND(X2,X1,X4,X7,X6,X5,X0,X3, 13,50,10,17); \
+ THREEFISH_ROUND(X4,X1,X6,X3,X0,X5,X2,X7, 25,29,39,43); \
+ THREEFISH_ROUND(X6,X1,X0,X7,X2,X5,X4,X3, 8,35,56,22); \
+ \
+ THREEFISH_INJECT_KEY(R2); \
+ } while(0);
+
+ THREEFISH_8_ROUNDS(1,2);
+ THREEFISH_8_ROUNDS(3,4);
+ THREEFISH_8_ROUNDS(5,6);
+ THREEFISH_8_ROUNDS(7,8);
+ THREEFISH_8_ROUNDS(9,10);
+ THREEFISH_8_ROUNDS(11,12);
+ THREEFISH_8_ROUNDS(13,14);
+ THREEFISH_8_ROUNDS(15,16);
+ THREEFISH_8_ROUNDS(17,18);
+
+ // message feed forward
+ H[0] = X0 ^ M[0];
+ H[1] = X1 ^ M[1];
+ H[2] = X2 ^ M[2];
+ H[3] = X3 ^ M[3];
+ H[4] = X4 ^ M[4];
+ H[5] = X5 ^ M[5];
+ H[6] = X6 ^ M[6];
+ H[7] = X7 ^ M[7];
+
+ // clear first flag if set
+ T[1] &= ~(static_cast<u64bit>(1) << 62);
+
+ msg_len -= to_proc;
+ msg += to_proc;
+ } while(msg_len);
+ }
+
+void reset_tweak(secure_vector<u64bit>& T,
+ type_code type, bool final)
+ {
+ T[0] = 0;
+
+ T[1] = (static_cast<u64bit>(type) << 56) |
+ (static_cast<u64bit>(1) << 62) |
+ (static_cast<u64bit>(final) << 63);
+ }
+
+void initial_block(secure_vector<u64bit>& H,
+ secure_vector<u64bit>& T,
+ size_t output_bits,
+ const std::string& personalization)
+ {
+ zeroise(H);
+
+ // ASCII("SHA3") followed by version (0x0001) code
+ byte config_str[32] = { 0x53, 0x48, 0x41, 0x33, 0x01, 0x00, 0 };
+ store_le(u32bit(output_bits), config_str + 8);
+
+ reset_tweak(T, SKEIN_CONFIG, true);
+ ubi_512(H, T, config_str, sizeof(config_str));
+
+ if(personalization != "")
+ {
+ /*
+ This is a limitation of this implementation, and not of the
+ algorithm specification. Could be fixed relatively easily, but
+ doesn't seem worth the trouble.
+ */
+ if(personalization.length() > 64)
+ throw Invalid_Argument("Skein personalization must be <= 64 bytes");
+
+ const byte* bits = reinterpret_cast<const byte*>(personalization.data());
+
+ reset_tweak(T, SKEIN_PERSONALIZATION, true);
+ ubi_512(H, T, bits, personalization.length());
+ }
+
+ reset_tweak(T, SKEIN_MSG, false);
+ }
+
+}
+
+Skein_512::Skein_512(size_t arg_output_bits,
+ const std::string& arg_personalization) :
+ personalization(arg_personalization),
+ output_bits(arg_output_bits),
+ H(9), T(3), buffer(64), buf_pos(0)
+ {
+ if(output_bits == 0 || output_bits % 8 != 0 || output_bits > 64*1024)
+ throw Invalid_Argument("Bad output bits size for Skein-512");
+
+ initial_block(H, T, output_bits, personalization);
+ }
+
+std::string Skein_512::name() const
+ {
+ if(personalization != "")
+ return "Skein-512(" + std::to_string(output_bits) + "," +
+ personalization + ")";
+ return "Skein-512(" + std::to_string(output_bits) + ")";
+ }
+
+HashFunction* Skein_512::clone() const
+ {
+ return new Skein_512(output_bits, personalization);
+ }
+
+void Skein_512::clear()
+ {
+ zeroise(H);
+ zeroise(T);
+ zeroise(buffer);
+ buf_pos = 0;
+ }
+
+void Skein_512::add_data(const byte input[], size_t length)
+ {
+ if(length == 0)
+ return;
+
+ if(buf_pos)
+ {
+ buffer_insert(buffer, buf_pos, input, length);
+ if(buf_pos + length > 64)
+ {
+ ubi_512(H, T, &buffer[0], buffer.size());
+
+ input += (64 - buf_pos);
+ length -= (64 - buf_pos);
+ buf_pos = 0;
+ }
+ }
+
+ const size_t full_blocks = (length - 1) / 64;
+
+ if(full_blocks)
+ ubi_512(H, T, input, 64*full_blocks);
+
+ length -= full_blocks * 64;
+
+ buffer_insert(buffer, buf_pos, input + full_blocks * 64, length);
+ buf_pos += length;
+ }
+
+void Skein_512::final_result(byte out[])
+ {
+ T[1] |= (static_cast<u64bit>(1) << 63); // final block flag
+
+ for(size_t i = buf_pos; i != buffer.size(); ++i)
+ buffer[i] = 0;
+
+ ubi_512(H, T, &buffer[0], buf_pos);
+
+ byte counter[8] = { 0 };
+
+ size_t out_bytes = output_bits / 8;
+
+ secure_vector<u64bit> H_out(9);
+
+ while(out_bytes)
+ {
+ const size_t to_proc = std::min<size_t>(out_bytes, 64);
+
+ copy_mem(&H_out[0], &H[0], 8);
+
+ reset_tweak(T, SKEIN_OUTPUT, true);
+ ubi_512(H_out, T, counter, sizeof(counter));
+
+ for(size_t i = 0; i != to_proc; ++i)
+ out[i] = get_byte(7-i%8, H_out[i/8]);
+
+ out_bytes -= to_proc;
+ out += to_proc;
+
+ for(size_t i = 0; i != sizeof(counter); ++i)
+ if(++counter[i])
+ break;
+ }
+
+ buf_pos = 0;
+ initial_block(H, T, output_bits, personalization);
+ }
+
+}
diff --git a/src/lib/hash/skein/skein_512.h b/src/lib/hash/skein/skein_512.h
new file mode 100644
index 000000000..e0abc06ae
--- /dev/null
+++ b/src/lib/hash/skein/skein_512.h
@@ -0,0 +1,52 @@
+/*
+* The Skein-512 hash function
+* (C) 2009 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_SKEIN_512_H__
+#define BOTAN_SKEIN_512_H__
+
+#include <botan/secmem.h>
+#include <botan/hash.h>
+#include <string>
+
+namespace Botan {
+
+/**
+* Skein-512, a SHA-3 candidate
+*/
+class BOTAN_DLL Skein_512 : public HashFunction
+ {
+ public:
+ /**
+ * @param output_bits the output size of Skein in bits
+ * @param personalization is a string that will paramaterize the
+ * hash output
+ */
+ Skein_512(size_t output_bits = 512,
+ const std::string& personalization = "");
+
+ size_t hash_block_size() const { return 64; }
+ size_t output_length() const { return output_bits / 8; }
+
+ HashFunction* clone() const;
+ std::string name() const;
+ void clear();
+ private:
+ void add_data(const byte input[], size_t length);
+ void final_result(byte out[]);
+
+ std::string personalization;
+ size_t output_bits;
+
+ secure_vector<u64bit> H;
+ secure_vector<u64bit> T;
+ secure_vector<byte> buffer;
+ size_t buf_pos;
+ };
+
+}
+
+#endif
diff --git a/src/lib/hash/tiger/info.txt b/src/lib/hash/tiger/info.txt
new file mode 100644
index 000000000..773f2b037
--- /dev/null
+++ b/src/lib/hash/tiger/info.txt
@@ -0,0 +1,5 @@
+define TIGER 20131128
+
+<requires>
+mdx_hash
+</requires>
diff --git a/src/lib/hash/tiger/tig_tab.cpp b/src/lib/hash/tiger/tig_tab.cpp
new file mode 100644
index 000000000..b76501d74
--- /dev/null
+++ b/src/lib/hash/tiger/tig_tab.cpp
@@ -0,0 +1,364 @@
+/*
+* S-Box Tables for Tiger
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/tiger.h>
+
+namespace Botan {
+
+const u64bit Tiger::SBOX1[256] = {
+ 0x02AAB17CF7E90C5E, 0xAC424B03E243A8EC, 0x72CD5BE30DD5FCD3,
+ 0x6D019B93F6F97F3A, 0xCD9978FFD21F9193, 0x7573A1C9708029E2,
+ 0xB164326B922A83C3, 0x46883EEE04915870, 0xEAACE3057103ECE6,
+ 0xC54169B808A3535C, 0x4CE754918DDEC47C, 0x0AA2F4DFDC0DF40C,
+ 0x10B76F18A74DBEFA, 0xC6CCB6235AD1AB6A, 0x13726121572FE2FF,
+ 0x1A488C6F199D921E, 0x4BC9F9F4DA0007CA, 0x26F5E6F6E85241C7,
+ 0x859079DBEA5947B6, 0x4F1885C5C99E8C92, 0xD78E761EA96F864B,
+ 0x8E36428C52B5C17D, 0x69CF6827373063C1, 0xB607C93D9BB4C56E,
+ 0x7D820E760E76B5EA, 0x645C9CC6F07FDC42, 0xBF38A078243342E0,
+ 0x5F6B343C9D2E7D04, 0xF2C28AEB600B0EC6, 0x6C0ED85F7254BCAC,
+ 0x71592281A4DB4FE5, 0x1967FA69CE0FED9F, 0xFD5293F8B96545DB,
+ 0xC879E9D7F2A7600B, 0x860248920193194E, 0xA4F9533B2D9CC0B3,
+ 0x9053836C15957613, 0xDB6DCF8AFC357BF1, 0x18BEEA7A7A370F57,
+ 0x037117CA50B99066, 0x6AB30A9774424A35, 0xF4E92F02E325249B,
+ 0x7739DB07061CCAE1, 0xD8F3B49CECA42A05, 0xBD56BE3F51382F73,
+ 0x45FAED5843B0BB28, 0x1C813D5C11BF1F83, 0x8AF0E4B6D75FA169,
+ 0x33EE18A487AD9999, 0x3C26E8EAB1C94410, 0xB510102BC0A822F9,
+ 0x141EEF310CE6123B, 0xFC65B90059DDB154, 0xE0158640C5E0E607,
+ 0x884E079826C3A3CF, 0x930D0D9523C535FD, 0x35638D754E9A2B00,
+ 0x4085FCCF40469DD5, 0xC4B17AD28BE23A4C, 0xCAB2F0FC6A3E6A2E,
+ 0x2860971A6B943FCD, 0x3DDE6EE212E30446, 0x6222F32AE01765AE,
+ 0x5D550BB5478308FE, 0xA9EFA98DA0EDA22A, 0xC351A71686C40DA7,
+ 0x1105586D9C867C84, 0xDCFFEE85FDA22853, 0xCCFBD0262C5EEF76,
+ 0xBAF294CB8990D201, 0xE69464F52AFAD975, 0x94B013AFDF133E14,
+ 0x06A7D1A32823C958, 0x6F95FE5130F61119, 0xD92AB34E462C06C0,
+ 0xED7BDE33887C71D2, 0x79746D6E6518393E, 0x5BA419385D713329,
+ 0x7C1BA6B948A97564, 0x31987C197BFDAC67, 0xDE6C23C44B053D02,
+ 0x581C49FED002D64D, 0xDD474D6338261571, 0xAA4546C3E473D062,
+ 0x928FCE349455F860, 0x48161BBACAAB94D9, 0x63912430770E6F68,
+ 0x6EC8A5E602C6641C, 0x87282515337DDD2B, 0x2CDA6B42034B701B,
+ 0xB03D37C181CB096D, 0xE108438266C71C6F, 0x2B3180C7EB51B255,
+ 0xDF92B82F96C08BBC, 0x5C68C8C0A632F3BA, 0x5504CC861C3D0556,
+ 0xABBFA4E55FB26B8F, 0x41848B0AB3BACEB4, 0xB334A273AA445D32,
+ 0xBCA696F0A85AD881, 0x24F6EC65B528D56C, 0x0CE1512E90F4524A,
+ 0x4E9DD79D5506D35A, 0x258905FAC6CE9779, 0x2019295B3E109B33,
+ 0xF8A9478B73A054CC, 0x2924F2F934417EB0, 0x3993357D536D1BC4,
+ 0x38A81AC21DB6FF8B, 0x47C4FBF17D6016BF, 0x1E0FAADD7667E3F5,
+ 0x7ABCFF62938BEB96, 0xA78DAD948FC179C9, 0x8F1F98B72911E50D,
+ 0x61E48EAE27121A91, 0x4D62F7AD31859808, 0xECEBA345EF5CEAEB,
+ 0xF5CEB25EBC9684CE, 0xF633E20CB7F76221, 0xA32CDF06AB8293E4,
+ 0x985A202CA5EE2CA4, 0xCF0B8447CC8A8FB1, 0x9F765244979859A3,
+ 0xA8D516B1A1240017, 0x0BD7BA3EBB5DC726, 0xE54BCA55B86ADB39,
+ 0x1D7A3AFD6C478063, 0x519EC608E7669EDD, 0x0E5715A2D149AA23,
+ 0x177D4571848FF194, 0xEEB55F3241014C22, 0x0F5E5CA13A6E2EC2,
+ 0x8029927B75F5C361, 0xAD139FABC3D6E436, 0x0D5DF1A94CCF402F,
+ 0x3E8BD948BEA5DFC8, 0xA5A0D357BD3FF77E, 0xA2D12E251F74F645,
+ 0x66FD9E525E81A082, 0x2E0C90CE7F687A49, 0xC2E8BCBEBA973BC5,
+ 0x000001BCE509745F, 0x423777BBE6DAB3D6, 0xD1661C7EAEF06EB5,
+ 0xA1781F354DAACFD8, 0x2D11284A2B16AFFC, 0xF1FC4F67FA891D1F,
+ 0x73ECC25DCB920ADA, 0xAE610C22C2A12651, 0x96E0A810D356B78A,
+ 0x5A9A381F2FE7870F, 0xD5AD62EDE94E5530, 0xD225E5E8368D1427,
+ 0x65977B70C7AF4631, 0x99F889B2DE39D74F, 0x233F30BF54E1D143,
+ 0x9A9675D3D9A63C97, 0x5470554FF334F9A8, 0x166ACB744A4F5688,
+ 0x70C74CAAB2E4AEAD, 0xF0D091646F294D12, 0x57B82A89684031D1,
+ 0xEFD95A5A61BE0B6B, 0x2FBD12E969F2F29A, 0x9BD37013FEFF9FE8,
+ 0x3F9B0404D6085A06, 0x4940C1F3166CFE15, 0x09542C4DCDF3DEFB,
+ 0xB4C5218385CD5CE3, 0xC935B7DC4462A641, 0x3417F8A68ED3B63F,
+ 0xB80959295B215B40, 0xF99CDAEF3B8C8572, 0x018C0614F8FCB95D,
+ 0x1B14ACCD1A3ACDF3, 0x84D471F200BB732D, 0xC1A3110E95E8DA16,
+ 0x430A7220BF1A82B8, 0xB77E090D39DF210E, 0x5EF4BD9F3CD05E9D,
+ 0x9D4FF6DA7E57A444, 0xDA1D60E183D4A5F8, 0xB287C38417998E47,
+ 0xFE3EDC121BB31886, 0xC7FE3CCC980CCBEF, 0xE46FB590189BFD03,
+ 0x3732FD469A4C57DC, 0x7EF700A07CF1AD65, 0x59C64468A31D8859,
+ 0x762FB0B4D45B61F6, 0x155BAED099047718, 0x68755E4C3D50BAA6,
+ 0xE9214E7F22D8B4DF, 0x2ADDBF532EAC95F4, 0x32AE3909B4BD0109,
+ 0x834DF537B08E3450, 0xFA209DA84220728D, 0x9E691D9B9EFE23F7,
+ 0x0446D288C4AE8D7F, 0x7B4CC524E169785B, 0x21D87F0135CA1385,
+ 0xCEBB400F137B8AA5, 0x272E2B66580796BE, 0x3612264125C2B0DE,
+ 0x057702BDAD1EFBB2, 0xD4BABB8EACF84BE9, 0x91583139641BC67B,
+ 0x8BDC2DE08036E024, 0x603C8156F49F68ED, 0xF7D236F7DBEF5111,
+ 0x9727C4598AD21E80, 0xA08A0896670A5FD7, 0xCB4A8F4309EBA9CB,
+ 0x81AF564B0F7036A1, 0xC0B99AA778199ABD, 0x959F1EC83FC8E952,
+ 0x8C505077794A81B9, 0x3ACAAF8F056338F0, 0x07B43F50627A6778,
+ 0x4A44AB49F5ECCC77, 0x3BC3D6E4B679EE98, 0x9CC0D4D1CF14108C,
+ 0x4406C00B206BC8A0, 0x82A18854C8D72D89, 0x67E366B35C3C432C,
+ 0xB923DD61102B37F2, 0x56AB2779D884271D, 0xBE83E1B0FF1525AF,
+ 0xFB7C65D4217E49A9, 0x6BDBE0E76D48E7D4, 0x08DF828745D9179E,
+ 0x22EA6A9ADD53BD34, 0xE36E141C5622200A, 0x7F805D1B8CB750EE,
+ 0xAFE5C7A59F58E837, 0xE27F996A4FB1C23C, 0xD3867DFB0775F0D0,
+ 0xD0E673DE6E88891A, 0x123AEB9EAFB86C25, 0x30F1D5D5C145B895,
+ 0xBB434A2DEE7269E7, 0x78CB67ECF931FA38, 0xF33B0372323BBF9C,
+ 0x52D66336FB279C74, 0x505F33AC0AFB4EAA, 0xE8A5CD99A2CCE187,
+ 0x534974801E2D30BB, 0x8D2D5711D5876D90, 0x1F1A412891BC038E,
+ 0xD6E2E71D82E56648, 0x74036C3A497732B7, 0x89B67ED96361F5AB,
+ 0xFFED95D8F1EA02A2, 0xE72B3BD61464D43D, 0xA6300F170BDC4820,
+ 0xEBC18760ED78A77A };
+
+const u64bit Tiger::SBOX2[256] = {
+ 0xE6A6BE5A05A12138, 0xB5A122A5B4F87C98, 0x563C6089140B6990,
+ 0x4C46CB2E391F5DD5, 0xD932ADDBC9B79434, 0x08EA70E42015AFF5,
+ 0xD765A6673E478CF1, 0xC4FB757EAB278D99, 0xDF11C6862D6E0692,
+ 0xDDEB84F10D7F3B16, 0x6F2EF604A665EA04, 0x4A8E0F0FF0E0DFB3,
+ 0xA5EDEEF83DBCBA51, 0xFC4F0A2A0EA4371E, 0xE83E1DA85CB38429,
+ 0xDC8FF882BA1B1CE2, 0xCD45505E8353E80D, 0x18D19A00D4DB0717,
+ 0x34A0CFEDA5F38101, 0x0BE77E518887CAF2, 0x1E341438B3C45136,
+ 0xE05797F49089CCF9, 0xFFD23F9DF2591D14, 0x543DDA228595C5CD,
+ 0x661F81FD99052A33, 0x8736E641DB0F7B76, 0x15227725418E5307,
+ 0xE25F7F46162EB2FA, 0x48A8B2126C13D9FE, 0xAFDC541792E76EEA,
+ 0x03D912BFC6D1898F, 0x31B1AAFA1B83F51B, 0xF1AC2796E42AB7D9,
+ 0x40A3A7D7FCD2EBAC, 0x1056136D0AFBBCC5, 0x7889E1DD9A6D0C85,
+ 0xD33525782A7974AA, 0xA7E25D09078AC09B, 0xBD4138B3EAC6EDD0,
+ 0x920ABFBE71EB9E70, 0xA2A5D0F54FC2625C, 0xC054E36B0B1290A3,
+ 0xF6DD59FF62FE932B, 0x3537354511A8AC7D, 0xCA845E9172FADCD4,
+ 0x84F82B60329D20DC, 0x79C62CE1CD672F18, 0x8B09A2ADD124642C,
+ 0xD0C1E96A19D9E726, 0x5A786A9B4BA9500C, 0x0E020336634C43F3,
+ 0xC17B474AEB66D822, 0x6A731AE3EC9BAAC2, 0x8226667AE0840258,
+ 0x67D4567691CAECA5, 0x1D94155C4875ADB5, 0x6D00FD985B813FDF,
+ 0x51286EFCB774CD06, 0x5E8834471FA744AF, 0xF72CA0AEE761AE2E,
+ 0xBE40E4CDAEE8E09A, 0xE9970BBB5118F665, 0x726E4BEB33DF1964,
+ 0x703B000729199762, 0x4631D816F5EF30A7, 0xB880B5B51504A6BE,
+ 0x641793C37ED84B6C, 0x7B21ED77F6E97D96, 0x776306312EF96B73,
+ 0xAE528948E86FF3F4, 0x53DBD7F286A3F8F8, 0x16CADCE74CFC1063,
+ 0x005C19BDFA52C6DD, 0x68868F5D64D46AD3, 0x3A9D512CCF1E186A,
+ 0x367E62C2385660AE, 0xE359E7EA77DCB1D7, 0x526C0773749ABE6E,
+ 0x735AE5F9D09F734B, 0x493FC7CC8A558BA8, 0xB0B9C1533041AB45,
+ 0x321958BA470A59BD, 0x852DB00B5F46C393, 0x91209B2BD336B0E5,
+ 0x6E604F7D659EF19F, 0xB99A8AE2782CCB24, 0xCCF52AB6C814C4C7,
+ 0x4727D9AFBE11727B, 0x7E950D0C0121B34D, 0x756F435670AD471F,
+ 0xF5ADD442615A6849, 0x4E87E09980B9957A, 0x2ACFA1DF50AEE355,
+ 0xD898263AFD2FD556, 0xC8F4924DD80C8FD6, 0xCF99CA3D754A173A,
+ 0xFE477BACAF91BF3C, 0xED5371F6D690C12D, 0x831A5C285E687094,
+ 0xC5D3C90A3708A0A4, 0x0F7F903717D06580, 0x19F9BB13B8FDF27F,
+ 0xB1BD6F1B4D502843, 0x1C761BA38FFF4012, 0x0D1530C4E2E21F3B,
+ 0x8943CE69A7372C8A, 0xE5184E11FEB5CE66, 0x618BDB80BD736621,
+ 0x7D29BAD68B574D0B, 0x81BB613E25E6FE5B, 0x071C9C10BC07913F,
+ 0xC7BEEB7909AC2D97, 0xC3E58D353BC5D757, 0xEB017892F38F61E8,
+ 0xD4EFFB9C9B1CC21A, 0x99727D26F494F7AB, 0xA3E063A2956B3E03,
+ 0x9D4A8B9A4AA09C30, 0x3F6AB7D500090FB4, 0x9CC0F2A057268AC0,
+ 0x3DEE9D2DEDBF42D1, 0x330F49C87960A972, 0xC6B2720287421B41,
+ 0x0AC59EC07C00369C, 0xEF4EAC49CB353425, 0xF450244EEF0129D8,
+ 0x8ACC46E5CAF4DEB6, 0x2FFEAB63989263F7, 0x8F7CB9FE5D7A4578,
+ 0x5BD8F7644E634635, 0x427A7315BF2DC900, 0x17D0C4AA2125261C,
+ 0x3992486C93518E50, 0xB4CBFEE0A2D7D4C3, 0x7C75D6202C5DDD8D,
+ 0xDBC295D8E35B6C61, 0x60B369D302032B19, 0xCE42685FDCE44132,
+ 0x06F3DDB9DDF65610, 0x8EA4D21DB5E148F0, 0x20B0FCE62FCD496F,
+ 0x2C1B912358B0EE31, 0xB28317B818F5A308, 0xA89C1E189CA6D2CF,
+ 0x0C6B18576AAADBC8, 0xB65DEAA91299FAE3, 0xFB2B794B7F1027E7,
+ 0x04E4317F443B5BEB, 0x4B852D325939D0A6, 0xD5AE6BEEFB207FFC,
+ 0x309682B281C7D374, 0xBAE309A194C3B475, 0x8CC3F97B13B49F05,
+ 0x98A9422FF8293967, 0x244B16B01076FF7C, 0xF8BF571C663D67EE,
+ 0x1F0D6758EEE30DA1, 0xC9B611D97ADEB9B7, 0xB7AFD5887B6C57A2,
+ 0x6290AE846B984FE1, 0x94DF4CDEACC1A5FD, 0x058A5BD1C5483AFF,
+ 0x63166CC142BA3C37, 0x8DB8526EB2F76F40, 0xE10880036F0D6D4E,
+ 0x9E0523C9971D311D, 0x45EC2824CC7CD691, 0x575B8359E62382C9,
+ 0xFA9E400DC4889995, 0xD1823ECB45721568, 0xDAFD983B8206082F,
+ 0xAA7D29082386A8CB, 0x269FCD4403B87588, 0x1B91F5F728BDD1E0,
+ 0xE4669F39040201F6, 0x7A1D7C218CF04ADE, 0x65623C29D79CE5CE,
+ 0x2368449096C00BB1, 0xAB9BF1879DA503BA, 0xBC23ECB1A458058E,
+ 0x9A58DF01BB401ECC, 0xA070E868A85F143D, 0x4FF188307DF2239E,
+ 0x14D565B41A641183, 0xEE13337452701602, 0x950E3DCF3F285E09,
+ 0x59930254B9C80953, 0x3BF299408930DA6D, 0xA955943F53691387,
+ 0xA15EDECAA9CB8784, 0x29142127352BE9A0, 0x76F0371FFF4E7AFB,
+ 0x0239F450274F2228, 0xBB073AF01D5E868B, 0xBFC80571C10E96C1,
+ 0xD267088568222E23, 0x9671A3D48E80B5B0, 0x55B5D38AE193BB81,
+ 0x693AE2D0A18B04B8, 0x5C48B4ECADD5335F, 0xFD743B194916A1CA,
+ 0x2577018134BE98C4, 0xE77987E83C54A4AD, 0x28E11014DA33E1B9,
+ 0x270CC59E226AA213, 0x71495F756D1A5F60, 0x9BE853FB60AFEF77,
+ 0xADC786A7F7443DBF, 0x0904456173B29A82, 0x58BC7A66C232BD5E,
+ 0xF306558C673AC8B2, 0x41F639C6B6C9772A, 0x216DEFE99FDA35DA,
+ 0x11640CC71C7BE615, 0x93C43694565C5527, 0xEA038E6246777839,
+ 0xF9ABF3CE5A3E2469, 0x741E768D0FD312D2, 0x0144B883CED652C6,
+ 0xC20B5A5BA33F8552, 0x1AE69633C3435A9D, 0x97A28CA4088CFDEC,
+ 0x8824A43C1E96F420, 0x37612FA66EEEA746, 0x6B4CB165F9CF0E5A,
+ 0x43AA1C06A0ABFB4A, 0x7F4DC26FF162796B, 0x6CBACC8E54ED9B0F,
+ 0xA6B7FFEFD2BB253E, 0x2E25BC95B0A29D4F, 0x86D6A58BDEF1388C,
+ 0xDED74AC576B6F054, 0x8030BDBC2B45805D, 0x3C81AF70E94D9289,
+ 0x3EFF6DDA9E3100DB, 0xB38DC39FDFCC8847, 0x123885528D17B87E,
+ 0xF2DA0ED240B1B642, 0x44CEFADCD54BF9A9, 0x1312200E433C7EE6,
+ 0x9FFCC84F3A78C748, 0xF0CD1F72248576BB, 0xEC6974053638CFE4,
+ 0x2BA7B67C0CEC4E4C, 0xAC2F4DF3E5CE32ED, 0xCB33D14326EA4C11,
+ 0xA4E9044CC77E58BC, 0x5F513293D934FCEF, 0x5DC9645506E55444,
+ 0x50DE418F317DE40A, 0x388CB31A69DDE259, 0x2DB4A83455820A86,
+ 0x9010A91E84711AE9, 0x4DF7F0B7B1498371, 0xD62A2EABC0977179,
+ 0x22FAC097AA8D5C0E };
+
+const u64bit Tiger::SBOX3[256] = {
+ 0xF49FCC2FF1DAF39B, 0x487FD5C66FF29281, 0xE8A30667FCDCA83F,
+ 0x2C9B4BE3D2FCCE63, 0xDA3FF74B93FBBBC2, 0x2FA165D2FE70BA66,
+ 0xA103E279970E93D4, 0xBECDEC77B0E45E71, 0xCFB41E723985E497,
+ 0xB70AAA025EF75017, 0xD42309F03840B8E0, 0x8EFC1AD035898579,
+ 0x96C6920BE2B2ABC5, 0x66AF4163375A9172, 0x2174ABDCCA7127FB,
+ 0xB33CCEA64A72FF41, 0xF04A4933083066A5, 0x8D970ACDD7289AF5,
+ 0x8F96E8E031C8C25E, 0xF3FEC02276875D47, 0xEC7BF310056190DD,
+ 0xF5ADB0AEBB0F1491, 0x9B50F8850FD58892, 0x4975488358B74DE8,
+ 0xA3354FF691531C61, 0x0702BBE481D2C6EE, 0x89FB24057DEDED98,
+ 0xAC3075138596E902, 0x1D2D3580172772ED, 0xEB738FC28E6BC30D,
+ 0x5854EF8F63044326, 0x9E5C52325ADD3BBE, 0x90AA53CF325C4623,
+ 0xC1D24D51349DD067, 0x2051CFEEA69EA624, 0x13220F0A862E7E4F,
+ 0xCE39399404E04864, 0xD9C42CA47086FCB7, 0x685AD2238A03E7CC,
+ 0x066484B2AB2FF1DB, 0xFE9D5D70EFBF79EC, 0x5B13B9DD9C481854,
+ 0x15F0D475ED1509AD, 0x0BEBCD060EC79851, 0xD58C6791183AB7F8,
+ 0xD1187C5052F3EEE4, 0xC95D1192E54E82FF, 0x86EEA14CB9AC6CA2,
+ 0x3485BEB153677D5D, 0xDD191D781F8C492A, 0xF60866BAA784EBF9,
+ 0x518F643BA2D08C74, 0x8852E956E1087C22, 0xA768CB8DC410AE8D,
+ 0x38047726BFEC8E1A, 0xA67738B4CD3B45AA, 0xAD16691CEC0DDE19,
+ 0xC6D4319380462E07, 0xC5A5876D0BA61938, 0x16B9FA1FA58FD840,
+ 0x188AB1173CA74F18, 0xABDA2F98C99C021F, 0x3E0580AB134AE816,
+ 0x5F3B05B773645ABB, 0x2501A2BE5575F2F6, 0x1B2F74004E7E8BA9,
+ 0x1CD7580371E8D953, 0x7F6ED89562764E30, 0xB15926FF596F003D,
+ 0x9F65293DA8C5D6B9, 0x6ECEF04DD690F84C, 0x4782275FFF33AF88,
+ 0xE41433083F820801, 0xFD0DFE409A1AF9B5, 0x4325A3342CDB396B,
+ 0x8AE77E62B301B252, 0xC36F9E9F6655615A, 0x85455A2D92D32C09,
+ 0xF2C7DEA949477485, 0x63CFB4C133A39EBA, 0x83B040CC6EBC5462,
+ 0x3B9454C8FDB326B0, 0x56F56A9E87FFD78C, 0x2DC2940D99F42BC6,
+ 0x98F7DF096B096E2D, 0x19A6E01E3AD852BF, 0x42A99CCBDBD4B40B,
+ 0xA59998AF45E9C559, 0x366295E807D93186, 0x6B48181BFAA1F773,
+ 0x1FEC57E2157A0A1D, 0x4667446AF6201AD5, 0xE615EBCACFB0F075,
+ 0xB8F31F4F68290778, 0x22713ED6CE22D11E, 0x3057C1A72EC3C93B,
+ 0xCB46ACC37C3F1F2F, 0xDBB893FD02AAF50E, 0x331FD92E600B9FCF,
+ 0xA498F96148EA3AD6, 0xA8D8426E8B6A83EA, 0xA089B274B7735CDC,
+ 0x87F6B3731E524A11, 0x118808E5CBC96749, 0x9906E4C7B19BD394,
+ 0xAFED7F7E9B24A20C, 0x6509EADEEB3644A7, 0x6C1EF1D3E8EF0EDE,
+ 0xB9C97D43E9798FB4, 0xA2F2D784740C28A3, 0x7B8496476197566F,
+ 0x7A5BE3E6B65F069D, 0xF96330ED78BE6F10, 0xEEE60DE77A076A15,
+ 0x2B4BEE4AA08B9BD0, 0x6A56A63EC7B8894E, 0x02121359BA34FEF4,
+ 0x4CBF99F8283703FC, 0x398071350CAF30C8, 0xD0A77A89F017687A,
+ 0xF1C1A9EB9E423569, 0x8C7976282DEE8199, 0x5D1737A5DD1F7ABD,
+ 0x4F53433C09A9FA80, 0xFA8B0C53DF7CA1D9, 0x3FD9DCBC886CCB77,
+ 0xC040917CA91B4720, 0x7DD00142F9D1DCDF, 0x8476FC1D4F387B58,
+ 0x23F8E7C5F3316503, 0x032A2244E7E37339, 0x5C87A5D750F5A74B,
+ 0x082B4CC43698992E, 0xDF917BECB858F63C, 0x3270B8FC5BF86DDA,
+ 0x10AE72BB29B5DD76, 0x576AC94E7700362B, 0x1AD112DAC61EFB8F,
+ 0x691BC30EC5FAA427, 0xFF246311CC327143, 0x3142368E30E53206,
+ 0x71380E31E02CA396, 0x958D5C960AAD76F1, 0xF8D6F430C16DA536,
+ 0xC8FFD13F1BE7E1D2, 0x7578AE66004DDBE1, 0x05833F01067BE646,
+ 0xBB34B5AD3BFE586D, 0x095F34C9A12B97F0, 0x247AB64525D60CA8,
+ 0xDCDBC6F3017477D1, 0x4A2E14D4DECAD24D, 0xBDB5E6D9BE0A1EEB,
+ 0x2A7E70F7794301AB, 0xDEF42D8A270540FD, 0x01078EC0A34C22C1,
+ 0xE5DE511AF4C16387, 0x7EBB3A52BD9A330A, 0x77697857AA7D6435,
+ 0x004E831603AE4C32, 0xE7A21020AD78E312, 0x9D41A70C6AB420F2,
+ 0x28E06C18EA1141E6, 0xD2B28CBD984F6B28, 0x26B75F6C446E9D83,
+ 0xBA47568C4D418D7F, 0xD80BADBFE6183D8E, 0x0E206D7F5F166044,
+ 0xE258A43911CBCA3E, 0x723A1746B21DC0BC, 0xC7CAA854F5D7CDD3,
+ 0x7CAC32883D261D9C, 0x7690C26423BA942C, 0x17E55524478042B8,
+ 0xE0BE477656A2389F, 0x4D289B5E67AB2DA0, 0x44862B9C8FBBFD31,
+ 0xB47CC8049D141365, 0x822C1B362B91C793, 0x4EB14655FB13DFD8,
+ 0x1ECBBA0714E2A97B, 0x6143459D5CDE5F14, 0x53A8FBF1D5F0AC89,
+ 0x97EA04D81C5E5B00, 0x622181A8D4FDB3F3, 0xE9BCD341572A1208,
+ 0x1411258643CCE58A, 0x9144C5FEA4C6E0A4, 0x0D33D06565CF620F,
+ 0x54A48D489F219CA1, 0xC43E5EAC6D63C821, 0xA9728B3A72770DAF,
+ 0xD7934E7B20DF87EF, 0xE35503B61A3E86E5, 0xCAE321FBC819D504,
+ 0x129A50B3AC60BFA6, 0xCD5E68EA7E9FB6C3, 0xB01C90199483B1C7,
+ 0x3DE93CD5C295376C, 0xAED52EDF2AB9AD13, 0x2E60F512C0A07884,
+ 0xBC3D86A3E36210C9, 0x35269D9B163951CE, 0x0C7D6E2AD0CDB5FA,
+ 0x59E86297D87F5733, 0x298EF221898DB0E7, 0x55000029D1A5AA7E,
+ 0x8BC08AE1B5061B45, 0xC2C31C2B6C92703A, 0x94CC596BAF25EF42,
+ 0x0A1D73DB22540456, 0x04B6A0F9D9C4179A, 0xEFFDAFA2AE3D3C60,
+ 0xF7C8075BB49496C4, 0x9CC5C7141D1CD4E3, 0x78BD1638218E5534,
+ 0xB2F11568F850246A, 0xEDFABCFA9502BC29, 0x796CE5F2DA23051B,
+ 0xAAE128B0DC93537C, 0x3A493DA0EE4B29AE, 0xB5DF6B2C416895D7,
+ 0xFCABBD25122D7F37, 0x70810B58105DC4B1, 0xE10FDD37F7882A90,
+ 0x524DCAB5518A3F5C, 0x3C9E85878451255B, 0x4029828119BD34E2,
+ 0x74A05B6F5D3CECCB, 0xB610021542E13ECA, 0x0FF979D12F59E2AC,
+ 0x6037DA27E4F9CC50, 0x5E92975A0DF1847D, 0xD66DE190D3E623FE,
+ 0x5032D6B87B568048, 0x9A36B7CE8235216E, 0x80272A7A24F64B4A,
+ 0x93EFED8B8C6916F7, 0x37DDBFF44CCE1555, 0x4B95DB5D4B99BD25,
+ 0x92D3FDA169812FC0, 0xFB1A4A9A90660BB6, 0x730C196946A4B9B2,
+ 0x81E289AA7F49DA68, 0x64669A0F83B1A05F, 0x27B3FF7D9644F48B,
+ 0xCC6B615C8DB675B3, 0x674F20B9BCEBBE95, 0x6F31238275655982,
+ 0x5AE488713E45CF05, 0xBF619F9954C21157, 0xEABAC46040A8EAE9,
+ 0x454C6FE9F2C0C1CD, 0x419CF6496412691C, 0xD3DC3BEF265B0F70,
+ 0x6D0E60F5C3578A9E };
+
+const u64bit Tiger::SBOX4[256] = {
+ 0x5B0E608526323C55, 0x1A46C1A9FA1B59F5, 0xA9E245A17C4C8FFA,
+ 0x65CA5159DB2955D7, 0x05DB0A76CE35AFC2, 0x81EAC77EA9113D45,
+ 0x528EF88AB6AC0A0D, 0xA09EA253597BE3FF, 0x430DDFB3AC48CD56,
+ 0xC4B3A67AF45CE46F, 0x4ECECFD8FBE2D05E, 0x3EF56F10B39935F0,
+ 0x0B22D6829CD619C6, 0x17FD460A74DF2069, 0x6CF8CC8E8510ED40,
+ 0xD6C824BF3A6ECAA7, 0x61243D581A817049, 0x048BACB6BBC163A2,
+ 0xD9A38AC27D44CC32, 0x7FDDFF5BAAF410AB, 0xAD6D495AA804824B,
+ 0xE1A6A74F2D8C9F94, 0xD4F7851235DEE8E3, 0xFD4B7F886540D893,
+ 0x247C20042AA4BFDA, 0x096EA1C517D1327C, 0xD56966B4361A6685,
+ 0x277DA5C31221057D, 0x94D59893A43ACFF7, 0x64F0C51CCDC02281,
+ 0x3D33BCC4FF6189DB, 0xE005CB184CE66AF1, 0xFF5CCD1D1DB99BEA,
+ 0xB0B854A7FE42980F, 0x7BD46A6A718D4B9F, 0xD10FA8CC22A5FD8C,
+ 0xD31484952BE4BD31, 0xC7FA975FCB243847, 0x4886ED1E5846C407,
+ 0x28CDDB791EB70B04, 0xC2B00BE2F573417F, 0x5C9590452180F877,
+ 0x7A6BDDFFF370EB00, 0xCE509E38D6D9D6A4, 0xEBEB0F00647FA702,
+ 0x1DCC06CF76606F06, 0xE4D9F28BA286FF0A, 0xD85A305DC918C262,
+ 0x475B1D8732225F54, 0x2D4FB51668CCB5FE, 0xA679B9D9D72BBA20,
+ 0x53841C0D912D43A5, 0x3B7EAA48BF12A4E8, 0x781E0E47F22F1DDF,
+ 0xEFF20CE60AB50973, 0x20D261D19DFFB742, 0x16A12B03062A2E39,
+ 0x1960EB2239650495, 0x251C16FED50EB8B8, 0x9AC0C330F826016E,
+ 0xED152665953E7671, 0x02D63194A6369570, 0x5074F08394B1C987,
+ 0x70BA598C90B25CE1, 0x794A15810B9742F6, 0x0D5925E9FCAF8C6C,
+ 0x3067716CD868744E, 0x910AB077E8D7731B, 0x6A61BBDB5AC42F61,
+ 0x93513EFBF0851567, 0xF494724B9E83E9D5, 0xE887E1985C09648D,
+ 0x34B1D3C675370CFD, 0xDC35E433BC0D255D, 0xD0AAB84234131BE0,
+ 0x08042A50B48B7EAF, 0x9997C4EE44A3AB35, 0x829A7B49201799D0,
+ 0x263B8307B7C54441, 0x752F95F4FD6A6CA6, 0x927217402C08C6E5,
+ 0x2A8AB754A795D9EE, 0xA442F7552F72943D, 0x2C31334E19781208,
+ 0x4FA98D7CEAEE6291, 0x55C3862F665DB309, 0xBD0610175D53B1F3,
+ 0x46FE6CB840413F27, 0x3FE03792DF0CFA59, 0xCFE700372EB85E8F,
+ 0xA7BE29E7ADBCE118, 0xE544EE5CDE8431DD, 0x8A781B1B41F1873E,
+ 0xA5C94C78A0D2F0E7, 0x39412E2877B60728, 0xA1265EF3AFC9A62C,
+ 0xBCC2770C6A2506C5, 0x3AB66DD5DCE1CE12, 0xE65499D04A675B37,
+ 0x7D8F523481BFD216, 0x0F6F64FCEC15F389, 0x74EFBE618B5B13C8,
+ 0xACDC82B714273E1D, 0xDD40BFE003199D17, 0x37E99257E7E061F8,
+ 0xFA52626904775AAA, 0x8BBBF63A463D56F9, 0xF0013F1543A26E64,
+ 0xA8307E9F879EC898, 0xCC4C27A4150177CC, 0x1B432F2CCA1D3348,
+ 0xDE1D1F8F9F6FA013, 0x606602A047A7DDD6, 0xD237AB64CC1CB2C7,
+ 0x9B938E7225FCD1D3, 0xEC4E03708E0FF476, 0xFEB2FBDA3D03C12D,
+ 0xAE0BCED2EE43889A, 0x22CB8923EBFB4F43, 0x69360D013CF7396D,
+ 0x855E3602D2D4E022, 0x073805BAD01F784C, 0x33E17A133852F546,
+ 0xDF4874058AC7B638, 0xBA92B29C678AA14A, 0x0CE89FC76CFAADCD,
+ 0x5F9D4E0908339E34, 0xF1AFE9291F5923B9, 0x6E3480F60F4A265F,
+ 0xEEBF3A2AB29B841C, 0xE21938A88F91B4AD, 0x57DFEFF845C6D3C3,
+ 0x2F006B0BF62CAAF2, 0x62F479EF6F75EE78, 0x11A55AD41C8916A9,
+ 0xF229D29084FED453, 0x42F1C27B16B000E6, 0x2B1F76749823C074,
+ 0x4B76ECA3C2745360, 0x8C98F463B91691BD, 0x14BCC93CF1ADE66A,
+ 0x8885213E6D458397, 0x8E177DF0274D4711, 0xB49B73B5503F2951,
+ 0x10168168C3F96B6B, 0x0E3D963B63CAB0AE, 0x8DFC4B5655A1DB14,
+ 0xF789F1356E14DE5C, 0x683E68AF4E51DAC1, 0xC9A84F9D8D4B0FD9,
+ 0x3691E03F52A0F9D1, 0x5ED86E46E1878E80, 0x3C711A0E99D07150,
+ 0x5A0865B20C4E9310, 0x56FBFC1FE4F0682E, 0xEA8D5DE3105EDF9B,
+ 0x71ABFDB12379187A, 0x2EB99DE1BEE77B9C, 0x21ECC0EA33CF4523,
+ 0x59A4D7521805C7A1, 0x3896F5EB56AE7C72, 0xAA638F3DB18F75DC,
+ 0x9F39358DABE9808E, 0xB7DEFA91C00B72AC, 0x6B5541FD62492D92,
+ 0x6DC6DEE8F92E4D5B, 0x353F57ABC4BEEA7E, 0x735769D6DA5690CE,
+ 0x0A234AA642391484, 0xF6F9508028F80D9D, 0xB8E319A27AB3F215,
+ 0x31AD9C1151341A4D, 0x773C22A57BEF5805, 0x45C7561A07968633,
+ 0xF913DA9E249DBE36, 0xDA652D9B78A64C68, 0x4C27A97F3BC334EF,
+ 0x76621220E66B17F4, 0x967743899ACD7D0B, 0xF3EE5BCAE0ED6782,
+ 0x409F753600C879FC, 0x06D09A39B5926DB6, 0x6F83AEB0317AC588,
+ 0x01E6CA4A86381F21, 0x66FF3462D19F3025, 0x72207C24DDFD3BFB,
+ 0x4AF6B6D3E2ECE2EB, 0x9C994DBEC7EA08DE, 0x49ACE597B09A8BC4,
+ 0xB38C4766CF0797BA, 0x131B9373C57C2A75, 0xB1822CCE61931E58,
+ 0x9D7555B909BA1C0C, 0x127FAFDD937D11D2, 0x29DA3BADC66D92E4,
+ 0xA2C1D57154C2ECBC, 0x58C5134D82F6FE24, 0x1C3AE3515B62274F,
+ 0xE907C82E01CB8126, 0xF8ED091913E37FCB, 0x3249D8F9C80046C9,
+ 0x80CF9BEDE388FB63, 0x1881539A116CF19E, 0x5103F3F76BD52457,
+ 0x15B7E6F5AE47F7A8, 0xDBD7C6DED47E9CCF, 0x44E55C410228BB1A,
+ 0xB647D4255EDB4E99, 0x5D11882BB8AAFC30, 0xF5098BBB29D3212A,
+ 0x8FB5EA14E90296B3, 0x677B942157DD025A, 0xFB58E7C0A390ACB5,
+ 0x89D3674C83BD4A01, 0x9E2DA4DF4BF3B93B, 0xFCC41E328CAB4829,
+ 0x03F38C96BA582C52, 0xCAD1BDBD7FD85DB2, 0xBBB442C16082AE83,
+ 0xB95FE86BA5DA9AB0, 0xB22E04673771A93F, 0x845358C9493152D8,
+ 0xBE2A488697B4541E, 0x95A2DC2DD38E6966, 0xC02C11AC923C852B,
+ 0x2388B1990DF2A87B, 0x7C8008FA1B4F37BE, 0x1F70D0C84D54E503,
+ 0x5490ADEC7ECE57D4, 0x002B3C27D9063A3A, 0x7EAEA3848030A2BF,
+ 0xC602326DED2003C0, 0x83A7287D69A94086, 0xC57A5FCB30F57A8A,
+ 0xB56844E479EBE779, 0xA373B40F05DCBCE9, 0xD71A786E88570EE2,
+ 0x879CBACDBDE8F6A0, 0x976AD1BCC164A32F, 0xAB21E25E9666D78B,
+ 0x901063AAE5E5C33C, 0x9818B34448698D90, 0xE36487AE3E1E8ABB,
+ 0xAFBDF931893BDCB4, 0x6345A0DC5FBBD519, 0x8628FE269B9465CA,
+ 0x1E5D01603F9C51EC, 0x4DE44006A15049B7, 0xBF6C70E5F776CBB1,
+ 0x411218F2EF552BED, 0xCB0C0708705A36A3, 0xE74D14754F986044,
+ 0xCD56D9430EA8280E, 0xC12591D7535F5065, 0xC83223F1720AEF96,
+ 0xC3A0396F7363A51F };
+
+}
diff --git a/src/lib/hash/tiger/tiger.cpp b/src/lib/hash/tiger/tiger.cpp
new file mode 100644
index 000000000..57250d6f5
--- /dev/null
+++ b/src/lib/hash/tiger/tiger.cpp
@@ -0,0 +1,187 @@
+/*
+* Tiger
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/tiger.h>
+#include <botan/exceptn.h>
+#include <botan/loadstor.h>
+#include <botan/parsing.h>
+
+namespace Botan {
+
+namespace {
+
+/*
+* Tiger Mixing Function
+*/
+inline void mix(secure_vector<u64bit>& X)
+ {
+ X[0] -= X[7] ^ 0xA5A5A5A5A5A5A5A5;
+ X[1] ^= X[0];
+ X[2] += X[1];
+ X[3] -= X[2] ^ ((~X[1]) << 19);
+ X[4] ^= X[3];
+ X[5] += X[4];
+ X[6] -= X[5] ^ ((~X[4]) >> 23);
+ X[7] ^= X[6];
+
+ X[0] += X[7];
+ X[1] -= X[0] ^ ((~X[7]) << 19);
+ X[2] ^= X[1];
+ X[3] += X[2];
+ X[4] -= X[3] ^ ((~X[2]) >> 23);
+ X[5] ^= X[4];
+ X[6] += X[5];
+ X[7] -= X[6] ^ 0x0123456789ABCDEF;
+ }
+
+}
+
+/*
+* Tiger Compression Function
+*/
+void Tiger::compress_n(const byte input[], size_t blocks)
+ {
+ u64bit A = digest[0], B = digest[1], C = digest[2];
+
+ for(size_t i = 0; i != blocks; ++i)
+ {
+ load_le(&X[0], input, X.size());
+
+ pass(A, B, C, X, 5); mix(X);
+ pass(C, A, B, X, 7); mix(X);
+ pass(B, C, A, X, 9);
+
+ for(size_t j = 3; j != passes; ++j)
+ {
+ mix(X);
+ pass(A, B, C, X, 9);
+ u64bit T = A; A = C; C = B; B = T;
+ }
+
+ A = (digest[0] ^= A);
+ B = digest[1] = B - digest[1];
+ C = (digest[2] += C);
+
+ input += hash_block_size();
+ }
+ }
+
+/*
+* Copy out the digest
+*/
+void Tiger::copy_out(byte output[])
+ {
+ for(size_t i = 0; i != output_length(); ++i)
+ output[i] = get_byte(7 - (i % 8), digest[i/8]);
+ }
+
+/*
+* Tiger Pass
+*/
+void Tiger::pass(u64bit& A, u64bit& B, u64bit& C,
+ const secure_vector<u64bit>& X,
+ byte mul)
+ {
+ C ^= X[0];
+ A -= SBOX1[get_byte(7, C)] ^ SBOX2[get_byte(5, C)] ^
+ SBOX3[get_byte(3, C)] ^ SBOX4[get_byte(1, C)];
+ B += SBOX1[get_byte(0, C)] ^ SBOX2[get_byte(2, C)] ^
+ SBOX3[get_byte(4, C)] ^ SBOX4[get_byte(6, C)];
+ B *= mul;
+
+ A ^= X[1];
+ B -= SBOX1[get_byte(7, A)] ^ SBOX2[get_byte(5, A)] ^
+ SBOX3[get_byte(3, A)] ^ SBOX4[get_byte(1, A)];
+ C += SBOX1[get_byte(0, A)] ^ SBOX2[get_byte(2, A)] ^
+ SBOX3[get_byte(4, A)] ^ SBOX4[get_byte(6, A)];
+ C *= mul;
+
+ B ^= X[2];
+ C -= SBOX1[get_byte(7, B)] ^ SBOX2[get_byte(5, B)] ^
+ SBOX3[get_byte(3, B)] ^ SBOX4[get_byte(1, B)];
+ A += SBOX1[get_byte(0, B)] ^ SBOX2[get_byte(2, B)] ^
+ SBOX3[get_byte(4, B)] ^ SBOX4[get_byte(6, B)];
+ A *= mul;
+
+ C ^= X[3];
+ A -= SBOX1[get_byte(7, C)] ^ SBOX2[get_byte(5, C)] ^
+ SBOX3[get_byte(3, C)] ^ SBOX4[get_byte(1, C)];
+ B += SBOX1[get_byte(0, C)] ^ SBOX2[get_byte(2, C)] ^
+ SBOX3[get_byte(4, C)] ^ SBOX4[get_byte(6, C)];
+ B *= mul;
+
+ A ^= X[4];
+ B -= SBOX1[get_byte(7, A)] ^ SBOX2[get_byte(5, A)] ^
+ SBOX3[get_byte(3, A)] ^ SBOX4[get_byte(1, A)];
+ C += SBOX1[get_byte(0, A)] ^ SBOX2[get_byte(2, A)] ^
+ SBOX3[get_byte(4, A)] ^ SBOX4[get_byte(6, A)];
+ C *= mul;
+
+ B ^= X[5];
+ C -= SBOX1[get_byte(7, B)] ^ SBOX2[get_byte(5, B)] ^
+ SBOX3[get_byte(3, B)] ^ SBOX4[get_byte(1, B)];
+ A += SBOX1[get_byte(0, B)] ^ SBOX2[get_byte(2, B)] ^
+ SBOX3[get_byte(4, B)] ^ SBOX4[get_byte(6, B)];
+ A *= mul;
+
+ C ^= X[6];
+ A -= SBOX1[get_byte(7, C)] ^ SBOX2[get_byte(5, C)] ^
+ SBOX3[get_byte(3, C)] ^ SBOX4[get_byte(1, C)];
+ B += SBOX1[get_byte(0, C)] ^ SBOX2[get_byte(2, C)] ^
+ SBOX3[get_byte(4, C)] ^ SBOX4[get_byte(6, C)];
+ B *= mul;
+
+ A ^= X[7];
+ B -= SBOX1[get_byte(7, A)] ^ SBOX2[get_byte(5, A)] ^
+ SBOX3[get_byte(3, A)] ^ SBOX4[get_byte(1, A)];
+ C += SBOX1[get_byte(0, A)] ^ SBOX2[get_byte(2, A)] ^
+ SBOX3[get_byte(4, A)] ^ SBOX4[get_byte(6, A)];
+ C *= mul;
+ }
+
+/*
+* Clear memory of sensitive data
+*/
+void Tiger::clear()
+ {
+ MDx_HashFunction::clear();
+ zeroise(X);
+ digest[0] = 0x0123456789ABCDEF;
+ digest[1] = 0xFEDCBA9876543210;
+ digest[2] = 0xF096A5B4C3B2E187;
+ }
+
+/*
+* Return the name of this type
+*/
+std::string Tiger::name() const
+ {
+ return "Tiger(" + std::to_string(output_length()) + "," +
+ std::to_string(passes) + ")";
+ }
+
+/*
+* Tiger Constructor
+*/
+Tiger::Tiger(size_t hash_len, size_t passes) :
+ MDx_HashFunction(64, false, false),
+ X(8),
+ digest(3),
+ hash_len(hash_len),
+ passes(passes)
+ {
+ if(output_length() != 16 && output_length() != 20 && output_length() != 24)
+ throw Invalid_Argument("Tiger: Illegal hash output size: " +
+ std::to_string(output_length()));
+
+ if(passes < 3)
+ throw Invalid_Argument("Tiger: Invalid number of passes: "
+ + std::to_string(passes));
+ clear();
+ }
+
+}
diff --git a/src/lib/hash/tiger/tiger.h b/src/lib/hash/tiger/tiger.h
new file mode 100644
index 000000000..70c70958b
--- /dev/null
+++ b/src/lib/hash/tiger/tiger.h
@@ -0,0 +1,55 @@
+/*
+* Tiger
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_TIGER_H__
+#define BOTAN_TIGER_H__
+
+#include <botan/mdx_hash.h>
+
+namespace Botan {
+
+/**
+* Tiger
+*/
+class BOTAN_DLL Tiger : public MDx_HashFunction
+ {
+ public:
+ std::string name() const;
+ size_t output_length() const { return hash_len; }
+
+ HashFunction* clone() const
+ {
+ return new Tiger(output_length(), passes);
+ }
+
+ void clear();
+
+ /**
+ * @param out_size specifies the output length; can be 16, 20, or 24
+ * @param passes to make in the algorithm
+ */
+ Tiger(size_t out_size = 24, size_t passes = 3);
+ private:
+ void compress_n(const byte[], size_t block);
+ void copy_out(byte[]);
+
+ static void pass(u64bit& A, u64bit& B, u64bit& C,
+ const secure_vector<u64bit>& M,
+ byte mul);
+
+ static const u64bit SBOX1[256];
+ static const u64bit SBOX2[256];
+ static const u64bit SBOX3[256];
+ static const u64bit SBOX4[256];
+
+ secure_vector<u64bit> X, digest;
+ const size_t hash_len, passes;
+ };
+
+}
+
+#endif
diff --git a/src/lib/hash/whirlpool/info.txt b/src/lib/hash/whirlpool/info.txt
new file mode 100644
index 000000000..8b0abc25a
--- /dev/null
+++ b/src/lib/hash/whirlpool/info.txt
@@ -0,0 +1,5 @@
+define WHIRLPOOL 20131128
+
+<requires>
+mdx_hash
+</requires>
diff --git a/src/lib/hash/whirlpool/whrl_tab.cpp b/src/lib/hash/whirlpool/whrl_tab.cpp
new file mode 100644
index 000000000..cf670f308
--- /dev/null
+++ b/src/lib/hash/whirlpool/whrl_tab.cpp
@@ -0,0 +1,540 @@
+/*
+* Diffusion Tables for Whirlpool
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/whrlpool.h>
+
+namespace Botan {
+
+const u64bit Whirlpool::C0[256] = {
+0x18186018C07830D8, 0x23238C2305AF4626, 0xC6C63FC67EF991B8, 0xE8E887E8136FCDFB,
+0x878726874CA113CB, 0xB8B8DAB8A9626D11, 0x0101040108050209, 0x4F4F214F426E9E0D,
+0x3636D836ADEE6C9B, 0xA6A6A2A6590451FF, 0xD2D26FD2DEBDB90C, 0xF5F5F3F5FB06F70E,
+0x7979F979EF80F296, 0x6F6FA16F5FCEDE30, 0x91917E91FCEF3F6D, 0x52525552AA07A4F8,
+0x60609D6027FDC047, 0xBCBCCABC89766535, 0x9B9B569BACCD2B37, 0x8E8E028E048C018A,
+0xA3A3B6A371155BD2, 0x0C0C300C603C186C, 0x7B7BF17BFF8AF684, 0x3535D435B5E16A80,
+0x1D1D741DE8693AF5, 0xE0E0A7E05347DDB3, 0xD7D77BD7F6ACB321, 0xC2C22FC25EED999C,
+0x2E2EB82E6D965C43, 0x4B4B314B627A9629, 0xFEFEDFFEA321E15D, 0x575741578216AED5,
+0x15155415A8412ABD, 0x7777C1779FB6EEE8, 0x3737DC37A5EB6E92, 0xE5E5B3E57B56D79E,
+0x9F9F469F8CD92313, 0xF0F0E7F0D317FD23, 0x4A4A354A6A7F9420, 0xDADA4FDA9E95A944,
+0x58587D58FA25B0A2, 0xC9C903C906CA8FCF, 0x2929A429558D527C, 0x0A0A280A5022145A,
+0xB1B1FEB1E14F7F50, 0xA0A0BAA0691A5DC9, 0x6B6BB16B7FDAD614, 0x85852E855CAB17D9,
+0xBDBDCEBD8173673C, 0x5D5D695DD234BA8F, 0x1010401080502090, 0xF4F4F7F4F303F507,
+0xCBCB0BCB16C08BDD, 0x3E3EF83EEDC67CD3, 0x0505140528110A2D, 0x676781671FE6CE78,
+0xE4E4B7E47353D597, 0x27279C2725BB4E02, 0x4141194132588273, 0x8B8B168B2C9D0BA7,
+0xA7A7A6A7510153F6, 0x7D7DE97DCF94FAB2, 0x95956E95DCFB3749, 0xD8D847D88E9FAD56,
+0xFBFBCBFB8B30EB70, 0xEEEE9FEE2371C1CD, 0x7C7CED7CC791F8BB, 0x6666856617E3CC71,
+0xDDDD53DDA68EA77B, 0x17175C17B84B2EAF, 0x4747014702468E45, 0x9E9E429E84DC211A,
+0xCACA0FCA1EC589D4, 0x2D2DB42D75995A58, 0xBFBFC6BF9179632E, 0x07071C07381B0E3F,
+0xADAD8EAD012347AC, 0x5A5A755AEA2FB4B0, 0x838336836CB51BEF, 0x3333CC3385FF66B6,
+0x636391633FF2C65C, 0x02020802100A0412, 0xAAAA92AA39384993, 0x7171D971AFA8E2DE,
+0xC8C807C80ECF8DC6, 0x19196419C87D32D1, 0x494939497270923B, 0xD9D943D9869AAF5F,
+0xF2F2EFF2C31DF931, 0xE3E3ABE34B48DBA8, 0x5B5B715BE22AB6B9, 0x88881A8834920DBC,
+0x9A9A529AA4C8293E, 0x262698262DBE4C0B, 0x3232C8328DFA64BF, 0xB0B0FAB0E94A7D59,
+0xE9E983E91B6ACFF2, 0x0F0F3C0F78331E77, 0xD5D573D5E6A6B733, 0x80803A8074BA1DF4,
+0xBEBEC2BE997C6127, 0xCDCD13CD26DE87EB, 0x3434D034BDE46889, 0x48483D487A759032,
+0xFFFFDBFFAB24E354, 0x7A7AF57AF78FF48D, 0x90907A90F4EA3D64, 0x5F5F615FC23EBE9D,
+0x202080201DA0403D, 0x6868BD6867D5D00F, 0x1A1A681AD07234CA, 0xAEAE82AE192C41B7,
+0xB4B4EAB4C95E757D, 0x54544D549A19A8CE, 0x93937693ECE53B7F, 0x222288220DAA442F,
+0x64648D6407E9C863, 0xF1F1E3F1DB12FF2A, 0x7373D173BFA2E6CC, 0x12124812905A2482,
+0x40401D403A5D807A, 0x0808200840281048, 0xC3C32BC356E89B95, 0xECEC97EC337BC5DF,
+0xDBDB4BDB9690AB4D, 0xA1A1BEA1611F5FC0, 0x8D8D0E8D1C830791, 0x3D3DF43DF5C97AC8,
+0x97976697CCF1335B, 0x0000000000000000, 0xCFCF1BCF36D483F9, 0x2B2BAC2B4587566E,
+0x7676C57697B3ECE1, 0x8282328264B019E6, 0xD6D67FD6FEA9B128, 0x1B1B6C1BD87736C3,
+0xB5B5EEB5C15B7774, 0xAFAF86AF112943BE, 0x6A6AB56A77DFD41D, 0x50505D50BA0DA0EA,
+0x45450945124C8A57, 0xF3F3EBF3CB18FB38, 0x3030C0309DF060AD, 0xEFEF9BEF2B74C3C4,
+0x3F3FFC3FE5C37EDA, 0x55554955921CAAC7, 0xA2A2B2A2791059DB, 0xEAEA8FEA0365C9E9,
+0x656589650FECCA6A, 0xBABAD2BAB9686903, 0x2F2FBC2F65935E4A, 0xC0C027C04EE79D8E,
+0xDEDE5FDEBE81A160, 0x1C1C701CE06C38FC, 0xFDFDD3FDBB2EE746, 0x4D4D294D52649A1F,
+0x92927292E4E03976, 0x7575C9758FBCEAFA, 0x06061806301E0C36, 0x8A8A128A249809AE,
+0xB2B2F2B2F940794B, 0xE6E6BFE66359D185, 0x0E0E380E70361C7E, 0x1F1F7C1FF8633EE7,
+0x6262956237F7C455, 0xD4D477D4EEA3B53A, 0xA8A89AA829324D81, 0x96966296C4F43152,
+0xF9F9C3F99B3AEF62, 0xC5C533C566F697A3, 0x2525942535B14A10, 0x59597959F220B2AB,
+0x84842A8454AE15D0, 0x7272D572B7A7E4C5, 0x3939E439D5DD72EC, 0x4C4C2D4C5A619816,
+0x5E5E655ECA3BBC94, 0x7878FD78E785F09F, 0x3838E038DDD870E5, 0x8C8C0A8C14860598,
+0xD1D163D1C6B2BF17, 0xA5A5AEA5410B57E4, 0xE2E2AFE2434DD9A1, 0x616199612FF8C24E,
+0xB3B3F6B3F1457B42, 0x2121842115A54234, 0x9C9C4A9C94D62508, 0x1E1E781EF0663CEE,
+0x4343114322528661, 0xC7C73BC776FC93B1, 0xFCFCD7FCB32BE54F, 0x0404100420140824,
+0x51515951B208A2E3, 0x99995E99BCC72F25, 0x6D6DA96D4FC4DA22, 0x0D0D340D68391A65,
+0xFAFACFFA8335E979, 0xDFDF5BDFB684A369, 0x7E7EE57ED79BFCA9, 0x242490243DB44819,
+0x3B3BEC3BC5D776FE, 0xABAB96AB313D4B9A, 0xCECE1FCE3ED181F0, 0x1111441188552299,
+0x8F8F068F0C890383, 0x4E4E254E4A6B9C04, 0xB7B7E6B7D1517366, 0xEBEB8BEB0B60CBE0,
+0x3C3CF03CFDCC78C1, 0x81813E817CBF1FFD, 0x94946A94D4FE3540, 0xF7F7FBF7EB0CF31C,
+0xB9B9DEB9A1676F18, 0x13134C13985F268B, 0x2C2CB02C7D9C5851, 0xD3D36BD3D6B8BB05,
+0xE7E7BBE76B5CD38C, 0x6E6EA56E57CBDC39, 0xC4C437C46EF395AA, 0x03030C03180F061B,
+0x565645568A13ACDC, 0x44440D441A49885E, 0x7F7FE17FDF9EFEA0, 0xA9A99EA921374F88,
+0x2A2AA82A4D825467, 0xBBBBD6BBB16D6B0A, 0xC1C123C146E29F87, 0x53535153A202A6F1,
+0xDCDC57DCAE8BA572, 0x0B0B2C0B58271653, 0x9D9D4E9D9CD32701, 0x6C6CAD6C47C1D82B,
+0x3131C43195F562A4, 0x7474CD7487B9E8F3, 0xF6F6FFF6E309F115, 0x464605460A438C4C,
+0xACAC8AAC092645A5, 0x89891E893C970FB5, 0x14145014A04428B4, 0xE1E1A3E15B42DFBA,
+0x16165816B04E2CA6, 0x3A3AE83ACDD274F7, 0x6969B9696FD0D206, 0x09092409482D1241,
+0x7070DD70A7ADE0D7, 0xB6B6E2B6D954716F, 0xD0D067D0CEB7BD1E, 0xEDED93ED3B7EC7D6,
+0xCCCC17CC2EDB85E2, 0x424215422A578468, 0x98985A98B4C22D2C, 0xA4A4AAA4490E55ED,
+0x2828A0285D885075, 0x5C5C6D5CDA31B886, 0xF8F8C7F8933FED6B, 0x8686228644A411C2 };
+
+const u64bit Whirlpool::C1[256] = {
+0xD818186018C07830, 0x2623238C2305AF46, 0xB8C6C63FC67EF991, 0xFBE8E887E8136FCD,
+0xCB878726874CA113, 0x11B8B8DAB8A9626D, 0x0901010401080502, 0x0D4F4F214F426E9E,
+0x9B3636D836ADEE6C, 0xFFA6A6A2A6590451, 0x0CD2D26FD2DEBDB9, 0x0EF5F5F3F5FB06F7,
+0x967979F979EF80F2, 0x306F6FA16F5FCEDE, 0x6D91917E91FCEF3F, 0xF852525552AA07A4,
+0x4760609D6027FDC0, 0x35BCBCCABC897665, 0x379B9B569BACCD2B, 0x8A8E8E028E048C01,
+0xD2A3A3B6A371155B, 0x6C0C0C300C603C18, 0x847B7BF17BFF8AF6, 0x803535D435B5E16A,
+0xF51D1D741DE8693A, 0xB3E0E0A7E05347DD, 0x21D7D77BD7F6ACB3, 0x9CC2C22FC25EED99,
+0x432E2EB82E6D965C, 0x294B4B314B627A96, 0x5DFEFEDFFEA321E1, 0xD5575741578216AE,
+0xBD15155415A8412A, 0xE87777C1779FB6EE, 0x923737DC37A5EB6E, 0x9EE5E5B3E57B56D7,
+0x139F9F469F8CD923, 0x23F0F0E7F0D317FD, 0x204A4A354A6A7F94, 0x44DADA4FDA9E95A9,
+0xA258587D58FA25B0, 0xCFC9C903C906CA8F, 0x7C2929A429558D52, 0x5A0A0A280A502214,
+0x50B1B1FEB1E14F7F, 0xC9A0A0BAA0691A5D, 0x146B6BB16B7FDAD6, 0xD985852E855CAB17,
+0x3CBDBDCEBD817367, 0x8F5D5D695DD234BA, 0x9010104010805020, 0x07F4F4F7F4F303F5,
+0xDDCBCB0BCB16C08B, 0xD33E3EF83EEDC67C, 0x2D0505140528110A, 0x78676781671FE6CE,
+0x97E4E4B7E47353D5, 0x0227279C2725BB4E, 0x7341411941325882, 0xA78B8B168B2C9D0B,
+0xF6A7A7A6A7510153, 0xB27D7DE97DCF94FA, 0x4995956E95DCFB37, 0x56D8D847D88E9FAD,
+0x70FBFBCBFB8B30EB, 0xCDEEEE9FEE2371C1, 0xBB7C7CED7CC791F8, 0x716666856617E3CC,
+0x7BDDDD53DDA68EA7, 0xAF17175C17B84B2E, 0x454747014702468E, 0x1A9E9E429E84DC21,
+0xD4CACA0FCA1EC589, 0x582D2DB42D75995A, 0x2EBFBFC6BF917963, 0x3F07071C07381B0E,
+0xACADAD8EAD012347, 0xB05A5A755AEA2FB4, 0xEF838336836CB51B, 0xB63333CC3385FF66,
+0x5C636391633FF2C6, 0x1202020802100A04, 0x93AAAA92AA393849, 0xDE7171D971AFA8E2,
+0xC6C8C807C80ECF8D, 0xD119196419C87D32, 0x3B49493949727092, 0x5FD9D943D9869AAF,
+0x31F2F2EFF2C31DF9, 0xA8E3E3ABE34B48DB, 0xB95B5B715BE22AB6, 0xBC88881A8834920D,
+0x3E9A9A529AA4C829, 0x0B262698262DBE4C, 0xBF3232C8328DFA64, 0x59B0B0FAB0E94A7D,
+0xF2E9E983E91B6ACF, 0x770F0F3C0F78331E, 0x33D5D573D5E6A6B7, 0xF480803A8074BA1D,
+0x27BEBEC2BE997C61, 0xEBCDCD13CD26DE87, 0x893434D034BDE468, 0x3248483D487A7590,
+0x54FFFFDBFFAB24E3, 0x8D7A7AF57AF78FF4, 0x6490907A90F4EA3D, 0x9D5F5F615FC23EBE,
+0x3D202080201DA040, 0x0F6868BD6867D5D0, 0xCA1A1A681AD07234, 0xB7AEAE82AE192C41,
+0x7DB4B4EAB4C95E75, 0xCE54544D549A19A8, 0x7F93937693ECE53B, 0x2F222288220DAA44,
+0x6364648D6407E9C8, 0x2AF1F1E3F1DB12FF, 0xCC7373D173BFA2E6, 0x8212124812905A24,
+0x7A40401D403A5D80, 0x4808082008402810, 0x95C3C32BC356E89B, 0xDFECEC97EC337BC5,
+0x4DDBDB4BDB9690AB, 0xC0A1A1BEA1611F5F, 0x918D8D0E8D1C8307, 0xC83D3DF43DF5C97A,
+0x5B97976697CCF133, 0x0000000000000000, 0xF9CFCF1BCF36D483, 0x6E2B2BAC2B458756,
+0xE17676C57697B3EC, 0xE68282328264B019, 0x28D6D67FD6FEA9B1, 0xC31B1B6C1BD87736,
+0x74B5B5EEB5C15B77, 0xBEAFAF86AF112943, 0x1D6A6AB56A77DFD4, 0xEA50505D50BA0DA0,
+0x5745450945124C8A, 0x38F3F3EBF3CB18FB, 0xAD3030C0309DF060, 0xC4EFEF9BEF2B74C3,
+0xDA3F3FFC3FE5C37E, 0xC755554955921CAA, 0xDBA2A2B2A2791059, 0xE9EAEA8FEA0365C9,
+0x6A656589650FECCA, 0x03BABAD2BAB96869, 0x4A2F2FBC2F65935E, 0x8EC0C027C04EE79D,
+0x60DEDE5FDEBE81A1, 0xFC1C1C701CE06C38, 0x46FDFDD3FDBB2EE7, 0x1F4D4D294D52649A,
+0x7692927292E4E039, 0xFA7575C9758FBCEA, 0x3606061806301E0C, 0xAE8A8A128A249809,
+0x4BB2B2F2B2F94079, 0x85E6E6BFE66359D1, 0x7E0E0E380E70361C, 0xE71F1F7C1FF8633E,
+0x556262956237F7C4, 0x3AD4D477D4EEA3B5, 0x81A8A89AA829324D, 0x5296966296C4F431,
+0x62F9F9C3F99B3AEF, 0xA3C5C533C566F697, 0x102525942535B14A, 0xAB59597959F220B2,
+0xD084842A8454AE15, 0xC57272D572B7A7E4, 0xEC3939E439D5DD72, 0x164C4C2D4C5A6198,
+0x945E5E655ECA3BBC, 0x9F7878FD78E785F0, 0xE53838E038DDD870, 0x988C8C0A8C148605,
+0x17D1D163D1C6B2BF, 0xE4A5A5AEA5410B57, 0xA1E2E2AFE2434DD9, 0x4E616199612FF8C2,
+0x42B3B3F6B3F1457B, 0x342121842115A542, 0x089C9C4A9C94D625, 0xEE1E1E781EF0663C,
+0x6143431143225286, 0xB1C7C73BC776FC93, 0x4FFCFCD7FCB32BE5, 0x2404041004201408,
+0xE351515951B208A2, 0x2599995E99BCC72F, 0x226D6DA96D4FC4DA, 0x650D0D340D68391A,
+0x79FAFACFFA8335E9, 0x69DFDF5BDFB684A3, 0xA97E7EE57ED79BFC, 0x19242490243DB448,
+0xFE3B3BEC3BC5D776, 0x9AABAB96AB313D4B, 0xF0CECE1FCE3ED181, 0x9911114411885522,
+0x838F8F068F0C8903, 0x044E4E254E4A6B9C, 0x66B7B7E6B7D15173, 0xE0EBEB8BEB0B60CB,
+0xC13C3CF03CFDCC78, 0xFD81813E817CBF1F, 0x4094946A94D4FE35, 0x1CF7F7FBF7EB0CF3,
+0x18B9B9DEB9A1676F, 0x8B13134C13985F26, 0x512C2CB02C7D9C58, 0x05D3D36BD3D6B8BB,
+0x8CE7E7BBE76B5CD3, 0x396E6EA56E57CBDC, 0xAAC4C437C46EF395, 0x1B03030C03180F06,
+0xDC565645568A13AC, 0x5E44440D441A4988, 0xA07F7FE17FDF9EFE, 0x88A9A99EA921374F,
+0x672A2AA82A4D8254, 0x0ABBBBD6BBB16D6B, 0x87C1C123C146E29F, 0xF153535153A202A6,
+0x72DCDC57DCAE8BA5, 0x530B0B2C0B582716, 0x019D9D4E9D9CD327, 0x2B6C6CAD6C47C1D8,
+0xA43131C43195F562, 0xF37474CD7487B9E8, 0x15F6F6FFF6E309F1, 0x4C464605460A438C,
+0xA5ACAC8AAC092645, 0xB589891E893C970F, 0xB414145014A04428, 0xBAE1E1A3E15B42DF,
+0xA616165816B04E2C, 0xF73A3AE83ACDD274, 0x066969B9696FD0D2, 0x4109092409482D12,
+0xD77070DD70A7ADE0, 0x6FB6B6E2B6D95471, 0x1ED0D067D0CEB7BD, 0xD6EDED93ED3B7EC7,
+0xE2CCCC17CC2EDB85, 0x68424215422A5784, 0x2C98985A98B4C22D, 0xEDA4A4AAA4490E55,
+0x752828A0285D8850, 0x865C5C6D5CDA31B8, 0x6BF8F8C7F8933FED, 0xC28686228644A411 };
+
+const u64bit Whirlpool::C2[256] = {
+0x30D818186018C078, 0x462623238C2305AF, 0x91B8C6C63FC67EF9, 0xCDFBE8E887E8136F,
+0x13CB878726874CA1, 0x6D11B8B8DAB8A962, 0x0209010104010805, 0x9E0D4F4F214F426E,
+0x6C9B3636D836ADEE, 0x51FFA6A6A2A65904, 0xB90CD2D26FD2DEBD, 0xF70EF5F5F3F5FB06,
+0xF2967979F979EF80, 0xDE306F6FA16F5FCE, 0x3F6D91917E91FCEF, 0xA4F852525552AA07,
+0xC04760609D6027FD, 0x6535BCBCCABC8976, 0x2B379B9B569BACCD, 0x018A8E8E028E048C,
+0x5BD2A3A3B6A37115, 0x186C0C0C300C603C, 0xF6847B7BF17BFF8A, 0x6A803535D435B5E1,
+0x3AF51D1D741DE869, 0xDDB3E0E0A7E05347, 0xB321D7D77BD7F6AC, 0x999CC2C22FC25EED,
+0x5C432E2EB82E6D96, 0x96294B4B314B627A, 0xE15DFEFEDFFEA321, 0xAED5575741578216,
+0x2ABD15155415A841, 0xEEE87777C1779FB6, 0x6E923737DC37A5EB, 0xD79EE5E5B3E57B56,
+0x23139F9F469F8CD9, 0xFD23F0F0E7F0D317, 0x94204A4A354A6A7F, 0xA944DADA4FDA9E95,
+0xB0A258587D58FA25, 0x8FCFC9C903C906CA, 0x527C2929A429558D, 0x145A0A0A280A5022,
+0x7F50B1B1FEB1E14F, 0x5DC9A0A0BAA0691A, 0xD6146B6BB16B7FDA, 0x17D985852E855CAB,
+0x673CBDBDCEBD8173, 0xBA8F5D5D695DD234, 0x2090101040108050, 0xF507F4F4F7F4F303,
+0x8BDDCBCB0BCB16C0, 0x7CD33E3EF83EEDC6, 0x0A2D050514052811, 0xCE78676781671FE6,
+0xD597E4E4B7E47353, 0x4E0227279C2725BB, 0x8273414119413258, 0x0BA78B8B168B2C9D,
+0x53F6A7A7A6A75101, 0xFAB27D7DE97DCF94, 0x374995956E95DCFB, 0xAD56D8D847D88E9F,
+0xEB70FBFBCBFB8B30, 0xC1CDEEEE9FEE2371, 0xF8BB7C7CED7CC791, 0xCC716666856617E3,
+0xA77BDDDD53DDA68E, 0x2EAF17175C17B84B, 0x8E45474701470246, 0x211A9E9E429E84DC,
+0x89D4CACA0FCA1EC5, 0x5A582D2DB42D7599, 0x632EBFBFC6BF9179, 0x0E3F07071C07381B,
+0x47ACADAD8EAD0123, 0xB4B05A5A755AEA2F, 0x1BEF838336836CB5, 0x66B63333CC3385FF,
+0xC65C636391633FF2, 0x041202020802100A, 0x4993AAAA92AA3938, 0xE2DE7171D971AFA8,
+0x8DC6C8C807C80ECF, 0x32D119196419C87D, 0x923B494939497270, 0xAF5FD9D943D9869A,
+0xF931F2F2EFF2C31D, 0xDBA8E3E3ABE34B48, 0xB6B95B5B715BE22A, 0x0DBC88881A883492,
+0x293E9A9A529AA4C8, 0x4C0B262698262DBE, 0x64BF3232C8328DFA, 0x7D59B0B0FAB0E94A,
+0xCFF2E9E983E91B6A, 0x1E770F0F3C0F7833, 0xB733D5D573D5E6A6, 0x1DF480803A8074BA,
+0x6127BEBEC2BE997C, 0x87EBCDCD13CD26DE, 0x68893434D034BDE4, 0x903248483D487A75,
+0xE354FFFFDBFFAB24, 0xF48D7A7AF57AF78F, 0x3D6490907A90F4EA, 0xBE9D5F5F615FC23E,
+0x403D202080201DA0, 0xD00F6868BD6867D5, 0x34CA1A1A681AD072, 0x41B7AEAE82AE192C,
+0x757DB4B4EAB4C95E, 0xA8CE54544D549A19, 0x3B7F93937693ECE5, 0x442F222288220DAA,
+0xC86364648D6407E9, 0xFF2AF1F1E3F1DB12, 0xE6CC7373D173BFA2, 0x248212124812905A,
+0x807A40401D403A5D, 0x1048080820084028, 0x9B95C3C32BC356E8, 0xC5DFECEC97EC337B,
+0xAB4DDBDB4BDB9690, 0x5FC0A1A1BEA1611F, 0x07918D8D0E8D1C83, 0x7AC83D3DF43DF5C9,
+0x335B97976697CCF1, 0x0000000000000000, 0x83F9CFCF1BCF36D4, 0x566E2B2BAC2B4587,
+0xECE17676C57697B3, 0x19E68282328264B0, 0xB128D6D67FD6FEA9, 0x36C31B1B6C1BD877,
+0x7774B5B5EEB5C15B, 0x43BEAFAF86AF1129, 0xD41D6A6AB56A77DF, 0xA0EA50505D50BA0D,
+0x8A5745450945124C, 0xFB38F3F3EBF3CB18, 0x60AD3030C0309DF0, 0xC3C4EFEF9BEF2B74,
+0x7EDA3F3FFC3FE5C3, 0xAAC755554955921C, 0x59DBA2A2B2A27910, 0xC9E9EAEA8FEA0365,
+0xCA6A656589650FEC, 0x6903BABAD2BAB968, 0x5E4A2F2FBC2F6593, 0x9D8EC0C027C04EE7,
+0xA160DEDE5FDEBE81, 0x38FC1C1C701CE06C, 0xE746FDFDD3FDBB2E, 0x9A1F4D4D294D5264,
+0x397692927292E4E0, 0xEAFA7575C9758FBC, 0x0C3606061806301E, 0x09AE8A8A128A2498,
+0x794BB2B2F2B2F940, 0xD185E6E6BFE66359, 0x1C7E0E0E380E7036, 0x3EE71F1F7C1FF863,
+0xC4556262956237F7, 0xB53AD4D477D4EEA3, 0x4D81A8A89AA82932, 0x315296966296C4F4,
+0xEF62F9F9C3F99B3A, 0x97A3C5C533C566F6, 0x4A102525942535B1, 0xB2AB59597959F220,
+0x15D084842A8454AE, 0xE4C57272D572B7A7, 0x72EC3939E439D5DD, 0x98164C4C2D4C5A61,
+0xBC945E5E655ECA3B, 0xF09F7878FD78E785, 0x70E53838E038DDD8, 0x05988C8C0A8C1486,
+0xBF17D1D163D1C6B2, 0x57E4A5A5AEA5410B, 0xD9A1E2E2AFE2434D, 0xC24E616199612FF8,
+0x7B42B3B3F6B3F145, 0x42342121842115A5, 0x25089C9C4A9C94D6, 0x3CEE1E1E781EF066,
+0x8661434311432252, 0x93B1C7C73BC776FC, 0xE54FFCFCD7FCB32B, 0x0824040410042014,
+0xA2E351515951B208, 0x2F2599995E99BCC7, 0xDA226D6DA96D4FC4, 0x1A650D0D340D6839,
+0xE979FAFACFFA8335, 0xA369DFDF5BDFB684, 0xFCA97E7EE57ED79B, 0x4819242490243DB4,
+0x76FE3B3BEC3BC5D7, 0x4B9AABAB96AB313D, 0x81F0CECE1FCE3ED1, 0x2299111144118855,
+0x03838F8F068F0C89, 0x9C044E4E254E4A6B, 0x7366B7B7E6B7D151, 0xCBE0EBEB8BEB0B60,
+0x78C13C3CF03CFDCC, 0x1FFD81813E817CBF, 0x354094946A94D4FE, 0xF31CF7F7FBF7EB0C,
+0x6F18B9B9DEB9A167, 0x268B13134C13985F, 0x58512C2CB02C7D9C, 0xBB05D3D36BD3D6B8,
+0xD38CE7E7BBE76B5C, 0xDC396E6EA56E57CB, 0x95AAC4C437C46EF3, 0x061B03030C03180F,
+0xACDC565645568A13, 0x885E44440D441A49, 0xFEA07F7FE17FDF9E, 0x4F88A9A99EA92137,
+0x54672A2AA82A4D82, 0x6B0ABBBBD6BBB16D, 0x9F87C1C123C146E2, 0xA6F153535153A202,
+0xA572DCDC57DCAE8B, 0x16530B0B2C0B5827, 0x27019D9D4E9D9CD3, 0xD82B6C6CAD6C47C1,
+0x62A43131C43195F5, 0xE8F37474CD7487B9, 0xF115F6F6FFF6E309, 0x8C4C464605460A43,
+0x45A5ACAC8AAC0926, 0x0FB589891E893C97, 0x28B414145014A044, 0xDFBAE1E1A3E15B42,
+0x2CA616165816B04E, 0x74F73A3AE83ACDD2, 0xD2066969B9696FD0, 0x124109092409482D,
+0xE0D77070DD70A7AD, 0x716FB6B6E2B6D954, 0xBD1ED0D067D0CEB7, 0xC7D6EDED93ED3B7E,
+0x85E2CCCC17CC2EDB, 0x8468424215422A57, 0x2D2C98985A98B4C2, 0x55EDA4A4AAA4490E,
+0x50752828A0285D88, 0xB8865C5C6D5CDA31, 0xED6BF8F8C7F8933F, 0x11C28686228644A4 };
+
+const u64bit Whirlpool::C3[256] = {
+0x7830D818186018C0, 0xAF462623238C2305, 0xF991B8C6C63FC67E, 0x6FCDFBE8E887E813,
+0xA113CB878726874C, 0x626D11B8B8DAB8A9, 0x0502090101040108, 0x6E9E0D4F4F214F42,
+0xEE6C9B3636D836AD, 0x0451FFA6A6A2A659, 0xBDB90CD2D26FD2DE, 0x06F70EF5F5F3F5FB,
+0x80F2967979F979EF, 0xCEDE306F6FA16F5F, 0xEF3F6D91917E91FC, 0x07A4F852525552AA,
+0xFDC04760609D6027, 0x766535BCBCCABC89, 0xCD2B379B9B569BAC, 0x8C018A8E8E028E04,
+0x155BD2A3A3B6A371, 0x3C186C0C0C300C60, 0x8AF6847B7BF17BFF, 0xE16A803535D435B5,
+0x693AF51D1D741DE8, 0x47DDB3E0E0A7E053, 0xACB321D7D77BD7F6, 0xED999CC2C22FC25E,
+0x965C432E2EB82E6D, 0x7A96294B4B314B62, 0x21E15DFEFEDFFEA3, 0x16AED55757415782,
+0x412ABD15155415A8, 0xB6EEE87777C1779F, 0xEB6E923737DC37A5, 0x56D79EE5E5B3E57B,
+0xD923139F9F469F8C, 0x17FD23F0F0E7F0D3, 0x7F94204A4A354A6A, 0x95A944DADA4FDA9E,
+0x25B0A258587D58FA, 0xCA8FCFC9C903C906, 0x8D527C2929A42955, 0x22145A0A0A280A50,
+0x4F7F50B1B1FEB1E1, 0x1A5DC9A0A0BAA069, 0xDAD6146B6BB16B7F, 0xAB17D985852E855C,
+0x73673CBDBDCEBD81, 0x34BA8F5D5D695DD2, 0x5020901010401080, 0x03F507F4F4F7F4F3,
+0xC08BDDCBCB0BCB16, 0xC67CD33E3EF83EED, 0x110A2D0505140528, 0xE6CE78676781671F,
+0x53D597E4E4B7E473, 0xBB4E0227279C2725, 0x5882734141194132, 0x9D0BA78B8B168B2C,
+0x0153F6A7A7A6A751, 0x94FAB27D7DE97DCF, 0xFB374995956E95DC, 0x9FAD56D8D847D88E,
+0x30EB70FBFBCBFB8B, 0x71C1CDEEEE9FEE23, 0x91F8BB7C7CED7CC7, 0xE3CC716666856617,
+0x8EA77BDDDD53DDA6, 0x4B2EAF17175C17B8, 0x468E454747014702, 0xDC211A9E9E429E84,
+0xC589D4CACA0FCA1E, 0x995A582D2DB42D75, 0x79632EBFBFC6BF91, 0x1B0E3F07071C0738,
+0x2347ACADAD8EAD01, 0x2FB4B05A5A755AEA, 0xB51BEF838336836C, 0xFF66B63333CC3385,
+0xF2C65C636391633F, 0x0A04120202080210, 0x384993AAAA92AA39, 0xA8E2DE7171D971AF,
+0xCF8DC6C8C807C80E, 0x7D32D119196419C8, 0x70923B4949394972, 0x9AAF5FD9D943D986,
+0x1DF931F2F2EFF2C3, 0x48DBA8E3E3ABE34B, 0x2AB6B95B5B715BE2, 0x920DBC88881A8834,
+0xC8293E9A9A529AA4, 0xBE4C0B262698262D, 0xFA64BF3232C8328D, 0x4A7D59B0B0FAB0E9,
+0x6ACFF2E9E983E91B, 0x331E770F0F3C0F78, 0xA6B733D5D573D5E6, 0xBA1DF480803A8074,
+0x7C6127BEBEC2BE99, 0xDE87EBCDCD13CD26, 0xE468893434D034BD, 0x75903248483D487A,
+0x24E354FFFFDBFFAB, 0x8FF48D7A7AF57AF7, 0xEA3D6490907A90F4, 0x3EBE9D5F5F615FC2,
+0xA0403D202080201D, 0xD5D00F6868BD6867, 0x7234CA1A1A681AD0, 0x2C41B7AEAE82AE19,
+0x5E757DB4B4EAB4C9, 0x19A8CE54544D549A, 0xE53B7F93937693EC, 0xAA442F222288220D,
+0xE9C86364648D6407, 0x12FF2AF1F1E3F1DB, 0xA2E6CC7373D173BF, 0x5A24821212481290,
+0x5D807A40401D403A, 0x2810480808200840, 0xE89B95C3C32BC356, 0x7BC5DFECEC97EC33,
+0x90AB4DDBDB4BDB96, 0x1F5FC0A1A1BEA161, 0x8307918D8D0E8D1C, 0xC97AC83D3DF43DF5,
+0xF1335B97976697CC, 0x0000000000000000, 0xD483F9CFCF1BCF36, 0x87566E2B2BAC2B45,
+0xB3ECE17676C57697, 0xB019E68282328264, 0xA9B128D6D67FD6FE, 0x7736C31B1B6C1BD8,
+0x5B7774B5B5EEB5C1, 0x2943BEAFAF86AF11, 0xDFD41D6A6AB56A77, 0x0DA0EA50505D50BA,
+0x4C8A574545094512, 0x18FB38F3F3EBF3CB, 0xF060AD3030C0309D, 0x74C3C4EFEF9BEF2B,
+0xC37EDA3F3FFC3FE5, 0x1CAAC75555495592, 0x1059DBA2A2B2A279, 0x65C9E9EAEA8FEA03,
+0xECCA6A656589650F, 0x686903BABAD2BAB9, 0x935E4A2F2FBC2F65, 0xE79D8EC0C027C04E,
+0x81A160DEDE5FDEBE, 0x6C38FC1C1C701CE0, 0x2EE746FDFDD3FDBB, 0x649A1F4D4D294D52,
+0xE0397692927292E4, 0xBCEAFA7575C9758F, 0x1E0C360606180630, 0x9809AE8A8A128A24,
+0x40794BB2B2F2B2F9, 0x59D185E6E6BFE663, 0x361C7E0E0E380E70, 0x633EE71F1F7C1FF8,
+0xF7C4556262956237, 0xA3B53AD4D477D4EE, 0x324D81A8A89AA829, 0xF4315296966296C4,
+0x3AEF62F9F9C3F99B, 0xF697A3C5C533C566, 0xB14A102525942535, 0x20B2AB59597959F2,
+0xAE15D084842A8454, 0xA7E4C57272D572B7, 0xDD72EC3939E439D5, 0x6198164C4C2D4C5A,
+0x3BBC945E5E655ECA, 0x85F09F7878FD78E7, 0xD870E53838E038DD, 0x8605988C8C0A8C14,
+0xB2BF17D1D163D1C6, 0x0B57E4A5A5AEA541, 0x4DD9A1E2E2AFE243, 0xF8C24E616199612F,
+0x457B42B3B3F6B3F1, 0xA542342121842115, 0xD625089C9C4A9C94, 0x663CEE1E1E781EF0,
+0x5286614343114322, 0xFC93B1C7C73BC776, 0x2BE54FFCFCD7FCB3, 0x1408240404100420,
+0x08A2E351515951B2, 0xC72F2599995E99BC, 0xC4DA226D6DA96D4F, 0x391A650D0D340D68,
+0x35E979FAFACFFA83, 0x84A369DFDF5BDFB6, 0x9BFCA97E7EE57ED7, 0xB44819242490243D,
+0xD776FE3B3BEC3BC5, 0x3D4B9AABAB96AB31, 0xD181F0CECE1FCE3E, 0x5522991111441188,
+0x8903838F8F068F0C, 0x6B9C044E4E254E4A, 0x517366B7B7E6B7D1, 0x60CBE0EBEB8BEB0B,
+0xCC78C13C3CF03CFD, 0xBF1FFD81813E817C, 0xFE354094946A94D4, 0x0CF31CF7F7FBF7EB,
+0x676F18B9B9DEB9A1, 0x5F268B13134C1398, 0x9C58512C2CB02C7D, 0xB8BB05D3D36BD3D6,
+0x5CD38CE7E7BBE76B, 0xCBDC396E6EA56E57, 0xF395AAC4C437C46E, 0x0F061B03030C0318,
+0x13ACDC565645568A, 0x49885E44440D441A, 0x9EFEA07F7FE17FDF, 0x374F88A9A99EA921,
+0x8254672A2AA82A4D, 0x6D6B0ABBBBD6BBB1, 0xE29F87C1C123C146, 0x02A6F153535153A2,
+0x8BA572DCDC57DCAE, 0x2716530B0B2C0B58, 0xD327019D9D4E9D9C, 0xC1D82B6C6CAD6C47,
+0xF562A43131C43195, 0xB9E8F37474CD7487, 0x09F115F6F6FFF6E3, 0x438C4C464605460A,
+0x2645A5ACAC8AAC09, 0x970FB589891E893C, 0x4428B414145014A0, 0x42DFBAE1E1A3E15B,
+0x4E2CA616165816B0, 0xD274F73A3AE83ACD, 0xD0D2066969B9696F, 0x2D12410909240948,
+0xADE0D77070DD70A7, 0x54716FB6B6E2B6D9, 0xB7BD1ED0D067D0CE, 0x7EC7D6EDED93ED3B,
+0xDB85E2CCCC17CC2E, 0x578468424215422A, 0xC22D2C98985A98B4, 0x0E55EDA4A4AAA449,
+0x8850752828A0285D, 0x31B8865C5C6D5CDA, 0x3FED6BF8F8C7F893, 0xA411C28686228644 };
+
+const u64bit Whirlpool::C4[256] = {
+0xC07830D818186018, 0x05AF462623238C23, 0x7EF991B8C6C63FC6, 0x136FCDFBE8E887E8,
+0x4CA113CB87872687, 0xA9626D11B8B8DAB8, 0x0805020901010401, 0x426E9E0D4F4F214F,
+0xADEE6C9B3636D836, 0x590451FFA6A6A2A6, 0xDEBDB90CD2D26FD2, 0xFB06F70EF5F5F3F5,
+0xEF80F2967979F979, 0x5FCEDE306F6FA16F, 0xFCEF3F6D91917E91, 0xAA07A4F852525552,
+0x27FDC04760609D60, 0x89766535BCBCCABC, 0xACCD2B379B9B569B, 0x048C018A8E8E028E,
+0x71155BD2A3A3B6A3, 0x603C186C0C0C300C, 0xFF8AF6847B7BF17B, 0xB5E16A803535D435,
+0xE8693AF51D1D741D, 0x5347DDB3E0E0A7E0, 0xF6ACB321D7D77BD7, 0x5EED999CC2C22FC2,
+0x6D965C432E2EB82E, 0x627A96294B4B314B, 0xA321E15DFEFEDFFE, 0x8216AED557574157,
+0xA8412ABD15155415, 0x9FB6EEE87777C177, 0xA5EB6E923737DC37, 0x7B56D79EE5E5B3E5,
+0x8CD923139F9F469F, 0xD317FD23F0F0E7F0, 0x6A7F94204A4A354A, 0x9E95A944DADA4FDA,
+0xFA25B0A258587D58, 0x06CA8FCFC9C903C9, 0x558D527C2929A429, 0x5022145A0A0A280A,
+0xE14F7F50B1B1FEB1, 0x691A5DC9A0A0BAA0, 0x7FDAD6146B6BB16B, 0x5CAB17D985852E85,
+0x8173673CBDBDCEBD, 0xD234BA8F5D5D695D, 0x8050209010104010, 0xF303F507F4F4F7F4,
+0x16C08BDDCBCB0BCB, 0xEDC67CD33E3EF83E, 0x28110A2D05051405, 0x1FE6CE7867678167,
+0x7353D597E4E4B7E4, 0x25BB4E0227279C27, 0x3258827341411941, 0x2C9D0BA78B8B168B,
+0x510153F6A7A7A6A7, 0xCF94FAB27D7DE97D, 0xDCFB374995956E95, 0x8E9FAD56D8D847D8,
+0x8B30EB70FBFBCBFB, 0x2371C1CDEEEE9FEE, 0xC791F8BB7C7CED7C, 0x17E3CC7166668566,
+0xA68EA77BDDDD53DD, 0xB84B2EAF17175C17, 0x02468E4547470147, 0x84DC211A9E9E429E,
+0x1EC589D4CACA0FCA, 0x75995A582D2DB42D, 0x9179632EBFBFC6BF, 0x381B0E3F07071C07,
+0x012347ACADAD8EAD, 0xEA2FB4B05A5A755A, 0x6CB51BEF83833683, 0x85FF66B63333CC33,
+0x3FF2C65C63639163, 0x100A041202020802, 0x39384993AAAA92AA, 0xAFA8E2DE7171D971,
+0x0ECF8DC6C8C807C8, 0xC87D32D119196419, 0x7270923B49493949, 0x869AAF5FD9D943D9,
+0xC31DF931F2F2EFF2, 0x4B48DBA8E3E3ABE3, 0xE22AB6B95B5B715B, 0x34920DBC88881A88,
+0xA4C8293E9A9A529A, 0x2DBE4C0B26269826, 0x8DFA64BF3232C832, 0xE94A7D59B0B0FAB0,
+0x1B6ACFF2E9E983E9, 0x78331E770F0F3C0F, 0xE6A6B733D5D573D5, 0x74BA1DF480803A80,
+0x997C6127BEBEC2BE, 0x26DE87EBCDCD13CD, 0xBDE468893434D034, 0x7A75903248483D48,
+0xAB24E354FFFFDBFF, 0xF78FF48D7A7AF57A, 0xF4EA3D6490907A90, 0xC23EBE9D5F5F615F,
+0x1DA0403D20208020, 0x67D5D00F6868BD68, 0xD07234CA1A1A681A, 0x192C41B7AEAE82AE,
+0xC95E757DB4B4EAB4, 0x9A19A8CE54544D54, 0xECE53B7F93937693, 0x0DAA442F22228822,
+0x07E9C86364648D64, 0xDB12FF2AF1F1E3F1, 0xBFA2E6CC7373D173, 0x905A248212124812,
+0x3A5D807A40401D40, 0x4028104808082008, 0x56E89B95C3C32BC3, 0x337BC5DFECEC97EC,
+0x9690AB4DDBDB4BDB, 0x611F5FC0A1A1BEA1, 0x1C8307918D8D0E8D, 0xF5C97AC83D3DF43D,
+0xCCF1335B97976697, 0x0000000000000000, 0x36D483F9CFCF1BCF, 0x4587566E2B2BAC2B,
+0x97B3ECE17676C576, 0x64B019E682823282, 0xFEA9B128D6D67FD6, 0xD87736C31B1B6C1B,
+0xC15B7774B5B5EEB5, 0x112943BEAFAF86AF, 0x77DFD41D6A6AB56A, 0xBA0DA0EA50505D50,
+0x124C8A5745450945, 0xCB18FB38F3F3EBF3, 0x9DF060AD3030C030, 0x2B74C3C4EFEF9BEF,
+0xE5C37EDA3F3FFC3F, 0x921CAAC755554955, 0x791059DBA2A2B2A2, 0x0365C9E9EAEA8FEA,
+0x0FECCA6A65658965, 0xB9686903BABAD2BA, 0x65935E4A2F2FBC2F, 0x4EE79D8EC0C027C0,
+0xBE81A160DEDE5FDE, 0xE06C38FC1C1C701C, 0xBB2EE746FDFDD3FD, 0x52649A1F4D4D294D,
+0xE4E0397692927292, 0x8FBCEAFA7575C975, 0x301E0C3606061806, 0x249809AE8A8A128A,
+0xF940794BB2B2F2B2, 0x6359D185E6E6BFE6, 0x70361C7E0E0E380E, 0xF8633EE71F1F7C1F,
+0x37F7C45562629562, 0xEEA3B53AD4D477D4, 0x29324D81A8A89AA8, 0xC4F4315296966296,
+0x9B3AEF62F9F9C3F9, 0x66F697A3C5C533C5, 0x35B14A1025259425, 0xF220B2AB59597959,
+0x54AE15D084842A84, 0xB7A7E4C57272D572, 0xD5DD72EC3939E439, 0x5A6198164C4C2D4C,
+0xCA3BBC945E5E655E, 0xE785F09F7878FD78, 0xDDD870E53838E038, 0x148605988C8C0A8C,
+0xC6B2BF17D1D163D1, 0x410B57E4A5A5AEA5, 0x434DD9A1E2E2AFE2, 0x2FF8C24E61619961,
+0xF1457B42B3B3F6B3, 0x15A5423421218421, 0x94D625089C9C4A9C, 0xF0663CEE1E1E781E,
+0x2252866143431143, 0x76FC93B1C7C73BC7, 0xB32BE54FFCFCD7FC, 0x2014082404041004,
+0xB208A2E351515951, 0xBCC72F2599995E99, 0x4FC4DA226D6DA96D, 0x68391A650D0D340D,
+0x8335E979FAFACFFA, 0xB684A369DFDF5BDF, 0xD79BFCA97E7EE57E, 0x3DB4481924249024,
+0xC5D776FE3B3BEC3B, 0x313D4B9AABAB96AB, 0x3ED181F0CECE1FCE, 0x8855229911114411,
+0x0C8903838F8F068F, 0x4A6B9C044E4E254E, 0xD1517366B7B7E6B7, 0x0B60CBE0EBEB8BEB,
+0xFDCC78C13C3CF03C, 0x7CBF1FFD81813E81, 0xD4FE354094946A94, 0xEB0CF31CF7F7FBF7,
+0xA1676F18B9B9DEB9, 0x985F268B13134C13, 0x7D9C58512C2CB02C, 0xD6B8BB05D3D36BD3,
+0x6B5CD38CE7E7BBE7, 0x57CBDC396E6EA56E, 0x6EF395AAC4C437C4, 0x180F061B03030C03,
+0x8A13ACDC56564556, 0x1A49885E44440D44, 0xDF9EFEA07F7FE17F, 0x21374F88A9A99EA9,
+0x4D8254672A2AA82A, 0xB16D6B0ABBBBD6BB, 0x46E29F87C1C123C1, 0xA202A6F153535153,
+0xAE8BA572DCDC57DC, 0x582716530B0B2C0B, 0x9CD327019D9D4E9D, 0x47C1D82B6C6CAD6C,
+0x95F562A43131C431, 0x87B9E8F37474CD74, 0xE309F115F6F6FFF6, 0x0A438C4C46460546,
+0x092645A5ACAC8AAC, 0x3C970FB589891E89, 0xA04428B414145014, 0x5B42DFBAE1E1A3E1,
+0xB04E2CA616165816, 0xCDD274F73A3AE83A, 0x6FD0D2066969B969, 0x482D124109092409,
+0xA7ADE0D77070DD70, 0xD954716FB6B6E2B6, 0xCEB7BD1ED0D067D0, 0x3B7EC7D6EDED93ED,
+0x2EDB85E2CCCC17CC, 0x2A57846842421542, 0xB4C22D2C98985A98, 0x490E55EDA4A4AAA4,
+0x5D8850752828A028, 0xDA31B8865C5C6D5C, 0x933FED6BF8F8C7F8, 0x44A411C286862286 };
+
+const u64bit Whirlpool::C5[256] = {
+0x18C07830D8181860, 0x2305AF462623238C, 0xC67EF991B8C6C63F, 0xE8136FCDFBE8E887,
+0x874CA113CB878726, 0xB8A9626D11B8B8DA, 0x0108050209010104, 0x4F426E9E0D4F4F21,
+0x36ADEE6C9B3636D8, 0xA6590451FFA6A6A2, 0xD2DEBDB90CD2D26F, 0xF5FB06F70EF5F5F3,
+0x79EF80F2967979F9, 0x6F5FCEDE306F6FA1, 0x91FCEF3F6D91917E, 0x52AA07A4F8525255,
+0x6027FDC04760609D, 0xBC89766535BCBCCA, 0x9BACCD2B379B9B56, 0x8E048C018A8E8E02,
+0xA371155BD2A3A3B6, 0x0C603C186C0C0C30, 0x7BFF8AF6847B7BF1, 0x35B5E16A803535D4,
+0x1DE8693AF51D1D74, 0xE05347DDB3E0E0A7, 0xD7F6ACB321D7D77B, 0xC25EED999CC2C22F,
+0x2E6D965C432E2EB8, 0x4B627A96294B4B31, 0xFEA321E15DFEFEDF, 0x578216AED5575741,
+0x15A8412ABD151554, 0x779FB6EEE87777C1, 0x37A5EB6E923737DC, 0xE57B56D79EE5E5B3,
+0x9F8CD923139F9F46, 0xF0D317FD23F0F0E7, 0x4A6A7F94204A4A35, 0xDA9E95A944DADA4F,
+0x58FA25B0A258587D, 0xC906CA8FCFC9C903, 0x29558D527C2929A4, 0x0A5022145A0A0A28,
+0xB1E14F7F50B1B1FE, 0xA0691A5DC9A0A0BA, 0x6B7FDAD6146B6BB1, 0x855CAB17D985852E,
+0xBD8173673CBDBDCE, 0x5DD234BA8F5D5D69, 0x1080502090101040, 0xF4F303F507F4F4F7,
+0xCB16C08BDDCBCB0B, 0x3EEDC67CD33E3EF8, 0x0528110A2D050514, 0x671FE6CE78676781,
+0xE47353D597E4E4B7, 0x2725BB4E0227279C, 0x4132588273414119, 0x8B2C9D0BA78B8B16,
+0xA7510153F6A7A7A6, 0x7DCF94FAB27D7DE9, 0x95DCFB374995956E, 0xD88E9FAD56D8D847,
+0xFB8B30EB70FBFBCB, 0xEE2371C1CDEEEE9F, 0x7CC791F8BB7C7CED, 0x6617E3CC71666685,
+0xDDA68EA77BDDDD53, 0x17B84B2EAF17175C, 0x4702468E45474701, 0x9E84DC211A9E9E42,
+0xCA1EC589D4CACA0F, 0x2D75995A582D2DB4, 0xBF9179632EBFBFC6, 0x07381B0E3F07071C,
+0xAD012347ACADAD8E, 0x5AEA2FB4B05A5A75, 0x836CB51BEF838336, 0x3385FF66B63333CC,
+0x633FF2C65C636391, 0x02100A0412020208, 0xAA39384993AAAA92, 0x71AFA8E2DE7171D9,
+0xC80ECF8DC6C8C807, 0x19C87D32D1191964, 0x497270923B494939, 0xD9869AAF5FD9D943,
+0xF2C31DF931F2F2EF, 0xE34B48DBA8E3E3AB, 0x5BE22AB6B95B5B71, 0x8834920DBC88881A,
+0x9AA4C8293E9A9A52, 0x262DBE4C0B262698, 0x328DFA64BF3232C8, 0xB0E94A7D59B0B0FA,
+0xE91B6ACFF2E9E983, 0x0F78331E770F0F3C, 0xD5E6A6B733D5D573, 0x8074BA1DF480803A,
+0xBE997C6127BEBEC2, 0xCD26DE87EBCDCD13, 0x34BDE468893434D0, 0x487A75903248483D,
+0xFFAB24E354FFFFDB, 0x7AF78FF48D7A7AF5, 0x90F4EA3D6490907A, 0x5FC23EBE9D5F5F61,
+0x201DA0403D202080, 0x6867D5D00F6868BD, 0x1AD07234CA1A1A68, 0xAE192C41B7AEAE82,
+0xB4C95E757DB4B4EA, 0x549A19A8CE54544D, 0x93ECE53B7F939376, 0x220DAA442F222288,
+0x6407E9C86364648D, 0xF1DB12FF2AF1F1E3, 0x73BFA2E6CC7373D1, 0x12905A2482121248,
+0x403A5D807A40401D, 0x0840281048080820, 0xC356E89B95C3C32B, 0xEC337BC5DFECEC97,
+0xDB9690AB4DDBDB4B, 0xA1611F5FC0A1A1BE, 0x8D1C8307918D8D0E, 0x3DF5C97AC83D3DF4,
+0x97CCF1335B979766, 0x0000000000000000, 0xCF36D483F9CFCF1B, 0x2B4587566E2B2BAC,
+0x7697B3ECE17676C5, 0x8264B019E6828232, 0xD6FEA9B128D6D67F, 0x1BD87736C31B1B6C,
+0xB5C15B7774B5B5EE, 0xAF112943BEAFAF86, 0x6A77DFD41D6A6AB5, 0x50BA0DA0EA50505D,
+0x45124C8A57454509, 0xF3CB18FB38F3F3EB, 0x309DF060AD3030C0, 0xEF2B74C3C4EFEF9B,
+0x3FE5C37EDA3F3FFC, 0x55921CAAC7555549, 0xA2791059DBA2A2B2, 0xEA0365C9E9EAEA8F,
+0x650FECCA6A656589, 0xBAB9686903BABAD2, 0x2F65935E4A2F2FBC, 0xC04EE79D8EC0C027,
+0xDEBE81A160DEDE5F, 0x1CE06C38FC1C1C70, 0xFDBB2EE746FDFDD3, 0x4D52649A1F4D4D29,
+0x92E4E03976929272, 0x758FBCEAFA7575C9, 0x06301E0C36060618, 0x8A249809AE8A8A12,
+0xB2F940794BB2B2F2, 0xE66359D185E6E6BF, 0x0E70361C7E0E0E38, 0x1FF8633EE71F1F7C,
+0x6237F7C455626295, 0xD4EEA3B53AD4D477, 0xA829324D81A8A89A, 0x96C4F43152969662,
+0xF99B3AEF62F9F9C3, 0xC566F697A3C5C533, 0x2535B14A10252594, 0x59F220B2AB595979,
+0x8454AE15D084842A, 0x72B7A7E4C57272D5, 0x39D5DD72EC3939E4, 0x4C5A6198164C4C2D,
+0x5ECA3BBC945E5E65, 0x78E785F09F7878FD, 0x38DDD870E53838E0, 0x8C148605988C8C0A,
+0xD1C6B2BF17D1D163, 0xA5410B57E4A5A5AE, 0xE2434DD9A1E2E2AF, 0x612FF8C24E616199,
+0xB3F1457B42B3B3F6, 0x2115A54234212184, 0x9C94D625089C9C4A, 0x1EF0663CEE1E1E78,
+0x4322528661434311, 0xC776FC93B1C7C73B, 0xFCB32BE54FFCFCD7, 0x0420140824040410,
+0x51B208A2E3515159, 0x99BCC72F2599995E, 0x6D4FC4DA226D6DA9, 0x0D68391A650D0D34,
+0xFA8335E979FAFACF, 0xDFB684A369DFDF5B, 0x7ED79BFCA97E7EE5, 0x243DB44819242490,
+0x3BC5D776FE3B3BEC, 0xAB313D4B9AABAB96, 0xCE3ED181F0CECE1F, 0x1188552299111144,
+0x8F0C8903838F8F06, 0x4E4A6B9C044E4E25, 0xB7D1517366B7B7E6, 0xEB0B60CBE0EBEB8B,
+0x3CFDCC78C13C3CF0, 0x817CBF1FFD81813E, 0x94D4FE354094946A, 0xF7EB0CF31CF7F7FB,
+0xB9A1676F18B9B9DE, 0x13985F268B13134C, 0x2C7D9C58512C2CB0, 0xD3D6B8BB05D3D36B,
+0xE76B5CD38CE7E7BB, 0x6E57CBDC396E6EA5, 0xC46EF395AAC4C437, 0x03180F061B03030C,
+0x568A13ACDC565645, 0x441A49885E44440D, 0x7FDF9EFEA07F7FE1, 0xA921374F88A9A99E,
+0x2A4D8254672A2AA8, 0xBBB16D6B0ABBBBD6, 0xC146E29F87C1C123, 0x53A202A6F1535351,
+0xDCAE8BA572DCDC57, 0x0B582716530B0B2C, 0x9D9CD327019D9D4E, 0x6C47C1D82B6C6CAD,
+0x3195F562A43131C4, 0x7487B9E8F37474CD, 0xF6E309F115F6F6FF, 0x460A438C4C464605,
+0xAC092645A5ACAC8A, 0x893C970FB589891E, 0x14A04428B4141450, 0xE15B42DFBAE1E1A3,
+0x16B04E2CA6161658, 0x3ACDD274F73A3AE8, 0x696FD0D2066969B9, 0x09482D1241090924,
+0x70A7ADE0D77070DD, 0xB6D954716FB6B6E2, 0xD0CEB7BD1ED0D067, 0xED3B7EC7D6EDED93,
+0xCC2EDB85E2CCCC17, 0x422A578468424215, 0x98B4C22D2C98985A, 0xA4490E55EDA4A4AA,
+0x285D8850752828A0, 0x5CDA31B8865C5C6D, 0xF8933FED6BF8F8C7, 0x8644A411C2868622 };
+
+const u64bit Whirlpool::C6[256] = {
+0x6018C07830D81818, 0x8C2305AF46262323, 0x3FC67EF991B8C6C6, 0x87E8136FCDFBE8E8,
+0x26874CA113CB8787, 0xDAB8A9626D11B8B8, 0x0401080502090101, 0x214F426E9E0D4F4F,
+0xD836ADEE6C9B3636, 0xA2A6590451FFA6A6, 0x6FD2DEBDB90CD2D2, 0xF3F5FB06F70EF5F5,
+0xF979EF80F2967979, 0xA16F5FCEDE306F6F, 0x7E91FCEF3F6D9191, 0x5552AA07A4F85252,
+0x9D6027FDC0476060, 0xCABC89766535BCBC, 0x569BACCD2B379B9B, 0x028E048C018A8E8E,
+0xB6A371155BD2A3A3, 0x300C603C186C0C0C, 0xF17BFF8AF6847B7B, 0xD435B5E16A803535,
+0x741DE8693AF51D1D, 0xA7E05347DDB3E0E0, 0x7BD7F6ACB321D7D7, 0x2FC25EED999CC2C2,
+0xB82E6D965C432E2E, 0x314B627A96294B4B, 0xDFFEA321E15DFEFE, 0x41578216AED55757,
+0x5415A8412ABD1515, 0xC1779FB6EEE87777, 0xDC37A5EB6E923737, 0xB3E57B56D79EE5E5,
+0x469F8CD923139F9F, 0xE7F0D317FD23F0F0, 0x354A6A7F94204A4A, 0x4FDA9E95A944DADA,
+0x7D58FA25B0A25858, 0x03C906CA8FCFC9C9, 0xA429558D527C2929, 0x280A5022145A0A0A,
+0xFEB1E14F7F50B1B1, 0xBAA0691A5DC9A0A0, 0xB16B7FDAD6146B6B, 0x2E855CAB17D98585,
+0xCEBD8173673CBDBD, 0x695DD234BA8F5D5D, 0x4010805020901010, 0xF7F4F303F507F4F4,
+0x0BCB16C08BDDCBCB, 0xF83EEDC67CD33E3E, 0x140528110A2D0505, 0x81671FE6CE786767,
+0xB7E47353D597E4E4, 0x9C2725BB4E022727, 0x1941325882734141, 0x168B2C9D0BA78B8B,
+0xA6A7510153F6A7A7, 0xE97DCF94FAB27D7D, 0x6E95DCFB37499595, 0x47D88E9FAD56D8D8,
+0xCBFB8B30EB70FBFB, 0x9FEE2371C1CDEEEE, 0xED7CC791F8BB7C7C, 0x856617E3CC716666,
+0x53DDA68EA77BDDDD, 0x5C17B84B2EAF1717, 0x014702468E454747, 0x429E84DC211A9E9E,
+0x0FCA1EC589D4CACA, 0xB42D75995A582D2D, 0xC6BF9179632EBFBF, 0x1C07381B0E3F0707,
+0x8EAD012347ACADAD, 0x755AEA2FB4B05A5A, 0x36836CB51BEF8383, 0xCC3385FF66B63333,
+0x91633FF2C65C6363, 0x0802100A04120202, 0x92AA39384993AAAA, 0xD971AFA8E2DE7171,
+0x07C80ECF8DC6C8C8, 0x6419C87D32D11919, 0x39497270923B4949, 0x43D9869AAF5FD9D9,
+0xEFF2C31DF931F2F2, 0xABE34B48DBA8E3E3, 0x715BE22AB6B95B5B, 0x1A8834920DBC8888,
+0x529AA4C8293E9A9A, 0x98262DBE4C0B2626, 0xC8328DFA64BF3232, 0xFAB0E94A7D59B0B0,
+0x83E91B6ACFF2E9E9, 0x3C0F78331E770F0F, 0x73D5E6A6B733D5D5, 0x3A8074BA1DF48080,
+0xC2BE997C6127BEBE, 0x13CD26DE87EBCDCD, 0xD034BDE468893434, 0x3D487A7590324848,
+0xDBFFAB24E354FFFF, 0xF57AF78FF48D7A7A, 0x7A90F4EA3D649090, 0x615FC23EBE9D5F5F,
+0x80201DA0403D2020, 0xBD6867D5D00F6868, 0x681AD07234CA1A1A, 0x82AE192C41B7AEAE,
+0xEAB4C95E757DB4B4, 0x4D549A19A8CE5454, 0x7693ECE53B7F9393, 0x88220DAA442F2222,
+0x8D6407E9C8636464, 0xE3F1DB12FF2AF1F1, 0xD173BFA2E6CC7373, 0x4812905A24821212,
+0x1D403A5D807A4040, 0x2008402810480808, 0x2BC356E89B95C3C3, 0x97EC337BC5DFECEC,
+0x4BDB9690AB4DDBDB, 0xBEA1611F5FC0A1A1, 0x0E8D1C8307918D8D, 0xF43DF5C97AC83D3D,
+0x6697CCF1335B9797, 0x0000000000000000, 0x1BCF36D483F9CFCF, 0xAC2B4587566E2B2B,
+0xC57697B3ECE17676, 0x328264B019E68282, 0x7FD6FEA9B128D6D6, 0x6C1BD87736C31B1B,
+0xEEB5C15B7774B5B5, 0x86AF112943BEAFAF, 0xB56A77DFD41D6A6A, 0x5D50BA0DA0EA5050,
+0x0945124C8A574545, 0xEBF3CB18FB38F3F3, 0xC0309DF060AD3030, 0x9BEF2B74C3C4EFEF,
+0xFC3FE5C37EDA3F3F, 0x4955921CAAC75555, 0xB2A2791059DBA2A2, 0x8FEA0365C9E9EAEA,
+0x89650FECCA6A6565, 0xD2BAB9686903BABA, 0xBC2F65935E4A2F2F, 0x27C04EE79D8EC0C0,
+0x5FDEBE81A160DEDE, 0x701CE06C38FC1C1C, 0xD3FDBB2EE746FDFD, 0x294D52649A1F4D4D,
+0x7292E4E039769292, 0xC9758FBCEAFA7575, 0x1806301E0C360606, 0x128A249809AE8A8A,
+0xF2B2F940794BB2B2, 0xBFE66359D185E6E6, 0x380E70361C7E0E0E, 0x7C1FF8633EE71F1F,
+0x956237F7C4556262, 0x77D4EEA3B53AD4D4, 0x9AA829324D81A8A8, 0x6296C4F431529696,
+0xC3F99B3AEF62F9F9, 0x33C566F697A3C5C5, 0x942535B14A102525, 0x7959F220B2AB5959,
+0x2A8454AE15D08484, 0xD572B7A7E4C57272, 0xE439D5DD72EC3939, 0x2D4C5A6198164C4C,
+0x655ECA3BBC945E5E, 0xFD78E785F09F7878, 0xE038DDD870E53838, 0x0A8C148605988C8C,
+0x63D1C6B2BF17D1D1, 0xAEA5410B57E4A5A5, 0xAFE2434DD9A1E2E2, 0x99612FF8C24E6161,
+0xF6B3F1457B42B3B3, 0x842115A542342121, 0x4A9C94D625089C9C, 0x781EF0663CEE1E1E,
+0x1143225286614343, 0x3BC776FC93B1C7C7, 0xD7FCB32BE54FFCFC, 0x1004201408240404,
+0x5951B208A2E35151, 0x5E99BCC72F259999, 0xA96D4FC4DA226D6D, 0x340D68391A650D0D,
+0xCFFA8335E979FAFA, 0x5BDFB684A369DFDF, 0xE57ED79BFCA97E7E, 0x90243DB448192424,
+0xEC3BC5D776FE3B3B, 0x96AB313D4B9AABAB, 0x1FCE3ED181F0CECE, 0x4411885522991111,
+0x068F0C8903838F8F, 0x254E4A6B9C044E4E, 0xE6B7D1517366B7B7, 0x8BEB0B60CBE0EBEB,
+0xF03CFDCC78C13C3C, 0x3E817CBF1FFD8181, 0x6A94D4FE35409494, 0xFBF7EB0CF31CF7F7,
+0xDEB9A1676F18B9B9, 0x4C13985F268B1313, 0xB02C7D9C58512C2C, 0x6BD3D6B8BB05D3D3,
+0xBBE76B5CD38CE7E7, 0xA56E57CBDC396E6E, 0x37C46EF395AAC4C4, 0x0C03180F061B0303,
+0x45568A13ACDC5656, 0x0D441A49885E4444, 0xE17FDF9EFEA07F7F, 0x9EA921374F88A9A9,
+0xA82A4D8254672A2A, 0xD6BBB16D6B0ABBBB, 0x23C146E29F87C1C1, 0x5153A202A6F15353,
+0x57DCAE8BA572DCDC, 0x2C0B582716530B0B, 0x4E9D9CD327019D9D, 0xAD6C47C1D82B6C6C,
+0xC43195F562A43131, 0xCD7487B9E8F37474, 0xFFF6E309F115F6F6, 0x05460A438C4C4646,
+0x8AAC092645A5ACAC, 0x1E893C970FB58989, 0x5014A04428B41414, 0xA3E15B42DFBAE1E1,
+0x5816B04E2CA61616, 0xE83ACDD274F73A3A, 0xB9696FD0D2066969, 0x2409482D12410909,
+0xDD70A7ADE0D77070, 0xE2B6D954716FB6B6, 0x67D0CEB7BD1ED0D0, 0x93ED3B7EC7D6EDED,
+0x17CC2EDB85E2CCCC, 0x15422A5784684242, 0x5A98B4C22D2C9898, 0xAAA4490E55EDA4A4,
+0xA0285D8850752828, 0x6D5CDA31B8865C5C, 0xC7F8933FED6BF8F8, 0x228644A411C28686 };
+
+const u64bit Whirlpool::C7[256] = {
+0x186018C07830D818, 0x238C2305AF462623, 0xC63FC67EF991B8C6, 0xE887E8136FCDFBE8,
+0x8726874CA113CB87, 0xB8DAB8A9626D11B8, 0x0104010805020901, 0x4F214F426E9E0D4F,
+0x36D836ADEE6C9B36, 0xA6A2A6590451FFA6, 0xD26FD2DEBDB90CD2, 0xF5F3F5FB06F70EF5,
+0x79F979EF80F29679, 0x6FA16F5FCEDE306F, 0x917E91FCEF3F6D91, 0x525552AA07A4F852,
+0x609D6027FDC04760, 0xBCCABC89766535BC, 0x9B569BACCD2B379B, 0x8E028E048C018A8E,
+0xA3B6A371155BD2A3, 0x0C300C603C186C0C, 0x7BF17BFF8AF6847B, 0x35D435B5E16A8035,
+0x1D741DE8693AF51D, 0xE0A7E05347DDB3E0, 0xD77BD7F6ACB321D7, 0xC22FC25EED999CC2,
+0x2EB82E6D965C432E, 0x4B314B627A96294B, 0xFEDFFEA321E15DFE, 0x5741578216AED557,
+0x155415A8412ABD15, 0x77C1779FB6EEE877, 0x37DC37A5EB6E9237, 0xE5B3E57B56D79EE5,
+0x9F469F8CD923139F, 0xF0E7F0D317FD23F0, 0x4A354A6A7F94204A, 0xDA4FDA9E95A944DA,
+0x587D58FA25B0A258, 0xC903C906CA8FCFC9, 0x29A429558D527C29, 0x0A280A5022145A0A,
+0xB1FEB1E14F7F50B1, 0xA0BAA0691A5DC9A0, 0x6BB16B7FDAD6146B, 0x852E855CAB17D985,
+0xBDCEBD8173673CBD, 0x5D695DD234BA8F5D, 0x1040108050209010, 0xF4F7F4F303F507F4,
+0xCB0BCB16C08BDDCB, 0x3EF83EEDC67CD33E, 0x05140528110A2D05, 0x6781671FE6CE7867,
+0xE4B7E47353D597E4, 0x279C2725BB4E0227, 0x4119413258827341, 0x8B168B2C9D0BA78B,
+0xA7A6A7510153F6A7, 0x7DE97DCF94FAB27D, 0x956E95DCFB374995, 0xD847D88E9FAD56D8,
+0xFBCBFB8B30EB70FB, 0xEE9FEE2371C1CDEE, 0x7CED7CC791F8BB7C, 0x66856617E3CC7166,
+0xDD53DDA68EA77BDD, 0x175C17B84B2EAF17, 0x47014702468E4547, 0x9E429E84DC211A9E,
+0xCA0FCA1EC589D4CA, 0x2DB42D75995A582D, 0xBFC6BF9179632EBF, 0x071C07381B0E3F07,
+0xAD8EAD012347ACAD, 0x5A755AEA2FB4B05A, 0x8336836CB51BEF83, 0x33CC3385FF66B633,
+0x6391633FF2C65C63, 0x020802100A041202, 0xAA92AA39384993AA, 0x71D971AFA8E2DE71,
+0xC807C80ECF8DC6C8, 0x196419C87D32D119, 0x4939497270923B49, 0xD943D9869AAF5FD9,
+0xF2EFF2C31DF931F2, 0xE3ABE34B48DBA8E3, 0x5B715BE22AB6B95B, 0x881A8834920DBC88,
+0x9A529AA4C8293E9A, 0x2698262DBE4C0B26, 0x32C8328DFA64BF32, 0xB0FAB0E94A7D59B0,
+0xE983E91B6ACFF2E9, 0x0F3C0F78331E770F, 0xD573D5E6A6B733D5, 0x803A8074BA1DF480,
+0xBEC2BE997C6127BE, 0xCD13CD26DE87EBCD, 0x34D034BDE4688934, 0x483D487A75903248,
+0xFFDBFFAB24E354FF, 0x7AF57AF78FF48D7A, 0x907A90F4EA3D6490, 0x5F615FC23EBE9D5F,
+0x2080201DA0403D20, 0x68BD6867D5D00F68, 0x1A681AD07234CA1A, 0xAE82AE192C41B7AE,
+0xB4EAB4C95E757DB4, 0x544D549A19A8CE54, 0x937693ECE53B7F93, 0x2288220DAA442F22,
+0x648D6407E9C86364, 0xF1E3F1DB12FF2AF1, 0x73D173BFA2E6CC73, 0x124812905A248212,
+0x401D403A5D807A40, 0x0820084028104808, 0xC32BC356E89B95C3, 0xEC97EC337BC5DFEC,
+0xDB4BDB9690AB4DDB, 0xA1BEA1611F5FC0A1, 0x8D0E8D1C8307918D, 0x3DF43DF5C97AC83D,
+0x976697CCF1335B97, 0x0000000000000000, 0xCF1BCF36D483F9CF, 0x2BAC2B4587566E2B,
+0x76C57697B3ECE176, 0x82328264B019E682, 0xD67FD6FEA9B128D6, 0x1B6C1BD87736C31B,
+0xB5EEB5C15B7774B5, 0xAF86AF112943BEAF, 0x6AB56A77DFD41D6A, 0x505D50BA0DA0EA50,
+0x450945124C8A5745, 0xF3EBF3CB18FB38F3, 0x30C0309DF060AD30, 0xEF9BEF2B74C3C4EF,
+0x3FFC3FE5C37EDA3F, 0x554955921CAAC755, 0xA2B2A2791059DBA2, 0xEA8FEA0365C9E9EA,
+0x6589650FECCA6A65, 0xBAD2BAB9686903BA, 0x2FBC2F65935E4A2F, 0xC027C04EE79D8EC0,
+0xDE5FDEBE81A160DE, 0x1C701CE06C38FC1C, 0xFDD3FDBB2EE746FD, 0x4D294D52649A1F4D,
+0x927292E4E0397692, 0x75C9758FBCEAFA75, 0x061806301E0C3606, 0x8A128A249809AE8A,
+0xB2F2B2F940794BB2, 0xE6BFE66359D185E6, 0x0E380E70361C7E0E, 0x1F7C1FF8633EE71F,
+0x62956237F7C45562, 0xD477D4EEA3B53AD4, 0xA89AA829324D81A8, 0x966296C4F4315296,
+0xF9C3F99B3AEF62F9, 0xC533C566F697A3C5, 0x25942535B14A1025, 0x597959F220B2AB59,
+0x842A8454AE15D084, 0x72D572B7A7E4C572, 0x39E439D5DD72EC39, 0x4C2D4C5A6198164C,
+0x5E655ECA3BBC945E, 0x78FD78E785F09F78, 0x38E038DDD870E538, 0x8C0A8C148605988C,
+0xD163D1C6B2BF17D1, 0xA5AEA5410B57E4A5, 0xE2AFE2434DD9A1E2, 0x6199612FF8C24E61,
+0xB3F6B3F1457B42B3, 0x21842115A5423421, 0x9C4A9C94D625089C, 0x1E781EF0663CEE1E,
+0x4311432252866143, 0xC73BC776FC93B1C7, 0xFCD7FCB32BE54FFC, 0x0410042014082404,
+0x515951B208A2E351, 0x995E99BCC72F2599, 0x6DA96D4FC4DA226D, 0x0D340D68391A650D,
+0xFACFFA8335E979FA, 0xDF5BDFB684A369DF, 0x7EE57ED79BFCA97E, 0x2490243DB4481924,
+0x3BEC3BC5D776FE3B, 0xAB96AB313D4B9AAB, 0xCE1FCE3ED181F0CE, 0x1144118855229911,
+0x8F068F0C8903838F, 0x4E254E4A6B9C044E, 0xB7E6B7D1517366B7, 0xEB8BEB0B60CBE0EB,
+0x3CF03CFDCC78C13C, 0x813E817CBF1FFD81, 0x946A94D4FE354094, 0xF7FBF7EB0CF31CF7,
+0xB9DEB9A1676F18B9, 0x134C13985F268B13, 0x2CB02C7D9C58512C, 0xD36BD3D6B8BB05D3,
+0xE7BBE76B5CD38CE7, 0x6EA56E57CBDC396E, 0xC437C46EF395AAC4, 0x030C03180F061B03,
+0x5645568A13ACDC56, 0x440D441A49885E44, 0x7FE17FDF9EFEA07F, 0xA99EA921374F88A9,
+0x2AA82A4D8254672A, 0xBBD6BBB16D6B0ABB, 0xC123C146E29F87C1, 0x535153A202A6F153,
+0xDC57DCAE8BA572DC, 0x0B2C0B582716530B, 0x9D4E9D9CD327019D, 0x6CAD6C47C1D82B6C,
+0x31C43195F562A431, 0x74CD7487B9E8F374, 0xF6FFF6E309F115F6, 0x4605460A438C4C46,
+0xAC8AAC092645A5AC, 0x891E893C970FB589, 0x145014A04428B414, 0xE1A3E15B42DFBAE1,
+0x165816B04E2CA616, 0x3AE83ACDD274F73A, 0x69B9696FD0D20669, 0x092409482D124109,
+0x70DD70A7ADE0D770, 0xB6E2B6D954716FB6, 0xD067D0CEB7BD1ED0, 0xED93ED3B7EC7D6ED,
+0xCC17CC2EDB85E2CC, 0x4215422A57846842, 0x985A98B4C22D2C98, 0xA4AAA4490E55EDA4,
+0x28A0285D88507528, 0x5C6D5CDA31B8865C, 0xF8C7F8933FED6BF8, 0x86228644A411C286 };
+
+}
diff --git a/src/lib/hash/whirlpool/whrlpool.cpp b/src/lib/hash/whirlpool/whrlpool.cpp
new file mode 100644
index 000000000..5356252b2
--- /dev/null
+++ b/src/lib/hash/whirlpool/whrlpool.cpp
@@ -0,0 +1,146 @@
+/*
+* Whirlpool
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/whrlpool.h>
+#include <botan/loadstor.h>
+
+namespace Botan {
+
+/*
+* Whirlpool Compression Function
+*/
+void Whirlpool::compress_n(const byte in[], size_t blocks)
+ {
+ static const u64bit RC[10] = {
+ 0x1823C6E887B8014F, 0x36A6D2F5796F9152,
+ 0x60BC9B8EA30C7B35, 0x1DE0D7C22E4BFE57,
+ 0x157737E59FF04ADA, 0x58C9290AB1A06B85,
+ 0xBD5D10F4CB3E0567, 0xE427418BA77D95D8,
+ 0xFBEE7C66DD17479E, 0xCA2DBF07AD5A8333
+ };
+
+ for(size_t i = 0; i != blocks; ++i)
+ {
+ load_be(&M[0], in, M.size());
+
+ u64bit K0, K1, K2, K3, K4, K5, K6, K7;
+ K0 = digest[0]; K1 = digest[1]; K2 = digest[2]; K3 = digest[3];
+ K4 = digest[4]; K5 = digest[5]; K6 = digest[6]; K7 = digest[7];
+
+ u64bit B0, B1, B2, B3, B4, B5, B6, B7;
+ B0 = K0 ^ M[0]; B1 = K1 ^ M[1]; B2 = K2 ^ M[2]; B3 = K3 ^ M[3];
+ B4 = K4 ^ M[4]; B5 = K5 ^ M[5]; B6 = K6 ^ M[6]; B7 = K7 ^ M[7];
+
+ for(size_t j = 0; j != 10; ++j)
+ {
+ u64bit T0, T1, T2, T3, T4, T5, T6, T7;
+ T0 = C0[get_byte(0, K0)] ^ C1[get_byte(1, K7)] ^
+ C2[get_byte(2, K6)] ^ C3[get_byte(3, K5)] ^
+ C4[get_byte(4, K4)] ^ C5[get_byte(5, K3)] ^
+ C6[get_byte(6, K2)] ^ C7[get_byte(7, K1)] ^ RC[j];
+ T1 = C0[get_byte(0, K1)] ^ C1[get_byte(1, K0)] ^
+ C2[get_byte(2, K7)] ^ C3[get_byte(3, K6)] ^
+ C4[get_byte(4, K5)] ^ C5[get_byte(5, K4)] ^
+ C6[get_byte(6, K3)] ^ C7[get_byte(7, K2)];
+ T2 = C0[get_byte(0, K2)] ^ C1[get_byte(1, K1)] ^
+ C2[get_byte(2, K0)] ^ C3[get_byte(3, K7)] ^
+ C4[get_byte(4, K6)] ^ C5[get_byte(5, K5)] ^
+ C6[get_byte(6, K4)] ^ C7[get_byte(7, K3)];
+ T3 = C0[get_byte(0, K3)] ^ C1[get_byte(1, K2)] ^
+ C2[get_byte(2, K1)] ^ C3[get_byte(3, K0)] ^
+ C4[get_byte(4, K7)] ^ C5[get_byte(5, K6)] ^
+ C6[get_byte(6, K5)] ^ C7[get_byte(7, K4)];
+ T4 = C0[get_byte(0, K4)] ^ C1[get_byte(1, K3)] ^
+ C2[get_byte(2, K2)] ^ C3[get_byte(3, K1)] ^
+ C4[get_byte(4, K0)] ^ C5[get_byte(5, K7)] ^
+ C6[get_byte(6, K6)] ^ C7[get_byte(7, K5)];
+ T5 = C0[get_byte(0, K5)] ^ C1[get_byte(1, K4)] ^
+ C2[get_byte(2, K3)] ^ C3[get_byte(3, K2)] ^
+ C4[get_byte(4, K1)] ^ C5[get_byte(5, K0)] ^
+ C6[get_byte(6, K7)] ^ C7[get_byte(7, K6)];
+ T6 = C0[get_byte(0, K6)] ^ C1[get_byte(1, K5)] ^
+ C2[get_byte(2, K4)] ^ C3[get_byte(3, K3)] ^
+ C4[get_byte(4, K2)] ^ C5[get_byte(5, K1)] ^
+ C6[get_byte(6, K0)] ^ C7[get_byte(7, K7)];
+ T7 = C0[get_byte(0, K7)] ^ C1[get_byte(1, K6)] ^
+ C2[get_byte(2, K5)] ^ C3[get_byte(3, K4)] ^
+ C4[get_byte(4, K3)] ^ C5[get_byte(5, K2)] ^
+ C6[get_byte(6, K1)] ^ C7[get_byte(7, K0)];
+
+ K0 = T0; K1 = T1; K2 = T2; K3 = T3;
+ K4 = T4; K5 = T5; K6 = T6; K7 = T7;
+
+ T0 = C0[get_byte(0, B0)] ^ C1[get_byte(1, B7)] ^
+ C2[get_byte(2, B6)] ^ C3[get_byte(3, B5)] ^
+ C4[get_byte(4, B4)] ^ C5[get_byte(5, B3)] ^
+ C6[get_byte(6, B2)] ^ C7[get_byte(7, B1)] ^ K0;
+ T1 = C0[get_byte(0, B1)] ^ C1[get_byte(1, B0)] ^
+ C2[get_byte(2, B7)] ^ C3[get_byte(3, B6)] ^
+ C4[get_byte(4, B5)] ^ C5[get_byte(5, B4)] ^
+ C6[get_byte(6, B3)] ^ C7[get_byte(7, B2)] ^ K1;
+ T2 = C0[get_byte(0, B2)] ^ C1[get_byte(1, B1)] ^
+ C2[get_byte(2, B0)] ^ C3[get_byte(3, B7)] ^
+ C4[get_byte(4, B6)] ^ C5[get_byte(5, B5)] ^
+ C6[get_byte(6, B4)] ^ C7[get_byte(7, B3)] ^ K2;
+ T3 = C0[get_byte(0, B3)] ^ C1[get_byte(1, B2)] ^
+ C2[get_byte(2, B1)] ^ C3[get_byte(3, B0)] ^
+ C4[get_byte(4, B7)] ^ C5[get_byte(5, B6)] ^
+ C6[get_byte(6, B5)] ^ C7[get_byte(7, B4)] ^ K3;
+ T4 = C0[get_byte(0, B4)] ^ C1[get_byte(1, B3)] ^
+ C2[get_byte(2, B2)] ^ C3[get_byte(3, B1)] ^
+ C4[get_byte(4, B0)] ^ C5[get_byte(5, B7)] ^
+ C6[get_byte(6, B6)] ^ C7[get_byte(7, B5)] ^ K4;
+ T5 = C0[get_byte(0, B5)] ^ C1[get_byte(1, B4)] ^
+ C2[get_byte(2, B3)] ^ C3[get_byte(3, B2)] ^
+ C4[get_byte(4, B1)] ^ C5[get_byte(5, B0)] ^
+ C6[get_byte(6, B7)] ^ C7[get_byte(7, B6)] ^ K5;
+ T6 = C0[get_byte(0, B6)] ^ C1[get_byte(1, B5)] ^
+ C2[get_byte(2, B4)] ^ C3[get_byte(3, B3)] ^
+ C4[get_byte(4, B2)] ^ C5[get_byte(5, B1)] ^
+ C6[get_byte(6, B0)] ^ C7[get_byte(7, B7)] ^ K6;
+ T7 = C0[get_byte(0, B7)] ^ C1[get_byte(1, B6)] ^
+ C2[get_byte(2, B5)] ^ C3[get_byte(3, B4)] ^
+ C4[get_byte(4, B3)] ^ C5[get_byte(5, B2)] ^
+ C6[get_byte(6, B1)] ^ C7[get_byte(7, B0)] ^ K7;
+
+ B0 = T0; B1 = T1; B2 = T2; B3 = T3;
+ B4 = T4; B5 = T5; B6 = T6; B7 = T7;
+ }
+
+ digest[0] ^= B0 ^ M[0];
+ digest[1] ^= B1 ^ M[1];
+ digest[2] ^= B2 ^ M[2];
+ digest[3] ^= B3 ^ M[3];
+ digest[4] ^= B4 ^ M[4];
+ digest[5] ^= B5 ^ M[5];
+ digest[6] ^= B6 ^ M[6];
+ digest[7] ^= B7 ^ M[7];
+
+ in += hash_block_size();
+ }
+ }
+
+/*
+* Copy out the digest
+*/
+void Whirlpool::copy_out(byte output[])
+ {
+ for(size_t i = 0; i != output_length(); i += 8)
+ store_be(digest[i/8], output + i);
+ }
+
+/*
+* Clear memory of sensitive data
+*/
+void Whirlpool::clear()
+ {
+ MDx_HashFunction::clear();
+ zeroise(M);
+ zeroise(digest);
+ }
+
+}
diff --git a/src/lib/hash/whirlpool/whrlpool.h b/src/lib/hash/whirlpool/whrlpool.h
new file mode 100644
index 000000000..d4ad805e1
--- /dev/null
+++ b/src/lib/hash/whirlpool/whrlpool.h
@@ -0,0 +1,47 @@
+/*
+* Whirlpool
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_WHIRLPOOL_H__
+#define BOTAN_WHIRLPOOL_H__
+
+#include <botan/mdx_hash.h>
+
+namespace Botan {
+
+/**
+* Whirlpool
+*/
+class BOTAN_DLL Whirlpool : public MDx_HashFunction
+ {
+ public:
+ std::string name() const { return "Whirlpool"; }
+ size_t output_length() const { return 64; }
+ HashFunction* clone() const { return new Whirlpool; }
+
+ void clear();
+
+ Whirlpool() : MDx_HashFunction(64, true, true, 32), M(8), digest(8)
+ { clear(); }
+ private:
+ void compress_n(const byte[], size_t blocks);
+ void copy_out(byte[]);
+
+ static const u64bit C0[256];
+ static const u64bit C1[256];
+ static const u64bit C2[256];
+ static const u64bit C3[256];
+ static const u64bit C4[256];
+ static const u64bit C5[256];
+ static const u64bit C6[256];
+ static const u64bit C7[256];
+
+ secure_vector<u64bit> M, digest;
+ };
+
+}
+
+#endif