snarkvm_console_collections/merkle_tree/path/
mod.rs1use super::*;
17
18#[derive(Clone, Debug, PartialEq, Eq, Hash)]
19pub struct MerklePath<E: Environment, const DEPTH: u8> {
20 leaf_index: U64<E>,
22 siblings: Vec<Field<E>>,
24}
25
26impl<E: Environment, const DEPTH: u8> TryFrom<(U64<E>, Vec<Field<E>>)> for MerklePath<E, DEPTH> {
27 type Error = Error;
28
29 fn try_from((leaf_index, siblings): (U64<E>, Vec<Field<E>>)) -> Result<Self> {
31 ensure!(DEPTH > 0, "Merkle tree depth must be greater than 0");
33 ensure!(DEPTH <= 64u8, "Merkle tree depth must be less than or equal to 64");
35 ensure!((*leaf_index as u128) < (1u128 << DEPTH), "Found an out of bounds Merkle leaf index");
37 ensure!(siblings.len() == DEPTH as usize, "Found an incorrect Merkle path length");
39 Ok(Self { leaf_index, siblings })
41 }
42}
43
44impl<E: Environment, const DEPTH: u8> MerklePath<E, DEPTH> {
45 pub fn leaf_index(&self) -> U64<E> {
47 self.leaf_index
48 }
49
50 pub fn siblings(&self) -> &[Field<E>] {
52 &self.siblings
53 }
54
55 pub fn verify<LH: LeafHash<Hash = PH::Hash>, PH: PathHash<Hash = Field<E>>>(
57 &self,
58 leaf_hasher: &LH,
59 path_hasher: &PH,
60 root: &PH::Hash,
61 leaf: &LH::Leaf,
62 ) -> bool {
63 if (*self.leaf_index as u128) >= (1u128 << DEPTH) {
65 eprintln!("Found an out of bounds Merkle leaf index");
66 return false;
67 }
68 else if self.siblings.len() != DEPTH as usize {
70 eprintln!("Found an incorrect Merkle path length");
71 return false;
72 }
73
74 let mut current_hash = match leaf_hasher.hash_leaf(leaf) {
76 Ok(candidate_leaf_hash) => candidate_leaf_hash,
77 Err(error) => {
78 eprintln!("Failed to hash the Merkle leaf during verification: {error}");
79 return false;
80 }
81 };
82
83 let indicators = (0..DEPTH).map(|i| ((*self.leaf_index >> i) & 1) == 0);
87
88 for (indicator, sibling_hash) in indicators.zip_eq(&self.siblings) {
90 let (left, right) = match indicator {
92 true => (current_hash, *sibling_hash),
93 false => (*sibling_hash, current_hash),
94 };
95 match path_hasher.hash_children(&left, &right) {
97 Ok(hash) => current_hash = hash,
98 Err(error) => {
99 eprintln!("Failed to hash the Merkle path during verification: {error}");
100 return false;
101 }
102 }
103 }
104
105 current_hash == *root
107 }
108}
109
110impl<E: Environment, const DEPTH: u8> FromBytes for MerklePath<E, DEPTH> {
111 #[inline]
113 fn read_le<R: Read>(mut reader: R) -> IoResult<Self> {
114 let leaf_index = u64::read_le(&mut reader)?;
116 let siblings =
118 (0..DEPTH).map(|_| Ok(Field::new(FromBytes::read_le(&mut reader)?))).collect::<IoResult<Vec<_>>>()?;
119 Self::try_from((U64::new(leaf_index), siblings)).map_err(error)
121 }
122}
123
124impl<E: Environment, const DEPTH: u8> ToBytes for MerklePath<E, DEPTH> {
125 #[inline]
127 fn write_le<W: Write>(&self, mut writer: W) -> IoResult<()> {
128 self.leaf_index.write_le(&mut writer)?;
130 self.siblings.iter().try_for_each(|sibling| sibling.write_le(&mut writer))
132 }
133}
134
135impl<E: Environment, const DEPTH: u8> Serialize for MerklePath<E, DEPTH> {
136 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
137 ToBytesSerializer::serialize(self, serializer)
138 }
139}
140
141impl<'de, E: Environment, const DEPTH: u8> Deserialize<'de> for MerklePath<E, DEPTH> {
142 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
143 let size = 8 + DEPTH as usize * (Field::<E>::size_in_bits() + 7) / 8;
145 FromBytesDeserializer::<Self>::deserialize(deserializer, "Merkle path", size)
146 }
147}