~smspillaz/nux/nux.fix_1036521

« back to all changes in this revision

Viewing changes to NuxCore/Crypto/NMD5.cpp

  • Committer: Neil Jagdish Patel
  • Date: 2010-09-01 19:25:37 UTC
  • Revision ID: neil.patel@canonical.com-20100901192537-mfz7rm6q262pewg6
Import and build NuxCore

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
**********************************************************************
 
3
** md5.c                                                            **
 
4
** RSA Data Security, Inc. MD5 Message Digest Algorithm             **
 
5
** Created: 2/17/90 RLR                                             **
 
6
** Revised: 1/91 SRD,AJ,BSK,JT Reference C Version                  **
 
7
**********************************************************************
 
8
*/
 
9
 
 
10
/*
 
11
**********************************************************************
 
12
** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
 
13
**                                                                  **
 
14
** License to copy and use this software is granted provided that   **
 
15
** it is identified as the "RSA Data Security, Inc. MD5 Message     **
 
16
** Digest Algorithm" in all material mentioning or referencing this **
 
17
** software or this function.                                       **
 
18
**                                                                  **
 
19
** License is also granted to make and use derivative works         **
 
20
** provided that such works are identified as "derived from the RSA **
 
21
** Data Security, Inc. MD5 Message Digest Algorithm" in all         **
 
22
** material mentioning or referencing the derived work.             **
 
23
**                                                                  **
 
24
** RSA Data Security, Inc. makes no representations concerning      **
 
25
** either the merchantability of this software or the suitability   **
 
26
** of this software for any particular purpose.  It is provided "as **
 
27
** is" without express or implied warranty of any kind.             **
 
28
**                                                                  **
 
29
** These notices must be retained in any copies of any part of this **
 
30
** documentation and/or software.                                   **
 
31
**********************************************************************
 
32
*/
 
33
 
 
34
/* -- include the following line if the md5.h header file is separate -- */
 
35
/* #include "md5.h" */
 
