diff --git a/src/core/backend/cpu/mod.rs b/src/core/backend/cpu/mod.rs index 9d32bbfbc..5927165d0 100644 --- a/src/core/backend/cpu/mod.rs +++ b/src/core/backend/cpu/mod.rs @@ -1,5 +1,6 @@ mod circle; mod fri; +pub mod quotients; use std::fmt::Debug; diff --git a/src/core/backend/cpu/quotients.rs b/src/core/backend/cpu/quotients.rs new file mode 100644 index 000000000..3b90ff41c --- /dev/null +++ b/src/core/backend/cpu/quotients.rs @@ -0,0 +1,45 @@ +use num_traits::Zero; + +use super::CPUBackend; +use crate::core::air::accumulation::ColumnAccumulator; +use crate::core::backend::Col; +use crate::core::commitment_scheme::quotients::{BatchedColumnOpenings, QuotientOps}; +use crate::core::constraints::pair_vanishing; +use crate::core::fields::m31::BaseField; +use crate::core::fields::qm31::SecureField; +use crate::core::fields::{ComplexConjugate, FieldExpOps}; +use crate::core::poly::circle::CircleDomain; +use crate::core::utils::bit_reverse_index; + +impl QuotientOps for CPUBackend { + fn accumulate_quotients( + domain: CircleDomain, + mut accum: ColumnAccumulator<'_, Self>, + columns: &[Col], + random_coeff: SecureField, + openings: &[BatchedColumnOpenings], + ) { + for row in 0..domain.size() { + let domain_point = domain.at(bit_reverse_index(row, domain.log_size())); + let mut row_accumlator = SecureField::zero(); + for opening in openings { + let mut numerator = SecureField::zero(); + for (column_index, open_value) in &opening.column_indices_and_values { + let column = &columns[*column_index]; + let value = column[row]; + numerator = numerator * random_coeff + (value - *open_value); + } + + let denominator = pair_vanishing( + opening.point, + opening.point.complex_conjugate(), + domain_point.into_ef(), + ); + + row_accumlator *= random_coeff.pow(opening.column_indices_and_values.len() as u128) + + numerator / denominator; + } + accum.accumulate(row, row_accumlator); + } + } +} diff --git a/src/core/commitment_scheme/mod.rs b/src/core/commitment_scheme/mod.rs index 7131d1b9d..ae61d794e 100644 --- a/src/core/commitment_scheme/mod.rs +++ b/src/core/commitment_scheme/mod.rs @@ -5,6 +5,7 @@ //! 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. +pub mod quotients; mod utils; use std::iter::zip; diff --git a/src/core/commitment_scheme/quotients.rs b/src/core/commitment_scheme/quotients.rs new file mode 100644 index 000000000..f1707b091 --- /dev/null +++ b/src/core/commitment_scheme/quotients.rs @@ -0,0 +1,21 @@ +use crate::core::air::accumulation::ColumnAccumulator; +use crate::core::backend::{Backend, Col}; +use crate::core::circle::CirclePoint; +use crate::core::fields::m31::BaseField; +use crate::core::fields::qm31::SecureField; +use crate::core::poly::circle::CircleDomain; + +pub trait QuotientOps: Backend { + fn accumulate_quotients( + domain: CircleDomain, + accum: ColumnAccumulator<'_, Self>, + columns: &[Col], + random_coeff: SecureField, + openings: &[BatchedColumnOpenings], + ); +} + +pub struct BatchedColumnOpenings { + pub point: CirclePoint, + pub column_indices_and_values: Vec<(usize, SecureField)>, +}