Move some FRI stuff into the FRI module (#471)

I think it would be nice to eventually have separate crates for IOP, FRI, PLONK, etc. This is one step toward that.
This commit is contained in:
Daniel Lubarov 2022-02-06 23:13:12 -08:00 committed by GitHub
parent 8f21fddd04
commit a43e138f57
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 157 additions and 134 deletions

View File

@ -0,0 +1,81 @@
use plonky2_field::extension_field::Extendable;
use plonky2_field::polynomial::PolynomialCoeffs;
use crate::fri::proof::FriChallenges;
use crate::fri::structure::{FriOpenings, FriOpeningsTarget};
use crate::fri::FriConfig;
use crate::hash::hash_types::RichField;
use crate::hash::merkle_tree::MerkleCap;
use crate::iop::challenger::{Challenger, RecursiveChallenger};
use crate::plonk::config::{AlgebraicHasher, GenericConfig, Hasher};
impl<F: RichField, H: Hasher<F>> Challenger<F, H> {
pub fn observe_openings<const D: usize>(&mut self, openings: &FriOpenings<F, D>)
where
F: RichField + Extendable<D>,
{
for v in &openings.batches {
self.observe_extension_elements(&v.values);
}
}
pub fn fri_challenges<C: GenericConfig<D, F = F>, const D: usize>(
&mut self,
commit_phase_merkle_caps: &[MerkleCap<F, C::Hasher>],
final_poly: &PolynomialCoeffs<F::Extension>,
pow_witness: F,
degree_bits: usize,
config: &FriConfig,
) -> FriChallenges<F, D>
where
F: RichField + Extendable<D>,
{
let num_fri_queries = config.num_query_rounds;
let lde_size = 1 << (degree_bits + config.rate_bits);
// Scaling factor to combine polynomials.
let fri_alpha = self.get_extension_challenge::<D>();
// Recover the random betas used in the FRI reductions.
let fri_betas = commit_phase_merkle_caps
.iter()
.map(|cap| {
self.observe_cap(cap);
self.get_extension_challenge::<D>()
})
.collect();
self.observe_extension_elements(&final_poly.coeffs);
let fri_pow_response = C::InnerHasher::hash_no_pad(
&self
.get_hash()
.elements
.iter()
.copied()
.chain(Some(pow_witness))
.collect::<Vec<_>>(),
)
.elements[0];
let fri_query_indices = (0..num_fri_queries)
.map(|_| self.get_challenge().to_canonical_u64() as usize % lde_size)
.collect();
FriChallenges {
fri_alpha,
fri_betas,
fri_pow_response,
fri_query_indices,
}
}
}
impl<F: RichField + Extendable<D>, H: AlgebraicHasher<F>, const D: usize>
RecursiveChallenger<F, H, D>
{
pub fn observe_openings(&mut self, openings: &FriOpeningsTarget<D>) {
for v in &openings.batches {
self.observe_extension_elements(&v.values);
}
}
}

View File

@ -1,5 +1,6 @@
use crate::fri::reduction_strategies::FriReductionStrategy;
mod challenges;
pub mod oracle;
pub mod proof;
pub mod prover;
@ -7,6 +8,7 @@ pub mod recursive_verifier;
pub mod reduction_strategies;
pub mod structure;
pub mod verifier;
pub mod witness_util;
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct FriConfig {

View File

@ -0,0 +1,71 @@
use itertools::Itertools;
use plonky2_field::extension_field::Extendable;
use crate::fri::proof::{FriProof, FriProofTarget};
use crate::hash::hash_types::RichField;
use crate::iop::witness::Witness;
use crate::plonk::config::AlgebraicHasher;
/// Set the targets in a `FriProofTarget` to their corresponding values in a `FriProof`.
pub fn set_fri_proof_target<F, W, H, const D: usize>(
witness: &mut W,
fri_proof: &FriProof<F, H, D>,
fri_proof_target: &FriProofTarget<D>,
) where
F: RichField + Extendable<D>,
W: Witness<F> + ?Sized,
H: AlgebraicHasher<F>,
{
witness.set_target(fri_proof_target.pow_witness, fri_proof.pow_witness);
for (&t, &x) in fri_proof_target
.final_poly
.0
.iter()
.zip_eq(&fri_proof.final_poly.coeffs)
{
witness.set_extension_target(t, x);
}
for (t, x) in fri_proof_target
.commit_phase_merkle_caps
.iter()
.zip_eq(&fri_proof.commit_phase_merkle_caps)
{
witness.set_cap_target(t, x);
}
for (qt, q) in fri_proof_target
.query_round_proofs
.iter()
.zip_eq(&fri_proof.query_round_proofs)
{
for (at, a) in qt
.initial_trees_proof
.evals_proofs
.iter()
.zip_eq(&q.initial_trees_proof.evals_proofs)
{
for (&t, &x) in at.0.iter().zip_eq(&a.0) {
witness.set_target(t, x);
}
for (&t, &x) in at.1.siblings.iter().zip_eq(&a.1.siblings) {
witness.set_hash_target(t, x);
}
}
for (st, s) in qt.steps.iter().zip_eq(&q.steps) {
for (&t, &x) in st.evals.iter().zip_eq(&s.evals) {
witness.set_extension_target(t, x);
}
for (&t, &x) in st
.merkle_proof
.siblings
.iter()
.zip_eq(&s.merkle_proof.siblings)
{
witness.set_hash_target(t, x);
}
}
}
}

View File

@ -2,11 +2,7 @@ use std::convert::TryInto;
use std::marker::PhantomData;
use plonky2_field::extension_field::{Extendable, FieldExtension};
use plonky2_field::polynomial::PolynomialCoeffs;
use crate::fri::proof::FriChallenges;
use crate::fri::structure::{FriOpenings, FriOpeningsTarget};
use crate::fri::FriConfig;
use crate::hash::hash_types::RichField;
use crate::hash::hash_types::{HashOut, HashOutTarget, MerkleCapTarget};
use crate::hash::hashing::{PlonkyPermutation, SPONGE_RATE, SPONGE_WIDTH};
@ -14,7 +10,7 @@ use crate::hash::merkle_tree::MerkleCap;
use crate::iop::ext_target::ExtensionTarget;
use crate::iop::target::Target;
use crate::plonk::circuit_builder::CircuitBuilder;
use crate::plonk::config::{AlgebraicHasher, GenericConfig, GenericHashOut, Hasher};
use crate::plonk::config::{AlgebraicHasher, GenericHashOut, Hasher};
/// Observes prover messages, and generates challenges by hashing the transcript, a la Fiat-Shamir.
#[derive(Clone)]
@ -72,15 +68,6 @@ impl<F: RichField, H: Hasher<F>> Challenger<F, H> {
}
}
pub fn observe_openings<const D: usize>(&mut self, openings: &FriOpenings<F, D>)
where
F: RichField + Extendable<D>,
{
for v in &openings.batches {
self.observe_extension_elements(&v.values);
}
}
pub fn observe_hash<OH: Hasher<F>>(&mut self, hash: OH::Hash) {
self.observe_elements(&hash.to_vec())
}
@ -138,56 +125,6 @@ impl<F: RichField, H: Hasher<F>> Challenger<F, H> {
.collect()
}
pub fn fri_challenges<C: GenericConfig<D, F = F>, const D: usize>(
&mut self,
commit_phase_merkle_caps: &[MerkleCap<F, C::Hasher>],
final_poly: &PolynomialCoeffs<F::Extension>,
pow_witness: F,
degree_bits: usize,
config: &FriConfig,
) -> FriChallenges<F, D>
where
F: RichField + Extendable<D>,
{
let num_fri_queries = config.num_query_rounds;
let lde_size = 1 << (degree_bits + config.rate_bits);
// Scaling factor to combine polynomials.
let fri_alpha = self.get_extension_challenge::<D>();
// Recover the random betas used in the FRI reductions.
let fri_betas = commit_phase_merkle_caps
.iter()
.map(|cap| {
self.observe_cap(cap);
self.get_extension_challenge::<D>()
})
.collect();
self.observe_extension_elements(&final_poly.coeffs);
let fri_pow_response = C::InnerHasher::hash_no_pad(
&self
.get_hash()
.elements
.iter()
.copied()
.chain(Some(pow_witness))
.collect::<Vec<_>>(),
)
.elements[0];
let fri_query_indices = (0..num_fri_queries)
.map(|_| self.get_challenge().to_canonical_u64() as usize % lde_size)
.collect();
FriChallenges {
fri_alpha,
fri_betas,
fri_pow_response,
fri_query_indices,
}
}
/// Absorb any buffered inputs. After calling this, the input buffer will be empty.
fn absorb_buffered_inputs(&mut self) {
if self.input_buffer.is_empty() {
@ -251,12 +188,6 @@ impl<F: RichField + Extendable<D>, H: AlgebraicHasher<F>, const D: usize>
}
}
pub fn observe_openings(&mut self, openings: &FriOpeningsTarget<D>) {
for v in &openings.batches {
self.observe_extension_elements(&v.values);
}
}
pub fn observe_hash(&mut self, hash: &HashOutTarget) {
self.observe_elements(&hash.elements)
}

View File

@ -5,7 +5,7 @@ use num::{BigUint, FromPrimitive, Zero};
use plonky2_field::extension_field::{Extendable, FieldExtension};
use plonky2_field::field_types::Field;
use crate::fri::proof::{FriProof, FriProofTarget};
use crate::fri::witness_util::set_fri_proof_target;
use crate::gadgets::arithmetic_u32::U32Target;
use crate::gadgets::biguint::BigUintTarget;
use crate::gadgets::nonnative::NonNativeTarget;
@ -258,69 +258,7 @@ pub trait Witness<F: Field> {
self.set_extension_target(t, x);
}
self.set_fri_proof_target(&proof.opening_proof, &proof_target.opening_proof);
}
/// Set the targets in a `FriProofTarget` to their corresponding values in a `FriProof`.
fn set_fri_proof_target<H: AlgebraicHasher<F>, const D: usize>(
&mut self,
fri_proof: &FriProof<F, H, D>,
fri_proof_target: &FriProofTarget<D>,
) where
F: RichField + Extendable<D>,
{
self.set_target(fri_proof_target.pow_witness, fri_proof.pow_witness);
for (&t, &x) in fri_proof_target
.final_poly
.0
.iter()
.zip_eq(&fri_proof.final_poly.coeffs)
{
self.set_extension_target(t, x);
}
for (t, x) in fri_proof_target
.commit_phase_merkle_caps
.iter()
.zip_eq(&fri_proof.commit_phase_merkle_caps)
{
self.set_cap_target(t, x);
}
for (qt, q) in fri_proof_target
.query_round_proofs
.iter()
.zip_eq(&fri_proof.query_round_proofs)
{
for (at, a) in qt
.initial_trees_proof
.evals_proofs
.iter()
.zip_eq(&q.initial_trees_proof.evals_proofs)
{
for (&t, &x) in at.0.iter().zip_eq(&a.0) {
self.set_target(t, x);
}
for (&t, &x) in at.1.siblings.iter().zip_eq(&a.1.siblings) {
self.set_hash_target(t, x);
}
}
for (st, s) in qt.steps.iter().zip_eq(&q.steps) {
for (&t, &x) in st.evals.iter().zip_eq(&s.evals) {
self.set_extension_target(t, x);
}
for (&t, &x) in st
.merkle_proof
.siblings
.iter()
.zip_eq(&s.merkle_proof.siblings)
{
self.set_hash_target(t, x);
}
}
}
set_fri_proof_target(self, &proof.opening_proof, &proof_target.opening_proof);
}
fn set_wire(&mut self, wire: Wire, value: F) {