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

# 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(CipherDir dir, const byte *userKey, unsigned int keylen)
    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