1use crate::{
6 hasher::NodeHasher,
7 proof::{
8 path_proof::{hash_path, shared_bits},
9 KeyOutOfScope, PathProof, PathProofTerminal,
10 },
11 trie::{InternalData, KeyPath, LeafData, Node, NodeKind, ValueHash, TERMINATOR},
12};
13
14#[cfg(not(feature = "std"))]
15use alloc::{vec, vec::Vec};
16
17use bitvec::prelude::*;
18use core::{cmp::Ordering, ops::Range};
19
20#[derive(Debug, Clone, Eq, PartialEq)]
22#[cfg_attr(
23 feature = "borsh",
24 derive(borsh::BorshDeserialize, borsh::BorshSerialize)
25)]
26#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
27pub struct MultiPathProof {
28 pub terminal: PathProofTerminal,
30 pub depth: usize,
32}
33
34#[derive(Debug, Clone, Eq, PartialEq)]
36#[cfg_attr(
37 feature = "borsh",
38 derive(borsh::BorshDeserialize, borsh::BorshSerialize)
39)]
40#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
41pub struct MultiProof {
42 pub paths: Vec<MultiPathProof>,
44 pub siblings: Vec<Node>,
59}
60
61struct PathProofRange {
65 lower: usize,
67 upper: usize,
69 path_bit_index: usize,
72}
73
74enum PathProofRangeStep {
75 Bisect {
76 left: PathProofRange,
77 right: PathProofRange,
78 },
79 Advance {
80 sibling: Node,
81 },
82}
83
84impl PathProofRange {
85 fn prove_unique_path_remainder(
86 &self,
87 path_proofs: &[PathProof],
88 ) -> Option<(MultiPathProof, Vec<Node>)> {
89 if self.lower != self.upper - 1 {
92 return None;
93 }
94
95 let path_proof = &path_proofs[self.lower];
96 let unique_siblings: Vec<Node> = path_proof
97 .siblings
98 .iter()
99 .skip(self.path_bit_index)
100 .copied()
101 .collect();
102
103 Some((
104 MultiPathProof {
105 terminal: path_proof.terminal.clone(),
106 depth: self.path_bit_index + unique_siblings.len(),
107 },
108 unique_siblings,
109 ))
110 }
111
112 fn step(&mut self, path_proofs: &[PathProof]) -> PathProofRangeStep {
113 let path_lower = path_proofs[self.lower].terminal.path();
119 let path_upper = path_proofs[self.upper - 1].terminal.path();
120
121 if path_lower[self.path_bit_index] != path_upper[self.path_bit_index] {
122 let mid = self.lower
134 + path_proofs[self.lower..self.upper]
135 .binary_search_by(|path_proof| {
136 if !path_proof.terminal.path()[self.path_bit_index] {
137 core::cmp::Ordering::Less
138 } else {
139 core::cmp::Ordering::Greater
140 }
141 })
142 .unwrap_err();
143
144 let left = PathProofRange {
145 path_bit_index: self.path_bit_index + 1,
146 lower: self.lower,
147 upper: mid,
148 };
149
150 let right = PathProofRange {
151 path_bit_index: self.path_bit_index + 1,
152 lower: mid,
153 upper: self.upper,
154 };
155
156 PathProofRangeStep::Bisect { left, right }
157 } else {
158 let sibling = path_proofs[self.lower].siblings[self.path_bit_index];
160 self.path_bit_index += 1;
161 PathProofRangeStep::Advance { sibling }
162 }
163 }
164}
165
166impl MultiProof {
167 pub fn from_path_proofs(path_proofs: Vec<PathProof>) -> Self {
173 if path_proofs.is_empty() {
208 return MultiProof {
209 paths: Vec::new(),
210 siblings: Vec::new(),
211 };
212 }
213
214 let mut paths: Vec<MultiPathProof> = vec![];
215 let mut siblings: Vec<Node> = vec![];
216
217 let mut proof_range = PathProofRange {
219 path_bit_index: 0,
220 lower: 0,
221 upper: path_proofs.len(),
222 };
223
224 let mut common_siblings: Vec<Node> = vec![];
226
227 let mut stack: Vec<PathProofRange> = vec![];
229
230 loop {
231 if let Some((sub_path_proof, unique_siblings)) =
233 proof_range.prove_unique_path_remainder(&path_proofs)
234 {
235 paths.push(sub_path_proof);
236 siblings.extend(unique_siblings);
237
238 assert!(common_siblings.is_empty());
240
241 proof_range = match stack.pop() {
243 Some(v) => v,
244 None => break,
245 };
246 continue;
247 }
248
249 match proof_range.step(&path_proofs) {
253 PathProofRangeStep::Bisect { left, right } => {
254 siblings.extend(common_siblings.drain(..));
256
257 proof_range = left;
259 stack.push(right);
260 }
261 PathProofRangeStep::Advance { sibling } => common_siblings.push(sibling),
262 };
263 }
264
265 Self { paths, siblings }
266 }
267}
268
269#[derive(Debug, Clone, Copy, PartialEq, Eq)]
271pub enum MultiProofVerificationError {
272 RootMismatch,
274 PathsOutOfOrder,
276 TooManySiblings,
278}
279
280#[derive(Debug, Clone)]
281struct VerifiedMultiPath {
282 terminal: PathProofTerminal,
283 depth: usize,
284 unique_siblings: Range<usize>,
285}
286
287#[derive(Debug, Clone)]
289struct VerifiedBisection {
290 start_depth: usize,
291 common_siblings: Range<usize>,
292}
293
294#[derive(Debug, Clone)]
296#[must_use = "VerifiedMultiProof only checks the consistency of the trie, not the values"]
297pub struct VerifiedMultiProof {
298 inner: Vec<VerifiedMultiPath>,
299 bisections: Vec<VerifiedBisection>,
300 siblings: Vec<Node>,
301 root: Node,
302}
303
304impl VerifiedMultiProof {
305 pub fn find_index_for(&self, key_path: &KeyPath) -> Result<usize, KeyOutOfScope> {
310 let search_result = self.inner.binary_search_by(|v| {
311 v.terminal.path()[..v.depth].cmp(&key_path.view_bits::<Msb0>()[..v.depth])
312 });
313
314 search_result.map_err(|_| KeyOutOfScope)
315 }
316
317 pub fn confirm_nonexistence(&self, key_path: &KeyPath) -> Result<bool, KeyOutOfScope> {
325 let index = self.find_index_for(key_path)?;
326 Ok(self.confirm_nonexistence_inner(key_path, index))
327 }
328
329 pub fn confirm_value(&self, expected_leaf: &LeafData) -> Result<bool, KeyOutOfScope> {
337 let index = self.find_index_for(&expected_leaf.key_path)?;
338 Ok(self.confirm_value_inner(&expected_leaf, index))
339 }
340
341 pub fn confirm_nonexistence_with_index(
354 &self,
355 key_path: &KeyPath,
356 index: usize,
357 ) -> Result<bool, KeyOutOfScope> {
358 let path = &self.inner[index];
359 let depth = path.depth;
360 let in_scope = path.terminal.path()[..depth] == key_path.view_bits::<Msb0>()[..depth];
361
362 if in_scope {
363 Ok(self.confirm_nonexistence_inner(key_path, index))
364 } else {
365 Err(KeyOutOfScope)
366 }
367 }
368
369 pub fn confirm_value_with_index(
382 &self,
383 expected_leaf: &LeafData,
384 index: usize,
385 ) -> Result<bool, KeyOutOfScope> {
386 let path = &self.inner[index];
387 let depth = path.depth;
388 let in_scope =
389 path.terminal.path()[..depth] == expected_leaf.key_path.view_bits::<Msb0>()[..depth];
390
391 if in_scope {
392 Ok(self.confirm_value_inner(&expected_leaf, index))
393 } else {
394 Err(KeyOutOfScope)
395 }
396 }
397
398 fn confirm_nonexistence_inner(&self, key_path: &KeyPath, index: usize) -> bool {
400 match self.inner[index].terminal {
401 PathProofTerminal::Terminator(_) => true,
402 PathProofTerminal::Leaf(ref leaf_data) => &leaf_data.key_path != key_path,
403 }
404 }
405
406 fn confirm_value_inner(&self, expected_leaf: &LeafData, index: usize) -> bool {
408 match self.inner[index].terminal {
409 PathProofTerminal::Terminator(_) => false,
410 PathProofTerminal::Leaf(ref leaf_data) => leaf_data == expected_leaf,
411 }
412 }
413}
414
415pub fn verify<H: NodeHasher>(
420 multi_proof: &MultiProof,
421 root: Node,
422) -> Result<VerifiedMultiProof, MultiProofVerificationError> {
423 let mut verified_paths = Vec::with_capacity(multi_proof.paths.len());
424 let mut verified_bisections = Vec::new();
425 for i in 0..multi_proof.paths.len() {
426 let path = &multi_proof.paths[i];
427 if i > 0 {
428 if path.terminal.path() <= multi_proof.paths[i - 1].terminal.path() {
429 return Err(MultiProofVerificationError::PathsOutOfOrder);
430 }
431 }
432 }
433
434 let (new_root, siblings_used) = verify_range::<H>(
435 0,
436 &multi_proof.paths,
437 &multi_proof.siblings,
438 0,
439 &mut verified_paths,
440 &mut verified_bisections,
441 )?;
442
443 if root != new_root {
444 return Err(MultiProofVerificationError::RootMismatch);
445 }
446
447 if siblings_used != multi_proof.siblings.len() {
448 return Err(MultiProofVerificationError::TooManySiblings);
449 }
450
451 Ok(VerifiedMultiProof {
452 inner: verified_paths,
453 bisections: verified_bisections,
454 siblings: multi_proof.siblings.clone(),
455 root: root,
456 })
457}
458
459fn verify_range<H: NodeHasher>(
461 start_depth: usize,
462 paths: &[MultiPathProof],
463 siblings: &[Node],
464 sibling_offset: usize,
465 verified_paths: &mut Vec<VerifiedMultiPath>,
466 verified_bisections: &mut Vec<VerifiedBisection>,
467) -> Result<(Node, usize), MultiProofVerificationError> {
468 if paths.is_empty() {
471 verified_paths.push(VerifiedMultiPath {
472 terminal: PathProofTerminal::Terminator(crate::trie_pos::TriePosition::new()),
473 depth: 0,
474 unique_siblings: Range { start: 0, end: 0 },
475 });
476 return Ok((TERMINATOR, 0));
477 }
478 if paths.len() == 1 {
479 let terminal_path = &paths[0];
482 let unique_len = terminal_path.depth - start_depth;
483
484 let node = hash_path::<H>(
485 terminal_path.terminal.node::<H>(),
486 &terminal_path.terminal.path()[start_depth..start_depth + unique_len],
487 siblings[..unique_len].iter().rev().copied(),
488 );
489
490 verified_paths.push(VerifiedMultiPath {
491 terminal: terminal_path.terminal.clone(),
492 depth: terminal_path.depth,
493 unique_siblings: Range {
494 start: sibling_offset,
495 end: sibling_offset + unique_len,
496 },
497 });
498
499 return Ok((node, unique_len));
500 }
501
502 let start_path = &paths[0];
503 let end_path = &paths[paths.len() - 1];
504
505 let common_bits = shared_bits(
506 &start_path.terminal.path()[start_depth..],
507 &end_path.terminal.path()[start_depth..],
508 );
509
510 let common_len = start_depth + common_bits;
511 let uncommon_start_len = common_len + 1;
514
515 let search_result = paths.binary_search_by(|item| {
517 if !item.terminal.path()[uncommon_start_len - 1] {
518 Ordering::Less
519 } else {
520 Ordering::Greater
521 }
522 });
523
524 let bisect_idx = search_result.unwrap_err();
529
530 if common_bits > 0 {
531 verified_bisections.push(VerifiedBisection {
532 start_depth,
533 common_siblings: Range {
534 start: sibling_offset,
535 end: sibling_offset + common_bits,
536 },
537 });
538 }
539
540 let (left_node, left_siblings_used) = verify_range::<H>(
542 uncommon_start_len,
543 &paths[..bisect_idx],
544 &siblings[common_bits..],
545 sibling_offset + common_bits,
546 verified_paths,
547 verified_bisections,
548 )?;
549
550 let (right_node, right_siblings_used) = verify_range::<H>(
552 uncommon_start_len,
553 &paths[bisect_idx..],
554 &siblings[common_bits + left_siblings_used..],
555 sibling_offset + common_bits + left_siblings_used,
556 verified_paths,
557 verified_bisections,
558 )?;
559
560 let total_siblings_used = common_bits + left_siblings_used + right_siblings_used;
561 let node = hash_path::<H>(
563 H::hash_internal(&InternalData {
564 left: left_node,
565 right: right_node,
566 }),
567 &start_path.terminal.path()[start_depth..common_len], siblings[..common_bits].iter().rev().copied(),
569 );
570 Ok((node, total_siblings_used))
571}
572
573#[derive(Debug, Clone, Copy)]
575pub enum MultiVerifyUpdateError {
576 OpsOutOfOrder,
578 OpOutOfScope,
580 RootMismatch,
582 PathPrefixOfAnother,
584}
585
586fn terminal_contains(terminal: &VerifiedMultiPath, key_path: &KeyPath) -> bool {
587 key_path.view_bits::<Msb0>()[..terminal.depth] == terminal.terminal.path()[..terminal.depth]
588}
589
590#[derive(Debug)]
596struct CommonSiblings {
597 bisection_stack: Vec<VerifiedBisection>,
598 stack: Vec<(usize, Node)>,
599 taken_siblings: usize,
600 terminal_index: usize,
601 bisection_index: usize,
602}
603
604impl CommonSiblings {
605 fn new() -> Self {
606 CommonSiblings {
607 bisection_stack: Vec::new(),
608 stack: Vec::new(),
609 taken_siblings: 0,
610 terminal_index: 0,
611 bisection_index: 0,
612 }
613 }
614
615 fn advance(&mut self, proof: &VerifiedMultiProof) {
616 let next_terminal = &proof.inner[self.terminal_index];
617
618 let mut prune = true;
619 while next_terminal.unique_siblings.start != self.taken_siblings {
620 let next_bisection = &proof.bisections[self.bisection_index];
621 self.bisection_index += 1;
622
623 assert_eq!(next_bisection.common_siblings.start, self.taken_siblings);
624 if prune {
625 self.pop_to(next_bisection.start_depth);
626 prune = false;
627 }
628
629 self.extend(
631 next_bisection.start_depth + 1,
632 next_bisection.common_siblings.end,
633 &proof.siblings,
634 );
635 self.bisection_stack.push(next_bisection.clone());
636 }
637
638 let terminal_n = next_terminal.unique_siblings.end - next_terminal.unique_siblings.start;
639 self.extend(
640 next_terminal.depth - terminal_n + 1,
641 next_terminal.unique_siblings.end,
642 &proof.siblings,
643 );
644 self.terminal_index += 1;
645 }
646
647 fn pop_to(&mut self, depth: usize) {
648 while self
649 .bisection_stack
650 .last()
651 .map_or(false, |b| b.start_depth >= depth)
652 {
653 let _ = self.bisection_stack.pop();
654 }
655
656 while self.stack.last().map_or(false, |(d, _)| *d >= depth) {
657 let _ = self.stack.pop();
658 }
659 }
660
661 fn extend(&mut self, start_depth: usize, end: usize, siblings: &[Node]) {
662 for (i, sibling) in siblings[self.taken_siblings..end].iter().enumerate() {
663 self.stack.push((start_depth + i, *sibling))
664 }
665
666 self.taken_siblings = end;
667 }
668
669 fn pop_if_at_depth(&mut self, depth: usize) -> Option<Node> {
670 if self.stack.last().map_or(false, |(d, _)| *d == depth) {
671 self.stack.pop().map(|(_, n)| n)
672 } else {
673 None
674 }
675 }
676}
677
678pub fn verify_update<H: NodeHasher>(
689 proof: &VerifiedMultiProof,
690 ops: Vec<(KeyPath, Option<ValueHash>)>,
691) -> Result<Node, MultiVerifyUpdateError> {
692 if ops.is_empty() {
693 return Ok(proof.root);
694 }
695
696 let mut pending_siblings: Vec<(Node, usize)> = Vec::new();
698
699 let mut last_key = None;
700 let mut last_terminal_index = None;
701 let mut next_pending_terminal_index = None;
702
703 let mut working_ops = Vec::new();
704
705 let mut common_siblings = CommonSiblings::new();
706 let ops_len = ops.len();
707
708 for (i, (key, op)) in ops.into_iter().chain(Some(([0u8; 32], None))).enumerate() {
710 let is_last = i == ops_len;
711
712 if is_last {
713 let updated_terminal_index = last_terminal_index.unwrap_or(0);
714 let start = next_pending_terminal_index.unwrap_or(0);
715
716 for terminal_index in start..proof.inner.len() {
718 let next = if terminal_index == proof.inner.len() - 1 {
719 None
720 } else {
721 Some(terminal_index + 1)
722 };
723
724 let terminal = &proof.inner[terminal_index];
725 let next_terminal = next.map(|n| &proof.inner[n]);
726
727 let ops = if terminal_index == updated_terminal_index {
728 &working_ops[..]
729 } else {
730 &[]
731 };
732
733 common_siblings.advance(&proof);
734 hash_and_compact_terminal::<H>(
735 &mut pending_siblings,
736 terminal,
737 next_terminal,
738 &mut common_siblings,
739 ops,
740 )?;
741 }
742 } else {
743 if let Some(last_key) = last_key {
745 if key <= last_key {
746 return Err(MultiVerifyUpdateError::OpsOutOfOrder);
747 }
748 }
749 last_key = Some(key);
750
751 let mut next_terminal_index = last_terminal_index.unwrap_or(0);
753 if proof.inner.len() <= next_terminal_index {
754 return Err(MultiVerifyUpdateError::OpOutOfScope);
755 }
756
757 while !terminal_contains(&proof.inner[next_terminal_index], &key) {
758 next_terminal_index += 1;
759 if proof.inner.len() <= next_terminal_index {
760 return Err(MultiVerifyUpdateError::OpOutOfScope);
761 }
762 }
763
764 if last_terminal_index.map_or(true, |x| x == next_terminal_index) {
766 last_terminal_index = Some(next_terminal_index);
767 working_ops.push((key, op));
768 continue;
769 }
770
771 let updated_index = last_terminal_index.unwrap();
773 last_terminal_index = Some(next_terminal_index);
774
775 let start = next_pending_terminal_index.unwrap_or(0);
777
778 for terminal_index in start..updated_index {
779 let terminal = &proof.inner[terminal_index];
780 let next_terminal = Some(&proof.inner[terminal_index + 1]);
781
782 common_siblings.advance(&proof);
783 hash_and_compact_terminal::<H>(
784 &mut pending_siblings,
785 terminal,
786 next_terminal,
787 &mut common_siblings,
788 &[],
789 )?;
790 }
791
792 let ops = core::mem::replace(&mut working_ops, Vec::new());
794 working_ops.push((key, op));
795
796 let terminal = &proof.inner[updated_index];
797 let next_terminal = proof.inner.get(updated_index + 1);
798 common_siblings.advance(&proof);
799
800 hash_and_compact_terminal::<H>(
801 &mut pending_siblings,
802 terminal,
803 next_terminal,
804 &mut common_siblings,
805 &ops,
806 )?;
807
808 next_pending_terminal_index = Some(updated_index + 1);
809 };
810 }
811
812 Ok(pending_siblings.pop().map(|n| n.0).unwrap_or(proof.root))
814}
815
816fn hash_and_compact_terminal<H: NodeHasher>(
817 pending_siblings: &mut Vec<(Node, usize)>,
818 terminal: &VerifiedMultiPath,
819 next_terminal: Option<&VerifiedMultiPath>,
820 common_siblings: &mut CommonSiblings,
821 ops: &[(KeyPath, Option<ValueHash>)],
822) -> Result<(), MultiVerifyUpdateError> {
823 let leaf = terminal.terminal.as_leaf_option();
824 let skip = terminal.depth;
825
826 let up_layers = if let Some(next_terminal) = next_terminal {
827 let n = shared_bits(terminal.terminal.path(), next_terminal.terminal.path());
828
829 if n == skip {
833 return Err(MultiVerifyUpdateError::PathPrefixOfAnother);
834 }
835
836 skip - (n + 1)
839 } else {
840 skip };
842
843 let ops = crate::update::leaf_ops_spliced(leaf, &ops);
844 let sub_root = crate::update::build_trie::<H>(skip, ops, |_| {});
845
846 let mut cur_node = sub_root;
847 let mut cur_layer = skip;
848 let end_layer = skip - up_layers;
849
850 for bit in terminal.terminal.path()[..terminal.depth]
854 .iter()
855 .by_vals()
856 .rev()
857 .take(up_layers)
858 {
859 let sibling = if pending_siblings.last().map_or(false, |p| p.1 == cur_layer) {
860 let _ = common_siblings.pop_if_at_depth(cur_layer);
862 pending_siblings.pop().unwrap().0
864 } else {
865 common_siblings.pop_if_at_depth(cur_layer).unwrap()
869 };
870
871 match (NodeKind::of::<H>(&cur_node), NodeKind::of::<H>(&sibling)) {
872 (NodeKind::Terminator, NodeKind::Terminator) => {}
873 (NodeKind::Leaf, NodeKind::Terminator) => {}
874 (NodeKind::Terminator, NodeKind::Leaf) => {
875 cur_node = sibling;
877 }
878 _ => {
879 let node_data = if bit {
881 InternalData {
882 left: sibling,
883 right: cur_node,
884 }
885 } else {
886 InternalData {
887 left: cur_node,
888 right: sibling,
889 }
890 };
891 cur_node = H::hash_internal(&node_data);
892 }
893 }
894
895 cur_layer -= 1;
896 }
897
898 pending_siblings.push((cur_node, end_layer));
899 Ok(())
900}
901
902#[cfg(test)]
903mod tests {
904 use super::{verify, verify_update, MultiProof};
905
906 use crate::proof::multi_proof::{
907 MultiVerifyUpdateError, VerifiedMultiPath, VerifiedMultiProof,
908 };
909 use crate::{
910 hasher::{Blake3Hasher, NodeHasher},
911 proof::{PathProof, PathProofTerminal},
912 trie::{InternalData, LeafData, ValueHash, TERMINATOR},
913 trie_pos::TriePosition,
914 update::build_trie,
915 };
916 use bitvec::prelude::*;
917 use nomt_test_utils::key_with_prefix;
918
919 #[test]
920 pub fn test_multiproof_creation_single_path_proof() {
921 let mut key_path = [0; 32];
922 key_path[0] = 0b10000000;
923 let sibling1 = [1; 32];
924 let sibling2 = [2; 32];
925 let path_proof = PathProof {
926 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
927 key_path, 256,
928 )),
929 siblings: vec![sibling1, sibling2],
930 };
931
932 let multi_proof = MultiProof::from_path_proofs(vec![path_proof]);
933 assert_eq!(multi_proof.paths.len(), 1);
934 assert_eq!(
935 multi_proof.paths[0].terminal,
936 PathProofTerminal::Terminator(TriePosition::from_path_and_depth(key_path, 256))
937 );
938 assert_eq!(multi_proof.paths[0].depth, 2);
939 assert_eq!(multi_proof.siblings.len(), 2);
940 assert_eq!(multi_proof.siblings, vec![sibling1, sibling2]);
941 }
942
943 #[test]
944 pub fn test_multiproof_creation_two_path_proofs() {
945 let mut key_path_1 = [0; 32];
946 key_path_1[0] = 0b00000000;
947
948 let mut key_path_2 = [0; 32];
949 key_path_2[0] = 0b00111000;
950
951 let sibling1 = [1; 32];
952 let sibling2 = [2; 32];
953 let sibling3 = [3; 32];
954 let sibling4 = [4; 32];
955 let sibling5 = [5; 32];
956 let sibling6 = [6; 32];
957
958 let sibling_x = [b'x'; 32];
959
960 let path_proof_1 = PathProof {
961 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
962 key_path_1, 256,
963 )),
964 siblings: vec![sibling1, sibling2, sibling_x, sibling3, sibling4],
965 };
966 let path_proof_2 = PathProof {
967 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
968 key_path_2, 256,
969 )),
970 siblings: vec![sibling1, sibling2, sibling_x, sibling5, sibling6],
971 };
972
973 let multi_proof = MultiProof::from_path_proofs(vec![path_proof_1, path_proof_2]);
974
975 assert_eq!(multi_proof.paths.len(), 2);
976 assert_eq!(multi_proof.siblings.len(), 6);
977
978 assert_eq!(
979 multi_proof.paths[0].terminal,
980 PathProofTerminal::Terminator(TriePosition::from_path_and_depth(key_path_1, 256))
981 );
982 assert_eq!(
983 multi_proof.paths[1].terminal,
984 PathProofTerminal::Terminator(TriePosition::from_path_and_depth(key_path_2, 256))
985 );
986
987 assert_eq!(multi_proof.paths[0].depth, 5);
988 assert_eq!(multi_proof.paths[1].depth, 5);
989
990 assert_eq!(
991 multi_proof.siblings,
992 vec![sibling1, sibling2, sibling3, sibling4, sibling5, sibling6]
993 );
994 }
995
996 #[test]
997 pub fn test_multiproof_creation_two_path_proofs_256_depth() {
998 let mut key_path_1 = [0; 32];
999 key_path_1[31] = 0b00000000;
1000
1001 let mut key_path_2 = [0; 32];
1002 key_path_2[31] = 0b00000001;
1003
1004 let mut siblings_1: Vec<[u8; 32]> = (0..255).map(|i| [i; 32]).collect();
1005 let mut siblings_2 = siblings_1.clone();
1006 siblings_1.push([b'2'; 32]);
1007 siblings_2.push([b'1'; 32]);
1008
1009 let path_proof_1 = PathProof {
1010 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
1011 key_path_1, 256,
1012 )),
1013 siblings: siblings_1.clone(),
1014 };
1015 let path_proof_2 = PathProof {
1016 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
1017 key_path_2, 256,
1018 )),
1019 siblings: siblings_2,
1020 };
1021
1022 let multi_proof = MultiProof::from_path_proofs(vec![path_proof_1, path_proof_2]);
1023
1024 assert_eq!(multi_proof.paths.len(), 2);
1025 assert_eq!(multi_proof.siblings.len(), 255);
1026
1027 assert_eq!(
1028 multi_proof.paths[0].terminal,
1029 PathProofTerminal::Terminator(TriePosition::from_path_and_depth(key_path_1, 256))
1030 );
1031 assert_eq!(
1032 multi_proof.paths[1].terminal,
1033 PathProofTerminal::Terminator(TriePosition::from_path_and_depth(key_path_2, 256))
1034 );
1035
1036 assert_eq!(multi_proof.paths[0].depth, 256);
1037 assert_eq!(multi_proof.paths[1].depth, 256);
1038
1039 siblings_1.pop();
1040 assert_eq!(multi_proof.siblings, siblings_1);
1041 }
1042
1043 #[test]
1044 pub fn test_multiproof_creation_multiple_path_proofs() {
1045 let mut key_path_1 = [0; 32];
1046 key_path_1[0] = 0b00000000;
1047
1048 let mut key_path_2 = [0; 32];
1049 key_path_2[0] = 0b01000000;
1050
1051 let mut key_path_3 = [0; 32];
1052 key_path_3[0] = 0b01001100;
1053
1054 let mut key_path_4 = [0; 32];
1055 key_path_4[0] = 0b11101100;
1056
1057 let mut key_path_5 = [0; 32];
1058 key_path_5[0] = 0b11110100;
1059
1060 let mut key_path_6 = [0; 32];
1061 key_path_6[0] = 0b11111000;
1062
1063 let sibling1 = [1; 32];
1064 let sibling2 = [2; 32];
1065 let sibling3 = [3; 32];
1066 let sibling4 = [4; 32];
1067 let sibling5 = [5; 32];
1068 let sibling6 = [6; 32];
1069 let sibling7 = [7; 32];
1070 let sibling8 = [8; 32];
1071 let sibling9 = [9; 32];
1072 let sibling10 = [10; 32];
1073 let sibling11 = [11; 32];
1074 let sibling12 = [12; 32];
1075 let sibling13 = [13; 32];
1076 let sibling14 = [14; 32];
1077 let sibling15 = [15; 32];
1078 let sibling16 = [16; 32];
1079 let sibling17 = [17; 32];
1080 let sibling18 = [18; 32];
1081 let sibling19 = [19; 32];
1082
1083 let path_proof_1 = PathProof {
1084 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
1085 key_path_1, 256,
1086 )),
1087 siblings: vec![sibling1, sibling2],
1088 };
1089
1090 let path_proof_2 = PathProof {
1091 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
1092 key_path_2, 256,
1093 )),
1094 siblings: vec![sibling1, sibling3, sibling4, sibling5, sibling6, sibling7],
1095 };
1096
1097 let path_proof_3 = PathProof {
1098 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
1099 key_path_3, 256,
1100 )),
1101 siblings: vec![sibling1, sibling3, sibling4, sibling5, sibling8, sibling9],
1102 };
1103
1104 let path_proof_4 = PathProof {
1105 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
1106 key_path_4, 256,
1107 )),
1108 siblings: vec![
1109 sibling10, sibling11, sibling12, sibling13, sibling14, sibling15,
1110 ],
1111 };
1112
1113 let path_proof_5 = PathProof {
1114 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
1115 key_path_5, 256,
1116 )),
1117 siblings: vec![
1118 sibling10, sibling11, sibling12, sibling16, sibling17, sibling18,
1119 ],
1120 };
1121
1122 let path_proof_6 = PathProof {
1123 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
1124 key_path_6, 256,
1125 )),
1126 siblings: vec![sibling10, sibling11, sibling12, sibling16, sibling19],
1127 };
1128
1129 let multi_proof = MultiProof::from_path_proofs(vec![
1130 path_proof_1,
1131 path_proof_2,
1132 path_proof_3,
1133 path_proof_4,
1134 path_proof_5,
1135 path_proof_6,
1136 ]);
1137
1138 assert_eq!(multi_proof.paths.len(), 6);
1139 assert_eq!(multi_proof.siblings.len(), 9);
1140
1141 assert_eq!(
1142 multi_proof.paths[0].terminal,
1143 PathProofTerminal::Terminator(TriePosition::from_path_and_depth(key_path_1, 256))
1144 );
1145 assert_eq!(
1146 multi_proof.paths[1].terminal,
1147 PathProofTerminal::Terminator(TriePosition::from_path_and_depth(key_path_2, 256))
1148 );
1149 assert_eq!(
1150 multi_proof.paths[2].terminal,
1151 PathProofTerminal::Terminator(TriePosition::from_path_and_depth(key_path_3, 256))
1152 );
1153 assert_eq!(
1154 multi_proof.paths[3].terminal,
1155 PathProofTerminal::Terminator(TriePosition::from_path_and_depth(key_path_4, 256))
1156 );
1157 assert_eq!(
1158 multi_proof.paths[4].terminal,
1159 PathProofTerminal::Terminator(TriePosition::from_path_and_depth(key_path_5, 256))
1160 );
1161 assert_eq!(
1162 multi_proof.paths[5].terminal,
1163 PathProofTerminal::Terminator(TriePosition::from_path_and_depth(key_path_6, 256))
1164 );
1165
1166 assert_eq!(multi_proof.paths[0].depth, 2);
1167 assert_eq!(multi_proof.paths[1].depth, 6);
1168 assert_eq!(multi_proof.paths[2].depth, 6);
1169 assert_eq!(multi_proof.paths[3].depth, 6);
1170 assert_eq!(multi_proof.paths[4].depth, 6);
1171 assert_eq!(multi_proof.paths[5].depth, 5);
1172
1173 assert_eq!(
1174 multi_proof.siblings,
1175 vec![
1176 sibling4, sibling5, sibling7, sibling9, sibling11, sibling12, sibling14, sibling15,
1177 sibling18
1178 ]
1179 );
1180 }
1181
1182 #[test]
1183 pub fn test_multiproof_creation_ext_siblings_order() {
1184 let mut key_path_0 = [0; 32];
1185 key_path_0[0] = 0b00001000;
1186
1187 let mut key_path_1 = [0; 32];
1188 key_path_1[0] = 0b00010000;
1189
1190 let mut key_path_2 = [0; 32];
1191 key_path_2[0] = 0b10000000;
1192
1193 let mut key_path_3 = [0; 32];
1194 key_path_3[0] = 0b10000010;
1195
1196 let mut key_path_4 = [0; 32];
1197 key_path_4[0] = 0b10010001;
1198
1199 let mut key_path_5 = [0; 32];
1200 key_path_5[0] = 0b10010011;
1201
1202 let sibling1 = [1; 32];
1203 let sibling2 = [2; 32];
1204 let sibling3 = [3; 32];
1205 let sibling4 = [4; 32];
1206 let sibling5 = [5; 32];
1207 let sibling6 = [6; 32];
1208 let sibling7 = [7; 32];
1209 let sibling8 = [8; 32];
1210 let sibling9 = [9; 32];
1211 let sibling10 = [10; 32];
1212 let sibling11 = [11; 32];
1213 let sibling12 = [12; 32];
1214 let sibling13 = [13; 32];
1215 let sibling14 = [14; 32];
1216 let sibling15 = [15; 32];
1217 let sibling16 = [16; 32];
1218 let sibling17 = [17; 32];
1219 let sibling18 = [18; 32];
1220 let sibling19 = [19; 32];
1221 let sibling20 = [20; 32];
1222 let sibling21 = [21; 32];
1223 let sibling22 = [22; 32];
1224 let sibling23 = [23; 32];
1225 let sibling24 = [24; 32];
1226
1227 let path_proof_0 = PathProof {
1228 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
1229 key_path_0, 256,
1230 )),
1231 siblings: vec![sibling1, sibling2, sibling3, sibling4, sibling5],
1232 };
1233
1234 let path_proof_1 = PathProof {
1235 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
1236 key_path_1, 256,
1237 )),
1238 siblings: vec![sibling1, sibling2, sibling3, sibling6, sibling7],
1239 };
1240
1241 let path_proof_2 = PathProof {
1242 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
1243 key_path_2, 256,
1244 )),
1245 siblings: vec![
1246 sibling8, sibling9, sibling10, sibling11, sibling12, sibling13, sibling14,
1247 sibling15,
1248 ],
1249 };
1250 let path_proof_3 = PathProof {
1251 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
1252 key_path_3, 256,
1253 )),
1254 siblings: vec![
1255 sibling8, sibling9, sibling10, sibling11, sibling12, sibling13, sibling16,
1256 sibling17,
1257 ],
1258 };
1259
1260 let path_proof_4 = PathProof {
1261 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
1262 key_path_4, 256,
1263 )),
1264 siblings: vec![
1265 sibling8, sibling9, sibling10, sibling18, sibling19, sibling20, sibling21,
1266 sibling22,
1267 ],
1268 };
1269
1270 let path_proof_5 = PathProof {
1271 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
1272 key_path_5, 256,
1273 )),
1274 siblings: vec![
1275 sibling8, sibling9, sibling10, sibling18, sibling19, sibling20, sibling23,
1276 sibling24,
1277 ],
1278 };
1279
1280 let multi_proof = MultiProof::from_path_proofs(vec![
1281 path_proof_0,
1282 path_proof_1,
1283 path_proof_2,
1284 path_proof_3,
1285 path_proof_4,
1286 path_proof_5,
1287 ]);
1288
1289 assert_eq!(multi_proof.paths.len(), 6);
1290 assert_eq!(multi_proof.siblings.len(), 14);
1291
1292 assert_eq!(
1293 multi_proof.siblings,
1294 vec![
1295 sibling2, sibling3, sibling5, sibling7, sibling9, sibling10, sibling12, sibling13,
1296 sibling15, sibling17, sibling19, sibling20, sibling22, sibling24
1297 ]
1298 );
1299 }
1300
1301 #[test]
1302 fn multi_proof_failure_empty_witness() {
1303 let multi_proof = MultiProof::from_path_proofs(Vec::new());
1304
1305 let _verified_multi_proof = verify::<Blake3Hasher>(&multi_proof, TERMINATOR).unwrap();
1306 }
1307
1308 #[test]
1309 fn multi_proof_verify_empty() {
1310 let multi_proof = MultiProof::from_path_proofs(Vec::new());
1311
1312 let verified_multi_proof = verify::<Blake3Hasher>(&multi_proof, TERMINATOR).unwrap();
1313
1314 assert_eq!(
1315 verify_update::<Blake3Hasher>(&verified_multi_proof, Vec::new()).unwrap(),
1316 TERMINATOR,
1317 );
1318 }
1319
1320 #[test]
1321 fn multi_proof_verify_empty_with_provided_updates() {
1322 let multi_proof = MultiProof::from_path_proofs(Vec::new());
1323
1324 let verified_multi_proof = verify::<Blake3Hasher>(&multi_proof, TERMINATOR).unwrap();
1325
1326 let mut key_path_0 = [0; 32];
1327 key_path_0[0] = 0b00001000;
1328
1329 let mut key_path_1 = [0; 32];
1330 key_path_1[0] = 0b00010000;
1331
1332 let mut key_path_2 = [0; 32];
1333 key_path_2[0] = 0b10000000;
1334
1335 let ops = vec![
1336 (key_path_0, Some([1; 32])),
1337 (key_path_1, Some([1; 32])),
1338 (key_path_2, Some([1; 32])),
1339 ];
1340
1341 let expected_root = build_trie::<Blake3Hasher>(
1342 0,
1343 ops.clone().into_iter().map(|(k, v)| (k, v.unwrap())),
1344 |_| {},
1345 );
1346
1347 assert_eq!(
1348 verify_update::<Blake3Hasher>(&verified_multi_proof, ops).unwrap(),
1349 expected_root,
1350 );
1351 }
1352
1353 #[test]
1354 pub fn test_verify_multiproof_two_leafs() {
1355 let mut key_path_0 = [0; 32];
1362 key_path_0[0] = 0b00000000;
1363
1364 let mut key_path_1 = [0; 32];
1365 key_path_1[0] = 0b10000000;
1366
1367 let mut key_path_2 = [0; 32];
1368 key_path_2[0] = 0b01000000;
1369
1370 let leaf_0 = LeafData {
1371 key_path: key_path_0,
1372 value_hash: [0; 32],
1373 };
1374
1375 let leaf_1 = LeafData {
1376 key_path: key_path_1,
1377 value_hash: [1; 32],
1378 };
1379
1380 let leaf_2 = LeafData {
1381 key_path: key_path_2,
1382 value_hash: [2; 32],
1383 };
1384
1385 let v0 = Blake3Hasher::hash_leaf(&leaf_0);
1387 let v1 = Blake3Hasher::hash_leaf(&leaf_1);
1388 let v2 = Blake3Hasher::hash_leaf(&leaf_2);
1389 let s3 = Blake3Hasher::hash_internal(&InternalData {
1390 left: v0.clone(),
1391 right: v2,
1392 });
1393 let root = Blake3Hasher::hash_internal(&InternalData {
1394 left: s3,
1395 right: v1,
1396 });
1397
1398 let path_proof_0 = PathProof {
1399 terminal: PathProofTerminal::Leaf(leaf_0.clone()),
1400 siblings: vec![v1, v2],
1401 };
1402 let path_proof_1 = PathProof {
1403 terminal: PathProofTerminal::Leaf(leaf_1.clone()),
1404 siblings: vec![s3],
1405 };
1406
1407 let multi_proof =
1408 MultiProof::from_path_proofs(vec![path_proof_0.clone(), path_proof_1.clone()]);
1409
1410 let verified = verify::<Blake3Hasher>(&multi_proof, root).unwrap();
1411
1412 assert!(verified.confirm_value(&leaf_0).unwrap());
1413 assert!(verified.confirm_value(&leaf_1).unwrap());
1414 }
1415
1416 #[test]
1417 fn multi_proof_verify_2_leaves_with_provided_updates() {
1418 let mut key_path_0 = [0; 32];
1425 key_path_0[0] = 0b00000000;
1426
1427 let mut key_path_1 = [0; 32];
1428 key_path_1[0] = 0b10000000;
1429
1430 let mut key_path_2 = [0; 32];
1431 key_path_2[0] = 0b01000000;
1432
1433 let leaf_0 = LeafData {
1434 key_path: key_path_0,
1435 value_hash: [0; 32],
1436 };
1437
1438 let leaf_1 = LeafData {
1439 key_path: key_path_1,
1440 value_hash: [1; 32],
1441 };
1442
1443 let leaf_2 = LeafData {
1444 key_path: key_path_2,
1445 value_hash: [2; 32],
1446 };
1447
1448 let v0 = Blake3Hasher::hash_leaf(&leaf_0);
1450 let v1 = Blake3Hasher::hash_leaf(&leaf_1);
1451 let v2 = Blake3Hasher::hash_leaf(&leaf_2);
1452 let s3 = Blake3Hasher::hash_internal(&InternalData {
1453 left: v0.clone(),
1454 right: v2,
1455 });
1456 let root = Blake3Hasher::hash_internal(&InternalData {
1457 left: s3,
1458 right: v1,
1459 });
1460
1461 let path_proof_0 = PathProof {
1462 terminal: PathProofTerminal::Leaf(leaf_0.clone()),
1463 siblings: vec![v1, v2],
1464 };
1465 let path_proof_1 = PathProof {
1466 terminal: PathProofTerminal::Leaf(leaf_1.clone()),
1467 siblings: vec![s3],
1468 };
1469
1470 let multi_proof =
1471 MultiProof::from_path_proofs(vec![path_proof_0.clone(), path_proof_1.clone()]);
1472
1473 let verified = verify::<Blake3Hasher>(&multi_proof, root).unwrap();
1474
1475 let mut key_path_3 = key_path_1;
1476 key_path_3[0] = 0b10100000;
1477
1478 let mut key_path_4 = key_path_0;
1479 key_path_4[0] = 0b00000100;
1480
1481 let ops = vec![
1482 (key_path_0, Some([2; 32])),
1483 (key_path_4, Some([1; 32])),
1484 (key_path_1, None),
1485 (key_path_3, Some([1; 32])),
1486 ];
1487
1488 let final_state = vec![
1489 (key_path_0, [2; 32]),
1490 (key_path_4, [1; 32]),
1491 (key_path_2, [2; 32]),
1492 (key_path_3, [1; 32]),
1493 ];
1494
1495 let expected_root = build_trie::<Blake3Hasher>(0, final_state, |_| {});
1496
1497 assert_eq!(
1498 verify_update::<Blake3Hasher>(&verified, ops).unwrap(),
1499 expected_root,
1500 );
1501 }
1502
1503 #[test]
1504 fn verify_update_terminal_with_multi_unique_siblings() {
1505 let mut k_alone = [0u8; 32];
1530 k_alone[0] = 0b00000000;
1531 let mut k_neighbor = [0u8; 32];
1532 k_neighbor[0] = 0b00000001;
1533 let mut k_other = [0u8; 32];
1534 k_other[0] = 0b10000000;
1535
1536 let make_leaf = |key_path, value_byte| {
1537 let leaf_data = LeafData {
1538 key_path,
1539 value_hash: [value_byte; 32],
1540 };
1541 let hash = Blake3Hasher::hash_leaf(&leaf_data);
1542 (leaf_data, hash)
1543 };
1544 let internal_hash =
1545 |left, right| Blake3Hasher::hash_internal(&InternalData { left, right });
1546
1547 let (l_alone, h_alone) = make_leaf(k_alone, 0xAA);
1548 let (l_neighbor, h_neighbor) = make_leaf(k_neighbor, 0xBB);
1549 let (l_other, h_other) = make_leaf(k_other, 0xCC);
1550
1551 let i7 = internal_hash(h_alone, h_neighbor);
1552 let i6 = internal_hash(i7, TERMINATOR);
1553 let i5 = internal_hash(i6, TERMINATOR);
1554 let i4 = internal_hash(i5, TERMINATOR);
1555 let i3 = internal_hash(i4, TERMINATOR);
1556 let i2 = internal_hash(i3, TERMINATOR);
1557 let i1 = internal_hash(i2, TERMINATOR);
1558 let root = internal_hash(i1, h_other);
1559
1560 let path_proof_alone = PathProof {
1562 terminal: PathProofTerminal::Leaf(l_alone.clone()),
1563 siblings: vec![
1564 h_other, TERMINATOR, TERMINATOR, TERMINATOR, TERMINATOR, TERMINATOR, TERMINATOR,
1565 h_neighbor,
1566 ],
1567 };
1568 let path_proof_other = PathProof {
1569 terminal: PathProofTerminal::Leaf(l_other.clone()),
1570 siblings: vec![i1],
1571 };
1572
1573 let multi_proof = MultiProof::from_path_proofs(vec![path_proof_alone, path_proof_other]);
1574
1575 let verified = verify::<Blake3Hasher>(&multi_proof, root).unwrap();
1576
1577 let new_value: ValueHash = [0xDD; 32];
1579 let ops = vec![(k_alone, Some(new_value))];
1580
1581 let new_state = vec![
1583 (k_alone, new_value),
1584 (k_neighbor, l_neighbor.value_hash),
1585 (k_other, l_other.value_hash),
1586 ];
1587 let expected_root = build_trie::<Blake3Hasher>(0, new_state, |_| {});
1588
1589 assert_eq!(
1590 verify_update::<Blake3Hasher>(&verified, ops).unwrap(),
1591 expected_root,
1592 );
1593 }
1594
1595 #[test]
1596 fn multi_proof_verify_4_leaves_with_long_bisections() {
1597 let make_leaf = |key_path, value_byte| {
1608 let leaf_data = LeafData {
1609 key_path,
1610 value_hash: [value_byte; 32],
1611 };
1612
1613 let hash = Blake3Hasher::hash_leaf(&leaf_data);
1614 (leaf_data, hash)
1615 };
1616 let internal_hash =
1617 |left, right| Blake3Hasher::hash_internal(&InternalData { left, right });
1618
1619 let mut key_path_0 = [0; 32];
1620 key_path_0[0] = 0b00000000;
1621
1622 let mut key_path_1 = [0; 32];
1623 key_path_1[0] = 0b00000001;
1624
1625 let mut key_path_2 = [0; 32];
1626 key_path_2[0] = 0b00001000;
1627
1628 let mut key_path_3 = [0; 32];
1629 key_path_3[0] = 0b00001001;
1630
1631 let (leaf_a, l8a) = make_leaf(key_path_0, 1);
1632 let (leaf_b, l8b) = make_leaf(key_path_1, 1);
1633 let (leaf_c, l8c) = make_leaf(key_path_2, 1);
1634 let (leaf_d, l8d) = make_leaf(key_path_3, 1);
1635
1636 let i7a = internal_hash(l8a, l8b);
1637 let i7b = internal_hash(l8c, l8d);
1638
1639 let i6a = internal_hash(i7a, [7; 32]);
1640 let i6b = internal_hash(i7b, [7; 32]);
1641
1642 let i5a = internal_hash(i6a, [6; 32]);
1643 let i5b = internal_hash(i6b, [6; 32]);
1644
1645 let i4 = internal_hash(i5a, i5b);
1646 let i3 = internal_hash(i4, [4; 32]);
1647 let i2 = internal_hash(i3, [3; 32]);
1648 let i1 = internal_hash(i2, [2; 32]);
1649 let root = internal_hash(i1, [1; 32]);
1650
1651 let path_proof_a = PathProof {
1652 terminal: PathProofTerminal::Leaf(leaf_a.clone()),
1653 siblings: vec![
1654 [1; 32], [2; 32], [3; 32], [4; 32], i5b, [6; 32], [7; 32], l8b,
1655 ],
1656 };
1657 let path_proof_b = PathProof {
1658 terminal: PathProofTerminal::Leaf(leaf_b.clone()),
1659 siblings: vec![
1660 [1; 32], [2; 32], [3; 32], [4; 32], i5b, [6; 32], [7; 32], l8a,
1661 ],
1662 };
1663 let path_proof_c = PathProof {
1664 terminal: PathProofTerminal::Leaf(leaf_c.clone()),
1665 siblings: vec![
1666 [1; 32], [2; 32], [3; 32], [4; 32], i5a, [6; 32], [7; 32], l8d,
1667 ],
1668 };
1669 let path_proof_d = PathProof {
1670 terminal: PathProofTerminal::Leaf(leaf_d.clone()),
1671 siblings: vec![
1672 [1; 32], [2; 32], [3; 32], [4; 32], i5a, [6; 32], [7; 32], l8c,
1673 ],
1674 };
1675
1676 let multi_proof = MultiProof::from_path_proofs(vec![
1677 path_proof_a.clone(),
1678 path_proof_b.clone(),
1679 path_proof_c.clone(),
1680 path_proof_d.clone(),
1681 ]);
1682
1683 let verified = verify::<Blake3Hasher>(&multi_proof, root).unwrap();
1684
1685 let ops = vec![(key_path_0, Some([69; 32])), (key_path_3, Some([69; 32]))];
1686
1687 let (_, l8a) = make_leaf(key_path_0, 69);
1688 let (_, l8b) = make_leaf(key_path_1, 1);
1689 let (_, l8c) = make_leaf(key_path_2, 1);
1690 let (_, l8d) = make_leaf(key_path_3, 69);
1691
1692 let i7a = internal_hash(l8a, l8b);
1693 let i7b = internal_hash(l8c, l8d);
1694
1695 let i6a = internal_hash(i7a, [7; 32]);
1696 let i6b = internal_hash(i7b, [7; 32]);
1697
1698 let i5a = internal_hash(i6a, [6; 32]);
1699 let i5b = internal_hash(i6b, [6; 32]);
1700
1701 let i4 = internal_hash(i5a, i5b);
1702
1703 let i3 = internal_hash(i4, [4; 32]);
1704 let i2 = internal_hash(i3, [3; 32]);
1705 let i1 = internal_hash(i2, [2; 32]);
1706 let post_root = internal_hash(i1, [1; 32]);
1707
1708 assert_eq!(
1709 verify_update::<Blake3Hasher>(&verified, ops).unwrap(),
1710 post_root,
1711 );
1712 }
1713
1714 #[test]
1715 pub fn test_verify_multiproof_multiple_leafs() {
1716 let path = |byte| [byte; 32];
1727
1728 let k0 = path(0b00000000);
1729 let k1 = path(0b00011000);
1730 let k2 = path(0b00101101);
1731 let k3 = path(0b10101010);
1732 let k4 = path(0b11000011);
1733 let k5 = path(0b11100010);
1734
1735 let make_leaf = |key_path| {
1736 let leaf_data = LeafData {
1737 key_path,
1738 value_hash: [key_path[0]; 32],
1739 };
1740
1741 let hash = Blake3Hasher::hash_leaf(&leaf_data);
1742 (leaf_data, hash)
1743 };
1744 let internal_hash =
1745 |left, right| Blake3Hasher::hash_internal(&InternalData { left, right });
1746
1747 let (l0, v0) = make_leaf(k0);
1748 let (l1, v1) = make_leaf(k1);
1749 let (l2, v2) = make_leaf(k2);
1750 let (l3, v3) = make_leaf(k3);
1751 let (l4, v4) = make_leaf(k4);
1752 let (l5, v5) = make_leaf(k5);
1753
1754 let i1 = internal_hash(v0, v1);
1755 let i2 = internal_hash(i1, v2);
1756 let i3 = internal_hash(i2, TERMINATOR);
1757
1758 let i4 = internal_hash(v4, TERMINATOR);
1759 let i5 = internal_hash(i4, v5);
1760 let i6 = internal_hash(v3, i5);
1761
1762 let root = internal_hash(i3, i6);
1763
1764 let leaf_proof = |leaf, siblings| PathProof {
1765 terminal: PathProofTerminal::Leaf(leaf),
1766 siblings,
1767 };
1768
1769 let path_proof_0 = leaf_proof(l0.clone(), vec![i6, TERMINATOR, v2, v1]);
1770 let path_proof_1 = leaf_proof(l1.clone(), vec![i6, TERMINATOR, v2, v0]);
1771 let path_proof_2 = leaf_proof(l2.clone(), vec![i6, TERMINATOR, i1]);
1772 let path_proof_3 = leaf_proof(l3.clone(), vec![i3, i5]);
1773 let path_proof_4 = leaf_proof(l4.clone(), vec![i3, v3, v5, TERMINATOR]);
1774 let path_proof_5 = leaf_proof(l5.clone(), vec![i3, v3, i4]);
1775
1776 let multi_proof = MultiProof::from_path_proofs(vec![
1777 path_proof_0.clone(),
1778 path_proof_1.clone(),
1779 path_proof_2.clone(),
1780 path_proof_3.clone(),
1781 path_proof_4.clone(),
1782 path_proof_5.clone(),
1783 ]);
1784
1785 let verified = verify::<Blake3Hasher>(&multi_proof, root).unwrap();
1786 assert!(verified.confirm_value(&l0).unwrap());
1787 assert!(verified.confirm_value(&l1).unwrap());
1788 assert!(verified.confirm_value(&l2).unwrap());
1789 assert!(verified.confirm_value(&l3).unwrap());
1790 assert!(verified.confirm_value(&l4).unwrap());
1791 assert!(verified.confirm_value(&l5).unwrap());
1792 }
1793
1794 #[test]
1795 pub fn test_verify_multiproof_siblings_structure() {
1796 let path = |byte| [byte; 32];
1815
1816 let k0 = path(0b00000000);
1817 let k1 = path(0b10000000);
1818 let k2 = path(0b10000001);
1819 let k3 = path(0b10011100);
1820 let k4 = path(0b10011110);
1821
1822 let make_leaf = |key_path| {
1823 let leaf_data = LeafData {
1824 key_path,
1825 value_hash: [key_path[0]; 32],
1826 };
1827
1828 let hash = Blake3Hasher::hash_leaf(&leaf_data);
1829 (leaf_data, hash)
1830 };
1831 let internal_hash =
1832 |left, right| Blake3Hasher::hash_internal(&InternalData { left, right });
1833
1834 let (_l0, v0) = make_leaf(k0);
1835 let (l1, v1) = make_leaf(k1);
1836 let (l2, v2) = make_leaf(k2);
1837 let (l3, v3) = make_leaf(k3);
1838 let (l4, v4) = make_leaf(k4);
1839
1840 let e1 = [1; 32];
1841 let e2 = [2; 32];
1842 let e3 = [3; 32];
1843 let e4 = [4; 32];
1844 let e5 = [5; 32];
1845 let e6 = [6; 32];
1846 let e7 = TERMINATOR;
1847
1848 let i1 = internal_hash(v1, v2);
1849 let i2 = internal_hash(i1, e1);
1850 let i3 = internal_hash(i2, e2);
1851 let i4 = internal_hash(i3, e3);
1852
1853 let i5 = internal_hash(v3, v4);
1854 let i6 = internal_hash(e4, i5);
1855 let i7 = internal_hash(e5, i6);
1856
1857 let i8 = internal_hash(i4, i7);
1858 let i9 = internal_hash(i8, e6);
1859 let i10 = internal_hash(i9, e7);
1860
1861 let root = internal_hash(v0, i10);
1862
1863 let leaf_proof = |leaf, siblings| PathProof {
1864 terminal: PathProofTerminal::Leaf(leaf),
1865 siblings,
1866 };
1867
1868 let path_proof_1 = leaf_proof(l1.clone(), vec![v0, e7, e6, i7, e3, e2, e1, v2]);
1869 let path_proof_2 = leaf_proof(l2.clone(), vec![v0, e7, e6, i7, e3, e2, e1, v1]);
1870 let path_proof_3 = leaf_proof(l3.clone(), vec![v0, e7, e6, i4, e5, e4, v4]);
1871 let path_proof_4 = leaf_proof(l4.clone(), vec![v0, e7, e6, i4, e5, e4, v3]);
1872
1873 let multi_proof = MultiProof::from_path_proofs(vec![
1874 path_proof_1.clone(),
1875 path_proof_2.clone(),
1876 path_proof_3.clone(),
1877 path_proof_4.clone(),
1878 ]);
1879
1880 assert_eq!(multi_proof.siblings, vec![v0, e7, e6, e3, e2, e1, e5, e4]);
1881
1882 let verified = verify::<Blake3Hasher>(&multi_proof, root).unwrap();
1883 assert!(verified.confirm_value(&l1).unwrap());
1884 assert!(verified.confirm_value(&l2).unwrap());
1885 assert!(verified.confirm_value(&l3).unwrap());
1886 assert!(verified.confirm_value(&l4).unwrap());
1887 }
1888
1889 #[test]
1890
1891 fn test_verify_update_underflow_prefix_paths() {
1892 let bits_prefix = bitvec![u8, Msb0; 1, 0, 1, 0]; let bits_longer = bitvec![u8, Msb0; 1, 0, 1, 0, 1, 1]; let kp_prefix = key_with_prefix(bits_prefix.iter().by_vals());
1896 let kp_longer = key_with_prefix(bits_longer.iter().by_vals());
1897
1898 let leaf_prefix = LeafData {
1900 key_path: kp_prefix,
1901 value_hash: [1; 32],
1902 };
1903
1904 let leaf_longer = LeafData {
1905 key_path: kp_longer,
1906 value_hash: [2; 32],
1907 };
1908
1909 let node_prefix = Blake3Hasher::hash_leaf(&leaf_prefix);
1910 let node_longer = Blake3Hasher::hash_leaf(&leaf_longer);
1911
1912 let vmp_prefix = VerifiedMultiPath {
1914 terminal: PathProofTerminal::Leaf(leaf_prefix.clone()),
1915 depth: bits_prefix.len(),
1916 unique_siblings: 0..0, };
1918
1919 let vmp_longer = VerifiedMultiPath {
1920 terminal: PathProofTerminal::Leaf(leaf_longer.clone()),
1921 depth: bits_longer.len(),
1922 unique_siblings: 0..0, };
1924
1925 let plausible_root = Blake3Hasher::hash_internal(&InternalData {
1929 left: node_prefix,
1930 right: node_longer,
1931 });
1932
1933 let verified_proof = VerifiedMultiProof {
1934 inner: vec![vmp_prefix, vmp_longer],
1935
1936 bisections: Vec::new(), siblings: Vec::new(), root: plausible_root,
1941 };
1942
1943 let mut key_op1_bits = bits_prefix.clone();
1945
1946 key_op1_bits.push(false); let key_op1 = key_with_prefix(key_op1_bits.iter().by_vals());
1949
1950 let mut key_op2_bits = bits_longer.clone();
1951
1952 key_op2_bits.push(true); let key_op2 = key_with_prefix(key_op2_bits.iter().by_vals());
1955
1956 let ops = vec![
1957 (key_op1, Some(ValueHash::default())), (key_op2, Some(ValueHash::default())), ];
1960
1961 assert!(ops[0].0 < ops[1].0);
1963
1964 match verify_update::<Blake3Hasher>(&verified_proof, ops).unwrap_err() {
1966 MultiVerifyUpdateError::PathPrefixOfAnother => (),
1967 _ => panic!(),
1968 }
1969 }
1970}