Crypto++  5.6.3
Free C++ class library of cryptographic schemes
sha3.cpp
1 // sha3.cpp - modified by Wei Dai from Ronny Van Keer's public domain Keccak-simple.c
2 // all modifications here are placed in the public domain by Wei Dai
3 
4 /*
5 The Keccak sponge function, designed by Guido Bertoni, Joan Daemen,
6 Michael Peeters and Gilles Van Assche. For more information, feedback or
7 questions, please refer to our website: http://keccak.noekeon.org/
8 
9 Implementation by Ronny Van Keer,
10 hereby denoted as "the implementer".
11 
12 To the extent possible under law, the implementer has waived all copyright
13 and related or neighboring rights to the source code in this file.
14 http://creativecommons.org/publicdomain/zero/1.0/
15 */
16 
17 #include "pch.h"
18 #include "sha3.h"
19 
20 NAMESPACE_BEGIN(CryptoPP)
21 
22 static const word64 KeccakF_RoundConstants[24] =
23 {
24  W64LIT(0x0000000000000001), W64LIT(0x0000000000008082), W64LIT(0x800000000000808a),
25  W64LIT(0x8000000080008000), W64LIT(0x000000000000808b), W64LIT(0x0000000080000001),
26  W64LIT(0x8000000080008081), W64LIT(0x8000000000008009), W64LIT(0x000000000000008a),
27  W64LIT(0x0000000000000088), W64LIT(0x0000000080008009), W64LIT(0x000000008000000a),
28  W64LIT(0x000000008000808b), W64LIT(0x800000000000008b), W64LIT(0x8000000000008089),
29  W64LIT(0x8000000000008003), W64LIT(0x8000000000008002), W64LIT(0x8000000000000080),
30  W64LIT(0x000000000000800a), W64LIT(0x800000008000000a), W64LIT(0x8000000080008081),
31  W64LIT(0x8000000000008080), W64LIT(0x0000000080000001), W64LIT(0x8000000080008008)
32 };
33 
34 static void KeccakF1600(word64 *state)
35 {
36  {
37  word64 Aba, Abe, Abi, Abo, Abu;
38  word64 Aga, Age, Agi, Ago, Agu;
39  word64 Aka, Ake, Aki, Ako, Aku;
40  word64 Ama, Ame, Ami, Amo, Amu;
41  word64 Asa, Ase, Asi, Aso, Asu;
42  word64 BCa, BCe, BCi, BCo, BCu;
43  word64 Da, De, Di, Do, Du;
44  word64 Eba, Ebe, Ebi, Ebo, Ebu;
45  word64 Ega, Ege, Egi, Ego, Egu;
46  word64 Eka, Eke, Eki, Eko, Eku;
47  word64 Ema, Eme, Emi, Emo, Emu;
48  word64 Esa, Ese, Esi, Eso, Esu;
49 
50  //copyFromState(A, state)
52  Block::Get(state)(Aba)(Abe)(Abi)(Abo)(Abu)(Aga)(Age)(Agi)(Ago)(Agu)(Aka)(Ake)(Aki)(Ako)(Aku)(Ama)(Ame)(Ami)(Amo)(Amu)(Asa)(Ase)(Asi)(Aso)(Asu);
53 
54  for( unsigned int round = 0; round < 24; round += 2 )
55  {
56  // prepareTheta
57  BCa = Aba^Aga^Aka^Ama^Asa;
58  BCe = Abe^Age^Ake^Ame^Ase;
59  BCi = Abi^Agi^Aki^Ami^Asi;
60  BCo = Abo^Ago^Ako^Amo^Aso;
61  BCu = Abu^Agu^Aku^Amu^Asu;
62 
63  //thetaRhoPiChiIotaPrepareTheta(round , A, E)
64  Da = BCu^rotlFixed(BCe, 1);
65  De = BCa^rotlFixed(BCi, 1);
66  Di = BCe^rotlFixed(BCo, 1);
67  Do = BCi^rotlFixed(BCu, 1);
68  Du = BCo^rotlFixed(BCa, 1);
69 
70  Aba ^= Da;
71  BCa = Aba;
72  Age ^= De;
73  BCe = rotlFixed(Age, 44);
74  Aki ^= Di;
75  BCi = rotlFixed(Aki, 43);
76  Amo ^= Do;
77  BCo = rotlFixed(Amo, 21);
78  Asu ^= Du;
79  BCu = rotlFixed(Asu, 14);
80  Eba = BCa ^((~BCe)& BCi );
81  Eba ^= (word64)KeccakF_RoundConstants[round];
82  Ebe = BCe ^((~BCi)& BCo );
83  Ebi = BCi ^((~BCo)& BCu );
84  Ebo = BCo ^((~BCu)& BCa );
85  Ebu = BCu ^((~BCa)& BCe );
86 
87  Abo ^= Do;
88  BCa = rotlFixed(Abo, 28);
89  Agu ^= Du;
90  BCe = rotlFixed(Agu, 20);
91  Aka ^= Da;
92  BCi = rotlFixed(Aka, 3);
93  Ame ^= De;
94  BCo = rotlFixed(Ame, 45);
95  Asi ^= Di;
96  BCu = rotlFixed(Asi, 61);
97  Ega = BCa ^((~BCe)& BCi );
98  Ege = BCe ^((~BCi)& BCo );
99  Egi = BCi ^((~BCo)& BCu );
100  Ego = BCo ^((~BCu)& BCa );
101  Egu = BCu ^((~BCa)& BCe );
102 
103  Abe ^= De;
104  BCa = rotlFixed(Abe, 1);
105  Agi ^= Di;
106  BCe = rotlFixed(Agi, 6);
107  Ako ^= Do;
108  BCi = rotlFixed(Ako, 25);
109  Amu ^= Du;
110  BCo = rotlFixed(Amu, 8);
111  Asa ^= Da;
112  BCu = rotlFixed(Asa, 18);
113  Eka = BCa ^((~BCe)& BCi );
114  Eke = BCe ^((~BCi)& BCo );
115  Eki = BCi ^((~BCo)& BCu );
116  Eko = BCo ^((~BCu)& BCa );
117  Eku = BCu ^((~BCa)& BCe );
118 
119  Abu ^= Du;
120  BCa = rotlFixed(Abu, 27);
121  Aga ^= Da;
122  BCe = rotlFixed(Aga, 36);
123  Ake ^= De;
124  BCi = rotlFixed(Ake, 10);
125  Ami ^= Di;
126  BCo = rotlFixed(Ami, 15);
127  Aso ^= Do;
128  BCu = rotlFixed(Aso, 56);
129  Ema = BCa ^((~BCe)& BCi );
130  Eme = BCe ^((~BCi)& BCo );
131  Emi = BCi ^((~BCo)& BCu );
132  Emo = BCo ^((~BCu)& BCa );
133  Emu = BCu ^((~BCa)& BCe );
134 
135  Abi ^= Di;
136  BCa = rotlFixed(Abi, 62);
137  Ago ^= Do;
138  BCe = rotlFixed(Ago, 55);
139  Aku ^= Du;
140  BCi = rotlFixed(Aku, 39);
141  Ama ^= Da;
142  BCo = rotlFixed(Ama, 41);
143  Ase ^= De;
144  BCu = rotlFixed(Ase, 2);
145  Esa = BCa ^((~BCe)& BCi );
146  Ese = BCe ^((~BCi)& BCo );
147  Esi = BCi ^((~BCo)& BCu );
148  Eso = BCo ^((~BCu)& BCa );
149  Esu = BCu ^((~BCa)& BCe );
150 
151  // prepareTheta
152  BCa = Eba^Ega^Eka^Ema^Esa;
153  BCe = Ebe^Ege^Eke^Eme^Ese;
154  BCi = Ebi^Egi^Eki^Emi^Esi;
155  BCo = Ebo^Ego^Eko^Emo^Eso;
156  BCu = Ebu^Egu^Eku^Emu^Esu;
157 
158  //thetaRhoPiChiIotaPrepareTheta(round+1, E, A)
159  Da = BCu^rotlFixed(BCe, 1);
160  De = BCa^rotlFixed(BCi, 1);
161  Di = BCe^rotlFixed(BCo, 1);
162  Do = BCi^rotlFixed(BCu, 1);
163  Du = BCo^rotlFixed(BCa, 1);
164 
165  Eba ^= Da;
166  BCa = Eba;
167  Ege ^= De;
168  BCe = rotlFixed(Ege, 44);
169  Eki ^= Di;
170  BCi = rotlFixed(Eki, 43);
171  Emo ^= Do;
172  BCo = rotlFixed(Emo, 21);
173  Esu ^= Du;
174  BCu = rotlFixed(Esu, 14);
175  Aba = BCa ^((~BCe)& BCi );
176  Aba ^= (word64)KeccakF_RoundConstants[round+1];
177  Abe = BCe ^((~BCi)& BCo );
178  Abi = BCi ^((~BCo)& BCu );
179  Abo = BCo ^((~BCu)& BCa );
180  Abu = BCu ^((~BCa)& BCe );
181 
182  Ebo ^= Do;
183  BCa = rotlFixed(Ebo, 28);
184  Egu ^= Du;
185  BCe = rotlFixed(Egu, 20);
186  Eka ^= Da;
187  BCi = rotlFixed(Eka, 3);
188  Eme ^= De;
189  BCo = rotlFixed(Eme, 45);
190  Esi ^= Di;
191  BCu = rotlFixed(Esi, 61);
192  Aga = BCa ^((~BCe)& BCi );
193  Age = BCe ^((~BCi)& BCo );
194  Agi = BCi ^((~BCo)& BCu );
195  Ago = BCo ^((~BCu)& BCa );
196  Agu = BCu ^((~BCa)& BCe );
197 
198  Ebe ^= De;
199  BCa = rotlFixed(Ebe, 1);
200  Egi ^= Di;
201  BCe = rotlFixed(Egi, 6);
202  Eko ^= Do;
203  BCi = rotlFixed(Eko, 25);
204  Emu ^= Du;
205  BCo = rotlFixed(Emu, 8);
206  Esa ^= Da;
207  BCu = rotlFixed(Esa, 18);
208  Aka = BCa ^((~BCe)& BCi );
209  Ake = BCe ^((~BCi)& BCo );
210  Aki = BCi ^((~BCo)& BCu );
211  Ako = BCo ^((~BCu)& BCa );
212  Aku = BCu ^((~BCa)& BCe );
213 
214  Ebu ^= Du;
215  BCa = rotlFixed(Ebu, 27);
216  Ega ^= Da;
217  BCe = rotlFixed(Ega, 36);
218  Eke ^= De;
219  BCi = rotlFixed(Eke, 10);
220  Emi ^= Di;
221  BCo = rotlFixed(Emi, 15);
222  Eso ^= Do;
223  BCu = rotlFixed(Eso, 56);
224  Ama = BCa ^((~BCe)& BCi );
225  Ame = BCe ^((~BCi)& BCo );
226  Ami = BCi ^((~BCo)& BCu );
227  Amo = BCo ^((~BCu)& BCa );
228  Amu = BCu ^((~BCa)& BCe );
229 
230  Ebi ^= Di;
231  BCa = rotlFixed(Ebi, 62);
232  Ego ^= Do;
233  BCe = rotlFixed(Ego, 55);
234  Eku ^= Du;
235  BCi = rotlFixed(Eku, 39);
236  Ema ^= Da;
237  BCo = rotlFixed(Ema, 41);
238  Ese ^= De;
239  BCu = rotlFixed(Ese, 2);
240  Asa = BCa ^((~BCe)& BCi );
241  Ase = BCe ^((~BCi)& BCo );
242  Asi = BCi ^((~BCo)& BCu );
243  Aso = BCo ^((~BCu)& BCa );
244  Asu = BCu ^((~BCa)& BCe );
245  }
246 
247  //copyToState(state, A)
248  Block::Put(NULL, state)(Aba)(Abe)(Abi)(Abo)(Abu)(Aga)(Age)(Agi)(Ago)(Agu)(Aka)(Ake)(Aki)(Ako)(Aku)(Ama)(Ame)(Ami)(Amo)(Amu)(Asa)(Ase)(Asi)(Aso)(Asu);
249  }
250 }
251 
252 void SHA3::Update(const byte *input, size_t length)
253 {
254  assert((input && length) || !(input || length));
255  if (!length)
256  return;
257 
258  size_t spaceLeft;
259  while (length >= (spaceLeft = r() - m_counter))
260  {
261  if (spaceLeft)
262  xorbuf(m_state.BytePtr() + m_counter, input, spaceLeft);
263  KeccakF1600(m_state);
264  input += spaceLeft;
265  length -= spaceLeft;
266  m_counter = 0;
267  }
268 
269  if (length)
270  xorbuf(m_state.BytePtr() + m_counter, input, length);
271  m_counter += (unsigned int)length;
272 }
273 
275 {
276  memset(m_state, 0, m_state.SizeInBytes());
277  m_counter = 0;
278 }
279 
280 void SHA3::TruncatedFinal(byte *hash, size_t size)
281 {
282  ThrowIfInvalidTruncatedSize(size);
283  m_state.BytePtr()[m_counter] ^= 1;
284  m_state.BytePtr()[r()-1] ^= 0x80;
285  KeccakF1600(m_state);
286  memcpy(hash, m_state, size);
287  Restart();
288 }
289 
290 NAMESPACE_END
T rotlFixed(T x, unsigned int y)
Performs a left rotate.
Definition: misc.h:1166
Classes for SHA-3 message digests.
void Restart()
Restart the hash.
Definition: sha3.cpp:274
void TruncatedFinal(byte *hash, size_t size)
Computes the hash of the current message.
Definition: sha3.cpp:280
void xorbuf(byte *buf, const byte *mask, size_t count)
Performs an XOR of a buffer with a mask.
Definition: misc.cpp:25
void Update(const byte *input, size_t length)
Updates a hash with additional input.
Definition: sha3.cpp:252
Crypto++ library namespace.
size_type SizeInBytes() const
Provides the number of bytes in the SecBlock.
Definition: secblock.h:523
byte * BytePtr()
Provides a byte pointer to the first element in the memory block.
Definition: secblock.h:516