blackjack21

[historical] Password bruteforce program
git clone git://mcdim.xyz/blackjack21.git
Log | Files | Refs | README | LICENSE

md5.cpp (10470B)


      1 /* MD5
      2  converted to C++ class by Frank Thilo (thilo@unix-ag.org)
      3  for bzflag (http://www.bzflag.org)
      4  
      5    based on:
      6  
      7    md5.h and md5.c
      8    reference implemantion of RFC 1321
      9  
     10    Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
     11 rights reserved.
     12  
     13 License to copy and use this software is granted provided that it
     14 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
     15 Algorithm" in all material mentioning or referencing this software
     16 or this function.
     17  
     18 License is also granted to make and use derivative works provided
     19 that such works are identified as "derived from the RSA Data
     20 Security, Inc. MD5 Message-Digest Algorithm" in all material
     21 mentioning or referencing the derived work.
     22  
     23 RSA Data Security, Inc. makes no representations concerning either
     24 the merchantability of this software or the suitability of this
     25 software for any particular purpose. It is provided "as is"
     26 without express or implied warranty of any kind.
     27  
     28 These notices must be retained in any copies of any part of this
     29 documentation and/or software.
     30  
     31 */
     32  
     33 /* interface header */
     34 #include "md5.h"
     35  
     36 /* system implementation headers */
     37 #include <cstdio>
     38  
     39  
     40 // Constants for MD5Transform routine.
     41 #define S11 7
     42 #define S12 12
     43 #define S13 17
     44 #define S14 22
     45 #define S21 5
     46 #define S22 9
     47 #define S23 14
     48 #define S24 20
     49 #define S31 4
     50 #define S32 11
     51 #define S33 16
     52 #define S34 23
     53 #define S41 6
     54 #define S42 10
     55 #define S43 15
     56 #define S44 21
     57  
     58 ///////////////////////////////////////////////
     59  
     60 // F, G, H and I are basic MD5 functions.
     61 inline MD5::uint4 MD5::F(uint4 x, uint4 y, uint4 z) {
     62   return x&y | ~x&z;
     63 }
     64  
     65 inline MD5::uint4 MD5::G(uint4 x, uint4 y, uint4 z) {
     66   return x&z | y&~z;
     67 }
     68  
     69 inline MD5::uint4 MD5::H(uint4 x, uint4 y, uint4 z) {
     70   return x^y^z;
     71 }
     72  
     73 inline MD5::uint4 MD5::I(uint4 x, uint4 y, uint4 z) {
     74   return y ^ (x | ~z);
     75 }
     76  
     77 // rotate_left rotates x left n bits.
     78 inline MD5::uint4 MD5::rotate_left(uint4 x, int n) {
     79   return (x << n) | (x >> (32-n));
     80 }
     81  
     82 // FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
     83 // Rotation is separate from addition to prevent recomputation.
     84 inline void MD5::FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
     85   a = rotate_left(a+ F(b,c,d) + x + ac, s) + b;
     86 }
     87  
     88 inline void MD5::GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
     89   a = rotate_left(a + G(b,c,d) + x + ac, s) + b;
     90 }
     91  
     92 inline void MD5::HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
     93   a = rotate_left(a + H(b,c,d) + x + ac, s) + b;
     94 }
     95  
     96 inline void MD5::II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
     97   a = rotate_left(a + I(b,c,d) + x + ac, s) + b;
     98 }
     99  
    100 //////////////////////////////////////////////
    101  
    102 // default ctor, just initailize
    103 MD5::MD5()
    104 {
    105   init();
    106 }
    107  
    108 //////////////////////////////////////////////
    109  
    110 // nifty shortcut ctor, compute MD5 for string and finalize it right away
    111 MD5::MD5(const std::string &text)
    112 {
    113   init();
    114   update(text.c_str(), text.length());
    115   finalize();
    116 }
    117  
    118 //////////////////////////////
    119  
    120 void MD5::init()
    121 {
    122   finalized=false;
    123  
    124   count[0] = 0;
    125   count[1] = 0;
    126  
    127   // load magic initialization constants.
    128   state[0] = 0x67452301;
    129   state[1] = 0xefcdab89;
    130   state[2] = 0x98badcfe;
    131   state[3] = 0x10325476;
    132 }
    133  
    134 //////////////////////////////
    135  
    136 // decodes input (unsigned char) into output (uint4). Assumes len is a multiple of 4.
    137 void MD5::decode(uint4 output[], const uint1 input[], size_type len)
    138 {
    139   for (unsigned int i = 0, j = 0; j < len; i++, j += 4)
    140     output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) |
    141       (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24);
    142 }
    143  
    144 //////////////////////////////
    145  
    146 // encodes input (uint4) into output (unsigned char). Assumes len is
    147 // a multiple of 4.
    148 void MD5::encode(uint1 output[], const uint4 input[], size_type len)
    149 {
    150   for (size_type i = 0, j = 0; j < len; i++, j += 4) {
    151     output[j] = input[i] & 0xff;
    152     output[j+1] = (input[i] >> 8) & 0xff;
    153     output[j+2] = (input[i] >> 16) & 0xff;
    154     output[j+3] = (input[i] >> 24) & 0xff;
    155   }
    156 }
    157  
    158 //////////////////////////////
    159  
    160 // apply MD5 algo on a block
    161 void MD5::transform(const uint1 block[blocksize])
    162 {
    163   uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
    164   decode (x, block, blocksize);
    165  
    166   /* Round 1 */
    167   FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
    168   FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
    169   FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
    170   FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
    171   FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
    172   FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
    173   FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
    174   FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
    175   FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
    176   FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
    177   FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
    178   FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
    179   FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
    180   FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
    181   FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
    182   FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
    183  
    184   /* Round 2 */
    185   GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
    186   GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
    187   GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
    188   GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
    189   GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
    190   GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
    191   GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
    192   GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
    193   GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
    194   GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
    195   GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
    196   GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
    197   GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
    198   GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
    199   GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
    200   GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
    201  
    202   /* Round 3 */
    203   HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
    204   HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
    205   HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
    206   HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
    207   HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
    208   HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
    209   HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
    210   HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
    211   HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
    212   HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
    213   HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
    214   HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
    215   HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
    216   HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
    217   HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
    218   HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
    219  
    220   /* Round 4 */
    221   II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
    222   II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
    223   II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
    224   II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
    225   II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
    226   II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
    227   II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
    228   II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
    229   II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
    230   II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
    231   II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
    232   II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
    233   II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
    234   II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
    235   II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
    236   II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
    237  
    238   state[0] += a;
    239   state[1] += b;
    240   state[2] += c;
    241   state[3] += d;
    242  
    243   // Zeroize sensitive information.
    244   memset(x, 0, sizeof x);
    245 }
    246  
    247 //////////////////////////////
    248  
    249 // MD5 block update operation. Continues an MD5 message-digest
    250 // operation, processing another message block
    251 void MD5::update(const unsigned char input[], size_type length)
    252 {
    253   // compute number of bytes mod 64
    254   size_type index = count[0] / 8 % blocksize;
    255  
    256   // Update number of bits
    257   if ((count[0] += (length << 3)) < (length << 3))
    258     count[1]++;
    259   count[1] += (length >> 29);
    260  
    261   // number of bytes we need to fill in buffer
    262   size_type firstpart = 64 - index;
    263  
    264   size_type i;
    265  
    266   // transform as many times as possible.
    267   if (length >= firstpart)
    268   {
    269     // fill buffer first, transform
    270     memcpy(&buffer[index], input, firstpart);
    271     transform(buffer);
    272  
    273     // transform chunks of blocksize (64 bytes)
    274     for (i = firstpart; i + blocksize <= length; i += blocksize)
    275       transform(&input[i]);
    276  
    277     index = 0;
    278   }
    279   else
    280     i = 0;
    281  
    282   // buffer remaining input
    283   memcpy(&buffer[index], &input[i], length-i);
    284 }
    285  
    286 //////////////////////////////
    287  
    288 // for convenience provide a verson with signed char
    289 void MD5::update(const char input[], size_type length)
    290 {
    291   update((const unsigned char*)input, length);
    292 }
    293  
    294 //////////////////////////////
    295  
    296 // MD5 finalization. Ends an MD5 message-digest operation, writing the
    297 // the message digest and zeroizing the context.
    298 MD5& MD5::finalize()
    299 {
    300   static unsigned char padding[64] = {
    301     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    302     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    303     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    304   };
    305  
    306   if (!finalized) {
    307     // Save number of bits
    308     unsigned char bits[8];
    309     encode(bits, count, 8);
    310  
    311     // pad out to 56 mod 64.
    312     size_type index = count[0] / 8 % 64;
    313     size_type padLen = (index < 56) ? (56 - index) : (120 - index);
    314     update(padding, padLen);
    315  
    316     // Append length (before padding)
    317     update(bits, 8);
    318  
    319     // Store state in digest
    320     encode(digest, state, 16);
    321  
    322     // Zeroize sensitive information.
    323     memset(buffer, 0, sizeof buffer);
    324     memset(count, 0, sizeof count);
    325  
    326     finalized=true;
    327   }
    328  
    329   return *this;
    330 }
    331  
    332 //////////////////////////////
    333  
    334 // return hex representation of digest as string
    335 std::string MD5::hexdigest() const
    336 {
    337   if (!finalized)
    338     return "";
    339  
    340   char buf[33];
    341   for (int i=0; i<16; i++)
    342     sprintf(buf+i*2, "%02x", digest[i]);
    343   buf[32]=0;
    344  
    345   return std::string(buf);
    346 }
    347  
    348 //////////////////////////////
    349  
    350 std::ostream& operator<<(std::ostream& out, MD5 md5)
    351 {
    352   return out << md5.hexdigest();
    353 }
    354  
    355 //////////////////////////////
    356  
    357 std::string md5(const std::string str)
    358 {
    359     MD5 md5 = MD5(str);
    360  
    361     return md5.hexdigest();
    362 }