Skip to content

Commit

Permalink
Merge pull request 0xPolygonZero#13 from topos-protocol/verifier-data
Browse files Browse the repository at this point in the history
Add a `VerifierState`
  • Loading branch information
Nashtare authored Jan 21, 2024
2 parents c429182 + 8fba4a9 commit 604e956
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 16 deletions.
18 changes: 18 additions & 0 deletions plonky_block_proof_gen/src/constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//! Hardcoded circuit constants to be used when generating the prover circuits.

use core::ops::Range;

/// Default range to be used for the `ArithmeticStark` table.
pub(crate) const DEFAULT_ARITHMETIC_RANGE: Range<usize> = 16..20;
/// Default range to be used for the `BytePackingStark` table.
pub(crate) const DEFAULT_BYTE_PACKING_RANGE: Range<usize> = 10..20;
/// Default range to be used for the `CpuStark` table.
pub(crate) const DEFAULT_CPU_RANGE: Range<usize> = 12..22;
/// Default range to be used for the `KeccakStark` table.
pub(crate) const DEFAULT_KECCAK_RANGE: Range<usize> = 14..17;
/// Default range to be used for the `KeccakSpongeStark` table.
pub(crate) const DEFAULT_KECCAK_SPONGE_RANGE: Range<usize> = 9..14;
/// Default range to be used for the `LogicStark` table.
pub(crate) const DEFAULT_LOGIC_RANGE: Range<usize> = 12..16;
/// Default range to be used for the `MemoryStark` table.
pub(crate) const DEFAULT_MEMORY_RANGE: Range<usize> = 17..25;
33 changes: 33 additions & 0 deletions plonky_block_proof_gen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,41 @@
//! curr_block_agg_proof: &GeneratedAggProof,
//! ) -> ProofGenResult<GeneratedBlockProof> { ... }
//! ```
//!
//! ## Verifying block proofs
//!
//! The `ProverState` can be used to verify any block proofs emitted with the
//! same set of circuits.
//! However, because the prover state can be quite heavy, the necessary verifier
//! data to verify block proofs can be saved independently into a
//! `VerifierState`, to allow anyone to easily verify block proofs.
//!
//! ```compile_fail
//! # use plonky_block_proof_gen::prover_state::ProverStateBuilder;
//! # use plonky_block_proof_gen::verifier_state::VerifierState;
//! let mut builder = ProverStateBuilder::default();
//!
//! // Generate a `ProverState` from the builder.
//! let prover_state = builder.build();
//!
//! // Derive a `VerifierState` from the `ProverState`.
//! let verifier_state: VerifierState = prover_state.into();
//!
//! // The prover generates some block proof.
//! let block_proof = prover_state.generate_block_proof(...);
//!
//! // Have the verifier attest validity of the proof.
//! assert!(verifier_state.verify(block_proof.intern).is_ok());
//! ```

pub(crate) mod constants;
pub mod proof_gen;
pub mod proof_types;
pub mod prover_state;
pub mod types;
pub mod verifier_state;

// Re-exports

pub use prover_state::ProverState;
pub use verifier_state::VerifierState;
32 changes: 16 additions & 16 deletions plonky_block_proof_gen/src/prover_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use log::info;
use paste::paste;
use plonky2_evm::{all_stark::AllStark, config::StarkConfig};

use crate::constants::*;
use crate::types::AllRecursiveCircuits;

