1#![forbid(unsafe_code)]
2#![deny(missing_docs, unstable_features)]
3#![cfg_attr(not(any(test, feature = "std")), no_std)]
4
5extern crate alloc;
7
8mod forest;
9mod hash;
10mod path;
11mod proof;
12
13pub(crate) use self::path::{Direction, Path};
14
15pub use self::forest::Forest;
16pub use self::hash::Hash;
17pub use self::proof::Proof;
18
19use alloc::vec;
20use core::iter::{repeat, Iterator};
21
22use blake2b_simd::{many::update_many, Params};
23
24use self::hash::HASH_SIZE;
25
26pub(crate) fn hash_leaf<T: AsRef<[u8]>>(value: T) -> Hash {
28 let mut params = Params::default();
29 params.hash_length(HASH_SIZE);
30
31 let mut state = params.to_state();
32
33 state.update(&[0]);
36 state.update(value.as_ref());
37
38 state.finalize().into()
39}
40
41pub(crate) fn hash_many_leaves<T: AsRef<[u8]>>(values: &[T]) -> impl Iterator<Item = Hash> {
43 let mut params = Params::default();
44 params.hash_length(HASH_SIZE);
45
46 let mut states = vec![params.to_state(); values.len()];
47
48 update_many(states.iter_mut().zip(repeat(&[0]).take(values.len())));
51 update_many(states.iter_mut().zip(values.iter()));
52
53 states.into_iter().map(|state| state.finalize().into())
54}
55
56pub(crate) fn hash_intermediate<T: AsRef<[u8]>>(a: T, b: T) -> Hash {
57 let mut params = Params::default();
58 params.hash_length(HASH_SIZE);
59
60 let mut state = params.to_state();
61
62 state.update(&[1]);
65 state.update(a.as_ref());
66 state.update(b.as_ref());
67
68 state.finalize().into()
69}