2 * Adapted from java to C by jimmikaelkael <jimmikaelkael@wanadoo.fr>
6 * Implements the MD4 message digest algorithm in Java.
11 * The MD4 Message-Digest Algorithm: <http://www.roxen.com/rfc/rfc1320.html>,
12 * IETF RFC-1320 (informational).
15 * @author Raif S. Naffah
20 static unsigned int context
[4];
23 * The basic MD4 atomic functions.
25 static unsigned int FF(int a
, int b
, int c
, int d
, int x
, int s
)
27 unsigned int t
= (a
+ ((b
& c
) | (~b
& d
)) + x
) & 0xFFFFFFFF;
28 return ((t
<< s
) & 0xFFFFFFFF) | (t
>> (32 - s
));
31 static unsigned int GG(int a
, int b
, int c
, int d
, int x
, int s
)
33 unsigned int t
= (a
+ ((b
& c
) | (b
& d
) | (c
& d
)) + x
+ 0x5A827999) & 0xFFFFFFFF;
34 return ((t
<< s
) & 0xFFFFFFFF) | (t
>> (32 - s
));
37 static unsigned int HH(int a
, int b
, int c
, int d
, int x
, int s
)
39 unsigned int t
= (a
+ (b
^ c
^ d
) + x
+ 0x6ED9EBA1) & 0xFFFFFFFF;
40 return ((t
<< s
) & 0xFFFFFFFF) | (t
>> (32 - s
));
44 * MD4 basic transformation.
46 * Transforms context based on 512 bits from input block
48 * @param block input block
50 static void transform(unsigned char *block
)
56 X
[i
] = (block
[i
*4+3] << 24) | (block
[i
*4+2] << 16) | (block
[i
*4+1] << 8) | block
[i
*4];
58 unsigned int A
= context
[0];
59 unsigned int B
= context
[1];
60 unsigned int C
= context
[2];
61 unsigned int D
= context
[3];
63 A
= FF(A
, B
, C
, D
, X
[0], 3);
64 D
= FF(D
, A
, B
, C
, X
[1], 7);
65 C
= FF(C
, D
, A
, B
, X
[2], 11);
66 B
= FF(B
, C
, D
, A
, X
[3], 19);
67 A
= FF(A
, B
, C
, D
, X
[4], 3);
68 D
= FF(D
, A
, B
, C
, X
[5], 7);
69 C
= FF(C
, D
, A
, B
, X
[6], 11);
70 B
= FF(B
, C
, D
, A
, X
[7], 19);
71 A
= FF(A
, B
, C
, D
, X
[8], 3);
72 D
= FF(D
, A
, B
, C
, X
[9], 7);
73 C
= FF(C
, D
, A
, B
, X
[10], 11);
74 B
= FF(B
, C
, D
, A
, X
[11], 19);
75 A
= FF(A
, B
, C
, D
, X
[12], 3);
76 D
= FF(D
, A
, B
, C
, X
[13], 7);
77 C
= FF(C
, D
, A
, B
, X
[14], 11);
78 B
= FF(B
, C
, D
, A
, X
[15], 19);
80 A
= GG(A
, B
, C
, D
, X
[0], 3);
81 D
= GG(D
, A
, B
, C
, X
[4], 5);
82 C
= GG(C
, D
, A
, B
, X
[8], 9);
83 B
= GG(B
, C
, D
, A
, X
[12], 13);
84 A
= GG(A
, B
, C
, D
, X
[1], 3);
85 D
= GG(D
, A
, B
, C
, X
[5], 5);
86 C
= GG(C
, D
, A
, B
, X
[9], 9);
87 B
= GG(B
, C
, D
, A
, X
[13], 13);
88 A
= GG(A
, B
, C
, D
, X
[2], 3);
89 D
= GG(D
, A
, B
, C
, X
[6], 5);
90 C
= GG(C
, D
, A
, B
, X
[10], 9);
91 B
= GG(B
, C
, D
, A
, X
[14], 13);
92 A
= GG(A
, B
, C
, D
, X
[3], 3);
93 D
= GG(D
, A
, B
, C
, X
[7], 5);
94 C
= GG(C
, D
, A
, B
, X
[11], 9);
95 B
= GG(B
, C
, D
, A
, X
[15], 13);
97 A
= HH(A
, B
, C
, D
, X
[0], 3);
98 D
= HH(D
, A
, B
, C
, X
[8], 9);
99 C
= HH(C
, D
, A
, B
, X
[4], 11);
100 B
= HH(B
, C
, D
, A
, X
[12], 15);
101 A
= HH(A
, B
, C
, D
, X
[2], 3);
102 D
= HH(D
, A
, B
, C
, X
[10], 9);
103 C
= HH(C
, D
, A
, B
, X
[6], 11);
104 B
= HH(B
, C
, D
, A
, X
[14], 15);
105 A
= HH(A
, B
, C
, D
, X
[1], 3);
106 D
= HH(D
, A
, B
, C
, X
[9], 9);
107 C
= HH(C
, D
, A
, B
, X
[5], 11);
108 B
= HH(B
, C
, D
, A
, X
[13], 15);
109 A
= HH(A
, B
, C
, D
, X
[3], 3);
110 D
= HH(D
, A
, B
, C
, X
[11], 9);
111 C
= HH(C
, D
, A
, B
, X
[7], 11);
112 B
= HH(B
, C
, D
, A
, X
[15], 15);
119 context
[0] &= 0xFFFFFFFF;
120 context
[1] &= 0xFFFFFFFF;
121 context
[2] &= 0xFFFFFFFF;
122 context
[3] &= 0xFFFFFFFF;
126 * Resets this object disregarding any temporary data present at the
127 * time of the invocation of this call.
129 static void engineReset()
131 // initial values of MD4 i.e. A, B, C, D
132 // as per rfc-1320; they are low-order byte first
133 context
[0] = 0x67452301;
134 context
[1] = 0xEFCDAB89;
135 context
[2] = 0x98BADCFE;
136 context
[3] = 0x10325476;
140 * produce a MD4 message digest from message of len bytes
142 unsigned char *MD4(unsigned char *message
, int len
, unsigned char *cipher
)
144 unsigned char buffer
[128];
145 unsigned int b
= len
* 8;
150 memcpy(buffer
, message
, 64);
156 memset(buffer
, 0, 128);
157 memcpy(buffer
, message
, len
);
161 *((unsigned int *)&buffer
[56]) = b
;
164 *((unsigned int *)&buffer
[120]) = b
;
166 transform(&buffer
[64]);
169 *((unsigned int *)&cipher
[0]) = context
[0];
170 *((unsigned int *)&cipher
[4]) = context
[1];
171 *((unsigned int *)&cipher
[8]) = context
[2];
172 *((unsigned int *)&cipher
[12]) = context
[3];
174 return (unsigned char *)cipher
;