]> git.sesse.net Git - freerainbowtables/blob - Common/rt api/md5.cpp
initial
[freerainbowtables] / Common / rt api / md5.cpp
1 /*
2  * This code implements the MD5 message-digest algorithm.
3  * The algorithm is due to Ron Rivest.  This code was
4  * written by Colin Plumb in 1993, no copyright is claimed.
5  * This code is in the public domain; do with it what you wish.
6  *
7  * Equivalent code is available from RSA Data Security, Inc.
8  * This code has been tested against that, and is equivalent,
9  * except that you don't need to include two pages of legalese
10  * with every copy.
11  *
12  * To compute the message digest of a chunk of bytes, declare an
13  * MD5Context structure, pass it to MD5Init, call MD5Update as
14  * needed on buffers full of bytes, and then call MD5Final, which
15  * will fill a supplied 16-byte array with the digest.
16  */
17
18 /* Brutally hacked by John Walker back from ANSI C to K&R (no
19    prototypes) to maintain the tradition that Netfone will compile
20    with Sun's original "cc". */
21
22 /*
23         Brutally modified by daVajj, optimized for lengths of 1 - 10.
24         Generic version used for longer indata
25 */
26
27 #include <cstdlib>
28 #include <cstring>
29 #include "md5.h"
30
31 /* The four core functions - F1 is optimized somewhat */
32 /* #define F1(x, y, z) (x & y | ~x & z) */
33 #define F1(x, y, z) (z ^ (x & (y ^ z)))
34 #define F2(x, y, z) F1(z, x, y)
35 #define F3(x, y, z) (x ^ y ^ z)
36 #define F4(x, y, z) (y ^ (x | ~z))
37
38 //Here's two different ways to do a left bitwise rotation. I've seen no major speed differences between them.
39 //#define ROL(x, n) ( _lrotl(x, n) ) //This also requires #include <windows.h>
40 #define ROL(x,n) ( x << n | x >>(32-n) )
41
42 /* This is the central step in the MD5 algorithm. */
43 #define MD5STEP(f, w, x, y, z, data, s) \
44         ( w += f(x, y, z) + data,  w = ROL(w,s) + x )
45         
46 void MD5_NEW( unsigned char * pData, int len, unsigned char * pDigest)
47 {
48         //Use optimized versions if available
49         switch( len )
50         {
51                 case 1:
52                 {
53                         //Main variables
54                         unsigned char in[4];
55                         
56                         memcpy(in, pData, 1);
57                         in[1] = 0x80;
58                         memset(in + 2, 0, 2);
59
60                         //START OF MD5TRANSFORM CODE
61                         //====================================================
62                         register uint32 a, b, c, d;
63                         uint32 * pUiIn = (uint32 *) in;
64
65                         a = 0x67452301;
66                         b = 0xefcdab89;
67                         c = 0x98badcfe;
68                         d = 0x10325476;
69
70                         MD5STEP(F1, a, b, c, d, pUiIn[0] + 0xd76aa478, 7);
71                         MD5STEP(F1, d, a, b, c, 0xe8c7b756, 12);
72                         MD5STEP(F1, c, d, a, b, 0x242070db, 17);
73                         MD5STEP(F1, b, c, d, a, 0xc1bdceee, 22);
74                         MD5STEP(F1, a, b, c, d, 0xf57c0faf, 7);
75                         MD5STEP(F1, d, a, b, c, 0x4787c62a, 12);
76                         MD5STEP(F1, c, d, a, b, 0xa8304613, 17);
77                         MD5STEP(F1, b, c, d, a, 0xfd469501, 22);
78                         MD5STEP(F1, a, b, c, d, 0x698098d8, 7);
79                         MD5STEP(F1, d, a, b, c, 0x8b44f7af, 12);
80                         MD5STEP(F1, c, d, a, b, 0xffff5bb1, 17);
81                         MD5STEP(F1, b, c, d, a, 0x895cd7be, 22);
82                         MD5STEP(F1, a, b, c, d, 0x6b901122, 7);
83                         MD5STEP(F1, d, a, b, c, 0xfd987193, 12);
84                         MD5STEP(F1, c, d, a, b, 8 + 0xa679438e, 17);
85                         MD5STEP(F1, b, c, d, a, 0x49b40821, 22);
86
87                         MD5STEP(F2, a, b, c, d, 0xf61e2562, 5);
88                         MD5STEP(F2, d, a, b, c, 0xc040b340, 9);
89                         MD5STEP(F2, c, d, a, b, 0x265e5a51, 14);
90                         MD5STEP(F2, b, c, d, a, pUiIn[0] + 0xe9b6c7aa, 20);
91                         MD5STEP(F2, a, b, c, d, 0xd62f105d, 5);
92                         MD5STEP(F2, d, a, b, c, 0x02441453, 9);
93                         MD5STEP(F2, c, d, a, b, 0xd8a1e681, 14);
94                         MD5STEP(F2, b, c, d, a, 0xe7d3fbc8, 20);
95                         MD5STEP(F2, a, b, c, d, 0x21e1cde6, 5);
96                         MD5STEP(F2, d, a, b, c, 8 + 0xc33707d6, 9);
97                         MD5STEP(F2, c, d, a, b, 0xf4d50d87, 14);
98                         MD5STEP(F2, b, c, d, a, 0x455a14ed, 20);
99                         MD5STEP(F2, a, b, c, d, 0xa9e3e905, 5);
100                         MD5STEP(F2, d, a, b, c, 0xfcefa3f8, 9);
101                         MD5STEP(F2, c, d, a, b, 0x676f02d9, 14);
102                         MD5STEP(F2, b, c, d, a, 0x8d2a4c8a, 20);
103
104                         MD5STEP(F3, a, b, c, d, 0xfffa3942, 4);
105                         MD5STEP(F3, d, a, b, c, 0x8771f681, 11);
106                         MD5STEP(F3, c, d, a, b, 0x6d9d6122, 16);
107                         MD5STEP(F3, b, c, d, a, 8 + 0xfde5380c, 23);
108                         MD5STEP(F3, a, b, c, d, 0xa4beea44, 4);
109                         MD5STEP(F3, d, a, b, c, 0x4bdecfa9, 11);
110                         MD5STEP(F3, c, d, a, b, 0xf6bb4b60, 16);
111                         MD5STEP(F3, b, c, d, a, 0xbebfbc70, 23);
112                         MD5STEP(F3, a, b, c, d, 0x289b7ec6, 4);
113                         MD5STEP(F3, d, a, b, c, pUiIn[0] + 0xeaa127fa, 11);
114                         MD5STEP(F3, c, d, a, b, 0xd4ef3085, 16);
115                         MD5STEP(F3, b, c, d, a, 0x04881d05, 23);
116                         MD5STEP(F3, a, b, c, d, 0xd9d4d039, 4);
117                         MD5STEP(F3, d, a, b, c, 0xe6db99e5, 11);
118                         MD5STEP(F3, c, d, a, b, 0x1fa27cf8, 16);
119                         MD5STEP(F3, b, c, d, a, 0xc4ac5665, 23);
120
121                         MD5STEP(F4, a, b, c, d, pUiIn[0] + 0xf4292244, 6);
122                         MD5STEP(F4, d, a, b, c, 0x432aff97, 10);
123                         MD5STEP(F4, c, d, a, b, 8 + 0xab9423a7, 15);
124                         MD5STEP(F4, b, c, d, a, 0xfc93a039, 21);
125                         MD5STEP(F4, a, b, c, d, 0x655b59c3, 6);
126                         MD5STEP(F4, d, a, b, c, 0x8f0ccc92, 10);
127                         MD5STEP(F4, c, d, a, b, 0xffeff47d, 15);
128                         MD5STEP(F4, b, c, d, a, 0x85845dd1, 21);
129                         MD5STEP(F4, a, b, c, d, 0x6fa87e4f, 6);
130                         MD5STEP(F4, d, a, b, c, 0xfe2ce6e0, 10);
131                         MD5STEP(F4, c, d, a, b, 0xa3014314, 15);
132                         MD5STEP(F4, b, c, d, a, 0x4e0811a1, 21);
133                         MD5STEP(F4, a, b, c, d, 0xf7537e82, 6);
134                         MD5STEP(F4, d, a, b, c, 0xbd3af235, 10);
135                         MD5STEP(F4, c, d, a, b, 0x2ad7d2bb, 15);
136                         MD5STEP(F4, b, c, d, a, 0xeb86d391, 21);
137
138                         uint32 buf[4] = { 0x67452301 + a, 0xefcdab89 + b, 0x98badcfe + c, 0x10325476 + d };
139                         memcpy(pDigest, buf, 16);
140                         return;
141                 }
142                 break;
143
144                 case 2:
145                 {
146                         //Main variables
147                         unsigned char in[4];
148                         
149                         memcpy(in, pData, 2);
150                         in[2] = 0x80;
151                         memset(in + 3, 0, 1);
152
153                         //START OF MD5TRANSFORM CODE
154                         //====================================================
155                         register uint32 a, b, c, d;
156                         uint32 * pUiIn = (uint32 *) in;
157
158                         a = 0x67452301;
159                         b = 0xefcdab89;
160                         c = 0x98badcfe;
161                         d = 0x10325476;
162
163                         MD5STEP(F1, a, b, c, d, pUiIn[0] + 0xd76aa478, 7);
164                         MD5STEP(F1, d, a, b, c, 0xe8c7b756, 12);
165                         MD5STEP(F1, c, d, a, b, 0x242070db, 17);
166                         MD5STEP(F1, b, c, d, a, 0xc1bdceee, 22);
167                         MD5STEP(F1, a, b, c, d, 0xf57c0faf, 7);
168                         MD5STEP(F1, d, a, b, c, 0x4787c62a, 12);
169                         MD5STEP(F1, c, d, a, b, 0xa8304613, 17);
170                         MD5STEP(F1, b, c, d, a, 0xfd469501, 22);
171                         MD5STEP(F1, a, b, c, d, 0x698098d8, 7);
172                         MD5STEP(F1, d, a, b, c, 0x8b44f7af, 12);
173                         MD5STEP(F1, c, d, a, b, 0xffff5bb1, 17);
174                         MD5STEP(F1, b, c, d, a, 0x895cd7be, 22);
175                         MD5STEP(F1, a, b, c, d, 0x6b901122, 7);
176                         MD5STEP(F1, d, a, b, c, 0xfd987193, 12);
177                         MD5STEP(F1, c, d, a, b, 16 + 0xa679438e, 17);
178                         MD5STEP(F1, b, c, d, a, 0x49b40821, 22);
179
180                         MD5STEP(F2, a, b, c, d, 0xf61e2562, 5);
181                         MD5STEP(F2, d, a, b, c, 0xc040b340, 9);
182                         MD5STEP(F2, c, d, a, b, 0x265e5a51, 14);
183                         MD5STEP(F2, b, c, d, a, pUiIn[0] + 0xe9b6c7aa, 20);
184                         MD5STEP(F2, a, b, c, d, 0xd62f105d, 5);
185                         MD5STEP(F2, d, a, b, c, 0x02441453, 9);
186                         MD5STEP(F2, c, d, a, b, 0xd8a1e681, 14);
187                         MD5STEP(F2, b, c, d, a, 0xe7d3fbc8, 20);
188                         MD5STEP(F2, a, b, c, d, 0x21e1cde6, 5);
189                         MD5STEP(F2, d, a, b, c, 16 + 0xc33707d6, 9);
190                         MD5STEP(F2, c, d, a, b, 0xf4d50d87, 14);
191                         MD5STEP(F2, b, c, d, a, 0x455a14ed, 20);
192                         MD5STEP(F2, a, b, c, d, 0xa9e3e905, 5);
193                         MD5STEP(F2, d, a, b, c, 0xfcefa3f8, 9);
194                         MD5STEP(F2, c, d, a, b, 0x676f02d9, 14);
195                         MD5STEP(F2, b, c, d, a, 0x8d2a4c8a, 20);
196
197                         MD5STEP(F3, a, b, c, d, 0xfffa3942, 4);
198                         MD5STEP(F3, d, a, b, c, 0x8771f681, 11);
199                         MD5STEP(F3, c, d, a, b, 0x6d9d6122, 16);
200                         MD5STEP(F3, b, c, d, a, 16 + 0xfde5380c, 23);
201                         MD5STEP(F3, a, b, c, d, 0xa4beea44, 4);
202                         MD5STEP(F3, d, a, b, c, 0x4bdecfa9, 11);
203                         MD5STEP(F3, c, d, a, b, 0xf6bb4b60, 16);
204                         MD5STEP(F3, b, c, d, a, 0xbebfbc70, 23);
205                         MD5STEP(F3, a, b, c, d, 0x289b7ec6, 4);
206                         MD5STEP(F3, d, a, b, c, pUiIn[0] + 0xeaa127fa, 11);
207                         MD5STEP(F3, c, d, a, b, 0xd4ef3085, 16);
208                         MD5STEP(F3, b, c, d, a, 0x04881d05, 23);
209                         MD5STEP(F3, a, b, c, d, 0xd9d4d039, 4);
210                         MD5STEP(F3, d, a, b, c, 0xe6db99e5, 11);
211                         MD5STEP(F3, c, d, a, b, 0x1fa27cf8, 16);
212                         MD5STEP(F3, b, c, d, a, 0xc4ac5665, 23);
213
214                         MD5STEP(F4, a, b, c, d, pUiIn[0] + 0xf4292244, 6);
215                         MD5STEP(F4, d, a, b, c, 0x432aff97, 10);
216                         MD5STEP(F4, c, d, a, b, 16 + 0xab9423a7, 15);
217                         MD5STEP(F4, b, c, d, a, 0xfc93a039, 21);
218                         MD5STEP(F4, a, b, c, d, 0x655b59c3, 6);
219                         MD5STEP(F4, d, a, b, c, 0x8f0ccc92, 10);
220                         MD5STEP(F4, c, d, a, b, 0xffeff47d, 15);
221                         MD5STEP(F4, b, c, d, a, 0x85845dd1, 21);
222                         MD5STEP(F4, a, b, c, d, 0x6fa87e4f, 6);
223                         MD5STEP(F4, d, a, b, c, 0xfe2ce6e0, 10);
224                         MD5STEP(F4, c, d, a, b, 0xa3014314, 15);
225                         MD5STEP(F4, b, c, d, a, 0x4e0811a1, 21);
226                         MD5STEP(F4, a, b, c, d, 0xf7537e82, 6);
227                         MD5STEP(F4, d, a, b, c, 0xbd3af235, 10);
228                         MD5STEP(F4, c, d, a, b, 0x2ad7d2bb, 15);
229                         MD5STEP(F4, b, c, d, a, 0xeb86d391, 21);
230                         uint32 buf[4] = { 0x67452301 + a, 0xefcdab89 + b, 0x98badcfe + c, 0x10325476 + d };
231                         memcpy(pDigest, buf, 16);
232                         return;
233                 }
234                 break;
235
236                 case 3:
237                 {
238                         //Main variables
239                         unsigned char in[4];
240                         
241                         memcpy(in, pData, 3);
242                         in[3] = 0x80;
243
244                         //START OF MD5TRANSFORM CODE
245                         //====================================================
246                         register uint32 a, b, c, d;
247                         uint32 * pUiIn = (uint32 *) in;
248
249                         a = 0x67452301;
250                         b = 0xefcdab89;
251                         c = 0x98badcfe;
252                         d = 0x10325476;
253
254                         MD5STEP(F1, a, b, c, d, pUiIn[0] + 0xd76aa478, 7);
255                         MD5STEP(F1, d, a, b, c, 0xe8c7b756, 12);
256                         MD5STEP(F1, c, d, a, b, 0x242070db, 17);
257                         MD5STEP(F1, b, c, d, a, 0xc1bdceee, 22);
258                         MD5STEP(F1, a, b, c, d, 0xf57c0faf, 7);
259                         MD5STEP(F1, d, a, b, c, 0x4787c62a, 12);
260                         MD5STEP(F1, c, d, a, b, 0xa8304613, 17);
261                         MD5STEP(F1, b, c, d, a, 0xfd469501, 22);
262                         MD5STEP(F1, a, b, c, d, 0x698098d8, 7);
263                         MD5STEP(F1, d, a, b, c, 0x8b44f7af, 12);
264                         MD5STEP(F1, c, d, a, b, 0xffff5bb1, 17);
265                         MD5STEP(F1, b, c, d, a, 0x895cd7be, 22);
266                         MD5STEP(F1, a, b, c, d, 0x6b901122, 7);
267                         MD5STEP(F1, d, a, b, c, 0xfd987193, 12);
268                         MD5STEP(F1, c, d, a, b, 24 + 0xa679438e, 17);
269                         MD5STEP(F1, b, c, d, a, 0x49b40821, 22);
270
271                         MD5STEP(F2, a, b, c, d, 0xf61e2562, 5);
272                         MD5STEP(F2, d, a, b, c, 0xc040b340, 9);
273                         MD5STEP(F2, c, d, a, b, 0x265e5a51, 14);
274                         MD5STEP(F2, b, c, d, a, pUiIn[0] + 0xe9b6c7aa, 20);
275                         MD5STEP(F2, a, b, c, d, 0xd62f105d, 5);
276                         MD5STEP(F2, d, a, b, c, 0x02441453, 9);
277                         MD5STEP(F2, c, d, a, b, 0xd8a1e681, 14);
278                         MD5STEP(F2, b, c, d, a, 0xe7d3fbc8, 20);
279                         MD5STEP(F2, a, b, c, d, 0x21e1cde6, 5);
280                         MD5STEP(F2, d, a, b, c, 24 + 0xc33707d6, 9);
281                         MD5STEP(F2, c, d, a, b, 0xf4d50d87, 14);
282                         MD5STEP(F2, b, c, d, a, 0x455a14ed, 20);
283                         MD5STEP(F2, a, b, c, d, 0xa9e3e905, 5);
284                         MD5STEP(F2, d, a, b, c, 0xfcefa3f8, 9);
285                         MD5STEP(F2, c, d, a, b, 0x676f02d9, 14);
286                         MD5STEP(F2, b, c, d, a, 0x8d2a4c8a, 20);
287
288                         MD5STEP(F3, a, b, c, d, 0xfffa3942, 4);
289                         MD5STEP(F3, d, a, b, c, 0x8771f681, 11);
290                         MD5STEP(F3, c, d, a, b, 0x6d9d6122, 16);
291                         MD5STEP(F3, b, c, d, a, 24 + 0xfde5380c, 23);
292                         MD5STEP(F3, a, b, c, d, 0xa4beea44, 4);
293                         MD5STEP(F3, d, a, b, c, 0x4bdecfa9, 11);
294                         MD5STEP(F3, c, d, a, b, 0xf6bb4b60, 16);
295                         MD5STEP(F3, b, c, d, a, 0xbebfbc70, 23);
296                         MD5STEP(F3, a, b, c, d, 0x289b7ec6, 4);
297                         MD5STEP(F3, d, a, b, c, pUiIn[0] + 0xeaa127fa, 11);
298                         MD5STEP(F3, c, d, a, b, 0xd4ef3085, 16);
299                         MD5STEP(F3, b, c, d, a, 0x04881d05, 23);
300                         MD5STEP(F3, a, b, c, d, 0xd9d4d039, 4);
301                         MD5STEP(F3, d, a, b, c, 0xe6db99e5, 11);
302                         MD5STEP(F3, c, d, a, b, 0x1fa27cf8, 16);
303                         MD5STEP(F3, b, c, d, a, 0xc4ac5665, 23);
304
305                         MD5STEP(F4, a, b, c, d, pUiIn[0] + 0xf4292244, 6);
306                         MD5STEP(F4, d, a, b, c, 0x432aff97, 10);
307                         MD5STEP(F4, c, d, a, b, 24 + 0xab9423a7, 15);
308                         MD5STEP(F4, b, c, d, a, 0xfc93a039, 21);
309                         MD5STEP(F4, a, b, c, d, 0x655b59c3, 6);
310                         MD5STEP(F4, d, a, b, c, 0x8f0ccc92, 10);
311                         MD5STEP(F4, c, d, a, b, 0xffeff47d, 15);
312                         MD5STEP(F4, b, c, d, a, 0x85845dd1, 21);
313                         MD5STEP(F4, a, b, c, d, 0x6fa87e4f, 6);
314                         MD5STEP(F4, d, a, b, c, 0xfe2ce6e0, 10);
315                         MD5STEP(F4, c, d, a, b, 0xa3014314, 15);
316                         MD5STEP(F4, b, c, d, a, 0x4e0811a1, 21);
317                         MD5STEP(F4, a, b, c, d, 0xf7537e82, 6);
318                         MD5STEP(F4, d, a, b, c, 0xbd3af235, 10);
319                         MD5STEP(F4, c, d, a, b, 0x2ad7d2bb, 15);
320                         MD5STEP(F4, b, c, d, a, 0xeb86d391, 21);
321                         uint32 buf[4] = { 0x67452301 + a, 0xefcdab89 + b, 0x98badcfe + c, 0x10325476 + d };
322                         memcpy(pDigest, buf, 16);
323                         return;
324                 }
325                 break;
326
327                 case 4:
328                 {
329                         //Main variables
330                         unsigned char in[4];
331                         
332                         memcpy(in, pData, 4);
333                         //in[4] = 0x80; //(uint32 *)in[1] = 128;
334
335                         //START OF MD5TRANSFORM CODE
336                         //====================================================
337                         register uint32 a, b, c, d;
338                         uint32 * pUiIn = (uint32 *) in;
339
340                         a = 0x67452301;
341                         b = 0xefcdab89;
342                         c = 0x98badcfe;
343                         d = 0x10325476;
344
345                         MD5STEP(F1, a, b, c, d, pUiIn[0] + 0xd76aa478, 7);
346                         MD5STEP(F1, d, a, b, c, 128 + 0xe8c7b756, 12);
347                         MD5STEP(F1, c, d, a, b, 0x242070db, 17);
348                         MD5STEP(F1, b, c, d, a, 0xc1bdceee, 22);
349                         MD5STEP(F1, a, b, c, d, 0xf57c0faf, 7);
350                         MD5STEP(F1, d, a, b, c, 0x4787c62a, 12);
351                         MD5STEP(F1, c, d, a, b, 0xa8304613, 17);
352                         MD5STEP(F1, b, c, d, a, 0xfd469501, 22);
353                         MD5STEP(F1, a, b, c, d, 0x698098d8, 7);
354                         MD5STEP(F1, d, a, b, c, 0x8b44f7af, 12);
355                         MD5STEP(F1, c, d, a, b, 0xffff5bb1, 17);
356                         MD5STEP(F1, b, c, d, a, 0x895cd7be, 22);
357                         MD5STEP(F1, a, b, c, d, 0x6b901122, 7);
358                         MD5STEP(F1, d, a, b, c, 0xfd987193, 12);
359                         MD5STEP(F1, c, d, a, b, 32 + 0xa679438e, 17);
360                         MD5STEP(F1, b, c, d, a, 0x49b40821, 22);
361
362                         MD5STEP(F2, a, b, c, d, 128 + 0xf61e2562, 5);
363                         MD5STEP(F2, d, a, b, c, 0xc040b340, 9);
364                         MD5STEP(F2, c, d, a, b, 0x265e5a51, 14);
365                         MD5STEP(F2, b, c, d, a, pUiIn[0] + 0xe9b6c7aa, 20);
366                         MD5STEP(F2, a, b, c, d, 0xd62f105d, 5);
367                         MD5STEP(F2, d, a, b, c, 0x02441453, 9);
368                         MD5STEP(F2, c, d, a, b, 0xd8a1e681, 14);
369                         MD5STEP(F2, b, c, d, a, 0xe7d3fbc8, 20);
370                         MD5STEP(F2, a, b, c, d, 0x21e1cde6, 5);
371                         MD5STEP(F2, d, a, b, c, 32 + 0xc33707d6, 9);
372                         MD5STEP(F2, c, d, a, b, 0xf4d50d87, 14);
373                         MD5STEP(F2, b, c, d, a, 0x455a14ed, 20);
374                         MD5STEP(F2, a, b, c, d, 0xa9e3e905, 5);
375                         MD5STEP(F2, d, a, b, c, 0xfcefa3f8, 9);
376                         MD5STEP(F2, c, d, a, b, 0x676f02d9, 14);
377                         MD5STEP(F2, b, c, d, a, 0x8d2a4c8a, 20);
378
379                         MD5STEP(F3, a, b, c, d, 0xfffa3942, 4);
380                         MD5STEP(F3, d, a, b, c, 0x8771f681, 11);
381                         MD5STEP(F3, c, d, a, b, 0x6d9d6122, 16);
382                         MD5STEP(F3, b, c, d, a, 32 + 0xfde5380c, 23);
383                         MD5STEP(F3, a, b, c, d, 128 + 0xa4beea44, 4);
384                         MD5STEP(F3, d, a, b, c, 0x4bdecfa9, 11);
385                         MD5STEP(F3, c, d, a, b, 0xf6bb4b60, 16);
386                         MD5STEP(F3, b, c, d, a, 0xbebfbc70, 23);
387                         MD5STEP(F3, a, b, c, d, 0x289b7ec6, 4);
388                         MD5STEP(F3, d, a, b, c, pUiIn[0] + 0xeaa127fa, 11);
389                         MD5STEP(F3, c, d, a, b, 0xd4ef3085, 16);
390                         MD5STEP(F3, b, c, d, a, 0x04881d05, 23);
391                         MD5STEP(F3, a, b, c, d, 0xd9d4d039, 4);
392                         MD5STEP(F3, d, a, b, c, 0xe6db99e5, 11);
393                         MD5STEP(F3, c, d, a, b, 0x1fa27cf8, 16);
394                         MD5STEP(F3, b, c, d, a, 0xc4ac5665, 23);
395
396                         MD5STEP(F4, a, b, c, d, pUiIn[0] + 0xf4292244, 6);
397                         MD5STEP(F4, d, a, b, c, 0x432aff97, 10);
398                         MD5STEP(F4, c, d, a, b, 32 + 0xab9423a7, 15);
399                         MD5STEP(F4, b, c, d, a, 0xfc93a039, 21);
400                         MD5STEP(F4, a, b, c, d, 0x655b59c3, 6);
401                         MD5STEP(F4, d, a, b, c, 0x8f0ccc92, 10);
402                         MD5STEP(F4, c, d, a, b, 0xffeff47d, 15);
403                         MD5STEP(F4, b, c, d, a, 128 + 0x85845dd1, 21);
404                         MD5STEP(F4, a, b, c, d, 0x6fa87e4f, 6);
405                         MD5STEP(F4, d, a, b, c, 0xfe2ce6e0, 10);
406                         MD5STEP(F4, c, d, a, b, 0xa3014314, 15);
407                         MD5STEP(F4, b, c, d, a, 0x4e0811a1, 21);
408                         MD5STEP(F4, a, b, c, d, 0xf7537e82, 6);
409                         MD5STEP(F4, d, a, b, c, 0xbd3af235, 10);
410                         MD5STEP(F4, c, d, a, b, 0x2ad7d2bb, 15);
411                         MD5STEP(F4, b, c, d, a, 0xeb86d391, 21);
412                         uint32 buf[4] = { 0x67452301 + a, 0xefcdab89 + b, 0x98badcfe + c, 0x10325476 + d };
413                         memcpy(pDigest, buf, 16);
414                         return;
415                 }
416                 break;
417
418                 case 5:
419                 {
420                         //Main variables
421                         unsigned char in[8];
422                         
423                         memcpy(in, pData, 5);
424                         in[5] = 0x80;
425                         memset(in + 6, 0, 2); //(uint32 *)in[1] = 128;
426
427                         //START OF MD5TRANSFORM CODE
428                         //====================================================
429                         register uint32 a, b, c, d;
430                         uint32 * pUiIn = (uint32 *) in;
431
432                         a = 0x67452301;
433                         b = 0xefcdab89;
434                         c = 0x98badcfe;
435                         d = 0x10325476;
436
437                         MD5STEP(F1, a, b, c, d, pUiIn[0] + 0xd76aa478, 7);
438                         MD5STEP(F1, d, a, b, c, pUiIn[1] + 0xe8c7b756, 12);
439                         MD5STEP(F1, c, d, a, b, 0x242070db, 17);
440                         MD5STEP(F1, b, c, d, a, 0xc1bdceee, 22);
441                         MD5STEP(F1, a, b, c, d, 0xf57c0faf, 7);
442                         MD5STEP(F1, d, a, b, c, 0x4787c62a, 12);
443                         MD5STEP(F1, c, d, a, b, 0xa8304613, 17);
444                         MD5STEP(F1, b, c, d, a, 0xfd469501, 22);
445                         MD5STEP(F1, a, b, c, d, 0x698098d8, 7);
446                         MD5STEP(F1, d, a, b, c, 0x8b44f7af, 12);
447                         MD5STEP(F1, c, d, a, b, 0xffff5bb1, 17);
448                         MD5STEP(F1, b, c, d, a, 0x895cd7be, 22);
449                         MD5STEP(F1, a, b, c, d, 0x6b901122, 7);
450                         MD5STEP(F1, d, a, b, c, 0xfd987193, 12);
451                         MD5STEP(F1, c, d, a, b, 40 + 0xa679438e, 17);
452                         MD5STEP(F1, b, c, d, a, 0x49b40821, 22);
453
454                         MD5STEP(F2, a, b, c, d, pUiIn[1] + 0xf61e2562, 5);
455                         MD5STEP(F2, d, a, b, c, 0xc040b340, 9);
456                         MD5STEP(F2, c, d, a, b, 0x265e5a51, 14);
457                         MD5STEP(F2, b, c, d, a, pUiIn[0] + 0xe9b6c7aa, 20);
458                         MD5STEP(F2, a, b, c, d, 0xd62f105d, 5);
459                         MD5STEP(F2, d, a, b, c, 0x02441453, 9);
460                         MD5STEP(F2, c, d, a, b, 0xd8a1e681, 14);
461                         MD5STEP(F2, b, c, d, a, 0xe7d3fbc8, 20);
462                         MD5STEP(F2, a, b, c, d, 0x21e1cde6, 5);
463                         MD5STEP(F2, d, a, b, c, 40 + 0xc33707d6, 9);
464                         MD5STEP(F2, c, d, a, b, 0xf4d50d87, 14);
465                         MD5STEP(F2, b, c, d, a, 0x455a14ed, 20);
466                         MD5STEP(F2, a, b, c, d, 0xa9e3e905, 5);
467                         MD5STEP(F2, d, a, b, c, 0xfcefa3f8, 9);
468                         MD5STEP(F2, c, d, a, b, 0x676f02d9, 14);
469                         MD5STEP(F2, b, c, d, a, 0x8d2a4c8a, 20);
470
471                         MD5STEP(F3, a, b, c, d, 0xfffa3942, 4);
472                         MD5STEP(F3, d, a, b, c, 0x8771f681, 11);
473                         MD5STEP(F3, c, d, a, b, 0x6d9d6122, 16);
474                         MD5STEP(F3, b, c, d, a, 40 + 0xfde5380c, 23);
475                         MD5STEP(F3, a, b, c, d, pUiIn[1] + 0xa4beea44, 4);
476                         MD5STEP(F3, d, a, b, c, 0x4bdecfa9, 11);
477                         MD5STEP(F3, c, d, a, b, 0xf6bb4b60, 16);
478                         MD5STEP(F3, b, c, d, a, 0xbebfbc70, 23);
479                         MD5STEP(F3, a, b, c, d, 0x289b7ec6, 4);
480                         MD5STEP(F3, d, a, b, c, pUiIn[0] + 0xeaa127fa, 11);
481                         MD5STEP(F3, c, d, a, b, 0xd4ef3085, 16);
482                         MD5STEP(F3, b, c, d, a, 0x04881d05, 23);
483                         MD5STEP(F3, a, b, c, d, 0xd9d4d039, 4);
484                         MD5STEP(F3, d, a, b, c, 0xe6db99e5, 11);
485                         MD5STEP(F3, c, d, a, b, 0x1fa27cf8, 16);
486                         MD5STEP(F3, b, c, d, a, 0xc4ac5665, 23);
487
488                         MD5STEP(F4, a, b, c, d, pUiIn[0] + 0xf4292244, 6);
489                         MD5STEP(F4, d, a, b, c, 0x432aff97, 10);
490                         MD5STEP(F4, c, d, a, b, 40 + 0xab9423a7, 15);
491                         MD5STEP(F4, b, c, d, a, 0xfc93a039, 21);
492                         MD5STEP(F4, a, b, c, d, 0x655b59c3, 6);
493                         MD5STEP(F4, d, a, b, c, 0x8f0ccc92, 10);
494                         MD5STEP(F4, c, d, a, b, 0xffeff47d, 15);
495                         MD5STEP(F4, b, c, d, a, pUiIn[1] + 0x85845dd1, 21);
496                         MD5STEP(F4, a, b, c, d, 0x6fa87e4f, 6);
497                         MD5STEP(F4, d, a, b, c, 0xfe2ce6e0, 10);
498                         MD5STEP(F4, c, d, a, b, 0xa3014314, 15);
499                         MD5STEP(F4, b, c, d, a, 0x4e0811a1, 21);
500                         MD5STEP(F4, a, b, c, d, 0xf7537e82, 6);
501                         MD5STEP(F4, d, a, b, c, 0xbd3af235, 10);
502                         MD5STEP(F4, c, d, a, b, 0x2ad7d2bb, 15);
503                         MD5STEP(F4, b, c, d, a, 0xeb86d391, 21);
504                         uint32 buf[4] = { 0x67452301 + a, 0xefcdab89 + b, 0x98badcfe + c, 0x10325476 + d };
505                         memcpy(pDigest, buf, 16);
506                         return;
507                 }
508                 break;
509
510                 case 6:
511                 {
512                         //Main variables
513                         unsigned char in[8];
514                         
515                         memcpy(in, pData, 6);
516                         in[6] = 0x80;
517                         memset(in + 7, 0, 1); //(uint32 *)in[1] = 128;
518
519                         //START OF MD5TRANSFORM CODE
520                         //====================================================
521                         register uint32 a, b, c, d;
522                         uint32 * pUiIn = (uint32 *) in;
523
524                         a = 0x67452301;
525                         b = 0xefcdab89;
526                         c = 0x98badcfe;
527                         d = 0x10325476;
528
529                         MD5STEP(F1, a, b, c, d, pUiIn[0] + 0xd76aa478, 7);
530                         MD5STEP(F1, d, a, b, c, pUiIn[1] + 0xe8c7b756, 12);
531                         MD5STEP(F1, c, d, a, b, 0x242070db, 17);
532                         MD5STEP(F1, b, c, d, a, 0xc1bdceee, 22);
533                         MD5STEP(F1, a, b, c, d, 0xf57c0faf, 7);
534                         MD5STEP(F1, d, a, b, c, 0x4787c62a, 12);
535                         MD5STEP(F1, c, d, a, b, 0xa8304613, 17);
536                         MD5STEP(F1, b, c, d, a, 0xfd469501, 22);
537                         MD5STEP(F1, a, b, c, d, 0x698098d8, 7);
538                         MD5STEP(F1, d, a, b, c, 0x8b44f7af, 12);
539                         MD5STEP(F1, c, d, a, b, 0xffff5bb1, 17);
540                         MD5STEP(F1, b, c, d, a, 0x895cd7be, 22);
541                         MD5STEP(F1, a, b, c, d, 0x6b901122, 7);
542                         MD5STEP(F1, d, a, b, c, 0xfd987193, 12);
543                         MD5STEP(F1, c, d, a, b, 48 + 0xa679438e, 17);
544                         MD5STEP(F1, b, c, d, a, 0x49b40821, 22);
545
546                         MD5STEP(F2, a, b, c, d, pUiIn[1] + 0xf61e2562, 5);
547                         MD5STEP(F2, d, a, b, c, 0xc040b340, 9);
548                         MD5STEP(F2, c, d, a, b, 0x265e5a51, 14);
549                         MD5STEP(F2, b, c, d, a, pUiIn[0] + 0xe9b6c7aa, 20);
550                         MD5STEP(F2, a, b, c, d, 0xd62f105d, 5);
551                         MD5STEP(F2, d, a, b, c, 0x02441453, 9);
552                         MD5STEP(F2, c, d, a, b, 0xd8a1e681, 14);
553                         MD5STEP(F2, b, c, d, a, 0xe7d3fbc8, 20);
554                         MD5STEP(F2, a, b, c, d, 0x21e1cde6, 5);
555                         MD5STEP(F2, d, a, b, c, 48 + 0xc33707d6, 9);
556                         MD5STEP(F2, c, d, a, b, 0xf4d50d87, 14);
557                         MD5STEP(F2, b, c, d, a, 0x455a14ed, 20);
558                         MD5STEP(F2, a, b, c, d, 0xa9e3e905, 5);
559                         MD5STEP(F2, d, a, b, c, 0xfcefa3f8, 9);
560                         MD5STEP(F2, c, d, a, b, 0x676f02d9, 14);
561                         MD5STEP(F2, b, c, d, a, 0x8d2a4c8a, 20);
562
563                         MD5STEP(F3, a, b, c, d, 0xfffa3942, 4);
564                         MD5STEP(F3, d, a, b, c, 0x8771f681, 11);
565                         MD5STEP(F3, c, d, a, b, 0x6d9d6122, 16);
566                         MD5STEP(F3, b, c, d, a, 48 + 0xfde5380c, 23);
567                         MD5STEP(F3, a, b, c, d, pUiIn[1] + 0xa4beea44, 4);
568                         MD5STEP(F3, d, a, b, c, 0x4bdecfa9, 11);
569                         MD5STEP(F3, c, d, a, b, 0xf6bb4b60, 16);
570                         MD5STEP(F3, b, c, d, a, 0xbebfbc70, 23);
571                         MD5STEP(F3, a, b, c, d, 0x289b7ec6, 4);
572                         MD5STEP(F3, d, a, b, c, pUiIn[0] + 0xeaa127fa, 11);
573                         MD5STEP(F3, c, d, a, b, 0xd4ef3085, 16);
574                         MD5STEP(F3, b, c, d, a, 0x04881d05, 23);
575                         MD5STEP(F3, a, b, c, d, 0xd9d4d039, 4);
576                         MD5STEP(F3, d, a, b, c, 0xe6db99e5, 11);
577                         MD5STEP(F3, c, d, a, b, 0x1fa27cf8, 16);
578                         MD5STEP(F3, b, c, d, a, 0xc4ac5665, 23);
579
580                         MD5STEP(F4, a, b, c, d, pUiIn[0] + 0xf4292244, 6);
581                         MD5STEP(F4, d, a, b, c, 0x432aff97, 10);
582                         MD5STEP(F4, c, d, a, b, 48 + 0xab9423a7, 15);
583                         MD5STEP(F4, b, c, d, a, 0xfc93a039, 21);
584                         MD5STEP(F4, a, b, c, d, 0x655b59c3, 6);
585                         MD5STEP(F4, d, a, b, c, 0x8f0ccc92, 10);
586                         MD5STEP(F4, c, d, a, b, 0xffeff47d, 15);
587                         MD5STEP(F4, b, c, d, a, pUiIn[1] + 0x85845dd1, 21);
588                         MD5STEP(F4, a, b, c, d, 0x6fa87e4f, 6);
589                         MD5STEP(F4, d, a, b, c, 0xfe2ce6e0, 10);
590                         MD5STEP(F4, c, d, a, b, 0xa3014314, 15);
591                         MD5STEP(F4, b, c, d, a, 0x4e0811a1, 21);
592                         MD5STEP(F4, a, b, c, d, 0xf7537e82, 6);
593                         MD5STEP(F4, d, a, b, c, 0xbd3af235, 10);
594                         MD5STEP(F4, c, d, a, b, 0x2ad7d2bb, 15);
595                         MD5STEP(F4, b, c, d, a, 0xeb86d391, 21);
596                         uint32 buf[4] = { 0x67452301 + a, 0xefcdab89 + b, 0x98badcfe + c, 0x10325476 + d };
597                         memcpy(pDigest, buf, 16);
598                         return;
599                 }
600                 break;
601
602                 case 7:
603                 {
604                         //Main variables
605                         unsigned char in[8];
606                         
607                         memcpy(in, pData, 7);
608                         in[7] = 0x80;
609
610                         //START OF MD5TRANSFORM CODE
611                         //====================================================
612                         register uint32 a, b, c, d;
613                         uint32 * pUiIn = (uint32 *) in;
614
615                         a = 0x67452301;
616                         b = 0xefcdab89;
617                         c = 0x98badcfe;
618                         d = 0x10325476;
619
620                         MD5STEP(F1, a, b, c, d, pUiIn[0] + 0xd76aa478, 7);
621                         MD5STEP(F1, d, a, b, c, pUiIn[1] + 0xe8c7b756, 12);
622                         MD5STEP(F1, c, d, a, b, 0x242070db, 17);
623                         MD5STEP(F1, b, c, d, a, 0xc1bdceee, 22);
624                         MD5STEP(F1, a, b, c, d, 0xf57c0faf, 7);
625                         MD5STEP(F1, d, a, b, c, 0x4787c62a, 12);
626                         MD5STEP(F1, c, d, a, b, 0xa8304613, 17);
627                         MD5STEP(F1, b, c, d, a, 0xfd469501, 22);
628                         MD5STEP(F1, a, b, c, d, 0x698098d8, 7);
629                         MD5STEP(F1, d, a, b, c, 0x8b44f7af, 12);
630                         MD5STEP(F1, c, d, a, b, 0xffff5bb1, 17);
631                         MD5STEP(F1, b, c, d, a, 0x895cd7be, 22);
632                         MD5STEP(F1, a, b, c, d, 0x6b901122, 7);
633                         MD5STEP(F1, d, a, b, c, 0xfd987193, 12);
634                         MD5STEP(F1, c, d, a, b, 56 + 0xa679438e, 17);
635                         MD5STEP(F1, b, c, d, a, 0x49b40821, 22);
636
637                         MD5STEP(F2, a, b, c, d, pUiIn[1] + 0xf61e2562, 5);
638                         MD5STEP(F2, d, a, b, c, 0xc040b340, 9);
639                         MD5STEP(F2, c, d, a, b, 0x265e5a51, 14);
640                         MD5STEP(F2, b, c, d, a, pUiIn[0] + 0xe9b6c7aa, 20);
641                         MD5STEP(F2, a, b, c, d, 0xd62f105d, 5);
642                         MD5STEP(F2, d, a, b, c, 0x02441453, 9);
643                         MD5STEP(F2, c, d, a, b, 0xd8a1e681, 14);
644                         MD5STEP(F2, b, c, d, a, 0xe7d3fbc8, 20);
645                         MD5STEP(F2, a, b, c, d, 0x21e1cde6, 5);
646                         MD5STEP(F2, d, a, b, c, 56 + 0xc33707d6, 9);
647                         MD5STEP(F2, c, d, a, b, 0xf4d50d87, 14);
648                         MD5STEP(F2, b, c, d, a, 0x455a14ed, 20);
649                         MD5STEP(F2, a, b, c, d, 0xa9e3e905, 5);
650                         MD5STEP(F2, d, a, b, c, 0xfcefa3f8, 9);
651                         MD5STEP(F2, c, d, a, b, 0x676f02d9, 14);
652                         MD5STEP(F2, b, c, d, a, 0x8d2a4c8a, 20);
653
654                         MD5STEP(F3, a, b, c, d, 0xfffa3942, 4);
655                         MD5STEP(F3, d, a, b, c, 0x8771f681, 11);
656                         MD5STEP(F3, c, d, a, b, 0x6d9d6122, 16);
657                         MD5STEP(F3, b, c, d, a, 56 + 0xfde5380c, 23);
658                         MD5STEP(F3, a, b, c, d, pUiIn[1] + 0xa4beea44, 4);
659                         MD5STEP(F3, d, a, b, c, 0x4bdecfa9, 11);
660                         MD5STEP(F3, c, d, a, b, 0xf6bb4b60, 16);
661                         MD5STEP(F3, b, c, d, a, 0xbebfbc70, 23);
662                         MD5STEP(F3, a, b, c, d, 0x289b7ec6, 4);
663                         MD5STEP(F3, d, a, b, c, pUiIn[0] + 0xeaa127fa, 11);
664                         MD5STEP(F3, c, d, a, b, 0xd4ef3085, 16);
665                         MD5STEP(F3, b, c, d, a, 0x04881d05, 23);
666                         MD5STEP(F3, a, b, c, d, 0xd9d4d039, 4);
667                         MD5STEP(F3, d, a, b, c, 0xe6db99e5, 11);
668                         MD5STEP(F3, c, d, a, b, 0x1fa27cf8, 16);
669                         MD5STEP(F3, b, c, d, a, 0xc4ac5665, 23);
670
671                         MD5STEP(F4, a, b, c, d, pUiIn[0] + 0xf4292244, 6);
672                         MD5STEP(F4, d, a, b, c, 0x432aff97, 10);
673                         MD5STEP(F4, c, d, a, b, 56 + 0xab9423a7, 15);
674                         MD5STEP(F4, b, c, d, a, 0xfc93a039, 21);
675                         MD5STEP(F4, a, b, c, d, 0x655b59c3, 6);
676                         MD5STEP(F4, d, a, b, c, 0x8f0ccc92, 10);
677                         MD5STEP(F4, c, d, a, b, 0xffeff47d, 15);
678                         MD5STEP(F4, b, c, d, a, pUiIn[1] + 0x85845dd1, 21);
679                         MD5STEP(F4, a, b, c, d, 0x6fa87e4f, 6);
680                         MD5STEP(F4, d, a, b, c, 0xfe2ce6e0, 10);
681                         MD5STEP(F4, c, d, a, b, 0xa3014314, 15);
682                         MD5STEP(F4, b, c, d, a, 0x4e0811a1, 21);
683                         MD5STEP(F4, a, b, c, d, 0xf7537e82, 6);
684                         MD5STEP(F4, d, a, b, c, 0xbd3af235, 10);
685                         MD5STEP(F4, c, d, a, b, 0x2ad7d2bb, 15);
686                         MD5STEP(F4, b, c, d, a, 0xeb86d391, 21);
687
688                         uint32 buf[4] = { 0x67452301 + a, 0xefcdab89 + b, 0x98badcfe + c, 0x10325476 + d };
689                         memcpy(pDigest, buf, 16);
690                         return;
691                 }
692                 break;
693
694                 case 8:
695                 {
696                         //Main variables
697                         unsigned char in[8];
698                         
699                         memcpy(in, pData, 8);
700
701                         //START OF MD5TRANSFORM CODE
702                         //====================================================
703                         register uint32 a, b, c, d;
704                         uint32 * pUiIn = (uint32 *) in;
705
706                         a = 0x67452301;
707                         b = 0xefcdab89;
708                         c = 0x98badcfe;
709                         d = 0x10325476;
710
711                         MD5STEP(F1, a, b, c, d, pUiIn[0] + 0xd76aa478, 7);
712                         MD5STEP(F1, d, a, b, c, pUiIn[1] + 0xe8c7b756, 12);
713                         MD5STEP(F1, c, d, a, b, 128 + 0x242070db, 17);
714                         MD5STEP(F1, b, c, d, a, 0xc1bdceee, 22);
715                         MD5STEP(F1, a, b, c, d, 0xf57c0faf, 7);
716                         MD5STEP(F1, d, a, b, c, 0x4787c62a, 12);
717                         MD5STEP(F1, c, d, a, b, 0xa8304613, 17);
718                         MD5STEP(F1, b, c, d, a, 0xfd469501, 22);
719                         MD5STEP(F1, a, b, c, d, 0x698098d8, 7);
720                         MD5STEP(F1, d, a, b, c, 0x8b44f7af, 12);
721                         MD5STEP(F1, c, d, a, b, 0xffff5bb1, 17);
722                         MD5STEP(F1, b, c, d, a, 0x895cd7be, 22);
723                         MD5STEP(F1, a, b, c, d, 0x6b901122, 7);
724                         MD5STEP(F1, d, a, b, c, 0xfd987193, 12);
725                         MD5STEP(F1, c, d, a, b, 64 + 0xa679438e, 17);
726                         MD5STEP(F1, b, c, d, a, 0x49b40821, 22);
727
728                         MD5STEP(F2, a, b, c, d, pUiIn[1] + 0xf61e2562, 5);
729                         MD5STEP(F2, d, a, b, c, 0xc040b340, 9);
730                         MD5STEP(F2, c, d, a, b, 0x265e5a51, 14);
731                         MD5STEP(F2, b, c, d, a, pUiIn[0] + 0xe9b6c7aa, 20);
732                         MD5STEP(F2, a, b, c, d, 0xd62f105d, 5);
733                         MD5STEP(F2, d, a, b, c, 0x02441453, 9);
734                         MD5STEP(F2, c, d, a, b, 0xd8a1e681, 14);
735                         MD5STEP(F2, b, c, d, a, 0xe7d3fbc8, 20);
736                         MD5STEP(F2, a, b, c, d, 0x21e1cde6, 5);
737                         MD5STEP(F2, d, a, b, c, 64 + 0xc33707d6, 9);
738                         MD5STEP(F2, c, d, a, b, 0xf4d50d87, 14);
739                         MD5STEP(F2, b, c, d, a, 0x455a14ed, 20);
740                         MD5STEP(F2, a, b, c, d, 0xa9e3e905, 5);
741                         MD5STEP(F2, d, a, b, c, 128 + 0xfcefa3f8, 9);
742                         MD5STEP(F2, c, d, a, b, 0x676f02d9, 14);
743                         MD5STEP(F2, b, c, d, a, 0x8d2a4c8a, 20);
744
745                         MD5STEP(F3, a, b, c, d, 0xfffa3942, 4);
746                         MD5STEP(F3, d, a, b, c, 0x8771f681, 11);
747                         MD5STEP(F3, c, d, a, b, 0x6d9d6122, 16);
748                         MD5STEP(F3, b, c, d, a, 64 + 0xfde5380c, 23);
749                         MD5STEP(F3, a, b, c, d, pUiIn[1] + 0xa4beea44, 4);
750                         MD5STEP(F3, d, a, b, c, 0x4bdecfa9, 11);
751                         MD5STEP(F3, c, d, a, b, 0xf6bb4b60, 16);
752                         MD5STEP(F3, b, c, d, a, 0xbebfbc70, 23);
753                         MD5STEP(F3, a, b, c, d, 0x289b7ec6, 4);
754                         MD5STEP(F3, d, a, b, c, pUiIn[0] + 0xeaa127fa, 11);
755                         MD5STEP(F3, c, d, a, b, 0xd4ef3085, 16);
756                         MD5STEP(F3, b, c, d, a, 0x04881d05, 23);
757                         MD5STEP(F3, a, b, c, d, 0xd9d4d039, 4);
758                         MD5STEP(F3, d, a, b, c, 0xe6db99e5, 11);
759                         MD5STEP(F3, c, d, a, b, 0x1fa27cf8, 16);
760                         MD5STEP(F3, b, c, d, a, 128 + 0xc4ac5665, 23);
761
762                         MD5STEP(F4, a, b, c, d, pUiIn[0] + 0xf4292244, 6);
763                         MD5STEP(F4, d, a, b, c, 0x432aff97, 10);
764                         MD5STEP(F4, c, d, a, b, 64 + 0xab9423a7, 15);
765                         MD5STEP(F4, b, c, d, a, 0xfc93a039, 21);
766                         MD5STEP(F4, a, b, c, d, 0x655b59c3, 6);
767                         MD5STEP(F4, d, a, b, c, 0x8f0ccc92, 10);
768                         MD5STEP(F4, c, d, a, b, 0xffeff47d, 15);
769                         MD5STEP(F4, b, c, d, a, pUiIn[1] + 0x85845dd1, 21);
770                         MD5STEP(F4, a, b, c, d, 0x6fa87e4f, 6);
771                         MD5STEP(F4, d, a, b, c, 0xfe2ce6e0, 10);
772                         MD5STEP(F4, c, d, a, b, 0xa3014314, 15);
773                         MD5STEP(F4, b, c, d, a, 0x4e0811a1, 21);
774                         MD5STEP(F4, a, b, c, d, 0xf7537e82, 6);
775                         MD5STEP(F4, d, a, b, c, 0xbd3af235, 10);
776                         MD5STEP(F4, c, d, a, b, 128 + 0x2ad7d2bb, 15);
777                         MD5STEP(F4, b, c, d, a, 0xeb86d391, 21);
778
779                         uint32 buf[4] = { 0x67452301 + a, 0xefcdab89 + b, 0x98badcfe + c, 0x10325476 + d };
780                         memcpy(pDigest, buf, 16);
781                         return;
782                 }
783                 break;
784
785                 case 9:
786                 {
787                         //Main variables
788                         unsigned char in[12];
789                         
790                         memcpy(in, pData, 9);
791                         in[9] = 0x80;
792                         memset(in + 10, 0, 2);
793
794                         //START OF MD5TRANSFORM CODE
795                         //====================================================
796                         register uint32 a, b, c, d;
797                         uint32 * pUiIn = (uint32 *) in;
798
799                         a = 0x67452301;
800                         b = 0xefcdab89;
801                         c = 0x98badcfe;
802                         d = 0x10325476;
803
804                         MD5STEP(F1, a, b, c, d, pUiIn[0] + 0xd76aa478, 7);
805                         MD5STEP(F1, d, a, b, c, pUiIn[1] + 0xe8c7b756, 12);
806                         MD5STEP(F1, c, d, a, b, pUiIn[2] + 0x242070db, 17);
807                         MD5STEP(F1, b, c, d, a, 0xc1bdceee, 22);
808                         MD5STEP(F1, a, b, c, d, 0xf57c0faf, 7);
809                         MD5STEP(F1, d, a, b, c, 0x4787c62a, 12);
810                         MD5STEP(F1, c, d, a, b, 0xa8304613, 17);
811                         MD5STEP(F1, b, c, d, a, 0xfd469501, 22);
812                         MD5STEP(F1, a, b, c, d, 0x698098d8, 7);
813                         MD5STEP(F1, d, a, b, c, 0x8b44f7af, 12);
814                         MD5STEP(F1, c, d, a, b, 0xffff5bb1, 17);
815                         MD5STEP(F1, b, c, d, a, 0x895cd7be, 22);
816                         MD5STEP(F1, a, b, c, d, 0x6b901122, 7);
817                         MD5STEP(F1, d, a, b, c, 0xfd987193, 12);
818                         MD5STEP(F1, c, d, a, b, 72 + 0xa679438e, 17);
819                         MD5STEP(F1, b, c, d, a, 0x49b40821, 22);
820
821                         MD5STEP(F2, a, b, c, d, pUiIn[1] + 0xf61e2562, 5);
822                         MD5STEP(F2, d, a, b, c, 0xc040b340, 9);
823                         MD5STEP(F2, c, d, a, b, 0x265e5a51, 14);
824                         MD5STEP(F2, b, c, d, a, pUiIn[0] + 0xe9b6c7aa, 20);
825                         MD5STEP(F2, a, b, c, d, 0xd62f105d, 5);
826                         MD5STEP(F2, d, a, b, c, 0x02441453, 9);
827                         MD5STEP(F2, c, d, a, b, 0xd8a1e681, 14);
828                         MD5STEP(F2, b, c, d, a, 0xe7d3fbc8, 20);
829                         MD5STEP(F2, a, b, c, d, 0x21e1cde6, 5);
830                         MD5STEP(F2, d, a, b, c, 72 + 0xc33707d6, 9);
831                         MD5STEP(F2, c, d, a, b, 0xf4d50d87, 14);
832                         MD5STEP(F2, b, c, d, a, 0x455a14ed, 20);
833                         MD5STEP(F2, a, b, c, d, 0xa9e3e905, 5);
834                         MD5STEP(F2, d, a, b, c, pUiIn[2] + 0xfcefa3f8, 9);
835                         MD5STEP(F2, c, d, a, b, 0x676f02d9, 14);
836                         MD5STEP(F2, b, c, d, a, 0x8d2a4c8a, 20);
837
838                         MD5STEP(F3, a, b, c, d, 0xfffa3942, 4);
839                         MD5STEP(F3, d, a, b, c, 0x8771f681, 11);
840                         MD5STEP(F3, c, d, a, b, 0x6d9d6122, 16);
841                         MD5STEP(F3, b, c, d, a, 72 + 0xfde5380c, 23);
842                         MD5STEP(F3, a, b, c, d, pUiIn[1] + 0xa4beea44, 4);
843                         MD5STEP(F3, d, a, b, c, 0x4bdecfa9, 11);
844                         MD5STEP(F3, c, d, a, b, 0xf6bb4b60, 16);
845                         MD5STEP(F3, b, c, d, a, 0xbebfbc70, 23);
846                         MD5STEP(F3, a, b, c, d, 0x289b7ec6, 4);
847                         MD5STEP(F3, d, a, b, c, pUiIn[0] + 0xeaa127fa, 11);
848                         MD5STEP(F3, c, d, a, b, 0xd4ef3085, 16);
849                         MD5STEP(F3, b, c, d, a, 0x04881d05, 23);
850                         MD5STEP(F3, a, b, c, d, 0xd9d4d039, 4);
851                         MD5STEP(F3, d, a, b, c, 0xe6db99e5, 11);
852                         MD5STEP(F3, c, d, a, b, 0x1fa27cf8, 16);
853                         MD5STEP(F3, b, c, d, a, pUiIn[2] + 0xc4ac5665, 23);
854
855                         MD5STEP(F4, a, b, c, d, pUiIn[0] + 0xf4292244, 6);
856                         MD5STEP(F4, d, a, b, c, 0x432aff97, 10);
857                         MD5STEP(F4, c, d, a, b, 72 + 0xab9423a7, 15);
858                         MD5STEP(F4, b, c, d, a, 0xfc93a039, 21);
859                         MD5STEP(F4, a, b, c, d, 0x655b59c3, 6);
860                         MD5STEP(F4, d, a, b, c, 0x8f0ccc92, 10);
861                         MD5STEP(F4, c, d, a, b, 0xffeff47d, 15);
862                         MD5STEP(F4, b, c, d, a, pUiIn[1] + 0x85845dd1, 21);
863                         MD5STEP(F4, a, b, c, d, 0x6fa87e4f, 6);
864                         MD5STEP(F4, d, a, b, c, 0xfe2ce6e0, 10);
865                         MD5STEP(F4, c, d, a, b, 0xa3014314, 15);
866                         MD5STEP(F4, b, c, d, a, 0x4e0811a1, 21);
867                         MD5STEP(F4, a, b, c, d, 0xf7537e82, 6);
868                         MD5STEP(F4, d, a, b, c, 0xbd3af235, 10);
869                         MD5STEP(F4, c, d, a, b, pUiIn[2] + 0x2ad7d2bb, 15);
870                         MD5STEP(F4, b, c, d, a, 0xeb86d391, 21);
871
872                         uint32 buf[4] = { 0x67452301 + a, 0xefcdab89 + b, 0x98badcfe + c, 0x10325476 + d };
873                         memcpy(pDigest, buf, 16);
874                         return;
875                 }
876                 break;
877
878                 case 10:
879                 {
880                         //Main variables
881                         unsigned char in[12];
882                         
883                         memcpy(in, pData, 10);
884                         in[10] = 0x80;
885                         memset(in + 11, 0, 1);
886
887                         //START OF MD5TRANSFORM CODE
888                         //====================================================
889                         register uint32 a, b, c, d;
890                         uint32 * pUiIn = (uint32 *) in;
891
892                         a = 0x67452301;
893                         b = 0xefcdab89;
894                         c = 0x98badcfe;
895                         d = 0x10325476;
896
897                         MD5STEP(F1, a, b, c, d, pUiIn[0] + 0xd76aa478, 7);
898                         MD5STEP(F1, d, a, b, c, pUiIn[1] + 0xe8c7b756, 12);
899                         MD5STEP(F1, c, d, a, b, pUiIn[2] + 0x242070db, 17);
900                         MD5STEP(F1, b, c, d, a, 0xc1bdceee, 22);
901                         MD5STEP(F1, a, b, c, d, 0xf57c0faf, 7);
902                         MD5STEP(F1, d, a, b, c, 0x4787c62a, 12);
903                         MD5STEP(F1, c, d, a, b, 0xa8304613, 17);
904                         MD5STEP(F1, b, c, d, a, 0xfd469501, 22);
905                         MD5STEP(F1, a, b, c, d, 0x698098d8, 7);
906                         MD5STEP(F1, d, a, b, c, 0x8b44f7af, 12);
907                         MD5STEP(F1, c, d, a, b, 0xffff5bb1, 17);
908                         MD5STEP(F1, b, c, d, a, 0x895cd7be, 22);
909                         MD5STEP(F1, a, b, c, d, 0x6b901122, 7);
910                         MD5STEP(F1, d, a, b, c, 0xfd987193, 12);
911                         MD5STEP(F1, c, d, a, b, 80 + 0xa679438e, 17);
912                         MD5STEP(F1, b, c, d, a, 0x49b40821, 22);
913
914                         MD5STEP(F2, a, b, c, d, pUiIn[1] + 0xf61e2562, 5);
915                         MD5STEP(F2, d, a, b, c, 0xc040b340, 9);
916                         MD5STEP(F2, c, d, a, b, 0x265e5a51, 14);
917                         MD5STEP(F2, b, c, d, a, pUiIn[0] + 0xe9b6c7aa, 20);
918                         MD5STEP(F2, a, b, c, d, 0xd62f105d, 5);
919                         MD5STEP(F2, d, a, b, c, 0x02441453, 9);
920                         MD5STEP(F2, c, d, a, b, 0xd8a1e681, 14);
921                         MD5STEP(F2, b, c, d, a, 0xe7d3fbc8, 20);
922                         MD5STEP(F2, a, b, c, d, 0x21e1cde6, 5);
923                         MD5STEP(F2, d, a, b, c, 80 + 0xc33707d6, 9);
924                         MD5STEP(F2, c, d, a, b, 0xf4d50d87, 14);
925                         MD5STEP(F2, b, c, d, a, 0x455a14ed, 20);
926                         MD5STEP(F2, a, b, c, d, 0xa9e3e905, 5);
927                         MD5STEP(F2, d, a, b, c, pUiIn[2] + 0xfcefa3f8, 9);
928                         MD5STEP(F2, c, d, a, b, 0x676f02d9, 14);
929                         MD5STEP(F2, b, c, d, a, 0x8d2a4c8a, 20);
930
931                         MD5STEP(F3, a, b, c, d, 0xfffa3942, 4);
932                         MD5STEP(F3, d, a, b, c, 0x8771f681, 11);
933                         MD5STEP(F3, c, d, a, b, 0x6d9d6122, 16);
934                         MD5STEP(F3, b, c, d, a, 80 + 0xfde5380c, 23);
935                         MD5STEP(F3, a, b, c, d, pUiIn[1] + 0xa4beea44, 4);
936                         MD5STEP(F3, d, a, b, c, 0x4bdecfa9, 11);
937                         MD5STEP(F3, c, d, a, b, 0xf6bb4b60, 16);
938                         MD5STEP(F3, b, c, d, a, 0xbebfbc70, 23);
939                         MD5STEP(F3, a, b, c, d, 0x289b7ec6, 4);
940                         MD5STEP(F3, d, a, b, c, pUiIn[0] + 0xeaa127fa, 11);
941                         MD5STEP(F3, c, d, a, b, 0xd4ef3085, 16);
942                         MD5STEP(F3, b, c, d, a, 0x04881d05, 23);
943                         MD5STEP(F3, a, b, c, d, 0xd9d4d039, 4);
944                         MD5STEP(F3, d, a, b, c, 0xe6db99e5, 11);
945                         MD5STEP(F3, c, d, a, b, 0x1fa27cf8, 16);
946                         MD5STEP(F3, b, c, d, a, pUiIn[2] + 0xc4ac5665, 23);
947
948                         MD5STEP(F4, a, b, c, d, pUiIn[0] + 0xf4292244, 6);
949                         MD5STEP(F4, d, a, b, c, 0x432aff97, 10);
950                         MD5STEP(F4, c, d, a, b, 80 + 0xab9423a7, 15);
951                         MD5STEP(F4, b, c, d, a, 0xfc93a039, 21);
952                         MD5STEP(F4, a, b, c, d, 0x655b59c3, 6);
953                         MD5STEP(F4, d, a, b, c, 0x8f0ccc92, 10);
954                         MD5STEP(F4, c, d, a, b, 0xffeff47d, 15);
955                         MD5STEP(F4, b, c, d, a, pUiIn[1] + 0x85845dd1, 21);
956                         MD5STEP(F4, a, b, c, d, 0x6fa87e4f, 6);
957                         MD5STEP(F4, d, a, b, c, 0xfe2ce6e0, 10);
958                         MD5STEP(F4, c, d, a, b, 0xa3014314, 15);
959                         MD5STEP(F4, b, c, d, a, 0x4e0811a1, 21);
960                         MD5STEP(F4, a, b, c, d, 0xf7537e82, 6);
961                         MD5STEP(F4, d, a, b, c, 0xbd3af235, 10);
962                         MD5STEP(F4, c, d, a, b, pUiIn[2] + 0x2ad7d2bb, 15);
963                         MD5STEP(F4, b, c, d, a, 0xeb86d391, 21);
964
965                         uint32 buf[4] = { 0x67452301 + a, 0xefcdab89 + b, 0x98badcfe + c, 0x10325476 + d };
966                         memcpy(pDigest, buf, 16);
967                         return;
968                 }
969                 break;
970
971                 default:
972                         //Main variables
973                         uint32 buf[4];
974                         unsigned char in[64];
975                         
976                         //Initialize
977                         buf[0] = 0x67452301;
978                         buf[1] = 0xefcdab89;
979                         buf[2] = 0x98badcfe;
980                         buf[3] = 0x10325476;
981
982                         /* Process data in 64-byte chunks */
983                         if( len >= 64 )
984                         {
985                                 while( len >= 64 )
986                                 {
987                                         memcpy(in, pData, 64);
988
989                                         //START OF MD5TRANSFORM CODE
990                                         //====================================================
991                                         register uint32 a, b, c, d;
992                                         uint32 * pUiIn = (uint32 *) in;
993                                 
994                                         a = buf[0];
995                                         b = buf[1];
996                                         c = buf[2];
997                                         d = buf[3];
998                                 
999                                         MD5STEP(F1, a, b, c, d, pUiIn[0] + 0xd76aa478, 7);
1000                                         MD5STEP(F1, d, a, b, c, pUiIn[1] + 0xe8c7b756, 12);
1001                                         MD5STEP(F1, c, d, a, b, pUiIn[2] + 0x242070db, 17);
1002                                         MD5STEP(F1, b, c, d, a, pUiIn[3] + 0xc1bdceee, 22);
1003                                         MD5STEP(F1, a, b, c, d, pUiIn[4] + 0xf57c0faf, 7);
1004                                         MD5STEP(F1, d, a, b, c, pUiIn[5] + 0x4787c62a, 12);
1005                                         MD5STEP(F1, c, d, a, b, pUiIn[6] + 0xa8304613, 17);
1006                                         MD5STEP(F1, b, c, d, a, pUiIn[7] + 0xfd469501, 22);
1007                                         MD5STEP(F1, a, b, c, d, pUiIn[8] + 0x698098d8, 7);
1008                                         MD5STEP(F1, d, a, b, c, pUiIn[9] + 0x8b44f7af, 12);
1009                                         MD5STEP(F1, c, d, a, b, pUiIn[10] + 0xffff5bb1, 17);
1010                                         MD5STEP(F1, b, c, d, a, pUiIn[11] + 0x895cd7be, 22);
1011                                         MD5STEP(F1, a, b, c, d, pUiIn[12] + 0x6b901122, 7);
1012                                         MD5STEP(F1, d, a, b, c, pUiIn[13] + 0xfd987193, 12);
1013                                         MD5STEP(F1, c, d, a, b, pUiIn[14] + 0xa679438e, 17);
1014                                         MD5STEP(F1, b, c, d, a, pUiIn[15] + 0x49b40821, 22);
1015                                 
1016                                         MD5STEP(F2, a, b, c, d, pUiIn[1] + 0xf61e2562, 5);
1017                                         MD5STEP(F2, d, a, b, c, pUiIn[6] + 0xc040b340, 9);
1018                                         MD5STEP(F2, c, d, a, b, pUiIn[11] + 0x265e5a51, 14);
1019                                         MD5STEP(F2, b, c, d, a, pUiIn[0] + 0xe9b6c7aa, 20);
1020                                         MD5STEP(F2, a, b, c, d, pUiIn[5] + 0xd62f105d, 5);
1021                                         MD5STEP(F2, d, a, b, c, pUiIn[10] + 0x02441453, 9);
1022                                         MD5STEP(F2, c, d, a, b, pUiIn[15] + 0xd8a1e681, 14);
1023                                         MD5STEP(F2, b, c, d, a, pUiIn[4] + 0xe7d3fbc8, 20);
1024                                         MD5STEP(F2, a, b, c, d, pUiIn[9] + 0x21e1cde6, 5);
1025                                         MD5STEP(F2, d, a, b, c, pUiIn[14] + 0xc33707d6, 9);
1026                                         MD5STEP(F2, c, d, a, b, pUiIn[3] + 0xf4d50d87, 14);
1027                                         MD5STEP(F2, b, c, d, a, pUiIn[8] + 0x455a14ed, 20);
1028                                         MD5STEP(F2, a, b, c, d, pUiIn[13] + 0xa9e3e905, 5);
1029                                         MD5STEP(F2, d, a, b, c, pUiIn[2] + 0xfcefa3f8, 9);
1030                                         MD5STEP(F2, c, d, a, b, pUiIn[7] + 0x676f02d9, 14);
1031                                         MD5STEP(F2, b, c, d, a, pUiIn[12] + 0x8d2a4c8a, 20);
1032                                 
1033                                         MD5STEP(F3, a, b, c, d, pUiIn[5] + 0xfffa3942, 4);
1034                                         MD5STEP(F3, d, a, b, c, pUiIn[8] + 0x8771f681, 11);
1035                                         MD5STEP(F3, c, d, a, b, pUiIn[11] + 0x6d9d6122, 16);
1036                                         MD5STEP(F3, b, c, d, a, pUiIn[14] + 0xfde5380c, 23);
1037                                         MD5STEP(F3, a, b, c, d, pUiIn[1] + 0xa4beea44, 4);
1038                                         MD5STEP(F3, d, a, b, c, pUiIn[4] + 0x4bdecfa9, 11);
1039                                         MD5STEP(F3, c, d, a, b, pUiIn[7] + 0xf6bb4b60, 16);
1040                                         MD5STEP(F3, b, c, d, a, pUiIn[10] + 0xbebfbc70, 23);
1041                                         MD5STEP(F3, a, b, c, d, pUiIn[13] + 0x289b7ec6, 4);
1042                                         MD5STEP(F3, d, a, b, c, pUiIn[0] + 0xeaa127fa, 11);
1043                                         MD5STEP(F3, c, d, a, b, pUiIn[3] + 0xd4ef3085, 16);
1044                                         MD5STEP(F3, b, c, d, a, pUiIn[6] + 0x04881d05, 23);
1045                                         MD5STEP(F3, a, b, c, d, pUiIn[9] + 0xd9d4d039, 4);
1046                                         MD5STEP(F3, d, a, b, c, pUiIn[12] + 0xe6db99e5, 11);
1047                                         MD5STEP(F3, c, d, a, b, pUiIn[15] + 0x1fa27cf8, 16);
1048                                         MD5STEP(F3, b, c, d, a, pUiIn[2] + 0xc4ac5665, 23);
1049                                 
1050                                         MD5STEP(F4, a, b, c, d, pUiIn[0] + 0xf4292244, 6);
1051                                         MD5STEP(F4, d, a, b, c, pUiIn[7] + 0x432aff97, 10);
1052                                         MD5STEP(F4, c, d, a, b, pUiIn[14] + 0xab9423a7, 15);
1053                                         MD5STEP(F4, b, c, d, a, pUiIn[5] + 0xfc93a039, 21);
1054                                         MD5STEP(F4, a, b, c, d, pUiIn[12] + 0x655b59c3, 6);
1055                                         MD5STEP(F4, d, a, b, c, pUiIn[3] + 0x8f0ccc92, 10);
1056                                         MD5STEP(F4, c, d, a, b, pUiIn[10] + 0xffeff47d, 15);
1057                                         MD5STEP(F4, b, c, d, a, pUiIn[1] + 0x85845dd1, 21);
1058                                         MD5STEP(F4, a, b, c, d, pUiIn[8] + 0x6fa87e4f, 6);
1059                                         MD5STEP(F4, d, a, b, c, pUiIn[15] + 0xfe2ce6e0, 10);
1060                                         MD5STEP(F4, c, d, a, b, pUiIn[6] + 0xa3014314, 15);
1061                                         MD5STEP(F4, b, c, d, a, pUiIn[13] + 0x4e0811a1, 21);
1062                                         MD5STEP(F4, a, b, c, d, pUiIn[4] + 0xf7537e82, 6);
1063                                         MD5STEP(F4, d, a, b, c, pUiIn[11] + 0xbd3af235, 10);
1064                                         MD5STEP(F4, c, d, a, b, pUiIn[2] + 0x2ad7d2bb, 15);
1065                                         MD5STEP(F4, b, c, d, a, pUiIn[9] + 0xeb86d391, 21);
1066                                 
1067                                         buf[0] += a;
1068                                         buf[1] += b;
1069                                         buf[2] += c;
1070                                         buf[3] += d;
1071                                         //END OF MD5TRANSFORM CODE
1072                                         //====================================================
1073
1074                                         pData += 64;
1075                                         len -= 64;
1076                                 }
1077                         }
1078
1079                         /* Handle any remaining bytes of data. */
1080                         memcpy(in, pData, len);
1081                     
1082                         //MD5FINAL STARTS HERE
1083                         //===========================================
1084                         unsigned count = len & 0x3F;
1085                         unsigned char * p = in + count;
1086                         *p++ = 0x80;
1087
1088                         // Bytes of padding needed to make 64 bytes
1089                         count = 63 - count;
1090
1091                         /* Pad out to 56 mod 64 */
1092                         if(count < 8)
1093                         {
1094                                 // Two lots of padding:  Pad the first block to 64 bytes
1095                                 memset(p, 0, count);
1096
1097                                 //START OF MD5TRANSFORM CODE
1098                                 //====================================================
1099                                 register uint32 a, b, c, d;
1100                                 uint32 * pUiIn = (uint32 *) in;
1101                         
1102                                 a = buf[0];
1103                                 b = buf[1];
1104                                 c = buf[2];
1105                                 d = buf[3];
1106                         
1107                                 MD5STEP(F1, a, b, c, d, pUiIn[0] + 0xd76aa478, 7);
1108                                 MD5STEP(F1, d, a, b, c, pUiIn[1] + 0xe8c7b756, 12);
1109                                 MD5STEP(F1, c, d, a, b, pUiIn[2] + 0x242070db, 17);
1110                                 MD5STEP(F1, b, c, d, a, pUiIn[3] + 0xc1bdceee, 22);
1111                                 MD5STEP(F1, a, b, c, d, pUiIn[4] + 0xf57c0faf, 7);
1112                                 MD5STEP(F1, d, a, b, c, pUiIn[5] + 0x4787c62a, 12);
1113                                 MD5STEP(F1, c, d, a, b, pUiIn[6] + 0xa8304613, 17);
1114                                 MD5STEP(F1, b, c, d, a, pUiIn[7] + 0xfd469501, 22);
1115                                 MD5STEP(F1, a, b, c, d, pUiIn[8] + 0x698098d8, 7);
1116                                 MD5STEP(F1, d, a, b, c, pUiIn[9] + 0x8b44f7af, 12);
1117                                 MD5STEP(F1, c, d, a, b, pUiIn[10] + 0xffff5bb1, 17);
1118                                 MD5STEP(F1, b, c, d, a, pUiIn[11] + 0x895cd7be, 22);
1119                                 MD5STEP(F1, a, b, c, d, pUiIn[12] + 0x6b901122, 7);
1120                                 MD5STEP(F1, d, a, b, c, pUiIn[13] + 0xfd987193, 12);
1121                                 MD5STEP(F1, c, d, a, b, pUiIn[14] + 0xa679438e, 17);
1122                                 MD5STEP(F1, b, c, d, a, pUiIn[15] + 0x49b40821, 22);
1123                         
1124                                 MD5STEP(F2, a, b, c, d, pUiIn[1] + 0xf61e2562, 5);
1125                                 MD5STEP(F2, d, a, b, c, pUiIn[6] + 0xc040b340, 9);
1126                                 MD5STEP(F2, c, d, a, b, pUiIn[11] + 0x265e5a51, 14);
1127                                 MD5STEP(F2, b, c, d, a, pUiIn[0] + 0xe9b6c7aa, 20);
1128                                 MD5STEP(F2, a, b, c, d, pUiIn[5] + 0xd62f105d, 5);
1129                                 MD5STEP(F2, d, a, b, c, pUiIn[10] + 0x02441453, 9);
1130                                 MD5STEP(F2, c, d, a, b, pUiIn[15] + 0xd8a1e681, 14);
1131                                 MD5STEP(F2, b, c, d, a, pUiIn[4] + 0xe7d3fbc8, 20);
1132                                 MD5STEP(F2, a, b, c, d, pUiIn[9] + 0x21e1cde6, 5);
1133                                 MD5STEP(F2, d, a, b, c, pUiIn[14] + 0xc33707d6, 9);
1134                                 MD5STEP(F2, c, d, a, b, pUiIn[3] + 0xf4d50d87, 14);
1135                                 MD5STEP(F2, b, c, d, a, pUiIn[8] + 0x455a14ed, 20);
1136                                 MD5STEP(F2, a, b, c, d, pUiIn[13] + 0xa9e3e905, 5);
1137                                 MD5STEP(F2, d, a, b, c, pUiIn[2] + 0xfcefa3f8, 9);
1138                                 MD5STEP(F2, c, d, a, b, pUiIn[7] + 0x676f02d9, 14);
1139                                 MD5STEP(F2, b, c, d, a, pUiIn[12] + 0x8d2a4c8a, 20);
1140                         
1141                                 MD5STEP(F3, a, b, c, d, pUiIn[5] + 0xfffa3942, 4);
1142                                 MD5STEP(F3, d, a, b, c, pUiIn[8] + 0x8771f681, 11);
1143                                 MD5STEP(F3, c, d, a, b, pUiIn[11] + 0x6d9d6122, 16);
1144                                 MD5STEP(F3, b, c, d, a, pUiIn[14] + 0xfde5380c, 23);
1145                                 MD5STEP(F3, a, b, c, d, pUiIn[1] + 0xa4beea44, 4);
1146                                 MD5STEP(F3, d, a, b, c, pUiIn[4] + 0x4bdecfa9, 11);
1147                                 MD5STEP(F3, c, d, a, b, pUiIn[7] + 0xf6bb4b60, 16);
1148                                 MD5STEP(F3, b, c, d, a, pUiIn[10] + 0xbebfbc70, 23);
1149                                 MD5STEP(F3, a, b, c, d, pUiIn[13] + 0x289b7ec6, 4);
1150                                 MD5STEP(F3, d, a, b, c, pUiIn[0] + 0xeaa127fa, 11);
1151                                 MD5STEP(F3, c, d, a, b, pUiIn[3] + 0xd4ef3085, 16);
1152                                 MD5STEP(F3, b, c, d, a, pUiIn[6] + 0x04881d05, 23);
1153                                 MD5STEP(F3, a, b, c, d, pUiIn[9] + 0xd9d4d039, 4);
1154                                 MD5STEP(F3, d, a, b, c, pUiIn[12] + 0xe6db99e5, 11);
1155                                 MD5STEP(F3, c, d, a, b, pUiIn[15] + 0x1fa27cf8, 16);
1156                                 MD5STEP(F3, b, c, d, a, pUiIn[2] + 0xc4ac5665, 23);
1157                         
1158                                 MD5STEP(F4, a, b, c, d, pUiIn[0] + 0xf4292244, 6);
1159                                 MD5STEP(F4, d, a, b, c, pUiIn[7] + 0x432aff97, 10);
1160                                 MD5STEP(F4, c, d, a, b, pUiIn[14] + 0xab9423a7, 15);
1161                                 MD5STEP(F4, b, c, d, a, pUiIn[5] + 0xfc93a039, 21);
1162                                 MD5STEP(F4, a, b, c, d, pUiIn[12] + 0x655b59c3, 6);
1163                                 MD5STEP(F4, d, a, b, c, pUiIn[3] + 0x8f0ccc92, 10);
1164                                 MD5STEP(F4, c, d, a, b, pUiIn[10] + 0xffeff47d, 15);
1165                                 MD5STEP(F4, b, c, d, a, pUiIn[1] + 0x85845dd1, 21);
1166                                 MD5STEP(F4, a, b, c, d, pUiIn[8] + 0x6fa87e4f, 6);
1167                                 MD5STEP(F4, d, a, b, c, pUiIn[15] + 0xfe2ce6e0, 10);
1168                                 MD5STEP(F4, c, d, a, b, pUiIn[6] + 0xa3014314, 15);
1169                                 MD5STEP(F4, b, c, d, a, pUiIn[13] + 0x4e0811a1, 21);
1170                                 MD5STEP(F4, a, b, c, d, pUiIn[4] + 0xf7537e82, 6);
1171                                 MD5STEP(F4, d, a, b, c, pUiIn[11] + 0xbd3af235, 10);
1172                                 MD5STEP(F4, c, d, a, b, pUiIn[2] + 0x2ad7d2bb, 15);
1173                                 MD5STEP(F4, b, c, d, a, pUiIn[9] + 0xeb86d391, 21);
1174                         
1175                                 buf[0] += a;
1176                                 buf[1] += b;
1177                                 buf[2] += c;
1178                                 buf[3] += d;
1179                                 //END OF MD5TRANSFORM CODE
1180                                 //====================================================      
1181
1182                                 // Now fill the next block with 56 bytes
1183                                 memset(in, 0, 56);
1184                         }
1185                         else
1186                         {
1187                                 // Pad block to 56 bytes
1188                                 memset(p, 0, count - 8);
1189                         }//*/
1190                     
1191
1192                         /* Append length in bits and transform */
1193                         ((uint32 *) in)[14] = len << 3;
1194                         ((uint32 *) in)[15] = len >> 29;
1195
1196                         //START OF MD5TRANSFORM CODE
1197                         //====================================================
1198                         register uint32 a, b, c, d;
1199                         uint32 * pUiIn = (uint32 *) in;
1200
1201                         a = buf[0];
1202                         b = buf[1];
1203                         c = buf[2];
1204                         d = buf[3];
1205
1206                         MD5STEP(F1, a, b, c, d, pUiIn[0] + 0xd76aa478, 7);
1207                         MD5STEP(F1, d, a, b, c, pUiIn[1] + 0xe8c7b756, 12);
1208                         MD5STEP(F1, c, d, a, b, pUiIn[2] + 0x242070db, 17);
1209                         MD5STEP(F1, b, c, d, a, pUiIn[3] + 0xc1bdceee, 22);
1210                         MD5STEP(F1, a, b, c, d, pUiIn[4] + 0xf57c0faf, 7);
1211                         MD5STEP(F1, d, a, b, c, pUiIn[5] + 0x4787c62a, 12);
1212                         MD5STEP(F1, c, d, a, b, pUiIn[6] + 0xa8304613, 17);
1213                         MD5STEP(F1, b, c, d, a, pUiIn[7] + 0xfd469501, 22);
1214                         MD5STEP(F1, a, b, c, d, pUiIn[8] + 0x698098d8, 7);
1215                         MD5STEP(F1, d, a, b, c, pUiIn[9] + 0x8b44f7af, 12);
1216                         MD5STEP(F1, c, d, a, b, pUiIn[10] + 0xffff5bb1, 17);
1217                         MD5STEP(F1, b, c, d, a, pUiIn[11] + 0x895cd7be, 22);
1218                         MD5STEP(F1, a, b, c, d, pUiIn[12] + 0x6b901122, 7);
1219                         MD5STEP(F1, d, a, b, c, pUiIn[13] + 0xfd987193, 12);
1220                         MD5STEP(F1, c, d, a, b, pUiIn[14] + 0xa679438e, 17);
1221                         MD5STEP(F1, b, c, d, a, pUiIn[15] + 0x49b40821, 22);
1222
1223                         MD5STEP(F2, a, b, c, d, pUiIn[1] + 0xf61e2562, 5);
1224                         MD5STEP(F2, d, a, b, c, pUiIn[6] + 0xc040b340, 9);
1225                         MD5STEP(F2, c, d, a, b, pUiIn[11] + 0x265e5a51, 14);
1226                         MD5STEP(F2, b, c, d, a, pUiIn[0] + 0xe9b6c7aa, 20);
1227                         MD5STEP(F2, a, b, c, d, pUiIn[5] + 0xd62f105d, 5);
1228                         MD5STEP(F2, d, a, b, c, pUiIn[10] + 0x02441453, 9);
1229                         MD5STEP(F2, c, d, a, b, pUiIn[15] + 0xd8a1e681, 14);
1230                         MD5STEP(F2, b, c, d, a, pUiIn[4] + 0xe7d3fbc8, 20);
1231                         MD5STEP(F2, a, b, c, d, pUiIn[9] + 0x21e1cde6, 5);
1232                         MD5STEP(F2, d, a, b, c, pUiIn[14] + 0xc33707d6, 9);
1233                         MD5STEP(F2, c, d, a, b, pUiIn[3] + 0xf4d50d87, 14);
1234                         MD5STEP(F2, b, c, d, a, pUiIn[8] + 0x455a14ed, 20);
1235                         MD5STEP(F2, a, b, c, d, pUiIn[13] + 0xa9e3e905, 5);
1236                         MD5STEP(F2, d, a, b, c, pUiIn[2] + 0xfcefa3f8, 9);
1237                         MD5STEP(F2, c, d, a, b, pUiIn[7] + 0x676f02d9, 14);
1238                         MD5STEP(F2, b, c, d, a, pUiIn[12] + 0x8d2a4c8a, 20);
1239
1240                         MD5STEP(F3, a, b, c, d, pUiIn[5] + 0xfffa3942, 4);
1241                         MD5STEP(F3, d, a, b, c, pUiIn[8] + 0x8771f681, 11);
1242                         MD5STEP(F3, c, d, a, b, pUiIn[11] + 0x6d9d6122, 16);
1243                         MD5STEP(F3, b, c, d, a, pUiIn[14] + 0xfde5380c, 23);
1244                         MD5STEP(F3, a, b, c, d, pUiIn[1] + 0xa4beea44, 4);
1245                         MD5STEP(F3, d, a, b, c, pUiIn[4] + 0x4bdecfa9, 11);
1246                         MD5STEP(F3, c, d, a, b, pUiIn[7] + 0xf6bb4b60, 16);
1247                         MD5STEP(F3, b, c, d, a, pUiIn[10] + 0xbebfbc70, 23);
1248                         MD5STEP(F3, a, b, c, d, pUiIn[13] + 0x289b7ec6, 4);
1249                         MD5STEP(F3, d, a, b, c, pUiIn[0] + 0xeaa127fa, 11);
1250                         MD5STEP(F3, c, d, a, b, pUiIn[3] + 0xd4ef3085, 16);
1251                         MD5STEP(F3, b, c, d, a, pUiIn[6] + 0x04881d05, 23);
1252                         MD5STEP(F3, a, b, c, d, pUiIn[9] + 0xd9d4d039, 4);
1253                         MD5STEP(F3, d, a, b, c, pUiIn[12] + 0xe6db99e5, 11);
1254                         MD5STEP(F3, c, d, a, b, pUiIn[15] + 0x1fa27cf8, 16);
1255                         MD5STEP(F3, b, c, d, a, pUiIn[2] + 0xc4ac5665, 23);
1256
1257                         MD5STEP(F4, a, b, c, d, pUiIn[0] + 0xf4292244, 6);
1258                         MD5STEP(F4, d, a, b, c, pUiIn[7] + 0x432aff97, 10);
1259                         MD5STEP(F4, c, d, a, b, pUiIn[14] + 0xab9423a7, 15);
1260                         MD5STEP(F4, b, c, d, a, pUiIn[5] + 0xfc93a039, 21);
1261                         MD5STEP(F4, a, b, c, d, pUiIn[12] + 0x655b59c3, 6);
1262                         MD5STEP(F4, d, a, b, c, pUiIn[3] + 0x8f0ccc92, 10);
1263                         MD5STEP(F4, c, d, a, b, pUiIn[10] + 0xffeff47d, 15);
1264                         MD5STEP(F4, b, c, d, a, pUiIn[1] + 0x85845dd1, 21);
1265                         MD5STEP(F4, a, b, c, d, pUiIn[8] + 0x6fa87e4f, 6);
1266                         MD5STEP(F4, d, a, b, c, pUiIn[15] + 0xfe2ce6e0, 10);
1267                         MD5STEP(F4, c, d, a, b, pUiIn[6] + 0xa3014314, 15);
1268                         MD5STEP(F4, b, c, d, a, pUiIn[13] + 0x4e0811a1, 21);
1269                         MD5STEP(F4, a, b, c, d, pUiIn[4] + 0xf7537e82, 6);
1270                         MD5STEP(F4, d, a, b, c, pUiIn[11] + 0xbd3af235, 10);
1271                         MD5STEP(F4, c, d, a, b, pUiIn[2] + 0x2ad7d2bb, 15);
1272                         MD5STEP(F4, b, c, d, a, pUiIn[9] + 0xeb86d391, 21);
1273
1274                         buf[0] += a;
1275                         buf[1] += b;
1276                         buf[2] += c;
1277                         buf[3] += d;
1278                         //END OF MD5TRANSFORM CODE
1279                         //====================================================
1280                             
1281                         memcpy(pDigest, buf, 16);
1282                         return;
1283
1284                 break;
1285         }
1286 }