From f14caf6e5b223f3d04134ec835e70cbd64c16b9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=BA=90=E6=96=87=E9=9B=A8?= <41315874+fumiama@users.noreply.github.com> Date: Mon, 18 Apr 2022 14:14:33 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96md5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- md5.c | 174 +++++++++++++++++++++++++++++++--------------------------- 1 file changed, 94 insertions(+), 80 deletions(-) diff --git a/md5.c b/md5.c index c509001..4361970 100644 --- a/md5.c +++ b/md5.c @@ -48,7 +48,75 @@ static uint32_t to_uint32(const uint8_t *bytes) { #endif } +#ifdef WORDS_BIGENDIAN + /* break chunk into sixteen 32-bit words w[j], 0 ≤ j ≤ 15 */ + #define break_chunk_into_w(trunk)\ + (for(i = 0; i < 16; i++) w[i] = to_uint32((trunk) + i*4)) +#else + /* break chunk into sixteen 32-bit words w[j], 0 ≤ j ≤ 15 */ + #define break_chunk_into_w(trunk) (w = (uint32_t*)(trunk)) +#endif + +//for each 512-bit chunk of message: +#define sum(trunk) {\ + /* break chunk into sixteen 32-bit words w[j], 0 ≤ j ≤ 15 */\ + break_chunk_into_w(trunk);\ +\ + /* Initialize hash value for this chunk: */\ + a = h0;\ + b = h1;\ + c = h2;\ + d = h3;\ +\ + /* Main loop: */\ + for(i = 0; i < 16; i++) {\ + f = (b & c) | ((~b) & d);\ + g = i;\ + temp = d;\ + d = c;\ + c = b;\ + b += LEFTROTATE((a + f + k[i] + w[g]), r[i]);\ + a = temp;\ + }\ + for(i = 16; i < 32; i++) {\ + f = (d & b) | ((~d) & c);\ + g = (5*i + 1) % 16;\ + temp = d;\ + d = c;\ + c = b;\ + b += LEFTROTATE((a + f + k[i] + w[g]), r[i]);\ + a = temp;\ + }\ + for(i = 32; i < 48; i++) {\ + f = b ^ c ^ d;\ + g = (3*i + 5) % 16;\ + temp = d;\ + d = c;\ + c = b;\ + b += LEFTROTATE((a + f + k[i] + w[g]), r[i]);\ + a = temp;\ + }\ + for(i = 48; i < 64; i++) {\ + f = c ^ (b | (~d));\ + g = (7*i) % 16;\ + temp = d;\ + d = c;\ + c = 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;\ +} + uint8_t* md5(const uint8_t *data, size_t data_len, uint8_t digest[16]) { + // buffer of last trunk + uint8_t trunk[64]; + #ifdef WORDS_BIGENDIAN uint32_t w[16]; #else @@ -62,95 +130,41 @@ uint8_t* md5(const uint8_t *data, size_t data_len, uint8_t digest[16]) { uint32_t h2 = 0x98badcfe; uint32_t h3 = 0x10325476; - // Message (to prepare) - uint8_t *msg = NULL; - - size_t new_len, offset; + size_t offset = 0; uint32_t a, b, c, d, i, f, g, temp; - //Pre-processing: + // Process the message in successive 512-bit chunks: + if(data_len >= 64) + for(offset=0; offset>29 == initial_len*8>>32, but avoids overflow. - to_bytes(data_len>>29, msg + new_len + 4); - - // Process the message in successive 512-bit chunks: - //for each 512-bit chunk of message: - for(offset=0; offset 56) { + sum(trunk); + memset(trunk, 0, 64); } - // cleanup - free(msg); + // append the len in bits at the end of the buffer. + to_bytes(data_len * 8, &trunk[56]); + // initial_len>>29 == initial_len*8>>32, but avoids overflow. + to_bytes(data_len>>29, &trunk[60]); - //var char digest[16] := h0 append h1 append h2 append h3 //(Output is in little-endian) + //sum the last trunk + sum(trunk); + + //var char digest[16] := h0 append h1 append h2 append h3 + //(Output is in little-endian) to_bytes(h0, &digest[0]); to_bytes(h1, &digest[4]); to_bytes(h2, &digest[8]);