Skip to main content

radix_common/crypto/
hash_accumulator.rs

1use blake2::Digest as Blake2Digest;
2
3use crate::prelude::*;
4
5/// Represents a 32-byte hash accumulator.
6#[derive(Default)]
7pub struct HashAccumulator {
8    inner: Blake2b256,
9    input_size: usize,
10}
11
12impl HashAccumulator {
13    pub fn new() -> Self {
14        Default::default()
15    }
16
17    /// Effectively concatenates `data` to the payload-to-be-hashed
18    pub fn concat(self, data: impl AsRef<[u8]>) -> Self {
19        let bytes = data.as_ref();
20
21        Self {
22            inner: self.inner.chain_update(bytes),
23            input_size: self
24                .input_size
25                .checked_add(bytes.len())
26                .expect("Input to digest somehow larger than usize"),
27        }
28    }
29
30    pub fn concat_mut(&mut self, data: impl AsRef<[u8]>) {
31        let bytes = data.as_ref();
32        self.inner.update(bytes);
33        self.input_size = self
34            .input_size
35            .checked_add(bytes.len())
36            .expect("Input to digest somehow larger than usize");
37    }
38
39    pub fn input_length(&self) -> usize {
40        self.input_size
41    }
42
43    pub fn finalize(self) -> Hash {
44        Hash(self.inner.finalize().into())
45    }
46}