Advertisement
nuit

Kember Identity

Mar 20th, 2011
168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.88 KB | None | 0 0
  1. /*
  2. My big optimization is to start with a random string, find its md5,
  3. and then use that computed md5 as the next source string, with one
  4. hex digit changed.  My theory is that since each md5 is effectively
  5. random, and there's no correlation between adjacent md5s, that
  6. changing one digit is just as good as creating a new string of 16
  7. new digits.  This lets me do only two expensive rand() calls per
  8. try.
  9. //*/
  10.  
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <time.h>
  15.  
  16. #define NHEXDIGITS   32
  17. #define PROGRESS_MOD (1024*1024)
  18.  
  19. const unsigned int T[64] = {
  20.     0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
  21.     0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
  22.     0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
  23.     0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
  24.     0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
  25.     0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
  26.     0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
  27.     0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
  28. };
  29.  
  30. const unsigned int passdata[128] = {
  31.     0, 7, 1, 12, 2, 17, 3, 22, 4, 7, 5, 12, 6, 17, 7, 22, 8, 7, 9, 12, 10, 17, 11, 22, 12, 7, 13, 12, 14, 17, 15, 22,
  32.     1, 5, 6, 9, 11, 14, 0, 20, 5, 5, 10, 9, 15, 14, 4, 20, 9, 5, 14, 9, 3, 14, 8, 20, 13, 5, 2, 9, 7, 14, 12, 20,
  33.     5, 4, 8, 11, 11, 16, 14, 23, 1, 4, 4, 11, 7, 16, 10, 23, 13, 4, 0, 11, 3, 16, 6, 23, 9, 4, 12, 11, 15, 16, 2, 23,
  34.     0, 6, 7, 10, 14, 15, 5, 21, 12, 6, 3, 10, 10, 15, 1, 21, 8, 6, 15, 10, 6, 15, 13, 21, 4, 6, 11, 10, 2, 15, 9, 21
  35. };
  36.  
  37. typedef struct md5_state_s {
  38.     unsigned int count[2];
  39.     unsigned int abcd[4];
  40.     unsigned char buf[64];
  41. } md5_state_t;
  42.  
  43. static void md5_process(md5_state_t *pms, const unsigned char *data)
  44. {
  45.     unsigned int a = pms->abcd[0];
  46.     unsigned int b = pms->abcd[1];
  47.     unsigned int c = pms->abcd[2];
  48.     unsigned int d = pms->abcd[3];
  49.     unsigned int t;
  50.     unsigned int xbuf[16];
  51.     const unsigned int *X;
  52.     int pass = 0;
  53.  
  54.     if(!((data - (const unsigned char *)0) & 3)) {
  55.         X = (const unsigned int *)data;
  56.     }
  57.     else {
  58.         memcpy(xbuf, data, 64);
  59.         X = xbuf;
  60.     }
  61.     for(pass = 0; pass < 16; pass++) {
  62. #define SET(a, b, c, d, k, s, Ti) t = a + (pass < 4 ? (((b) & (c)) | (~(b) & (d))) : (pass < 8 ? (((b) & (d)) | ((c) & ~(d))) : (pass < 12 ? ((b) ^ (c) ^ (d)) : ((c) ^ ((b) | ~(d)))))) + X[k] + Ti; a = (((t) << (s)) | ((t) >> (32 - (s)))) + b
  63.         SET(a, b, c, d, passdata[pass*8+0], passdata[pass*8+1], T[pass*4+0]);
  64.         SET(d, a, b, c, passdata[pass*8+2], passdata[pass*8+3], T[pass*4+1]);
  65.         SET(c, d, a, b, passdata[pass*8+4], passdata[pass*8+5], T[pass*4+2]);
  66.         SET(b, c, d, a, passdata[pass*8+6], passdata[pass*8+7], T[pass*4+3]);
  67. #undef SET
  68.     }
  69.     pms->abcd[0] += a;
  70.     pms->abcd[1] += b;
  71.     pms->abcd[2] += c;
  72.     pms->abcd[3] += d;
  73. }
  74.  
  75. void md5_init(md5_state_t *pms)
  76. {
  77.     pms->count[0] = 0;
  78.     pms->count[1] = 0;
  79.     pms->abcd[0] = 0x67452301;
  80.     pms->abcd[1] = 0xefcdab89;
  81.     pms->abcd[2] = 0x98badcfe;
  82.     pms->abcd[3] = 0x10325476;
  83. }
  84.  
  85. void md5_append(md5_state_t *pms, const unsigned char *data, int nbytes)
  86. {
  87.     const unsigned char *p = data;
  88.     const int offset       = (pms->count[0] >> 3) & 63;
  89.     unsigned int nbits     = (unsigned int)(nbytes << 3);
  90.     int left               = nbytes;
  91.  
  92.     if (nbytes <= 0) {
  93.         return;
  94.     }
  95.     pms->count[1] += nbytes >> 29;
  96.     pms->count[0] += nbits;
  97.     if (pms->count[0] < nbits) {
  98.         pms->count[1]++;
  99.     }
  100.     if (offset) {
  101.         const int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
  102.         memcpy(pms->buf + offset, p, copy);
  103.         if (offset + copy < 64) {
  104.             return;
  105.         }
  106.         p += copy;
  107.         left -= copy;
  108.         md5_process(pms, pms->buf);
  109.     }
  110.     for(; left >= 64; p += 64, left -= 64) {
  111.         md5_process(pms, p);
  112.     }
  113.  
  114.     if (left) {
  115.         memcpy(pms->buf, p, left);
  116.     }
  117. }
  118.  
  119. void md5_finish(md5_state_t *pms, unsigned char digest[16])
  120. {
  121.     static const unsigned char pad[64] = {
  122.         128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  123.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  124.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  125.         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  126.     };
  127.     unsigned char data[8];
  128.     int i;
  129.  
  130.     for (i = 0; i < 8; ++i) {
  131.         data[i] = (unsigned char)(pms->count[i >> 2] >> ((i & 3) << 3));
  132.     }
  133.  
  134.     md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
  135.     md5_append(pms, data, 8);
  136.     for(i = 0; i < 16; ++i) {
  137.         digest[i] = (unsigned char)(pms->abcd[i >> 2] >> ((i & 3) << 3));
  138.     }
  139. }
  140.  
  141. const char * md5(const char *input, int inputlength)
  142. {
  143.     md5_state_t state;
  144.     static unsigned char digest[16];
  145.     static char hex_output[16*2 + 1];
  146.     int di;
  147.  
  148.     md5_init(&state);
  149.     md5_append(&state, (const unsigned char *)input, inputlength);
  150.     md5_finish(&state, digest);
  151.     for (di = 0; di < 16; ++di) {
  152.         sprintf(hex_output + di * 2, "%02x", digest[di]);
  153.     }
  154.     return hex_output;
  155. }
  156.  
  157. int main( void )
  158. {
  159.     static const char digits[] = "0123456789abcdef";
  160.     unsigned long ntries = 0;
  161.     char source[33];
  162.     int i;
  163.  
  164.     const time_t start = time(NULL);
  165.  
  166.     srand(start);
  167.     memset( source, 0, sizeof( source ) );
  168.     for ( i = 0; i < NHEXDIGITS; i++ ) {
  169.         source[ i ] = digits[ rand() % 16 ];
  170.     }
  171.  
  172.     while (1) {
  173.         if ( ntries % PROGRESS_MOD == 0 ) {
  174.             const time_t now     = time(NULL);
  175.             const time_t elapsed = now - start;
  176.             const float  rate    = elapsed ? ((float)ntries/(float)elapsed) : 0;
  177.  
  178.             printf( "# %lu, %6lu, %12lu, %9.1f, %-24.24s, %s\n",
  179.                     now, elapsed, ntries, rate, ctime(&now), source );
  180.             fflush(stdout);
  181.         }
  182.         ++ntries;
  183.  
  184.         const char * const calculated_md5 = md5( source, NHEXDIGITS );
  185.         if ( memcmp( calculated_md5, source, NHEXDIGITS ) == 0 ) {
  186.             printf("We found it: %s matches %s\n", source, calculated_md5 );
  187.             exit(0);
  188.         }
  189.         /*
  190.     Rather than come up with all random digits, we just randomize one digit.
  191.     If we randomize one digit, we can't get into a kember loop. therefore it is
  192.     much more likely to find the identity
  193.     possibility we run into a hash we already checked is highly unlikely.
  194.     and if, we still get another new hash out of it...coz of the random digit
  195.     //*/
  196.         memcpy( source, calculated_md5, NHEXDIGITS );
  197.         source[ rand() % NHEXDIGITS ] = digits[ rand() % 16 ];
  198.     }
  199.     return 0;
  200. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement