Progress on verifier

This commit is contained in:
wborgeaud 2022-05-11 14:35:33 +02:00
parent 5b146d558f
commit d0fb76c8db
6 changed files with 167 additions and 82 deletions

View File

@ -5,12 +5,14 @@ use plonky2::field::packed_field::PackedField;
use plonky2::hash::hash_types::RichField;
use crate::constraint_consumer::{ConstraintConsumer, RecursiveConstraintConsumer};
use crate::cross_table_lookup::CrossTableLookup;
use crate::stark::Stark;
use crate::vars::{StarkEvaluationTargets, StarkEvaluationVars};
pub struct AllStark<F: RichField + Extendable<D>, const D: usize> {
pub cpu: CpuStark<F, D>,
pub keccak: KeccakStark<F, D>,
pub cpu_stark: CpuStark<F, D>,
pub keccak_stark: KeccakStark<F, D>,
pub cross_table_lookups: Vec<CrossTableLookup>,
}
pub struct CpuStark<F, const D: usize> {

View File

@ -42,31 +42,30 @@ impl CrossTableLookup {
/// Lookup data for one table.
#[derive(Clone)]
pub struct LookupData<F: Field> {
pub zs_beta_gammas: Vec<(PolynomialValues<F>, F, F, Vec<usize>)>,
}
impl<F: Field> Default for LookupData<F> {
fn default() -> Self {
Self {
zs_beta_gammas: Vec::new(),
}
}
pub beta: F,
pub gamma: F,
pub zs_columns: Vec<(PolynomialValues<F>, Vec<usize>)>,
}
impl<F: Field> LookupData<F> {
pub fn new(beta: F, gamma: F) -> Self {
Self {
beta,
gamma,
zs_columns: vec![],
}
}
pub fn len(&self) -> usize {
self.zs_beta_gammas.len()
self.zs_columns.len()
}
pub fn is_empty(&self) -> bool {
self.zs_beta_gammas.is_empty()
self.zs_columns.is_empty()
}
pub fn z_polys(&self) -> Vec<PolynomialValues<F>> {
self.zs_beta_gammas
.iter()
.map(|(p, _, _, _)| p.clone())
.collect()
self.zs_columns.iter().map(|(p, _)| p.clone()).collect()
}
}
@ -76,20 +75,19 @@ pub fn cross_table_lookup_zs<F: RichField, C: GenericConfig<D, F = F>, const D:
cross_table_lookups: &[CrossTableLookup],
challenger: &mut Challenger<F, C::Hasher>,
) -> Vec<LookupData<F>> {
let beta = challenger.get_challenge();
let gamma = challenger.get_challenge();
cross_table_lookups.iter().fold(
vec![LookupData::default(); trace_poly_values.len()],
vec![LookupData::new(beta, gamma); trace_poly_values.len()],
|mut acc, cross_table_lookup| {
let CrossTableLookup {
looking_table,
looking_columns,
looked_table,
looked_columns,
..
} = cross_table_lookup;
for _ in 0..config.num_challenges {
let beta = challenger.get_challenge();
let gamma = challenger.get_challenge();
let z_looking = partial_products(
&trace_poly_values[*looking_table as usize],
looking_columns,
@ -103,18 +101,12 @@ pub fn cross_table_lookup_zs<F: RichField, C: GenericConfig<D, F = F>, const D:
gamma,
);
acc[*looking_table as usize].zs_beta_gammas.push((
z_looking,
beta,
gamma,
looking_columns.clone(),
));
acc[*looked_table as usize].zs_beta_gammas.push((
z_looked,
beta,
gamma,
looked_columns.clone(),
));
acc[*looking_table as usize]
.zs_columns
.push((z_looking, looking_columns.clone()));
acc[*looked_table as usize]
.zs_columns
.push((z_looked, looked_columns.clone()));
}
acc
},

View File

@ -9,14 +9,16 @@ use plonky2::iop::target::Target;
use plonky2::plonk::circuit_builder::CircuitBuilder;
use plonky2::plonk::config::{AlgebraicHasher, GenericConfig};
use crate::all_stark::AllStark;
use crate::config::StarkConfig;
use crate::permutation::{
get_n_permutation_challenge_sets, get_n_permutation_challenge_sets_target,
get_n_permutation_challenge_sets, get_n_permutation_challenge_sets_target, PermutationChallenge,
};
use crate::proof::*;
use crate::stark::Stark;
fn get_challenges<F, C, S, const D: usize>(
challenger: &mut Challenger<F, C::Hasher>,
stark: &S,
trace_cap: &MerkleCap<F, C::Hasher>,
permutation_zs_cap: Option<&MerkleCap<F, C::Hasher>>,
@ -35,13 +37,11 @@ where
{
let num_challenges = config.num_challenges;
let mut challenger = Challenger::<F, C::Hasher>::new();
challenger.observe_cap(trace_cap);
let permutation_challenge_sets = permutation_zs_cap.map(|permutation_zs_cap| {
let tmp = get_n_permutation_challenge_sets(
&mut challenger,
challenger,
num_challenges,
stark.permutation_batch_size(),
);
@ -70,6 +70,42 @@ where
}
}
impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize> AllProof<F, C, D> {
/// Computes all Fiat-Shamir challenges used in the STARK proof.
pub(crate) fn get_challenges(
&self,
all_stark: &AllStark<F, D>,
config: &StarkConfig,
) -> AllProofChallenges<F, D> {
let num_challenges = config.num_challenges;
let mut challenger = Challenger::<F, C::Hasher>::new();
for proof in self.proofs() {
challenger.observe_cap(&proof.proof.trace_cap);
}
let ctl_challenges = PermutationChallenge {
beta: challenger.get_challenge(),
gamma: challenger.get_challenge(),
};
AllProofChallenges {
cpu_challenges: self.cpu_proof.get_challenges(
&mut challenger,
&all_stark.cpu_stark,
config,
),
keccak_challenges: self.keccak_proof.get_challenges(
&mut challenger,
&all_stark.keccak_stark,
config,
),
ctl_challenges,
}
}
}
impl<F, C, const D: usize> StarkProofWithPublicInputs<F, C, D>
where
F: RichField + Extendable<D>,
@ -81,9 +117,9 @@ where
&self,
stark: &S,
config: &StarkConfig,
degree_bits: usize,
) -> Vec<usize> {
self.get_challenges(stark, config, degree_bits)
let mut challenger = Challenger::new();
self.get_challenges(&mut challenger, stark, config)
.fri_challenges
.fri_query_indices
}
@ -91,10 +127,12 @@ where
/// Computes all Fiat-Shamir challenges used in the STARK proof.
pub(crate) fn get_challenges<S: Stark<F, D>>(
&self,
challenger: &mut Challenger<F, C::Hasher>,
stark: &S,
config: &StarkConfig,
degree_bits: usize,
) -> StarkProofChallenges<F, D> {
let degree_bits = self.proof.recover_degree_bits(config);
let StarkProof {
trace_cap,
permutation_zs_cap,
@ -110,6 +148,7 @@ where
} = &self.proof;
get_challenges::<F, C, S, D>(
challenger,
stark,
trace_cap,
permutation_zs_cap.as_ref(),

View File

@ -16,7 +16,25 @@ use plonky2::plonk::config::GenericConfig;
use rayon::prelude::*;
use crate::config::StarkConfig;
use crate::permutation::PermutationChallengeSet;
use crate::permutation::{PermutationChallenge, PermutationChallengeSet};
#[derive(Debug, Clone)]
pub struct AllProof<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize> {
pub cpu_proof: StarkProofWithPublicInputs<F, C, D>,
pub keccak_proof: StarkProofWithPublicInputs<F, C, D>,
}
impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize> AllProof<F, C, D> {
pub fn proofs(&self) -> [&StarkProofWithPublicInputs<F, C, D>; 2] {
[&self.cpu_proof, &self.keccak_proof]
}
}
pub(crate) struct AllProofChallenges<F: RichField + Extendable<D>, const D: usize> {
pub cpu_challenges: StarkProofChallenges<F, D>,
pub keccak_challenges: StarkProofChallenges<F, D>,
pub ctl_challenges: PermutationChallenge<F>,
}
#[derive(Debug, Clone)]
pub struct StarkProof<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize> {

View File

@ -28,19 +28,18 @@ use crate::permutation::{
compute_permutation_z_polys, get_n_permutation_challenge_sets, PermutationChallengeSet,
};
use crate::permutation::{PermutationChallenge, PermutationCheckVars};
use crate::proof::{StarkOpeningSet, StarkProof, StarkProofWithPublicInputs};
use crate::proof::{AllProof, StarkOpeningSet, StarkProof, StarkProofWithPublicInputs};
use crate::stark::Stark;
use crate::vanishing_poly::eval_vanishing_poly;
use crate::vars::StarkEvaluationVars;
pub fn prove<F, C, S, const D: usize>(
all_starks: AllStark<F, D>,
all_stark: AllStark<F, D>,
config: &StarkConfig,
trace_poly_values: Vec<Vec<PolynomialValues<F>>>,
cross_table_lookups: Vec<CrossTableLookup>,
public_inputs: Vec<Vec<F>>,
timing: &mut TimingTree,
) -> Result<Vec<StarkProofWithPublicInputs<F, C, D>>>
) -> Result<AllProof<F, C, D>>
where
F: RichField + Extendable<D>,
C: GenericConfig<D, F = F>,
@ -93,12 +92,12 @@ where
let lookup_zs = cross_table_lookup_zs::<F, C, D>(
config,
&trace_poly_values,
&cross_table_lookups,
&all_stark.cross_table_lookups,
&mut challenger,
);
let cpu_proof = prove_single_table(
&all_starks.cpu,
&all_stark.cpu_stark,
config,
&trace_poly_values[Table::Cpu as usize],
&trace_commitments[Table::Cpu as usize],
@ -108,7 +107,7 @@ where
timing,
)?;
let keccak_proof = prove_single_table(
&all_starks.keccak,
&all_stark.keccak_stark,
config,
&trace_poly_values[Table::Keccak as usize],
&trace_commitments[Table::Keccak as usize],
@ -118,7 +117,10 @@ where
timing,
)?;
Ok(vec![cpu_proof, keccak_proof])
Ok(AllProof {
cpu_proof,
keccak_proof,
})
}
fn prove_single_table<F, C, S, const D: usize>(
@ -375,26 +377,24 @@ where
},
);
let lookup_check_data = lookup_data
.zs_beta_gammas
.zs_columns
.iter()
.enumerate()
.map(
|(i, (_, beta, gamma, columns))| CTLCheckVars::<F, F, P, 1> {
local_z: permutation_zs_commitment_challenges
.unwrap()
.0
.get_lde_values_packed(i_start, step)[num_permutation_zs + i],
next_z: permutation_zs_commitment_challenges
.unwrap()
.0
.get_lde_values_packed(i_next_start, step)[num_permutation_zs + i],
challenges: PermutationChallenge {
beta: *beta,
gamma: *gamma,
},
columns: columns.to_vec(),
.map(|(i, (_, columns))| CTLCheckVars::<F, F, P, 1> {
local_z: permutation_zs_commitment_challenges
.unwrap()
.0
.get_lde_values_packed(i_start, step)[num_permutation_zs + i],
next_z: permutation_zs_commitment_challenges
.unwrap()
.0
.get_lde_values_packed(i_next_start, step)[num_permutation_zs + i],
challenges: PermutationChallenge {
beta: lookup_data.beta,
gamma: lookup_data.gamma,
},
)
columns: columns.to_vec(),
})
.collect::<Vec<_>>();
eval_vanishing_poly::<F, F, P, C, S, D, 1>(
stark,

View File

@ -9,35 +9,69 @@ use plonky2::hash::hash_types::RichField;
use plonky2::plonk::config::{GenericConfig, Hasher};
use plonky2::plonk::plonk_common::reduce_with_powers;
use crate::all_stark::{AllStark, KeccakStark};
use crate::config::StarkConfig;
use crate::constraint_consumer::ConstraintConsumer;
use crate::permutation::PermutationCheckVars;
use crate::proof::{StarkOpeningSet, StarkProofChallenges, StarkProofWithPublicInputs};
use crate::proof::{
AllProof, AllProofChallenges, StarkOpeningSet, StarkProofChallenges, StarkProofWithPublicInputs,
};
use crate::stark::Stark;
use crate::vanishing_poly::eval_vanishing_poly;
use crate::vars::StarkEvaluationVars;
pub fn verify_stark_proof<
F: RichField + Extendable<D>,
C: GenericConfig<D, F = F>,
S: Stark<F, D>,
const D: usize,
>(
stark: S,
proof_with_pis: StarkProofWithPublicInputs<F, C, D>,
pub fn verify_proof<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>(
all_stark: AllStark<F, D>,
all_proof: AllProof<F, C, D>,
config: &StarkConfig,
) -> Result<()>
where
[(); S::COLUMNS]:,
[(); S::PUBLIC_INPUTS]:,
[(); KeccakStark::<F, D>::COLUMNS]:,
[(); C::Hasher::HASH_SIZE]:,
{
ensure!(proof_with_pis.public_inputs.len() == S::PUBLIC_INPUTS);
let degree_bits = proof_with_pis.proof.recover_degree_bits(config);
let challenges = proof_with_pis.get_challenges(&stark, config, degree_bits);
verify_stark_proof_with_challenges(stark, proof_with_pis, challenges, degree_bits, config)
let AllProofChallenges {
cpu_challenges,
keccak_challenges,
ctl_challenges,
} = all_proof.get_challenges(&all_stark, config);
// Verify CTL
verify_stark_proof_with_challenges(
all_stark.cpu_stark,
all_proof.cpu_proof,
cpu_challenges,
config,
)?;
verify_stark_proof_with_challenges(
all_stark.keccak_stark,
all_proof.keccak_proof,
keccak_challenges,
config,
)
}
// pub fn verify_stark_proof<
// F: RichField + Extendable<D>,
// C: GenericConfig<D, F = F>,
// S: Stark<F, D>,
// const D: usize,
// >(
// stark: S,
// proof_with_pis: StarkProofWithPublicInputs<F, C, D>,
// config: &StarkConfig,
// ) -> Result<()>
// where
// [(); S::COLUMNS]:,
// [(); S::PUBLIC_INPUTS]:,
// [(); C::Hasher::HASH_SIZE]:,
// {
// ensure!(proof_with_pis.public_inputs.len() == S::PUBLIC_INPUTS);
// let degree_bits = proof_with_pis.proof.recover_degree_bits(config);
// let challenges = proof_with_pis.get_challenges(&stark, config, degree_bits);
// verify_stark_proof_with_challenges(stark, proof_with_pis, challenges, degree_bits, config)
// }
pub(crate) fn verify_stark_proof_with_challenges<
F: RichField + Extendable<D>,
C: GenericConfig<D, F = F>,
@ -47,7 +81,6 @@ pub(crate) fn verify_stark_proof_with_challenges<
stark: S,
proof_with_pis: StarkProofWithPublicInputs<F, C, D>,
challenges: StarkProofChallenges<F, D>,
degree_bits: usize,
config: &StarkConfig,
) -> Result<()>
where
@ -77,6 +110,7 @@ where
.collect::<Vec<_>>(),
};
let degree_bits = proof.recover_degree_bits(config);
let (l_1, l_last) = eval_l_1_and_l_last(degree_bits, challenges.stark_zeta);
let last = F::primitive_root_of_unity(degree_bits).inverse();
let z_last = challenges.stark_zeta - last.into();