diff --git a/src/commitment_scheme/merkle_input.rs b/src/commitment_scheme/merkle_input.rs index a73a970c2..6053fce05 100644 --- a/src/commitment_scheme/merkle_input.rs +++ b/src/commitment_scheme/merkle_input.rs @@ -98,31 +98,31 @@ impl<'a, F: Field> MerkleTreeInput<'a, F> { self.columns_to_inject.len() } - // Returns the structure of the merkle tree. i.e. for each depth, the length of the columns + // Returns the column layout of the merkle tree. i.e. for each depth, the length of the columns // assigned to it. // TODO(Ohad): implement this logic for the verifier. - pub fn configuration(&self) -> MerkleTreeConfig { + pub fn column_layout(&self) -> MerkleTreeColumnLayout { let column_sizes = self .columns_to_inject .iter() .map(|col| col.len()) .collect::>(); - MerkleTreeConfig { + MerkleTreeColumnLayout { column_sizes, injected_depths_map: self.injected_depths_map.clone(), } } } -/// The structure of a mixed degree merkle tree. +/// The column layout of a mixed degree merkle tree. /// The sizes of columns assigned to every layer, ordered as they were inserted & injected into hash /// blocks. -pub struct MerkleTreeConfig { +pub struct MerkleTreeColumnLayout { column_sizes: Vec, injected_depths_map: Vec>, } -impl MerkleTreeConfig { +impl MerkleTreeColumnLayout { pub fn sort_queries_by_layer(&self, queries: &[Vec]) -> Vec>> { let mut queries_to_layers = vec![vec![]; self.height()]; (1..=self.height()).for_each(|i| { @@ -261,7 +261,7 @@ mod tests { merkle_input.insert_column(2, &column_length_4); merkle_input.insert_column(3, &column_length_16); - let merkle_config = merkle_input.configuration(); + let merkle_config = merkle_input.column_layout(); assert_eq!(merkle_config.column_lengths_at_depth(3), vec![4, 16]); assert_eq!(merkle_config.column_lengths_at_depth(2), vec![8, 4]); @@ -280,7 +280,7 @@ mod tests { let queries = vec![vec![0], vec![1], vec![2], vec![3], vec![4], vec![5]]; - let merkle_config = merkle_input.configuration(); + let merkle_config = merkle_input.column_layout(); let sorted_queries = merkle_config.sort_queries_by_layer(&queries); assert_eq!( diff --git a/src/commitment_scheme/mixed_degree_decommitment.rs b/src/commitment_scheme/mixed_degree_decommitment.rs index 96c9d6e33..dde6a4930 100644 --- a/src/commitment_scheme/mixed_degree_decommitment.rs +++ b/src/commitment_scheme/mixed_degree_decommitment.rs @@ -4,14 +4,14 @@ use itertools::Itertools; use merging_iterator::MergeIter; use super::hasher::Hasher; -use super::merkle_input::MerkleTreeConfig; +use super::merkle_input::MerkleTreeColumnLayout; use super::mixed_degree_merkle_tree::queried_nodes_in_layer; use crate::core::fields::{Field, IntoSlice}; /// A Merkle proof of queried indices. /// Used for storing a all the paths from the query leaves to the root. /// A correctly generated decommitment should hold all the information needed to generate the root -/// of the tree, proving the queried values and the tree's structure. +/// of the tree, proving the queried values and the tree's column layout. // TODO(Ohad): write printing functions. pub struct MixedDecommitment { pub hashes: Vec, @@ -34,7 +34,7 @@ impl MixedDecommitment { pub fn verify( &self, root: H::Hash, - structure: &MerkleTreeConfig, + column_layout: &MerkleTreeColumnLayout, queries: &[Vec], mut queried_values: impl Iterator, ) -> bool @@ -42,16 +42,16 @@ impl MixedDecommitment { F: IntoSlice, { let mut witness_hashes = self.hashes.iter(); - let sorted_queries_by_layer = structure.sort_queries_by_layer(queries); + let sorted_queries_by_layer = column_layout.sort_queries_by_layer(queries); let mut next_layer_hashes = vec![]; let mut ancestor_indices = vec![]; let mut witness_elements = self.witness_elements.iter().copied(); - for i in (1..=structure.height()).rev() { + for i in (1..=column_layout.height()).rev() { (next_layer_hashes, ancestor_indices) = Self::verify_single_layer( i, &sorted_queries_by_layer[i - 1], - structure, + column_layout, ancestor_indices.iter().copied().peekable(), queried_values.by_ref(), &mut witness_elements, @@ -67,7 +67,7 @@ impl MixedDecommitment { fn verify_single_layer<'a>( layer_depth: usize, queries_to_layer: &[Vec], - structure: &MerkleTreeConfig, + column_layout: &MerkleTreeColumnLayout, mut previous_layers_indices: Peekable + Clone>, mut queried_values: impl Iterator, mut witness_elements: impl Iterator, @@ -78,7 +78,7 @@ impl MixedDecommitment { F: IntoSlice, { let directly_queried_node_indices = - queried_nodes_in_layer(queries_to_layer.iter(), structure, layer_depth); + queried_nodes_in_layer(queries_to_layer.iter(), column_layout, layer_depth); let mut node_indices = MergeIter::new( directly_queried_node_indices.iter().copied(), previous_layers_indices.clone().map(|q| q / 2), @@ -97,7 +97,7 @@ impl MixedDecommitment { for &node_index in &node_indices { // Push correct child hashes to the hasher. match previous_layers_indices.next_if(|hash_index| *hash_index / 2 == node_index) { - None if layer_depth < structure.height() => { + None if layer_depth < column_layout.height() => { hasher.update(witness_hashes_iter.next().unwrap().as_ref()); hasher.update(witness_hashes_iter.next().unwrap().as_ref()); } @@ -129,7 +129,7 @@ impl MixedDecommitment { // Chunk size - according to the column's length and the current depth, we calculate the // number of elements from that column 'injected' to the current node. - for (chunk_size, column_queries) in structure + for (chunk_size, column_queries) in column_layout .column_lengths_at_depth(layer_depth) .iter() .map(|&column_length| column_length >> (layer_depth - 1)) @@ -154,9 +154,7 @@ mod tests { use crate::commitment_scheme::blake3_hash::Blake3Hasher; use crate::commitment_scheme::hasher::Hasher; use crate::commitment_scheme::merkle_input::MerkleTreeInput; - use crate::commitment_scheme::mixed_degree_merkle_tree::{ - MixedDegreeMerkleTree, MixedDegreeMerkleTreeConfig, - }; + use crate::commitment_scheme::mixed_degree_merkle_tree::MixedDegreeMerkleTree; use crate::core::fields::m31::M31; #[test] @@ -168,17 +166,11 @@ mod tests { input.insert_column(TREE_HEIGHT, &column_length_8); input.insert_column(TREE_HEIGHT - 1, &column_length_4); input.insert_column(TREE_HEIGHT - 1, &column_length_8); - let config = input.configuration(); - let mut tree = MixedDegreeMerkleTree::::new( - input, - MixedDegreeMerkleTreeConfig { - multi_layer_sizes: [3, 1].to_vec(), - }, - ); - let commitment = tree.commit(); + let config = input.column_layout(); + let (tree, commitment) = MixedDegreeMerkleTree::::commit_default(&input); let queries: Vec> = vec![vec![2], vec![0_usize], vec![4, 7]]; - let decommitment = tree.decommit(&queries); + let decommitment = tree.decommit(&input, &queries); assert!(decommitment.verify( commitment, &config, @@ -197,18 +189,12 @@ mod tests { input.insert_column(TREE_HEIGHT, &column_length_8); input.insert_column(TREE_HEIGHT - 1, &column_length_4); input.insert_column(TREE_HEIGHT - 1, &column_length_8); - let config = input.configuration(); - let mut tree = MixedDegreeMerkleTree::::new( - input, - MixedDegreeMerkleTreeConfig { - multi_layer_sizes: [3, 1].to_vec(), - }, - ); - tree.commit(); + let config = input.column_layout(); + let (tree, _) = MixedDegreeMerkleTree::::commit_default(&input); let false_commitment = Blake3Hasher::hash(b"false_commitment"); let queries: Vec> = vec![vec![2], vec![0_usize], vec![4, 7]]; - let decommitment = tree.decommit(&queries); + let decommitment = tree.decommit(&input, &queries); assert!(decommitment.verify( false_commitment, @@ -228,17 +214,11 @@ mod tests { input.insert_column(TREE_HEIGHT, &column_length_8); input.insert_column(TREE_HEIGHT - 1, &column_length_4); input.insert_column(TREE_HEIGHT - 1, &column_length_8); - let config = input.configuration(); - let mut tree = MixedDegreeMerkleTree::::new( - input, - MixedDegreeMerkleTreeConfig { - multi_layer_sizes: vec![3, 1], - }, - ); - let commitment = tree.commit(); + let config = input.column_layout(); + let (tree, commitment) = MixedDegreeMerkleTree::::commit_default(&input); let queries: Vec> = vec![vec![2], vec![0_usize], vec![4, 7]]; - let mut decommitment = tree.decommit(&queries); + let mut decommitment = tree.decommit(&input, &queries); decommitment.hashes[0] = Blake3Hasher::hash(b"false_hash"); assert!(decommitment.verify( diff --git a/src/commitment_scheme/mixed_degree_merkle_tree.rs b/src/commitment_scheme/mixed_degree_merkle_tree.rs index 8e1c760dc..afbaf7204 100644 --- a/src/commitment_scheme/mixed_degree_merkle_tree.rs +++ b/src/commitment_scheme/mixed_degree_merkle_tree.rs @@ -4,7 +4,7 @@ use itertools::Itertools; use merging_iterator::MergeIter; use super::hasher::Hasher; -use super::merkle_input::{MerkleTreeConfig, MerkleTreeInput}; +use super::merkle_input::{MerkleTreeColumnLayout, MerkleTreeInput}; use super::merkle_multilayer::MerkleMultiLayer; use super::mixed_degree_decommitment::MixedDecommitment; use crate::commitment_scheme::merkle_multilayer::MerkleMultiLayerConfig; @@ -12,6 +12,8 @@ use crate::commitment_scheme::utils::get_column_chunk; use crate::core::fields::{Field, IntoSlice}; /// A mixed degree merkle tree. +/// Stored as a vector of ['MerkleMultiLayer']s, each with a configurable height. +/// Only stores the generated hash values. /// /// # Example /// @@ -26,11 +28,11 @@ use crate::core::fields::{Field, IntoSlice}; /// input.insert_column(7, &column); /// /// -/// let mut tree = MixedDegreeMerkleTree::::new(input,MixedDegreeMerkleTreeConfig {multi_layer_sizes: [5,2].to_vec(),}); -/// let root = tree.commit(); -pub struct MixedDegreeMerkleTree<'a, F: Field, H: Hasher> { - input: MerkleTreeInput<'a, F>, - pub multi_layers: Vec>, +/// let (tree, commitment) = MixedDegreeMerkleTree::::commit_default(&input); +pub struct MixedDegreeMerkleTree { + column_layout: MerkleTreeColumnLayout, + multi_layers: Vec>, + _field: std::marker::PhantomData, } /// Sets the heights of the multi layers in the tree in ascending order. @@ -38,12 +40,53 @@ pub struct MixedDegreeMerkleTreeConfig { pub multi_layer_sizes: Vec, } -impl<'a, F: Field, H: Hasher> MixedDegreeMerkleTree<'a, F, H> +impl<'a, F: Field, H: Hasher> MixedDegreeMerkleTree where F: IntoSlice, { - pub fn new(input: MerkleTreeInput<'a, F>, config: MixedDegreeMerkleTreeConfig) -> Self { - let tree_height = input.max_injected_depth(); + pub fn commit_default(input: &MerkleTreeInput<'a, F>) -> (Self, H::Hash) { + // Default configuration is a single tree. + let config = MixedDegreeMerkleTreeConfig { + multi_layer_sizes: vec![input.max_injected_depth()], + }; + + Self::commit(input, config) + } + + /// Generate a mixed degree merkle tree with configured ['MerkleMultiLayer'] sizes. + /// The sum of layer sizes must match the depth of the deepest column of the input. + /// + /// # Example + /// + /// ```rust + /// use stwo::commitment_scheme::merkle_input::MerkleTreeInput; + /// use stwo::commitment_scheme::mixed_degree_merkle_tree::*; + /// use stwo::commitment_scheme::blake3_hash::Blake3Hasher; + /// use stwo::core::fields::m31::M31; + /// + /// let mut input = MerkleTreeInput::::new(); + /// let column = vec![M31::from_u32_unchecked(0); 1024]; + /// input.insert_column(7, &column); + /// let config = MixedDegreeMerkleTreeConfig {multi_layer_sizes: vec![4,2,1]}; + /// + /// + /// let (tree, commitment) = MixedDegreeMerkleTree::::commit(&input, config); + pub fn commit( + input: &MerkleTreeInput<'a, F>, + config: MixedDegreeMerkleTreeConfig, + ) -> (Self, H::Hash) { + let mut tree = Self { + column_layout: input.column_layout(), + multi_layers: vec![], + _field: std::marker::PhantomData, + }; + tree.init_memory(config); + let root = tree.hash(input); + (tree, root) + } + + fn init_memory(&mut self, config: MixedDegreeMerkleTreeConfig) { + let tree_height = self.height(); Self::validate_config(&config, tree_height); let mut layers = Vec::>::new(); @@ -55,20 +98,13 @@ where current_depth -= layer_height; } - MixedDegreeMerkleTree { - input, - multi_layers: layers, - } - } - - pub fn height(&self) -> usize { - self.input.max_injected_depth() + self.multi_layers = layers; } - pub fn commit(&mut self) -> H::Hash { + fn hash(&mut self, input: &MerkleTreeInput<'a, F>) -> H::Hash { let mut curr_layer = self.height() - self.multi_layer_height(0); // Bottom layer. - self.multi_layers[0].commit_layer::(&self.input, &[]); + self.multi_layers[0].commit_layer::(input, &[]); // Rest of the tree. for i in 1..self.multi_layers.len() { // TODO(Ohad): implement Hash oracle and avoid these copies. @@ -78,7 +114,7 @@ where .collect::>(); debug_assert_eq!(prev_hashes.len(), 1 << (curr_layer)); curr_layer -= self.multi_layer_height(i); - self.multi_layers[i].commit_layer::(&self.input, &prev_hashes); + self.multi_layers[i].commit_layer::(input, &prev_hashes); } let mut top_layer_roots = self.multi_layers.last().unwrap().get_roots(); let root = top_layer_roots @@ -89,6 +125,10 @@ where root } + pub fn height(&self) -> usize { + self.column_layout.height() + } + /// Generates a mixed degree merkle decommitment. /// /// # Arguments @@ -101,9 +141,7 @@ where /// ```rust /// use stwo::commitment_scheme::blake3_hash::Blake3Hasher; /// use stwo::commitment_scheme::merkle_input::MerkleTreeInput; - /// use stwo::commitment_scheme::mixed_degree_merkle_tree::{ - /// MixedDegreeMerkleTree, MixedDegreeMerkleTreeConfig, - /// }; + /// use stwo::commitment_scheme::mixed_degree_merkle_tree::MixedDegreeMerkleTree; /// use stwo::core::fields::m31::M31; /// /// let mut input = MerkleTreeInput::::new(); @@ -111,31 +149,30 @@ where /// let column_1 = vec![M31::from_u32_unchecked(0); 512]; /// input.insert_column(7, &column_0); /// input.insert_column(6, &column_1); - /// let mut tree = MixedDegreeMerkleTree::::new( - /// input, - /// MixedDegreeMerkleTreeConfig { - /// multi_layer_sizes: [5, 2].to_vec(), - /// }, - /// ); - /// let root = tree.commit(); + /// let (tree, commitment) = MixedDegreeMerkleTree::::commit_default(&input); /// /// let queries = vec![vec![0], vec![300, 511]]; - /// let decommitment = tree.decommit(queries.as_ref()); + /// let decommitment = tree.decommit(&input, queries.as_ref()); /// ``` // TODO(Ohad): introduce a proper query struct, then deprecate 'drain' usage and accepting vecs. - pub fn decommit(&self, queries: &[Vec]) -> MixedDecommitment { + pub fn decommit( + &self, + input: &MerkleTreeInput<'a, F>, + queries: &[Vec], + ) -> MixedDecommitment { assert_eq!( queries.len(), - self.input.n_injected_columns(), + input.n_injected_columns(), "Number of query vectors does not match number of injected columns." ); let mut decommitment = MixedDecommitment::::new(); - let queries_to_layers = self.input.configuration().sort_queries_by_layer(queries); + let queries_to_layers = input.column_layout().sort_queries_by_layer(queries); // Decommitment layers are built from the bottom up, excluding the root. let mut ancestor_indices = vec![]; - (1..=self.input.max_injected_depth()).rev().for_each(|i| { + (1..=input.max_injected_depth()).rev().for_each(|i| { ancestor_indices = self.decommit_single_layer( + input, i, &queries_to_layers[i - 1], ancestor_indices.iter().copied().peekable(), @@ -190,20 +227,19 @@ where // 'queries_to_layer'- queries to columns at this layer. fn decommit_single_layer( &self, + input: &MerkleTreeInput<'a, F>, layer_depth: usize, queries_to_layer: &[Vec], mut previous_layers_indices: Peekable + Clone>, decommitment: &mut MixedDecommitment, ) -> Vec { - let directly_queried_node_indices = queried_nodes_in_layer( - queries_to_layer.iter(), - &self.input.configuration(), - layer_depth, - ); + let directly_queried_node_indices = + queried_nodes_in_layer(queries_to_layer.iter(), &self.column_layout, layer_depth); let mut index_value_iterator = directly_queried_node_indices .iter() .copied() - .zip(self.layer_felt_witnesses_and_queried_elements( + .zip(Self::layer_felt_witnesses_and_queried_elements( + input, layer_depth, queries_to_layer.iter(), directly_queried_node_indices.iter().copied(), @@ -240,7 +276,7 @@ where decommitment.witness_elements.extend(witness); decommitment.queried_values.extend(queried); } else { - let injected_elements = self.input.get_injected_elements(layer_depth, node_index); + let injected_elements = input.get_injected_elements(layer_depth, node_index); decommitment.witness_elements.extend(injected_elements); } } @@ -250,7 +286,7 @@ where // Returns the felt witnesses and queried elements for the given node indices in the specified // layer. Assumes that the queries & node indices are sorted in ascending order. fn layer_felt_witnesses_and_queried_elements( - &self, + input: &MerkleTreeInput<'a, F>, layer_depth: usize, queries: impl Iterator>, node_indices: impl ExactSizeIterator, @@ -265,8 +301,7 @@ where for (node_index, (witness_elements, queried_elements)) in node_indices.zip(witnesses_and_queried_values_by_node.iter_mut()) { - for (column, column_queries) in self - .input + for (column, column_queries) in input .get_columns(layer_depth) .iter() .zip(column_query_iterators.iter_mut()) @@ -302,10 +337,10 @@ where /// was inserted to the tree's input in that layer. pub fn queried_nodes_in_layer<'a>( queries: impl Iterator>, - config: &MerkleTreeConfig, + column_layout: &MerkleTreeColumnLayout, layer_depth: usize, ) -> Vec { - let columns_lengths = config.column_lengths_at_depth(layer_depth); + let columns_lengths = column_layout.column_lengths_at_depth(layer_depth); let column_log_lengths = columns_lengths.iter().map(|c_len| c_len.ilog2() as usize); let mut node_queries = queries .into_iter() @@ -329,24 +364,33 @@ mod tests { use itertools::Itertools; - use super::{queried_nodes_in_layer, MixedDegreeMerkleTree, MixedDegreeMerkleTreeConfig}; - use crate::commitment_scheme::blake2_hash::Blake2sHasher; + use super::{MixedDegreeMerkleTree, MixedDegreeMerkleTreeConfig}; use crate::commitment_scheme::blake3_hash::Blake3Hasher; use crate::commitment_scheme::hasher::Hasher; use crate::commitment_scheme::merkle_input::MerkleTreeInput; + use crate::commitment_scheme::mixed_degree_merkle_tree::queried_nodes_in_layer; use crate::core::fields::m31::M31; use crate::core::fields::Field; use crate::m31; + fn hash_symmetric_path( + initial_value: &[H::NativeType], + path_length: usize, + ) -> H::Hash { + (1..path_length).fold(H::hash(initial_value), |curr_hash, _| { + H::concat_and_hash(&curr_hash, &curr_hash) + }) + } + #[test] - fn new_mixed_degree_merkle_tree_test() { + fn commit_configured_multi_layer_sizes_test() { let mut input = super::MerkleTreeInput::::new(); let column = vec![M31::from_u32_unchecked(0); 1 << 12]; input.insert_column(12, &column); let multi_layer_sizes = [5, 4, 3].to_vec(); - let tree = MixedDegreeMerkleTree::::new( - input, + let (tree, _root) = MixedDegreeMerkleTree::::commit( + &input, MixedDegreeMerkleTreeConfig { multi_layer_sizes: multi_layer_sizes.clone(), }, @@ -368,32 +412,23 @@ mod tests { #[test] #[should_panic] - fn new_mixed_degree_merkle_tree_bad_config_test() { + fn mixed_degree_merkle_tree_bad_config_test() { let mut input = super::MerkleTreeInput::::new(); let column = vec![M31::from_u32_unchecked(0); 4096]; input.insert_column(12, &column); // This should panic because the sum of the layer heights is not equal to the tree height // deferred by the input. - MixedDegreeMerkleTree::::new( - input, + MixedDegreeMerkleTree::::commit( + &input, MixedDegreeMerkleTreeConfig { multi_layer_sizes: [5, 4, 2].to_vec(), }, ); } - fn hash_symmetric_path( - initial_value: &[H::NativeType], - path_length: usize, - ) -> H::Hash { - (1..path_length).fold(H::hash(initial_value), |curr_hash, _| { - H::concat_and_hash(&curr_hash, &curr_hash) - }) - } - #[test] - fn commit_test() { + fn commit_default_test() { const TREE_HEIGHT: usize = 8; const INJECT_DEPTH: usize = 3; let mut input = super::MerkleTreeInput::::new(); @@ -401,12 +436,7 @@ mod tests { let injected_column = vec![M31::from_u32_unchecked(1); 1 << (INJECT_DEPTH - 1)]; input.insert_column(TREE_HEIGHT + 1, &base_column); input.insert_column(INJECT_DEPTH, &injected_column); - let mut tree = MixedDegreeMerkleTree::::new( - input, - MixedDegreeMerkleTreeConfig { - multi_layer_sizes: [5, 2, 2].to_vec(), - }, - ); + let expected_hash_at_injected_depth = hash_symmetric_path::( 0_u32.to_le_bytes().as_ref(), TREE_HEIGHT + 1 - INJECT_DEPTH, @@ -417,23 +447,38 @@ mod tests { let expected_result = hash_symmetric_path::(sack_at_injected_depth.as_ref(), INJECT_DEPTH); - let root = tree.commit(); + let (_, root) = MixedDegreeMerkleTree::::commit_default(&input); assert_eq!(root, expected_result); } + #[test] + fn commit_configured_test() { + const TREE_HEIGHT: usize = 8; + const INJECT_DEPTH: usize = 3; + let mut input = super::MerkleTreeInput::::new(); + let base_column = vec![M31::from_u32_unchecked(0); 1 << (TREE_HEIGHT)]; + let injected_column = vec![M31::from_u32_unchecked(1); 1 << (INJECT_DEPTH - 1)]; + input.insert_column(TREE_HEIGHT + 1, &base_column); + input.insert_column(INJECT_DEPTH, &injected_column); + + let config = super::MixedDegreeMerkleTreeConfig { + multi_layer_sizes: vec![5, 2, 2], + }; + let (_, expected) = MixedDegreeMerkleTree::::commit_default(&input); + + let (_, root) = MixedDegreeMerkleTree::::commit(&input, config); + + assert_eq!(root, expected); + } + #[test] fn get_hash_at_test() { const TREE_HEIGHT: usize = 3; let mut input = super::MerkleTreeInput::::new(); let base_column = (0..4).map(M31::from_u32_unchecked).collect::>(); input.insert_column(TREE_HEIGHT, &base_column); - let mut tree = MixedDegreeMerkleTree::::new( - input, - MixedDegreeMerkleTreeConfig { - multi_layer_sizes: [2, 1].to_vec(), - }, - ); - let root = tree.commit(); + + let (tree, root) = MixedDegreeMerkleTree::::commit_default(&input); assert_eq!(root, tree.get_hash_at(0, 0)); let mut hasher = Blake3Hasher::new(); @@ -465,12 +510,7 @@ mod tests { let mut input = super::MerkleTreeInput::::new(); let base_column = (0..4).map(M31::from_u32_unchecked).collect::>(); input.insert_column(TREE_HEIGHT, &base_column); - let tree = MixedDegreeMerkleTree::::new( - input, - MixedDegreeMerkleTreeConfig { - multi_layer_sizes: [2, 1].to_vec(), - }, - ); + let (tree, _) = MixedDegreeMerkleTree::::commit_default(&input); tree.get_hash_at(4, 0); } @@ -488,7 +528,7 @@ mod tests { .collect::>(); super::queried_nodes_in_layer( column_queries_at_depth.iter(), - &input.configuration(), + &input.column_layout(), i, ) }) @@ -544,12 +584,8 @@ mod tests { merkle_input.insert_column(4, &col_length_8); merkle_input.insert_column(3, &col_length_8); merkle_input.insert_column(3, &col_length_4); - let tree = MixedDegreeMerkleTree::::new( - merkle_input, - MixedDegreeMerkleTreeConfig { - multi_layer_sizes: [4].to_vec(), - }, - ); + let (tree, _root) = + MixedDegreeMerkleTree::::commit_default(&merkle_input); let zero_column_queries = vec![0, 15]; let first_column_queries = vec![0, 7]; @@ -562,20 +598,22 @@ mod tests { third_column_queries, ]; - let node_indices = - queried_nodes_in_layer(queries.iter().take(2), &tree.input.configuration(), 4); - let w4 = tree.layer_felt_witnesses_and_queried_elements( - 4, - queries[..2].iter(), - node_indices.iter().copied(), - ); - let node_indices = - queried_nodes_in_layer(queries.iter().skip(2), &tree.input.configuration(), 3); - let w3 = tree.layer_felt_witnesses_and_queried_elements( - 4, - queries[2..4].iter(), - node_indices.iter().copied(), - ); + let node_indices = queried_nodes_in_layer(queries.iter().take(2), &tree.column_layout, 4); + let w4 = + MixedDegreeMerkleTree::::layer_felt_witnesses_and_queried_elements( + &merkle_input, + 4, + queries[..2].iter(), + node_indices.iter().copied(), + ); + let node_indices = queried_nodes_in_layer(queries.iter().skip(2), &tree.column_layout, 3); + let w3 = + MixedDegreeMerkleTree::::layer_felt_witnesses_and_queried_elements( + &merkle_input, + 4, + queries[2..4].iter(), + node_indices.iter().copied(), + ); assert_eq!( format!("{:?}", w4), @@ -603,14 +641,8 @@ mod tests { input.insert_column(TREE_HEIGHT - 6, &column_2); input.insert_column(TREE_HEIGHT - 4, &column_1); input.insert_column(TREE_HEIGHT, &column_3); - let configuration = input.configuration(); - let mut tree = MixedDegreeMerkleTree::::new( - input, - MixedDegreeMerkleTreeConfig { - multi_layer_sizes: vec![8], - }, - ); - let commitment = tree.commit(); + let configuration = input.column_layout(); + let (tree, commitment) = MixedDegreeMerkleTree::::commit_default(&input); let queries: Vec> = vec![ vec![2], vec![0], @@ -621,7 +653,7 @@ mod tests { vec![0, 1, 1000, 4095], ]; - let test_decommitment = tree.decommit(&queries); + let test_decommitment = tree.decommit(&input, &queries); assert!(test_decommitment.verify( commitment, &configuration,