bankai_types/utils/
mmr.rs

1//! MMR (Merkle Mountain Range) utility functions
2//!
3//! This module provides utilities for working with Merkle Mountain Ranges,
4//! including hashing functions for both Keccak and Poseidon.
5
6extern crate alloc;
7use alloy_primitives::FixedBytes;
8use alloy_primitives::keccak256;
9use starknet_crypto::{Felt, poseidon_hash};
10
11use crate::proofs::HashingFunctionDto;
12
13/// Converts a header hash into an MMR leaf hash
14///
15/// Takes a header hash and applies the specified hashing function to create
16/// an MMR leaf. This is the first step in creating MMR commitments.
17///
18/// # Arguments
19///
20/// * `hash` - The header hash to convert
21/// * `hashing_function` - Which hash function to use (Keccak or Poseidon)
22///
23/// # Returns
24///
25/// The hashed leaf value suitable for MMR insertion
26pub fn hash_to_leaf(hash: FixedBytes<32>, hashing_function: &HashingFunctionDto) -> FixedBytes<32> {
27    match hashing_function {
28        HashingFunctionDto::Keccak => keccak256(hash.as_slice()),
29        HashingFunctionDto::Poseidon => {
30            let root_bytes = hash.as_slice();
31            let high = Felt::from_bytes_be_slice(&root_bytes[0..16]);
32            let low = Felt::from_bytes_be_slice(&root_bytes[16..32]);
33
34            let hashed_root = poseidon_hash(low, high);
35            FixedBytes::from_slice(hashed_root.to_bytes_be().as_slice())
36        }
37    }
38}
39
40#[cfg(test)]
41mod tests {
42    use alloy_primitives::hex::FromHex;
43
44    use super::*;
45
46    #[test]
47    fn test_hash_to_leaf_keccak() {
48        let input =
49            "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef".to_string();
50        let expected =
51            "0xcae36a6a44328f3fb063df12b0cf3fa225a3c6dbdd6acef0f6e619d33890cf24".to_string();
52        let result = hash_to_leaf(
53            FixedBytes::from_hex(input).unwrap(),
54            &HashingFunctionDto::Keccak,
55        );
56        assert_eq!(result, FixedBytes::from_hex(expected).unwrap());
57    }
58
59    #[test]
60    fn test_hash_to_leaf_poseidon() {
61        let input =
62            "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef".to_string();
63        let expected =
64            "0x05206aa252b669b3d3348eede13d91a5002293e2da9f3ca4ee905dd2578793b9".to_string();
65        let result = hash_to_leaf(
66            FixedBytes::from_hex(input).unwrap(),
67            &HashingFunctionDto::Poseidon,
68        );
69        assert_eq!(result, FixedBytes::from_hex(expected).unwrap());
70    }
71}