36
 
 
37
/*****************************************************************************************
 
38
CLASS:                  CMD5Checksum
 
39
DESCRIPTION:    Implements the "RSA Data Security, Inc. MD5 Message-Digest Algorithm".
 
40
NOTES:                  Calculates the RSA MD5 checksum for a file or congiguous array of data. 
 
41
 
 
42
Below are extracts from a memo on The MD5 Message-Digest Algorithm by R. Rivest of MIT 
 
43
Laboratory for Computer Science and RSA Data Security, Inc., April 1992. 
 
44
 
 
45
1. Executive Summary
 
46
This document describes the MD5 message-digest algorithm. The
 
47
algorithm takes as input a message of arbitrary length and produces
 
48
as output a 128-bit "fingerprint" or "message digest" of the input.
 
49
It is conjectured that it is computationally infeasible to produce
 
50
two messages having the same message digest, or to produce any
 
51
message having a given prespecified target message digest. The MD5
 
52
algorithm is intended for digital signature applications, where a
 
53
large file must be "compressed" in a secure manner before being
 
54
encrypted with a private (secret) key under a public-key cryptosystem
 
55
such as RSA.
 
56
 
 
57
The MD5 algorithm is designed to be quite fast on 32-bit machines. In
 
58
addition, the MD5 algorithm does not require any large substitution
 
59
tables; the algorithm can be coded quite compactly.
 
60
The MD5 algorithm is an extension of the MD4 message-digest algorithm
 
61
1,2]. MD5 is slightly slower than MD4, but is more "conservative" in
 
62
design. MD5 was designed because it was felt that MD4 was perhaps
 
63
being adopted for use more quickly than justified by the existing
 
64
critical review; because MD4 was designed to be exceptionally fast,
 
65
it is "at the edge" in terms of risking successful cryptanalytic
 
66
attack. MD5 backs off a bit, giving up a little in speed for a much
 
67
greater likelihood of ultimate security. It incorporates some
 
68
suggestions made by various reviewers, and contains additional
 
69
optimizations. The MD5 algorithm is being placed in the public domain
 
70
for review and possible adoption as a standard.
 
71
 
 
72
 
 
73
2. Terminology and Notation
 
74
In this document a "word" is a 32-bit quantity and a "byte" is an
 
75
eight-bit quantity. A sequence of bits can be interpreted in a
 
76
natural manner as a sequence of bytes, where each consecutive group
 
77
of eight bits is interpreted as a byte with the high-order (most
 
78
significant) bit of each byte listed first. Similarly, a sequence of
 
79
bytes can be interpreted as a sequence of 32-bit words, where each
 
80
consecutive group of four bytes is interpreted as a word with the
 
81
low-order (least significant) byte given first.
 
82
Let x_i denote "x sub i". If the subscript is an expression, we
 
83
surround it in braces, as in x_{i+1}. Similarly, we use ^ for
 
84
superscripts (exponentiation), so that x^i denotes x to the i-th   power.
 
85
Let the symbol "+" denote addition of words (i.e., modulo-2^32
 
86
addition). Let X <<< s denote the 32-bit value obtained by circularly
 
87
shifting (rotating) X left by s bit positions. Let not(X) denote the
 
88
bit-wise complement of X, and let X v Y denote the bit-wise OR of X
 
89
and Y. Let X xor Y denote the bit-wise XOR of X and Y, and let XY
 
90
denote the bit-wise AND of X and Y.
 
91
 
 
92
 
 
93
3. MD5 Algorithm Description
 
94
We begin by supposing that we have a b-bit message as input, and that
 
95
we wish to find its message digest. Here b is an arbitrary
 
96
nonnegative integer; b may be zero, it need not be a multiple of
 
97
eight, and it may be arbitrarily large. We imagine the bits of the
 
98
message written down as follows:          m_0 m_1 ... m_{b-1}
 
99
The following five steps are performed to compute the message digest
 
100
of the message.
 
101
 
 
102
3.1 Step 1. Append Padding Bits
 
103
The message is "padded" (extended) so that its length (in bits) is
 
104
congruent to 448, modulo 512. That is, the message is extended so
 
105
that it is just 64 bits shy of being a multiple of 512 bits long.
 
106
Padding is always performed, even if the length of the message is
 
107
already congruent to 448, modulo 512.
 
108
Padding is performed as follows: a single "1" bit is appended to the
 
109
message, and then "0" bits are appended so that the length in bits of
 
110
the padded message becomes congruent to 448, modulo 512. In all, at
 
111
least one bit and at most 512 bits are appended.
 
112
 
 
113
3.2 Step 2. Append Length
 
114
A 64-bit representation of b (the length of the message before the
 
115
padding bits were added) is appended to the result of the previous
 
116
step. In the unlikely event that b is greater than 2^64, then only
 
117
the low-order 64 bits of b are used. (These bits are appended as two
 
118
32-bit words and appended low-order word first in accordance with the
 
119
previous conventions.)
 
120
At this point the resulting message (after padding with bits and with
 
121
b) has a length that is an exact multiple of 512 bits. Equivalently,
 
122
this message has a length that is an exact multiple of 16 (32-bit)
 
123
words. Let M[0 ... N-1] denote the words of the resulting message,
 
124
where N is a multiple of 16.
 
125
 
 
126
3.3 Step 3. Initialize MD Buffer
 
127
A four-word buffer (A,B,C,D) is used to compute the message digest.
 
128
Here each of A, B, C, D is a 32-bit register. These registers are
 
129
initialized to the following values in hexadecimal, low-order bytes   first):
 
130
word A: 01 23 45 67          word B: 89 ab cd ef
 
131
word C: fe dc ba 98          word D: 76 54 32 10
 
132
 
 
133
3.4 Step 4. Process Message in 16-Word Blocks
 
134
We first define four auxiliary functions that each take as input
 
135
three 32-bit words and produce as output one 32-bit word.
 
136
F(X,Y,Z) = XY v not(X) Z          G(X,Y,Z) = XZ v Y not(Z)
 
137
H(X,Y,Z) = X xor Y xor Z          I(X,Y,Z) = Y xor (X v not(Z))
 
138
In each bit position F acts as a conditional: if X then Y else Z.
 
139
The function F could have been defined using + instead of v since XY
 
140
and not(X)Z will never have 1's in the same bit position.) It is
 
141
interesting to note that if the bits of X, Y, and Z are independent
 
142
and unbiased, the each bit of F(X,Y,Z) will be independent and   unbiased.
 
143
The functions G, H, and I are similar to the function F, in that they
 
144
act in "bitwise parallel" to produce their output from the bits of X,
 
145
Y, and Z, in such a manner that if the corresponding bits of X, Y,
 
146
and Z are independent and unbiased, then each bit of G(X,Y,Z),
 
147
H(X,Y,Z), and I(X,Y,Z) will be independent and unbiased. Note that
 
148
the function H is the bit-wise "xor" or "parity" function of its   inputs.
 
149
This step uses a 64-element table T[1 ... 64] constructed from the
 
150
sine function. Let T[i] denote the i-th element of the table, which
 
151
is equal to the integer part of 4294967296 times abs(sin(i)), where i
 
152
is in radians. The elements of the table are given in the appendix.
 
153
Do the following:   
 
154
 
 
155
//Process each 16-word block.
 
156
For i = 0 to N/16-1 do     // Copy block i into X.      
 
157
For j = 0 to 15 do
 
158
Set X[j] to M[i*16+j].     
 
159
end //of loop on j
 
160
 
 
161
// Save A as AA, B as BB, C as CC, and D as DD.
 
162
AA = A     BB = B
 
163
CC = C     DD = D     
 
164
 
 
165
// Round 1.
 
166
// Let [abcd k s i] denote the operation
 
167
// a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s).
 
168
// Do the following 16 operations.
 
169
[ABCD  0  7  1]  [DABC  1 12  2]  [CDAB  2 17  3]  [BCDA  3 22  4]
 
170
[ABCD  4  7  5]  [DABC  5 12  6]  [CDAB  6 17  7]  [BCDA  7 22  8]
 
171
[ABCD  8  7  9]  [DABC  9 12 10]  [CDAB 10 17 11]  [BCDA 11 22 12]
 
172
[ABCD 12  7 13]  [DABC 13 12 14]  [CDAB 14 17 15]  [BCDA 15 22 16]
 
173
 
 
174
// Round 2.      
 
175
// Let [abcd k s i] denote the operation 
 
176
// a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s).
 
177
// Do the following 16 operations.
 
178
[ABCD  1  5 17]  [DABC  6  9 18]  [CDAB 11 14 19]  [BCDA  0 20 20]
 
179
[ABCD  5  5 21]  [DABC 10  9 22]  [CDAB 15 14 23]  [BCDA  4 20 24]
 
180
[ABCD  9  5 25]  [DABC 14  9 26]  [CDAB  3 14 27]  [BCDA  8 20 28]
 
181
[ABCD 13  5 29]  [DABC  2  9 30]  [CDAB  7 14 31]  [BCDA 12 20 32]
 
182
 
 
183
// Round 3.      
 
184
// Let [abcd k s t] denote the operation
 
185
// a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s).
 
186
// Do the following 16 operations.
 
187
[ABCD  5  4 33]  [DABC  8 11 34]  [CDAB 11 16 35]  [BCDA 14 23 36]
 
188
[ABCD  1  4 37]  [DABC  4 11 38]  [CDAB  7 16 39]  [BCDA 10 23 40]
 
189
[ABCD 13  4 41]  [DABC  0 11 42]  [CDAB  3 16 43]  [BCDA  6 23 44]
 
190
[ABCD  9  4 45]  [DABC 12 11 46]  [CDAB 15 16 47]  [BCDA  2 23 48]
 
191
 
 
192
// Round 4. 
 
193
// Let [abcd k s t] denote the operation
 
194
// a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s).
 
195
// Do the following 16 operations.
 
196
[ABCD  0  6 49]  [DABC  7 10 50]  [CDAB 14 15 51]  [BCDA  5 21 52]
 
197
[ABCD 12  6 53]  [DABC  3 10 54]  [CDAB 10 15 55]  [BCDA  1 21 56]
 
198
[ABCD  8  6 57]  [DABC 15 10 58]  [CDAB  6 15 59]  [BCDA 13 21 60]
 
199
[ABCD  4  6 61]  [DABC 11 10 62]  [CDAB  2 15 63]  [BCDA  9 21 64]
 
200
 
 
201
// Then perform the following additions. (That is increment each
 
202
//   of the four registers by the value it had before this block
 
203
//   was started.) 
 
204
A = A + AA     B = B + BB     C = C + CC  D = D + DD   
 
205
 
 
206
end // of loop on i
 
207
 
 
208
3.5 Step 5. Output
 
209
The message digest produced as output is A, B, C, D. That is, we
 
210
begin with the low-order byte of A, and end with the high-order byte of D.
 
211
This completes the description of MD5.
 
212
 
 
213
Summary
 
214
The MD5 message-digest algorithm is simple to implement, and provides
 
215
a "fingerprint" or message digest of a message of arbitrary length.
 
216
It is conjectured that the difficulty of coming up with two messages
 
217
having the same message digest is on the order of 2^64 operations,
 
218
and that the difficulty of coming up with any message having a given
 
219
message digest is on the order of 2^128 operations. The MD5 algorithm
 
220
has been carefully scrutinized for weaknesses. It is, however, a
 
221
relatively new algorithm and further security analysis is of course
 
222
justified, as is the case with any new proposal of this sort.
 
223
 
 
224
 
 
225
5. Differences Between MD4 and MD5
 
226
The following are the differences between MD4 and MD5:
 
227
1.   A fourth round has been added.
 
228
2.   Each step now has a unique additive constant.
 
229
3.   The function g in round 2 was changed from (XY v XZ v YZ) to
 
230
(XZ v Y not(Z)) to make g less symmetric.
 
231
4.   Each step now adds in the result of the previous step.  This
 
232
promotes a faster "avalanche effect".
 
233
5.   The order in which input words are accessed in rounds 2 and
 
234
3 is changed, to make these patterns less like each other.
 
235
6.   The shift amounts in each round have been approximately
 
236
optimized, to yield a faster "avalanche effect." The shifts in
 
237
different rounds are distinct.
 
238
 
 
239
References
 
240
[1] Rivest, R., "The MD4 Message Digest Algorithm", RFC 1320, MIT and
 
241
RSA Data Security, Inc., April 1992.
 
242
[2] Rivest, R., "The MD4 message digest algorithm", in A.J.  Menezes
 
243
and S.A. Vanstone, editors, Advances in Cryptology - CRYPTO '90
 
244
Proceedings, pages 303-311, Springer-Verlag, 1991.
 
245
[3] CCITT Recommendation X.509 (1988), "The Directory -
 
246
Authentication Framework."APPENDIX A - Reference Implementation
 
247
 
 
248
 
 
249
The level of security discussed in this memo is considered to be
 
250
sufficient for implementing very high security hybrid digital-
 
251
signature schemes based on MD5 and a public-key cryptosystem.
 
252
Author's Address
 
253
Ronald L. Rivest   Massachusetts Institute of Technology
 
254
Laboratory for Computer Science   NE43-324   545 Technology Square
 
255
Cambridge, MA  02139-1986   Phone: (617) 253-5880
 
256
EMail: rivest@theory.lcs.mit.edu
 
257
 
 
258
 
 
259
*****************************************************************************************/
 
