diff --git a/src/core/commitment_scheme/mod.rs b/src/core/commitment_scheme/mod.rs index d4c39ad5f..093dcef0f 100644 --- a/src/core/commitment_scheme/mod.rs +++ b/src/core/commitment_scheme/mod.rs @@ -6,374 +6,11 @@ //! the existence of such polynomials, and are ok with having a small decoding list. //! Note: Opened points cannot come from the commitment domain. +mod prover; pub mod quotients; pub mod utils; +mod verifier; -use std::iter::zip; -use std::ops::Deref; - -use itertools::Itertools; - +pub use self::prover::{CommitmentSchemeProof, CommitmentSchemeProver}; pub use self::utils::TreeVec; -use super::backend::cpu::{CPUCircleEvaluation, CPUCirclePoly}; -use super::backend::CPUBackend; -use super::channel::Blake2sChannel; -use super::circle::CirclePoint; -use super::fields::m31::BaseField; -use super::fields::qm31::SecureField; -use super::fri::{ - CirclePolyDegreeBound, FriConfig, FriProof, FriProver, FriVerifier, SparseCircleEvaluation, -}; -use super::oods::get_pair_oods_quotient; -use super::poly::circle::{CanonicCoset, CircleDomain, CircleEvaluation}; -use super::poly::BitReversedOrder; -use super::proof_of_work::{ProofOfWork, ProofOfWorkProof}; -use super::prover::{ - VerificationError, LOG_BLOWUP_FACTOR, LOG_LAST_LAYER_DEGREE_BOUND, N_QUERIES, - PROOF_OF_WORK_BITS, -}; -use super::queries::SparseSubCircleDomain; -use super::ColumnVec; -use crate::commitment_scheme::blake2_hash::{Blake2sHash, Blake2sHasher}; -use crate::commitment_scheme::merkle_decommitment::MerkleDecommitment; -use crate::commitment_scheme::merkle_tree::MerkleTree; -use crate::core::channel::Channel; - -type MerkleHasher = Blake2sHasher; -type ProofChannel = Blake2sChannel; - -/// The prover side of a FRI polynomial commitment scheme. See [self]. -pub struct CommitmentSchemeProver { - pub trees: TreeVec, - pub log_blowup_factor: u32, -} - -impl CommitmentSchemeProver { - pub fn new(log_blowup_factor: u32) -> Self { - CommitmentSchemeProver { - trees: TreeVec::::default(), - log_blowup_factor, - } - } - - pub fn commit(&mut self, polynomials: ColumnVec, channel: &mut ProofChannel) { - let tree = CommitmentTreeProver::new(polynomials, self.log_blowup_factor, channel); - self.trees.push(tree); - } - - pub fn roots(&self) -> TreeVec { - self.trees.as_ref().map(|tree| tree.root()) - } - - pub fn polynomials(&self) -> TreeVec> { - self.trees - .as_ref() - .map(|tree| tree.polynomials.iter().collect()) - } - - fn evaluations(&self) -> TreeVec>> { - self.trees - .as_ref() - .map(|tree| tree.evaluations.iter().collect()) - } - - pub fn prove_values( - &self, - prove_points: TreeVec>>>, - channel: &mut ProofChannel, - ) -> CommitmentSchemeProof { - // Evaluate polynomials on open points. - let proved_values = - self.polynomials() - .zip_cols(&prove_points) - .map_cols(|(poly, points)| { - points - .iter() - .map(|point| poly.eval_at_point(*point)) - .collect_vec() - }); - channel.mix_felts(&proved_values.clone().flatten_cols()); - - // Compute oods quotients for boundary constraints on prove_points. - let quotients = self - .evaluations() - .zip_cols(&proved_values) - .zip_cols(&prove_points) - .map_cols(|((evaluation, values), points)| { - zip(points, values) - .map(|(&point, &value)| { - get_pair_oods_quotient(point, value, evaluation).bit_reverse() - }) - .collect_vec() - }); - - // Run FRI commitment phase on the oods quotients. - let fri_config = FriConfig::new(LOG_LAST_LAYER_DEGREE_BOUND, LOG_BLOWUP_FACTOR, N_QUERIES); - // TODO(spapini): Remove rev() when we start accumulating by size. - // This is only done because fri demands descending sizes. - let fri_prover = FriProver::::commit( - channel, - fri_config, - "ients.flatten_cols_rev(), - ); - - // Proof of work. - let proof_of_work = ProofOfWork::new(PROOF_OF_WORK_BITS).prove(channel); - - // FRI decommitment phase. - let (fri_proof, fri_query_domains) = fri_prover.decommit(channel); - - // Decommit the FRI queries on the merkle trees. - let decommitment_results = self.trees.as_ref().map(|tree| { - tree.decommit( - fri_query_domains[&(tree.polynomials[0].log_size() + self.log_blowup_factor)] - .flatten(), - ) - }); - let queried_values = decommitment_results.as_ref().map(|(v, _)| v.clone()); - let decommitments = decommitment_results.map(|(_, d)| d); - - CommitmentSchemeProof { - proved_values, - decommitments, - queried_values, - proof_of_work, - fri_proof, - } - } -} - -#[derive(Debug)] -pub struct CommitmentSchemeProof { - pub proved_values: TreeVec>>, - pub decommitments: TreeVec>, - pub queried_values: TreeVec>>, - pub proof_of_work: ProofOfWorkProof, - pub fri_proof: FriProof, -} - -/// Prover data for a single commitment tree in a commitment scheme. The commitment scheme allows to -/// commit on a set of polynomials at a time. This corresponds to such a set. -pub struct CommitmentTreeProver { - pub polynomials: ColumnVec, - pub evaluations: ColumnVec>, - // TODO(AlonH): Change to mixed degree merkle and remove values clone. - commitment: MerkleTree, -} - -impl CommitmentTreeProver { - fn new( - polynomials: ColumnVec, - log_blowup_factor: u32, - channel: &mut ProofChannel, - ) -> Self { - let evaluations = polynomials - .iter() - .map(|poly| { - poly.evaluate( - CanonicCoset::new(poly.log_size() + log_blowup_factor).circle_domain(), - ) - }) - .collect_vec(); - let commitment = MerkleTree::::commit( - evaluations - .iter() - .map(|eval| eval.values.clone()) - .collect_vec(), - ); - channel.mix_digest(commitment.root()); - - CommitmentTreeProver { - polynomials, - evaluations, - commitment, - } - } - - // TODO(AlonH): change interface after integrating mixed degree merkle. - /// Decommits the merkle tree on the given query positions. - fn decommit( - &self, - queries: Vec, - ) -> ( - ColumnVec>, - MerkleDecommitment, - ) { - let values = self - .evaluations - .iter() - .map(|c| queries.iter().map(|p| c[*p]).collect()) - .collect(); - let decommitment = self.commitment.generate_decommitment(queries); - (values, decommitment) - } -} - -impl Deref for CommitmentTreeProver { - type Target = MerkleTree; - - fn deref(&self) -> &Self::Target { - &self.commitment - } -} - -/// The verifier side of a FRI polynomial commitment scheme. See [self]. -#[derive(Default)] -pub struct CommitmentSchemeVerifier { - pub trees: TreeVec, -} - -impl CommitmentSchemeVerifier { - pub fn new() -> Self { - Self::default() - } - - /// A [TreeVec] of the log sizes of each column in each commitment tree. - fn column_log_sizes(&self) -> TreeVec> { - self.trees.as_ref().map(|tree| tree.log_sizes.to_vec()) - } - - /// Reads a commitment from the prover. - pub fn commit( - &mut self, - commitment: Blake2sHash, - log_sizes: Vec, - channel: &mut ProofChannel, - ) { - let verifier = CommitmentTreeVerifier::new(commitment, log_sizes, channel); - self.trees.push(verifier); - } - - pub fn verify_values( - &self, - prove_points: TreeVec>>>, - proof: CommitmentSchemeProof, - channel: &mut ProofChannel, - ) -> Result<(), VerificationError> { - channel.mix_felts(&proof.proved_values.clone().flatten_cols()); - - // Compute degree bounds for OODS quotients without looking at the proof. - let bounds = self - .column_log_sizes() - .zip_cols(&prove_points) - .map_cols(|(log_size, prove_points)| { - vec![CirclePolyDegreeBound::new(log_size); prove_points.len()] - }) - .flatten_cols_rev(); - - // FRI commitment phase on OODS quotients. - let fri_config = FriConfig::new(LOG_LAST_LAYER_DEGREE_BOUND, LOG_BLOWUP_FACTOR, N_QUERIES); - let mut fri_verifier = - FriVerifier::commit(channel, fri_config, proof.fri_proof, bounds).unwrap(); - - // Verify proof of work. - ProofOfWork::new(PROOF_OF_WORK_BITS).verify(channel, &proof.proof_of_work)?; - - // Get FRI query domains. - let fri_query_domains = fri_verifier.column_opening_positions(channel); - - // Verify merkle decommitments. - if !self - .trees - .as_ref() - .zip(&proof.decommitments) - .map(|(tree, decommitment)| { - // TODO(spapini): Also very proved_values here. - tree.verify( - decommitment, - &fri_query_domains[&(tree.log_sizes[0] + LOG_BLOWUP_FACTOR)].flatten(), - ) - }) - .iter() - .all(|x| *x) - { - return Err(VerificationError::MerkleVerificationFailed); - } - - // Answer FRI queries. - let mut fri_answers = self - .column_log_sizes() - .zip_cols(proof.proved_values) - .zip_cols(prove_points) - .zip_cols(proof.queried_values) - .map_cols( - // For each column. - |(((log_size, proved_values), opened_points), queried_values)| { - zip(opened_points, proved_values) - .map(|(point, value)| { - // For each opening point of that column. - eval_quotients_on_sparse_domain( - queried_values.clone(), - &fri_query_domains[&(log_size + LOG_BLOWUP_FACTOR)], - CanonicCoset::new(log_size + LOG_BLOWUP_FACTOR).circle_domain(), - point, - value, - ) - }) - .collect_vec() - }, - ) - .flatten_cols() - .into_iter() - .collect::, _>>()?; - - // TODO(spapini): Remove reverse. - fri_answers.reverse(); - fri_verifier.decommit(fri_answers)?; - Ok(()) - } -} - -/// Evaluates the oods quotients on the sparse domain. -fn eval_quotients_on_sparse_domain( - queried_values: Vec, - query_domains: &SparseSubCircleDomain, - commitment_domain: CircleDomain, - point: CirclePoint, - value: SecureField, -) -> Result, VerificationError> { - let queried_values = &mut queried_values.into_iter(); - let res = SparseCircleEvaluation::new( - query_domains - .iter() - .map(|subdomain| { - let values = queried_values.take(1 << subdomain.log_size).collect_vec(); - if values.len() != 1 << subdomain.log_size { - return Err(VerificationError::InvalidStructure); - } - let subeval = - CircleEvaluation::new(subdomain.to_circle_domain(&commitment_domain), values); - Ok(get_pair_oods_quotient(point, value, &subeval).bit_reverse()) - }) - .collect::>()?, - ); - assert!( - queried_values.is_empty(), - "Not all queried values were used" - ); - Ok(res) -} - -/// Verifier data for a single commitment tree in a commitment scheme. -pub struct CommitmentTreeVerifier { - pub commitment: Blake2sHash, - pub log_sizes: Vec, -} - -impl CommitmentTreeVerifier { - pub fn new(commitment: Blake2sHash, log_sizes: Vec, channel: &mut ProofChannel) -> Self { - channel.mix_digest(commitment); - CommitmentTreeVerifier { - commitment, - log_sizes, - } - } - - pub fn verify( - &self, - decommitment: &MerkleDecommitment, - positions: &[usize], - ) -> bool { - decommitment.verify(self.commitment, positions) - } -} +pub use self::verifier::{CommitmentSchemeVerifier, CommitmentTreeVerifier}; diff --git a/src/core/commitment_scheme/prover.rs b/src/core/commitment_scheme/prover.rs new file mode 100644 index 000000000..5961ce28a --- /dev/null +++ b/src/core/commitment_scheme/prover.rs @@ -0,0 +1,210 @@ +//! Implements a FRI polynomial commitment scheme. +//! This is a protocol where the prover can commit on a set of polynomials and then prove their +//! opening on a set of points. +//! Note: This implementation is not really a polynomial commitment scheme, because we are not in +//! the unique decoding regime. This is enough for a STARK proof though, where we onyl want to imply +//! the existence of such polynomials, and re ok with having a small decoding list. + +use std::iter::zip; +use std::ops::Deref; + +use itertools::Itertools; + +use super::super::backend::cpu::{CPUCircleEvaluation, CPUCirclePoly}; +use super::super::backend::CPUBackend; +use super::super::channel::Blake2sChannel; +use super::super::circle::CirclePoint; +use super::super::fields::m31::BaseField; +use super::super::fields::qm31::SecureField; +use super::super::fri::{FriConfig, FriProof, FriProver}; +use super::super::oods::get_pair_oods_quotient; +use super::super::poly::circle::CanonicCoset; +use super::super::poly::BitReversedOrder; +use super::super::proof_of_work::{ProofOfWork, ProofOfWorkProof}; +use super::super::prover::{ + LOG_BLOWUP_FACTOR, LOG_LAST_LAYER_DEGREE_BOUND, N_QUERIES, PROOF_OF_WORK_BITS, +}; +use super::super::ColumnVec; +use super::utils::TreeVec; +use crate::commitment_scheme::blake2_hash::{Blake2sHash, Blake2sHasher}; +use crate::commitment_scheme::merkle_decommitment::MerkleDecommitment; +use crate::commitment_scheme::merkle_tree::MerkleTree; +use crate::core::channel::Channel; + +type MerkleHasher = Blake2sHasher; +type ProofChannel = Blake2sChannel; + +/// The prover side of a FRI polynomial commitment scheme. See [self]. +pub struct CommitmentSchemeProver { + pub trees: TreeVec, + pub log_blowup_factor: u32, +} + +impl CommitmentSchemeProver { + pub fn new(log_blowup_factor: u32) -> Self { + CommitmentSchemeProver { + trees: TreeVec::::default(), + log_blowup_factor, + } + } + + pub fn commit(&mut self, polynomials: ColumnVec, channel: &mut ProofChannel) { + let tree = CommitmentTreeProver::new(polynomials, self.log_blowup_factor, channel); + self.trees.push(tree); + } + + pub fn roots(&self) -> TreeVec { + self.trees.as_ref().map(|tree| tree.root()) + } + + pub fn polynomials(&self) -> TreeVec> { + self.trees + .as_ref() + .map(|tree| tree.polynomials.iter().collect()) + } + + fn evaluations(&self) -> TreeVec>> { + self.trees + .as_ref() + .map(|tree| tree.evaluations.iter().collect()) + } + + pub fn prove_values( + &self, + prove_points: TreeVec>>>, + channel: &mut ProofChannel, + ) -> CommitmentSchemeProof { + // Evaluate polynomials on open points. + let proved_values = + self.polynomials() + .zip_cols(&prove_points) + .map_cols(|(poly, points)| { + points + .iter() + .map(|point| poly.eval_at_point(*point)) + .collect_vec() + }); + channel.mix_felts(&proved_values.clone().flatten_cols()); + + // Compute oods quotients for boundary constraints on prove_points. + let quotients = self + .evaluations() + .zip_cols(&proved_values) + .zip_cols(&prove_points) + .map_cols(|((evaluation, values), points)| { + zip(points, values) + .map(|(&point, &value)| { + get_pair_oods_quotient(point, value, evaluation).bit_reverse() + }) + .collect_vec() + }); + + // Run FRI commitment phase on the oods quotients. + let fri_config = FriConfig::new(LOG_LAST_LAYER_DEGREE_BOUND, LOG_BLOWUP_FACTOR, N_QUERIES); + // TODO(spapini): Remove rev() when we start accumulating by size. + // This is only done because fri demands descending sizes. + let fri_prover = FriProver::::commit( + channel, + fri_config, + "ients.flatten_cols_rev(), + ); + + // Proof of work. + let proof_of_work = ProofOfWork::new(PROOF_OF_WORK_BITS).prove(channel); + + // FRI decommitment phase. + let (fri_proof, fri_query_domains) = fri_prover.decommit(channel); + + // Decommit the FRI queries on the merkle trees. + let decommitment_results = self.trees.as_ref().map(|tree| { + tree.decommit( + fri_query_domains[&(tree.polynomials[0].log_size() + self.log_blowup_factor)] + .flatten(), + ) + }); + let queried_values = decommitment_results.as_ref().map(|(v, _)| v.clone()); + let decommitments = decommitment_results.map(|(_, d)| d); + + CommitmentSchemeProof { + proved_values, + decommitments, + queried_values, + proof_of_work, + fri_proof, + } + } +} + +#[derive(Debug)] +pub struct CommitmentSchemeProof { + pub proved_values: TreeVec>>, + pub decommitments: TreeVec>, + pub queried_values: TreeVec>>, + pub proof_of_work: ProofOfWorkProof, + pub fri_proof: FriProof, +} + +/// Prover data for a single commitment tree in a commitment scheme. The commitment scheme allows to +/// commit on a set of polynomials at a time. This corresponds to such a set. +pub struct CommitmentTreeProver { + pub polynomials: ColumnVec, + pub evaluations: ColumnVec>, + // TODO(AlonH): Change to mixed degree merkle and remove values clone. + commitment: MerkleTree, +} + +impl CommitmentTreeProver { + fn new( + polynomials: ColumnVec, + log_blowup_factor: u32, + channel: &mut ProofChannel, + ) -> Self { + let evaluations = polynomials + .iter() + .map(|poly| { + poly.evaluate( + CanonicCoset::new(poly.log_size() + log_blowup_factor).circle_domain(), + ) + }) + .collect_vec(); + let commitment = MerkleTree::::commit( + evaluations + .iter() + .map(|eval| eval.values.clone()) + .collect_vec(), + ); + channel.mix_digest(commitment.root()); + + CommitmentTreeProver { + polynomials, + evaluations, + commitment, + } + } + + // TODO(AlonH): change interface after integrating mixed degree merkle. + /// Decommits the merkle tree on the given query positions. + fn decommit( + &self, + queries: Vec, + ) -> ( + ColumnVec>, + MerkleDecommitment, + ) { + let values = self + .evaluations + .iter() + .map(|c| queries.iter().map(|p| c[*p]).collect()) + .collect(); + let decommitment = self.commitment.generate_decommitment(queries); + (values, decommitment) + } +} + +impl Deref for CommitmentTreeProver { + type Target = MerkleTree; + + fn deref(&self) -> &Self::Target { + &self.commitment + } +} diff --git a/src/core/commitment_scheme/verifier.rs b/src/core/commitment_scheme/verifier.rs new file mode 100644 index 000000000..3af6b6957 --- /dev/null +++ b/src/core/commitment_scheme/verifier.rs @@ -0,0 +1,187 @@ +use std::iter::zip; + +use itertools::Itertools; + +use super::super::channel::Blake2sChannel; +use super::super::circle::CirclePoint; +use super::super::fields::m31::BaseField; +use super::super::fields::qm31::SecureField; +use super::super::fri::{CirclePolyDegreeBound, FriConfig, FriVerifier, SparseCircleEvaluation}; +use super::super::oods::get_pair_oods_quotient; +use super::super::poly::circle::{CanonicCoset, CircleDomain, CircleEvaluation}; +use super::super::proof_of_work::ProofOfWork; +use super::super::prover::{ + LOG_BLOWUP_FACTOR, LOG_LAST_LAYER_DEGREE_BOUND, N_QUERIES, PROOF_OF_WORK_BITS, +}; +use super::super::queries::SparseSubCircleDomain; +use super::utils::TreeVec; +use super::CommitmentSchemeProof; +use crate::commitment_scheme::blake2_hash::{Blake2sHash, Blake2sHasher}; +use crate::commitment_scheme::merkle_decommitment::MerkleDecommitment; +use crate::core::channel::Channel; +use crate::core::prover::VerificationError; +use crate::core::ColumnVec; + +type MerkleHasher = Blake2sHasher; +type ProofChannel = Blake2sChannel; + +/// The verifier side of a FRI polynomial commitment scheme. See [self]. +#[derive(Default)] +pub struct CommitmentSchemeVerifier { + pub trees: TreeVec, +} + +impl CommitmentSchemeVerifier { + pub fn new() -> Self { + Self::default() + } + + /// A [TreeVec] of the log sizes of each column in each commitment tree. + fn column_log_sizes(&self) -> TreeVec> { + self.trees.as_ref().map(|tree| tree.log_sizes.to_vec()) + } + + /// Reads a commitment from the prover. + pub fn commit( + &mut self, + commitment: Blake2sHash, + log_sizes: Vec, + channel: &mut ProofChannel, + ) { + let verifier = CommitmentTreeVerifier::new(commitment, log_sizes, channel); + self.trees.push(verifier); + } + + pub fn verify_values( + &self, + prove_points: TreeVec>>>, + proof: CommitmentSchemeProof, + channel: &mut ProofChannel, + ) -> Result<(), VerificationError> { + channel.mix_felts(&proof.proved_values.clone().flatten_cols()); + + // Compute degree bounds for OODS quotients without looking at the proof. + let bounds = self + .column_log_sizes() + .zip_cols(&prove_points) + .map_cols(|(log_size, prove_points)| { + vec![CirclePolyDegreeBound::new(log_size); prove_points.len()] + }) + .flatten_cols_rev(); + + // FRI commitment phase on OODS quotients. + let fri_config = FriConfig::new(LOG_LAST_LAYER_DEGREE_BOUND, LOG_BLOWUP_FACTOR, N_QUERIES); + let mut fri_verifier = + FriVerifier::commit(channel, fri_config, proof.fri_proof, bounds).unwrap(); + + // Verify proof of work. + ProofOfWork::new(PROOF_OF_WORK_BITS).verify(channel, &proof.proof_of_work)?; + + // Get FRI query domains. + let fri_query_domains = fri_verifier.column_opening_positions(channel); + + // Verify merkle decommitments. + if !self + .trees + .as_ref() + .zip(&proof.decommitments) + .map(|(tree, decommitment)| { + // TODO(spapini): Also very proved_values here. + tree.verify( + decommitment, + &fri_query_domains[&(tree.log_sizes[0] + LOG_BLOWUP_FACTOR)].flatten(), + ) + }) + .iter() + .all(|x| *x) + { + return Err(VerificationError::MerkleVerificationFailed); + } + + // Answer FRI queries. + let mut fri_answers = self + .column_log_sizes() + .zip_cols(proof.proved_values) + .zip_cols(prove_points) + .zip_cols(proof.queried_values) + .map_cols( + // For each column. + |(((log_size, proved_values), opened_points), queried_values)| { + zip(opened_points, proved_values) + .map(|(point, value)| { + // For each opening point of that column. + eval_quotients_on_sparse_domain( + queried_values.clone(), + &fri_query_domains[&(log_size + LOG_BLOWUP_FACTOR)], + CanonicCoset::new(log_size + LOG_BLOWUP_FACTOR).circle_domain(), + point, + value, + ) + }) + .collect_vec() + }, + ) + .flatten_cols() + .into_iter() + .collect::, _>>()?; + + // TODO(spapini): Remove reverse. + fri_answers.reverse(); + fri_verifier.decommit(fri_answers)?; + Ok(()) + } +} + +/// Evaluates the oods quotients on the sparse domain. +fn eval_quotients_on_sparse_domain( + queried_values: Vec, + query_domains: &SparseSubCircleDomain, + commitment_domain: CircleDomain, + point: CirclePoint, + value: SecureField, +) -> Result, VerificationError> { + let queried_values = &mut queried_values.into_iter(); + let res = SparseCircleEvaluation::new( + query_domains + .iter() + .map(|subdomain| { + let values = queried_values.take(1 << subdomain.log_size).collect_vec(); + if values.len() != 1 << subdomain.log_size { + return Err(VerificationError::InvalidStructure); + } + let subeval = + CircleEvaluation::new(subdomain.to_circle_domain(&commitment_domain), values); + Ok(get_pair_oods_quotient(point, value, &subeval).bit_reverse()) + }) + .collect::>()?, + ); + assert!( + queried_values.is_empty(), + "Not all queried values were used" + ); + Ok(res) +} + +/// Verifier data for a single commitment tree in a commitment scheme. +pub struct CommitmentTreeVerifier { + pub commitment: Blake2sHash, + pub log_sizes: Vec, +} + +impl CommitmentTreeVerifier { + pub fn new(commitment: Blake2sHash, log_sizes: Vec, channel: &mut ProofChannel) -> Self { + channel.mix_digest(commitment); + CommitmentTreeVerifier { + commitment, + log_sizes, + } + } + + pub fn verify( + &self, + decommitment: &MerkleDecommitment, + positions: &[usize], + ) -> bool { + decommitment.verify(self.commitment, positions) + } +} diff --git a/src/core/prover/mod.rs b/src/core/prover/mod.rs index 92760c090..d8ace6156 100644 --- a/src/core/prover/mod.rs +++ b/src/core/prover/mod.rs @@ -219,7 +219,7 @@ pub enum VerificationError { mod tests { use num_traits::Zero; - use crate::core::air::evaluation::{DomainEvaluationAccumulator, PointEvaluationAccumulator}; + use crate::core::air::accumulation::{DomainEvaluationAccumulator, PointEvaluationAccumulator}; use crate::core::air::{Air, Component, ComponentTrace, Mask}; use crate::core::backend::cpu::CPUCircleEvaluation; use crate::core::backend::CPUBackend;