Per table recursion

This commit is contained in:
wborgeaud 2022-08-25 22:04:28 +02:00
parent aebcdd52cf
commit 9e9ff9872b
4 changed files with 136 additions and 4 deletions

View File

@ -59,7 +59,7 @@ impl<F: RichField + Extendable<D>, const D: usize> AllStark<F, D> {
}
}
#[derive(Debug, Copy, Clone)]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum Table {
Cpu = 0,
Keccak = 1,

View File

@ -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<D>,
cross_table_lookups: &'a [CrossTableLookup<F>],
ctl_challenges: &'a GrandProductChallengeSet<Target>,
num_permutation_zs: usize,
) -> Vec<Self> {
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<

View File

@ -33,7 +33,7 @@ impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize> A
pub fn nums_ctl_zs(&self) -> Vec<usize> {
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<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, 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<const D: usize> {

View File

@ -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<D>,
C: GenericConfig<D, F = F>,
const D: usize,
> {
pub recursive_proofs: Vec<ProofWithPublicInputs<F, C, D>>,
}
pub(crate) fn recursively_prove_stark_proof<
F: RichField + Extendable<D>,
C: GenericConfig<D, F = F>,
S: Stark<F, D>,
const D: usize,
>(
table: Table,
stark: S,
all_stark: &AllStark<F, D>,
all_proof: &AllProof<F, C, D>,
cross_table_lookups: &[CrossTableLookup<F>],
inner_config: &StarkConfig,
circuit_config: CircuitConfig,
) -> Result<ProofWithPublicInputs<F, C, D>>
where
[(); S::COLUMNS]:,
[(); S::PUBLIC_INPUTS]:,
[(); C::Hasher::HASH_SIZE]:,
C::Hasher: AlgebraicHasher<F>,
{
let mut builder = CircuitBuilder::<F, D>::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,
&degree_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::<F, C>(&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::<F, C, _, D>(
&mut builder,
stark,
&all_proof_target.stark_proofs[table as usize],
&stark_challenges[table as usize],
&ctl_vars,
inner_config,
);
let data = builder.build::<C>();
data.prove(pw)
}
pub fn verify_proof_circuit<
F: RichField + Extendable<D>,
C: GenericConfig<D, F = F>,