2 converted to C++ class by Frank Thilo (thilo@unix-ag.org)
3 for bzflag (http://www.bzflag.org)
8 reference implemantion of RFC 1321
10 Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
13 License to copy and use this software is granted provided that it
14 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
15 Algorithm" in all material mentioning or referencing this software
18 License is also granted to make and use derivative works provided
19 that such works are identified as "derived from the RSA Data
20 Security, Inc. MD5 Message-Digest Algorithm" in all material
21 mentioning or referencing the derived work.
23 RSA Data Security, Inc. makes no representations concerning either
24 the merchantability of this software or the suitability of this
25 software for any particular purpose. It is provided "as is"
26 without express or implied warranty of any kind.
28 These notices must be retained in any copies of any part of this
29 documentation and/or software.
33 /* interface header */
36 /* system implementation headers */
40 // Constants for MD5Transform routine.
58 ///////////////////////////////////////////////
60 // F, G, H and I are basic MD5 functions.
61 inline MD5::uint4
MD5::F(uint4 x
, uint4 y
, uint4 z
)
63 return ((x
& y
) | (~x
& z
));
66 inline MD5::uint4
MD5::G(uint4 x
, uint4 y
, uint4 z
)
68 return ((x
& z
) | (y
&~z
));
71 inline MD5::uint4
MD5::H(uint4 x
, uint4 y
, uint4 z
)
76 inline MD5::uint4
MD5::I(uint4 x
, uint4 y
, uint4 z
)
81 // rotate_left rotates x left n bits.
82 inline MD5::uint4
MD5::rotate_left(uint4 x
, int n
)
84 return (x
<< n
) | (x
>> (32 - n
));
87 // FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
88 // Rotation is separate from addition to prevent recomputation.
89 inline void MD5::FF(uint4
&a
, uint4 b
, uint4 c
, uint4 d
, uint4 x
, uint4 s
, uint4 ac
)
91 a
= rotate_left(a
+ F(b
, c
, d
) + x
+ ac
, s
) + b
;
94 inline void MD5::GG(uint4
&a
, uint4 b
, uint4 c
, uint4 d
, uint4 x
, uint4 s
, uint4 ac
)
96 a
= rotate_left(a
+ G(b
, c
, d
) + x
+ ac
, s
) + b
;
99 inline void MD5::HH(uint4
&a
, uint4 b
, uint4 c
, uint4 d
, uint4 x
, uint4 s
, uint4 ac
)
101 a
= rotate_left(a
+ H(b
, c
, d
) + x
+ ac
, s
) + b
;
104 inline void MD5::II(uint4
&a
, uint4 b
, uint4 c
, uint4 d
, uint4 x
, uint4 s
, uint4 ac
)
106 a
= rotate_left(a
+ I(b
, c
, d
) + x
+ ac
, s
) + b
;
109 //////////////////////////////////////////////
111 // default ctor, just initailize
117 //////////////////////////////////////////////
119 // nifty shortcut ctor, compute MD5 for string and finalize it right away
120 MD5::MD5(const std::string
&text
)
123 update(text
.c_str(), text
.length());
127 //////////////////////////////
136 // load magic initialization constants.
137 state
[0] = 0x67452301;
138 state
[1] = 0xefcdab89;
139 state
[2] = 0x98badcfe;
140 state
[3] = 0x10325476;
143 //////////////////////////////
145 // decodes input (unsigned char) into output (uint4). Assumes len is a multiple of 4.
146 void MD5::decode(uint4 output
[], const uint1 input
[], size_type len
)
148 for (unsigned int i
= 0, j
= 0; j
< len
; i
++, j
+= 4)
149 output
[i
] = ((uint4
)input
[j
]) | (((uint4
)input
[j
+ 1]) << 8) |
150 (((uint4
)input
[j
+ 2]) << 16) | (((uint4
)input
[j
+ 3]) << 24);
153 //////////////////////////////
155 // encodes input (uint4) into output (unsigned char). Assumes len is
157 void MD5::encode(uint1 output
[], const uint4 input
[], size_type len
)
159 for (size_type i
= 0, j
= 0; j
< len
; i
++, j
+= 4) {
160 output
[j
] = input
[i
] & 0xff;
161 output
[j
+ 1] = (input
[i
] >> 8) & 0xff;
162 output
[j
+ 2] = (input
[i
] >> 16) & 0xff;
163 output
[j
+ 3] = (input
[i
] >> 24) & 0xff;
167 //////////////////////////////
169 // apply MD5 algo on a block
170 void MD5::transform(const uint1 block
[blocksize
])
172 uint4 a
= state
[0], b
= state
[1], c
= state
[2], d
= state
[3], x
[16];
173 decode (x
, block
, blocksize
);
176 FF (a
, b
, c
, d
, x
[ 0], S11
, 0xd76aa478); /* 1 */
177 FF (d
, a
, b
, c
, x
[ 1], S12
, 0xe8c7b756); /* 2 */
178 FF (c
, d
, a
, b
, x
[ 2], S13
, 0x242070db); /* 3 */
179 FF (b
, c
, d
, a
, x
[ 3], S14
, 0xc1bdceee); /* 4 */
180 FF (a
, b
, c
, d
, x
[ 4], S11
, 0xf57c0faf); /* 5 */
181 FF (d
, a
, b
, c
, x
[ 5], S12
, 0x4787c62a); /* 6 */
182 FF (c
, d
, a
, b
, x
[ 6], S13
, 0xa8304613); /* 7 */
183 FF (b
, c
, d
, a
, x
[ 7], S14
, 0xfd469501); /* 8 */
184 FF (a
, b
, c
, d
, x
[ 8], S11
, 0x698098d8); /* 9 */
185 FF (d
, a
, b
, c
, x
[ 9], S12
, 0x8b44f7af); /* 10 */
186 FF (c
, d
, a
, b
, x
[10], S13
, 0xffff5bb1); /* 11 */
187 FF (b
, c
, d
, a
, x
[11], S14
, 0x895cd7be); /* 12 */
188 FF (a
, b
, c
, d
, x
[12], S11
, 0x6b901122); /* 13 */
189 FF (d
, a
, b
, c
, x
[13], S12
, 0xfd987193); /* 14 */
190 FF (c
, d
, a
, b
, x
[14], S13
, 0xa679438e); /* 15 */
191 FF (b
, c
, d
, a
, x
[15], S14
, 0x49b40821); /* 16 */
194 GG (a
, b
, c
, d
, x
[ 1], S21
, 0xf61e2562); /* 17 */
195 GG (d
, a
, b
, c
, x
[ 6], S22
, 0xc040b340); /* 18 */
196 GG (c
, d
, a
, b
, x
[11], S23
, 0x265e5a51); /* 19 */
197 GG (b
, c
, d
, a
, x
[ 0], S24
, 0xe9b6c7aa); /* 20 */
198 GG (a
, b
, c
, d
, x
[ 5], S21
, 0xd62f105d); /* 21 */
199 GG (d
, a
, b
, c
, x
[10], S22
, 0x2441453); /* 22 */
200 GG (c
, d
, a
, b
, x
[15], S23
, 0xd8a1e681); /* 23 */
201 GG (b
, c
, d
, a
, x
[ 4], S24
, 0xe7d3fbc8); /* 24 */
202 GG (a
, b
, c
, d
, x
[ 9], S21
, 0x21e1cde6); /* 25 */
203 GG (d
, a
, b
, c
, x
[14], S22
, 0xc33707d6); /* 26 */
204 GG (c
, d
, a
, b
, x
[ 3], S23
, 0xf4d50d87); /* 27 */
205 GG (b
, c
, d
, a
, x
[ 8], S24
, 0x455a14ed); /* 28 */
206 GG (a
, b
, c
, d
, x
[13], S21
, 0xa9e3e905); /* 29 */
207 GG (d
, a
, b
, c
, x
[ 2], S22
, 0xfcefa3f8); /* 30 */
208 GG (c
, d
, a
, b
, x
[ 7], S23
, 0x676f02d9); /* 31 */
209 GG (b
, c
, d
, a
, x
[12], S24
, 0x8d2a4c8a); /* 32 */
212 HH (a
, b
, c
, d
, x
[ 5], S31
, 0xfffa3942); /* 33 */
213 HH (d
, a
, b
, c
, x
[ 8], S32
, 0x8771f681); /* 34 */
214 HH (c
, d
, a
, b
, x
[11], S33
, 0x6d9d6122); /* 35 */
215 HH (b
, c
, d
, a
, x
[14], S34
, 0xfde5380c); /* 36 */
216 HH (a
, b
, c
, d
, x
[ 1], S31
, 0xa4beea44); /* 37 */
217 HH (d
, a
, b
, c
, x
[ 4], S32
, 0x4bdecfa9); /* 38 */
218 HH (c
, d
, a
, b
, x
[ 7], S33
, 0xf6bb4b60); /* 39 */
219 HH (b
, c
, d
, a
, x
[10], S34
, 0xbebfbc70); /* 40 */
220 HH (a
, b
, c
, d
, x
[13], S31
, 0x289b7ec6); /* 41 */
221 HH (d
, a
, b
, c
, x
[ 0], S32
, 0xeaa127fa); /* 42 */
222 HH (c
, d
, a
, b
, x
[ 3], S33
, 0xd4ef3085); /* 43 */
223 HH (b
, c
, d
, a
, x
[ 6], S34
, 0x4881d05); /* 44 */
224 HH (a
, b
, c
, d
, x
[ 9], S31
, 0xd9d4d039); /* 45 */
225 HH (d
, a
, b
, c
, x
[12], S32
, 0xe6db99e5); /* 46 */
226 HH (c
, d
, a
, b
, x
[15], S33
, 0x1fa27cf8); /* 47 */
227 HH (b
, c
, d
, a
, x
[ 2], S34
, 0xc4ac5665); /* 48 */
230 II (a
, b
, c
, d
, x
[ 0], S41
, 0xf4292244); /* 49 */
231 II (d
, a
, b
, c
, x
[ 7], S42
, 0x432aff97); /* 50 */
232 II (c
, d
, a
, b
, x
[14], S43
, 0xab9423a7); /* 51 */
233 II (b
, c
, d
, a
, x
[ 5], S44
, 0xfc93a039); /* 52 */
234 II (a
, b
, c
, d
, x
[12], S41
, 0x655b59c3); /* 53 */
235 II (d
, a
, b
, c
, x
[ 3], S42
, 0x8f0ccc92); /* 54 */
236 II (c
, d
, a
, b
, x
[10], S43
, 0xffeff47d); /* 55 */
237 II (b
, c
, d
, a
, x
[ 1], S44
, 0x85845dd1); /* 56 */
238 II (a
, b
, c
, d
, x
[ 8], S41
, 0x6fa87e4f); /* 57 */
239 II (d
, a
, b
, c
, x
[15], S42
, 0xfe2ce6e0); /* 58 */
240 II (c
, d
, a
, b
, x
[ 6], S43
, 0xa3014314); /* 59 */
241 II (b
, c
, d
, a
, x
[13], S44
, 0x4e0811a1); /* 60 */
242 II (a
, b
, c
, d
, x
[ 4], S41
, 0xf7537e82); /* 61 */
243 II (d
, a
, b
, c
, x
[11], S42
, 0xbd3af235); /* 62 */
244 II (c
, d
, a
, b
, x
[ 2], S43
, 0x2ad7d2bb); /* 63 */
245 II (b
, c
, d
, a
, x
[ 9], S44
, 0xeb86d391); /* 64 */
252 // Zeroize sensitive information.
253 memset(x
, 0, sizeof x
);
256 //////////////////////////////
258 // MD5 block update operation. Continues an MD5 message-digest
259 // operation, processing another message block
260 void MD5::update(const unsigned char input
[], size_type length
)
262 // compute number of bytes mod 64
263 size_type index
= count
[0] / 8 % blocksize
;
265 // Update number of bits
266 if ((count
[0] += (length
<< 3)) < (length
<< 3))
268 count
[1] += (length
>> 29);
270 // number of bytes we need to fill in buffer
271 size_type firstpart
= 64 - index
;
275 // transform as many times as possible.
276 if (length
>= firstpart
) {
277 // fill buffer first, transform
278 memcpy(&buffer
[index
], input
, firstpart
);
281 // transform chunks of blocksize (64 bytes)
282 for (i
= firstpart
; i
+ blocksize
<= length
; i
+= blocksize
)
283 transform(&input
[i
]);
289 // buffer remaining input
290 memcpy(&buffer
[index
], &input
[i
], length
- i
);
293 //////////////////////////////
295 // for convenience provide a verson with signed char
296 void MD5::update(const char input
[], size_type length
)
298 update((const unsigned char *)input
, length
);
301 //////////////////////////////
303 // MD5 finalization. Ends an MD5 message-digest operation, writing the
304 // the message digest and zeroizing the context.
307 static unsigned char padding
[64] = {
308 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
309 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
310 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
314 // Save number of bits
315 unsigned char bits
[8];
316 encode(bits
, count
, 8);
318 // pad out to 56 mod 64.
319 size_type index
= count
[0] / 8 % 64;
320 size_type padLen
= (index
< 56) ? (56 - index
) : (120 - index
);
321 update(padding
, padLen
);
323 // Append length (before padding)
326 // Store state in digest
327 encode(digest
, state
, 16);
329 // Zeroize sensitive information.
330 memset(buffer
, 0, sizeof buffer
);
331 memset(count
, 0, sizeof count
);
339 //////////////////////////////
341 // return hex representation of digest as string
342 std::string
MD5::hexdigest() const
348 for (int i
= 0; i
< 16; i
++)
349 sprintf(buf
+ i
* 2, "%02x", digest
[i
]);
352 return std::string(buf
);
355 // return the slected number of bytes from the digest
356 void MD5::bindigest(void *buf
, int len
) const
358 memcpy(buf
, digest
, len
);
361 //////////////////////////////
363 // std::string md5(const std::string str)
365 // MD5 md5 = MD5(str);
367 // return md5.hexdigest();