From 9e9ff9872ba18599cf5465c1db746d8db50d50fd Mon Sep 17 00:00:00 2001 From: wborgeaud Date: Thu, 25 Aug 2022 22:04:28 +0200 Subject: [PATCH] Per table recursion --- evm/src/all_stark.rs | 2 +- evm/src/cross_table_lookup.rs | 53 +++++++++++++++++++++++ evm/src/proof.rs | 6 ++- evm/src/recursive_verifier.rs | 79 ++++++++++++++++++++++++++++++++++- 4 files changed, 136 insertions(+), 4 deletions(-) diff --git a/evm/src/all_stark.rs b/evm/src/all_stark.rs index 1131d529..77af0119 100644 --- a/evm/src/all_stark.rs +++ b/evm/src/all_stark.rs @@ -59,7 +59,7 @@ impl, const D: usize> AllStark { } } -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Copy, Clone, Eq, PartialEq)] pub enum Table { Cpu = 0, Keccak = 1, diff --git a/evm/src/cross_table_lookup.rs b/evm/src/cross_table_lookup.rs index b4b8d6fb..899b46d7 100644 --- a/evm/src/cross_table_lookup.rs +++ b/evm/src/cross_table_lookup.rs @@ -474,6 +474,59 @@ impl<'a, F: Field, const D: usize> CtlCheckVarsTarget<'a, F, D> { } ctl_vars_per_table } + + pub(crate) fn from_proof( + table: Table, + proof: &StarkProofWithPublicInputsTarget, + cross_table_lookups: &'a [CrossTableLookup], + ctl_challenges: &'a GrandProductChallengeSet, + num_permutation_zs: usize, + ) -> Vec { + let mut ctl_zs = { + let openings = &proof.proof.openings; + let ctl_zs = openings.permutation_ctl_zs.iter().skip(num_permutation_zs); + let ctl_zs_next = openings + .permutation_ctl_zs_next + .iter() + .skip(num_permutation_zs); + ctl_zs.zip(ctl_zs_next) + }; + + let mut ctl_vars = vec![]; + for CrossTableLookup { + looking_tables, + looked_table, + .. + } in cross_table_lookups + { + for &challenges in &ctl_challenges.challenges { + for looking_table in looking_tables { + if looking_table.table == table { + let (looking_z, looking_z_next) = ctl_zs.next().unwrap(); + ctl_vars.push(Self { + local_z: *looking_z, + next_z: *looking_z_next, + challenges, + columns: &looking_table.columns, + filter_column: &looking_table.filter_column, + }); + } + } + + if looked_table.table == table { + let (looked_z, looked_z_next) = ctl_zs.next().unwrap(); + ctl_vars.push(Self { + local_z: *looked_z, + next_z: *looked_z_next, + challenges, + columns: &looked_table.columns, + filter_column: &looked_table.filter_column, + }); + } + } + } + ctl_vars + } } pub(crate) fn eval_cross_table_lookup_checks_circuit< diff --git a/evm/src/proof.rs b/evm/src/proof.rs index 4f81308d..e81514eb 100644 --- a/evm/src/proof.rs +++ b/evm/src/proof.rs @@ -33,7 +33,7 @@ impl, C: GenericConfig, const D: usize> A pub fn nums_ctl_zs(&self) -> Vec { self.stark_proofs .iter() - .map(|proof| proof.proof.openings.ctl_zs_last.len()) + .map(|proof| proof.proof.num_ctl_zs()) .collect() } } @@ -76,6 +76,10 @@ impl, C: GenericConfig, const D: usize> S let lde_bits = config.fri_config.cap_height + initial_merkle_proof.siblings.len(); lde_bits - config.fri_config.rate_bits } + + pub fn num_ctl_zs(&self) -> usize { + self.openings.ctl_zs_last.len() + } } pub struct StarkProofTarget { diff --git a/evm/src/recursive_verifier.rs b/evm/src/recursive_verifier.rs index b69a5519..cfd1b36a 100644 --- a/evm/src/recursive_verifier.rs +++ b/evm/src/recursive_verifier.rs @@ -1,3 +1,4 @@ +use anyhow::Result; use itertools::Itertools; use plonky2::field::extension::Extendable; use plonky2::field::types::Field; @@ -5,9 +6,12 @@ use plonky2::fri::witness_util::set_fri_proof_target; use plonky2::hash::hash_types::RichField; use plonky2::iop::ext_target::ExtensionTarget; use plonky2::iop::target::Target; -use plonky2::iop::witness::Witness; +use plonky2::iop::witness::{PartialWitness, Witness}; use plonky2::plonk::circuit_builder::CircuitBuilder; +use plonky2::plonk::circuit_data::CircuitConfig; +use plonky2::plonk::config::Hasher; use plonky2::plonk::config::{AlgebraicHasher, GenericConfig}; +use plonky2::plonk::proof::ProofWithPublicInputs; use plonky2::util::reducing::ReducingFactorTarget; use plonky2::with_context; @@ -15,7 +19,9 @@ use crate::all_stark::{AllStark, Table}; use crate::config::StarkConfig; use crate::constraint_consumer::RecursiveConstraintConsumer; use crate::cpu::cpu_stark::CpuStark; -use crate::cross_table_lookup::{verify_cross_table_lookups_circuit, CtlCheckVarsTarget}; +use crate::cross_table_lookup::{ + verify_cross_table_lookups_circuit, CrossTableLookup, CtlCheckVarsTarget, +}; use crate::keccak::keccak_stark::KeccakStark; use crate::logic::LogicStark; use crate::memory::memory_stark::MemoryStark; @@ -29,6 +35,75 @@ use crate::stark::Stark; use crate::vanishing_poly::eval_vanishing_poly_circuit; use crate::vars::StarkEvaluationTargets; +pub(crate) struct AllRecursiveProofs< + F: RichField + Extendable, + C: GenericConfig, + const D: usize, +> { + pub recursive_proofs: Vec>, +} + +pub(crate) fn recursively_prove_stark_proof< + F: RichField + Extendable, + C: GenericConfig, + S: Stark, + const D: usize, +>( + table: Table, + stark: S, + all_stark: &AllStark, + all_proof: &AllProof, + cross_table_lookups: &[CrossTableLookup], + inner_config: &StarkConfig, + circuit_config: CircuitConfig, +) -> Result> +where + [(); S::COLUMNS]:, + [(); S::PUBLIC_INPUTS]:, + [(); C::Hasher::HASH_SIZE]:, + C::Hasher: AlgebraicHasher, +{ + let mut builder = CircuitBuilder::::new(circuit_config); + let mut pw = PartialWitness::new(); + + let nums_ctl_zs = all_proof.nums_ctl_zs(); + let degree_bits = all_proof.degree_bits(inner_config); + let num_permutation_zs = stark.num_permutation_batches(inner_config); + let all_proof_target = add_virtual_all_proof( + &mut builder, + all_stark, + inner_config, + °ree_bits, + &nums_ctl_zs, + ); + set_all_proof_target(&mut pw, &all_proof_target, all_proof, builder.zero()); + + let AllProofChallengesTarget { + stark_challenges, + ctl_challenges, + } = all_proof_target.get_challenges::(&mut builder, all_stark, inner_config); + + let ctl_vars = CtlCheckVarsTarget::from_proof( + table, + &all_proof_target.stark_proofs[table as usize], + cross_table_lookups, + &ctl_challenges, + num_permutation_zs, + ); + + verify_stark_proof_with_challenges_circuit::( + &mut builder, + stark, + &all_proof_target.stark_proofs[table as usize], + &stark_challenges[table as usize], + &ctl_vars, + inner_config, + ); + + let data = builder.build::(); + data.prove(pw) +} + pub fn verify_proof_circuit< F: RichField + Extendable, C: GenericConfig,