Skip to content

Commit

Permalink
Clean up fri quotients
Browse files Browse the repository at this point in the history
  • Loading branch information
spapinistarkware committed Mar 25, 2024
1 parent 5f6376d commit 50ec779
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 44 deletions.
18 changes: 10 additions & 8 deletions src/core/backend/cpu/quotients.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::core::fields::m31::BaseField;
use crate::core::fields::qm31::SecureField;
use crate::core::fields::secure_column::SecureColumn;
use crate::core::fields::{ComplexConjugate, FieldExpOps};
use crate::core::poly::circle::{CircleDomain, CircleEvaluation};
use crate::core::poly::circle::{CircleDomain, CircleEvaluation, SecureEvaluation};
use crate::core::poly::BitReversedOrder;
use crate::core::utils::bit_reverse_index;

Expand All @@ -18,16 +18,17 @@ impl QuotientOps for CPUBackend {
columns: &[&CircleEvaluation<Self, BaseField, BitReversedOrder>],
random_coeff: SecureField,
samples: &[ColumnSampleBatch],
) -> SecureColumn<Self> {
let mut res = SecureColumn::zeros(domain.size());
) -> SecureEvaluation<Self> {
let mut values = SecureColumn::zeros(domain.size());
// TODO(spapini): bit reverse iterator.
for row in 0..domain.size() {
// TODO(alonh): Make an efficient bit reverse domain iterator, possibly for AVX backend.
let domain_point = domain.at(bit_reverse_index(row, domain.log_size()));
let row_value =
accumulate_row_quotients(samples, columns, row, random_coeff, domain_point);
res.set(row, row_value);
values.set(row, row_value);
}
res
SecureEvaluation { domain, values }
}
}

Expand All @@ -41,11 +42,11 @@ pub fn accumulate_row_quotients(
let mut row_accumlator = SecureField::zero();
for sample in samples {
let mut numerator = SecureField::zero();
for (column_index, sampled_value) in &sample.column_indices_and_values {
for (column_index, sample_value) in &sample.column_indices_and_values {
let column = &columns[*column_index];
let value = column[row];
let current_numerator =
complex_conjugate_line(domain_point, value, sample.point, *sampled_value);
complex_conjugate_line(domain_point, value, sample.point, *sample_value);
numerator = numerator * random_coeff + current_numerator;
}

Expand Down Expand Up @@ -90,7 +91,8 @@ mod tests {
}],
);
let quot_poly_base_field =
CPUCircleEvaluation::new(eval_domain, quot_eval.columns[0].clone()).interpolate();
CPUCircleEvaluation::new(eval_domain, quot_eval.values.columns[0].clone())
.interpolate();
assert!(quot_poly_base_field.is_in_fft_space(LOG_SIZE));
}
}
61 changes: 25 additions & 36 deletions src/core/commitment_scheme/quotients.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,15 @@ use std::collections::BTreeMap;

use itertools::{izip, multiunzip, Itertools};

use crate::core::backend::cpu::quotients::accumulate_row_quotients;
use crate::core::backend::Backend;
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::fields::secure_column::SecureColumn;
use crate::core::fri::SparseCircleEvaluation;
use crate::core::poly::circle::{CanonicCoset, CircleDomain, CircleEvaluation, SecureEvaluation};
use crate::core::poly::BitReversedOrder;
use crate::core::prover::VerificationError;
use crate::core::queries::SparseSubCircleDomain;
use crate::core::utils::bit_reverse_index;

pub trait QuotientOps: Backend {
/// Accumulates the quotients of the columns at the given domain.
Expand All @@ -28,7 +25,7 @@ pub trait QuotientOps: Backend {
columns: &[&CircleEvaluation<Self, BaseField, BitReversedOrder>],
random_coeff: SecureField,
samples: &[ColumnSampleBatch],
) -> SecureColumn<Self>;
) -> SecureEvaluation<Self>;
}

