Created
April 7, 2019 18:07
-
-
Save ngg/12a550679eac2ad6ff4dfc574a2b41a4 to your computer and use it in GitHub Desktop.
fastcoll patch for md5suffix
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/block0.cpp b/block0.cpp | |
index ad99358..e92eb04 100644 | |
--- a/block0.cpp | |
+++ b/block0.cpp | |
@@ -83,11 +83,18 @@ void find_block0(uint32 block[], const uint32 IV[]) | |
Q[Qoff + 16] = (xrng64() & 0x1ffdffff) | 0xa0000000 | (~Q[Qoff + 15] & 0x40020000); | |
MD5_REVERSE_STEP(0, 0xd76aa478, 7); | |
+ if (!ok_uint32(block[0])) continue; | |
MD5_REVERSE_STEP(6, 0xa8304613, 17); | |
+ if (!ok_uint32(block[6])) continue; | |
MD5_REVERSE_STEP(7, 0xfd469501, 22); | |
MD5_REVERSE_STEP(11, 0x895cd7be, 22); | |
+ if (!ok_uint32(block[11])) continue; | |
+ if (!ok_uint32(block[11] + (1 << 15))) continue; | |
MD5_REVERSE_STEP(14, 0xa679438e, 17); | |
+ if (!ok_uint32(block[14])) continue; | |
+ if (!ok_uint32(block[14] + (1 << 31))) continue; | |
MD5_REVERSE_STEP(15, 0x49b40821, 22); | |
+ if (!ok_uint32(block[15])) continue; | |
const uint32 tt1 = FF(Q[Qoff + 1], Q[Qoff + 0], Q[Qoff - 1]) + Q[Qoff - 2] + 0xe8c7b756; | |
const uint32 tt17 = GG(Q[Qoff + 16], Q[Qoff + 15], Q[Qoff + 14]) + Q[Qoff + 13] + 0xf61e2562; | |
@@ -120,6 +127,7 @@ void find_block0(uint32 block[], const uint32 IV[]) | |
continue; | |
block[1] = q17-q16; block[1] = RR(block[1], 5); block[1] -= tt17; | |
+ if (!ok_uint32(block[1])) continue; | |
uint32 q2 = block[1] + tt1; q2 = RL(q2, 12); q2 += Q[Qoff + 1]; | |
block[5] = tt5 - q2; | |
@@ -129,6 +137,7 @@ void find_block0(uint32 block[], const uint32 IV[]) | |
Q[Qoff + 19] = q19; | |
Q[Qoff + 20] = q20; | |
MD5_REVERSE_STEP(2, 0x242070db, 17); | |
+ if (!ok_uint32(block[2])) continue; | |
counter = 0; | |
break; | |
@@ -149,6 +158,7 @@ void find_block0(uint32 block[], const uint32 IV[]) | |
Q[Qoff+4] = q4 ^ q4mask[counter2]; | |
++counter2; | |
MD5_REVERSE_STEP(5, 0x4787c62a, 12); | |
+ if (!ok_uint32(block[5])) continue; | |
uint32 q21 = tt21 + block[5]; | |
q21 = RL(q21,5); q21 += Q[Qoff+20]; | |
if (0 != ((q21^Q[Qoff+20]) & 0x80020000)) | |
@@ -156,8 +166,12 @@ void find_block0(uint32 block[], const uint32 IV[]) | |
Q[Qoff + 21] = q21; | |
MD5_REVERSE_STEP(3, 0xc1bdceee, 22); | |
+ if (!ok_uint32(block[3])) continue; | |
MD5_REVERSE_STEP(4, 0xf57c0faf, 7); | |
+ if (!ok_uint32(block[4])) continue; | |
+ if (!ok_uint32(block[4] + (1 << 31))) continue; | |
MD5_REVERSE_STEP(7, 0xfd469501, 22); | |
+ if (!ok_uint32(block[7])) continue; | |
const uint32 tt22 = GG(Q[Qoff + 21], Q[Qoff + 20], Q[Qoff + 19]) + Q[Qoff + 18] + 0x02441453; | |
const uint32 tt23 = Q[Qoff + 19] + 0xd8a1e681 + block[15]; | |
@@ -178,8 +192,10 @@ void find_block0(uint32 block[], const uint32 IV[]) | |
uint32 q10 = Q[Qoff+10] ^ (q9q10mask[counter3] & 0x60); | |
Q[Qoff + 9] = q9backup ^ (q9q10mask[counter3] & 0x2000); | |
++counter3; | |
+ if (!ok_uint32(tt13-q10)) continue; | |
uint32 m10 = RR(Q[Qoff+11]-q10,17); | |
m10 -= FF(q10, Q[Qoff+9], Q[Qoff+8]) + tt10; | |
+ if (!ok_uint32(m10)) continue; | |
uint32 aa = Q[Qoff + 21]; | |
uint32 dd = tt22+m10; dd = RL(dd, 9) + aa; | |
@@ -204,10 +220,13 @@ void find_block0(uint32 block[], const uint32 IV[]) | |
{ | |
uint32 q9 = Q[Qoff + 9] ^ q9mask[counter4]; | |
block[12] = tt12 - FF(Q[Qoff + 12], Q[Qoff + 11], q10) - q9; | |
+ if (!ok_uint32(block[12])) continue; | |
uint32 m8 = q9 - Q[Qoff + 8]; | |
block[8] = RR(m8, 7) - tt8; | |
+ if (!ok_uint32(block[8])) continue; | |
uint32 m9 = q10 - q9; | |
block[9] = RR(m9, 12) - FF(q9, Q[Qoff + 8], Q[Qoff + 7]) - tt9; | |
+ if (!ok_uint32(block[9])) continue; | |
uint32 a = aa, b = bb, c = cc, d = dd; | |
MD5_STEP(GG, a, b, c, d, block[9], 0x21e1cde6, 5); | |
@@ -288,7 +307,12 @@ void find_block0(uint32 block[], const uint32 IV[]) | |
if ( (IHV3&(1<<25))!=0 || (IHV2&(1<<25))!=0 || (IHV1&(1<<25))!=0 | |
|| ((IHV2^IHV1)&1)!=0) stevens = false; | |
- if (!(wang || stevens)) continue; | |
+ //if (!(wang || stevens)) continue; | |
+ if (!wang) { | |
+ if (stevens) | |
+ std::cout << "S" << std::flush; | |
+ continue; | |
+ } | |
std::cout << "." << std::flush; | |
@@ -302,6 +326,12 @@ void find_block0(uint32 block[], const uint32 IV[]) | |
block2[4] += 1<<31; | |
block2[11] += 1<<15; | |
block2[14] += 1<<31; | |
+ for (int t = 0; t < 16; ++t) | |
+ if (!ok_uint32(block[t])) | |
+ std::cout << "REALLY BAD " << t << std::endl; | |
+ for (int t = 0; t < 16; ++t) | |
+ if (!ok_uint32(block2[t])) | |
+ std::cout << "REALLY BAD2 " << t << std::endl; | |
md5_compress(IV1, block); | |
md5_compress(IV2, block2); | |
diff --git a/block1.cpp b/block1.cpp | |
index bb612d9..36bcc26 100644 | |
--- a/block1.cpp | |
+++ b/block1.cpp | |
@@ -55,7 +55,7 @@ void find_block1_stevens_00(uint32 block[], const uint32 IV[]); | |
void find_block1(uint32 block[], const uint32 IV[]) | |
{ | |
- if ( ((IV[1]^IV[2])&(1<<31))==0 && ((IV[1]^IV[3])&(1<<31))==0 | |
+ if (false && ((IV[1]^IV[2])&(1<<31))==0 && ((IV[1]^IV[3])&(1<<31))==0 | |
&& (IV[3]&(1<<25))==0 && (IV[2]&(1<<25))==0 && (IV[1]&(1<<25))==0 && ((IV[2]^IV[1])&1)==0 | |
) | |
{ | |
diff --git a/block1wang.cpp b/block1wang.cpp | |
index e559390..9ac11ae 100644 | |
--- a/block1wang.cpp | |
+++ b/block1wang.cpp | |
@@ -46,15 +46,17 @@ notice and the version number should be present. | |
#include <vector> | |
#include "main.hpp" | |
+uint32 tab[128] = {0}; | |
+uint32 good16 = 0, num16 = 0; | |
void find_block1_wang(uint32 block[], const uint32 IV[]) | |
{ | |
uint32 Q[68] = { IV[0], IV[3], IV[2], IV[1] }; | |
- std::vector<uint32> q4mask(1<<6); | |
+ std::vector<uint32> q4mask(1<<10); | |
for (unsigned k = 0; k < q4mask.size(); ++k) | |
q4mask[k] = ((k<<13) ^ (k<<19)) & 0x01c0e000; | |
- std::vector<uint32> q9mask(1<<5), q10mask(1<<5); | |
+ std::vector<uint32> q9mask(1<<7), q10mask(1<<7); | |
for (unsigned k = 0; k < q9mask.size(); ++k) | |
{ | |
uint32 msk = (k<<5) ^ (k<<13) ^ (k<<17) ^ (k<<24); | |
@@ -62,7 +64,7 @@ void find_block1_wang(uint32 block[], const uint32 IV[]) | |
q10mask[k] = msk & 0x18000020; | |
} | |
- std::vector<uint32> q9mask2(1<<10); | |
+ std::vector<uint32> q9mask2(1<<13); | |
for (unsigned k = 0; k < q9mask2.size(); ++k) | |
q9mask2[k] = ((k<<1) ^ (k<<7) ^ (k<<14) ^ (k<<15) ^ (k<<22)) & 0x6074041c; | |
@@ -77,23 +79,47 @@ void find_block1_wang(uint32 block[], const uint32 IV[]) | |
Q[Qoff + 4] = 0x3a040010 | (Q[Qoff + 3] & 0x80000601); | |
Q[Qoff + 5] = (xrng64() & 0x03c0e000) | 0x482f0e50 | aa; | |
Q[Qoff + 6] = (xrng64() & 0x600c0000) | 0x05e2ec56 | aa; | |
- Q[Qoff + 7] = (xrng64() & 0x604c203e) | 0x16819e01 | bb | (Q[Qoff + 6] & 0x01000000); | |
- Q[Qoff + 8] = (xrng64() & 0x604c7c1c) | 0x043283e0 | (Q[Qoff + 7] & 0x80000002); | |
- Q[Qoff + 9] = (xrng64() & 0x00002800) | 0x1c0101c1 | (Q[Qoff + 8] & 0x80001000); | |
- Q[Qoff + 10] = 0x078bcbc0 | bb; | |
- Q[Qoff + 11] = (xrng64() & 0x07800000) | 0x607dc7df | bb; | |
- Q[Qoff + 12] = (xrng64() & 0x00f00f7f) | 0x00081080 | (Q[Qoff + 11] & 0xe7000000); | |
- Q[Qoff + 13] = (xrng64() & 0x00701f77) | 0x3f0fe008 | aa; | |
- Q[Qoff + 14] = (xrng64() & 0x00701f77) | 0x408be088 | aa; | |
- Q[Qoff + 15] = (xrng64() & 0x00ff3ff7) | 0x7d000000; | |
- Q[Qoff + 16] = (xrng64() & 0x4ffdffff) | 0x20000000 | (~Q[Qoff + 15] & 0x00020000); | |
- | |
MD5_REVERSE_STEP(5, 0x4787c62a, 12); | |
+ Q[Qoff + 7] = (xrng64() & 0x604c203e) | 0x16819e01 | bb | (Q[Qoff + 6] & 0x01000000); | |
MD5_REVERSE_STEP(6, 0xa8304613, 17); | |
+ if (!ok_uint32(block[6])) continue; | |
+ Q[Qoff + 8] = (xrng64() & 0x604c7c1c) | 0x043283e0 | (Q[Qoff + 7] & 0x80000002); | |
MD5_REVERSE_STEP(7, 0xfd469501, 22); | |
- MD5_REVERSE_STEP(11, 0x895cd7be, 22); | |
- MD5_REVERSE_STEP(14, 0xa679438e, 17); | |
+ if (!ok_uint32(block[7])) continue; | |
+ int block14t; | |
+ for (block14t = 1000; block14t > 0; block14t--) { | |
+ Q[Qoff + 9] = (xrng64() & 0x00002800) | 0x1c0101c1 | (Q[Qoff + 8] & 0x80001000); | |
+ Q[Qoff + 10] = 0x078bcbc0 | bb; | |
+ Q[Qoff + 11] = (xrng64() & 0x07800000) | 0x607dc7df | bb; | |
+ Q[Qoff + 12] = (xrng64() & 0x00f00f7f) | 0x00081080 | (Q[Qoff + 11] & 0xe7000000); | |
+ MD5_REVERSE_STEP(11, 0x895cd7be, 22); | |
+ if (!ok_uint32(block[11])) continue; | |
+ if (!ok_uint32(block[11] - (1 << 15))) continue; | |
+ Q[Qoff + 13] = (xrng64() & 0x00701f77) | 0x3f0fe008 | aa; | |
+ Q[Qoff + 14] = (xrng64() & 0x00701f77) | 0x408be088 | aa; | |
+ //Q[Qoff + 15] = (xrng64() & 0x00ff3ff7) | 0x7d000000; | |
+ Q[Qoff + 15] = (xrng64() & 0x00ff3ff7) | 0x7d020000; | |
+ MD5_REVERSE_STEP(14, 0xa679438e, 17); | |
+ if (!ok_uint32(block[14])) continue; | |
+ if (!ok_uint32(block[14] + (1 << 31))) continue; | |
+ if (((block[14] >> 24) & 0x7F) != 'g') continue; | |
+ break; | |
+ } | |
+ if (block14t == 0) continue; | |
+ if (((block[14] >> 24) & 0x7F) != 'g') { | |
+ std::cout << "REALLY BAD14" << std::endl; | |
+ } | |
+ const uint32 block15 = 0x20657669; // "ive " | |
+ //Q[Qoff + 16] = (xrng64() & 0x4ffdffff) | 0x20000000 | (~Q[Qoff + 15] & 0x00020000); | |
+ Q[Qoff + 16] = RL(block15 + 0x49b40821 + Q[Qoff + 12] + FF(Q[Qoff + 15], Q[Qoff + 14], Q[Qoff + 13]), 22) + Q[Qoff + 15]; | |
+ if (Q[Qoff + 16] != ((Q[Qoff + 16] & 0x4ffdffff) | 0x20000000 | (~Q[Qoff + 15] & 0x00020000))) { | |
+ continue; | |
+ } | |
MD5_REVERSE_STEP(15, 0x49b40821, 22); | |
+ if (block[15] != block15) { | |
+ std::cout << "REALLY BAD15" << std::endl; | |
+ } | |
+ if (!ok_uint32(block[15])) continue; | |
const uint32 tt17 = GG(Q[Qoff + 16], Q[Qoff + 15], Q[Qoff + 14]) + Q[Qoff + 13] + 0xf61e2562; | |
const uint32 tt18 = Q[Qoff + 14] + 0xc040b340 + block[6]; | |
@@ -105,13 +131,14 @@ void find_block1_wang(uint32 block[], const uint32 IV[]) | |
const uint32 q1a = 0x04200040 | (Q[Qoff + 2] & 0xf01e1080); | |
unsigned counter = 0; | |
- while (counter < (1 << 12)) | |
+ while (counter < (1 << 15)) | |
{ | |
++counter; | |
uint32 q1 = q1a | (xrng64() & 0x01c0e71f); | |
uint32 m1 = Q[Qoff+2] - q1; | |
m1 = RR(m1, 12) - FF(q1, Q[Qoff+0], Q[Qoff-1]) - tt1; | |
+ if (!ok_uint32(m1)) continue; | |
const uint32 q16 = Q[Qoff+16]; | |
uint32 q17 = tt17 + m1; | |
@@ -129,6 +156,7 @@ void find_block1_wang(uint32 block[], const uint32 IV[]) | |
uint32 m0 = q1 - Q[Qoff + 0]; | |
m0 = RR(m0, 7) - tt0; | |
+ if (!ok_uint32(m0)) continue; | |
uint32 q20 = GG(q19, q18, q17) + q16 + 0xe9b6c7aa + m0; | |
q20 = RL(q20, 20); q20 += q19; | |
@@ -143,6 +171,7 @@ void find_block1_wang(uint32 block[], const uint32 IV[]) | |
block[0] = m0; | |
block[1] = m1; | |
MD5_REVERSE_STEP(2, 0x242070db, 17); | |
+ if (!ok_uint32(block[2])) continue; | |
counter = 0; | |
break; | |
@@ -156,19 +185,24 @@ void find_block1_wang(uint32 block[], const uint32 IV[]) | |
const uint32 tt21 = GG(Q[Qoff+20], Q[Qoff+19], Q[Qoff+18]) + Q[Qoff+17] + 0xd62f105d; | |
counter = 0; | |
- while (counter < (1<<6)) | |
+ while (counter < (1<<10)) | |
{ | |
Q[Qoff + 4] = q4b ^ q4mask[counter]; | |
++counter; | |
MD5_REVERSE_STEP(5, 0x4787c62a, 12); | |
+ if (!ok_uint32(block[5])) continue; | |
uint32 q21 = tt21 + block[5]; | |
q21 = RL(q21, 5); q21 += Q[Qoff+20]; | |
if (0 != ((q21^Q[Qoff+20]) & 0x80020000)) continue; | |
Q[Qoff+21] = q21; | |
MD5_REVERSE_STEP(3, 0xc1bdceee, 22); | |
+ if (!ok_uint32(block[3])) continue; | |
MD5_REVERSE_STEP(4, 0xf57c0faf, 7); | |
+ if (!ok_uint32(block[4])) continue; | |
+ if (!ok_uint32(block[4] + (1 << 31))) continue; | |
MD5_REVERSE_STEP(7, 0xfd469501, 22); | |
+ if (!ok_uint32(block[7])) continue; | |
const uint32 tt10 = Q[Qoff + 7] + 0xffff5bb1; | |
const uint32 tt22 = GG(Q[Qoff + 21], Q[Qoff + 20], Q[Qoff + 19]) + Q[Qoff + 18] + 0x02441453; | |
@@ -176,7 +210,7 @@ void find_block1_wang(uint32 block[], const uint32 IV[]) | |
const uint32 tt24 = Q[Qoff + 20] + 0xe7d3fbc8 + block[4]; | |
unsigned counter2 = 0; | |
- while (counter2 < (1<<5)) | |
+ while (counter2 < (1<<7)) | |
{ | |
uint32 q10 = q10b ^ q10mask[counter2]; | |
uint32 m10 = RR(Q[Qoff+11]-q10,17); | |
@@ -184,6 +218,7 @@ void find_block1_wang(uint32 block[], const uint32 IV[]) | |
++counter2; | |
m10 -= FF(q10, q9, Q[Qoff+8]) + tt10; | |
+ if (!ok_uint32(m10)) continue; | |
uint32 aa = Q[Qoff + 21]; | |
uint32 dd = tt22+m10; dd = RL(dd, 9) + aa; | |
@@ -202,14 +237,18 @@ void find_block1_wang(uint32 block[], const uint32 IV[]) | |
Q[Qoff + 9] = q9; | |
Q[Qoff + 10] = q10; | |
MD5_REVERSE_STEP(13, 0xfd987193, 12); | |
+ if (!ok_uint32(block[13])) continue; | |
- for (unsigned k9 = 0; k9 < (1<<10);) | |
+ for (unsigned k9 = 0; k9 < (1<<13);) | |
{ | |
uint32 a = aa, b = bb, c = cc, d = dd; | |
Q[Qoff + 9] = q9 ^ q9mask2[k9]; ++k9; | |
MD5_REVERSE_STEP(8, 0x698098d8, 7); | |
+ if (!ok_uint32(block[8])) continue; | |
MD5_REVERSE_STEP(9, 0x8b44f7af, 12); | |
+ if (!ok_uint32(block[9])) continue; | |
MD5_REVERSE_STEP(12, 0x6b901122, 7); | |
+ if (!ok_uint32(block[12])) continue; | |
MD5_STEP(GG, a, b, c, d, block[9], 0x21e1cde6, 5); | |
MD5_STEP(GG, d, a, b, c, block[14], 0xc33707d6, 9); | |
@@ -293,6 +332,12 @@ void find_block1_wang(uint32 block[], const uint32 IV[]) | |
block2[4] += 1<<31; | |
block2[11] -= 1<<15; | |
block2[14] += 1<<31; | |
+ for (int t = 0; t < 16; ++t) | |
+ if (!ok_uint32(block[t])) | |
+ std::cout << "REALLY BAD " << t << std::endl; | |
+ for (int t = 0; t < 16; ++t) | |
+ if (!ok_uint32(block2[t])) | |
+ std::cout << "REALLY BAD2 " << t << std::endl; | |
md5_compress(IV1, block); | |
md5_compress(IV2, block2); | |
diff --git a/main.cpp b/main.cpp | |
index b964560..24ddb5c 100644 | |
--- a/main.cpp | |
+++ b/main.cpp | |
@@ -289,8 +289,10 @@ int main(int argc, char** argv) | |
save_block(ofs1, msg1block0); | |
save_block(ofs1, msg1block1); | |
+ ofs1 << "me the flag!"; | |
save_block(ofs2, msg2block0); | |
save_block(ofs2, msg2block1); | |
+ ofs2 << "me the flag!"; | |
if (verbose) | |
cout << "Running time: " << runtime.elapsed() << " s" << endl; | |
return 0; | |
diff --git a/main.hpp b/main.hpp | |
index fd972e4..5385f63 100644 | |
--- a/main.hpp | |
+++ b/main.hpp | |
@@ -85,3 +85,15 @@ inline uint32 RR(uint32 x, unsigned int n) | |
block[t] = RR(block[t], RC) - FF(Q[Qoff + t], Q[Qoff + t - 1], Q[Qoff + t - 2]) - Q[Qoff + t - 3] - AC ) | |
#define Qoff 3 | |
+ | |
+inline bool ok_uint8(unsigned char c) { | |
+ if (c < 0xa1) return c != '\n' && c != '\r'; | |
+ //return true; | |
+ if (c < 0xc1) return c == 0xa4 || c == 0xac || c == 0xad || c == 0xbb || c == 0xbf; | |
+ if (c < 0xe0) return c < 0xdb; | |
+ return c < 0xf3; | |
+} | |
+ | |
+inline bool ok_uint32(uint32 c) { | |
+ return ok_uint8(c) && ok_uint8(c >> 8) && ok_uint8(c >> 16) && ok_uint8(c >> 24); | |
+} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment