Crypto++  5.6.5 Free C++ class library of cryptographic schemes
shacal2.cpp
1 // shacal2.cpp - by Kevin Springle, 2003
2 //
3 // Portions of this code were derived from
4 // Wei Dai's implementation of SHA-2
5 //
6 // The original code and all modifications are in the public domain.
7
8 #include "pch.h"
9 #include "shacal2.h"
10 #include "misc.h"
11
12 NAMESPACE_BEGIN(CryptoPP)
13
14 // SHACAL-2 function and round definitions
15
16 #define S0(x) (rotrFixed(x,2)^rotrFixed(x,13)^rotrFixed(x,22))
17 #define S1(x) (rotrFixed(x,6)^rotrFixed(x,11)^rotrFixed(x,25))
18 #define s0(x) (rotrFixed(x,7)^rotrFixed(x,18)^(x>>3))
19 #define s1(x) (rotrFixed(x,17)^rotrFixed(x,19)^(x>>10))
20
21 #define Ch(x,y,z) (z^(x&(y^z)))
22 #define Maj(x,y,z) ((x&y)|(z&(x|y)))
23
24 /* R is the SHA-256 round function. */
25 /* This macro increments the k argument as a side effect. */
26 #define R(a,b,c,d,e,f,g,h,k) \
27  h+=S1(e)+Ch(e,f,g)+*k++;d+=h;h+=S0(a)+Maj(a,b,c);
28
29 /* P is the inverse of the SHA-256 round function. */
30 /* This macro decrements the k argument as a side effect. */
31 #define P(a,b,c,d,e,f,g,h,k) \
32  h-=S0(a)+Maj(a,b,c);d-=h;h-=S1(e)+Ch(e,f,g)+*--k;
33
34 void SHACAL2::Base::UncheckedSetKey(const byte *userKey, unsigned int keylen, const NameValuePairs &)
35 {
36  AssertValidKeyLength(keylen);
37
38  word32 *rk = m_key;
39  unsigned int i;
40
41  GetUserKey(BIG_ENDIAN_ORDER, rk, m_key.size(), userKey, keylen);
42  for (i = 0; i < 48; i++, rk++)
43  {
44  rk[16] = rk[0] + s0(rk[1]) + rk[9] + s1(rk[14]);
45  rk[0] += K[i];
46  }
47  for (i = 48; i < 64; i++, rk++)
48  {
49  rk[0] += K[i];
50  }
51 }
52
54
55 void SHACAL2::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
56 {
57  word32 a, b, c, d, e, f, g, h;
58  const word32 *rk = m_key;
59
60  /*
61  * map byte array block to cipher state:
62  */
63  Block::Get(inBlock)(a)(b)(c)(d)(e)(f)(g)(h);
64
65  // Perform SHA-256 transformation.
66
67  /* 64 operations, partially loop unrolled */
68  for (unsigned int j=0; j<64; j+=8)
69  {
70  R(a,b,c,d,e,f,g,h,rk);
71  R(h,a,b,c,d,e,f,g,rk);
72  R(g,h,a,b,c,d,e,f,rk);
73  R(f,g,h,a,b,c,d,e,rk);
74  R(e,f,g,h,a,b,c,d,rk);
75  R(d,e,f,g,h,a,b,c,rk);
76  R(c,d,e,f,g,h,a,b,rk);
77  R(b,c,d,e,f,g,h,a,rk);
78  }
79
80  /*
81  * map cipher state to byte array block:
82  */
83
84  Block::Put(xorBlock, outBlock)(a)(b)(c)(d)(e)(f)(g)(h);
85 }
86
87 void SHACAL2::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
88 {
89  word32 a, b, c, d, e, f, g, h;
90  const word32 *rk = m_key + 64;
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 inverse SHA-256 transformation.
98
99  /* 64 operations, partially loop unrolled */
100  for (unsigned int j=0; j<64; j+=8)
101  {
102  P(b,c,d,e,f,g,h,a,rk);
103  P(c,d,e,f,g,h,a,b,rk);
104  P(d,e,f,g,h,a,b,c,rk);
105  P(e,f,g,h,a,b,c,d,rk);
106  P(f,g,h,a,b,c,d,e,rk);
107  P(g,h,a,b,c,d,e,f,rk);
108  P(h,a,b,c,d,e,f,g,rk);
109  P(a,b,c,d,e,f,g,h,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 // The SHACAL-2 round constants are identical to the SHA-256 round constants.
120 const word32 SHACAL2::Base::K[64] =
121 {
122  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
123  0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
124  0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
125  0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
126  0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
127  0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
128  0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
129  0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
130  0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
131  0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
132  0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
133  0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
134  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
135  0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
136  0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
137  0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
138 };
139
140 NAMESPACE_END
Utility functions for the Crypto++ library.
Access a block of memory.
Definition: misc.h:2259
byte order is big-endian
Definition: cryptlib.h:132
Access a block of memory.
Definition: misc.h:2221
Crypto++ library namespace.
Interface for retrieving values given their names.
Definition: cryptlib.h:282
Classes for the SHACAL-2 block cipher.