spongefish/
keccak.rs

1//! **Warning**: this function is not SHA3.
2//! Despite internally we use the same permutation function,
3//! we build a duplex sponge in overwrite mode
4//! on the top of it using the `DuplexSponge` trait.
5use std::fmt::Debug;
6
7use zerocopy::IntoBytes;
8use zeroize::{Zeroize, ZeroizeOnDrop};
9
10use crate::duplex_sponge::{DuplexSponge, Permutation};
11
12/// A duplex sponge based on the permutation [`keccak::f1600`]
13/// using [`DuplexSponge`].
14///
15/// **Warning**: This function is not SHA3.
16/// Despite internally we use the same permutation function,
17/// we build a duplex sponge in overwrite mode
18/// on the top of it using the `DuplexSponge` trait.
19pub type Keccak = DuplexSponge<KeccakF1600>;
20
21/// Keccak permutation internal state: 25 64-bit words,
22/// or equivalently 200 bytes in little-endian order.
23#[derive(Clone, PartialEq, Eq, Default, Zeroize, ZeroizeOnDrop)]
24pub struct KeccakF1600([u64; 25]);
25
26impl Permutation for KeccakF1600 {
27    type U = u8;
28    const N: usize = 136 + 64;
29    const R: usize = 136;
30
31    fn new(iv: [u8; 32]) -> Self {
32        let mut state = Self::default();
33        state.as_mut()[Self::R..Self::R + 32].copy_from_slice(&iv);
34        state
35    }
36
37    fn permute(&mut self) {
38        keccak::f1600(&mut self.0);
39    }
40}
41
42impl AsRef<[u8]> for KeccakF1600 {
43    fn as_ref(&self) -> &[u8] {
44        self.0.as_bytes()
45    }
46}
47
48impl AsMut<[u8]> for KeccakF1600 {
49    fn as_mut(&mut self) -> &mut [u8] {
50        self.0.as_mut_bytes()
51    }
52}
53
54/// Censored version of Debug
55impl Debug for KeccakF1600 {
56    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57        f.debug_tuple("AlignedKeccakF1600")
58            .field(&"<redacted>")
59            .finish()
60    }
61}