2 Copyright (C) 2003, 2010 - Wolfire Games
4 This file is part of Lugaru.
6 Lugaru is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 See the GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 // MD5.CC - source code for the C++/object oriented translation and
23 // modification of MD5.
25 // Translation and modification (c) 1995 by Mordechai T. Abzug
27 // This translation/ modification is provided "as is," without express or
28 // implied warranty of any kind.
30 // The translator/ modifier does not claim (1) that MD5 will do what you think
31 // it does; (2) that this translation/ modification is accurate; or (3) that
32 // this software is "merchantible." (Language for this disclaimer partially
33 // copied from the disclaimer below).
37 MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
38 MDDRIVER.C - test driver for MD2, MD4 and MD5
41 Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
44 License to copy and use this software is granted provided that it
45 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
46 Algorithm" in all material mentioning or referencing this software
49 License is also granted to make and use derivative works provided
50 that such works are identified as "derived from the RSA Data
51 Security, Inc. MD5 Message-Digest Algorithm" in all material
52 mentioning or referencing the derived work.
54 RSA Data Security, Inc. makes no representations concerning either
55 the merchantability of this software or the suitability of this
56 software for any particular purpose. It is provided "as is"
57 without express or implied warranty of any kind.
59 These notices must be retained in any copies of any part of this
60 documentation and/or software.
72 //#include <strings.h>
78 // MD5 simple initialization method
89 // MD5 block update operation. Continues an MD5 message-digest
90 // operation, processing another message block, and updating the
93 void MD5::update (uint1 *input, uint4 input_length) {
95 uint4 input_index, buffer_index;
96 uint4 buffer_space; // how much space is left in buffer
98 if (finalized){ // so we can't update!
99 cerr << "MD5::update: Can't update a finalized digest!" << endl;
103 // Compute number of bytes mod 64
104 buffer_index = (unsigned int)((count[0] >> 3) & 0x3F);
106 // Update number of bits
107 if ( (count[0] += ((uint4) input_length << 3))<((uint4) input_length << 3) )
110 count[1] += ((uint4)input_length >> 29);
113 buffer_space = 64 - buffer_index; // how much space is left in buffer
115 // Transform as many times as possible.
116 if (input_length >= buffer_space) { // ie. we have enough to fill the buffer
117 // fill the rest of the buffer and transform
118 memcpy (buffer + buffer_index, input, buffer_space);
121 // now, transform each 64-byte piece of the input, bypassing the buffer
122 for (input_index = buffer_space; input_index + 63 < input_length;
124 transform (input+input_index);
126 buffer_index = 0; // so we can buffer remaining
129 input_index=0; // so we can buffer the whole input
132 // and here we do the buffering:
133 memcpy(buffer+buffer_index, input+input_index, input_length-input_index);
138 // MD5 update for files.
139 // Like above, except that it works on files (and uses above as a primitive.)
141 void MD5::update(FILE *file){
143 unsigned char buffer[1024];
146 while (len=fread(buffer, 1, 1024, file))
158 // MD5 update for istreams.
159 // Like update for files; see above.
161 void MD5::update(istream& stream){
163 unsigned char buffer[1024];
166 while (stream.good()){
167 stream.read((char *)buffer, (long)1024); // note that return value of read is unusable.
179 // MD5 update for ifstreams.
180 // Like update for files; see above.
182 void MD5::update(ifstream& stream){
184 unsigned char buffer[1024];
187 while (stream.good()){
188 stream.read((char *)buffer, (long)1024); // note that return value of read is unusable.
200 // MD5 finalization. Ends an MD5 message-digest operation, writing the
201 // the message digest and zeroizing the context.
204 void MD5::finalize (){
206 unsigned char bits[8];
207 unsigned int index, padLen;
208 static uint1 PADDING[64]={
209 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
210 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
211 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
215 cerr << "MD5::finalize: Already finalized this digest!" << endl;
219 // Save number of bits
220 encode (bits, count, 8);
222 // Pad out to 56 mod 64.
223 index = (uint4) ((count[0] >> 3) & 0x3f);
224 padLen = (index < 56) ? (56 - index) : (120 - index);
225 update (PADDING, padLen);
227 // Append length (before padding)
230 // Store state in digest
231 encode (digest, state, 16);
233 // Zeroize sensitive information
234 memset (buffer, 0, sizeof(*buffer));
243 MD5::MD5(FILE *file){
245 init(); // must be called be all constructors
253 MD5::MD5(istream& stream){
255 init(); // must called by all constructors
262 MD5::MD5(ifstream& stream){
264 init(); // must called by all constructors
271 unsigned char *MD5::raw_digest(){
273 uint1 *s = new uint1[16];
276 cerr << "MD5::raw_digest: Can't get digest if you haven't "<<
277 "finalized the digest!" <<endl;
278 return ( (unsigned char*) "");
281 memcpy(s, digest, 16);
287 char *MD5::hex_digest(){
290 char *s= new char[33];
293 cerr << "MD5::hex_digest: Can't get digest if you haven't "<<
294 "finalized the digest!" <<endl;
299 sprintf(s+i*2, "%02x", digest[i]);
310 ostream& operator<<(ostream &stream, MD5 context){
312 stream << context.hex_digest();
324 finalized=0; // we just started!
326 // Nothing counted, so count=0
330 // Load magic initialization constants.
331 state[0] = 0x67452301;
332 state[1] = 0xefcdab89;
333 state[2] = 0x98badcfe;
334 state[3] = 0x10325476;
339 // Constants for MD5Transform routine.
340 // Although we could use C++ style constants, defines are actually better,
341 // since they let us easily evade scope clashes.
363 // MD5 basic transformation. Transforms state based on block.
364 void MD5::transform (uint1 block[64]){
366 uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
368 decode (x, block, 64);
370 assert(!finalized); // not just a user error, since the method is private
373 FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
374 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
375 FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
376 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
377 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
378 FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
379 FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
380 FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
381 FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
382 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
383 FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
384 FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
385 FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
386 FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
387 FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
388 FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
391 GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
392 GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
393 GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
394 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
395 GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
396 GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
397 GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
398 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
399 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
400 GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
401 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
402 GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
403 GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
404 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
405 GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
406 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
409 HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
410 HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
411 HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
412 HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
413 HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
414 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
415 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
416 HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
417 HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
418 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
419 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
420 HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
421 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
422 HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
423 HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
424 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
427 II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
428 II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
429 II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
430 II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
431 II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
432 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
433 II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
434 II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
435 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
436 II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
437 II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
438 II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
439 II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
440 II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
441 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
442 II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
449 // Zeroize sensitive information.
450 memset ( (uint1 *) x, 0, sizeof(x));
456 // Encodes input (UINT4) into output (unsigned char). Assumes len is
458 void MD5::encode (uint1 *output, uint4 *input, uint4 len) {
462 for (i = 0, j = 0; j < len; i++, j += 4) {
463 output[j] = (uint1) (input[i] & 0xff);
464 output[j+1] = (uint1) ((input[i] >> 8) & 0xff);
465 output[j+2] = (uint1) ((input[i] >> 16) & 0xff);
466 output[j+3] = (uint1) ((input[i] >> 24) & 0xff);
473 // Decodes input (unsigned char) into output (UINT4). Assumes len is
475 void MD5::decode (uint4 *output, uint1 *input, uint4 len){
479 for (i = 0, j = 0; j < len; i++, j += 4)
480 output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) |
481 (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24);
488 // Note: Replace "for loop" with standard memcpy if possible.
489 void MD5::memcpy (uint1 *output, uint1 *input, uint4 len){
493 for (i = 0; i < len; i++)
494 output[i] = input[i];
499 // Note: Replace "for loop" with standard memset if possible.
500 void MD5::memset (uint1 *output, uint1 value, uint4 len){
504 for (i = 0; i < len; i++)
510 // ROTATE_LEFT rotates x left n bits.
512 inline unsigned int MD5::rotate_left (uint4 x, uint4 n){
513 return (x << n) | (x >> (32-n)) ;
519 // F, G, H and I are basic MD5 functions.
521 inline unsigned int MD5::F (uint4 x, uint4 y, uint4 z){
522 return (x & y) | (~x & z);
525 inline unsigned int MD5::G (uint4 x, uint4 y, uint4 z){
526 return (x & z) | (y & ~z);
529 inline unsigned int MD5::H (uint4 x, uint4 y, uint4 z){
533 inline unsigned int MD5::I (uint4 x, uint4 y, uint4 z){
539 // FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
540 // Rotation is separate from addition to prevent recomputation.
543 inline void MD5::FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
545 a += F(b, c, d) + x + ac;
546 a = rotate_left (a, s) +b;
549 inline void MD5::GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
551 a += G(b, c, d) + x + ac;
552 a = rotate_left (a, s) +b;
555 inline void MD5::HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
557 a += H(b, c, d) + x + ac;
558 a = rotate_left (a, s) +b;
561 inline void MD5::II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
563 a += I(b, c, d) + x + ac;
564 a = rotate_left (a, s) +b;