1use alloc::vec::Vec;
2use core::{
3 num::NonZero,
4 ops::{Deref, DerefMut},
5};
6
7use super::{Eidos, InnerNodeInfo, MerkleError, NodeIndex, Word};
8use crate::utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable};
9
10#[derive(Clone, Debug, Default, PartialEq, Eq)]
18#[cfg_attr(
19 all(feature = "arbitrary", test),
20 miden_test_serialization_macros::serialization_test
21)]
22pub struct MerklePath {
23 nodes: Vec<Word>,
24}
25
26impl MerklePath {
27 pub fn new(nodes: Vec<Word>) -> Self {
38 assert!(nodes.len() <= u8::MAX.into(), "MerklePath may have at most 255 items");
39 Self { nodes }
40 }
41
42 pub fn at_depth(&self, depth: NonZero<u8>) -> Option<Word> {
51 let index = u8::checked_sub(self.depth(), depth.get())?;
52 self.nodes.get(index as usize).copied()
53 }
54
55 pub fn depth(&self) -> u8 {
57 u8::try_from(self.nodes.len()).expect("MerklePath may have at most 255 items")
58 }
59
60 pub fn nodes(&self) -> &[Word] {
62 &self.nodes
63 }
64
65 pub fn compute_root(&self, index: u64, node: Word) -> Result<Word, MerkleError> {
67 let mut index = NodeIndex::new(self.depth(), index)?;
68 let root = self.nodes.iter().copied().fold(node, |node, sibling| {
69 let input = index.build_node(node, sibling);
71 index.move_up();
72 Eidos::merge(&input)
73 });
74 Ok(root)
75 }
76
77 pub fn verify(&self, index: u64, node: Word, root: &Word) -> Result<(), MerkleError> {
84 let computed_root = self.compute_root(index, node)?;
85 if &computed_root != root {
86 return Err(MerkleError::ConflictingRoots {
87 expected_root: *root,
88 actual_root: computed_root,
89 });
90 }
91
92 Ok(())
93 }
94
95 pub fn authenticated_nodes(
112 &self,
113 index: u64,
114 node_to_prove: Word,
115 ) -> Result<InnerNodeIterator<'_>, MerkleError> {
116 Ok(InnerNodeIterator {
117 nodes: &self.nodes,
118 index: NodeIndex::new(self.depth(), index)?,
119 value: node_to_prove,
120 })
121 }
122}
123
124impl From<MerklePath> for Vec<Word> {
128 fn from(path: MerklePath) -> Self {
129 path.nodes
130 }
131}
132
133impl From<Vec<Word>> for MerklePath {
134 fn from(path: Vec<Word>) -> Self {
135 Self::new(path)
136 }
137}
138
139impl From<&[Word]> for MerklePath {
140 fn from(path: &[Word]) -> Self {
141 path.iter().copied().collect()
142 }
143}
144
145impl Deref for MerklePath {
146 type Target = [Word];
147
148 fn deref(&self) -> &Self::Target {
149 &self.nodes
150 }
151}
152
153impl DerefMut for MerklePath {
154 fn deref_mut(&mut self) -> &mut Self::Target {
155 &mut self.nodes
156 }
157}
158
159impl FromIterator<Word> for MerklePath {
163 fn from_iter<T: IntoIterator<Item = Word>>(iter: T) -> Self {
164 Self::new(iter.into_iter().take(usize::from(u8::MAX) + 1).collect())
165 }
166}
167
168impl IntoIterator for MerklePath {
169 type Item = Word;
170 type IntoIter = alloc::vec::IntoIter<Word>;
171
172 fn into_iter(self) -> Self::IntoIter {
173 self.nodes.into_iter()
174 }
175}
176
177pub struct InnerNodeIterator<'a> {
179 nodes: &'a [Word],
180 index: NodeIndex,
181 value: Word,
182}
183
184impl Iterator for InnerNodeIterator<'_> {
185 type Item = InnerNodeInfo;
186
187 fn next(&mut self) -> Option<Self::Item> {
188 if !self.index.is_root() {
189 let sibling_pos = self.nodes.len() - self.index.depth() as usize;
190 let (left, right) = if self.index.is_position_odd() {
191 (self.nodes[sibling_pos], self.value)
192 } else {
193 (self.value, self.nodes[sibling_pos])
194 };
195
196 self.value = Eidos::merge(&[left, right]);
197 self.index.move_up();
198
199 Some(InnerNodeInfo { value: self.value, left, right })
200 } else {
201 None
202 }
203 }
204}
205
206#[derive(Clone, Debug, Default, PartialEq, Eq)]
211#[cfg_attr(
212 all(feature = "arbitrary", test),
213 miden_test_serialization_macros::serialization_test
214)]
215pub struct MerkleProof {
216 pub value: Word,
218 pub path: MerklePath,
220}
221
222impl MerkleProof {
223 pub fn new(value: Word, path: MerklePath) -> Self {
225 Self { value, path }
226 }
227}
228
229impl From<(MerklePath, Word)> for MerkleProof {
230 fn from((path, value): (MerklePath, Word)) -> Self {
231 MerkleProof::new(value, path)
232 }
233}
234
235#[derive(Clone, Debug, Default, PartialEq, Eq)]
240#[cfg_attr(
241 all(feature = "arbitrary", test),
242 miden_test_serialization_macros::serialization_test
243)]
244pub struct RootPath {
245 pub root: Word,
247 pub path: MerklePath,
249}
250
251impl Serializable for MerklePath {
255 fn write_into<W: ByteWriter>(&self, target: &mut W) {
256 assert!(self.nodes.len() <= u8::MAX.into(), "MerklePath may have at most 255 items");
259 target.write_u8(self.nodes.len() as u8);
260 target.write_many(&self.nodes);
261 }
262}
263
264impl Deserializable for MerklePath {
265 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
266 let count = source.read_u8()?.into();
267 let nodes: Vec<Word> = source.read_many_iter(count)?.collect::<Result<_, _>>()?;
268 Ok(Self { nodes })
269 }
270}
271
272impl Serializable for MerkleProof {
273 fn write_into<W: ByteWriter>(&self, target: &mut W) {
274 self.value.write_into(target);
275 self.path.write_into(target);
276 }
277}
278
279impl Deserializable for MerkleProof {
280 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
281 let value = Word::read_from(source)?;
282 let path = MerklePath::read_from(source)?;
283 Ok(Self { value, path })
284 }
285}
286
287impl Serializable for RootPath {
288 fn write_into<W: ByteWriter>(&self, target: &mut W) {
289 self.root.write_into(target);
290 self.path.write_into(target);
291 }
292}
293
294impl Deserializable for RootPath {
295 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
296 let root = Word::read_from(source)?;
297 let path = MerklePath::read_from(source)?;
298 Ok(Self { root, path })
299 }
300}
301
302#[cfg(test)]
306mod tests {
307 use crate::{
308 merkle::{MerklePath, int_to_node},
309 utils::Serializable,
310 };
311
312 #[test]
313 #[should_panic(expected = "MerklePath may have at most 255 items")]
314 fn new_rejects_more_than_255_nodes() {
315 let _ = MerklePath::new(vec![int_to_node(0); u8::MAX as usize + 1]);
316 }
317
318 #[test]
322 fn serialization_roundtrip_boundary_lengths() {
323 use miden_serde_utils::Deserializable;
324
325 use crate::merkle::MerklePath;
326
327 for len in [65usize, 254, 255] {
328 let path = MerklePath::new((0..len as u64).map(int_to_node).collect());
329 let bytes = path.to_bytes();
330 let round_trip = MerklePath::read_from_bytes(&bytes).unwrap();
331 assert_eq!(path, round_trip, "round trip failed for length {len}");
332 }
333 }
334
335 #[test]
336 #[should_panic(expected = "MerklePath may have at most 255 items")]
337 fn from_iter_caps_allocation_and_rejects_excess_nodes() {
338 let nodes = (0..usize::MAX).map(|_| int_to_node(0));
340 let _ = MerklePath::from_iter(nodes);
341 }
342
343 #[test]
344 #[should_panic(expected = "MerklePath may have at most 255 items")]
345 fn depth_rejects_an_internally_invalid_length() {
346 let path = MerklePath {
349 nodes: vec![int_to_node(0); u8::MAX as usize + 1],
350 };
351 let _ = path.depth();
352 }
353
354 #[test]
355 #[should_panic(expected = "MerklePath may have at most 255 items")]
356 fn serialization_rejects_an_internally_invalid_length() {
357 let path = MerklePath {
358 nodes: vec![int_to_node(0); u8::MAX as usize + 1],
359 };
360 let _ = path.to_bytes();
361 }
362
363 #[test]
364 fn test_inner_nodes() {
365 let nodes = vec![int_to_node(1), int_to_node(2), int_to_node(3), int_to_node(4)];
366 let merkle_path = MerklePath::new(nodes);
367
368 let index = 6;
369 let node = int_to_node(5);
370 let root = merkle_path.compute_root(index, node).unwrap();
371
372 let inner_root =
373 merkle_path.authenticated_nodes(index, node).unwrap().last().unwrap().value;
374
375 assert_eq!(root, inner_root);
376 }
377}