PR feedback

This commit is contained in:
wborgeaud 2022-10-06 16:40:03 +02:00
parent 0bc3f20479
commit 39fc219324
4 changed files with 225 additions and 192 deletions

View File

@ -203,9 +203,10 @@ mod tests {
use crate::memory::NUM_CHANNELS;
use crate::proof::{AllProof, PublicValues};
use crate::prover::prove_with_traces;
use crate::recursive_verifier::tests::recursively_verify_all_proof;
use crate::recursive_verifier::{
add_virtual_recursive_all_proof, all_verifier_data_recursive_stark_proof,
recursively_verify_all_proof, set_recursive_all_proof_target, RecursiveAllProof,
set_recursive_all_proof_target, RecursiveAllProof,
};
use crate::stark::Stark;
use crate::util::{limb_from_bits_le, trace_rows_to_poly_values};

View File

@ -47,6 +47,8 @@ impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize> A
ctl_challenges,
}
}
#[allow(unused)] // TODO: should be used soon
pub(crate) fn get_challenger_states(
&self,
all_stark: &AllStark<F, D>,

View File

@ -36,6 +36,7 @@ pub(crate) struct AllProofChallenges<F: RichField + Extendable<D>, const D: usiz
pub ctl_challenges: GrandProductChallengeSet<F>,
}
#[allow(unused)] // TODO: should be used soon
pub(crate) struct AllChallengerState<F: RichField + Extendable<D>, const D: usize> {
/// Sponge state of the challenger before starting each proof,
/// along with the final state after all proofs are done. This final state isn't strictly needed.

View File

@ -10,7 +10,7 @@ use plonky2::hash::hashing::SPONGE_WIDTH;
use plonky2::iop::challenger::{Challenger, RecursiveChallenger};
use plonky2::iop::ext_target::ExtensionTarget;
use plonky2::iop::target::Target;
use plonky2::iop::witness::{PartialWitness, Witness};
use plonky2::iop::witness::Witness;
use plonky2::plonk::circuit_builder::CircuitBuilder;
use plonky2::plonk::circuit_data::{CircuitConfig, VerifierCircuitData, VerifierCircuitTarget};
use plonky2::plonk::config::Hasher;
@ -36,9 +36,9 @@ use crate::permutation::{
GrandProductChallengeSet, PermutationCheckDataTarget,
};
use crate::proof::{
AllChallengerState, AllProof, AllProofTarget, BlockMetadata, BlockMetadataTarget, PublicValues,
PublicValuesTarget, StarkOpeningSetTarget, StarkProof, StarkProofChallengesTarget,
StarkProofTarget, TrieRoots, TrieRootsTarget,
AllProof, AllProofTarget, BlockMetadata, BlockMetadataTarget, PublicValues, PublicValuesTarget,
StarkOpeningSetTarget, StarkProof, StarkProofChallengesTarget, StarkProofTarget, TrieRoots,
TrieRootsTarget,
};
use crate::stark::Stark;
use crate::util::h160_limbs;
@ -244,107 +244,6 @@ impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>
}
}
/// Recursively verify a Stark proof.
/// Outputs the recursive proof and the associated verifier data.
#[cfg(test)]
fn recursively_verify_stark_proof<
F: RichField + Extendable<D>,
C: GenericConfig<D, F = F>,
S: Stark<F, D>,
const D: usize,
>(
table: Table,
stark: S,
proof: &StarkProof<F, C, D>,
cross_table_lookups: &[CrossTableLookup<F>],
ctl_challenges: &GrandProductChallengeSet<F>,
challenger_state_before_vals: [F; SPONGE_WIDTH],
inner_config: &StarkConfig,
circuit_config: &CircuitConfig,
) -> Result<(ProofWithPublicInputs<F, C, D>, VerifierCircuitData<F, C, D>)>
where
[(); S::COLUMNS]:,
[(); C::Hasher::HASH_SIZE]:,
C::Hasher: AlgebraicHasher<F>,
{
let mut builder = CircuitBuilder::<F, D>::new(circuit_config.clone());
let mut pw = PartialWitness::new();
let num_permutation_zs = stark.num_permutation_batches(inner_config);
let num_permutation_batch_size = stark.permutation_batch_size();
let proof_target = add_virtual_stark_proof(
&mut builder,
&stark,
inner_config,
proof.recover_degree_bits(inner_config),
proof.num_ctl_zs(),
);
set_stark_proof_target(&mut pw, &proof_target, proof, builder.zero());
builder.register_public_inputs(
&proof_target
.trace_cap
.0
.iter()
.flat_map(|h| h.elements)
.collect::<Vec<_>>(),
);
let ctl_challenges_target = GrandProductChallengeSet {
challenges: (0..inner_config.num_challenges)
.map(|_| GrandProductChallenge {
beta: builder.add_virtual_public_input(),
gamma: builder.add_virtual_public_input(),
})
.collect(),
};
for i in 0..inner_config.num_challenges {
pw.set_target(
ctl_challenges_target.challenges[i].beta,
ctl_challenges.challenges[i].beta,
);
pw.set_target(
ctl_challenges_target.challenges[i].gamma,
ctl_challenges.challenges[i].gamma,
);
}
let ctl_vars = CtlCheckVarsTarget::from_proof(
table,
&proof_target,
cross_table_lookups,
&ctl_challenges_target,
num_permutation_zs,
);
let challenger_state_before = std::array::from_fn(|_| builder.add_virtual_public_input());
pw.set_target_arr(challenger_state_before, challenger_state_before_vals);
let mut challenger =
RecursiveChallenger::<F, C::Hasher, D>::from_state(challenger_state_before);
let challenges = proof_target.get_challenges::<F, C>(
&mut builder,
&mut challenger,
num_permutation_zs > 0,
num_permutation_batch_size,
inner_config,
);
let challenger_state_after = challenger.compact(&mut builder);
builder.register_public_inputs(&challenger_state_after);
builder.register_public_inputs(&proof_target.openings.ctl_zs_last);
verify_stark_proof_with_challenges_circuit::<F, C, _, D>(
&mut builder,
&stark,
&proof_target,
&challenges,
&ctl_vars,
inner_config,
);
let data = builder.build::<C>();
Ok((data.prove(pw)?, data.verifier_data()))
}
/// Returns the verifier data for the recursive Stark circuit.
fn verifier_data_recursive_stark_proof<
F: RichField + Extendable<D>,
@ -488,92 +387,6 @@ where
]
}
/// Recursively verify every Stark proof in an `AllProof`.
#[cfg(test)]
pub fn recursively_verify_all_proof<
F: RichField + Extendable<D>,
C: GenericConfig<D, F = F>,
const D: usize,
>(
all_stark: &AllStark<F, D>,
all_proof: &AllProof<F, C, D>,
inner_config: &StarkConfig,
circuit_config: &CircuitConfig,
) -> Result<RecursiveAllProof<F, C, D>>
where
[(); CpuStark::<F, D>::COLUMNS]:,
[(); KeccakStark::<F, D>::COLUMNS]:,
[(); KeccakMemoryStark::<F, D>::COLUMNS]:,
[(); LogicStark::<F, D>::COLUMNS]:,
[(); MemoryStark::<F, D>::COLUMNS]:,
[(); C::Hasher::HASH_SIZE]:,
C::Hasher: AlgebraicHasher<F>,
{
let AllChallengerState {
states,
ctl_challenges,
} = all_proof.get_challenger_states(all_stark, inner_config);
Ok(RecursiveAllProof {
recursive_proofs: [
recursively_verify_stark_proof(
Table::Cpu,
all_stark.cpu_stark,
&all_proof.stark_proofs[Table::Cpu as usize],
&all_stark.cross_table_lookups,
&ctl_challenges,
states[0],
inner_config,
circuit_config,
)?
.0,
recursively_verify_stark_proof(
Table::Keccak,
all_stark.keccak_stark,
&all_proof.stark_proofs[Table::Keccak as usize],
&all_stark.cross_table_lookups,
&ctl_challenges,
states[1],
inner_config,
circuit_config,
)?
.0,
recursively_verify_stark_proof(
Table::KeccakMemory,
all_stark.keccak_memory_stark,
&all_proof.stark_proofs[Table::KeccakMemory as usize],
&all_stark.cross_table_lookups,
&ctl_challenges,
states[2],
inner_config,
circuit_config,
)?
.0,
recursively_verify_stark_proof(
Table::Logic,
all_stark.logic_stark,
&all_proof.stark_proofs[Table::Logic as usize],
&all_stark.cross_table_lookups,
&ctl_challenges,
states[3],
inner_config,
circuit_config,
)?
.0,
recursively_verify_stark_proof(
Table::Memory,
all_stark.memory_stark,
&all_proof.stark_proofs[Table::Memory as usize],
&all_stark.cross_table_lookups,
&ctl_challenges,
states[4],
inner_config,
circuit_config,
)?
.0,
],
})
}
/// Recursively verifies an inner proof.
fn verify_stark_proof_with_challenges_circuit<
F: RichField + Extendable<D>,
@ -1028,3 +841,219 @@ pub fn set_block_metadata_target<F, W, const D: usize>(
F::from_canonical_u64(block_metadata.block_base_fee.as_u64()),
);
}
#[cfg(test)]
pub(crate) mod tests {
use anyhow::Result;
use plonky2::field::extension::Extendable;
use plonky2::hash::hash_types::RichField;
use plonky2::hash::hashing::SPONGE_WIDTH;
use plonky2::iop::challenger::RecursiveChallenger;
use plonky2::iop::witness::{PartialWitness, Witness};
use plonky2::plonk::circuit_builder::CircuitBuilder;
use plonky2::plonk::circuit_data::{CircuitConfig, VerifierCircuitData};
use plonky2::plonk::config::Hasher;
use plonky2::plonk::config::{AlgebraicHasher, GenericConfig};
use plonky2::plonk::proof::ProofWithPublicInputs;
use crate::all_stark::{AllStark, Table};
use crate::config::StarkConfig;
use crate::cpu::cpu_stark::CpuStark;
use crate::cross_table_lookup::{CrossTableLookup, CtlCheckVarsTarget};
use crate::keccak::keccak_stark::KeccakStark;
use crate::keccak_memory::keccak_memory_stark::KeccakMemoryStark;
use crate::logic::LogicStark;
use crate::memory::memory_stark::MemoryStark;
use crate::permutation::{GrandProductChallenge, GrandProductChallengeSet};
use crate::proof::{AllChallengerState, AllProof, StarkProof};
use crate::recursive_verifier::{
add_virtual_stark_proof, set_stark_proof_target,
verify_stark_proof_with_challenges_circuit, RecursiveAllProof,
};
use crate::stark::Stark;
/// Recursively verify a Stark proof.
/// Outputs the recursive proof and the associated verifier data.
fn recursively_verify_stark_proof<
F: RichField + Extendable<D>,
C: GenericConfig<D, F = F>,
S: Stark<F, D>,
const D: usize,
>(
table: Table,
stark: S,
proof: &StarkProof<F, C, D>,
cross_table_lookups: &[CrossTableLookup<F>],
ctl_challenges: &GrandProductChallengeSet<F>,
challenger_state_before_vals: [F; SPONGE_WIDTH],
inner_config: &StarkConfig,
circuit_config: &CircuitConfig,
) -> Result<(ProofWithPublicInputs<F, C, D>, VerifierCircuitData<F, C, D>)>
where
[(); S::COLUMNS]:,
[(); C::Hasher::HASH_SIZE]:,
C::Hasher: AlgebraicHasher<F>,
{
let mut builder = CircuitBuilder::<F, D>::new(circuit_config.clone());
let mut pw = PartialWitness::new();
let num_permutation_zs = stark.num_permutation_batches(inner_config);
let num_permutation_batch_size = stark.permutation_batch_size();
let proof_target = add_virtual_stark_proof(
&mut builder,
&stark,
inner_config,
proof.recover_degree_bits(inner_config),
proof.num_ctl_zs(),
);
set_stark_proof_target(&mut pw, &proof_target, proof, builder.zero());
builder.register_public_inputs(
&proof_target
.trace_cap
.0
.iter()
.flat_map(|h| h.elements)
.collect::<Vec<_>>(),
);
let ctl_challenges_target = GrandProductChallengeSet {
challenges: (0..inner_config.num_challenges)
.map(|_| GrandProductChallenge {
beta: builder.add_virtual_public_input(),
gamma: builder.add_virtual_public_input(),
})
.collect(),
};
for i in 0..inner_config.num_challenges {
pw.set_target(
ctl_challenges_target.challenges[i].beta,
ctl_challenges.challenges[i].beta,
);
pw.set_target(
ctl_challenges_target.challenges[i].gamma,
ctl_challenges.challenges[i].gamma,
);
}
let ctl_vars = CtlCheckVarsTarget::from_proof(
table,
&proof_target,
cross_table_lookups,
&ctl_challenges_target,
num_permutation_zs,
);
let challenger_state_before = std::array::from_fn(|_| builder.add_virtual_public_input());
pw.set_target_arr(challenger_state_before, challenger_state_before_vals);
let mut challenger =
RecursiveChallenger::<F, C::Hasher, D>::from_state(challenger_state_before);
let challenges = proof_target.get_challenges::<F, C>(
&mut builder,
&mut challenger,
num_permutation_zs > 0,
num_permutation_batch_size,
inner_config,
);
let challenger_state_after = challenger.compact(&mut builder);
builder.register_public_inputs(&challenger_state_after);
builder.register_public_inputs(&proof_target.openings.ctl_zs_last);
verify_stark_proof_with_challenges_circuit::<F, C, _, D>(
&mut builder,
&stark,
&proof_target,
&challenges,
&ctl_vars,
inner_config,
);
let data = builder.build::<C>();
Ok((data.prove(pw)?, data.verifier_data()))
}
/// Recursively verify every Stark proof in an `AllProof`.
pub fn recursively_verify_all_proof<
F: RichField + Extendable<D>,
C: GenericConfig<D, F = F>,
const D: usize,
>(
all_stark: &AllStark<F, D>,
all_proof: &AllProof<F, C, D>,
inner_config: &StarkConfig,
circuit_config: &CircuitConfig,
) -> Result<RecursiveAllProof<F, C, D>>
where
[(); CpuStark::<F, D>::COLUMNS]:,
[(); KeccakStark::<F, D>::COLUMNS]:,
[(); KeccakMemoryStark::<F, D>::COLUMNS]:,
[(); LogicStark::<F, D>::COLUMNS]:,
[(); MemoryStark::<F, D>::COLUMNS]:,
[(); C::Hasher::HASH_SIZE]:,
C::Hasher: AlgebraicHasher<F>,
{
let AllChallengerState {
states,
ctl_challenges,
} = all_proof.get_challenger_states(all_stark, inner_config);
Ok(RecursiveAllProof {
recursive_proofs: [
recursively_verify_stark_proof(
Table::Cpu,
all_stark.cpu_stark,
&all_proof.stark_proofs[Table::Cpu as usize],
&all_stark.cross_table_lookups,
&ctl_challenges,
states[0],
inner_config,
circuit_config,
)?
.0,
recursively_verify_stark_proof(
Table::Keccak,
all_stark.keccak_stark,
&all_proof.stark_proofs[Table::Keccak as usize],
&all_stark.cross_table_lookups,
&ctl_challenges,
states[1],
inner_config,
circuit_config,
)?
.0,
recursively_verify_stark_proof(
Table::KeccakMemory,
all_stark.keccak_memory_stark,
&all_proof.stark_proofs[Table::KeccakMemory as usize],
&all_stark.cross_table_lookups,
&ctl_challenges,
states[2],
inner_config,
circuit_config,
)?
.0,
recursively_verify_stark_proof(
Table::Logic,
all_stark.logic_stark,
&all_proof.stark_proofs[Table::Logic as usize],
&all_stark.cross_table_lookups,
&ctl_challenges,
states[3],
inner_config,
circuit_config,
)?
.0,
recursively_verify_stark_proof(
Table::Memory,
all_stark.memory_stark,
&all_proof.stark_proofs[Table::Memory as usize],
&all_stark.cross_table_lookups,
&ctl_challenges,
states[4],
inner_config,
circuit_config,
)?
.0,
],
})
}
}