Advertisement
pseudocreator

MD5-implementation (reheck code!)

Mar 24th, 2014
361
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.89 KB | None | 0 0
  1. /*
  2.  * Simple MD5 implementation
  3.  */
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <stdint.h>
  8.  
  9. // leftrotate function definition
  10. #define LEFTROTATE(x, c) (((x) << (c)) | ((x) >> (32 - (c))))
  11.  
  12. // These vars will contain the hash
  13. uint32_t h0, h1, h2, h3;
  14.  
  15. void md5(uint8_t *initial_msg, size_t initial_len) {
  16.  
  17.     // Message (to prepare)
  18.     uint8_t *msg = NULL;
  19.  
  20.     // Note: All variables are unsigned 32 bit and wrap modulo 2^32 when calculating
  21.  
  22.     // r specifies the per-round shift amounts
  23.  
  24.     uint32_t r[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
  25.                     5,  9, 14, 20, 5,  9, 14, 20, 5,  9, 14, 20, 5,  9, 14, 20,
  26.                     4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
  27.                     6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21};
  28.  
  29.     // Use binary integer part of the sines of integers (in radians) as constants// Initialize variables:
  30.     h0 = 0x67452301;
  31.     h1 = 0xefcdab89;
  32.     h2 = 0x98badcfe;
  33.     h3 = 0x10325476;
  34.  
  35.  
  36.     int new_len;
  37.     for(new_len = initial_len*8 + 1; new_len%512!=448; new_len++);
  38.     new_len /= 8;
  39.  
  40.     msg = calloc(new_len + 64, 1); // also appends "0" bits
  41.                                    // (we alloc also 64 extra bytes...)
  42.     memcpy(msg, initial_msg, initial_len);
  43.     msg[initial_len] = 128; // write the "1" bit
  44.  
  45.     uint32_t bits_len = 8*initial_len; // note, we append the len
  46.     memcpy(msg + new_len, &bits_len, 4);           // in bits at the end of the buffer
  47.  
  48.     // Process the message in successive 512-bit chunks:
  49.     //for each 512-bit chunk of message:
  50.     int offset;
  51.     for(offset=0; offset<new_len; offset += (512/8)) {
  52.  
  53.         // break chunk into sixteen 32-bit words w[j], 0 ≤ j ≤ 15
  54.         uint32_t *w = (uint32_t *) (msg + offset);
  55.  
  56. #ifdef DEBUG
  57.         printf("offset: %d %xn", offset, offset);
  58.  
  59.         int j;
  60.         for(j =0; j < 64; j++) printf("%x ", ((uint8_t *) w)[j]);
  61.         puts("");
  62. #endif
  63.  
  64.         // Initialize hash value for this chunk:
  65.         uint32_t a = h0;
  66.         uint32_t b = h1;
  67.         uint32_t c = h2;
  68.         uint32_t d = h3;
  69.  
  70.         // Main loop:
  71.         uint32_t i;
  72.         for(i = 0; i<64; i++) {
  73.  
  74.             uint32_t f, g;
  75.  
  76.              if (i < 16) {
  77.                 f = (b & c) | ((~b) & d);
  78.                 g = i;
  79.             } else if (i < 32) {
  80.                 f = (d & b) | ((~d) & c);
  81.                 g = (5*i + 1) % 16;
  82.             } else if (i < 48) {
  83.                 f = b ^ c ^ d;
  84.                 g = (3*i + 5) % 16;          
  85.             } else {
  86.                 f = c ^ (b | (~d));
  87.                 g = (7*i) % 16;
  88.             }
  89.  
  90.              uint32_t temp = d;
  91.             d = c;
  92.             c = b;
  93.             b = b + LEFTROTATE((a + f + k[i] + w[g]), r[i]);
  94.             a = temp;
  95.  
  96.         }
  97.  
  98.         // Add this chunk's hash to result so far:
  99.  
  100.         h0 += a;
  101.         h1 += b;
  102.         h2 += c;
  103.         h3 += d;
  104.  
  105.     }
  106.  
  107.     // cleanup
  108.     free(msg);
  109.  
  110. }
  111.  
  112. int main(int argc, char **argv) {
  113.  
  114.     if (argc < 2) {
  115.         printf("usage: %s 'string'n", argv[0]);
  116.         return 1;
  117.     }
  118.  
  119.     char *msg = argv[1];
  120.     size_t len = strlen(msg);
  121.  
  122.     // benchmark
  123.     int i;
  124.     for (i = 0; i < 1000000; i++) {
  125.         md5(msg, len);
  126.     }
  127.  
  128.     //var char digest[16] := h0 append h1 append h2 append h3 //(Output is in little-endian)
  129.     uint8_t *p;
  130.  
  131.     // display result
  132.  
  133.     p=(uint8_t *)&h0;
  134.     printf("%2.2x%2.2x%2.2x%2.2x", p[0], p[1], p[2], p[3], h0);
  135.  
  136.     p=(uint8_t *)&h1;
  137.     printf("%2.2x%2.2x%2.2x%2.2x", p[0], p[1], p[2], p[3], h1);
  138.  
  139.     p=(uint8_t *)&h2;
  140.     printf("%2.2x%2.2x%2.2x%2.2x", p[0], p[1], p[2], p[3], h2);
  141.  
  142.     p=(uint8_t *)&h3;
  143.     printf("%2.2x%2.2x%2.2x%2.2x", p[0], p[1], p[2], p[3], h3);
  144.     puts("");
  145.  
  146.     return 0;
  147. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement