1#![allow(clippy::needless_range_loop, dead_code)]
2
3use crate::symmetric::KeccakState;
4
5pub(crate) const SHAKE128_RATE: usize = 168;
6const SHAKE256_RATE: usize = 136;
7const SHA3_256_RATE: usize = 136;
8const SHA3_512_RATE: usize = 72;
9const NROUNDS: usize = 24;
10
11fn rol(a: u64, offset: u64) -> u64
12{
13 (a << offset) ^ (a >> (64-offset))
14}
15
16pub fn load64(x: &[u8]) -> u64
24{
25 let mut r = 0u64;
26 for i in 0..8 {
27 r |= (x[i] as u64) << (8 * i);
28 }
29 r
30}
31
32pub fn store64(x: &mut[u8], mut u: u64)
39{
40 for i in x.iter_mut().take(8) {
41 *i = u as u8;
42 u >>= 8;
43 }
44}
45
46const KECCAKF_ROUNDCONSTANTS: [u64; NROUNDS] = [
48 0x0000000000000001,
49 0x0000000000008082,
50 0x800000000000808a,
51 0x8000000080008000,
52 0x000000000000808b,
53 0x0000000080000001,
54 0x8000000080008081,
55 0x8000000000008009,
56 0x000000000000008a,
57 0x0000000000000088,
58 0x0000000080008009,
59 0x000000008000000a,
60 0x000000008000808b,
61 0x800000000000008b,
62 0x8000000000008089,
63 0x8000000000008003,
64 0x8000000000008002,
65 0x8000000000000080,
66 0x000000000000800a,
67 0x800000008000000a,
68 0x8000000080008081,
69 0x8000000000008080,
70 0x0000000080000001,
71 0x8000000080008008
72];
73
74pub fn keccakf1600_statepermute(state: &mut[u64])
80{
81 let mut aba = state[ 0];
83 let mut abe = state[ 1];
84 let mut abi = state[ 2];
85 let mut abo = state[ 3];
86 let mut abu = state[ 4];
87 let mut aga = state[ 5];
88 let mut age = state[ 6];
89 let mut agi = state[ 7];
90 let mut ago = state[ 8];
91 let mut agu = state[ 9];
92 let mut aka = state[10];
93 let mut ake = state[11];
94 let mut aki = state[12];
95 let mut ako = state[13];
96 let mut aku = state[14];
97 let mut ama = state[15];
98 let mut ame = state[16];
99 let mut ami = state[17];
100 let mut amo = state[18];
101 let mut amu = state[19];
102 let mut asa = state[20];
103 let mut ase = state[21];
104 let mut asi = state[22];
105 let mut aso = state[23];
106 let mut asu = state[24];
107
108 for round in (0..NROUNDS).step_by(2) {
109 let mut bca = aba^aga^aka^ama^asa;
111 let mut bce = abe^age^ake^ame^ase;
112 let mut bci = abi^agi^aki^ami^asi;
113 let mut bco = abo^ago^ako^amo^aso;
114 let mut bcu = abu^agu^aku^amu^asu;
115
116 let mut da = bcu^rol(bce, 1);
118 let mut de = bca^rol(bci, 1);
119 let mut di = bce^rol(bco, 1);
120 let mut d_o = bci^rol(bcu, 1);
121 let mut du = bco^rol(bca, 1);
122
123 aba ^= da;
124 bca = aba;
125 age ^= de;
126 bce = rol(age, 44);
127 aki ^= di;
128 bci = rol(aki, 43);
129 amo ^= d_o;
130 bco = rol(amo, 21);
131 asu ^= du;
132 bcu = rol(asu, 14);
133 let mut eba = bca ^((!bce)& bci );
134 eba ^= KECCAKF_ROUNDCONSTANTS[round];
135 let mut ebe = bce ^((!bci)& bco );
136 let mut ebi = bci ^((!bco)& bcu );
137 let mut ebo = bco ^((!bcu)& bca );
138 let mut ebu = bcu ^((!bca)& bce );
139
140 abo ^= d_o;
141 bca = rol(abo, 28);
142 agu ^= du;
143 bce = rol(agu, 20);
144 aka ^= da;
145 bci = rol(aka, 3);
146 ame ^= de;
147 bco = rol(ame, 45);
148 asi ^= di;
149 bcu = rol(asi, 61);
150 let mut ega = bca ^((!bce)& bci );
151 let mut ege = bce ^((!bci)& bco );
152 let mut egi = bci ^((!bco)& bcu );
153 let mut ego = bco ^((!bcu)& bca );
154 let mut egu = bcu ^((!bca)& bce );
155
156 abe ^= de;
157 bca = rol(abe, 1);
158 agi ^= di;
159 bce = rol(agi, 6);
160 ako ^= d_o;
161 bci = rol(ako, 25);
162 amu ^= du;
163 bco = rol(amu, 8);
164 asa ^= da;
165 bcu = rol(asa, 18);
166 let mut eka = bca ^((!bce)& bci );
167 let mut eke = bce ^((!bci)& bco );
168 let mut eki = bci ^((!bco)& bcu );
169 let mut eko = bco ^((!bcu)& bca );
170 let mut eku = bcu ^((!bca)& bce );
171
172 abu ^= du;
173 bca = rol(abu, 27);
174 aga ^= da;
175 bce = rol(aga, 36);
176 ake ^= de;
177 bci = rol(ake, 10);
178 ami ^= di;
179 bco = rol(ami, 15);
180 aso ^= d_o;
181 bcu = rol(aso, 56);
182 let mut ema = bca ^((!bce)& bci );
183 let mut eme = bce ^((!bci)& bco );
184 let mut emi = bci ^((!bco)& bcu );
185 let mut emo = bco ^((!bcu)& bca );
186 let mut emu = bcu ^((!bca)& bce );
187
188 abi ^= di;
189 bca = rol(abi, 62);
190 ago ^= d_o;
191 bce = rol(ago, 55);
192 aku ^= du;
193 bci = rol(aku, 39);
194 ama ^= da;
195 bco = rol(ama, 41);
196 ase ^= de;
197 bcu = rol(ase, 2);
198 let mut esa = bca ^((!bce)& bci );
199 let mut ese = bce ^((!bci)& bco );
200 let mut esi = bci ^((!bco)& bcu );
201 let mut eso = bco ^((!bcu)& bca );
202 let mut esu = bcu ^((!bca)& bce );
203
204 bca = eba^ega^eka^ema^esa;
206 bce = ebe^ege^eke^eme^ese;
207 bci = ebi^egi^eki^emi^esi;
208 bco = ebo^ego^eko^emo^eso;
209 bcu = ebu^egu^eku^emu^esu;
210
211 da = bcu^rol(bce, 1);
213 de = bca^rol(bci, 1);
214 di = bce^rol(bco, 1);
215 d_o = bci^rol(bcu, 1);
216 du = bco^rol(bca, 1);
217
218 eba ^= da;
219 bca = eba;
220 ege ^= de;
221 bce = rol(ege, 44);
222 eki ^= di;
223 bci = rol(eki, 43);
224 emo ^= d_o;
225 bco = rol(emo, 21);
226 esu ^= du;
227 bcu = rol(esu, 14);
228 aba = bca ^((!bce)& bci );
229 aba ^= KECCAKF_ROUNDCONSTANTS[round+1];
230 abe = bce ^((!bci)& bco );
231 abi = bci ^((!bco)& bcu );
232 abo = bco ^((!bcu)& bca );
233 abu = bcu ^((!bca)& bce );
234
235 ebo ^= d_o;
236 bca = rol(ebo, 28);
237 egu ^= du;
238 bce = rol(egu, 20);
239 eka ^= da;
240 bci = rol(eka, 3);
241 eme ^= de;
242 bco = rol(eme, 45);
243 esi ^= di;
244 bcu = rol(esi, 61);
245 aga = bca ^((!bce)& bci );
246 age = bce ^((!bci)& bco );
247 agi = bci ^((!bco)& bcu );
248 ago = bco ^((!bcu)& bca );
249 agu = bcu ^((!bca)& bce );
250
251 ebe ^= de;
252 bca = rol(ebe, 1);
253 egi ^= di;
254 bce = rol(egi, 6);
255 eko ^= d_o;
256 bci = rol(eko, 25);
257 emu ^= du;
258 bco = rol(emu, 8);
259 esa ^= da;
260 bcu = rol(esa, 18);
261 aka = bca ^((!bce)& bci );
262 ake = bce ^((!bci)& bco );
263 aki = bci ^((!bco)& bcu );
264 ako = bco ^((!bcu)& bca );
265 aku = bcu ^((!bca)& bce );
266
267 ebu ^= du;
268 bca = rol(ebu, 27);
269 ega ^= da;
270 bce = rol(ega, 36);
271 eke ^= de;
272 bci = rol(eke, 10);
273 emi ^= di;
274 bco = rol(emi, 15);
275 eso ^= d_o;
276 bcu = rol(eso, 56);
277 ama = bca ^((!bce)& bci );
278 ame = bce ^((!bci)& bco );
279 ami = bci ^((!bco)& bcu );
280 amo = bco ^((!bcu)& bca );
281 amu = bcu ^((!bca)& bce );
282
283 ebi ^= di;
284 bca = rol(ebi, 62);
285 ego ^= d_o;
286 bce = rol(ego, 55);
287 eku ^= du;
288 bci = rol(eku, 39);
289 ema ^= da;
290 bco = rol(ema, 41);
291 ese ^= de;
292 bcu = rol(ese, 2);
293 asa = bca ^((!bce)& bci );
294 ase = bce ^((!bci)& bco );
295 asi = bci ^((!bco)& bcu );
296 aso = bco ^((!bcu)& bca );
297 asu = bcu ^((!bca)& bce );
298 }
299
300 state[ 0] = aba;
301 state[ 1] = abe;
302 state[ 2] = abi;
303 state[ 3] = abo;
304 state[ 4] = abu;
305 state[ 5] = aga;
306 state[ 6] = age;
307 state[ 7] = agi;
308 state[ 8] = ago;
309 state[ 9] = agu;
310 state[10] = aka;
311 state[11] = ake;
312 state[12] = aki;
313 state[13] = ako;
314 state[14] = aku;
315 state[15] = ama;
316 state[16] = ame;
317 state[17] = ami;
318 state[18] = amo;
319 state[19] = amu;
320 state[20] = asa;
321 state[21] = ase;
322 state[22] = asi;
323 state[23] = aso;
324 state[24] = asu;
325}
326
327pub(crate) fn keccak_squeezeblocks(h: &mut[u8], mut nblocks: usize, s: &mut [u64], r: usize)
338{
339 let mut idx = 0usize;
340 while nblocks > 0 {
341 keccakf1600_statepermute(s);
342 for i in 0..r/8 {
343 store64(&mut h[idx+8*i..], s[i])
344 }
345 idx += r;
346 nblocks -= 1;
347 }
348}
349
350pub(crate) fn shake128_squeezeblocks(out: &mut[u8], nblocks: usize, state: &mut KeccakState)
361{
362 keccak_squeezeblocks(out, nblocks, &mut state.s, SHAKE128_RATE);
363}
364
365pub(crate) fn shake256(out: &mut[u8], mut outlen: usize, input: &[u8], inlen: usize)
374{
375 let mut state = KeccakState::new();
376 let mut idx = 0;
377 shake256_absorb_once(&mut state, input, inlen);
378 let nblocks = outlen/SHAKE256_RATE;
379 shake256_squeezeblocks(&mut out[idx..], nblocks, &mut state);
380 outlen -= nblocks*SHAKE256_RATE;
381 idx += nblocks*SHAKE256_RATE;
382 shake256_squeeze(&mut out[idx..], outlen, &mut state);
383}
384
385pub(crate) fn sha3_256(h: &mut[u8], input: &[u8], inlen: usize)
393{
394 let mut s = [0u64; 25];
395 keccak_absorb_once(&mut s, SHA3_256_RATE, input, inlen, 0x06);
396 keccakf1600_statepermute(&mut s);
397 for i in 0..4 {
398 store64(&mut h[8*i..], s[i]);
399 }
400}
401
402pub(crate) fn sha3_512(h: &mut[u8], input: &[u8], inlen: usize)
410{
411 let mut s = [0u64; 25];
412 keccak_absorb_once(&mut s, SHA3_512_RATE, input, inlen, 0x06);
413 keccakf1600_statepermute(&mut s);
414 for i in 0..8 {
415 store64(&mut h[8*i..], s[i]);
416 }
417}
418
419
420
421fn keccak_finalize(s: &mut[u64], pos: usize, r: usize, p: u8)
430{
431 s[pos/8] ^= (p as u64) << 8*(pos%8);
432 s[r/8-1] ^= 1u64 << 63;
433}
434
435pub(crate) fn keccak_absorb_once(
446 s: &mut[u64],
447 r: usize,
448 input: &[u8],
449 mut inlen:
450 usize,
451 p: u8)
452{
453 for i in s.iter_mut() {
455 *i = 0;
456 }
457
458 let mut idx = 0usize;
459 while inlen >= r {
460 for i in 0..(r/8) {
461 s[i] ^= load64(&input[idx+8*i..]);
462 }
463 idx += r;
464 inlen -= r;
465 keccakf1600_statepermute(s);
466 }
467
468 for i in 0..inlen {
469 s[i/8] ^= (input[idx+i] as u64) << 8*(i%8);
470 }
471 s[inlen/8] ^= (p as u64) << 8*(inlen%8);
472 s[(r-1)/8] ^= 1u64 << 63;
473}
474
475pub(crate) fn keccak_squeeze(
488 out: &mut[u8],
489 mut outlen: usize,
490 s: &mut [u64],
491 mut pos: usize,
492 r: usize
493) -> usize
494{
495 let mut idx = 0;
496 while outlen > 0 {
497 if pos == r {
498 keccakf1600_statepermute(s);
499 pos = 0
500 }
501 let mut i = pos;
502 while i < r && i < pos+outlen {
503 out[idx] = (s[i/8] >> 8*(i%8)) as u8;
504 i += 1;
505 idx += 1;
506 }
507 outlen -= i-pos;
508 pos = i;
509 }
510 pos
511}
512
513fn shake128_init(state: &mut KeccakState)
519{
520 state.reset()
521}
522
523
524fn shake128_finalize(state: &mut KeccakState)
530{
531 keccak_finalize(&mut state.s, state.pos, SHAKE128_RATE, 0x1F);
532 state.pos = SHAKE128_RATE;
533}
534
535fn shake128_squeeze(out: &mut[u8], outlen: usize, state: &mut KeccakState)
544{
545 state.pos = keccak_squeeze(out, outlen, &mut state.s, state.pos, SHAKE128_RATE);
546}
547
548pub(crate) fn shake128_absorb_once(state: &mut KeccakState, input: &[u8], inlen: usize)
556{
557 keccak_absorb_once(&mut state.s, SHAKE128_RATE, input, inlen, 0x1F);
558 state.pos = SHAKE128_RATE;
559}
560
561fn shake256_init(state: &mut KeccakState) {
562 state.reset();
563}
564
565fn shake256_finalize(state: &mut KeccakState)
566{
567 keccak_finalize(&mut state.s, state.pos, SHAKE256_RATE, 0x1F);
568 state.pos = SHAKE256_RATE;
569}
570
571fn shake256_squeeze(out: &mut[u8], outlen: usize, state: &mut KeccakState)
572{
573 state.pos = keccak_squeeze(out, outlen, &mut state.s, state.pos, SHAKE256_RATE);
574}
575
576fn shake256_absorb_once(state: &mut KeccakState, input: &[u8], inlen: usize)
577{
578 keccak_absorb_once(&mut state.s, SHAKE256_RATE, input, inlen, 0x1F);
579 state.pos = SHAKE256_RATE;
580}
581
582fn shake256_squeezeblocks(out: &mut[u8], nblocks: usize, state: &mut KeccakState)
583{
584 keccak_squeezeblocks(out, nblocks, &mut state.s, SHAKE256_RATE);
585}
586
587fn shake128(out: &mut[u8], mut outlen: usize, input: &[u8], inlen: usize)
588{
589 let mut state = KeccakState::new();
590 let mut idx = 0;
591 shake128_absorb_once(&mut state, input, inlen);
592 let nblocks = outlen/SHAKE128_RATE;
593 shake128_squeezeblocks(&mut out[idx..], nblocks, &mut state);
594 outlen -= nblocks*SHAKE128_RATE;
595 idx += nblocks*SHAKE128_RATE;
596 shake128_squeeze(&mut out[idx..], outlen, &mut state);
597}
598