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

Generated on Sun Mar 14 20:44:28 2004 for Crypto++ by doxygen 1.3.6-20040222