1 /**\r
2 * Secure Hashing Tool\r
3 * *\r
4 * Authors:\r
5 * Bob Jamison\r
6 *\r
7 * Copyright (C) 2006 Bob Jamison\r
8 *\r
9 * This library is free software; you can redistribute it and/or\r
10 * modify it under the terms of the GNU Lesser General Public\r
11 * License as published by the Free Software Foundation; either\r
12 * version 2.1 of the License, or (at your option) any later version.\r
13 *\r
14 * This library is distributed in the hope that it will be useful,\r
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
17 * Lesser General Public License for more details.\r
18 *\r
19 * You should have received a copy of the GNU Lesser General Public\r
20 * License along with this library; if not, write to the Free Software\r
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\r
22 */\r
23 \r
24 #include "digest.h"\r
25 \r
26 \r
27 //########################################################################\r
28 //## U T I L\r
29 //########################################################################\r
30 \r
31 /**\r
32 * Use this to print out a 64-bit int when otherwise difficult\r
33 */\r
34 /*\r
35 static void pl(unsigned long long val)\r
36 {\r
37 for (int shift=56 ; shift>=0 ; shift-=8)\r
38 {\r
39 int ch = (val >> shift) & 0xff;\r
40 printf("%02x", ch);\r
41 }\r
42 }\r
43 */\r
44 \r
45 \r
46 static char *hexDigits = "0123456789abcdef";\r
47 \r
48 static std::string toHex(const std::vector<unsigned char> &bytes)\r
49 {\r
50 std::string str;\r
51 std::vector<unsigned char>::const_iterator iter;\r
52 for (iter = bytes.begin() ; iter != bytes.end() ; iter++)\r
53 {\r
54 unsigned char ch = *iter;\r
55 str.push_back(hexDigits[(ch>>4) & 0x0f]);\r
56 str.push_back(hexDigits[(ch ) & 0x0f]);\r
57 }\r
58 return str;\r
59 }\r
60 \r
61 \r
62 //########################################################################\r
63 //## D I G E S T\r
64 //########################################################################\r
65 \r
66 \r
67 /**\r
68 *\r
69 */\r
70 std::string Digest::finishHex()\r
71 {\r
72 std::vector<unsigned char> hash = finish();\r
73 std::string str = toHex(hash);\r
74 return str;\r
75 }\r
76 \r
77 \r
78 //4.1.1 and 4.1.2\r
79 #define SHA_ROTL(X,n) ( ((X) << (n)) | ( ((X) & 0xffffffffL) >> (32-(n))) )\r
80 #define SHA_Ch(x,y,z) ((z)^((x)&((y)^(z))))\r
81 #define SHA_Maj(x,y,z) (((x)&(y))^((z)&((x)^(y))))\r
82 \r
83 \r
84 //########################################################################\r
85 //## S H A 1\r
86 //########################################################################\r
87 \r
88 \r
89 /**\r
90 *\r
91 */\r
92 void Sha1Digest::reset()\r
93 {\r
94 lenW = 0;\r
95 size = 0;\r
96 \r
97 // Initialize H with the magic constants (see FIPS180 for constants)\r
98 H[0] = 0x67452301L;\r
99 H[1] = 0xefcdab89L;\r
100 H[2] = 0x98badcfeL;\r
101 H[3] = 0x10325476L;\r
102 H[4] = 0xc3d2e1f0L;\r
103 \r
104 for (int i = 0 ; i < 80 ; i++)\r
105 W[i] = 0;\r
106 }\r
107 \r
108 \r
109 \r
110 \r
111 void Sha1Digest::hashblock()\r
112 {\r
113 //for (int t = 0; t < 16 ; t++)\r
114 // printf("%2d %08lx\n", t, W[t]);\r
115 \r
116 //see 6.1.2\r
117 for (int t = 16; t < 80 ; t++)\r
118 W[t] = SHA_ROTL((W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]), 1);\r
119 \r
120 unsigned long a = H[0];\r
121 unsigned long b = H[1];\r
122 unsigned long c = H[2];\r
123 unsigned long d = H[3];\r
124 unsigned long e = H[4];\r
125 \r
126 unsigned long T;\r
127 \r
128 int t = 0;\r
129 for ( ; t < 20 ; t++)\r
130 {\r
131 //see 4.1.1 for the boolops on B,C, and D\r
132 T = (SHA_ROTL(a,5) + ((b&c)^(~b&d)) + //Ch(b,c,d))\r
133 e + 0x5a827999L + W[t]) & 0xffffffffL;\r
134 e = d; d = c; c = SHA_ROTL(b, 30); b = a; a = T;\r
135 //printf("%2d %08lx %08lx %08lx %08lx %08lx\n", t, a, b, c, d, e);\r
136 }\r
137 for ( ; t < 40 ; t++)\r
138 {\r
139 T = (SHA_ROTL(a,5) + (b^c^d) +\r
140 e + 0x6ed9eba1L + W[t]) & 0xffffffffL;\r
141 e = d; d = c; c = SHA_ROTL(b, 30); b = a; a = T;\r
142 //printf("%2d %08lx %08lx %08lx %08lx %08lx\n", t, a, b, c, d, e);\r
143 }\r
144 for ( ; t < 60 ; t++)\r
145 {\r
146 T = (SHA_ROTL(a,5) + ((b&c)^(b&d)^(c&d)) +\r
147 e + 0x8f1bbcdcL + W[t]) & 0xffffffffL;\r
148 e = d; d = c; c = SHA_ROTL(b, 30); b = a; a = T;\r
149 //printf("%2d %08lx %08lx %08lx %08lx %08lx\n", t, a, b, c, d, e);\r
150 }\r
151 for ( ; t < 80 ; t++)\r
152 {\r
153 T = (SHA_ROTL(a,5) + (b^c^d) +\r
154 e + 0xca62c1d6L + W[t]) & 0xffffffffL;\r
155 e = d; d = c; c = SHA_ROTL(b, 30); b = a; a = T;\r
156 //printf("%2d %08lx %08lx %08lx %08lx %08lx\n", t, a, b, c, d, e);\r
157 }\r
158 \r
159 H[0] += a;\r
160 H[1] += b;\r
161 H[2] += c;\r
162 H[3] += d;\r
163 H[4] += e;\r
164 }\r
165 \r
166 \r
167 /**\r
168 *\r
169 */\r
170 void Sha1Digest::update(unsigned char val)\r
171 {\r
172 int wordNr = lenW >> 2;\r
173 W[wordNr] <<= 8;\r
174 W[wordNr] |= (unsigned long)val;\r
175 size += 8;\r
176 lenW++;\r
177 if (lenW >= 64)\r
178 {\r
179 hashblock();\r
180 lenW = 0;\r
181 }\r
182 }\r
183 \r
184 \r
185 /**\r
186 *\r
187 */\r
188 std::vector<unsigned char> Sha1Digest::finish()\r
189 {\r
190 //save our size before padding\r
191 unsigned long long sizeOut = size;\r
192 \r
193 // Pad with a binary 1 (0x80)\r
194 update((unsigned char)0x80);\r
195 //append 0's to make a 56-byte buf.\r
196 //use mod, so that we will loop around once if already over 56\r
197 while (lenW != 56)\r
198 update((unsigned char)0x00);\r
199 //append 64-bit size\r
200 for (int shift = 56 ; shift>=0 ; shift-= 8)\r
201 {\r
202 unsigned char ch = (unsigned char)((sizeOut >> shift) & 0xff);\r
203 update(ch);\r
204 }\r
205 \r
206 // Output hash\r
207 std::vector<unsigned char> ret;\r
208 for (int wordNr = 0 ; wordNr < 5 ; wordNr++)\r
209 {\r
210 ret.push_back((unsigned char)((H[wordNr] >> 24) & 0xff));\r
211 ret.push_back((unsigned char)((H[wordNr] >> 16) & 0xff));\r
212 ret.push_back((unsigned char)((H[wordNr] >> 8) & 0xff));\r
213 ret.push_back((unsigned char)((H[wordNr] ) & 0xff));\r
214 }\r
215 \r
216 // Re-initialize the context (also zeroizes contents)\r
217 reset();\r
218 \r
219 return ret;\r
220 \r
221 }\r
222 \r
223 \r
224 //########################################################################\r
225 //## SHA224\r
226 //########################################################################\r
227 \r
228 \r
229 /**\r
230 * SHA-224 and SHA-512 share the same operations and constants\r
231 */ \r
232 \r
233 #define SHA_Rot32(x,s) (((x) >> s) | ((x) << (32 - s)))\r
234 #define SHA_SIGMA0(x) (SHA_Rot32(x, 2) ^ SHA_Rot32(x, 13) ^ SHA_Rot32(x, 22))\r
235 #define SHA_SIGMA1(x) (SHA_Rot32(x, 6) ^ SHA_Rot32(x, 11) ^ SHA_Rot32(x, 25))\r
236 #define SHA_sigma0(x) (SHA_Rot32(x, 7) ^ SHA_Rot32(x, 18) ^ ((x) >> 3))\r
237 #define SHA_sigma1(x) (SHA_Rot32(x, 17) ^ SHA_Rot32(x, 19) ^ ((x) >> 10))\r
238 \r
239 \r
240 static unsigned long sha256constants[64] =\r
241 {\r
242 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,\r
243 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,\r
244 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,\r
245 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,\r
246 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,\r
247 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,\r
248 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,\r
249 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,\r
250 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,\r
251 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,\r
252 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,\r
253 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,\r
254 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,\r
255 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,\r
256 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,\r
257 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL\r
258 };\r
259 \r
260 \r
261 \r
262 \r
263 \r
264 /**\r
265 *\r
266 */\r
267 void Sha224Digest::reset()\r
268 {\r
269 lenW = 0;\r
270 size = 0;\r
271 \r
272 // Initialize H with the magic constants (see FIPS180 for constants)\r
273 H[0] = 0xc1059ed8L;\r
274 H[1] = 0x367cd507L;\r
275 H[2] = 0x3070dd17L;\r
276 H[3] = 0xf70e5939L;\r
277 H[4] = 0xffc00b31L;\r
278 H[5] = 0x68581511L;\r
279 H[6] = 0x64f98fa7L;\r
280 H[7] = 0xbefa4fa4L;\r
281 \r
282 for (int i = 0 ; i < 64 ; i++)\r
283 W[i] = 0;\r
284 }\r
285 \r
286 \r
287 \r
288 \r
289 \r
290 void Sha224Digest::hashblock()\r
291 {\r
292 //for (int t = 0; t < 16 ; t++)\r
293 // printf("%2d %08lx\n", t, W[t]);\r
294 \r
295 //see 6.2.2\r
296 for (int t = 16; t < 64 ; t++)\r
297 W[t] = SHA_sigma1(W[t-2]) + W[t-7] + SHA_sigma0(W[t-15]) + W[t-16];\r
298 \r
299 unsigned long a = H[0];\r
300 unsigned long b = H[1];\r
301 unsigned long c = H[2];\r
302 unsigned long d = H[3];\r
303 unsigned long e = H[4];\r
304 unsigned long f = H[5];\r
305 unsigned long g = H[6];\r
306 unsigned long h = H[7];\r
307 \r
308 for (int t = 0 ; t < 64 ; t++)\r
309 {\r
310 //see 4.1.1 for the boolops\r
311 unsigned long T1 = h + SHA_SIGMA1(e) + SHA_Ch(e,f,g) +\r
312 sha256constants[t] + W[t];\r
313 unsigned long T2 = SHA_SIGMA0(a) + SHA_Maj(a,b,c);\r
314 h = g; g = f; f = e; e = d + T1 ; d = c; c = b; b = a; a = T1 + T2;\r
315 //printf("%2d %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",\r
316 // t, a, b, c, d, e, f, g, h);\r
317 }\r
318 \r
319 H[0] += a;\r
320 H[1] += b;\r
321 H[2] += c;\r
322 H[3] += d;\r
323 H[4] += e;\r
324 H[5] += f;\r
325 H[6] += g;\r
326 H[7] += h;\r
327 }\r
328 \r
329 \r
330 /**\r
331 *\r
332 */\r
333 void Sha224Digest::update(unsigned char val)\r
334 {\r
335 int wordNr = lenW >> 2;\r
336 W[wordNr] <<= 8;\r
337 W[wordNr] |= (unsigned long)val;\r
338 size += 8;\r
339 lenW++;\r
340 if (lenW >= 64)\r
341 {\r
342 hashblock();\r
343 lenW = 0;\r
344 }\r
345 }\r
346 \r
347 \r
348 /**\r
349 *\r
350 */\r
351 std::vector<unsigned char> Sha224Digest::finish()\r
352 {\r
353 //save our size before padding\r
354 unsigned long long sizeOut = size;\r
355 \r
356 // Pad with a binary 1 (0x80)\r
357 update((unsigned char)0x80);\r
358 //append 0's to make a 56-byte buf.\r
359 //use mod, so that we will loop around once if already over 56\r
360 while (lenW != 56)\r
361 update((unsigned char)0x00);\r
362 //append 64-bit size\r
363 for (int shift = 56 ; shift>=0 ; shift-= 8)\r
364 {\r
365 unsigned char ch = (unsigned char)((sizeOut >> shift) & 0xff);\r
366 update(ch);\r
367 }\r
368 \r
369 // Output hash\r
370 std::vector<unsigned char> ret;\r
371 for (int wordNr = 0 ; wordNr < 7 ; wordNr++)\r
372 {\r
373 ret.push_back((unsigned char)((H[wordNr] >> 24) & 0xff));\r
374 ret.push_back((unsigned char)((H[wordNr] >> 16) & 0xff));\r
375 ret.push_back((unsigned char)((H[wordNr] >> 8) & 0xff));\r
376 ret.push_back((unsigned char)((H[wordNr] ) & 0xff));\r
377 }\r
378 \r
379 // Re-initialize the context (also zeroizes contents)\r
380 reset();\r
381 \r
382 return ret;\r
383 \r
384 }\r
385 \r
386 //########################################################################\r
387 //## SHA256\r
388 //########################################################################\r
389 \r
390 \r
391 \r
392 \r
393 \r
394 /**\r
395 *\r
396 */\r
397 void Sha256Digest::reset()\r
398 {\r
399 lenW = 0;\r
400 size = 0;\r
401 \r
402 // Initialize H with the magic constants (see FIPS180 for constants)\r
403 H[0] = 0x6a09e667L;\r
404 H[1] = 0xbb67ae85L;\r
405 H[2] = 0x3c6ef372L;\r
406 H[3] = 0xa54ff53aL;\r
407 H[4] = 0x510e527fL;\r
408 H[5] = 0x9b05688cL;\r
409 H[6] = 0x1f83d9abL;\r
410 H[7] = 0x5be0cd19L;\r
411 \r
412 for (int i = 0 ; i < 64 ; i++)\r
413 W[i] = 0;\r
414 }\r
415 \r
416 \r
417 \r
418 \r
419 \r
420 void Sha256Digest::hashblock()\r
421 {\r
422 //for (int t = 0; t < 16 ; t++)\r
423 // printf("%2d %08lx\n", t, W[t]);\r
424 \r
425 //see 6.2.2\r
426 for (int t = 16; t < 64 ; t++)\r
427 W[t] = SHA_sigma1(W[t-2]) + W[t-7] + SHA_sigma0(W[t-15]) + W[t-16];\r
428 \r
429 unsigned long a = H[0];\r
430 unsigned long b = H[1];\r
431 unsigned long c = H[2];\r
432 unsigned long d = H[3];\r
433 unsigned long e = H[4];\r
434 unsigned long f = H[5];\r
435 unsigned long g = H[6];\r
436 unsigned long h = H[7];\r
437 \r
438 for (int t = 0 ; t < 64 ; t++)\r
439 {\r
440 //see 4.1.1 for the boolops\r
441 unsigned long T1 = h + SHA_SIGMA1(e) + SHA_Ch(e,f,g) +\r
442 sha256constants[t] + W[t];\r
443 unsigned long T2 = SHA_SIGMA0(a) + SHA_Maj(a,b,c);\r
444 h = g; g = f; f = e; e = d + T1 ; d = c; c = b; b = a; a = T1 + T2;\r
445 //printf("%2d %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",\r
446 // t, a, b, c, d, e, f, g, h);\r
447 }\r
448 \r
449 H[0] += a;\r
450 H[1] += b;\r
451 H[2] += c;\r
452 H[3] += d;\r
453 H[4] += e;\r
454 H[5] += f;\r
455 H[6] += g;\r
456 H[7] += h;\r
457 }\r
458 \r
459 \r
460 /**\r
461 *\r
462 */\r
463 void Sha256Digest::update(unsigned char val)\r
464 {\r
465 int wordNr = lenW >> 2;\r
466 W[wordNr] <<= 8;\r
467 W[wordNr] |= (unsigned long)val;\r
468 size += 8;\r
469 lenW++;\r
470 if (lenW >= 64)\r
471 {\r
472 hashblock();\r
473 lenW = 0;\r
474 }\r
475 }\r
476 \r
477 \r
478 /**\r
479 *\r
480 */\r
481 std::vector<unsigned char> Sha256Digest::finish()\r
482 {\r
483 //save our size before padding\r
484 unsigned long long sizeOut = size;\r
485 \r
486 // Pad with a binary 1 (0x80)\r
487 update((unsigned char)0x80);\r
488 //append 0's to make a 56-byte buf.\r
489 //use mod, so that we will loop around once if already over 56\r
490 while (lenW != 56)\r
491 update((unsigned char)0x00);\r
492 //append 64-bit size\r
493 for (int shift = 56 ; shift>=0 ; shift-= 8)\r
494 {\r
495 unsigned char ch = (unsigned char)((sizeOut >> shift) & 0xff);\r
496 update(ch);\r
497 }\r
498 \r
499 // Output hash\r
500 std::vector<unsigned char> ret;\r
501 for (int wordNr = 0 ; wordNr < 8 ; wordNr++)\r
502 {\r
503 ret.push_back((unsigned char)((H[wordNr] >> 24) & 0xff));\r
504 ret.push_back((unsigned char)((H[wordNr] >> 16) & 0xff));\r
505 ret.push_back((unsigned char)((H[wordNr] >> 8) & 0xff));\r
506 ret.push_back((unsigned char)((H[wordNr] ) & 0xff));\r
507 }\r
508 \r
509 // Re-initialize the context (also zeroizes contents)\r
510 reset();\r
511 \r
512 return ret;\r
513 \r
514 }\r
515 \r
516 \r
517 \r
518 //########################################################################\r
519 //## SHA384\r
520 //########################################################################\r
521 \r
522 /**\r
523 * SHA-384 and SHA-512 share the same operations and constants\r
524 */\r
525 \r
526 #undef SHA_SIGMA0\r
527 #undef SHA_SIGMA1\r
528 #undef SHA_sigma0\r
529 #undef SHA_sigma1\r
530 \r
531 #define SHA_Rot64(x,s) (((x) >> s) | ((x) << (64 - s)))\r
532 #define SHA_SIGMA0(x) (SHA_Rot64(x, 28) ^ SHA_Rot64(x, 34) ^ SHA_Rot64(x, 39))\r
533 #define SHA_SIGMA1(x) (SHA_Rot64(x, 14) ^ SHA_Rot64(x, 18) ^ SHA_Rot64(x, 41))\r
534 #define SHA_sigma0(x) (SHA_Rot64(x, 1) ^ SHA_Rot64(x, 8) ^ ((x) >> 7))\r
535 #define SHA_sigma1(x) (SHA_Rot64(x, 19) ^ SHA_Rot64(x, 61) ^ ((x) >> 6))\r
536 \r
537 \r
538 static unsigned long long sha512constants[80] =\r
539 {\r
540 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,\r
541 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,\r
542 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,\r
543 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,\r
544 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,\r
545 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,\r
546 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,\r
547 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,\r
548 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,\r
549 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,\r
550 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,\r
551 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,\r
552 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,\r
553 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,\r
554 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,\r
555 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,\r
556 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,\r
557 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,\r
558 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,\r
559 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,\r
560 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,\r
561 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,\r
562 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,\r
563 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,\r
564 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,\r
565 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,\r
566 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,\r
567 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,\r
568 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,\r
569 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,\r
570 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,\r
571 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,\r
572 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,\r
573 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,\r
574 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,\r
575 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,\r
576 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,\r
577 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,\r
578 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,\r
579 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL\r
580 };\r
581 \r
582 \r
583 \r
584 \r
585 /**\r
586 *\r
587 */\r
588 void Sha384Digest::reset()\r
589 {\r
590 lenW = 0;\r
591 size = 0;\r
592 \r
593 // SHA-384 differs from SHA-512 by these constants\r
594 H[0] = 0xcbbb9d5dc1059ed8ULL;\r
595 H[1] = 0x629a292a367cd507ULL;\r
596 H[2] = 0x9159015a3070dd17ULL;\r
597 H[3] = 0x152fecd8f70e5939ULL;\r
598 H[4] = 0x67332667ffc00b31ULL;\r
599 H[5] = 0x8eb44a8768581511ULL;\r
600 H[6] = 0xdb0c2e0d64f98fa7ULL;\r
601 H[7] = 0x47b5481dbefa4fa4ULL;\r
602 \r
603 for (int i = 0 ; i < 80 ; i++)\r
604 W[i] = 0;\r
605 }\r
606 \r
607 \r
608 \r
609 \r
610 \r
611 void Sha384Digest::hashblock()\r
612 {\r
613 /*\r
614 for (int t = 0; t < 16 ; t++)\r
615 {\r
616 printf("%2d ", t);\r
617 pl(W[t]);\r
618 printf("\n");\r
619 }\r
620 */\r
621 \r
622 //see 6.2.2\r
623 for (int t = 16; t < 80 ; t++)\r
624 W[t] = SHA_sigma1(W[t-2]) + W[t-7] + SHA_sigma0(W[t-15]) + W[t-16];\r
625 \r
626 unsigned long long a = H[0];\r
627 unsigned long long b = H[1];\r
628 unsigned long long c = H[2];\r
629 unsigned long long d = H[3];\r
630 unsigned long long e = H[4];\r
631 unsigned long long f = H[5];\r
632 unsigned long long g = H[6];\r
633 unsigned long long h = H[7];\r
634 \r
635 for (int t = 0 ; t < 80 ; t++)\r
636 {\r
637 //see 4.1.1 for the boolops\r
638 unsigned long long T1 = h + SHA_SIGMA1(e) + SHA_Ch(e,f,g) +\r
639 sha512constants[t] + W[t];\r
640 unsigned long long T2 = SHA_SIGMA0(a) + SHA_Maj(a,b,c);\r
641 h = g; g = f; f = e; e = d + T1 ; d = c; c = b; b = a; a = T1 + T2;\r
642 }\r
643 \r
644 H[0] += a;\r
645 H[1] += b;\r
646 H[2] += c;\r
647 H[3] += d;\r
648 H[4] += e;\r
649 H[5] += f;\r
650 H[6] += g;\r
651 H[7] += h;\r
652 }\r
653 \r
654 \r
655 /**\r
656 *\r
657 */\r
658 void Sha384Digest::update(unsigned char val)\r
659 {\r
660 int wordNr = lenW >> 3;\r
661 W[wordNr] <<= 8;\r
662 W[wordNr] |= (unsigned long)val;\r
663 size += 8;\r
664 lenW++;\r
665 if (lenW >= 128)\r
666 {\r
667 hashblock();\r
668 lenW = 0;\r
669 }\r
670 }\r
671 \r
672 \r
673 /**\r
674 *\r
675 */\r
676 std::vector<unsigned char> Sha384Digest::finish()\r
677 {\r
678 //save our size before padding\r
679 unsigned long long sizeOut = size;\r
680 \r
681 // Pad with a binary 1 (0x80)\r
682 update((unsigned char)0x80);\r
683 //append 0's to make a 112-byte buf.\r
684 //we will loop around once if already over 112\r
685 while (lenW != 112)\r
686 update((unsigned char)0x00);\r
687 \r
688 //append 128-bit size\r
689 for (int i = 0 ; i < 8 ; i++) //64 upper bits\r
690 update((unsigned char)0x00);\r
691 for (int shift = 56 ; shift>=0 ; shift-= 8) //64 lower length bits\r
692 {\r
693 unsigned char ch = (unsigned char)((sizeOut >> shift) & 0xff);\r
694 update(ch);\r
695 }\r
696 \r
697 // Output hash\r
698 //for SHA-384, we use the left-most 6 64-bit words\r
699 std::vector<unsigned char> ret;\r
700 for (int wordNr = 0 ; wordNr < 6 ; wordNr++)\r
701 {\r
702 ret.push_back((unsigned char)((H[wordNr] >> 56) & 0xff));\r
703 ret.push_back((unsigned char)((H[wordNr] >> 48) & 0xff));\r
704 ret.push_back((unsigned char)((H[wordNr] >> 40) & 0xff));\r
705 ret.push_back((unsigned char)((H[wordNr] >> 32) & 0xff));\r
706 ret.push_back((unsigned char)((H[wordNr] >> 24) & 0xff));\r
707 ret.push_back((unsigned char)((H[wordNr] >> 16) & 0xff));\r
708 ret.push_back((unsigned char)((H[wordNr] >> 8) & 0xff));\r
709 ret.push_back((unsigned char)((H[wordNr] ) & 0xff));\r
710 }\r
711 \r
712 // Re-initialize the context (also zeroizes contents)\r
713 reset();\r
714 \r
715 return ret;\r
716 \r
717 }\r
718 \r
719 \r
720 //########################################################################\r
721 //## SHA512\r
722 //########################################################################\r
723 \r
724 \r
725 \r
726 \r
727 \r
728 /**\r
729 *\r
730 */\r
731 void Sha512Digest::reset()\r
732 {\r
733 lenW = 0;\r
734 size = 0;\r
735 \r
736 // Initialize H with the magic constants (see FIPS180 for constants)\r
737 H[0] = 0x6a09e667f3bcc908ULL;\r
738 H[1] = 0xbb67ae8584caa73bULL;\r
739 H[2] = 0x3c6ef372fe94f82bULL;\r
740 H[3] = 0xa54ff53a5f1d36f1ULL;\r
741 H[4] = 0x510e527fade682d1ULL;\r
742 H[5] = 0x9b05688c2b3e6c1fULL;\r
743 H[6] = 0x1f83d9abfb41bd6bULL;\r
744 H[7] = 0x5be0cd19137e2179ULL;\r
745 \r
746 for (int i = 0 ; i < 80 ; i++)\r
747 W[i] = 0;\r
748 }\r
749 \r
750 \r
751 \r
752 \r
753 \r
754 void Sha512Digest::hashblock()\r
755 {\r
756 /*\r
757 for (int t = 0; t < 16 ; t++)\r
758 {\r
759 printf("%2d ", t);\r
760 pl(W[t]);\r
761 printf("\n");\r
762 }\r
763 */\r
764 \r
765 //see 6.2.2\r
766 for (int t = 16; t < 80 ; t++)\r
767 W[t] = SHA_sigma1(W[t-2]) + W[t-7] + SHA_sigma0(W[t-15]) + W[t-16];\r
768 \r
769 unsigned long long a = H[0];\r
770 unsigned long long b = H[1];\r
771 unsigned long long c = H[2];\r
772 unsigned long long d = H[3];\r
773 unsigned long long e = H[4];\r
774 unsigned long long f = H[5];\r
775 unsigned long long g = H[6];\r
776 unsigned long long h = H[7];\r
777 \r
778 for (int t = 0 ; t < 80 ; t++)\r
779 {\r
780 //see 4.1.1 for the boolops\r
781 unsigned long long T1 = h + SHA_SIGMA1(e) + SHA_Ch(e,f,g) +\r
782 sha512constants[t] + W[t];\r
783 unsigned long long T2 = SHA_SIGMA0(a) + SHA_Maj(a,b,c);\r
784 h = g; g = f; f = e; e = d + T1 ; d = c; c = b; b = a; a = T1 + T2;\r
785 }\r
786 \r
787 H[0] += a;\r
788 H[1] += b;\r
789 H[2] += c;\r
790 H[3] += d;\r
791 H[4] += e;\r
792 H[5] += f;\r
793 H[6] += g;\r
794 H[7] += h;\r
795 }\r
796 \r
797 \r
798 /**\r
799 *\r
800 */\r
801 void Sha512Digest::update(unsigned char val)\r
802 {\r
803 int wordNr = lenW >> 3;\r
804 W[wordNr] <<= 8;\r
805 W[wordNr] |= (unsigned long)val;\r
806 size += 8;\r
807 lenW++;\r
808 if (lenW >= 128)\r
809 {\r
810 hashblock();\r
811 lenW = 0;\r
812 }\r
813 }\r
814 \r
815 \r
816 /**\r
817 *\r
818 */\r
819 std::vector<unsigned char> Sha512Digest::finish()\r
820 {\r
821 //save our size before padding\r
822 unsigned long long sizeOut = size;\r
823 \r
824 // Pad with a binary 1 (0x80)\r
825 update((unsigned char)0x80);\r
826 //append 0's to make a 112-byte buf.\r
827 //we will loop around once if already over 112\r
828 while (lenW != 112)\r
829 update((unsigned char)0x00);\r
830 \r
831 //append 128-bit size\r
832 for (int i = 0 ; i < 8 ; i++) //64 upper bits\r
833 update((unsigned char)0x00);\r
834 for (int shift = 56 ; shift>=0 ; shift-= 8) //64 lower length bits\r
835 {\r
836 unsigned char ch = (unsigned char)((sizeOut >> shift) & 0xff);\r
837 update(ch);\r
838 }\r
839 \r
840 // Output hash\r
841 std::vector<unsigned char> ret;\r
842 for (int wordNr = 0 ; wordNr < 8 ; wordNr++)\r
843 {\r
844 ret.push_back((unsigned char)((H[wordNr] >> 56) & 0xff));\r
845 ret.push_back((unsigned char)((H[wordNr] >> 48) & 0xff));\r
846 ret.push_back((unsigned char)((H[wordNr] >> 40) & 0xff));\r
847 ret.push_back((unsigned char)((H[wordNr] >> 32) & 0xff));\r
848 ret.push_back((unsigned char)((H[wordNr] >> 24) & 0xff));\r
849 ret.push_back((unsigned char)((H[wordNr] >> 16) & 0xff));\r
850 ret.push_back((unsigned char)((H[wordNr] >> 8) & 0xff));\r
851 ret.push_back((unsigned char)((H[wordNr] ) & 0xff));\r
852 }\r
853 \r
854 // Re-initialize the context (also zeroizes contents)\r
855 reset();\r
856 \r
857 return ret;\r
858 \r
859 }\r
860 \r
861 \r
862 \r
863 //########################################################################\r
864 //## M D 5\r
865 //########################################################################\r
866 \r
867 static int md5r[64] =\r
868 {\r
869 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, \r
870 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,\r
871 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,\r
872 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21\r
873 };\r
874 \r
875 static unsigned long md5k[64] =\r
876 {\r
877 0xd76aa478L, 0xe8c7b756L, 0x242070dbL, 0xc1bdceeeL, \r
878 0xf57c0fafL, 0x4787c62aL, 0xa8304613L, 0xfd469501L, \r
879 0x698098d8L, 0x8b44f7afL, 0xffff5bb1L, 0x895cd7beL, \r
880 0x6b901122L, 0xfd987193L, 0xa679438eL, 0x49b40821L, \r
881 0xf61e2562L, 0xc040b340L, 0x265e5a51L, 0xe9b6c7aaL, \r
882 0xd62f105dL, 0x02441453L, 0xd8a1e681L, 0xe7d3fbc8L, \r
883 0x21e1cde6L, 0xc33707d6L, 0xf4d50d87L, 0x455a14edL, \r
884 0xa9e3e905L, 0xfcefa3f8L, 0x676f02d9L, 0x8d2a4c8aL, \r
885 0xfffa3942L, 0x8771f681L, 0x6d9d6122L, 0xfde5380cL, \r
886 0xa4beea44L, 0x4bdecfa9L, 0xf6bb4b60L, 0xbebfbc70L, \r
887 0x289b7ec6L, 0xeaa127faL, 0xd4ef3085L, 0x04881d05L, \r
888 0xd9d4d039L, 0xe6db99e5L, 0x1fa27cf8L, 0xc4ac5665L, \r
889 0xf4292244L, 0x432aff97L, 0xab9423a7L, 0xfc93a039L, \r
890 0x655b59c3L, 0x8f0ccc92L, 0xffeff47dL, 0x85845dd1L, \r
891 0x6fa87e4fL, 0xfe2ce6e0L, 0xa3014314L, 0x4e0811a1L, \r
892 0xf7537e82L, 0xbd3af235L, 0x2ad7d2bbL, 0xeb86d391L\r
893 };\r
894 \r
895 #define MD5_ROTL(X,n) (((X) << (n)) | ((X) >> (32-(n))))\r
896 \r
897 \r
898 /**\r
899 *\r
900 */\r
901 void Md5Digest::reset()\r
902 {\r
903 size = 0;\r
904 lenW = 0;\r
905 \r
906 hash[0] = 0x67452301L;\r
907 hash[1] = 0xefcdab89L;\r
908 hash[2] = 0x98badcfeL;\r
909 hash[3] = 0x10325476L;\r
910 \r
911 for (int i = 0 ; i < 64 ; i++)\r
912 W[i] = 0;\r
913 \r
914 }\r
915 \r
916 \r
917 \r
918 \r
919 \r
920 \r
921 /**\r
922 *\r
923 */\r
924 void Md5Digest::hashblock()\r
925 {\r
926 //for (int t = 0; t < 16 ; t++)\r
927 // printf("%2d %08lx\n", t, W[t]);\r
928 \r
929 unsigned long a = hash[0];\r
930 unsigned long b = hash[1];\r
931 unsigned long c = hash[2];\r
932 unsigned long d = hash[3];\r
933 \r
934 int t = 0;\r
935 for ( ; t < 16 ; t++)\r
936 {\r
937 unsigned long f = d ^ ( b & ( c ^ d));\r
938 unsigned int g = t;\r
939 unsigned long temp = d; d = c; c = b;\r
940 b += MD5_ROTL(((a + f + md5k[t] + W[g])), md5r[t]);\r
941 a = temp;\r
942 //printf("%2d %08lx %08lx %08lx %08lx\n", t, a, b, c, d);\r
943 }\r
944 for ( ; t < 32 ; t++)\r
945 {\r
946 unsigned long f = c ^ ( d & ( b ^ c));\r
947 unsigned int g = (5 * t + 1) & 0xf;\r
948 unsigned long temp = d; d = c; c = b;\r
949 b += MD5_ROTL(((a + f + md5k[t] + W[g])), md5r[t]);\r
950 a = temp;\r
951 }\r
952 for ( ; t < 48 ; t++)\r
953 {\r
954 unsigned long f = b ^ c ^ d;\r
955 unsigned int g = (3 * t + 5) & 0xf;\r
956 unsigned long temp = d; d = c; c = b;\r
957 b += MD5_ROTL(((a + f + md5k[t] + W[g])), md5r[t]);\r
958 a = temp;\r
959 }\r
960 for ( ; t < 64 ; t++)\r
961 {\r
962 unsigned long f = c ^ (b | ~d);\r
963 unsigned int g = (7 * t) & 0xf;\r
964 unsigned long temp = d; d = c; c = b;\r
965 b += MD5_ROTL(((a + f + md5k[t] + W[g])), md5r[t]);\r
966 a = temp;\r
967 }\r
968 \r
969 hash[0] += a;\r
970 hash[1] += b;\r
971 hash[2] += c;\r
972 hash[3] += d;\r
973 }\r
974 \r
975 \r
976 /**\r
977 *\r
978 */\r
979 void Md5Digest::update(unsigned char val)\r
980 {\r
981 int wordNr = lenW >> 2;\r
982 /*\r
983 W[wordNr] <<= 8;\r
984 W[wordNr] |= (unsigned long)val;\r
985 */\r
986 W[wordNr] = ( (W[wordNr] >> 8) & 0x00ffffff ) |\r
987 ( ((unsigned long)val) << 24 );\r
988 size += 8;\r
989 lenW++;\r
990 if (lenW >= 64)\r
991 {\r
992 hashblock();\r
993 lenW = 0;\r
994 }\r
995 }\r
996 \r
997 \r
998 \r
999 \r
1000 /**\r
1001 *\r
1002 */\r
1003 std::vector<unsigned char> Md5Digest::finish()\r
1004 {\r
1005 //save our size before padding\r
1006 unsigned long long sizeOut = size;\r
1007 \r
1008 // Pad with a binary 1 (0x80)\r
1009 update((unsigned char)0x80);\r
1010 //append 0's to make a 56-byte buf.\r
1011 //use mod, so that we will loop around once if already over 56\r
1012 while (lenW != 56)\r
1013 update((unsigned char)0x00);\r
1014 \r
1015 \r
1016 //Append the length. Lower 32 bits first\r
1017 update( (unsigned char) ((sizeOut ) & 0xff));\r
1018 update( (unsigned char) ((sizeOut>> 8) & 0xff));\r
1019 update( (unsigned char) ((sizeOut>>16) & 0xff));\r
1020 update( (unsigned char) ((sizeOut>>24) & 0xff));\r
1021 update( (unsigned char) ((sizeOut>>32) & 0xff));\r
1022 update( (unsigned char) ((sizeOut>>40) & 0xff));\r
1023 update( (unsigned char) ((sizeOut>>48) & 0xff));\r
1024 update( (unsigned char) ((sizeOut>>56) & 0xff));\r
1025 \r
1026 //Output hash\r
1027 std::vector<unsigned char> ret;\r
1028 for (int wordNr = 0 ; wordNr<4 ; wordNr++)\r
1029 {\r
1030 unsigned long w = hash[wordNr];\r
1031 ret.push_back( (unsigned char) ((w ) & 0xff) );\r
1032 ret.push_back( (unsigned char) ((w >> 8) & 0xff) );\r
1033 ret.push_back( (unsigned char) ((w >> 16) & 0xff) );\r
1034 ret.push_back( (unsigned char) ((w >> 24) & 0xff) );\r
1035 }\r
1036 \r
1037 // Re-initialize the context (also zeroizes contents)\r
1038 reset();\r
1039 \r
1040 return ret;\r
1041 }\r
1042 \r
1043 \r
1044 \r
1045 \r
1046 \r
1047 \r
1048 //########################################################################\r
1049 //## T E S T S\r
1050 //########################################################################\r
1051 \r
1052 /**\r
1053 * Compile this file alone with -DDIGEST_TEST to run the\r
1054 * tests below:\r
1055 * > gcc -DDIGEST_TEST digest.cpp -o digest\r
1056 * > digest \r
1057 */\r
1058 \r
1059 #ifdef DIGEST_TEST\r
1060 \r
1061 \r
1062 typedef struct\r
1063 {\r
1064 char *msg;\r
1065 char *val;\r
1066 } TestPair;\r
1067 \r
1068 static TestPair md5tests[] =\r
1069 {\r
1070 {\r
1071 "",\r
1072 "d41d8cd98f00b204e9800998ecf8427e"\r
1073 },\r
1074 {\r
1075 "a",\r
1076 "0cc175b9c0f1b6a831c399e269772661"\r
1077 },\r
1078 {\r
1079 "abc",\r
1080 "900150983cd24fb0d6963f7d28e17f72"\r
1081 },\r
1082 {\r
1083 "message digest",\r
1084 "f96b697d7cb7938d525a2f31aaf161d0"\r
1085 },\r
1086 {\r
1087 "abcdefghijklmnopqrstuvwxyz",\r
1088 "c3fcd3d76192e4007dfb496cca67e13b"\r
1089 },\r
1090 {\r
1091 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",\r
1092 "d174ab98d277d9f5a5611c2c9f419d9f"\r
1093 },\r
1094 {\r
1095 "12345678901234567890123456789012345678901234567890123456789012345678901234567890",\r
1096 "57edf4a22be3c955ac49da2e2107b67a"\r
1097 },\r
1098 {\r
1099 NULL,\r
1100 NULL\r
1101 }\r
1102 };\r
1103 \r
1104 \r
1105 \r
1106 static TestPair sha1tests[] =\r
1107 {\r
1108 {\r
1109 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",\r
1110 "84983e441c3bd26ebaae4aa1f95129e5e54670f1"\r
1111 },\r
1112 {\r
1113 NULL,\r
1114 NULL\r
1115 }\r
1116 };\r
1117 \r
1118 static TestPair sha224tests[] =\r
1119 {\r
1120 {\r
1121 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",\r
1122 "75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525"\r
1123 },\r
1124 {\r
1125 NULL,\r
1126 NULL\r
1127 }\r
1128 };\r
1129 \r
1130 static TestPair sha256tests[] =\r
1131 {\r
1132 {\r
1133 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",\r
1134 "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"\r
1135 },\r
1136 {\r
1137 NULL,\r
1138 NULL\r
1139 }\r
1140 };\r
1141 \r
1142 static TestPair sha384tests[] =\r
1143 {\r
1144 {\r
1145 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"\r
1146 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",\r
1147 "09330c33f71147e83d192fc782cd1b4753111b173b3b05d22fa08086e3b0f712"\r
1148 "fcc7c71a557e2db966c3e9fa91746039"\r
1149 },\r
1150 {\r
1151 NULL,\r
1152 NULL\r
1153 }\r
1154 };\r
1155 \r
1156 static TestPair sha512tests[] =\r
1157 {\r
1158 {\r
1159 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"\r
1160 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",\r
1161 "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018"\r
1162 "501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909"\r
1163 },\r
1164 {\r
1165 NULL,\r
1166 NULL\r
1167 }\r
1168 };\r
1169 \r
1170 \r
1171 bool hashTests(Digest &digest, TestPair *tp)\r
1172 {\r
1173 for (TestPair *pair = tp ; pair->msg ; pair++)\r
1174 {\r
1175 digest.reset();\r
1176 std::string msg = pair->msg;\r
1177 std::string val = pair->val;\r
1178 digest.append(msg);\r
1179 std::string res = digest.finishHex();\r
1180 printf("### Msg '%s':\n hash '%s'\n exp '%s'\n",\r
1181 msg.c_str(), res.c_str(), val.c_str());\r
1182 if (res != val)\r
1183 {\r
1184 printf("ERROR: Hash mismatch\n");\r
1185 return false;\r
1186 }\r
1187 }\r
1188 return true;\r
1189 }\r
1190 \r
1191 \r
1192 bool millionATest(Digest &digest, const std::string &exp)\r
1193 {\r
1194 digest.reset();\r
1195 for (int i=0 ; i<1000000 ; i++)\r
1196 digest.append('a');\r
1197 std::string res = digest.finishHex();\r
1198 printf("\nHash of 1,000,000 'a'\n calc %s\n exp %s\n",\r
1199 res.c_str(), exp.c_str());\r
1200 if (res != exp)\r
1201 {\r
1202 printf("ERROR: Mismatch.\n");\r
1203 return false;\r
1204 }\r
1205 return true;\r
1206 }\r
1207 \r
1208 static bool doTests()\r
1209 {\r
1210 printf("##########################################\n");\r
1211 printf("## MD5\n");\r
1212 printf("##########################################\n");\r
1213 Md5Digest md5;\r
1214 if (!hashTests(md5, md5tests))\r
1215 return false;\r
1216 if (!millionATest(md5, "7707d6ae4e027c70eea2a935c2296f21"))\r
1217 return false;\r
1218 printf("\n\n\n");\r
1219 printf("##########################################\n");\r
1220 printf("## SHA1\n");\r
1221 printf("##########################################\n");\r
1222 Sha1Digest sha1;\r
1223 if (!hashTests(sha1, sha1tests))\r
1224 return false;\r
1225 if (!millionATest(sha1, "34aa973cd4c4daa4f61eeb2bdbad27316534016f"))\r
1226 return false;\r
1227 printf("\n\n\n");\r
1228 printf("##########################################\n");\r
1229 printf("## SHA224\n");\r
1230 printf("##########################################\n");\r
1231 Sha224Digest sha224;\r
1232 if (!hashTests(sha224, sha224tests))\r
1233 return false;\r
1234 if (!millionATest(sha224,\r
1235 "20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67"))\r
1236 return false;\r
1237 printf("\n\n\n");\r
1238 printf("##########################################\n");\r
1239 printf("## SHA256\n");\r
1240 printf("##########################################\n");\r
1241 Sha256Digest sha256;\r
1242 if (!hashTests(sha256, sha256tests))\r
1243 return false;\r
1244 if (!millionATest(sha256,\r
1245 "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"))\r
1246 return false;\r
1247 printf("\n\n\n");\r
1248 printf("##########################################\n");\r
1249 printf("## SHA384\n");\r
1250 printf("##########################################\n");\r
1251 Sha384Digest sha384;\r
1252 if (!hashTests(sha384, sha384tests))\r
1253 return false;\r
1254 /**/\r
1255 if (!millionATest(sha384,\r
1256 "9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b"\r
1257 "07b8b3dc38ecc4ebae97ddd87f3d8985"))\r
1258 return false;\r
1259 /**/\r
1260 printf("\n\n\n");\r
1261 printf("##########################################\n");\r
1262 printf("## SHA512\n");\r
1263 printf("##########################################\n");\r
1264 Sha512Digest sha512;\r
1265 if (!hashTests(sha512, sha512tests))\r
1266 return false;\r
1267 if (!millionATest(sha512,\r
1268 "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973eb"\r
1269 "de0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b"))\r
1270 return false;\r
1271 return true;\r
1272 }\r
1273 \r
1274 \r
1275 int main(int argc, char **argv)\r
1276 {\r
1277 doTests();\r
1278 printf("####### done ########\n");\r
1279 return 0;\r
1280 }\r
1281 \r
1282 \r
1283 #endif /* DIGEST_TEST */\r
1284 \r
1285 //########################################################################\r
1286 //## E N D O F F I L E\r
1287 //########################################################################\r