shacal2.cpp

00001 // shacal2.cpp - by Kevin Springle, 2003
00002 //
00003 // Portions of this code were derived from
00004 // Wei Dai's implementation of SHA-2
00005 //
00006 // The original code and all modifications are in the public domain.
00007 
00008 #include "pch.h"
00009 #include "shacal2.h"
00010 #include "misc.h"
00011 
00012 NAMESPACE_BEGIN(CryptoPP)
00013 
00014 // SHACAL-2 function and round definitions
00015 
00016 #define S0(x) (rotrFixed(x,2)^rotrFixed(x,13)^rotrFixed(x,22))
00017 #define S1(x) (rotrFixed(x,6)^rotrFixed(x,11)^rotrFixed(x,25))
00018 #define s0(x) (rotrFixed(x,7)^rotrFixed(x,18)^(x>>3))
00019 #define s1(x) (rotrFixed(x,17)^rotrFixed(x,19)^(x>>10))
00020 
00021 #define Ch(x,y,z) (z^(x&(y^z)))
00022 #define Maj(x,y,z) ((x&y)|(z&(x|y)))
00023 
00024 /* R is the SHA-256 round function. */
00025 /* This macro increments the k argument as a side effect. */
00026 #define R(a,b,c,d,e,f,g,h,k) \
00027         h+=S1(e)+Ch(e,f,g)+*k++;d+=h;h+=S0(a)+Maj(a,b,c);
00028 
00029 /* P is the inverse of the SHA-256 round function. */
00030 /* This macro decrements the k argument as a side effect. */
00031 #define P(a,b,c,d,e,f,g,h,k) \
00032         h-=S0(a)+Maj(a,b,c);d-=h;h-=S1(e)+Ch(e,f,g)+*--k;
00033 
00034 void SHACAL2::Base::UncheckedSetKey(const byte *userKey, unsigned int keylen, const NameValuePairs &)
00035 {
00036         AssertValidKeyLength(keylen);
00037 
00038         word32 *rk = m_key;
00039         unsigned int i;
00040 
00041         GetUserKey(BIG_ENDIAN_ORDER, rk, m_key.size(), userKey, keylen);
00042         for (i = 0; i < 48; i++, rk++)
00043         {
00044                 rk[16] = rk[0] + s0(rk[1]) + rk[9] + s1(rk[14]);
00045                 rk[0] += K[i];
00046         }
00047         for (i = 48; i < 64; i++, rk++)
00048         {
00049                 rk[0] += K[i];
00050         }
00051 }
00052 
00053 typedef BlockGetAndPut<word32, BigEndian> Block;
00054 
00055 void SHACAL2::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
00056 {
00057         word32 a, b, c, d, e, f, g, h;
00058         const word32 *rk = m_key;
00059 
00060         /*
00061          * map byte array block to cipher state:
00062          */
00063         Block::Get(inBlock)(a)(b)(c)(d)(e)(f)(g)(h);
00064 
00065         // Perform SHA-256 transformation.
00066 
00067         /* 64 operations, partially loop unrolled */
00068         for (unsigned int j=0; j<64; j+=8)
00069         {
00070                 R(a,b,c,d,e,f,g,h,rk);
00071                 R(h,a,b,c,d,e,f,g,rk);
00072                 R(g,h,a,b,c,d,e,f,rk);
00073                 R(f,g,h,a,b,c,d,e,rk);
00074                 R(e,f,g,h,a,b,c,d,rk);
00075                 R(d,e,f,g,h,a,b,c,rk);
00076                 R(c,d,e,f,g,h,a,b,rk);
00077                 R(b,c,d,e,f,g,h,a,rk);
00078         }
00079 
00080         /*
00081          * map cipher state to byte array block:
00082          */
00083 
00084         Block::Put(xorBlock, outBlock)(a)(b)(c)(d)(e)(f)(g)(h);
00085 }
00086 
00087 void SHACAL2::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
00088 {
00089         word32 a, b, c, d, e, f, g, h;
00090         const word32 *rk = m_key + 64;
00091 
00092         /*
00093          * map byte array block to cipher state:
00094          */
00095         Block::Get(inBlock)(a)(b)(c)(d)(e)(f)(g)(h);
00096 
00097         // Perform inverse SHA-256 transformation.
00098 
00099         /* 64 operations, partially loop unrolled */
00100         for (unsigned int j=0; j<64; j+=8)
00101         {
00102                 P(b,c,d,e,f,g,h,a,rk);
00103                 P(c,d,e,f,g,h,a,b,rk);
00104                 P(d,e,f,g,h,a,b,c,rk);
00105                 P(e,f,g,h,a,b,c,d,rk);
00106                 P(f,g,h,a,b,c,d,e,rk);
00107                 P(g,h,a,b,c,d,e,f,rk);
00108                 P(h,a,b,c,d,e,f,g,rk);
00109                 P(a,b,c,d,e,f,g,h,rk);
00110         }
00111 
00112         /*
00113          * map cipher state to byte array block:
00114          */
00115 
00116         Block::Put(xorBlock, outBlock)(a)(b)(c)(d)(e)(f)(g)(h);
00117 }
00118 
00119 // The SHACAL-2 round constants are identical to the SHA-256 round constants.
00120 const word32 SHACAL2::Base::K[64] =
00121 {
00122         0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
00123         0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
00124         0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
00125         0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
00126         0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
00127         0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
00128         0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
00129         0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
00130         0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
00131         0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
00132         0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
00133         0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
00134         0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
00135         0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
00136         0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
00137         0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
00138 };
00139 
00140 NAMESPACE_END

Generated on Sat Dec 23 02:07:10 2006 for Crypto++ by  doxygen 1.5.1-p1