1use alloc::vec::Vec;
2use core::{
3 num::NonZero,
4 ops::{Deref, DerefMut},
5};
6
7use super::{InnerNodeInfo, MerkleError, NodeIndex, Poseidon2, Word};
8use crate::utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable};
9
10#[derive(Clone, Debug, Default, PartialEq, Eq)]
18pub struct MerklePath {
19 nodes: Vec<Word>,
20}
21
22impl MerklePath {
23 pub fn new(nodes: Vec<Word>) -> Self {
34 assert!(nodes.len() <= u8::MAX.into(), "MerklePath may have at most 255 items");
35 Self { nodes }
36 }
37
38 pub fn at_depth(&self, depth: NonZero<u8>) -> Option<Word> {
47 let index = u8::checked_sub(self.depth(), depth.get())?;
48 self.nodes.get(index as usize).copied()
49 }
50
51 pub fn depth(&self) -> u8 {
53 u8::try_from(self.nodes.len()).expect("MerklePath may have at most 255 items")
54 }
55
56 pub fn nodes(&self) -> &[Word] {
58 &self.nodes
59 }
60
61 pub fn compute_root(&self, index: u64, node: Word) -> Result<Word, MerkleError> {
63 let mut index = NodeIndex::new(self.depth(), index)?;
64 let root = self.nodes.iter().copied().fold(node, |node, sibling| {
65 let input = index.build_node(node, sibling);
67 index.move_up();
68 Poseidon2::merge(&input)
69 });
70 Ok(root)
71 }
72
73 pub fn verify(&self, index: u64, node: Word, root: &Word) -> Result<(), MerkleError> {
80 let computed_root = self.compute_root(index, node)?;
81 if &computed_root != root {
82 return Err(MerkleError::ConflictingRoots {
83 expected_root: *root,
84 actual_root: computed_root,
85 });
86 }
87
88 Ok(())
89 }
90
91 pub fn authenticated_nodes(
108 &self,
109 index: u64,
110 node_to_prove: Word,
111 ) -> Result<InnerNodeIterator<'_>, MerkleError> {
112 Ok(InnerNodeIterator {
113 nodes: &self.nodes,
114 index: NodeIndex::new(self.depth(), index)?,
115 value: node_to_prove,
116 })
117 }
118}
119
120impl From<MerklePath> for Vec<Word> {
124 fn from(path: MerklePath) -> Self {
125 path.nodes
126 }
127}
128
129impl From<Vec<Word>> for MerklePath {
130 fn from(path: Vec<Word>) -> Self {
131 Self::new(path)
132 }
133}
134
135impl From<&[Word]> for MerklePath {
136 fn from(path: &[Word]) -> Self {
137 path.iter().copied().collect()
138 }
139}
140
141impl Deref for MerklePath {
142 type Target = [Word];
143
144 fn deref(&self) -> &Self::Target {
145 &self.nodes
146 }
147}
148
149impl DerefMut for MerklePath {
150 fn deref_mut(&mut self) -> &mut Self::Target {
151 &mut self.nodes
152 }
153}
154
155impl FromIterator<Word> for MerklePath {
159 fn from_iter<T: IntoIterator<Item = Word>>(iter: T) -> Self {
160 Self::new(iter.into_iter().take(usize::from(u8::MAX) + 1).collect())
161 }
162}
163
164impl IntoIterator for MerklePath {
165 type Item = Word;
166 type IntoIter = alloc::vec::IntoIter<Word>;
167
168 fn into_iter(self) -> Self::IntoIter {
169 self.nodes.into_iter()
170 }
171}
172
173pub struct InnerNodeIterator<'a> {
175 nodes: &'a [Word],
176 index: NodeIndex,
177 value: Word,
178}
179
180impl Iterator for InnerNodeIterator<'_> {
181 type Item = InnerNodeInfo;
182
183 fn next(&mut self) -> Option<Self::Item> {
184 if !self.index.is_root() {
185 let sibling_pos = self.nodes.len() - self.index.depth() as usize;
186 let (left, right) = if self.index.is_position_odd() {
187 (self.nodes[sibling_pos], self.value)
188 } else {
189 (self.value, self.nodes[sibling_pos])
190 };
191
192 self.value = Poseidon2::merge(&[left, right]);
193 self.index.move_up();
194
195 Some(InnerNodeInfo { value: self.value, left, right })
196 } else {
197 None
198 }
199 }
200}
201
202#[derive(Clone, Debug, Default, PartialEq, Eq)]
207pub struct MerkleProof {
208 pub value: Word,
210 pub path: MerklePath,
212}
213
214impl MerkleProof {
215 pub fn new(value: Word, path: MerklePath) -> Self {
217 Self { value, path }
218 }
219}
220
221impl From<(MerklePath, Word)> for MerkleProof {
222 fn from((path, value): (MerklePath, Word)) -> Self {
223 MerkleProof::new(value, path)
224 }
225}
226
227#[derive(Clone, Debug, Default, PartialEq, Eq)]
232pub struct RootPath {
233 pub root: Word,
235 pub path: MerklePath,
237}
238
239impl Serializable for MerklePath {
243 fn write_into<W: ByteWriter>(&self, target: &mut W) {
244 assert!(self.nodes.len() <= u8::MAX.into(), "MerklePath may have at most 255 items");
247 target.write_u8(self.nodes.len() as u8);
248 target.write_many(&self.nodes);
249 }
250}
251
252impl Deserializable for MerklePath {
253 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
254 let count = source.read_u8()?.into();
255 let nodes: Vec<Word> = source.read_many_iter(count)?.collect::<Result<_, _>>()?;
256 Ok(Self { nodes })
257 }
258}
259
260impl Serializable for MerkleProof {
261 fn write_into<W: ByteWriter>(&self, target: &mut W) {
262 self.value.write_into(target);
263 self.path.write_into(target);
264 }
265}
266
267impl Deserializable for MerkleProof {
268 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
269 let value = Word::read_from(source)?;
270 let path = MerklePath::read_from(source)?;
271 Ok(Self { value, path })
272 }
273}
274
275impl Serializable for RootPath {
276 fn write_into<W: ByteWriter>(&self, target: &mut W) {
277 self.root.write_into(target);
278 self.path.write_into(target);
279 }
280}
281
282impl Deserializable for RootPath {
283 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
284 let root = Word::read_from(source)?;
285 let path = MerklePath::read_from(source)?;
286 Ok(Self { root, path })
287 }
288}
289
290#[cfg(test)]
294mod tests {
295 use crate::{
296 merkle::{MerklePath, int_to_node},
297 utils::Serializable,
298 };
299
300 #[test]
301 #[should_panic(expected = "MerklePath may have at most 255 items")]
302 fn new_rejects_more_than_255_nodes() {
303 let _ = MerklePath::new(vec![int_to_node(0); u8::MAX as usize + 1]);
304 }
305
306 #[test]
307 #[should_panic(expected = "MerklePath may have at most 255 items")]
308 fn from_iter_caps_allocation_and_rejects_excess_nodes() {
309 let nodes = (0..usize::MAX).map(|_| int_to_node(0));
311 let _ = MerklePath::from_iter(nodes);
312 }
313
314 #[test]
315 #[should_panic(expected = "MerklePath may have at most 255 items")]
316 fn depth_rejects_an_internally_invalid_length() {
317 let path = MerklePath {
320 nodes: vec![int_to_node(0); u8::MAX as usize + 1],
321 };
322 let _ = path.depth();
323 }
324
325 #[test]
326 #[should_panic(expected = "MerklePath may have at most 255 items")]
327 fn serialization_rejects_an_internally_invalid_length() {
328 let path = MerklePath {
329 nodes: vec![int_to_node(0); u8::MAX as usize + 1],
330 };
331 let _ = path.to_bytes();
332 }
333
334 #[test]
335 fn test_inner_nodes() {
336 let nodes = vec![int_to_node(1), int_to_node(2), int_to_node(3), int_to_node(4)];
337 let merkle_path = MerklePath::new(nodes);
338
339 let index = 6;
340 let node = int_to_node(5);
341 let root = merkle_path.compute_root(index, node).unwrap();
342
343 let inner_root =
344 merkle_path.authenticated_nodes(index, node).unwrap().last().unwrap().value;
345
346 assert_eq!(root, inner_root);
347 }
348}