From 815c6a07880a018e764cc407cce527b9fb6422f2 Mon Sep 17 00:00:00 2001 From: sword_smith Date: Fri, 9 Aug 2024 18:30:58 +0200 Subject: [PATCH 01/14] feat(mmr): root from auth struct snippet Add stub for calculating a Merkle root from an authentication struct. Also adds code to generate the witness. Cf. https://github.com/Neptune-Crypto/twenty-first/pull/228 --- tasm-lib/src/lib.rs | 5 +- tasm-lib/src/mmr.rs | 2 + tasm-lib/src/mmr/authentication_struct.rs | 1 + .../src/mmr/authentication_struct/shared.rs | 716 ++++++++++++ .../mmr/root_from_authentication_struct.rs | 1026 +++++++++++++++++ 5 files changed, 1748 insertions(+), 2 deletions(-) create mode 100644 tasm-lib/src/mmr/authentication_struct.rs create mode 100644 tasm-lib/src/mmr/authentication_struct/shared.rs create mode 100644 tasm-lib/src/mmr/root_from_authentication_struct.rs diff --git a/tasm-lib/src/lib.rs b/tasm-lib/src/lib.rs index ea85fbc6c..4ac635a9a 100644 --- a/tasm-lib/src/lib.rs +++ b/tasm-lib/src/lib.rs @@ -183,8 +183,9 @@ pub(crate) fn execute_test( terminal_state } -/// If the environment variable TASMLIB_TRITON_TUI is set, write the initial VM state -/// to file `vm_state.json`. +/// If the environment variable TASMLIB_TRITON_TUI is set, write +/// 1. the program to file `program.tasm`, and +/// 2. the VM state to file `vm_state.json`. /// /// This file can be used to debug the program using the [Triton TUI]: /// ```sh diff --git a/tasm-lib/src/mmr.rs b/tasm-lib/src/mmr.rs index cf240a9dc..9ef3b582f 100644 --- a/tasm-lib/src/mmr.rs +++ b/tasm-lib/src/mmr.rs @@ -1,7 +1,9 @@ +pub mod authentication_struct; pub mod bag_peaks; pub mod calculate_new_peaks_from_append; pub mod calculate_new_peaks_from_leaf_mutation; pub mod leaf_index_to_mt_index_and_peak_index; +pub mod root_from_authentication_struct; pub mod verify_from_memory; pub mod verify_from_secret_in_leaf_index_on_stack; pub mod verify_from_secret_in_secret_leaf_index; diff --git a/tasm-lib/src/mmr/authentication_struct.rs b/tasm-lib/src/mmr/authentication_struct.rs new file mode 100644 index 000000000..eec3c896b --- /dev/null +++ b/tasm-lib/src/mmr/authentication_struct.rs @@ -0,0 +1 @@ +pub mod shared; diff --git a/tasm-lib/src/mmr/authentication_struct/shared.rs b/tasm-lib/src/mmr/authentication_struct/shared.rs new file mode 100644 index 000000000..16758680b --- /dev/null +++ b/tasm-lib/src/mmr/authentication_struct/shared.rs @@ -0,0 +1,716 @@ +use std::collections::HashMap; +use std::collections::HashSet; + +use itertools::Itertools; +use num_traits::One; + +use crate::twenty_first::bfe; +use crate::twenty_first::prelude::*; +use crate::twenty_first::util_types::mmr::mmr_accumulator::MmrAccumulator; +use crate::twenty_first::util_types::mmr::shared_advanced::get_peak_heights; +use crate::twenty_first::util_types::mmr::shared_basic::leaf_index_to_mt_index_and_peak_index; + +const ROOT_MT_INDEX: u64 = 1; + +/// A witness to facilitate the proving of the authenticity of a Merkle +/// authentication struct. +#[derive(Debug, Clone)] +pub struct AuthStructIntegrityProof { + // All indices are Merkle tree node indices + pub nd_auth_struct_indices: Vec, + pub nd_sibling_indices: Vec<(u64, u64)>, + pub nd_siblings: Vec<(Digest, Digest)>, +} + +/// An authentication structure that can be used to prove membership of a list +/// of leaves in a Merkle tree, along with the indexed leaves in question, and +/// the witness necessary to prove membership in a ZK program. +#[derive(Debug, Clone)] +pub struct AuthenticatedMerkleAuthStruct { + pub auth_struct: Vec, + pub indexed_leafs: Vec<(u64, Digest)>, + pub witness: AuthStructIntegrityProof, +} + +impl AuthStructIntegrityProof { + /// Return the Merkle tree node indices of the digests required to prove + /// membership for the specified leaf indices, as well as the node indices + /// that can be derived from the leaf indices and their authentication + /// path. + fn auth_struct_and_nd_indices( + num_leafs: u64, + leaf_indices: &[u64], + ) -> (Vec, Vec<(u64, u64)>) { + // The set of indices of nodes that need to be included in the authentications + // structure. In principle, every node of every authentication path is needed. + // The root is never needed. Hence, it is not considered below. + let mut node_is_needed = HashSet::new(); + + // The set of indices of nodes that can be computed from other nodes in the + // authentication structure or the leafs that are explicitly supplied during + // verification. Every node on the direct path from the leaf to the root can + // be computed by the very nature of “authentication path”. + let mut node_can_be_computed = HashSet::new(); + + for &leaf_index in leaf_indices { + assert!(num_leafs > leaf_index, "Leaf index must be less than number of leafs. Got leaf_index = {leaf_index}; num_leafs = {num_leafs}"); + + let mut node_index = leaf_index + num_leafs; + while node_index > ROOT_MT_INDEX { + let sibling_index = node_index ^ 1; + node_can_be_computed.insert(node_index); + node_is_needed.insert(sibling_index); + node_index /= 2; + } + } + + let set_difference = node_is_needed.difference(&node_can_be_computed).copied(); + let set_union = node_is_needed + .union(&node_can_be_computed) + .sorted_unstable() + .rev(); + + let mut set_union = set_union.peekable(); + + let mut set_union_as_ordered_pairs = Vec::new(); + while set_union.peek().is_some() { + let right_index = *set_union.next().unwrap(); + + // Crashes on odd-length of input list, which is what we want, as + // this acts as a sanity check. + let left_index = *set_union.next().unwrap(); + set_union_as_ordered_pairs.push((left_index, right_index)); + } + + ( + set_difference.sorted_unstable().rev().collect(), + set_union_as_ordered_pairs, + ) + } + + pub fn root_from_authentication_struct( + &self, + tree_height: u32, + auth_struct: Vec, + indexed_leafs: Vec<(u64, Digest)>, + ) -> Digest { + fn digest_to_xfe(digest: Digest, challenge: XFieldElement) -> XFieldElement { + let leaf_xfe_lo = XFieldElement::new([digest.0[0], digest.0[1], digest.0[2]]); + let leaf_xfe_hi = + challenge * XFieldElement::new([digest.0[3], digest.0[4], BFieldElement::one()]); + + leaf_xfe_lo + leaf_xfe_hi + } + + fn node_index_to_bfe(node_index: u64) -> BFieldElement { + BFieldElement::new(node_index) + } + + // Sanity check + assert_eq!( + self.nd_auth_struct_indices.len(), + auth_struct.len(), + "Provided auth struct length must match that specified in receiver" + ); + + // Get challenges + let (alpha, beta, gamma) = { + let mut sponge = Tip5::init(); + sponge.pad_and_absorb_all(&indexed_leafs.encode()); + sponge.pad_and_absorb_all(&auth_struct.encode()); + let challenges = sponge.sample_scalars(3); + (challenges[0], challenges[1], challenges[2]) + }; + + // Accumulate `p` from public data + let mut p = XFieldElement::one(); + for i in (0..indexed_leafs.len()).rev() { + let node_index_as_bfe = node_index_to_bfe((1 << tree_height) ^ indexed_leafs[i].0); + let leaf_as_xfe = digest_to_xfe(indexed_leafs[i].1, alpha); + let fact = leaf_as_xfe - beta + gamma * node_index_as_bfe; + p *= fact; + } + + let mut prev = 0; + for i in (0..auth_struct.len()).rev() { + let auth_struct_index = self.nd_auth_struct_indices[i]; + + // `auth_struct` must be sorted high-to-low by node-index. But since + // we're traversing in reverse order, the inequality is flipped. + assert!(auth_struct_index > prev); + prev = auth_struct_index; + + let auth_struct_index_as_bfe = node_index_to_bfe(auth_struct_index); + + let auth_str_elem_as_xfe = digest_to_xfe(auth_struct[i], alpha); + let fact = auth_str_elem_as_xfe - beta + gamma * auth_struct_index_as_bfe; + p *= fact; + } + + // Use secret data to invert `p` back and to calculate the root + let mut t = auth_struct + .first() + .copied() + .unwrap_or_else(|| indexed_leafs.first().unwrap().1); + let mut t_xfe = digest_to_xfe(t, alpha); + let mut parent_index_bfe = BFieldElement::one(); + for ((l, r), (left_index, right_index)) in self + .nd_siblings + .iter() + .zip_eq(self.nd_sibling_indices.clone()) + { + assert_eq!(left_index + 1, right_index); + + t = Tip5::hash_pair(*l, *r); + + let l_xfe = digest_to_xfe(*l, alpha); + let r_xfe = digest_to_xfe(*r, alpha); + t_xfe = digest_to_xfe(t, alpha); + + let left_index_bfe = node_index_to_bfe(left_index); + let right_index_bfe = node_index_to_bfe(right_index); + parent_index_bfe = left_index_bfe / bfe!(2); + + let fact1 = l_xfe - beta + gamma * left_index_bfe; + let fact2 = r_xfe - beta + gamma * right_index_bfe; + let fact_parent = t_xfe - beta + gamma * parent_index_bfe; + + p *= fact1.inverse() * fact2.inverse() * fact_parent; + } + + assert_eq!(t_xfe - beta + gamma, p); + + assert!(parent_index_bfe.is_one()); + + t + } + + /// Return the authentication structure authenticity witness, + /// authentication structure, and the (leaf-index, leaf-digest) pairs + /// from a list of MMR membership proofs. All MMR membership proofs must + /// belong under the same peak, i.e., be part of the same Merkle tree in + /// the list of Merkle trees that the MMR contains. + /// + /// Panics if the input list of MMR-membership proofs is empty, or if they + /// do not all belong under the same peak. + pub fn new_from_mmr_membership_proofs( + mmra: &MmrAccumulator, + indexed_mmr_mps: Vec<(u64, Digest, MmrMembershipProof)>, + ) -> HashMap { + #[derive(Clone, Debug)] + struct IndexedAuthenticatedMmrLeaf { + merkle_tree_node_index: u64, + merkle_tree_leaf_index: u64, + leaf_digest: Digest, + membership_proof: MmrMembershipProof, + } + + // Split indexed MMR-mps into a hashmap with one entry for each + // referenced peak in the MMR. + let num_mmr_leafs = mmra.num_leafs(); + let mut peak_index_to_indexed_mmr_mp: HashMap> = + HashMap::default(); + let peak_heights = get_peak_heights(num_mmr_leafs); + for (mmr_leaf_index, leaf, mmr_mp) in indexed_mmr_mps { + let (mt_index, peak_index) = + leaf_index_to_mt_index_and_peak_index(mmr_leaf_index, num_mmr_leafs); + let peak_index_as_usize: usize = peak_index.try_into().unwrap(); + let num_leafs_local_mt = 1 << peak_heights[peak_index_as_usize]; + let mt_leaf_index = mt_index - num_leafs_local_mt; + peak_index_to_indexed_mmr_mp + .entry(peak_index) + .or_default() + .push(IndexedAuthenticatedMmrLeaf { + merkle_tree_node_index: mt_index, + merkle_tree_leaf_index: mt_leaf_index, + leaf_digest: leaf, + membership_proof: mmr_mp, + }); + } + + // Loop over all peaks and collect an authentication witness struct + // for each peak. + let mut peak_index_to_authenticated_auth_struct = HashMap::default(); + for (peak_index, indexed_mmr_mp_structs) in peak_index_to_indexed_mmr_mp { + let peak_index_as_usize: usize = peak_index.try_into().unwrap(); + let num_leafs_in_local_mt = 1 << peak_heights[peak_index_as_usize]; + let local_mt_leaf_indices = indexed_mmr_mp_structs + .iter() + .map(|x| x.merkle_tree_leaf_index) + .collect_vec(); + + let (nd_auth_struct_indices, nd_sibling_indices) = + Self::auth_struct_and_nd_indices(num_leafs_in_local_mt, &local_mt_leaf_indices); + let peak = mmra.peaks()[peak_index_as_usize]; + + let mut node_digests: HashMap = HashMap::default(); + node_digests.insert(ROOT_MT_INDEX, peak); + + // Loop over all indexed leafs for this peak + for indexed_mmr_mp in indexed_mmr_mp_structs.iter() { + let mut mt_node_index = indexed_mmr_mp.merkle_tree_node_index; + let mut node = indexed_mmr_mp.leaf_digest; + + // Loop over all authentication path elements for this indexed leaf + for ap_elem in indexed_mmr_mp.membership_proof.authentication_path.iter() { + node_digests.insert(mt_node_index, node); + node_digests.insert(mt_node_index ^ 1, *ap_elem); + node = if mt_node_index & 1 == 0 { + Tip5::hash_pair(node, *ap_elem) + } else { + Tip5::hash_pair(*ap_elem, node) + }; + + mt_node_index /= 2; + } + + // Sanity check that MMR-MPs are valid + assert_eq!(peak, node, "Derived peak must match provided peak"); + } + let nd_siblings = nd_sibling_indices + .iter() + .map(|(left_idx, right_idx)| (node_digests[left_idx], node_digests[right_idx])) + .collect_vec(); + let auth_struct = nd_auth_struct_indices + .iter() + .map(|idx| node_digests[idx]) + .collect_vec(); + let indexed_leafs = indexed_mmr_mp_structs + .into_iter() + .map(|indexed_mmr_mp| { + ( + indexed_mmr_mp.merkle_tree_leaf_index, + indexed_mmr_mp.leaf_digest, + ) + }) + .collect_vec(); + + let witness = Self { + nd_auth_struct_indices, + nd_sibling_indices, + nd_siblings, + }; + + peak_index_to_authenticated_auth_struct.insert( + peak_index, + AuthenticatedMerkleAuthStruct { + auth_struct, + indexed_leafs, + witness, + }, + ); + } + + peak_index_to_authenticated_auth_struct + } + + /// Return the authentication structure witness, authentication structure, + /// and the (leaf-index, leaf-digest) pairs. + pub fn new_from_merkle_tree( + tree: &MerkleTree, + mut revealed_leaf_indices: Vec, + ) -> AuthenticatedMerkleAuthStruct { + revealed_leaf_indices.sort_unstable(); + revealed_leaf_indices.dedup(); + revealed_leaf_indices.reverse(); + let num_leafs: u64 = tree.num_leafs() as u64; + + let (mut nd_auth_struct_indices, nd_sibling_indices) = + Self::auth_struct_and_nd_indices(num_leafs, &revealed_leaf_indices); + if revealed_leaf_indices.is_empty() { + nd_auth_struct_indices = vec![ROOT_MT_INDEX]; + } + + let nd_siblings = nd_sibling_indices + .iter() + .map(|&(l, r)| { + let l: usize = l.try_into().unwrap(); + let r: usize = r.try_into().unwrap(); + (tree.node(l).unwrap(), tree.node(r).unwrap()) + }) + .collect_vec(); + + let revealed_leafs = revealed_leaf_indices + .iter() + .map(|j| tree.node((*j + num_leafs) as usize).unwrap()) + .collect_vec(); + let indexed_leafs = revealed_leaf_indices + .clone() + .into_iter() + .zip_eq(revealed_leafs) + .collect_vec(); + + let auth_struct = nd_auth_struct_indices + .iter() + .map(|node_index| tree.node(*node_index as usize).unwrap()) + .collect_vec(); + + let witness = Self { + nd_auth_struct_indices, + nd_sibling_indices, + nd_siblings, + }; + + AuthenticatedMerkleAuthStruct { + auth_struct, + indexed_leafs, + witness, + } + } +} + +#[cfg(test)] +mod tests { + use proptest::collection::vec; + use proptest::prop_assert_eq; + use rand::random; + use test_strategy::proptest; + + use crate::twenty_first::math::other::random_elements; + use crate::twenty_first::util_types::mmr::mmr_accumulator::util::mmra_with_mps; + + use super::*; + + #[proptest(cases = 20)] + fn root_from_authentication_struct_mmr_prop_test( + #[strategy(0..u64::MAX / 2)] mmr_leaf_count: u64, + #[strategy(0usize..20)] _num_revealed_leafs: usize, + #[strategy(vec(0u64..#mmr_leaf_count, #_num_revealed_leafs))] + mmr_revealed_leaf_indices: Vec, + ) { + let indexed_leafs_input: Vec<(u64, Digest)> = mmr_revealed_leaf_indices + .iter() + .map(|idx| (*idx, random())) + .collect_vec(); + let (mmra, mmr_mps) = mmra_with_mps(mmr_leaf_count, indexed_leafs_input.clone()); + let indexed_mmr_mps = mmr_mps + .into_iter() + .zip_eq(indexed_leafs_input) + .map(|(mmr_mp, (idx, leaf))| (idx, leaf, mmr_mp)) + .collect_vec(); + + let authenticated_auth_structs = + AuthStructIntegrityProof::new_from_mmr_membership_proofs(&mmra, indexed_mmr_mps); + + let peak_heights = get_peak_heights(mmr_leaf_count); + for (peak_index, authentication_auth_struct) in authenticated_auth_structs { + let AuthenticatedMerkleAuthStruct { + auth_struct, + indexed_leafs, + witness, + } = &authentication_auth_struct; + let tree_height: u32 = peak_heights[peak_index as usize]; + let computed_root = witness.root_from_authentication_struct( + tree_height, + auth_struct.to_owned(), + indexed_leafs.to_owned(), + ); + + prop_assert_eq!(mmra.peaks()[peak_index as usize], computed_root); + } + } + + #[test] + fn auth_struct_on_empty_mmr() { + let empty_mmra = MmrAccumulator::init(vec![], 0); + let authenticated_auth_structs = + AuthStructIntegrityProof::new_from_mmr_membership_proofs(&empty_mmra, vec![]); + assert!(authenticated_auth_structs.is_empty()); + } + + #[test] + fn auth_struct_non_empty_mmr_empty_leaf_list() { + let mmra_10_leafs = MmrAccumulator::new_from_leafs(vec![Digest::default(); 10]); + let authenticated_auth_structs = + AuthStructIntegrityProof::new_from_mmr_membership_proofs(&mmra_10_leafs, vec![]); + assert!(authenticated_auth_structs.is_empty()); + } + + #[should_panic] + #[test] + fn panics_on_missing_nd_digests() { + let tree_height = 3u32; + let num_leafs = 1u64 << tree_height; + let leafs: Vec = random_elements(num_leafs.try_into().unwrap()); + let tree = MerkleTree::::new::(&leafs).unwrap(); + + let authenticated_auth_struct = + AuthStructIntegrityProof::new_from_merkle_tree(&tree, vec![0]); + let AuthenticatedMerkleAuthStruct { + auth_struct, + indexed_leafs, + mut witness, + } = authenticated_auth_struct; + witness.nd_sibling_indices.clear(); + witness.nd_siblings.clear(); + + witness.root_from_authentication_struct(tree_height, auth_struct, indexed_leafs); + } + + #[test] + fn auth_struct_from_mmr_mps_test_height_5_9_indices() { + let local_tree_height = 5; + let mmr_leaf_indices = [0, 1, 2, 16, 17, 18, 27, 29, 31]; + let indexed_leafs_input: Vec<(u64, Digest)> = mmr_leaf_indices + .iter() + .map(|idx| (*idx, random())) + .collect_vec(); + let (mmra, mmr_mps) = mmra_with_mps(1 << local_tree_height, indexed_leafs_input.clone()); + let indexed_mmr_mps = mmr_mps + .into_iter() + .zip_eq(indexed_leafs_input) + .map(|(mmr_mp, (idx, leaf))| (idx, leaf, mmr_mp)) + .collect_vec(); + + let authenticity_witnesses = + AuthStructIntegrityProof::new_from_mmr_membership_proofs(&mmra, indexed_mmr_mps); + assert!( + authenticity_witnesses.len().is_one(), + "All indices belong to first peak" + ); + let AuthenticatedMerkleAuthStruct { + auth_struct, + indexed_leafs, + witness, + } = &authenticity_witnesses[&0]; + + let tree_height: u32 = local_tree_height.try_into().unwrap(); + let computed_root = witness.root_from_authentication_struct( + tree_height, + auth_struct.to_owned(), + indexed_leafs.to_owned(), + ); + + let peak_index = 0; + let expected_root = mmra.peaks()[peak_index]; + assert_eq!(expected_root, computed_root); + } + + #[test] + fn auth_struct_from_mmr_mps_test_height_4_2_indices() { + let local_tree_height = 4; + let mmr_leaf_indices = [0, 1]; + let indexed_leafs_input: Vec<(u64, Digest)> = mmr_leaf_indices + .iter() + .map(|idx| (*idx, random())) + .collect_vec(); + let (mmra, mmr_mps) = mmra_with_mps(1 << local_tree_height, indexed_leafs_input.clone()); + let indexed_mmr_mps = mmr_mps + .into_iter() + .zip_eq(indexed_leafs_input) + .map(|(mmr_mp, (idx, leaf))| (idx, leaf, mmr_mp)) + .collect_vec(); + + let authenticity_witnesses = + AuthStructIntegrityProof::new_from_mmr_membership_proofs(&mmra, indexed_mmr_mps); + assert!( + authenticity_witnesses.len().is_one(), + "All indices belong to first peak" + ); + let AuthenticatedMerkleAuthStruct { + auth_struct, + indexed_leafs, + witness, + } = &authenticity_witnesses[&0]; + + let tree_height: u32 = local_tree_height.try_into().unwrap(); + let computed_root = witness.root_from_authentication_struct( + tree_height, + auth_struct.to_owned(), + indexed_leafs.to_owned(), + ); + + let peak_index = 0; + let expected_root = mmra.peaks()[peak_index]; + assert_eq!(expected_root, computed_root); + } + + #[proptest(cases = 20)] + fn root_from_authentication_struct_prop_test( + #[strategy(0..12u64)] tree_height: u64, + #[strategy(0usize..100)] _num_revealed_leafs: usize, + #[strategy(vec(0u64..1<<#tree_height, #_num_revealed_leafs))] revealed_leaf_indices: Vec< + u64, + >, + ) { + let num_leafs = 1u64 << tree_height; + let leafs: Vec = random_elements(num_leafs.try_into().unwrap()); + let tree = MerkleTree::::new::(&leafs).unwrap(); + + let authenticated_auth_struct = + AuthStructIntegrityProof::new_from_merkle_tree(&tree, revealed_leaf_indices); + let AuthenticatedMerkleAuthStruct { + auth_struct, + indexed_leafs, + witness, + } = authenticated_auth_struct; + + let tree_height: u32 = tree_height.try_into().unwrap(); + let computed_root = + witness.root_from_authentication_struct(tree_height, auth_struct, indexed_leafs); + let expected_root = tree.root(); + prop_assert_eq!(expected_root, computed_root); + } + + fn prop_from_merkle_tree( + tree_height: usize, + leaf_indices: Vec, + nd_auth_struct_indices: Vec, + nd_sibling_indices: Vec<(u64, u64)>, + ) { + let leafs: Vec = random_elements(1 << tree_height); + let tree = MerkleTree::::new::(&leafs).unwrap(); + + let auth_struct = nd_auth_struct_indices + .iter() + .map(|i| tree.node(*i as usize).unwrap()) + .collect_vec(); + let revealed_leafs = leaf_indices + .iter() + .map(|i| tree.leaf(*i as usize).unwrap()) + .collect_vec(); + let revealed_leafs = leaf_indices + .into_iter() + .zip_eq(revealed_leafs) + .collect_vec(); + let nd_siblings = nd_sibling_indices + .iter() + .map(|(left_idx, right_idx)| { + ( + tree.node(*left_idx as usize).unwrap(), + tree.node(*right_idx as usize).unwrap(), + ) + }) + .collect_vec(); + + let mmr_auth_struct = AuthStructIntegrityProof { + nd_auth_struct_indices, + nd_sibling_indices, + nd_siblings, + }; + let tree_height: u32 = tree_height.try_into().unwrap(); + let calculated_root = mmr_auth_struct.root_from_authentication_struct( + tree_height, + auth_struct, + revealed_leafs, + ); + assert_eq!(tree.root(), calculated_root); + } + + #[test] + fn root_from_authentication_struct_tree_height_0_no_revealed_leafs() { + let tree_height = 0; + let leaf_indices = vec![]; + let nd_auth_struct_indices = vec![1]; + let nd_sibling_indices = vec![]; + prop_from_merkle_tree( + tree_height, + leaf_indices, + nd_auth_struct_indices, + nd_sibling_indices, + ) + } + + #[test] + fn root_from_authentication_struct_tree_height_0_1_revealed() { + let tree_height = 0; + let leaf_indices = vec![0]; + let nd_auth_struct_indices = vec![]; + let nd_sibling_indices = vec![]; + prop_from_merkle_tree( + tree_height, + leaf_indices, + nd_auth_struct_indices, + nd_sibling_indices, + ) + } + + #[test] + fn root_from_authentication_struct_tree_height_1_1_revealed() { + let tree_height = 1; + let leaf_indices = vec![0u64]; + let nd_auth_struct_indices = vec![3]; + let nd_sibling_indices = vec![(2u64, 3u64)]; + prop_from_merkle_tree( + tree_height, + leaf_indices, + nd_auth_struct_indices, + nd_sibling_indices, + ) + } + + #[test] + fn root_from_authentication_struct_tree_height_1_2_revealed() { + let tree_height = 1; + let leaf_indices = vec![0u64, 1]; + let nd_auth_struct_indices = vec![]; + let nd_sibling_indices = vec![(2u64, 3u64)]; + prop_from_merkle_tree( + tree_height, + leaf_indices, + nd_auth_struct_indices, + nd_sibling_indices, + ) + } + + #[test] + fn root_from_authentication_struct_tree_height_2_0_revealed() { + let tree_height = 2; + let leaf_indices = vec![]; + let auth_struct_indices = vec![1]; + let nd_sibling_indices = vec![]; + prop_from_merkle_tree( + tree_height, + leaf_indices, + auth_struct_indices, + nd_sibling_indices, + ) + } + + #[test] + fn root_from_authentication_struct_tree_height_2_2_revealed() { + let tree_height = 2; + let leaf_indices = vec![0u64, 1]; + let auth_struct_indices = vec![3]; + let nd_sibling_indices = vec![(4u64, 5u64), (2, 3)]; + prop_from_merkle_tree( + tree_height, + leaf_indices, + auth_struct_indices, + nd_sibling_indices, + ) + } + + #[test] + fn root_from_authentication_struct_tree_height_4_4_revealed() { + let tree_height = 4; + let leaf_indices = vec![14u64, 12, 10, 8]; + let num_leafs = 1 << tree_height; + let auth_struct_indices = vec![ + num_leafs + 15, + num_leafs + 13, + num_leafs + 11, + num_leafs + 9, + 2, + ]; + let nd_sibling_indices_layer_height_0 = [(14u64, 15u64), (12, 13), (10, 11), (8, 9)] + .map(|(l, r)| (l + num_leafs, r + num_leafs)); + let nd_sibling_indices_layer_height_1 = [(14u64, 15u64), (12u64, 13u64)]; + let nd_sibling_indices_layer_height_2 = [(6u64, 7u64)]; + let nd_sibling_indices_layer_height_3 = [(2u64, 3u64)]; + let nd_sibling_indices = [ + nd_sibling_indices_layer_height_0.to_vec(), + nd_sibling_indices_layer_height_1.to_vec(), + nd_sibling_indices_layer_height_2.to_vec(), + nd_sibling_indices_layer_height_3.to_vec(), + ] + .concat(); + + prop_from_merkle_tree( + tree_height, + leaf_indices, + auth_struct_indices, + nd_sibling_indices, + ) + } +} diff --git a/tasm-lib/src/mmr/root_from_authentication_struct.rs b/tasm-lib/src/mmr/root_from_authentication_struct.rs new file mode 100644 index 000000000..4a8a16a82 --- /dev/null +++ b/tasm-lib/src/mmr/root_from_authentication_struct.rs @@ -0,0 +1,1026 @@ +use triton_vm::prelude::*; +use twenty_first::math::x_field_element::EXTENSION_DEGREE; + +use crate::data_type::DataType; +use crate::hashing::absorb_multiple::AbsorbMultiple; +use crate::library::Library; +use crate::prelude::BasicSnippet; + +pub struct RootFromAuthenticationStruct; + +impl RootFromAuthenticationStruct { + fn indexed_leaf_element_type() -> DataType { + DataType::Tuple(vec![DataType::U64, DataType::Digest]) + } +} + +impl BasicSnippet for RootFromAuthenticationStruct { + fn inputs(&self) -> Vec<(DataType, String)> { + vec![ + (DataType::U32, "tree_height".to_owned()), + ( + DataType::List(Box::new(DataType::Digest)), + "auth_struct".to_owned(), + ), + ( + DataType::List(Box::new(Self::indexed_leaf_element_type())), + "indexed_leafs".to_owned(), + ), + ] + } + + fn outputs(&self) -> Vec<(DataType, String)> { + vec![(DataType::Digest, "root".to_owned())] + } + + fn entrypoint(&self) -> String { + "tasmlib_mmr_root_from_authentication_struct".to_owned() + } + + fn code(&self, library: &mut Library) -> Vec { + let absorb_multiple = library.import(Box::new(AbsorbMultiple)); + let alpha_challenge_pointer_write = library.kmalloc(EXTENSION_DEGREE as u32); + let alpha_challenge_pointer_read = + alpha_challenge_pointer_write + bfe!(EXTENSION_DEGREE as u64 - 1); + let beta_challenge_pointer_write = library.kmalloc(EXTENSION_DEGREE as u32); + let beta_challenge_pointer_read = + beta_challenge_pointer_write + bfe!(EXTENSION_DEGREE as u64 - 1); + let gamma_challenge_pointer_write = library.kmalloc(EXTENSION_DEGREE as u32); + let gamma_challenge_pointer_read = + gamma_challenge_pointer_write + bfe!(EXTENSION_DEGREE as u64 - 1); + + let indexed_leaf_element_size = Self::indexed_leaf_element_type().stack_size(); + let calculate_and_store_challenges = triton_asm!( + // _ *auth_struct *indexed_leafs + + sponge_init + // _ *auth_struct *indexed_leafs + + read_mem 1 + push 1 + add + // _ *auth_struct indexed_leafs_len *indexed_leafs + + swap 1 + // _ *auth_struct *indexed_leafs indexed_leafs_len + + push {indexed_leaf_element_size} + mul + push 1 + add + // _ *auth_struct *indexed_leafs indexed_leafs_size + + call {absorb_multiple} + // _ *auth_struct + + read_mem 1 + push 1 + add + // _ auth_struct_len *auth_struct + + swap 1 + push {Digest::LEN} + mul + push 1 + add + // _ *auth_struct auth_struct_size + + call {absorb_multiple} + // _ + + sponge_squeeze + // _ w9 w8 w7 w6 w5 w4 w3 w2 w1 w0 + + pop 1 + // _ w9 w8 w7 w6 w5 w4 w3 w2 w1 + hint alpha: XFieldElement = stack[0..3] + hint minus_beta: XFieldElement = stack[3..6] + hint gamma: XFieldElement = stack[6..9] + // _ [gamma] [-beta] [alpha] <- rename + + push {alpha_challenge_pointer_write} + write_mem {EXTENSION_DEGREE} + pop 1 + // _ [gamma] [-beta] + + push {beta_challenge_pointer_write} + write_mem {EXTENSION_DEGREE} + pop 1 + // _ [gamma] + + push {gamma_challenge_pointer_write} + write_mem {EXTENSION_DEGREE} + pop 1 + // _ + ); + + let u64_size = DataType::U64.stack_size(); + const TWO_POW_32: u64 = 1 << 32; + let u64_to_bfe = triton_asm!( + // _ leaf_idx_hi leaf_idx_lo + + swap 1 + push {TWO_POW_32} + mul + // _ leaf_idx_lo (leaf_idx_hi << 32) + + add + + // _ leaf_idx_as_bfe + ); + + let digest_to_xfe = triton_asm!( + // _ [digest] + + push 1 + push {alpha_challenge_pointer_read} + read_mem {EXTENSION_DEGREE} + pop 1 + // _ l4 l3 l2 l1 l0 1 [α; 3] + + xx_mul + // _ l4 l3 l2 [(l1 l0 1) * α] + + xx_add + // _ xfe + ); + + let entrypoint = self.entrypoint(); + let accumulate_indexed_leafs_loop_label = format!("{entrypoint}_acc_indexed_leafs"); + let accumulated_indexed_leafs_loop = triton_asm!( + // INVARIANT: _ num_leafs *auth_struct *idx_leafs *idx_leafs[n]_lw [0; 2] [p; 3] + {accumulate_indexed_leafs_loop_label}: + // _ num_leafs *auth_struct *idx_leafs *idx_leafs[n]_lw [0; 2] [p; 3] + + /* Read leaf-index, convert it to BFE, and multiply it with `gamma` challenge */ + push {gamma_challenge_pointer_read} + read_mem {EXTENSION_DEGREE} + pop 1 + // _ num_leafs *auth_struct *idx_leafs *idx_leafs[n]_lw [0; 2] [p; 3] [gamma] + // _ num_leafs *auth_struct *idx_leafs *idx_leafs[n]_lw [0; 2] [p; 3] [γ] <-- rename + + dup 8 + read_mem {u64_size} + swap 11 + pop 1 + // _ num_leafs *auth_struct *idx_leafs (*idx_leafs[n]_lw - 2) [0; 2] [p; 3] [γ] [leaf_idx; 2] + + {&u64_to_bfe} + // _ num_leafs *auth_struct *idx_leafs (*idx_leafs[n]_lw - 2) [0; 2] [p; 3] [γ] leaf_idx_bfe + + dup 12 + add + // _ num_leafs *auth_struct *idx_leafs (*idx_leafs[n]_lw - 2) [0; 2] [p; 3] [γ] node_idx_bfe + + xb_mul + // _ num_leafs *auth_struct *idx_leafs (*idx_leafs[n]_lw - 2) [0; 2] [p; 3] [γ * node_idx; 3] + + dup 8 + read_mem {Digest::LEN} + swap 14 + pop 1 + // _ num_leafs *auth_struct *idx_leafs *idx_leafs[n-1]_lw [0; 2] [p; 3] [γ * node_idx; 3] [leaf; 5] + // _ num_leafs *auth_struct *idx_leafs *idx_leafs[n-1]_lw [0; 2] [p; 3] [γ * node_idx; 3] l4 l3 l2 l1 l0 + + /* Convert `leaf` to XFE, using challenge */ + {&digest_to_xfe} + hint leaf_as_xfe: XFieldElement = stack[0..2] + // _ num_leafs *auth_struct *idx_leafs *idx_leafs[n-1]_lw [0; 2] [p; 3] [γ * node_idx; 3] [(l1 l0 1) * α + (l4 l3 l2)] + // _ num_leafs *auth_struct *idx_leafs *idx_leafs[n-1]_lw [0; 2] [p; 3] [γ * node_idx; 3] [leaf_as_xfe] <-- rename + + push {beta_challenge_pointer_read} + read_mem {EXTENSION_DEGREE} + pop 1 + // _ num_leafs *auth_struct *idx_leafs *idx_leafs[n-1]_lw [0; 2] [p; 3] [γ * node_idx; 3] [leaf_as_xfe] [-beta] + + xx_add + // _ num_leafs *auth_struct *idx_leafs *idx_leafs[n-1]_lw [0; 2] [p; 3] [γ * node_idx; 3] [leaf_as_xfe - beta] + + xx_add + // _ num_leafs *auth_struct *idx_leafs *idx_leafs[n-1]_lw [0; 2] [p; 3] [γ * node_idx + leaf_as_xfe - beta] + + xx_mul + // _ num_leafs *auth_struct *idx_leafs *idx_leafs[n-1]_lw [0; 2] [p'; 3] + + recurse_or_return + ); + let accumulate_indexed_leafs_from_public_data = triton_asm!( + // _ num_leafs *auth_struct *indexed_leafs + + dup 0 + read_mem 1 + push 1 + add + swap 1 + // _ num_leafs *auth_struct *indexed_leafs *indexed_leafs indexed_leafs_len + + push {indexed_leaf_element_size} + mul + // _ num_leafs *auth_struct *indexed_leafs *indexed_leafs (indexed_leafs_size - 1) + + add + // _ num_leafs *auth_struct *indexed_leafs *indexed_leafs_last_word + + push 0 + push 0 + push 0 + push 0 + push 1 + hint prev = stack[3..5] + hint p: XFieldElement = stack[0..3] + // _ num_leafs *auth_struct *indexed_leafs *indexed_leafs_last_word [0u64; 2] [p; 3] + + dup 6 + dup 6 + eq + push 0 + eq + skiz + call {accumulate_indexed_leafs_loop_label} + // _ num_leafs *auth_struct *indexed_leafs *indexed_leafs [0u64; 2] [p; 3] + ); + + let accumulate_auth_struct_leafs_from_public_data_label = + format!("{entrypoint}_auth_struct_loop"); + + // let u64_lt = library.import(Box::new(LtU64PreserveArgs)); + let u64_lt = triton_asm!( + // _ lhs_hi lhs_lo rhs_hi rhs_lo + + /* calculate rhs_hi < lhs_hi || rhs_hi == lhs_hi && rhs_lo < lhs_lo */ + dup 2 + swap 1 + // _ lhs_hi lhs_lo rhs_hi lhs_lo rhs_lo + + lt + // _ lhs_hi lhs_lo rhs_hi (lhs_lo > rhs_lo) + // _ lhs_hi lhs_lo rhs_hi (rhs_lo < lhs_lo) + + dup 1 + dup 4 + eq + // _ lhs_hi lhs_lo rhs_hi (rhs_lo < lhs_lo) (rhs_hi == lhs_hi) + + mul + // _ lhs_hi lhs_lo rhs_hi (rhs_lo < lhs_lo && rhs_hi == lhs_hi) + + dup 3 + swap 1 + swap 2 + // _ lhs_hi lhs_lo (rhs_lo < lhs_lo && rhs_hi == lhs_hi) lhs_hi rhs_hi + + lt + // _ lhs_hi lhs_lo (rhs_lo < lhs_lo && rhs_hi == lhs_hi) (lhs_hi > rhs_hi) + // _ lhs_hi lhs_lo (rhs_lo < lhs_lo && rhs_hi == lhs_hi) (rhs_hi < lhs_hi) + + add + // _ lhs_hi lhs_lo (rhs_lo < lhs_lo && rhs_hi == lhs_hi || rhs_hi < lhs_hi) + ); + + let accumulate_auth_struct_leafs_from_public_data = triton_asm!( + // INVARIANT: _ *auth_struct *auth_struct[n]_lw [prev; 2] [p] + {accumulate_auth_struct_leafs_from_public_data_label}: + /* Divine in auth-struct node-index and verify ordering */ + + divine 2 + hint auth_struct_elem_node_index: u64 = stack[0..2] + // _ *auth_struct *auth_struct[n]_lw [prev; 2] [p] [node_index] + + + /* Notice that the u64-lt snippet crashes if divined node-index + words are not valid u32s. So no need to check explicitly. */ + dup 6 + dup 6 + {&u64_lt} + // _ *auth_struct *auth_struct[n]_lw [prev; 2] [p] [node_index] (prev < nodex_index) + + assert + // _ *auth_struct *auth_struct[n]_lw [prev; 2] [p] [node_index] + // _ *auth_struct *auth_struct[n]_lw prev_hi prev_lo p2 p1 p0 node_index_hi node_index_lo + + swap 5 + pop 1 + swap 5 + pop 1 + // _ *auth_struct *auth_struct[n]_lw [node_index] [p] + + /* Calculate `node_index * challenge` */ + push {gamma_challenge_pointer_read} + read_mem {EXTENSION_DEGREE} + pop 1 + // _ *auth_struct *auth_struct[n]_lw [node_index] [p] [γ] + + dup 7 + push {TWO_POW_32} + mul + dup 7 + add + // _ *auth_struct *auth_struct[n]_lw [node_index] [p] [γ] node_index_bfe + + xb_mul + // _ *auth_struct *auth_struct[n]_lw [node_index] [p] [node_index * γ] + + /* Read auth-struct element and convert to XFE */ + dup 8 + read_mem {Digest::LEN} + swap 14 + pop 1 + // _ *auth_struct *auth_struct[n]_lw [node_index] [p] [node_index * γ] [auth_struct_digest] + + {&digest_to_xfe} + // _ *auth_struct *auth_struct[n]_lw [node_index] [p] [node_index * γ] [auth_struct_xfe] + + push {beta_challenge_pointer_read} + read_mem {EXTENSION_DEGREE} + pop 1 + xx_add + // _ *auth_struct *auth_struct[n]_lw [node_index] [p] [node_index * γ] [auth_struct_xfe - beta] + + xx_add + // _ *auth_struct *auth_struct[n]_lw [node_index] [p] [node_index * γ + auth_struct_xfe - beta] + + xx_mul + // _ *auth_struct *auth_struct[n]_lw [node_index] [p * (node_index * γ + auth_struct_xfe - beta)] + // _ *auth_struct *auth_struct[n]_lw [prev] [p'] <-- rename + + recurse_or_return + ); + + let set_initial_t_value = triton_asm!( + // _ num_leafs *indexed_leafs *auth_struct [p] + + /* Set `t` digest to according to the rules: + let mut t = auth_struct + .first() + .copied() + .unwrap_or_else(|| indexed_leafs.first().unwrap().1); + */ + dup 3 + read_mem 1 + pop 1 + // _ num_leafs *indexed_leafs *auth_struct [p] auth_struct_len + ); + + triton_asm!( + {entrypoint}: + // _ tree_height *auth_struct *indexed_leafs + + dup 1 + dup 1 + // _ tree_height *auth_struct *indexed_leafs *auth_struct *indexed_leafs + + {&calculate_and_store_challenges} + // _ tree_height *auth_struct *indexed_leafs + + /* Calculate number of leafs in Merkle tree */ + swap 2 + push 2 + pow + swap 2 + hint num_leafs = stack[2] + // _ num_leafs *auth_struct *indexed_leafs + + {&accumulate_indexed_leafs_from_public_data} + // _ num_leafs *auth_struct *indexed_leafs *indexed_leafs [garbage; 2] [p; 3] + // _ num_leafs *auth_struct *indexed_leafs *indexed_leafs [garbage; 2] p2 p1 p0 <-- rename + + /* Prepare for next loop, absorption of auth-struct digests into accumulator */ + swap 7 + swap 6 + pop 1 + // _ num_leafs p0 *auth_struct *indexed_leafs [0; 2] p2 p1 + + dup 5 + read_mem 1 + push 1 + add + swap 1 + // _ num_leafs p0 *auth_struct *indexed_leafs [0; 2] p2 p1 *auth_struct auth_struct_len + + push {Digest::LEN} + mul + add + // _ num_leafs p0 *auth_struct *indexed_leafs [0; 2] p2 p1 *auth_struct_last_word + + swap 5 + swap 7 + // _ num_leafs *indexed_leafs *auth_struct *auth_struct_last_word [0; 2] p2 p1 p0 + // _ num_leafs *indexed_leafs *auth_struct *auth_struct_last_word [prev; 2] [p] <-- rename + + dup 6 + dup 6 + eq + push 0 + eq + // _ num_leafs *indexed_leafs *auth_struct *auth_struct_last_word [prev; 2] [p] (*auth_struct_last_word != *auth_struct) + + skiz + call {accumulate_auth_struct_leafs_from_public_data_label} + // _ num_leafs *indexed_leafs *auth_struct *auth_struct_last_word [prev; 2] [p] + + /* Cleanup stack before next loop */ + swap 3 + pop 1 + swap 3 + pop 1 + swap 3 + pop 1 + // _ num_leafs *indexed_leafs *auth_struct [p] + + return + + {&accumulated_indexed_leafs_loop} + {&accumulate_auth_struct_leafs_from_public_data} + ) + } +} + +#[cfg(test)] +mod tests { + use std::collections::HashMap; + use std::collections::VecDeque; + + use itertools::Itertools; + use num::One; + use rand::rngs::StdRng; + use rand::Rng; + use rand::SeedableRng; + use twenty_first::prelude::CpuParallel; + use twenty_first::prelude::MerkleTree; + use twenty_first::prelude::Sponge; + + use crate::rust_shadowing_helper_functions::list::list_insert; + use crate::rust_shadowing_helper_functions::list::load_list_with_copy_elements; + use crate::snippet_bencher::BenchmarkCase; + use crate::traits::procedure::Procedure; + use crate::traits::procedure::ProcedureInitialState; + use crate::traits::procedure::ShadowedProcedure; + use crate::traits::rust_shadow::RustShadow; + use crate::VmHasher; + + use super::*; + + const SIZE_OF_INDEXED_LEAFS_ELEMENT: usize = Digest::LEN + 2; + + #[test] + fn test() { + ShadowedProcedure::new(RootFromAuthenticationStruct).test(); + } + + impl Procedure for RootFromAuthenticationStruct { + fn rust_shadow( + &self, + stack: &mut Vec, + memory: &mut std::collections::HashMap, + nondeterminism: &NonDeterminism, + public_input: &[BFieldElement], + sponge: &mut Option, + ) -> Vec { + fn digest_to_xfe(digest: Digest, challenge: XFieldElement) -> XFieldElement { + let [l0, l1, l2, l3, l4] = digest.0; + let leaf_xfe_lo = XFieldElement::new([BFieldElement::new(1), l0, l1]); + let leaf_xfe_hi = XFieldElement::new([l2, l3, l4]); + + challenge * leaf_xfe_lo + leaf_xfe_hi + } + + assert_eq!( + SIZE_OF_INDEXED_LEAFS_ELEMENT, + Self::indexed_leaf_element_type().stack_size() + ); + let indexed_leafs_pointer = stack.pop().unwrap(); + let auth_struct_pointer = stack.pop().unwrap(); + let tree_height: u32 = stack.pop().unwrap().try_into().unwrap(); + + let bfes_to_indexed_leaf = + |bfes: [BFieldElement; SIZE_OF_INDEXED_LEAFS_ELEMENT]| -> (u64, Digest) { + *<(u64, Digest)>::decode(&bfes).unwrap() + }; + let bfes_to_digest = |bfes: [BFieldElement; Digest::LEN]| -> Digest { + println!("bfes_to_digest:\nbfes: {bfes:?}"); + *Digest::decode(&bfes[0..Digest::LEN]).unwrap() + }; + + let indexed_leafs: Vec<[BFieldElement; SIZE_OF_INDEXED_LEAFS_ELEMENT]> = + load_list_with_copy_elements(indexed_leafs_pointer, memory); + println!("indexed_leafs: {indexed_leafs:?}"); + let indexed_leafs = indexed_leafs + .into_iter() + .map(bfes_to_indexed_leaf) + .collect_vec(); + let auth_struct: Vec<[BFieldElement; Digest::LEN]> = + load_list_with_copy_elements(auth_struct_pointer, memory); + println!("auth_struct: {auth_struct:?}"); + let auth_struct = auth_struct.into_iter().map(bfes_to_digest).collect_vec(); + + let sponge = sponge.as_mut().expect("sponge must be initialized"); + + sponge.pad_and_absorb_all(&indexed_leafs.encode()); + sponge.pad_and_absorb_all(&auth_struct.encode()); + + let sponge_output = sponge.squeeze(); + let alpha = XFieldElement::new([sponge_output[1], sponge_output[2], sponge_output[3]]); + let beta = -XFieldElement::new([sponge_output[4], sponge_output[5], sponge_output[6]]); + let gamma = XFieldElement::new([sponge_output[7], sponge_output[8], sponge_output[9]]); + println!("alpha {alpha}"); + println!("-beta {}", -beta); + println!("gamma {}", -gamma); + + let num_leafs = 1 << tree_height; + let mut p = XFieldElement::one(); + for (leaf_idx, leaf) in indexed_leafs.iter().copied().rev() { + let leaf_idx_as_bfe = bfe!(leaf_idx); + let node_idx_as_bfe = leaf_idx_as_bfe + bfe!(num_leafs); + + let leaf_as_xfe = digest_to_xfe(leaf, alpha); + + println!("gamma * node_idx_as_bfe = {}", gamma * node_idx_as_bfe); + println!("leaf_as_xfe = {}", leaf_as_xfe); + + let fact = leaf_as_xfe - beta + gamma * node_idx_as_bfe; + println!("indexed-leaf fact: {fact}"); + p *= fact; + } + + println!("Rust-shadow, p, after indexed-leafs absorption: {p}"); + + let mut prev = 0u64; + let mut individual_tokens: VecDeque = + nondeterminism.individual_tokens.to_owned().into(); + for auth_struct_elem in auth_struct.iter().copied().rev() { + let auth_struct_elem_node_index_hi: u32 = + individual_tokens.pop_front().unwrap().try_into().unwrap(); + let auth_struct_elem_node_index_lo: u32 = + individual_tokens.pop_front().unwrap().try_into().unwrap(); + let auth_struct_elem_node_index = ((auth_struct_elem_node_index_hi as u64) << 32) + + auth_struct_elem_node_index_lo as u64; + println!("auth_struct_elem_node_index: {auth_struct_elem_node_index}"); + assert!(auth_struct_elem_node_index > prev); + prev = auth_struct_elem_node_index; + + let auth_struct_index_as_bfe = bfe!(auth_struct_elem_node_index); + + let auth_struct_elem_xfe = digest_to_xfe(auth_struct_elem, alpha); + let fact = auth_struct_elem_xfe - beta + gamma * auth_struct_index_as_bfe; + + println!("auth struct fact: {fact}"); + p *= fact; + } + + println!("Rust-shadow, p, after auth-struct absorption: {p}"); + + vec![] + } + + fn pseudorandom_initial_state( + &self, + seed: [u8; 32], + bench_case: Option, + ) -> ProcedureInitialState { + let mut rng: StdRng = SeedableRng::from_seed(seed); + + // TODO: use real `mmr_authentication_struct` code here + let tree_height = rng.gen_range(1..5); + let leaf_count = 1 << tree_height; + let num_revealed_leafs = rng.gen_range(1..leaf_count); + let revealed_leaf_indices = (0..num_revealed_leafs) + .map(|_| rng.gen_range(0..leaf_count)) + .unique() + .collect_vec(); + let leafs = (0..leaf_count).map(|_| rng.gen()).collect_vec(); + let tree = MerkleTree::::new::(&leafs).unwrap(); + let mmr_authentication_struct = + mmr_authentication_struct::AuthStructIntegrityProof::new_from_merkle_tree( + &tree, + revealed_leaf_indices, + ); + + let mut memory = HashMap::new(); + let authentication_structure_ptr = rng.gen(); + let indexed_leafs_ptr = rng.gen(); + + println!( + "indexed_leafs.len(): {}", + mmr_authentication_struct.indexed_leafs.len() + ); + println!( + "authentication_structure.len(): {}", + mmr_authentication_struct.auth_struct.len() + ); + + list_insert( + authentication_structure_ptr, + mmr_authentication_struct.auth_struct.clone(), + &mut memory, + ); + list_insert( + indexed_leafs_ptr, + mmr_authentication_struct.indexed_leafs, + &mut memory, + ); + + let stack = [ + self.init_stack_for_isolated_run(), + vec![ + bfe!(tree_height), + authentication_structure_ptr, + indexed_leafs_ptr, + ], + ] + .concat(); + + println!( + "node indices: {}", + mmr_authentication_struct + .witness + .nd_auth_struct_indices + .iter() + .join(", ") + ); + let individual_tokens = mmr_authentication_struct + .witness + .nd_auth_struct_indices + .into_iter() + .rev() + .flat_map(|node_index| node_index.encode().into_iter().rev().collect_vec()) + .collect_vec(); + println!("individual_tokens: {}", individual_tokens.iter().join(", ")); + let nondeterminism = NonDeterminism::new(individual_tokens).with_ram(memory); + ProcedureInitialState { + stack, + nondeterminism, + public_input: vec![], + sponge: Some(Tip5::init()), + } + } + + fn corner_case_initial_states(&self) -> Vec { + vec![] + } + } +} + +// TODO: Use this logic from `twenty-first` instead! +mod mmr_authentication_struct { + use std::collections::{HashMap, HashSet}; + + use itertools::Itertools; + use num::One; + use twenty_first::{ + prelude::{AlgebraicHasher, Inverse, MerkleTree, Mmr, MmrMembershipProof, Sponge}, + util_types::mmr::{ + mmr_accumulator::MmrAccumulator, shared_advanced::get_peak_heights, + shared_basic::leaf_index_to_mt_index_and_peak_index, + }, + }; + + use super::*; + + const ROOT_MT_INDEX: u64 = 1; + + /// A witness to facilitate the proving of the authenticity of a Merkle + /// authentication struct. + #[derive(Debug, Clone)] + pub struct AuthStructIntegrityProof { + // All indices are Merkle tree node indices + pub nd_auth_struct_indices: Vec, + pub nd_sibling_indices: Vec<(u64, u64)>, + pub nd_siblings: Vec<(Digest, Digest)>, + } + + /// An authentication structure that can be used to prove membership of a list + /// of leaves in a Merkle tree, along with the indexed leaves in question, and + /// the witness necessary to prove membership in a ZK program. + #[derive(Debug, Clone)] + pub struct AuthenticatedMerkleAuthStruct { + pub auth_struct: Vec, + pub indexed_leafs: Vec<(u64, Digest)>, + pub witness: AuthStructIntegrityProof, + } + + impl AuthStructIntegrityProof { + /// Return the Merkle tree node indices of the digests required to prove + /// membership for the specified leaf indices, as well as the node indices + /// that can be derived from the leaf indices and their authentication + /// path. + fn auth_struct_and_nd_indices( + num_leafs: u64, + leaf_indices: &[u64], + ) -> (Vec, Vec<(u64, u64)>) { + // The set of indices of nodes that need to be included in the authentications + // structure. In principle, every node of every authentication path is needed. + // The root is never needed. Hence, it is not considered below. + let mut node_is_needed = HashSet::new(); + + // The set of indices of nodes that can be computed from other nodes in the + // authentication structure or the leafs that are explicitly supplied during + // verification. Every node on the direct path from the leaf to the root can + // be computed by the very nature of “authentication path”. + let mut node_can_be_computed = HashSet::new(); + + for &leaf_index in leaf_indices { + assert!(num_leafs > leaf_index, "Leaf index must be less than number of leafs. Got leaf_index = {leaf_index}; num_leafs = {num_leafs}"); + + let mut node_index = leaf_index + num_leafs; + while node_index > ROOT_MT_INDEX { + let sibling_index = node_index ^ 1; + node_can_be_computed.insert(node_index); + node_is_needed.insert(sibling_index); + node_index /= 2; + } + } + + let set_difference = node_is_needed.difference(&node_can_be_computed).copied(); + let set_union = node_is_needed + .union(&node_can_be_computed) + .sorted_unstable() + .rev(); + + let mut set_union = set_union.peekable(); + + let mut set_union_as_ordered_pairs = Vec::new(); + while set_union.peek().is_some() { + let right_index = *set_union.next().unwrap(); + + // Crashes on odd-length of input list, which is what we want, as + // this acts as a sanity check. + let left_index = *set_union.next().unwrap(); + set_union_as_ordered_pairs.push((left_index, right_index)); + } + + ( + set_difference.sorted_unstable().rev().collect(), + set_union_as_ordered_pairs, + ) + } + + pub fn root_from_authentication_struct( + &self, + tree_height: u32, + auth_struct: Vec, + indexed_leafs: Vec<(u64, Digest)>, + ) -> Digest { + fn digest_to_xfe(digest: Digest, challenge: XFieldElement) -> XFieldElement { + let leaf_xfe_lo = XFieldElement::new([digest.0[0], digest.0[1], digest.0[2]]); + let leaf_xfe_hi = challenge + * XFieldElement::new([digest.0[3], digest.0[4], BFieldElement::one()]); + + leaf_xfe_lo + leaf_xfe_hi + } + + fn node_index_to_bfe(node_index: u64) -> BFieldElement { + BFieldElement::new(node_index) + } + + // Sanity check + assert_eq!( + self.nd_auth_struct_indices.len(), + auth_struct.len(), + "Provided auth struct length must match that specified in receiver" + ); + + // Get challenges + let (alpha, beta, gamma) = { + let mut sponge = Tip5::init(); + sponge.pad_and_absorb_all(&indexed_leafs.encode()); + sponge.pad_and_absorb_all(&auth_struct.encode()); + let challenges = sponge.sample_scalars(3); + (challenges[0], challenges[1], challenges[2]) + }; + + // Accumulate `p` from public data + let mut p = XFieldElement::one(); + for i in (0..indexed_leafs.len()).rev() { + let node_index_as_bfe = node_index_to_bfe((1 << tree_height) ^ indexed_leafs[i].0); + let leaf_as_xfe = digest_to_xfe(indexed_leafs[i].1, alpha); + let fact = leaf_as_xfe - beta + gamma * node_index_as_bfe; + p *= fact; + } + + let mut prev = 0; + for i in (0..auth_struct.len()).rev() { + let auth_struct_index = self.nd_auth_struct_indices[i]; + + // `auth_struct` must be sorted high-to-low by node-index. But since + // we're traversing in reverse order, the inequality is flipped. + assert!(auth_struct_index > prev); + prev = auth_struct_index; + + let auth_struct_index_as_bfe = node_index_to_bfe(auth_struct_index); + + let auth_str_elem_as_xfe = digest_to_xfe(auth_struct[i], alpha); + let fact = auth_str_elem_as_xfe - beta + gamma * auth_struct_index_as_bfe; + p *= fact; + } + + // Use secret data to invert `p` back and to calculate the root + let mut t = auth_struct + .first() + .copied() + .unwrap_or_else(|| indexed_leafs.first().unwrap().1); + let mut t_xfe = digest_to_xfe(t, alpha); + let mut parent_index_bfe = BFieldElement::one(); + for ((l, r), (left_index, right_index)) in self + .nd_siblings + .iter() + .zip_eq(self.nd_sibling_indices.clone()) + { + assert_eq!(left_index + 1, right_index); + + t = Tip5::hash_pair(*l, *r); + + let l_xfe = digest_to_xfe(*l, alpha); + let r_xfe = digest_to_xfe(*r, alpha); + t_xfe = digest_to_xfe(t, alpha); + + let left_index_bfe = node_index_to_bfe(left_index); + let right_index_bfe = node_index_to_bfe(right_index); + parent_index_bfe = left_index_bfe / bfe!(2); + + let fact1 = l_xfe - beta + gamma * left_index_bfe; + let fact2 = r_xfe - beta + gamma * right_index_bfe; + let fact_parent = t_xfe - beta + gamma * parent_index_bfe; + + p *= fact1.inverse() * fact2.inverse() * fact_parent; + } + + assert_eq!(t_xfe - beta + gamma, p); + assert!(parent_index_bfe.is_one()); + + t + } + + /// Return the authentication structure authenticity witness, + /// authentication structure, and the (leaf-index, leaf-digest) pairs + /// from a list of MMR membership proofs. All MMR membership proofs must + /// belong under the same peak, i.e., be part of the same Merkle tree in + /// the list of Merkle trees that the MMR contains. + /// + /// Panics if the input list of MMR-membership proofs is empty, or if they + /// do not all belong under the same peak. + pub fn new_from_mmr_membership_proofs( + mmra: &MmrAccumulator, + indexed_mmr_mps: Vec<(u64, Digest, MmrMembershipProof)>, + ) -> HashMap { + #[derive(Clone, Debug)] + struct IndexedAuthenticatedMmrLeaf { + merkle_tree_node_index: u64, + merkle_tree_leaf_index: u64, + leaf_digest: Digest, + membership_proof: MmrMembershipProof, + } + + // Split indexed MMR-mps into a hashmap with one entry for each + // referenced peak in the MMR. + let num_mmr_leafs = mmra.num_leafs(); + let mut peak_index_to_indexed_mmr_mp: HashMap> = + HashMap::default(); + let peak_heights = get_peak_heights(num_mmr_leafs); + for (mmr_leaf_index, leaf, mmr_mp) in indexed_mmr_mps { + let (mt_index, peak_index) = + leaf_index_to_mt_index_and_peak_index(mmr_leaf_index, num_mmr_leafs); + let peak_index_as_usize: usize = peak_index.try_into().unwrap(); + let num_leafs_local_mt = 1 << peak_heights[peak_index_as_usize]; + let mt_leaf_index = mt_index - num_leafs_local_mt; + peak_index_to_indexed_mmr_mp + .entry(peak_index) + .or_default() + .push(IndexedAuthenticatedMmrLeaf { + merkle_tree_node_index: mt_index, + merkle_tree_leaf_index: mt_leaf_index, + leaf_digest: leaf, + membership_proof: mmr_mp, + }); + } + + // Loop over all peaks and collect an authentication witness struct + // for each peak. + let mut peak_index_to_authenticated_auth_struct = HashMap::default(); + for (peak_index, indexed_mmr_mp_structs) in peak_index_to_indexed_mmr_mp { + let peak_index_as_usize: usize = peak_index.try_into().unwrap(); + let num_leafs_in_local_mt = 1 << peak_heights[peak_index_as_usize]; + let local_mt_leaf_indices = indexed_mmr_mp_structs + .iter() + .map(|x| x.merkle_tree_leaf_index) + .collect_vec(); + + let (nd_auth_struct_indices, nd_sibling_indices) = + Self::auth_struct_and_nd_indices(num_leafs_in_local_mt, &local_mt_leaf_indices); + let peak = mmra.peaks()[peak_index_as_usize]; + + let mut node_digests: HashMap = HashMap::default(); + node_digests.insert(ROOT_MT_INDEX, peak); + + // Loop over all indexed leafs for this peak + for indexed_mmr_mp in indexed_mmr_mp_structs.iter() { + let mut mt_node_index = indexed_mmr_mp.merkle_tree_node_index; + let mut node = indexed_mmr_mp.leaf_digest; + + // Loop over all authentication path elements for this indexed leaf + for ap_elem in indexed_mmr_mp.membership_proof.authentication_path.iter() { + node_digests.insert(mt_node_index, node); + node_digests.insert(mt_node_index ^ 1, *ap_elem); + node = if mt_node_index & 1 == 0 { + Tip5::hash_pair(node, *ap_elem) + } else { + Tip5::hash_pair(*ap_elem, node) + }; + + mt_node_index /= 2; + } + + // Sanity check that MMR-MPs are valid + assert_eq!(peak, node, "Derived peak must match provided peak"); + } + let nd_siblings = nd_sibling_indices + .iter() + .map(|(left_idx, right_idx)| (node_digests[left_idx], node_digests[right_idx])) + .collect_vec(); + let auth_struct = nd_auth_struct_indices + .iter() + .map(|idx| node_digests[idx]) + .collect_vec(); + let indexed_leafs = indexed_mmr_mp_structs + .into_iter() + .map(|indexed_mmr_mp| { + ( + indexed_mmr_mp.merkle_tree_leaf_index, + indexed_mmr_mp.leaf_digest, + ) + }) + .collect_vec(); + + let witness = Self { + nd_auth_struct_indices, + nd_sibling_indices, + nd_siblings, + }; + + peak_index_to_authenticated_auth_struct.insert( + peak_index, + AuthenticatedMerkleAuthStruct { + auth_struct, + indexed_leafs, + witness, + }, + ); + } + + peak_index_to_authenticated_auth_struct + } + + /// Return the authentication structure witness, authentication structure, + /// and the (leaf-index, leaf-digest) pairs. + pub fn new_from_merkle_tree( + tree: &MerkleTree, + mut revealed_leaf_indices: Vec, + ) -> AuthenticatedMerkleAuthStruct { + revealed_leaf_indices.sort_unstable(); + revealed_leaf_indices.dedup(); + revealed_leaf_indices.reverse(); + let num_leafs: u64 = tree.num_leafs() as u64; + + let (mut nd_auth_struct_indices, nd_sibling_indices) = + Self::auth_struct_and_nd_indices(num_leafs, &revealed_leaf_indices); + if revealed_leaf_indices.is_empty() { + nd_auth_struct_indices = vec![ROOT_MT_INDEX]; + } + + let nd_siblings = nd_sibling_indices + .iter() + .map(|&(l, r)| { + let l: usize = l.try_into().unwrap(); + let r: usize = r.try_into().unwrap(); + (tree.node(l).unwrap(), tree.node(r).unwrap()) + }) + .collect_vec(); + + let revealed_leafs = revealed_leaf_indices + .iter() + .map(|j| tree.node((*j + num_leafs) as usize).unwrap()) + .collect_vec(); + let indexed_leafs = revealed_leaf_indices + .clone() + .into_iter() + .zip_eq(revealed_leafs) + .collect_vec(); + + let auth_struct = nd_auth_struct_indices + .iter() + .map(|node_index| tree.node(*node_index as usize).unwrap()) + .collect_vec(); + + let witness = Self { + nd_auth_struct_indices, + nd_sibling_indices, + nd_siblings, + }; + + AuthenticatedMerkleAuthStruct { + auth_struct, + indexed_leafs, + witness, + } + } + } +} From 923f4b931fbc36b5b5e6cfb69de9b0973c69ca52 Mon Sep 17 00:00:00 2001 From: sword-smith Date: Mon, 12 Aug 2024 23:24:52 +0200 Subject: [PATCH 02/14] mmr::authentication_struct: implement snipet and disallow empty list of leafs When calculating the root, don't allow the list of leafs to be empty. We think we never need the snippet with those inputs, so that should be fine. It makes the initialization of the `t` value (that should end up containing the root) simpler, as we can do: ```rust let mut t = indexed_leafs.first().unwrap().1; ``` instead of ```rust let mut t = auth_struct .first() .copied() .unwrap_or_else(|| indexed_leafs.first().unwrap().1); ``` Code works with sane test. --- ...thentication_struct_derive_challenges.json | 24 + tasm-lib/src/mmr.rs | 1 - tasm-lib/src/mmr/authentication_struct.rs | 2 + .../derive_challenges.rs | 248 +++++ .../root_from_authentication_struct.rs | 863 ++++++++---------- .../src/mmr/authentication_struct/shared.rs | 53 +- .../src/rust_shadowing_helper_functions.rs | 27 + .../rust_shadowing_helper_functions/memory.rs | 15 + 8 files changed, 731 insertions(+), 502 deletions(-) create mode 100644 tasm-lib/benchmarks/tasmlib_mmr_authentication_struct_derive_challenges.json create mode 100644 tasm-lib/src/mmr/authentication_struct/derive_challenges.rs rename tasm-lib/src/mmr/{ => authentication_struct}/root_from_authentication_struct.rs (52%) create mode 100644 tasm-lib/src/rust_shadowing_helper_functions/memory.rs diff --git a/tasm-lib/benchmarks/tasmlib_mmr_authentication_struct_derive_challenges.json b/tasm-lib/benchmarks/tasmlib_mmr_authentication_struct_derive_challenges.json new file mode 100644 index 000000000..e317de7aa --- /dev/null +++ b/tasm-lib/benchmarks/tasmlib_mmr_authentication_struct_derive_challenges.json @@ -0,0 +1,24 @@ +[ + { + "name": "tasmlib_mmr_authentication_struct_derive_challenges", + "benchmark_result": { + "clock_cycle_count": 1196, + "hash_table_height": 985, + "u32_table_height": 25, + "op_stack_table_height": 833, + "ram_table_height": 1454 + }, + "case": "CommonCase" + }, + { + "name": "tasmlib_mmr_authentication_struct_derive_challenges", + "benchmark_result": { + "clock_cycle_count": 2102, + "hash_table_height": 1891, + "u32_table_height": 26, + "op_stack_table_height": 1437, + "ram_table_height": 2964 + }, + "case": "WorstCase" + } +] \ No newline at end of file diff --git a/tasm-lib/src/mmr.rs b/tasm-lib/src/mmr.rs index 9ef3b582f..803819eca 100644 --- a/tasm-lib/src/mmr.rs +++ b/tasm-lib/src/mmr.rs @@ -3,7 +3,6 @@ pub mod bag_peaks; pub mod calculate_new_peaks_from_append; pub mod calculate_new_peaks_from_leaf_mutation; pub mod leaf_index_to_mt_index_and_peak_index; -pub mod root_from_authentication_struct; pub mod verify_from_memory; pub mod verify_from_secret_in_leaf_index_on_stack; pub mod verify_from_secret_in_secret_leaf_index; diff --git a/tasm-lib/src/mmr/authentication_struct.rs b/tasm-lib/src/mmr/authentication_struct.rs index eec3c896b..2406a8f55 100644 --- a/tasm-lib/src/mmr/authentication_struct.rs +++ b/tasm-lib/src/mmr/authentication_struct.rs @@ -1 +1,3 @@ +pub mod derive_challenges; +pub mod root_from_authentication_struct; pub mod shared; diff --git a/tasm-lib/src/mmr/authentication_struct/derive_challenges.rs b/tasm-lib/src/mmr/authentication_struct/derive_challenges.rs new file mode 100644 index 000000000..a4920f92d --- /dev/null +++ b/tasm-lib/src/mmr/authentication_struct/derive_challenges.rs @@ -0,0 +1,248 @@ +use triton_vm::prelude::*; + +use crate::data_type::DataType; +use crate::hashing::absorb_multiple::AbsorbMultiple; +use crate::mmr::authentication_struct::shared; +use crate::prelude::BasicSnippet; +use crate::Library; + +/// Derive and return the challenges that the authentication structure verification +/// program uses. +pub struct DeriveChallenges; + +impl BasicSnippet for DeriveChallenges { + fn inputs(&self) -> Vec<(DataType, String)> { + vec![ + ( + DataType::List(Box::new(DataType::Digest)), + "auth_struct".to_owned(), + ), + ( + DataType::List(Box::new(shared::indexed_leaf_element_type())), + "indexed_leafs".to_owned(), + ), + ] + } + + fn outputs(&self) -> Vec<(DataType, String)> { + vec![ + (DataType::Xfe, "alpha".to_owned()), + (DataType::Xfe, "-beta".to_owned()), + (DataType::Xfe, "gamma".to_owned()), + ] + } + + fn entrypoint(&self) -> String { + "tasmlib_mmr_authentication_struct_derive_challenges".to_owned() + } + + fn code(&self, library: &mut Library) -> Vec { + let absorb_multiple = library.import(Box::new(AbsorbMultiple)); + + let entrypoint = self.entrypoint(); + + let indexed_leaf_element_size = shared::indexed_leaf_element_type().stack_size(); + triton_asm!( + {entrypoint}: + // _ *auth_struct *indexed_leafs + + sponge_init + // _ *auth_struct *indexed_leafs + + read_mem 1 + push 1 + add + // _ *auth_struct indexed_leafs_len *indexed_leafs + + swap 1 + // _ *auth_struct *indexed_leafs indexed_leafs_len + + push {indexed_leaf_element_size} + mul + push 1 + add + // _ *auth_struct *indexed_leafs indexed_leafs_size + + call {absorb_multiple} + // _ *auth_struct + + read_mem 1 + push 1 + add + // _ auth_struct_len *auth_struct + + swap 1 + push {Digest::LEN} + mul + push 1 + add + // _ *auth_struct auth_struct_size + + call {absorb_multiple} + // _ + + sponge_squeeze + // _ w9 w8 w7 w6 w5 w4 w3 w2 w1 w0 + + pop 1 + // _ w9 w8 w7 w6 w5 w4 w3 w2 w1 + // _ [gamma] [-beta] [alpha] <- rename + + return + ) + } +} + +#[cfg(test)] +mod tests { + use std::collections::HashMap; + + use itertools::Itertools; + use num::One; + use rand::rngs::StdRng; + use rand::Rng; + use rand::SeedableRng; + use shared::AuthenticatedMerkleAuthStruct; + use twenty_first::prelude::Sponge; + use twenty_first::util_types::mmr::mmr_accumulator::util::mmra_with_mps; + + use crate::mmr::authentication_struct::shared::AuthStructIntegrityProof; + use crate::rust_shadowing_helper_functions::list::list_insert; + use crate::rust_shadowing_helper_functions::list::load_list_with_copy_elements; + use crate::snippet_bencher::BenchmarkCase; + use crate::traits::procedure::Procedure; + use crate::traits::procedure::ProcedureInitialState; + use crate::traits::procedure::ShadowedProcedure; + use crate::traits::rust_shadow::RustShadow; + use crate::VmHasher; + + use super::*; + + const SIZE_OF_INDEXED_LEAFS_ELEMENT: usize = Digest::LEN + 2; + + #[test] + fn test() { + ShadowedProcedure::new(DeriveChallenges).test(); + } + + impl Procedure for DeriveChallenges { + fn rust_shadow( + &self, + stack: &mut Vec, + memory: &mut HashMap, + _nondeterminism: &NonDeterminism, + _public_input: &[BFieldElement], + sponge: &mut Option, + ) -> Vec { + let indexed_leafs_pointer = stack.pop().unwrap(); + let auth_struct_pointer = stack.pop().unwrap(); + let bfes_to_indexed_leaf = + |bfes: [BFieldElement; SIZE_OF_INDEXED_LEAFS_ELEMENT]| -> (u64, Digest) { + *<(u64, Digest)>::decode(&bfes).unwrap() + }; + let bfes_to_digest = |bfes: [BFieldElement; Digest::LEN]| -> Digest { + *Digest::decode(&bfes[0..Digest::LEN]).unwrap() + }; + let indexed_leafs: Vec<[BFieldElement; SIZE_OF_INDEXED_LEAFS_ELEMENT]> = + load_list_with_copy_elements(indexed_leafs_pointer, memory); + let indexed_leafs = indexed_leafs + .into_iter() + .map(bfes_to_indexed_leaf) + .collect_vec(); + let auth_struct: Vec<[BFieldElement; Digest::LEN]> = + load_list_with_copy_elements(auth_struct_pointer, memory); + let auth_struct = auth_struct.into_iter().map(bfes_to_digest).collect_vec(); + + let sponge = sponge.as_mut().expect("sponge must be initialized"); + + sponge.pad_and_absorb_all(&indexed_leafs.encode()); + sponge.pad_and_absorb_all(&auth_struct.encode()); + + let sponge_output = sponge.squeeze(); + for elem in sponge_output.into_iter().skip(1).rev() { + stack.push(elem); + } + + vec![] + } + + fn pseudorandom_initial_state( + &self, + seed: [u8; 32], + bench_case: Option, + ) -> ProcedureInitialState { + let mut rng: StdRng = SeedableRng::from_seed(seed); + + let (tree_height, num_revealed_leafs) = match bench_case { + Some(BenchmarkCase::CommonCase) => (32, 10), + Some(BenchmarkCase::WorstCase) => (62, 10), + None => (rng.gen_range(0..62), 10), + }; + + let leaf_count = 1 << tree_height; + let revealed_leaf_indices = (0..num_revealed_leafs) + .map(|_| rng.gen_range(0..leaf_count)) + .unique() + .collect_vec(); + let indexed_leafs = revealed_leaf_indices + .into_iter() + .map(|leaf_idx: u64| (leaf_idx, rng.gen())) + .collect_vec(); + let (mmra, mps) = mmra_with_mps(leaf_count, indexed_leafs.clone()); + let indexed_mmr_mps = indexed_leafs + .into_iter() + .zip_eq(mps) + .map(|((leaf_idx, leaf), mp)| (leaf_idx, leaf, mp)) + .collect_vec(); + let authenticity_witnesses = + AuthStructIntegrityProof::new_from_mmr_membership_proofs(&mmra, indexed_mmr_mps); + assert!( + authenticity_witnesses.len().is_one(), + "All indices belong to first peak" + ); + let AuthenticatedMerkleAuthStruct { + auth_struct, + indexed_leafs, + .. + } = &authenticity_witnesses[&0]; + + let mut memory = HashMap::new(); + let authentication_structure_ptr = rng.gen(); + let indexed_leafs_ptr = rng.gen(); + + list_insert( + authentication_structure_ptr, + auth_struct.to_owned(), + &mut memory, + ); + list_insert(indexed_leafs_ptr, indexed_leafs.to_owned(), &mut memory); + + let stack = [ + self.init_stack_for_isolated_run(), + vec![authentication_structure_ptr, indexed_leafs_ptr], + ] + .concat(); + + let nondeterminism = NonDeterminism::default().with_ram(memory); + ProcedureInitialState { + stack, + nondeterminism, + public_input: vec![], + sponge: Some(Tip5::init()), + } + } + } +} + +#[cfg(test)] +mod benches { + use crate::traits::procedure::ShadowedProcedure; + use crate::traits::rust_shadow::RustShadow; + + use super::*; + + #[test] + fn bag_peaks_benchmark() { + ShadowedProcedure::new(DeriveChallenges).bench(); + } +} diff --git a/tasm-lib/src/mmr/root_from_authentication_struct.rs b/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs similarity index 52% rename from tasm-lib/src/mmr/root_from_authentication_struct.rs rename to tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs index 4a8a16a82..404ba496c 100644 --- a/tasm-lib/src/mmr/root_from_authentication_struct.rs +++ b/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs @@ -1,9 +1,10 @@ use triton_vm::prelude::*; use twenty_first::math::x_field_element::EXTENSION_DEGREE; +use twenty_first::prelude::Inverse; use crate::data_type::DataType; -use crate::hashing::absorb_multiple::AbsorbMultiple; use crate::library::Library; +use crate::mmr::authentication_struct::derive_challenges::DeriveChallenges; use crate::prelude::BasicSnippet; pub struct RootFromAuthenticationStruct; @@ -38,7 +39,6 @@ impl BasicSnippet for RootFromAuthenticationStruct { } fn code(&self, library: &mut Library) -> Vec { - let absorb_multiple = library.import(Box::new(AbsorbMultiple)); let alpha_challenge_pointer_write = library.kmalloc(EXTENSION_DEGREE as u32); let alpha_challenge_pointer_read = alpha_challenge_pointer_write + bfe!(EXTENSION_DEGREE as u64 - 1); @@ -48,51 +48,19 @@ impl BasicSnippet for RootFromAuthenticationStruct { let gamma_challenge_pointer_write = library.kmalloc(EXTENSION_DEGREE as u32); let gamma_challenge_pointer_read = gamma_challenge_pointer_write + bfe!(EXTENSION_DEGREE as u64 - 1); + let t_digest_pointer_write = library.kmalloc(Digest::LEN as u32); + let t_digest_pointer_read = t_digest_pointer_write + bfe!(Digest::LEN as u64 - 1); + let t_xfe_pointer_write = library.kmalloc(EXTENSION_DEGREE as u32); + let t_xfe_pointer_read = t_xfe_pointer_write + bfe!(EXTENSION_DEGREE as u64 - 1); + let p_pointer_write = library.kmalloc(EXTENSION_DEGREE as u32); + let p_pointer_read = p_pointer_write + bfe!(EXTENSION_DEGREE as u64 - 1); let indexed_leaf_element_size = Self::indexed_leaf_element_type().stack_size(); + let derive_challenges = library.import(Box::new(DeriveChallenges)); let calculate_and_store_challenges = triton_asm!( // _ *auth_struct *indexed_leafs - sponge_init - // _ *auth_struct *indexed_leafs - - read_mem 1 - push 1 - add - // _ *auth_struct indexed_leafs_len *indexed_leafs - - swap 1 - // _ *auth_struct *indexed_leafs indexed_leafs_len - - push {indexed_leaf_element_size} - mul - push 1 - add - // _ *auth_struct *indexed_leafs indexed_leafs_size - - call {absorb_multiple} - // _ *auth_struct - - read_mem 1 - push 1 - add - // _ auth_struct_len *auth_struct - - swap 1 - push {Digest::LEN} - mul - push 1 - add - // _ *auth_struct auth_struct_size - - call {absorb_multiple} - // _ - - sponge_squeeze - // _ w9 w8 w7 w6 w5 w4 w3 w2 w1 w0 - - pop 1 - // _ w9 w8 w7 w6 w5 w4 w3 w2 w1 + call {derive_challenges} hint alpha: XFieldElement = stack[0..3] hint minus_beta: XFieldElement = stack[3..6] hint gamma: XFieldElement = stack[6..9] @@ -165,6 +133,8 @@ impl BasicSnippet for RootFromAuthenticationStruct { pop 1 // _ num_leafs *auth_struct *idx_leafs (*idx_leafs[n]_lw - 2) [0; 2] [p; 3] [γ] [leaf_idx; 2] + // TODO: Assert that `leaf_idx < num_leafs`? + {&u64_to_bfe} // _ num_leafs *auth_struct *idx_leafs (*idx_leafs[n]_lw - 2) [0; 2] [p; 3] [γ] leaf_idx_bfe @@ -214,6 +184,15 @@ impl BasicSnippet for RootFromAuthenticationStruct { swap 1 // _ num_leafs *auth_struct *indexed_leafs *indexed_leafs indexed_leafs_len + /* Disallow empty list of indexed leafs */ + dup 0 + push 0 + eq + push 0 + eq + assert + // _ num_leafs *auth_struct *indexed_leafs *indexed_leafs indexed_leafs_len + push {indexed_leaf_element_size} mul // _ num_leafs *auth_struct *indexed_leafs *indexed_leafs (indexed_leafs_size - 1) @@ -346,21 +325,187 @@ impl BasicSnippet for RootFromAuthenticationStruct { recurse_or_return ); - let set_initial_t_value = triton_asm!( - // _ num_leafs *indexed_leafs *auth_struct [p] + let nd_loop_label = format!("{entrypoint}_nd_loop"); + let dup_top_two_digests = triton_asm![dup 9; Digest::LEN * 2]; + let dup_top_digest = triton_asm![dup 4; Digest::LEN]; + let dup_top_xfe = triton_asm![dup 2; EXTENSION_DEGREE]; + let one_half = BFieldElement::new(2).inverse(); + let nd_loop = triton_asm!( + // _ INVARIANT: _ + {nd_loop_label}: + divine 1 + // _ left_index - /* Set `t` digest to according to the rules: - let mut t = auth_struct - .first() - .copied() - .unwrap_or_else(|| indexed_leafs.first().unwrap().1); - */ - dup 3 - read_mem 1 - pop 1 - // _ num_leafs *indexed_leafs *auth_struct [p] auth_struct_len + divine 1 + // _ left_index right_index + + dup 1 + push 1 + add + eq + // _ l_index_bfe (left_index + 1 == right_index) + + assert + // _ l_index_bfe + + /* Update parent index */ + push {one_half} + mul + hint parent_index: BFieldElement = stack[0..1] + // _ (l_index_bfe / 2) + // _ parent_index <-- rename + + /* Calculate parent digest, preserving child digests */ + divine {Digest::LEN} + hint right: Digest = stack[0..5] + + divine {Digest::LEN} + hint left: Digest = stack[0..5] + + {&dup_top_two_digests} + hash + hint t: Digest = stack[0..5] + // _ parent_index [right] [left] [t] + + {&dup_top_digest} + push {t_digest_pointer_write} + write_mem {Digest::LEN} + pop 1 + // _ parent_index [right] [left] [t] + + {&digest_to_xfe} + hint t_xfe: XFieldElement = stack[0..3] + // _ parent_index [right] [left] [t_xfe] + + {&dup_top_xfe} + push {t_xfe_pointer_write} + write_mem {EXTENSION_DEGREE} + pop 1 + // _ parent_index [right] [left] [t_xfe] + + push {beta_challenge_pointer_read} + read_mem {EXTENSION_DEGREE} + pop 1 + xx_add + // _ parent_index [right] [left] [t_xfe - β] + + dup 13 + push {gamma_challenge_pointer_read} + read_mem {EXTENSION_DEGREE} + pop 1 + // _ parent_index [right] [left] [t_xfe - β] parent_index [γ] + + swap 1 + swap 2 + swap 3 + xb_mul + // _ parent_index [right] [left] [t_xfe - β] [γ * parent_index] + + xx_add + // _ parent_index [right] [left] [t_xfe - β + γ * parent_index] + // _ parent_index [right] [left] [fact_parent] <-- rename + + /* Accumulate `fact_parent` into `p` */ + push {p_pointer_read} + read_mem {EXTENSION_DEGREE} + pop 1 + xx_mul + push {p_pointer_write} + write_mem {EXTENSION_DEGREE} + pop 1 + // _ parent_index [right] [left] + + /* Claculate `fact_1` */ + {&digest_to_xfe} + // _ parent_index [right] [left_xfe] + + push {beta_challenge_pointer_read} + read_mem {EXTENSION_DEGREE} + pop 1 + xx_add + // _ parent_index [right] [left_xfe - β] + + push {gamma_challenge_pointer_read} + read_mem {EXTENSION_DEGREE} + pop 1 + // _ parent_index [right] [left_xfe - β] [γ] + + dup 11 + push 2 + mul + // _ parent_index [right] [left_xfe - β] [γ] left_index + + xb_mul + // _ parent_index [right] [left_xfe - β] [γ * left_index] + + xx_add + // _ parent_index [right] [left_xfe - β + γ * left_index] + // _ parent_index [right] [fact_1] <-- rename + + x_invert + // _ parent_index [right] [fact_1^{-1}] + + /* Divide `fact_1` out of `p` */ + push {p_pointer_read} + read_mem {EXTENSION_DEGREE} + pop 1 + xx_mul + push {p_pointer_write} + write_mem {EXTENSION_DEGREE} + pop 1 + // _ parent_index [right] + + /* Calculate `fact_2` */ + {&digest_to_xfe} + // _ parent_index [right_xfe] + + push {beta_challenge_pointer_read} + read_mem {EXTENSION_DEGREE} + pop 1 + xx_add + // _ parent_index [right_xfe - β] + + push {gamma_challenge_pointer_read} + read_mem {EXTENSION_DEGREE} + pop 1 + // _ parent_index [right_xfe - β] [γ] + + dup 6 + push 2 + mul + push 1 + add + // _ parent_index [right_xfe - β] [γ] right_index + + xb_mul + // _ parent_index [right_xfe - β] [right_index * γ] + + xx_add + // _ parent_index [right_xfe - β + right_index * γ] + // _ parent_index [fact_2] <-- rename + + x_invert + // _ parent_index [fact_2^{-1}] + + /* Divide `fact_2` out of `p` */ + push {p_pointer_read} + read_mem {EXTENSION_DEGREE} + pop 1 + xx_mul + push {p_pointer_write} + write_mem {EXTENSION_DEGREE} + pop 1 + // _ parent_index + + push 1 + eq + skiz + return + + recurse ); + let compare_xfes = DataType::Xfe.compare(); triton_asm!( {entrypoint}: // _ tree_height *auth_struct *indexed_leafs @@ -372,65 +517,146 @@ impl BasicSnippet for RootFromAuthenticationStruct { {&calculate_and_store_challenges} // _ tree_height *auth_struct *indexed_leafs - /* Calculate number of leafs in Merkle tree */ + /* Calculate number of leafs in Merkle tree + Notice that `tree_num_leafs` is not necessarily a u32, but is a + BFE and a power of two whose log_2 value is in the range + [0,63] */ swap 2 push 2 pow swap 2 - hint num_leafs = stack[2] - // _ num_leafs *auth_struct *indexed_leafs + hint tree_num_leafs: BFieldElement = stack[2] + // _ tree_num_leafs *auth_struct *indexed_leafs {&accumulate_indexed_leafs_from_public_data} - // _ num_leafs *auth_struct *indexed_leafs *indexed_leafs [garbage; 2] [p; 3] - // _ num_leafs *auth_struct *indexed_leafs *indexed_leafs [garbage; 2] p2 p1 p0 <-- rename + // _ tree_num_leafs *auth_struct *indexed_leafs *indexed_leafs [garbage; 2] [p; 3] + // _ tree_num_leafs *auth_struct *indexed_leafs *indexed_leafs [garbage; 2] p2 p1 p0 <-- rename /* Prepare for next loop, absorption of auth-struct digests into accumulator */ swap 7 swap 6 pop 1 - // _ num_leafs p0 *auth_struct *indexed_leafs [0; 2] p2 p1 + // _ tree_num_leafs p0 *auth_struct *indexed_leafs [0; 2] p2 p1 dup 5 read_mem 1 push 1 add swap 1 - // _ num_leafs p0 *auth_struct *indexed_leafs [0; 2] p2 p1 *auth_struct auth_struct_len + // _ tree_num_leafs p0 *auth_struct *indexed_leafs [0; 2] p2 p1 *auth_struct auth_struct_len push {Digest::LEN} mul add - // _ num_leafs p0 *auth_struct *indexed_leafs [0; 2] p2 p1 *auth_struct_last_word + // _ tree_num_leafs p0 *auth_struct *indexed_leafs [0; 2] p2 p1 *auth_struct_last_word swap 5 swap 7 - // _ num_leafs *indexed_leafs *auth_struct *auth_struct_last_word [0; 2] p2 p1 p0 - // _ num_leafs *indexed_leafs *auth_struct *auth_struct_last_word [prev; 2] [p] <-- rename + // _ tree_num_leafs *indexed_leafs *auth_struct *auth_struct_last_word [0; 2] p2 p1 p0 + // _ tree_num_leafs *indexed_leafs *auth_struct *auth_struct_last_word [prev; 2] [p] <-- rename dup 6 dup 6 eq push 0 eq - // _ num_leafs *indexed_leafs *auth_struct *auth_struct_last_word [prev; 2] [p] (*auth_struct_last_word != *auth_struct) + // _ tree_num_leafs *indexed_leafs *auth_struct *auth_struct_last_word [prev; 2] [p] (*auth_struct_last_word != *auth_struct) skiz call {accumulate_auth_struct_leafs_from_public_data_label} - // _ num_leafs *indexed_leafs *auth_struct *auth_struct_last_word [prev; 2] [p] + // _ tree_num_leafs *indexed_leafs *auth_struct *auth_struct_last_word [prev; 2] [p] /* Cleanup stack before next loop */ - swap 3 + swap 4 pop 1 - swap 3 + swap 4 pop 1 - swap 3 + swap 4 + pop 2 + // _ tree_num_leafs *indexed_leafs [p] + + /* Set initial t values, from indexed_leafs[0] */ + dup 3 + push {Digest::LEN} + add + read_mem {Digest::LEN} + pop 1 + // _ tree_num_leafs *indexed_leafs [p] [t; 5] + + dup 4 + dup 4 + dup 4 + dup 4 + dup 4 + {&digest_to_xfe} + // _ tree_num_leafs *indexed_leafs [p] [t; 5] [t_xfe] + + /* Write t values, and `p` to static memory */ + push {t_xfe_pointer_write} + write_mem {EXTENSION_DEGREE} pop 1 - // _ num_leafs *indexed_leafs *auth_struct [p] + push {t_digest_pointer_write} + write_mem {Digest::LEN} + pop 1 + // _ tree_num_leafs *indexed_leafs [p] + + push {p_pointer_write} + write_mem {EXTENSION_DEGREE} + pop 2 + // _ tree_num_leafs + + /* Call the ND-loop if tree_num_leafs != 1 */ + push 1 + eq + push 0 + eq + // (tree_num_leafs != 1) + + skiz + call {nd_loop_label} + // _ + + /* Assert that p == t_xfe - beta + gamma */ + break + push {p_pointer_read} + read_mem {EXTENSION_DEGREE} + pop 1 + // _ [p] + + push {t_xfe_pointer_read} + read_mem {EXTENSION_DEGREE} + pop 1 + // _ [p] [t_xfe] + + push {beta_challenge_pointer_read} + read_mem {EXTENSION_DEGREE} + pop 1 + xx_add + // _ [p] [t_xfe - β] + + push {gamma_challenge_pointer_read} + read_mem {EXTENSION_DEGREE} + pop 1 + xx_add + // _ [p] [t_xfe - β + γ] + + {&compare_xfes} + // _ (p == t_xfe - β + γ) + + assert + // _ + + /* Return `t` (digest) */ + push {t_digest_pointer_read} + read_mem {Digest::LEN} + pop 1 + // _ [t] return {&accumulated_indexed_leafs_loop} {&accumulate_auth_struct_leafs_from_public_data} + {&nd_loop} ) } } @@ -445,12 +671,16 @@ mod tests { use rand::rngs::StdRng; use rand::Rng; use rand::SeedableRng; + use twenty_first::prelude::AlgebraicHasher; use twenty_first::prelude::CpuParallel; use twenty_first::prelude::MerkleTree; use twenty_first::prelude::Sponge; + use crate::mmr::authentication_struct::shared::AuthStructIntegrityProof; + use crate::rust_shadowing_helper_functions::input::consume_digest_from_secret_in; use crate::rust_shadowing_helper_functions::list::list_insert; use crate::rust_shadowing_helper_functions::list::load_list_with_copy_elements; + use crate::rust_shadowing_helper_functions::memory::write_to_memory; use crate::snippet_bencher::BenchmarkCase; use crate::traits::procedure::Procedure; use crate::traits::procedure::ProcedureInitialState; @@ -484,6 +714,33 @@ mod tests { challenge * leaf_xfe_lo + leaf_xfe_hi } + fn mimic_use_of_static_memory( + memory: &mut HashMap, + alpha: XFieldElement, + beta: XFieldElement, + gamma: XFieldElement, + t: Digest, + t_xfe: XFieldElement, + p: XFieldElement, + ) { + const ALPHA_POINTER_WRITE: BFieldElement = BFieldElement::new(BFieldElement::P - 4); + const BETA_POINTER_WRITE: BFieldElement = BFieldElement::new(BFieldElement::P - 7); + const GAMMA_POINTER_WRITE: BFieldElement = + BFieldElement::new(BFieldElement::P - 10); + const T_DIGEST_POINTER_WRITE: BFieldElement = + BFieldElement::new(BFieldElement::P - 15); + const T_XFE_POINTER_WRITE: BFieldElement = + BFieldElement::new(BFieldElement::P - 18); + const P_POINTER_WRITE: BFieldElement = BFieldElement::new(BFieldElement::P - 21); + + write_to_memory(ALPHA_POINTER_WRITE, alpha, memory); + write_to_memory(BETA_POINTER_WRITE, beta, memory); + write_to_memory(GAMMA_POINTER_WRITE, gamma, memory); + write_to_memory(T_DIGEST_POINTER_WRITE, t, memory); + write_to_memory(T_XFE_POINTER_WRITE, t_xfe, memory); + write_to_memory(P_POINTER_WRITE, p, memory); + } + assert_eq!( SIZE_OF_INDEXED_LEAFS_ELEMENT, Self::indexed_leaf_element_type().stack_size() @@ -497,20 +754,17 @@ mod tests { *<(u64, Digest)>::decode(&bfes).unwrap() }; let bfes_to_digest = |bfes: [BFieldElement; Digest::LEN]| -> Digest { - println!("bfes_to_digest:\nbfes: {bfes:?}"); *Digest::decode(&bfes[0..Digest::LEN]).unwrap() }; let indexed_leafs: Vec<[BFieldElement; SIZE_OF_INDEXED_LEAFS_ELEMENT]> = load_list_with_copy_elements(indexed_leafs_pointer, memory); - println!("indexed_leafs: {indexed_leafs:?}"); let indexed_leafs = indexed_leafs .into_iter() .map(bfes_to_indexed_leaf) .collect_vec(); let auth_struct: Vec<[BFieldElement; Digest::LEN]> = load_list_with_copy_elements(auth_struct_pointer, memory); - println!("auth_struct: {auth_struct:?}"); let auth_struct = auth_struct.into_iter().map(bfes_to_digest).collect_vec(); let sponge = sponge.as_mut().expect("sponge must be initialized"); @@ -522,28 +776,17 @@ mod tests { let alpha = XFieldElement::new([sponge_output[1], sponge_output[2], sponge_output[3]]); let beta = -XFieldElement::new([sponge_output[4], sponge_output[5], sponge_output[6]]); let gamma = XFieldElement::new([sponge_output[7], sponge_output[8], sponge_output[9]]); - println!("alpha {alpha}"); - println!("-beta {}", -beta); - println!("gamma {}", -gamma); - let num_leafs = 1 << tree_height; + let tree_num_leafs = 1 << tree_height; let mut p = XFieldElement::one(); for (leaf_idx, leaf) in indexed_leafs.iter().copied().rev() { let leaf_idx_as_bfe = bfe!(leaf_idx); - let node_idx_as_bfe = leaf_idx_as_bfe + bfe!(num_leafs); - + let node_idx_as_bfe = leaf_idx_as_bfe + bfe!(tree_num_leafs); let leaf_as_xfe = digest_to_xfe(leaf, alpha); - - println!("gamma * node_idx_as_bfe = {}", gamma * node_idx_as_bfe); - println!("leaf_as_xfe = {}", leaf_as_xfe); - let fact = leaf_as_xfe - beta + gamma * node_idx_as_bfe; - println!("indexed-leaf fact: {fact}"); p *= fact; } - println!("Rust-shadow, p, after indexed-leafs absorption: {p}"); - let mut prev = 0u64; let mut individual_tokens: VecDeque = nondeterminism.individual_tokens.to_owned().into(); @@ -554,7 +797,6 @@ mod tests { individual_tokens.pop_front().unwrap().try_into().unwrap(); let auth_struct_elem_node_index = ((auth_struct_elem_node_index_hi as u64) << 32) + auth_struct_elem_node_index_lo as u64; - println!("auth_struct_elem_node_index: {auth_struct_elem_node_index}"); assert!(auth_struct_elem_node_index > prev); prev = auth_struct_elem_node_index; @@ -563,11 +805,45 @@ mod tests { let auth_struct_elem_xfe = digest_to_xfe(auth_struct_elem, alpha); let fact = auth_struct_elem_xfe - beta + gamma * auth_struct_index_as_bfe; - println!("auth struct fact: {fact}"); p *= fact; } - println!("Rust-shadow, p, after auth-struct absorption: {p}"); + let mut t = indexed_leafs[0].1; + let mut t_xfe = digest_to_xfe(t, alpha); + if tree_num_leafs != 1 { + loop { + let left_index = individual_tokens.pop_front().unwrap(); + let right_index = individual_tokens.pop_front().unwrap(); + assert_eq!(left_index + bfe!(1), right_index); + + let parent_index = left_index / bfe!(2); + + let right = consume_digest_from_secret_in(&mut individual_tokens); + let left = consume_digest_from_secret_in(&mut individual_tokens); + + t = Tip5::hash_pair(left, right); + t_xfe = digest_to_xfe(t, alpha); + let l_xfe = digest_to_xfe(left, alpha); + let r_xfe = digest_to_xfe(right, alpha); + let fact1 = l_xfe - beta + gamma * left_index; + let fact2 = r_xfe - beta + gamma * right_index; + let fact_parent = t_xfe - beta + gamma * parent_index; + + p *= fact1.inverse() * fact2.inverse() * fact_parent; + + if parent_index.is_one() { + break; + } + } + } + + assert_eq!(t_xfe - beta + gamma, p); + + for elem in t.encode().into_iter().rev() { + stack.push(elem); + } + + mimic_use_of_static_memory(memory, alpha, -beta, gamma, t, t_xfe, p); vec![] } @@ -580,25 +856,28 @@ mod tests { let mut rng: StdRng = SeedableRng::from_seed(seed); // TODO: use real `mmr_authentication_struct` code here - let tree_height = rng.gen_range(1..5); + let tree_height = rng.gen_range(0..5); let leaf_count = 1 << tree_height; - let num_revealed_leafs = rng.gen_range(1..leaf_count); + let num_revealed_leafs = rng.gen_range(1..=leaf_count); let revealed_leaf_indices = (0..num_revealed_leafs) .map(|_| rng.gen_range(0..leaf_count)) .unique() .collect_vec(); + println!( + "revealed_leaf_indices: [{}]", + revealed_leaf_indices.iter().join(", ") + ); let leafs = (0..leaf_count).map(|_| rng.gen()).collect_vec(); let tree = MerkleTree::::new::(&leafs).unwrap(); let mmr_authentication_struct = - mmr_authentication_struct::AuthStructIntegrityProof::new_from_merkle_tree( - &tree, - revealed_leaf_indices, - ); + AuthStructIntegrityProof::new_from_merkle_tree(&tree, revealed_leaf_indices); + println!("tree.root() = {}", tree.root()); let mut memory = HashMap::new(); let authentication_structure_ptr = rng.gen(); let indexed_leafs_ptr = rng.gen(); + println!("leaf_count: {leaf_count}"); println!( "indexed_leafs.len(): {}", mmr_authentication_struct.indexed_leafs.len() @@ -637,13 +916,40 @@ mod tests { .iter() .join(", ") ); - let individual_tokens = mmr_authentication_struct + let nd_auth_struct_indices = mmr_authentication_struct .witness .nd_auth_struct_indices .into_iter() .rev() .flat_map(|node_index| node_index.encode().into_iter().rev().collect_vec()) .collect_vec(); + println!( + "nd_auth_struct_indices (encoded as BFEs): {}", + nd_auth_struct_indices.iter().join(", ") + ); + let nd_loop_nd = mmr_authentication_struct + .witness + .nd_sibling_indices + .iter() + .copied() + .zip_eq( + mmr_authentication_struct + .witness + .nd_siblings + .iter() + .copied(), + ) + .flat_map(|((left_index, right_index), (left_node, right_node))| { + [ + vec![bfe!(left_index), bfe!(right_index)], + right_node.encode().into_iter().rev().collect_vec(), + left_node.encode().into_iter().rev().collect_vec(), + ] + .concat() + }) + .collect_vec(); + + let individual_tokens = [nd_auth_struct_indices, nd_loop_nd].concat(); println!("individual_tokens: {}", individual_tokens.iter().join(", ")); let nondeterminism = NonDeterminism::new(individual_tokens).with_ram(memory); ProcedureInitialState { @@ -659,368 +965,3 @@ mod tests { } } } - -// TODO: Use this logic from `twenty-first` instead! -mod mmr_authentication_struct { - use std::collections::{HashMap, HashSet}; - - use itertools::Itertools; - use num::One; - use twenty_first::{ - prelude::{AlgebraicHasher, Inverse, MerkleTree, Mmr, MmrMembershipProof, Sponge}, - util_types::mmr::{ - mmr_accumulator::MmrAccumulator, shared_advanced::get_peak_heights, - shared_basic::leaf_index_to_mt_index_and_peak_index, - }, - }; - - use super::*; - - const ROOT_MT_INDEX: u64 = 1; - - /// A witness to facilitate the proving of the authenticity of a Merkle - /// authentication struct. - #[derive(Debug, Clone)] - pub struct AuthStructIntegrityProof { - // All indices are Merkle tree node indices - pub nd_auth_struct_indices: Vec, - pub nd_sibling_indices: Vec<(u64, u64)>, - pub nd_siblings: Vec<(Digest, Digest)>, - } - - /// An authentication structure that can be used to prove membership of a list - /// of leaves in a Merkle tree, along with the indexed leaves in question, and - /// the witness necessary to prove membership in a ZK program. - #[derive(Debug, Clone)] - pub struct AuthenticatedMerkleAuthStruct { - pub auth_struct: Vec, - pub indexed_leafs: Vec<(u64, Digest)>, - pub witness: AuthStructIntegrityProof, - } - - impl AuthStructIntegrityProof { - /// Return the Merkle tree node indices of the digests required to prove - /// membership for the specified leaf indices, as well as the node indices - /// that can be derived from the leaf indices and their authentication - /// path. - fn auth_struct_and_nd_indices( - num_leafs: u64, - leaf_indices: &[u64], - ) -> (Vec, Vec<(u64, u64)>) { - // The set of indices of nodes that need to be included in the authentications - // structure. In principle, every node of every authentication path is needed. - // The root is never needed. Hence, it is not considered below. - let mut node_is_needed = HashSet::new(); - - // The set of indices of nodes that can be computed from other nodes in the - // authentication structure or the leafs that are explicitly supplied during - // verification. Every node on the direct path from the leaf to the root can - // be computed by the very nature of “authentication path”. - let mut node_can_be_computed = HashSet::new(); - - for &leaf_index in leaf_indices { - assert!(num_leafs > leaf_index, "Leaf index must be less than number of leafs. Got leaf_index = {leaf_index}; num_leafs = {num_leafs}"); - - let mut node_index = leaf_index + num_leafs; - while node_index > ROOT_MT_INDEX { - let sibling_index = node_index ^ 1; - node_can_be_computed.insert(node_index); - node_is_needed.insert(sibling_index); - node_index /= 2; - } - } - - let set_difference = node_is_needed.difference(&node_can_be_computed).copied(); - let set_union = node_is_needed - .union(&node_can_be_computed) - .sorted_unstable() - .rev(); - - let mut set_union = set_union.peekable(); - - let mut set_union_as_ordered_pairs = Vec::new(); - while set_union.peek().is_some() { - let right_index = *set_union.next().unwrap(); - - // Crashes on odd-length of input list, which is what we want, as - // this acts as a sanity check. - let left_index = *set_union.next().unwrap(); - set_union_as_ordered_pairs.push((left_index, right_index)); - } - - ( - set_difference.sorted_unstable().rev().collect(), - set_union_as_ordered_pairs, - ) - } - - pub fn root_from_authentication_struct( - &self, - tree_height: u32, - auth_struct: Vec, - indexed_leafs: Vec<(u64, Digest)>, - ) -> Digest { - fn digest_to_xfe(digest: Digest, challenge: XFieldElement) -> XFieldElement { - let leaf_xfe_lo = XFieldElement::new([digest.0[0], digest.0[1], digest.0[2]]); - let leaf_xfe_hi = challenge - * XFieldElement::new([digest.0[3], digest.0[4], BFieldElement::one()]); - - leaf_xfe_lo + leaf_xfe_hi - } - - fn node_index_to_bfe(node_index: u64) -> BFieldElement { - BFieldElement::new(node_index) - } - - // Sanity check - assert_eq!( - self.nd_auth_struct_indices.len(), - auth_struct.len(), - "Provided auth struct length must match that specified in receiver" - ); - - // Get challenges - let (alpha, beta, gamma) = { - let mut sponge = Tip5::init(); - sponge.pad_and_absorb_all(&indexed_leafs.encode()); - sponge.pad_and_absorb_all(&auth_struct.encode()); - let challenges = sponge.sample_scalars(3); - (challenges[0], challenges[1], challenges[2]) - }; - - // Accumulate `p` from public data - let mut p = XFieldElement::one(); - for i in (0..indexed_leafs.len()).rev() { - let node_index_as_bfe = node_index_to_bfe((1 << tree_height) ^ indexed_leafs[i].0); - let leaf_as_xfe = digest_to_xfe(indexed_leafs[i].1, alpha); - let fact = leaf_as_xfe - beta + gamma * node_index_as_bfe; - p *= fact; - } - - let mut prev = 0; - for i in (0..auth_struct.len()).rev() { - let auth_struct_index = self.nd_auth_struct_indices[i]; - - // `auth_struct` must be sorted high-to-low by node-index. But since - // we're traversing in reverse order, the inequality is flipped. - assert!(auth_struct_index > prev); - prev = auth_struct_index; - - let auth_struct_index_as_bfe = node_index_to_bfe(auth_struct_index); - - let auth_str_elem_as_xfe = digest_to_xfe(auth_struct[i], alpha); - let fact = auth_str_elem_as_xfe - beta + gamma * auth_struct_index_as_bfe; - p *= fact; - } - - // Use secret data to invert `p` back and to calculate the root - let mut t = auth_struct - .first() - .copied() - .unwrap_or_else(|| indexed_leafs.first().unwrap().1); - let mut t_xfe = digest_to_xfe(t, alpha); - let mut parent_index_bfe = BFieldElement::one(); - for ((l, r), (left_index, right_index)) in self - .nd_siblings - .iter() - .zip_eq(self.nd_sibling_indices.clone()) - { - assert_eq!(left_index + 1, right_index); - - t = Tip5::hash_pair(*l, *r); - - let l_xfe = digest_to_xfe(*l, alpha); - let r_xfe = digest_to_xfe(*r, alpha); - t_xfe = digest_to_xfe(t, alpha); - - let left_index_bfe = node_index_to_bfe(left_index); - let right_index_bfe = node_index_to_bfe(right_index); - parent_index_bfe = left_index_bfe / bfe!(2); - - let fact1 = l_xfe - beta + gamma * left_index_bfe; - let fact2 = r_xfe - beta + gamma * right_index_bfe; - let fact_parent = t_xfe - beta + gamma * parent_index_bfe; - - p *= fact1.inverse() * fact2.inverse() * fact_parent; - } - - assert_eq!(t_xfe - beta + gamma, p); - assert!(parent_index_bfe.is_one()); - - t - } - - /// Return the authentication structure authenticity witness, - /// authentication structure, and the (leaf-index, leaf-digest) pairs - /// from a list of MMR membership proofs. All MMR membership proofs must - /// belong under the same peak, i.e., be part of the same Merkle tree in - /// the list of Merkle trees that the MMR contains. - /// - /// Panics if the input list of MMR-membership proofs is empty, or if they - /// do not all belong under the same peak. - pub fn new_from_mmr_membership_proofs( - mmra: &MmrAccumulator, - indexed_mmr_mps: Vec<(u64, Digest, MmrMembershipProof)>, - ) -> HashMap { - #[derive(Clone, Debug)] - struct IndexedAuthenticatedMmrLeaf { - merkle_tree_node_index: u64, - merkle_tree_leaf_index: u64, - leaf_digest: Digest, - membership_proof: MmrMembershipProof, - } - - // Split indexed MMR-mps into a hashmap with one entry for each - // referenced peak in the MMR. - let num_mmr_leafs = mmra.num_leafs(); - let mut peak_index_to_indexed_mmr_mp: HashMap> = - HashMap::default(); - let peak_heights = get_peak_heights(num_mmr_leafs); - for (mmr_leaf_index, leaf, mmr_mp) in indexed_mmr_mps { - let (mt_index, peak_index) = - leaf_index_to_mt_index_and_peak_index(mmr_leaf_index, num_mmr_leafs); - let peak_index_as_usize: usize = peak_index.try_into().unwrap(); - let num_leafs_local_mt = 1 << peak_heights[peak_index_as_usize]; - let mt_leaf_index = mt_index - num_leafs_local_mt; - peak_index_to_indexed_mmr_mp - .entry(peak_index) - .or_default() - .push(IndexedAuthenticatedMmrLeaf { - merkle_tree_node_index: mt_index, - merkle_tree_leaf_index: mt_leaf_index, - leaf_digest: leaf, - membership_proof: mmr_mp, - }); - } - - // Loop over all peaks and collect an authentication witness struct - // for each peak. - let mut peak_index_to_authenticated_auth_struct = HashMap::default(); - for (peak_index, indexed_mmr_mp_structs) in peak_index_to_indexed_mmr_mp { - let peak_index_as_usize: usize = peak_index.try_into().unwrap(); - let num_leafs_in_local_mt = 1 << peak_heights[peak_index_as_usize]; - let local_mt_leaf_indices = indexed_mmr_mp_structs - .iter() - .map(|x| x.merkle_tree_leaf_index) - .collect_vec(); - - let (nd_auth_struct_indices, nd_sibling_indices) = - Self::auth_struct_and_nd_indices(num_leafs_in_local_mt, &local_mt_leaf_indices); - let peak = mmra.peaks()[peak_index_as_usize]; - - let mut node_digests: HashMap = HashMap::default(); - node_digests.insert(ROOT_MT_INDEX, peak); - - // Loop over all indexed leafs for this peak - for indexed_mmr_mp in indexed_mmr_mp_structs.iter() { - let mut mt_node_index = indexed_mmr_mp.merkle_tree_node_index; - let mut node = indexed_mmr_mp.leaf_digest; - - // Loop over all authentication path elements for this indexed leaf - for ap_elem in indexed_mmr_mp.membership_proof.authentication_path.iter() { - node_digests.insert(mt_node_index, node); - node_digests.insert(mt_node_index ^ 1, *ap_elem); - node = if mt_node_index & 1 == 0 { - Tip5::hash_pair(node, *ap_elem) - } else { - Tip5::hash_pair(*ap_elem, node) - }; - - mt_node_index /= 2; - } - - // Sanity check that MMR-MPs are valid - assert_eq!(peak, node, "Derived peak must match provided peak"); - } - let nd_siblings = nd_sibling_indices - .iter() - .map(|(left_idx, right_idx)| (node_digests[left_idx], node_digests[right_idx])) - .collect_vec(); - let auth_struct = nd_auth_struct_indices - .iter() - .map(|idx| node_digests[idx]) - .collect_vec(); - let indexed_leafs = indexed_mmr_mp_structs - .into_iter() - .map(|indexed_mmr_mp| { - ( - indexed_mmr_mp.merkle_tree_leaf_index, - indexed_mmr_mp.leaf_digest, - ) - }) - .collect_vec(); - - let witness = Self { - nd_auth_struct_indices, - nd_sibling_indices, - nd_siblings, - }; - - peak_index_to_authenticated_auth_struct.insert( - peak_index, - AuthenticatedMerkleAuthStruct { - auth_struct, - indexed_leafs, - witness, - }, - ); - } - - peak_index_to_authenticated_auth_struct - } - - /// Return the authentication structure witness, authentication structure, - /// and the (leaf-index, leaf-digest) pairs. - pub fn new_from_merkle_tree( - tree: &MerkleTree, - mut revealed_leaf_indices: Vec, - ) -> AuthenticatedMerkleAuthStruct { - revealed_leaf_indices.sort_unstable(); - revealed_leaf_indices.dedup(); - revealed_leaf_indices.reverse(); - let num_leafs: u64 = tree.num_leafs() as u64; - - let (mut nd_auth_struct_indices, nd_sibling_indices) = - Self::auth_struct_and_nd_indices(num_leafs, &revealed_leaf_indices); - if revealed_leaf_indices.is_empty() { - nd_auth_struct_indices = vec![ROOT_MT_INDEX]; - } - - let nd_siblings = nd_sibling_indices - .iter() - .map(|&(l, r)| { - let l: usize = l.try_into().unwrap(); - let r: usize = r.try_into().unwrap(); - (tree.node(l).unwrap(), tree.node(r).unwrap()) - }) - .collect_vec(); - - let revealed_leafs = revealed_leaf_indices - .iter() - .map(|j| tree.node((*j + num_leafs) as usize).unwrap()) - .collect_vec(); - let indexed_leafs = revealed_leaf_indices - .clone() - .into_iter() - .zip_eq(revealed_leafs) - .collect_vec(); - - let auth_struct = nd_auth_struct_indices - .iter() - .map(|node_index| tree.node(*node_index as usize).unwrap()) - .collect_vec(); - - let witness = Self { - nd_auth_struct_indices, - nd_sibling_indices, - nd_siblings, - }; - - AuthenticatedMerkleAuthStruct { - auth_struct, - indexed_leafs, - witness, - } - } - } -} diff --git a/tasm-lib/src/mmr/authentication_struct/shared.rs b/tasm-lib/src/mmr/authentication_struct/shared.rs index 16758680b..d17f4920f 100644 --- a/tasm-lib/src/mmr/authentication_struct/shared.rs +++ b/tasm-lib/src/mmr/authentication_struct/shared.rs @@ -4,6 +4,7 @@ use std::collections::HashSet; use itertools::Itertools; use num_traits::One; +use crate::data_type::DataType; use crate::twenty_first::bfe; use crate::twenty_first::prelude::*; use crate::twenty_first::util_types::mmr::mmr_accumulator::MmrAccumulator; @@ -12,6 +13,10 @@ use crate::twenty_first::util_types::mmr::shared_basic::leaf_index_to_mt_index_a const ROOT_MT_INDEX: u64 = 1; +pub(super) fn indexed_leaf_element_type() -> DataType { + DataType::Tuple(vec![DataType::U64, DataType::Digest]) +} + /// A witness to facilitate the proving of the authenticity of a Merkle /// authentication struct. #[derive(Debug, Clone)] @@ -88,6 +93,9 @@ impl AuthStructIntegrityProof { ) } + /// Calculate a root from an authentication structure, indexed leafs, and + /// additional witness data on `self`. Crashes if the witness data is + /// incorrect and if the list of indexed leafs is empty. pub fn root_from_authentication_struct( &self, tree_height: u32, @@ -148,10 +156,7 @@ impl AuthStructIntegrityProof { } // Use secret data to invert `p` back and to calculate the root - let mut t = auth_struct - .first() - .copied() - .unwrap_or_else(|| indexed_leafs.first().unwrap().1); + let mut t = indexed_leafs.first().unwrap().1; let mut t_xfe = digest_to_xfe(t, alpha); let mut parent_index_bfe = BFieldElement::one(); for ((l, r), (left_index, right_index)) in self @@ -159,7 +164,10 @@ impl AuthStructIntegrityProof { .iter() .zip_eq(self.nd_sibling_indices.clone()) { + let left_index_bfe = node_index_to_bfe(left_index); + let right_index_bfe = node_index_to_bfe(right_index); assert_eq!(left_index + 1, right_index); + parent_index_bfe = left_index_bfe / bfe!(2); t = Tip5::hash_pair(*l, *r); @@ -167,10 +175,6 @@ impl AuthStructIntegrityProof { let r_xfe = digest_to_xfe(*r, alpha); t_xfe = digest_to_xfe(t, alpha); - let left_index_bfe = node_index_to_bfe(left_index); - let right_index_bfe = node_index_to_bfe(right_index); - parent_index_bfe = left_index_bfe / bfe!(2); - let fact1 = l_xfe - beta + gamma * left_index_bfe; let fact2 = r_xfe - beta + gamma * right_index_bfe; let fact_parent = t_xfe - beta + gamma * parent_index_bfe; @@ -315,11 +319,8 @@ impl AuthStructIntegrityProof { revealed_leaf_indices.reverse(); let num_leafs: u64 = tree.num_leafs() as u64; - let (mut nd_auth_struct_indices, nd_sibling_indices) = + let (nd_auth_struct_indices, nd_sibling_indices) = Self::auth_struct_and_nd_indices(num_leafs, &revealed_leaf_indices); - if revealed_leaf_indices.is_empty() { - nd_auth_struct_indices = vec![ROOT_MT_INDEX]; - } let nd_siblings = nd_sibling_indices .iter() @@ -597,20 +598,6 @@ mod tests { assert_eq!(tree.root(), calculated_root); } - #[test] - fn root_from_authentication_struct_tree_height_0_no_revealed_leafs() { - let tree_height = 0; - let leaf_indices = vec![]; - let nd_auth_struct_indices = vec![1]; - let nd_sibling_indices = vec![]; - prop_from_merkle_tree( - tree_height, - leaf_indices, - nd_auth_struct_indices, - nd_sibling_indices, - ) - } - #[test] fn root_from_authentication_struct_tree_height_0_1_revealed() { let tree_height = 0; @@ -653,20 +640,6 @@ mod tests { ) } - #[test] - fn root_from_authentication_struct_tree_height_2_0_revealed() { - let tree_height = 2; - let leaf_indices = vec![]; - let auth_struct_indices = vec![1]; - let nd_sibling_indices = vec![]; - prop_from_merkle_tree( - tree_height, - leaf_indices, - auth_struct_indices, - nd_sibling_indices, - ) - } - #[test] fn root_from_authentication_struct_tree_height_2_2_revealed() { let tree_height = 2; diff --git a/tasm-lib/src/rust_shadowing_helper_functions.rs b/tasm-lib/src/rust_shadowing_helper_functions.rs index bfe6f833f..edaf24808 100644 --- a/tasm-lib/src/rust_shadowing_helper_functions.rs +++ b/tasm-lib/src/rust_shadowing_helper_functions.rs @@ -2,3 +2,30 @@ pub mod array; pub mod claim; pub mod dyn_malloc; pub mod list; +pub mod memory; + +/// Count the number of non-leaf nodes that were inserted *prior* to +/// the insertion of this leaf. +pub fn non_leaf_nodes_left(leaf_index: u64) -> u64 { + // This formula is derived as follows: + // To get the heights of peaks before this leaf index was inserted, bit-decompose + // the number of leaves before it was inserted. + // Number of leaves in tree of height h = 2^h + // Number of nodes in tree of height h = 2^(h + 1) - 1 + // Number of non-leaves is `#(nodes) - #(leaves)`. + // Thus: f(x) = sum_{h}(2^h - 1) + + // An upper limit for the loop iterator is the log_2_floor(leaf_index) + let log_2_floor_plus_one = u64::BITS - leaf_index.leading_zeros(); + let mut h = 0; + let mut ret = 0; + while h != log_2_floor_plus_one { + let pow = (1 << h) & leaf_index; + if pow != 0 { + ret += pow - 1; + } + h += 1; + } + + ret +} diff --git a/tasm-lib/src/rust_shadowing_helper_functions/memory.rs b/tasm-lib/src/rust_shadowing_helper_functions/memory.rs new file mode 100644 index 000000000..aaeda8e7f --- /dev/null +++ b/tasm-lib/src/rust_shadowing_helper_functions/memory.rs @@ -0,0 +1,15 @@ +use std::collections::HashMap; + +use triton_vm::prelude::BFieldCodec; +use triton_vm::prelude::BFieldElement; + +pub fn write_to_memory( + mut pointer: BFieldElement, + value: T, + memory: &mut HashMap, +) { + for word in value.encode() { + memory.insert(pointer, word); + pointer.increment(); + } +} From 01c947a76ea75f8d64eeae95270d869685d7b9de Mon Sep 17 00:00:00 2001 From: sword_smith Date: Thu, 15 Aug 2024 12:44:05 +0200 Subject: [PATCH 03/14] mmr::auhtentication_struct: Refactor tests Make Rust-shadowing and state initialization nicer. --- .../root_from_authentication_struct.rs | 164 ++++++++++-------- .../src/mmr/authentication_struct/shared.rs | 2 +- 2 files changed, 94 insertions(+), 72 deletions(-) diff --git a/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs b/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs index 404ba496c..2d156f4e4 100644 --- a/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs +++ b/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs @@ -668,16 +668,16 @@ mod tests { use itertools::Itertools; use num::One; + use num::Zero; use rand::rngs::StdRng; use rand::Rng; use rand::SeedableRng; use twenty_first::prelude::AlgebraicHasher; - use twenty_first::prelude::CpuParallel; - use twenty_first::prelude::MerkleTree; use twenty_first::prelude::Sponge; + use twenty_first::util_types::mmr::mmr_accumulator::util::mmra_with_mps; use crate::mmr::authentication_struct::shared::AuthStructIntegrityProof; - use crate::rust_shadowing_helper_functions::input::consume_digest_from_secret_in; + use crate::rust_shadowing_helper_functions::input::read_digest_from_input; use crate::rust_shadowing_helper_functions::list::list_insert; use crate::rust_shadowing_helper_functions::list::load_list_with_copy_elements; use crate::rust_shadowing_helper_functions::memory::write_to_memory; @@ -703,7 +703,7 @@ mod tests { stack: &mut Vec, memory: &mut std::collections::HashMap, nondeterminism: &NonDeterminism, - public_input: &[BFieldElement], + _public_input: &[BFieldElement], sponge: &mut Option, ) -> Vec { fn digest_to_xfe(digest: Digest, challenge: XFieldElement) -> XFieldElement { @@ -741,10 +741,63 @@ mod tests { write_to_memory(P_POINTER_WRITE, p, memory); } + fn accumulate_indexed_leafs( + indexed_leafs: &[(u64, Digest)], + alpha: XFieldElement, + beta: XFieldElement, + gamma: XFieldElement, + tree_num_leafs: u64, + ) -> XFieldElement { + let mut p = XFieldElement::one(); + for (leaf_idx, leaf) in indexed_leafs.iter().copied().rev() { + let leaf_idx_as_bfe = bfe!(leaf_idx); + let node_idx_as_bfe = leaf_idx_as_bfe + bfe!(tree_num_leafs); + let leaf_as_xfe = digest_to_xfe(leaf, alpha); + let fact = leaf_as_xfe - beta + gamma * node_idx_as_bfe; + p *= fact; + } + + p + } + + fn accumulate_auth_struct( + mut p: XFieldElement, + auth_struct: Vec, + individual_tokens: &mut VecDeque, + alpha: XFieldElement, + beta: XFieldElement, + gamma: XFieldElement, + ) -> XFieldElement { + let mut prev = 0u64; + + for auth_struct_elem in auth_struct.iter().copied().rev() { + let auth_struct_elem_node_index_hi: u32 = + individual_tokens.pop_front().unwrap().try_into().unwrap(); + let auth_struct_elem_node_index_lo: u32 = + individual_tokens.pop_front().unwrap().try_into().unwrap(); + let auth_struct_elem_node_index = ((auth_struct_elem_node_index_hi as u64) + << 32) + + auth_struct_elem_node_index_lo as u64; + assert!(auth_struct_elem_node_index > prev); + prev = auth_struct_elem_node_index; + + let auth_struct_index_as_bfe = bfe!(auth_struct_elem_node_index); + + let auth_struct_elem_xfe = digest_to_xfe(auth_struct_elem, alpha); + let fact = auth_struct_elem_xfe - beta + gamma * auth_struct_index_as_bfe; + + p *= fact; + } + + p + } + assert_eq!( SIZE_OF_INDEXED_LEAFS_ELEMENT, Self::indexed_leaf_element_type().stack_size() ); + + // declare input-arguments let indexed_leafs_pointer = stack.pop().unwrap(); let auth_struct_pointer = stack.pop().unwrap(); let tree_height: u32 = stack.pop().unwrap().try_into().unwrap(); @@ -767,8 +820,8 @@ mod tests { load_list_with_copy_elements(auth_struct_pointer, memory); let auth_struct = auth_struct.into_iter().map(bfes_to_digest).collect_vec(); + // Calculate challenges let sponge = sponge.as_mut().expect("sponge must be initialized"); - sponge.pad_and_absorb_all(&indexed_leafs.encode()); sponge.pad_and_absorb_all(&auth_struct.encode()); @@ -777,37 +830,17 @@ mod tests { let beta = -XFieldElement::new([sponge_output[4], sponge_output[5], sponge_output[6]]); let gamma = XFieldElement::new([sponge_output[7], sponge_output[8], sponge_output[9]]); - let tree_num_leafs = 1 << tree_height; - let mut p = XFieldElement::one(); - for (leaf_idx, leaf) in indexed_leafs.iter().copied().rev() { - let leaf_idx_as_bfe = bfe!(leaf_idx); - let node_idx_as_bfe = leaf_idx_as_bfe + bfe!(tree_num_leafs); - let leaf_as_xfe = digest_to_xfe(leaf, alpha); - let fact = leaf_as_xfe - beta + gamma * node_idx_as_bfe; - p *= fact; - } + let tree_num_leafs = 1u64 << tree_height; + + // Accumulate into `p` from public data + let mut p = + accumulate_indexed_leafs(&indexed_leafs, alpha, beta, gamma, tree_num_leafs); - let mut prev = 0u64; let mut individual_tokens: VecDeque = nondeterminism.individual_tokens.to_owned().into(); - for auth_struct_elem in auth_struct.iter().copied().rev() { - let auth_struct_elem_node_index_hi: u32 = - individual_tokens.pop_front().unwrap().try_into().unwrap(); - let auth_struct_elem_node_index_lo: u32 = - individual_tokens.pop_front().unwrap().try_into().unwrap(); - let auth_struct_elem_node_index = ((auth_struct_elem_node_index_hi as u64) << 32) - + auth_struct_elem_node_index_lo as u64; - assert!(auth_struct_elem_node_index > prev); - prev = auth_struct_elem_node_index; - - let auth_struct_index_as_bfe = bfe!(auth_struct_elem_node_index); - - let auth_struct_elem_xfe = digest_to_xfe(auth_struct_elem, alpha); - let fact = auth_struct_elem_xfe - beta + gamma * auth_struct_index_as_bfe; - - p *= fact; - } + p = accumulate_auth_struct(p, auth_struct, &mut individual_tokens, alpha, beta, gamma); + // "Unaccumulate" into `p` from secret data, and calculate Merkle root let mut t = indexed_leafs[0].1; let mut t_xfe = digest_to_xfe(t, alpha); if tree_num_leafs != 1 { @@ -818,8 +851,8 @@ mod tests { let parent_index = left_index / bfe!(2); - let right = consume_digest_from_secret_in(&mut individual_tokens); - let left = consume_digest_from_secret_in(&mut individual_tokens); + let right = read_digest_from_input(&mut individual_tokens); + let left = read_digest_from_input(&mut individual_tokens); t = Tip5::hash_pair(left, right); t_xfe = digest_to_xfe(t, alpha); @@ -839,6 +872,7 @@ mod tests { assert_eq!(t_xfe - beta + gamma, p); + // Return the Merkle root on the stack for elem in t.encode().into_iter().rev() { stack.push(elem); } @@ -855,38 +889,39 @@ mod tests { ) -> ProcedureInitialState { let mut rng: StdRng = SeedableRng::from_seed(seed); - // TODO: use real `mmr_authentication_struct` code here let tree_height = rng.gen_range(0..5); - let leaf_count = 1 << tree_height; - let num_revealed_leafs = rng.gen_range(1..=leaf_count); + let num_leafs_in_merkle_tree = 1 << tree_height; + let num_revealed_leafs = rng.gen_range(1..=num_leafs_in_merkle_tree); let revealed_leaf_indices = (0..num_revealed_leafs) - .map(|_| rng.gen_range(0..leaf_count)) + .map(|_| rng.gen_range(0..num_leafs_in_merkle_tree)) .unique() .collect_vec(); - println!( - "revealed_leaf_indices: [{}]", - revealed_leaf_indices.iter().join(", ") - ); - let leafs = (0..leaf_count).map(|_| rng.gen()).collect_vec(); - let tree = MerkleTree::::new::(&leafs).unwrap(); + let num_revealed_leafs = revealed_leaf_indices.len(); + assert!(!num_revealed_leafs.is_zero()); + + let revealed_leafs: Vec = + (0..num_revealed_leafs).map(|_| rng.gen()).collect_vec(); + let indexed_leafs = revealed_leaf_indices + .into_iter() + .zip_eq(revealed_leafs) + .collect_vec(); + + let (mmra, mps) = mmra_with_mps(num_leafs_in_merkle_tree, indexed_leafs.clone()); + let indexed_mmr_mps = indexed_leafs + .into_iter() + .zip_eq(mps) + .map(|((idx, leaf), mp)| (idx, leaf, mp)) + .collect_vec(); + let mmr_authentication_struct = - AuthStructIntegrityProof::new_from_merkle_tree(&tree, revealed_leaf_indices); - println!("tree.root() = {}", tree.root()); + AuthStructIntegrityProof::new_from_mmr_membership_proofs(&mmra, indexed_mmr_mps); + assert!(mmr_authentication_struct.len().is_one()); + let mmr_authentication_struct = &mmr_authentication_struct[&0]; let mut memory = HashMap::new(); let authentication_structure_ptr = rng.gen(); let indexed_leafs_ptr = rng.gen(); - println!("leaf_count: {leaf_count}"); - println!( - "indexed_leafs.len(): {}", - mmr_authentication_struct.indexed_leafs.len() - ); - println!( - "authentication_structure.len(): {}", - mmr_authentication_struct.auth_struct.len() - ); - list_insert( authentication_structure_ptr, mmr_authentication_struct.auth_struct.clone(), @@ -894,7 +929,7 @@ mod tests { ); list_insert( indexed_leafs_ptr, - mmr_authentication_struct.indexed_leafs, + mmr_authentication_struct.indexed_leafs.clone(), &mut memory, ); @@ -908,25 +943,13 @@ mod tests { ] .concat(); - println!( - "node indices: {}", - mmr_authentication_struct - .witness - .nd_auth_struct_indices - .iter() - .join(", ") - ); let nd_auth_struct_indices = mmr_authentication_struct .witness .nd_auth_struct_indices - .into_iter() + .iter() .rev() .flat_map(|node_index| node_index.encode().into_iter().rev().collect_vec()) .collect_vec(); - println!( - "nd_auth_struct_indices (encoded as BFEs): {}", - nd_auth_struct_indices.iter().join(", ") - ); let nd_loop_nd = mmr_authentication_struct .witness .nd_sibling_indices @@ -950,7 +973,6 @@ mod tests { .collect_vec(); let individual_tokens = [nd_auth_struct_indices, nd_loop_nd].concat(); - println!("individual_tokens: {}", individual_tokens.iter().join(", ")); let nondeterminism = NonDeterminism::new(individual_tokens).with_ram(memory); ProcedureInitialState { stack, diff --git a/tasm-lib/src/mmr/authentication_struct/shared.rs b/tasm-lib/src/mmr/authentication_struct/shared.rs index d17f4920f..58f371df6 100644 --- a/tasm-lib/src/mmr/authentication_struct/shared.rs +++ b/tasm-lib/src/mmr/authentication_struct/shared.rs @@ -529,7 +529,7 @@ mod tests { #[proptest(cases = 20)] fn root_from_authentication_struct_prop_test( #[strategy(0..12u64)] tree_height: u64, - #[strategy(0usize..100)] _num_revealed_leafs: usize, + #[strategy(1usize..100)] _num_revealed_leafs: usize, #[strategy(vec(0u64..1<<#tree_height, #_num_revealed_leafs))] revealed_leaf_indices: Vec< u64, >, From 9d39e8843670be5edeb89a4578c0aa1317b83474 Mon Sep 17 00:00:00 2001 From: sword_smith Date: Thu, 15 Aug 2024 13:00:47 +0200 Subject: [PATCH 04/14] mmr::authentication_struct: Add benchmarks for TASM program --- ...b_mmr_root_from_authentication_struct.json | 24 ++++++++++++++++ .../root_from_authentication_struct.rs | 28 +++++++++++++++++-- 2 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json diff --git a/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json b/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json new file mode 100644 index 000000000..a7a1a6c9d --- /dev/null +++ b/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json @@ -0,0 +1,24 @@ +[ + { + "name": "tasmlib_mmr_root_from_authentication_struct", + "benchmark_result": { + "clock_cycle_count": 93344, + "hash_table_height": 5437, + "u32_table_height": 11235, + "op_stack_table_height": 140194, + "ram_table_height": 39822 + }, + "case": "CommonCase" + }, + { + "name": "tasmlib_mmr_root_from_authentication_struct", + "benchmark_result": { + "clock_cycle_count": 193548, + "hash_table_height": 10771, + "u32_table_height": 41115, + "op_stack_table_height": 290804, + "ram_table_height": 82518 + }, + "case": "WorstCase" + } +] \ No newline at end of file diff --git a/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs b/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs index 2d156f4e4..198f09355 100644 --- a/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs +++ b/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs @@ -617,7 +617,6 @@ impl BasicSnippet for RootFromAuthenticationStruct { // _ /* Assert that p == t_xfe - beta + gamma */ - break push {p_pointer_read} read_mem {EXTENSION_DEGREE} pop 1 @@ -663,6 +662,7 @@ impl BasicSnippet for RootFromAuthenticationStruct { #[cfg(test)] mod tests { + use std::cmp::min; use std::collections::HashMap; use std::collections::VecDeque; @@ -889,9 +889,18 @@ mod tests { ) -> ProcedureInitialState { let mut rng: StdRng = SeedableRng::from_seed(seed); - let tree_height = rng.gen_range(0..5); + let (tree_height, num_revealed_leafs) = match bench_case { + None => { + let tree_height = rng.gen_range(0..32); + let num_leafs_in_merkle_tree = 1 << tree_height; + let num_revealed_leafs = rng.gen_range(1..=min(num_leafs_in_merkle_tree, 20)); + (tree_height, num_revealed_leafs) + } + Some(BenchmarkCase::CommonCase) => (32, 20), + Some(BenchmarkCase::WorstCase) => (62, 20), + }; let num_leafs_in_merkle_tree = 1 << tree_height; - let num_revealed_leafs = rng.gen_range(1..=num_leafs_in_merkle_tree); + let revealed_leaf_indices = (0..num_revealed_leafs) .map(|_| rng.gen_range(0..num_leafs_in_merkle_tree)) .unique() @@ -987,3 +996,16 @@ mod tests { } } } + +#[cfg(test)] +mod benches { + use crate::traits::procedure::ShadowedProcedure; + use crate::traits::rust_shadow::RustShadow; + + use super::*; + + #[test] + fn bench_root_from_auth_struct() { + ShadowedProcedure::new(RootFromAuthenticationStruct).bench(); + } +} From 2dbf5bb9d0abba205a7eb6188ab0ba65f88d852b Mon Sep 17 00:00:00 2001 From: sword_smith Date: Thu, 15 Aug 2024 13:41:14 +0200 Subject: [PATCH 05/14] perf(mmr::authentication_struct): Read ND indices in one go --- .../tasmlib_mmr_root_from_authentication_struct.json | 8 ++++---- .../root_from_authentication_struct.rs | 5 +---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json b/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json index a7a1a6c9d..6a8f98295 100644 --- a/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json +++ b/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json @@ -2,8 +2,8 @@ { "name": "tasmlib_mmr_root_from_authentication_struct", "benchmark_result": { - "clock_cycle_count": 93344, - "hash_table_height": 5437, + "clock_cycle_count": 92793, + "hash_table_height": 5431, "u32_table_height": 11235, "op_stack_table_height": 140194, "ram_table_height": 39822 @@ -13,8 +13,8 @@ { "name": "tasmlib_mmr_root_from_authentication_struct", "benchmark_result": { - "clock_cycle_count": 193548, - "hash_table_height": 10771, + "clock_cycle_count": 192404, + "hash_table_height": 10765, "u32_table_height": 41115, "op_stack_table_height": 290804, "ram_table_height": 82518 diff --git a/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs b/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs index 198f09355..626719d6c 100644 --- a/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs +++ b/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs @@ -333,10 +333,7 @@ impl BasicSnippet for RootFromAuthenticationStruct { let nd_loop = triton_asm!( // _ INVARIANT: _ {nd_loop_label}: - divine 1 - // _ left_index - - divine 1 + divine 2 // _ left_index right_index dup 1 From 4df0ad951e6b3badf02e1af70b06f555ed8c9ab8 Mon Sep 17 00:00:00 2001 From: sword_smith Date: Thu, 15 Aug 2024 14:12:32 +0200 Subject: [PATCH 06/14] perf(mmr::authentication_struct): Don't store t_xfe to memory Instead of storing this value to memory in each loop iteration, we just calculate it from `t: Digest` when we need it. --- ...b_mmr_root_from_authentication_struct.json | 16 ++++----- .../root_from_authentication_struct.rs | 35 ++++--------------- 2 files changed, 14 insertions(+), 37 deletions(-) diff --git a/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json b/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json index 6a8f98295..6e012149d 100644 --- a/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json +++ b/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json @@ -2,22 +2,22 @@ { "name": "tasmlib_mmr_root_from_authentication_struct", "benchmark_result": { - "clock_cycle_count": 92793, - "hash_table_height": 5431, + "clock_cycle_count": 89479, + "hash_table_height": 5419, "u32_table_height": 11235, - "op_stack_table_height": 140194, - "ram_table_height": 39822 + "op_stack_table_height": 135778, + "ram_table_height": 38168 }, "case": "CommonCase" }, { "name": "tasmlib_mmr_root_from_authentication_struct", "benchmark_result": { - "clock_cycle_count": 192404, - "hash_table_height": 10765, + "clock_cycle_count": 185532, + "hash_table_height": 10753, "u32_table_height": 41115, - "op_stack_table_height": 290804, - "ram_table_height": 82518 + "op_stack_table_height": 281644, + "ram_table_height": 79085 }, "case": "WorstCase" } diff --git a/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs b/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs index 626719d6c..b4adf98d5 100644 --- a/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs +++ b/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs @@ -50,8 +50,6 @@ impl BasicSnippet for RootFromAuthenticationStruct { gamma_challenge_pointer_write + bfe!(EXTENSION_DEGREE as u64 - 1); let t_digest_pointer_write = library.kmalloc(Digest::LEN as u32); let t_digest_pointer_read = t_digest_pointer_write + bfe!(Digest::LEN as u64 - 1); - let t_xfe_pointer_write = library.kmalloc(EXTENSION_DEGREE as u32); - let t_xfe_pointer_read = t_xfe_pointer_write + bfe!(EXTENSION_DEGREE as u64 - 1); let p_pointer_write = library.kmalloc(EXTENSION_DEGREE as u32); let p_pointer_read = p_pointer_write + bfe!(EXTENSION_DEGREE as u64 - 1); @@ -328,7 +326,6 @@ impl BasicSnippet for RootFromAuthenticationStruct { let nd_loop_label = format!("{entrypoint}_nd_loop"); let dup_top_two_digests = triton_asm![dup 9; Digest::LEN * 2]; let dup_top_digest = triton_asm![dup 4; Digest::LEN]; - let dup_top_xfe = triton_asm![dup 2; EXTENSION_DEGREE]; let one_half = BFieldElement::new(2).inverse(); let nd_loop = triton_asm!( // _ INVARIANT: _ @@ -374,12 +371,6 @@ impl BasicSnippet for RootFromAuthenticationStruct { hint t_xfe: XFieldElement = stack[0..3] // _ parent_index [right] [left] [t_xfe] - {&dup_top_xfe} - push {t_xfe_pointer_write} - write_mem {EXTENSION_DEGREE} - pop 1 - // _ parent_index [right] [left] [t_xfe] - push {beta_challenge_pointer_read} read_mem {EXTENSION_DEGREE} pop 1 @@ -580,18 +571,7 @@ impl BasicSnippet for RootFromAuthenticationStruct { pop 1 // _ tree_num_leafs *indexed_leafs [p] [t; 5] - dup 4 - dup 4 - dup 4 - dup 4 - dup 4 - {&digest_to_xfe} - // _ tree_num_leafs *indexed_leafs [p] [t; 5] [t_xfe] - - /* Write t values, and `p` to static memory */ - push {t_xfe_pointer_write} - write_mem {EXTENSION_DEGREE} - pop 1 + /* Write t value, and `p` to static memory */ push {t_digest_pointer_write} write_mem {Digest::LEN} pop 1 @@ -619,9 +599,10 @@ impl BasicSnippet for RootFromAuthenticationStruct { pop 1 // _ [p] - push {t_xfe_pointer_read} - read_mem {EXTENSION_DEGREE} + push {t_digest_pointer_read} + read_mem {Digest::LEN} pop 1 + {&digest_to_xfe} // _ [p] [t_xfe] push {beta_challenge_pointer_read} @@ -717,7 +698,6 @@ mod tests { beta: XFieldElement, gamma: XFieldElement, t: Digest, - t_xfe: XFieldElement, p: XFieldElement, ) { const ALPHA_POINTER_WRITE: BFieldElement = BFieldElement::new(BFieldElement::P - 4); @@ -726,15 +706,12 @@ mod tests { BFieldElement::new(BFieldElement::P - 10); const T_DIGEST_POINTER_WRITE: BFieldElement = BFieldElement::new(BFieldElement::P - 15); - const T_XFE_POINTER_WRITE: BFieldElement = - BFieldElement::new(BFieldElement::P - 18); - const P_POINTER_WRITE: BFieldElement = BFieldElement::new(BFieldElement::P - 21); + const P_POINTER_WRITE: BFieldElement = BFieldElement::new(BFieldElement::P - 18); write_to_memory(ALPHA_POINTER_WRITE, alpha, memory); write_to_memory(BETA_POINTER_WRITE, beta, memory); write_to_memory(GAMMA_POINTER_WRITE, gamma, memory); write_to_memory(T_DIGEST_POINTER_WRITE, t, memory); - write_to_memory(T_XFE_POINTER_WRITE, t_xfe, memory); write_to_memory(P_POINTER_WRITE, p, memory); } @@ -874,7 +851,7 @@ mod tests { stack.push(elem); } - mimic_use_of_static_memory(memory, alpha, -beta, gamma, t, t_xfe, p); + mimic_use_of_static_memory(memory, alpha, -beta, gamma, t, p); vec![] } From 13cfc841e3831668b6d46a9578f2dd2161e3b1fe Mon Sep 17 00:00:00 2001 From: sword_smith Date: Thu, 15 Aug 2024 14:32:04 +0200 Subject: [PATCH 07/14] perf(mmr::authentication_path): Save two `mul` by buffering left_index, not parent_index It's a bit more performant to store `left_index` on the stack and then calculate from it `parent_index` and `right_index` then to store `parent_index` as we did before and calculate the left and right index from that. --- ...b_mmr_root_from_authentication_struct.json | 12 +-- .../root_from_authentication_struct.rs | 79 +++++++++---------- .../src/mmr/authentication_struct/shared.rs | 6 +- 3 files changed, 45 insertions(+), 52 deletions(-) diff --git a/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json b/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json index 6e012149d..295148f39 100644 --- a/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json +++ b/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json @@ -2,10 +2,10 @@ { "name": "tasmlib_mmr_root_from_authentication_struct", "benchmark_result": { - "clock_cycle_count": 89479, - "hash_table_height": 5419, + "clock_cycle_count": 87275, + "hash_table_height": 5413, "u32_table_height": 11235, - "op_stack_table_height": 135778, + "op_stack_table_height": 133574, "ram_table_height": 38168 }, "case": "CommonCase" @@ -13,10 +13,10 @@ { "name": "tasmlib_mmr_root_from_authentication_struct", "benchmark_result": { - "clock_cycle_count": 185532, - "hash_table_height": 10753, + "clock_cycle_count": 180956, + "hash_table_height": 10747, "u32_table_height": 41115, - "op_stack_table_height": 281644, + "op_stack_table_height": 277068, "ram_table_height": 79085 }, "case": "WorstCase" diff --git a/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs b/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs index b4adf98d5..32d672a6e 100644 --- a/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs +++ b/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs @@ -340,15 +340,9 @@ impl BasicSnippet for RootFromAuthenticationStruct { // _ l_index_bfe (left_index + 1 == right_index) assert + hint left_index: BFieldElement = stack[0..1] // _ l_index_bfe - /* Update parent index */ - push {one_half} - mul - hint parent_index: BFieldElement = stack[0..1] - // _ (l_index_bfe / 2) - // _ parent_index <-- rename - /* Calculate parent digest, preserving child digests */ divine {Digest::LEN} hint right: Digest = stack[0..5] @@ -359,39 +353,41 @@ impl BasicSnippet for RootFromAuthenticationStruct { {&dup_top_two_digests} hash hint t: Digest = stack[0..5] - // _ parent_index [right] [left] [t] + // _ left_index [right] [left] [t] {&dup_top_digest} push {t_digest_pointer_write} write_mem {Digest::LEN} pop 1 - // _ parent_index [right] [left] [t] + // _ left_index [right] [left] [t] {&digest_to_xfe} hint t_xfe: XFieldElement = stack[0..3] - // _ parent_index [right] [left] [t_xfe] + // _ left_index [right] [left] [t_xfe] push {beta_challenge_pointer_read} read_mem {EXTENSION_DEGREE} pop 1 xx_add - // _ parent_index [right] [left] [t_xfe - β] + // _ left_index [right] [left] [t_xfe - β] dup 13 + push {one_half} + mul push {gamma_challenge_pointer_read} read_mem {EXTENSION_DEGREE} pop 1 - // _ parent_index [right] [left] [t_xfe - β] parent_index [γ] + // _ left_index [right] [left] [t_xfe - β] parent_index [γ] swap 1 swap 2 swap 3 xb_mul - // _ parent_index [right] [left] [t_xfe - β] [γ * parent_index] + // _ left_index [right] [left] [t_xfe - β] [γ * parent_index] xx_add - // _ parent_index [right] [left] [t_xfe - β + γ * parent_index] - // _ parent_index [right] [left] [fact_parent] <-- rename + // _ left_index [right] [left] [t_xfe - β + γ * parent_index] + // _ left_index [right] [left] [fact_parent] <-- rename /* Accumulate `fact_parent` into `p` */ push {p_pointer_read} @@ -401,39 +397,37 @@ impl BasicSnippet for RootFromAuthenticationStruct { push {p_pointer_write} write_mem {EXTENSION_DEGREE} pop 1 - // _ parent_index [right] [left] + // _ left_index [right] [left] - /* Claculate `fact_1` */ + /* Calculate `fact_left` */ {&digest_to_xfe} - // _ parent_index [right] [left_xfe] + // _ left_index [right] [left_xfe] push {beta_challenge_pointer_read} read_mem {EXTENSION_DEGREE} pop 1 xx_add - // _ parent_index [right] [left_xfe - β] + // _ left_index [right] [left_xfe - β] push {gamma_challenge_pointer_read} read_mem {EXTENSION_DEGREE} pop 1 - // _ parent_index [right] [left_xfe - β] [γ] + // _ left_index [right] [left_xfe - β] [γ] dup 11 - push 2 - mul - // _ parent_index [right] [left_xfe - β] [γ] left_index + // _ left_index [right] [left_xfe - β] [γ] left_index xb_mul - // _ parent_index [right] [left_xfe - β] [γ * left_index] + // _ left_index [right] [left_xfe - β] [γ * left_index] xx_add - // _ parent_index [right] [left_xfe - β + γ * left_index] - // _ parent_index [right] [fact_1] <-- rename + // _ left_index [right] [left_xfe - β + γ * left_index] + // _ left_index [right] [fact_left] <-- rename x_invert - // _ parent_index [right] [fact_1^{-1}] + // _ left_index [right] [fact_left^{-1}] - /* Divide `fact_1` out of `p` */ + /* Divide `fact_left` out of `p` */ push {p_pointer_read} read_mem {EXTENSION_DEGREE} pop 1 @@ -441,41 +435,39 @@ impl BasicSnippet for RootFromAuthenticationStruct { push {p_pointer_write} write_mem {EXTENSION_DEGREE} pop 1 - // _ parent_index [right] + // _ left_index [right] - /* Calculate `fact_2` */ + /* Calculate `fact_right` */ {&digest_to_xfe} - // _ parent_index [right_xfe] + // _ left_index [right_xfe] push {beta_challenge_pointer_read} read_mem {EXTENSION_DEGREE} pop 1 xx_add - // _ parent_index [right_xfe - β] + // _ left_index [right_xfe - β] push {gamma_challenge_pointer_read} read_mem {EXTENSION_DEGREE} pop 1 - // _ parent_index [right_xfe - β] [γ] + // _ left_index [right_xfe - β] [γ] dup 6 - push 2 - mul push 1 add - // _ parent_index [right_xfe - β] [γ] right_index + // _ left_index [right_xfe - β] [γ] right_index xb_mul - // _ parent_index [right_xfe - β] [right_index * γ] + // _ left_index [right_xfe - β] [right_index * γ] xx_add - // _ parent_index [right_xfe - β + right_index * γ] - // _ parent_index [fact_2] <-- rename + // _ left_index [right_xfe - β + right_index * γ] + // _ left_index [fact_right] <-- rename x_invert - // _ parent_index [fact_2^{-1}] + // _ left_index [fact_right^{-1}] - /* Divide `fact_2` out of `p` */ + /* Divide `fact_right` out of `p` */ push {p_pointer_read} read_mem {EXTENSION_DEGREE} pop 1 @@ -483,9 +475,10 @@ impl BasicSnippet for RootFromAuthenticationStruct { push {p_pointer_write} write_mem {EXTENSION_DEGREE} pop 1 - // _ parent_index + // _ left_index - push 1 + /* Terminate loop when left_index == 2 <=> parent_index == 1 */ + push 2 eq skiz return diff --git a/tasm-lib/src/mmr/authentication_struct/shared.rs b/tasm-lib/src/mmr/authentication_struct/shared.rs index 58f371df6..5418c0635 100644 --- a/tasm-lib/src/mmr/authentication_struct/shared.rs +++ b/tasm-lib/src/mmr/authentication_struct/shared.rs @@ -175,11 +175,11 @@ impl AuthStructIntegrityProof { let r_xfe = digest_to_xfe(*r, alpha); t_xfe = digest_to_xfe(t, alpha); - let fact1 = l_xfe - beta + gamma * left_index_bfe; - let fact2 = r_xfe - beta + gamma * right_index_bfe; + let fact_left = l_xfe - beta + gamma * left_index_bfe; + let fact_right = r_xfe - beta + gamma * right_index_bfe; let fact_parent = t_xfe - beta + gamma * parent_index_bfe; - p *= fact1.inverse() * fact2.inverse() * fact_parent; + p *= fact_left.inverse() * fact_right.inverse() * fact_parent; } assert_eq!(t_xfe - beta + gamma, p); From a2fe7eb6f4f003b88f12bf11ff7accca64ff86fc Mon Sep 17 00:00:00 2001 From: sword_smith Date: Thu, 15 Aug 2024 15:16:32 +0200 Subject: [PATCH 08/14] perf(mmr::authentication_struct): Keep `p` on stack in nd-loop --- ...b_mmr_root_from_authentication_struct.json | 16 +- .../root_from_authentication_struct.rs | 198 +++++++++--------- 2 files changed, 110 insertions(+), 104 deletions(-) diff --git a/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json b/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json index 295148f39..e6ea6a91f 100644 --- a/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json +++ b/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json @@ -2,22 +2,22 @@ { "name": "tasmlib_mmr_root_from_authentication_struct", "benchmark_result": { - "clock_cycle_count": 87275, - "hash_table_height": 5413, + "clock_cycle_count": 85070, + "hash_table_height": 5407, "u32_table_height": 11235, - "op_stack_table_height": 133574, - "ram_table_height": 38168 + "op_stack_table_height": 132462, + "ram_table_height": 39264 }, "case": "CommonCase" }, { "name": "tasmlib_mmr_root_from_authentication_struct", "benchmark_result": { - "clock_cycle_count": 180956, - "hash_table_height": 10747, + "clock_cycle_count": 176379, + "hash_table_height": 10741, "u32_table_height": 41115, - "op_stack_table_height": 277068, - "ram_table_height": 79085 + "op_stack_table_height": 274770, + "ram_table_height": 81367 }, "case": "WorstCase" } diff --git a/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs b/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs index 32d672a6e..b94ebdc44 100644 --- a/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs +++ b/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs @@ -50,8 +50,10 @@ impl BasicSnippet for RootFromAuthenticationStruct { gamma_challenge_pointer_write + bfe!(EXTENSION_DEGREE as u64 - 1); let t_digest_pointer_write = library.kmalloc(Digest::LEN as u32); let t_digest_pointer_read = t_digest_pointer_write + bfe!(Digest::LEN as u64 - 1); - let p_pointer_write = library.kmalloc(EXTENSION_DEGREE as u32); - let p_pointer_read = p_pointer_write + bfe!(EXTENSION_DEGREE as u64 - 1); + let right_digest_pointer_write = library.kmalloc(Digest::LEN as u32); + let right_digest_pointer_read = right_digest_pointer_write + bfe!(Digest::LEN as u64 - 1); + let left_digest_pointer_write = library.kmalloc(Digest::LEN as u32); + let left_digest_pointer_read = left_digest_pointer_write + bfe!(Digest::LEN as u64 - 1); let indexed_leaf_element_size = Self::indexed_leaf_element_type().stack_size(); let derive_challenges = library.import(Box::new(DeriveChallenges)); @@ -324,164 +326,163 @@ impl BasicSnippet for RootFromAuthenticationStruct { ); let nd_loop_label = format!("{entrypoint}_nd_loop"); - let dup_top_two_digests = triton_asm![dup 9; Digest::LEN * 2]; let dup_top_digest = triton_asm![dup 4; Digest::LEN]; let one_half = BFieldElement::new(2).inverse(); let nd_loop = triton_asm!( - // _ INVARIANT: _ + // _ INVARIANT: _ [p] {nd_loop_label}: divine 2 - // _ left_index right_index + // _ [p] left_index right_index dup 1 push 1 add eq - // _ l_index_bfe (left_index + 1 == right_index) + // _ [p] l_index_bfe (left_index + 1 == right_index) assert hint left_index: BFieldElement = stack[0..1] - // _ l_index_bfe + // _ [p] l_index_bfe + + swap 3 + swap 2 + swap 1 + // _ l_index_bfe [p] /* Calculate parent digest, preserving child digests */ divine {Digest::LEN} hint right: Digest = stack[0..5] - - divine {Digest::LEN} - hint left: Digest = stack[0..5] - - {&dup_top_two_digests} - hash - hint t: Digest = stack[0..5] - // _ left_index [right] [left] [t] + // _ l_index_bfe [p] [right] {&dup_top_digest} - push {t_digest_pointer_write} + push {right_digest_pointer_write} write_mem {Digest::LEN} pop 1 - // _ left_index [right] [left] [t] + // _ l_index_bfe [p] [right] {&digest_to_xfe} - hint t_xfe: XFieldElement = stack[0..3] - // _ left_index [right] [left] [t_xfe] + // _ l_index_bfe [p] [right_xfe] push {beta_challenge_pointer_read} read_mem {EXTENSION_DEGREE} pop 1 xx_add - // _ left_index [right] [left] [t_xfe - β] + // _ l_index_bfe [p] [right_xfe - β] - dup 13 - push {one_half} - mul push {gamma_challenge_pointer_read} read_mem {EXTENSION_DEGREE} pop 1 - // _ left_index [right] [left] [t_xfe - β] parent_index [γ] + // _ l_index_bfe [p] [right_xfe - β] [γ] + + dup 9 + push 1 + add + // _ l_index_bfe [p] [right_xfe - β] [γ] r_index_bfe - swap 1 - swap 2 - swap 3 xb_mul - // _ left_index [right] [left] [t_xfe - β] [γ * parent_index] + // _ l_index_bfe [p] [right_xfe - β] [γ * r_index_bfe] xx_add - // _ left_index [right] [left] [t_xfe - β + γ * parent_index] - // _ left_index [right] [left] [fact_parent] <-- rename + // _ l_index_bfe [p] [t_xfe - β + γ * parent_index] + // _ l_index_bfe [p] [fact_right] - /* Accumulate `fact_parent` into `p` */ - push {p_pointer_read} - read_mem {EXTENSION_DEGREE} - pop 1 - xx_mul - push {p_pointer_write} - write_mem {EXTENSION_DEGREE} + divine {Digest::LEN} + hint left: Digest = stack[0..5] + // _ l_index_bfe [p] [fact_right] [left] + + {&dup_top_digest} + push {left_digest_pointer_write} + write_mem {Digest::LEN} pop 1 - // _ left_index [right] [left] + // _ l_index_bfe [p] [fact_right] [left] - /* Calculate `fact_left` */ {&digest_to_xfe} - // _ left_index [right] [left_xfe] + // _ l_index_bfe [p] [fact_right] [left_xfe] push {beta_challenge_pointer_read} read_mem {EXTENSION_DEGREE} pop 1 xx_add - // _ left_index [right] [left_xfe - β] + // _ l_index_bfe [p] [fact_right] [left_xfe - β] push {gamma_challenge_pointer_read} read_mem {EXTENSION_DEGREE} pop 1 - // _ left_index [right] [left_xfe - β] [γ] - - dup 11 - // _ left_index [right] [left_xfe - β] [γ] left_index + // _ l_index_bfe [p] [fact_right] [left_xfe - β] [γ] + dup 12 xb_mul - // _ left_index [right] [left_xfe - β] [γ * left_index] + // _ l_index_bfe [p] [fact_right] [left_xfe - β] [l_index_bfe * γ] xx_add - // _ left_index [right] [left_xfe - β + γ * left_index] - // _ left_index [right] [fact_left] <-- rename + // _ l_index_bfe [p] [fact_right] [fact_left] + + xx_mul + // _ l_index_bfe [p] [fact_right * fact_left] x_invert - // _ left_index [right] [fact_left^{-1}] + // _ l_index_bfe [p] [(fact_right*fact_left)^{-1}] - /* Divide `fact_left` out of `p` */ - push {p_pointer_read} - read_mem {EXTENSION_DEGREE} - pop 1 xx_mul - push {p_pointer_write} - write_mem {EXTENSION_DEGREE} + // _ l_index_bfe [p * (fact_right*fact_left)^{-1}] + + /* Calculate t = hash(left, right) */ + push {right_digest_pointer_read} + read_mem {Digest::LEN} pop 1 - // _ left_index [right] + push {left_digest_pointer_read} + read_mem {Digest::LEN} + pop 1 + hash + // _ l_index_bfe [p * (fact_right*fact_left)^{-1}] [t] + + // TODO: We only need to store `t` here if l_index_bfe == 2 + {&dup_top_digest} + push {t_digest_pointer_write} + write_mem {Digest::LEN} + pop 1 + // _ l_index_bfe [p * (fact_right*fact_left)^{-1}] [t] - /* Calculate `fact_right` */ {&digest_to_xfe} - // _ left_index [right_xfe] + // _ l_index_bfe [p * (fact_right*fact_left)^{-1}] [t_xfe] push {beta_challenge_pointer_read} read_mem {EXTENSION_DEGREE} pop 1 xx_add - // _ left_index [right_xfe - β] + // _ l_index_bfe [p * (fact_right*fact_left)^{-1}] [t_xfe - β] push {gamma_challenge_pointer_read} read_mem {EXTENSION_DEGREE} pop 1 - // _ left_index [right_xfe - β] [γ] + // _ l_index_bfe [p * (fact_right*fact_left)^{-1}] [t_xfe - β] [γ] - dup 6 - push 1 - add - // _ left_index [right_xfe - β] [γ] right_index + dup 9 + push {one_half} + mul + // _ l_index_bfe [p * (fact_right*fact_left)^{-1}] [t_xfe - β] [γ] parent_index xb_mul - // _ left_index [right_xfe - β] [right_index * γ] + // _ l_index_bfe [p * (fact_right*fact_left)^{-1}] [t_xfe - β] [parent_index * γ] xx_add - // _ left_index [right_xfe - β + right_index * γ] - // _ left_index [fact_right] <-- rename + // _ l_index_bfe [p * (fact_right*fact_left)^{-1}] [fact_parent] - x_invert - // _ left_index [fact_right^{-1}] - - /* Divide `fact_right` out of `p` */ - push {p_pointer_read} - read_mem {EXTENSION_DEGREE} - pop 1 xx_mul - push {p_pointer_write} - write_mem {EXTENSION_DEGREE} - pop 1 - // _ left_index + // _ l_index_bfe [p * (fact_right*fact_left)^{-1} * fact_parent] + // _ l_index_bfe [p'] + + swap 1 + swap 2 + swap 3 + // _ [p'] l_index_bfe /* Terminate loop when left_index == 2 <=> parent_index == 1 */ push 2 eq skiz return + // _ [p'] recurse ); @@ -564,34 +565,32 @@ impl BasicSnippet for RootFromAuthenticationStruct { pop 1 // _ tree_num_leafs *indexed_leafs [p] [t; 5] - /* Write t value, and `p` to static memory */ + /* Write t value */ push {t_digest_pointer_write} write_mem {Digest::LEN} pop 1 // _ tree_num_leafs *indexed_leafs [p] - push {p_pointer_write} - write_mem {EXTENSION_DEGREE} - pop 2 - // _ tree_num_leafs + // _ tree_num_leafs *indexed_leafs p2 p1 p0 + swap 2 + swap 4 + swap 1 + swap 3 + pop 1 + // _ [p] tree_num_leafs /* Call the ND-loop if tree_num_leafs != 1 */ push 1 eq push 0 eq - // (tree_num_leafs != 1) + // [p] (tree_num_leafs != 1) skiz call {nd_loop_label} - // _ - - /* Assert that p == t_xfe - beta + gamma */ - push {p_pointer_read} - read_mem {EXTENSION_DEGREE} - pop 1 // _ [p] + /* Assert that p == t_xfe - beta + gamma */ push {t_digest_pointer_read} read_mem {Digest::LEN} pop 1 @@ -691,7 +690,8 @@ mod tests { beta: XFieldElement, gamma: XFieldElement, t: Digest, - p: XFieldElement, + right: Digest, + left: Digest, ) { const ALPHA_POINTER_WRITE: BFieldElement = BFieldElement::new(BFieldElement::P - 4); const BETA_POINTER_WRITE: BFieldElement = BFieldElement::new(BFieldElement::P - 7); @@ -699,13 +699,17 @@ mod tests { BFieldElement::new(BFieldElement::P - 10); const T_DIGEST_POINTER_WRITE: BFieldElement = BFieldElement::new(BFieldElement::P - 15); - const P_POINTER_WRITE: BFieldElement = BFieldElement::new(BFieldElement::P - 18); + const RIGHT_DIGEST_POINTER_WRITE: BFieldElement = + BFieldElement::new(BFieldElement::P - 20); + const LEFT_DIGEST_POINTER_WRITE: BFieldElement = + BFieldElement::new(BFieldElement::P - 25); write_to_memory(ALPHA_POINTER_WRITE, alpha, memory); write_to_memory(BETA_POINTER_WRITE, beta, memory); write_to_memory(GAMMA_POINTER_WRITE, gamma, memory); write_to_memory(T_DIGEST_POINTER_WRITE, t, memory); - write_to_memory(P_POINTER_WRITE, p, memory); + write_to_memory(RIGHT_DIGEST_POINTER_WRITE, right, memory); + write_to_memory(LEFT_DIGEST_POINTER_WRITE, left, memory); } fn accumulate_indexed_leafs( @@ -810,6 +814,8 @@ mod tests { // "Unaccumulate" into `p` from secret data, and calculate Merkle root let mut t = indexed_leafs[0].1; let mut t_xfe = digest_to_xfe(t, alpha); + let mut right = Digest::default(); + let mut left = Digest::default(); if tree_num_leafs != 1 { loop { let left_index = individual_tokens.pop_front().unwrap(); @@ -818,8 +824,8 @@ mod tests { let parent_index = left_index / bfe!(2); - let right = read_digest_from_input(&mut individual_tokens); - let left = read_digest_from_input(&mut individual_tokens); + right = read_digest_from_input(&mut individual_tokens); + left = read_digest_from_input(&mut individual_tokens); t = Tip5::hash_pair(left, right); t_xfe = digest_to_xfe(t, alpha); @@ -844,7 +850,7 @@ mod tests { stack.push(elem); } - mimic_use_of_static_memory(memory, alpha, -beta, gamma, t, p); + mimic_use_of_static_memory(memory, alpha, -beta, gamma, t, right, left); vec![] } From b8a587454fb82ba91b12cb18c9798c64a02a570b Mon Sep 17 00:00:00 2001 From: sword_smith Date: Thu, 15 Aug 2024 15:24:08 +0200 Subject: [PATCH 09/14] perf(mmr::authentication_struct): Only store `t` digest in last loop iteration --- ...b_mmr_root_from_authentication_struct.json | 16 +++++------ .../root_from_authentication_struct.rs | 28 +++++++++++++++---- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json b/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json index e6ea6a91f..1708cd5fc 100644 --- a/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json +++ b/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json @@ -2,22 +2,22 @@ { "name": "tasmlib_mmr_root_from_authentication_struct", "benchmark_result": { - "clock_cycle_count": 85070, - "hash_table_height": 5407, + "clock_cycle_count": 82876, + "hash_table_height": 5413, "u32_table_height": 11235, - "op_stack_table_height": 132462, - "ram_table_height": 39264 + "op_stack_table_height": 128066, + "ram_table_height": 36514 }, "case": "CommonCase" }, { "name": "tasmlib_mmr_root_from_authentication_struct", "benchmark_result": { - "clock_cycle_count": 176379, - "hash_table_height": 10741, + "clock_cycle_count": 171813, + "hash_table_height": 10747, "u32_table_height": 41115, - "op_stack_table_height": 274770, - "ram_table_height": 81367 + "op_stack_table_height": 265630, + "ram_table_height": 75652 }, "case": "WorstCase" } diff --git a/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs b/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs index b94ebdc44..259b7e745 100644 --- a/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs +++ b/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs @@ -325,8 +325,22 @@ impl BasicSnippet for RootFromAuthenticationStruct { recurse_or_return ); - let nd_loop_label = format!("{entrypoint}_nd_loop"); let dup_top_digest = triton_asm![dup 4; Digest::LEN]; + let store_t_digest_in_memory_label = format!("{entrypoint}_store_t_digest"); + let store_t_digest_in_memory = triton_asm!( + {store_t_digest_in_memory_label}: + // _ [t] + + {&dup_top_digest} + push {t_digest_pointer_write} + write_mem {Digest::LEN} + pop 1 + // _ [t] + + return + ); + + let nd_loop_label = format!("{entrypoint}_nd_loop"); let one_half = BFieldElement::new(2).inverse(); let nd_loop = triton_asm!( // _ INVARIANT: _ [p] @@ -436,11 +450,12 @@ impl BasicSnippet for RootFromAuthenticationStruct { hash // _ l_index_bfe [p * (fact_right*fact_left)^{-1}] [t] - // TODO: We only need to store `t` here if l_index_bfe == 2 - {&dup_top_digest} - push {t_digest_pointer_write} - write_mem {Digest::LEN} - pop 1 + /* Store [t] digest in memory if this is last loop iteration */ + dup 8 + push 2 + eq + skiz + call {store_t_digest_in_memory_label} // _ l_index_bfe [p * (fact_right*fact_left)^{-1}] [t] {&digest_to_xfe} @@ -626,6 +641,7 @@ impl BasicSnippet for RootFromAuthenticationStruct { {&accumulated_indexed_leafs_loop} {&accumulate_auth_struct_leafs_from_public_data} {&nd_loop} + {&store_t_digest_in_memory} ) } } From a51f079e7c8f63ebacd1f9e76420e7581d998b81 Mon Sep 17 00:00:00 2001 From: sword_smith Date: Thu, 15 Aug 2024 16:33:31 +0200 Subject: [PATCH 10/14] bench(mmr:authentication_struct): More realistic bench params In a mutator-set context for which this is developed, the leaf-indices will be grouped together. The benchmark now reflects that. --- ...b_mmr_root_from_authentication_struct.json | 20 +++---- .../root_from_authentication_struct.rs | 57 +++++++++++++++---- 2 files changed, 56 insertions(+), 21 deletions(-) diff --git a/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json b/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json index 1708cd5fc..b723f98fa 100644 --- a/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json +++ b/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json @@ -2,22 +2,22 @@ { "name": "tasmlib_mmr_root_from_authentication_struct", "benchmark_result": { - "clock_cycle_count": 82876, - "hash_table_height": 5413, - "u32_table_height": 11235, - "op_stack_table_height": 128066, - "ram_table_height": 36514 + "clock_cycle_count": 21218, + "hash_table_height": 1753, + "u32_table_height": 2932, + "op_stack_table_height": 32926, + "ram_table_height": 9604 }, "case": "CommonCase" }, { "name": "tasmlib_mmr_root_from_authentication_struct", "benchmark_result": { - "clock_cycle_count": 171813, - "hash_table_height": 10747, - "u32_table_height": 41115, - "op_stack_table_height": 265630, - "ram_table_height": 75652 + "clock_cycle_count": 26162, + "hash_table_height": 2053, + "u32_table_height": 1736, + "op_stack_table_height": 40578, + "ram_table_height": 11786 }, "case": "WorstCase" } diff --git a/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs b/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs index 259b7e745..b6cfc3033 100644 --- a/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs +++ b/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs @@ -580,7 +580,7 @@ impl BasicSnippet for RootFromAuthenticationStruct { pop 1 // _ tree_num_leafs *indexed_leafs [p] [t; 5] - /* Write t value */ + /* Write t value (in case we're not entering the loop) */ push {t_digest_pointer_write} write_mem {Digest::LEN} pop 1 @@ -878,22 +878,57 @@ mod tests { ) -> ProcedureInitialState { let mut rng: StdRng = SeedableRng::from_seed(seed); - let (tree_height, num_revealed_leafs) = match bench_case { + let num_chunks = 45; + let num_accessible_chunk_indices = 1 << 8; + let (tree_height, revealed_leaf_indices) = match bench_case { None => { - let tree_height = rng.gen_range(0..32); + let tree_height = rng.gen_range(0..62); let num_leafs_in_merkle_tree = 1 << tree_height; - let num_revealed_leafs = rng.gen_range(1..=min(num_leafs_in_merkle_tree, 20)); - (tree_height, num_revealed_leafs) + let num_revealed_leafs = + rng.gen_range(1..=min(num_leafs_in_merkle_tree, num_chunks)); + + let revealed_leaf_indices = (0..num_revealed_leafs) + .map(|_| { + rng.gen_range( + 0..min(num_accessible_chunk_indices, num_leafs_in_merkle_tree), + ) + }) + .unique() + .collect_vec(); + + (tree_height, revealed_leaf_indices) + } + + // In both benchmarks, we leafs from the middle of the Merkle + // tree. Were we pick the indices is not so relevant for + // performance, as long as they're grouped together in a + // realistic way for the mutator set. + Some(BenchmarkCase::CommonCase) => { + let tree_height = 32; + let midpoint = 1 << (tree_height - 1); + let revealed_leaf_indices = (0..num_chunks) + .map(|_| rng.gen_range(midpoint..num_accessible_chunk_indices + midpoint)) + .unique() + .collect_vec(); + + (tree_height, revealed_leaf_indices) + } + Some(BenchmarkCase::WorstCase) => { + let tree_height = 62; + let midpoint = 1 << (tree_height - 1); + let revealed_leaf_indices = (0..num_chunks) + .map(|_| rng.gen_range(midpoint..num_accessible_chunk_indices + midpoint)) + .unique() + .collect_vec(); + + (tree_height, revealed_leaf_indices) } - Some(BenchmarkCase::CommonCase) => (32, 20), - Some(BenchmarkCase::WorstCase) => (62, 20), }; let num_leafs_in_merkle_tree = 1 << tree_height; - let revealed_leaf_indices = (0..num_revealed_leafs) - .map(|_| rng.gen_range(0..num_leafs_in_merkle_tree)) - .unique() - .collect_vec(); + // This picks leaf-indices with low values but I don't think that + // matters for performance. + let num_revealed_leafs = revealed_leaf_indices.len(); assert!(!num_revealed_leafs.is_zero()); From d11f6830002232a8c814e847a660027aa619b9b8 Mon Sep 17 00:00:00 2001 From: Alan Szepieniec Date: Tue, 6 May 2025 12:03:11 +0200 Subject: [PATCH 11/14] chore: Update dependencies Also: adapt `StaticAllocation` to reflect new conventions. --- tasm-lib/Cargo.toml | 2 +- .../derive_challenges.rs | 17 +++--- .../root_from_authentication_struct.rs | 61 ++++++++++--------- .../src/mmr/authentication_struct/shared.rs | 13 ++-- .../src/rust_shadowing_helper_functions.rs | 1 + .../rust_shadowing_helper_functions/input.rs | 58 ++++++++++++++++++ 6 files changed, 109 insertions(+), 43 deletions(-) create mode 100644 tasm-lib/src/rust_shadowing_helper_functions/input.rs diff --git a/tasm-lib/Cargo.toml b/tasm-lib/Cargo.toml index 58f64886c..bf2308ee4 100644 --- a/tasm-lib/Cargo.toml +++ b/tasm-lib/Cargo.toml @@ -32,7 +32,7 @@ itertools = "0" ndarray = { version = "0.16" } num = "0" num-traits = "0" -rand = "0.9.0" +rand = "0.9.1" serde = { version = "1", features = ["derive"] } serde_json = "1" strum = { version = "0.27", features = ["derive"] } diff --git a/tasm-lib/src/mmr/authentication_struct/derive_challenges.rs b/tasm-lib/src/mmr/authentication_struct/derive_challenges.rs index a4920f92d..616a2b11b 100644 --- a/tasm-lib/src/mmr/authentication_struct/derive_challenges.rs +++ b/tasm-lib/src/mmr/authentication_struct/derive_challenges.rs @@ -4,7 +4,7 @@ use crate::data_type::DataType; use crate::hashing::absorb_multiple::AbsorbMultiple; use crate::mmr::authentication_struct::shared; use crate::prelude::BasicSnippet; -use crate::Library; +use crate::prelude::Library; /// Derive and return the challenges that the authentication structure verification /// program uses. @@ -99,9 +99,9 @@ mod tests { use itertools::Itertools; use num::One; - use rand::rngs::StdRng; use rand::Rng; use rand::SeedableRng; + use rand::rngs::StdRng; use shared::AuthenticatedMerkleAuthStruct; use twenty_first::prelude::Sponge; use twenty_first::util_types::mmr::mmr_accumulator::util::mmra_with_mps; @@ -114,7 +114,6 @@ mod tests { use crate::traits::procedure::ProcedureInitialState; use crate::traits::procedure::ShadowedProcedure; use crate::traits::rust_shadow::RustShadow; - use crate::VmHasher; use super::*; @@ -132,7 +131,7 @@ mod tests { memory: &mut HashMap, _nondeterminism: &NonDeterminism, _public_input: &[BFieldElement], - sponge: &mut Option, + sponge: &mut Option, ) -> Vec { let indexed_leafs_pointer = stack.pop().unwrap(); let auth_struct_pointer = stack.pop().unwrap(); @@ -176,17 +175,17 @@ mod tests { let (tree_height, num_revealed_leafs) = match bench_case { Some(BenchmarkCase::CommonCase) => (32, 10), Some(BenchmarkCase::WorstCase) => (62, 10), - None => (rng.gen_range(0..62), 10), + None => (rng.random_range(0..62), 10), }; let leaf_count = 1 << tree_height; let revealed_leaf_indices = (0..num_revealed_leafs) - .map(|_| rng.gen_range(0..leaf_count)) + .map(|_| rng.random_range(0..leaf_count)) .unique() .collect_vec(); let indexed_leafs = revealed_leaf_indices .into_iter() - .map(|leaf_idx: u64| (leaf_idx, rng.gen())) + .map(|leaf_idx: u64| (leaf_idx, rng.random())) .collect_vec(); let (mmra, mps) = mmra_with_mps(leaf_count, indexed_leafs.clone()); let indexed_mmr_mps = indexed_leafs @@ -207,8 +206,8 @@ mod tests { } = &authenticity_witnesses[&0]; let mut memory = HashMap::new(); - let authentication_structure_ptr = rng.gen(); - let indexed_leafs_ptr = rng.gen(); + let authentication_structure_ptr = rng.random(); + let indexed_leafs_ptr = rng.random(); list_insert( authentication_structure_ptr, diff --git a/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs b/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs index b6cfc3033..0d30b40df 100644 --- a/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs +++ b/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs @@ -1,6 +1,5 @@ use triton_vm::prelude::*; use twenty_first::math::x_field_element::EXTENSION_DEGREE; -use twenty_first::prelude::Inverse; use crate::data_type::DataType; use crate::library::Library; @@ -39,21 +38,24 @@ impl BasicSnippet for RootFromAuthenticationStruct { } fn code(&self, library: &mut Library) -> Vec { - let alpha_challenge_pointer_write = library.kmalloc(EXTENSION_DEGREE as u32); - let alpha_challenge_pointer_read = - alpha_challenge_pointer_write + bfe!(EXTENSION_DEGREE as u64 - 1); - let beta_challenge_pointer_write = library.kmalloc(EXTENSION_DEGREE as u32); - let beta_challenge_pointer_read = - beta_challenge_pointer_write + bfe!(EXTENSION_DEGREE as u64 - 1); - let gamma_challenge_pointer_write = library.kmalloc(EXTENSION_DEGREE as u32); - let gamma_challenge_pointer_read = - gamma_challenge_pointer_write + bfe!(EXTENSION_DEGREE as u64 - 1); - let t_digest_pointer_write = library.kmalloc(Digest::LEN as u32); - let t_digest_pointer_read = t_digest_pointer_write + bfe!(Digest::LEN as u64 - 1); - let right_digest_pointer_write = library.kmalloc(Digest::LEN as u32); - let right_digest_pointer_read = right_digest_pointer_write + bfe!(Digest::LEN as u64 - 1); - let left_digest_pointer_write = library.kmalloc(Digest::LEN as u32); - let left_digest_pointer_read = left_digest_pointer_write + bfe!(Digest::LEN as u64 - 1); + let alpha_challenge_pointer = library.kmalloc(EXTENSION_DEGREE as u32); + let alpha_challenge_pointer_write = alpha_challenge_pointer.write_address(); + let alpha_challenge_pointer_read = alpha_challenge_pointer.read_address(); + let beta_challenge_pointer = library.kmalloc(EXTENSION_DEGREE as u32); + let beta_challenge_pointer_write = beta_challenge_pointer.write_address(); + let beta_challenge_pointer_read = beta_challenge_pointer.read_address(); + let gamma_challenge_pointer = library.kmalloc(EXTENSION_DEGREE as u32); + let gamma_challenge_pointer_write = gamma_challenge_pointer.write_address(); + let gamma_challenge_pointer_read = gamma_challenge_pointer.read_address(); + let t_digest_pointer = library.kmalloc(Digest::LEN as u32); + let t_digest_pointer_write = t_digest_pointer.write_address(); + let t_digest_pointer_read = t_digest_pointer.read_address(); + let right_digest_pointer = library.kmalloc(Digest::LEN as u32); + let right_digest_pointer_write = right_digest_pointer.write_address(); + let right_digest_pointer_read = right_digest_pointer.read_address(); + let left_digest_pointer = library.kmalloc(Digest::LEN as u32); + let left_digest_pointer_write = left_digest_pointer.write_address(); + let left_digest_pointer_read = left_digest_pointer.read_address(); let indexed_leaf_element_size = Self::indexed_leaf_element_type().stack_size(); let derive_challenges = library.import(Box::new(DeriveChallenges)); @@ -655,10 +657,10 @@ mod tests { use itertools::Itertools; use num::One; use num::Zero; - use rand::rngs::StdRng; use rand::Rng; use rand::SeedableRng; - use twenty_first::prelude::AlgebraicHasher; + use rand::rngs::StdRng; + use twenty_first::prelude::Sponge; use twenty_first::util_types::mmr::mmr_accumulator::util::mmra_with_mps; @@ -672,7 +674,6 @@ mod tests { use crate::traits::procedure::ProcedureInitialState; use crate::traits::procedure::ShadowedProcedure; use crate::traits::rust_shadow::RustShadow; - use crate::VmHasher; use super::*; @@ -690,7 +691,7 @@ mod tests { memory: &mut std::collections::HashMap, nondeterminism: &NonDeterminism, _public_input: &[BFieldElement], - sponge: &mut Option, + sponge: &mut Option, ) -> Vec { fn digest_to_xfe(digest: Digest, challenge: XFieldElement) -> XFieldElement { let [l0, l1, l2, l3, l4] = digest.0; @@ -882,14 +883,14 @@ mod tests { let num_accessible_chunk_indices = 1 << 8; let (tree_height, revealed_leaf_indices) = match bench_case { None => { - let tree_height = rng.gen_range(0..62); + let tree_height = rng.random_range(0..62); let num_leafs_in_merkle_tree = 1 << tree_height; let num_revealed_leafs = - rng.gen_range(1..=min(num_leafs_in_merkle_tree, num_chunks)); + rng.random_range(1..=min(num_leafs_in_merkle_tree, num_chunks)); let revealed_leaf_indices = (0..num_revealed_leafs) .map(|_| { - rng.gen_range( + rng.random_range( 0..min(num_accessible_chunk_indices, num_leafs_in_merkle_tree), ) }) @@ -907,7 +908,9 @@ mod tests { let tree_height = 32; let midpoint = 1 << (tree_height - 1); let revealed_leaf_indices = (0..num_chunks) - .map(|_| rng.gen_range(midpoint..num_accessible_chunk_indices + midpoint)) + .map(|_| { + rng.random_range(midpoint..num_accessible_chunk_indices + midpoint) + }) .unique() .collect_vec(); @@ -917,7 +920,9 @@ mod tests { let tree_height = 62; let midpoint = 1 << (tree_height - 1); let revealed_leaf_indices = (0..num_chunks) - .map(|_| rng.gen_range(midpoint..num_accessible_chunk_indices + midpoint)) + .map(|_| { + rng.random_range(midpoint..num_accessible_chunk_indices + midpoint) + }) .unique() .collect_vec(); @@ -933,7 +938,7 @@ mod tests { assert!(!num_revealed_leafs.is_zero()); let revealed_leafs: Vec = - (0..num_revealed_leafs).map(|_| rng.gen()).collect_vec(); + (0..num_revealed_leafs).map(|_| rng.random()).collect_vec(); let indexed_leafs = revealed_leaf_indices .into_iter() .zip_eq(revealed_leafs) @@ -952,8 +957,8 @@ mod tests { let mmr_authentication_struct = &mmr_authentication_struct[&0]; let mut memory = HashMap::new(); - let authentication_structure_ptr = rng.gen(); - let indexed_leafs_ptr = rng.gen(); + let authentication_structure_ptr = rng.random(); + let indexed_leafs_ptr = rng.random(); list_insert( authentication_structure_ptr, diff --git a/tasm-lib/src/mmr/authentication_struct/shared.rs b/tasm-lib/src/mmr/authentication_struct/shared.rs index 5418c0635..c1eba8a9d 100644 --- a/tasm-lib/src/mmr/authentication_struct/shared.rs +++ b/tasm-lib/src/mmr/authentication_struct/shared.rs @@ -58,7 +58,10 @@ impl AuthStructIntegrityProof { let mut node_can_be_computed = HashSet::new(); for &leaf_index in leaf_indices { - assert!(num_leafs > leaf_index, "Leaf index must be less than number of leafs. Got leaf_index = {leaf_index}; num_leafs = {num_leafs}"); + assert!( + num_leafs > leaf_index, + "Leaf index must be less than number of leafs. Got leaf_index = {leaf_index}; num_leafs = {num_leafs}" + ); let mut node_index = leaf_index + num_leafs; while node_index > ROOT_MT_INDEX { @@ -311,7 +314,7 @@ impl AuthStructIntegrityProof { /// Return the authentication structure witness, authentication structure, /// and the (leaf-index, leaf-digest) pairs. pub fn new_from_merkle_tree( - tree: &MerkleTree, + tree: &MerkleTree, mut revealed_leaf_indices: Vec, ) -> AuthenticatedMerkleAuthStruct { revealed_leaf_indices.sort_unstable(); @@ -433,7 +436,7 @@ mod tests { let tree_height = 3u32; let num_leafs = 1u64 << tree_height; let leafs: Vec = random_elements(num_leafs.try_into().unwrap()); - let tree = MerkleTree::::new::(&leafs).unwrap(); + let tree = MerkleTree::par_new(&leafs).unwrap(); let authenticated_auth_struct = AuthStructIntegrityProof::new_from_merkle_tree(&tree, vec![0]); @@ -536,7 +539,7 @@ mod tests { ) { let num_leafs = 1u64 << tree_height; let leafs: Vec = random_elements(num_leafs.try_into().unwrap()); - let tree = MerkleTree::::new::(&leafs).unwrap(); + let tree = MerkleTree::par_new(&leafs).unwrap(); let authenticated_auth_struct = AuthStructIntegrityProof::new_from_merkle_tree(&tree, revealed_leaf_indices); @@ -560,7 +563,7 @@ mod tests { nd_sibling_indices: Vec<(u64, u64)>, ) { let leafs: Vec = random_elements(1 << tree_height); - let tree = MerkleTree::::new::(&leafs).unwrap(); + let tree = MerkleTree::par_new(&leafs).unwrap(); let auth_struct = nd_auth_struct_indices .iter() diff --git a/tasm-lib/src/rust_shadowing_helper_functions.rs b/tasm-lib/src/rust_shadowing_helper_functions.rs index edaf24808..c3a1a225e 100644 --- a/tasm-lib/src/rust_shadowing_helper_functions.rs +++ b/tasm-lib/src/rust_shadowing_helper_functions.rs @@ -1,6 +1,7 @@ pub mod array; pub mod claim; pub mod dyn_malloc; +pub mod input; pub mod list; pub mod memory; diff --git a/tasm-lib/src/rust_shadowing_helper_functions/input.rs b/tasm-lib/src/rust_shadowing_helper_functions/input.rs new file mode 100644 index 000000000..a766bddfd --- /dev/null +++ b/tasm-lib/src/rust_shadowing_helper_functions/input.rs @@ -0,0 +1,58 @@ +use std::collections::VecDeque; + +use num::Zero; +use triton_vm::prelude::*; +use twenty_first::math::other::random_elements; + +use crate::Digest; + +pub fn write_digest_to_std_in(std_in: &mut Vec, digest: Digest) { + let digest_elements = digest.values(); + for i in 0..Digest::LEN { + std_in.push(digest_elements[Digest::LEN - 1 - i]); + } +} + +pub fn write_value_to_secret_in(secret_in: &mut Vec, value: BFieldElement) { + secret_in.push(value) +} + +pub fn write_digest_to_secret_in(secret_in: &mut Vec, digest: Digest) { + let digest_elements = digest.values(); + for i in 0..Digest::LEN { + secret_in.push(digest_elements[Digest::LEN - 1 - i]); + } +} + +pub fn write_dummy_ap_path(input: &mut Vec, ap_length: usize) { + input.push(BFieldElement::new(ap_length as u64)); + let ap_elements: Vec = random_elements(ap_length); + for ap_element in ap_elements.iter() { + write_digest_to_secret_in(input, *ap_element); + } +} + +pub fn read_digest_from_std_in(std_in: &[BFieldElement], std_in_cursor: &mut usize) -> Digest { + let mut values = [BFieldElement::zero(); Digest::LEN]; + let mut i = 0; + while i < Digest::LEN { + values[Digest::LEN - 1 - i] = std_in[*std_in_cursor]; + *std_in_cursor += 1; + i += 1; + } + + Digest::new(values) +} + +/// Read and consume a digest from an input source, either public input or +/// secret input. Returns the digest. +pub fn read_digest_from_input(secret_in: &mut VecDeque) -> Digest { + let mut values = [BFieldElement::zero(); Digest::LEN]; + let mut i = 0; + while i < Digest::LEN { + values[Digest::LEN - 1 - i] = secret_in.pop_front().unwrap(); + i += 1; + } + + Digest::new(values) +} From 94d4d17cedc94146547ccea8914ac6d538886d66 Mon Sep 17 00:00:00 2001 From: Alan Szepieniec Date: Tue, 6 May 2025 15:55:56 +0200 Subject: [PATCH 12/14] chore: Depend on new `twenty-first` version for Merkle tree --- tasm-lib/Cargo.toml | 3 + ...thentication_struct_derive_challenges.json | 18 +- ...b_mmr_root_from_authentication_struct.json | 20 +- .../arithmetic/bfe/primitive_root_of_unity.rs | 2 +- tasm-lib/src/arithmetic/xfe/mod_pow_u32.rs | 2 +- .../xfe/to_the_power_of_power_of_2.rs | 2 +- tasm-lib/src/array/sum_of_xfes.rs | 2 +- tasm-lib/src/hashing/absorb_multiple.rs | 2 +- .../hashing/absorb_multiple_static_size.rs | 4 +- .../algebraic_hasher/hash_static_size.rs | 2 +- .../hashing/algebraic_hasher/hash_varlen.rs | 2 +- .../algebraic_hasher/sample_scalar_one.rs | 4 +- .../algebraic_hasher/sample_scalars.rs | 4 +- ...sample_scalars_static_length_dyn_malloc.rs | 6 +- .../sample_scalars_static_length_kmalloc.rs | 6 +- ...le_scalars_static_length_static_pointer.rs | 6 +- tasm-lib/src/hashing/hash_from_stack.rs | 2 +- tasm-lib/src/hashing/merkle_root.rs | 26 ++- tasm-lib/src/hashing/merkle_root_from_xfes.rs | 40 +++- tasm-lib/src/hashing/sponge_hasher/absorb.rs | 6 +- tasm-lib/src/hashing/sponge_hasher/init.rs | 2 +- .../sponge_hasher/pad_and_absorb_all.rs | 2 +- tasm-lib/src/hashing/sponge_hasher/squeeze.rs | 4 +- tasm-lib/src/hashing/squeeze_repeatedly.rs | 2 +- .../squeeze_repeatedly_static_number.rs | 2 +- .../list/horner_evaluation_dynamic_length.rs | 2 +- .../src/list/multiset_equality_digests.rs | 2 +- tasm-lib/src/list/multiset_equality_u64s.rs | 2 +- tasm-lib/src/list/sum_xfes.rs | 4 +- .../derive_challenges.rs | 4 +- .../root_from_authentication_struct.rs | 6 +- tasm-lib/src/mmr/bag_peaks.rs | 2 +- .../mmr/calculate_new_peaks_from_append.rs | 2 +- .../leaf_index_to_mt_index_and_peak_index.rs | 2 +- tasm-lib/src/mmr/verify_from_memory.rs | 4 +- ...rify_from_secret_in_leaf_index_on_stack.rs | 12 +- ...verify_from_secret_in_secret_leaf_index.rs | 12 +- tasm-lib/src/mmr/verify_mmr_successor.rs | 8 +- .../neptune/mutator_set/get_swbf_indices.rs | 2 +- .../neptune/neptune_like_types_for_tests.rs | 4 +- .../rust_shadowing_helper_functions/array.rs | 2 +- .../rust_shadowing_helper_functions/input.rs | 2 +- .../rust_shadowing_helper_functions/list.rs | 2 +- .../manual_tasm_object_implementations.rs | 8 +- tasm-lib/src/structure/tasm_object.rs | 2 +- .../src/structure/verify_nd_si_integrity.rs | 2 +- .../challenges/new_empty_input_and_output.rs | 2 +- .../challenges/new_generic_dyn_claim.rs | 4 +- .../instantiate_fiat_shamir_with_claim.rs | 4 +- .../verifier/fri/barycentric_evaluation.rs | 8 +- tasm-lib/src/verifier/fri/collinear_y.rs | 2 +- tasm-lib/src/verifier/fri/number_of_rounds.rs | 2 +- tasm-lib/src/verifier/fri/test_helpers.rs | 2 +- tasm-lib/src/verifier/fri/verify.rs | 189 +++++++++++++++--- .../fri/verify_fri_authentication_paths.rs | 4 +- .../master_table/air_constraint_evaluation.rs | 4 +- .../master_table/divide_out_zerofiers.rs | 8 +- .../master_table/verify_table_rows.rs | 8 +- .../master_table/zerofiers_inverse.rs | 6 +- tasm-lib/src/verifier/out_of_domain_points.rs | 6 +- tasm-lib/src/verifier/stark_verify.rs | 4 +- .../verifier/vm_proof_iter/dequeue_next_as.rs | 6 +- tasm-lib/src/verifier/xfe_ntt.rs | 4 +- 63 files changed, 341 insertions(+), 179 deletions(-) diff --git a/tasm-lib/Cargo.toml b/tasm-lib/Cargo.toml index bf2308ee4..91b02014e 100644 --- a/tasm-lib/Cargo.toml +++ b/tasm-lib/Cargo.toml @@ -39,6 +39,9 @@ strum = { version = "0.27", features = ["derive"] } tasm-object-derive.workspace = true triton-vm = { version = "0.48.0", default-features = false } +# revision "8b372a513c5b0c91578b62c902219818f5d76d2d" is tip of tip of PR branch asz/merkle-tree-index-types on 2025-05-06 +twenty-first = { git = "https://github.com/Neptune-Crypto/twenty-first", rev = "8b372a513c5b0c91578b62c902219818f5d76d2d" } + [dev-dependencies.cargo-husky] version = "1" default-features = false diff --git a/tasm-lib/benchmarks/tasmlib_mmr_authentication_struct_derive_challenges.json b/tasm-lib/benchmarks/tasmlib_mmr_authentication_struct_derive_challenges.json index e317de7aa..76919995e 100644 --- a/tasm-lib/benchmarks/tasmlib_mmr_authentication_struct_derive_challenges.json +++ b/tasm-lib/benchmarks/tasmlib_mmr_authentication_struct_derive_challenges.json @@ -2,22 +2,22 @@ { "name": "tasmlib_mmr_authentication_struct_derive_challenges", "benchmark_result": { - "clock_cycle_count": 1196, - "hash_table_height": 985, - "u32_table_height": 25, - "op_stack_table_height": 833, - "ram_table_height": 1454 + "clock_cycle_count": 1122, + "hash_table_height": 961, + "u32_table_height": 30, + "op_stack_table_height": 785, + "ram_table_height": 1439 }, "case": "CommonCase" }, { "name": "tasmlib_mmr_authentication_struct_derive_challenges", "benchmark_result": { - "clock_cycle_count": 2102, - "hash_table_height": 1891, + "clock_cycle_count": 2046, + "hash_table_height": 1885, "u32_table_height": 26, - "op_stack_table_height": 1437, - "ram_table_height": 2964 + "op_stack_table_height": 1401, + "ram_table_height": 2974 }, "case": "WorstCase" } diff --git a/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json b/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json index b723f98fa..e1155b886 100644 --- a/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json +++ b/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json @@ -2,22 +2,22 @@ { "name": "tasmlib_mmr_root_from_authentication_struct", "benchmark_result": { - "clock_cycle_count": 21218, - "hash_table_height": 1753, - "u32_table_height": 2932, - "op_stack_table_height": 32926, - "ram_table_height": 9604 + "clock_cycle_count": 21485, + "hash_table_height": 1759, + "u32_table_height": 3034, + "op_stack_table_height": 33376, + "ram_table_height": 9732 }, "case": "CommonCase" }, { "name": "tasmlib_mmr_root_from_authentication_struct", "benchmark_result": { - "clock_cycle_count": 26162, - "hash_table_height": 2053, - "u32_table_height": 1736, - "op_stack_table_height": 40578, - "ram_table_height": 11786 + "clock_cycle_count": 25085, + "hash_table_height": 1975, + "u32_table_height": 1805, + "op_stack_table_height": 38944, + "ram_table_height": 11316 }, "case": "WorstCase" } diff --git a/tasm-lib/src/arithmetic/bfe/primitive_root_of_unity.rs b/tasm-lib/src/arithmetic/bfe/primitive_root_of_unity.rs index efa4954fb..3469adc55 100644 --- a/tasm-lib/src/arithmetic/bfe/primitive_root_of_unity.rs +++ b/tasm-lib/src/arithmetic/bfe/primitive_root_of_unity.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; +use triton_vm::prelude::twenty_first::math::traits::PrimitiveRootOfUnity as PRU; use triton_vm::prelude::*; -use twenty_first::math::traits::PrimitiveRootOfUnity as PRU; use crate::prelude::*; use crate::traits::basic_snippet::Reviewer; diff --git a/tasm-lib/src/arithmetic/xfe/mod_pow_u32.rs b/tasm-lib/src/arithmetic/xfe/mod_pow_u32.rs index 0098b289e..e4ae2b37b 100644 --- a/tasm-lib/src/arithmetic/xfe/mod_pow_u32.rs +++ b/tasm-lib/src/arithmetic/xfe/mod_pow_u32.rs @@ -142,7 +142,7 @@ impl BasicSnippet for XfeModPowU32 { #[cfg(test)] pub mod tests { - use twenty_first::math::traits::ModPowU32; + use triton_vm::prelude::twenty_first::math::traits::ModPowU32; use super::*; use crate::empty_stack; diff --git a/tasm-lib/src/arithmetic/xfe/to_the_power_of_power_of_2.rs b/tasm-lib/src/arithmetic/xfe/to_the_power_of_power_of_2.rs index 5399e1079..ef34f71ea 100644 --- a/tasm-lib/src/arithmetic/xfe/to_the_power_of_power_of_2.rs +++ b/tasm-lib/src/arithmetic/xfe/to_the_power_of_power_of_2.rs @@ -90,7 +90,7 @@ impl BasicSnippet for ToThePowerOfPowerOf2 { #[cfg(test)] mod tests { - use twenty_first::math::traits::ModPowU32; + use triton_vm::prelude::twenty_first::math::traits::ModPowU32; use super::*; use crate::arithmetic::xfe::mod_pow_u32::XfeModPowU32; diff --git a/tasm-lib/src/array/sum_of_xfes.rs b/tasm-lib/src/array/sum_of_xfes.rs index 52aae39ed..092d8bee4 100644 --- a/tasm-lib/src/array/sum_of_xfes.rs +++ b/tasm-lib/src/array/sum_of_xfes.rs @@ -1,6 +1,6 @@ use num::Zero; use triton_vm::prelude::*; -use twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use crate::data_type::ArrayType; use crate::memory::load_words_from_memory_pop_pointer; diff --git a/tasm-lib/src/hashing/absorb_multiple.rs b/tasm-lib/src/hashing/absorb_multiple.rs index 8c777c34a..8e43467f0 100644 --- a/tasm-lib/src/hashing/absorb_multiple.rs +++ b/tasm-lib/src/hashing/absorb_multiple.rs @@ -146,7 +146,7 @@ impl BasicSnippet for AbsorbMultiple { mod tests { use std::collections::VecDeque; - use twenty_first::prelude::Sponge; + use triton_vm::prelude::twenty_first::prelude::Sponge; use super::*; use crate::empty_stack; diff --git a/tasm-lib/src/hashing/absorb_multiple_static_size.rs b/tasm-lib/src/hashing/absorb_multiple_static_size.rs index a7962c5ef..020dcfb64 100644 --- a/tasm-lib/src/hashing/absorb_multiple_static_size.rs +++ b/tasm-lib/src/hashing/absorb_multiple_static_size.rs @@ -1,5 +1,5 @@ use triton_vm::prelude::*; -use twenty_first::math::tip5::RATE; +use triton_vm::prelude::twenty_first::math::tip5::RATE; use crate::memory::load_words_from_memory_pop_pointer; use crate::prelude::*; @@ -102,7 +102,7 @@ impl BasicSnippet for AbsorbMultipleStaticSize { #[cfg(test)] mod tests { - use twenty_first::prelude::Sponge; + use triton_vm::prelude::twenty_first::prelude::Sponge; use super::*; use crate::test_prelude::*; diff --git a/tasm-lib/src/hashing/algebraic_hasher/hash_static_size.rs b/tasm-lib/src/hashing/algebraic_hasher/hash_static_size.rs index 870b09f70..68019bec2 100644 --- a/tasm-lib/src/hashing/algebraic_hasher/hash_static_size.rs +++ b/tasm-lib/src/hashing/algebraic_hasher/hash_static_size.rs @@ -53,7 +53,7 @@ impl BasicSnippet for HashStaticSize { #[cfg(test)] mod tests { - use twenty_first::prelude::*; + use triton_vm::prelude::twenty_first::prelude::*; use super::*; use crate::test_prelude::*; diff --git a/tasm-lib/src/hashing/algebraic_hasher/hash_varlen.rs b/tasm-lib/src/hashing/algebraic_hasher/hash_varlen.rs index ab6598279..4da808dcf 100644 --- a/tasm-lib/src/hashing/algebraic_hasher/hash_varlen.rs +++ b/tasm-lib/src/hashing/algebraic_hasher/hash_varlen.rs @@ -73,7 +73,7 @@ impl BasicSnippet for HashVarlen { mod tests { use std::collections::VecDeque; - use twenty_first::prelude::*; + use triton_vm::prelude::twenty_first::prelude::*; use super::*; use crate::empty_stack; diff --git a/tasm-lib/src/hashing/algebraic_hasher/sample_scalar_one.rs b/tasm-lib/src/hashing/algebraic_hasher/sample_scalar_one.rs index 98b3d87a2..1416e6b75 100644 --- a/tasm-lib/src/hashing/algebraic_hasher/sample_scalar_one.rs +++ b/tasm-lib/src/hashing/algebraic_hasher/sample_scalar_one.rs @@ -46,8 +46,8 @@ impl BasicSnippet for SampleScalarOne { #[cfg(test)] mod tests { - use twenty_first::math::x_field_element::EXTENSION_DEGREE; - use twenty_first::util_types::sponge::Sponge; + use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; + use triton_vm::prelude::twenty_first::util_types::sponge::Sponge; use super::*; use crate::test_prelude::*; diff --git a/tasm-lib/src/hashing/algebraic_hasher/sample_scalars.rs b/tasm-lib/src/hashing/algebraic_hasher/sample_scalars.rs index ade4859c6..4fc8a955a 100644 --- a/tasm-lib/src/hashing/algebraic_hasher/sample_scalars.rs +++ b/tasm-lib/src/hashing/algebraic_hasher/sample_scalars.rs @@ -1,5 +1,5 @@ use triton_vm::prelude::*; -use twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use crate::hashing::squeeze_repeatedly::SqueezeRepeatedly; use crate::list::new::New; @@ -80,7 +80,7 @@ impl BasicSnippet for SampleScalars { #[cfg(test)] mod tests { - use twenty_first::prelude::*; + use triton_vm::prelude::twenty_first::prelude::*; use super::*; use crate::empty_stack; diff --git a/tasm-lib/src/hashing/algebraic_hasher/sample_scalars_static_length_dyn_malloc.rs b/tasm-lib/src/hashing/algebraic_hasher/sample_scalars_static_length_dyn_malloc.rs index 0109bb1e2..28c72f30b 100644 --- a/tasm-lib/src/hashing/algebraic_hasher/sample_scalars_static_length_dyn_malloc.rs +++ b/tasm-lib/src/hashing/algebraic_hasher/sample_scalars_static_length_dyn_malloc.rs @@ -1,6 +1,6 @@ use triton_vm::prelude::*; -use twenty_first::math::tip5::RATE; -use twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::twenty_first::math::tip5::RATE; +use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use crate::data_type::ArrayType; use crate::hashing::squeeze_repeatedly_static_number::SqueezeRepeatedlyStaticNumber; @@ -79,7 +79,7 @@ impl BasicSnippet for SampleScalarsStaticLengthDynMalloc { #[cfg(test)] mod tests { - use twenty_first::prelude::*; + use triton_vm::prelude::twenty_first::prelude::*; use super::*; use crate::memory::dyn_malloc::DYN_MALLOC_FIRST_ADDRESS; diff --git a/tasm-lib/src/hashing/algebraic_hasher/sample_scalars_static_length_kmalloc.rs b/tasm-lib/src/hashing/algebraic_hasher/sample_scalars_static_length_kmalloc.rs index d265401be..711192566 100644 --- a/tasm-lib/src/hashing/algebraic_hasher/sample_scalars_static_length_kmalloc.rs +++ b/tasm-lib/src/hashing/algebraic_hasher/sample_scalars_static_length_kmalloc.rs @@ -1,6 +1,6 @@ use triton_vm::prelude::*; -use twenty_first::math::tip5::RATE; -use twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::twenty_first::math::tip5::RATE; +use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use crate::hashing::algebraic_hasher::sample_scalars_static_length_dyn_malloc::SampleScalarsStaticLengthDynMalloc; use crate::hashing::squeeze_repeatedly_static_number::SqueezeRepeatedlyStaticNumber; @@ -84,7 +84,7 @@ impl BasicSnippet for SampleScalarsStaticLengthKMalloc { pub(crate) mod tests { use std::ops::Neg; - use twenty_first::util_types::sponge::Sponge; + use triton_vm::prelude::twenty_first::util_types::sponge::Sponge; use super::*; use crate::rust_shadowing_helper_functions::array::array_get; diff --git a/tasm-lib/src/hashing/algebraic_hasher/sample_scalars_static_length_static_pointer.rs b/tasm-lib/src/hashing/algebraic_hasher/sample_scalars_static_length_static_pointer.rs index 49ee137c2..c7d80a3e4 100644 --- a/tasm-lib/src/hashing/algebraic_hasher/sample_scalars_static_length_static_pointer.rs +++ b/tasm-lib/src/hashing/algebraic_hasher/sample_scalars_static_length_static_pointer.rs @@ -1,6 +1,6 @@ use triton_vm::prelude::*; -use twenty_first::math::tip5::RATE; -use twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::twenty_first::math::tip5::RATE; +use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use crate::hashing::algebraic_hasher::sample_scalars_static_length_dyn_malloc::SampleScalarsStaticLengthDynMalloc; use crate::hashing::squeeze_repeatedly_static_number::SqueezeRepeatedlyStaticNumber; @@ -72,7 +72,7 @@ impl BasicSnippet for SampleScalarsStaticLengthStaticPointer { #[cfg(test)] pub(crate) mod tests { - use twenty_first::util_types::sponge::Sponge; + use triton_vm::prelude::twenty_first::util_types::sponge::Sponge; use super::*; use crate::prelude::Tip5; diff --git a/tasm-lib/src/hashing/hash_from_stack.rs b/tasm-lib/src/hashing/hash_from_stack.rs index cd265831a..07b532d36 100644 --- a/tasm-lib/src/hashing/hash_from_stack.rs +++ b/tasm-lib/src/hashing/hash_from_stack.rs @@ -1,5 +1,5 @@ use triton_vm::prelude::*; -use twenty_first::prelude::*; +use triton_vm::prelude::twenty_first::prelude::*; use crate::prelude::*; diff --git a/tasm-lib/src/hashing/merkle_root.rs b/tasm-lib/src/hashing/merkle_root.rs index 3f2872d78..507cce913 100644 --- a/tasm-lib/src/hashing/merkle_root.rs +++ b/tasm-lib/src/hashing/merkle_root.rs @@ -205,8 +205,8 @@ impl BasicSnippet for MerkleRoot { #[cfg(test)] mod tests { + use ::twenty_first::util_types::merkle_tree::MerkleTree; use proptest::collection::vec; - use twenty_first::util_types::merkle_tree::MerkleTree; use super::*; use crate::rust_shadowing_helper_functions::dyn_malloc::dynamic_allocator; @@ -234,19 +234,31 @@ mod tests { memory: &mut HashMap, ) { let leafs_pointer = stack.pop().unwrap(); - let leafs = *Vec::decode_from_memory(memory, leafs_pointer).unwrap(); - let mt = MerkleTree::par_new(&leafs).unwrap(); + let leafs = *Vec::::decode_from_memory(memory, leafs_pointer).unwrap(); + let leafs_compatible = leafs + .iter() + .map(|d| { + d.values() + .map(|b| ::twenty_first::prelude::BFieldElement::new(b.value())) + }) + .map(::twenty_first::prelude::Digest) + .collect_vec(); + let mt = MerkleTree::par_new(&leafs_compatible).unwrap(); // mimic snippet: write internal nodes to memory, skipping (dummy) node 0 let tree_pointer = dynamic_allocator(memory); let num_internal_nodes = leafs.len(); - for (node_index, node) in (0..num_internal_nodes).zip(mt.nodes()).skip(1) { - let node_address = tree_pointer + bfe!(node_index * Digest::LEN); - encode_to_memory(memory, node_address, node); + for node_index in 1_u64..(num_internal_nodes as u64) { + let node = mt.node(node_index).unwrap(); + let node_address = tree_pointer + bfe!(node_index * (Digest::LEN as u64)); + let node_compatible = Digest(node.values().map(|b| BFieldElement::new(b.value()))); + encode_to_memory(memory, node_address, &node_compatible); } - stack.extend(mt.root().reversed().values()); + let root = mt.root().reversed().values(); + let root_compatible = root.map(|b| BFieldElement::new(b.value())); + stack.extend(root_compatible); } fn pseudorandom_initial_state( diff --git a/tasm-lib/src/hashing/merkle_root_from_xfes.rs b/tasm-lib/src/hashing/merkle_root_from_xfes.rs index 63f2b6a3b..d9f82b739 100644 --- a/tasm-lib/src/hashing/merkle_root_from_xfes.rs +++ b/tasm-lib/src/hashing/merkle_root_from_xfes.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; +use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use triton_vm::prelude::*; -use twenty_first::math::x_field_element::EXTENSION_DEGREE; use crate::hashing::merkle_root::MerkleRoot; use crate::prelude::*; @@ -209,8 +209,8 @@ impl BasicSnippet for MerkleRootFromXfes { #[cfg(test)] mod tests { + use ::twenty_first::prelude::MerkleTree; use proptest::collection::vec; - use twenty_first::util_types::merkle_tree::MerkleTree; use super::*; use crate::rust_shadowing_helper_functions::dyn_malloc::dynamic_allocator; @@ -244,10 +244,21 @@ mod tests { let leafs_pointer = stack.pop().unwrap(); let leafs = *Vec::::decode_from_memory(memory, leafs_pointer).unwrap(); let leafs = leafs.into_iter().map(Digest::from).collect_vec(); - let mt = MerkleTree::par_new(&leafs).unwrap(); + let leafs_compatible = leafs + .iter() + .map(|d| { + d.values() + .map(|v| v.value()) + .map(::twenty_first::prelude::BFieldElement::from) + }) + .map(::twenty_first::prelude::Digest) + .collect_vec(); + let mt = MerkleTree::par_new(&leafs_compatible).unwrap(); if leafs.len() == 1 { - stack.extend(mt.root().reversed().values()); + let root = mt.root().reversed().values(); + let root_compatible = root.map(|v| BFieldElement::new(v.value())); + stack.extend(root_compatible); return; } @@ -255,22 +266,31 @@ mod tests { let first_layer_pointer = dynamic_allocator(memory); list_new(first_layer_pointer, memory); for node_count in 0..(leafs.len() >> 1) { - let node_index = node_count + (1 << (mt.height() - 1)); + let node_index = (node_count as u64) + (1 << (mt.height() - 1)); let node = mt.node(node_index).unwrap(); - list_push(first_layer_pointer, node.values().to_vec(), memory) + let node_values = node.values().to_vec(); + let node_values_compatible = node_values + .into_iter() + .map(|b| BFieldElement::new(b.value())) + .collect_vec(); + list_push(first_layer_pointer, node_values_compatible, memory) } let rest_of_tree_pointer = dynamic_allocator(memory); for layer in 2..=mt.height() { for node_count in 0..(leafs.len() >> layer) { - let node_index = node_count + (1 << (mt.height() - layer)); + let node_index = (node_count as u64) + (1 << (mt.height() - layer)); let node = mt.node(node_index).unwrap(); - let pointer = rest_of_tree_pointer + bfe!(node_index * Digest::LEN); - encode_to_memory(memory, pointer, &node); + let pointer = rest_of_tree_pointer + bfe!(node_index * (Digest::LEN as u64)); + let node_compatible = + Digest(node.values().map(|b| BFieldElement::new(b.value()))); + encode_to_memory(memory, pointer, &node_compatible); } } - stack.extend(mt.root().reversed().values()); + let root = mt.root().reversed().values(); + let root_compatible = root.map(|b| BFieldElement::new(b.value())); + stack.extend(root_compatible); } fn pseudorandom_initial_state( diff --git a/tasm-lib/src/hashing/sponge_hasher/absorb.rs b/tasm-lib/src/hashing/sponge_hasher/absorb.rs index 6ce2ebcb3..a8ae31aa9 100644 --- a/tasm-lib/src/hashing/sponge_hasher/absorb.rs +++ b/tasm-lib/src/hashing/sponge_hasher/absorb.rs @@ -1,5 +1,5 @@ use triton_vm::prelude::*; -use twenty_first::math::tip5::RATE; +use triton_vm::prelude::twenty_first::math::tip5::RATE; use crate::data_type::ArrayType; use crate::prelude::*; @@ -76,8 +76,8 @@ impl BasicSnippet for Absorb { mod tests { use arbitrary::Arbitrary; use arbitrary::Unstructured; - use twenty_first::math::other::random_elements; - use twenty_first::prelude::Sponge; + use triton_vm::prelude::twenty_first::math::other::random_elements; + use triton_vm::prelude::twenty_first::prelude::Sponge; use super::*; use crate::empty_stack; diff --git a/tasm-lib/src/hashing/sponge_hasher/init.rs b/tasm-lib/src/hashing/sponge_hasher/init.rs index 4b862343f..e61f7476d 100644 --- a/tasm-lib/src/hashing/sponge_hasher/init.rs +++ b/tasm-lib/src/hashing/sponge_hasher/init.rs @@ -32,7 +32,7 @@ impl BasicSnippet for Init { mod tests { use arbitrary::Arbitrary; use arbitrary::Unstructured; - use twenty_first::prelude::Sponge; + use triton_vm::prelude::twenty_first::prelude::Sponge; use super::*; use crate::empty_stack; diff --git a/tasm-lib/src/hashing/sponge_hasher/pad_and_absorb_all.rs b/tasm-lib/src/hashing/sponge_hasher/pad_and_absorb_all.rs index d5760e2bc..b90b2bd46 100644 --- a/tasm-lib/src/hashing/sponge_hasher/pad_and_absorb_all.rs +++ b/tasm-lib/src/hashing/sponge_hasher/pad_and_absorb_all.rs @@ -49,7 +49,7 @@ mod tests { use arbitrary::Arbitrary; use arbitrary::Unstructured; use triton_vm::prelude::*; - use twenty_first::prelude::Sponge; + use triton_vm::prelude::twenty_first::prelude::Sponge; use super::*; use crate::empty_stack; diff --git a/tasm-lib/src/hashing/sponge_hasher/squeeze.rs b/tasm-lib/src/hashing/sponge_hasher/squeeze.rs index 738a8b9d7..15490bc96 100644 --- a/tasm-lib/src/hashing/sponge_hasher/squeeze.rs +++ b/tasm-lib/src/hashing/sponge_hasher/squeeze.rs @@ -1,5 +1,5 @@ use triton_vm::prelude::*; -use twenty_first::math::tip5::RATE; +use triton_vm::prelude::twenty_first::math::tip5::RATE; use crate::data_type::ArrayType; use crate::prelude::*; @@ -66,7 +66,7 @@ impl BasicSnippet for Squeeze { mod tests { use arbitrary::Arbitrary; use arbitrary::Unstructured; - use twenty_first::prelude::Sponge; + use triton_vm::prelude::twenty_first::prelude::Sponge; use super::*; use crate::empty_stack; diff --git a/tasm-lib/src/hashing/squeeze_repeatedly.rs b/tasm-lib/src/hashing/squeeze_repeatedly.rs index a697c199e..9dc51d2fb 100644 --- a/tasm-lib/src/hashing/squeeze_repeatedly.rs +++ b/tasm-lib/src/hashing/squeeze_repeatedly.rs @@ -55,7 +55,7 @@ impl BasicSnippet for SqueezeRepeatedly { #[cfg(test)] mod tests { - use twenty_first::prelude::Sponge; + use triton_vm::prelude::twenty_first::prelude::Sponge; use super::*; use crate::empty_stack; diff --git a/tasm-lib/src/hashing/squeeze_repeatedly_static_number.rs b/tasm-lib/src/hashing/squeeze_repeatedly_static_number.rs index 79f6c2cc2..6a9888141 100644 --- a/tasm-lib/src/hashing/squeeze_repeatedly_static_number.rs +++ b/tasm-lib/src/hashing/squeeze_repeatedly_static_number.rs @@ -1,5 +1,5 @@ use triton_vm::prelude::*; -use twenty_first::math::tip5::RATE; +use triton_vm::prelude::twenty_first::math::tip5::RATE; use crate::prelude::*; diff --git a/tasm-lib/src/list/horner_evaluation_dynamic_length.rs b/tasm-lib/src/list/horner_evaluation_dynamic_length.rs index 2ea8564fc..73fb80617 100644 --- a/tasm-lib/src/list/horner_evaluation_dynamic_length.rs +++ b/tasm-lib/src/list/horner_evaluation_dynamic_length.rs @@ -99,7 +99,7 @@ impl BasicSnippet for HornerEvaluationDynamicLength { #[cfg(test)] mod tests { use itertools::Itertools; - use twenty_first::math::polynomial::Polynomial; + use triton_vm::prelude::twenty_first::math::polynomial::Polynomial; use super::*; use crate::test_prelude::*; diff --git a/tasm-lib/src/list/multiset_equality_digests.rs b/tasm-lib/src/list/multiset_equality_digests.rs index ecf690e91..6a406a7d4 100644 --- a/tasm-lib/src/list/multiset_equality_digests.rs +++ b/tasm-lib/src/list/multiset_equality_digests.rs @@ -227,7 +227,7 @@ impl BasicSnippet for MultisetEqualityDigests { #[cfg(test)] mod tests { use num::One; - use twenty_first::math::other::random_elements; + use triton_vm::prelude::twenty_first::math::other::random_elements; use super::*; use crate::empty_stack; diff --git a/tasm-lib/src/list/multiset_equality_u64s.rs b/tasm-lib/src/list/multiset_equality_u64s.rs index 7e3eaa4f5..6756c257c 100644 --- a/tasm-lib/src/list/multiset_equality_u64s.rs +++ b/tasm-lib/src/list/multiset_equality_u64s.rs @@ -1,5 +1,5 @@ use triton_vm::prelude::*; -use twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use crate::hashing::algebraic_hasher::hash_varlen::HashVarlen; use crate::prelude::*; diff --git a/tasm-lib/src/list/sum_xfes.rs b/tasm-lib/src/list/sum_xfes.rs index 15b4496fe..615c0e9ed 100644 --- a/tasm-lib/src/list/sum_xfes.rs +++ b/tasm-lib/src/list/sum_xfes.rs @@ -1,5 +1,5 @@ use triton_vm::prelude::*; -use twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use crate::prelude::*; @@ -181,7 +181,7 @@ impl BasicSnippet for SumOfXfes { #[cfg(test)] mod tests { - use twenty_first::math::x_field_element::EXTENSION_DEGREE; + use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use super::*; use crate::rust_shadowing_helper_functions::list::insert_random_list; diff --git a/tasm-lib/src/mmr/authentication_struct/derive_challenges.rs b/tasm-lib/src/mmr/authentication_struct/derive_challenges.rs index 616a2b11b..5cc608c57 100644 --- a/tasm-lib/src/mmr/authentication_struct/derive_challenges.rs +++ b/tasm-lib/src/mmr/authentication_struct/derive_challenges.rs @@ -103,8 +103,8 @@ mod tests { use rand::SeedableRng; use rand::rngs::StdRng; use shared::AuthenticatedMerkleAuthStruct; - use twenty_first::prelude::Sponge; - use twenty_first::util_types::mmr::mmr_accumulator::util::mmra_with_mps; + use triton_vm::prelude::twenty_first::prelude::Sponge; + use triton_vm::prelude::twenty_first::util_types::mmr::mmr_accumulator::util::mmra_with_mps; use crate::mmr::authentication_struct::shared::AuthStructIntegrityProof; use crate::rust_shadowing_helper_functions::list::list_insert; diff --git a/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs b/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs index 0d30b40df..8723383cf 100644 --- a/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs +++ b/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs @@ -1,5 +1,5 @@ use triton_vm::prelude::*; -use twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use crate::data_type::DataType; use crate::library::Library; @@ -661,8 +661,8 @@ mod tests { use rand::SeedableRng; use rand::rngs::StdRng; - use twenty_first::prelude::Sponge; - use twenty_first::util_types::mmr::mmr_accumulator::util::mmra_with_mps; + use triton_vm::prelude::twenty_first::prelude::Sponge; + use triton_vm::prelude::twenty_first::util_types::mmr::mmr_accumulator::util::mmra_with_mps; use crate::mmr::authentication_struct::shared::AuthStructIntegrityProof; use crate::rust_shadowing_helper_functions::input::read_digest_from_input; diff --git a/tasm-lib/src/mmr/bag_peaks.rs b/tasm-lib/src/mmr/bag_peaks.rs index 79f6aa90c..64e3d0f09 100644 --- a/tasm-lib/src/mmr/bag_peaks.rs +++ b/tasm-lib/src/mmr/bag_peaks.rs @@ -154,8 +154,8 @@ impl BasicSnippet for BagPeaks { mod tests { use std::collections::HashMap; + use triton_vm::prelude::twenty_first::math::other::random_elements; use triton_vm::twenty_first::prelude::Mmr; - use twenty_first::math::other::random_elements; use super::*; use crate::test_prelude::*; diff --git a/tasm-lib/src/mmr/calculate_new_peaks_from_append.rs b/tasm-lib/src/mmr/calculate_new_peaks_from_append.rs index 5249f96f3..cad464ab3 100644 --- a/tasm-lib/src/mmr/calculate_new_peaks_from_append.rs +++ b/tasm-lib/src/mmr/calculate_new_peaks_from_append.rs @@ -114,7 +114,7 @@ impl BasicSnippet for CalculateNewPeaksFromAppend { #[cfg(test)] mod tests { - use twenty_first::util_types::mmr::mmr_accumulator::MmrAccumulator; + use triton_vm::prelude::twenty_first::util_types::mmr::mmr_accumulator::MmrAccumulator; use super::*; use crate::memory::FIRST_NON_DETERMINISTICALLY_INITIALIZED_MEMORY_ADDRESS; diff --git a/tasm-lib/src/mmr/leaf_index_to_mt_index_and_peak_index.rs b/tasm-lib/src/mmr/leaf_index_to_mt_index_and_peak_index.rs index 7fbfeaad4..a737bfa40 100644 --- a/tasm-lib/src/mmr/leaf_index_to_mt_index_and_peak_index.rs +++ b/tasm-lib/src/mmr/leaf_index_to_mt_index_and_peak_index.rs @@ -141,7 +141,7 @@ impl BasicSnippet for MmrLeafIndexToMtIndexAndPeakIndex { #[cfg(test)] pub(crate) mod tests { - use twenty_first::util_types::mmr::shared_basic::leaf_index_to_mt_index_and_peak_index; + use triton_vm::prelude::twenty_first::util_types::mmr::shared_basic::leaf_index_to_mt_index_and_peak_index; use super::*; use crate::test_prelude::*; diff --git a/tasm-lib/src/mmr/verify_from_memory.rs b/tasm-lib/src/mmr/verify_from_memory.rs index d0745be2a..92e56c07f 100644 --- a/tasm-lib/src/mmr/verify_from_memory.rs +++ b/tasm-lib/src/mmr/verify_from_memory.rs @@ -133,8 +133,8 @@ impl BasicSnippet for MmrVerifyFromMemory { mod tests { use itertools::Itertools; use rand::prelude::*; - use twenty_first::math::other::random_elements; - use twenty_first::util_types::mmr::mmr_accumulator::util::mmra_with_mps; + use triton_vm::prelude::twenty_first::math::other::random_elements; + use triton_vm::prelude::twenty_first::util_types::mmr::mmr_accumulator::util::mmra_with_mps; use super::*; use crate::empty_stack; diff --git a/tasm-lib/src/mmr/verify_from_secret_in_leaf_index_on_stack.rs b/tasm-lib/src/mmr/verify_from_secret_in_leaf_index_on_stack.rs index fdae7e5b1..ba695f77a 100644 --- a/tasm-lib/src/mmr/verify_from_secret_in_leaf_index_on_stack.rs +++ b/tasm-lib/src/mmr/verify_from_secret_in_leaf_index_on_stack.rs @@ -88,12 +88,12 @@ impl BasicSnippet for MmrVerifyFromSecretInLeafIndexOnStack { #[cfg(test)] mod tests { - use twenty_first::math::other::random_elements; - use twenty_first::util_types::mmr::mmr_accumulator::MmrAccumulator; - use twenty_first::util_types::mmr::mmr_accumulator::util::mmra_with_mps; - use twenty_first::util_types::mmr::mmr_membership_proof::MmrMembershipProof; - use twenty_first::util_types::mmr::mmr_trait::Mmr; - use twenty_first::util_types::mmr::shared_basic::leaf_index_to_mt_index_and_peak_index; + use triton_vm::prelude::twenty_first::math::other::random_elements; + use triton_vm::prelude::twenty_first::util_types::mmr::mmr_accumulator::MmrAccumulator; + use triton_vm::prelude::twenty_first::util_types::mmr::mmr_accumulator::util::mmra_with_mps; + use triton_vm::prelude::twenty_first::util_types::mmr::mmr_membership_proof::MmrMembershipProof; + use triton_vm::prelude::twenty_first::util_types::mmr::mmr_trait::Mmr; + use triton_vm::prelude::twenty_first::util_types::mmr::shared_basic::leaf_index_to_mt_index_and_peak_index; use super::*; use crate::rust_shadowing_helper_functions; diff --git a/tasm-lib/src/mmr/verify_from_secret_in_secret_leaf_index.rs b/tasm-lib/src/mmr/verify_from_secret_in_secret_leaf_index.rs index cba48dd3a..bf704ad3f 100644 --- a/tasm-lib/src/mmr/verify_from_secret_in_secret_leaf_index.rs +++ b/tasm-lib/src/mmr/verify_from_secret_in_secret_leaf_index.rs @@ -104,12 +104,12 @@ impl BasicSnippet for MmrVerifyFromSecretInSecretLeafIndex { mod tests { use num::One; use tasm_lib::test_helpers::test_assertion_failure; - use twenty_first::math::other::random_elements; - use twenty_first::util_types::mmr::mmr_accumulator::MmrAccumulator; - use twenty_first::util_types::mmr::mmr_accumulator::util::mmra_with_mps; - use twenty_first::util_types::mmr::mmr_membership_proof::MmrMembershipProof; - use twenty_first::util_types::mmr::mmr_trait::Mmr; - use twenty_first::util_types::mmr::shared_basic::leaf_index_to_mt_index_and_peak_index; + use triton_vm::prelude::twenty_first::math::other::random_elements; + use triton_vm::prelude::twenty_first::util_types::mmr::mmr_accumulator::MmrAccumulator; + use triton_vm::prelude::twenty_first::util_types::mmr::mmr_accumulator::util::mmra_with_mps; + use triton_vm::prelude::twenty_first::util_types::mmr::mmr_membership_proof::MmrMembershipProof; + use triton_vm::prelude::twenty_first::util_types::mmr::mmr_trait::Mmr; + use triton_vm::prelude::twenty_first::util_types::mmr::shared_basic::leaf_index_to_mt_index_and_peak_index; use super::*; use crate::rust_shadowing_helper_functions; diff --git a/tasm-lib/src/mmr/verify_mmr_successor.rs b/tasm-lib/src/mmr/verify_mmr_successor.rs index af463cd05..db7668f24 100644 --- a/tasm-lib/src/mmr/verify_mmr_successor.rs +++ b/tasm-lib/src/mmr/verify_mmr_successor.rs @@ -1,8 +1,8 @@ use std::collections::HashMap; use triton_vm::prelude::*; -use twenty_first::util_types::mmr::mmr_accumulator::MmrAccumulator; -use twenty_first::util_types::mmr::mmr_successor_proof::MmrSuccessorProof; +use triton_vm::prelude::twenty_first::util_types::mmr::mmr_accumulator::MmrAccumulator; +use triton_vm::prelude::twenty_first::util_types::mmr::mmr_successor_proof::MmrSuccessorProof; use crate::arithmetic::u64 as u64_lib; use crate::hashing::merkle_step_mem_u64_index::MerkleStepMemU64Index; @@ -411,8 +411,8 @@ impl VerifyMmrSuccessor { mod tests { use std::collections::VecDeque; - use twenty_first::util_types::mmr::mmr_accumulator::MmrAccumulator; - use twenty_first::util_types::mmr::mmr_successor_proof::MmrSuccessorProof; + use triton_vm::prelude::twenty_first::util_types::mmr::mmr_accumulator::MmrAccumulator; + use triton_vm::prelude::twenty_first::util_types::mmr::mmr_successor_proof::MmrSuccessorProof; use super::*; use crate::empty_stack; diff --git a/tasm-lib/src/neptune/mutator_set/get_swbf_indices.rs b/tasm-lib/src/neptune/mutator_set/get_swbf_indices.rs index 3a0731884..1017f6b9f 100644 --- a/tasm-lib/src/neptune/mutator_set/get_swbf_indices.rs +++ b/tasm-lib/src/neptune/mutator_set/get_swbf_indices.rs @@ -151,7 +151,7 @@ pub(crate) fn u32_to_u128_add_another_u128() -> RawCode { #[cfg(test)] mod tests { - use twenty_first::prelude::Sponge; + use triton_vm::prelude::twenty_first::prelude::Sponge; use super::*; use crate::empty_stack; diff --git a/tasm-lib/src/neptune/neptune_like_types_for_tests.rs b/tasm-lib/src/neptune/neptune_like_types_for_tests.rs index 040768880..8d37a13f8 100644 --- a/tasm-lib/src/neptune/neptune_like_types_for_tests.rs +++ b/tasm-lib/src/neptune/neptune_like_types_for_tests.rs @@ -1,7 +1,7 @@ use arbitrary::Arbitrary; use triton_vm::prelude::*; -use twenty_first::prelude::MmrMembershipProof; -use twenty_first::util_types::mmr::mmr_accumulator::MmrAccumulator; +use triton_vm::prelude::twenty_first::prelude::MmrMembershipProof; +use triton_vm::prelude::twenty_first::util_types::mmr::mmr_accumulator::MmrAccumulator; use crate::prelude::TasmObject; diff --git a/tasm-lib/src/rust_shadowing_helper_functions/array.rs b/tasm-lib/src/rust_shadowing_helper_functions/array.rs index 6f15600fb..a6adb3291 100644 --- a/tasm-lib/src/rust_shadowing_helper_functions/array.rs +++ b/tasm-lib/src/rust_shadowing_helper_functions/array.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use num::Zero; -use twenty_first::prelude::*; +use triton_vm::prelude::twenty_first::prelude::*; use crate::prelude::*; diff --git a/tasm-lib/src/rust_shadowing_helper_functions/input.rs b/tasm-lib/src/rust_shadowing_helper_functions/input.rs index a766bddfd..955ce52c8 100644 --- a/tasm-lib/src/rust_shadowing_helper_functions/input.rs +++ b/tasm-lib/src/rust_shadowing_helper_functions/input.rs @@ -2,7 +2,7 @@ use std::collections::VecDeque; use num::Zero; use triton_vm::prelude::*; -use twenty_first::math::other::random_elements; +use triton_vm::prelude::twenty_first::math::other::random_elements; use crate::Digest; diff --git a/tasm-lib/src/rust_shadowing_helper_functions/list.rs b/tasm-lib/src/rust_shadowing_helper_functions/list.rs index 2a98a7d8a..80669d816 100644 --- a/tasm-lib/src/rust_shadowing_helper_functions/list.rs +++ b/tasm-lib/src/rust_shadowing_helper_functions/list.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use num::Zero; use num_traits::ConstOne; use triton_vm::prelude::*; -use twenty_first::math::other::random_elements; +use triton_vm::prelude::twenty_first::math::other::random_elements; use crate::U32_TO_USIZE_ERR; use crate::USIZE_TO_U64_ERR; diff --git a/tasm-lib/src/structure/manual_tasm_object_implementations.rs b/tasm-lib/src/structure/manual_tasm_object_implementations.rs index 4e802e9f2..0fe6f116e 100644 --- a/tasm-lib/src/structure/manual_tasm_object_implementations.rs +++ b/tasm-lib/src/structure/manual_tasm_object_implementations.rs @@ -1,10 +1,10 @@ use itertools::Itertools; use num_traits::Zero; use triton_vm::prelude::*; -use twenty_first::error::BFieldCodecError; -use twenty_first::error::PolynomialBFieldCodecError; -use twenty_first::math::x_field_element::EXTENSION_DEGREE; -use twenty_first::prelude::*; +use triton_vm::prelude::twenty_first::error::BFieldCodecError; +use triton_vm::prelude::twenty_first::error::PolynomialBFieldCodecError; +use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::twenty_first::prelude::*; use super::tasm_object::Result; use crate::prelude::*; diff --git a/tasm-lib/src/structure/tasm_object.rs b/tasm-lib/src/structure/tasm_object.rs index de9adf18b..e8d4940c0 100644 --- a/tasm-lib/src/structure/tasm_object.rs +++ b/tasm-lib/src/structure/tasm_object.rs @@ -330,7 +330,7 @@ mod tests { /// Test derivation of field getters and manual derivations of the `field!` macro mod derive_tests { use num_traits::ConstZero; - use twenty_first::math::x_field_element::EXTENSION_DEGREE; + use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use super::*; use crate::maybe_write_debuggable_vm_state_to_disk; diff --git a/tasm-lib/src/structure/verify_nd_si_integrity.rs b/tasm-lib/src/structure/verify_nd_si_integrity.rs index 7136ff864..f270755b5 100644 --- a/tasm-lib/src/structure/verify_nd_si_integrity.rs +++ b/tasm-lib/src/structure/verify_nd_si_integrity.rs @@ -77,7 +77,7 @@ mod tests { use arbitrary::Arbitrary; use arbitrary::Unstructured; use num_traits::ConstZero; - use twenty_first::util_types::mmr::mmr_successor_proof::MmrSuccessorProof; + use triton_vm::prelude::twenty_first::util_types::mmr::mmr_successor_proof::MmrSuccessorProof; use super::*; use crate::memory::encode_to_memory; diff --git a/tasm-lib/src/verifier/challenges/new_empty_input_and_output.rs b/tasm-lib/src/verifier/challenges/new_empty_input_and_output.rs index f914ce083..ff5840134 100644 --- a/tasm-lib/src/verifier/challenges/new_empty_input_and_output.rs +++ b/tasm-lib/src/verifier/challenges/new_empty_input_and_output.rs @@ -3,7 +3,7 @@ use triton_vm::air::challenge_id::ChallengeId; use triton_vm::air::cross_table_argument::CrossTableArg; use triton_vm::air::cross_table_argument::EvalArg; use triton_vm::prelude::*; -use twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use crate::hashing::algebraic_hasher::sample_scalars_static_length_static_pointer::SampleScalarsStaticLengthStaticPointer; use crate::prelude::*; diff --git a/tasm-lib/src/verifier/challenges/new_generic_dyn_claim.rs b/tasm-lib/src/verifier/challenges/new_generic_dyn_claim.rs index 247450db0..65c8b0ec9 100644 --- a/tasm-lib/src/verifier/challenges/new_generic_dyn_claim.rs +++ b/tasm-lib/src/verifier/challenges/new_generic_dyn_claim.rs @@ -4,7 +4,7 @@ use triton_vm::air::cross_table_argument::CrossTableArg; use triton_vm::air::cross_table_argument::EvalArg; use triton_vm::challenges::Challenges; use triton_vm::prelude::*; -use twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use crate::hashing::algebraic_hasher::sample_scalars_static_length_static_pointer::SampleScalarsStaticLengthStaticPointer; use crate::prelude::*; @@ -215,7 +215,7 @@ impl BasicSnippet for NewGenericDynClaim { #[cfg(test)] mod tests { use triton_vm::challenges::Challenges; - use twenty_first::math::other::random_elements; + use triton_vm::prelude::twenty_first::math::other::random_elements; use super::*; use crate::rust_shadowing_helper_functions::array::insert_as_array; diff --git a/tasm-lib/src/verifier/claim/instantiate_fiat_shamir_with_claim.rs b/tasm-lib/src/verifier/claim/instantiate_fiat_shamir_with_claim.rs index 0d1d04ec2..c87885d7d 100644 --- a/tasm-lib/src/verifier/claim/instantiate_fiat_shamir_with_claim.rs +++ b/tasm-lib/src/verifier/claim/instantiate_fiat_shamir_with_claim.rs @@ -69,8 +69,8 @@ impl BasicSnippet for InstantiateFiatShamirWithClaim { #[cfg(test)] mod tests { - use twenty_first::math::other::random_elements; - use twenty_first::prelude::Sponge; + use triton_vm::prelude::twenty_first::math::other::random_elements; + use triton_vm::prelude::twenty_first::prelude::Sponge; use super::*; use crate::rust_shadowing_helper_functions::claim::load_claim_from_memory; diff --git a/tasm-lib/src/verifier/fri/barycentric_evaluation.rs b/tasm-lib/src/verifier/fri/barycentric_evaluation.rs index 48a9213be..e548baacf 100644 --- a/tasm-lib/src/verifier/fri/barycentric_evaluation.rs +++ b/tasm-lib/src/verifier/fri/barycentric_evaluation.rs @@ -1,5 +1,5 @@ use triton_vm::prelude::*; -use twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use crate::arithmetic::bfe::primitive_root_of_unity::PrimitiveRootOfUnity; use crate::prelude::*; @@ -222,9 +222,9 @@ impl BasicSnippet for BarycentricEvaluation { #[cfg(test)] mod tests { - use twenty_first::math::other::random_elements; - use twenty_first::math::polynomial::barycentric_evaluate; - use twenty_first::math::traits::PrimitiveRootOfUnity; + use triton_vm::prelude::twenty_first::math::other::random_elements; + use triton_vm::prelude::twenty_first::math::polynomial::barycentric_evaluate; + use triton_vm::prelude::twenty_first::math::traits::PrimitiveRootOfUnity; use super::*; use crate::library::STATIC_MEMORY_FIRST_ADDRESS; diff --git a/tasm-lib/src/verifier/fri/collinear_y.rs b/tasm-lib/src/verifier/fri/collinear_y.rs index 2df749926..34a40cd43 100644 --- a/tasm-lib/src/verifier/fri/collinear_y.rs +++ b/tasm-lib/src/verifier/fri/collinear_y.rs @@ -115,7 +115,7 @@ impl BasicSnippet for CollinearYXfe { #[cfg(test)] mod tests { - use twenty_first::math::polynomial::Polynomial; + use triton_vm::prelude::twenty_first::math::polynomial::Polynomial; use super::*; use crate::test_prelude::*; diff --git a/tasm-lib/src/verifier/fri/number_of_rounds.rs b/tasm-lib/src/verifier/fri/number_of_rounds.rs index bb9a202c2..c122553db 100644 --- a/tasm-lib/src/verifier/fri/number_of_rounds.rs +++ b/tasm-lib/src/verifier/fri/number_of_rounds.rs @@ -65,7 +65,7 @@ impl BasicSnippet for NumberOfRounds { mod tests { use triton_vm::arithmetic_domain::ArithmeticDomain; use triton_vm::fri::Fri; - use twenty_first::math::traits::PrimitiveRootOfUnity; + use triton_vm::prelude::twenty_first::math::traits::PrimitiveRootOfUnity; use super::*; use crate::memory::dyn_malloc::DYN_MALLOC_ADDRESS; diff --git a/tasm-lib/src/verifier/fri/test_helpers.rs b/tasm-lib/src/verifier/fri/test_helpers.rs index f3a4358eb..d355c67af 100644 --- a/tasm-lib/src/verifier/fri/test_helpers.rs +++ b/tasm-lib/src/verifier/fri/test_helpers.rs @@ -6,7 +6,7 @@ use triton_vm::table::NUM_QUOTIENT_SEGMENTS; use triton_vm::table::master_table::MasterAuxTable; use triton_vm::table::master_table::MasterMainTable; use triton_vm::table::master_table::MasterTable; -use twenty_first::prelude::*; +use triton_vm::prelude::twenty_first::prelude::*; use crate::prelude::Digest; diff --git a/tasm-lib/src/verifier/fri/verify.rs b/tasm-lib/src/verifier/fri/verify.rs index 860db599b..9648371aa 100644 --- a/tasm-lib/src/verifier/fri/verify.rs +++ b/tasm-lib/src/verifier/fri/verify.rs @@ -1,19 +1,19 @@ +use ::twenty_first::util_types::merkle_tree::MerkleTree; +use ::twenty_first::util_types::merkle_tree::MerkleTreeInclusionProof; use anyhow::bail; use itertools::Itertools; use num::Zero; use triton_vm::arithmetic_domain::ArithmeticDomain; use triton_vm::error::FriValidationError; use triton_vm::fri::Fri; +use triton_vm::prelude::twenty_first::math::polynomial::Polynomial; +use triton_vm::prelude::twenty_first::math::polynomial::barycentric_evaluate; +use triton_vm::prelude::twenty_first::math::traits::ModPowU32; +use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use triton_vm::prelude::*; use triton_vm::proof_item::FriResponse; use triton_vm::proof_item::ProofItemVariant; use triton_vm::proof_stream::ProofStream; -use twenty_first::math::polynomial::Polynomial; -use twenty_first::math::polynomial::barycentric_evaluate; -use twenty_first::math::traits::ModPowU32; -use twenty_first::math::x_field_element::EXTENSION_DEGREE; -use twenty_first::util_types::merkle_tree::MerkleTree; -use twenty_first::util_types::merkle_tree::MerkleTreeInclusionProof; use crate::data_type::StructType; use crate::field; @@ -928,7 +928,7 @@ impl FriVerify { let num_collinearity_check = self.num_collinearity_checks as usize; let mut a_indices = proof_stream.sample_indices(domain_length, num_collinearity_check); - let tree_height = self.domain_length.ilog2() as usize; + let tree_height = self.domain_length.ilog2(); let fri_response = proof_stream .dequeue() .unwrap() @@ -942,11 +942,25 @@ impl FriVerify { // Check if last codeword matches the given root let codeword_digests = Self::map_convert_xfe_to_digest(&last_codeword); - let mt: MerkleTree = MerkleTree::par_new(&codeword_digests).unwrap(); + let codeword_digests_compatible = codeword_digests + .into_iter() + .map(|d| { + ::twenty_first::prelude::Digest( + d.values() + .map(|b| ::twenty_first::prelude::BFieldElement::new(b.value())), + ) + }) + .collect_vec(); + let mt: MerkleTree = MerkleTree::par_new(&codeword_digests_compatible).unwrap(); let last_codeword_merkle_root = mt.root(); let last_root = roots.last().unwrap(); - if *last_root != last_codeword_merkle_root { + let last_root_compatible = ::twenty_first::prelude::Digest( + last_root + .values() + .map(|b| ::twenty_first::prelude::BFieldElement::new(b.value())), + ); + if last_root_compatible != last_codeword_merkle_root { bail!(FriValidationError::BadMerkleRootForLastCodeword); } @@ -965,18 +979,53 @@ impl FriVerify { } // reduplicate authentication structures if necessary + let indexed_a_leafs_compatible = indexed_a_leaves + .iter() + .map(|(index, leaf)| { + ( + *index as u64, + ::twenty_first::prelude::Digest( + leaf.values() + .map(|b| ::twenty_first::prelude::BFieldElement::new(b.value())), + ), + ) + }) + .collect_vec(); + let fri_response_auth_structure_compatible = fri_response + .auth_structure + .iter() + .map(|d| { + ::twenty_first::prelude::Digest( + d.values() + .map(|b| ::twenty_first::prelude::BFieldElement::new(b.value())), + ) + }) + .collect_vec(); if num_nondeterministic_digests_read >= nondeterministic_digests.len() { let inclusion_proof = MerkleTreeInclusionProof { tree_height, - indexed_leafs: indexed_a_leaves.clone(), - authentication_structure: fri_response.auth_structure, + indexed_leafs: indexed_a_leafs_compatible, + authentication_structure: fri_response_auth_structure_compatible, }; // sanity check: the authentication structure was valid, right? - assert!(inclusion_proof.clone().verify(roots[0])); + let root_zero_compatible = ::twenty_first::prelude::Digest( + roots[0] + .values() + .map(|b| ::twenty_first::prelude::BFieldElement::new(b.value())), + ); + assert!(inclusion_proof.clone().verify(root_zero_compatible)); let reduplicated_authentication_paths = inclusion_proof.into_authentication_paths()?; + let reduplicated_authentication_paths_compatible = reduplicated_authentication_paths + .into_iter() + .map(|path| { + path.into_iter() + .map(|n| Digest(n.values().map(|b| BFieldElement::new(b.value())))) + .collect_vec() + }) + .collect_vec(); nondeterministic_digests.extend( - reduplicated_authentication_paths + reduplicated_authentication_paths_compatible .into_iter() .rev() .flatten(), @@ -984,16 +1033,37 @@ impl FriVerify { } // verify authentication paths for A leafs - for indexed_leaf in indexed_a_leaves.iter().rev() { + for (index, leaf) in indexed_a_leaves.iter().rev() { + let indexed_leaf = ( + *index as u64, + ::twenty_first::prelude::Digest( + leaf.values() + .map(|b| ::twenty_first::prelude::BFieldElement::new(b.value())), + ), + ); let authentication_path = &nondeterministic_digests[num_nondeterministic_digests_read - ..(num_nondeterministic_digests_read + tree_height)]; - num_nondeterministic_digests_read += tree_height; + ..(num_nondeterministic_digests_read + (tree_height as usize))]; + let authentication_path_compatible = authentication_path + .iter() + .map(|d| { + ::twenty_first::prelude::Digest( + d.values() + .map(|b| ::twenty_first::prelude::BFieldElement::new(b.value())), + ) + }) + .collect_vec(); + num_nondeterministic_digests_read += tree_height as usize; let inclusion_proof = MerkleTreeInclusionProof { tree_height, - indexed_leafs: vec![*indexed_leaf], - authentication_structure: authentication_path.to_vec(), + indexed_leafs: vec![indexed_leaf], + authentication_structure: authentication_path_compatible, }; - assert!(inclusion_proof.verify(roots[0])); + let root_zero_compatible = ::twenty_first::prelude::Digest( + roots[0] + .values() + .map(|b| ::twenty_first::prelude::BFieldElement::new(b.value())), + ); + assert!(inclusion_proof.verify(root_zero_compatible)); } // save indices and revealed leafs of first round's codeword for returning @@ -1028,18 +1098,54 @@ impl FriVerify { // reduplicate authentication structures if necessary if num_nondeterministic_digests_read >= nondeterministic_digests.len() { + let indexed_b_leafs_compatible = + indexed_b_leaves + .iter() + .map(|(index, leaf)| { + ( + *index as u64, + ::twenty_first::prelude::Digest(leaf.values().map(|b| { + ::twenty_first::prelude::BFieldElement::new(b.value()) + })), + ) + }) + .collect_vec(); + let fri_response_auth_structure_compatible = fri_response + .auth_structure + .iter() + .map(|d| { + ::twenty_first::prelude::Digest( + d.values() + .map(|b| ::twenty_first::prelude::BFieldElement::new(b.value())), + ) + }) + .collect_vec(); let inclusion_proof = MerkleTreeInclusionProof { tree_height: current_tree_height, - indexed_leafs: indexed_b_leaves.clone(), - authentication_structure: fri_response.auth_structure, + indexed_leafs: indexed_b_leafs_compatible, + authentication_structure: fri_response_auth_structure_compatible, }; // sanity check: the auth structure was valid, right? - assert!(inclusion_proof.clone().verify(roots[r])); + let root_r_compatible = ::twenty_first::prelude::Digest( + roots[r] + .values() + .map(|b| ::twenty_first::prelude::BFieldElement::new(b.value())), + ); + assert!(inclusion_proof.clone().verify(root_r_compatible)); let reduplicated_authentication_paths = inclusion_proof.into_authentication_paths()?; - nondeterministic_digests.extend( + let reduplicated_authentication_paths_compatible = reduplicated_authentication_paths + .into_iter() + .map(|path| { + path.into_iter() + .map(|d| Digest(d.values().map(|b| BFieldElement::new(b.value())))) + .collect_vec() + }) + .collect_vec(); + nondeterministic_digests.extend( + reduplicated_authentication_paths_compatible .into_iter() .rev() .flatten(), @@ -1047,17 +1153,38 @@ impl FriVerify { } // verify authentication paths for B leafs - for indexed_leaf in indexed_b_leaves.iter().rev() { + for (index, leaf) in indexed_b_leaves.iter().rev() { + let indexed_leaf_compatible = ( + *index as u64, + ::twenty_first::prelude::Digest( + leaf.values() + .map(|b| ::twenty_first::prelude::BFieldElement::new(b.value())), + ), + ); let authentication_path = &nondeterministic_digests [num_nondeterministic_digests_read - ..(num_nondeterministic_digests_read + current_tree_height)]; - num_nondeterministic_digests_read += current_tree_height; + ..(num_nondeterministic_digests_read + (current_tree_height as usize))]; + let authentication_path_compatible = authentication_path + .iter() + .map(|d| { + ::twenty_first::prelude::Digest( + d.values() + .map(|b| ::twenty_first::prelude::BFieldElement::new(b.value())), + ) + }) + .collect_vec(); + num_nondeterministic_digests_read += current_tree_height as usize; let inclusion_proof = MerkleTreeInclusionProof { tree_height: current_tree_height, - indexed_leafs: vec![*indexed_leaf], - authentication_structure: authentication_path.to_vec(), + indexed_leafs: vec![indexed_leaf_compatible], + authentication_structure: authentication_path_compatible, }; - if !inclusion_proof.verify(roots[r]) { + let root_r_compatible = ::twenty_first::prelude::Digest( + roots[r] + .values() + .map(|b| ::twenty_first::prelude::BFieldElement::new(b.value())), + ); + if !inclusion_proof.verify(root_r_compatible) { bail!(FriValidationError::BadMerkleAuthenticationPath); } } @@ -1150,9 +1277,9 @@ mod tests { use num_traits::Zero; use proptest::collection::vec; use rayon::prelude::*; + use triton_vm::prelude::twenty_first::math::ntt::ntt; + use triton_vm::prelude::twenty_first::util_types::sponge::Sponge; use triton_vm::proof_item::ProofItem; - use twenty_first::math::ntt::ntt; - use twenty_first::util_types::sponge::Sponge; use super::*; use crate::empty_stack; diff --git a/tasm-lib/src/verifier/fri/verify_fri_authentication_paths.rs b/tasm-lib/src/verifier/fri/verify_fri_authentication_paths.rs index a8cdefe3a..1b76b27c5 100644 --- a/tasm-lib/src/verifier/fri/verify_fri_authentication_paths.rs +++ b/tasm-lib/src/verifier/fri/verify_fri_authentication_paths.rs @@ -1,5 +1,5 @@ use triton_vm::prelude::*; -use twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use crate::prelude::*; @@ -131,7 +131,7 @@ mod tests { use rand::distr::StandardUniform; use strum::EnumIter; use strum::IntoEnumIterator; - use twenty_first::prelude::*; + use triton_vm::prelude::twenty_first::prelude::*; use super::*; use crate::rust_shadowing_helper_functions; diff --git a/tasm-lib/src/verifier/master_table/air_constraint_evaluation.rs b/tasm-lib/src/verifier/master_table/air_constraint_evaluation.rs index e0ab6300a..b33b12fac 100644 --- a/tasm-lib/src/verifier/master_table/air_constraint_evaluation.rs +++ b/tasm-lib/src/verifier/master_table/air_constraint_evaluation.rs @@ -10,7 +10,7 @@ use triton_vm::table::auxiliary_table::Evaluable; use triton_vm::table::master_table::MasterAuxTable; use triton_vm::table::master_table::MasterMainTable; use triton_vm::table::master_table::MasterTable; -use twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use crate::data_type::ArrayType; use crate::memory::dyn_malloc::DYN_MALLOC_ADDRESS; @@ -299,7 +299,7 @@ mod tests { use triton_vm::proof_stream::ProofStream; use triton_vm::table::master_table::MasterMainTable; use triton_vm::table::master_table::MasterTable; - use twenty_first::math::x_field_element::EXTENSION_DEGREE; + use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use super::*; use crate::execute_test; diff --git a/tasm-lib/src/verifier/master_table/divide_out_zerofiers.rs b/tasm-lib/src/verifier/master_table/divide_out_zerofiers.rs index 53b4970a1..981499735 100644 --- a/tasm-lib/src/verifier/master_table/divide_out_zerofiers.rs +++ b/tasm-lib/src/verifier/master_table/divide_out_zerofiers.rs @@ -2,7 +2,7 @@ use triton_vm::prelude::LabelledInstruction; use triton_vm::prelude::*; use triton_vm::table::ConstraintType; use triton_vm::table::master_table::MasterAuxTable; -use twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use crate::prelude::*; use crate::verifier::master_table::air_constraint_evaluation::AirConstraintEvaluation; @@ -151,8 +151,8 @@ mod tests { use itertools::Itertools; use rand::prelude::*; - use twenty_first::math::traits::ModPowU32; - use twenty_first::math::traits::PrimitiveRootOfUnity; + use triton_vm::prelude::twenty_first::math::traits::ModPowU32; + use triton_vm::prelude::twenty_first::math::traits::PrimitiveRootOfUnity; use super::*; use crate::empty_stack; @@ -330,7 +330,7 @@ mod bench { use std::collections::HashMap; use itertools::Itertools; - use twenty_first::math::traits::PrimitiveRootOfUnity; + use triton_vm::prelude::twenty_first::math::traits::PrimitiveRootOfUnity; use super::*; use crate::empty_stack; diff --git a/tasm-lib/src/verifier/master_table/verify_table_rows.rs b/tasm-lib/src/verifier/master_table/verify_table_rows.rs index 3be57428d..2a10610df 100644 --- a/tasm-lib/src/verifier/master_table/verify_table_rows.rs +++ b/tasm-lib/src/verifier/master_table/verify_table_rows.rs @@ -5,7 +5,7 @@ use triton_vm::table::NUM_QUOTIENT_SEGMENTS; use triton_vm::table::master_table::MasterAuxTable; use triton_vm::table::master_table::MasterMainTable; use triton_vm::table::master_table::MasterTable; -use twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use crate::hashing::algebraic_hasher::hash_static_size::HashStaticSize; use crate::prelude::*; @@ -203,9 +203,9 @@ impl BasicSnippet for VerifyTableRows { #[cfg(test)] mod tests { - use twenty_first::math::other::random_elements; - use twenty_first::math::tip5::RATE; - use twenty_first::prelude::*; + use triton_vm::prelude::twenty_first::math::other::random_elements; + use triton_vm::prelude::twenty_first::math::tip5::RATE; + use triton_vm::prelude::twenty_first::prelude::*; use super::*; use crate::memory::encode_to_memory; diff --git a/tasm-lib/src/verifier/master_table/zerofiers_inverse.rs b/tasm-lib/src/verifier/master_table/zerofiers_inverse.rs index 2af550688..28c2a0764 100644 --- a/tasm-lib/src/verifier/master_table/zerofiers_inverse.rs +++ b/tasm-lib/src/verifier/master_table/zerofiers_inverse.rs @@ -1,7 +1,7 @@ use strum::EnumCount; use triton_vm::prelude::*; use triton_vm::table::ConstraintType; -use twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use crate::arithmetic::xfe::to_the_power_of_power_of_2::ToThePowerOfPowerOf2; use crate::prelude::*; @@ -175,8 +175,8 @@ impl BasicSnippet for ZerofiersInverse { #[cfg(test)] mod tests { use num::One; - use twenty_first::math::traits::ModPowU32; - use twenty_first::math::traits::PrimitiveRootOfUnity; + use triton_vm::prelude::twenty_first::math::traits::ModPowU32; + use triton_vm::prelude::twenty_first::math::traits::PrimitiveRootOfUnity; use super::*; use crate::rust_shadowing_helper_functions::array::insert_as_array; diff --git a/tasm-lib/src/verifier/out_of_domain_points.rs b/tasm-lib/src/verifier/out_of_domain_points.rs index b6d927d37..601c25fb5 100644 --- a/tasm-lib/src/verifier/out_of_domain_points.rs +++ b/tasm-lib/src/verifier/out_of_domain_points.rs @@ -1,5 +1,5 @@ use triton_vm::prelude::*; -use twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use crate::data_type::ArrayType; use crate::prelude::*; @@ -125,8 +125,8 @@ impl BasicSnippet for OutOfDomainPoints { #[cfg(test)] mod tests { use triton_vm::table::NUM_QUOTIENT_SEGMENTS; - use twenty_first::math::traits::ModPowU32; - use twenty_first::math::traits::PrimitiveRootOfUnity; + use triton_vm::prelude::twenty_first::math::traits::ModPowU32; + use triton_vm::prelude::twenty_first::math::traits::PrimitiveRootOfUnity; use super::*; use crate::rust_shadowing_helper_functions::array::insert_as_array; diff --git a/tasm-lib/src/verifier/stark_verify.rs b/tasm-lib/src/verifier/stark_verify.rs index 7c2c327fb..557f326ed 100644 --- a/tasm-lib/src/verifier/stark_verify.rs +++ b/tasm-lib/src/verifier/stark_verify.rs @@ -7,8 +7,8 @@ use triton_vm::table::NUM_QUOTIENT_SEGMENTS; use triton_vm::table::master_table::MasterAuxTable; use triton_vm::table::master_table::MasterMainTable; use triton_vm::table::master_table::MasterTable; -use twenty_first::math::x_field_element::EXTENSION_DEGREE; -use twenty_first::prelude::MerkleTreeInclusionProof; +use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::twenty_first::prelude::MerkleTreeInclusionProof; use super::master_table::air_constraint_evaluation::AirConstraintEvaluation; use super::master_table::air_constraint_evaluation::MemoryLayout; diff --git a/tasm-lib/src/verifier/vm_proof_iter/dequeue_next_as.rs b/tasm-lib/src/verifier/vm_proof_iter/dequeue_next_as.rs index b9c2427dd..383b08f16 100644 --- a/tasm-lib/src/verifier/vm_proof_iter/dequeue_next_as.rs +++ b/tasm-lib/src/verifier/vm_proof_iter/dequeue_next_as.rs @@ -5,8 +5,8 @@ use triton_vm::proof_item::ProofItemVariant; use triton_vm::table::AuxiliaryRow; use triton_vm::table::MainRow; use triton_vm::table::QuotientSegments; -use twenty_first::math::x_field_element::EXTENSION_DEGREE; -use twenty_first::prelude::Polynomial; +use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::twenty_first::prelude::Polynomial; use crate::hashing::sponge_hasher::pad_and_absorb_all::PadAndAbsorbAll; use crate::prelude::*; @@ -378,7 +378,7 @@ mod tests { use triton_vm::proof_stream::ProofStream; use triton_vm::table::master_table::MasterMainTable; use triton_vm::table::master_table::MasterTable; - use twenty_first::prelude::*; + use triton_vm::prelude::twenty_first::prelude::*; use super::*; use crate::empty_stack; diff --git a/tasm-lib/src/verifier/xfe_ntt.rs b/tasm-lib/src/verifier/xfe_ntt.rs index 9db8f5db5..114defc3c 100644 --- a/tasm-lib/src/verifier/xfe_ntt.rs +++ b/tasm-lib/src/verifier/xfe_ntt.rs @@ -462,8 +462,8 @@ impl BasicSnippet for XfeNtt { #[cfg(test)] mod tests { - use twenty_first::math::ntt::ntt; - use twenty_first::math::traits::PrimitiveRootOfUnity; + use triton_vm::prelude::twenty_first::math::ntt::ntt; + use triton_vm::prelude::twenty_first::math::traits::PrimitiveRootOfUnity; use super::*; use crate::empty_stack; From 678444d6ed2947d3615f6d50131d8e596bc52cd4 Mon Sep 17 00:00:00 2001 From: Alan Szepieniec Date: Tue, 6 May 2025 16:34:05 +0200 Subject: [PATCH 13/14] chore: Integrate reviewer comments Co-authored-by: Ferdinand Sauer --- ...thentication_struct_derive_challenges.json | 12 +- ...b_mmr_root_from_authentication_struct.json | 8 +- tasm-lib/src/lib.rs | 5 +- .../derive_challenges.rs | 42 ++++--- .../root_from_authentication_struct.rs | 106 +++++++++--------- .../src/rust_shadowing_helper_functions.rs | 2 - .../rust_shadowing_helper_functions/input.rs | 58 ---------- .../rust_shadowing_helper_functions/memory.rs | 15 --- 8 files changed, 87 insertions(+), 161 deletions(-) delete mode 100644 tasm-lib/src/rust_shadowing_helper_functions/input.rs delete mode 100644 tasm-lib/src/rust_shadowing_helper_functions/memory.rs diff --git a/tasm-lib/benchmarks/tasmlib_mmr_authentication_struct_derive_challenges.json b/tasm-lib/benchmarks/tasmlib_mmr_authentication_struct_derive_challenges.json index 76919995e..a6cb3ac15 100644 --- a/tasm-lib/benchmarks/tasmlib_mmr_authentication_struct_derive_challenges.json +++ b/tasm-lib/benchmarks/tasmlib_mmr_authentication_struct_derive_challenges.json @@ -2,10 +2,10 @@ { "name": "tasmlib_mmr_authentication_struct_derive_challenges", "benchmark_result": { - "clock_cycle_count": 1122, - "hash_table_height": 961, + "clock_cycle_count": 1118, + "hash_table_height": 955, "u32_table_height": 30, - "op_stack_table_height": 785, + "op_stack_table_height": 777, "ram_table_height": 1439 }, "case": "CommonCase" @@ -13,10 +13,10 @@ { "name": "tasmlib_mmr_authentication_struct_derive_challenges", "benchmark_result": { - "clock_cycle_count": 2046, - "hash_table_height": 1885, + "clock_cycle_count": 2042, + "hash_table_height": 1879, "u32_table_height": 26, - "op_stack_table_height": 1401, + "op_stack_table_height": 1393, "ram_table_height": 2974 }, "case": "WorstCase" diff --git a/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json b/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json index e1155b886..dd1afaadf 100644 --- a/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json +++ b/tasm-lib/benchmarks/tasmlib_mmr_root_from_authentication_struct.json @@ -2,10 +2,10 @@ { "name": "tasmlib_mmr_root_from_authentication_struct", "benchmark_result": { - "clock_cycle_count": 21485, + "clock_cycle_count": 21481, "hash_table_height": 1759, "u32_table_height": 3034, - "op_stack_table_height": 33376, + "op_stack_table_height": 33368, "ram_table_height": 9732 }, "case": "CommonCase" @@ -13,10 +13,10 @@ { "name": "tasmlib_mmr_root_from_authentication_struct", "benchmark_result": { - "clock_cycle_count": 25085, + "clock_cycle_count": 25081, "hash_table_height": 1975, "u32_table_height": 1805, - "op_stack_table_height": 38944, + "op_stack_table_height": 38936, "ram_table_height": 11316 }, "case": "WorstCase" diff --git a/tasm-lib/src/lib.rs b/tasm-lib/src/lib.rs index 4ac635a9a..ea85fbc6c 100644 --- a/tasm-lib/src/lib.rs +++ b/tasm-lib/src/lib.rs @@ -183,9 +183,8 @@ pub(crate) fn execute_test( terminal_state } -/// If the environment variable TASMLIB_TRITON_TUI is set, write -/// 1. the program to file `program.tasm`, and -/// 2. the VM state to file `vm_state.json`. +/// If the environment variable TASMLIB_TRITON_TUI is set, write the initial VM state +/// to file `vm_state.json`. /// /// This file can be used to debug the program using the [Triton TUI]: /// ```sh diff --git a/tasm-lib/src/mmr/authentication_struct/derive_challenges.rs b/tasm-lib/src/mmr/authentication_struct/derive_challenges.rs index 5cc608c57..93e2a1e1c 100644 --- a/tasm-lib/src/mmr/authentication_struct/derive_challenges.rs +++ b/tasm-lib/src/mmr/authentication_struct/derive_challenges.rs @@ -50,8 +50,7 @@ impl BasicSnippet for DeriveChallenges { // _ *auth_struct *indexed_leafs read_mem 1 - push 1 - add + addi 1 // _ *auth_struct indexed_leafs_len *indexed_leafs swap 1 @@ -59,23 +58,20 @@ impl BasicSnippet for DeriveChallenges { push {indexed_leaf_element_size} mul - push 1 - add + addi 1 // _ *auth_struct *indexed_leafs indexed_leafs_size call {absorb_multiple} // _ *auth_struct read_mem 1 - push 1 - add + addi 1 // _ auth_struct_len *auth_struct swap 1 push {Digest::LEN} mul - push 1 - add + addi 1 // _ *auth_struct auth_struct_size call {absorb_multiple} @@ -96,6 +92,7 @@ impl BasicSnippet for DeriveChallenges { #[cfg(test)] mod tests { use std::collections::HashMap; + use std::collections::VecDeque; use itertools::Itertools; use num::One; @@ -110,9 +107,9 @@ mod tests { use crate::rust_shadowing_helper_functions::list::list_insert; use crate::rust_shadowing_helper_functions::list::load_list_with_copy_elements; use crate::snippet_bencher::BenchmarkCase; - use crate::traits::procedure::Procedure; - use crate::traits::procedure::ProcedureInitialState; - use crate::traits::procedure::ShadowedProcedure; + use crate::test_prelude::MemPreserver; + use crate::test_prelude::MemPreserverInitialState; + use crate::test_prelude::ShadowedMemPreserver; use crate::traits::rust_shadow::RustShadow; use super::*; @@ -121,16 +118,17 @@ mod tests { #[test] fn test() { - ShadowedProcedure::new(DeriveChallenges).test(); + ShadowedMemPreserver::new(DeriveChallenges).test(); } - impl Procedure for DeriveChallenges { + impl MemPreserver for DeriveChallenges { fn rust_shadow( &self, stack: &mut Vec, - memory: &mut HashMap, - _nondeterminism: &NonDeterminism, - _public_input: &[BFieldElement], + memory: &HashMap, + _nd_tokens: VecDeque, + _nd_digests: VecDeque, + _stdin: VecDeque, sponge: &mut Option, ) -> Vec { let indexed_leafs_pointer = stack.pop().unwrap(); @@ -169,7 +167,7 @@ mod tests { &self, seed: [u8; 32], bench_case: Option, - ) -> ProcedureInitialState { + ) -> MemPreserverInitialState { let mut rng: StdRng = SeedableRng::from_seed(seed); let (tree_height, num_revealed_leafs) = match bench_case { @@ -223,11 +221,11 @@ mod tests { .concat(); let nondeterminism = NonDeterminism::default().with_ram(memory); - ProcedureInitialState { + MemPreserverInitialState { stack, nondeterminism, - public_input: vec![], - sponge: Some(Tip5::init()), + public_input: vec![].into(), + sponge_state: Some(Tip5::init()), } } } @@ -235,13 +233,13 @@ mod tests { #[cfg(test)] mod benches { - use crate::traits::procedure::ShadowedProcedure; + use crate::test_prelude::ShadowedMemPreserver; use crate::traits::rust_shadow::RustShadow; use super::*; #[test] fn bag_peaks_benchmark() { - ShadowedProcedure::new(DeriveChallenges).bench(); + ShadowedMemPreserver::new(DeriveChallenges).bench(); } } diff --git a/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs b/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs index 8723383cf..9054d018b 100644 --- a/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs +++ b/tasm-lib/src/mmr/authentication_struct/root_from_authentication_struct.rs @@ -1,5 +1,5 @@ -use triton_vm::prelude::*; use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::*; use crate::data_type::DataType; use crate::library::Library; @@ -38,24 +38,16 @@ impl BasicSnippet for RootFromAuthenticationStruct { } fn code(&self, library: &mut Library) -> Vec { - let alpha_challenge_pointer = library.kmalloc(EXTENSION_DEGREE as u32); - let alpha_challenge_pointer_write = alpha_challenge_pointer.write_address(); - let alpha_challenge_pointer_read = alpha_challenge_pointer.read_address(); - let beta_challenge_pointer = library.kmalloc(EXTENSION_DEGREE as u32); - let beta_challenge_pointer_write = beta_challenge_pointer.write_address(); - let beta_challenge_pointer_read = beta_challenge_pointer.read_address(); - let gamma_challenge_pointer = library.kmalloc(EXTENSION_DEGREE as u32); - let gamma_challenge_pointer_write = gamma_challenge_pointer.write_address(); - let gamma_challenge_pointer_read = gamma_challenge_pointer.read_address(); - let t_digest_pointer = library.kmalloc(Digest::LEN as u32); - let t_digest_pointer_write = t_digest_pointer.write_address(); - let t_digest_pointer_read = t_digest_pointer.read_address(); - let right_digest_pointer = library.kmalloc(Digest::LEN as u32); - let right_digest_pointer_write = right_digest_pointer.write_address(); - let right_digest_pointer_read = right_digest_pointer.read_address(); - let left_digest_pointer = library.kmalloc(Digest::LEN as u32); - let left_digest_pointer_write = left_digest_pointer.write_address(); - let left_digest_pointer_read = left_digest_pointer.read_address(); + let alpha_challenge_allocation = library.kmalloc(EXTENSION_DEGREE as u32); + let beta_challenge_allocation = library.kmalloc(EXTENSION_DEGREE as u32); + let beta_challenge_read_address = beta_challenge_allocation.read_address(); + let gamma_challenge_allocation = library.kmalloc(EXTENSION_DEGREE as u32); + let gamma_challenge_read_address = gamma_challenge_allocation.read_address(); + let t_digest_allocation = library.kmalloc(Digest::LEN as u32); + let t_digest_write_address = t_digest_allocation.write_address(); + let t_digest_read_address = t_digest_allocation.read_address(); + let right_digest_allocation = library.kmalloc(Digest::LEN as u32); + let left_digest_allocation = library.kmalloc(Digest::LEN as u32); let indexed_leaf_element_size = Self::indexed_leaf_element_type().stack_size(); let derive_challenges = library.import(Box::new(DeriveChallenges)); @@ -68,17 +60,17 @@ impl BasicSnippet for RootFromAuthenticationStruct { hint gamma: XFieldElement = stack[6..9] // _ [gamma] [-beta] [alpha] <- rename - push {alpha_challenge_pointer_write} + push {alpha_challenge_allocation.write_address()} write_mem {EXTENSION_DEGREE} pop 1 // _ [gamma] [-beta] - push {beta_challenge_pointer_write} + push {beta_challenge_allocation.write_address()} write_mem {EXTENSION_DEGREE} pop 1 // _ [gamma] - push {gamma_challenge_pointer_write} + push {gamma_challenge_allocation.write_address()} write_mem {EXTENSION_DEGREE} pop 1 // _ @@ -103,7 +95,7 @@ impl BasicSnippet for RootFromAuthenticationStruct { // _ [digest] push 1 - push {alpha_challenge_pointer_read} + push {alpha_challenge_allocation.read_address()} read_mem {EXTENSION_DEGREE} pop 1 // _ l4 l3 l2 l1 l0 1 [α; 3] @@ -123,7 +115,7 @@ impl BasicSnippet for RootFromAuthenticationStruct { // _ num_leafs *auth_struct *idx_leafs *idx_leafs[n]_lw [0; 2] [p; 3] /* Read leaf-index, convert it to BFE, and multiply it with `gamma` challenge */ - push {gamma_challenge_pointer_read} + push {gamma_challenge_read_address} read_mem {EXTENSION_DEGREE} pop 1 // _ num_leafs *auth_struct *idx_leafs *idx_leafs[n]_lw [0; 2] [p; 3] [gamma] @@ -160,7 +152,7 @@ impl BasicSnippet for RootFromAuthenticationStruct { // _ num_leafs *auth_struct *idx_leafs *idx_leafs[n-1]_lw [0; 2] [p; 3] [γ * node_idx; 3] [(l1 l0 1) * α + (l4 l3 l2)] // _ num_leafs *auth_struct *idx_leafs *idx_leafs[n-1]_lw [0; 2] [p; 3] [γ * node_idx; 3] [leaf_as_xfe] <-- rename - push {beta_challenge_pointer_read} + push {beta_challenge_read_address} read_mem {EXTENSION_DEGREE} pop 1 // _ num_leafs *auth_struct *idx_leafs *idx_leafs[n-1]_lw [0; 2] [p; 3] [γ * node_idx; 3] [leaf_as_xfe] [-beta] @@ -286,7 +278,7 @@ impl BasicSnippet for RootFromAuthenticationStruct { // _ *auth_struct *auth_struct[n]_lw [node_index] [p] /* Calculate `node_index * challenge` */ - push {gamma_challenge_pointer_read} + push {gamma_challenge_read_address} read_mem {EXTENSION_DEGREE} pop 1 // _ *auth_struct *auth_struct[n]_lw [node_index] [p] [γ] @@ -311,7 +303,7 @@ impl BasicSnippet for RootFromAuthenticationStruct { {&digest_to_xfe} // _ *auth_struct *auth_struct[n]_lw [node_index] [p] [node_index * γ] [auth_struct_xfe] - push {beta_challenge_pointer_read} + push {beta_challenge_read_address} read_mem {EXTENSION_DEGREE} pop 1 xx_add @@ -334,7 +326,7 @@ impl BasicSnippet for RootFromAuthenticationStruct { // _ [t] {&dup_top_digest} - push {t_digest_pointer_write} + push {t_digest_write_address} write_mem {Digest::LEN} pop 1 // _ [t] @@ -371,7 +363,7 @@ impl BasicSnippet for RootFromAuthenticationStruct { // _ l_index_bfe [p] [right] {&dup_top_digest} - push {right_digest_pointer_write} + push {right_digest_allocation.write_address()} write_mem {Digest::LEN} pop 1 // _ l_index_bfe [p] [right] @@ -379,13 +371,13 @@ impl BasicSnippet for RootFromAuthenticationStruct { {&digest_to_xfe} // _ l_index_bfe [p] [right_xfe] - push {beta_challenge_pointer_read} + push {beta_challenge_read_address} read_mem {EXTENSION_DEGREE} pop 1 xx_add // _ l_index_bfe [p] [right_xfe - β] - push {gamma_challenge_pointer_read} + push {gamma_challenge_read_address} read_mem {EXTENSION_DEGREE} pop 1 // _ l_index_bfe [p] [right_xfe - β] [γ] @@ -407,7 +399,7 @@ impl BasicSnippet for RootFromAuthenticationStruct { // _ l_index_bfe [p] [fact_right] [left] {&dup_top_digest} - push {left_digest_pointer_write} + push {left_digest_allocation.write_address()} write_mem {Digest::LEN} pop 1 // _ l_index_bfe [p] [fact_right] [left] @@ -415,13 +407,13 @@ impl BasicSnippet for RootFromAuthenticationStruct { {&digest_to_xfe} // _ l_index_bfe [p] [fact_right] [left_xfe] - push {beta_challenge_pointer_read} + push {beta_challenge_read_address} read_mem {EXTENSION_DEGREE} pop 1 xx_add // _ l_index_bfe [p] [fact_right] [left_xfe - β] - push {gamma_challenge_pointer_read} + push {gamma_challenge_read_address} read_mem {EXTENSION_DEGREE} pop 1 // _ l_index_bfe [p] [fact_right] [left_xfe - β] [γ] @@ -443,10 +435,10 @@ impl BasicSnippet for RootFromAuthenticationStruct { // _ l_index_bfe [p * (fact_right*fact_left)^{-1}] /* Calculate t = hash(left, right) */ - push {right_digest_pointer_read} + push {right_digest_allocation.read_address()} read_mem {Digest::LEN} pop 1 - push {left_digest_pointer_read} + push {left_digest_allocation.read_address()} read_mem {Digest::LEN} pop 1 hash @@ -463,13 +455,13 @@ impl BasicSnippet for RootFromAuthenticationStruct { {&digest_to_xfe} // _ l_index_bfe [p * (fact_right*fact_left)^{-1}] [t_xfe] - push {beta_challenge_pointer_read} + push {beta_challenge_read_address} read_mem {EXTENSION_DEGREE} pop 1 xx_add // _ l_index_bfe [p * (fact_right*fact_left)^{-1}] [t_xfe - β] - push {gamma_challenge_pointer_read} + push {gamma_challenge_read_address} read_mem {EXTENSION_DEGREE} pop 1 // _ l_index_bfe [p * (fact_right*fact_left)^{-1}] [t_xfe - β] [γ] @@ -583,7 +575,7 @@ impl BasicSnippet for RootFromAuthenticationStruct { // _ tree_num_leafs *indexed_leafs [p] [t; 5] /* Write t value (in case we're not entering the loop) */ - push {t_digest_pointer_write} + push {t_digest_write_address} write_mem {Digest::LEN} pop 1 // _ tree_num_leafs *indexed_leafs [p] @@ -608,19 +600,19 @@ impl BasicSnippet for RootFromAuthenticationStruct { // _ [p] /* Assert that p == t_xfe - beta + gamma */ - push {t_digest_pointer_read} + push {t_digest_read_address} read_mem {Digest::LEN} pop 1 {&digest_to_xfe} // _ [p] [t_xfe] - push {beta_challenge_pointer_read} + push {beta_challenge_read_address} read_mem {EXTENSION_DEGREE} pop 1 xx_add // _ [p] [t_xfe - β] - push {gamma_challenge_pointer_read} + push {gamma_challenge_read_address} read_mem {EXTENSION_DEGREE} pop 1 xx_add @@ -633,7 +625,7 @@ impl BasicSnippet for RootFromAuthenticationStruct { // _ /* Return `t` (digest) */ - push {t_digest_pointer_read} + push {t_digest_read_address} read_mem {Digest::LEN} pop 1 // _ [t] @@ -664,11 +656,10 @@ mod tests { use triton_vm::prelude::twenty_first::prelude::Sponge; use triton_vm::prelude::twenty_first::util_types::mmr::mmr_accumulator::util::mmra_with_mps; + use crate::memory::encode_to_memory; use crate::mmr::authentication_struct::shared::AuthStructIntegrityProof; - use crate::rust_shadowing_helper_functions::input::read_digest_from_input; use crate::rust_shadowing_helper_functions::list::list_insert; use crate::rust_shadowing_helper_functions::list::load_list_with_copy_elements; - use crate::rust_shadowing_helper_functions::memory::write_to_memory; use crate::snippet_bencher::BenchmarkCase; use crate::traits::procedure::Procedure; use crate::traits::procedure::ProcedureInitialState; @@ -677,6 +668,19 @@ mod tests { use super::*; + /// Read and consume a digest from an input source, either public input or + /// secret input. Returns the digest. + pub(crate) fn read_digest_from_input(secret_in: &mut VecDeque) -> Digest { + let mut values = [BFieldElement::zero(); Digest::LEN]; + let mut i = 0; + while i < Digest::LEN { + values[Digest::LEN - 1 - i] = secret_in.pop_front().unwrap(); + i += 1; + } + + Digest::new(values) + } + const SIZE_OF_INDEXED_LEAFS_ELEMENT: usize = Digest::LEN + 2; #[test] @@ -721,12 +725,12 @@ mod tests { const LEFT_DIGEST_POINTER_WRITE: BFieldElement = BFieldElement::new(BFieldElement::P - 25); - write_to_memory(ALPHA_POINTER_WRITE, alpha, memory); - write_to_memory(BETA_POINTER_WRITE, beta, memory); - write_to_memory(GAMMA_POINTER_WRITE, gamma, memory); - write_to_memory(T_DIGEST_POINTER_WRITE, t, memory); - write_to_memory(RIGHT_DIGEST_POINTER_WRITE, right, memory); - write_to_memory(LEFT_DIGEST_POINTER_WRITE, left, memory); + encode_to_memory(memory, ALPHA_POINTER_WRITE, &alpha); + encode_to_memory(memory, BETA_POINTER_WRITE, &beta); + encode_to_memory(memory, GAMMA_POINTER_WRITE, &gamma); + encode_to_memory(memory, T_DIGEST_POINTER_WRITE, &t); + encode_to_memory(memory, RIGHT_DIGEST_POINTER_WRITE, &right); + encode_to_memory(memory, LEFT_DIGEST_POINTER_WRITE, &left); } fn accumulate_indexed_leafs( diff --git a/tasm-lib/src/rust_shadowing_helper_functions.rs b/tasm-lib/src/rust_shadowing_helper_functions.rs index c3a1a225e..3dc001ddc 100644 --- a/tasm-lib/src/rust_shadowing_helper_functions.rs +++ b/tasm-lib/src/rust_shadowing_helper_functions.rs @@ -1,9 +1,7 @@ pub mod array; pub mod claim; pub mod dyn_malloc; -pub mod input; pub mod list; -pub mod memory; /// Count the number of non-leaf nodes that were inserted *prior* to /// the insertion of this leaf. diff --git a/tasm-lib/src/rust_shadowing_helper_functions/input.rs b/tasm-lib/src/rust_shadowing_helper_functions/input.rs deleted file mode 100644 index 955ce52c8..000000000 --- a/tasm-lib/src/rust_shadowing_helper_functions/input.rs +++ /dev/null @@ -1,58 +0,0 @@ -use std::collections::VecDeque; - -use num::Zero; -use triton_vm::prelude::*; -use triton_vm::prelude::twenty_first::math::other::random_elements; - -use crate::Digest; - -pub fn write_digest_to_std_in(std_in: &mut Vec, digest: Digest) { - let digest_elements = digest.values(); - for i in 0..Digest::LEN { - std_in.push(digest_elements[Digest::LEN - 1 - i]); - } -} - -pub fn write_value_to_secret_in(secret_in: &mut Vec, value: BFieldElement) { - secret_in.push(value) -} - -pub fn write_digest_to_secret_in(secret_in: &mut Vec, digest: Digest) { - let digest_elements = digest.values(); - for i in 0..Digest::LEN { - secret_in.push(digest_elements[Digest::LEN - 1 - i]); - } -} - -pub fn write_dummy_ap_path(input: &mut Vec, ap_length: usize) { - input.push(BFieldElement::new(ap_length as u64)); - let ap_elements: Vec = random_elements(ap_length); - for ap_element in ap_elements.iter() { - write_digest_to_secret_in(input, *ap_element); - } -} - -pub fn read_digest_from_std_in(std_in: &[BFieldElement], std_in_cursor: &mut usize) -> Digest { - let mut values = [BFieldElement::zero(); Digest::LEN]; - let mut i = 0; - while i < Digest::LEN { - values[Digest::LEN - 1 - i] = std_in[*std_in_cursor]; - *std_in_cursor += 1; - i += 1; - } - - Digest::new(values) -} - -/// Read and consume a digest from an input source, either public input or -/// secret input. Returns the digest. -pub fn read_digest_from_input(secret_in: &mut VecDeque) -> Digest { - let mut values = [BFieldElement::zero(); Digest::LEN]; - let mut i = 0; - while i < Digest::LEN { - values[Digest::LEN - 1 - i] = secret_in.pop_front().unwrap(); - i += 1; - } - - Digest::new(values) -} diff --git a/tasm-lib/src/rust_shadowing_helper_functions/memory.rs b/tasm-lib/src/rust_shadowing_helper_functions/memory.rs deleted file mode 100644 index aaeda8e7f..000000000 --- a/tasm-lib/src/rust_shadowing_helper_functions/memory.rs +++ /dev/null @@ -1,15 +0,0 @@ -use std::collections::HashMap; - -use triton_vm::prelude::BFieldCodec; -use triton_vm::prelude::BFieldElement; - -pub fn write_to_memory( - mut pointer: BFieldElement, - value: T, - memory: &mut HashMap, -) { - for word in value.encode() { - memory.insert(pointer, word); - pointer.increment(); - } -} From ccd7382b9c85f4f9fb7fb6fa781236ad2a14ed58 Mon Sep 17 00:00:00 2001 From: Alan Szepieniec Date: Tue, 6 May 2025 16:35:36 +0200 Subject: [PATCH 14/14] chore: Cargo fmt --- tasm-lib/src/array/sum_of_xfes.rs | 2 +- tasm-lib/src/hashing/absorb_multiple_static_size.rs | 2 +- tasm-lib/src/hashing/algebraic_hasher/sample_scalars.rs | 2 +- .../sample_scalars_static_length_dyn_malloc.rs | 2 +- .../sample_scalars_static_length_kmalloc.rs | 2 +- .../sample_scalars_static_length_static_pointer.rs | 2 +- tasm-lib/src/hashing/hash_from_stack.rs | 2 +- tasm-lib/src/hashing/sponge_hasher/absorb.rs | 2 +- tasm-lib/src/hashing/sponge_hasher/pad_and_absorb_all.rs | 2 +- tasm-lib/src/hashing/sponge_hasher/squeeze.rs | 2 +- tasm-lib/src/hashing/squeeze_repeatedly_static_number.rs | 2 +- tasm-lib/src/list/multiset_equality_u64s.rs | 2 +- tasm-lib/src/list/sum_xfes.rs | 2 +- tasm-lib/src/mmr/verify_mmr_successor.rs | 2 +- tasm-lib/src/neptune/neptune_like_types_for_tests.rs | 2 +- tasm-lib/src/rust_shadowing_helper_functions/list.rs | 2 +- .../src/structure/manual_tasm_object_implementations.rs | 2 +- .../src/verifier/challenges/new_empty_input_and_output.rs | 2 +- tasm-lib/src/verifier/challenges/new_generic_dyn_claim.rs | 2 +- tasm-lib/src/verifier/fri/barycentric_evaluation.rs | 2 +- tasm-lib/src/verifier/fri/test_helpers.rs | 2 +- .../src/verifier/fri/verify_fri_authentication_paths.rs | 2 +- .../src/verifier/master_table/air_constraint_evaluation.rs | 4 ++-- tasm-lib/src/verifier/master_table/divide_out_zerofiers.rs | 2 +- tasm-lib/src/verifier/master_table/verify_table_rows.rs | 2 +- tasm-lib/src/verifier/master_table/zerofiers_inverse.rs | 2 +- tasm-lib/src/verifier/out_of_domain_points.rs | 4 ++-- tasm-lib/src/verifier/stark_verify.rs | 4 ++-- tasm-lib/src/verifier/vm_proof_iter/dequeue_next_as.rs | 6 +++--- 29 files changed, 34 insertions(+), 34 deletions(-) diff --git a/tasm-lib/src/array/sum_of_xfes.rs b/tasm-lib/src/array/sum_of_xfes.rs index 092d8bee4..c7fbd216c 100644 --- a/tasm-lib/src/array/sum_of_xfes.rs +++ b/tasm-lib/src/array/sum_of_xfes.rs @@ -1,6 +1,6 @@ use num::Zero; -use triton_vm::prelude::*; use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::*; use crate::data_type::ArrayType; use crate::memory::load_words_from_memory_pop_pointer; diff --git a/tasm-lib/src/hashing/absorb_multiple_static_size.rs b/tasm-lib/src/hashing/absorb_multiple_static_size.rs index 020dcfb64..ffa8e6b57 100644 --- a/tasm-lib/src/hashing/absorb_multiple_static_size.rs +++ b/tasm-lib/src/hashing/absorb_multiple_static_size.rs @@ -1,5 +1,5 @@ -use triton_vm::prelude::*; use triton_vm::prelude::twenty_first::math::tip5::RATE; +use triton_vm::prelude::*; use crate::memory::load_words_from_memory_pop_pointer; use crate::prelude::*; diff --git a/tasm-lib/src/hashing/algebraic_hasher/sample_scalars.rs b/tasm-lib/src/hashing/algebraic_hasher/sample_scalars.rs index 4fc8a955a..d7f8b96ab 100644 --- a/tasm-lib/src/hashing/algebraic_hasher/sample_scalars.rs +++ b/tasm-lib/src/hashing/algebraic_hasher/sample_scalars.rs @@ -1,5 +1,5 @@ -use triton_vm::prelude::*; use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::*; use crate::hashing::squeeze_repeatedly::SqueezeRepeatedly; use crate::list::new::New; diff --git a/tasm-lib/src/hashing/algebraic_hasher/sample_scalars_static_length_dyn_malloc.rs b/tasm-lib/src/hashing/algebraic_hasher/sample_scalars_static_length_dyn_malloc.rs index 28c72f30b..bd4c5ea7b 100644 --- a/tasm-lib/src/hashing/algebraic_hasher/sample_scalars_static_length_dyn_malloc.rs +++ b/tasm-lib/src/hashing/algebraic_hasher/sample_scalars_static_length_dyn_malloc.rs @@ -1,6 +1,6 @@ -use triton_vm::prelude::*; use triton_vm::prelude::twenty_first::math::tip5::RATE; use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::*; use crate::data_type::ArrayType; use crate::hashing::squeeze_repeatedly_static_number::SqueezeRepeatedlyStaticNumber; diff --git a/tasm-lib/src/hashing/algebraic_hasher/sample_scalars_static_length_kmalloc.rs b/tasm-lib/src/hashing/algebraic_hasher/sample_scalars_static_length_kmalloc.rs index 711192566..69ed68546 100644 --- a/tasm-lib/src/hashing/algebraic_hasher/sample_scalars_static_length_kmalloc.rs +++ b/tasm-lib/src/hashing/algebraic_hasher/sample_scalars_static_length_kmalloc.rs @@ -1,6 +1,6 @@ -use triton_vm::prelude::*; use triton_vm::prelude::twenty_first::math::tip5::RATE; use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::*; use crate::hashing::algebraic_hasher::sample_scalars_static_length_dyn_malloc::SampleScalarsStaticLengthDynMalloc; use crate::hashing::squeeze_repeatedly_static_number::SqueezeRepeatedlyStaticNumber; diff --git a/tasm-lib/src/hashing/algebraic_hasher/sample_scalars_static_length_static_pointer.rs b/tasm-lib/src/hashing/algebraic_hasher/sample_scalars_static_length_static_pointer.rs index c7d80a3e4..25a759a60 100644 --- a/tasm-lib/src/hashing/algebraic_hasher/sample_scalars_static_length_static_pointer.rs +++ b/tasm-lib/src/hashing/algebraic_hasher/sample_scalars_static_length_static_pointer.rs @@ -1,6 +1,6 @@ -use triton_vm::prelude::*; use triton_vm::prelude::twenty_first::math::tip5::RATE; use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::*; use crate::hashing::algebraic_hasher::sample_scalars_static_length_dyn_malloc::SampleScalarsStaticLengthDynMalloc; use crate::hashing::squeeze_repeatedly_static_number::SqueezeRepeatedlyStaticNumber; diff --git a/tasm-lib/src/hashing/hash_from_stack.rs b/tasm-lib/src/hashing/hash_from_stack.rs index 07b532d36..d7385e9d8 100644 --- a/tasm-lib/src/hashing/hash_from_stack.rs +++ b/tasm-lib/src/hashing/hash_from_stack.rs @@ -1,5 +1,5 @@ -use triton_vm::prelude::*; use triton_vm::prelude::twenty_first::prelude::*; +use triton_vm::prelude::*; use crate::prelude::*; diff --git a/tasm-lib/src/hashing/sponge_hasher/absorb.rs b/tasm-lib/src/hashing/sponge_hasher/absorb.rs index a8ae31aa9..78beee630 100644 --- a/tasm-lib/src/hashing/sponge_hasher/absorb.rs +++ b/tasm-lib/src/hashing/sponge_hasher/absorb.rs @@ -1,5 +1,5 @@ -use triton_vm::prelude::*; use triton_vm::prelude::twenty_first::math::tip5::RATE; +use triton_vm::prelude::*; use crate::data_type::ArrayType; use crate::prelude::*; diff --git a/tasm-lib/src/hashing/sponge_hasher/pad_and_absorb_all.rs b/tasm-lib/src/hashing/sponge_hasher/pad_and_absorb_all.rs index b90b2bd46..2a99b33bd 100644 --- a/tasm-lib/src/hashing/sponge_hasher/pad_and_absorb_all.rs +++ b/tasm-lib/src/hashing/sponge_hasher/pad_and_absorb_all.rs @@ -48,8 +48,8 @@ impl BasicSnippet for PadAndAbsorbAll { mod tests { use arbitrary::Arbitrary; use arbitrary::Unstructured; - use triton_vm::prelude::*; use triton_vm::prelude::twenty_first::prelude::Sponge; + use triton_vm::prelude::*; use super::*; use crate::empty_stack; diff --git a/tasm-lib/src/hashing/sponge_hasher/squeeze.rs b/tasm-lib/src/hashing/sponge_hasher/squeeze.rs index 15490bc96..a151df611 100644 --- a/tasm-lib/src/hashing/sponge_hasher/squeeze.rs +++ b/tasm-lib/src/hashing/sponge_hasher/squeeze.rs @@ -1,5 +1,5 @@ -use triton_vm::prelude::*; use triton_vm::prelude::twenty_first::math::tip5::RATE; +use triton_vm::prelude::*; use crate::data_type::ArrayType; use crate::prelude::*; diff --git a/tasm-lib/src/hashing/squeeze_repeatedly_static_number.rs b/tasm-lib/src/hashing/squeeze_repeatedly_static_number.rs index 6a9888141..841b84769 100644 --- a/tasm-lib/src/hashing/squeeze_repeatedly_static_number.rs +++ b/tasm-lib/src/hashing/squeeze_repeatedly_static_number.rs @@ -1,5 +1,5 @@ -use triton_vm::prelude::*; use triton_vm::prelude::twenty_first::math::tip5::RATE; +use triton_vm::prelude::*; use crate::prelude::*; diff --git a/tasm-lib/src/list/multiset_equality_u64s.rs b/tasm-lib/src/list/multiset_equality_u64s.rs index 6756c257c..29c4b7257 100644 --- a/tasm-lib/src/list/multiset_equality_u64s.rs +++ b/tasm-lib/src/list/multiset_equality_u64s.rs @@ -1,5 +1,5 @@ -use triton_vm::prelude::*; use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::*; use crate::hashing::algebraic_hasher::hash_varlen::HashVarlen; use crate::prelude::*; diff --git a/tasm-lib/src/list/sum_xfes.rs b/tasm-lib/src/list/sum_xfes.rs index 615c0e9ed..9d33318d8 100644 --- a/tasm-lib/src/list/sum_xfes.rs +++ b/tasm-lib/src/list/sum_xfes.rs @@ -1,5 +1,5 @@ -use triton_vm::prelude::*; use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::*; use crate::prelude::*; diff --git a/tasm-lib/src/mmr/verify_mmr_successor.rs b/tasm-lib/src/mmr/verify_mmr_successor.rs index db7668f24..b20623f02 100644 --- a/tasm-lib/src/mmr/verify_mmr_successor.rs +++ b/tasm-lib/src/mmr/verify_mmr_successor.rs @@ -1,8 +1,8 @@ use std::collections::HashMap; -use triton_vm::prelude::*; use triton_vm::prelude::twenty_first::util_types::mmr::mmr_accumulator::MmrAccumulator; use triton_vm::prelude::twenty_first::util_types::mmr::mmr_successor_proof::MmrSuccessorProof; +use triton_vm::prelude::*; use crate::arithmetic::u64 as u64_lib; use crate::hashing::merkle_step_mem_u64_index::MerkleStepMemU64Index; diff --git a/tasm-lib/src/neptune/neptune_like_types_for_tests.rs b/tasm-lib/src/neptune/neptune_like_types_for_tests.rs index 8d37a13f8..fa77855c3 100644 --- a/tasm-lib/src/neptune/neptune_like_types_for_tests.rs +++ b/tasm-lib/src/neptune/neptune_like_types_for_tests.rs @@ -1,7 +1,7 @@ use arbitrary::Arbitrary; -use triton_vm::prelude::*; use triton_vm::prelude::twenty_first::prelude::MmrMembershipProof; use triton_vm::prelude::twenty_first::util_types::mmr::mmr_accumulator::MmrAccumulator; +use triton_vm::prelude::*; use crate::prelude::TasmObject; diff --git a/tasm-lib/src/rust_shadowing_helper_functions/list.rs b/tasm-lib/src/rust_shadowing_helper_functions/list.rs index 80669d816..ed42d633d 100644 --- a/tasm-lib/src/rust_shadowing_helper_functions/list.rs +++ b/tasm-lib/src/rust_shadowing_helper_functions/list.rs @@ -2,8 +2,8 @@ use std::collections::HashMap; use num::Zero; use num_traits::ConstOne; -use triton_vm::prelude::*; use triton_vm::prelude::twenty_first::math::other::random_elements; +use triton_vm::prelude::*; use crate::U32_TO_USIZE_ERR; use crate::USIZE_TO_U64_ERR; diff --git a/tasm-lib/src/structure/manual_tasm_object_implementations.rs b/tasm-lib/src/structure/manual_tasm_object_implementations.rs index 0fe6f116e..4d2628466 100644 --- a/tasm-lib/src/structure/manual_tasm_object_implementations.rs +++ b/tasm-lib/src/structure/manual_tasm_object_implementations.rs @@ -1,10 +1,10 @@ use itertools::Itertools; use num_traits::Zero; -use triton_vm::prelude::*; use triton_vm::prelude::twenty_first::error::BFieldCodecError; use triton_vm::prelude::twenty_first::error::PolynomialBFieldCodecError; use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use triton_vm::prelude::twenty_first::prelude::*; +use triton_vm::prelude::*; use super::tasm_object::Result; use crate::prelude::*; diff --git a/tasm-lib/src/verifier/challenges/new_empty_input_and_output.rs b/tasm-lib/src/verifier/challenges/new_empty_input_and_output.rs index ff5840134..792a00020 100644 --- a/tasm-lib/src/verifier/challenges/new_empty_input_and_output.rs +++ b/tasm-lib/src/verifier/challenges/new_empty_input_and_output.rs @@ -2,8 +2,8 @@ use num::One; use triton_vm::air::challenge_id::ChallengeId; use triton_vm::air::cross_table_argument::CrossTableArg; use triton_vm::air::cross_table_argument::EvalArg; -use triton_vm::prelude::*; use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::*; use crate::hashing::algebraic_hasher::sample_scalars_static_length_static_pointer::SampleScalarsStaticLengthStaticPointer; use crate::prelude::*; diff --git a/tasm-lib/src/verifier/challenges/new_generic_dyn_claim.rs b/tasm-lib/src/verifier/challenges/new_generic_dyn_claim.rs index 65c8b0ec9..dddb1cbaa 100644 --- a/tasm-lib/src/verifier/challenges/new_generic_dyn_claim.rs +++ b/tasm-lib/src/verifier/challenges/new_generic_dyn_claim.rs @@ -3,8 +3,8 @@ use triton_vm::air::challenge_id::ChallengeId; use triton_vm::air::cross_table_argument::CrossTableArg; use triton_vm::air::cross_table_argument::EvalArg; use triton_vm::challenges::Challenges; -use triton_vm::prelude::*; use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::*; use crate::hashing::algebraic_hasher::sample_scalars_static_length_static_pointer::SampleScalarsStaticLengthStaticPointer; use crate::prelude::*; diff --git a/tasm-lib/src/verifier/fri/barycentric_evaluation.rs b/tasm-lib/src/verifier/fri/barycentric_evaluation.rs index e548baacf..5f6f6f6fe 100644 --- a/tasm-lib/src/verifier/fri/barycentric_evaluation.rs +++ b/tasm-lib/src/verifier/fri/barycentric_evaluation.rs @@ -1,5 +1,5 @@ -use triton_vm::prelude::*; use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::*; use crate::arithmetic::bfe::primitive_root_of_unity::PrimitiveRootOfUnity; use crate::prelude::*; diff --git a/tasm-lib/src/verifier/fri/test_helpers.rs b/tasm-lib/src/verifier/fri/test_helpers.rs index d355c67af..7aaf6f7fa 100644 --- a/tasm-lib/src/verifier/fri/test_helpers.rs +++ b/tasm-lib/src/verifier/fri/test_helpers.rs @@ -1,12 +1,12 @@ use itertools::Itertools; use triton_vm::challenges::Challenges; +use triton_vm::prelude::twenty_first::prelude::*; use triton_vm::prelude::*; use triton_vm::proof_stream::ProofStream; use triton_vm::table::NUM_QUOTIENT_SEGMENTS; use triton_vm::table::master_table::MasterAuxTable; use triton_vm::table::master_table::MasterMainTable; use triton_vm::table::master_table::MasterTable; -use triton_vm::prelude::twenty_first::prelude::*; use crate::prelude::Digest; diff --git a/tasm-lib/src/verifier/fri/verify_fri_authentication_paths.rs b/tasm-lib/src/verifier/fri/verify_fri_authentication_paths.rs index 1b76b27c5..275ba9000 100644 --- a/tasm-lib/src/verifier/fri/verify_fri_authentication_paths.rs +++ b/tasm-lib/src/verifier/fri/verify_fri_authentication_paths.rs @@ -1,5 +1,5 @@ -use triton_vm::prelude::*; use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::*; use crate::prelude::*; diff --git a/tasm-lib/src/verifier/master_table/air_constraint_evaluation.rs b/tasm-lib/src/verifier/master_table/air_constraint_evaluation.rs index b33b12fac..ff0a94940 100644 --- a/tasm-lib/src/verifier/master_table/air_constraint_evaluation.rs +++ b/tasm-lib/src/verifier/master_table/air_constraint_evaluation.rs @@ -5,12 +5,12 @@ use triton_vm::constraints::static_air_constraint_evaluation_tasm; use triton_vm::memory_layout::DynamicTasmConstraintEvaluationMemoryLayout; use triton_vm::memory_layout::IntegralMemoryLayout; use triton_vm::memory_layout::StaticTasmConstraintEvaluationMemoryLayout; +use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use triton_vm::prelude::*; use triton_vm::table::auxiliary_table::Evaluable; use triton_vm::table::master_table::MasterAuxTable; use triton_vm::table::master_table::MasterMainTable; use triton_vm::table::master_table::MasterTable; -use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use crate::data_type::ArrayType; use crate::memory::dyn_malloc::DYN_MALLOC_ADDRESS; @@ -296,10 +296,10 @@ mod tests { use arbitrary::Unstructured; use num_traits::ConstZero; use rand::distr::StandardUniform; + use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use triton_vm::proof_stream::ProofStream; use triton_vm::table::master_table::MasterMainTable; use triton_vm::table::master_table::MasterTable; - use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use super::*; use crate::execute_test; diff --git a/tasm-lib/src/verifier/master_table/divide_out_zerofiers.rs b/tasm-lib/src/verifier/master_table/divide_out_zerofiers.rs index 981499735..f5d4982d8 100644 --- a/tasm-lib/src/verifier/master_table/divide_out_zerofiers.rs +++ b/tasm-lib/src/verifier/master_table/divide_out_zerofiers.rs @@ -1,8 +1,8 @@ use triton_vm::prelude::LabelledInstruction; +use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use triton_vm::prelude::*; use triton_vm::table::ConstraintType; use triton_vm::table::master_table::MasterAuxTable; -use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use crate::prelude::*; use crate::verifier::master_table::air_constraint_evaluation::AirConstraintEvaluation; diff --git a/tasm-lib/src/verifier/master_table/verify_table_rows.rs b/tasm-lib/src/verifier/master_table/verify_table_rows.rs index 2a10610df..3e2c9fba5 100644 --- a/tasm-lib/src/verifier/master_table/verify_table_rows.rs +++ b/tasm-lib/src/verifier/master_table/verify_table_rows.rs @@ -1,11 +1,11 @@ use strum::Display; use strum::EnumIter; +use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use triton_vm::prelude::*; use triton_vm::table::NUM_QUOTIENT_SEGMENTS; use triton_vm::table::master_table::MasterAuxTable; use triton_vm::table::master_table::MasterMainTable; use triton_vm::table::master_table::MasterTable; -use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use crate::hashing::algebraic_hasher::hash_static_size::HashStaticSize; use crate::prelude::*; diff --git a/tasm-lib/src/verifier/master_table/zerofiers_inverse.rs b/tasm-lib/src/verifier/master_table/zerofiers_inverse.rs index 28c2a0764..c0c6d1663 100644 --- a/tasm-lib/src/verifier/master_table/zerofiers_inverse.rs +++ b/tasm-lib/src/verifier/master_table/zerofiers_inverse.rs @@ -1,7 +1,7 @@ use strum::EnumCount; +use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use triton_vm::prelude::*; use triton_vm::table::ConstraintType; -use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; use crate::arithmetic::xfe::to_the_power_of_power_of_2::ToThePowerOfPowerOf2; use crate::prelude::*; diff --git a/tasm-lib/src/verifier/out_of_domain_points.rs b/tasm-lib/src/verifier/out_of_domain_points.rs index 601c25fb5..3a6bb1703 100644 --- a/tasm-lib/src/verifier/out_of_domain_points.rs +++ b/tasm-lib/src/verifier/out_of_domain_points.rs @@ -1,5 +1,5 @@ -use triton_vm::prelude::*; use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::*; use crate::data_type::ArrayType; use crate::prelude::*; @@ -124,9 +124,9 @@ impl BasicSnippet for OutOfDomainPoints { #[cfg(test)] mod tests { - use triton_vm::table::NUM_QUOTIENT_SEGMENTS; use triton_vm::prelude::twenty_first::math::traits::ModPowU32; use triton_vm::prelude::twenty_first::math::traits::PrimitiveRootOfUnity; + use triton_vm::table::NUM_QUOTIENT_SEGMENTS; use super::*; use crate::rust_shadowing_helper_functions::array::insert_as_array; diff --git a/tasm-lib/src/verifier/stark_verify.rs b/tasm-lib/src/verifier/stark_verify.rs index 557f326ed..67275075f 100644 --- a/tasm-lib/src/verifier/stark_verify.rs +++ b/tasm-lib/src/verifier/stark_verify.rs @@ -1,5 +1,7 @@ use itertools::Itertools; use triton_vm::challenges::Challenges; +use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::twenty_first::prelude::MerkleTreeInclusionProof; use triton_vm::prelude::*; use triton_vm::proof_item::ProofItemVariant; use triton_vm::proof_stream::ProofStream; @@ -7,8 +9,6 @@ use triton_vm::table::NUM_QUOTIENT_SEGMENTS; use triton_vm::table::master_table::MasterAuxTable; use triton_vm::table::master_table::MasterMainTable; use triton_vm::table::master_table::MasterTable; -use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; -use triton_vm::prelude::twenty_first::prelude::MerkleTreeInclusionProof; use super::master_table::air_constraint_evaluation::AirConstraintEvaluation; use super::master_table::air_constraint_evaluation::MemoryLayout; diff --git a/tasm-lib/src/verifier/vm_proof_iter/dequeue_next_as.rs b/tasm-lib/src/verifier/vm_proof_iter/dequeue_next_as.rs index 383b08f16..58792f235 100644 --- a/tasm-lib/src/verifier/vm_proof_iter/dequeue_next_as.rs +++ b/tasm-lib/src/verifier/vm_proof_iter/dequeue_next_as.rs @@ -1,12 +1,12 @@ use triton_vm::fri::AuthenticationStructure; +use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; +use triton_vm::prelude::twenty_first::prelude::Polynomial; use triton_vm::prelude::*; use triton_vm::proof_item::FriResponse; use triton_vm::proof_item::ProofItemVariant; use triton_vm::table::AuxiliaryRow; use triton_vm::table::MainRow; use triton_vm::table::QuotientSegments; -use triton_vm::prelude::twenty_first::math::x_field_element::EXTENSION_DEGREE; -use triton_vm::prelude::twenty_first::prelude::Polynomial; use crate::hashing::sponge_hasher::pad_and_absorb_all::PadAndAbsorbAll; use crate::prelude::*; @@ -374,11 +374,11 @@ mod tests { use num_traits::One; use num_traits::Zero; use strum::IntoEnumIterator; + use triton_vm::prelude::twenty_first::prelude::*; use triton_vm::proof_item::ProofItem; use triton_vm::proof_stream::ProofStream; use triton_vm::table::master_table::MasterMainTable; use triton_vm::table::master_table::MasterTable; - use triton_vm::prelude::twenty_first::prelude::*; use super::*; use crate::empty_stack;