From b8fa1923a530a7eb59b4695387230ef2132950e9 Mon Sep 17 00:00:00 2001 From: Alon Haramati Date: Wed, 21 Feb 2024 14:45:00 +0200 Subject: [PATCH] Create MaskEvaluator. --- src/core/air/evaluation.rs | 10 ++++--- src/core/air/mod.rs | 55 +++++++++++++++++++++++++++++++++++++- src/core/mod.rs | 2 ++ src/fibonacci/mod.rs | 13 +++++---- 4 files changed, 68 insertions(+), 12 deletions(-) diff --git a/src/core/air/evaluation.rs b/src/core/air/evaluation.rs index 83e07f05a..aecf8a1c6 100644 --- a/src/core/air/evaluation.rs +++ b/src/core/air/evaluation.rs @@ -165,18 +165,18 @@ impl<'a> ColumnAccumulator<'a, CPUBackend> { /// Evaluates components' constraint polynomials and aggregates them into a composition polynomial. pub struct ConstraintEvaluator<'a, B: Backend> { - traces: slice::Iter<'a, ComponentTrace<'a, B>>, + component_traces: slice::Iter<'a, ComponentTrace<'a, B>>, evaluation_accumulator: DomainEvaluationAccumulator, } impl<'a> ConstraintEvaluator<'a, CPUBackend> { pub fn new( - traces: &'a [ComponentTrace<'a, CPUBackend>], + component_traces: &'a [ComponentTrace<'a, CPUBackend>], max_log_size: u32, random_coeff: SecureField, ) -> Self { Self { - traces: traces.iter(), + component_traces: component_traces.iter(), evaluation_accumulator: DomainEvaluationAccumulator::new(random_coeff, max_log_size), } } @@ -189,7 +189,9 @@ impl<'a> ConstraintEvaluator<'a, CPUBackend> { impl<'a, B: Backend> ComponentVisitor for ConstraintEvaluator<'a, B> { fn visit>(&mut self, component: &C) { component.evaluate_constraint_quotients_on_domain( - self.traces.next().expect("no more component traces"), + self.component_traces + .next() + .expect("no more component traces"), &mut self.evaluation_accumulator, ) } diff --git a/src/core/air/mod.rs b/src/core/air/mod.rs index bc36b0599..246e8d54a 100644 --- a/src/core/air/mod.rs +++ b/src/core/air/mod.rs @@ -1,3 +1,4 @@ +use core::slice; use std::iter::zip; use std::ops::Deref; @@ -9,7 +10,7 @@ use super::circle::CirclePoint; use super::fields::m31::BaseField; use super::fields::qm31::SecureField; use super::poly::circle::{CanonicCoset, CirclePoly}; -use super::ColumnVec; +use super::{ColumnVec, ComponentVec}; pub mod evaluation; @@ -43,6 +44,19 @@ pub trait AirExt: Air { self.visit_components(&mut evaluator); evaluator.finalize() } + + fn mask_points_and_values( + &self, + point: CirclePoint, + component_traces: &[ComponentTrace<'_, CPUBackend>], + ) -> ( + ComponentVec>>, + ComponentVec>, + ) { + let mut visitor = MaskEvaluator::new(point, component_traces); + self.visit_components(&mut visitor); + visitor.finalize() + } } impl> AirExt for A {} @@ -69,6 +83,45 @@ impl ComponentVisitor for MaxConstraintLogDegreeBoundVisitor { } } +struct MaskEvaluator<'a, B: Backend> { + point: CirclePoint, + component_traces: slice::Iter<'a, ComponentTrace<'a, B>>, + component_points: ComponentVec>>, + component_values: ComponentVec>, +} + +impl<'a, B: Backend> MaskEvaluator<'a, B> { + pub fn new( + point: CirclePoint, + component_traces: &'a [ComponentTrace<'a, B>], + ) -> Self { + Self { + point, + component_traces: component_traces.iter(), + component_points: Vec::new(), + component_values: Vec::new(), + } + } + + pub fn finalize( + self, + ) -> ( + ComponentVec>>, + ComponentVec>, + ) { + (self.component_points, self.component_values) + } +} + +impl<'a, B: Backend> ComponentVisitor for MaskEvaluator<'a, B> { + fn visit>(&mut self, component: &C) { + let trace = self.component_traces.next().unwrap(); + let (points, values) = component.mask_points_and_values(self.point, trace); + self.component_points.push(points); + self.component_values.push(values); + } +} + /// Holds the mask offsets at each column. /// Holds a vector with an entry for each column. Each entry holds the offsets /// of the mask at that column. diff --git a/src/core/mod.rs b/src/core/mod.rs index 9c6784fe1..ad319ca42 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -15,3 +15,5 @@ pub mod utils; /// A vector in which each element relates (by index) to a column in the trace. pub type ColumnVec = Vec; +/// A vector of [ColumnVec]s. Each [ColumnVec] relates (by index) to a component in the air. +pub type ComponentVec = Vec>; diff --git a/src/fibonacci/mod.rs b/src/fibonacci/mod.rs index cb48e0317..7044f314e 100644 --- a/src/fibonacci/mod.rs +++ b/src/fibonacci/mod.rs @@ -23,7 +23,7 @@ use crate::core::oods::{get_oods_quotient, get_pair_oods_quotient, quotient_log_ use crate::core::poly::circle::{CanonicCoset, CircleEvaluation}; use crate::core::poly::BitReversedOrder; use crate::core::proof_of_work::{ProofOfWork, ProofOfWorkProof}; -use crate::core::ColumnVec; +use crate::core::ComponentVec; type Channel = Blake2sChannel; type MerkleHasher = Blake2sHasher; @@ -57,7 +57,7 @@ pub struct FibonacciProof { pub trace_decommitments: Vec>, pub composition_polynomial_commitment: ::Hash, pub composition_polynomial_decommitment: MerkleDecommitment, - pub trace_oods_values: ColumnVec>, + pub trace_oods_values: ComponentVec>, pub composition_polynomial_opened_values: Vec, pub trace_opened_values: Vec, pub proof_of_work: ProofOfWorkProof, @@ -128,8 +128,7 @@ impl Fibonacci { let oods_point = CirclePoint::::get_random_point(channel); let (trace_oods_points, trace_oods_values) = self .air - .component - .mask_points_and_values(oods_point, &component_traces[0]); + .mask_points_and_values(oods_point, &component_traces); let composition_polynomial_oods_value = composition_polynomial_commitment_scheme.polynomials[0].eval_at_point(oods_point); @@ -144,7 +143,7 @@ impl Fibonacci { ) .bit_reverse(), ); - for (point, value) in zip(&trace_oods_points[0], &trace_oods_values[0]) { + for (point, value) in zip(&trace_oods_points[0][0], &trace_oods_values[0][0]) { oods_quotients.push( get_pair_oods_quotient(*point, *value, &trace_commitment_scheme.evaluations[0]) .bit_reverse(), @@ -217,7 +216,7 @@ pub fn verify_proof(proof: FibonacciProof) -> bool { PointEvaluationAccumulator::new(random_coeff, fib.air.max_constraint_log_degree_bound()); fib.air.component.evaluate_quotients_by_mask( oods_point, - &proof.trace_oods_values[0], + &proof.trace_oods_values[0][0], &mut evaluation_accumulator, ); let composition_polynomial_oods_value = evaluation_accumulator.finalize(); @@ -268,7 +267,7 @@ pub fn verify_proof(proof: FibonacciProof) -> bool { } assert!(opened_values.next().is_none(), "Not all values were used."); sparse_circle_evaluations.push(SparseCircleEvaluation::new(evaluation)); - for (oods_point, oods_value) in zip(&trace_oods_points[0], &proof.trace_oods_values[0]) { + for (oods_point, oods_value) in zip(&trace_oods_points[0], &proof.trace_oods_values[0][0]) { let mut evaluation = Vec::with_capacity(trace_opening_positions.len()); let mut opened_values = proof.trace_opened_values.iter().copied(); for sub_circle_domain in trace_opening_positions.iter() {