diff --git a/src/core/backend/avx512/quotients.rs b/src/core/backend/avx512/quotients.rs index b13a3dc8a..4433acd4d 100644 --- a/src/core/backend/avx512/quotients.rs +++ b/src/core/backend/avx512/quotients.rs @@ -3,7 +3,7 @@ use itertools::zip_eq; use super::qm31::PackedQM31; use super::{AVX512Backend, VECS_LOG_SIZE}; use crate::core::backend::avx512::PackedBaseField; -use crate::core::backend::cpu::quotients::column_constants; +use crate::core::backend::cpu::quotients::{quotient_constants, QuotientConstants}; use crate::core::circle::CirclePoint; use crate::core::commitment_scheme::quotients::{ColumnSampleBatch, QuotientOps}; use crate::core::fields::m31::BaseField; @@ -23,7 +23,7 @@ impl QuotientOps for AVX512Backend { ) -> SecureEvaluation { assert!(domain.log_size() >= VECS_LOG_SIZE as u32); let mut values = SecureColumn::::zeros(domain.size()); - let column_constants = column_constants(sample_batches, random_coeff); + let quotient_constants = quotient_constants(sample_batches, random_coeff); // TODO(spapini): bit reverse iterator. for vec_row in 0..(1 << (domain.log_size() - VECS_LOG_SIZE as u32)) { @@ -39,7 +39,7 @@ impl QuotientOps for AVX512Backend { let row_accumulator = accumulate_row_quotients( sample_batches, columns, - &column_constants, + "ient_constants, vec_row, random_coeff, (domain_points_x, domain_points_y), @@ -53,13 +53,14 @@ impl QuotientOps for AVX512Backend { pub fn accumulate_row_quotients( sample_batches: &[ColumnSampleBatch], columns: &[&CircleEvaluation], - column_constants: &[Vec<(SecureField, SecureField, SecureField)>], + quotient_constants: &QuotientConstants, vec_row: usize, random_coeff: SecureField, domain_point_vec: (PackedBaseField, PackedBaseField), ) -> PackedQM31 { let mut row_accumulator = PackedQM31::zero(); - for (sample_batch, sample_constants) in zip_eq(sample_batches, column_constants) { + for (sample_batch, sample_constants) in zip_eq(sample_batches, "ient_constants.line_coeffs) + { let mut numerator = PackedQM31::zero(); for ((column_index, _), (a, b, c)) in zip_eq(&sample_batch.columns_and_values, sample_constants) diff --git a/src/core/backend/cpu/quotients.rs b/src/core/backend/cpu/quotients.rs index f8266c3cd..453e560dd 100644 --- a/src/core/backend/cpu/quotients.rs +++ b/src/core/backend/cpu/quotients.rs @@ -4,7 +4,7 @@ use num_traits::{One, Zero}; use super::CPUBackend; use crate::core::circle::CirclePoint; use crate::core::commitment_scheme::quotients::{ColumnSampleBatch, PointSample, QuotientOps}; -use crate::core::constraints::{complex_conjugate_line_coefficients, pair_vanishing}; +use crate::core::constraints::{complex_conjugate_line_coeffs, pair_vanishing}; use crate::core::fields::m31::BaseField; use crate::core::fields::qm31::SecureField; use crate::core::fields::secure_column::SecureColumn; @@ -21,7 +21,7 @@ impl QuotientOps for CPUBackend { sample_batches: &[ColumnSampleBatch], ) -> SecureEvaluation { let mut values = SecureColumn::zeros(domain.size()); - let column_constants = column_constants(sample_batches, random_coeff); + let quotient_constants = quotient_constants(sample_batches, random_coeff); for row in 0..domain.size() { // TODO(alonh): Make an efficient bit reverse domain iterator, possibly for AVX backend. @@ -29,7 +29,7 @@ impl QuotientOps for CPUBackend { let row_value = accumulate_row_quotients( sample_batches, columns, - &column_constants, + "ient_constants, row, random_coeff, domain_point, @@ -43,13 +43,14 @@ impl QuotientOps for CPUBackend { pub fn accumulate_row_quotients( sample_batches: &[ColumnSampleBatch], columns: &[&CircleEvaluation], - column_constants: &[Vec<(SecureField, SecureField, SecureField)>], + quotient_constants: &QuotientConstants, row: usize, random_coeff: SecureField, domain_point: CirclePoint, ) -> SecureField { let mut row_accumulator = SecureField::zero(); - for (sample_batch, sample_constants) in zip_eq(sample_batches, column_constants) { + for (sample_batch, sample_constants) in zip_eq(sample_batches, "ient_constants.line_coeffs) + { let mut numerator = SecureField::zero(); for ((column_index, _), (a, b, c)) in zip_eq(&sample_batch.columns_and_values, sample_constants) @@ -73,10 +74,11 @@ pub fn accumulate_row_quotients( row_accumulator } -/// Precompute the complex conjugate line constants for each column in each sample batch. +/// Precompute the complex conjugate line coefficients for each column in each sample batch. /// Specifically, for the i-th (in a sample batch) column's numerator term -/// `alpha^i * (F(p) - (a * p.y + b))`, we precompute the constants `alpha^i * a` and alpha^i * `b`. -pub fn column_constants( +/// `alpha^i * (c * F(p) - (a * p.y + b))`, we precompute and return the constants: +/// (`alpha^i * a`, `alpha^i * b`, `alpha^i * c`). +pub fn column_line_coeffs( sample_batches: &[ColumnSampleBatch], random_coeff: SecureField, ) -> Vec> { @@ -93,13 +95,28 @@ pub fn column_constants( point: sample_batch.point, value: *sampled_value, }; - complex_conjugate_line_coefficients(&sample, alpha) + complex_conjugate_line_coeffs(&sample, alpha) }) .collect() }) .collect() } +pub fn quotient_constants( + sample_batches: &[ColumnSampleBatch], + random_coeff: SecureField, +) -> QuotientConstants { + let line_coeffs = column_line_coeffs(sample_batches, random_coeff); + QuotientConstants { line_coeffs } +} + +/// Holds the precomputed constant values used in each quotient evaluation. +pub struct QuotientConstants { + /// The line coefficients for each quotient numerator term. For more details see + /// [self::column_line_coeffs]. + pub line_coeffs: Vec>, +} + #[cfg(test)] mod tests { use crate::core::backend::cpu::{CPUCircleEvaluation, CPUCirclePoly}; diff --git a/src/core/commitment_scheme/quotients.rs b/src/core/commitment_scheme/quotients.rs index 8cc8386b9..7c84204ed 100644 --- a/src/core/commitment_scheme/quotients.rs +++ b/src/core/commitment_scheme/quotients.rs @@ -4,7 +4,7 @@ use std::iter::zip; use itertools::{izip, multiunzip, Itertools}; -use crate::core::backend::cpu::quotients::{accumulate_row_quotients, column_constants}; +use crate::core::backend::cpu::quotients::{accumulate_row_quotients, quotient_constants}; use crate::core::circle::CirclePoint; use crate::core::fields::m31::BaseField; use crate::core::fields::qm31::SecureField; @@ -124,7 +124,7 @@ pub fn fri_answers_for_log_size( ) -> Result, VerificationError> { let commitment_domain = CanonicCoset::new(log_size).circle_domain(); let sample_batches = ColumnSampleBatch::new_vec(samples); - let column_constants = column_constants(&sample_batches, random_coeff); + let quotient_constants = quotient_constants(&sample_batches, random_coeff); for queried_values in queried_values_per_column { if queried_values.len() != query_domain.flatten().len() { return Err(VerificationError::InvalidStructure( @@ -155,7 +155,7 @@ pub fn fri_answers_for_log_size( let value = accumulate_row_quotients( &sample_batches, &column_evals.iter().collect_vec(), - &column_constants, + "ient_constants, row, random_coeff, domain_point, diff --git a/src/core/constraints.rs b/src/core/constraints.rs index 5631788e5..872c0cf1f 100644 --- a/src/core/constraints.rs +++ b/src/core/constraints.rs @@ -95,7 +95,7 @@ pub fn complex_conjugate_line( /// (conj(sample.y), conj(sample.value)). /// Relies on the fact that every polynomial F over the base /// field holds: F(p*) == F(p)* (* being the complex conjugate). -pub fn complex_conjugate_line_coefficients( +pub fn complex_conjugate_line_coeffs( sample: &PointSample, alpha: SecureField, ) -> (SecureField, SecureField, SecureField) {