1
+ #include <md4.h>
2
+ #include "funcs.h"
3
+
4
+ void _a4 (uint32_t * a , uint32_t b , uint32_t c , uint32_t d , uint8_t k , uint8_t s , uint32_t (* OP )(uint32_t , uint32_t , uint32_t ), uint32_t * X , uint32_t z )
5
+
6
+ {
7
+ (* a ) = ROTL (((* a ) + OP (b , c , d ) + X [k ] + z ), s );
8
+ }
9
+
10
+ uint8_t * MD4 (uint8_t * message , uint64_t message_len , uint8_t * digest )
11
+ {
12
+ uint8_t * M = NULL ;
13
+ uint32_t A = 0x67452301 , B = 0xefcdab89 , C = 0x98badcfe , D = 0x10325476 ; // Step 3. Initialize MD Buffer
14
+ uint32_t AA , BB , CC , DD ;
15
+ uint32_t X [16 ];
16
+ uint32_t zs [3 ] = {0x0 ,
17
+ 0x5A827999 ,
18
+ 0x6ED9EBA1 };
19
+ uint64_t b = message_len * 8 ;
20
+ uint64_t shy_bits = b % 512 ;
21
+ uint64_t remaining_bits ;
22
+ uint64_t N ;
23
+
24
+ // Step 1. Append Padding Bits
25
+ if (shy_bits < 448 )
26
+ {
27
+ remaining_bits = 448 - shy_bits ;
28
+ }
29
+ else if (shy_bits >= 448 )
30
+ {
31
+ remaining_bits = 512 - shy_bits + 448 ;
32
+ }
33
+ N = (b + remaining_bits + 64 ) / 8 ;
34
+ M = (uint8_t * )malloc (N );
35
+ memset (M , 0 , N );
36
+ memcpy (M , message , message_len );
37
+ memset (M + message_len , 0 , remaining_bits / 8 );
38
+ M [message_len ] = 1 << 7 ;
39
+
40
+ // Step 2. Append Length
41
+ for (uint8_t i = 0 ; i < 8 ; i ++ )
42
+ {
43
+ M [N - 8 + i ] = (uint8_t )(b >> i * 8 ) & 0xFF ;
44
+ }
45
+
46
+ // Step 4. Process Message in 16-Word Blocks
47
+ for (uint64_t i = 0 ; i <= N / 64 - 1 ; i ++ )
48
+ {
49
+ for (uint8_t j = 0 ; j <= 15 ; j ++ )
50
+ {
51
+ X [j ] = (uint32_t )M [i * 64 + j * 4 ] |
52
+ ((uint32_t )M [i * 64 + j * 4 + 1 ] << 8 ) |
53
+ ((uint32_t )M [i * 64 + j * 4 + 2 ] << 16 ) |
54
+ ((uint32_t )M [i * 64 + j * 4 + 3 ] << 24 );
55
+ }
56
+
57
+ AA = A ;
58
+ BB = B ;
59
+ CC = C ;
60
+ DD = D ;
61
+
62
+ // Round 1
63
+ _a4 (& A , B , C , D , 0 , 3 , F , X , 0 );
64
+ _a4 (& D , A , B , C , 1 , 7 , F , X , 0 );
65
+ _a4 (& C , D , A , B , 2 , 11 , F , X , 0 );
66
+ _a4 (& B , C , D , A , 3 , 19 , F , X , 0 );
67
+
68
+ _a4 (& A , B , C , D , 4 , 3 , F , X , 0 );
69
+ _a4 (& D , A , B , C , 5 , 7 , F , X , 0 );
70
+ _a4 (& C , D , A , B , 6 , 11 , F , X , 0 );
71
+ _a4 (& B , C , D , A , 7 , 19 , F , X , 0 );
72
+
73
+ _a4 (& A , B , C , D , 8 , 3 , F , X , 0 );
74
+ _a4 (& D , A , B , C , 9 , 7 , F , X , 0 );
75
+ _a4 (& C , D , A , B , 10 , 11 , F , X , 0 );
76
+ _a4 (& B , C , D , A , 11 , 19 , F , X , 0 );
77
+
78
+ _a4 (& A , B , C , D , 12 , 3 , F , X , 0 );
79
+ _a4 (& D , A , B , C , 13 , 7 , F , X , 0 );
80
+ _a4 (& C , D , A , B , 14 , 11 , F , X , 0 );
81
+ _a4 (& B , C , D , A , 15 , 19 , F , X , 0 );
82
+
83
+ // Round 2
84
+ _a4 (& A , B , C , D , 0 , 3 , G , X , zs [1 ]);
85
+ _a4 (& D , A , B , C , 4 , 5 , G , X , zs [1 ]);
86
+ _a4 (& C , D , A , B , 8 , 9 , G , X , zs [1 ]);
87
+ _a4 (& B , C , D , A , 12 , 13 , G , X , zs [1 ]);
88
+
89
+ _a4 (& A , B , C , D , 1 , 3 , G , X , zs [1 ]);
90
+ _a4 (& D , A , B , C , 5 , 5 , G , X , zs [1 ]);
91
+ _a4 (& C , D , A , B , 9 , 9 , G , X , zs [1 ]);
92
+ _a4 (& B , C , D , A , 13 , 13 , G , X , zs [1 ]);
93
+
94
+ _a4 (& A , B , C , D , 2 , 3 , G , X , zs [1 ]);
95
+ _a4 (& D , A , B , C , 6 , 5 , G , X , zs [1 ]);
96
+ _a4 (& C , D , A , B , 10 , 9 , G , X , zs [1 ]);
97
+ _a4 (& B , C , D , A , 14 , 13 , G , X , zs [1 ]);
98
+
99
+ _a4 (& A , B , C , D , 3 , 3 , G , X , zs [1 ]);
100
+ _a4 (& D , A , B , C , 7 , 5 , G , X , zs [1 ]);
101
+ _a4 (& C , D , A , B , 11 , 9 , G , X , zs [1 ]);
102
+ _a4 (& B , C , D , A , 15 , 13 , G , X , zs [1 ]);
103
+
104
+ // Round 3
105
+ _a4 (& A , B , C , D , 0 , 3 , H , X , zs [2 ]);
106
+ _a4 (& D , A , B , C , 8 , 9 , H , X , zs [2 ]);
107
+ _a4 (& C , D , A , B , 4 , 11 , H , X , zs [2 ]);
108
+ _a4 (& B , C , D , A , 12 , 15 , H , X , zs [2 ]);
109
+
110
+ _a4 (& A , B , C , D , 2 , 3 , H , X , zs [2 ]);
111
+ _a4 (& D , A , B , C , 10 , 9 , H , X , zs [2 ]);
112
+ _a4 (& C , D , A , B , 6 , 11 , H , X , zs [2 ]);
113
+ _a4 (& B , C , D , A , 14 , 15 , H , X , zs [2 ]);
114
+
115
+ _a4 (& A , B , C , D , 1 , 3 , H , X , zs [2 ]);
116
+ _a4 (& D , A , B , C , 9 , 9 , H , X , zs [2 ]);
117
+ _a4 (& C , D , A , B , 5 , 11 , H , X , zs [2 ]);
118
+ _a4 (& B , C , D , A , 13 , 15 , H , X , zs [2 ]);
119
+
120
+ _a4 (& A , B , C , D , 3 , 3 , H , X , zs [2 ]);
121
+ _a4 (& D , A , B , C , 11 , 9 , H , X , zs [2 ]);
122
+ _a4 (& C , D , A , B , 7 , 11 , H , X , zs [2 ]);
123
+ _a4 (& B , C , D , A , 15 , 15 , H , X , zs [2 ]);
124
+
125
+ A += AA ;
126
+ B += BB ;
127
+ C += CC ;
128
+ D += DD ;
129
+ }
130
+
131
+ uint32_t ABCD [] = {A , B , C , D };
132
+
133
+ for (size_t i = 0 ; i < 4 ; ++ i )
134
+ {
135
+ digest [i * 4 ] = (uint8_t )(ABCD [i ] & 0xFF );
136
+ digest [i * 4 + 1 ] = (uint8_t )((ABCD [i ] >> 8 ) & 0xFF );
137
+ digest [i * 4 + 2 ] = (uint8_t )((ABCD [i ] >> 16 ) & 0xFF );
138
+ digest [i * 4 + 3 ] = (uint8_t )((ABCD [i ] >> 24 ) & 0xFF );
139
+ }
140
+
141
+ return digest ;
142
+ }
0 commit comments