Replace AlgebraicConfig with GenericConfig (#425)

It works fine if we bound recursion methods with `C::Hasher: AlgebraicHasher<F>`. This bound feels natural to me - it's like saying "the recursion methods assume the inner hasher has a circuit implementation".
This commit is contained in:
Daniel Lubarov 2022-01-09 08:33:12 -08:00 committed by GitHub
parent 8ec78fc0c1
commit bde6114428
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 25 additions and 37 deletions

View File

@ -16,7 +16,7 @@ use crate::iop::challenger::RecursiveChallenger;
use crate::iop::ext_target::{flatten_target, ExtensionTarget};
use crate::iop::target::{BoolTarget, Target};
use crate::plonk::circuit_builder::CircuitBuilder;
use crate::plonk::config::{AlgebraicConfig, AlgebraicHasher, GenericConfig};
use crate::plonk::config::{AlgebraicHasher, GenericConfig};
use crate::plonk::proof::OpeningSetTarget;
use crate::util::reducing::ReducingFactorTarget;
use crate::with_context;
@ -119,7 +119,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
);
}
pub fn verify_fri_proof<C: AlgebraicConfig<D, F = F>>(
pub fn verify_fri_proof<C: GenericConfig<D, F = F>>(
&mut self,
instance: &FriInstanceInfoTarget<D>,
// Openings of the PLONK polynomials.
@ -128,7 +128,9 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
proof: &FriProofTarget<D>,
challenger: &mut RecursiveChallenger<F, C::Hasher, D>,
params: &FriParams,
) {
) where
C::Hasher: AlgebraicHasher<F>,
{
if let Some(max_arity_bits) = params.max_arity_bits() {
self.check_recursion_config::<C>(max_arity_bits);
}
@ -282,7 +284,7 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
sum
}
fn fri_verifier_query_round<C: AlgebraicConfig<D, F = F>>(
fn fri_verifier_query_round<C: GenericConfig<D, F = F>>(
&mut self,
instance: &FriInstanceInfoTarget<D>,
alpha: ExtensionTarget<D>,
@ -294,7 +296,9 @@ impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
betas: &[ExtensionTarget<D>],
round_proof: &FriQueryRoundTarget<D>,
params: &FriParams,
) {
) where
C::Hasher: AlgebraicHasher<F>,
{
let n_log = log2_strict(n);
// Note that this `low_bits` decomposition permits non-canonical binary encodings. Here we

View File

@ -66,29 +66,10 @@ pub trait GenericConfig<const D: usize>:
type InnerHasher: AlgebraicHasher<Self::F>;
}
/// Configuration trait for "algebraic" configurations, i.e., those using an algebraic hash function
/// in Merkle trees.
/// Same as `GenericConfig` trait but with `InnerHasher: AlgebraicHasher<F>`.
pub trait AlgebraicConfig<const D: usize>:
Debug + Clone + Sync + Sized + Send + Eq + PartialEq
{
type F: RichField + Extendable<D, Extension = Self::FE>;
type FE: FieldExtension<D, BaseField = Self::F>;
type Hasher: AlgebraicHasher<Self::F>;
type InnerHasher: AlgebraicHasher<Self::F>;
}
impl<A: AlgebraicConfig<D>, const D: usize> GenericConfig<D> for A {
type F = <Self as AlgebraicConfig<D>>::F;
type FE = <Self as AlgebraicConfig<D>>::FE;
type Hasher = <Self as AlgebraicConfig<D>>::Hasher;
type InnerHasher = <Self as AlgebraicConfig<D>>::InnerHasher;
}
/// Configuration using Poseidon over the Goldilocks field.
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct PoseidonGoldilocksConfig;
impl AlgebraicConfig<2> for PoseidonGoldilocksConfig {
impl GenericConfig<2> for PoseidonGoldilocksConfig {
type F = GoldilocksField;
type FE = QuadraticExtension<Self::F>;
type Hasher = PoseidonHash;
@ -98,7 +79,7 @@ impl AlgebraicConfig<2> for PoseidonGoldilocksConfig {
/// Configuration using GMiMC over the Goldilocks field.
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct GMiMCGoldilocksConfig;
impl AlgebraicConfig<2> for GMiMCGoldilocksConfig {
impl GenericConfig<2> for GMiMCGoldilocksConfig {
type F = GoldilocksField;
type FE = QuadraticExtension<Self::F>;
type Hasher = GMiMCHash;

View File

@ -4,7 +4,7 @@ use crate::hash::hash_types::{HashOutTarget, RichField};
use crate::iop::challenger::RecursiveChallenger;
use crate::plonk::circuit_builder::CircuitBuilder;
use crate::plonk::circuit_data::{CircuitConfig, CommonCircuitData, VerifierCircuitTarget};
use crate::plonk::config::AlgebraicConfig;
use crate::plonk::config::{AlgebraicHasher, GenericConfig};
use crate::plonk::proof::ProofWithPublicInputsTarget;
use crate::plonk::vanishing_poly::eval_vanishing_poly_recursively;
use crate::plonk::vars::EvaluationTargets;
@ -13,13 +13,15 @@ use crate::with_context;
impl<F: RichField + Extendable<D>, const D: usize> CircuitBuilder<F, D> {
/// Recursively verifies an inner proof.
pub fn add_recursive_verifier<C: AlgebraicConfig<D, F = F>>(
pub fn add_recursive_verifier<C: GenericConfig<D, F = F>>(
&mut self,
proof_with_pis: ProofWithPublicInputsTarget<D>,
inner_config: &CircuitConfig,
inner_verifier_data: &VerifierCircuitTarget,
inner_common_data: &CommonCircuitData<F, C, D>,
) {
) where
C::Hasher: AlgebraicHasher<F>,
{
let ProofWithPublicInputsTarget {
proof,
public_inputs,
@ -253,15 +255,13 @@ mod tests {
}
// Set the targets in a `ProofTarget` to their corresponding values in a `Proof`.
fn set_proof_target<
F: RichField + Extendable<D>,
C: AlgebraicConfig<D, F = F>,
const D: usize,
>(
fn set_proof_target<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>(
proof: &ProofWithPublicInputs<F, C, D>,
pt: &ProofWithPublicInputsTarget<D>,
pw: &mut PartialWitness<F>,
) {
) where
C::Hasher: AlgebraicHasher<F>,
{
let ProofWithPublicInputs {
proof,
public_inputs,
@ -561,7 +561,7 @@ mod tests {
fn recursive_proof<
F: RichField + Extendable<D>,
C: GenericConfig<D, F = F>,
InnerC: AlgebraicConfig<D, F = F>,
InnerC: GenericConfig<D, F = F>,
const D: usize,
>(
inner_proof: ProofWithPublicInputs<F, InnerC, D>,
@ -576,7 +576,10 @@ mod tests {
ProofWithPublicInputs<F, C, D>,
VerifierOnlyCircuitData<C, D>,
CommonCircuitData<F, C, D>,
)> {
)>
where
InnerC::Hasher: AlgebraicHasher<F>,
{
let mut builder = CircuitBuilder::<F, D>::new(config.clone());
let mut pw = PartialWitness::new();
let pt = proof_to_proof_target(&inner_proof, &mut builder);