Skip to content

Commit 9df5375

Browse files
Added fastcoll 1.0.0.5-1 to hashclash.
1 parent 08a203f commit 9df5375

11 files changed

+2520
-0
lines changed

Makefile.am

+12
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ lib_libhashclash_la_SOURCES=\
2525
lib_libhashclash_la_LDFLAGS=-no-undefined
2626

2727
bin_PROGRAMS=\
28+
bin/md5_fastcoll \
2829
bin/md5_diffpathforward \
2930
bin/md5_diffpathbackward \
3031
bin/md5_diffpathconnect \
@@ -40,6 +41,17 @@ bin_PROGRAMS=\
4041
AM_CPPFLAGS=-I$(top_srcdir)/lib
4142
LDADD=lib/libhashclash.la
4243

44+
bin_md5_fastcoll_SOURCES=\
45+
src/md5fastcoll/main.cpp \
46+
src/md5fastcoll/md5.cpp \
47+
src/md5fastcoll/block0.cpp \
48+
src/md5fastcoll/block1.cpp \
49+
src/md5fastcoll/block1wang.cpp \
50+
src/md5fastcoll/block1stevens00.cpp \
51+
src/md5fastcoll/block1stevens01.cpp \
52+
src/md5fastcoll/block1stevens10.cpp \
53+
src/md5fastcoll/block1stevens11.cpp
54+
4355
bin_md5_diffpathforward_SOURCES=\
4456
src/md5forward/dostep.cpp \
4557
src/md5forward/forward.cpp \

src/md5fastcoll/block0.cpp

