Skip to content

Commit

Permalink
Remove FRI PolyOps dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
spapinistarkware committed Mar 12, 2024
1 parent 58568c8 commit 6b11c43
Show file tree
Hide file tree
Showing 15 changed files with 99 additions and 100 deletions.
5 changes: 2 additions & 3 deletions src/core/air/component_visitors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use super::{Air, Component, ComponentTrace, ComponentVisitor};
use crate::core::air::evaluation::{DomainEvaluationAccumulator, PointEvaluationAccumulator};
use crate::core::backend::{Backend, CPUBackend};
use crate::core::circle::CirclePoint;
use crate::core::fields::m31::BaseField;
use crate::core::fields::qm31::SecureField;
use crate::core::fri::CirclePolyDegreeBound;
use crate::core::poly::circle::{CanonicCoset, CirclePoly, SecureCirclePoly};
Expand Down Expand Up @@ -205,10 +204,10 @@ pub trait AirExt: Air<CPUBackend> {

fn component_traces<'a>(
&'a self,
polynomials: &'a [CirclePoly<CPUBackend, BaseField>],
polynomials: &'a [CirclePoly<CPUBackend>],
) -> Vec<ComponentTrace<'_, CPUBackend>> {
struct ComponentTracesVisitor<'a, B: Backend> {
polynomials: slice::Iter<'a, CirclePoly<B, BaseField>>,
polynomials: slice::Iter<'a, CirclePoly<B>>,
component_traces: Vec<ComponentTrace<'a, B>>,
}

Expand Down
5 changes: 2 additions & 3 deletions src/core/air/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use itertools::Itertools;
use self::evaluation::{DomainEvaluationAccumulator, PointEvaluationAccumulator};
use super::backend::Backend;
use super::circle::CirclePoint;
use super::fields::m31::BaseField;
use super::fields::qm31::SecureField;
use super::poly::circle::{CanonicCoset, CirclePoly};
use super::ColumnVec;
Expand Down Expand Up @@ -122,11 +121,11 @@ pub trait Component<B: Backend> {
}

pub struct ComponentTrace<'a, B: Backend> {
pub columns: Vec<&'a CirclePoly<B, BaseField>>,
pub columns: Vec<&'a CirclePoly<B>>,
}

impl<'a, B: Backend> ComponentTrace<'a, B> {
pub fn new(columns: Vec<&'a CirclePoly<B, BaseField>>) -> Self {
pub fn new(columns: Vec<&'a CirclePoly<B>>) -> Self {
Self { columns }
}
}
14 changes: 6 additions & 8 deletions src/core/backend/avx512/circle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::core::poly::BitReversedOrder;

// TODO(spapini): Everything is returned in redundant representation, where values can also be P.
// Decide if and when it's ok and what to do if it's not.
impl PolyOps<BaseField> for AVX512Backend {
impl PolyOps for AVX512Backend {
fn new_canonical_ordered(
coset: CanonicCoset,
values: Col<Self, BaseField>,
Expand All @@ -27,9 +27,7 @@ impl PolyOps<BaseField> for AVX512Backend {
CircleEvaluation::new(eval.domain, Col::<AVX512Backend, _>::from_iter(eval.values))
}

fn interpolate(
eval: CircleEvaluation<Self, BaseField, BitReversedOrder>,
) -> CirclePoly<Self, BaseField> {
fn interpolate(eval: CircleEvaluation<Self, BaseField, BitReversedOrder>) -> CirclePoly<Self> {
let mut values = eval.values;
let log_size = values.length.ilog2();

Expand Down Expand Up @@ -60,7 +58,7 @@ impl PolyOps<BaseField> for AVX512Backend {
}

fn eval_at_point<E: ExtensionOf<BaseField>>(
poly: &CirclePoly<Self, BaseField>,
poly: &CirclePoly<Self>,
point: CirclePoint<E>,
) -> E {
// TODO(spapini): Optimize.
Expand All @@ -84,14 +82,14 @@ impl PolyOps<BaseField> for AVX512Backend {
fold(cast_slice(&poly.coeffs.data), &mappings)
}

fn extend(poly: &CirclePoly<Self, BaseField>, log_size: u32) -> CirclePoly<Self, BaseField> {
fn extend(poly: &CirclePoly<Self>, log_size: u32) -> CirclePoly<Self> {
// TODO(spapini): Optimize or get rid of extend.
poly.evaluate(CanonicCoset::new(log_size).circle_domain())
.interpolate()
}

fn evaluate(
poly: &CirclePoly<Self, BaseField>,
poly: &CirclePoly<Self>,
domain: CircleDomain,
) -> CircleEvaluation<Self, BaseField, BitReversedOrder> {
// TODO(spapini): Precompute twiddles.
Expand Down Expand Up @@ -217,7 +215,7 @@ mod tests {
fn test_circle_poly_extend() {
for log_size in MIN_FFT_LOG_SIZE..(CACHED_FFT_LOG_SIZE + 2) {
let log_size = log_size as u32;
let poly = CirclePoly::<AVX512Backend, _>::new(
let poly = CirclePoly::<AVX512Backend>::new(
(0..(1 << log_size))
.map(BaseField::from_u32_unchecked)
.collect(),
Expand Down
23 changes: 14 additions & 9 deletions src/core/backend/cpu/circle.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use num_traits::Zero;

use super::CPUBackend;
use crate::core::circle::CirclePoint;
use crate::core::fft::{butterfly, ibutterfly};
Expand Down Expand Up @@ -31,11 +33,11 @@ fn get_twiddles(domain: CircleDomain) -> Vec<Vec<BaseField>> {
res
}

impl<F: ExtensionOf<BaseField>> PolyOps<F> for CPUBackend {
impl PolyOps for CPUBackend {
fn new_canonical_ordered(
coset: CanonicCoset,
values: Col<Self, F>,
) -> CircleEvaluation<Self, F, BitReversedOrder> {
values: Col<Self, BaseField>,
) -> CircleEvaluation<Self, BaseField, BitReversedOrder> {
let domain = coset.circle_domain();
assert_eq!(values.len(), domain.size());
let mut new_values = Vec::with_capacity(values.len());
Expand All @@ -50,7 +52,7 @@ impl<F: ExtensionOf<BaseField>> PolyOps<F> for CPUBackend {
CircleEvaluation::new(domain, new_values)
}

fn interpolate(eval: CircleEvaluation<Self, F, BitReversedOrder>) -> CirclePoly<Self, F> {
fn interpolate(eval: CircleEvaluation<Self, BaseField, BitReversedOrder>) -> CirclePoly<Self> {
let twiddles = get_twiddles(eval.domain);

let mut values = eval.values;
Expand All @@ -75,7 +77,10 @@ impl<F: ExtensionOf<BaseField>> PolyOps<F> for CPUBackend {
CirclePoly::new(values)
}

fn eval_at_point<E: ExtensionOf<F>>(poly: &CirclePoly<Self, F>, point: CirclePoint<E>) -> E {
fn eval_at_point<E: ExtensionOf<BaseField>>(
poly: &CirclePoly<Self>,
point: CirclePoint<E>,
) -> E {
// TODO(Andrew): Allocation here expensive for small polynomials.
let mut mappings = vec![point.y, point.x];
let mut x = point.x;
Expand All @@ -87,18 +92,18 @@ impl<F: ExtensionOf<BaseField>> PolyOps<F> for CPUBackend {
fold(&poly.coeffs, &mappings)
}

fn extend(poly: &CirclePoly<Self, F>, log_size: u32) -> CirclePoly<Self, F> {
fn extend(poly: &CirclePoly<Self>, log_size: u32) -> CirclePoly<Self> {
assert!(log_size >= poly.log_size());
let mut coeffs = Vec::with_capacity(1 << log_size);
coeffs.extend_from_slice(&poly.coeffs);
coeffs.resize(1 << log_size, F::zero());
coeffs.resize(1 << log_size, BaseField::zero());
CirclePoly::new(coeffs)
}

fn evaluate(
poly: &CirclePoly<Self, F>,
poly: &CirclePoly<Self>,
domain: CircleDomain,
) -> CircleEvaluation<Self, F, BitReversedOrder> {
) -> CircleEvaluation<Self, BaseField, BitReversedOrder> {
let twiddles = get_twiddles(domain);

let mut values = poly.extend(domain.log_size()).coeffs;
Expand Down
2 changes: 1 addition & 1 deletion src/core/backend/cpu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ impl<F: Field> Column<F> for Vec<F> {
}
}

pub type CPUCirclePoly<F> = CirclePoly<CPUBackend, F>;
pub type CPUCirclePoly = CirclePoly<CPUBackend>;
pub type CPUCircleEvaluation<F, EvalOrder> = CircleEvaluation<CPUBackend, F, EvalOrder>;
// TODO(spapini): Remove the EvalOrder on LineEvaluation.
pub type CPULineEvaluation<F, EvalOrder> = LineEvaluation<CPUBackend, F, EvalOrder>;
Expand Down
8 changes: 1 addition & 7 deletions src/core/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,6 @@ pub mod avx512;
pub mod cpu;

pub trait Backend:
Copy
+ Clone
+ Debug
+ FieldOps<BaseField>
+ FieldOps<SecureField>
+ PolyOps<BaseField>
+ PolyOps<SecureField>
Copy + Clone + Debug + FieldOps<BaseField> + FieldOps<SecureField> + PolyOps
{
}
10 changes: 3 additions & 7 deletions src/core/commitment_scheme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,7 @@ impl CommitmentSchemeProver {
}
}

pub fn commit(
&mut self,
polynomials: ColumnVec<CPUCirclePoly<BaseField>>,
channel: &mut Blake2sChannel,
) {
pub fn commit(&mut self, polynomials: ColumnVec<CPUCirclePoly>, channel: &mut Blake2sChannel) {
let tree = CommitmentTreeProver::new(polynomials, self.log_blowup_factor, channel);
self.trees.push(tree);
}
Expand All @@ -82,15 +78,15 @@ impl CommitmentSchemeProver {
}

pub struct CommitmentTreeProver {
pub polynomials: ColumnVec<CPUCirclePoly<BaseField>>,
pub polynomials: ColumnVec<CPUCirclePoly>,
pub evaluations: ColumnVec<CPUCircleEvaluation<BaseField, BitReversedOrder>>,
// TODO(AlonH): Change to mixed degree merkle and remove values clone.
pub commitment: MerkleTree<BaseField, Blake2sHasher>,
}

impl CommitmentTreeProver {
pub fn new(
polynomials: Vec<CPUCirclePoly<BaseField>>,
polynomials: Vec<CPUCirclePoly>,
log_blowup_factor: u32,
channel: &mut Blake2sChannel,
) -> Self {
Expand Down
5 changes: 4 additions & 1 deletion src/core/constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ mod tests {
use crate::core::fields::{ComplexConjugate, FieldExpOps};
use crate::core::poly::circle::CanonicCoset;
use crate::core::poly::NaturalOrder;
use crate::core::utils::secure_eval_to_base_eval;
use crate::m31;

#[test]
Expand Down Expand Up @@ -217,7 +218,9 @@ mod tests {
large_domain,
quotient_polynomial_values,
);
let quotient_polynomial = quotient_evaluation.bit_reverse().interpolate();
let quotient_polynomial = secure_eval_to_base_eval(&quotient_evaluation)
.bit_reverse()
.interpolate();

// Check that the quotient polynomial is indeed in the wanted fft space.
assert!(quotient_polynomial.is_in_fft_space(log_domain_size));
Expand Down
40 changes: 19 additions & 21 deletions src/core/fri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use super::channel::Channel;
use super::fields::m31::BaseField;
use super::fields::qm31::SecureField;
use super::fields::{ExtensionOf, Field, FieldOps};
use super::poly::circle::{CircleEvaluation, PolyOps};
use super::poly::circle::CircleEvaluation;
use super::poly::line::{LineEvaluation, LinePoly};
use super::poly::BitReversedOrder;
// TODO(andrew): Create fri/ directory, move queries.rs there and split this file up.
Expand Down Expand Up @@ -106,7 +106,7 @@ pub trait FriOps: FieldOps<SecureField> + Sized {
) where
F: ExtensionOf<BaseField>,
SecureField: ExtensionOf<F> + Field,
Self: PolyOps<F>;
Self: FieldOps<F>;
}

/// A FRI prover that applies the FRI protocol to prove a set of polynomials are of low degree.
Expand Down Expand Up @@ -145,7 +145,7 @@ impl<B: FriOps, H: Hasher<NativeType = u8>> FriProver<B, H> {
where
F: ExtensionOf<BaseField>,
SecureField: ExtensionOf<F>,
B: PolyOps<F>,
B: FieldOps<F>,
{
assert!(!columns.is_empty(), "no columns");
assert!(columns.is_sorted_by_key(|e| Reverse(e.len())), "not sorted");
Expand Down Expand Up @@ -183,7 +183,7 @@ impl<B: FriOps, H: Hasher<NativeType = u8>> FriProver<B, H> {
where
F: ExtensionOf<BaseField>,
SecureField: ExtensionOf<F>,
B: FriOps + PolyOps<F>,
B: FriOps + FieldOps<F>,
{
// Returns the length of the [LineEvaluation] a [CircleEvaluation] gets folded into.
let folded_len = |e: &CircleEvaluation<B, F, _>| e.len() >> CIRCLE_TO_LINE_FOLD_STEP;
Expand Down Expand Up @@ -964,7 +964,7 @@ mod tests {
#[test]
fn fold_circle_to_line_works() {
const LOG_DEGREE: u32 = 4;
let circle_evaluation = polynomial_evaluation::<BaseField>(LOG_DEGREE, LOG_BLOWUP_FACTOR);
let circle_evaluation = polynomial_evaluation(LOG_DEGREE, LOG_BLOWUP_FACTOR);
let num_folded_evals = circle_evaluation.domain.size() >> CIRCLE_TO_LINE_FOLD_STEP;
let alpha = SecureField::one();
let folded_domain = LineDomain::new(circle_evaluation.domain.half_coset);
Expand All @@ -985,7 +985,7 @@ mod tests {
const LOG_EXPECTED_BLOWUP_FACTOR: u32 = LOG_BLOWUP_FACTOR;
const LOG_INVALID_BLOWUP_FACTOR: u32 = LOG_BLOWUP_FACTOR - 1;
let config = FriConfig::new(2, LOG_EXPECTED_BLOWUP_FACTOR, 3);
let evaluation = polynomial_evaluation::<BaseField>(6, LOG_INVALID_BLOWUP_FACTOR);
let evaluation = polynomial_evaluation(6, LOG_INVALID_BLOWUP_FACTOR);

FriProver::commit(&mut test_channel(), config, &[evaluation]);
}
Expand All @@ -1003,7 +1003,7 @@ mod tests {
#[test]
fn valid_proof_passes_verification() -> Result<(), VerificationError> {
const LOG_DEGREE: u32 = 3;
let polynomial = polynomial_evaluation::<BaseField>(LOG_DEGREE, LOG_BLOWUP_FACTOR);
let polynomial = polynomial_evaluation(LOG_DEGREE, LOG_BLOWUP_FACTOR);
let log_domain_size = polynomial.domain.log_size();
let queries = Queries::from_positions(vec![5], log_domain_size);
let config = FriConfig::new(1, LOG_BLOWUP_FACTOR, queries.len());
Expand All @@ -1019,8 +1019,7 @@ mod tests {
#[test]
fn valid_mixed_degree_proof_passes_verification() -> Result<(), VerificationError> {
const LOG_DEGREES: [u32; 3] = [6, 5, 4];
let polynomials =
LOG_DEGREES.map(|log_d| polynomial_evaluation::<BaseField>(log_d, LOG_BLOWUP_FACTOR));
let polynomials = LOG_DEGREES.map(|log_d| polynomial_evaluation(log_d, LOG_BLOWUP_FACTOR));
let log_domain_size = polynomials[0].domain.log_size();
let queries = Queries::from_positions(vec![7, 70], log_domain_size);
let config = FriConfig::new(2, LOG_BLOWUP_FACTOR, queries.len());
Expand All @@ -1036,8 +1035,7 @@ mod tests {
#[test]
fn valid_mixed_degree_end_to_end_proof_passes_verification() -> Result<(), VerificationError> {
const LOG_DEGREES: [u32; 3] = [6, 5, 4];
let polynomials =
LOG_DEGREES.map(|log_d| polynomial_evaluation::<BaseField>(log_d, LOG_BLOWUP_FACTOR));
let polynomials = LOG_DEGREES.map(|log_d| polynomial_evaluation(log_d, LOG_BLOWUP_FACTOR));
let config = FriConfig::new(2, LOG_BLOWUP_FACTOR, 3);
let prover = FriProver::commit(&mut test_channel(), config, &polynomials);
let (proof, prover_opening_positions) = prover.decommit(&mut test_channel());
Expand All @@ -1056,7 +1054,7 @@ mod tests {
#[test]
fn proof_with_removed_layer_fails_verification() {
const LOG_DEGREE: u32 = 6;
let polynomial = polynomial_evaluation::<BaseField>(6, LOG_BLOWUP_FACTOR);
let polynomial = polynomial_evaluation(6, LOG_BLOWUP_FACTOR);
let log_domain_size = polynomial.domain.log_size();
let queries = Queries::from_positions(vec![1], log_domain_size);
let config = FriConfig::new(2, LOG_BLOWUP_FACTOR, queries.len());
Expand All @@ -1078,7 +1076,7 @@ mod tests {
#[test]
fn proof_with_added_layer_fails_verification() {
const LOG_DEGREE: u32 = 6;
let polynomial = polynomial_evaluation::<BaseField>(LOG_DEGREE, LOG_BLOWUP_FACTOR);
let polynomial = polynomial_evaluation(LOG_DEGREE, LOG_BLOWUP_FACTOR);
let log_domain_size = polynomial.domain.log_size();
let queries = Queries::from_positions(vec![1], log_domain_size);
let config = FriConfig::new(2, LOG_BLOWUP_FACTOR, queries.len());
Expand All @@ -1100,7 +1098,7 @@ mod tests {
#[test]
fn proof_with_invalid_inner_layer_evaluation_fails_verification() {
const LOG_DEGREE: u32 = 6;
let polynomial = polynomial_evaluation::<BaseField>(LOG_DEGREE, LOG_BLOWUP_FACTOR);
let polynomial = polynomial_evaluation(LOG_DEGREE, LOG_BLOWUP_FACTOR);
let log_domain_size = polynomial.domain.log_size();
let queries = Queries::from_positions(vec![5], log_domain_size);
let config = FriConfig::new(2, LOG_BLOWUP_FACTOR, queries.len());
Expand All @@ -1123,7 +1121,7 @@ mod tests {
#[test]
fn proof_with_invalid_inner_layer_decommitment_fails_verification() {
const LOG_DEGREE: u32 = 6;
let polynomial = polynomial_evaluation::<BaseField>(LOG_DEGREE, LOG_BLOWUP_FACTOR);
let polynomial = polynomial_evaluation(LOG_DEGREE, LOG_BLOWUP_FACTOR);
let log_domain_size = polynomial.domain.log_size();
let queries = Queries::from_positions(vec![5], log_domain_size);
let config = FriConfig::new(2, LOG_BLOWUP_FACTOR, queries.len());
Expand All @@ -1147,7 +1145,7 @@ mod tests {
fn proof_with_invalid_last_layer_degree_fails_verification() {
const LOG_DEGREE: u32 = 6;
const LOG_MAX_LAST_LAYER_DEGREE: u32 = 2;
let polynomial = polynomial_evaluation::<BaseField>(LOG_DEGREE, LOG_BLOWUP_FACTOR);
let polynomial = polynomial_evaluation(LOG_DEGREE, LOG_BLOWUP_FACTOR);
let log_domain_size = polynomial.domain.log_size();
let queries = Queries::from_positions(vec![1, 7, 8], log_domain_size);
let config = FriConfig::new(LOG_MAX_LAST_LAYER_DEGREE, LOG_BLOWUP_FACTOR, queries.len());
Expand All @@ -1168,7 +1166,7 @@ mod tests {
#[test]
fn proof_with_invalid_last_layer_fails_verification() {
const LOG_DEGREE: u32 = 6;
let polynomial = polynomial_evaluation::<BaseField>(LOG_DEGREE, LOG_BLOWUP_FACTOR);
let polynomial = polynomial_evaluation(LOG_DEGREE, LOG_BLOWUP_FACTOR);
let log_domain_size = polynomial.domain.log_size();
let queries = Queries::from_positions(vec![1, 7, 8], log_domain_size);
let config = FriConfig::new(2, LOG_BLOWUP_FACTOR, queries.len());
Expand All @@ -1192,7 +1190,7 @@ mod tests {
#[should_panic]
fn decommit_queries_on_invalid_domain_fails_verification() {
const LOG_DEGREE: u32 = 3;
let polynomial = polynomial_evaluation::<BaseField>(LOG_DEGREE, LOG_BLOWUP_FACTOR);
let polynomial = polynomial_evaluation(LOG_DEGREE, LOG_BLOWUP_FACTOR);
let log_domain_size = polynomial.domain.log_size();
let queries = Queries::from_positions(vec![5], log_domain_size);
let config = FriConfig::new(1, LOG_BLOWUP_FACTOR, queries.len());
Expand All @@ -1211,11 +1209,11 @@ mod tests {
/// Returns an evaluation of a random polynomial with degree `2^log_degree`.
///
/// The evaluation domain size is `2^(log_degree + log_blowup_factor)`.
fn polynomial_evaluation<F: ExtensionOf<BaseField>>(
fn polynomial_evaluation(
log_degree: u32,
log_blowup_factor: u32,
) -> CPUCircleEvaluation<F, BitReversedOrder> {
let poly = CPUCirclePoly::<F>::new(vec![F::one(); 1 << log_degree]);
) -> CPUCircleEvaluation<BaseField, BitReversedOrder> {
let poly = CPUCirclePoly::new(vec![BaseField::one(); 1 << log_degree]);
let coset = Coset::half_odds(log_degree + log_blowup_factor - 1);
let domain = CircleDomain::new(coset);
poly.evaluate(domain)
Expand Down
Loading

0 comments on commit 6b11c43

Please sign in to comment.