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 ea85fbc6..4ac635a9 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 cf240a9d..9ef3b582 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 00000000..eec3c896 --- /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 00000000..16758680 --- /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 00000000..4a8a16a8 --- /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 00000000..e317de7a --- /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 9ef3b582..803819ec 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 eec3c896..2406a8f5 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 00000000..a4920f92 --- /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 4a8a16a8..404ba496 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 16758680..d17f4920 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 bfe6f833..edaf2480 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 00000000..aaeda8e7 --- /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 404ba496..2d156f4e 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 d17f4920..58f371df 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 00000000..a7a1a6c9 --- /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 2d156f4e..198f0935 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 a7a1a6c9..6a8f9829 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 198f0935..626719d6 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 6a8f9829..6e012149 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 626719d6..b4adf98d 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 6e012149..295148f3 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 b4adf98d..32d672a6 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 58f371df..5418c063 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 295148f3..e6ea6a91 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 32d672a6..b94ebdc4 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 e6ea6a91..1708cd5f 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 b94ebdc4..259b7e74 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 1708cd5f..b723f98f 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 259b7e74..b6cfc303 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 58f64886..bf2308ee 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 a4920f92..616a2b11 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 b6cfc303..0d30b40d 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 5418c063..c1eba8a9 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 edaf2480..c3a1a225 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 00000000..a766bddf --- /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 bf2308ee..91b02014 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 e317de7a..76919995 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 b723f98f..e1155b88 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 efa4954f..3469adc5 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 0098b289..e4ae2b37 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 5399e107..ef34f71e 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 52aae39e..092d8bee 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 8c777c34..8e43467f 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 a7962c5e..020dcfb6 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 870b09f7..68019bec 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 ab659827..4da808dc 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 98b3d87a..1416e6b7 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 ade4859c..4fc8a955 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 0109bb1e..28c72f30 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 d265401b..71119256 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 49ee137c..c7d80a3e 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 cd265831..07b532d3 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 3f2872d7..507cce91 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 63f2b6a3..d9f82b73 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 6ce2ebcb..a8ae31aa 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 4b862343..e61f7476 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 d5760e2b..b90b2bd4 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 738a8b9d..15490bc9 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 a697c199..9dc51d2f 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 79f6c2cc..6a988814 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 2ea8564f..73fb8061 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 ecf690e9..6a406a7d 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 7e3eaa4f..6756c257 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 15b4496f..615c0e9e 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 616a2b11..5cc608c5 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 0d30b40d..8723383c 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 79f6aa90..64e3d0f0 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 5249f96f..cad464ab 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 7fbfeaad..a737bfa4 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 d0745be2..92e56c07 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 fdae7e5b..ba695f77 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 cba48dd3..bf704ad3 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 af463cd0..db7668f2 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 3a073188..1017f6b9 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 04076888..8d37a13f 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 6f15600f..a6adb329 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 a766bddf..955ce52c 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 2a98a7d8..80669d81 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 4e802e9f..0fe6f116 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 de9adf18..e8d4940c 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 7136ff86..f270755b 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 f914ce08..ff584013 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 247450db..65c8b0ec 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 0d1d04ec..c87885d7 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 48a9213b..e548baac 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 2df74992..34a40cd4 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 bb9a202c..c122553d 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 f3a4358e..d355c67a 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 860db599..9648371a 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 a8cdefe3..1b76b27c 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 e0ab6300..b33b12fa 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 53b4970a..98149973 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 3be57428..2a10610d 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 2af55068..28c2a076 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 b6d927d3..601c25fb 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 7c2c327f..557f326e 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 b9c2427d..383b08f1 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 9db8f5db..114defc3 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 76919995..a6cb3ac1 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 e1155b88..dd1afaad 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 4ac635a9..ea85fbc6 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 5cc608c5..93e2a1e1 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 8723383c..9054d018 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 c3a1a225..3dc001dd 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 955ce52c..00000000 --- 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 aaeda8e7..00000000 --- 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 092d8bee..c7fbd216 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 020dcfb6..ffa8e6b5 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 4fc8a955..d7f8b96a 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 28c72f30..bd4c5ea7 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 71119256..69ed6854 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 c7d80a3e..25a759a6 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 07b532d3..d7385e9d 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 a8ae31aa..78beee63 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 b90b2bd4..2a99b33b 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 15490bc9..a151df61 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 6a988814..841b8476 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 6756c257..29c4b725 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 615c0e9e..9d33318d 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 db7668f2..b20623f0 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 8d37a13f..fa77855c 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 80669d81..ed42d633 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 0fe6f116..4d262846 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 ff584013..792a0002 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 65c8b0ec..dddb1cba 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 e548baac..5f6f6f6f 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 d355c67a..7aaf6f7f 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 1b76b27c..275ba900 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 b33b12fa..ff0a9494 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 98149973..f5d4982d 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 2a10610d..3e2c9fba 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 28c2a076..c0c6d166 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 601c25fb..3a6bb170 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 557f326e..67275075 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 383b08f1..58792f23 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;