Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add FRI layer 0 (WIP) #895

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions crates/prover/proof.cairo

Large diffs are not rendered by default.

60 changes: 21 additions & 39 deletions crates/prover/src/core/backend/cpu/quotients.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
use itertools::{izip, zip_eq};
use itertools::{izip, zip_eq, Itertools};
use num_traits::{One, Zero};

use super::CpuBackend;
use crate::core::circle::CirclePoint;
use crate::core::constraints::complex_conjugate_line_coeffs;
use crate::core::fields::cm31::CM31;
use crate::core::fields::m31::BaseField;
use crate::core::fields::m31::{BaseField, M31};
use crate::core::fields::qm31::SecureField;
use crate::core::fields::secure_column::SecureColumnByCoords;
use crate::core::fields::FieldExpOps;
use crate::core::pcs::quotients::{ColumnSampleBatch, PointSample, QuotientOps};
use crate::core::poly::circle::{CircleDomain, CircleEvaluation, SecureEvaluation};
use crate::core::poly::BitReversedOrder;
use crate::core::utils::{bit_reverse, bit_reverse_index};
use crate::core::utils::bit_reverse_index;

impl QuotientOps for CpuBackend {
fn accumulate_quotients(
Expand All @@ -23,15 +23,15 @@ impl QuotientOps for CpuBackend {
_log_blowup_factor: u32,
) -> SecureEvaluation<Self, BitReversedOrder> {
let mut values = unsafe { SecureColumnByCoords::uninitialized(domain.size()) };
let quotient_constants = quotient_constants(sample_batches, random_coeff, domain);
let quotient_constants = quotient_constants(sample_batches, random_coeff);

for row in 0..domain.size() {
let domain_point = domain.at(bit_reverse_index(row, domain.log_size()));
let query_values_at_row = columns.iter().map(|col| col[row]).collect_vec();
let row_value = accumulate_row_quotients(
sample_batches,
columns,
&query_values_at_row,
&quotient_constants,
row,
domain_point,
);
values.set(row, row_value);
Expand All @@ -42,23 +42,22 @@ impl QuotientOps for CpuBackend {

pub fn accumulate_row_quotients(
sample_batches: &[ColumnSampleBatch],
columns: &[&CircleEvaluation<CpuBackend, BaseField, BitReversedOrder>],
queried_values_at_row: &[BaseField],
quotient_constants: &QuotientConstants,
row: usize,
domain_point: CirclePoint<BaseField>,
) -> SecureField {
let denominator_inverses = denominator_inverses(sample_batches, domain_point);
let mut row_accumulator = SecureField::zero();
for (sample_batch, line_coeffs, batch_coeff, denominator_inverses) in izip!(
for (sample_batch, line_coeffs, batch_coeff, denominator_inverse) in izip!(
sample_batches,
&quotient_constants.line_coeffs,
&quotient_constants.batch_random_coeffs,
&quotient_constants.denominator_inverses
denominator_inverses
) {
let mut numerator = SecureField::zero();
for ((column_index, _), (a, b, c)) in zip_eq(&sample_batch.columns_and_values, line_coeffs)
{
let column = &columns[*column_index];
let value = column[row] * *c;
let value = queried_values_at_row[*column_index] * *c;
// The numerator is a line equation passing through
// (sample_point.y, sample_value), (conj(sample_point), conj(sample_value))
// evaluated at (domain_point.y, value).
Expand All @@ -69,8 +68,7 @@ pub fn accumulate_row_quotients(
numerator += value - linear_term;
}

row_accumulator =
row_accumulator * *batch_coeff + numerator.mul_cm31(denominator_inverses[row]);
row_accumulator = row_accumulator * *batch_coeff + numerator.mul_cm31(denominator_inverse);
}
row_accumulator
}
Expand Down Expand Up @@ -118,9 +116,9 @@ pub fn batch_random_coeffs(

fn denominator_inverses(
sample_batches: &[ColumnSampleBatch],
domain: CircleDomain,
) -> Vec<Vec<CM31>> {
let mut flat_denominators = Vec::with_capacity(sample_batches.len() * domain.size());
domain_point: CirclePoint<M31>,
) -> Vec<CM31> {
let mut denominators = Vec::new();
// We want a P to be on a line that passes through a point Pr + uPi in QM31^2, and its conjugate
// Pr - uPi. Thus, Pr - P is parallel to Pi. Or, (Pr - P).x * Pi.y - (Pr - P).y * Pi.x = 0.
for sample_batch in sample_batches {
Expand All @@ -129,36 +127,22 @@ fn denominator_inverses(
let pry = sample_batch.point.y.0;
let pix = sample_batch.point.x.1;
let piy = sample_batch.point.y.1;
for row in 0..domain.size() {
let domain_point = domain.at(row);
flat_denominators.push((prx - domain_point.x) * piy - (pry - domain_point.y) * pix);
}
denominators.push((prx - domain_point.x) * piy - (pry - domain_point.y) * pix);
}

let mut flat_denominator_inverses = vec![CM31::zero(); flat_denominators.len()];
CM31::batch_inverse(&flat_denominators, &mut flat_denominator_inverses);
let mut denominator_inverses = vec![CM31::zero(); denominators.len()];
CM31::batch_inverse(&denominators, &mut denominator_inverses);

flat_denominator_inverses
.chunks_mut(domain.size())
.map(|denominator_inverses| {
bit_reverse(denominator_inverses);
denominator_inverses.to_vec()
})
.collect()
denominator_inverses
}

pub fn quotient_constants(
sample_batches: &[ColumnSampleBatch],
random_coeff: SecureField,
domain: CircleDomain,
) -> QuotientConstants {
let line_coeffs = column_line_coeffs(sample_batches, random_coeff);
let batch_random_coeffs = batch_random_coeffs(sample_batches, random_coeff);
let denominator_inverses = denominator_inverses(sample_batches, domain);
QuotientConstants {
line_coeffs,
batch_random_coeffs,
denominator_inverses,
line_coeffs: column_line_coeffs(sample_batches, random_coeff),
batch_random_coeffs: batch_random_coeffs(sample_batches, random_coeff),
}
}

Expand All @@ -170,8 +154,6 @@ pub struct QuotientConstants {
/// The random coefficients used to linearly combine the batched quotients For more details see
/// [self::batch_random_coeffs].
pub batch_random_coeffs: Vec<SecureField>,
/// The inverses of the denominators of the quotients.
pub denominator_inverses: Vec<Vec<CM31>>,
}

#[cfg(test)]
Expand Down
5 changes: 4 additions & 1 deletion crates/prover/src/core/backend/simd/poseidon252.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use itertools::Itertools;
#[cfg(feature = "parallel")]
use rayon::prelude::*;
use starknet_ff::FieldElement as FieldElement252;

use super::SimdBackend;
Expand All @@ -8,6 +10,7 @@ use crate::core::fields::m31::BaseField;
use crate::core::vcs::ops::MerkleHasher;
use crate::core::vcs::ops::MerkleOps;
use crate::core::vcs::poseidon252_merkle::Poseidon252MerkleHasher;
use crate::parallel_iter;

impl ColumnOps<FieldElement252> for SimdBackend {
type Column = Vec<FieldElement252>;
Expand All @@ -24,7 +27,7 @@ impl MerkleOps<Poseidon252MerkleHasher> for SimdBackend {
prev_layer: Option<&Vec<FieldElement252>>,
columns: &[&Col<Self, BaseField>],
) -> Vec<FieldElement252> {
(0..(1 << log_size))
parallel_iter!(0..(1 << log_size))
.map(|i| {
Poseidon252MerkleHasher::hash_node(
prev_layer.map(|prev_layer| (prev_layer[2 * i], prev_layer[2 * i + 1])),
Expand Down
Loading
Loading