From f1ce145189e63e7758679ade2ced66f84018a352 Mon Sep 17 00:00:00 2001 From: Shahar Papini Date: Fri, 15 Mar 2024 06:55:26 +0200 Subject: [PATCH] Move SecureColumn --- src/core/air/evaluation.rs | 47 +++-------------------------- src/core/channel.rs | 5 +-- src/core/fields/mod.rs | 1 + src/core/fields/qm31.rs | 1 - src/core/fields/secure_column.rs | 41 +++++++++++++++++++++++++ src/core/poly/circle/mod.rs | 2 +- src/core/poly/circle/secure_poly.rs | 22 ++++++++------ src/core/prover/mod.rs | 6 ++-- 8 files changed, 66 insertions(+), 59 deletions(-) create mode 100644 src/core/fields/secure_column.rs diff --git a/src/core/air/evaluation.rs b/src/core/air/evaluation.rs index cca111d2e..3f7e5bd6a 100644 --- a/src/core/air/evaluation.rs +++ b/src/core/air/evaluation.rs @@ -3,50 +3,13 @@ //! Given a random alpha, the combined polynomial is defined as //! f(p) = sum_i alpha^{N-1-i} u_i (P). use crate::core::backend::cpu::CPUCircleEvaluation; -use crate::core::backend::{Backend, CPUBackend, Col, Column}; +use crate::core::backend::{Backend, CPUBackend}; use crate::core::fields::m31::BaseField; use crate::core::fields::qm31::SecureField; -use crate::core::fields::{ExtensionOf, FieldExpOps}; +use crate::core::fields::secure_column::SecureColumn; +use crate::core::fields::FieldExpOps; use crate::core::poly::circle::{CanonicCoset, CirclePoly, SecureCirclePoly}; use crate::core::poly::BitReversedOrder; -use crate::core::utils::IteratorMutExt; - -pub const SECURE_EXTENSION_DEGREE: usize = - >::EXTENSION_DEGREE; - -// TODO(spapini): find a better place for this -pub struct SecureColumn { - pub cols: [Col; SECURE_EXTENSION_DEGREE], -} - -impl SecureColumn { - fn at(&self, index: usize) -> SecureField { - SecureField::from_m31_array(std::array::from_fn(|i| self.cols[i][index])) - } - - fn set(&mut self, index: usize, value: SecureField) { - self.cols - .iter_mut() - .map(|c| &mut c[index]) - .assign(value.to_m31_array()); - } -} - -impl SecureColumn { - pub fn zeros(len: usize) -> Self { - Self { - cols: std::array::from_fn(|_| Col::::zeros(len)), - } - } - - pub fn len(&self) -> usize { - self.cols[0].len() - } - - pub fn is_empty(&self) -> bool { - self.cols[0].is_empty() - } -} /// Accumulates evaluations of u_i(P0) at a single point. /// Computes f(P0), the combined polynomial at that point. @@ -167,7 +130,7 @@ impl DomainEvaluationAccumulator { .skip(1) { let coeffs = SecureColumn { - cols: values.cols.map(|c| { + columns: values.columns.map(|c| { CPUCircleEvaluation::<_, BitReversedOrder>::new( CanonicCoset::new(log_size as u32).circle_domain(), c, @@ -185,7 +148,7 @@ impl DomainEvaluationAccumulator { } } - SecureCirclePoly(res_coeffs.cols.map(CirclePoly::new)) + SecureCirclePoly(res_coeffs.columns.map(CirclePoly::new)) } } diff --git a/src/core/channel.rs b/src/core/channel.rs index ade14e691..7d67f368f 100644 --- a/src/core/channel.rs +++ b/src/core/channel.rs @@ -1,7 +1,8 @@ use std::iter; use super::fields::m31::{BaseField, N_BYTES_FELT, P}; -use super::fields::qm31::{SecureField, SECURE_FIELD_EXTENSION_DEGREE}; +use super::fields::qm31::SecureField; +use super::fields::secure_column::SECURE_EXTENSION_DEGREE; use super::fields::IntoSlice; use crate::commitment_scheme::blake2_hash::{Blake2sHash, Blake2sHasher}; use crate::commitment_scheme::hasher::Hasher; @@ -122,7 +123,7 @@ impl Channel for Blake2sChannel { fn draw_felt(&mut self) -> SecureField { let felts: [BaseField; FELTS_PER_HASH] = self.draw_base_felts(); - SecureField::from_m31_array(felts[..SECURE_FIELD_EXTENSION_DEGREE].try_into().unwrap()) + SecureField::from_m31_array(felts[..SECURE_EXTENSION_DEGREE].try_into().unwrap()) } fn draw_felts(&mut self, n_felts: usize) -> Vec { diff --git a/src/core/fields/mod.rs b/src/core/fields/mod.rs index 6bb0894ad..2114bc050 100644 --- a/src/core/fields/mod.rs +++ b/src/core/fields/mod.rs @@ -10,6 +10,7 @@ use super::backend::ColumnOps; pub mod cm31; pub mod m31; pub mod qm31; +pub mod secure_column; pub trait FieldOps: ColumnOps { // TODO(Ohad): change to use a mutable slice. diff --git a/src/core/fields/qm31.rs b/src/core/fields/qm31.rs index 7fe683053..3862ba321 100644 --- a/src/core/fields/qm31.rs +++ b/src/core/fields/qm31.rs @@ -8,7 +8,6 @@ use crate::core::fields::cm31::CM31; use crate::core::fields::m31::M31; use crate::{impl_extension_field, impl_field}; -pub const SECURE_FIELD_EXTENSION_DEGREE: usize = 4; pub const P4: u128 = 21267647892944572736998860269687930881; // (2 ** 31 - 1) ** 4 pub const R: CM31 = CM31::from_u32_unchecked(2, 1); diff --git a/src/core/fields/secure_column.rs b/src/core/fields/secure_column.rs new file mode 100644 index 000000000..99b6ffdb9 --- /dev/null +++ b/src/core/fields/secure_column.rs @@ -0,0 +1,41 @@ +use super::m31::BaseField; +use super::qm31::SecureField; +use super::ExtensionOf; +use crate::core::backend::{Backend, CPUBackend, Col, Column}; +use crate::core::utils::IteratorMutExt; + +pub const SECURE_EXTENSION_DEGREE: usize = + >::EXTENSION_DEGREE; + +/// An array of `SECURE_EXTENSION_DEGREE` base field columns, that represents a column of secure +/// field elements. +pub struct SecureColumn { + pub columns: [Col; SECURE_EXTENSION_DEGREE], +} +impl SecureColumn { + pub fn at(&self, index: usize) -> SecureField { + SecureField::from_m31_array(std::array::from_fn(|i| self.columns[i][index])) + } + + pub fn set(&mut self, index: usize, value: SecureField) { + self.columns + .iter_mut() + .map(|c| &mut c[index]) + .assign(value.to_m31_array()); + } +} +impl SecureColumn { + pub fn zeros(len: usize) -> Self { + Self { + columns: std::array::from_fn(|_| Col::::zeros(len)), + } + } + + pub fn len(&self) -> usize { + self.columns[0].len() + } + + pub fn is_empty(&self) -> bool { + self.columns[0].is_empty() + } +} diff --git a/src/core/poly/circle/mod.rs b/src/core/poly/circle/mod.rs index f2cdb308d..903a1dcc5 100644 --- a/src/core/poly/circle/mod.rs +++ b/src/core/poly/circle/mod.rs @@ -10,7 +10,7 @@ pub use domain::{CircleDomain, MAX_CIRCLE_DOMAIN_LOG_SIZE}; pub use evaluation::{CircleEvaluation, CosetSubEvaluation}; pub use ops::PolyOps; pub use poly::CirclePoly; -pub use secure_poly::{combine_secure_value, SecureCirclePoly}; +pub use secure_poly::SecureCirclePoly; #[cfg(test)] mod tests { diff --git a/src/core/poly/circle/secure_poly.rs b/src/core/poly/circle/secure_poly.rs index 986c648bd..c2783afb2 100644 --- a/src/core/poly/circle/secure_poly.rs +++ b/src/core/poly/circle/secure_poly.rs @@ -1,15 +1,15 @@ use std::ops::Deref; -use crate::core::air::evaluation::SECURE_EXTENSION_DEGREE; use crate::core::backend::cpu::CPUCirclePoly; use crate::core::circle::CirclePoint; use crate::core::fields::qm31::SecureField; +use crate::core::fields::secure_column::SECURE_EXTENSION_DEGREE; pub struct SecureCirclePoly(pub [CPUCirclePoly; SECURE_EXTENSION_DEGREE]); impl SecureCirclePoly { pub fn eval_at_point(&self, point: CirclePoint) -> SecureField { - combine_secure_value(self.eval_columns_at_point(point)) + Self::eval_from_partial_evals(self.eval_columns_at_point(point)) } pub fn eval_columns_at_point( @@ -23,6 +23,16 @@ impl SecureCirclePoly { self[3].eval_at_point(point), ] } + + /// Evaluates the polynomial at a point, given evaluations of its composing base field + /// polynomials at that point. + pub fn eval_from_partial_evals(evals: [SecureField; SECURE_EXTENSION_DEGREE]) -> SecureField { + let mut res = evals[0]; + res += evals[1] * SecureField::from_u32_unchecked(0, 1, 0, 0); + res += evals[2] * SecureField::from_u32_unchecked(0, 0, 1, 0); + res += evals[3] * SecureField::from_u32_unchecked(0, 0, 0, 1); + res + } } impl Deref for SecureCirclePoly { @@ -32,11 +42,3 @@ impl Deref for SecureCirclePoly { &self.0 } } - -pub fn combine_secure_value(value: [SecureField; SECURE_EXTENSION_DEGREE]) -> SecureField { - let mut res = value[0]; - res += value[1] * SecureField::from_u32_unchecked(0, 1, 0, 0); - res += value[2] * SecureField::from_u32_unchecked(0, 0, 1, 0); - res += value[3] * SecureField::from_u32_unchecked(0, 0, 0, 1); - res -} diff --git a/src/core/prover/mod.rs b/src/core/prover/mod.rs index dae2e2715..92760c090 100644 --- a/src/core/prover/mod.rs +++ b/src/core/prover/mod.rs @@ -3,7 +3,7 @@ use thiserror::Error; use super::commitment_scheme::{CommitmentSchemeProof, TreeVec}; use super::fri::FriVerificationError; -use super::poly::circle::MAX_CIRCLE_DOMAIN_LOG_SIZE; +use super::poly::circle::{SecureCirclePoly, MAX_CIRCLE_DOMAIN_LOG_SIZE}; use super::proof_of_work::ProofOfWorkVerificationError; use super::ColumnVec; use crate::commitment_scheme::blake2_hash::Blake2sHasher; @@ -16,7 +16,7 @@ use crate::core::circle::CirclePoint; use crate::core::commitment_scheme::{CommitmentSchemeProver, CommitmentSchemeVerifier}; use crate::core::fields::m31::BaseField; use crate::core::fields::qm31::SecureField; -use crate::core::poly::circle::{combine_secure_value, CircleEvaluation}; +use crate::core::poly::circle::CircleEvaluation; use crate::core::poly::BitReversedOrder; use crate::core::ComponentVec; @@ -158,7 +158,7 @@ fn opened_values_to_mask( air: &impl Air, mut opened_values: TreeVec>>, ) -> Result<(ComponentVec>, SecureField), ()> { - let composition_oods_values = combine_secure_value( + let composition_oods_values = SecureCirclePoly::eval_from_partial_evals( opened_values .pop() .unwrap()