260
 
 
261
#include "NKernel.h"
 
262
#include "NMD5.h"
 
263
NAMESPACE_BEGIN
 
264
 
 
265
/* forward declaration */
 
266
static void Transform (UINT4 *buf, UINT4 *in);
 
267
 
 
268
static unsigned char PADDING[64] = {
 
269
        0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
270
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
271
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
272
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
273
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
274
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
275
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
276
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 
277
};
 
278
 
 
279
/* F, G and H are basic MD5 functions: selection, majority, parity */
 
280
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
 
281
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
 
282
#define H(x, y, z) ((x) ^ (y) ^ (z))
 
283
#define I(x, y, z) ((y) ^ ((x) | (~z))) 
 
284
 
 
285
/* ROTATE_LEFT rotates x left n bits */
 
286
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
 
287
 
 
288
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */
 
289
/* Rotation is separate from addition to prevent recomputation */
 
290
#define FF(a, b, c, d, x, s, ac) \
 
291
{(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
 
292
    (a) = ROTATE_LEFT ((a), (s)); \
 
293
    (a) += (b); \
 
294
}
 
295
#define GG(a, b, c, d, x, s, ac) \
 
296
{(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
 
297
    (a) = ROTATE_LEFT ((a), (s)); \
 
298
    (a) += (b); \
 
299
}
 
300
#define HH(a, b, c, d, x, s, ac) \
 
301
{(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
 
302
    (a) = ROTATE_LEFT ((a), (s)); \
 
303
    (a) += (b); \
 
304
}
 
305
#define II(a, b, c, d, x, s, ac) \
 
306
{(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
 
307
    (a) = ROTATE_LEFT ((a), (s)); \
 
308
    (a) += (b); \
 
309
}
 
310
 
 
311
void MD5Init (MD5_CTX *mdContext)
 
312
{
 
313
    mdContext->i[0] = mdContext->i[1] = (UINT4)0;
 
314
 
 
315
    /* Load magic initialization constants.
 
316
    */
 
317
    mdContext->buf[0] = (UINT4)0x67452301;
 
318
    mdContext->buf[1] = (UINT4)0xefcdab89;
 
319
    mdContext->buf[2] = (UINT4)0x98badcfe;
 
320
    mdContext->buf[3] = (UINT4)0x10325476;
 
321
}
 
322
 
 
323
/* MD5 block update operation. Continues an MD5 message-digest
 
324
  operation, processing another message block, and updating the
 
325
  context.
 
326
 */
 
327
void MD5Update (MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen)
 
328
{
 
329
    UINT4 in[16];
 
330
    int mdi;
 
331
    unsigned int i, ii;
 
332
 
 
333
    if( inLen <= 0 )
 
334
        return;
 
335
 
 
336
    /* compute number of bytes mod 64 */
 
337
    mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
 
338
 
 
339
    /* update number of bits */
 
340
    if ((mdContext->i[0] + ((UINT4)inLen << 3)) < mdContext->i[0])
 
341
        mdContext->i[1]++;
 
342
    mdContext->i[0] += ((UINT4)inLen << 3);
 
343
    mdContext->i[1] += ((UINT4)inLen >> 29);
 
344
 
 
345
    while (inLen--) {
 
346
        /* add new character to buffer, increment mdi */
 
347
        mdContext->in[mdi++] = *inBuf++;
 
348
 
 
349
        /* transform if necessary */
 
350
        if (mdi == 0x40) {
 
351
            for (i = 0, ii = 0; i < 16; i++, ii += 4)
 
352
                in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
 
353
                (((UINT4)mdContext->in[ii+2]) << 16) |
 
354
                (((UINT4)mdContext->in[ii+1]) << 8) |
 
355
                ((UINT4)mdContext->in[ii]);
 
356
            Transform (mdContext->buf, in);
 
357
            mdi = 0;
 
358
        }
 
359
    }
 
360
}
 
361
 
 
362
void MD5Final (MD5_CTX *mdContext)
 
363
{
 
364
    UINT4 in[16];
 
365
    int mdi;
 
366
    unsigned int i, ii;
 
367
    unsigned int padLen;
 
368
 
 
369
    /* save number of bits */
 
370
    in[14] = mdContext->i[0];
 
371
    in[15] = mdContext->i[1];
 
372
 
 
373
    /* compute number of bytes mod 64 */
 
374
    mdi = (int)((mdContext->i[0] >> 3) & 0x3F);
 
375
 
 
376
    /* pad out to 56 mod 64 */
 
377
    padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi);
 
378
    MD5Update (mdContext, PADDING, padLen);
 
379
 
 
380
    /* append length in bits and transform */
 
381
    for (i = 0, ii = 0; i < 14; i++, ii += 4)
 
382
        in[i] = (((UINT4)mdContext->in[ii+3]) << 24) |
 
383
        (((UINT4)mdContext->in[ii+2]) << 16) |
 
384
        (((UINT4)mdContext->in[ii+1]) << 8) |
 
385
        ((UINT4)mdContext->in[ii]);
 
386
    Transform (mdContext->buf, in);
 
387
 
 
388
    /* store buffer in digest */
 
389
    for (i = 0, ii = 0; i < 4; i++, ii += 4) {
 
390
        mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF);
 
391
        mdContext->digest[ii+1] =
 
392
            (unsigned char)((mdContext->buf[i] >> 8) & 0xFF);
 
393
        mdContext->digest[ii+2] =
 
394
            (unsigned char)((mdContext->buf[i] >> 16) & 0xFF);
 
395
        mdContext->digest[ii+3] =
 
396
            (unsigned char)((mdContext->buf[i] >> 24) & 0xFF);
 
397
    }
 
398
}
 
399
 
 
400
/* Basic MD5 step. Transform buf based on in.
 
401
*/
 
402
static void Transform (UINT4 *buf, UINT4 *in)
 
403
{
 
404
    UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
 
405
 
 
406
    /* Round 1 */
 
407
#define S11 7
 
408
#define S12 12
 
409
#define S13 17
 
410
#define S14 22
 
411
    FF ( a, b, c, d, in[ 0], S11, 3614090360UL); /* 1 */
 
412
    FF ( d, a, b, c, in[ 1], S12, 3905402710UL); /* 2 */
 
413
    FF ( c, d, a, b, in[ 2], S13,  606105819UL); /* 3 */
 
414
    FF ( b, c, d, a, in[ 3], S14, 3250441966UL); /* 4 */
 
415
    FF ( a, b, c, d, in[ 4], S11, 4118548399UL); /* 5 */
 
416
    FF ( d, a, b, c, in[ 5], S12, 1200080426UL); /* 6 */
 
417
    FF ( c, d, a, b, in[ 6], S13, 2821735955UL); /* 7 */
 
418
    FF ( b, c, d, a, in[ 7], S14, 4249261313UL); /* 8 */
 
419
    FF ( a, b, c, d, in[ 8], S11, 1770035416UL); /* 9 */
 
420
    FF ( d, a, b, c, in[ 9], S12, 2336552879UL); /* 10 */
 
421
    FF ( c, d, a, b, in[10], S13, 4294925233UL); /* 11 */
 
422
    FF ( b, c, d, a, in[11], S14, 2304563134UL); /* 12 */
 
423
    FF ( a, b, c, d, in[12], S11, 1804603682UL); /* 13 */
 
424
    FF ( d, a, b, c, in[13], S12, 4254626195UL); /* 14 */
 
425
    FF ( c, d, a, b, in[14], S13, 2792965006UL); /* 15 */
 
426
    FF ( b, c, d, a, in[15], S14, 1236535329UL); /* 16 */
 
427
 
 
428
    /* Round 2 */
 
429
#define S21 5
 
430
#define S22 9
 
431
#define S23 14
 
432
#define S24 20
 
433
    GG ( a, b, c, d, in[ 1], S21, 4129170786UL); /* 17 */
 
434
    GG ( d, a, b, c, in[ 6], S22, 3225465664UL); /* 18 */
 
435
    GG ( c, d, a, b, in[11], S23,  643717713UL); /* 19 */
 
436
    GG ( b, c, d, a, in[ 0], S24, 3921069994UL); /* 20 */
 
437
    GG ( a, b, c, d, in[ 5], S21, 3593408605UL); /* 21 */
 
438
    GG ( d, a, b, c, in[10], S22,   38016083UL); /* 22 */
 
439
    GG ( c, d, a, b, in[15], S23, 3634488961UL); /* 23 */
 
440
    GG ( b, c, d, a, in[ 4], S24, 3889429448UL); /* 24 */
 
441
    GG ( a, b, c, d, in[ 9], S21,  568446438UL); /* 25 */
 
442
    GG ( d, a, b, c, in[14], S22, 3275163606UL); /* 26 */
 
443
    GG ( c, d, a, b, in[ 3], S23, 4107603335UL); /* 27 */
 
444
    GG ( b, c, d, a, in[ 8], S24, 1163531501UL); /* 28 */
 
445
    GG ( a, b, c, d, in[13], S21, 2850285829UL); /* 29 */
 
446
    GG ( d, a, b, c, in[ 2], S22, 4243563512UL); /* 30 */
 
447
    GG ( c, d, a, b, in[ 7], S23, 1735328473UL); /* 31 */
 
448
    GG ( b, c, d, a, in[12], S24, 2368359562UL); /* 32 */
 
449
 
 
450
    /* Round 3 */
 
451
#define S31 4
 
452
#define S32 11
 
453
#define S33 16
 
454
#define S34 23
 
455
    HH ( a, b, c, d, in[ 5], S31, 4294588738UL); /* 33 */
 
456
    HH ( d, a, b, c, in[ 8], S32, 2272392833UL); /* 34 */
 
457
    HH ( c, d, a, b, in[11], S33, 1839030562UL); /* 35 */
 
458
    HH ( b, c, d, a, in[14], S34, 4259657740UL); /* 36 */
 
459
    HH ( a, b, c, d, in[ 1], S31, 2763975236UL); /* 37 */
 
460
    HH ( d, a, b, c, in[ 4], S32, 1272893353UL); /* 38 */
 
461
    HH ( c, d, a, b, in[ 7], S33, 4139469664UL); /* 39 */
 
462
    HH ( b, c, d, a, in[10], S34, 3200236656UL); /* 40 */
 
463
    HH ( a, b, c, d, in[13], S31,  681279174UL); /* 41 */
 
464
    HH ( d, a, b, c, in[ 0], S32, 3936430074UL); /* 42 */
 
465
    HH ( c, d, a, b, in[ 3], S33, 3572445317UL); /* 43 */
 
466
    HH ( b, c, d, a, in[ 6], S34,   76029189UL); /* 44 */
 
467
    HH ( a, b, c, d, in[ 9], S31, 3654602809UL); /* 45 */
 
468
    HH ( d, a, b, c, in[12], S32, 3873151461UL); /* 46 */
 
469
    HH ( c, d, a, b, in[15], S33,  530742520UL); /* 47 */
 
470
    HH ( b, c, d, a, in[ 2], S34, 3299628645UL); /* 48 */
 
471
 
 
472
    /* Round 4 */
 
473
#define S41 6
 
474
#define S42 10
 
475
#define S43 15
 
476
#define S44 21
 
477
    II ( a, b, c, d, in[ 0], S41, 4096336452UL); /* 49 */
 
478
    II ( d, a, b, c, in[ 7], S42, 1126891415UL); /* 50 */
 
479
    II ( c, d, a, b, in[14], S43, 2878612391UL); /* 51 */
 
480
    II ( b, c, d, a, in[ 5], S44, 4237533241UL); /* 52 */
 
481
    II ( a, b, c, d, in[12], S41, 1700485571UL); /* 53 */
 
482
    II ( d, a, b, c, in[ 3], S42, 2399980690UL); /* 54 */
 
483
    II ( c, d, a, b, in[10], S43, 4293915773UL); /* 55 */
 
484
    II ( b, c, d, a, in[ 1], S44, 2240044497UL); /* 56 */
 
485
    II ( a, b, c, d, in[ 8], S41, 1873313359UL); /* 57 */
 
486
    II ( d, a, b, c, in[15], S42, 4264355552UL); /* 58 */
 
487
    II ( c, d, a, b, in[ 6], S43, 2734768916UL); /* 59 */
 
488
    II ( b, c, d, a, in[13], S44, 1309151649UL); /* 60 */
 
489
    II ( a, b, c, d, in[ 4], S41, 4149444226UL); /* 61 */
 
490
    II ( d, a, b, c, in[11], S42, 3174756917UL); /* 62 */
 
491
    II ( c, d, a, b, in[ 2], S43,  718787259UL); /* 63 */
 
492
    II ( b, c, d, a, in[ 9], S44, 3951481745UL); /* 64 */
 
493
 
 
494
    buf[0] += a;
 
495
    buf[1] += b;
 
496
    buf[2] += c;
 
497
    buf[3] += d;
 
498
}
 
499
 
 
500
NAMESPACE_END
 
501
 
 
502
/*
 
503
**********************************************************************
 
504
** End of md5.c                                                     **
 
505
******************************* (cut) ********************************
 
506
*/
 
507
 
 
508
// 
 
509
// 
 
510
// /*
 
511
// **********************************************************************
 
512
// ** md5driver.c -- sample routines to test                           **
 
513
// ** RSA Data Security, Inc. MD5 message digest algorithm.            **
 
514
// ** Created: 2/16/90 RLR                                             **
 
515
// ** Updated: 1/91 SRD                                                **
 
516
// **********************************************************************
 
517
// */
 
518
// 
 
519
// /*
 
520
// **********************************************************************
 
521
// ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. **
 
522
// **                                                                  **
 
523
// ** RSA Data Security, Inc. makes no representations concerning      **
 
524
// ** either the merchantability of this software or the suitability   **
 
525
// ** of this software for any particular purpose.  It is provided "as **
 
526
// ** is" without express or implied warranty of any kind.             **
 
527
// **                                                                  **
 
528
// ** These notices must be retained in any copies of any part of this **
 
529
// ** documentation and/or software.                                   **
 
530
// **********************************************************************
 
531
// */
 
532
// 
 
533
// #include <stdio.h>
 
534
// #include <sys/types.h>
 
535
// #include <time.h>
 
536
// #include <string.h>
 
537
// /* -- include the following file if the file md5.h is separate -- */
 
538
// /* #include "md5.h" */
 
539
// 
 
540
// /* Prints message digest buffer in mdContext as 32 hexadecimal digits.
 
541
// Order is from low-order byte to high-order byte of digest.
 
542
// Each byte is printed with high-order hexadecimal digit first.
 
543
// */
 
544
// static void MDPrint (mdContext)
 
545
// MD5_CTX *mdContext;
 
546
// {
 
547
//     int i;
 
548
// 
 
549
//     for (i = 0; i < 16; i++)
 
550
//         printf ("%02x", mdContext->digest[i]);
 
551
// }
 
552
// 
 
553
// /* size of test block */
 
554
// #define TEST_BLOCK_SIZE 1000
 
555
// 
 
556
// /* number of blocks to process */
 
557
// #define TEST_BLOCKS 10000
 
558
// 
 
559
// /* number of test bytes = TEST_BLOCK_SIZE * TEST_BLOCKS */
 
560
// static long TEST_BYTES = (long)TEST_BLOCK_SIZE * (long)TEST_BLOCKS;
 
561
// 
 
562
// /* A time trial routine, to measure the speed of MD5.
 
563
// Measures wall time required to digest TEST_BLOCKS * TEST_BLOCK_SIZE
 
564
// characters.
 
565
// */
 
566
// static void MDTimeTrial ()
 
567
// {
 
568
//     MD5_CTX mdContext;
 
569
//     time_t endTime, startTime;
 
570
//     unsigned char data[TEST_BLOCK_SIZE];
 
571
//     unsigned int i;
 
572
// 
 
573
//     /* initialize test data */
 
574
//     for (i = 0; i < TEST_BLOCK_SIZE; i++)
 
575
//         data[i] = (unsigned char)(i & 0xFF);
 
576
// 
 
577
//     /* start timer */
 
578
//     printf ("MD5 time trial. Processing %ld characters...\n", TEST_BYTES);
 
579
//     time (&startTime);
 
580
// 
 
581
//     /* digest data in TEST_BLOCK_SIZE byte blocks */
 
582
//     MD5Init (&mdContext);
 
583
//     for (i = TEST_BLOCKS; i > 0; i--)
 
584
//         MD5Update (&mdContext, data, TEST_BLOCK_SIZE);
 
585
//     MD5Final (&mdContext);
 
586
// 
 
587
//     /* stop timer, get time difference */
 
588
//     time (&endTime);
 
589
//     MDPrint (&mdContext);
 
590
//     printf (" is digest of test input.\n");
 
591
//     printf
 
592
//         ("Seconds to process test input: %ld\n", (long)(endTime-startTime));
 
593
//     printf
 
594
//         ("Characters processed per second: %ld\n",
 
595
//         TEST_BYTES/(endTime-startTime));
 
596
// }
 
597
// 
 
598
// /* Computes the message digest for string inString.
 
599
// Prints out message digest, a space, the string (in quotes) and a
 
600
// carriage return.
 
601
// */
 
602
// static void MDString (inString)
 
603
// char *inString;
 
604
// {
 
605
//     MD5_CTX mdContext;
 
606
//     unsigned int len = strlen (inString);
 
607
// 
 
608
//     MD5Init (&mdContext);
 
609
//     MD5Update (&mdContext, inString, len);
 
610
//     MD5Final (&mdContext);
 
611
//     MDPrint (&mdContext);
 
612
//     printf (" \"%s\"\n\n", inString);
 
613
// }
 
614
// 
 
615
// /* Computes the message digest for a specified file.
 
616
// Prints out message digest, a space, the file name, and a carriage
 
617
// return.
 
618
// */
 
619
// static void MDFile (filename)
 
620
// char *filename;
 
621
// {
 
622
//     FILE *inFile = fopen (filename, "rb");
 
623
//     MD5_CTX mdContext;
 
624
//     int bytes;
 
625
//     unsigned char data[1024];
 
626
// 
 
627
//     if (inFile == NULL) {
 
628
//         printf ("%s can't be opened.\n", filename);
 
629
//         return;
 
630
//     }
 
631
// 
 
632
//     MD5Init (&mdContext);
 
633
//     while ((bytes = fread (data, 1, 1024, inFile)) != 0)
 
634
//         MD5Update (&mdContext, data, bytes);
 
635
//     MD5Final (&mdContext);
 
636
//     MDPrint (&mdContext);
 
637
//     printf (" %s\n", filename);
 
638
//     fclose (inFile);
 
639
// }
 
640
// 
 
641
// /* Writes the message digest of the data from stdin onto stdout,
 
642
// followed by a carriage return.
 
643
// */
 
644
// static void MDFilter ()
 
645
// {
 
646
//     MD5_CTX mdContext;
 
647
//     int bytes;
 
648
//     unsigned char data[16];
 
649
// 
 
650
//     MD5Init (&mdContext);
 
651
//     while ((bytes = fread (data, 1, 16, stdin)) != 0)
 
652
//         MD5Update (&mdContext, data, bytes);
 
653
//     MD5Final (&mdContext);
 
654
//     MDPrint (&mdContext);
 
655
//     printf ("\n");
 
656
// }
 
657
// 
 
658
// /* Runs a standard suite of test data.
 
659
// */
 
660
// static void MDTestSuite ()
 
661
// {
 
662
//     printf ("MD5 test suite results:\n\n");
 
663
//     MDString ("");
 
664
//     MDString ("a");
 
665
//     MDString ("abc");
 
666
//     MDString ("message digest");
 
667
//     MDString ("abcdefghijklmnopqrstuvwxyz");
 
668
//     MDString
 
669
//         ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
 
670
//     MDString
 
671
//         ("1234567890123456789012345678901234567890\
 
672
//          1234567890123456789012345678901234567890");
 
673
//     /* Contents of file foo are "abc" */
 
674
//     MDFile ("foo");
 
675
// }
 
676
// 
 
677
// void main (argc, argv)
 
678
// int argc;
 
679
// char *argv[];
 
680
// {
 
681
//     int i;
 
682
// 
 
683
//     /* For each command line argument in turn:
 
684
//     ** filename          -- prints message digest and name of file
 
685
//     ** -sstring          -- prints message digest and contents of string
 
686
//     ** -t                -- prints time trial statistics for 1M characters
 
687
//     ** -x                -- execute a standard suite of test data
 
688
//     ** (no args)         -- writes messages digest of stdin onto stdout
 
689
//     */
 
690
//     if (argc == 1)
 
691
//         MDFilter ();
 
692
//     else
 
693
//         for (i = 1; i < argc; i++)
 
694
//             if (argv[i][0] == '-' && argv[i][1] == 's')
 
695
//                 MDString (argv[i] + 2);
 
696
//             else if (strcmp (argv[i], "-t") == 0)
 
697
//                 MDTimeTrial ();
 
698
//             else if (strcmp (argv[i], "-x") == 0)
 
699
//                 MDTestSuite ();
 
700
//             else MDFile (argv[i]);
 
701
// }
 
702
// 
 
703
// /*
 
704
// **********************************************************************
 
705
// ** End of md5driver.c                                               **
 
706
// ******************************* (cut) ********************************
 
707
// */