Skip to main content

axhash_core/hasher/
core.rs

1use crate::constants::SECRET;
2use crate::math::{DEFAULT_ACC, folded_multiply, seed_lane};
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 {
15            acc: DEFAULT_ACC,
16            sponge: 0,
17            sponge_bits: 0,
18        }
19    }
20
21    #[inline(always)]
22    pub fn new_with_seed(seed: u64) -> Self {
23        Self {
24            acc: seed_lane(seed, 0),
25            sponge: 0,
26            sponge_bits: 0,
27        }
28    }
29
30    #[inline(always)]
31    pub(crate) fn flush_sponge(&mut self) {
32        if self.sponge_bits != 0 {
33            self.flush_sponge_slow();
34        }
35    }
36
37    #[inline(always)]
38    pub(crate) fn flush_sponge_hot(&mut self) {
39        let lo = self.sponge as u64;
40        let hi = (self.sponge >> 64) as u64;
41        self.acc = folded_multiply(lo ^ self.acc, hi ^ SECRET[1]);
42        self.sponge = 0;
43        self.sponge_bits = 0;
44    }
45
46    #[inline(never)]
47    #[cold]
48    pub(crate) fn flush_sponge_slow(&mut self) {
49        self.flush_sponge_hot();
50    }
51
52    #[inline(always)]
53    pub(crate) fn push_num<T: Into<u128>>(&mut self, value: T, bits: u8) {
54        if self.sponge_bits as u16 + bits as u16 > 128 {
55            self.flush_sponge();
56        }
57
58        self.sponge |= value.into() << self.sponge_bits;
59        self.sponge_bits += bits;
60    }
61}
62
63impl Default for AxHasher {
64    #[inline(always)]
65    fn default() -> Self {
66        Self::new()
67    }
68}