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 std::string SHACAL2::Base::AlgorithmProvider() const
48 {
49 #if CRYPTOPP_SHANI_AVAILABLE
50 if (HasSHA())
51 return "SHANI";
52 #endif
53 return "C++";
54 }
55
56 void SHACAL2::Base::UncheckedSetKey(const byte *userKey, unsigned int keylen, const NameValuePairs &)
57 {
58 AssertValidKeyLength(keylen);
59
60 word32 *rk = m_key;
61 unsigned int i;
62
63 // 32-bit GCC 5.4 hack... m_key.size() returns 0. Note: this surfaced after changing
64 // m_key to FixedSizeAlignedSecBlock at commit 1ab1e08ac5b5a0d63374de0c.
65 GetUserKey(BIG_ENDIAN_ORDER, rk, 64, userKey, keylen);
66 for (i = 0; i < 48; i++, rk++)
67 {
68 rk[16] = rk[0] + s0(rk[1]) + rk[9] + s1(rk[14]);
69 rk[0] += K[i];
70 }
71 for (i = 48; i < 64; i++, rk++)
72 {
73 rk[0] += K[i];
74 }
75 }
76
77 typedef BlockGetAndPut<word32, BigEndian> Block;
78
79 void SHACAL2::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
80 {
81 #if CRYPTOPP_SHANI_AVAILABLE
82 if (HasSHA())
83 {
84 SHACAL2_Enc_ProcessAndXorBlock_SHANI(m_key, inBlock, xorBlock, outBlock);
85 return;
86 }
87 #endif
88
89 word32 a, b, c, d, e, f, g, h;
90 const word32 *rk = m_key;
91
92 /*
93 * map byte array block to cipher state:
94 */
95 Block::Get(inBlock)(a)(b)(c)(d)(e)(f)(g)(h);
96
97 // Perform SHA-256 transformation.
98
99 /* 64 operations, partially loop unrolled */
100 for (unsigned int j=0; j<64; j+=8)
101 {
102 R(a,b,c,d,e,f,g,h,rk);
103 R(h,a,b,c,d,e,f,g,rk);
104 R(g,h,a,b,c,d,e,f,rk);
105 R(f,g,h,a,b,c,d,e,rk);
106 R(e,f,g,h,a,b,c,d,rk);
107 R(d,e,f,g,h,a,b,c,rk);
108 R(c,d,e,f,g,h,a,b,rk);
109 R(b,c,d,e,f,g,h,a,rk);
110 }
111
112 /*
113 * map cipher state to byte array block:
114 */
115
116 Block::Put(xorBlock, outBlock)(a)(b)(c)(d)(e)(f)(g)(h);
117 }
118
119 void SHACAL2::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
120 {
121 word32 a, b, c, d, e, f, g, h;
122 const word32 *rk = m_key + 64;
123
124 /*
125 * map byte array block to cipher state:
126 */
127 Block::Get(inBlock)(a)(b)(c)(d)(e)(f)(g)(h);
128
129 // Perform inverse SHA-256 transformation.
130
131 /* 64 operations, partially loop unrolled */
132 for (unsigned int j=0; j<64; j+=8)
133 {
134 P(b,c,d,e,f,g,h,a,rk);
135 P(c,d,e,f,g,h,a,b,rk);
136 P(d,e,f,g,h,a,b,c,rk);
137 P(e,f,g,h,a,b,c,d,rk);
138 P(f,g,h,a,b,c,d,e,rk);
139 P(g,h,a,b,c,d,e,f,rk);
140 P(h,a,b,c,d,e,f,g,rk);
141 P(a,b,c,d,e,f,g,h,rk);
142 }
143
144 /*
145 * map cipher state to byte array block:
146 */
147
148 Block::Put(xorBlock, outBlock)(a)(b)(c)(d)(e)(f)(g)(h);
149 }
150
151 // The SHACAL-2 round constants are identical to the SHA-256 round constants.
152 const word32 SHACAL2::Base::K[64] =
153 {
154 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
155 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
156 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
157 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
158 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
159 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
160 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
161 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
162 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
163 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
164 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
165 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
166 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
167 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
168 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
169 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
170 };
171
172 NAMESPACE_END
HasSHA
bool HasSHA()
Determines SHA availability.
Definition: cpu.h:189
misc.h
Utility functions for the Crypto++ library.
config.h
Library configuration file.
BlockGetAndPut
Access a block of memory.
Definition: misc.h:2466
pch.h
Precompiled header file.
BIG_ENDIAN_ORDER
byte order is big-endian
Definition: cryptlib.h:147
cpu.h
Functions for CPU features and intrinsics.
PutBlock
Access a block of memory.
Definition: misc.h:2429
CryptoPP
Crypto++ library namespace.
NameValuePairs
Interface for retrieving values given their names.
Definition: cryptlib.h:293
shacal2.h
Classes for the SHACAL-2 block cipher.