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)]
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)]
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 false,
635 );
636 self.bisection_stack.push(next_bisection.clone());
637 }
638
639 let terminal_n = next_terminal.unique_siblings.end - next_terminal.unique_siblings.start;
640 self.extend(
641 next_terminal.depth - terminal_n + 1,
642 next_terminal.unique_siblings.end,
643 &proof.siblings,
644 true,
645 );
646 self.terminal_index += 1;
647 }
648
649 fn pop_to(&mut self, depth: usize) {
650 while self
651 .bisection_stack
652 .last()
653 .map_or(false, |b| b.start_depth >= depth)
654 {
655 let _ = self.bisection_stack.pop();
656 }
657
658 while self.stack.last().map_or(false, |(d, _)| *d >= depth) {
659 let _ = self.stack.pop();
660 }
661 }
662
663 fn extend(&mut self, start_depth: usize, end: usize, siblings: &[Node], reverse: bool) {
664 if reverse {
665 for (i, sibling) in siblings[self.taken_siblings..end].iter().rev().enumerate() {
666 self.stack.push((start_depth + i, *sibling))
667 }
668 } else {
669 for (i, sibling) in siblings[self.taken_siblings..end].iter().enumerate() {
670 self.stack.push((start_depth + i, *sibling))
671 }
672 }
673
674 self.taken_siblings = end;
675 }
676
677 fn pop_if_at_depth(&mut self, depth: usize) -> Option<Node> {
678 if self.stack.last().map_or(false, |(d, _)| *d == depth) {
679 self.stack.pop().map(|(_, n)| n)
680 } else {
681 None
682 }
683 }
684}
685
686pub fn verify_update<H: NodeHasher>(
697 proof: &VerifiedMultiProof,
698 ops: Vec<(KeyPath, Option<ValueHash>)>,
699) -> Result<Node, MultiVerifyUpdateError> {
700 if ops.is_empty() {
701 return Ok(proof.root);
702 }
703
704 let mut pending_siblings: Vec<(Node, usize)> = Vec::new();
706
707 let mut last_key = None;
708 let mut last_terminal_index = None;
709 let mut next_pending_terminal_index = None;
710
711 let mut working_ops = Vec::new();
712
713 let mut common_siblings = CommonSiblings::new();
714 let ops_len = ops.len();
715
716 for (i, (key, op)) in ops.into_iter().chain(Some(([0u8; 32], None))).enumerate() {
718 let is_last = i == ops_len;
719
720 if is_last {
721 let updated_terminal_index = last_terminal_index.unwrap_or(0);
722 let start = next_pending_terminal_index.unwrap_or(0);
723
724 for terminal_index in start..proof.inner.len() {
726 let next = if terminal_index == proof.inner.len() - 1 {
727 None
728 } else {
729 Some(terminal_index + 1)
730 };
731
732 let terminal = &proof.inner[terminal_index];
733 let next_terminal = next.map(|n| &proof.inner[n]);
734
735 let ops = if terminal_index == updated_terminal_index {
736 &working_ops[..]
737 } else {
738 &[]
739 };
740
741 common_siblings.advance(&proof);
742 hash_and_compact_terminal::<H>(
743 &mut pending_siblings,
744 terminal,
745 next_terminal,
746 &mut common_siblings,
747 ops,
748 )?;
749 }
750 } else {
751 if let Some(last_key) = last_key {
753 if key <= last_key {
754 return Err(MultiVerifyUpdateError::OpsOutOfOrder);
755 }
756 }
757 last_key = Some(key);
758
759 let mut next_terminal_index = last_terminal_index.unwrap_or(0);
761 if proof.inner.len() <= next_terminal_index {
762 return Err(MultiVerifyUpdateError::OpOutOfScope);
763 }
764
765 while !terminal_contains(&proof.inner[next_terminal_index], &key) {
766 next_terminal_index += 1;
767 if proof.inner.len() <= next_terminal_index {
768 return Err(MultiVerifyUpdateError::OpOutOfScope);
769 }
770 }
771
772 if last_terminal_index.map_or(true, |x| x == next_terminal_index) {
774 last_terminal_index = Some(next_terminal_index);
775 working_ops.push((key, op));
776 continue;
777 }
778
779 let updated_index = last_terminal_index.unwrap();
781 last_terminal_index = Some(next_terminal_index);
782
783 let start = next_pending_terminal_index.unwrap_or(0);
785
786 for terminal_index in start..updated_index {
787 let terminal = &proof.inner[terminal_index];
788 let next_terminal = Some(&proof.inner[terminal_index + 1]);
789
790 common_siblings.advance(&proof);
791 hash_and_compact_terminal::<H>(
792 &mut pending_siblings,
793 terminal,
794 next_terminal,
795 &mut common_siblings,
796 &[],
797 )?;
798 }
799
800 let ops = core::mem::replace(&mut working_ops, Vec::new());
802 working_ops.push((key, op));
803
804 let terminal = &proof.inner[updated_index];
805 let next_terminal = proof.inner.get(updated_index + 1);
806 common_siblings.advance(&proof);
807
808 hash_and_compact_terminal::<H>(
809 &mut pending_siblings,
810 terminal,
811 next_terminal,
812 &mut common_siblings,
813 &ops,
814 )?;
815
816 next_pending_terminal_index = Some(updated_index + 1);
817 };
818 }
819
820 Ok(pending_siblings.pop().map(|n| n.0).unwrap_or(proof.root))
822}
823
824fn hash_and_compact_terminal<H: NodeHasher>(
825 pending_siblings: &mut Vec<(Node, usize)>,
826 terminal: &VerifiedMultiPath,
827 next_terminal: Option<&VerifiedMultiPath>,
828 common_siblings: &mut CommonSiblings,
829 ops: &[(KeyPath, Option<ValueHash>)],
830) -> Result<(), MultiVerifyUpdateError> {
831 let leaf = terminal.terminal.as_leaf_option();
832 let skip = terminal.depth;
833
834 let up_layers = if let Some(next_terminal) = next_terminal {
835 let n = shared_bits(terminal.terminal.path(), next_terminal.terminal.path());
836
837 if n == skip {
841 return Err(MultiVerifyUpdateError::PathPrefixOfAnother);
842 }
843
844 skip - (n + 1)
847 } else {
848 skip };
850
851 let ops = crate::update::leaf_ops_spliced(leaf, &ops);
852 let sub_root = crate::update::build_trie::<H>(skip, ops, |_| {});
853
854 let mut cur_node = sub_root;
855 let mut cur_layer = skip;
856 let end_layer = skip - up_layers;
857
858 for bit in terminal.terminal.path()[..terminal.depth]
862 .iter()
863 .by_vals()
864 .rev()
865 .take(up_layers)
866 {
867 let sibling = if pending_siblings.last().map_or(false, |p| p.1 == cur_layer) {
868 let _ = common_siblings.pop_if_at_depth(cur_layer);
870 pending_siblings.pop().unwrap().0
872 } else {
873 common_siblings.pop_if_at_depth(cur_layer).unwrap()
877 };
878
879 match (NodeKind::of::<H>(&cur_node), NodeKind::of::<H>(&sibling)) {
880 (NodeKind::Terminator, NodeKind::Terminator) => {}
881 (NodeKind::Leaf, NodeKind::Terminator) => {}
882 (NodeKind::Terminator, NodeKind::Leaf) => {
883 cur_node = sibling;
885 }
886 _ => {
887 let node_data = if bit {
889 InternalData {
890 left: sibling,
891 right: cur_node,
892 }
893 } else {
894 InternalData {
895 left: cur_node,
896 right: sibling,
897 }
898 };
899 cur_node = H::hash_internal(&node_data);
900 }
901 }
902
903 cur_layer -= 1;
904 }
905
906 pending_siblings.push((cur_node, end_layer));
907 Ok(())
908}
909
910#[cfg(test)]
911mod tests {
912 use super::{verify, verify_update, MultiProof};
913
914 use crate::proof::multi_proof::{
915 MultiVerifyUpdateError, VerifiedMultiPath, VerifiedMultiProof,
916 };
917 use crate::{
918 hasher::{Blake3Hasher, NodeHasher},
919 proof::{PathProof, PathProofTerminal},
920 trie::{InternalData, KeyPath, LeafData, ValueHash, TERMINATOR},
921 trie_pos::TriePosition,
922 update::build_trie,
923 };
924 use bitvec::prelude::*;
925
926 #[test]
927 pub fn test_multiproof_creation_single_path_proof() {
928 let mut key_path = [0; 32];
929 key_path[0] = 0b10000000;
930 let sibling1 = [1; 32];
931 let sibling2 = [2; 32];
932 let path_proof = PathProof {
933 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
934 key_path, 256,
935 )),
936 siblings: vec![sibling1, sibling2],
937 };
938
939 let multi_proof = MultiProof::from_path_proofs(vec![path_proof]);
940 assert_eq!(multi_proof.paths.len(), 1);
941 assert_eq!(
942 multi_proof.paths[0].terminal,
943 PathProofTerminal::Terminator(TriePosition::from_path_and_depth(key_path, 256))
944 );
945 assert_eq!(multi_proof.paths[0].depth, 2);
946 assert_eq!(multi_proof.siblings.len(), 2);
947 assert_eq!(multi_proof.siblings, vec![sibling1, sibling2]);
948 }
949
950 #[test]
951 pub fn test_multiproof_creation_two_path_proofs() {
952 let mut key_path_1 = [0; 32];
953 key_path_1[0] = 0b00000000;
954
955 let mut key_path_2 = [0; 32];
956 key_path_2[0] = 0b00111000;
957
958 let sibling1 = [1; 32];
959 let sibling2 = [2; 32];
960 let sibling3 = [3; 32];
961 let sibling4 = [4; 32];
962 let sibling5 = [5; 32];
963 let sibling6 = [6; 32];
964
965 let sibling_x = [b'x'; 32];
966
967 let path_proof_1 = PathProof {
968 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
969 key_path_1, 256,
970 )),
971 siblings: vec![sibling1, sibling2, sibling_x, sibling3, sibling4],
972 };
973 let path_proof_2 = PathProof {
974 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
975 key_path_2, 256,
976 )),
977 siblings: vec![sibling1, sibling2, sibling_x, sibling5, sibling6],
978 };
979
980 let multi_proof = MultiProof::from_path_proofs(vec![path_proof_1, path_proof_2]);
981
982 assert_eq!(multi_proof.paths.len(), 2);
983 assert_eq!(multi_proof.siblings.len(), 6);
984
985 assert_eq!(
986 multi_proof.paths[0].terminal,
987 PathProofTerminal::Terminator(TriePosition::from_path_and_depth(key_path_1, 256))
988 );
989 assert_eq!(
990 multi_proof.paths[1].terminal,
991 PathProofTerminal::Terminator(TriePosition::from_path_and_depth(key_path_2, 256))
992 );
993
994 assert_eq!(multi_proof.paths[0].depth, 5);
995 assert_eq!(multi_proof.paths[1].depth, 5);
996
997 assert_eq!(
998 multi_proof.siblings,
999 vec![sibling1, sibling2, sibling3, sibling4, sibling5, sibling6]
1000 );
1001 }
1002
1003 #[test]
1004 pub fn test_multiproof_creation_two_path_proofs_256_depth() {
1005 let mut key_path_1 = [0; 32];
1006 key_path_1[31] = 0b00000000;
1007
1008 let mut key_path_2 = [0; 32];
1009 key_path_2[31] = 0b00000001;
1010
1011 let mut siblings_1: Vec<[u8; 32]> = (0..255).map(|i| [i; 32]).collect();
1012 let mut siblings_2 = siblings_1.clone();
1013 siblings_1.push([b'2'; 32]);
1014 siblings_2.push([b'1'; 32]);
1015
1016 let path_proof_1 = PathProof {
1017 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
1018 key_path_1, 256,
1019 )),
1020 siblings: siblings_1.clone(),
1021 };
1022 let path_proof_2 = PathProof {
1023 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
1024 key_path_2, 256,
1025 )),
1026 siblings: siblings_2,
1027 };
1028
1029 let multi_proof = MultiProof::from_path_proofs(vec![path_proof_1, path_proof_2]);
1030
1031 assert_eq!(multi_proof.paths.len(), 2);
1032 assert_eq!(multi_proof.siblings.len(), 255);
1033
1034 assert_eq!(
1035 multi_proof.paths[0].terminal,
1036 PathProofTerminal::Terminator(TriePosition::from_path_and_depth(key_path_1, 256))
1037 );
1038 assert_eq!(
1039 multi_proof.paths[1].terminal,
1040 PathProofTerminal::Terminator(TriePosition::from_path_and_depth(key_path_2, 256))
1041 );
1042
1043 assert_eq!(multi_proof.paths[0].depth, 256);
1044 assert_eq!(multi_proof.paths[1].depth, 256);
1045
1046 siblings_1.pop();
1047 assert_eq!(multi_proof.siblings, siblings_1);
1048 }
1049
1050 #[test]
1051 pub fn test_multiproof_creation_multiple_path_proofs() {
1052 let mut key_path_1 = [0; 32];
1053 key_path_1[0] = 0b00000000;
1054
1055 let mut key_path_2 = [0; 32];
1056 key_path_2[0] = 0b01000000;
1057
1058 let mut key_path_3 = [0; 32];
1059 key_path_3[0] = 0b01001100;
1060
1061 let mut key_path_4 = [0; 32];
1062 key_path_4[0] = 0b11101100;
1063
1064 let mut key_path_5 = [0; 32];
1065 key_path_5[0] = 0b11110100;
1066
1067 let mut key_path_6 = [0; 32];
1068 key_path_6[0] = 0b11111000;
1069
1070 let sibling1 = [1; 32];
1071 let sibling2 = [2; 32];
1072 let sibling3 = [3; 32];
1073 let sibling4 = [4; 32];
1074 let sibling5 = [5; 32];
1075 let sibling6 = [6; 32];
1076 let sibling7 = [7; 32];
1077 let sibling8 = [8; 32];
1078 let sibling9 = [9; 32];
1079 let sibling10 = [10; 32];
1080 let sibling11 = [11; 32];
1081 let sibling12 = [12; 32];
1082 let sibling13 = [13; 32];
1083 let sibling14 = [14; 32];
1084 let sibling15 = [15; 32];
1085 let sibling16 = [16; 32];
1086 let sibling17 = [17; 32];
1087 let sibling18 = [18; 32];
1088 let sibling19 = [19; 32];
1089
1090 let path_proof_1 = PathProof {
1091 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
1092 key_path_1, 256,
1093 )),
1094 siblings: vec![sibling1, sibling2],
1095 };
1096
1097 let path_proof_2 = PathProof {
1098 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
1099 key_path_2, 256,
1100 )),
1101 siblings: vec![sibling1, sibling3, sibling4, sibling5, sibling6, sibling7],
1102 };
1103
1104 let path_proof_3 = PathProof {
1105 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
1106 key_path_3, 256,
1107 )),
1108 siblings: vec![sibling1, sibling3, sibling4, sibling5, sibling8, sibling9],
1109 };
1110
1111 let path_proof_4 = PathProof {
1112 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
1113 key_path_4, 256,
1114 )),
1115 siblings: vec![
1116 sibling10, sibling11, sibling12, sibling13, sibling14, sibling15,
1117 ],
1118 };
1119
1120 let path_proof_5 = PathProof {
1121 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
1122 key_path_5, 256,
1123 )),
1124 siblings: vec![
1125 sibling10, sibling11, sibling12, sibling16, sibling17, sibling18,
1126 ],
1127 };
1128
1129 let path_proof_6 = PathProof {
1130 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
1131 key_path_6, 256,
1132 )),
1133 siblings: vec![sibling10, sibling11, sibling12, sibling16, sibling19],
1134 };
1135
1136 let multi_proof = MultiProof::from_path_proofs(vec![
1137 path_proof_1,
1138 path_proof_2,
1139 path_proof_3,
1140 path_proof_4,
1141 path_proof_5,
1142 path_proof_6,
1143 ]);
1144
1145 assert_eq!(multi_proof.paths.len(), 6);
1146 assert_eq!(multi_proof.siblings.len(), 9);
1147
1148 assert_eq!(
1149 multi_proof.paths[0].terminal,
1150 PathProofTerminal::Terminator(TriePosition::from_path_and_depth(key_path_1, 256))
1151 );
1152 assert_eq!(
1153 multi_proof.paths[1].terminal,
1154 PathProofTerminal::Terminator(TriePosition::from_path_and_depth(key_path_2, 256))
1155 );
1156 assert_eq!(
1157 multi_proof.paths[2].terminal,
1158 PathProofTerminal::Terminator(TriePosition::from_path_and_depth(key_path_3, 256))
1159 );
1160 assert_eq!(
1161 multi_proof.paths[3].terminal,
1162 PathProofTerminal::Terminator(TriePosition::from_path_and_depth(key_path_4, 256))
1163 );
1164 assert_eq!(
1165 multi_proof.paths[4].terminal,
1166 PathProofTerminal::Terminator(TriePosition::from_path_and_depth(key_path_5, 256))
1167 );
1168 assert_eq!(
1169 multi_proof.paths[5].terminal,
1170 PathProofTerminal::Terminator(TriePosition::from_path_and_depth(key_path_6, 256))
1171 );
1172
1173 assert_eq!(multi_proof.paths[0].depth, 2);
1174 assert_eq!(multi_proof.paths[1].depth, 6);
1175 assert_eq!(multi_proof.paths[2].depth, 6);
1176 assert_eq!(multi_proof.paths[3].depth, 6);
1177 assert_eq!(multi_proof.paths[4].depth, 6);
1178 assert_eq!(multi_proof.paths[5].depth, 5);
1179
1180 assert_eq!(
1181 multi_proof.siblings,
1182 vec![
1183 sibling4, sibling5, sibling7, sibling9, sibling11, sibling12, sibling14, sibling15,
1184 sibling18
1185 ]
1186 );
1187 }
1188
1189 #[test]
1190 pub fn test_multiproof_creation_ext_siblings_order() {
1191 let mut key_path_0 = [0; 32];
1192 key_path_0[0] = 0b00001000;
1193
1194 let mut key_path_1 = [0; 32];
1195 key_path_1[0] = 0b00010000;
1196
1197 let mut key_path_2 = [0; 32];
1198 key_path_2[0] = 0b10000000;
1199
1200 let mut key_path_3 = [0; 32];
1201 key_path_3[0] = 0b10000010;
1202
1203 let mut key_path_4 = [0; 32];
1204 key_path_4[0] = 0b10010001;
1205
1206 let mut key_path_5 = [0; 32];
1207 key_path_5[0] = 0b10010011;
1208
1209 let sibling1 = [1; 32];
1210 let sibling2 = [2; 32];
1211 let sibling3 = [3; 32];
1212 let sibling4 = [4; 32];
1213 let sibling5 = [5; 32];
1214 let sibling6 = [6; 32];
1215 let sibling7 = [7; 32];
1216 let sibling8 = [8; 32];
1217 let sibling9 = [9; 32];
1218 let sibling10 = [10; 32];
1219 let sibling11 = [11; 32];
1220 let sibling12 = [12; 32];
1221 let sibling13 = [13; 32];
1222 let sibling14 = [14; 32];
1223 let sibling15 = [15; 32];
1224 let sibling16 = [16; 32];
1225 let sibling17 = [17; 32];
1226 let sibling18 = [18; 32];
1227 let sibling19 = [19; 32];
1228 let sibling20 = [20; 32];
1229 let sibling21 = [21; 32];
1230 let sibling22 = [22; 32];
1231 let sibling23 = [23; 32];
1232 let sibling24 = [24; 32];
1233
1234 let path_proof_0 = PathProof {
1235 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
1236 key_path_0, 256,
1237 )),
1238 siblings: vec![sibling1, sibling2, sibling3, sibling4, sibling5],
1239 };
1240
1241 let path_proof_1 = PathProof {
1242 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
1243 key_path_1, 256,
1244 )),
1245 siblings: vec![sibling1, sibling2, sibling3, sibling6, sibling7],
1246 };
1247
1248 let path_proof_2 = PathProof {
1249 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
1250 key_path_2, 256,
1251 )),
1252 siblings: vec![
1253 sibling8, sibling9, sibling10, sibling11, sibling12, sibling13, sibling14,
1254 sibling15,
1255 ],
1256 };
1257 let path_proof_3 = PathProof {
1258 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
1259 key_path_3, 256,
1260 )),
1261 siblings: vec![
1262 sibling8, sibling9, sibling10, sibling11, sibling12, sibling13, sibling16,
1263 sibling17,
1264 ],
1265 };
1266
1267 let path_proof_4 = PathProof {
1268 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
1269 key_path_4, 256,
1270 )),
1271 siblings: vec![
1272 sibling8, sibling9, sibling10, sibling18, sibling19, sibling20, sibling21,
1273 sibling22,
1274 ],
1275 };
1276
1277 let path_proof_5 = PathProof {
1278 terminal: PathProofTerminal::Terminator(TriePosition::from_path_and_depth(
1279 key_path_5, 256,
1280 )),
1281 siblings: vec![
1282 sibling8, sibling9, sibling10, sibling18, sibling19, sibling20, sibling23,
1283 sibling24,
1284 ],
1285 };
1286
1287 let multi_proof = MultiProof::from_path_proofs(vec![
1288 path_proof_0,
1289 path_proof_1,
1290 path_proof_2,
1291 path_proof_3,
1292 path_proof_4,
1293 path_proof_5,
1294 ]);
1295
1296 assert_eq!(multi_proof.paths.len(), 6);
1297 assert_eq!(multi_proof.siblings.len(), 14);
1298
1299 assert_eq!(
1300 multi_proof.siblings,
1301 vec![
1302 sibling2, sibling3, sibling5, sibling7, sibling9, sibling10, sibling12, sibling13,
1303 sibling15, sibling17, sibling19, sibling20, sibling22, sibling24
1304 ]
1305 );
1306 }
1307
1308 #[test]
1309 fn multi_proof_failure_empty_witness() {
1310 let multi_proof = MultiProof::from_path_proofs(Vec::new());
1311
1312 let _verified_multi_proof = verify::<Blake3Hasher>(&multi_proof, TERMINATOR).unwrap();
1313 }
1314
1315 #[test]
1316 fn multi_proof_verify_empty() {
1317 let multi_proof = MultiProof::from_path_proofs(Vec::new());
1318
1319 let verified_multi_proof = verify::<Blake3Hasher>(&multi_proof, TERMINATOR).unwrap();
1320
1321 assert_eq!(
1322 verify_update::<Blake3Hasher>(&verified_multi_proof, Vec::new()).unwrap(),
1323 TERMINATOR,
1324 );
1325 }
1326
1327 #[test]
1328 fn multi_proof_verify_empty_with_provided_updates() {
1329 let multi_proof = MultiProof::from_path_proofs(Vec::new());
1330
1331 let verified_multi_proof = verify::<Blake3Hasher>(&multi_proof, TERMINATOR).unwrap();
1332
1333 let mut key_path_0 = [0; 32];
1334 key_path_0[0] = 0b00001000;
1335
1336 let mut key_path_1 = [0; 32];
1337 key_path_1[0] = 0b00010000;
1338
1339 let mut key_path_2 = [0; 32];
1340 key_path_2[0] = 0b10000000;
1341
1342 let ops = vec![
1343 (key_path_0, Some([1; 32])),
1344 (key_path_1, Some([1; 32])),
1345 (key_path_2, Some([1; 32])),
1346 ];
1347
1348 let expected_root = build_trie::<Blake3Hasher>(
1349 0,
1350 ops.clone().into_iter().map(|(k, v)| (k, v.unwrap())),
1351 |_| {},
1352 );
1353
1354 assert_eq!(
1355 verify_update::<Blake3Hasher>(&verified_multi_proof, ops).unwrap(),
1356 expected_root,
1357 );
1358 }
1359
1360 #[test]
1361 pub fn test_verify_multiproof_two_leafs() {
1362 let mut key_path_0 = [0; 32];
1369 key_path_0[0] = 0b00000000;
1370
1371 let mut key_path_1 = [0; 32];
1372 key_path_1[0] = 0b10000000;
1373
1374 let mut key_path_2 = [0; 32];
1375 key_path_2[0] = 0b01000000;
1376
1377 let leaf_0 = LeafData {
1378 key_path: key_path_0,
1379 value_hash: [0; 32],
1380 };
1381
1382 let leaf_1 = LeafData {
1383 key_path: key_path_1,
1384 value_hash: [1; 32],
1385 };
1386
1387 let leaf_2 = LeafData {
1388 key_path: key_path_2,
1389 value_hash: [2; 32],
1390 };
1391
1392 let v0 = Blake3Hasher::hash_leaf(&leaf_0);
1394 let v1 = Blake3Hasher::hash_leaf(&leaf_1);
1395 let v2 = Blake3Hasher::hash_leaf(&leaf_2);
1396 let s3 = Blake3Hasher::hash_internal(&InternalData {
1397 left: v0.clone(),
1398 right: v2,
1399 });
1400 let root = Blake3Hasher::hash_internal(&InternalData {
1401 left: s3,
1402 right: v1,
1403 });
1404
1405 let path_proof_0 = PathProof {
1406 terminal: PathProofTerminal::Leaf(leaf_0.clone()),
1407 siblings: vec![v1, v2],
1408 };
1409 let path_proof_1 = PathProof {
1410 terminal: PathProofTerminal::Leaf(leaf_1.clone()),
1411 siblings: vec![s3],
1412 };
1413
1414 let multi_proof =
1415 MultiProof::from_path_proofs(vec![path_proof_0.clone(), path_proof_1.clone()]);
1416
1417 let verified = verify::<Blake3Hasher>(&multi_proof, root).unwrap();
1418
1419 assert!(verified.confirm_value(&leaf_0).unwrap());
1420 assert!(verified.confirm_value(&leaf_1).unwrap());
1421 }
1422
1423 #[test]
1424 fn multi_proof_verify_2_leaves_with_provided_updates() {
1425 let mut key_path_0 = [0; 32];
1432 key_path_0[0] = 0b00000000;
1433
1434 let mut key_path_1 = [0; 32];
1435 key_path_1[0] = 0b10000000;
1436
1437 let mut key_path_2 = [0; 32];
1438 key_path_2[0] = 0b01000000;
1439
1440 let leaf_0 = LeafData {
1441 key_path: key_path_0,
1442 value_hash: [0; 32],
1443 };
1444
1445 let leaf_1 = LeafData {
1446 key_path: key_path_1,
1447 value_hash: [1; 32],
1448 };
1449
1450 let leaf_2 = LeafData {
1451 key_path: key_path_2,
1452 value_hash: [2; 32],
1453 };
1454
1455 let v0 = Blake3Hasher::hash_leaf(&leaf_0);
1457 let v1 = Blake3Hasher::hash_leaf(&leaf_1);
1458 let v2 = Blake3Hasher::hash_leaf(&leaf_2);
1459 let s3 = Blake3Hasher::hash_internal(&InternalData {
1460 left: v0.clone(),
1461 right: v2,
1462 });
1463 let root = Blake3Hasher::hash_internal(&InternalData {
1464 left: s3,
1465 right: v1,
1466 });
1467
1468 let path_proof_0 = PathProof {
1469 terminal: PathProofTerminal::Leaf(leaf_0.clone()),
1470 siblings: vec![v1, v2],
1471 };
1472 let path_proof_1 = PathProof {
1473 terminal: PathProofTerminal::Leaf(leaf_1.clone()),
1474 siblings: vec![s3],
1475 };
1476
1477 let multi_proof =
1478 MultiProof::from_path_proofs(vec![path_proof_0.clone(), path_proof_1.clone()]);
1479
1480 let verified = verify::<Blake3Hasher>(&multi_proof, root).unwrap();
1481
1482 let mut key_path_3 = key_path_1;
1483 key_path_3[0] = 0b10100000;
1484
1485 let mut key_path_4 = key_path_0;
1486 key_path_4[0] = 0b00000100;
1487
1488 let ops = vec![
1489 (key_path_0, Some([2; 32])),
1490 (key_path_4, Some([1; 32])),
1491 (key_path_1, None),
1492 (key_path_3, Some([1; 32])),
1493 ];
1494
1495 let final_state = vec![
1496 (key_path_0, [2; 32]),
1497 (key_path_4, [1; 32]),
1498 (key_path_2, [2; 32]),
1499 (key_path_3, [1; 32]),
1500 ];
1501
1502 let expected_root = build_trie::<Blake3Hasher>(0, final_state, |_| {});
1503
1504 assert_eq!(
1505 verify_update::<Blake3Hasher>(&verified, ops).unwrap(),
1506 expected_root,
1507 );
1508 }
1509
1510 #[test]
1511 fn multi_proof_verify_4_leaves_with_long_bisections() {
1512 let make_leaf = |key_path, value_byte| {
1523 let leaf_data = LeafData {
1524 key_path,
1525 value_hash: [value_byte; 32],
1526 };
1527
1528 let hash = Blake3Hasher::hash_leaf(&leaf_data);
1529 (leaf_data, hash)
1530 };
1531 let internal_hash =
1532 |left, right| Blake3Hasher::hash_internal(&InternalData { left, right });
1533
1534 let mut key_path_0 = [0; 32];
1535 key_path_0[0] = 0b00000000;
1536
1537 let mut key_path_1 = [0; 32];
1538 key_path_1[0] = 0b00000001;
1539
1540 let mut key_path_2 = [0; 32];
1541 key_path_2[0] = 0b00001000;
1542
1543 let mut key_path_3 = [0; 32];
1544 key_path_3[0] = 0b00001001;
1545
1546 let (leaf_a, l8a) = make_leaf(key_path_0, 1);
1547 let (leaf_b, l8b) = make_leaf(key_path_1, 1);
1548 let (leaf_c, l8c) = make_leaf(key_path_2, 1);
1549 let (leaf_d, l8d) = make_leaf(key_path_3, 1);
1550
1551 let i7a = internal_hash(l8a, l8b);
1552 let i7b = internal_hash(l8c, l8d);
1553
1554 let i6a = internal_hash(i7a, [7; 32]);
1555 let i6b = internal_hash(i7b, [7; 32]);
1556
1557 let i5a = internal_hash(i6a, [6; 32]);
1558 let i5b = internal_hash(i6b, [6; 32]);
1559
1560 let i4 = internal_hash(i5a, i5b);
1561 let i3 = internal_hash(i4, [4; 32]);
1562 let i2 = internal_hash(i3, [3; 32]);
1563 let i1 = internal_hash(i2, [2; 32]);
1564 let root = internal_hash(i1, [1; 32]);
1565
1566 let path_proof_a = PathProof {
1567 terminal: PathProofTerminal::Leaf(leaf_a.clone()),
1568 siblings: vec![
1569 [1; 32], [2; 32], [3; 32], [4; 32], i5b, [6; 32], [7; 32], l8b,
1570 ],
1571 };
1572 let path_proof_b = PathProof {
1573 terminal: PathProofTerminal::Leaf(leaf_b.clone()),
1574 siblings: vec![
1575 [1; 32], [2; 32], [3; 32], [4; 32], i5b, [6; 32], [7; 32], l8a,
1576 ],
1577 };
1578 let path_proof_c = PathProof {
1579 terminal: PathProofTerminal::Leaf(leaf_c.clone()),
1580 siblings: vec![
1581 [1; 32], [2; 32], [3; 32], [4; 32], i5a, [6; 32], [7; 32], l8d,
1582 ],
1583 };
1584 let path_proof_d = PathProof {
1585 terminal: PathProofTerminal::Leaf(leaf_d.clone()),
1586 siblings: vec![
1587 [1; 32], [2; 32], [3; 32], [4; 32], i5a, [6; 32], [7; 32], l8c,
1588 ],
1589 };
1590
1591 let multi_proof = MultiProof::from_path_proofs(vec![
1592 path_proof_a.clone(),
1593 path_proof_b.clone(),
1594 path_proof_c.clone(),
1595 path_proof_d.clone(),
1596 ]);
1597
1598 let verified = verify::<Blake3Hasher>(&multi_proof, root).unwrap();
1599
1600 let ops = vec![(key_path_0, Some([69; 32])), (key_path_3, Some([69; 32]))];
1601
1602 let (_, l8a) = make_leaf(key_path_0, 69);
1603 let (_, l8b) = make_leaf(key_path_1, 1);
1604 let (_, l8c) = make_leaf(key_path_2, 1);
1605 let (_, l8d) = make_leaf(key_path_3, 69);
1606
1607 let i7a = internal_hash(l8a, l8b);
1608 let i7b = internal_hash(l8c, l8d);
1609
1610 let i6a = internal_hash(i7a, [7; 32]);
1611 let i6b = internal_hash(i7b, [7; 32]);
1612
1613 let i5a = internal_hash(i6a, [6; 32]);
1614 let i5b = internal_hash(i6b, [6; 32]);
1615
1616 let i4 = internal_hash(i5a, i5b);
1617
1618 let i3 = internal_hash(i4, [4; 32]);
1619 let i2 = internal_hash(i3, [3; 32]);
1620 let i1 = internal_hash(i2, [2; 32]);
1621 let post_root = internal_hash(i1, [1; 32]);
1622
1623 assert_eq!(
1624 verify_update::<Blake3Hasher>(&verified, ops).unwrap(),
1625 post_root,
1626 );
1627 }
1628
1629 #[test]
1630 pub fn test_verify_multiproof_multiple_leafs() {
1631 let path = |byte| [byte; 32];
1642
1643 let k0 = path(0b00000000);
1644 let k1 = path(0b00011000);
1645 let k2 = path(0b00101101);
1646 let k3 = path(0b10101010);
1647 let k4 = path(0b11000011);
1648 let k5 = path(0b11100010);
1649
1650 let make_leaf = |key_path| {
1651 let leaf_data = LeafData {
1652 key_path,
1653 value_hash: [key_path[0]; 32],
1654 };
1655
1656 let hash = Blake3Hasher::hash_leaf(&leaf_data);
1657 (leaf_data, hash)
1658 };
1659 let internal_hash =
1660 |left, right| Blake3Hasher::hash_internal(&InternalData { left, right });
1661
1662 let (l0, v0) = make_leaf(k0);
1663 let (l1, v1) = make_leaf(k1);
1664 let (l2, v2) = make_leaf(k2);
1665 let (l3, v3) = make_leaf(k3);
1666 let (l4, v4) = make_leaf(k4);
1667 let (l5, v5) = make_leaf(k5);
1668
1669 let i1 = internal_hash(v0, v1);
1670 let i2 = internal_hash(i1, v2);
1671 let i3 = internal_hash(i2, TERMINATOR);
1672
1673 let i4 = internal_hash(v4, TERMINATOR);
1674 let i5 = internal_hash(i4, v5);
1675 let i6 = internal_hash(v3, i5);
1676
1677 let root = internal_hash(i3, i6);
1678
1679 let leaf_proof = |leaf, siblings| PathProof {
1680 terminal: PathProofTerminal::Leaf(leaf),
1681 siblings,
1682 };
1683
1684 let path_proof_0 = leaf_proof(l0.clone(), vec![i6, TERMINATOR, v2, v1]);
1685 let path_proof_1 = leaf_proof(l1.clone(), vec![i6, TERMINATOR, v2, v0]);
1686 let path_proof_2 = leaf_proof(l2.clone(), vec![i6, TERMINATOR, i1]);
1687 let path_proof_3 = leaf_proof(l3.clone(), vec![i3, i5]);
1688 let path_proof_4 = leaf_proof(l4.clone(), vec![i3, v3, v5, TERMINATOR]);
1689 let path_proof_5 = leaf_proof(l5.clone(), vec![i3, v3, i4]);
1690
1691 let multi_proof = MultiProof::from_path_proofs(vec![
1692 path_proof_0.clone(),
1693 path_proof_1.clone(),
1694 path_proof_2.clone(),
1695 path_proof_3.clone(),
1696 path_proof_4.clone(),
1697 path_proof_5.clone(),
1698 ]);
1699
1700 let verified = verify::<Blake3Hasher>(&multi_proof, root).unwrap();
1701 assert!(verified.confirm_value(&l0).unwrap());
1702 assert!(verified.confirm_value(&l1).unwrap());
1703 assert!(verified.confirm_value(&l2).unwrap());
1704 assert!(verified.confirm_value(&l3).unwrap());
1705 assert!(verified.confirm_value(&l4).unwrap());
1706 assert!(verified.confirm_value(&l5).unwrap());
1707 }
1708
1709 #[test]
1710 pub fn test_verify_multiproof_siblings_structure() {
1711 let path = |byte| [byte; 32];
1730
1731 let k0 = path(0b00000000);
1732 let k1 = path(0b10000000);
1733 let k2 = path(0b10000001);
1734 let k3 = path(0b10011100);
1735 let k4 = path(0b10011110);
1736
1737 let make_leaf = |key_path| {
1738 let leaf_data = LeafData {
1739 key_path,
1740 value_hash: [key_path[0]; 32],
1741 };
1742
1743 let hash = Blake3Hasher::hash_leaf(&leaf_data);
1744 (leaf_data, hash)
1745 };
1746 let internal_hash =
1747 |left, right| Blake3Hasher::hash_internal(&InternalData { left, right });
1748
1749 let (_l0, v0) = make_leaf(k0);
1750 let (l1, v1) = make_leaf(k1);
1751 let (l2, v2) = make_leaf(k2);
1752 let (l3, v3) = make_leaf(k3);
1753 let (l4, v4) = make_leaf(k4);
1754
1755 let e1 = [1; 32];
1756 let e2 = [2; 32];
1757 let e3 = [3; 32];
1758 let e4 = [4; 32];
1759 let e5 = [5; 32];
1760 let e6 = [6; 32];
1761 let e7 = TERMINATOR;
1762
1763 let i1 = internal_hash(v1, v2);
1764 let i2 = internal_hash(i1, e1);
1765 let i3 = internal_hash(i2, e2);
1766 let i4 = internal_hash(i3, e3);
1767
1768 let i5 = internal_hash(v3, v4);
1769 let i6 = internal_hash(e4, i5);
1770 let i7 = internal_hash(e5, i6);
1771
1772 let i8 = internal_hash(i4, i7);
1773 let i9 = internal_hash(i8, e6);
1774 let i10 = internal_hash(i9, e7);
1775
1776 let root = internal_hash(v0, i10);
1777
1778 let leaf_proof = |leaf, siblings| PathProof {
1779 terminal: PathProofTerminal::Leaf(leaf),
1780 siblings,
1781 };
1782
1783 let path_proof_1 = leaf_proof(l1.clone(), vec![v0, e7, e6, i7, e3, e2, e1, v2]);
1784 let path_proof_2 = leaf_proof(l2.clone(), vec![v0, e7, e6, i7, e3, e2, e1, v1]);
1785 let path_proof_3 = leaf_proof(l3.clone(), vec![v0, e7, e6, i4, e5, e4, v4]);
1786 let path_proof_4 = leaf_proof(l4.clone(), vec![v0, e7, e6, i4, e5, e4, v3]);
1787
1788 let multi_proof = MultiProof::from_path_proofs(vec![
1789 path_proof_1.clone(),
1790 path_proof_2.clone(),
1791 path_proof_3.clone(),
1792 path_proof_4.clone(),
1793 ]);
1794
1795 assert_eq!(multi_proof.siblings, vec![v0, e7, e6, e3, e2, e1, e5, e4]);
1796
1797 let verified = verify::<Blake3Hasher>(&multi_proof, root).unwrap();
1798 assert!(verified.confirm_value(&l1).unwrap());
1799 assert!(verified.confirm_value(&l2).unwrap());
1800 assert!(verified.confirm_value(&l3).unwrap());
1801 assert!(verified.confirm_value(&l4).unwrap());
1802 }
1803
1804 #[test]
1805
1806 fn test_verify_update_underflow_prefix_paths() {
1807 let bits_prefix = bitvec![u8, Msb0; 1, 0, 1, 0]; let bits_longer = bitvec![u8, Msb0; 1, 0, 1, 0, 1, 1]; let keypath_from_bits = |bits: &BitSlice<u8, Msb0>| -> KeyPath {
1813 let mut kp = KeyPath::default();
1814
1815 for (i, bit) in bits.iter().by_vals().enumerate() {
1816 if i >= 256 {
1817 break;
1818 }
1819
1820 if bit {
1821 kp[i / 8] |= 1 << (7 - (i % 8));
1822 }
1823 }
1824
1825 kp
1826 };
1827
1828 let kp_prefix = keypath_from_bits(&bits_prefix);
1829 let kp_longer = keypath_from_bits(&bits_longer);
1830
1831 let leaf_prefix = LeafData {
1833 key_path: kp_prefix,
1834 value_hash: [1; 32],
1835 };
1836
1837 let leaf_longer = LeafData {
1838 key_path: kp_longer,
1839 value_hash: [2; 32],
1840 };
1841
1842 let node_prefix = Blake3Hasher::hash_leaf(&leaf_prefix);
1843 let node_longer = Blake3Hasher::hash_leaf(&leaf_longer);
1844
1845 let vmp_prefix = VerifiedMultiPath {
1847 terminal: PathProofTerminal::Leaf(leaf_prefix.clone()),
1848 depth: bits_prefix.len(),
1849 unique_siblings: 0..0, };
1851
1852 let vmp_longer = VerifiedMultiPath {
1853 terminal: PathProofTerminal::Leaf(leaf_longer.clone()),
1854 depth: bits_longer.len(),
1855 unique_siblings: 0..0, };
1857
1858 let plausible_root = Blake3Hasher::hash_internal(&InternalData {
1862 left: node_prefix,
1863 right: node_longer,
1864 });
1865
1866 let verified_proof = VerifiedMultiProof {
1867 inner: vec![vmp_prefix, vmp_longer],
1868
1869 bisections: Vec::new(), siblings: Vec::new(), root: plausible_root,
1874 };
1875
1876 let mut key_op1_bits = bits_prefix.clone();
1878
1879 key_op1_bits.push(false); let key_op1 = keypath_from_bits(&key_op1_bits);
1882
1883 let mut key_op2_bits = bits_longer.clone();
1884
1885 key_op2_bits.push(true); let key_op2 = keypath_from_bits(&key_op2_bits);
1888
1889 let ops = vec![
1890 (key_op1, Some(ValueHash::default())), (key_op2, Some(ValueHash::default())), ];
1893
1894 assert!(ops[0].0 < ops[1].0);
1896
1897 match verify_update::<Blake3Hasher>(&verified_proof, ops).unwrap_err() {
1899 MultiVerifyUpdateError::PathPrefixOfAnother => (),
1900 _ => panic!(),
1901 }
1902 }
1903}