|
| 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