Verification algorithm–understanding of md5 algorithm (c language)

RFC 1321: MD5 Message Digest Algorithm (rfc-editor.org)icon-default.png?t=N7T8https://www. rfc-editor.org/rfc/rfc1321 official reference document, you can directly copy the code in References. After the MD type is defined as 5, it can be successfully executed by directly using the code inside. The MDString function can actually be used after changing it. The following is Understand the execution process of MD5 algorithm

1. Filling in position

The complement is an integer multiple of 512bit (64 bytes), because the iterative algorithm uses 64 bytes as one time

Rules:

1. The first bit at the end of the data is padded with 1, which means the first byte is 0x80 (1000 0000b), and then dynamically padded with 0 until it reaches an integer multiple of 64 bytes.

2. Write the effective data length (data length before complementing) in the last 8 bytes (64bit) of the complemented data. The unit is bit, which is the number of bytes * 8. The placement method I personally use is the last eight bytes. Forced conversion to uint32 pointer writing, no problem after testing

3. Rule 1 must be executed, that is to say, if the last block is 56 bytes (448bit), then you cannot just fill in the 8 bytes of the data length, you must fill in the 0x80 of rule 1, which means that the filling will continue to the next block. 64 bytes

Therefore, there will be two situations when filling the position.

1. The length d (remainder) is less than 56 bytes: only the 64 bytes need to be filled, and the last 8 bytes are written into the length.

2. The length d (remainder) is greater than 56 bytes: not only the 64 bytes are filled, but also an additional 64 bytes, and the last 8 bytes of the next 64 bytes are written into the length.

2. Operation

I have read a lot of md5 parsing but can’t understand how md5 is calculated. In fact, this part can be copied directly from the official code. In the MD5Transform function, let’s talk about how the calculation process is performed.

1. Take the 64-byte data and put it into a 16-bit array of uint32_t in memory order.

2. Create 4 new variables to take the value of the current magic number abcd, instead of directly bringing the magic number into the calculation. The initial value of the magic number abcd is

0x67452301; 0xefcdab89; 0x98badcfe; 0x10325476;

3. Variables and arrays are brought into the function operations in the official reference document.

4. Each of the magic numbers abcd + = corresponds to the operation result of the newly created variable

5. Get the next 64 bytes of data and repeat until the end

The calculation in the official reference document in step 3 is as follows,

typedef unsigned long int UINT4;

#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21

#define F(x, y, z) (((x) & amp; (y)) | ((~x) & amp; (z)))
#define G(x, y, z) (((x) & amp; (z)) | ((y) & amp; (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))

#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))


#define FF(a, b, c, d, x, s, ac) {(a) + = F ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); (a) + = (b);}

#define GG(a, b, c, d, x, s, ac) {(a) + = G ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); (a) + = (b);}

#define HH(a, b, c, d, x, s, ac) {(a) + = H ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); (a) + = (b);}

#define II(a, b, c, d, x, s, ac) {(a) + = I ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); (a) + = (b);}




//See the content of MD5Transform for the operation part.

  /* Round 1 */
  FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
  FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
  FF (c, d, a, b, x[2], S13, 0x242070db); /* 3 */
  FF (b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */
  FF (a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */
  FF (d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */
  FF (c, d, a, b, x[6], S13, 0xa8304613); /* 7 */
  FF (b, c, d, a, x[7], S14, 0xfd469501); /* 8 */
  FF (a, b, c, d, x[8], S11, 0x698098d8); /* 9 */
  FF (d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */
  FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
  FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
  FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
  FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
  FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
  FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */

  /* Round 2 */
  GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
  GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
  GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
  GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
  GG (a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */
  GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
  GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
  GG (b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */
  GG (a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */
  GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
  GG (c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */
  GG (b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */
  GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
  GG (d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */
  GG (c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */
  GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */

  /* Round 3 */
  HH (a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */
  HH (d, a, b, c, x[8], S32, 0x8771f681); /* 34 */
  HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
  HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
  HH (a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */
  HH (d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */
  HH (c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */
  HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
  HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
  HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
  HH (c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */
  HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
  HH (a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */
  HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
  HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
  HH (b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */

  /* Round 4 */
  II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
  II (d, a, b, c, x[7], S42, 0x432aff97); /* 50 */
  II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
  II (b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */
  II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
  II (d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */
  II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
  II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
  II (a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */
  II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
  II (c, d, a, b, x[6], S43, 0xa3014314); /* 59 */
  II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
  II (a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */
  II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
  II (c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */
  II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */

You don’t need to worry about what he did, just copy it from the official document. It probably means doing 4 kinds of bit operations, then + and then doing bit loops.

3.Output

The magic number after calculation is the value of md5. It needs to be printed by bytes. The order of printf(“%x”) is messed up.

(Please upload what I have written when you have time)