/*
Author: crazyd <crazydiamondzgy@hotmail.com>
Date: 2002-12-29
Note: This code is written in embedded assembly, and the most important part of MD5 is written in assembly.
It has a high computing speed, which is nearly twice faster than the C code,
You can call the md5init, md5update, and md5final functions in sequence.
The following standard code:
Standard Code:
# Include "md5.h"
Void main ()
{
Md5_ctx context;
Md5init (& context );
Md5update (& context, "crazyd", strlen ("crazyd "));
Md5final (& context );
}
Special instructions:
Context. State [0] is a 32-bit unsigned integer, and the following array elements are the same,
Their memory storage and display direction are the opposite, so pay special attention to it.
*/
# Include <windows. h>
Typedef struct {
DWORD State [4]; // enpolicted message
DWORD count [2]; // bits of plaintext
Unsigned char buffer [64];
} Md5_ctx;
Void md5init (md5_ctx *);
Void md5update (md5_ctx *, unsigned char *, unsigned INT); // The plaintext to be encrypted is the parameter in the center.
Void md5final (md5_ctx *);
# 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 a ESI
# Define B EDI
# Define c edX
# Define D EBX
# Define tmp1 eax
# Define tmp2 ECx
# Define x (I) [x + 4 * I]
Static void md5transform (DWORD [4], unsigned char [64]);
Static unsigned char padding [64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
# Define ff (a, B, c, d, X, S, AC )/
_ ASM mov tmp1, B/
_ ASM and tmp1, C/
_ ASM mov tmp2, B/
_ ASM not tmp2/
_ ASM and tmp2, D/
_ ASM or tmp2, tmp1/
_ ASM lea a, [tmp2 + A + AC]/
_ ASM Add a, X/
_ ASM rol A, S/
_ ASM Add a, B/
# Define Gg (a, B, c, d, X, S, AC )/
_ ASM mov tmp1, B/
_ ASM and tmp1, D/
_ ASM mov tmp2, D/
_ ASM not tmp2/
_ ASM and tmp2, C/
_ ASM or tmp2, tmp1/
_ ASM lea a, [tmp2 + A + AC]/
_ ASM Add a, X/
_ ASM rol A, S/
_ ASM Add a, B
# Define HH (a, B, c, d, X, S, AC )/
_ ASM mov tmp2, B/
_ Asm xor tmp2, C/
_ Asm xor tmp2, D/
_ ASM lea a, [tmp2 + A + AC]/
_ ASM Add a, X/
_ ASM rol A, S/
_ ASM Add a, B
# Define II (a, B, c, d, X, S, AC )/
_ ASM mov tmp2, D/
_ ASM not tmp2/
_ ASM or tmp2, B/
_ Asm xor tmp2, C/
_ ASM lea a, [tmp2 + A + AC]/
_ ASM Add a, X/
_ ASM rol A, S/
_ ASM Add a, B
Void md5init (md5_ctx * context)
{
Context-> count [0] = context-> count [1] = 0;
Context-> State [0] = 0x67452301;
Context-> State [1] = 0xefcdab89;
Context-> State [2] = 0x98badcfe;
Context-> State [3] = 0x10325476;
}
Void md5update (md5_ctx * context, unsigned char * input, unsigned int inputlen)
{
Unsigned int I, index, partlen;
Index = (unsigned INT) (context-> count [0]> 3) & 0x3f );
If (context-> count [0] + = (DWORD) inputlen <3) <(DWORD) inputlen <3 ))
Context-> count [1] ++;
Context-> count [1] + = (DWORD) inputlen> 29 );
Partlen = 64-index;
If (inputlen> = partlen ){
Copymemory (& context-> buffer [Index], input, partlen );
Md5transform (context-> state, context-> buffer );
For (I = partlen; I + 63 <inputlen; I ++ = 64 ){}
Index = 0;
}
Else
I = 0;
/* Buffer remaining input */
Copymemory (& context-> buffer [Index], & input [I], inputlen-I );
}
Void md5final (md5_ctx * context)
{
Unsigned char bits [8];
Unsigned int index, padlen;
Copymemory (bits, context-> count, 8 );
Index = (unsigned INT) (context-> count [0]> 3) & 0x3f );
Padlen = (index <56 )? (56-index): (120-index );
Md5update (context, padding, padlen );
Md5update (context, bits, 8 );
}
Static void md5transform (DWORD State [4], unsigned char block [64])
{
Dword x [16];
_ ASM {
// Initial
MoV A, 0x67452301
MoV B, 0xefcdab89
MoV C, 0x98badcfe
MoV D, 0x10325476
// Copy string from block to state
// Considering that using APIs affects registers, you can copy the memory.
Push ESI
Push EDI
XOR ECx, ECx
MoV ESI, dword ptr [block]
Lea EDI, [x]
Roll:
MoV eax, dword ptr [ESI + ECx]
MoV dword ptr [EDI + ECx], eax
Add ECx, 4
CMP ECx, 64
JB roll
Pop EDI
Pop ESI
}
/* 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, 0xeaa1_fa);/* 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 */
_ ASM {
MoV tmp1, dword ptr [State]
Add dword ptr [tmp1],
Add dword ptr [tmp1 + 4], B
Add dword ptr [tmp1 + 8], c
Add dword ptr [tmp1 + 12], d
}
}