1pub const SHAKE128_RATE: usize = 168;
16pub const SHAKE256_RATE: usize = 136;
17
18const NROUNDS: usize = 24;
19
20#[derive(Copy, Clone)]
22pub struct KeccakState {
23 pub s: [u64; 25],
24 pub pos: usize,
25}
26
27impl Default for KeccakState {
28 fn default() -> Self {
29 KeccakState {
30 s: [0u64; 25],
31 pos: 0,
32 }
33 }
34}
35
36impl KeccakState {
37 pub fn init(&mut self) {
39 self.s.fill(0);
40 self.pos = 0;
41 }
42}
43
44fn rol(a: u64, offset: u64) -> u64 {
53 (a << offset) ^ (a >> (64 - offset))
54}
55
56pub fn load64(x: &[u8]) -> u64 {
58 let mut r = 0u64;
59 for i in 0..8 {
60 r |= (x[i] as u64) << (8 * i);
61 }
62 r
63}
64
65pub fn store64(x: &mut [u8], u: u64) {
67 for i in 0..8 {
68 x[i] = (u >> 8 * i) as u8;
69 }
70}
71
72const KECCAKF_ROUNDCONSTANTS: [u64; NROUNDS] = [
74 0x0000000000000001u64,
75 0x0000000000008082u64,
76 0x800000000000808au64,
77 0x8000000080008000u64,
78 0x000000000000808bu64,
79 0x0000000080000001u64,
80 0x8000000080008081u64,
81 0x8000000000008009u64,
82 0x000000000000008au64,
83 0x0000000000000088u64,
84 0x0000000080008009u64,
85 0x000000008000000au64,
86 0x000000008000808bu64,
87 0x800000000000008bu64,
88 0x8000000000008089u64,
89 0x8000000000008003u64,
90 0x8000000000008002u64,
91 0x8000000000000080u64,
92 0x000000000000800au64,
93 0x800000008000000au64,
94 0x8000000080008081u64,
95 0x8000000000008080u64,
96 0x0000000080000001u64,
97 0x8000000080008008u64,
98];
99
100pub fn keccakf1600_statepermute(state: &mut [u64]) {
102 let mut aba = state[0];
103 let mut abe = state[1];
104 let mut abi = state[2];
105 let mut abo = state[3];
106 let mut abu = state[4];
107 let mut aga = state[5];
108 let mut age = state[6];
109 let mut agi = state[7];
110 let mut ago = state[8];
111 let mut agu = state[9];
112 let mut aka = state[10];
113 let mut ake = state[11];
114 let mut aki = state[12];
115 let mut ako = state[13];
116 let mut aku = state[14];
117 let mut ama = state[15];
118 let mut ame = state[16];
119 let mut ami = state[17];
120 let mut amo = state[18];
121 let mut amu = state[19];
122 let mut asa = state[20];
123 let mut ase = state[21];
124 let mut asi = state[22];
125 let mut aso = state[23];
126 let mut asu = state[24];
127
128 for round in (0..NROUNDS).step_by(2) {
129 let mut bca = aba ^ aga ^ aka ^ ama ^ asa;
130 let mut bce = abe ^ age ^ ake ^ ame ^ ase;
131 let mut bci = abi ^ agi ^ aki ^ ami ^ asi;
132 let mut bco = abo ^ ago ^ ako ^ amo ^ aso;
133 let mut bcu = abu ^ agu ^ aku ^ amu ^ asu;
134
135 let mut da = bcu ^ rol(bce, 1);
136 let mut de = bca ^ rol(bci, 1);
137 let mut di = bce ^ rol(bco, 1);
138 let mut d_o = bci ^ rol(bcu, 1);
139 let mut du = bco ^ rol(bca, 1);
140
141 aba ^= da;
142 bca = aba;
143 age ^= de;
144 bce = rol(age, 44);
145 aki ^= di;
146 bci = rol(aki, 43);
147 amo ^= d_o;
148 bco = rol(amo, 21);
149 asu ^= du;
150 bcu = rol(asu, 14);
151 let mut eba = bca ^ ((!bce) & bci);
152 eba ^= KECCAKF_ROUNDCONSTANTS[round];
153 let mut ebe = bce ^ ((!bci) & bco);
154 let mut ebi = bci ^ ((!bco) & bcu);
155 let mut ebo = bco ^ ((!bcu) & bca);
156 let mut ebu = bcu ^ ((!bca) & bce);
157
158 abo ^= d_o;
159 bca = rol(abo, 28);
160 agu ^= du;
161 bce = rol(agu, 20);
162 aka ^= da;
163 bci = rol(aka, 3);
164 ame ^= de;
165 bco = rol(ame, 45);
166 asi ^= di;
167 bcu = rol(asi, 61);
168 let mut ega = bca ^ ((!bce) & bci);
169 let mut ege = bce ^ ((!bci) & bco);
170 let mut egi = bci ^ ((!bco) & bcu);
171 let mut ego = bco ^ ((!bcu) & bca);
172 let mut egu = bcu ^ ((!bca) & bce);
173
174 abe ^= de;
175 bca = rol(abe, 1);
176 agi ^= di;
177 bce = rol(agi, 6);
178 ako ^= d_o;
179 bci = rol(ako, 25);
180 amu ^= du;
181 bco = rol(amu, 8);
182 asa ^= da;
183 bcu = rol(asa, 18);
184 let mut eka = bca ^ ((!bce) & bci);
185 let mut eke = bce ^ ((!bci) & bco);
186 let mut eki = bci ^ ((!bco) & bcu);
187 let mut eko = bco ^ ((!bcu) & bca);
188 let mut eku = bcu ^ ((!bca) & bce);
189
190 abu ^= du;
191 bca = rol(abu, 27);
192 aga ^= da;
193 bce = rol(aga, 36);
194 ake ^= de;
195 bci = rol(ake, 10);
196 ami ^= di;
197 bco = rol(ami, 15);
198 aso ^= d_o;
199 bcu = rol(aso, 56);
200 let mut ema = bca ^ ((!bce) & bci);
201 let mut eme = bce ^ ((!bci) & bco);
202 let mut emi = bci ^ ((!bco) & bcu);
203 let mut emo = bco ^ ((!bcu) & bca);
204 let mut emu = bcu ^ ((!bca) & bce);
205
206 abi ^= di;
207 bca = rol(abi, 62);
208 ago ^= d_o;
209 bce = rol(ago, 55);
210 aku ^= du;
211 bci = rol(aku, 39);
212 ama ^= da;
213 bco = rol(ama, 41);
214 ase ^= de;
215 bcu = rol(ase, 2);
216 let mut esa = bca ^ ((!bce) & bci);
217 let mut ese = bce ^ ((!bci) & bco);
218 let mut esi = bci ^ ((!bco) & bcu);
219 let mut eso = bco ^ ((!bcu) & bca);
220 let mut esu = bcu ^ ((!bca) & bce);
221
222 bca = eba ^ ega ^ eka ^ ema ^ esa;
223 bce = ebe ^ ege ^ eke ^ eme ^ ese;
224 bci = ebi ^ egi ^ eki ^ emi ^ esi;
225 bco = ebo ^ ego ^ eko ^ emo ^ eso;
226 bcu = ebu ^ egu ^ eku ^ emu ^ esu;
227
228 da = bcu ^ rol(bce, 1);
229 de = bca ^ rol(bci, 1);
230 di = bce ^ rol(bco, 1);
231 d_o = bci ^ rol(bcu, 1);
232 du = bco ^ rol(bca, 1);
233
234 eba ^= da;
235 bca = eba;
236 ege ^= de;
237 bce = rol(ege, 44);
238 eki ^= di;
239 bci = rol(eki, 43);
240 emo ^= d_o;
241 bco = rol(emo, 21);
242 esu ^= du;
243 bcu = rol(esu, 14);
244 aba = bca ^ ((!bce) & bci);
245 aba ^= KECCAKF_ROUNDCONSTANTS[round + 1];
246 abe = bce ^ ((!bci) & bco);
247 abi = bci ^ ((!bco) & bcu);
248 abo = bco ^ ((!bcu) & bca);
249 abu = bcu ^ ((!bca) & bce);
250
251 ebo ^= d_o;
252 bca = rol(ebo, 28);
253 egu ^= du;
254 bce = rol(egu, 20);
255 eka ^= da;
256 bci = rol(eka, 3);
257 eme ^= de;
258 bco = rol(eme, 45);
259 esi ^= di;
260 bcu = rol(esi, 61);
261 aga = bca ^ ((!bce) & bci);
262 age = bce ^ ((!bci) & bco);
263 agi = bci ^ ((!bco) & bcu);
264 ago = bco ^ ((!bcu) & bca);
265 agu = bcu ^ ((!bca) & bce);
266
267 ebe ^= de;
268 bca = rol(ebe, 1);
269 egi ^= di;
270 bce = rol(egi, 6);
271 eko ^= d_o;
272 bci = rol(eko, 25);
273 emu ^= du;
274 bco = rol(emu, 8);
275 esa ^= da;
276 bcu = rol(esa, 18);
277 aka = bca ^ ((!bce) & bci);
278 ake = bce ^ ((!bci) & bco);
279 aki = bci ^ ((!bco) & bcu);
280 ako = bco ^ ((!bcu) & bca);
281 aku = bcu ^ ((!bca) & bce);
282
283 ebu ^= du;
284 bca = rol(ebu, 27);
285 ega ^= da;
286 bce = rol(ega, 36);
287 eke ^= de;
288 bci = rol(eke, 10);
289 emi ^= di;
290 bco = rol(emi, 15);
291 eso ^= d_o;
292 bcu = rol(eso, 56);
293 ama = bca ^ ((!bce) & bci);
294 ame = bce ^ ((!bci) & bco);
295 ami = bci ^ ((!bco) & bcu);
296 amo = bco ^ ((!bcu) & bca);
297 amu = bcu ^ ((!bca) & bce);
298
299 ebi ^= di;
300 bca = rol(ebi, 62);
301 ego ^= d_o;
302 bce = rol(ego, 55);
303 eku ^= du;
304 bci = rol(eku, 39);
305 ema ^= da;
306 bco = rol(ema, 41);
307 ese ^= de;
308 bcu = rol(ese, 2);
309 asa = bca ^ ((!bce) & bci);
310 ase = bce ^ ((!bci) & bco);
311 asi = bci ^ ((!bco) & bcu);
312 aso = bco ^ ((!bcu) & bca);
313 asu = bcu ^ ((!bca) & bce);
314 }
315
316 state[0] = aba;
317 state[1] = abe;
318 state[2] = abi;
319 state[3] = abo;
320 state[4] = abu;
321 state[5] = aga;
322 state[6] = age;
323 state[7] = agi;
324 state[8] = ago;
325 state[9] = agu;
326 state[10] = aka;
327 state[11] = ake;
328 state[12] = aki;
329 state[13] = ako;
330 state[14] = aku;
331 state[15] = ama;
332 state[16] = ame;
333 state[17] = ami;
334 state[18] = amo;
335 state[19] = amu;
336 state[20] = asa;
337 state[21] = ase;
338 state[22] = asi;
339 state[23] = aso;
340 state[24] = asu;
341}
342
343fn keccak_absorb(state: &mut KeccakState, r: usize, input: &[u8], mut inlen: usize) {
345 let mut idx = 0;
346 let mut pos = state.pos;
347 while pos + inlen >= r {
348 for i in pos..r {
349 state.s[i / 8] ^= (input[idx] as u64) << 8 * (i % 8);
350 idx += 1;
351 }
352 inlen -= r - pos;
353 keccakf1600_statepermute(&mut state.s);
354 pos = 0;
355 }
356 let mut i = pos;
357 while i < pos + inlen {
358 state.s[i / 8] ^= (input[idx] as u64) << 8 * (i % 8);
359 idx += 1;
360 i += 1
361 }
362 state.pos = i;
363}
364
365fn keccak_finalize(s: &mut [u64; 25], pos: usize, r: usize, p: u8) {
367 s[pos / 8] ^= (p as u64) << 8 * (pos % 8);
368 s[r / 8 - 1] ^= 1u64 << 63;
369}
370
371fn keccak_squeeze(
376 out: &mut [u8],
377 mut outlen: usize,
378 s: &mut [u64; 25],
379 mut pos: usize,
380 r: usize,
381) -> usize {
382 while outlen != 0 {
383 if pos == r {
384 keccakf1600_statepermute(s);
385 pos = 0;
386 }
387 let mut i = pos;
388 let mut idx = 0;
389 while i < r && i < pos + outlen {
390 out[idx] = (s[i / 8] >> 8 * (i % 8)) as u8;
393 idx += 1;
395 i += 1;
396 }
397 outlen -= i - pos;
398 pos = i;
399 }
400
401 return pos;
402}
403
404fn keccak_absorb_once(s: &mut [u64; 25], r: usize, input: &[u8], mut inlen: usize, p: u8) {
406 s.fill(0);
407 let mut idx = 0;
408 while inlen >= r {
409 for i in 0..r / 8 {
410 s[i] ^= load64(&input[idx + 8 * i..]);
411 }
412 idx += r;
413 inlen -= r;
414 keccakf1600_statepermute(s);
415 }
416
417 for i in 0..inlen {
418 s[i / 8] ^= (input[idx + i] as u64) << 8 * (i % 8);
419 }
420
421 s[inlen / 8] ^= (p as u64) << 8 * (inlen % 8);
422 s[(r - 1) / 8] ^= 1u64 << 63;
423}
424
425fn keccak_squeezeblocks(out: &mut [u8], mut nblocks: usize, s: &mut [u64], r: usize) {
429 let mut idx = 0usize;
430 while nblocks > 0 {
431 keccakf1600_statepermute(s);
432 for i in 0..(r >> 3) {
433 store64(&mut out[idx + 8 * i..], s[i])
434 }
435 idx += r;
436 nblocks -= 1;
437 }
438}
439
440pub fn shake128_absorb(state: &mut KeccakState, input: &[u8], inlen: usize) {
442 keccak_absorb(state, SHAKE128_RATE, input, inlen);
443}
444
445pub fn shake128_finalize(state: &mut KeccakState) {
447 keccak_finalize(&mut state.s, state.pos as usize, SHAKE128_RATE, 0x1F);
448 state.pos = SHAKE128_RATE;
449}
450
451pub fn shake128_squeezeblocks(output: &mut [u8], nblocks: usize, s: &mut KeccakState) {
455 keccak_squeezeblocks(output, nblocks, &mut s.s, SHAKE128_RATE);
456}
457
458pub fn shake256_absorb(state: &mut KeccakState, input: &[u8], inlen: usize) {
460 keccak_absorb(state, SHAKE256_RATE, input, inlen);
461}
462
463pub fn shake256_finalize(state: &mut KeccakState) {
465 keccak_finalize(&mut state.s, state.pos, SHAKE256_RATE, 0x1F);
466 state.pos = SHAKE256_RATE;
467}
468
469pub fn shake256_squeeze(out: &mut [u8], outlen: usize, state: &mut KeccakState) {
472 state.pos = keccak_squeeze(out, outlen, &mut state.s, state.pos, SHAKE256_RATE);
473}
474
475pub fn shake256_absorb_once(state: &mut KeccakState, input: &[u8], inlen: usize) {
477 keccak_absorb_once(&mut state.s, SHAKE256_RATE, input, inlen, 0x1F);
478 state.pos = SHAKE256_RATE;
479}
480
481pub fn shake256_squeezeblocks(out: &mut [u8], nblocks: usize, state: &mut KeccakState) {
485 keccak_squeezeblocks(out, nblocks, &mut state.s, SHAKE256_RATE);
486}
487
488pub fn shake256(output: &mut [u8], mut outlen: usize, input: &[u8], inlen: usize) {
490 let mut state = KeccakState::default();
491
492 shake256_absorb_once(&mut state, input, inlen);
493 let nblocks = outlen / SHAKE256_RATE;
494 shake256_squeezeblocks(output, nblocks, &mut state);
495 outlen -= nblocks * SHAKE256_RATE;
496 let idx = nblocks * SHAKE256_RATE;
497 shake256_squeeze(&mut output[idx..], outlen, &mut state);
498}
499
500pub fn shake128_stream_init(state: &mut KeccakState, seed: &[u8], nonce: u16) {
501 let t = [nonce as u8, (nonce >> 8) as u8];
502 state.init();
503 shake128_absorb(state, seed, crate::params_dilithium5::SEEDBYTES);
504 shake128_absorb(state, &t, 2);
505 shake128_finalize(state);
506}
507
508pub fn shake256_stream_init(state: &mut KeccakState, seed: &[u8], nonce: u16) {
509 let t = [nonce as u8, (nonce >> 8) as u8];
510 state.init();
511 shake256_absorb(state, seed, crate::params_dilithium5::CRHBYTES);
512 shake256_absorb(state, &t, 2);
513 shake256_finalize(state);
514}