Crypto++  5.6.5
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 "cpu.h"
18 #include "misc.h"
19 #include "cpu.h"
20 
21 NAMESPACE_BEGIN(CryptoPP)
22 
23 // SHACAL-2 function and round definitions
24 
25 #define S0(x) (rotrConstant<2>(x)^rotrConstant<13>(x)^rotrConstant<22>(x))
26 #define S1(x) (rotrConstant<6>(x)^rotrConstant<11>(x)^rotrConstant<25>(x))
27 #define s0(x) (rotrConstant<7>(x)^rotrConstant<18>(x)^(x>>3))
28 #define s1(x) (rotrConstant<17>(x)^rotrConstant<19>(x)^(x>>10))
29 
30 #define Ch(x,y,z) (z^(x&(y^z)))
31 #define Maj(x,y,z) ((x&y)|(z&(x|y)))
32 
33 /* R is the SHA-256 round function. */
34 /* This macro increments the k argument as a side effect. */
35 #define R(a,b,c,d,e,f,g,h,k) \
36  h+=S1(e)+Ch(e,f,g)+*k++;d+=h;h+=S0(a)+Maj(a,b,c);
37 
38 /* P is the inverse of the SHA-256 round function. */
39 /* This macro decrements the k argument as a side effect. */
40 #define P(a,b,c,d,e,f,g,h,k) \
41  h-=S0(a)+Maj(a,b,c);d-=h;h-=S1(e)+Ch(e,f,g)+*--k;
42 
43 #if CRYPTOPP_SHANI_AVAILABLE
44 extern void SHACAL2_Enc_ProcessAndXorBlock_SHANI(const word32* subKeys,
45  const byte *inBlock, const byte *xorBlock, byte *outBlock);
46 #endif
47 
48 void SHACAL2::Base::UncheckedSetKey(const byte *userKey, unsigned int keylen, const NameValuePairs &)
49 {
50  AssertValidKeyLength(keylen);
51 
52  word32 *rk = m_key;
53  unsigned int i;
54 
55  // 32-bit GCC 5.4 hack... m_key.size() returns 0. Note: this surfaced after changing
56  // m_key to FixedSizeAlignedSecBlock at commit 1ab1e08ac5b5a0d63374de0c.
57  GetUserKey(BIG_ENDIAN_ORDER, rk, 64, userKey, keylen);
58  for (i = 0; i < 48; i++, rk++)
59  {
60  rk[16] = rk[0] + s0(rk[1]) + rk[9] + s1(rk[14]);
61  rk[0] += K[i];
62  }
63  for (i = 48; i < 64; i++, rk++)
64  {
65  rk[0] += K[i];
66  }
67 }
68 
70 
71 void SHACAL2::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
72 {
73 #if CRYPTOPP_SHANI_AVAILABLE
74  if (HasSHA())
75  {
76  SHACAL2_Enc_ProcessAndXorBlock_SHANI(m_key, inBlock, xorBlock, outBlock);
77  return;
78  }
79 #endif
80 
81  word32 a, b, c, d, e, f, g, h;
82  const word32 *rk = m_key;
83 
84  /*
85  * map byte array block to cipher state:
86  */
87  Block::Get(inBlock)(a)(b)(c)(d)(e)(f)(g)(h);
88 
89  // Perform SHA-256 transformation.
90 
91  /* 64 operations, partially loop unrolled */
92  for (unsigned int j=0; j<64; j+=8)
93  {
94  R(a,b,c,d,e,f,g,h,rk);
95  R(h,a,b,c,d,e,f,g,rk);
96  R(g,h,a,b,c,d,e,f,rk);
97  R(f,g,h,a,b,c,d,e,rk);
98  R(e,f,g,h,a,b,c,d,rk);
99  R(d,e,f,g,h,a,b,c,rk);
100  R(c,d,e,f,g,h,a,b,rk);
101  R(b,c,d,e,f,g,h,a,rk);
102  }
103 
104  /*
105  * map cipher state to byte array block:
106  */
107 
108  Block::Put(xorBlock, outBlock)(a)(b)(c)(d)(e)(f)(g)(h);
109 }
110 
111 void SHACAL2::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
112 {
113  word32 a, b, c, d, e, f, g, h;
114  const word32 *rk = m_key + 64;
115 
116  /*
117  * map byte array block to cipher state:
118  */
119  Block::Get(inBlock)(a)(b)(c)(d)(e)(f)(g)(h);
120 
121  // Perform inverse SHA-256 transformation.
122 
123  /* 64 operations, partially loop unrolled */
124  for (unsigned int j=0; j<64; j+=8)
125  {
126  P(b,c,d,e,f,g,h,a,rk);
127  P(c,d,e,f,g,h,a,b,rk);
128  P(d,e,f,g,h,a,b,c,rk);
129  P(e,f,g,h,a,b,c,d,rk);
130  P(f,g,h,a,b,c,d,e,rk);
131  P(g,h,a,b,c,d,e,f,rk);
132  P(h,a,b,c,d,e,f,g,rk);
133  P(a,b,c,d,e,f,g,h,rk);
134  }
135 
136  /*
137  * map cipher state to byte array block:
138  */
139 
140  Block::Put(xorBlock, outBlock)(a)(b)(c)(d)(e)(f)(g)(h);
141 }
142 
143 // The SHACAL-2 round constants are identical to the SHA-256 round constants.
144 const word32 SHACAL2::Base::K[64] =
145 {
146  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
147  0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
148  0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
149  0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
150  0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
151  0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
152  0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
153  0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
154  0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
155  0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
156  0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
157  0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
158  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
159  0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
160  0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
161  0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
162 };
163 
164 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:2403
byte order is big-endian
Definition: cryptlib.h:145
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:294
Classes for the SHACAL-2 block cipher.