Code

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