keccak-rust 1.0.2

Keccak implementation in Rust
Documentation
use super::*;

pub struct Sponge {
    pub rate: Rate,
    capacity: Capacity,
    keccak_f: KeccakF,
}

impl Sponge {
    pub fn new(rate: Rate, capacity: Capacity, width: StateBitsWidth) -> Sponge {
        Sponge {
            rate: rate,
            capacity: capacity,
            keccak_f: KeccakF::new(width),
        }
    }

    pub fn absorb(&self, mut state: &mut State, message: &BytesArr) {
        assert!(
            message.len() % self.rate == 0,
            "Message is not divisible entirely by bytes rate"
        );

        let chunks_total = message.len() / self.rate;

        let words: Vec<u64> = Sponge::bits_to_u64_words_le(message);

        for chunk_i in 0..chunks_total {
            let chunk_offset: usize = chunk_i * (self.rate / 8);
            let mut x = 0;
            let mut y = 0;
            for i in 0..(self.rate / 8) {
                let word = words[chunk_offset + i];
                state[x][y] ^= word;
                if x < 5 - 1 {
                    x += 1;
                } else {
                    y += 1;
                    x = 0;
                }
            }
            self.keccak_f.permutations(&mut state);
        }
    }

    pub fn squeeze(&self, state: &mut State) -> BytesVec {
        let mut output: Vec<u8> = vec![];

        let output_len: usize = self.capacity / 2;
        let elems_total: usize = output_len / 8;
        let mut counter: usize = 0;

        'outer: for i in 0..5 {
            for j in 0..5 {
                output.append(&mut state[j][i].to_le_bytes().to_vec());
                if counter == elems_total {
                    break 'outer;
                }
                counter += 1;
            }
        }

        output.resize(output_len, 0);
        output
    }

    fn bits_to_u64_words_le(message: &BytesArr) -> Vec<u64> {
        let words_total = message.len() / 8;
        let mut words: Vec<u64> = vec![0; words_total];

        for i in 0..words_total {
            let mut word_bits: [u8; 8] = Default::default();
            word_bits.copy_from_slice(&message[i * 8..i * 8 + 8]);
            words[i] = u64::from_le_bytes(word_bits);
        }
        words
    }
}