Skip to content

Commit

Permalink
modify code to match coset fft
Browse files Browse the repository at this point in the history
  • Loading branch information
kevaundray committed Oct 9, 2024
1 parent 21ecbef commit ce42365
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 44 deletions.
23 changes: 18 additions & 5 deletions cryptography/erasure_codes/src/reed_solomon.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
use bls12_381::{batch_inversion::batch_inverse, ff::Field, Scalar};
use bls12_381::{
batch_inversion::batch_inverse,
ff::{Field, PrimeField},
Scalar,
};

use crate::errors::RSError;
use polynomial::{domain::Domain, poly_coeff::vanishing_poly};
use polynomial::{domain::Domain, poly_coeff::vanishing_poly, CosetFFT};

/// ErasurePattern is an abstraction created to capture the idea
/// that erasures do not appear in completely random locations.
Expand Down Expand Up @@ -62,6 +66,8 @@ pub struct ReedSolomon {
/// The domain that we will use to efficiently compute the vanishing polynomial with, when the erasure pattern
/// being used is `BlockSynchronizedErasures`.
block_size_domain: Domain,

fft_coset_gen: CosetFFT,
}

impl ReedSolomon {
Expand All @@ -77,13 +83,16 @@ impl ReedSolomon {

let block_size_domain = Domain::new(block_size);

let fft_coset_gen = CosetFFT::new(Scalar::MULTIPLICATIVE_GENERATOR);

Self {
poly_len,
evaluation_domain,
expansion_factor,
block_size,
block_size_domain,
num_blocks,
fft_coset_gen,
}
}

Expand Down Expand Up @@ -294,8 +303,12 @@ impl ReedSolomon {

let dz_poly = self.evaluation_domain.ifft_scalars(ez_eval);

let coset_dz_eval = self.evaluation_domain.coset_fft_scalars(dz_poly);
let mut inv_coset_z_x_eval = self.evaluation_domain.coset_fft_scalars(z_x);
let coset_dz_eval = self
.evaluation_domain
.coset_fft_scalars(dz_poly, &self.fft_coset_gen);
let mut inv_coset_z_x_eval = self
.evaluation_domain
.coset_fft_scalars(z_x, &self.fft_coset_gen);
// We know that none of the values will be zero since we are evaluating z_x
// over a coset, that we know it has no roots in.
batch_inverse(&mut inv_coset_z_x_eval);
Expand All @@ -307,7 +320,7 @@ impl ReedSolomon {

let coefficients = self
.evaluation_domain
.coset_ifft_scalars(coset_quotient_eval);
.coset_ifft_scalars(coset_quotient_eval, &self.fft_coset_gen);

// Check that the polynomial being returned has the correct degree
//
Expand Down
89 changes: 50 additions & 39 deletions cryptography/kzg_multi_open/src/fk20/verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ use crate::{
verification_key::VerificationKey,
};
use bls12_381::{
batch_inversion::batch_inverse, ff::Field, g1_batch_normalize, lincomb::g1_lincomb,
multi_pairings, reduce_bytes_to_scalar_bias, G1Point, G2Point, G2Prepared, Scalar,
ff::Field, g1_batch_normalize, lincomb::g1_lincomb, multi_pairings,
reduce_bytes_to_scalar_bias, G1Point, G2Point, G2Prepared, Scalar,
};
use polynomial::{domain::Domain, poly_coeff::poly_add};
use polynomial::{domain::Domain, poly_coeff::poly_add, CosetFFT};
use sha2::{Digest, Sha256};
use std::mem::size_of;

Expand Down Expand Up @@ -48,7 +48,7 @@ pub struct FK20Verifier {
//
pub coset_gens_pow_n: Vec<Scalar>,
//
inv_coset_gens_pow_n: Vec<Vec<Scalar>>,
coset_fft_gens: Vec<CosetFFT>,
}

impl FK20Verifier {
Expand Down Expand Up @@ -78,14 +78,7 @@ impl FK20Verifier {
.map(|&coset_gen| coset_gen.pow_vartime([n as u64]))
.collect();

let inv_coset_gens_pow_n: Vec<_> = coset_gens
.iter()
.map(|&coset_gen| {
let mut inv_coset_gen_powers = compute_powers(coset_gen, n);
batch_inverse(&mut inv_coset_gen_powers); // The coset generators are all roots of unity, so none of them will be zero
inv_coset_gen_powers
})
.collect();
let coset_fft_gens: Vec<_> = coset_gens.iter().map(|gen| CosetFFT::new(*gen)).collect();

Self {
verification_key,
Expand All @@ -94,7 +87,7 @@ impl FK20Verifier {
tau_pow_n,
neg_g2_gen,
coset_gens_pow_n,
inv_coset_gens_pow_n,
coset_fft_gens,
}
}

Expand Down Expand Up @@ -193,32 +186,13 @@ impl FK20Verifier {
.expect("number of row_commitments and number of weights should be the same");

// Linearly combine the interpolation polynomials using the same randomness `r`
let mut random_sum_interpolation_poly = Vec::new();
let coset_evals = bit_reversed_coset_evals.to_vec();
for (k, mut coset_eval) in coset_evals.into_iter().enumerate() {
// Reverse the order, so it matches the fft domain
reverse_bit_order(&mut coset_eval);

// Compute the interpolation polynomial
let ifft_scalars = self.coset_domain.ifft_scalars(coset_eval);
let inv_coset_gen_pow_n =
&self.inv_coset_gens_pow_n[bit_reversed_coset_indices[k] as usize];
let ifft_scalars: Vec<_> = ifft_scalars
.into_iter()
.zip(inv_coset_gen_pow_n)
.map(|(scalar, inv_h_k_pow)| scalar * inv_h_k_pow)
.collect();

// Scale the interpolation polynomial by the challenge
let scale_factor = r_powers[k];
let scaled_interpolation_poly = ifft_scalars
.into_iter()
.map(|coeff| coeff * scale_factor)
.collect::<Vec<_>>();

random_sum_interpolation_poly =
poly_add(random_sum_interpolation_poly, scaled_interpolation_poly);
}
let random_sum_interpolation_poly = compute_sum_interpolation_poly(
&self.coset_domain,
&self.coset_fft_gens,
&bit_reversed_coset_evals,
&bit_reversed_coset_indices,
&r_powers,
);
let comm_random_sum_interpolation_poly = self
.verification_key
.commit_g1(&random_sum_interpolation_poly);
Expand Down Expand Up @@ -337,6 +311,43 @@ fn compute_powers(value: Scalar, num_elements: usize) -> Vec<Scalar> {
powers
}

fn compute_sum_interpolation_poly(
coset_domain: &Domain,
coset_fft_gens: &[CosetFFT],
bit_reversed_coset_evals: &[Vec<Scalar>],
bit_reversed_coset_indices: &[CosetIndex],
r_powers: &[Scalar],
) -> Vec<Scalar> {
let mut random_sum_interpolation_poly = Vec::new();
let coset_evals = bit_reversed_coset_evals.to_vec();
for (k, mut coset_eval) in coset_evals.into_iter().enumerate() {
// Reverse the order, so it matches the fft domain
reverse_bit_order(&mut coset_eval);

// Compute the interpolation polynomial
let index = bit_reversed_coset_indices[k] as usize;
let ifft_scalars = coset_domain.coset_ifft_scalars(coset_eval, &coset_fft_gens[index]);
// let inv_coset_gen_pow_n = &inv_coset_gens_pow_n[bit_reversed_coset_indices[k] as usize];
// let ifft_scalars: Vec<_> = ifft_scalars
// .into_iter()
// .zip(inv_coset_gen_pow_n)
// .map(|(scalar, inv_h_k_pow)| scalar * inv_h_k_pow)
// .collect();

// Scale the interpolation polynomial by the challenge
let scale_factor = r_powers[k];
let scaled_interpolation_poly = ifft_scalars
.into_iter()
.map(|coeff| coeff * scale_factor)
.collect::<Vec<_>>();

random_sum_interpolation_poly =
poly_add(random_sum_interpolation_poly, scaled_interpolation_poly);
}

random_sum_interpolation_poly
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down

0 comments on commit ce42365

Please sign in to comment.