Fabcoin Core  0.16.2
P2P Digital Currency
keccak.cpp
Go to the documentation of this file.
1 // keccak.cpp - modified by Wei Dai from Ronny Van Keer's public domain sha3-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 "keccak.h"
19 
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 Keccak::Update(const byte *input, size_t length)
253 {
254  CRYPTOPP_ASSERT((input && length) || !(input || length));
255  if (!length) { return; }
256 
257  size_t spaceLeft;
258  while (length >= (spaceLeft = r() - m_counter))
259  {
260  if (spaceLeft)
261  xorbuf(m_state.BytePtr() + m_counter, input, spaceLeft);
262  KeccakF1600(m_state);
263  input += spaceLeft;
264  length -= spaceLeft;
265  m_counter = 0;
266  }
267 
268  if (length)
269  xorbuf(m_state.BytePtr() + m_counter, input, length);
270  m_counter += (unsigned int)length;
271 }
272 
274 {
275  memset(m_state, 0, m_state.SizeInBytes());
276  m_counter = 0;
277 }
278 
279 void Keccak::TruncatedFinal(byte *hash, size_t size)
280 {
282 
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 
uint8_t byte
Definition: Common.h:57
PutBlock< T, B, PA > Put
Definition: misc.h:2237
T rotlFixed(T x, unsigned int y)
Performs a left rotate.
Definition: misc.h:1263
#define NAMESPACE_BEGIN(x)
Definition: config.h:200
void TruncatedFinal(byte *hash, size_t size)
Computes the hash of the current message.
Definition: keccak.cpp:279
Classes for Keccak message digests.
static GetBlock< T, B, GA > Get(const void *block)
Definition: misc.h:2236
Access a block of memory.
Definition: misc.h:2233
unsigned int r() const
Definition: keccak.h:63
void ThrowIfInvalidTruncatedSize(size_t size) const
Validates a truncated digest size.
Definition: cryptlib.cpp:416
void Update(const byte *input, size_t length)
Updates a hash with additional input.
Definition: keccak.cpp:252
unsigned int m_counter
Definition: keccak.h:66
#define W64LIT(x)
Definition: config.h:241
BlockGetAndPut< word32, BigEndian > Block
Definition: cast.cpp:34
unsigned long long word64
Definition: config.h:240
void Restart()
Restart the hash.
Definition: keccak.cpp:273
FixedSizeSecBlock< word64, 25 > m_state
Definition: keccak.h:65
#define CRYPTOPP_ASSERT(exp)
Definition: trap.h:92
void xorbuf(byte *buf, const byte *mask, size_t count)
Performs an XOR of a buffer with a mask.
Definition: misc.cpp:28
uint8_t const size_t const size
Definition: sha3.h:20
void * memcpy(void *a, const void *b, size_t c)
#define round(a, b, c, x, mul)
#define NAMESPACE_END
Definition: config.h:201
size_type SizeInBytes() const
Provides the number of bytes in the SecBlock.
Definition: secblock.h:538
byte * BytePtr()
Provides a byte pointer to the first element in the memory block.
Definition: secblock.h:531