1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
//!
//! SMT hash functions.
//!
//! The hash is defined on the *logical* (uncompressed) 256-level binary tree:
//!
//! - **Empty**: `EMPTY_HASH = [0u8; 32]`
//! - **Leaf**: `Keccak256(0x01 || key_hash || value)`
//! - **Internal**: if both children are empty → `EMPTY_HASH`,
//! otherwise `Keccak256(left_hash || right_hash)`
//!
//! The empty-empty special case ensures that `wrap_hash(EMPTY, path)`
//! stays `EMPTY` regardless of path length, which is essential for
//! proof verification (non-membership proofs start from `EMPTY_HASH`
//! at depth 256 and must reconstruct empty subtrees correctly).
//!
//! Compression is transparent to hashing. A compressed node that skips
//! N levels is equivalent to N nested single-child internal nodes.
//! [`wrap_hash`] reproduces that chain efficiently.
//!
use ;
use EMPTY_HASH;
use BitPath;
/// Hashes a leaf: `Keccak256(0x01 || key_hash || value)`.
/// Hashes an internal node.
///
/// If both children are empty, returns `EMPTY_HASH` (preserving the
/// empty-subtree invariant). Otherwise `Keccak256(left_hash || right_hash)`.
/// "Lifts" a hash through a compressed path by nesting it inside
/// single-child internal nodes.
///
/// For each bit in `path` (from the last bit back to the first):
/// - bit = 0 → `H(hash || EMPTY_HASH)` (hash is on the left)
/// - bit = 1 → `H(EMPTY_HASH || hash)` (hash is on the right)