+320
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,320 @@
1+
/*
2+
3+
MD5 collision generator
4+
=======================
5+
Source code files:
6+
block0.cpp
7+
block1.cpp
8+
main.cpp
9+
main.hpp
10+
md5.cpp
11+
block1wang.cpp
12+
block1stevens00.cpp
13+
block1stevens01.cpp
14+
block1stevens10.cpp
15+
block1stevens11.cpp
16+
Win32 executable:
17+
fastcoll_v1.0.0.5.exe
18+
19+
Version
20+
=======
21+
version 1.0.0.5-1, April 2006.
22+
23+
Copyright
24+
=========
25+
© M. Stevens, 2006. All rights reserved.
26+
27+
Disclaimer
28+
==========
29+
This software is provided as is. Use is at the user's risk.
30+
No guarantee whatsoever is given on how it may function or malfunction.
31+
Support cannot be expected.
32+
This software is meant for scientific and educational purposes only.
33+
It is forbidden to use it for other than scientific or educational purposes.
34+
In particular, commercial and malicious use is not allowed.
35+
Further distribution of this software, by whatever means, is not allowed
36+
without our consent.
37+
This includes publication of source code or executables in printed form,
38+
on websites, newsgroups, CD-ROM's, etc.
39+
Changing the (source) code without our consent is not allowed.
40+
In all versions of the source code this disclaimer, the copyright
41+
notice and the version number should be present.
42+
43+
*/
44+
45+
#include <iostream>
46+
#include <vector>
47+
#include "main.hpp"
48+
49+
uint32 seed32_1, seed32_2;
50+
51+
void find_block0(uint32 block[], const uint32 IV[])
52+
{
53+
uint32 Q[68] = { IV[0], IV[3], IV[2], IV[1] };
54+
55+
std::vector<uint32> q4mask(1<<4);
56+
for (unsigned k = 0; k < q4mask.size(); ++k)
57+
q4mask[k] = ((k<<2) ^ (k<<26)) & 0x38000004;
58+
59+
std::vector<uint32> q9q10mask(1<<3);
60+
for (unsigned k = 0; k < q9q10mask.size(); ++k)
61+
q9q10mask[k] = ((k<<13) ^ (k<<4)) & 0x2060;
62+
63+
std::vector<uint32> q9mask(1<<16);
64+
for (unsigned k = 0; k < q9mask.size(); ++k)
65+
q9mask[k] = ((k<<1) ^ (k<<2) ^ (k<<5) ^ (k<<7) ^ (k<<8) ^ (k<<10) ^ (k<<11) ^ (k<<13)) & 0x0eb94f16;
66+
67+
while (true)
68+
{
69+
Q[Qoff + 1] = xrng64();
70+
Q[Qoff + 3] = (xrng64() & 0xfe87bc3f) | 0x017841c0;
71+
Q[Qoff + 4] = (xrng64() & 0x44000033) | 0x000002c0 | (Q[Qoff + 3] & 0x0287bc00);
72+
Q[Qoff + 5] = 0x41ffffc8 | (Q[Qoff + 4] & 0x04000033);
73+
Q[Qoff + 6] = 0xb84b82d6;
74+
Q[Qoff + 7] = (xrng64() & 0x68000084) | 0x02401b43;
75+
Q[Qoff + 8] = (xrng64() & 0x2b8f6e04) | 0x005090d3 | (~Q[Qoff + 7] & 0x40000000);
76+
Q[Qoff + 9] = 0x20040068 | (Q[Qoff + 8] & 0x00020000) | (~Q[Qoff + 8] & 0x40000000);
77+
Q[Qoff + 10] = (xrng64() & 0x40000000) | 0x1040b089;
78+
Q[Qoff + 11] = (xrng64() & 0x10408008) | 0x0fbb7f16 | (~Q[Qoff + 10] & 0x40000000);
79+
Q[Qoff + 12] = (xrng64() & 0x1ed9df7f) | 0x00022080 | (~Q[Qoff + 11] & 0x40200000);
80+
Q[Qoff + 13] = (xrng64() & 0x5efb4f77) | 0x20049008;
81+
Q[Qoff + 14] = (xrng64() & 0x1fff5f77) | 0x0000a088 | (~Q[Qoff + 13] & 0x40000000);
82+
Q[Qoff + 15] = (xrng64() & 0x5efe7ff7) | 0x80008000 | (~Q[Qoff + 14] & 0x00010000);
83+
Q[Qoff + 16] = (xrng64() & 0x1ffdffff) | 0xa0000000 | (~Q[Qoff + 15] & 0x40020000);
84+
85+
MD5_REVERSE_STEP(0, 0xd76aa478, 7);
86+
MD5_REVERSE_STEP(6, 0xa8304613, 17);
87+
MD5_REVERSE_STEP(7, 0xfd469501, 22);
88+
MD5_REVERSE_STEP(11, 0x895cd7be, 22);
89+
MD5_REVERSE_STEP(14, 0xa679438e, 17);
90+
MD5_REVERSE_STEP(15, 0x49b40821, 22);
91+
92+
const uint32 tt1 = FF(Q[Qoff + 1], Q[Qoff + 0], Q[Qoff - 1]) + Q[Qoff - 2] + 0xe8c7b756;
93+
const uint32 tt17 = GG(Q[Qoff + 16], Q[Qoff + 15], Q[Qoff + 14]) + Q[Qoff + 13] + 0xf61e2562;
94+
const uint32 tt18 = Q[Qoff + 14] + 0xc040b340 + block[6];
95+
const uint32 tt19 = Q[Qoff + 15] + 0x265e5a51 + block[11];
96+
const uint32 tt20 = Q[Qoff + 16] + 0xe9b6c7aa + block[0];
97+
const uint32 tt5 = RR(Q[Qoff + 6] - Q[Qoff + 5], 12) - FF(Q[Qoff + 5], Q[Qoff + 4], Q[Qoff + 3]) - 0x4787c62a;
98+
99+
// change q17 until conditions are met on q18, q19 and q20
100+
unsigned counter = 0;
101+
while (counter < (1 << 7))
102+
{
103+
const uint32 q16 = Q[Qoff + 16];
104+
uint32 q17 = ((xrng64() & 0x3ffd7ff7) | (q16&0xc0008008)) ^ 0x40000000;
105+
++counter;
106+
107+
uint32 q18 = GG(q17, q16, Q[Qoff + 15]) + tt18;
108+
q18 = RL(q18, 9); q18 += q17;
109+
if (0x00020000 != ((q18^q17)&0xa0020000))
110+
continue;
111+
112+
uint32 q19 = GG(q18, q17, q16) + tt19;
113+
q19 = RL(q19, 14); q19 += q18;
114+
if (0x80000000 != (q19 & 0x80020000))
115+
continue;
116+
117+
uint32 q20 = GG(q19, q18, q17) + tt20;
118+
q20 = RL(q20, 20); q20 += q19;
119+
if (0x00040000 != ((q20^q19) & 0x80040000))
120+
continue;
121+
122+
block[1] = q17-q16; block[1] = RR(block[1], 5); block[1] -= tt17;
123+
uint32 q2 = block[1] + tt1; q2 = RL(q2, 12); q2 += Q[Qoff + 1];
124+
block[5] = tt5 - q2;
125+
126+
Q[Qoff + 2] = q2;
127+
Q[Qoff + 17] = q17;
128+
Q[Qoff + 18] = q18;
129+
Q[Qoff + 19] = q19;
130+
Q[Qoff + 20] = q20;
131+
MD5_REVERSE_STEP(2, 0x242070db, 17);
132+
133+
counter = 0;
134+
break;
135+
}
136+
if (counter != 0)
137+
continue;
138+
139+
const uint32 q4 = Q[Qoff + 4];
140+
const uint32 q9backup = Q[Qoff + 9];
141+
const uint32 tt21 = GG(Q[Qoff+20], Q[Qoff+19], Q[Qoff+18]) + Q[Qoff+17] + 0xd62f105d;
142+
143+
// iterate over possible changes of q4
144+
// while keeping all conditions on q1-q20 intact
145+
// this changes m3, m4, m5 and m7
146+
unsigned counter2 = 0;
147+
while (counter2 < (1<<4))
148+
{
149+
Q[Qoff+4] = q4 ^ q4mask[counter2];
150+
++counter2;
151+
MD5_REVERSE_STEP(5, 0x4787c62a, 12);
152+
uint32 q21 = tt21 + block[5];
153+
q21 = RL(q21,5); q21 += Q[Qoff+20];
154+
if (0 != ((q21^Q[Qoff+20]) & 0x80020000))
155+
continue;
156+
157+
Q[Qoff + 21] = q21;
158+
MD5_REVERSE_STEP(3, 0xc1bdceee, 22);
159+
MD5_REVERSE_STEP(4, 0xf57c0faf, 7);
160+
MD5_REVERSE_STEP(7, 0xfd469501, 22);
161+
162+
const uint32 tt22 = GG(Q[Qoff + 21], Q[Qoff + 20], Q[Qoff + 19]) + Q[Qoff + 18] + 0x02441453;
163+
const uint32 tt23 = Q[Qoff + 19] + 0xd8a1e681 + block[15];
164+
const uint32 tt24 = Q[Qoff + 20] + 0xe7d3fbc8 + block[4];
165+
166+
const uint32 tt9 = Q[Qoff + 6] + 0x8b44f7af;
167+
const uint32 tt10 = Q[Qoff + 7] + 0xffff5bb1;
168+
const uint32 tt8 = FF(Q[Qoff + 8], Q[Qoff + 7], Q[Qoff + 6]) + Q[Qoff + 5] + 0x698098d8;
169+
const uint32 tt12 = RR(Q[Qoff+13]-Q[Qoff+12],7) - 0x6b901122;
170+
const uint32 tt13 = RR(Q[Qoff+14]-Q[Qoff+13],12) - FF(Q[Qoff+13],Q[Qoff+12],Q[Qoff+11]) - 0xfd987193;
171+
172+
// iterate over possible changes of q9 and q10
173+
// while keeping conditions on q1-q21 intact
174+
// this changes m8, m9, m10, m12 and m13 (and not m11!)
175+
// the possible changes of q9 that also do not change m10 are used below
176+
for (unsigned counter3 = 0; counter3 < (1<<3);)
177+
{
178+
uint32 q10 = Q[Qoff+10] ^ (q9q10mask[counter3] & 0x60);
179+
Q[Qoff + 9] = q9backup ^ (q9q10mask[counter3] & 0x2000);
180+
++counter3;
181+
uint32 m10 = RR(Q[Qoff+11]-q10,17);
182+
m10 -= FF(q10, Q[Qoff+9], Q[Qoff+8]) + tt10;
183+
184+
uint32 aa = Q[Qoff + 21];
185+
uint32 dd = tt22+m10; dd = RL(dd, 9) + aa;
186+
if (0x80000000 != (dd & 0x80000000)) continue;
187+
188+
uint32 bb = Q[Qoff + 20];
189+
uint32 cc = tt23 + GG(dd, aa, bb);
190+
if (0 != (cc & 0x20000)) continue;
191+
cc = RL(cc, 14) + dd;
192+
if (0 != (cc & 0x80000000)) continue;
193+
194+
bb = tt24 + GG(cc, dd, aa); bb = RL(bb, 20) + cc;
195+
if (0 == (bb & 0x80000000)) continue;
196+
197+
block[10] = m10;
198+
block[13] = tt13 - q10;
199+
200+
// iterate over possible changes of q9
201+
// while keeping intact conditions on q1-q24
202+
// this changes m8, m9 and m12 (but not m10!)
203+
for (unsigned counter4 = 0; counter4 < (1<<16); ++counter4)
204+
{
205+
uint32 q9 = Q[Qoff + 9] ^ q9mask[counter4];
206+
block[12] = tt12 - FF(Q[Qoff + 12], Q[Qoff + 11], q10) - q9;
207+
uint32 m8 = q9 - Q[Qoff + 8];
208+
block[8] = RR(m8, 7) - tt8;
209+
uint32 m9 = q10 - q9;
210+
block[9] = RR(m9, 12) - FF(q9, Q[Qoff + 8], Q[Qoff + 7]) - tt9;
211+
212+
uint32 a = aa, b = bb, c = cc, d = dd;
213+
MD5_STEP(GG, a, b, c, d, block[9], 0x21e1cde6, 5);
214+
MD5_STEP(GG, d, a, b, c, block[14], 0xc33707d6, 9);
215+
MD5_STEP(GG, c, d, a, b, block[3], 0xf4d50d87, 14);
216+
MD5_STEP(GG, b, c, d, a, block[8], 0x455a14ed, 20);
217+
MD5_STEP(GG, a, b, c, d, block[13], 0xa9e3e905, 5);
218+
MD5_STEP(GG, d, a, b, c, block[2], 0xfcefa3f8, 9);
219+
MD5_STEP(GG, c, d, a, b, block[7], 0x676f02d9, 14);
220+
MD5_STEP(GG, b, c, d, a, block[12], 0x8d2a4c8a, 20);
221+
MD5_STEP(HH, a, b, c, d, block[5], 0xfffa3942, 4);
222+
MD5_STEP(HH, d, a, b, c, block[8], 0x8771f681, 11);
223+
224+
c += HH(d, a, b) + block[11] + 0x6d9d6122;
225+
if (0 != (c & (1 << 15)))
226+
continue;
227+
c = (c<<16 | c>>16) + d;
228+
229+
MD5_STEP(HH, b, c, d, a, block[14], 0xfde5380c, 23);
230+
MD5_STEP(HH, a, b, c, d, block[1], 0xa4beea44, 4);
231+
MD5_STEP(HH, d, a, b, c, block[4], 0x4bdecfa9, 11);
232+
MD5_STEP(HH, c, d, a, b, block[7], 0xf6bb4b60, 16);
233+
MD5_STEP(HH, b, c, d, a, block[10], 0xbebfbc70, 23);
234+
MD5_STEP(HH, a, b, c, d, block[13], 0x289b7ec6, 4);
235+
MD5_STEP(HH, d, a, b, c, block[0], 0xeaa127fa, 11);
236+
MD5_STEP(HH, c, d, a, b, block[3], 0xd4ef3085, 16);
237+
MD5_STEP(HH, b, c, d, a, block[6], 0x04881d05, 23);
238+
MD5_STEP(HH, a, b, c, d, block[9], 0xd9d4d039, 4);
239+
MD5_STEP(HH, d, a, b, c, block[12], 0xe6db99e5, 11);
240+
MD5_STEP(HH, c, d, a, b, block[15], 0x1fa27cf8, 16);
241+
MD5_STEP(HH, b, c, d, a, block[2], 0xc4ac5665, 23);
242+
if (0 != ((b^d) & 0x80000000))
243+
continue;
244+
245+
MD5_STEP(II, a, b, c, d, block[0], 0xf4292244, 6);
246+
if (0 != ((a^c) >> 31)) continue;
247+
MD5_STEP(II, d, a, b, c, block[7], 0x432aff97, 10);
248+
if (0 == ((b^d) >> 31)) continue;
249+
MD5_STEP(II, c, d, a, b, block[14], 0xab9423a7, 15);
250+
if (0 != ((a^c) >> 31)) continue;
251+
MD5_STEP(II, b, c, d, a, block[5], 0xfc93a039, 21);
252+
if (0 != ((b^d) >> 31)) continue;
253+
MD5_STEP(II, a, b, c, d, block[12], 0x655b59c3, 6);
254+
if (0 != ((a^c) >> 31)) continue;
255+
MD5_STEP(II, d, a, b, c, block[3], 0x8f0ccc92, 10);
256+
if (0 != ((b^d) >> 31)) continue;
257+
MD5_STEP(II, c, d, a, b, block[10], 0xffeff47d, 15);
258+
if (0 != ((a^c) >> 31)) continue;
259+
MD5_STEP(II, b, c, d, a, block[1], 0x85845dd1, 21);
260+
if (0 != ((b^d) >> 31)) continue;
261+
MD5_STEP(II, a, b, c, d, block[8], 0x6fa87e4f, 6);
262+
if (0 != ((a^c) >> 31)) continue;
263+
MD5_STEP(II, d, a, b, c, block[15], 0xfe2ce6e0, 10);
264+
if (0 != ((b^d) >> 31)) continue;
265+
MD5_STEP(II, c, d, a, b, block[6], 0xa3014314, 15);
266+
if (0 != ((a^c) >> 31)) continue;
267+
MD5_STEP(II, b, c, d, a, block[13], 0x4e0811a1, 21);
268+
if (0 == ((b^d) >> 31)) continue;
269+
MD5_STEP(II, a, b, c, d, block[4], 0xf7537e82, 6);
270+
if (0 != ((a^c) >> 31)) continue;
271+
MD5_STEP(II, d, a, b, c, block[11], 0xbd3af235, 10);
272+
if (0 != ((b^d) >> 31)) continue;
273+
MD5_STEP(II, c, d, a, b, block[2], 0x2ad7d2bb, 15);
274+
if (0 != ((a^c) >> 31)) continue;
275+
MD5_STEP(II, b, c, d, a, block[9], 0xeb86d391, 21);
276+
277+
uint32 IHV1 = b + IV[1];
278+
uint32 IHV2 = c + IV[2];
279+
uint32 IHV3 = d + IV[3];
280+
281+
bool wang = true;
282+
if (0x02000000 != ((IHV2^IHV1) & 0x86000000)) wang = false;
283+
if (0 != ((IHV1^IHV3) & 0x82000000)) wang = false;
284+
if (0 != (IHV1 & 0x06000020)) wang = false;
285+
286+
bool stevens = true;
287+
if ( ((IHV1^IHV2)>>31)!=0 || ((IHV1^IHV3)>>31)!= 0 ) stevens = false;
288+
if ( (IHV3&(1<<25))!=0 || (IHV2&(1<<25))!=0 || (IHV1&(1<<25))!=0
289+
|| ((IHV2^IHV1)&1)!=0) stevens = false;
290+
291+
if (!(wang || stevens)) continue;
292+
293+
std::cout << "." << std::flush;
294+
295+
uint32 IV1[4], IV2[4];
296+
for (int t = 0; t < 4; ++t)
297+
IV2[t] = IV1[t] = IV[t];
298+
299+
uint32 block2[16];
300+
for (int t = 0; t < 16; ++t)
301+
block2[t] = block[t];
302+
block2[4] += 1<<31;
303+
block2[11] += 1<<15;
304+
block2[14] += 1<<31;
305+
306+
md5_compress(IV1, block);
307+
md5_compress(IV2, block2);
308+
if ( (IV2[0] == IV1[0] + (1<<31))
309+
&& (IV2[1] == IV1[1] + (1<<31) + (1<<25))
310+
&& (IV2[2] == IV1[2] + (1<<31) + (1<<25))
311+
&& (IV2[3] == IV1[3] + (1<<31) + (1<<25)))
312+
return;
313+
314+
if (IV2[0] != IV1[0] + (1<<31))
315+
std::cout << "!" << std::flush;
316+
}
317+
}
318+
}
319+
}
320+
}

0 commit comments

Comments
 (0)