From 8893fc7f3ab2125e3ba2e5115a9757731be75914 Mon Sep 17 00:00:00 2001 From: Alon Haramati Date: Mon, 26 Feb 2024 10:08:54 +0200 Subject: [PATCH] Create QuotientLogBoundsVisitor. --- src/core/air/evaluation.rs | 3 ++- src/core/air/mod.rs | 48 ++++++++++++++++++++++++++++++++++++++ src/core/oods.rs | 19 --------------- src/fibonacci/mod.rs | 12 +++------- 4 files changed, 53 insertions(+), 29 deletions(-) diff --git a/src/core/air/evaluation.rs b/src/core/air/evaluation.rs index 91239d007..bb4622b9e 100644 --- a/src/core/air/evaluation.rs +++ b/src/core/air/evaluation.rs @@ -238,7 +238,8 @@ impl<'a, B: Backend> ComponentVisitor for ConstraintEvaluator<'a, B> { } } -/// Evaluates components' constraint polynomials and aggregates them into a composition polynomial. +/// Evaluates components' constraint polynomials at a single point and aggregates them into a +/// composition polynomial value. pub struct ConstraintPointEvaluator<'a> { point: CirclePoint, mask_values: slice::Iter<'a, ColumnVec>>, diff --git a/src/core/air/mod.rs b/src/core/air/mod.rs index 00c8e6c2b..2bc1a765c 100644 --- a/src/core/air/mod.rs +++ b/src/core/air/mod.rs @@ -1,4 +1,5 @@ use core::slice; +use std::collections::BTreeMap; use std::iter::zip; use std::ops::Deref; @@ -12,6 +13,7 @@ use super::backend::{Backend, CPUBackend}; use super::circle::CirclePoint; use super::fields::m31::BaseField; use super::fields::qm31::SecureField; +use super::fri::CirclePolyDegreeBound; use super::poly::circle::{CanonicCoset, CirclePoly}; use super::{ColumnVec, ComponentVec}; @@ -85,6 +87,20 @@ pub trait AirExt: Air { self.visit_components(&mut evaluator); evaluator.finalize() } + + /// Returns the log degree bounds of the quotient polynomials in descending order. + fn quotient_log_bounds(&self) -> Vec { + let mut bounds_visitor = QuotientLogBoundsVisitor::new(); + self.visit_components(&mut bounds_visitor); + let mut bounds = bounds_visitor.finalize(); + // Add the composition polynomial's log degree bound. + bounds.push(self.max_constraint_log_degree_bound()); + bounds + .into_iter() + .rev() + .map(CirclePolyDegreeBound::new) + .collect() + } } impl> AirExt for A {} @@ -180,6 +196,38 @@ impl ComponentVisitor for MaskPointsEvaluator { } } +struct QuotientLogBoundsVisitor { + // Maps the log degree bound to the number of quotients with that bound. + bounds: BTreeMap, +} + +impl QuotientLogBoundsVisitor { + pub fn new() -> Self { + Self { + bounds: BTreeMap::new(), + } + } + + pub fn finalize(self) -> Vec { + self.bounds + .into_iter() + .flat_map(|(bound, n)| (0..n).map(|_| bound).collect_vec()) + .collect() + } +} + +impl ComponentVisitor for QuotientLogBoundsVisitor { + fn visit>(&mut self, component: &C) { + for (mask_points, trace_bound) in zip( + component.mask().iter(), + &component.trace_log_degree_bounds(), + ) { + let n = self.bounds.entry(*trace_bound); + *n.or_default() += mask_points.len(); + } + } +} + /// 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/oods.rs b/src/core/oods.rs index 168e6d46e..5173fa7a8 100644 --- a/src/core/oods.rs +++ b/src/core/oods.rs @@ -1,16 +1,11 @@ -use std::iter::zip; - use itertools::enumerate; -use super::air::Component; use super::backend::cpu::CPUCircleEvaluation; -use super::backend::Backend; use super::circle::CirclePoint; use super::constraints::{complex_conjugate_line, pair_vanishing, point_vanishing}; use super::fields::m31::BaseField; use super::fields::qm31::SecureField; use super::fields::ComplexConjugate; -use super::fri::CirclePolyDegreeBound; use super::poly::circle::CircleEvaluation; use super::poly::{BitReversedOrder, NaturalOrder}; use super::utils::bit_reverse_index; @@ -81,17 +76,3 @@ pub fn get_pair_oods_quotient( } CircleEvaluation::new(eval.domain, values) } - -pub fn quotient_log_bounds(component: impl Component) -> Vec { - zip( - component.mask().iter(), - &component.trace_log_degree_bounds(), - ) - .flat_map(|(trace_points, trace_bound)| { - trace_points - .iter() - .map(|_| CirclePolyDegreeBound::new(*trace_bound)) - .collect::>() - }) - .collect() -} diff --git a/src/fibonacci/mod.rs b/src/fibonacci/mod.rs index 9cdb065b5..9b8cbde5e 100644 --- a/src/fibonacci/mod.rs +++ b/src/fibonacci/mod.rs @@ -15,10 +15,8 @@ use crate::core::commitment_scheme::{CommitmentSchemeProver, CommitmentSchemeVer use crate::core::fields::m31::BaseField; use crate::core::fields::qm31::SecureField; use crate::core::fields::{Field, IntoSlice}; -use crate::core::fri::{ - CirclePolyDegreeBound, FriConfig, FriProof, FriProver, FriVerifier, SparseCircleEvaluation, -}; -use crate::core::oods::{get_oods_quotient, get_pair_oods_quotient, quotient_log_bounds}; +use crate::core::fri::{FriConfig, FriProof, FriProver, FriVerifier, SparseCircleEvaluation}; +use crate::core::oods::{get_oods_quotient, get_pair_oods_quotient}; use crate::core::poly::circle::{CanonicCoset, CircleEvaluation}; use crate::core::poly::BitReversedOrder; use crate::core::proof_of_work::{ProofOfWork, ProofOfWorkProof}; @@ -212,11 +210,7 @@ pub fn verify_proof(proof: FibonacciProof) -> bool { random_coeff, ); - // TODO(AlonH): Get bounds from air. - let mut bounds = vec![CirclePolyDegreeBound::new( - fib.air.max_constraint_log_degree_bound(), - )]; - bounds.append(&mut quotient_log_bounds(fib.air.component)); + let bounds = fib.air.quotient_log_bounds(); 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();