ab_merkle_tree/
lib.rs

1//! Merkle Tree implementations.
2//!
3//! This crate contains several Merkle Tree implementations that are a subset of each other.
4//!
5//! Currently [`BalancedHashedMerkleTree`] and [`UnbalancedHashedMerkleTree`] are available, with
6//! [`BalancedHashedMerkleTree`] being an optimized special case of [`UnbalancedHashedMerkleTree`]
7//! and both return the same results for identical inputs.
8//!
9//! [`BalancedHashedMerkleTree`]: balanced_hashed::BalancedHashedMerkleTree
10//! [`UnbalancedHashedMerkleTree`]: unbalanced_hashed::UnbalancedHashedMerkleTree
11
12#![expect(incomplete_features, reason = "generic_const_exprs")]
13#![feature(
14    array_chunks,
15    generic_arg_infer,
16    generic_const_exprs,
17    maybe_uninit_slice,
18    maybe_uninit_uninit_array_transpose,
19    ptr_as_ref_unchecked,
20    trusted_len
21)]
22#![no_std]
23
24pub mod balanced_hashed;
25pub mod unbalanced_hashed;
26
27#[cfg(feature = "alloc")]
28extern crate alloc;
29
30use blake3::{KEY_LEN, OUT_LEN};
31
32/// Used as a key in keyed blake3 hash for inner nodes of Merkle Trees.
33///
34/// This value is a blake3 hash of as string `merkle-tree-inner-node`.
35// TODO: Replace with hashing once https://github.com/BLAKE3-team/BLAKE3/issues/440 is resolved
36pub const INNER_NODE_DOMAIN_SEPARATOR: [u8; KEY_LEN] = [
37    0x53, 0x11, 0x7d, 0x4d, 0xa8, 0x1a, 0x34, 0x35, 0x0b, 0x1a, 0x30, 0xd4, 0x28, 0x6d, 0x7e, 0x5a,
38    0x1e, 0xb0, 0xa2, 0x0f, 0x5e, 0x5e, 0x26, 0x94, 0x47, 0x4b, 0x4f, 0xbd, 0x86, 0xc3, 0xc0, 0x7e,
39];
40
41/// Helper function to hash two nodes together using [`blake3::keyed_hash()`] and
42/// [`INNER_NODE_DOMAIN_SEPARATOR`]
43#[inline(always)]
44pub fn hash_pair(left: &[u8; OUT_LEN], right: &[u8; OUT_LEN]) -> [u8; OUT_LEN] {
45    let mut pair = [0u8; OUT_LEN * 2];
46    pair[..OUT_LEN].copy_from_slice(left);
47    pair[OUT_LEN..].copy_from_slice(right);
48
49    *blake3::keyed_hash(&INNER_NODE_DOMAIN_SEPARATOR, &pair).as_bytes()
50}