diff options
author | lloyd <[email protected]> | 2008-11-23 02:03:16 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2008-11-23 02:03:16 +0000 |
commit | f4ad8ecfa14b59dbf06a9595f8dacccb3b7f04e3 (patch) | |
tree | 76077c951bb44373ad7c2ca632f2e24cf758e88f /src | |
parent | 8ec4a1fe7e8af6f8223908cdf8fe7de39170fc2a (diff) |
I had not anticipated this being really worthwhile, but it turns out
to have been so! Change MDx_HashFunction::hash to a new compress_n
which hashes an arbitrary number of blocks. I had a thought this might
reduce a bit of loop overhead but the results were far better than I
anticipated. Speedup across the board of about 2%, and very
noticable (+10%) increases for MD4 and Tiger (probably b/c both
of those have so few instructions in each iteration of the
compression function).
Before:
SHA-1:
amd64: 211.9 MiB/s
core: 210.0 MiB/s
sse2: 295.2 MiB/s
MD4: 476.2 MiB/s
MD5: 355.2 MiB/s
SHA-256: 99.8 MiB/s
SHA-512: 151.4 MiB/s
RIPEMD-128: 326.9 MiB/s
RIPEMD-160: 225.1 MiB/s
Tiger: 214.8 MiB/s
Whirlpool: 38.4 MiB/s
After:
SHA-1:
amd64: 215.6 MiB/s
core: 213.8 MiB/s
sse2: 299.9 MiB/s
MD4: 528.4 MiB/s
MD5: 368.8 MiB/s
SHA-256: 103.9 MiB/s
SHA-512: 156.8 MiB/s
RIPEMD-128: 334.8 MiB/s
RIPEMD-160: 229.7 MiB/s
Tiger: 240.7 MiB/s
Whirlpool: 38.6 MiB/s
Diffstat (limited to 'src')
33 files changed, 876 insertions, 746 deletions
diff --git a/src/hash/fork256/fork256.cpp b/src/hash/fork256/fork256.cpp index 5ac779cab..dc023004d 100644 --- a/src/hash/fork256/fork256.cpp +++ b/src/hash/fork256/fork256.cpp @@ -40,7 +40,7 @@ inline void step(u32bit& A, u32bit& B, u32bit& C, u32bit& D, /************************************************* * FORK-256 Compression Function * *************************************************/ -void FORK_256::hash(const byte input[]) +void FORK_256::compress_n(const byte input[], u32bit blocks) { const u32bit DELTA[16] = { 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, @@ -48,71 +48,75 @@ void FORK_256::hash(const byte input[]) 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174 }; - u32bit A1, B1, C1, D1, E1, F1, G1, H1; - u32bit A2, B2, C2, D2, E2, F2, G2, H2; - u32bit A3, B3, C3, D3, E3, F3, G3, H3; - u32bit A4, B4, C4, D4, E4, F4, G4, H4; - - A1 = A2 = A3 = A4 = digest[0]; - B1 = B2 = B3 = B4 = digest[1]; - C1 = C2 = C3 = C4 = digest[2]; - D1 = D2 = D3 = D4 = digest[3]; - E1 = E2 = E3 = E4 = digest[4]; - F1 = F2 = F3 = F4 = digest[5]; - G1 = G2 = G3 = G4 = digest[6]; - H1 = H2 = H3 = H4 = digest[7]; - - for(u32bit j = 0; j != 16; ++j) - M[j] = load_be<u32bit>(input, j); - - step(A1, B1, C1, D1, E1, F1, G1, H1, M[ 0], M[ 1], DELTA[ 0], DELTA[ 1]); - step(A2, B2, C2, D2, E2, F2, G2, H2, M[14], M[15], DELTA[15], DELTA[14]); - step(A3, B3, C3, D3, E3, F3, G3, H3, M[ 7], M[ 6], DELTA[ 1], DELTA[ 0]); - step(A4, B4, C4, D4, E4, F4, G4, H4, M[ 5], M[12], DELTA[14], DELTA[15]); - - step(H1, A1, B1, C1, D1, E1, F1, G1, M[ 2], M[ 3], DELTA[ 2], DELTA[ 3]); - step(H2, A2, B2, C2, D2, E2, F2, G2, M[11], M[ 9], DELTA[13], DELTA[12]); - step(H3, A3, B3, C3, D3, E3, F3, G3, M[10], M[14], DELTA[ 3], DELTA[ 2]); - step(H4, A4, B4, C4, D4, E4, F4, G4, M[ 1], M[ 8], DELTA[12], DELTA[13]); - - step(G1, H1, A1, B1, C1, D1, E1, F1, M[ 4], M[ 5], DELTA[ 4], DELTA[ 5]); - step(G2, H2, A2, B2, C2, D2, E2, F2, M[ 8], M[10], DELTA[11], DELTA[10]); - step(G3, H3, A3, B3, C3, D3, E3, F3, M[13], M[ 2], DELTA[ 5], DELTA[ 4]); - step(G4, H4, A4, B4, C4, D4, E4, F4, M[15], M[ 0], DELTA[10], DELTA[11]); - - step(F1, G1, H1, A1, B1, C1, D1, E1, M[ 6], M[ 7], DELTA[ 6], DELTA[ 7]); - step(F2, G2, H2, A2, B2, C2, D2, E2, M[ 3], M[ 4], DELTA[ 9], DELTA[ 8]); - step(F3, G3, H3, A3, B3, C3, D3, E3, M[ 9], M[12], DELTA[ 7], DELTA[ 6]); - step(F4, G4, H4, A4, B4, C4, D4, E4, M[13], M[11], DELTA[ 8], DELTA[ 9]); - - step(E1, F1, G1, H1, A1, B1, C1, D1, M[ 8], M[ 9], DELTA[ 8], DELTA[ 9]); - step(E2, F2, G2, H2, A2, B2, C2, D2, M[ 2], M[13], DELTA[ 7], DELTA[ 6]); - step(E3, F3, G3, H3, A3, B3, C3, D3, M[11], M[ 4], DELTA[ 9], DELTA[ 8]); - step(E4, F4, G4, H4, A4, B4, C4, D4, M[ 3], M[10], DELTA[ 6], DELTA[ 7]); - - step(D1, E1, F1, G1, H1, A1, B1, C1, M[10], M[11], DELTA[10], DELTA[11]); - step(D2, E2, F2, G2, H2, A2, B2, C2, M[ 0], M[ 5], DELTA[ 5], DELTA[ 4]); - step(D3, E3, F3, G3, H3, A3, B3, C3, M[15], M[ 8], DELTA[11], DELTA[10]); - step(D4, E4, F4, G4, H4, A4, B4, C4, M[ 9], M[ 2], DELTA[ 4], DELTA[ 5]); - - step(C1, D1, E1, F1, G1, H1, A1, B1, M[12], M[13], DELTA[12], DELTA[13]); - step(C2, D2, E2, F2, G2, H2, A2, B2, M[ 6], M[ 7], DELTA[ 3], DELTA[ 2]); - step(C3, D3, E3, F3, G3, H3, A3, B3, M[ 5], M[ 0], DELTA[13], DELTA[12]); - step(C4, D4, E4, F4, G4, H4, A4, B4, M[ 7], M[14], DELTA[ 2], DELTA[ 3]); - - step(B1, C1, D1, E1, F1, G1, H1, A1, M[14], M[15], DELTA[14], DELTA[15]); - step(B2, C2, D2, E2, F2, G2, H2, A2, M[12], M[ 1], DELTA[ 1], DELTA[ 0]); - step(B3, C3, D3, E3, F3, G3, H3, A3, M[ 1], M[ 3], DELTA[15], DELTA[14]); - step(B4, C4, D4, E4, F4, G4, H4, A4, M[ 4], M[ 6], DELTA[ 0], DELTA[ 1]); - - digest[0] += (A1 + A2) ^ (A3 + A4); - digest[1] += (B1 + B2) ^ (B3 + B4); - digest[2] += (C1 + C2) ^ (C3 + C4); - digest[3] += (D1 + D2) ^ (D3 + D4); - digest[4] += (E1 + E2) ^ (E3 + E4); - digest[5] += (F1 + F2) ^ (F3 + F4); - digest[6] += (G1 + G2) ^ (G3 + G4); - digest[7] += (H1 + H2) ^ (H3 + H4); + for(u32bit i = 0; i != blocks; ++i) + { + u32bit A1, B1, C1, D1, E1, F1, G1, H1; + u32bit A2, B2, C2, D2, E2, F2, G2, H2; + u32bit A3, B3, C3, D3, E3, F3, G3, H3; + u32bit A4, B4, C4, D4, E4, F4, G4, H4; + + A1 = A2 = A3 = A4 = digest[0]; + B1 = B2 = B3 = B4 = digest[1]; + C1 = C2 = C3 = C4 = digest[2]; + D1 = D2 = D3 = D4 = digest[3]; + E1 = E2 = E3 = E4 = digest[4]; + F1 = F2 = F3 = F4 = digest[5]; + G1 = G2 = G3 = G4 = digest[6]; + H1 = H2 = H3 = H4 = digest[7]; + + for(u32bit j = 0; j != 16; ++j) + M[j] = load_be<u32bit>(input, j); + input += HASH_BLOCK_SIZE; + + step(A1, B1, C1, D1, E1, F1, G1, H1, M[ 0], M[ 1], DELTA[ 0], DELTA[ 1]); + step(A2, B2, C2, D2, E2, F2, G2, H2, M[14], M[15], DELTA[15], DELTA[14]); + step(A3, B3, C3, D3, E3, F3, G3, H3, M[ 7], M[ 6], DELTA[ 1], DELTA[ 0]); + step(A4, B4, C4, D4, E4, F4, G4, H4, M[ 5], M[12], DELTA[14], DELTA[15]); + + step(H1, A1, B1, C1, D1, E1, F1, G1, M[ 2], M[ 3], DELTA[ 2], DELTA[ 3]); + step(H2, A2, B2, C2, D2, E2, F2, G2, M[11], M[ 9], DELTA[13], DELTA[12]); + step(H3, A3, B3, C3, D3, E3, F3, G3, M[10], M[14], DELTA[ 3], DELTA[ 2]); + step(H4, A4, B4, C4, D4, E4, F4, G4, M[ 1], M[ 8], DELTA[12], DELTA[13]); + + step(G1, H1, A1, B1, C1, D1, E1, F1, M[ 4], M[ 5], DELTA[ 4], DELTA[ 5]); + step(G2, H2, A2, B2, C2, D2, E2, F2, M[ 8], M[10], DELTA[11], DELTA[10]); + step(G3, H3, A3, B3, C3, D3, E3, F3, M[13], M[ 2], DELTA[ 5], DELTA[ 4]); + step(G4, H4, A4, B4, C4, D4, E4, F4, M[15], M[ 0], DELTA[10], DELTA[11]); + + step(F1, G1, H1, A1, B1, C1, D1, E1, M[ 6], M[ 7], DELTA[ 6], DELTA[ 7]); + step(F2, G2, H2, A2, B2, C2, D2, E2, M[ 3], M[ 4], DELTA[ 9], DELTA[ 8]); + step(F3, G3, H3, A3, B3, C3, D3, E3, M[ 9], M[12], DELTA[ 7], DELTA[ 6]); + step(F4, G4, H4, A4, B4, C4, D4, E4, M[13], M[11], DELTA[ 8], DELTA[ 9]); + + step(E1, F1, G1, H1, A1, B1, C1, D1, M[ 8], M[ 9], DELTA[ 8], DELTA[ 9]); + step(E2, F2, G2, H2, A2, B2, C2, D2, M[ 2], M[13], DELTA[ 7], DELTA[ 6]); + step(E3, F3, G3, H3, A3, B3, C3, D3, M[11], M[ 4], DELTA[ 9], DELTA[ 8]); + step(E4, F4, G4, H4, A4, B4, C4, D4, M[ 3], M[10], DELTA[ 6], DELTA[ 7]); + + step(D1, E1, F1, G1, H1, A1, B1, C1, M[10], M[11], DELTA[10], DELTA[11]); + step(D2, E2, F2, G2, H2, A2, B2, C2, M[ 0], M[ 5], DELTA[ 5], DELTA[ 4]); + step(D3, E3, F3, G3, H3, A3, B3, C3, M[15], M[ 8], DELTA[11], DELTA[10]); + step(D4, E4, F4, G4, H4, A4, B4, C4, M[ 9], M[ 2], DELTA[ 4], DELTA[ 5]); + + step(C1, D1, E1, F1, G1, H1, A1, B1, M[12], M[13], DELTA[12], DELTA[13]); + step(C2, D2, E2, F2, G2, H2, A2, B2, M[ 6], M[ 7], DELTA[ 3], DELTA[ 2]); + step(C3, D3, E3, F3, G3, H3, A3, B3, M[ 5], M[ 0], DELTA[13], DELTA[12]); + step(C4, D4, E4, F4, G4, H4, A4, B4, M[ 7], M[14], DELTA[ 2], DELTA[ 3]); + + step(B1, C1, D1, E1, F1, G1, H1, A1, M[14], M[15], DELTA[14], DELTA[15]); + step(B2, C2, D2, E2, F2, G2, H2, A2, M[12], M[ 1], DELTA[ 1], DELTA[ 0]); + step(B3, C3, D3, E3, F3, G3, H3, A3, M[ 1], M[ 3], DELTA[15], DELTA[14]); + step(B4, C4, D4, E4, F4, G4, H4, A4, M[ 4], M[ 6], DELTA[ 0], DELTA[ 1]); + + digest[0] += (A1 + A2) ^ (A3 + A4); + digest[1] += (B1 + B2) ^ (B3 + B4); + digest[2] += (C1 + C2) ^ (C3 + C4); + digest[3] += (D1 + D2) ^ (D3 + D4); + digest[4] += (E1 + E2) ^ (E3 + E4); + digest[5] += (F1 + F2) ^ (F3 + F4); + digest[6] += (G1 + G2) ^ (G3 + G4); + digest[7] += (H1 + H2) ^ (H3 + H4); + } } /************************************************* diff --git a/src/hash/fork256/fork256.h b/src/hash/fork256/fork256.h index 8ad9c1f8d..d27e8693f 100644 --- a/src/hash/fork256/fork256.h +++ b/src/hash/fork256/fork256.h @@ -21,7 +21,7 @@ class BOTAN_DLL FORK_256 : public MDx_HashFunction HashFunction* clone() const { return new FORK_256; } FORK_256() : MDx_HashFunction(32, 64, true, true) { clear(); } private: - void hash(const byte[]); + void compress_n(const byte[], u32bit blocks); void copy_out(byte[]); SecureBuffer<u32bit, 8> digest; diff --git a/src/hash/has160/has160.cpp b/src/hash/has160/has160.cpp index 422e4916a..f31016629 100644 --- a/src/hash/has160/has160.cpp +++ b/src/hash/has160/has160.cpp @@ -56,64 +56,79 @@ inline void F4(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, /************************************************* * HAS-160 Compression Function * *************************************************/ -void HAS_160::hash(const byte input[]) +void HAS_160::compress_n(const byte input[], u32bit blocks) { - for(u32bit j = 0; j != 16; ++j) - X[j] = load_le<u32bit>(input, j); - - u32bit A = digest[0], B = digest[1], C = digest[2], - D = digest[3], E = digest[4]; - - 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); - - digest[0] += A; digest[1] += B; digest[2] += C; - digest[3] += D; digest[4] += E; + for(u32bit i = 0; i != blocks; ++i) + { + for(u32bit j = 0; j != 16; ++j) + X[j] = load_le<u32bit>(input, j); + + u32bit A = digest[0], B = digest[1], C = digest[2], + D = digest[3], E = digest[4]; + + 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); + + digest[0] += A; digest[1] += B; digest[2] += C; + digest[3] += D; digest[4] += E; + } } /************************************************* diff --git a/src/hash/has160/has160.h b/src/hash/has160/has160.h index 9e35bfdca..d3a422833 100644 --- a/src/hash/has160/has160.h +++ b/src/hash/has160/has160.h @@ -21,7 +21,7 @@ class BOTAN_DLL HAS_160 : public MDx_HashFunction HashFunction* clone() const { return new HAS_160; } HAS_160() : MDx_HashFunction(20, 64, false, true) { clear(); } private: - void hash(const byte[]); + void compress_n(const byte[], u32bit blocks); void copy_out(byte[]); SecureBuffer<u32bit, 20> X; diff --git a/src/hash/md4/md4.cpp b/src/hash/md4/md4.cpp index e2a18f424..c6adeb744 100644 --- a/src/hash/md4/md4.cpp +++ b/src/hash/md4/md4.cpp @@ -43,35 +43,39 @@ inline void HH(u32bit& A, u32bit B, u32bit C, u32bit D, u32bit M, byte S) /************************************************* * MD4 Compression Function * *************************************************/ -void MD4::hash(const byte input[]) +void MD4::compress_n(const byte input[], u32bit blocks) { - for(u32bit j = 0; j != 16; ++j) - M[j] = load_le<u32bit>(input, j); - - u32bit A = digest[0], B = digest[1], C = digest[2], D = digest[3]; - - 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); - - digest[0] += A; digest[1] += B; digest[2] += C; digest[3] += D; + for(u32bit i = 0; i != blocks; ++i) + { + for(u32bit j = 0; j != 16; ++j) + M[j] = load_le<u32bit>(input, j); + input += HASH_BLOCK_SIZE; + + u32bit A = digest[0], B = digest[1], C = digest[2], D = digest[3]; + + 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); + + digest[0] += A; digest[1] += B; digest[2] += C; digest[3] += D; + } } /************************************************* diff --git a/src/hash/md4/md4.h b/src/hash/md4/md4.h index bb0fac576..009bba640 100644 --- a/src/hash/md4/md4.h +++ b/src/hash/md4/md4.h @@ -21,7 +21,8 @@ class BOTAN_DLL MD4 : public MDx_HashFunction HashFunction* clone() const { return new MD4; } MD4() : MDx_HashFunction(16, 64, false, true) { clear(); } protected: - void hash(const byte[]); + void compress_n(const byte input[], u32bit blocks); + void hash_old(const byte[]); void copy_out(byte[]); SecureBuffer<u32bit, 48> M; diff --git a/src/hash/md4_ia32/md4_ia32.cpp b/src/hash/md4_ia32/md4_ia32.cpp index 1483d0e8f..6a4b47067 100644 --- a/src/hash/md4_ia32/md4_ia32.cpp +++ b/src/hash/md4_ia32/md4_ia32.cpp @@ -13,9 +13,13 @@ extern "C" void botan_md4_ia32_compress(u32bit[4], const byte[64], u32bit[16]); /************************************************* * MD4 Compression Function * *************************************************/ -void MD4_IA32::hash(const byte input[]) +void MD4_IA32::compress_n(const byte input[], u32bit blocks) { - botan_md4_ia32_compress(digest, input, M); + for(u32bit i = 0; i != blocks; ++i) + { + botan_md4_ia32_compress(digest, input, M); + input += HASH_BLOCK_SIZE; + } } } diff --git a/src/hash/md4_ia32/md4_ia32.h b/src/hash/md4_ia32/md4_ia32.h index 94ee3b028..e9798830d 100644 --- a/src/hash/md4_ia32/md4_ia32.h +++ b/src/hash/md4_ia32/md4_ia32.h @@ -18,7 +18,7 @@ class BOTAN_DLL MD4_IA32 : public MD4 public: HashFunction* clone() const { return new MD4_IA32; } private: - void hash(const byte[]); + void compress_n(const byte[], u32bit blocks); }; } diff --git a/src/hash/md5/md5.cpp b/src/hash/md5/md5.cpp index 2fd75f0fb..7adac69d3 100644 --- a/src/hash/md5/md5.cpp +++ b/src/hash/md5/md5.cpp @@ -1,6 +1,6 @@ /************************************************* * MD5 Source File * -* (C) 1999-2007 Jack Lloyd * +* (C) 1999-2008 Jack Lloyd * *************************************************/ #include <botan/md5.h> @@ -56,50 +56,54 @@ inline void II(u32bit& A, u32bit B, u32bit C, u32bit D, u32bit msg, /************************************************* * MD5 Compression Function * *************************************************/ -void MD5::hash(const byte input[]) +void MD5::compress_n(const byte input[], u32bit blocks) { - for(u32bit j = 0; j != 16; ++j) - M[j] = load_le<u32bit>(input, j); - - u32bit A = digest[0], B = digest[1], C = digest[2], D = digest[3]; - - 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); - - digest[0] += A; digest[1] += B; digest[2] += C; digest[3] += D; + for(u32bit i = 0; i != blocks; ++i) + { + for(u32bit j = 0; j != 16; ++j) + M[j] = load_le<u32bit>(input, j); + input += HASH_BLOCK_SIZE; + + u32bit A = digest[0], B = digest[1], C = digest[2], D = digest[3]; + + 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); + + digest[0] += A; digest[1] += B; digest[2] += C; digest[3] += D; + } } /************************************************* diff --git a/src/hash/md5/md5.h b/src/hash/md5/md5.h index bcd32507a..8ed72b044 100644 --- a/src/hash/md5/md5.h +++ b/src/hash/md5/md5.h @@ -1,7 +1,7 @@ -/************************************************* -* MD5 Header File * -* (C) 1999-2007 Jack Lloyd * -*************************************************/ +/** +* MD5 Header File +* (C) 1999-2008 Jack Lloyd +*/ #ifndef BOTAN_MD5_H__ #define BOTAN_MD5_H__ @@ -10,9 +10,9 @@ namespace Botan { -/************************************************* -* MD5 * -*************************************************/ +/** +* MD5 +*/ class BOTAN_DLL MD5 : public MDx_HashFunction { public: @@ -21,7 +21,7 @@ class BOTAN_DLL MD5 : public MDx_HashFunction HashFunction* clone() const { return new MD5; } MD5() : MDx_HashFunction(16, 64, false, true) { clear(); } protected: - void hash(const byte[]); + void compress_n(const byte[], u32bit blocks); void copy_out(byte[]); SecureBuffer<u32bit, 16> M; diff --git a/src/hash/md5_ia32/md5_ia32.cpp b/src/hash/md5_ia32/md5_ia32.cpp index 7616292e3..15fa7d3dc 100644 --- a/src/hash/md5_ia32/md5_ia32.cpp +++ b/src/hash/md5_ia32/md5_ia32.cpp @@ -18,9 +18,13 @@ void botan_md5_ia32_compress(u32bit[4], const byte[64], u32bit[16]); /************************************************* * MD5 Compression Function * *************************************************/ -void MD5_IA32::hash(const byte input[]) +void MD5_IA32::compress_n(const byte input[], u32bit blocks) { - botan_md5_ia32_compress(digest, input, M); + for(u32bit i = 0; i != blocks; ++i) + { + botan_md5_ia32_compress(digest, input, M); + input += HASH_BLOCK_SIZE; + } } } diff --git a/src/hash/md5_ia32/md5_ia32.h b/src/hash/md5_ia32/md5_ia32.h index 7ff463799..a5365aa58 100644 --- a/src/hash/md5_ia32/md5_ia32.h +++ b/src/hash/md5_ia32/md5_ia32.h @@ -18,7 +18,7 @@ class BOTAN_DLL MD5_IA32 : public MD5 public: HashFunction* clone() const { return new MD5_IA32; } private: - void hash(const byte[]); + void compress_n(const byte[], u32bit blocks); }; } diff --git a/src/hash/mdx_hash/mdx_hash.cpp b/src/hash/mdx_hash/mdx_hash.cpp index 0d88afba1..35a06d213 100644 --- a/src/hash/mdx_hash/mdx_hash.cpp +++ b/src/hash/mdx_hash/mdx_hash.cpp @@ -1,7 +1,7 @@ -/************************************************* -* MDx Hash Function Source File * -* (C) 1999-2007 Jack Lloyd * -*************************************************/ +/** +* Merkle-Damgard Hash Function +* (C) 1999-2008 Jack Lloyd +*/ #include <botan/mdx_hash.h> #include <botan/exceptn.h> @@ -9,9 +9,9 @@ namespace Botan { -/************************************************* -* MDx_HashFunction Constructor * -*************************************************/ +/** +* MDx_HashFunction Constructor +*/ MDx_HashFunction::MDx_HashFunction(u32bit hash_len, u32bit block_len, bool byte_end, bool bit_end, u32bit cnt_size) : @@ -23,18 +23,40 @@ MDx_HashFunction::MDx_HashFunction(u32bit hash_len, u32bit block_len, count = position = 0; } -/************************************************* -* Clear memory of sensitive data * -*************************************************/ +/** +* Clear memory of sensitive data +*/ void MDx_HashFunction::clear() throw() { buffer.clear(); count = position = 0; } -/************************************************* -* Update the hash * -*************************************************/ +/** +* Update the hash +*/ +/* +void MDx_HashFunction::compress_n(const byte block[], u32bit block_n) + { + for(u32bit j = 0; j != block_n; ++j) + { + hash(block); + block += HASH_BLOCK_SIZE; + } + } +*/ +/** +* Update the hash +*/ +/* +void MDx_HashFunction::hash(const byte block[]) + { + compress_n(block, 1); + } +*/ +/** +* Update the hash +*/ void MDx_HashFunction::add_data(const byte input[], u32bit length) { count += length; @@ -45,48 +67,48 @@ void MDx_HashFunction::add_data(const byte input[], u32bit length) if(position + length >= HASH_BLOCK_SIZE) { - hash(buffer.begin()); + compress_n(buffer.begin(), 1); input += (HASH_BLOCK_SIZE - position); length -= (HASH_BLOCK_SIZE - position); position = 0; } } - while(length >= HASH_BLOCK_SIZE) - { - hash(input); - input += HASH_BLOCK_SIZE; - length -= HASH_BLOCK_SIZE; - } + const u32bit full_blocks = length / HASH_BLOCK_SIZE; + const u32bit remaining = length % HASH_BLOCK_SIZE; - buffer.copy(position, input, length); + compress_n(input, full_blocks); - position += length; + buffer.copy(position, input + full_blocks * HASH_BLOCK_SIZE, remaining); + position += remaining; } -/************************************************* -* Finalize a Hash * -*************************************************/ +/** +* Finalize a hash +*/ void MDx_HashFunction::final_result(byte output[]) { + buffer[position] = (BIG_BIT_ENDIAN ? 0x80 : 0x01); for(u32bit j = position+1; j != HASH_BLOCK_SIZE; ++j) buffer[j] = 0; + if(position >= HASH_BLOCK_SIZE - COUNT_SIZE) { - hash(buffer); + compress_n(buffer, 1); buffer.clear(); } + write_count(buffer + HASH_BLOCK_SIZE - COUNT_SIZE); - hash(buffer); + compress_n(buffer, 1); copy_out(output); clear(); } -/************************************************* -* Write the count bits to the buffer * -*************************************************/ +/** +* Write the count bits to the buffer +*/ void MDx_HashFunction::write_count(byte out[]) { if(COUNT_SIZE < 8) diff --git a/src/hash/mdx_hash/mdx_hash.h b/src/hash/mdx_hash/mdx_hash.h index b07a78de7..484774aea 100644 --- a/src/hash/mdx_hash/mdx_hash.h +++ b/src/hash/mdx_hash/mdx_hash.h @@ -1,7 +1,7 @@ -/************************************************* -* MDx Hash Function Header File * -* (C) 1999-2007 Jack Lloyd * -*************************************************/ +/** +* MDx Hash Function Header File +* (C) 1999-2008 Jack Lloyd +*/ #ifndef BOTAN_MDX_BASE_H__ #define BOTAN_MDX_BASE_H__ @@ -10,9 +10,9 @@ namespace Botan { -/************************************************* -* MDx Hash Function Base Class * -*************************************************/ +/** +* MDx Hash Function Base Class +*/ class BOTAN_DLL MDx_HashFunction : public HashFunction { public: @@ -27,7 +27,11 @@ class BOTAN_DLL MDx_HashFunction : public HashFunction void add_data(const byte[], u32bit); void final_result(byte output[]); - virtual void hash(const byte[]) = 0; + // these are mutually recurisve unless one is overridden + // (backwards compatability hack) + virtual void compress_n(const byte block[], u32bit block_n) = 0; + //virtual void hash(const byte[]); + virtual void copy_out(byte[]) = 0; virtual void write_count(byte[]); diff --git a/src/hash/rmd128/rmd128.cpp b/src/hash/rmd128/rmd128.cpp index 4c33350b6..52d0c5f56 100644 --- a/src/hash/rmd128/rmd128.cpp +++ b/src/hash/rmd128/rmd128.cpp @@ -56,89 +56,93 @@ inline void F4(u32bit& A, u32bit B, u32bit C, u32bit D, /************************************************* * RIPEMD-128 Compression Function * *************************************************/ -void RIPEMD_128::hash(const byte input[]) +void RIPEMD_128::compress_n(const byte input[], u32bit blocks) { - for(u32bit j = 0; j != 16; ++j) - M[j] = load_le<u32bit>(input, j); - - u32bit A1 = digest[0], A2 = A1, B1 = digest[1], B2 = B1, - C1 = digest[2], C2 = C1, D1 = digest[3], D2 = D1; - - const u32bit MAGIC2 = 0x5A827999, MAGIC3 = 0x6ED9EBA1, - MAGIC4 = 0x8F1BBCDC, MAGIC5 = 0x50A28BE6, - MAGIC6 = 0x5C4DD124, MAGIC7 = 0x6D703EF3; - - 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; + for(u32bit i = 0; i != blocks; ++i) + { + for(u32bit j = 0; j != 16; ++j) + M[j] = load_le<u32bit>(input, j); + input += HASH_BLOCK_SIZE; + + u32bit A1 = digest[0], A2 = A1, B1 = digest[1], B2 = B1, + C1 = digest[2], C2 = C1, D1 = digest[3], D2 = D1; + + const u32bit MAGIC2 = 0x5A827999, MAGIC3 = 0x6ED9EBA1, + MAGIC4 = 0x8F1BBCDC, MAGIC5 = 0x50A28BE6, + MAGIC6 = 0x5C4DD124, MAGIC7 = 0x6D703EF3; + + 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; + } } /************************************************* diff --git a/src/hash/rmd128/rmd128.h b/src/hash/rmd128/rmd128.h index 2cb98e516..923b2bf80 100644 --- a/src/hash/rmd128/rmd128.h +++ b/src/hash/rmd128/rmd128.h @@ -21,7 +21,7 @@ class BOTAN_DLL RIPEMD_128 : public MDx_HashFunction HashFunction* clone() const { return new RIPEMD_128; } RIPEMD_128() : MDx_HashFunction(16, 64, false, true) { clear(); } private: - void hash(const byte[]); + void compress_n(const byte[], u32bit blocks); void copy_out(byte[]); SecureBuffer<u32bit, 16> M; diff --git a/src/hash/rmd160/rmd160.cpp b/src/hash/rmd160/rmd160.cpp index 20c0ad4f1..e8961ac67 100644 --- a/src/hash/rmd160/rmd160.cpp +++ b/src/hash/rmd160/rmd160.cpp @@ -71,108 +71,112 @@ inline void F5(u32bit& A, u32bit B, u32bit& C, u32bit D, u32bit E, /************************************************* * RIPEMD-160 Compression Function * *************************************************/ -void RIPEMD_160::hash(const byte input[]) +void RIPEMD_160::compress_n(const byte input[], u32bit blocks) { - for(u32bit j = 0; j != 16; ++j) - M[j] = load_le<u32bit>(input, j); - - 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; - - const u32bit MAGIC2 = 0x5A827999, MAGIC3 = 0x6ED9EBA1, - MAGIC4 = 0x8F1BBCDC, MAGIC5 = 0xA953FD4E, - MAGIC6 = 0x50A28BE6, MAGIC7 = 0x5C4DD124, - MAGIC8 = 0x6D703EF3, MAGIC9 = 0x7A6D76E9; - - 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; + for(u32bit i = 0; i != blocks; ++i) + { + for(u32bit j = 0; j != 16; ++j) + M[j] = load_le<u32bit>(input, j); + input += HASH_BLOCK_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; + + const u32bit MAGIC2 = 0x5A827999, MAGIC3 = 0x6ED9EBA1, + MAGIC4 = 0x8F1BBCDC, MAGIC5 = 0xA953FD4E, + MAGIC6 = 0x50A28BE6, MAGIC7 = 0x5C4DD124, + MAGIC8 = 0x6D703EF3, MAGIC9 = 0x7A6D76E9; + + 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; + } } /************************************************* diff --git a/src/hash/rmd160/rmd160.h b/src/hash/rmd160/rmd160.h index 0544f21cc..939fe5668 100644 --- a/src/hash/rmd160/rmd160.h +++ b/src/hash/rmd160/rmd160.h @@ -21,7 +21,7 @@ class BOTAN_DLL RIPEMD_160 : public MDx_HashFunction HashFunction* clone() const { return new RIPEMD_160; } RIPEMD_160() : MDx_HashFunction(20, 64, false, true) { clear(); } private: - void hash(const byte[]); + void compress_n(const byte[], u32bit blocks); void copy_out(byte[]); SecureBuffer<u32bit, 16> M; diff --git a/src/hash/sha1/sha160.cpp b/src/hash/sha1/sha160.cpp index 142cddcd3..302151921 100644 --- a/src/hash/sha1/sha160.cpp +++ b/src/hash/sha1/sha160.cpp @@ -52,61 +52,65 @@ inline void F4(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg) /************************************************* * SHA-160 Compression Function * *************************************************/ -void SHA_160::hash(const byte input[]) +void SHA_160::compress_n(const byte input[], u32bit blocks) { - for(u32bit j = 0; j != 16; j += 4) + for(u32bit i = 0; i != blocks; ++i) { - W[j ] = load_be<u32bit>(input, j); - W[j+1] = load_be<u32bit>(input, j+1); - W[j+2] = load_be<u32bit>(input, j+2); - W[j+3] = load_be<u32bit>(input, j+3); + for(u32bit j = 0; j != 16; j += 4) + { + W[j ] = load_be<u32bit>(input, j); + W[j+1] = load_be<u32bit>(input, j+1); + W[j+2] = load_be<u32bit>(input, j+2); + W[j+3] = load_be<u32bit>(input, j+3); + } + input += HASH_BLOCK_SIZE; + + for(u32bit j = 16; j != 80; j += 4) + { + 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); + } + + u32bit A = digest[0], B = digest[1], C = digest[2], + D = digest[3], E = digest[4]; + + 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]); + + digest[0] += A; digest[1] += B; digest[2] += C; + digest[3] += D; digest[4] += E; } - - for(u32bit j = 16; j != 80; j += 4) - { - 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); - } - - u32bit A = digest[0], B = digest[1], C = digest[2], - D = digest[3], E = digest[4]; - - 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]); - - digest[0] += A; digest[1] += B; digest[2] += C; - digest[3] += D; digest[4] += E; } /************************************************* diff --git a/src/hash/sha1/sha160.h b/src/hash/sha1/sha160.h index 021dc95ec..640a8a683 100644 --- a/src/hash/sha1/sha160.h +++ b/src/hash/sha1/sha160.h @@ -24,7 +24,7 @@ class BOTAN_DLL SHA_160 : public MDx_HashFunction protected: SHA_160(u32bit W_size); - void hash(const byte[]); + void compress_n(const byte[], u32bit blocks); void copy_out(byte[]); SecureBuffer<u32bit, 5> digest; diff --git a/src/hash/sha1_amd64/sha1_amd64.cpp b/src/hash/sha1_amd64/sha1_amd64.cpp index 703fd6f2d..f69c1fdd0 100644 --- a/src/hash/sha1_amd64/sha1_amd64.cpp +++ b/src/hash/sha1_amd64/sha1_amd64.cpp @@ -17,9 +17,13 @@ void botan_sha160_amd64_compress(u32bit[5], const byte[64], u32bit[80]); /************************************************* * SHA-160 Compression Function * *************************************************/ -void SHA_160_AMD64::hash(const byte input[]) +void SHA_160_AMD64::compress_n(const byte input[], u32bit blocks) { - botan_sha160_amd64_compress(digest, input, W); + for(u32bit i = 0; i != blocks; ++i) + { + botan_sha160_amd64_compress(digest, input, W); + input += HASH_BLOCK_SIZE; + } } } diff --git a/src/hash/sha1_amd64/sha1_amd64.h b/src/hash/sha1_amd64/sha1_amd64.h index 891b3a869..38a83e4de 100644 --- a/src/hash/sha1_amd64/sha1_amd64.h +++ b/src/hash/sha1_amd64/sha1_amd64.h @@ -18,7 +18,7 @@ class BOTAN_DLL SHA_160_AMD64 : public SHA_160 public: HashFunction* clone() const { return new SHA_160_AMD64; } private: - void hash(const byte[]); + void compress_n(const byte[], u32bit blocks); }; } diff --git a/src/hash/sha1_ia32/sha1_ia32.h b/src/hash/sha1_ia32/sha1_ia32.h index e294cc42c..403095f11 100644 --- a/src/hash/sha1_ia32/sha1_ia32.h +++ b/src/hash/sha1_ia32/sha1_ia32.h @@ -21,7 +21,7 @@ class BOTAN_DLL SHA_160_IA32 : public SHA_160 // Note 81 instead of normal 80: IA-32 asm needs an extra temp SHA_160_IA32() : SHA_160(81) {} private: - void hash(const byte[]); + void compress_n(const byte[], u32bit blocks); }; } diff --git a/src/hash/sha1_sse2/sha1_sse2.cpp b/src/hash/sha1_sse2/sha1_sse2.cpp index 1d47cb1df..e2e0352fe 100644 --- a/src/hash/sha1_sse2/sha1_sse2.cpp +++ b/src/hash/sha1_sse2/sha1_sse2.cpp @@ -10,9 +10,13 @@ namespace Botan { /************************************************* * SHA-160 Compression Function * *************************************************/ -void SHA_160_SSE2::hash(const byte input[]) +void SHA_160_SSE2::compress_n(const byte input[], u32bit blocks) { - botan_sha1_sse2_compress(digest, reinterpret_cast<const u32bit*>(input)); + for(u32bit i = 0; i != blocks; ++i) + { + botan_sha1_sse2_compress(digest, reinterpret_cast<const u32bit*>(input)); + input += HASH_BLOCK_SIZE; + } } } diff --git a/src/hash/sha1_sse2/sha1_sse2.h b/src/hash/sha1_sse2/sha1_sse2.h index 4bd8c1baa..57348e461 100644 --- a/src/hash/sha1_sse2/sha1_sse2.h +++ b/src/hash/sha1_sse2/sha1_sse2.h @@ -19,7 +19,7 @@ class BOTAN_DLL SHA_160_SSE2 : public SHA_160 HashFunction* clone() const { return new SHA_160_SSE2; } SHA_160_SSE2() : SHA_160(0) {} // no W needed private: - void hash(const byte[]); + void compress_n(const byte[], u32bit blocks); }; extern "C" void botan_sha1_sse2_compress(u32bit[5], const u32bit*); diff --git a/src/hash/sha2/sha2_32.cpp b/src/hash/sha2/sha2_32.cpp index f0710469b..be2638747 100644 --- a/src/hash/sha2/sha2_32.cpp +++ b/src/hash/sha2/sha2_32.cpp @@ -46,55 +46,91 @@ inline void F1(u32bit A, u32bit B, u32bit C, u32bit& D, /************************************************* * SHA-256 Compression Function * *************************************************/ -void SHA_224_256_BASE::hash(const byte input[]) +void SHA_224_256_BASE::compress_n(const byte input[], u32bit blocks) { - for(u32bit j = 0; j != 16; ++j) - W[j] = load_be<u32bit>(input, j); - - for(u32bit j = 16; j != 64; ++j) - W[j] = sigma(W[j- 2], 17, 19, 10) + W[j- 7] + - sigma(W[j-15], 7, 18, 3) + W[j-16]; - - 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]; - - F1(A,B,C,D,E,F,G,H,W[ 0],0x428A2F98); F1(H,A,B,C,D,E,F,G,W[ 1],0x71374491); - F1(G,H,A,B,C,D,E,F,W[ 2],0xB5C0FBCF); F1(F,G,H,A,B,C,D,E,W[ 3],0xE9B5DBA5); - F1(E,F,G,H,A,B,C,D,W[ 4],0x3956C25B); F1(D,E,F,G,H,A,B,C,W[ 5],0x59F111F1); - F1(C,D,E,F,G,H,A,B,W[ 6],0x923F82A4); F1(B,C,D,E,F,G,H,A,W[ 7],0xAB1C5ED5); - F1(A,B,C,D,E,F,G,H,W[ 8],0xD807AA98); F1(H,A,B,C,D,E,F,G,W[ 9],0x12835B01); - F1(G,H,A,B,C,D,E,F,W[10],0x243185BE); F1(F,G,H,A,B,C,D,E,W[11],0x550C7DC3); - F1(E,F,G,H,A,B,C,D,W[12],0x72BE5D74); F1(D,E,F,G,H,A,B,C,W[13],0x80DEB1FE); - F1(C,D,E,F,G,H,A,B,W[14],0x9BDC06A7); F1(B,C,D,E,F,G,H,A,W[15],0xC19BF174); - F1(A,B,C,D,E,F,G,H,W[16],0xE49B69C1); F1(H,A,B,C,D,E,F,G,W[17],0xEFBE4786); - F1(G,H,A,B,C,D,E,F,W[18],0x0FC19DC6); F1(F,G,H,A,B,C,D,E,W[19],0x240CA1CC); - F1(E,F,G,H,A,B,C,D,W[20],0x2DE92C6F); F1(D,E,F,G,H,A,B,C,W[21],0x4A7484AA); - F1(C,D,E,F,G,H,A,B,W[22],0x5CB0A9DC); F1(B,C,D,E,F,G,H,A,W[23],0x76F988DA); - F1(A,B,C,D,E,F,G,H,W[24],0x983E5152); F1(H,A,B,C,D,E,F,G,W[25],0xA831C66D); - F1(G,H,A,B,C,D,E,F,W[26],0xB00327C8); F1(F,G,H,A,B,C,D,E,W[27],0xBF597FC7); - F1(E,F,G,H,A,B,C,D,W[28],0xC6E00BF3); F1(D,E,F,G,H,A,B,C,W[29],0xD5A79147); - F1(C,D,E,F,G,H,A,B,W[30],0x06CA6351); F1(B,C,D,E,F,G,H,A,W[31],0x14292967); - F1(A,B,C,D,E,F,G,H,W[32],0x27B70A85); F1(H,A,B,C,D,E,F,G,W[33],0x2E1B2138); - F1(G,H,A,B,C,D,E,F,W[34],0x4D2C6DFC); F1(F,G,H,A,B,C,D,E,W[35],0x53380D13); - F1(E,F,G,H,A,B,C,D,W[36],0x650A7354); F1(D,E,F,G,H,A,B,C,W[37],0x766A0ABB); - F1(C,D,E,F,G,H,A,B,W[38],0x81C2C92E); F1(B,C,D,E,F,G,H,A,W[39],0x92722C85); - F1(A,B,C,D,E,F,G,H,W[40],0xA2BFE8A1); F1(H,A,B,C,D,E,F,G,W[41],0xA81A664B); - F1(G,H,A,B,C,D,E,F,W[42],0xC24B8B70); F1(F,G,H,A,B,C,D,E,W[43],0xC76C51A3); - F1(E,F,G,H,A,B,C,D,W[44],0xD192E819); F1(D,E,F,G,H,A,B,C,W[45],0xD6990624); - F1(C,D,E,F,G,H,A,B,W[46],0xF40E3585); F1(B,C,D,E,F,G,H,A,W[47],0x106AA070); - F1(A,B,C,D,E,F,G,H,W[48],0x19A4C116); F1(H,A,B,C,D,E,F,G,W[49],0x1E376C08); - F1(G,H,A,B,C,D,E,F,W[50],0x2748774C); F1(F,G,H,A,B,C,D,E,W[51],0x34B0BCB5); - F1(E,F,G,H,A,B,C,D,W[52],0x391C0CB3); F1(D,E,F,G,H,A,B,C,W[53],0x4ED8AA4A); - F1(C,D,E,F,G,H,A,B,W[54],0x5B9CCA4F); F1(B,C,D,E,F,G,H,A,W[55],0x682E6FF3); - F1(A,B,C,D,E,F,G,H,W[56],0x748F82EE); F1(H,A,B,C,D,E,F,G,W[57],0x78A5636F); - F1(G,H,A,B,C,D,E,F,W[58],0x84C87814); F1(F,G,H,A,B,C,D,E,W[59],0x8CC70208); - F1(E,F,G,H,A,B,C,D,W[60],0x90BEFFFA); F1(D,E,F,G,H,A,B,C,W[61],0xA4506CEB); - F1(C,D,E,F,G,H,A,B,W[62],0xBEF9A3F7); F1(B,C,D,E,F,G,H,A,W[63],0xC67178F2); - - digest[0] += A; digest[1] += B; digest[2] += C; - digest[3] += D; digest[4] += E; digest[5] += F; - digest[6] += G; digest[7] += H; + for(u32bit i = 0; i != blocks; ++i) + { + for(u32bit j = 0; j != 16; ++j) + W[j] = load_be<u32bit>(input, j); + input += HASH_BLOCK_SIZE; + + for(u32bit j = 16; j != 64; ++j) + W[j] = sigma(W[j- 2], 17, 19, 10) + W[j- 7] + + sigma(W[j-15], 7, 18, 3) + W[j-16]; + + 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]; + + F1(A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98); + F1(H, A, B, C, D, E, F, G, W[ 1], 0x71374491); + F1(G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF); + F1(F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5); + F1(E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B); + F1(D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1); + F1(C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4); + F1(B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5); + F1(A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98); + F1(H, A, B, C, D, E, F, G, W[ 9], 0x12835B01); + F1(G, H, A, B, C, D, E, F, W[10], 0x243185BE); + F1(F, G, H, A, B, C, D, E, W[11], 0x550C7DC3); + F1(E, F, G, H, A, B, C, D, W[12], 0x72BE5D74); + F1(D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE); + F1(C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7); + F1(B, C, D, E, F, G, H, A, W[15], 0xC19BF174); + F1(A, B, C, D, E, F, G, H, W[16], 0xE49B69C1); + F1(H, A, B, C, D, E, F, G, W[17], 0xEFBE4786); + F1(G, H, A, B, C, D, E, F, W[18], 0x0FC19DC6); + F1(F, G, H, A, B, C, D, E, W[19], 0x240CA1CC); + F1(E, F, G, H, A, B, C, D, W[20], 0x2DE92C6F); + F1(D, E, F, G, H, A, B, C, W[21], 0x4A7484AA); + F1(C, D, E, F, G, H, A, B, W[22], 0x5CB0A9DC); + F1(B, C, D, E, F, G, H, A, W[23], 0x76F988DA); + F1(A, B, C, D, E, F, G, H, W[24], 0x983E5152); + F1(H, A, B, C, D, E, F, G, W[25], 0xA831C66D); + F1(G, H, A, B, C, D, E, F, W[26], 0xB00327C8); + F1(F, G, H, A, B, C, D, E, W[27], 0xBF597FC7); + F1(E, F, G, H, A, B, C, D, W[28], 0xC6E00BF3); + F1(D, E, F, G, H, A, B, C, W[29], 0xD5A79147); + F1(C, D, E, F, G, H, A, B, W[30], 0x06CA6351); + F1(B, C, D, E, F, G, H, A, W[31], 0x14292967); + F1(A, B, C, D, E, F, G, H, W[32], 0x27B70A85); + F1(H, A, B, C, D, E, F, G, W[33], 0x2E1B2138); + F1(G, H, A, B, C, D, E, F, W[34], 0x4D2C6DFC); + F1(F, G, H, A, B, C, D, E, W[35], 0x53380D13); + F1(E, F, G, H, A, B, C, D, W[36], 0x650A7354); + F1(D, E, F, G, H, A, B, C, W[37], 0x766A0ABB); + F1(C, D, E, F, G, H, A, B, W[38], 0x81C2C92E); + F1(B, C, D, E, F, G, H, A, W[39], 0x92722C85); + F1(A, B, C, D, E, F, G, H, W[40], 0xA2BFE8A1); + F1(H, A, B, C, D, E, F, G, W[41], 0xA81A664B); + F1(G, H, A, B, C, D, E, F, W[42], 0xC24B8B70); + F1(F, G, H, A, B, C, D, E, W[43], 0xC76C51A3); + F1(E, F, G, H, A, B, C, D, W[44], 0xD192E819); + F1(D, E, F, G, H, A, B, C, W[45], 0xD6990624); + F1(C, D, E, F, G, H, A, B, W[46], 0xF40E3585); + F1(B, C, D, E, F, G, H, A, W[47], 0x106AA070); + F1(A, B, C, D, E, F, G, H, W[48], 0x19A4C116); + F1(H, A, B, C, D, E, F, G, W[49], 0x1E376C08); + F1(G, H, A, B, C, D, E, F, W[50], 0x2748774C); + F1(F, G, H, A, B, C, D, E, W[51], 0x34B0BCB5); + F1(E, F, G, H, A, B, C, D, W[52], 0x391C0CB3); + F1(D, E, F, G, H, A, B, C, W[53], 0x4ED8AA4A); + F1(C, D, E, F, G, H, A, B, W[54], 0x5B9CCA4F); + F1(B, C, D, E, F, G, H, A, W[55], 0x682E6FF3); + F1(A, B, C, D, E, F, G, H, W[56], 0x748F82EE); + F1(H, A, B, C, D, E, F, G, W[57], 0x78A5636F); + F1(G, H, A, B, C, D, E, F, W[58], 0x84C87814); + F1(F, G, H, A, B, C, D, E, W[59], 0x8CC70208); + F1(E, F, G, H, A, B, C, D, W[60], 0x90BEFFFA); + F1(D, E, F, G, H, A, B, C, W[61], 0xA4506CEB); + F1(C, D, E, F, G, H, A, B, W[62], 0xBEF9A3F7); + F1(B, C, D, E, F, G, H, A, W[63], 0xC67178F2); + + digest[0] += A; digest[1] += B; digest[2] += C; + digest[3] += D; digest[4] += E; digest[5] += F; + digest[6] += G; digest[7] += H; + } } /************************************************* diff --git a/src/hash/sha2/sha2_32.h b/src/hash/sha2/sha2_32.h index 220767c1b..f4c8d978a 100644 --- a/src/hash/sha2/sha2_32.h +++ b/src/hash/sha2/sha2_32.h @@ -24,7 +24,7 @@ class BOTAN_DLL SHA_224_256_BASE : public MDx_HashFunction SecureBuffer<u32bit, 64> W; SecureBuffer<u32bit, 8> digest; private: - void hash(const byte[]); + void compress_n(const byte[], u32bit blocks); void copy_out(byte[]); }; diff --git a/src/hash/sha2/sha2_64.cpp b/src/hash/sha2/sha2_64.cpp index 809111d5e..73333af79 100644 --- a/src/hash/sha2/sha2_64.cpp +++ b/src/hash/sha2/sha2_64.cpp @@ -45,103 +45,107 @@ inline u64bit sigma(u64bit X, u32bit rot1, u32bit rot2, u32bit shift) /************************************************* * SHA-{384,512} Compression Function * *************************************************/ -void SHA_384_512_BASE::hash(const byte input[]) +void SHA_384_512_BASE::compress_n(const byte input[], u32bit blocks) { - for(u32bit j = 0; j != 16; ++j) - W[j] = load_be<u64bit>(input, j); - - for(u32bit j = 16; j != 80; ++j) - W[j] = sigma(W[j- 2], 19, 61, 6) + W[j- 7] + - sigma(W[j-15], 1, 8, 7) + W[j-16]; - - 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]; - - F1(A,B,C,D,E,F,G,H,W[ 0],0x428A2F98D728AE22); - F1(H,A,B,C,D,E,F,G,W[ 1],0x7137449123EF65CD); - F1(G,H,A,B,C,D,E,F,W[ 2],0xB5C0FBCFEC4D3B2F); - F1(F,G,H,A,B,C,D,E,W[ 3],0xE9B5DBA58189DBBC); - F1(E,F,G,H,A,B,C,D,W[ 4],0x3956C25BF348B538); - F1(D,E,F,G,H,A,B,C,W[ 5],0x59F111F1B605D019); - F1(C,D,E,F,G,H,A,B,W[ 6],0x923F82A4AF194F9B); - F1(B,C,D,E,F,G,H,A,W[ 7],0xAB1C5ED5DA6D8118); - F1(A,B,C,D,E,F,G,H,W[ 8],0xD807AA98A3030242); - F1(H,A,B,C,D,E,F,G,W[ 9],0x12835B0145706FBE); - F1(G,H,A,B,C,D,E,F,W[10],0x243185BE4EE4B28C); - F1(F,G,H,A,B,C,D,E,W[11],0x550C7DC3D5FFB4E2); - F1(E,F,G,H,A,B,C,D,W[12],0x72BE5D74F27B896F); - F1(D,E,F,G,H,A,B,C,W[13],0x80DEB1FE3B1696B1); - F1(C,D,E,F,G,H,A,B,W[14],0x9BDC06A725C71235); - F1(B,C,D,E,F,G,H,A,W[15],0xC19BF174CF692694); - F1(A,B,C,D,E,F,G,H,W[16],0xE49B69C19EF14AD2); - F1(H,A,B,C,D,E,F,G,W[17],0xEFBE4786384F25E3); - F1(G,H,A,B,C,D,E,F,W[18],0x0FC19DC68B8CD5B5); - F1(F,G,H,A,B,C,D,E,W[19],0x240CA1CC77AC9C65); - F1(E,F,G,H,A,B,C,D,W[20],0x2DE92C6F592B0275); - F1(D,E,F,G,H,A,B,C,W[21],0x4A7484AA6EA6E483); - F1(C,D,E,F,G,H,A,B,W[22],0x5CB0A9DCBD41FBD4); - F1(B,C,D,E,F,G,H,A,W[23],0x76F988DA831153B5); - F1(A,B,C,D,E,F,G,H,W[24],0x983E5152EE66DFAB); - F1(H,A,B,C,D,E,F,G,W[25],0xA831C66D2DB43210); - F1(G,H,A,B,C,D,E,F,W[26],0xB00327C898FB213F); - F1(F,G,H,A,B,C,D,E,W[27],0xBF597FC7BEEF0EE4); - F1(E,F,G,H,A,B,C,D,W[28],0xC6E00BF33DA88FC2); - F1(D,E,F,G,H,A,B,C,W[29],0xD5A79147930AA725); - F1(C,D,E,F,G,H,A,B,W[30],0x06CA6351E003826F); - F1(B,C,D,E,F,G,H,A,W[31],0x142929670A0E6E70); - F1(A,B,C,D,E,F,G,H,W[32],0x27B70A8546D22FFC); - F1(H,A,B,C,D,E,F,G,W[33],0x2E1B21385C26C926); - F1(G,H,A,B,C,D,E,F,W[34],0x4D2C6DFC5AC42AED); - F1(F,G,H,A,B,C,D,E,W[35],0x53380D139D95B3DF); - F1(E,F,G,H,A,B,C,D,W[36],0x650A73548BAF63DE); - F1(D,E,F,G,H,A,B,C,W[37],0x766A0ABB3C77B2A8); - F1(C,D,E,F,G,H,A,B,W[38],0x81C2C92E47EDAEE6); - F1(B,C,D,E,F,G,H,A,W[39],0x92722C851482353B); - F1(A,B,C,D,E,F,G,H,W[40],0xA2BFE8A14CF10364); - F1(H,A,B,C,D,E,F,G,W[41],0xA81A664BBC423001); - F1(G,H,A,B,C,D,E,F,W[42],0xC24B8B70D0F89791); - F1(F,G,H,A,B,C,D,E,W[43],0xC76C51A30654BE30); - F1(E,F,G,H,A,B,C,D,W[44],0xD192E819D6EF5218); - F1(D,E,F,G,H,A,B,C,W[45],0xD69906245565A910); - F1(C,D,E,F,G,H,A,B,W[46],0xF40E35855771202A); - F1(B,C,D,E,F,G,H,A,W[47],0x106AA07032BBD1B8); - F1(A,B,C,D,E,F,G,H,W[48],0x19A4C116B8D2D0C8); - F1(H,A,B,C,D,E,F,G,W[49],0x1E376C085141AB53); - F1(G,H,A,B,C,D,E,F,W[50],0x2748774CDF8EEB99); - F1(F,G,H,A,B,C,D,E,W[51],0x34B0BCB5E19B48A8); - F1(E,F,G,H,A,B,C,D,W[52],0x391C0CB3C5C95A63); - F1(D,E,F,G,H,A,B,C,W[53],0x4ED8AA4AE3418ACB); - F1(C,D,E,F,G,H,A,B,W[54],0x5B9CCA4F7763E373); - F1(B,C,D,E,F,G,H,A,W[55],0x682E6FF3D6B2B8A3); - F1(A,B,C,D,E,F,G,H,W[56],0x748F82EE5DEFB2FC); - F1(H,A,B,C,D,E,F,G,W[57],0x78A5636F43172F60); - F1(G,H,A,B,C,D,E,F,W[58],0x84C87814A1F0AB72); - F1(F,G,H,A,B,C,D,E,W[59],0x8CC702081A6439EC); - F1(E,F,G,H,A,B,C,D,W[60],0x90BEFFFA23631E28); - F1(D,E,F,G,H,A,B,C,W[61],0xA4506CEBDE82BDE9); - F1(C,D,E,F,G,H,A,B,W[62],0xBEF9A3F7B2C67915); - F1(B,C,D,E,F,G,H,A,W[63],0xC67178F2E372532B); - F1(A,B,C,D,E,F,G,H,W[64],0xCA273ECEEA26619C); - F1(H,A,B,C,D,E,F,G,W[65],0xD186B8C721C0C207); - F1(G,H,A,B,C,D,E,F,W[66],0xEADA7DD6CDE0EB1E); - F1(F,G,H,A,B,C,D,E,W[67],0xF57D4F7FEE6ED178); - F1(E,F,G,H,A,B,C,D,W[68],0x06F067AA72176FBA); - F1(D,E,F,G,H,A,B,C,W[69],0x0A637DC5A2C898A6); - F1(C,D,E,F,G,H,A,B,W[70],0x113F9804BEF90DAE); - F1(B,C,D,E,F,G,H,A,W[71],0x1B710B35131C471B); - F1(A,B,C,D,E,F,G,H,W[72],0x28DB77F523047D84); - F1(H,A,B,C,D,E,F,G,W[73],0x32CAAB7B40C72493); - F1(G,H,A,B,C,D,E,F,W[74],0x3C9EBE0A15C9BEBC); - F1(F,G,H,A,B,C,D,E,W[75],0x431D67C49C100D4C); - F1(E,F,G,H,A,B,C,D,W[76],0x4CC5D4BECB3E42B6); - F1(D,E,F,G,H,A,B,C,W[77],0x597F299CFC657E2A); - F1(C,D,E,F,G,H,A,B,W[78],0x5FCB6FAB3AD6FAEC); - F1(B,C,D,E,F,G,H,A,W[79],0x6C44198C4A475817); - - digest[0] += A; digest[1] += B; digest[2] += C; - digest[3] += D; digest[4] += E; digest[5] += F; - digest[6] += G; digest[7] += H; + for(u32bit i = 0; i != blocks; ++i) + { + for(u32bit j = 0; j != 16; ++j) + W[j] = load_be<u64bit>(input, j); + input += HASH_BLOCK_SIZE; + + for(u32bit j = 16; j != 80; ++j) + W[j] = sigma(W[j- 2], 19, 61, 6) + W[j- 7] + + sigma(W[j-15], 1, 8, 7) + W[j-16]; + + 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]; + + F1(A,B,C,D,E,F,G,H,W[ 0],0x428A2F98D728AE22); + F1(H,A,B,C,D,E,F,G,W[ 1],0x7137449123EF65CD); + F1(G,H,A,B,C,D,E,F,W[ 2],0xB5C0FBCFEC4D3B2F); + F1(F,G,H,A,B,C,D,E,W[ 3],0xE9B5DBA58189DBBC); + F1(E,F,G,H,A,B,C,D,W[ 4],0x3956C25BF348B538); + F1(D,E,F,G,H,A,B,C,W[ 5],0x59F111F1B605D019); + F1(C,D,E,F,G,H,A,B,W[ 6],0x923F82A4AF194F9B); + F1(B,C,D,E,F,G,H,A,W[ 7],0xAB1C5ED5DA6D8118); + F1(A,B,C,D,E,F,G,H,W[ 8],0xD807AA98A3030242); + F1(H,A,B,C,D,E,F,G,W[ 9],0x12835B0145706FBE); + F1(G,H,A,B,C,D,E,F,W[10],0x243185BE4EE4B28C); + F1(F,G,H,A,B,C,D,E,W[11],0x550C7DC3D5FFB4E2); + F1(E,F,G,H,A,B,C,D,W[12],0x72BE5D74F27B896F); + F1(D,E,F,G,H,A,B,C,W[13],0x80DEB1FE3B1696B1); + F1(C,D,E,F,G,H,A,B,W[14],0x9BDC06A725C71235); + F1(B,C,D,E,F,G,H,A,W[15],0xC19BF174CF692694); + F1(A,B,C,D,E,F,G,H,W[16],0xE49B69C19EF14AD2); + F1(H,A,B,C,D,E,F,G,W[17],0xEFBE4786384F25E3); + F1(G,H,A,B,C,D,E,F,W[18],0x0FC19DC68B8CD5B5); + F1(F,G,H,A,B,C,D,E,W[19],0x240CA1CC77AC9C65); + F1(E,F,G,H,A,B,C,D,W[20],0x2DE92C6F592B0275); + F1(D,E,F,G,H,A,B,C,W[21],0x4A7484AA6EA6E483); + F1(C,D,E,F,G,H,A,B,W[22],0x5CB0A9DCBD41FBD4); + F1(B,C,D,E,F,G,H,A,W[23],0x76F988DA831153B5); + F1(A,B,C,D,E,F,G,H,W[24],0x983E5152EE66DFAB); + F1(H,A,B,C,D,E,F,G,W[25],0xA831C66D2DB43210); + F1(G,H,A,B,C,D,E,F,W[26],0xB00327C898FB213F); + F1(F,G,H,A,B,C,D,E,W[27],0xBF597FC7BEEF0EE4); + F1(E,F,G,H,A,B,C,D,W[28],0xC6E00BF33DA88FC2); + F1(D,E,F,G,H,A,B,C,W[29],0xD5A79147930AA725); + F1(C,D,E,F,G,H,A,B,W[30],0x06CA6351E003826F); + F1(B,C,D,E,F,G,H,A,W[31],0x142929670A0E6E70); + F1(A,B,C,D,E,F,G,H,W[32],0x27B70A8546D22FFC); + F1(H,A,B,C,D,E,F,G,W[33],0x2E1B21385C26C926); + F1(G,H,A,B,C,D,E,F,W[34],0x4D2C6DFC5AC42AED); + F1(F,G,H,A,B,C,D,E,W[35],0x53380D139D95B3DF); + F1(E,F,G,H,A,B,C,D,W[36],0x650A73548BAF63DE); + F1(D,E,F,G,H,A,B,C,W[37],0x766A0ABB3C77B2A8); + F1(C,D,E,F,G,H,A,B,W[38],0x81C2C92E47EDAEE6); + F1(B,C,D,E,F,G,H,A,W[39],0x92722C851482353B); + F1(A,B,C,D,E,F,G,H,W[40],0xA2BFE8A14CF10364); + F1(H,A,B,C,D,E,F,G,W[41],0xA81A664BBC423001); + F1(G,H,A,B,C,D,E,F,W[42],0xC24B8B70D0F89791); + F1(F,G,H,A,B,C,D,E,W[43],0xC76C51A30654BE30); + F1(E,F,G,H,A,B,C,D,W[44],0xD192E819D6EF5218); + F1(D,E,F,G,H,A,B,C,W[45],0xD69906245565A910); + F1(C,D,E,F,G,H,A,B,W[46],0xF40E35855771202A); + F1(B,C,D,E,F,G,H,A,W[47],0x106AA07032BBD1B8); + F1(A,B,C,D,E,F,G,H,W[48],0x19A4C116B8D2D0C8); + F1(H,A,B,C,D,E,F,G,W[49],0x1E376C085141AB53); + F1(G,H,A,B,C,D,E,F,W[50],0x2748774CDF8EEB99); + F1(F,G,H,A,B,C,D,E,W[51],0x34B0BCB5E19B48A8); + F1(E,F,G,H,A,B,C,D,W[52],0x391C0CB3C5C95A63); + F1(D,E,F,G,H,A,B,C,W[53],0x4ED8AA4AE3418ACB); + F1(C,D,E,F,G,H,A,B,W[54],0x5B9CCA4F7763E373); + F1(B,C,D,E,F,G,H,A,W[55],0x682E6FF3D6B2B8A3); + F1(A,B,C,D,E,F,G,H,W[56],0x748F82EE5DEFB2FC); + F1(H,A,B,C,D,E,F,G,W[57],0x78A5636F43172F60); + F1(G,H,A,B,C,D,E,F,W[58],0x84C87814A1F0AB72); + F1(F,G,H,A,B,C,D,E,W[59],0x8CC702081A6439EC); + F1(E,F,G,H,A,B,C,D,W[60],0x90BEFFFA23631E28); + F1(D,E,F,G,H,A,B,C,W[61],0xA4506CEBDE82BDE9); + F1(C,D,E,F,G,H,A,B,W[62],0xBEF9A3F7B2C67915); + F1(B,C,D,E,F,G,H,A,W[63],0xC67178F2E372532B); + F1(A,B,C,D,E,F,G,H,W[64],0xCA273ECEEA26619C); + F1(H,A,B,C,D,E,F,G,W[65],0xD186B8C721C0C207); + F1(G,H,A,B,C,D,E,F,W[66],0xEADA7DD6CDE0EB1E); + F1(F,G,H,A,B,C,D,E,W[67],0xF57D4F7FEE6ED178); + F1(E,F,G,H,A,B,C,D,W[68],0x06F067AA72176FBA); + F1(D,E,F,G,H,A,B,C,W[69],0x0A637DC5A2C898A6); + F1(C,D,E,F,G,H,A,B,W[70],0x113F9804BEF90DAE); + F1(B,C,D,E,F,G,H,A,W[71],0x1B710B35131C471B); + F1(A,B,C,D,E,F,G,H,W[72],0x28DB77F523047D84); + F1(H,A,B,C,D,E,F,G,W[73],0x32CAAB7B40C72493); + F1(G,H,A,B,C,D,E,F,W[74],0x3C9EBE0A15C9BEBC); + F1(F,G,H,A,B,C,D,E,W[75],0x431D67C49C100D4C); + F1(E,F,G,H,A,B,C,D,W[76],0x4CC5D4BECB3E42B6); + F1(D,E,F,G,H,A,B,C,W[77],0x597F299CFC657E2A); + F1(C,D,E,F,G,H,A,B,W[78],0x5FCB6FAB3AD6FAEC); + F1(B,C,D,E,F,G,H,A,W[79],0x6C44198C4A475817); + + digest[0] += A; digest[1] += B; digest[2] += C; + digest[3] += D; digest[4] += E; digest[5] += F; + digest[6] += G; digest[7] += H; + } } /************************************************* diff --git a/src/hash/sha2/sha2_64.h b/src/hash/sha2/sha2_64.h index 9cd79ae1b..51efb455b 100644 --- a/src/hash/sha2/sha2_64.h +++ b/src/hash/sha2/sha2_64.h @@ -23,7 +23,7 @@ class BOTAN_DLL SHA_384_512_BASE : public MDx_HashFunction SecureBuffer<u64bit, 8> digest; private: - void hash(const byte[]); + void compress_n(const byte[], u32bit blocks); void copy_out(byte[]); SecureBuffer<u64bit, 80> W; diff --git a/src/hash/tiger/tiger.cpp b/src/hash/tiger/tiger.cpp index 055819dbd..3ff25766a 100644 --- a/src/hash/tiger/tiger.cpp +++ b/src/hash/tiger/tiger.cpp @@ -13,25 +13,29 @@ namespace Botan { /************************************************* * Tiger Compression Function * *************************************************/ -void Tiger::hash(const byte input[]) +void Tiger::compress_n(const byte input[], u32bit blocks) { - for(u32bit j = 0; j != 8; ++j) - X[j] = load_le<u64bit>(input, j); + for(u32bit i = 0; i != blocks; ++i) + { + for(u32bit j = 0; j != 8; ++j) + X[j] = load_le<u64bit>(input, j); + input += HASH_BLOCK_SIZE; - u64bit A = digest[0], B = digest[1], C = digest[2]; + u64bit A = digest[0], B = digest[1], C = digest[2]; - pass(A, B, C, X, 5); mix(X); - pass(C, A, B, X, 7); mix(X); - pass(B, C, A, X, 9); + pass(A, B, C, X, 5); mix(X); + pass(C, A, B, X, 7); mix(X); + pass(B, C, A, X, 9); - for(u32bit j = 3; j != PASS; ++j) - { - mix(X); - pass(A, B, C, X, 9); - u64bit T = A; A = C; C = B; B = T; - } + for(u32bit j = 3; j != PASS; ++j) + { + mix(X); + pass(A, B, C, X, 9); + u64bit T = A; A = C; C = B; B = T; + } - digest[0] ^= A; digest[1] = B - digest[1]; digest[2] += C; + digest[0] ^= A; digest[1] = B - digest[1]; digest[2] += C; + } } /************************************************* diff --git a/src/hash/tiger/tiger.h b/src/hash/tiger/tiger.h index 4c95fa784..4cbe1c419 100644 --- a/src/hash/tiger/tiger.h +++ b/src/hash/tiger/tiger.h @@ -21,7 +21,7 @@ class BOTAN_DLL Tiger : public MDx_HashFunction HashFunction* clone() const { return new Tiger(OUTPUT_LENGTH); } Tiger(u32bit = 24, u32bit = 3); private: - void hash(const byte[]); + void compress_n(const byte[], u32bit block); void copy_out(byte[]); static void pass(u64bit&, u64bit&, u64bit&, u64bit[8], byte); diff --git a/src/hash/whirlpool/whrlpool.cpp b/src/hash/whirlpool/whrlpool.cpp index 9319a8b2a..b604f9400 100644 --- a/src/hash/whirlpool/whrlpool.cpp +++ b/src/hash/whirlpool/whrlpool.cpp @@ -11,7 +11,7 @@ namespace Botan { /************************************************* * Whirlpool Compression Function * *************************************************/ -void Whirlpool::hash(const byte in[]) +void Whirlpool::compress_n(const byte in[], u32bit blocks) { static const u64bit RC[10] = { 0x1823C6E887B8014F, 0x36A6D2F5796F9152, @@ -21,101 +21,105 @@ void Whirlpool::hash(const byte in[]) 0xFBEE7C66DD17479E, 0xCA2DBF07AD5A8333 }; - for(u32bit j = 0; j != 8; ++j) - M[j] = load_be<u64bit>(in, j); + for(u32bit i = 0; i != blocks; ++i) + { + for(u32bit j = 0; j != 8; ++j) + M[j] = load_be<u64bit>(in, j); + in += HASH_BLOCK_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 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]; + 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(u32bit 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)]; + for(u32bit 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; + 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; + 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; - } + 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]; + 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]; + } } /************************************************* diff --git a/src/hash/whirlpool/whrlpool.h b/src/hash/whirlpool/whrlpool.h index 22f747520..25a5bb34d 100644 --- a/src/hash/whirlpool/whrlpool.h +++ b/src/hash/whirlpool/whrlpool.h @@ -21,7 +21,7 @@ class BOTAN_DLL Whirlpool : public MDx_HashFunction HashFunction* clone() const { return new Whirlpool; } Whirlpool() : MDx_HashFunction(64, 64, true, true, 32) { clear(); } private: - void hash(const byte[]); + void compress_n(const byte[], u32bit blocks); void copy_out(byte[]); static const u64bit C0[256]; |