Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Simple MD5 implementation
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdint.h>
- // leftrotate function definition
- #define LEFTROTATE(x, c) (((x) << (c)) | ((x) >> (32 - (c))))
- // These vars will contain the hash
- uint32_t h0, h1, h2, h3;
- void md5(uint8_t *initial_msg, size_t initial_len) {
- // Message (to prepare)
- uint8_t *msg = NULL;
- // Note: All variables are unsigned 32 bit and wrap modulo 2^32 when calculating
- // r specifies the per-round shift amounts
- uint32_t r[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
- 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
- 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
- 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21};
- // Use binary integer part of the sines of integers (in radians) as constants// Initialize variables:
- h0 = 0x67452301;
- h1 = 0xefcdab89;
- h2 = 0x98badcfe;
- h3 = 0x10325476;
- int new_len;
- for(new_len = initial_len*8 + 1; new_len%512!=448; new_len++);
- new_len /= 8;
- msg = calloc(new_len + 64, 1); // also appends "0" bits
- // (we alloc also 64 extra bytes...)
- memcpy(msg, initial_msg, initial_len);
- msg[initial_len] = 128; // write the "1" bit
- uint32_t bits_len = 8*initial_len; // note, we append the len
- memcpy(msg + new_len, &bits_len, 4); // in bits at the end of the buffer
- // Process the message in successive 512-bit chunks:
- //for each 512-bit chunk of message:
- int offset;
- for(offset=0; offset<new_len; offset += (512/8)) {
- // break chunk into sixteen 32-bit words w[j], 0 ≤ j ≤ 15
- uint32_t *w = (uint32_t *) (msg + offset);
- #ifdef DEBUG
- printf("offset: %d %xn", offset, offset);
- int j;
- for(j =0; j < 64; j++) printf("%x ", ((uint8_t *) w)[j]);
- puts("");
- #endif
- // Initialize hash value for this chunk:
- uint32_t a = h0;
- uint32_t b = h1;
- uint32_t c = h2;
- uint32_t d = h3;
- // Main loop:
- uint32_t i;
- for(i = 0; i<64; i++) {
- uint32_t f, g;
- if (i < 16) {
- f = (b & c) | ((~b) & d);
- g = i;
- } else if (i < 32) {
- f = (d & b) | ((~d) & c);
- g = (5*i + 1) % 16;
- } else if (i < 48) {
- f = b ^ c ^ d;
- g = (3*i + 5) % 16;
- } else {
- f = c ^ (b | (~d));
- g = (7*i) % 16;
- }
- uint32_t temp = d;
- d = c;
- c = b;
- b = b + LEFTROTATE((a + f + k[i] + w[g]), r[i]);
- a = temp;
- }
- // Add this chunk's hash to result so far:
- h0 += a;
- h1 += b;
- h2 += c;
- h3 += d;
- }
- // cleanup
- free(msg);
- }
- int main(int argc, char **argv) {
- if (argc < 2) {
- printf("usage: %s 'string'n", argv[0]);
- return 1;
- }
- char *msg = argv[1];
- size_t len = strlen(msg);
- // benchmark
- int i;
- for (i = 0; i < 1000000; i++) {
- md5(msg, len);
- }
- //var char digest[16] := h0 append h1 append h2 append h3 //(Output is in little-endian)
- uint8_t *p;
- // display result
- p=(uint8_t *)&h0;
- printf("%2.2x%2.2x%2.2x%2.2x", p[0], p[1], p[2], p[3], h0);
- p=(uint8_t *)&h1;
- printf("%2.2x%2.2x%2.2x%2.2x", p[0], p[1], p[2], p[3], h1);
- p=(uint8_t *)&h2;
- printf("%2.2x%2.2x%2.2x%2.2x", p[0], p[1], p[2], p[3], h2);
- p=(uint8_t *)&h3;
- printf("%2.2x%2.2x%2.2x%2.2x", p[0], p[1], p[2], p[3], h3);
- puts("");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement