Skip to content

Commit 498857b

Browse files
committed
refactor: Convert VerifyMmrSuccessor to new MemPreserver trait
Convert this snippet to a trait that guarantees that there is no modification of memory. This helps us reason about the soundness of this snippet.
1 parent c5a0c94 commit 498857b

File tree

2 files changed

+55
-60
lines changed

2 files changed

+55
-60
lines changed

tasm-lib/src/mmr/verify_mmr_successor.rs

Lines changed: 53 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,25 @@
1-
use triton_vm::{
2-
program::NonDeterminism,
3-
triton_asm,
4-
twenty_first::util_types::mmr::{
5-
mmr_accumulator::MmrAccumulator, mmr_successor_proof::MmrSuccessorProof,
6-
},
7-
};
8-
9-
use crate::{
10-
arithmetic::u64::{
11-
add_u64::AddU64, log_2_floor_u64::Log2FloorU64, lt_u64::LtU64ConsumeArgs,
12-
popcount_u64::PopCountU64, shift_right_u64::ShiftRightU64, sub_u64::SubU64,
13-
},
14-
data_type::DataType,
15-
field,
16-
hashing::merkle_step_u64_index::MerkleStepU64Index,
17-
mmr::{
18-
bag_peaks::BagPeaks,
19-
leaf_index_to_mt_index_and_peak_index::MmrLeafIndexToMtIndexAndPeakIndex,
20-
},
21-
prelude::BasicSnippet,
22-
Digest,
23-
};
1+
use triton_vm::program::NonDeterminism;
2+
use triton_vm::triton_asm;
3+
use triton_vm::twenty_first::util_types::mmr::mmr_accumulator::MmrAccumulator;
4+
use triton_vm::twenty_first::util_types::mmr::mmr_successor_proof::MmrSuccessorProof;
5+
6+
use crate::arithmetic::u64::add_u64::AddU64;
7+
use crate::arithmetic::u64::log_2_floor_u64::Log2FloorU64;
8+
use crate::arithmetic::u64::lt_u64::LtU64ConsumeArgs;
9+
use crate::arithmetic::u64::popcount_u64::PopCountU64;
10+
use crate::arithmetic::u64::shift_right_u64::ShiftRightU64;
11+
use crate::arithmetic::u64::sub_u64::SubU64;
12+
use crate::data_type::DataType;
13+
use crate::field;
14+
use crate::hashing::merkle_step_u64_index::MerkleStepU64Index;
15+
use crate::mmr::bag_peaks::BagPeaks;
16+
use crate::mmr::leaf_index_to_mt_index_and_peak_index::MmrLeafIndexToMtIndexAndPeakIndex;
17+
use crate::prelude::BasicSnippet;
18+
use crate::Digest;
2419

2520
/// Verify that one MMR is a successor to another.
2621
///
27-
/// Verify a the scucessorship relation between two MMRs. A `MmrSuccessorProof`
22+
/// Verify a the successorship relation between two MMRs. A `MmrSuccessorProof`
2823
/// is necessary to demonstrate this relation, but it is not a *stack* argument
2924
/// because this algorithm obtains the relevant info (authentication paths) from
3025
/// nondeterministic digests. Accordingly, nondeterminism must be initialized
@@ -369,38 +364,34 @@ impl VerifyMmrSuccessor {
369364
#[cfg(test)]
370365
mod test {
371366
use std::collections::HashMap;
367+
use std::collections::VecDeque;
372368

373369
use itertools::Itertools;
374370
use rand::prelude::StdRng;
375371
use rand::Rng;
376372
use rand::RngCore;
377373
use rand::SeedableRng;
378374
use triton_vm::error::InstructionError;
379-
use triton_vm::{
380-
prelude::BFieldElement,
381-
program::NonDeterminism,
382-
twenty_first::{
383-
prelude::Mmr,
384-
util_types::mmr::{
385-
mmr_accumulator::MmrAccumulator, mmr_successor_proof::MmrSuccessorProof,
386-
shared_advanced::get_peak_heights,
387-
shared_basic::leaf_index_to_mt_index_and_peak_index,
388-
},
389-
},
390-
};
375+
use triton_vm::prelude::BFieldElement;
376+
use triton_vm::prelude::Tip5;
377+
use triton_vm::program::NonDeterminism;
378+
use triton_vm::twenty_first::prelude::Mmr;
379+
use triton_vm::twenty_first::util_types::mmr::mmr_accumulator::MmrAccumulator;
380+
use triton_vm::twenty_first::util_types::mmr::mmr_successor_proof::MmrSuccessorProof;
381+
use triton_vm::twenty_first::util_types::mmr::shared_advanced::get_peak_heights;
382+
use triton_vm::twenty_first::util_types::mmr::shared_basic::leaf_index_to_mt_index_and_peak_index;
391383

392384
use crate::empty_stack;
393385
use crate::memory::encode_to_memory;
394386
use crate::memory::FIRST_NON_DETERMINISTICALLY_INITIALIZED_MEMORY_ADDRESS;
387+
use crate::prelude::TasmObject;
388+
use crate::snippet_bencher::BenchmarkCase;
395389
use crate::test_helpers::negative_test;
396-
use crate::traits::algorithm::ShadowedAlgorithm;
390+
use crate::traits::mem_preserver::MemPreserver;
391+
use crate::traits::mem_preserver::MemPreserverInitialState;
392+
use crate::traits::mem_preserver::ShadowedMemPreserver;
397393
use crate::traits::rust_shadow::RustShadow;
398-
use crate::{
399-
prelude::TasmObject,
400-
snippet_bencher::BenchmarkCase,
401-
traits::algorithm::{Algorithm, AlgorithmInitialState},
402-
Digest,
403-
};
394+
use crate::Digest;
404395
use rand::thread_rng;
405396

406397
use super::VerifyMmrSuccessor;
@@ -434,7 +425,7 @@ mod test {
434425
old_mmr: &MmrAccumulator,
435426
new_mmr: &MmrAccumulator,
436427
mmr_successor_proof: &MmrSuccessorProof,
437-
) -> AlgorithmInitialState {
428+
) -> MemPreserverInitialState {
438429
let mut nondeterminism = NonDeterminism::new(vec![]);
439430
VerifyMmrSuccessor::update_nondeterminism(&mut nondeterminism, mmr_successor_proof);
440431
let old_mmr_address = FIRST_NON_DETERMINISTICALLY_INITIALIZED_MEMORY_ADDRESS;
@@ -443,13 +434,14 @@ mod test {
443434
let mut stack = empty_stack();
444435
stack.push(old_mmr_address);
445436
stack.push(new_mmr_address);
446-
AlgorithmInitialState {
437+
MemPreserverInitialState {
447438
stack,
448439
nondeterminism,
440+
..Default::default()
449441
}
450442
}
451443

452-
fn failing_initial_states() -> Vec<AlgorithmInitialState> {
444+
fn failing_initial_states() -> Vec<MemPreserverInitialState> {
453445
let mut rng = thread_rng();
454446
let mut initial_states = vec![];
455447
for old_num_leafs in [1u64, 8] {
@@ -539,13 +531,15 @@ mod test {
539531
initial_states
540532
}
541533

542-
impl Algorithm for VerifyMmrSuccessor {
534+
impl MemPreserver for VerifyMmrSuccessor {
543535
fn rust_shadow(
544536
&self,
545537
stack: &mut Vec<BFieldElement>,
546-
memory: &mut HashMap<BFieldElement, BFieldElement>,
547-
nondeterminism: &NonDeterminism,
548-
) {
538+
memory: &HashMap<BFieldElement, BFieldElement>,
539+
_nd_tokens: VecDeque<BFieldElement>,
540+
nd_digests: VecDeque<Digest>,
541+
_sponge: &mut Option<Tip5>,
542+
) -> Vec<BFieldElement> {
549543
let new_mmr_pointer = stack.pop().unwrap();
550544
let old_mmr_pointer = stack.pop().unwrap();
551545

@@ -554,17 +548,19 @@ mod test {
554548

555549
let num_digests = num_digests_to_read(&old_mmr, &new_mmr);
556550

557-
let digests = nondeterminism.digests[0..num_digests].to_vec();
551+
let digests = (0..num_digests).map(|i| nd_digests[i]).collect_vec();
558552
let mmr_successor_proof = MmrSuccessorProof { paths: digests };
559553

560554
assert!(mmr_successor_proof.verify(&old_mmr, &new_mmr));
555+
556+
vec![]
561557
}
562558

563559
fn pseudorandom_initial_state(
564560
&self,
565561
seed: [u8; 32],
566562
bench_case: Option<BenchmarkCase>,
567-
) -> AlgorithmInitialState {
563+
) -> MemPreserverInitialState {
568564
let mut rng: StdRng = SeedableRng::from_seed(seed);
569565
let old_num_leafs = match bench_case {
570566
Some(BenchmarkCase::WorstCase) => u64::MAX >> 2,
@@ -594,7 +590,7 @@ mod test {
594590
initial_state_from_mmr_tuple(&old_mmr, &new_mmr, &mmr_successor_proof)
595591
}
596592

597-
fn corner_case_initial_states(&self) -> Vec<AlgorithmInitialState> {
593+
fn corner_case_initial_states(&self) -> Vec<MemPreserverInitialState> {
598594
let mut rng = thread_rng();
599595
let mut initial_states = vec![];
600596
for old_num_leafs in [0u64, 1, 8] {
@@ -629,15 +625,15 @@ mod test {
629625

630626
#[test]
631627
fn verify_mmr_successor_simple_test() {
632-
ShadowedAlgorithm::new(VerifyMmrSuccessor).test();
628+
ShadowedMemPreserver::new(VerifyMmrSuccessor).test();
633629
}
634630

635631
#[test]
636632
fn verify_mmr_successor_negative_test() {
637633
for (i, init_state) in failing_initial_states().into_iter().enumerate() {
638634
println!("Trying failing initial state {i}.");
639635
negative_test(
640-
&ShadowedAlgorithm::new(VerifyMmrSuccessor),
636+
&ShadowedMemPreserver::new(VerifyMmrSuccessor),
641637
init_state.into(),
642638
&[
643639
InstructionError::AssertionFailed,
@@ -677,13 +673,13 @@ mod test {
677673

678674
#[cfg(test)]
679675
mod bench {
680-
use crate::traits::algorithm::ShadowedAlgorithm;
676+
use crate::traits::mem_preserver::ShadowedMemPreserver;
681677
use crate::traits::rust_shadow::RustShadow;
682678

683679
use super::*;
684680

685681
#[test]
686682
fn verify_mmr_successor_benchmark() {
687-
ShadowedAlgorithm::new(VerifyMmrSuccessor).bench();
683+
ShadowedMemPreserver::new(VerifyMmrSuccessor).bench();
688684
}
689685
}

tasm-lib/src/traits/mem_preserver.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ use crate::snippet_bencher::BenchmarkCase;
1313
use crate::snippet_bencher::NamedBenchmarkResult;
1414
use crate::test_helpers::test_rust_equivalence_given_complete_state;
1515
use crate::InitVmState;
16-
use crate::VmHasher;
1716

1817
use super::basic_snippet::BasicSnippet;
1918
use super::rust_shadow::RustShadow;
@@ -37,7 +36,7 @@ pub trait MemPreserver: BasicSnippet {
3736
memory: &HashMap<BFieldElement, BFieldElement>,
3837
nd_tokens: VecDeque<BFieldElement>,
3938
nd_digests: VecDeque<Digest>,
40-
sponge: &mut Option<VmHasher>,
39+
sponge: &mut Option<Tip5>,
4140
) -> Vec<BFieldElement>;
4241

4342
fn pseudorandom_initial_state(
@@ -96,7 +95,7 @@ where
9695
nondeterminism: &NonDeterminism,
9796
stack: &mut Vec<BFieldElement>,
9897
memory: &mut HashMap<BFieldElement, BFieldElement>,
99-
sponge: &mut Option<VmHasher>,
98+
sponge: &mut Option<Tip5>,
10099
) -> Vec<BFieldElement> {
101100
self.mem_preserver.borrow().rust_shadow(
102101
stack,

0 commit comments

Comments
 (0)