/// A batch of column samplings at a point.
Expand All @@ -41,19 +38,19 @@ pub struct ColumnSampleBatch {
impl ColumnSampleBatch {
/// Groups column opening by opening point.
/// # Arguments
/// opening: For each column, a vector of openings.
pub fn new(openings: &[&Vec<PointSample>]) -> Vec<Self> {
openings
/// opening: For each column, a vector of samples.
pub fn new(samples: &[&Vec<PointSample>]) -> Vec<Self> {
samples
.iter()
.enumerate()
.flat_map(|(column_index, openings)| {
openings.iter().map(move |opening| (column_index, opening))
.flat_map(|(column_index, samples)| {
samples.iter().map(move |opening| (column_index, opening))
})
.group_by(|(_, opening)| opening.point)
.into_iter()
.map(|(point, column_openings)| Self {
.map(|(point, column_samples)| Self {
point,
column_indices_and_values: column_openings
column_indices_and_values: column_samples
.map(|(column_index, opening)| (column_index, opening.value))
.collect(),
})
Expand All @@ -76,33 +73,32 @@ pub fn compute_fri_quotients<B: QuotientOps>(
.into_iter()
.sorted_by_key(|(log_size, _)| Reverse(*log_size))
.map(|(log_size, tuples)| {
let (columns, openings): (Vec<_>, Vec<_>) = multiunzip(tuples);
let (columns, samples): (Vec<_>, Vec<_>) = multiunzip(tuples);
let domain = CanonicCoset::new(log_size).circle_domain();
// TODO: slice.
let batched_openings = ColumnSampleBatch::new(&openings);
let values = B::accumulate_quotients(domain, &columns, random_coeff, &batched_openings);
SecureEvaluation { domain, values }
let batched_samples = ColumnSampleBatch::new(&samples);
B::accumulate_quotients(domain, &columns, random_coeff, &batched_samples)
})
.collect()
}

pub fn fri_answers(
column_log_sizes: Vec<u32>,
openings: &[Vec<PointSample>],
samples: &[Vec<PointSample>],
random_coeff: SecureField,
query_domain_per_log_size: BTreeMap<u32, SparseSubCircleDomain>,
queried_values_per_column: &[Vec<BaseField>],
) -> Result<Vec<SparseCircleEvaluation<SecureField>>, VerificationError> {
izip!(column_log_sizes, openings, queried_values_per_column)
izip!(column_log_sizes, samples, queried_values_per_column)
.group_by(|(c, ..)| *c)
.into_iter()
.sorted_by_key(|(log_size, _)| Reverse(*log_size))
.map(|(log_size, tuples)| {
let (_, openings, queried_valued_per_column): (Vec<_>, Vec<_>, Vec<_>) =
let (_, samples, queried_valued_per_column): (Vec<_>, Vec<_>, Vec<_>) =
multiunzip(tuples);
fri_answers_for_log_size(
log_size,
&openings,
&samples,
random_coeff,
&query_domain_per_log_size[&log_size],
&queried_valued_per_column,
Expand All @@ -113,13 +109,13 @@ pub fn fri_answers(

pub fn fri_answers_for_log_size(
log_size: u32,
openings: &[&Vec<PointSample>],
samples: &[&Vec<PointSample>],
random_coeff: SecureField,
query_domain: &SparseSubCircleDomain,
queried_values_per_column: &[&Vec<BaseField>],
) -> Result<SparseCircleEvaluation<SecureField>, VerificationError> {
let commitment_domain = CanonicCoset::new(log_size).circle_domain();
let batched_openings = ColumnSampleBatch::new(openings);
let batched_samples = ColumnSampleBatch::new(samples);
for x in queried_values_per_column {
if x.len() != query_domain.flatten().len() {
return Err(VerificationError::InvalidStructure);
Expand All @@ -141,20 +137,13 @@ pub fn fri_answers_for_log_size(
CircleEvaluation::new(domain, q.take(domain.size()).copied().collect_vec())
})
.collect_vec();
// TODO(spapini): bit reverse iterator.
let values = (0..domain.size())
.map(|row| {
let domain_point = domain.at(bit_reverse_index(row, log_size));
accumulate_row_quotients(
&batched_openings,
&column_evals.iter().collect_vec(),
row,
random_coeff,
domain_point,
)
})
.collect();
CircleEvaluation::new(domain, values)
CPUBackend::accumulate_quotients(
domain,
&column_evals.iter().collect_vec(),
random_coeff,
&batched_samples,
)
.to_cpu()
})
.collect(),
);
Expand Down

0 comments on commit 50ec779

Please sign in to comment.