Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

/ray/src/lib/crypto/rmd160hash.cc

Go to the documentation of this file.
00001 /*
00002  * lib/crypto/rmd160hash.cc
00003  * 
00004  * Implementation of class RMD160Hash, a class for 
00005  * computing the RMD160 mesage digest / hash algorithm (RIPE MD 160). 
00006  * 
00007  * Copyright (c) 2001--2004 by Wolfgang Wieser ] wwieser (a) gmx <*> de [ 
00008  * 
00009  * This file may be distributed and/or modified under the terms of the 
00010  * GNU General Public License version 2 as published by the Free Software 
00011  * Foundation. (See COPYING.GPL for details.)
00012  * 
00013  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00014  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00015  * 
00016  */
00017 
00018 #include "rmd160hash.h"
00019 
00020 const SecureHashBase::Parameters RMD160Hash::par=
00021 {
00022     INIT_FIELD(hash_size) 20,
00023     INIT_FIELD(block_size) 64,
00024     INIT_FIELD(hash_ID) 0x2000,
00025     INIT_FIELD(name) "RMD160"
00026 };
00027 
00028 static inline uint32 rmd_func0(uint32 x,uint32 y,uint32 z)
00029 {  return(x ^ y ^ z);  }
00030 
00031 static inline uint32 rmd_func1(uint32 x,uint32 y,uint32 z)
00032 //{  return((x & y) | ((~x) & z));  }  // slower 
00033 {  return(z ^ (x & (y ^ z)));  }  // faster
00034 
00035 static inline uint32 rmd_func2(uint32 x,uint32 y,uint32 z)
00036 {  return((x | (~y)) ^ z);  }
00037 
00038 static inline uint32 rmd_func3(uint32 x,uint32 y,uint32 z)
00039 {  return((x & z) | (y & (~z)));  }
00040 
00041 static inline uint32 rmd_func4(uint32 x,uint32 y,uint32 z)
00042 {  return(x ^ (y | (~z)));  }
00043 
00044 static inline uint32 rotate(uint32 x,int n)
00045 {  return((x<<n) | (x>>(32-n)));  }
00046 
00047 
00048 // All this magic stuff...
00049 static const uint32 rmd_init_state[5]=
00050 { 0x67452301U, 0xefcdab89U, 0x98badcfeU, 0x10325476U, 0xc3d2e1f0U };
00051 
00052 #if UNROLLED!=2
00053 // Constants: 
00054 static const uint32 K[5]=
00055     { 0x00000000, 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xA953FD4E };
00056 static const uint32 KK[5]=
00057     { 0x50A28BE6, 0x5C4DD124, 0x6D703EF3, 0x7A6D76E9, 0x00000000 };
00058 
00059 // Message selection permutation:
00060 static const unsigned short int R[80]=
00061     { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 
00062       7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, 
00063       3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, 
00064       1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, 
00065       4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 };
00066 static const unsigned short int RR[80]=
00067     { 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 
00068       6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, 
00069       15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, 
00070       8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, 
00071       12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 };
00072 
00073 // Bit shift value: 
00074 static const unsigned short int S[80]=
00075     { 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, 
00076       7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, 
00077       11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, 
00078       11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, 
00079       9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 };
00080 static const unsigned short int SS[80]=
00081     { 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, 
00082       9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, 
00083       9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, 
00084       15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, 
00085       8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 };
00086 #endif  /* !UNROLLED */
00087 
00088 
00089 // msg: size 64 bytes
00090 // w: temporary buffer where AtomicHash stores (expanded) input data (msg). 
00091 void RMD160Hash::AtomicHash(const unsigned char *msg,uint32 *w)
00092 {
00093     register uint32 *p;
00094     uint32 *we=&w[16];
00095     
00096     // Fill message into w-buffer. 
00097     msg+=3;
00098     for(p=w; p<we; p++)
00099     {
00100         // We want LSB first...
00101         *p= uint32(*(msg--));   *p<<=8;
00102         *p|=uint32(*(msg--));   *p<<=8;
00103         *p|=uint32(*(msg--));   *p<<=8;
00104         *p|=uint32(*(msg  ));
00105         msg+=7;
00106     }
00107     
00108     #if UNROLLED==0
00109     
00110     uint32 a,b,c,d,e;
00111     uint32 aa,bb,cc,dd,ee;
00112     
00113     // Assign current hash state: 
00114     a=aa=state[0];
00115     b=bb=state[1];
00116     c=cc=state[2];
00117     d=dd=state[3];
00118     e=ee=state[4];
00119     
00120     // Now, compute the rounds: 
00121     const uint32 *Kp=K,*KKp=KK;
00122     int j=0;
00123     uint32 tmp;
00124     for(; j<16; j++)
00125     {
00126         tmp = rotate(a + rmd_func0(b,c,d) + w[ /*R[*/ j /*]*/] + *Kp, S[j]) + e;
00127         a=e; e=d; d=rotate(c,10); c=b; b=tmp;
00128         tmp = rotate(aa + rmd_func4(bb,cc,dd) + w[RR[j]] + *KKp, SS[j]) + ee;
00129         aa=ee; ee=dd; dd=rotate(cc,10); cc=bb; bb=tmp;
00130     }
00131     for(++Kp,++KKp; j<32; j++)
00132     {
00133         tmp = rotate(a + rmd_func1(b,c,d) + w[R[j]] + *Kp, S[j]) + e;
00134         a=e; e=d; d=rotate(c,10); c=b; b=tmp;
00135         tmp = rotate(aa + rmd_func3(bb,cc,dd) + w[RR[j]] + *KKp, SS[j]) + ee;
00136         aa=ee; ee=dd; dd=rotate(cc,10); cc=bb; bb=tmp;
00137     }
00138     for(++Kp,++KKp; j<48; j++)
00139     {
00140         tmp = rotate(a + rmd_func2(b,c,d) + w[R[j]] + *Kp, S[j]) + e;
00141         a=e; e=d; d=rotate(c,10); c=b; b=tmp;
00142         tmp = rotate(aa + rmd_func2(bb,cc,dd) + w[RR[j]] + *KKp, SS[j]) + ee;
00143         aa=ee; ee=dd; dd=rotate(cc,10); cc=bb; bb=tmp;
00144     }
00145     for(++Kp,++KKp; j<64; j++)
00146     {
00147         tmp = rotate(a + rmd_func3(b,c,d) + w[R[j]] + *Kp, S[j]) + e;
00148         a=e; e=d; d=rotate(c,10); c=b; b=tmp;
00149         tmp = rotate(aa + rmd_func1(bb,cc,dd) + w[RR[j]] + *KKp, SS[j]) + ee;
00150         aa=ee; ee=dd; dd=rotate(cc,10); cc=bb; bb=tmp;
00151     }
00152     for(++Kp,++KKp; j<80; j++)
00153     {
00154         tmp = rotate(a + rmd_func4(b,c,d) + w[R[j]] + *Kp, S[j]) + e;
00155         a=e; e=d; d=rotate(c,10); c=b; b=tmp;
00156         tmp = rotate(aa + rmd_func0(bb,cc,dd) + w[RR[j]] + *KKp, SS[j]) + ee;
00157         aa=ee; ee=dd; dd=rotate(cc,10); cc=bb; bb=tmp;
00158     }
00159     
00160     // Add result to state: 
00161     tmp =      state[1] + c + dd;
00162     state[1] = state[2] + d + ee;
00163     state[2] = state[3] + e + aa;
00164     state[3] = state[4] + a + bb;
00165     state[4] = state[0] + b + cc;
00166     state[0] = tmp;
00167     
00168     #elif UNROLLED==1
00169     
00170     uint32 a,b,c,d,e;
00171     uint32 aa,bb,cc,dd,ee;
00172     
00173     // Assign current hash state: 
00174     a=aa=state[0];
00175     b=bb=state[1];
00176     c=cc=state[2];
00177     d=dd=state[3];
00178     e=ee=state[4];
00179     
00180     // Now, compute the rounds: 
00181     const uint32 *Kp=K,*KKp=KK;
00182     int j=0;
00183     for(; j<15; )
00184     {
00185         a = rotate(a + rmd_func0(b,c,d) + w[ /*R[*/ j /*]*/] + *Kp, S[j]) + e;
00186         c=rotate(c,10);
00187         aa = rotate(aa + rmd_func4(bb,cc,dd) + w[RR[j]] + *KKp, SS[j]) + ee;
00188         cc=rotate(cc,10);  ++j;
00189         
00190         e = rotate(e + rmd_func0(a,b,c) + w[ /*R[*/ j /*]*/] + *Kp, S[j]) + d;
00191         b=rotate(b,10);
00192         ee = rotate(ee + rmd_func4(aa,bb,cc) + w[RR[j]] + *KKp, SS[j]) + dd;
00193         bb=rotate(bb,10);  ++j;
00194         
00195         d = rotate(d + rmd_func0(e,a,b) + w[ /*R[*/ j /*]*/] + *Kp, S[j]) + c;
00196         a=rotate(a,10);
00197         dd = rotate(dd + rmd_func4(ee,aa,bb) + w[RR[j]] + *KKp, SS[j]) + cc;
00198         aa=rotate(aa,10);  ++j;
00199         
00200         c = rotate(c + rmd_func0(d,e,a) + w[ /*R[*/ j /*]*/] + *Kp, S[j]) + b;
00201         e=rotate(e,10);
00202         cc = rotate(cc + rmd_func4(dd,ee,aa) + w[RR[j]] + *KKp, SS[j]) + bb;
00203         ee=rotate(ee,10);  ++j;
00204         
00205         b = rotate(b + rmd_func0(c,d,e) + w[ /*R[*/ j /*]*/] + *Kp, S[j]) + a;
00206         d=rotate(d,10);
00207         bb = rotate(bb + rmd_func4(cc,dd,ee) + w[RR[j]] + *KKp, SS[j]) + aa;
00208         dd=rotate(dd,10);  ++j;
00209     }
00210     a = rotate(a + rmd_func0(b,c,d) + w[ /*R[*/ j /*]*/] + *Kp, S[j]) + e;
00211     c=rotate(c,10);
00212     aa = rotate(aa + rmd_func4(bb,cc,dd) + w[RR[j]] + *KKp, SS[j]) + ee;
00213     cc=rotate(cc,10);  ++j;
00214     
00215     for(++Kp,++KKp; j<31; )
00216     {
00217         e = rotate(e + rmd_func1(a,b,c) + w[R[j]] + *Kp, S[j]) + d;
00218         b=rotate(b,10);
00219         ee = rotate(ee + rmd_func3(aa,bb,cc) + w[RR[j]] + *KKp, SS[j]) + dd;
00220         bb=rotate(bb,10);  ++j;
00221         
00222         d = rotate(d + rmd_func1(e,a,b) + w[R[j]] + *Kp, S[j]) + c;
00223         a=rotate(a,10);
00224         dd = rotate(dd + rmd_func3(ee,aa,bb) + w[RR[j]] + *KKp, SS[j]) + cc;
00225         aa=rotate(aa,10);  ++j;
00226         
00227         c = rotate(c + rmd_func1(d,e,a) + w[R[j]] + *Kp, S[j]) + b;
00228         e=rotate(e,10);
00229         cc = rotate(cc + rmd_func3(dd,ee,aa) + w[RR[j]] + *KKp, SS[j]) + bb;
00230         ee=rotate(ee,10);  ++j;
00231         
00232         b = rotate(b + rmd_func1(c,d,e) + w[R[j]] + *Kp, S[j]) + a;
00233         d=rotate(d,10);
00234         bb = rotate(bb + rmd_func3(cc,dd,ee) + w[RR[j]] + *KKp, SS[j]) + aa;
00235         dd=rotate(dd,10);  ++j;
00236         
00237         a = rotate(a + rmd_func1(b,c,d) + w[R[j]] + *Kp, S[j]) + e;
00238         c=rotate(c,10);
00239         aa = rotate(aa + rmd_func3(bb,cc,dd) + w[RR[j]] + *KKp, SS[j]) + ee;
00240         cc=rotate(cc,10);  ++j;
00241     }
00242     e = rotate(e + rmd_func1(a,b,c) + w[R[j]] + *Kp, S[j]) + d;
00243     b=rotate(b,10);
00244     ee = rotate(ee + rmd_func3(aa,bb,cc) + w[RR[j]] + *KKp, SS[j]) + dd;
00245     bb=rotate(bb,10);  ++j;
00246     
00247     for(++Kp,++KKp; j<47; )
00248     {
00249         d = rotate(d + rmd_func2(e,a,b) + w[R[j]] + *Kp, S[j]) + c;
00250         a=rotate(a,10);
00251         dd = rotate(dd + rmd_func2(ee,aa,bb) + w[RR[j]] + *KKp, SS[j]) + cc;
00252         aa=rotate(aa,10);  ++j;
00253         
00254         c = rotate(c + rmd_func2(d,e,a) + w[R[j]] + *Kp, S[j]) + b;
00255         e=rotate(e,10);
00256         cc = rotate(cc + rmd_func2(dd,ee,aa) + w[RR[j]] + *KKp, SS[j]) + bb;
00257         ee=rotate(ee,10);  ++j;
00258         
00259         b = rotate(b + rmd_func2(c,d,e) + w[R[j]] + *Kp, S[j]) + a;
00260         d=rotate(d,10);
00261         bb = rotate(bb + rmd_func2(cc,dd,ee) + w[RR[j]] + *KKp, SS[j]) + aa;
00262         dd=rotate(dd,10);  ++j;
00263         
00264         a = rotate(a + rmd_func2(b,c,d) + w[R[j]] + *Kp, S[j]) + e;
00265         c=rotate(c,10);
00266         aa = rotate(aa + rmd_func2(bb,cc,dd) + w[RR[j]] + *KKp, SS[j]) + ee;
00267         cc=rotate(cc,10);  ++j;
00268         
00269         e = rotate(e + rmd_func2(a,b,c) + w[R[j]] + *Kp, S[j]) + d;
00270         b=rotate(b,10);
00271         ee = rotate(ee + rmd_func2(aa,bb,cc) + w[RR[j]] + *KKp, SS[j]) + dd;
00272         bb=rotate(bb,10);  ++j;
00273     }
00274     d = rotate(d + rmd_func2(e,a,b) + w[R[j]] + *Kp, S[j]) + c;
00275     a=rotate(a,10);
00276     dd = rotate(dd + rmd_func2(ee,aa,bb) + w[RR[j]] + *KKp, SS[j]) + cc;
00277     aa=rotate(aa,10);  ++j;
00278 
00279     for(++Kp,++KKp; j<63; )
00280     {
00281         c = rotate(c + rmd_func3(d,e,a) + w[R[j]] + *Kp, S[j]) + b;
00282         e=rotate(e,10);
00283         cc = rotate(cc + rmd_func1(dd,ee,aa) + w[RR[j]] + *KKp, SS[j]) + bb;
00284         ee=rotate(ee,10);  ++j;
00285         
00286         b = rotate(b + rmd_func3(c,d,e) + w[R[j]] + *Kp, S[j]) + a;
00287         d=rotate(d,10);
00288         bb = rotate(bb + rmd_func1(cc,dd,ee) + w[RR[j]] + *KKp, SS[j]) + aa;
00289         dd=rotate(dd,10);  ++j;
00290         
00291         a = rotate(a + rmd_func3(b,c,d) + w[R[j]] + *Kp, S[j]) + e;
00292         c=rotate(c,10);
00293         aa = rotate(aa + rmd_func1(bb,cc,dd) + w[RR[j]] + *KKp, SS[j]) + ee;
00294         cc=rotate(cc,10);  ++j;
00295         
00296         e = rotate(e + rmd_func3(a,b,c) + w[R[j]] + *Kp, S[j]) + d;
00297         b=rotate(b,10);
00298         ee = rotate(ee + rmd_func1(aa,bb,cc) + w[RR[j]] + *KKp, SS[j]) + dd;
00299         bb=rotate(bb,10);  ++j;
00300         
00301         d = rotate(d + rmd_func3(e,a,b) + w[R[j]] + *Kp, S[j]) + c;
00302         a=rotate(a,10);
00303         dd = rotate(dd + rmd_func1(ee,aa,bb) + w[RR[j]] + *KKp, SS[j]) + cc;
00304         aa=rotate(aa,10);  ++j;
00305     }
00306     c = rotate(c + rmd_func3(d,e,a) + w[R[j]] + *Kp, S[j]) + b;
00307     e=rotate(e,10);
00308     cc = rotate(cc + rmd_func1(dd,ee,aa) + w[RR[j]] + *KKp, SS[j]) + bb;
00309     ee=rotate(ee,10);  ++j;
00310     
00311     for(++Kp,++KKp; j<79; )
00312     {
00313         b = rotate(b + rmd_func4(c,d,e) + w[R[j]] + *Kp, S[j]) + a;
00314         d=rotate(d,10);
00315         bb = rotate(bb + rmd_func0(cc,dd,ee) + w[RR[j]] + *KKp, SS[j]) + aa;
00316         dd=rotate(dd,10);  ++j;
00317         
00318         a = rotate(a + rmd_func4(b,c,d) + w[R[j]] + *Kp, S[j]) + e;
00319         c=rotate(c,10);
00320         aa = rotate(aa + rmd_func0(bb,cc,dd) + w[RR[j]] + *KKp, SS[j]) + ee;
00321         cc=rotate(cc,10);  ++j;
00322         
00323         e = rotate(e + rmd_func4(a,b,c) + w[R[j]] + *Kp, S[j]) + d;
00324         b=rotate(b,10);
00325         ee = rotate(ee + rmd_func0(aa,bb,cc) + w[RR[j]] + *KKp, SS[j]) + dd;
00326         bb=rotate(bb,10);  ++j;
00327         
00328         d = rotate(d + rmd_func4(e,a,b) + w[R[j]] + *Kp, S[j]) + c;
00329         a=rotate(a,10);
00330         dd = rotate(dd + rmd_func0(ee,aa,bb) + w[RR[j]] + *KKp, SS[j]) + cc;
00331         aa=rotate(aa,10);  ++j;
00332         
00333         c = rotate(c + rmd_func4(d,e,a) + w[R[j]] + *Kp, S[j]) + b;
00334         e=rotate(e,10);
00335         cc = rotate(cc + rmd_func0(dd,ee,aa) + w[RR[j]] + *KKp, SS[j]) + bb;
00336         ee=rotate(ee,10);  ++j;
00337     }
00338     b = rotate(b + rmd_func4(c,d,e) + w[R[j]] + *Kp, S[j]) + a;
00339     d=rotate(d,10);
00340     bb = rotate(bb + rmd_func0(cc,dd,ee) + w[RR[j]] + *KKp, SS[j]) + aa;
00341     dd=rotate(dd,10);  ++j;
00342     
00343     // Add result to state: 
00344     uint32 tmp;
00345     tmp =      state[1] + c + dd;
00346     state[1] = state[2] + d + ee;
00347     state[2] = state[3] + e + aa;
00348     state[3] = state[4] + a + bb;
00349     state[4] = state[0] + b + cc;
00350     state[0] = tmp;
00351     
00352     #elif UNROLLED==2
00353     
00354     uint32 x0,x1,x2,x3,x4;
00355     uint32 y0,y1,y2,y3,y4;
00356     
00357     // Assign (current) hash state to x and y: 
00358     x0 = y0 = state[0];
00359     x1 = y1 = state[1];
00360     x2 = y2 = state[2];
00361     x3 = y3 = state[3];
00362     x4 = y4 = state[4];
00363     
00364 //-----------------------------------------------------------------------------
00365 // Define the ten transforms.
00366 //-----------------------------------------------------------------------------
00367 #define T1(a,b,c,d,e,x,s) {                     \
00368             (a) += rmd_func0((b),(c),(d)) + (x);            \
00369             (a) = rotate((a),(s)) + (e);            \
00370             (c) = rotate((c),10);}
00371 #define T2(a,b,c,d,e,x,s) {                     \
00372             (a) += rmd_func1((b),(c),(d)) + (x) + 0x5a827999UL; \
00373             (a) = rotate((a),(s)) + (e);            \
00374             (c) = rotate((c),10);}
00375 #define T3(a,b,c,d,e,x,s) {                     \
00376             (a) += rmd_func2((b),(c),(d)) + (x) + 0x6ed9eba1UL; \
00377             (a) = rotate((a),(s)) + (e);            \
00378             (c) = rotate((c),10);}
00379 #define T4(a,b,c,d,e,x,s) {                     \
00380             (a) += rmd_func3((b),(c),(d)) + (x) + 0x8f1bbcdcUL; \
00381             (a) = rotate((a),(s)) + (e);            \
00382             (c) = rotate((c),10);}
00383 #define T5(a,b,c,d,e,x,s) {                     \
00384             (a) += rmd_func4((b),(c),(d)) + (x) + 0xa953fd4eUL; \
00385             (a) = rotate((a),(s)) + (e);            \
00386             (c) = rotate((c),10);}
00387 
00388 #define S1(a,b,c,d,e,x,s) {                     \
00389             (a) += rmd_func0((b),(c),(d)) + (x);            \
00390             (a) = rotate((a),(s)) + (e);            \
00391             (c) = rotate((c),10);}
00392 #define S2(a,b,c,d,e,x,s) {                     \
00393             (a) += rmd_func1((b),(c),(d)) + (x) + 0x7a6d76e9UL; \
00394             (a) = rotate((a),(s)) + (e);            \
00395             (c) = rotate((c),10);}
00396 #define S3(a,b,c,d,e,x,s) {                     \
00397             (a) += rmd_func2((b),(c),(d)) + (x) + 0x6d703ef3UL; \
00398             (a) = rotate((a),(s)) + (e);            \
00399             (c) = rotate((c),10);}
00400 #define S4(a,b,c,d,e,x,s) {                     \
00401             (a) += rmd_func3((b),(c),(d)) + (x) + 0x5c4dd124UL; \
00402             (a) = rotate((a),(s)) + (e);            \
00403             (c) = rotate((c),10);}
00404 #define S5(a,b,c,d,e,x,s) {                     \
00405             (a) += rmd_func4((b),(c),(d)) + (x) + 0x50a28be6UL; \
00406             (a) = rotate((a),(s)) + (e);            \
00407             (c) = rotate((c),10);}
00408 
00409     //------------------------------------
00410     // Perform the ten calculation rounds.
00411     //------------------------------------
00412     T1( x0 , x1 , x2 , x3 , x4 , w[ 0] , 11 );
00413     T1( x4 , x0 , x1 , x2 , x3 , w[ 1] , 14 );
00414     T1( x3 , x4 , x0 , x1 , x2 , w[ 2] , 15 );
00415     T1( x2 , x3 , x4 , x0 , x1 , w[ 3] , 12 );
00416     T1( x1 , x2 , x3 , x4 , x0 , w[ 4] ,  5 );
00417     T1( x0 , x1 , x2 , x3 , x4 , w[ 5] ,  8 );
00418     T1( x4 , x0 , x1 , x2 , x3 , w[ 6] ,  7 );
00419     T1( x3 , x4 , x0 , x1 , x2 , w[ 7] ,  9 );
00420     T1( x2 , x3 , x4 , x0 , x1 , w[ 8] , 11 );
00421     T1( x1 , x2 , x3 , x4 , x0 , w[ 9] , 13 );
00422     T1( x0 , x1 , x2 , x3 , x4 , w[10] , 14 );
00423     T1( x4 , x0 , x1 , x2 , x3 , w[11] , 15 );
00424     T1( x3 , x4 , x0 , x1 , x2 , w[12] ,  6 );
00425     T1( x2 , x3 , x4 , x0 , x1 , w[13] ,  7 );
00426     T1( x1 , x2 , x3 , x4 , x0 , w[14] ,  9 );
00427     T1( x0 , x1 , x2 , x3 , x4 , w[15] ,  8 );
00428 
00429     T2( x4 , x0 , x1 , x2 , x3 , w[ 7] ,  7 );
00430     T2( x3 , x4 , x0 , x1 , x2 , w[ 4] ,  6 );
00431     T2( x2 , x3 , x4 , x0 , x1 , w[13] ,  8 );
00432     T2( x1 , x2 , x3 , x4 , x0 , w[ 1] , 13 );
00433     T2( x0 , x1 , x2 , x3 , x4 , w[10] , 11 );
00434     T2( x4 , x0 , x1 , x2 , x3 , w[ 6] ,  9 );
00435     T2( x3 , x4 , x0 , x1 , x2 , w[15] ,  7 );
00436     T2( x2 , x3 , x4 , x0 , x1 , w[ 3] , 15 );
00437     T2( x1 , x2 , x3 , x4 , x0 , w[12] ,  7 );
00438     T2( x0 , x1 , x2 , x3 , x4 , w[ 0] , 12 );
00439     T2( x4 , x0 , x1 , x2 , x3 , w[ 9] , 15 );
00440     T2( x3 , x4 , x0 , x1 , x2 , w[ 5] ,  9 );
00441     T2( x2 , x3 , x4 , x0 , x1 , w[ 2] , 11 );
00442     T2( x1 , x2 , x3 , x4 , x0 , w[14] ,  7 );
00443     T2( x0 , x1 , x2 , x3 , x4 , w[11] , 13 );
00444     T2( x4 , x0 , x1 , x2 , x3 , w[ 8] , 12 );
00445 
00446     T3( x3 , x4 , x0 , x1 , x2 , w[ 3] , 11 );
00447     T3( x2 , x3 , x4 , x0 , x1 , w[10] , 13 );
00448     T3( x1 , x2 , x3 , x4 , x0 , w[14] ,  6 );
00449     T3( x0 , x1 , x2 , x3 , x4 , w[ 4] ,  7 );
00450     T3( x4 , x0 , x1 , x2 , x3 , w[ 9] , 14 );
00451     T3( x3 , x4 , x0 , x1 , x2 , w[15] ,  9 );
00452     T3( x2 , x3 , x4 , x0 , x1 , w[ 8] , 13 );
00453     T3( x1 , x2 , x3 , x4 , x0 , w[ 1] , 15 );
00454     T3( x0 , x1 , x2 , x3 , x4 , w[ 2] , 14 );
00455     T3( x4 , x0 , x1 , x2 , x3 , w[ 7] ,  8 );
00456     T3( x3 , x4 , x0 , x1 , x2 , w[ 0] , 13 );
00457     T3( x2 , x3 , x4 , x0 , x1 , w[ 6] ,  6 );
00458     T3( x1 , x2 , x3 , x4 , x0 , w[13] ,  5 );
00459     T3( x0 , x1 , x2 , x3 , x4 , w[11] , 12 );
00460     T3( x4 , x0 , x1 , x2 , x3 , w[ 5] ,  7 );
00461     T3( x3 , x4 , x0 , x1 , x2 , w[12] ,  5 );
00462 
00463     T4( x2 , x3 , x4 , x0 , x1 , w[ 1] , 11 );
00464     T4( x1 , x2 , x3 , x4 , x0 , w[ 9] , 12 );
00465     T4( x0 , x1 , x2 , x3 , x4 , w[11] , 14 );
00466     T4( x4 , x0 , x1 , x2 , x3 , w[10] , 15 );
00467     T4( x3 , x4 , x0 , x1 , x2 , w[ 0] , 14 );
00468     T4( x2 , x3 , x4 , x0 , x1 , w[ 8] , 15 );
00469     T4( x1 , x2 , x3 , x4 , x0 , w[12] ,  9 );
00470     T4( x0 , x1 , x2 , x3 , x4 , w[ 4] ,  8 );
00471     T4( x4 , x0 , x1 , x2 , x3 , w[13] ,  9 );
00472     T4( x3 , x4 , x0 , x1 , x2 , w[ 3] , 14 );
00473     T4( x2 , x3 , x4 , x0 , x1 , w[ 7] ,  5 );
00474     T4( x1 , x2 , x3 , x4 , x0 , w[15] ,  6 );
00475     T4( x0 , x1 , x2 , x3 , x4 , w[14] ,  8 );
00476     T4( x4 , x0 , x1 , x2 , x3 , w[ 5] ,  6 );
00477     T4( x3 , x4 , x0 , x1 , x2 , w[ 6] ,  5 );
00478     T4( x2 , x3 , x4 , x0 , x1 , w[ 2] , 12 );
00479 
00480     T5( x1 , x2 , x3 , x4 , x0 , w[ 4] ,  9 );
00481     T5( x0 , x1 , x2 , x3 , x4 , w[ 0] , 15 );
00482     T5( x4 , x0 , x1 , x2 , x3 , w[ 5] ,  5 );
00483     T5( x3 , x4 , x0 , x1 , x2 , w[ 9] , 11 );
00484     T5( x2 , x3 , x4 , x0 , x1 , w[ 7] ,  6 );
00485     T5( x1 , x2 , x3 , x4 , x0 , w[12] ,  8 );
00486     T5( x0 , x1 , x2 , x3 , x4 , w[ 2] , 13 );
00487     T5( x4 , x0 , x1 , x2 , x3 , w[10] , 12 );
00488     T5( x3 , x4 , x0 , x1 , x2 , w[14] ,  5 );
00489     T5( x2 , x3 , x4 , x0 , x1 , w[ 1] , 12 );
00490     T5( x1 , x2 , x3 , x4 , x0 , w[ 3] , 13 );
00491     T5( x0 , x1 , x2 , x3 , x4 , w[ 8] , 14 );
00492     T5( x4 , x0 , x1 , x2 , x3 , w[11] , 11 );
00493     T5( x3 , x4 , x0 , x1 , x2 , w[ 6] ,  8 );
00494     T5( x2 , x3 , x4 , x0 , x1 , w[15] ,  5 );
00495     T5( x1 , x2 , x3 , x4 , x0 , w[13] ,  6 );
00496 
00497     S5( y0 , y1 , y2 , y3 , y4 , w[ 5] ,  8 );
00498     S5( y4 , y0 , y1 , y2 , y3 , w[14] ,  9 );
00499     S5( y3 , y4 , y0 , y1 , y2 , w[ 7] ,  9 );
00500     S5( y2 , y3 , y4 , y0 , y1 , w[ 0] , 11 );
00501     S5( y1 , y2 , y3 , y4 , y0 , w[ 9] , 13 );
00502     S5( y0 , y1 , y2 , y3 , y4 , w[ 2] , 15 );
00503     S5( y4 , y0 , y1 , y2 , y3 , w[11] , 15 );
00504     S5( y3 , y4 , y0 , y1 , y2 , w[ 4] ,  5 );
00505     S5( y2 , y3 , y4 , y0 , y1 , w[13] ,  7 );
00506     S5( y1 , y2 , y3 , y4 , y0 , w[ 6] ,  7 );
00507     S5( y0 , y1 , y2 , y3 , y4 , w[15] ,  8 );
00508     S5( y4 , y0 , y1 , y2 , y3 , w[ 8] , 11 );
00509     S5( y3 , y4 , y0 , y1 , y2 , w[ 1] , 14 );
00510     S5( y2 , y3 , y4 , y0 , y1 , w[10] , 14 );
00511     S5( y1 , y2 , y3 , y4 , y0 , w[ 3] , 12 );
00512     S5( y0 , y1 , y2 , y3 , y4 , w[12] ,  6 );
00513 
00514     S4( y4 , y0 , y1 , y2 , y3 , w[ 6] ,  9 );
00515     S4( y3 , y4 , y0 , y1 , y2 , w[11] , 13 );
00516     S4( y2 , y3 , y4 , y0 , y1 , w[ 3] , 15 );
00517     S4( y1 , y2 , y3 , y4 , y0 , w[ 7] ,  7 );
00518     S4( y0 , y1 , y2 , y3 , y4 , w[ 0] , 12 );
00519     S4( y4 , y0 , y1 , y2 , y3 , w[13] ,  8 );
00520     S4( y3 , y4 , y0 , y1 , y2 , w[ 5] ,  9 );
00521     S4( y2 , y3 , y4 , y0 , y1 , w[10] , 11 );
00522     S4( y1 , y2 , y3 , y4 , y0 , w[14] ,  7 );
00523     S4( y0 , y1 , y2 , y3 , y4 , w[15] ,  7 );
00524     S4( y4 , y0 , y1 , y2 , y3 , w[ 8] , 12 );
00525     S4( y3 , y4 , y0 , y1 , y2 , w[12] ,  7 );
00526     S4( y2 , y3 , y4 , y0 , y1 , w[ 4] ,  6 );
00527     S4( y1 , y2 , y3 , y4 , y0 , w[ 9] , 15 );
00528     S4( y0 , y1 , y2 , y3 , y4 , w[ 1] , 13 );
00529     S4( y4 , y0 , y1 , y2 , y3 , w[ 2] , 11 );
00530     
00531     S3( y3 , y4 , y0 , y1 , y2 , w[15] ,  9 );
00532     S3( y2 , y3 , y4 , y0 , y1 , w[ 5] ,  7 );
00533     S3( y1 , y2 , y3 , y4 , y0 , w[ 1] , 15 );
00534     S3( y0 , y1 , y2 , y3 , y4 , w[ 3] , 11 );
00535     S3( y4 , y0 , y1 , y2 , y3 , w[ 7] ,  8 );
00536     S3( y3 , y4 , y0 , y1 , y2 , w[14] ,  6 );
00537     S3( y2 , y3 , y4 , y0 , y1 , w[ 6] ,  6 );
00538     S3( y1 , y2 , y3 , y4 , y0 , w[ 9] , 14 );
00539     S3( y0 , y1 , y2 , y3 , y4 , w[11] , 12 );
00540     S3( y4 , y0 , y1 , y2 , y3 , w[ 8] , 13 );
00541     S3( y3 , y4 , y0 , y1 , y2 , w[12] ,  5 );
00542     S3( y2 , y3 , y4 , y0 , y1 , w[ 2] , 14 );
00543     S3( y1 , y2 , y3 , y4 , y0 , w[10] , 13 );
00544     S3( y0 , y1 , y2 , y3 , y4 , w[ 0] , 13 );
00545     S3( y4 , y0 , y1 , y2 , y3 , w[ 4] ,  7 );
00546     S3( y3 , y4 , y0 , y1 , y2 , w[13] ,  5 );
00547     
00548     S2( y2 , y3 , y4 , y0 , y1 , w[ 8] , 15 );
00549     S2( y1 , y2 , y3 , y4 , y0 , w[ 6] ,  5 );
00550     S2( y0 , y1 , y2 , y3 , y4 , w[ 4] ,  8 );
00551     S2( y4 , y0 , y1 , y2 , y3 , w[ 1] , 11 );
00552     S2( y3 , y4 , y0 , y1 , y2 , w[ 3] , 14 );
00553     S2( y2 , y3 , y4 , y0 , y1 , w[11] , 14 );
00554     S2( y1 , y2 , y3 , y4 , y0 , w[15] ,  6 );
00555     S2( y0 , y1 , y2 , y3 , y4 , w[ 0] , 14 );
00556     S2( y4 , y0 , y1 , y2 , y3 , w[ 5] ,  6 );
00557     S2( y3 , y4 , y0 , y1 , y2 , w[12] ,  9 );
00558     S2( y2 , y3 , y4 , y0 , y1 , w[ 2] , 12 );
00559     S2( y1 , y2 , y3 , y4 , y0 , w[13] ,  9 );
00560     S2( y0 , y1 , y2 , y3 , y4 , w[ 9] , 12 );
00561     S2( y4 , y0 , y1 , y2 , y3 , w[ 7] ,  5 );
00562     S2( y3 , y4 , y0 , y1 , y2 , w[10] , 15 );
00563     S2( y2 , y3 , y4 , y0 , y1 , w[14] ,  8 );
00564     
00565     S1( y1 , y2 , y3 , y4 , y0 , w[12] ,  8 );
00566     S1( y0 , y1 , y2 , y3 , y4 , w[15] ,  5 );
00567     S1( y4 , y0 , y1 , y2 , y3 , w[10] , 12 );
00568     S1( y3 , y4 , y0 , y1 , y2 , w[ 4] ,  9 );
00569     S1( y2 , y3 , y4 , y0 , y1 , w[ 1] , 12 );
00570     S1( y1 , y2 , y3 , y4 , y0 , w[ 5] ,  5 );
00571     S1( y0 , y1 , y2 , y3 , y4 , w[ 8] , 14 );
00572     S1( y4 , y0 , y1 , y2 , y3 , w[ 7] ,  6 );
00573     S1( y3 , y4 , y0 , y1 , y2 , w[ 6] ,  8 );
00574     S1( y2 , y3 , y4 , y0 , y1 , w[ 2] , 13 );
00575     S1( y1 , y2 , y3 , y4 , y0 , w[13] ,  6 );
00576     S1( y0 , y1 , y2 , y3 , y4 , w[14] ,  5 );
00577     S1( y4 , y0 , y1 , y2 , y3 , w[ 0] , 15 );
00578     S1( y3 , y4 , y0 , y1 , y2 , w[ 3] , 13 );
00579     S1( y2 , y3 , y4 , y0 , y1 , w[ 9] , 11 );
00580     S1( y1 , y2 , y3 , y4 , y0 , w[11] , 11 );
00581     
00582     // Add result to state: 
00583     y3 += x2 + state[1];
00584     state[1] = state[2] + x3 + y4;
00585     state[2] = state[3] + x4 + y0;
00586     state[3] = state[4] + x0 + y1;
00587     state[4] = state[0] + x1 + y2;
00588     state[0] = y3;
00589     #else
00590     #error Illegal value for UNROLLED macro. 
00591     #endif  /* UNROLLED */
00592 }
00593 
00594 
00595 void RMD160Hash::GetHash(char *buf) const
00596 {
00597     register unsigned char *hsh=(unsigned char*)buf;
00598     for(register const uint32 *i=state,*ie=&state[5]; i<ie; i++)
00599     {
00600         uint32 j=*i;
00601         *(hsh++)=(unsigned char)(j & 0xffU);  j>>=8;
00602         *(hsh++)=(unsigned char)(j & 0xffU);  j>>=8;
00603         *(hsh++)=(unsigned char)(j & 0xffU);  j>>=8;
00604         *(hsh++)=(unsigned char)(j & 0xffU);
00605     }
00606 }
00607 
00608 
00609 void RMD160Hash::reset()
00610 {
00611     length=0LLU;
00612     
00613     state[0]=rmd_init_state[0];
00614     state[1]=rmd_init_state[1];
00615     state[2]=rmd_init_state[2];
00616     state[3]=rmd_init_state[3];
00617     state[4]=rmd_init_state[4];
00618     
00619     tmp_size=0;
00620     for(unsigned char *d=tmpbuf,*de=d+64; d<de; d++)
00621     {  *d=(unsigned char)0;  }
00622 }
00623 
00624 
00625 void RMD160Hash::feed(const char *_buf,size_t len)
00626 {
00627     if(!len)
00628     {  return;  }
00629     
00630     const unsigned char *buf=(const unsigned char*)_buf;
00631     uint32 w[16];
00632     
00633     if(tmp_size)  // There is some data left from last time. 
00634     {
00635         size_t needed=64-tmp_size;
00636         if(len>=needed)
00637         {
00638             for(unsigned char *d=&tmpbuf[tmp_size],*de=&tmpbuf[64]; d<de; d++)
00639             {  *d=*(buf++);  }
00640             AtomicHash(tmpbuf,w);
00641             len-=needed;
00642             tmp_size=0;
00643             length+=64LLU;
00644             if(!len)
00645             {  return;  }
00646         }
00647         else
00648         {
00649             unsigned char *d=&tmpbuf[tmp_size];
00650             tmp_size+=int(len);
00651             for(unsigned char *de=&tmpbuf[tmp_size]; d<de; d++)
00652             {  *d=*(buf++);  }
00653             return;
00654         }
00655     }
00656     
00657     size_t l=len;
00658     for(;;)
00659     {
00660         if(l<64)
00661         {  break;  }
00662         AtomicHash((const unsigned char*)buf,w);
00663         buf+=64;
00664         l-=64;
00665     }
00666     length+=uint64(len-l);
00667     if(l)  // Some bytes left; store them for later. 
00668     {
00669         for(unsigned char *d=tmpbuf,*de=d+l; d<de; d++)
00670         {  *d=*(buf++);  }
00671         tmp_size=int(l);
00672     }
00673 }
00674 
00675 
00676 void RMD160Hash::final()
00677 {
00678     uint32 w[16];
00679     int pad80=0;
00680     
00681     // Now, let's see if we need padding. 
00682     // We must check for >=56 as we always have to add one 0x80 padding. 
00683     // Padding does not count for the length, of course.
00684     length+=uint64(tmp_size);
00685     if(tmp_size>=56)  // We need to pad the tmpbuf with zeros and hash it. 
00686     {
00687         unsigned char *d=&tmpbuf[tmp_size];
00688         *(d++)=(unsigned char)0x80;   // append binary 10000000. 
00689         for(unsigned char *de=&tmpbuf[64]; d<de; d++)
00690         {  *d=(unsigned char)0;  }
00691         AtomicHash(tmpbuf,w);
00692         tmp_size=0;
00693         ++pad80;
00694     }
00695     
00696     // The length was counted in bytes, but we need the number of bits here: 
00697     uint64 len=length*8LLU;
00698     
00699     // Now, we have to fill up tmpbuf with zeros and add the length in bits 
00700     // as the last 8 bytes. 
00701     unsigned char *d=&tmpbuf[tmp_size];
00702     if(!pad80)
00703     {  *(d++)=(unsigned char)0x80;  }  // append binary 10000000. 
00704     for(unsigned char *de=&tmpbuf[56]; d<de; d++)
00705     {  *d=(unsigned char)0;  }
00706     
00707     // Add less significant word: 
00708     uint32 word = uint32(len & 0xffffffffLLU);
00709     *(d++)=(unsigned char)(word & 0xffU);  word>>=8;
00710     *(d++)=(unsigned char)(word & 0xffU);  word>>=8;
00711     *(d++)=(unsigned char)(word & 0xffU);  word>>=8;
00712     *(d++)=(unsigned char)(word & 0xffU);
00713     
00714     // Add more significant word: 
00715     word = uint32(len >> 32);
00716     *(d++)=(unsigned char)(word & 0xffU);  word>>=8;
00717     *(d++)=(unsigned char)(word & 0xffU);  word>>=8;
00718     *(d++)=(unsigned char)(word & 0xffU);  word>>=8;
00719     *(d  )=(unsigned char)(word & 0xffU);
00720     
00721     AtomicHash(tmpbuf,w);
00722     tmp_size=0;
00723 }

Generated on Sat Feb 19 22:33:45 2005 for Ray by doxygen 1.3.5