-
Notifications
You must be signed in to change notification settings - Fork 312
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
Check base field #55
Check base field #55
Changes from 11 commits
845382b
abc0ca3
6ee9cea
d882283
e09a617
59dfe5d
2794cb9
b465bcd
482b400
60e9464
9eb35c3
7334341
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,13 @@ | ||
use crate::field::extension_field::{flatten, Extendable, FieldExtension}; | ||
use crate::field::extension_field::{flatten, Extendable, FieldExtension, OEF}; | ||
use crate::field::field::Field; | ||
use crate::field::lagrange::{barycentric_weights, interpolant, interpolate}; | ||
use crate::fri::FriConfig; | ||
use crate::hash::hash_n_to_1; | ||
use crate::merkle_proofs::verify_merkle_proof; | ||
use crate::plonk_challenger::Challenger; | ||
use crate::plonk_common::reduce_with_powers; | ||
use crate::polynomial::commitment::SALT_SIZE; | ||
use crate::polynomial::polynomial::PolynomialCoeffs; | ||
use crate::proof::{FriInitialTreeProof, FriProof, FriQueryRound, Hash}; | ||
use crate::proof::{FriInitialTreeProof, FriProof, FriQueryRound, Hash, OpeningSet}; | ||
use crate::util::{log2_strict, reverse_bits, reverse_index_bits_in_place}; | ||
use anyhow::{ensure, Result}; | ||
|
||
|
@@ -65,8 +65,10 @@ fn fri_verify_proof_of_work<F: Field + Extendable<D>, const D: usize>( | |
|
||
pub fn verify_fri_proof<F: Field + Extendable<D>, const D: usize>( | ||
purported_degree_log: usize, | ||
// Point-evaluation pairs for polynomial commitments. | ||
points: &[(F::Extension, F::Extension)], | ||
// Openings of the PLONK polynomials. | ||
os: &OpeningSet<F, D>, | ||
// Point at which the PLONK polynomials are opened. | ||
zeta: F::Extension, | ||
// Scaling factor to combine polynomials. | ||
alpha: F::Extension, | ||
initial_merkle_roots: &[Hash<F>], | ||
|
@@ -108,11 +110,10 @@ pub fn verify_fri_proof<F: Field + Extendable<D>, const D: usize>( | |
"Number of reductions should be non-zero." | ||
); | ||
|
||
let interpolant = interpolant(points); | ||
for round_proof in &proof.query_round_proofs { | ||
fri_verifier_query_round( | ||
&interpolant, | ||
points, | ||
os, | ||
zeta, | ||
alpha, | ||
initial_merkle_roots, | ||
&proof, | ||
|
@@ -142,29 +143,84 @@ fn fri_verify_initial_proof<F: Field>( | |
fn fri_combine_initial<F: Field + Extendable<D>, const D: usize>( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel this is getting pretty complicated; I tried to refactor a bit here, though with limited success. I guess there's only so much we can do.
What do you think? Feel free to pick any changes you like and ignore the rest. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the tweaks, they're all great! I've merged them all. |
||
proof: &FriInitialTreeProof<F>, | ||
alpha: F::Extension, | ||
interpolant: &PolynomialCoeffs<F::Extension>, | ||
points: &[(F::Extension, F::Extension)], | ||
os: &OpeningSet<F, D>, | ||
zeta: F::Extension, | ||
subgroup_x: F, | ||
config: &FriConfig, | ||
) -> F::Extension { | ||
let e = proof | ||
.evals_proofs | ||
assert!(D > 1, "Not implemented for D=1."); | ||
let degree_log = proof.evals_proofs[0].1.siblings.len() - config.rate_bits; | ||
|
||
let mut cur_alpha = F::Extension::ONE; | ||
|
||
let mut poly_count = 0; | ||
let mut e = F::Extension::ZERO; | ||
|
||
let ev = vec![0, 1, 4] | ||
.iter() | ||
.flat_map(|&i| { | ||
let v = &proof.evals_proofs[i].0; | ||
&v[..v.len() - if config.blinding[i] { SALT_SIZE } else { 0 }] | ||
}) | ||
.rev() | ||
.fold(F::Extension::ZERO, |acc, &e| { | ||
poly_count += 1; | ||
alpha * acc + e.into() | ||
}); | ||
let composition_eval = [&os.constants, &os.plonk_sigmas, &os.quotient_polys] | ||
.iter() | ||
.enumerate() | ||
.flat_map(|(i, (v, _))| &v[..v.len() - if config.blinding[i] { SALT_SIZE } else { 0 }]) | ||
.flat_map(|v| v.iter()) | ||
.rev() | ||
.fold(F::Extension::ZERO, |acc, &e| alpha * acc + e.into()); | ||
let numerator = e - interpolant.eval(subgroup_x.into()); | ||
let denominator = points | ||
.fold(F::Extension::ZERO, |acc, &e| acc * alpha + e); | ||
let numerator = ev - composition_eval; | ||
let denominator = F::Extension::from_basefield(subgroup_x) - zeta; | ||
e += cur_alpha * numerator / denominator; | ||
cur_alpha = alpha.exp(poly_count); | ||
|
||
let ev = proof.evals_proofs[3].0 | ||
[..proof.evals_proofs[3].0.len() - if config.blinding[3] { SALT_SIZE } else { 0 }] | ||
.iter() | ||
.rev() | ||
.fold(F::Extension::ZERO, |acc, &e| { | ||
poly_count += 1; | ||
alpha * acc + e.into() | ||
}); | ||
let zeta_right = F::Extension::primitive_root_of_unity(degree_log) * zeta; | ||
let zs_interpol = interpolant(&[ | ||
(zeta, reduce_with_powers(&os.plonk_zs, alpha)), | ||
(zeta_right, reduce_with_powers(&os.plonk_zs_right, alpha)), | ||
]); | ||
let numerator = ev - zs_interpol.eval(subgroup_x.into()); | ||
let denominator = (F::Extension::from_basefield(subgroup_x) - zeta) | ||
* (F::Extension::from_basefield(subgroup_x) - zeta_right); | ||
e += cur_alpha * numerator / denominator; | ||
cur_alpha = alpha.exp(poly_count); | ||
|
||
let ev = proof.evals_proofs[2].0 | ||
[..proof.evals_proofs[2].0.len() - if config.blinding[2] { SALT_SIZE } else { 0 }] | ||
.iter() | ||
.map(|&(x, _)| F::Extension::from_basefield(subgroup_x) - x) | ||
.product(); | ||
numerator / denominator | ||
.rev() | ||
.fold(F::Extension::ZERO, |acc, &e| { | ||
poly_count += 1; | ||
alpha * acc + e.into() | ||
}); | ||
let zeta_frob = zeta.frobenius(); | ||
let wire_evals_frob = os.wires.iter().map(|e| e.frobenius()).collect::<Vec<_>>(); | ||
let wires_interpol = interpolant(&[ | ||
(zeta, reduce_with_powers(&os.wires, alpha)), | ||
(zeta_frob, reduce_with_powers(&wire_evals_frob, alpha)), | ||
]); | ||
let numerator = ev - wires_interpol.eval(subgroup_x.into()); | ||
let denominator = (F::Extension::from_basefield(subgroup_x) - zeta) | ||
* (F::Extension::from_basefield(subgroup_x) - zeta_frob); | ||
e += cur_alpha * numerator / denominator; | ||
|
||
e | ||
} | ||
|
||
fn fri_verifier_query_round<F: Field + Extendable<D>, const D: usize>( | ||
interpolant: &PolynomialCoeffs<F::Extension>, | ||
points: &[(F::Extension, F::Extension)], | ||
os: &OpeningSet<F, D>, | ||
zeta: F::Extension, | ||
alpha: F::Extension, | ||
initial_merkle_roots: &[Hash<F>], | ||
proof: &FriProof<F, D>, | ||
|
@@ -195,8 +251,8 @@ fn fri_verifier_query_round<F: Field + Extendable<D>, const D: usize>( | |
fri_combine_initial( | ||
&round_proof.initial_trees_proof, | ||
alpha, | ||
interpolant, | ||
points, | ||
os, | ||
zeta, | ||
subgroup_x, | ||
config, | ||
) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a bit annoying having to remove these tests, but since the FRI API is now very PLONK specific it doesn't make sense to update these tests since they'll end up being the same as those in
commitment.rs
.If we need FRI for something other that polynomial commitments in the future, we could add some kind of
FriInitialData
trait and make the FRI API more general.