mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-08 08:43:06 +00:00
Finish recursive verifier
This commit is contained in:
parent
88c58c3227
commit
670e48380a
@ -58,81 +58,78 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
proof: &FriProofTarget<D>,
|
||||
challenger: &mut RecursiveChallenger,
|
||||
config: &FriConfig,
|
||||
) -> Result<()> {
|
||||
) {
|
||||
let mut inputs = challenger.get_hash(self).elements.to_vec();
|
||||
inputs.push(proof.pow_witness);
|
||||
|
||||
let hash = self.hash_n_to_m(inputs, 1, false)[0];
|
||||
self.assert_trailing_zeros::<64>(hash, config.proof_of_work_bits);
|
||||
|
||||
Ok(())
|
||||
self.assert_trailing_zeros::<2>(hash, config.proof_of_work_bits);
|
||||
}
|
||||
|
||||
// pub fn verify_fri_proof<const D: usize>(
|
||||
// purported_degree_log: usize,
|
||||
// // 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>],
|
||||
// proof: &FriProof<F, D>,
|
||||
// challenger: &mut Challenger<F>,
|
||||
// config: &FriConfig,
|
||||
// ) -> Result<()> {
|
||||
// let total_arities = config.reduction_arity_bits.iter().sum::<usize>();
|
||||
// ensure!(
|
||||
// purported_degree_log
|
||||
// == log2_strict(proof.final_poly.len()) + total_arities - config.rate_bits,
|
||||
// "Final polynomial has wrong degree."
|
||||
// );
|
||||
//
|
||||
// // Size of the LDE domain.
|
||||
// let n = proof.final_poly.len() << total_arities;
|
||||
//
|
||||
// // Recover the random betas used in the FRI reductions.
|
||||
// let betas = proof
|
||||
// .commit_phase_merkle_roots
|
||||
// .iter()
|
||||
// .map(|root| {
|
||||
// challenger.observe_hash(root);
|
||||
// challenger.get_extension_challenge()
|
||||
// })
|
||||
// .collect::<Vec<_>>();
|
||||
// challenger.observe_extension_elements(&proof.final_poly.coeffs);
|
||||
//
|
||||
// // Check PoW.
|
||||
// fri_verify_proof_of_work(proof, challenger, config)?;
|
||||
//
|
||||
// // Check that parameters are coherent.
|
||||
// ensure!(
|
||||
// config.num_query_rounds == proof.query_round_proofs.len(),
|
||||
// "Number of query rounds does not match config."
|
||||
// );
|
||||
// ensure!(
|
||||
// !config.reduction_arity_bits.is_empty(),
|
||||
// "Number of reductions should be non-zero."
|
||||
// );
|
||||
//
|
||||
// for round_proof in &proof.query_round_proofs {
|
||||
// fri_verifier_query_round(
|
||||
// os,
|
||||
// zeta,
|
||||
// alpha,
|
||||
// initial_merkle_roots,
|
||||
// &proof,
|
||||
// challenger,
|
||||
// n,
|
||||
// &betas,
|
||||
// round_proof,
|
||||
// config,
|
||||
// )?;
|
||||
// }
|
||||
//
|
||||
// Ok(())
|
||||
// }
|
||||
//
|
||||
pub fn verify_fri_proof(
|
||||
&mut self,
|
||||
purported_degree_log: usize,
|
||||
// Openings of the PLONK polynomials.
|
||||
os: &OpeningSetTarget<D>,
|
||||
// Point at which the PLONK polynomials are opened.
|
||||
zeta: ExtensionTarget<D>,
|
||||
// Scaling factor to combine polynomials.
|
||||
alpha: ExtensionTarget<D>,
|
||||
initial_merkle_roots: &[HashTarget],
|
||||
proof: &FriProofTarget<D>,
|
||||
challenger: &mut RecursiveChallenger,
|
||||
config: &FriConfig,
|
||||
) {
|
||||
let total_arities = config.reduction_arity_bits.iter().sum::<usize>();
|
||||
debug_assert_eq!(
|
||||
purported_degree_log,
|
||||
log2_strict(proof.final_poly.len()) + total_arities - config.rate_bits,
|
||||
"Final polynomial has wrong degree."
|
||||
);
|
||||
|
||||
// Size of the LDE domain.
|
||||
let n = proof.final_poly.len() << total_arities;
|
||||
|
||||
// Recover the random betas used in the FRI reductions.
|
||||
let betas = proof
|
||||
.commit_phase_merkle_roots
|
||||
.iter()
|
||||
.map(|root| {
|
||||
challenger.observe_hash(root);
|
||||
challenger.get_extension_challenge(self)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
challenger.observe_extension_elements(&proof.final_poly.0);
|
||||
|
||||
// Check PoW.
|
||||
self.fri_verify_proof_of_work(proof, challenger, config);
|
||||
|
||||
// Check that parameters are coherent.
|
||||
debug_assert_eq!(
|
||||
config.num_query_rounds,
|
||||
proof.query_round_proofs.len(),
|
||||
"Number of query rounds does not match config."
|
||||
);
|
||||
debug_assert!(
|
||||
!config.reduction_arity_bits.is_empty(),
|
||||
"Number of reductions should be non-zero."
|
||||
);
|
||||
|
||||
for round_proof in &proof.query_round_proofs {
|
||||
self.fri_verifier_query_round(
|
||||
os,
|
||||
zeta,
|
||||
alpha,
|
||||
initial_merkle_roots,
|
||||
&proof,
|
||||
challenger,
|
||||
n,
|
||||
&betas,
|
||||
round_proof,
|
||||
config,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn fri_verify_initial_proof(
|
||||
&mut self,
|
||||
@ -265,7 +262,7 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
betas: &[ExtensionTarget<D>],
|
||||
round_proof: &FriQueryRoundTarget<D>,
|
||||
config: &FriConfig,
|
||||
) -> Result<()> {
|
||||
) {
|
||||
let n_log = log2_strict(n);
|
||||
let mut evaluations: Vec<Vec<ExtensionTarget<D>>> = Vec::new();
|
||||
// TODO: Do we need to range check `x_index` to a target smaller than `p`?
|
||||
@ -312,14 +309,15 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
let mut evals = round_proof.steps[i].evals.clone();
|
||||
// Insert P(y) into the evaluation vector, since it wasn't included by the prover.
|
||||
let (low_x_index, high_x_index) = self.split_low_high(x_index, arity_bits);
|
||||
// TODO: Uncomment this.
|
||||
// evals.insert(x_index & (arity - 1), e_x);
|
||||
// evaluations.push(evals);
|
||||
// self.verify_merkle_proof(
|
||||
// flatten_target(&evaluations[i]),
|
||||
// x_index >> arity_bits,
|
||||
// proof.commit_phase_merkle_roots[i],
|
||||
// &round_proof.steps[i].merkle_proof,
|
||||
// )?;
|
||||
evaluations.push(evals);
|
||||
self.verify_merkle_proof(
|
||||
flatten_target(&evaluations[i]),
|
||||
high_x_index,
|
||||
proof.commit_phase_merkle_roots[i],
|
||||
&round_proof.steps[i].merkle_proof,
|
||||
);
|
||||
|
||||
if i > 0 {
|
||||
// Update the point x to x^arity.
|
||||
@ -349,7 +347,5 @@ impl<F: Extendable<D>, const D: usize> CircuitBuilder<F, D> {
|
||||
// to the one sent by the prover.
|
||||
let eval = proof.final_poly.eval_scalar(self, subgroup_x);
|
||||
self.assert_equal_extension(eval, purported_eval);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,6 +6,10 @@ use crate::target::Target;
|
||||
pub struct PolynomialCoeffsExtTarget<const D: usize>(pub Vec<ExtensionTarget<D>>);
|
||||
|
||||
impl<const D: usize> PolynomialCoeffsExtTarget<D> {
|
||||
pub fn len(&self) -> usize {
|
||||
self.0.len()
|
||||
}
|
||||
|
||||
pub fn eval_scalar<F: Extendable<D>>(
|
||||
&self,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
use crate::circuit_builder::CircuitBuilder;
|
||||
use crate::field::extension_field::target::ExtensionTarget;
|
||||
use crate::field::extension_field::{Extendable, FieldExtension};
|
||||
use crate::field::field::Field;
|
||||
use crate::hash::{permute, SPONGE_RATE, SPONGE_WIDTH};
|
||||
use crate::proof::{Hash, HashTarget, OpeningSet};
|
||||
use crate::target::Target;
|
||||
use std::convert::TryInto;
|
||||
|
||||
/// Observes prover messages, and generates challenges by hashing the transcript.
|
||||
#[derive(Clone)]
|
||||
@ -41,9 +43,7 @@ impl<F: Field> Challenger<F> {
|
||||
where
|
||||
F: Extendable<D>,
|
||||
{
|
||||
for &e in &element.to_basefield_array() {
|
||||
self.observe_element(e);
|
||||
}
|
||||
self.observe_elements(&element.to_basefield_array());
|
||||
}
|
||||
|
||||
pub fn observe_elements(&mut self, elements: &[F]) {
|
||||
@ -177,7 +177,7 @@ impl<F: Field> Default for Challenger<F> {
|
||||
}
|
||||
|
||||
/// A recursive version of `Challenger`.
|
||||
pub(crate) struct RecursiveChallenger {
|
||||
pub struct RecursiveChallenger {
|
||||
sponge_state: [Target; SPONGE_WIDTH],
|
||||
input_buffer: Vec<Target>,
|
||||
output_buffer: Vec<Target>,
|
||||
@ -212,6 +212,16 @@ impl RecursiveChallenger {
|
||||
self.observe_elements(&hash.elements)
|
||||
}
|
||||
|
||||
pub fn observe_extension_element<const D: usize>(&mut self, element: ExtensionTarget<D>) {
|
||||
self.observe_elements(&element.0);
|
||||
}
|
||||
|
||||
pub fn observe_extension_elements<const D: usize>(&mut self, elements: &[ExtensionTarget<D>]) {
|
||||
for &element in elements {
|
||||
self.observe_extension_element(element);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_challenge<F: Extendable<D>, const D: usize>(
|
||||
&mut self,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
@ -269,6 +279,13 @@ impl RecursiveChallenger {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_extension_challenge<F: Extendable<D>, const D: usize>(
|
||||
&mut self,
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
) -> ExtensionTarget<D> {
|
||||
self.get_n_challenges(builder, D).try_into().unwrap()
|
||||
}
|
||||
|
||||
/// Absorb any buffered inputs. After calling this, the input buffer will be empty.
|
||||
fn absorb_buffered_inputs<F: Extendable<D>, const D: usize>(
|
||||
&mut self,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user