--- /dev/null
+/**************************************************************************\
+|
+| Copyright (C) 2012 CWI
+|
+| Contact:
+| Marc Stevens
+| Cryptology Group
+| Centrum Wiskunde & Informatica
+| P.O. Box 94079, 1090 GB Amsterdam, Netherlands
+| marc@marc-stevens.nl
+|
+| Permission is hereby granted, free of charge, to any person obtaining a copy
+| of this software and associated documentation files (the "Software"), to deal
+| in the Software without restriction, including without limitation the rights
+| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+| copies of the Software, and to permit persons to whom the Software is
+| furnished to do so, subject to the following conditions:
+|
+| The above copyright notice and this permission notice shall be included in
+| all copies or substantial portions of the Software.
+|
+| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+| THE SOFTWARE.
+|
+\**************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libdetectcoll.h"
+
+#define rotate_right(x,n) (((x)>>(n))|((x)<<(32-(n))))
+#define rotate_left(x,n) (((x)<<(n))|((x)>>(32-(n))))
+
+void swap_bytes(uint32_t val[16]) {
+ unsigned i;
+ for (i = 0; i < 16; ++i) {
+ val[i] = ((val[i]<<8)&0xFF00FF00)|((val[i]>>8)&0xFF00FF);
+ val[i] = (val[i]<<16) | (val[i]>>16);
+ }
+}
+
+const unsigned md5_wt[] =
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
+ , 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12
+ , 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2
+ , 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 };
+#define md5_ff(b,c,d) ((d) ^ ((b) & ((c) ^ (d))))
+#define md5_gg(b,c,d) ((c) ^ ((d) & ((b) ^ (c))))
+#define md5_hh(b,c,d) ((b) ^ (c) ^ (d))
+#define md5_ii(b,c,d) ((c) ^ ((b) | ~(d)))
+#define HASHUTIL5_MD5COMPRESS_STEP(f, a, b, c, d, m, ac, rc) \
+ a += f(b, c, d) + m + ac; a = rotate_left(a,rc); a += b;
+#define HASHUTIL5_MD5COMPRESS_STEP_BW(f, a, b, c, d, m, ac, rc) \
+ a -= b; a = rotate_right(a,rc); a -= f(b,c,d) + m + ac;
+
+#define sha1_f1(b,c,d) ((d)^((b)&((c)^(d))))
+#define sha1_f2(b,c,d) ((b)^(c)^(d))
+#define sha1_f3(b,c,d) (((b) & ((c)|(d))) | ((c)&(d)))
+#define sha1_f4(b,c,d) ((b)^(c)^(d))
+#define HASHCLASH_SHA1COMPRESS_ROUND1_STEP(a, b, c, d, e, m, t) \
+ e += rotate_left(a, 5) + sha1_f1(b,c,d) + 0x5A827999 + m[t]; b = rotate_left(b, 30);
+#define HASHCLASH_SHA1COMPRESS_ROUND2_STEP(a, b, c, d, e, m, t) \
+ e += rotate_left(a, 5) + sha1_f2(b,c,d) + 0x6ED9EBA1 + m[t]; b = rotate_left(b, 30);
+#define HASHCLASH_SHA1COMPRESS_ROUND3_STEP(a, b, c, d, e, m, t) \
+ e += rotate_left(a, 5) + sha1_f3(b,c,d) + 0x8F1BBCDC + m[t]; b = rotate_left(b, 30);
+#define HASHCLASH_SHA1COMPRESS_ROUND4_STEP(a, b, c, d, e, m, t) \
+ e += rotate_left(a, 5) + sha1_f4(b,c,d) + 0xCA62C1D6 + m[t]; b = rotate_left(b, 30);
+#define HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW(a, b, c, d, e, m, t) \
+ b = rotate_right(b, 30); e -= rotate_left(a, 5) + sha1_f1(b,c,d) + 0x5A827999 + m[t];
+#define HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW(a, b, c, d, e, m, t) \
+ b = rotate_right(b, 30); e -= rotate_left(a, 5) + sha1_f2(b,c,d) + 0x6ED9EBA1 + m[t];
+#define HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW(a, b, c, d, e, m, t) \
+ b = rotate_right(b, 30); e -= rotate_left(a, 5) + sha1_f3(b,c,d) + 0x8F1BBCDC + m[t];
+#define HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW(a, b, c, d, e, m, t) \
+ b = rotate_right(b, 30); e -= rotate_left(a, 5) + sha1_f4(b,c,d) + 0xCA62C1D6 + m[t];
+
+#define STORE_STATE(i) states[(4*(i))] = a; states[(4*(i))+1] = b; states[(4*(i))+2] = c; states[(4*(i))+3] = d;
+#define LOAD_STATE(i) a = states[(4*(i))]; b = states[(4*(i))+1]; c = states[(4*(i))+2]; d = states[(4*(i))+3];
+
+#define SHA1_STORE_STATE(i) states[(5*(i))] = a; states[(5*(i))+1] = b; states[(5*(i))+2] = c; states[(5*(i))+3] = d; states[(5*(i))+4] = e;
+#define SHA1_LOAD_STATE(i) a = states[(4*(i))]; b = states[(4*(i))+1]; c = states[(4*(i))+2]; d = states[(4*(i))+3]; e = states[(5*(i))+4];
+
+
+
+
+
+
+
+
+
+
+void sha1compress_me(const uint32_t block[16], uint32_t me[80]) {
+ unsigned i;
+ if ( (const uint32_t*)(block) != (const uint32_t*)(me) )
+ memcpy(me, block, 64);
+ for (i = 16; i < 80; ++i)
+ me[i]=rotate_left(me[i-3] ^ me[i-8] ^ me[i-14] ^ me[i-16], 1);
+}
+
+void sha1compress_states(uint32_t ihv[5], const uint32_t me[80], uint32_t states[81*5]) {
+ uint32_t a = ihv[0], b = ihv[1], c = ihv[2], d = ihv[3], e = ihv[4];
+
+ HASHCLASH_SHA1COMPRESS_ROUND1_STEP( a, b, c, d, e, me, 0 );
+ HASHCLASH_SHA1COMPRESS_ROUND1_STEP( e, a, b, c, d, me, 1 );
+ HASHCLASH_SHA1COMPRESS_ROUND1_STEP( d, e, a, b, c, me, 2 );
+ HASHCLASH_SHA1COMPRESS_ROUND1_STEP( c, d, e, a, b, me, 3 );
+ HASHCLASH_SHA1COMPRESS_ROUND1_STEP( b, c, d, e, a, me, 4 );
+ HASHCLASH_SHA1COMPRESS_ROUND1_STEP( a, b, c, d, e, me, 5 );
+ HASHCLASH_SHA1COMPRESS_ROUND1_STEP( e, a, b, c, d, me, 6 );
+ HASHCLASH_SHA1COMPRESS_ROUND1_STEP( d, e, a, b, c, me, 7 );
+ HASHCLASH_SHA1COMPRESS_ROUND1_STEP( c, d, e, a, b, me, 8 );
+ HASHCLASH_SHA1COMPRESS_ROUND1_STEP( b, c, d, e, a, me, 9 );
+ HASHCLASH_SHA1COMPRESS_ROUND1_STEP( a, b, c, d, e, me, 10 );
+ HASHCLASH_SHA1COMPRESS_ROUND1_STEP( e, a, b, c, d, me, 11 );
+ HASHCLASH_SHA1COMPRESS_ROUND1_STEP( d, e, a, b, c, me, 12 );
+ HASHCLASH_SHA1COMPRESS_ROUND1_STEP( c, d, e, a, b, me, 13 );
+ HASHCLASH_SHA1COMPRESS_ROUND1_STEP( b, c, d, e, a, me, 14 );
+ HASHCLASH_SHA1COMPRESS_ROUND1_STEP( a, b, c, d, e, me, 15 );
+ HASHCLASH_SHA1COMPRESS_ROUND1_STEP( e, a, b, c, d, me, 16 );
+ HASHCLASH_SHA1COMPRESS_ROUND1_STEP( d, e, a, b, c, me, 17 );
+ HASHCLASH_SHA1COMPRESS_ROUND1_STEP( c, d, e, a, b, me, 18 );
+ HASHCLASH_SHA1COMPRESS_ROUND1_STEP( b, c, d, e, a, me, 19 );
+
+// SHA1_STORE_STATE(20);
+ HASHCLASH_SHA1COMPRESS_ROUND2_STEP( a, b, c, d, e, me, 20 );
+// SHA1_STORE_STATE(21);
+ HASHCLASH_SHA1COMPRESS_ROUND2_STEP( e, a, b, c, d, me, 21 );
+// SHA1_STORE_STATE(22);
+ HASHCLASH_SHA1COMPRESS_ROUND2_STEP( d, e, a, b, c, me, 22 );
+// SHA1_STORE_STATE(23);
+ HASHCLASH_SHA1COMPRESS_ROUND2_STEP( c, d, e, a, b, me, 23 );
+// SHA1_STORE_STATE(24);
+ HASHCLASH_SHA1COMPRESS_ROUND2_STEP( b, c, d, e, a, me, 24 );
+// SHA1_STORE_STATE(25);
+ HASHCLASH_SHA1COMPRESS_ROUND2_STEP( a, b, c, d, e, me, 25 );
+// SHA1_STORE_STATE(26);
+ HASHCLASH_SHA1COMPRESS_ROUND2_STEP( e, a, b, c, d, me, 26 );
+// SHA1_STORE_STATE(27);
+ HASHCLASH_SHA1COMPRESS_ROUND2_STEP( d, e, a, b, c, me, 27 );
+// SHA1_STORE_STATE(28);
+ HASHCLASH_SHA1COMPRESS_ROUND2_STEP( c, d, e, a, b, me, 28 );
+// SHA1_STORE_STATE(29);
+ HASHCLASH_SHA1COMPRESS_ROUND2_STEP( b, c, d, e, a, me, 29 );
+// SHA1_STORE_STATE(30);
+ HASHCLASH_SHA1COMPRESS_ROUND2_STEP( a, b, c, d, e, me, 30 );
+// SHA1_STORE_STATE(31);
+ HASHCLASH_SHA1COMPRESS_ROUND2_STEP( e, a, b, c, d, me, 31 );
+// SHA1_STORE_STATE(32);
+ HASHCLASH_SHA1COMPRESS_ROUND2_STEP( d, e, a, b, c, me, 32 );
+// SHA1_STORE_STATE(33);
+ HASHCLASH_SHA1COMPRESS_ROUND2_STEP( c, d, e, a, b, me, 33 );
+// SHA1_STORE_STATE(34);
+ HASHCLASH_SHA1COMPRESS_ROUND2_STEP( b, c, d, e, a, me, 34 );
+// SHA1_STORE_STATE(35);
+ HASHCLASH_SHA1COMPRESS_ROUND2_STEP( a, b, c, d, e, me, 35 );
+// SHA1_STORE_STATE(36);
+ HASHCLASH_SHA1COMPRESS_ROUND2_STEP( e, a, b, c, d, me, 36 );
+// SHA1_STORE_STATE(37);
+ HASHCLASH_SHA1COMPRESS_ROUND2_STEP( d, e, a, b, c, me, 37 );
+// SHA1_STORE_STATE(38);
+ HASHCLASH_SHA1COMPRESS_ROUND2_STEP( c, d, e, a, b, me, 38 );
+// SHA1_STORE_STATE(39);
+ HASHCLASH_SHA1COMPRESS_ROUND2_STEP( b, c, d, e, a, me, 39 );
+
+// SHA1_STORE_STATE(40);
+ HASHCLASH_SHA1COMPRESS_ROUND3_STEP( a, b, c, d, e, me, 40 );
+// SHA1_STORE_STATE(41);
+ HASHCLASH_SHA1COMPRESS_ROUND3_STEP( e, a, b, c, d, me, 41 );
+// SHA1_STORE_STATE(42);
+ HASHCLASH_SHA1COMPRESS_ROUND3_STEP( d, e, a, b, c, me, 42 );
+// SHA1_STORE_STATE(43);
+ HASHCLASH_SHA1COMPRESS_ROUND3_STEP( c, d, e, a, b, me, 43 );
+// SHA1_STORE_STATE(44);
+ HASHCLASH_SHA1COMPRESS_ROUND3_STEP( b, c, d, e, a, me, 44 );
+// SHA1_STORE_STATE(45);
+ HASHCLASH_SHA1COMPRESS_ROUND3_STEP( a, b, c, d, e, me, 45 );
+// SHA1_STORE_STATE(46);
+ HASHCLASH_SHA1COMPRESS_ROUND3_STEP( e, a, b, c, d, me, 46 );
+// SHA1_STORE_STATE(47);
+ HASHCLASH_SHA1COMPRESS_ROUND3_STEP( d, e, a, b, c, me, 47 );
+// SHA1_STORE_STATE(48);
+ HASHCLASH_SHA1COMPRESS_ROUND3_STEP( c, d, e, a, b, me, 48 );
+// SHA1_STORE_STATE(49);
+ HASHCLASH_SHA1COMPRESS_ROUND3_STEP( b, c, d, e, a, me, 49 );
+// SHA1_STORE_STATE(50);
+ HASHCLASH_SHA1COMPRESS_ROUND3_STEP( a, b, c, d, e, me, 50 );
+// SHA1_STORE_STATE(51);
+ HASHCLASH_SHA1COMPRESS_ROUND3_STEP( e, a, b, c, d, me, 51 );
+// SHA1_STORE_STATE(52);
+ HASHCLASH_SHA1COMPRESS_ROUND3_STEP( d, e, a, b, c, me, 52 );
+// SHA1_STORE_STATE(53);
+ HASHCLASH_SHA1COMPRESS_ROUND3_STEP( c, d, e, a, b, me, 53 );
+// SHA1_STORE_STATE(54);
+ HASHCLASH_SHA1COMPRESS_ROUND3_STEP( b, c, d, e, a, me, 54 );
+// SHA1_STORE_STATE(55);
+ HASHCLASH_SHA1COMPRESS_ROUND3_STEP( a, b, c, d, e, me, 55 );
+// SHA1_STORE_STATE(56);
+ HASHCLASH_SHA1COMPRESS_ROUND3_STEP( e, a, b, c, d, me, 56 );
+// SHA1_STORE_STATE(57);
+ HASHCLASH_SHA1COMPRESS_ROUND3_STEP( d, e, a, b, c, me, 57 );
+// SHA1_STORE_STATE(58);
+ HASHCLASH_SHA1COMPRESS_ROUND3_STEP( c, d, e, a, b, me, 58 );
+ SHA1_STORE_STATE(59);
+ HASHCLASH_SHA1COMPRESS_ROUND3_STEP( b, c, d, e, a, me, 59 );
+
+ SHA1_STORE_STATE(60);
+ HASHCLASH_SHA1COMPRESS_ROUND4_STEP( a, b, c, d, e, me, 60 );
+ SHA1_STORE_STATE(61);
+ HASHCLASH_SHA1COMPRESS_ROUND4_STEP( e, a, b, c, d, me, 61 );
+ SHA1_STORE_STATE(62);
+ HASHCLASH_SHA1COMPRESS_ROUND4_STEP( d, e, a, b, c, me, 62 );
+ SHA1_STORE_STATE(63);
+ HASHCLASH_SHA1COMPRESS_ROUND4_STEP( c, d, e, a, b, me, 63 );
+ SHA1_STORE_STATE(64);
+ HASHCLASH_SHA1COMPRESS_ROUND4_STEP( b, c, d, e, a, me, 64 );
+ SHA1_STORE_STATE(65);
+ HASHCLASH_SHA1COMPRESS_ROUND4_STEP( a, b, c, d, e, me, 65 );
+ SHA1_STORE_STATE(66);
+ HASHCLASH_SHA1COMPRESS_ROUND4_STEP( e, a, b, c, d, me, 66 );
+ SHA1_STORE_STATE(67);
+ HASHCLASH_SHA1COMPRESS_ROUND4_STEP( d, e, a, b, c, me, 67 );
+ SHA1_STORE_STATE(68);
+ HASHCLASH_SHA1COMPRESS_ROUND4_STEP( c, d, e, a, b, me, 68 );
+ SHA1_STORE_STATE(69);
+ HASHCLASH_SHA1COMPRESS_ROUND4_STEP( b, c, d, e, a, me, 69 );
+ SHA1_STORE_STATE(70);
+ HASHCLASH_SHA1COMPRESS_ROUND4_STEP( a, b, c, d, e, me, 70 );
+ SHA1_STORE_STATE(71);
+ HASHCLASH_SHA1COMPRESS_ROUND4_STEP( e, a, b, c, d, me, 71 );
+ SHA1_STORE_STATE(72);
+ HASHCLASH_SHA1COMPRESS_ROUND4_STEP( d, e, a, b, c, me, 72 );
+ SHA1_STORE_STATE(73);
+ HASHCLASH_SHA1COMPRESS_ROUND4_STEP( c, d, e, a, b, me, 73 );
+// SHA1_STORE_STATE(74);
+ HASHCLASH_SHA1COMPRESS_ROUND4_STEP( b, c, d, e, a, me, 74 );
+// SHA1_STORE_STATE(75);
+ HASHCLASH_SHA1COMPRESS_ROUND4_STEP( a, b, c, d, e, me, 75 );
+// SHA1_STORE_STATE(76);
+ HASHCLASH_SHA1COMPRESS_ROUND4_STEP( e, a, b, c, d, me, 76 );
+// SHA1_STORE_STATE(77);
+ HASHCLASH_SHA1COMPRESS_ROUND4_STEP( d, e, a, b, c, me, 77 );
+// SHA1_STORE_STATE(78);
+ HASHCLASH_SHA1COMPRESS_ROUND4_STEP( c, d, e, a, b, me, 78 );
+// SHA1_STORE_STATE(79);
+ HASHCLASH_SHA1COMPRESS_ROUND4_STEP( b, c, d, e, a, me, 79 );
+// SHA1_STORE_STATE(80);
+
+ ihv[0] += a; ihv[1] += b; ihv[2] += c; ihv[3] += d; ihv[4] += e;
+}
+
+int sha1recompress_fast(unsigned t, uint32_t ihv[5], const uint32_t me[80], const uint32_t state[5], const uint32_t rihv[5]) {
+ uint32_t a = state[0], b = state[1], c = state[2], d = state[3], e = state[4];
+ switch (t) {
+ case 79: HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW( b, c, d, e, a, me, 79 );
+ case 78: HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW( c, d, e, a, b, me, 78 );
+ case 77: HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW( d, e, a, b, c, me, 77 );
+ case 76: HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW( e, a, b, c, d, me, 76 );
+ case 75: HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW( a, b, c, d, e, me, 75 );
+ case 74: HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW( b, c, d, e, a, me, 74 );
+ case 73: HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW( c, d, e, a, b, me, 73 );
+ case 72: HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW( d, e, a, b, c, me, 72 );
+ case 71: HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW( e, a, b, c, d, me, 71 );
+ case 70: HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW( a, b, c, d, e, me, 70 );
+ case 69: HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW( b, c, d, e, a, me, 69 );
+ case 68: HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW( c, d, e, a, b, me, 68 );
+ case 67: HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW( d, e, a, b, c, me, 67 );
+ case 66: HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW( e, a, b, c, d, me, 66 );
+ case 65: HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW( a, b, c, d, e, me, 65 );
+ case 64: HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW( b, c, d, e, a, me, 64 );
+ case 63: HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW( c, d, e, a, b, me, 63 );
+ case 62: HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW( d, e, a, b, c, me, 62 );
+ case 61: HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW( e, a, b, c, d, me, 61 );
+ case 60: HASHCLASH_SHA1COMPRESS_ROUND4_STEP_BW( a, b, c, d, e, me, 60 );
+ case 59: HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW( b, c, d, e, a, me, 59 );
+ case 58: HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW( c, d, e, a, b, me, 58 );
+ case 57: HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW( d, e, a, b, c, me, 57 );
+ case 56: HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW( e, a, b, c, d, me, 56 );
+ case 55: HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW( a, b, c, d, e, me, 55 );
+ case 54: HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW( b, c, d, e, a, me, 54 );
+ case 53: HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW( c, d, e, a, b, me, 53 );
+ case 52: HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW( d, e, a, b, c, me, 52 );
+ case 51: HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW( e, a, b, c, d, me, 51 );
+ case 50: HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW( a, b, c, d, e, me, 50 );
+ case 49: HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW( b, c, d, e, a, me, 49 );
+ case 48: HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW( c, d, e, a, b, me, 48 );
+ case 47: HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW( d, e, a, b, c, me, 47 );
+ case 46: HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW( e, a, b, c, d, me, 46 );
+ case 45: HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW( a, b, c, d, e, me, 45 );
+ case 44: HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW( b, c, d, e, a, me, 44 );
+ case 43: HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW( c, d, e, a, b, me, 43 );
+ case 42: HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW( d, e, a, b, c, me, 42 );
+ case 41: HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW( e, a, b, c, d, me, 41 );
+ case 40: HASHCLASH_SHA1COMPRESS_ROUND3_STEP_BW( a, b, c, d, e, me, 40 );
+ case 39: HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW( b, c, d, e, a, me, 39 );
+ case 38: HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW( c, d, e, a, b, me, 38 );
+ case 37: HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW( d, e, a, b, c, me, 37 );
+ case 36: HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW( e, a, b, c, d, me, 36 );
+ case 35: HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW( a, b, c, d, e, me, 35 );
+ case 34: HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW( b, c, d, e, a, me, 34 );
+ case 33: HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW( c, d, e, a, b, me, 33 );
+ case 32: HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW( d, e, a, b, c, me, 32 );
+ case 31: HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW( e, a, b, c, d, me, 31 );
+ case 30: HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW( a, b, c, d, e, me, 30 );
+ case 29: HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW( b, c, d, e, a, me, 29 );
+ case 28: HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW( c, d, e, a, b, me, 28 );
+ case 27: HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW( d, e, a, b, c, me, 27 );
+ case 26: HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW( e, a, b, c, d, me, 26 );
+ case 25: HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW( a, b, c, d, e, me, 25 );
+ case 24: HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW( b, c, d, e, a, me, 24 );
+ case 23: HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW( c, d, e, a, b, me, 23 );
+ case 22: HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW( d, e, a, b, c, me, 22 );
+ case 21: HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW( e, a, b, c, d, me, 21 );
+ case 20: HASHCLASH_SHA1COMPRESS_ROUND2_STEP_BW( a, b, c, d, e, me, 20 );
+ case 19: HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW( b, c, d, e, a, me, 19 );
+ case 18: HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW( c, d, e, a, b, me, 18 );
+ case 17: HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW( d, e, a, b, c, me, 17 );
+ case 16: HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW( e, a, b, c, d, me, 16 );
+ case 15: HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW( a, b, c, d, e, me, 15 );
+ case 14: HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW( b, c, d, e, a, me, 14 );
+ case 13: HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW( c, d, e, a, b, me, 13 );
+ case 12: HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW( d, e, a, b, c, me, 12 );
+ case 11: HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW( e, a, b, c, d, me, 11 );
+ case 10: HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW( a, b, c, d, e, me, 10 );
+ case 9: HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW( b, c, d, e, a, me, 9 );
+ case 8: HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW( c, d, e, a, b, me, 8 );
+ case 7: HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW( d, e, a, b, c, me, 7 );
+ case 6: HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW( e, a, b, c, d, me, 6 );
+ case 5: HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW( a, b, c, d, e, me, 5 );
+ case 4: HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW( b, c, d, e, a, me, 4 );
+ case 3: HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW( c, d, e, a, b, me, 3 );
+ case 2: HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW( d, e, a, b, c, me, 2 );
+ case 1: HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW( e, a, b, c, d, me, 1 );
+ case 0: HASHCLASH_SHA1COMPRESS_ROUND1_STEP_BW( a, b, c, d, e, me, 0 );
+ }
+ ihv[0] = a; ihv[1] = b; ihv[2] = c; ihv[3] = d; ihv[4] = e;
+ a = state[0]; b = state[1]; c = state[2]; d = state[3]; e = state[4];
+
+ switch (t+1) {
+ case 0: HASHCLASH_SHA1COMPRESS_ROUND1_STEP( a, b, c, d, e, me, 0 );
+ case 1: HASHCLASH_SHA1COMPRESS_ROUND1_STEP( e, a, b, c, d, me, 1 );
+ case 2: HASHCLASH_SHA1COMPRESS_ROUND1_STEP( d, e, a, b, c, me, 2 );
+ case 3: HASHCLASH_SHA1COMPRESS_ROUND1_STEP( c, d, e, a, b, me, 3 );
+ case 4: HASHCLASH_SHA1COMPRESS_ROUND1_STEP( b, c, d, e, a, me, 4 );
+ case 5: HASHCLASH_SHA1COMPRESS_ROUND1_STEP( a, b, c, d, e, me, 5 );
+ case 6: HASHCLASH_SHA1COMPRESS_ROUND1_STEP( e, a, b, c, d, me, 6 );
+ case 7: HASHCLASH_SHA1COMPRESS_ROUND1_STEP( d, e, a, b, c, me, 7 );
+ case 8: HASHCLASH_SHA1COMPRESS_ROUND1_STEP( c, d, e, a, b, me, 8 );
+ case 9: HASHCLASH_SHA1COMPRESS_ROUND1_STEP( b, c, d, e, a, me, 9 );
+ case 10: HASHCLASH_SHA1COMPRESS_ROUND1_STEP( a, b, c, d, e, me, 10 );
+ case 11: HASHCLASH_SHA1COMPRESS_ROUND1_STEP( e, a, b, c, d, me, 11 );
+ case 12: HASHCLASH_SHA1COMPRESS_ROUND1_STEP( d, e, a, b, c, me, 12 );
+ case 13: HASHCLASH_SHA1COMPRESS_ROUND1_STEP( c, d, e, a, b, me, 13 );
+ case 14: HASHCLASH_SHA1COMPRESS_ROUND1_STEP( b, c, d, e, a, me, 14 );
+ case 15: HASHCLASH_SHA1COMPRESS_ROUND1_STEP( a, b, c, d, e, me, 15 );
+ case 16: HASHCLASH_SHA1COMPRESS_ROUND1_STEP( e, a, b, c, d, me, 16 );
+ case 17: HASHCLASH_SHA1COMPRESS_ROUND1_STEP( d, e, a, b, c, me, 17 );
+ case 18: HASHCLASH_SHA1COMPRESS_ROUND1_STEP( c, d, e, a, b, me, 18 );
+ case 19: HASHCLASH_SHA1COMPRESS_ROUND1_STEP( b, c, d, e, a, me, 19 );
+ case 20: HASHCLASH_SHA1COMPRESS_ROUND2_STEP( a, b, c, d, e, me, 20 );
+ case 21: HASHCLASH_SHA1COMPRESS_ROUND2_STEP( e, a, b, c, d, me, 21 );
+ case 22: HASHCLASH_SHA1COMPRESS_ROUND2_STEP( d, e, a, b, c, me, 22 );
+ case 23: HASHCLASH_SHA1COMPRESS_ROUND2_STEP( c, d, e, a, b, me, 23 );
+ case 24: HASHCLASH_SHA1COMPRESS_ROUND2_STEP( b, c, d, e, a, me, 24 );
+ case 25: HASHCLASH_SHA1COMPRESS_ROUND2_STEP( a, b, c, d, e, me, 25 );
+ case 26: HASHCLASH_SHA1COMPRESS_ROUND2_STEP( e, a, b, c, d, me, 26 );
+ case 27: HASHCLASH_SHA1COMPRESS_ROUND2_STEP( d, e, a, b, c, me, 27 );
+ case 28: HASHCLASH_SHA1COMPRESS_ROUND2_STEP( c, d, e, a, b, me, 28 );
+ case 29: HASHCLASH_SHA1COMPRESS_ROUND2_STEP( b, c, d, e, a, me, 29 );
+ case 30: HASHCLASH_SHA1COMPRESS_ROUND2_STEP( a, b, c, d, e, me, 30 );
+ case 31: HASHCLASH_SHA1COMPRESS_ROUND2_STEP( e, a, b, c, d, me, 31 );
+ case 32: HASHCLASH_SHA1COMPRESS_ROUND2_STEP( d, e, a, b, c, me, 32 );
+ case 33: HASHCLASH_SHA1COMPRESS_ROUND2_STEP( c, d, e, a, b, me, 33 );
+ case 34: HASHCLASH_SHA1COMPRESS_ROUND2_STEP( b, c, d, e, a, me, 34 );
+ case 35: HASHCLASH_SHA1COMPRESS_ROUND2_STEP( a, b, c, d, e, me, 35 );
+ case 36: HASHCLASH_SHA1COMPRESS_ROUND2_STEP( e, a, b, c, d, me, 36 );
+ case 37: HASHCLASH_SHA1COMPRESS_ROUND2_STEP( d, e, a, b, c, me, 37 );
+ case 38: HASHCLASH_SHA1COMPRESS_ROUND2_STEP( c, d, e, a, b, me, 38 );
+ case 39: HASHCLASH_SHA1COMPRESS_ROUND2_STEP( b, c, d, e, a, me, 39 );
+ case 40: HASHCLASH_SHA1COMPRESS_ROUND3_STEP( a, b, c, d, e, me, 40 );
+ case 41: HASHCLASH_SHA1COMPRESS_ROUND3_STEP( e, a, b, c, d, me, 41 );
+ case 42: HASHCLASH_SHA1COMPRESS_ROUND3_STEP( d, e, a, b, c, me, 42 );
+ case 43: HASHCLASH_SHA1COMPRESS_ROUND3_STEP( c, d, e, a, b, me, 43 );
+ case 44: HASHCLASH_SHA1COMPRESS_ROUND3_STEP( b, c, d, e, a, me, 44 );
+ case 45: HASHCLASH_SHA1COMPRESS_ROUND3_STEP( a, b, c, d, e, me, 45 );
+ case 46: HASHCLASH_SHA1COMPRESS_ROUND3_STEP( e, a, b, c, d, me, 46 );
+ case 47: HASHCLASH_SHA1COMPRESS_ROUND3_STEP( d, e, a, b, c, me, 47 );
+ case 48: HASHCLASH_SHA1COMPRESS_ROUND3_STEP( c, d, e, a, b, me, 48 );
+ case 49: HASHCLASH_SHA1COMPRESS_ROUND3_STEP( b, c, d, e, a, me, 49 );
+ case 50: HASHCLASH_SHA1COMPRESS_ROUND3_STEP( a, b, c, d, e, me, 50 );
+ case 51: HASHCLASH_SHA1COMPRESS_ROUND3_STEP( e, a, b, c, d, me, 51 );
+ case 52: HASHCLASH_SHA1COMPRESS_ROUND3_STEP( d, e, a, b, c, me, 52 );
+ case 53: HASHCLASH_SHA1COMPRESS_ROUND3_STEP( c, d, e, a, b, me, 53 );
+ case 54: HASHCLASH_SHA1COMPRESS_ROUND3_STEP( b, c, d, e, a, me, 54 );
+ case 55: HASHCLASH_SHA1COMPRESS_ROUND3_STEP( a, b, c, d, e, me, 55 );
+ case 56: HASHCLASH_SHA1COMPRESS_ROUND3_STEP( e, a, b, c, d, me, 56 );
+ case 57: HASHCLASH_SHA1COMPRESS_ROUND3_STEP( d, e, a, b, c, me, 57 );
+ case 58: HASHCLASH_SHA1COMPRESS_ROUND3_STEP( c, d, e, a, b, me, 58 );
+ case 59: HASHCLASH_SHA1COMPRESS_ROUND3_STEP( b, c, d, e, a, me, 59 );
+ case 60: HASHCLASH_SHA1COMPRESS_ROUND4_STEP( a, b, c, d, e, me, 60 );
+ case 61: HASHCLASH_SHA1COMPRESS_ROUND4_STEP( e, a, b, c, d, me, 61 );
+ case 62: HASHCLASH_SHA1COMPRESS_ROUND4_STEP( d, e, a, b, c, me, 62 );
+ case 63: HASHCLASH_SHA1COMPRESS_ROUND4_STEP( c, d, e, a, b, me, 63 );
+ case 64: HASHCLASH_SHA1COMPRESS_ROUND4_STEP( b, c, d, e, a, me, 64 );
+ case 65: HASHCLASH_SHA1COMPRESS_ROUND4_STEP( a, b, c, d, e, me, 65 );
+ case 66: HASHCLASH_SHA1COMPRESS_ROUND4_STEP( e, a, b, c, d, me, 66 );
+ case 67: HASHCLASH_SHA1COMPRESS_ROUND4_STEP( d, e, a, b, c, me, 67 );
+ case 68: HASHCLASH_SHA1COMPRESS_ROUND4_STEP( c, d, e, a, b, me, 68 );
+ case 69: HASHCLASH_SHA1COMPRESS_ROUND4_STEP( b, c, d, e, a, me, 69 );
+ case 70: HASHCLASH_SHA1COMPRESS_ROUND4_STEP( a, b, c, d, e, me, 70 );
+ case 71: HASHCLASH_SHA1COMPRESS_ROUND4_STEP( e, a, b, c, d, me, 71 );
+ case 72: HASHCLASH_SHA1COMPRESS_ROUND4_STEP( d, e, a, b, c, me, 72 );
+ case 73: HASHCLASH_SHA1COMPRESS_ROUND4_STEP( c, d, e, a, b, me, 73 );
+ case 74: HASHCLASH_SHA1COMPRESS_ROUND4_STEP( b, c, d, e, a, me, 74 );
+ case 75: HASHCLASH_SHA1COMPRESS_ROUND4_STEP( a, b, c, d, e, me, 75 );
+ case 76: HASHCLASH_SHA1COMPRESS_ROUND4_STEP( e, a, b, c, d, me, 76 );
+ case 77: HASHCLASH_SHA1COMPRESS_ROUND4_STEP( d, e, a, b, c, me, 77 );
+ case 78: HASHCLASH_SHA1COMPRESS_ROUND4_STEP( c, d, e, a, b, me, 78 );
+ case 79: HASHCLASH_SHA1COMPRESS_ROUND4_STEP( b, c, d, e, a, me, 79 );
+ }
+ return (rihv[0] == ihv[0]+a && rihv[1] == ihv[1]+b && rihv[2] == ihv[2]+c && rihv[3] == ihv[3]+d && rihv[4] == ihv[4]+e);
+}
+
+typedef struct {
+ int dvtype;
+ int dvK;
+ int dvB;
+} sha1_dv_t;
+sha1_dv_t sha1_dvs[] = {
+ { 1, 46, 0 },
+ { 1, 47, 0 },
+ { 1, 48, 0 },
+ { 1, 49, 0 },
+ { 1, 50, 0 },
+ { 1, 51, 0 },
+ { 1, 48, 2 },
+ { 1, 49, 2 },
+ { 1, 50, 2 },
+ { 2, 45, 0 },
+ { 2, 46, 0 },
+ { 2, 47, 0 },
+ { 2, 48, 0 },
+ { 2, 49, 0 },
+ { 2, 50, 0 },
+ { 2, 51, 0 },
+ { 2, 52, 0 },
+ { 2, 53, 0 },
+ { 2, 54, 0 },
+ { 2, 56 ,0 },
+ { 2, 57, 0 },
+ { 2, 58, 0 },
+ { 0, 0, 0} // end of table marker
+};
+
+const uint32_t sha1_dv_xm_table[][80] = {
+{ 0x2c000010, 0xf4000014, 0xb4000008, 0x08000000, 0x9800000c, 0xd8000010, 0x08000010, 0xb8000010, 0x98000000, 0x60000000, 0x00000008, 0xc0000000, 0x90000014, 0x10000010, 0xb8000014, 0x28000000, 0x20000010, 0x48000000, 0x08000018, 0x60000000, 0x90000010, 0xf0000010, 0x90000008, 0xc0000000, 0x90000010, 0xf0000010, 0xb0000008, 0x40000000, 0x90000000, 0xf0000010, 0x90000018, 0x60000000, 0x90000010, 0x90000010, 0x90000000, 0x80000000, 0x00000010, 0xa0000000, 0x20000000, 0xa0000000, 0x20000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x20000000, 0x00000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000040, 0x40000002, 0x80000004, 0x80000080, 0x80000006, 0x00000049, 0x00000103, 0x80000009, 0x80000012, 0x80000202, 0x00000018, 0x00000164, 0x00000408, 0x800000e6, 0x8000004c},
+{ 0xc8000010, 0x2c000010, 0xf4000014, 0xb4000008, 0x08000000, 0x9800000c, 0xd8000010, 0x08000010, 0xb8000010, 0x98000000, 0x60000000, 0x00000008, 0xc0000000, 0x90000014, 0x10000010, 0xb8000014, 0x28000000, 0x20000010, 0x48000000, 0x08000018, 0x60000000, 0x90000010, 0xf0000010, 0x90000008, 0xc0000000, 0x90000010, 0xf0000010, 0xb0000008, 0x40000000, 0x90000000, 0xf0000010, 0x90000018, 0x60000000, 0x90000010, 0x90000010, 0x90000000, 0x80000000, 0x00000010, 0xa0000000, 0x20000000, 0xa0000000, 0x20000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x20000000, 0x00000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000040, 0x40000002, 0x80000004, 0x80000080, 0x80000006, 0x00000049, 0x00000103, 0x80000009, 0x80000012, 0x80000202, 0x00000018, 0x00000164, 0x00000408, 0x800000e6},
+{ 0xb800000a, 0xc8000010, 0x2c000010, 0xf4000014, 0xb4000008, 0x08000000, 0x9800000c, 0xd8000010, 0x08000010, 0xb8000010, 0x98000000, 0x60000000, 0x00000008, 0xc0000000, 0x90000014, 0x10000010, 0xb8000014, 0x28000000, 0x20000010, 0x48000000, 0x08000018, 0x60000000, 0x90000010, 0xf0000010, 0x90000008, 0xc0000000, 0x90000010, 0xf0000010, 0xb0000008, 0x40000000, 0x90000000, 0xf0000010, 0x90000018, 0x60000000, 0x90000010, 0x90000010, 0x90000000, 0x80000000, 0x00000010, 0xa0000000, 0x20000000, 0xa0000000, 0x20000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x20000000, 0x00000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000040, 0x40000002, 0x80000004, 0x80000080, 0x80000006, 0x00000049, 0x00000103, 0x80000009, 0x80000012, 0x80000202, 0x00000018, 0x00000164, 0x00000408},
+{ 0x18000000, 0xb800000a, 0xc8000010, 0x2c000010, 0xf4000014, 0xb4000008, 0x08000000, 0x9800000c, 0xd8000010, 0x08000010, 0xb8000010, 0x98000000, 0x60000000, 0x00000008, 0xc0000000, 0x90000014, 0x10000010, 0xb8000014, 0x28000000, 0x20000010, 0x48000000, 0x08000018, 0x60000000, 0x90000010, 0xf0000010, 0x90000008, 0xc0000000, 0x90000010, 0xf0000010, 0xb0000008, 0x40000000, 0x90000000, 0xf0000010, 0x90000018, 0x60000000, 0x90000010, 0x90000010, 0x90000000, 0x80000000, 0x00000010, 0xa0000000, 0x20000000, 0xa0000000, 0x20000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x20000000, 0x00000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000040, 0x40000002, 0x80000004, 0x80000080, 0x80000006, 0x00000049, 0x00000103, 0x80000009, 0x80000012, 0x80000202, 0x00000018, 0x00000164},
+{ 0x0800000c, 0x18000000, 0xb800000a, 0xc8000010, 0x2c000010, 0xf4000014, 0xb4000008, 0x08000000, 0x9800000c, 0xd8000010, 0x08000010, 0xb8000010, 0x98000000, 0x60000000, 0x00000008, 0xc0000000, 0x90000014, 0x10000010, 0xb8000014, 0x28000000, 0x20000010, 0x48000000, 0x08000018, 0x60000000, 0x90000010, 0xf0000010, 0x90000008, 0xc0000000, 0x90000010, 0xf0000010, 0xb0000008, 0x40000000, 0x90000000, 0xf0000010, 0x90000018, 0x60000000, 0x90000010, 0x90000010, 0x90000000, 0x80000000, 0x00000010, 0xa0000000, 0x20000000, 0xa0000000, 0x20000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x20000000, 0x00000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000040, 0x40000002, 0x80000004, 0x80000080, 0x80000006, 0x00000049, 0x00000103, 0x80000009, 0x80000012, 0x80000202, 0x00000018},
+{ 0xe8000000, 0x0800000c, 0x18000000, 0xb800000a, 0xc8000010, 0x2c000010, 0xf4000014, 0xb4000008, 0x08000000, 0x9800000c, 0xd8000010, 0x08000010, 0xb8000010, 0x98000000, 0x60000000, 0x00000008, 0xc0000000, 0x90000014, 0x10000010, 0xb8000014, 0x28000000, 0x20000010, 0x48000000, 0x08000018, 0x60000000, 0x90000010, 0xf0000010, 0x90000008, 0xc0000000, 0x90000010, 0xf0000010, 0xb0000008, 0x40000000, 0x90000000, 0xf0000010, 0x90000018, 0x60000000, 0x90000010, 0x90000010, 0x90000000, 0x80000000, 0x00000010, 0xa0000000, 0x20000000, 0xa0000000, 0x20000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x20000000, 0x00000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000040, 0x40000002, 0x80000004, 0x80000080, 0x80000006, 0x00000049, 0x00000103, 0x80000009, 0x80000012, 0x80000202},
+{ 0xe000002a, 0x20000043, 0xb0000040, 0xd0000053, 0xd0000022, 0x20000000, 0x60000032, 0x60000043, 0x20000040, 0xe0000042, 0x60000002, 0x80000001, 0x00000020, 0x00000003, 0x40000052, 0x40000040, 0xe0000052, 0xa0000000, 0x80000040, 0x20000001, 0x20000060, 0x80000001, 0x40000042, 0xc0000043, 0x40000022, 0x00000003, 0x40000042, 0xc0000043, 0xc0000022, 0x00000001, 0x40000002, 0xc0000043, 0x40000062, 0x80000001, 0x40000042, 0x40000042, 0x40000002, 0x00000002, 0x00000040, 0x80000002, 0x80000000, 0x80000002, 0x80000040, 0x00000000, 0x80000040, 0x80000000, 0x00000040, 0x80000000, 0x00000040, 0x80000002, 0x00000000, 0x80000000, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000080, 0x00000004, 0x00000009, 0x00000101, 0x00000009, 0x00000012, 0x00000202, 0x0000001a, 0x00000124, 0x0000040c, 0x00000026, 0x0000004a, 0x0000080a, 0x00000060, 0x00000590, 0x00001020},
+{ 0x60000000, 0xe000002a, 0x20000043, 0xb0000040, 0xd0000053, 0xd0000022, 0x20000000, 0x60000032, 0x60000043, 0x20000040, 0xe0000042, 0x60000002, 0x80000001, 0x00000020, 0x00000003, 0x40000052, 0x40000040, 0xe0000052, 0xa0000000, 0x80000040, 0x20000001, 0x20000060, 0x80000001, 0x40000042, 0xc0000043, 0x40000022, 0x00000003, 0x40000042, 0xc0000043, 0xc0000022, 0x00000001, 0x40000002, 0xc0000043, 0x40000062, 0x80000001, 0x40000042, 0x40000042, 0x40000002, 0x00000002, 0x00000040, 0x80000002, 0x80000000, 0x80000002, 0x80000040, 0x00000000, 0x80000040, 0x80000000, 0x00000040, 0x80000000, 0x00000040, 0x80000002, 0x00000000, 0x80000000, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000080, 0x00000004, 0x00000009, 0x00000101, 0x00000009, 0x00000012, 0x00000202, 0x0000001a, 0x00000124, 0x0000040c, 0x00000026, 0x0000004a, 0x0000080a, 0x00000060, 0x00000590},
+{ 0x20000030, 0x60000000, 0xe000002a, 0x20000043, 0xb0000040, 0xd0000053, 0xd0000022, 0x20000000, 0x60000032, 0x60000043, 0x20000040, 0xe0000042, 0x60000002, 0x80000001, 0x00000020, 0x00000003, 0x40000052, 0x40000040, 0xe0000052, 0xa0000000, 0x80000040, 0x20000001, 0x20000060, 0x80000001, 0x40000042, 0xc0000043, 0x40000022, 0x00000003, 0x40000042, 0xc0000043, 0xc0000022, 0x00000001, 0x40000002, 0xc0000043, 0x40000062, 0x80000001, 0x40000042, 0x40000042, 0x40000002, 0x00000002, 0x00000040, 0x80000002, 0x80000000, 0x80000002, 0x80000040, 0x00000000, 0x80000040, 0x80000000, 0x00000040, 0x80000000, 0x00000040, 0x80000002, 0x00000000, 0x80000000, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000080, 0x00000004, 0x00000009, 0x00000101, 0x00000009, 0x00000012, 0x00000202, 0x0000001a, 0x00000124, 0x0000040c, 0x00000026, 0x0000004a, 0x0000080a, 0x00000060},
+{ 0xec000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010, 0x0000000c, 0xb8000010, 0x08000018, 0x78000010, 0x08000014, 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010, 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, 0x98000010, 0xa0000000, 0x00000000, 0x00000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x60000000, 0x00000018, 0xe0000000, 0x90000000, 0x30000010, 0xb0000000, 0x20000000, 0x20000000, 0xa0000000, 0x00000010, 0x80000000, 0x20000000, 0x20000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000041, 0x40000022, 0x80000005, 0xc0000082, 0xc0000046, 0x4000004b, 0x80000107, 0x00000089, 0x00000014, 0x8000024b, 0x0000011b, 0x8000016d, 0x8000041a, 0x000002e4, 0x80000054, 0x00000967},
+{ 0x2400001c, 0xec000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010, 0x0000000c, 0xb8000010, 0x08000018, 0x78000010, 0x08000014, 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010, 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, 0x98000010, 0xa0000000, 0x00000000, 0x00000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x60000000, 0x00000018, 0xe0000000, 0x90000000, 0x30000010, 0xb0000000, 0x20000000, 0x20000000, 0xa0000000, 0x00000010, 0x80000000, 0x20000000, 0x20000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000041, 0x40000022, 0x80000005, 0xc0000082, 0xc0000046, 0x4000004b, 0x80000107, 0x00000089, 0x00000014, 0x8000024b, 0x0000011b, 0x8000016d, 0x8000041a, 0x000002e4, 0x80000054},
+{ 0x20000010, 0x2400001c, 0xec000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010, 0x0000000c, 0xb8000010, 0x08000018, 0x78000010, 0x08000014, 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010, 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, 0x98000010, 0xa0000000, 0x00000000, 0x00000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x60000000, 0x00000018, 0xe0000000, 0x90000000, 0x30000010, 0xb0000000, 0x20000000, 0x20000000, 0xa0000000, 0x00000010, 0x80000000, 0x20000000, 0x20000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000041, 0x40000022, 0x80000005, 0xc0000082, 0xc0000046, 0x4000004b, 0x80000107, 0x00000089, 0x00000014, 0x8000024b, 0x0000011b, 0x8000016d, 0x8000041a, 0x000002e4},
+{ 0xbc00001a, 0x20000010, 0x2400001c, 0xec000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010, 0x0000000c, 0xb8000010, 0x08000018, 0x78000010, 0x08000014, 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010, 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, 0x98000010, 0xa0000000, 0x00000000, 0x00000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x60000000, 0x00000018, 0xe0000000, 0x90000000, 0x30000010, 0xb0000000, 0x20000000, 0x20000000, 0xa0000000, 0x00000010, 0x80000000, 0x20000000, 0x20000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000041, 0x40000022, 0x80000005, 0xc0000082, 0xc0000046, 0x4000004b, 0x80000107, 0x00000089, 0x00000014, 0x8000024b, 0x0000011b, 0x8000016d, 0x8000041a},
+{ 0x3c000004, 0xbc00001a, 0x20000010, 0x2400001c, 0xec000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010, 0x0000000c, 0xb8000010, 0x08000018, 0x78000010, 0x08000014, 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010, 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, 0x98000010, 0xa0000000, 0x00000000, 0x00000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x60000000, 0x00000018, 0xe0000000, 0x90000000, 0x30000010, 0xb0000000, 0x20000000, 0x20000000, 0xa0000000, 0x00000010, 0x80000000, 0x20000000, 0x20000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000041, 0x40000022, 0x80000005, 0xc0000082, 0xc0000046, 0x4000004b, 0x80000107, 0x00000089, 0x00000014, 0x8000024b, 0x0000011b, 0x8000016d},
+{ 0xb400001c, 0x3c000004, 0xbc00001a, 0x20000010, 0x2400001c, 0xec000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010, 0x0000000c, 0xb8000010, 0x08000018, 0x78000010, 0x08000014, 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010, 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, 0x98000010, 0xa0000000, 0x00000000, 0x00000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x60000000, 0x00000018, 0xe0000000, 0x90000000, 0x30000010, 0xb0000000, 0x20000000, 0x20000000, 0xa0000000, 0x00000010, 0x80000000, 0x20000000, 0x20000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000041, 0x40000022, 0x80000005, 0xc0000082, 0xc0000046, 0x4000004b, 0x80000107, 0x00000089, 0x00000014, 0x8000024b, 0x0000011b},
+{ 0xc0000010, 0xb400001c, 0x3c000004, 0xbc00001a, 0x20000010, 0x2400001c, 0xec000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010, 0x0000000c, 0xb8000010, 0x08000018, 0x78000010, 0x08000014, 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010, 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, 0x98000010, 0xa0000000, 0x00000000, 0x00000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x60000000, 0x00000018, 0xe0000000, 0x90000000, 0x30000010, 0xb0000000, 0x20000000, 0x20000000, 0xa0000000, 0x00000010, 0x80000000, 0x20000000, 0x20000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000041, 0x40000022, 0x80000005, 0xc0000082, 0xc0000046, 0x4000004b, 0x80000107, 0x00000089, 0x00000014, 0x8000024b},
+{ 0x0c000002, 0xc0000010, 0xb400001c, 0x3c000004, 0xbc00001a, 0x20000010, 0x2400001c, 0xec000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010, 0x0000000c, 0xb8000010, 0x08000018, 0x78000010, 0x08000014, 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010, 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, 0x98000010, 0xa0000000, 0x00000000, 0x00000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x60000000, 0x00000018, 0xe0000000, 0x90000000, 0x30000010, 0xb0000000, 0x20000000, 0x20000000, 0xa0000000, 0x00000010, 0x80000000, 0x20000000, 0x20000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000041, 0x40000022, 0x80000005, 0xc0000082, 0xc0000046, 0x4000004b, 0x80000107, 0x00000089, 0x00000014},
+{ 0xcc000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x3c000004, 0xbc00001a, 0x20000010, 0x2400001c, 0xec000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010, 0x0000000c, 0xb8000010, 0x08000018, 0x78000010, 0x08000014, 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010, 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, 0x98000010, 0xa0000000, 0x00000000, 0x00000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x60000000, 0x00000018, 0xe0000000, 0x90000000, 0x30000010, 0xb0000000, 0x20000000, 0x20000000, 0xa0000000, 0x00000010, 0x80000000, 0x20000000, 0x20000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000041, 0x40000022, 0x80000005, 0xc0000082, 0xc0000046, 0x4000004b, 0x80000107, 0x00000089},
+{ 0x0400001c, 0xcc000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x3c000004, 0xbc00001a, 0x20000010, 0x2400001c, 0xec000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010, 0x0000000c, 0xb8000010, 0x08000018, 0x78000010, 0x08000014, 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010, 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, 0x98000010, 0xa0000000, 0x00000000, 0x00000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x60000000, 0x00000018, 0xe0000000, 0x90000000, 0x30000010, 0xb0000000, 0x20000000, 0x20000000, 0xa0000000, 0x00000010, 0x80000000, 0x20000000, 0x20000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000041, 0x40000022, 0x80000005, 0xc0000082, 0xc0000046, 0x4000004b, 0x80000107},
+{ 0x2600001a, 0x00000010, 0x0400001c, 0xcc000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x3c000004, 0xbc00001a, 0x20000010, 0x2400001c, 0xec000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010, 0x0000000c, 0xb8000010, 0x08000018, 0x78000010, 0x08000014, 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010, 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, 0x98000010, 0xa0000000, 0x00000000, 0x00000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x60000000, 0x00000018, 0xe0000000, 0x90000000, 0x30000010, 0xb0000000, 0x20000000, 0x20000000, 0xa0000000, 0x00000010, 0x80000000, 0x20000000, 0x20000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000041, 0x40000022, 0x80000005, 0xc0000082, 0xc0000046},
+{ 0x26000014, 0x2600001a, 0x00000010, 0x0400001c, 0xcc000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x3c000004, 0xbc00001a, 0x20000010, 0x2400001c, 0xec000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010, 0x0000000c, 0xb8000010, 0x08000018, 0x78000010, 0x08000014, 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010, 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, 0x98000010, 0xa0000000, 0x00000000, 0x00000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x60000000, 0x00000018, 0xe0000000, 0x90000000, 0x30000010, 0xb0000000, 0x20000000, 0x20000000, 0xa0000000, 0x00000010, 0x80000000, 0x20000000, 0x20000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000041, 0x40000022, 0x80000005, 0xc0000082},
+{ 0x2400001c, 0x26000014, 0x2600001a, 0x00000010, 0x0400001c, 0xcc000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x3c000004, 0xbc00001a, 0x20000010, 0x2400001c, 0xec000014, 0x0c000002, 0xc0000010, 0xb400001c, 0x2c000004, 0xbc000018, 0xb0000010, 0x0000000c, 0xb8000010, 0x08000018, 0x78000010, 0x08000014, 0x70000010, 0xb800001c, 0xe8000000, 0xb0000004, 0x58000010, 0xb000000c, 0x48000000, 0xb0000000, 0xb8000010, 0x98000010, 0xa0000000, 0x00000000, 0x00000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0x20000000, 0x00000010, 0x60000000, 0x00000018, 0xe0000000, 0x90000000, 0x30000010, 0xb0000000, 0x20000000, 0x20000000, 0xa0000000, 0x00000010, 0x80000000, 0x20000000, 0x20000000, 0x20000000, 0x80000000, 0x00000010, 0x00000000, 0x20000010, 0xa0000000, 0x00000000, 0x20000000, 0x20000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000020, 0x00000001, 0x40000002, 0x40000041, 0x40000022, 0x80000005}
+};
+
+void gen_sha1_dv_xm_tables() {
+ int i,j,K,B;
+ uint32_t xm[80];
+ for (i = 0; sha1_dvs[i].dvtype != 0; ++i) {
+ K = sha1_dvs[i].dvK;
+ B = sha1_dvs[i].dvB;
+ for (j = 0; j < 80; ++j)
+ xm[j] = 0;
+ switch (sha1_dvs[i].dvtype) {
+ case 1:
+ xm[K+0] = (1<<4);
+ xm[K+1] = (1<<29)|(1<<31);
+ xm[K+3] = (1<<29);
+ xm[K+4] = (1<<29);
+ xm[K+15] = (1<<0);
+ break;
+ case 2:
+ xm[K+0] = (1<<29);
+ xm[K+1] = (1<<31);
+ xm[K+2] = (1<<4);
+ xm[K+4] = (1<<4)|(1<<29);
+ xm[K+5] = (1<<29)|(1<<31);
+ xm[K+7] = (1<<29);
+ xm[K+8] = (1<<29);
+ xm[K+15] = (1<<0);
+ break;
+ default:
+ printf("huh?!?");
+ exit(1);
+ }
+ if (B)
+ for (j = 0; j < 16; ++j)
+ xm[K+j] = rotate_left(xm[K+j],B);
+ for (j = K+16; j < 80; ++j)
+ xm[j]=rotate_left(xm[j-3] ^ xm[j-8] ^ xm[j-14] ^ xm[j-16], 1);
+ for (j = K-1; j >= 0; --j)
+ xm[j+16-16]=rotate_right(xm[j+16-0],1) ^ xm[j+16-3] ^ xm[j+16-8] ^ xm[j+16-14];
+#if 0
+// generate tables
+ printf("{");
+ for (j = 0; j < 80; ++j)
+ printf("%s 0x%08x", (j==0)?" ":",", xm[j]);
+ printf("},\n");
+#else
+// verify tables
+ for (j = 0; j < 80; ++j)
+ if (xm[j] != sha1_dv_xm_table[i][j]) {
+#ifdef VERBOSE_COLLDETECT
+ printf("mismatch: %d %d\n", i, j);
+#endif
+ exit(0);
+ }
+#endif
+ }
+}
+
+void print_sha1_coll(uint64_t total, const uint32_t ihv1[5], const uint32_t block1[16], const uint32_t ihv2[5], const uint32_t block2[16], const char* DV) {
+ unsigned i;
+ printf("Found collision in block %llu using DV %s:\n dm: ", (long long unsigned int)((total>>6)-1), DV);
+ for (i = 0; i < 16; ++i)
+ if (block2[i]-block1[i])
+ printf("dm%d=%08x ", i, block2[i]-block1[i]);
+ printf("\n ihv1=");
+ for (i = 0; i < 5; ++i)
+ printf("%08x", ihv1[i]);
+ printf("\n ihv2=");
+ for (i = 0; i < 5; ++i)
+ printf("%08x", ihv2[i]);
+ printf("\n");
+}
+
+char dv_string[10];
+void sha1_process(SHA1_CTX* ctx, const uint32_t block[16]) {
+ unsigned i,j,t;
+ ctx->ihv1[0] = ctx->ihv[0];
+ ctx->ihv1[1] = ctx->ihv[1];
+ ctx->ihv1[2] = ctx->ihv[2];
+ ctx->ihv1[3] = ctx->ihv[3];
+ ctx->ihv1[4] = ctx->ihv[4];
+ sha1compress_me(block, ctx->m1);
+ sha1compress_states(ctx->ihv, ctx->m1, ctx->states);
+ for (i = 0; sha1_dvs[i].dvtype != 0; ++i) {
+ t = sha1_dvs[i].dvK+13;
+ for (j = 0; j < 80; ++j)
+ ctx->m2[j] = ctx->m1[j] ^ sha1_dv_xm_table[i][j];
+ if (sha1recompress_fast(t, ctx->ihv2, ctx->m2, ctx->states+((t+1)*5), ctx->ihv)) {
+#ifdef VERBOSE_COLLDETECT
+ sprintf(dv_string, "%s(%d,%d)", sha1_dvs[i].dvtype==1?"I":"II", sha1_dvs[i].dvK, sha1_dvs[i].dvB);
+ print_sha1_coll(ctx->total, ctx->ihv1, ctx->m1, ctx->ihv2, ctx->m2, dv_string);
+#endif
+ ctx->found_collision = 1;
+ if (ctx->safe_hash) {
+ sha1compress_states(ctx->ihv, ctx->m1, ctx->states);
+ sha1compress_states(ctx->ihv, ctx->m1, ctx->states);
+ }
+ }
+#ifdef DETECT_REDUCED_SHA_COLLISION // to verify SHA-1 collision detection code with collisions for reduced-step SHA-1
+ if (ctx->ihv1[0]==ctx->ihv2[0] && ctx->ihv1[1]==ctx->ihv2[1] && ctx->ihv1[2]==ctx->ihv2[2] && ctx->ihv1[3]==ctx->ihv2[3] && ctx->ihv1[4]==ctx->ihv2[4]) {
+#ifdef VERBOSE_COLLDETECT
+ printf("Partial collision found\n");
+ sprintf(dv_string, "%s(%d,%d)", sha1_dvs[i].dvtype==1?"I":"II", sha1_dvs[i].dvK, sha1_dvs[i].dvB);
+ print_sha1_coll(ctx->total, ctx->ihv1, ctx->m1, ctx->ihv2, ctx->m2, dv_string);
+#endif
+ }
+#endif
+ }
+}
+
+void SHA1Init(SHA1_CTX* ctx) {
+ static const union { unsigned char bytes[4]; uint32_t value; } endianness = { { 0, 1, 2, 3 } };
+ static const uint32_t littleendian = 0x03020100;
+ ctx->total = 0;
+ ctx->ihv[0] = 0x67452301;
+ ctx->ihv[1] = 0xEFCDAB89;
+ ctx->ihv[2] = 0x98BADCFE;
+ ctx->ihv[3] = 0x10325476;
+ ctx->ihv[4] = 0xC3D2E1F0;
+ ctx->found_collision = 0;
+ ctx->safe_hash = 1;
+ ctx->bigendian = (endianness.value != littleendian);
+ gen_sha1_dv_xm_tables(); // verify or construct sha1_dv_xm_table from sha1_dvs
+}
+void SHA1Init_unsafe(SHA1_CTX* ctx) {
+ static const union { unsigned char bytes[4]; uint32_t value; } endianness = { { 0, 1, 2, 3 } };
+ static const uint32_t littleendian = 0x03020100;
+ ctx->total = 0;
+ ctx->ihv[0] = 0x67452301;
+ ctx->ihv[1] = 0xEFCDAB89;
+ ctx->ihv[2] = 0x98BADCFE;
+ ctx->ihv[3] = 0x10325476;
+ ctx->ihv[4] = 0xC3D2E1F0;
+ ctx->found_collision = 0;
+ ctx->safe_hash = 0;
+ ctx->bigendian = (endianness.value != littleendian);
+}
+
+void SHA1Update(SHA1_CTX* ctx, const char* buf, unsigned len) {
+ unsigned left, fill;
+ if (ctx == NULL) exit(1);
+ if (len == 0) return;
+ if (buf == NULL) exit(1);
+
+ left = ctx->total&63;
+ fill = 64 - left;
+
+ if (left && len >= fill) {
+ ctx->total += fill;
+
+ memcpy(ctx->buffer + left, buf, fill);
+ if (!ctx->bigendian)
+ swap_bytes((uint32_t*)(ctx->buffer));
+ sha1_process(ctx, (uint32_t*)(ctx->buffer));
+ buf += fill;
+ len -= fill;
+ left = 0;
+ }
+ while (len >= 64) {
+ ctx->total += 64;
+ if (!ctx->bigendian) {
+ memcpy(ctx->buffer, buf, 64);
+ swap_bytes((uint32_t*)(ctx->buffer));
+ sha1_process(ctx, (uint32_t*)(ctx->buffer));
+ } else
+ sha1_process(ctx, (uint32_t*)(buf));
+ buf += 64;
+ len -= 64;
+ }
+ if (len > 0) {
+ ctx->total += len;
+ memcpy(ctx->buffer + left, buf, len);
+ }
+}
+
+static const unsigned char sha1_padding[64] =
+{
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+int SHA1Final(unsigned char output[20], SHA1_CTX *ctx)
+{
+ uint32_t last = ctx->total&63;
+ uint32_t padn = (last < 56) ? (56-last) : (120-last);
+ SHA1Update(ctx, (const char*)(sha1_padding), padn);
+ ctx->total -= padn;
+ ctx->total <<= 3;
+ ctx->buffer[56] = (unsigned char)(ctx->total>>56);
+ ctx->buffer[57] = (unsigned char)(ctx->total>>48);
+ ctx->buffer[58] = (unsigned char)(ctx->total>>40);
+ ctx->buffer[59] = (unsigned char)(ctx->total>>32);
+ ctx->buffer[60] = (unsigned char)(ctx->total>>24);
+ ctx->buffer[61] = (unsigned char)(ctx->total>>16);
+ ctx->buffer[62] = (unsigned char)(ctx->total>>8);
+ ctx->buffer[63] = (unsigned char)(ctx->total);
+ if (!ctx->bigendian)
+ swap_bytes((uint32_t*)(ctx->buffer));
+ sha1_process(ctx, (uint32_t*)(ctx->buffer));
+ output[0] = (unsigned char)(ctx->ihv[0]>>24);
+ output[1] = (unsigned char)(ctx->ihv[0]>>16);
+ output[2] = (unsigned char)(ctx->ihv[0]>>8);
+ output[3] = (unsigned char)(ctx->ihv[0]);
+ output[4] = (unsigned char)(ctx->ihv[1]>>24);
+ output[5] = (unsigned char)(ctx->ihv[1]>>16);
+ output[6] = (unsigned char)(ctx->ihv[1]>>8);
+ output[7] = (unsigned char)(ctx->ihv[1]);
+ output[8] = (unsigned char)(ctx->ihv[2]>>24);
+ output[9] = (unsigned char)(ctx->ihv[2]>>16);
+ output[10] = (unsigned char)(ctx->ihv[2]>>8);
+ output[11] = (unsigned char)(ctx->ihv[2]);
+ output[12] = (unsigned char)(ctx->ihv[3]>>24);
+ output[13] = (unsigned char)(ctx->ihv[3]>>16);
+ output[14] = (unsigned char)(ctx->ihv[3]>>8);
+ output[15] = (unsigned char)(ctx->ihv[3]);
+ output[16] = (unsigned char)(ctx->ihv[4]>>24);
+ output[17] = (unsigned char)(ctx->ihv[4]>>16);
+ output[18] = (unsigned char)(ctx->ihv[4]>>8);
+ output[19] = (unsigned char)(ctx->ihv[4]);
+ return ctx->found_collision;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+void md5compress_states(uint32_t ihv[4], const uint32_t block[16], uint32_t states[260])
+{
+ uint32_t a = ihv[0]; uint32_t b = ihv[1]; uint32_t c = ihv[2]; uint32_t d = ihv[3];
+
+// STORE_STATE(0);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ff, a, b, c, d, block[ 0], 0xd76aa478, 7);
+// STORE_STATE(1);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ff, d, a, b, c, block[ 1], 0xe8c7b756, 12);
+// STORE_STATE(2);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ff, c, d, a, b, block[ 2], 0x242070db, 17);
+// STORE_STATE(3);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ff, b, c, d, a, block[ 3], 0xc1bdceee, 22);
+// STORE_STATE(4);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ff, a, b, c, d, block[ 4], 0xf57c0faf, 7);
+// STORE_STATE(5);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ff, d, a, b, c, block[ 5], 0x4787c62a, 12);
+// STORE_STATE(6);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ff, c, d, a, b, block[ 6], 0xa8304613, 17);
+// STORE_STATE(7);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ff, b, c, d, a, block[ 7], 0xfd469501, 22);
+// STORE_STATE(8);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ff, a, b, c, d, block[ 8], 0x698098d8, 7);
+// STORE_STATE(9);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ff, d, a, b, c, block[ 9], 0x8b44f7af, 12);
+// STORE_STATE(10);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ff, c, d, a, b, block[10], 0xffff5bb1, 17);
+// STORE_STATE(11);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ff, b, c, d, a, block[11], 0x895cd7be, 22);
+// STORE_STATE(12);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ff, a, b, c, d, block[12], 0x6b901122, 7);
+// STORE_STATE(13);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ff, d, a, b, c, block[13], 0xfd987193, 12);
+// STORE_STATE(14);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ff, c, d, a, b, block[14], 0xa679438e, 17);
+// STORE_STATE(15);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ff, b, c, d, a, block[15], 0x49b40821, 22);
+// STORE_STATE(16);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_gg, a, b, c, d, block[ 1], 0xf61e2562, 5);
+// STORE_STATE(17);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_gg, d, a, b, c, block[ 6], 0xc040b340, 9);
+// STORE_STATE(18);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_gg, c, d, a, b, block[11], 0x265e5a51, 14);
+// STORE_STATE(19);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_gg, b, c, d, a, block[ 0], 0xe9b6c7aa, 20);
+// STORE_STATE(20);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_gg, a, b, c, d, block[ 5], 0xd62f105d, 5);
+// STORE_STATE(21);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_gg, d, a, b, c, block[10], 0x02441453, 9);
+// STORE_STATE(22);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_gg, c, d, a, b, block[15], 0xd8a1e681, 14);
+// STORE_STATE(23);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_gg, b, c, d, a, block[ 4], 0xe7d3fbc8, 20);
+// STORE_STATE(24);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_gg, a, b, c, d, block[ 9], 0x21e1cde6, 5);
+// STORE_STATE(25);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_gg, d, a, b, c, block[14], 0xc33707d6, 9);
+// STORE_STATE(26);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_gg, c, d, a, b, block[ 3], 0xf4d50d87, 14);
+// STORE_STATE(27);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_gg, b, c, d, a, block[ 8], 0x455a14ed, 20);
+// STORE_STATE(28);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_gg, a, b, c, d, block[13], 0xa9e3e905, 5);
+// STORE_STATE(29);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_gg, d, a, b, c, block[ 2], 0xfcefa3f8, 9);
+// STORE_STATE(30);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_gg, c, d, a, b, block[ 7], 0x676f02d9, 14);
+// STORE_STATE(31);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_gg, b, c, d, a, block[12], 0x8d2a4c8a, 20);
+// STORE_STATE(32);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_hh, a, b, c, d, block[ 5], 0xfffa3942, 4);
+// STORE_STATE(33);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_hh, d, a, b, c, block[ 8], 0x8771f681, 11);
+// STORE_STATE(34);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_hh, c, d, a, b, block[11], 0x6d9d6122, 16);
+// STORE_STATE(35);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_hh, b, c, d, a, block[14], 0xfde5380c, 23);
+// STORE_STATE(36);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_hh, a, b, c, d, block[ 1], 0xa4beea44, 4);
+// STORE_STATE(37);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_hh, d, a, b, c, block[ 4], 0x4bdecfa9, 11);
+ STORE_STATE(38);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_hh, c, d, a, b, block[ 7], 0xf6bb4b60, 16);
+// STORE_STATE(39);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_hh, b, c, d, a, block[10], 0xbebfbc70, 23);
+// STORE_STATE(40);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_hh, a, b, c, d, block[13], 0x289b7ec6, 4);
+// STORE_STATE(41);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_hh, d, a, b, c, block[ 0], 0xeaa127fa, 11);
+// STORE_STATE(42);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_hh, c, d, a, b, block[ 3], 0xd4ef3085, 16);
+// STORE_STATE(43);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_hh, b, c, d, a, block[ 6], 0x04881d05, 23);
+// STORE_STATE(44);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_hh, a, b, c, d, block[ 9], 0xd9d4d039, 4);
+ STORE_STATE(45);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_hh, d, a, b, c, block[12], 0xe6db99e5, 11);
+// STORE_STATE(46);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_hh, c, d, a, b, block[15], 0x1fa27cf8, 16);
+// STORE_STATE(47);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_hh, b, c, d, a, block[ 2], 0xc4ac5665, 23);
+// STORE_STATE(48);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ii, a, b, c, d, block[ 0], 0xf4292244, 6);
+// STORE_STATE(49);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ii, d, a, b, c, block[ 7], 0x432aff97, 10);
+// STORE_STATE(50);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ii, c, d, a, b, block[14], 0xab9423a7, 15);
+ STORE_STATE(51);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ii, b, c, d, a, block[ 5], 0xfc93a039, 21);
+// STORE_STATE(52);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ii, a, b, c, d, block[12], 0x655b59c3, 6);
+// STORE_STATE(53);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ii, d, a, b, c, block[ 3], 0x8f0ccc92, 10);
+// STORE_STATE(54);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ii, c, d, a, b, block[10], 0xffeff47d, 15);
+// STORE_STATE(55);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ii, b, c, d, a, block[ 1], 0x85845dd1, 21);
+// STORE_STATE(56);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ii, a, b, c, d, block[ 8], 0x6fa87e4f, 6);
+// STORE_STATE(57);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ii, d, a, b, c, block[15], 0xfe2ce6e0, 10);
+// STORE_STATE(58);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ii, c, d, a, b, block[ 6], 0xa3014314, 15);
+// STORE_STATE(59);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ii, b, c, d, a, block[13], 0x4e0811a1, 21);
+// STORE_STATE(60);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ii, a, b, c, d, block[ 4], 0xf7537e82, 6);
+// STORE_STATE(61);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ii, d, a, b, c, block[11], 0xbd3af235, 10);
+// STORE_STATE(62);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ii, c, d, a, b, block[ 2], 0x2ad7d2bb, 15);
+// STORE_STATE(63);
+ HASHUTIL5_MD5COMPRESS_STEP(md5_ii, b, c, d, a, block[ 9], 0xeb86d391, 21);
+// STORE_STATE(64);
+
+ ihv[0] += a; ihv[1] += b; ihv[2] += c; ihv[3] += d;
+}
+
+int md5recompress_fast(unsigned t, uint32_t ihv[4], const uint32_t block[16], const uint32_t state[4], const uint32_t rihv[4])
+{
+ uint32_t a = state[0], b = state[1], c = state[2], d = state[3];
+ switch (t) {
+ case 63: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ii, b, c, d, a, block[ 9], 0xeb86d391, 21);
+ case 62: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ii, c, d, a, b, block[ 2], 0x2ad7d2bb, 15);
+ case 61: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ii, d, a, b, c, block[11], 0xbd3af235, 10);
+ case 60: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ii, a, b, c, d, block[ 4], 0xf7537e82, 6);
+ case 59: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ii, b, c, d, a, block[13], 0x4e0811a1, 21);
+ case 58: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ii, c, d, a, b, block[ 6], 0xa3014314, 15);
+ case 57: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ii, d, a, b, c, block[15], 0xfe2ce6e0, 10);
+ case 56: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ii, a, b, c, d, block[ 8], 0x6fa87e4f, 6);
+ case 55: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ii, b, c, d, a, block[ 1], 0x85845dd1, 21);
+ case 54: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ii, c, d, a, b, block[10], 0xffeff47d, 15);
+ case 53: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ii, d, a, b, c, block[ 3], 0x8f0ccc92, 10);
+ case 52: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ii, a, b, c, d, block[12], 0x655b59c3, 6);
+ case 51: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ii, b, c, d, a, block[ 5], 0xfc93a039, 21);
+ case 50: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ii, c, d, a, b, block[14], 0xab9423a7, 15);
+ case 49: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ii, d, a, b, c, block[ 7], 0x432aff97, 10);
+ case 48: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ii, a, b, c, d, block[ 0], 0xf4292244, 6);
+ case 47: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_hh, b, c, d, a, block[ 2], 0xc4ac5665, 23);
+ case 46: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_hh, c, d, a, b, block[15], 0x1fa27cf8, 16);
+ case 45: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_hh, d, a, b, c, block[12], 0xe6db99e5, 11);
+ case 44: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_hh, a, b, c, d, block[ 9], 0xd9d4d039, 4);
+ case 43: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_hh, b, c, d, a, block[ 6], 0x04881d05, 23);
+ case 42: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_hh, c, d, a, b, block[ 3], 0xd4ef3085, 16);
+ case 41: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_hh, d, a, b, c, block[ 0], 0xeaa127fa, 11);
+ case 40: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_hh, a, b, c, d, block[13], 0x289b7ec6, 4);
+ case 39: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_hh, b, c, d, a, block[10], 0xbebfbc70, 23);
+ case 38: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_hh, c, d, a, b, block[ 7], 0xf6bb4b60, 16);
+ case 37: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_hh, d, a, b, c, block[ 4], 0x4bdecfa9, 11);
+ case 36: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_hh, a, b, c, d, block[ 1], 0xa4beea44, 4);
+ case 35: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_hh, b, c, d, a, block[14], 0xfde5380c, 23);
+ case 34: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_hh, c, d, a, b, block[11], 0x6d9d6122, 16);
+ case 33: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_hh, d, a, b, c, block[ 8], 0x8771f681, 11);
+ case 32: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_hh, a, b, c, d, block[ 5], 0xfffa3942, 4);
+ case 31: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_gg, b, c, d, a, block[12], 0x8d2a4c8a, 20);
+ case 30: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_gg, c, d, a, b, block[ 7], 0x676f02d9, 14);
+ case 29: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_gg, d, a, b, c, block[ 2], 0xfcefa3f8, 9);
+ case 28: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_gg, a, b, c, d, block[13], 0xa9e3e905, 5);
+ case 27: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_gg, b, c, d, a, block[ 8], 0x455a14ed, 20);
+ case 26: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_gg, c, d, a, b, block[ 3], 0xf4d50d87, 14);
+ case 25: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_gg, d, a, b, c, block[14], 0xc33707d6, 9);
+ case 24: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_gg, a, b, c, d, block[ 9], 0x21e1cde6, 5);
+ case 23: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_gg, b, c, d, a, block[ 4], 0xe7d3fbc8, 20);
+ case 22: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_gg, c, d, a, b, block[15], 0xd8a1e681, 14);
+ case 21: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_gg, d, a, b, c, block[10], 0x02441453, 9);
+ case 20: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_gg, a, b, c, d, block[ 5], 0xd62f105d, 5);
+ case 19: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_gg, b, c, d, a, block[ 0], 0xe9b6c7aa, 20);
+ case 18: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_gg, c, d, a, b, block[11], 0x265e5a51, 14);
+ case 17: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_gg, d, a, b, c, block[ 6], 0xc040b340, 9);
+ case 16: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_gg, a, b, c, d, block[ 1], 0xf61e2562, 5);
+ case 15: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ff, b, c, d, a, block[15], 0x49b40821, 22);
+ case 14: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ff, c, d, a, b, block[14], 0xa679438e, 17);
+ case 13: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ff, d, a, b, c, block[13], 0xfd987193, 12);
+ case 12: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ff, a, b, c, d, block[12], 0x6b901122, 7);
+ case 11: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ff, b, c, d, a, block[11], 0x895cd7be, 22);
+ case 10: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ff, c, d, a, b, block[10], 0xffff5bb1, 17);
+ case 9: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ff, d, a, b, c, block[ 9], 0x8b44f7af, 12);
+ case 8: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ff, a, b, c, d, block[ 8], 0x698098d8, 7);
+ case 7: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ff, b, c, d, a, block[ 7], 0xfd469501, 22);
+ case 6: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ff, c, d, a, b, block[ 6], 0xa8304613, 17);
+ case 5: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ff, d, a, b, c, block[ 5], 0x4787c62a, 12);
+ case 4: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ff, a, b, c, d, block[ 4], 0xf57c0faf, 7);
+ case 3: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ff, b, c, d, a, block[ 3], 0xc1bdceee, 22);
+ case 2: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ff, c, d, a, b, block[ 2], 0x242070db, 17);
+ case 1: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ff, d, a, b, c, block[ 1], 0xe8c7b756, 12);
+ case 0: HASHUTIL5_MD5COMPRESS_STEP_BW(md5_ff, a, b, c, d, block[ 0], 0xd76aa478, 7);
+ }
+ ihv[0] = a; ihv[1] = b; ihv[2] = c; ihv[3] = d;
+ a = state[0]; b = state[1]; c = state[2]; d = state[3];
+ switch (t+1) {
+ case 0: HASHUTIL5_MD5COMPRESS_STEP(md5_ff, a, b, c, d, block[ 0], 0xd76aa478, 7);
+ case 1: HASHUTIL5_MD5COMPRESS_STEP(md5_ff, d, a, b, c, block[ 1], 0xe8c7b756, 12);
+ case 2: HASHUTIL5_MD5COMPRESS_STEP(md5_ff, c, d, a, b, block[ 2], 0x242070db, 17);
+ case 3: HASHUTIL5_MD5COMPRESS_STEP(md5_ff, b, c, d, a, block[ 3], 0xc1bdceee, 22);
+ case 4: HASHUTIL5_MD5COMPRESS_STEP(md5_ff, a, b, c, d, block[ 4], 0xf57c0faf, 7);
+ case 5: HASHUTIL5_MD5COMPRESS_STEP(md5_ff, d, a, b, c, block[ 5], 0x4787c62a, 12);
+ case 6: HASHUTIL5_MD5COMPRESS_STEP(md5_ff, c, d, a, b, block[ 6], 0xa8304613, 17);
+ case 7: HASHUTIL5_MD5COMPRESS_STEP(md5_ff, b, c, d, a, block[ 7], 0xfd469501, 22);
+ case 8: HASHUTIL5_MD5COMPRESS_STEP(md5_ff, a, b, c, d, block[ 8], 0x698098d8, 7);
+ case 9: HASHUTIL5_MD5COMPRESS_STEP(md5_ff, d, a, b, c, block[ 9], 0x8b44f7af, 12);
+ case 10: HASHUTIL5_MD5COMPRESS_STEP(md5_ff, c, d, a, b, block[10], 0xffff5bb1, 17);
+ case 11: HASHUTIL5_MD5COMPRESS_STEP(md5_ff, b, c, d, a, block[11], 0x895cd7be, 22);
+ case 12: HASHUTIL5_MD5COMPRESS_STEP(md5_ff, a, b, c, d, block[12], 0x6b901122, 7);
+ case 13: HASHUTIL5_MD5COMPRESS_STEP(md5_ff, d, a, b, c, block[13], 0xfd987193, 12);
+ case 14: HASHUTIL5_MD5COMPRESS_STEP(md5_ff, c, d, a, b, block[14], 0xa679438e, 17);
+ case 15: HASHUTIL5_MD5COMPRESS_STEP(md5_ff, b, c, d, a, block[15], 0x49b40821, 22);
+ case 16: HASHUTIL5_MD5COMPRESS_STEP(md5_gg, a, b, c, d, block[ 1], 0xf61e2562, 5);
+ case 17: HASHUTIL5_MD5COMPRESS_STEP(md5_gg, d, a, b, c, block[ 6], 0xc040b340, 9);
+ case 18: HASHUTIL5_MD5COMPRESS_STEP(md5_gg, c, d, a, b, block[11], 0x265e5a51, 14);
+ case 19: HASHUTIL5_MD5COMPRESS_STEP(md5_gg, b, c, d, a, block[ 0], 0xe9b6c7aa, 20);
+ case 20: HASHUTIL5_MD5COMPRESS_STEP(md5_gg, a, b, c, d, block[ 5], 0xd62f105d, 5);
+ case 21: HASHUTIL5_MD5COMPRESS_STEP(md5_gg, d, a, b, c, block[10], 0x02441453, 9);
+ case 22: HASHUTIL5_MD5COMPRESS_STEP(md5_gg, c, d, a, b, block[15], 0xd8a1e681, 14);
+ case 23: HASHUTIL5_MD5COMPRESS_STEP(md5_gg, b, c, d, a, block[ 4], 0xe7d3fbc8, 20);
+ case 24: HASHUTIL5_MD5COMPRESS_STEP(md5_gg, a, b, c, d, block[ 9], 0x21e1cde6, 5);
+ case 25: HASHUTIL5_MD5COMPRESS_STEP(md5_gg, d, a, b, c, block[14], 0xc33707d6, 9);
+ case 26: HASHUTIL5_MD5COMPRESS_STEP(md5_gg, c, d, a, b, block[ 3], 0xf4d50d87, 14);
+ case 27: HASHUTIL5_MD5COMPRESS_STEP(md5_gg, b, c, d, a, block[ 8], 0x455a14ed, 20);
+ case 28: HASHUTIL5_MD5COMPRESS_STEP(md5_gg, a, b, c, d, block[13], 0xa9e3e905, 5);
+ case 29: HASHUTIL5_MD5COMPRESS_STEP(md5_gg, d, a, b, c, block[ 2], 0xfcefa3f8, 9);
+ case 30: HASHUTIL5_MD5COMPRESS_STEP(md5_gg, c, d, a, b, block[ 7], 0x676f02d9, 14);
+ case 31: HASHUTIL5_MD5COMPRESS_STEP(md5_gg, b, c, d, a, block[12], 0x8d2a4c8a, 20);
+ case 32: HASHUTIL5_MD5COMPRESS_STEP(md5_hh, a, b, c, d, block[ 5], 0xfffa3942, 4);
+ case 33: HASHUTIL5_MD5COMPRESS_STEP(md5_hh, d, a, b, c, block[ 8], 0x8771f681, 11);
+ case 34: HASHUTIL5_MD5COMPRESS_STEP(md5_hh, c, d, a, b, block[11], 0x6d9d6122, 16);
+ case 35: HASHUTIL5_MD5COMPRESS_STEP(md5_hh, b, c, d, a, block[14], 0xfde5380c, 23);
+ case 36: HASHUTIL5_MD5COMPRESS_STEP(md5_hh, a, b, c, d, block[ 1], 0xa4beea44, 4);
+ case 37: HASHUTIL5_MD5COMPRESS_STEP(md5_hh, d, a, b, c, block[ 4], 0x4bdecfa9, 11);
+ case 38: HASHUTIL5_MD5COMPRESS_STEP(md5_hh, c, d, a, b, block[ 7], 0xf6bb4b60, 16);
+ case 39: HASHUTIL5_MD5COMPRESS_STEP(md5_hh, b, c, d, a, block[10], 0xbebfbc70, 23);
+ case 40: HASHUTIL5_MD5COMPRESS_STEP(md5_hh, a, b, c, d, block[13], 0x289b7ec6, 4);
+ case 41: HASHUTIL5_MD5COMPRESS_STEP(md5_hh, d, a, b, c, block[ 0], 0xeaa127fa, 11);
+ case 42: HASHUTIL5_MD5COMPRESS_STEP(md5_hh, c, d, a, b, block[ 3], 0xd4ef3085, 16);
+ case 43: HASHUTIL5_MD5COMPRESS_STEP(md5_hh, b, c, d, a, block[ 6], 0x04881d05, 23);
+ case 44: HASHUTIL5_MD5COMPRESS_STEP(md5_hh, a, b, c, d, block[ 9], 0xd9d4d039, 4);
+ case 45: HASHUTIL5_MD5COMPRESS_STEP(md5_hh, d, a, b, c, block[12], 0xe6db99e5, 11);
+ case 46: HASHUTIL5_MD5COMPRESS_STEP(md5_hh, c, d, a, b, block[15], 0x1fa27cf8, 16);
+ case 47: HASHUTIL5_MD5COMPRESS_STEP(md5_hh, b, c, d, a, block[ 2], 0xc4ac5665, 23);
+ case 48: HASHUTIL5_MD5COMPRESS_STEP(md5_ii, a, b, c, d, block[ 0], 0xf4292244, 6);
+ case 49: HASHUTIL5_MD5COMPRESS_STEP(md5_ii, d, a, b, c, block[ 7], 0x432aff97, 10);
+ case 50: HASHUTIL5_MD5COMPRESS_STEP(md5_ii, c, d, a, b, block[14], 0xab9423a7, 15);
+ case 51: HASHUTIL5_MD5COMPRESS_STEP(md5_ii, b, c, d, a, block[ 5], 0xfc93a039, 21);
+ case 52: HASHUTIL5_MD5COMPRESS_STEP(md5_ii, a, b, c, d, block[12], 0x655b59c3, 6);
+ case 53: HASHUTIL5_MD5COMPRESS_STEP(md5_ii, d, a, b, c, block[ 3], 0x8f0ccc92, 10);
+ case 54: HASHUTIL5_MD5COMPRESS_STEP(md5_ii, c, d, a, b, block[10], 0xffeff47d, 15);
+ case 55: HASHUTIL5_MD5COMPRESS_STEP(md5_ii, b, c, d, a, block[ 1], 0x85845dd1, 21);
+ case 56: HASHUTIL5_MD5COMPRESS_STEP(md5_ii, a, b, c, d, block[ 8], 0x6fa87e4f, 6);
+ case 57: HASHUTIL5_MD5COMPRESS_STEP(md5_ii, d, a, b, c, block[15], 0xfe2ce6e0, 10);
+ case 58: HASHUTIL5_MD5COMPRESS_STEP(md5_ii, c, d, a, b, block[ 6], 0xa3014314, 15);
+ case 59: HASHUTIL5_MD5COMPRESS_STEP(md5_ii, b, c, d, a, block[13], 0x4e0811a1, 21);
+ case 60: HASHUTIL5_MD5COMPRESS_STEP(md5_ii, a, b, c, d, block[ 4], 0xf7537e82, 6);
+ case 61: HASHUTIL5_MD5COMPRESS_STEP(md5_ii, d, a, b, c, block[11], 0xbd3af235, 10);
+ case 62: HASHUTIL5_MD5COMPRESS_STEP(md5_ii, c, d, a, b, block[ 2], 0x2ad7d2bb, 15);
+ case 63: HASHUTIL5_MD5COMPRESS_STEP(md5_ii, b, c, d, a, block[ 9], 0xeb86d391, 21);
+ }
+ return (rihv[0] == ihv[0]+a && rihv[1] == ihv[1]+b && rihv[2] == ihv[2]+c && rihv[3] == ihv[3]+d);
+}
+
+msgdiff_tuples_t msgdiff_tuples[] = {
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 1<<31, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<15, /*12*/ 0, /*13*/ 0, /*14*/ 1<<31, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 1<<8, /*3*/ 0, /*4*/ 1<<31, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<15, /*12*/ 0, /*13*/ 0, /*14*/ 1<<31, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<0, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<1, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<2, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<3, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<4, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<5, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<6, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<7, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<8, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<9, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<10, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<11, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<12, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<13, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<14, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<15, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<16, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<17, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<18, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<19, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<20, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<21, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<22, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<23, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<24, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<25, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<26, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<27, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<28, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<29, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<30, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<31, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 0, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 1<<10, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 1<<31, /*11*/ 0, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 1<<31, /*9*/ 0, /*10*/ 0, /*11*/ 0, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 0, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 1<<8, /*7*/ 0, /*8*/ 0, /*9*/ 1<<31, /*10*/ 0, /*11*/ 0, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 1<<31 }, /*t*/ 37, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 1<<31, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 1<<27, /*10*/ 0, /*11*/ 0, /*12*/ 1<<31, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 37, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 1<<20, /*5*/ 0, /*6*/ 0, /*7*/ 1<<31, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 0, /*12*/ 0, /*13*/ 1<<31, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 1<<8, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 0, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 37, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 1<<10, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<21, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 1<<10, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<31, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 1<<31, /*6*/ 0, /*7*/ 0, /*8*/ 1<<31, /*9*/ 0, /*10*/ 0, /*11*/ 0, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 0, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 1<<8, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 0, /*12*/ 0, /*13*/ 0, /*14*/ 1<<31, /*15*/ 0 }, /*t*/ 37, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 1<<31, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 0, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 0, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 1<<31, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 0, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 0, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 0, /*12*/ 0, /*13*/ 0, /*14*/ 1<<31, /*15*/ 0 }, /*t*/ 44, /*negate*/ 0, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 1<<25, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 0, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 1<<10, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 0, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 1<<25, /*9*/ 0, /*10*/ 0, /*11*/ 0, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<21, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 0, /*12*/ 0, /*13*/ 0, /*14*/ 1<<16, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 1<<20, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 0, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 1<<8, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 0, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 50, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 1<<27, /*10*/ 0, /*11*/ 0, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 50, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 1<<10, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 1<<27, /*10*/ 0, /*11*/ 0, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 37, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 1<<31, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 1<<31, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 0, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 1<<31, /*9*/ 0, /*10*/ 0, /*11*/ 1<<21, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 1<<25, /*9*/ 0, /*10*/ 0, /*11*/ 0, /*12*/ 0, /*13*/ 1<<31, /*14*/ 0, /*15*/ 0 }, /*t*/ 44, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 },
+
+ { { /*0*/ 0, /*1*/ 0, /*2*/ 0, /*3*/ 0, /*4*/ 0, /*5*/ 0, /*6*/ 0, /*7*/ 0, /*8*/ 0, /*9*/ 0, /*10*/ 0, /*11*/ 0, /*12*/ 0, /*13*/ 0, /*14*/ 0, /*15*/ 0 }, /*t*/ 0, /*negate*/ 1, /*zero*/ 1, /*msb*/ 1 } // end of array marker
+};
+
+void print_coll(uint64_t total, const uint32_t ihv1[4], const uint32_t block1[16], const uint32_t ihv2[4], const uint32_t block2[16]) {
+ unsigned i;
+ printf("Found collision in block %llu:\n dm: ", (long long unsigned int)((total>>6)-1));
+ for (i = 0; i < 16; ++i)
+ if (block2[i]-block1[i])
+ printf("dm%d=%08x ", i, block2[i]-block1[i]);
+ printf("\n ihv1=");
+ for (i = 0; i < 4; ++i)
+ printf("%08x", ihv1[i]);
+ printf("\n ihv2=");
+ for (i = 0; i < 4; ++i)
+ printf("%08x", ihv2[i]);
+ printf("\n");
+}
+
+int detect_coll(const uint32_t block1[16], const uint32_t states[260], const uint32_t statesmsb[260], const uint32_t tihv[4], uint32_t ihv2[4], uint32_t block2[16]) {
+ unsigned i,j;
+ for (i = 0; msgdiff_tuples[i].t != 0; ++i) {
+ for (j = 0; j < 16; ++j)
+ block2[j] = block1[j] + msgdiff_tuples[i].msgdiff[j];
+ if (msgdiff_tuples[i].zero) {
+ if (md5recompress_fast(msgdiff_tuples[i].t, ihv2, block2, states+((msgdiff_tuples[i].t+1)*4), tihv))
+ return 1;
+ }
+ if (msgdiff_tuples[i].msb) {
+ if (md5recompress_fast(msgdiff_tuples[i].t, ihv2, block2, statesmsb+((msgdiff_tuples[i].t+1)*4), tihv))
+ return 1;
+ }
+ if (msgdiff_tuples[i].negate) {
+ for (j = 0; j < 16; ++j)
+ block2[j] = block1[j] - msgdiff_tuples[i].msgdiff[j];
+ if (msgdiff_tuples[i].zero) {
+ if (md5recompress_fast(msgdiff_tuples[i].t, ihv2, block2, states+((msgdiff_tuples[i].t+1)*4), tihv))
+ return 1;
+ }
+ if (msgdiff_tuples[i].msb) {
+ if (md5recompress_fast(msgdiff_tuples[i].t, ihv2, block2, statesmsb+((msgdiff_tuples[i].t+1)*4), tihv))
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+void md5_process(MD5_CTX* ctx, const uint32_t* block)
+{
+ unsigned i;
+ ctx->ihv1[0] = ctx->ihv[0];
+ ctx->ihv1[1] = ctx->ihv[1];
+ ctx->ihv1[2] = ctx->ihv[2];
+ ctx->ihv1[3] = ctx->ihv[3];
+ md5compress_states(ctx->ihv, block, ctx->states);
+ for (i = 0; i < 260; ++i)
+ ctx->statesmsb[i] = ctx->states[i] + (1<<31);
+ if (detect_coll(block, ctx->states, ctx->statesmsb, ctx->ihv, ctx->ihv2, ctx->m2)) {
+#ifdef VERBOSE_COLLDETECT
+ print_coll(ctx->total, ctx->ihv1, block, ctx->ihv2, ctx->m2);
+#endif
+ ctx->found_collision = 1;
+ if (ctx->safe_hash) {
+ // block was carefully constructed for one specific ihv-value
+ // update ihv once or twice more with block to break the collision property
+ md5compress_states(ctx->ihv, block, ctx->states);
+ md5compress_states(ctx->ihv, block, ctx->states);
+ }
+ }
+ // check for special den Boer & Bosselaers attack (zero difference block, differential path entirely MSB differences)
+ if (ctx->total >= 128 && md5recompress_fast(44, ctx->ihv2, block, ctx->statesmsb+((44+1)*4), ctx->ihv)) {
+ if ((ctx->ihv2[0] != (ctx->ihv1[0]^(1<<31))) || (ctx->ihv2[1] != (ctx->ihv1[1]^(1<<31))) || (ctx->ihv2[2] != (ctx->ihv1[2]^(1<<31))) || (ctx->ihv2[3] != (ctx->ihv1[3]^(1<<31)))) {
+ // not den Boer & Bosselears attack, but regular near-collision attack
+#ifdef VERBOSE_COLLDETECT
+ print_coll(ctx->total, ctx->ihv1, block, ctx->ihv2, block);
+#endif
+ ctx->found_collision = 1;
+ if (ctx->safe_hash) {
+ // block was carefully constructed for one specific ihv-value
+ // update ihv once or twice more with block to break the collision property
+ md5compress_states(ctx->ihv, block, ctx->states);
+ md5compress_states(ctx->ihv, block, ctx->states);
+ }
+ } else {
+ // check for necessary previous collision block
+ for (i=0; i < 4; ++i)
+ ctx->ihv1[i] = ctx->previhv[i];
+ md5compress_states(ctx->ihv1, ctx->prevblock, ctx->states);
+ for (i = 0; i < 260; ++i)
+ ctx->statesmsb[i] = ctx->states[i] + (1<<31);
+ if (detect_coll(ctx->prevblock, ctx->states, ctx->statesmsb, ctx->ihv2, ctx->tmpihv, ctx->tmpblock)) {
+#ifdef VERBOSE_COLLDETECT
+ print_coll(ctx->total, ctx->ihv1, block, ctx->ihv2, block);
+ print_coll(ctx->total-64, ctx->previhv, ctx->prevblock, ctx->tmpihv, ctx->tmpblock);
+#endif
+ ctx->found_collision = 1;
+ if (ctx->safe_hash) {
+ // block was carefully constructed for one specific ihv-value
+ // update ihv once or twice more with block to break the collision property
+ md5compress_states(ctx->ihv, block, ctx->states);
+ md5compress_states(ctx->ihv, block, ctx->states);
+ }
+ }
+ }
+ }
+ // need to store the last ihv and block
+ for (i = 0; i < 4; ++i)
+ ctx->previhv[i] = ctx->ihv1[i];
+ for (i = 0; i < 16; ++i)
+ ctx->prevblock[i] = block[i];
+}
+
+
+
+
+
+void MD5Init(MD5_CTX* ctx) {
+ static const union { unsigned char bytes[4]; uint32_t value; } endianness = { { 0, 1, 2, 3 } };
+ static const uint32_t littleendian = 0x03020100;
+ ctx->total = 0;
+ ctx->ihv[0] = 0x67452301;
+ ctx->ihv[1] = 0xefcdab89;
+ ctx->ihv[2] = 0x98badcfe;
+ ctx->ihv[3] = 0x10325476;
+ ctx->found_collision = 0;
+ ctx->safe_hash = 1;
+ ctx->bigendian = (endianness.value != littleendian);
+}
+void MD5Init_unsafe(MD5_CTX* ctx) {
+ static const union { unsigned char bytes[4]; uint32_t value; } endianness = { { 0, 1, 2, 3 } };
+ static const uint32_t littleendian = 0x03020100;
+ ctx->total = 0;
+ ctx->ihv[0] = 0x67452301;
+ ctx->ihv[1] = 0xefcdab89;
+ ctx->ihv[2] = 0x98badcfe;
+ ctx->ihv[3] = 0x10325476;
+ ctx->found_collision = 0;
+ ctx->safe_hash = 0;
+ ctx->bigendian = (endianness.value != littleendian);
+}
+
+void MD5Update(MD5_CTX* ctx, const char* buf, unsigned len) {
+ unsigned left, fill;
+ if (ctx == NULL) exit(1);
+ if (len == 0) return;
+ if (buf == NULL) exit(1);
+
+ left = ctx->total&63;
+ fill = 64 - left;
+
+ if (left && len >= fill) {
+ ctx->total += fill;
+
+ memcpy(ctx->buffer + left, buf, fill);
+ if (ctx->bigendian)
+ swap_bytes((uint32_t*)(ctx->buffer));
+ md5_process(ctx, (uint32_t*)(ctx->buffer));
+ buf += fill;
+ len -= fill;
+ left = 0;
+ }
+ while (len >= 64) {
+ ctx->total += 64;
+ if (ctx->bigendian) {
+ memcpy(ctx->buffer, buf, 64);
+ swap_bytes((uint32_t*)(ctx->buffer));
+ md5_process(ctx, (uint32_t*)(ctx->buffer));
+ } else
+ md5_process(ctx, (const uint32_t*)(buf));
+ buf += 64;
+ len -= 64;
+ }
+ if (len > 0) {
+ ctx->total += len;
+ memcpy(ctx->buffer + left, buf, len);
+ }
+}
+
+static const unsigned char md5_padding[64] =
+{
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+int MD5Final(unsigned char output[16], MD5_CTX *ctx)
+{
+ uint32_t last = ctx->total&63;
+ uint32_t padn = (last < 56) ? (56-last) : (120-last);
+ MD5Update(ctx, (const char*)(md5_padding), padn);
+ ctx->total -= padn;
+ ctx->total <<= 3;
+ ctx->buffer[56] = (unsigned char)(ctx->total);
+ ctx->buffer[57] = (unsigned char)(ctx->total>>8);
+ ctx->buffer[58] = (unsigned char)(ctx->total>>16);
+ ctx->buffer[59] = (unsigned char)(ctx->total>>24);
+ ctx->buffer[60] = (unsigned char)(ctx->total>>32);
+ ctx->buffer[61] = (unsigned char)(ctx->total>>40);
+ ctx->buffer[62] = (unsigned char)(ctx->total>>48);
+ ctx->buffer[63] = (unsigned char)(ctx->total>>56);
+ if (ctx->bigendian)
+ swap_bytes((uint32_t*)(ctx->buffer));
+ md5_process(ctx, (uint32_t*)(ctx->buffer));
+ output[0] = (unsigned char)(ctx->ihv[0]);
+ output[1] = (unsigned char)(ctx->ihv[0]>>8);
+ output[2] = (unsigned char)(ctx->ihv[0]>>16);
+ output[3] = (unsigned char)(ctx->ihv[0]>>24);
+ output[4] = (unsigned char)(ctx->ihv[1]);
+ output[5] = (unsigned char)(ctx->ihv[1]>>8);
+ output[6] = (unsigned char)(ctx->ihv[1]>>16);
+ output[7] = (unsigned char)(ctx->ihv[1]>>24);
+ output[8] = (unsigned char)(ctx->ihv[2]);
+ output[9] = (unsigned char)(ctx->ihv[2]>>8);
+ output[10] = (unsigned char)(ctx->ihv[2]>>16);
+ output[11] = (unsigned char)(ctx->ihv[2]>>24);
+ output[12] = (unsigned char)(ctx->ihv[3]);
+ output[13] = (unsigned char)(ctx->ihv[3]>>8);
+ output[14] = (unsigned char)(ctx->ihv[3]>>16);
+ output[15] = (unsigned char)(ctx->ihv[3]>>24);
+ return ctx->found_collision;
+}
+