mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-04 14:53:08 +00:00
Add upgradeability to AllRecursiveCircuits and output verifier data (#1387)
* Add upgradeable preprocessed sizes * Add verifier data
This commit is contained in:
parent
3440ba94e6
commit
6dd2e313c4
@ -15,7 +15,7 @@ use plonky2::iop::target::{BoolTarget, Target};
|
||||
use plonky2::iop::witness::{PartialWitness, WitnessWrite};
|
||||
use plonky2::plonk::circuit_builder::CircuitBuilder;
|
||||
use plonky2::plonk::circuit_data::{
|
||||
CircuitConfig, CircuitData, CommonCircuitData, VerifierCircuitTarget,
|
||||
CircuitConfig, CircuitData, CommonCircuitData, VerifierCircuitData, VerifierCircuitTarget,
|
||||
};
|
||||
use plonky2::plonk::config::{AlgebraicHasher, GenericConfig};
|
||||
use plonky2::plonk::proof::{ProofWithPublicInputs, ProofWithPublicInputsTarget};
|
||||
@ -430,6 +430,78 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Expand the preprocessed STARK table circuits with the provided ranges.
|
||||
///
|
||||
/// If a range for a given table is contained within the current one, this will be a no-op.
|
||||
/// Otherwise, it will add the circuits for the missing table sizes, and regenerate the upper circuits.
|
||||
pub fn expand(
|
||||
&mut self,
|
||||
all_stark: &AllStark<F, D>,
|
||||
degree_bits_ranges: &[Range<usize>; NUM_TABLES],
|
||||
stark_config: &StarkConfig,
|
||||
) {
|
||||
self.by_table[Table::Arithmetic as usize].expand(
|
||||
Table::Arithmetic,
|
||||
&all_stark.arithmetic_stark,
|
||||
degree_bits_ranges[Table::Arithmetic as usize].clone(),
|
||||
&all_stark.cross_table_lookups,
|
||||
stark_config,
|
||||
);
|
||||
self.by_table[Table::BytePacking as usize].expand(
|
||||
Table::BytePacking,
|
||||
&all_stark.byte_packing_stark,
|
||||
degree_bits_ranges[Table::BytePacking as usize].clone(),
|
||||
&all_stark.cross_table_lookups,
|
||||
stark_config,
|
||||
);
|
||||
self.by_table[Table::Cpu as usize].expand(
|
||||
Table::Cpu,
|
||||
&all_stark.cpu_stark,
|
||||
degree_bits_ranges[Table::Cpu as usize].clone(),
|
||||
&all_stark.cross_table_lookups,
|
||||
stark_config,
|
||||
);
|
||||
self.by_table[Table::Keccak as usize].expand(
|
||||
Table::Keccak,
|
||||
&all_stark.keccak_stark,
|
||||
degree_bits_ranges[Table::Keccak as usize].clone(),
|
||||
&all_stark.cross_table_lookups,
|
||||
stark_config,
|
||||
);
|
||||
self.by_table[Table::KeccakSponge as usize].expand(
|
||||
Table::KeccakSponge,
|
||||
&all_stark.keccak_sponge_stark,
|
||||
degree_bits_ranges[Table::KeccakSponge as usize].clone(),
|
||||
&all_stark.cross_table_lookups,
|
||||
stark_config,
|
||||
);
|
||||
self.by_table[Table::Logic as usize].expand(
|
||||
Table::Logic,
|
||||
&all_stark.logic_stark,
|
||||
degree_bits_ranges[Table::Logic as usize].clone(),
|
||||
&all_stark.cross_table_lookups,
|
||||
stark_config,
|
||||
);
|
||||
self.by_table[Table::Memory as usize].expand(
|
||||
Table::Memory,
|
||||
&all_stark.memory_stark,
|
||||
degree_bits_ranges[Table::Memory as usize].clone(),
|
||||
&all_stark.cross_table_lookups,
|
||||
stark_config,
|
||||
);
|
||||
|
||||
// Regenerate the upper circuits.
|
||||
self.root = Self::create_root_circuit(&self.by_table, stark_config);
|
||||
self.aggregation = Self::create_aggregation_circuit(&self.root);
|
||||
self.block = Self::create_block_circuit(&self.aggregation);
|
||||
}
|
||||
|
||||
/// Outputs the `VerifierCircuitData` needed to verify any block proof
|
||||
/// generated by an honest prover.
|
||||
pub fn final_verifier_data(&self) -> VerifierCircuitData<F, C, D> {
|
||||
self.block.circuit.verifier_data()
|
||||
}
|
||||
|
||||
fn create_root_circuit(
|
||||
by_table: &[RecursiveCircuitsForTable<F, C, D>; NUM_TABLES],
|
||||
stark_config: &StarkConfig,
|
||||
@ -1201,6 +1273,32 @@ where
|
||||
Self { by_stark_size }
|
||||
}
|
||||
|
||||
fn expand<S: Stark<F, D>>(
|
||||
&mut self,
|
||||
table: Table,
|
||||
stark: &S,
|
||||
degree_bits_range: Range<usize>,
|
||||
all_ctls: &[CrossTableLookup<F>],
|
||||
stark_config: &StarkConfig,
|
||||
) {
|
||||
let new_ranges = degree_bits_range
|
||||
.filter(|degree_bits| !self.by_stark_size.contains_key(degree_bits))
|
||||
.collect_vec();
|
||||
|
||||
for degree_bits in new_ranges {
|
||||
self.by_stark_size.insert(
|
||||
degree_bits,
|
||||
RecursiveCircuitsForTableSize::new::<S>(
|
||||
table,
|
||||
stark,
|
||||
degree_bits,
|
||||
all_ctls,
|
||||
stark_config,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// For each initial `degree_bits`, get the final circuit at the end of that shrinking chain.
|
||||
/// Each of these final circuits should have degree `THRESHOLD_DEGREE_BITS`.
|
||||
fn final_circuits(&self) -> Vec<&CircuitData<F, C, D>> {
|
||||
|
||||
@ -77,9 +77,12 @@ fn test_empty_txn_list() -> anyhow::Result<()> {
|
||||
addresses: vec![],
|
||||
};
|
||||
|
||||
let all_circuits = AllRecursiveCircuits::<F, C, D>::new(
|
||||
// Initialize the preprocessed circuits for the zkEVM.
|
||||
// The provided ranges are the minimal ones to prove an empty list, except the one of the CPU
|
||||
// that is wrong for testing purposes, see below.
|
||||
let mut all_circuits = AllRecursiveCircuits::<F, C, D>::new(
|
||||
&all_stark,
|
||||
&[16..17, 10..11, 15..16, 14..15, 9..11, 12..13, 18..19], // Minimal ranges to prove an empty list
|
||||
&[16..17, 10..11, 12..13, 14..15, 9..11, 12..13, 18..19], // Minimal ranges to prove an empty list
|
||||
&config,
|
||||
);
|
||||
|
||||
@ -111,6 +114,20 @@ fn test_empty_txn_list() -> anyhow::Result<()> {
|
||||
assert_eq!(all_circuits, all_circuits_from_bytes);
|
||||
}
|
||||
|
||||
let mut timing = TimingTree::new("prove", log::Level::Info);
|
||||
// We're missing some preprocessed circuits.
|
||||
assert!(all_circuits
|
||||
.prove_root(&all_stark, &config, inputs.clone(), &mut timing)
|
||||
.is_err());
|
||||
|
||||
// Expand the preprocessed circuits.
|
||||
// We pass an empty range if we don't want to add different table sizes.
|
||||
all_circuits.expand(
|
||||
&all_stark,
|
||||
&[0..0, 0..0, 15..16, 0..0, 0..0, 0..0, 0..0],
|
||||
&StarkConfig::standard_fast_config(),
|
||||
);
|
||||
|
||||
let mut timing = TimingTree::new("prove", log::Level::Info);
|
||||
let (root_proof, public_values) =
|
||||
all_circuits.prove_root(&all_stark, &config, inputs, &mut timing)?;
|
||||
@ -129,7 +146,11 @@ fn test_empty_txn_list() -> anyhow::Result<()> {
|
||||
all_circuits.verify_aggregation(&agg_proof)?;
|
||||
|
||||
let (block_proof, _) = all_circuits.prove_block(None, &agg_proof, public_values)?;
|
||||
all_circuits.verify_block(&block_proof)
|
||||
all_circuits.verify_block(&block_proof)?;
|
||||
|
||||
// Get the verifier associated to these preprocessed circuits, and have it verify the block_proof.
|
||||
let verifier = all_circuits.final_verifier_data();
|
||||
verifier.verify(block_proof)
|
||||
}
|
||||
|
||||
fn init_logger() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user