/// Plonky2 proving state. Note that this is generally going to be massive in
Expand All @@ -21,28 +22,28 @@ pub struct ProverState {
/// Builder for the prover state.
#[derive(Debug)]
pub struct ProverStateBuilder {
arithmetic_circuit_size: Range<usize>,
byte_packing_circuit_size: Range<usize>,
cpu_circuit_size: Range<usize>,
keccak_circuit_size: Range<usize>,
keccak_sponge_circuit_size: Range<usize>,
logic_circuit_size: Range<usize>,
memory_circuit_size: Range<usize>,
pub(crate) arithmetic_circuit_size: Range<usize>,
pub(crate) byte_packing_circuit_size: Range<usize>,
pub(crate) cpu_circuit_size: Range<usize>,
pub(crate) keccak_circuit_size: Range<usize>,
pub(crate) keccak_sponge_circuit_size: Range<usize>,
pub(crate) logic_circuit_size: Range<usize>,
pub(crate) memory_circuit_size: Range<usize>,
}

impl Default for ProverStateBuilder {
fn default() -> Self {
// These ranges are somewhat arbitrary, but should be enough for testing
// The default ranges are somewhat arbitrary, but should be enough for testing
// purposes against most transactions.
// Some heavy contract deployments may require bumping these ranges though.
Self {
arithmetic_circuit_size: 16..20,
byte_packing_circuit_size: 10..20,
cpu_circuit_size: 12..22,
keccak_circuit_size: 14..17,
keccak_sponge_circuit_size: 9..14,
logic_circuit_size: 12..16,
memory_circuit_size: 17..25,
arithmetic_circuit_size: DEFAULT_ARITHMETIC_RANGE,
byte_packing_circuit_size: DEFAULT_BYTE_PACKING_RANGE,
cpu_circuit_size: DEFAULT_CPU_RANGE,
keccak_circuit_size: DEFAULT_KECCAK_RANGE,
keccak_sponge_circuit_size: DEFAULT_KECCAK_SPONGE_RANGE,
logic_circuit_size: DEFAULT_LOGIC_RANGE,
memory_circuit_size: DEFAULT_MEMORY_RANGE,
}
}
}
Expand Down Expand Up @@ -75,7 +76,6 @@ impl ProverStateBuilder {
pub fn build(self) -> ProverState {
info!("Initializing Plonky2 aggregation prover state (This may take a while)...");

// ... Yeah I don't understand the mysterious ranges either :)
let state = AllRecursiveCircuits::new(
&AllStark::default(),
&[
Expand Down
8 changes: 8 additions & 0 deletions plonky_block_proof_gen/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,11 @@ pub type AllRecursiveCircuits = plonky2_evm::fixed_recursive_verifier::AllRecurs
PoseidonGoldilocksConfig,
2,
>;

/// A type alias for the verifier data necessary to verify succinct block
/// proofs.
/// While the prover state [`AllRecursiveCircuits`] can also verify proofs, this
/// [`VerifierData`] is much lighter, allowing anyone to verify block proofs,
/// regardless of the underlying hardware.
pub type VerifierData =
plonky2::plonk::circuit_data::VerifierCircuitData<GoldilocksField, PoseidonGoldilocksConfig, 2>;
72 changes: 72 additions & 0 deletions plonky_block_proof_gen/src/verifier_state.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
//! This module defines the `VerifierState`, that contains the necessary data to
//! handle succinct block proofs verification.

use core::borrow::Borrow;

use log::info;
use plonky2::recursion::cyclic_recursion::check_cyclic_proof_verifier_data;

use crate::proof_gen::ProofGenResult;
use crate::prover_state::ProverStateBuilder;
use crate::types::PlonkyProofIntern;
use crate::{prover_state::ProverState, types::VerifierData};

/// Plonky2 verifier state.
///
/// The default generation requires generating all the prover data before
/// extracting the verifier-related data, which can take a long time and require
/// a large amount of memory.
pub struct VerifierState {
/// The verification circuit data associated to the block proof layer of the
/// plonky2 prover state.
pub state: VerifierData,
}

/// Builder for the verifier state.
/// This is essentially the same as the [`ProverStateBuilder`], in that we need
/// to first generate the entire prover state before extracting the verifier
/// data.
pub type VerifierStateBuilder = ProverStateBuilder;

impl VerifierStateBuilder {
/// Instantiate the verifier state from the builder. Note that this is a
/// very expensive call!
pub fn build_verifier(self) -> VerifierState {
info!("Initializing Plonky2 aggregation verifier state (This may take a while)...");
let ProverState { state } = self.build();
info!("Finished initializing Plonky2 aggregation verifier state!");

VerifierState {
state: state.final_verifier_data(),
}
}
}

/// Extracts the verifier state from the entire prover state.
impl<T: Borrow<ProverState>> From<T> for VerifierState {
fn from(prover_state: T) -> Self {
VerifierState {
state: prover_state.borrow().state.final_verifier_data(),
}
}
}

impl VerifierState {
/// Verifies a `block_proof`.
pub fn verify(&self, block_proof: &PlonkyProofIntern) -> ProofGenResult<()> {
// Proof verification
self.state
.verify(block_proof.clone())
.map_err(|err| err.to_string())?;

// Verifier data verification
check_cyclic_proof_verifier_data(
block_proof,
&self.state.verifier_only,
&self.state.common,
)
.map_err(|err| err.to_string())?;

Ok(())
}
}

0 comments on commit 604e956

Please sign in to comment.