Crypto++  7.0
Free C++ class library of cryptographic schemes
shacal2.cpp
1 // shacal2.cpp - written by Kevin Springle, 2003
2 //
3 // Portions of this code were derived from
4 // Wei Dai's implementation of SHA-2
5 //
6 // Jack Lloyd and the Botan team allowed Crypto++ to use parts of
7 // Botan's implementation under the same license as Crypto++
8 // is released. The code for SHACAL2_Enc_ProcessAndXorBlock_SHANI
9 // below is Botan's x86_encrypt_blocks with minor tweaks. Many thanks
10 // to the Botan team. Also see http://github.com/randombit/botan/.
11 //
12 // The original code and all modifications are in the public domain.
13 
14 #include "pch.h"
15 #include "config.h"
16 #include "shacal2.h"
17 #include "misc.h"
18 #include "cpu.h"
19 
20 NAMESPACE_BEGIN(CryptoPP)
21 
22 // SHACAL-2 function and round definitions
23 
24 #define S0(x) (rotrConstant<2>(x)^rotrConstant<13>(x)^rotrConstant<22>(x))
25 #define S1(x) (rotrConstant<6>(x)^rotrConstant<11>(x)^rotrConstant<25>(x))
26 #define s0(x) (rotrConstant<7>(x)^rotrConstant<18>(x)^(x>>3))
27 #define s1(x) (rotrConstant<17>(x)^rotrConstant<19>(x)^(x>>10))
28 
29 #define Ch(x,y,z) (z^(x&(y^z)))
30 #define Maj(x,y,z) ((x&y)|(z&(x|y)))
31 
32 /* R is the SHA-256 round function. */
33 /* This macro increments the k argument as a side effect. */
34 #define R(a,b,c,d,e,f,g,h,k) \
35  h+=S1(e)+Ch(e,f,g)+*k++;d+=h;h+=S0(a)+Maj(a,b,c);
36 
37 /* P is the inverse of the SHA-256 round function. */
38 /* This macro decrements the k argument as a side effect. */
39 #define P(a,b,c,d,e,f,g,h,k) \
40  h-=S0(a)+Maj(a,b,c);d-=h;h-=S1(e)+Ch(e,f,g)+*--k;
41 
42 #if CRYPTOPP_SHANI_AVAILABLE
43 extern void SHACAL2_Enc_ProcessAndXorBlock_SHANI(const word32* subKeys,
44  const byte *inBlock, const byte *xorBlock, byte *outBlock);
45 #endif
46 
47 void SHACAL2::Base::UncheckedSetKey(const byte *userKey, unsigned int keylen, const NameValuePairs &)
48 {
49  AssertValidKeyLength(keylen);
50 
51  word32 *rk = m_key;
52  unsigned int i;
53 
54  // 32-bit GCC 5.4 hack... m_key.size() returns 0. Note: this surfaced after changing
55  // m_key to FixedSizeAlignedSecBlock at commit 1ab1e08ac5b5a0d63374de0c.
56  GetUserKey(BIG_ENDIAN_ORDER, rk, 64, userKey, keylen);
57  for (i = 0; i < 48; i++, rk++)
58  {
59  rk[16] = rk[0] + s0(rk[1]) + rk[9] + s1(rk[14]);
60  rk[0] += K[i];
61  }
62  for (i = 48; i < 64; i++, rk++)
63  {
64  rk[0] += K[i];
65  }
66 }
67 
69 
70 void SHACAL2::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
71 {
72 #if CRYPTOPP_SHANI_AVAILABLE
73  if (HasSHA())
74  {
75  SHACAL2_Enc_ProcessAndXorBlock_SHANI(m_key, inBlock, xorBlock, outBlock);
76  return;
77  }
78 #endif
79 
80  word32 a, b, c, d, e, f, g, h;
81  const word32 *rk = m_key;
82 
83  /*
84  * map byte array block to cipher state:
85  */
86  Block::Get(inBlock)(a)(b)(c)(d)(e)(f)(g)(h);
87 
88  // Perform SHA-256 transformation.
89 
90  /* 64 operations, partially loop unrolled */
91  for (unsigned int j=0; j<64; j+=8)
92  {
93  R(a,b,c,d,e,f,g,h,rk);
94  R(h,a,b,c,d,e,f,g,rk);
95  R(g,h,a,b,c,d,e,f,rk);
96  R(f,g,h,a,b,c,d,e,rk);
97  R(e,f,g,h,a,b,c,d,rk);
98  R(d,e,f,g,h,a,b,c,rk);
99  R(c,d,e,f,g,h,a,b,rk);
100  R(b,c,d,e,f,g,h,a,rk);
101  }
102 
103  /*
104  * map cipher state to byte array block:
105  */
106 
107  Block::Put(xorBlock, outBlock)(a)(b)(c)(d)(e)(f)(g)(h);
108 }
109 
110 void SHACAL2::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
111 {
112  word32 a, b, c, d, e, f, g, h;
113  const word32 *rk = m_key + 64;
114 
115  /*
116  * map byte array block to cipher state:
117  */
118  Block::Get(inBlock)(a)(b)(c)(d)(e)(f)(g)(h);
119 
120  // Perform inverse SHA-256 transformation.
121 
122  /* 64 operations, partially loop unrolled */
123  for (unsigned int j=0; j<64; j+=8)
124  {
125  P(b,c,d,e,f,g,h,a,rk);
126  P(c,d,e,f,g,h,a,b,rk);
127  P(d,e,f,g,h,a,b,c,rk);
128  P(e,f,g,h,a,b,c,d,rk);
129  P(f,g,h,a,b,c,d,e,rk);
130  P(g,h,a,b,c,d,e,f,rk);
131  P(h,a,b,c,d,e,f,g,rk);
132  P(a,b,c,d,e,f,g,h,rk);
133  }
134 
135  /*
136  * map cipher state to byte array block:
137  */
138 
139  Block::Put(xorBlock, outBlock)(a)(b)(c)(d)(e)(f)(g)(h);
140 }
141 
142 // The SHACAL-2 round constants are identical to the SHA-256 round constants.
143 const word32 SHACAL2::Base::K[64] =
144 {
145  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
146  0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
147  0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
148  0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
149  0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
150  0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
151  0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
152  0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
153  0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
154  0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
155  0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
156  0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
157  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
158  0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
159  0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
160  0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
161 };
162 
163 NAMESPACE_END
bool HasSHA()
Determines SHA availability.
Definition: cpu.h:184
Utility functions for the Crypto++ library.
Library configuration file.
Access a block of memory.
Definition: misc.h:2402
Precompiled header file.
byte order is big-endian
Definition: cryptlib.h:144
Functions for CPU features and intrinsics.
Access a block of memory.
Definition: misc.h:2365
Crypto++ library namespace.
Interface for retrieving values given their names.
Definition: cryptlib.h:290
Classes for the SHACAL-2 block cipher.