Added PrecomputedReducedEvals struct

This commit is contained in:
wborgeaud 2021-07-19 20:46:18 +02:00
parent a9e5f1e4e2
commit 69dc14f88a

View File

@ -8,7 +8,7 @@ use crate::fri::FriConfig;
use crate::hash::hash_n_to_1; use crate::hash::hash_n_to_1;
use crate::merkle_proofs::verify_merkle_proof; use crate::merkle_proofs::verify_merkle_proof;
use crate::plonk_challenger::Challenger; use crate::plonk_challenger::Challenger;
use crate::plonk_common::PlonkPolynomials; use crate::plonk_common::{reduce_with_powers, PlonkPolynomials};
use crate::proof::{FriInitialTreeProof, FriProof, FriQueryRound, Hash, OpeningSet}; use crate::proof::{FriInitialTreeProof, FriProof, FriQueryRound, Hash, OpeningSet};
use crate::util::scaling::ReducingFactor; use crate::util::scaling::ReducingFactor;
use crate::util::{log2_strict, reverse_bits, reverse_index_bits_in_place}; use crate::util::{log2_strict, reverse_bits, reverse_index_bits_in_place};
@ -112,11 +112,13 @@ pub fn verify_fri_proof<F: Field + Extendable<D>, const D: usize>(
"Number of reductions should be non-zero." "Number of reductions should be non-zero."
); );
let precomputed_reduced_evals = PrecomputedReducedEvals::from_os_and_alpha(&os, alpha);
for round_proof in &proof.query_round_proofs { for round_proof in &proof.query_round_proofs {
fri_verifier_query_round( fri_verifier_query_round(
os, os,
zeta, zeta,
alpha, alpha,
precomputed_reduced_evals,
initial_merkle_roots, initial_merkle_roots,
&proof, &proof,
challenger, challenger,
@ -142,12 +144,44 @@ fn fri_verify_initial_proof<F: Field>(
Ok(()) Ok(())
} }
/// Holds the reduced (by `alpha`) evaluations at `zeta` for the polynomial opened just at
/// zeta, for `Z` at zeta and for `Z` at `g*zeta`.
#[derive(Copy, Clone)]
struct PrecomputedReducedEvals<F: Extendable<D>, const D: usize> {
pub single: F::Extension,
pub zs: F::Extension,
pub zs_right: F::Extension,
}
impl<F: Extendable<D>, const D: usize> PrecomputedReducedEvals<F, D> {
fn from_os_and_alpha(os: &OpeningSet<F, D>, alpha: F::Extension) -> Self {
let mut alpha = ReducingFactor::new(alpha);
let single = alpha.reduce(
os.constants
.iter()
.chain(&os.plonk_sigmas)
.chain(&os.wires)
.chain(&os.quotient_polys)
.chain(&os.partial_products),
);
let zs = alpha.reduce(os.plonk_zs.iter());
let zs_right = alpha.reduce(os.plonk_zs_right.iter());
Self {
single,
zs,
zs_right,
}
}
}
fn fri_combine_initial<F: Field + Extendable<D>, const D: usize>( fn fri_combine_initial<F: Field + Extendable<D>, const D: usize>(
proof: &FriInitialTreeProof<F>, proof: &FriInitialTreeProof<F>,
alpha: F::Extension, alpha: F::Extension,
os: &OpeningSet<F, D>, os: &OpeningSet<F, D>,
zeta: F::Extension, zeta: F::Extension,
subgroup_x: F, subgroup_x: F,
precomputed_reduced_evals: PrecomputedReducedEvals<F, D>,
common_data: &CommonCircuitData<F, D>, common_data: &CommonCircuitData<F, D>,
) -> F::Extension { ) -> F::Extension {
let config = &common_data.config; let config = &common_data.config;
@ -174,19 +208,8 @@ fn fri_combine_initial<F: Field + Extendable<D>, const D: usize>(
[common_data.partial_products_range()], [common_data.partial_products_range()],
) )
.map(|&e| F::Extension::from_basefield(e)); .map(|&e| F::Extension::from_basefield(e));
let single_openings = os let single_composition_eval = alpha.reduce(single_evals);
.constants let single_numerator = single_composition_eval - precomputed_reduced_evals.single;
.iter()
.chain(&os.plonk_sigmas)
.chain(&os.wires)
.chain(&os.quotient_polys)
.chain(&os.partial_products);
let single_diffs = single_evals
.into_iter()
.zip(single_openings)
.map(|(e, &o)| e - o)
.collect::<Vec<_>>();
let single_numerator = alpha.reduce(single_diffs.iter());
let single_denominator = subgroup_x - zeta; let single_denominator = subgroup_x - zeta;
sum += single_numerator / single_denominator; sum += single_numerator / single_denominator;
alpha.reset(); alpha.reset();
@ -201,8 +224,8 @@ fn fri_combine_initial<F: Field + Extendable<D>, const D: usize>(
let zeta_right = F::Extension::primitive_root_of_unity(degree_log) * zeta; let zeta_right = F::Extension::primitive_root_of_unity(degree_log) * zeta;
let zs_interpol = interpolate2( let zs_interpol = interpolate2(
[ [
(zeta, alpha.clone().reduce(os.plonk_zs.iter())), (zeta, precomputed_reduced_evals.zs),
(zeta_right, alpha.reduce(os.plonk_zs_right.iter())), (zeta_right, precomputed_reduced_evals.zs_right),
], ],
subgroup_x, subgroup_x,
); );
@ -218,6 +241,7 @@ fn fri_verifier_query_round<F: Field + Extendable<D>, const D: usize>(
os: &OpeningSet<F, D>, os: &OpeningSet<F, D>,
zeta: F::Extension, zeta: F::Extension,
alpha: F::Extension, alpha: F::Extension,
precomputed_reduced_evals: PrecomputedReducedEvals<F, D>,
initial_merkle_roots: &[Hash<F>], initial_merkle_roots: &[Hash<F>],
proof: &FriProof<F, D>, proof: &FriProof<F, D>,
challenger: &mut Challenger<F>, challenger: &mut Challenger<F>,
@ -251,6 +275,7 @@ fn fri_verifier_query_round<F: Field + Extendable<D>, const D: usize>(
os, os,
zeta, zeta,
subgroup_x, subgroup_x,
precomputed_reduced_evals,
common_data, common_data,
) )
} else { } else {