Skip to main content

axhash_core/hasher/
core.rs

1use crate::constants::SECRET;
2use crate::math::folded_multiply;
3
4#[derive(Clone, Debug)]
5pub struct AxHasher {
6    pub(crate) acc: u64,
7    pub(crate) sponge: u128,
8    pub(crate) sponge_bits: u8,
9}
10
11impl AxHasher {
12    #[inline(always)]
13    pub fn new() -> Self {
14        Self::new_with_seed(0)
15    }
16
17    #[inline(always)]
18    pub fn new_with_seed(seed: u64) -> Self {
19        Self {
20            acc: seed ^ SECRET[0],
21            sponge: 0,
22            sponge_bits: 0,
23        }
24    }
25
26    #[inline(always)]
27    pub(crate) fn flush_sponge(&mut self) {
28        if self.sponge_bits == 0 {
29            return;
30        }
31
32        let lo = self.sponge as u64;
33        let hi = (self.sponge >> 64) as u64;
34        self.acc = folded_multiply(lo ^ self.acc, hi ^ SECRET[1]);
35        self.sponge = 0;
36        self.sponge_bits = 0;
37    }
38
39    #[inline(always)]
40    pub(crate) fn push_num<T: Into<u128>>(&mut self, value: T, bits: u8) {
41        if self.sponge_bits as u16 + bits as u16 > 128 {
42            self.flush_sponge();
43        }
44
45        self.sponge |= value.into() << self.sponge_bits;
46        self.sponge_bits += bits;
47    }
48}
49
50impl Default for AxHasher {
51    #[inline(always)]
52    fn default() -> Self {
53        Self::new()
54    }
55}