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

sha.cpp

00001 // sha.cpp - modified by Wei Dai from Steve Reid's public domain sha1.c
00002 
00003 // Steve Reid implemented SHA-1. Wei Dai implemented SHA-2.
00004 // Both are in the public domain.
00005 
00006 #include "pch.h"
00007 #include "sha.h"
00008 #include "misc.h"
00009 
00010 NAMESPACE_BEGIN(CryptoPP)
00011 
00012 // start of Steve Reid's code
00013 
00014 #define blk0(i) (W[i] = data[i])
00015 #define blk1(i) (W[i&15] = rotlFixed(W[(i+13)&15]^W[(i+8)&15]^W[(i+2)&15]^W[i&15],1))
00016 
00017 #ifndef CRYPTOPP_IMPORTS
00018 
00019 void SHA::InitState(HashWordType *state)
00020 {
00021         state[0] = 0x67452301L;
00022         state[1] = 0xEFCDAB89L;
00023         state[2] = 0x98BADCFEL;
00024         state[3] = 0x10325476L;
00025         state[4] = 0xC3D2E1F0L;
00026 }
00027 
00028 #define f1(x,y,z) (z^(x&(y^z)))
00029 #define f2(x,y,z) (x^y^z)
00030 #define f3(x,y,z) ((x&y)|(z&(x|y)))
00031 #define f4(x,y,z) (x^y^z)
00032 
00033 /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
00034 #define R0(v,w,x,y,z,i) z+=f1(w,x,y)+blk0(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30);
00035 #define R1(v,w,x,y,z,i) z+=f1(w,x,y)+blk1(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30);
00036 #define R2(v,w,x,y,z,i) z+=f2(w,x,y)+blk1(i)+0x6ED9EBA1+rotlFixed(v,5);w=rotlFixed(w,30);
00037 #define R3(v,w,x,y,z,i) z+=f3(w,x,y)+blk1(i)+0x8F1BBCDC+rotlFixed(v,5);w=rotlFixed(w,30);
00038 #define R4(v,w,x,y,z,i) z+=f4(w,x,y)+blk1(i)+0xCA62C1D6+rotlFixed(v,5);w=rotlFixed(w,30);
00039 
00040 void SHA::Transform(word32 *state, const word32 *data)
00041 {
00042         word32 W[16];
00043     /* Copy context->state[] to working vars */
00044     word32 a = state[0];
00045     word32 b = state[1];
00046     word32 c = state[2];
00047     word32 d = state[3];
00048     word32 e = state[4];
00049     /* 4 rounds of 20 operations each. Loop unrolled. */
00050     R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
00051     R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
00052     R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
00053     R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
00054     R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
00055     R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
00056     R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
00057     R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
00058     R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
00059     R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
00060     R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
00061     R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
00062     R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
00063     R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
00064     R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
00065     R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
00066     R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
00067     R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
00068     R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
00069     R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
00070     /* Add the working vars back into context.state[] */
00071     state[0] += a;
00072     state[1] += b;
00073     state[2] += c;
00074     state[3] += d;
00075     state[4] += e;
00076     /* Wipe variables */
00077     a = b = c = d = e = 0;
00078         memset(W, 0, sizeof(W));
00079 }
00080 
00081 #endif  // #ifndef CRYPTOPP_IMPORTS
00082 
00083 // end of Steve Reid's code
00084 
00085 // *************************************************************
00086 
00087 void SHA256::InitState(HashWordType *state)
00088 {
00089         state[0] = 0x6a09e667;
00090         state[1] = 0xbb67ae85;
00091         state[2] = 0x3c6ef372;
00092         state[3] = 0xa54ff53a;
00093         state[4] = 0x510e527f;
00094         state[5] = 0x9b05688c;
00095         state[6] = 0x1f83d9ab;
00096         state[7] = 0x5be0cd19;
00097 }
00098 
00099 #define blk2(i) (W[i&15]+=s1(W[(i-2)&15])+W[(i-7)&15]+s0(W[(i-15)&15]))
00100 
00101 #define Ch(x,y,z) (z^(x&(y^z)))
00102 #define Maj(x,y,z) ((x&y)|(z&(x|y)))
00103 
00104 #define a(i) T[(0-i)&7]
00105 #define b(i) T[(1-i)&7]
00106 #define c(i) T[(2-i)&7]
00107 #define d(i) T[(3-i)&7]
00108 #define e(i) T[(4-i)&7]
00109 #define f(i) T[(5-i)&7]
00110 #define g(i) T[(6-i)&7]
00111 #define h(i) T[(7-i)&7]
00112 
00113 #define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+K[i+j]+(j?blk2(i):blk0(i));\
00114         d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i))
00115 
00116 // for SHA256
00117 #define S0(x) (rotrFixed(x,2)^rotrFixed(x,13)^rotrFixed(x,22))
00118 #define S1(x) (rotrFixed(x,6)^rotrFixed(x,11)^rotrFixed(x,25))
00119 #define s0(x) (rotrFixed(x,7)^rotrFixed(x,18)^(x>>3))
00120 #define s1(x) (rotrFixed(x,17)^rotrFixed(x,19)^(x>>10))
00121 
00122 void SHA256::Transform(word32 *state, const word32 *data)
00123 {
00124         word32 W[16];
00125         word32 T[8];
00126     /* Copy context->state[] to working vars */
00127         memcpy(T, state, sizeof(T));
00128     /* 64 operations, partially loop unrolled */
00129         for (unsigned int j=0; j<64; j+=16)
00130         {
00131                 R( 0); R( 1); R( 2); R( 3);
00132                 R( 4); R( 5); R( 6); R( 7);
00133                 R( 8); R( 9); R(10); R(11);
00134                 R(12); R(13); R(14); R(15);
00135         }
00136     /* Add the working vars back into context.state[] */
00137     state[0] += a(0);
00138     state[1] += b(0);
00139     state[2] += c(0);
00140     state[3] += d(0);
00141     state[4] += e(0);
00142     state[5] += f(0);
00143     state[6] += g(0);
00144     state[7] += h(0);
00145     /* Wipe variables */
00146         memset(W, 0, sizeof(W));
00147         memset(T, 0, sizeof(T));
00148 }
00149 
00150 const word32 SHA256::K[64] = {
00151         0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
00152         0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
00153         0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
00154         0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
00155         0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
00156         0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
00157         0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
00158         0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
00159         0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
00160         0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
00161         0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
00162         0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
00163         0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
00164         0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
00165         0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
00166         0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
00167 };
00168 
00169 #undef S0
00170 #undef S1
00171 #undef s0
00172 #undef s1
00173 
00174 // *************************************************************
00175 
00176 #ifdef WORD64_AVAILABLE
00177 
00178 void SHA512::InitState(HashWordType *state)
00179 {
00180         state[0] = W64LIT(0x6a09e667f3bcc908);
00181         state[1] = W64LIT(0xbb67ae8584caa73b);
00182         state[2] = W64LIT(0x3c6ef372fe94f82b);
00183         state[3] = W64LIT(0xa54ff53a5f1d36f1);
00184         state[4] = W64LIT(0x510e527fade682d1);
00185         state[5] = W64LIT(0x9b05688c2b3e6c1f);
00186         state[6] = W64LIT(0x1f83d9abfb41bd6b);
00187         state[7] = W64LIT(0x5be0cd19137e2179);
00188 }
00189 
00190 // for SHA512
00191 #define S0(x) (rotrFixed(x,28)^rotrFixed(x,34)^rotrFixed(x,39))
00192 #define S1(x) (rotrFixed(x,14)^rotrFixed(x,18)^rotrFixed(x,41))
00193 #define s0(x) (rotrFixed(x,1)^rotrFixed(x,8)^(x>>7))
00194 #define s1(x) (rotrFixed(x,19)^rotrFixed(x,61)^(x>>6))
00195 
00196 void SHA512::Transform(word64 *state, const word64 *data)
00197 {
00198         word64 W[16];
00199         word64 T[8];
00200     /* Copy context->state[] to working vars */
00201         memcpy(T, state, sizeof(T));
00202     /* 80 operations, partially loop unrolled */
00203         for (unsigned int j=0; j<80; j+=16)
00204         {
00205                 R( 0); R( 1); R( 2); R( 3);
00206                 R( 4); R( 5); R( 6); R( 7);
00207                 R( 8); R( 9); R(10); R(11);
00208                 R(12); R(13); R(14); R(15);
00209         }
00210     /* Add the working vars back into context.state[] */
00211     state[0] += a(0);
00212     state[1] += b(0);
00213     state[2] += c(0);
00214     state[3] += d(0);
00215     state[4] += e(0);
00216     state[5] += f(0);
00217     state[6] += g(0);
00218     state[7] += h(0);
00219     /* Wipe variables */
00220         memset(W, 0, sizeof(W));
00221         memset(T, 0, sizeof(T));
00222 }
00223 
00224 const word64 SHA512::K[80] = {
00225         W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd),
00226         W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc),
00227         W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019),
00228         W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118),
00229         W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe),
00230         W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2),
00231         W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1),
00232         W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694),
00233         W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3),
00234         W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65),
00235         W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483),
00236         W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5),
00237         W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210),
00238         W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4),
00239         W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725),
00240         W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70),
00241         W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926),
00242         W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df),
00243         W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8),
00244         W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b),
00245         W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001),
00246         W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30),
00247         W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910),
00248         W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8),
00249         W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53),
00250         W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8),
00251         W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb),
00252         W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3),
00253         W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60),
00254         W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec),
00255         W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9),
00256         W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b),
00257         W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207),
00258         W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178),
00259         W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6),
00260         W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b),
00261         W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493),
00262         W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c),
00263         W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a),
00264         W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817)
00265 };
00266 
00267 void SHA384::InitState(HashWordType *state)
00268 {
00269         state[0] = W64LIT(0xcbbb9d5dc1059ed8);
00270         state[1] = W64LIT(0x629a292a367cd507);
00271         state[2] = W64LIT(0x9159015a3070dd17);
00272         state[3] = W64LIT(0x152fecd8f70e5939);
00273         state[4] = W64LIT(0x67332667ffc00b31);
00274         state[5] = W64LIT(0x8eb44a8768581511);
00275         state[6] = W64LIT(0xdb0c2e0d64f98fa7);
00276         state[7] = W64LIT(0x47b5481dbefa4fa4);
00277 }
00278 
00279 #endif
00280 
00281 NAMESPACE_END

Generated on Sat Jan 22 09:44:34 2005 for Crypto++ by  doxygen 1.4.0