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
12NAMESPACE_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
34void 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
53typedef BlockGetAndPut<word32, BigEndian> Block;
54
55void 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
87void 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.
120const 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
140NAMESPACE_END
141