From 8a81dde11acf2b5dfd4dd13f5d444d942d7be8e2 Mon Sep 17 00:00:00 2001 From: Robin Salen <30937548+Nashtare@users.noreply.github.com> Date: Fri, 12 Jul 2024 02:40:12 +0900 Subject: [PATCH] Add necessary 2-to-1 aggreg. components for `proof_gen` (#364) * Two to one aggregation * Comments * Two-to-one block aggregation proof * Minor * Minor * feat: Implement two-to-one Block Aggregation WIP: compute hashes directly from witness and check against public inputs WIP: add TwoToOneBlockAggCircuitData WIP: add test WIP: rewrite to use hasher circuitry WIP: test: can generate proofs of unrelated blocks WIP: test/refactor: generate multiple blocks WIP: test/refactor: autoformat WIP: refactor: use result iterator WIP: convert PIS WIP: feat: witness: set public input hashes WIP: feat: cache proofs in /tmp WIP: config: default to no cache WIP: bug: cache write-read assertion fails WIP: bug: prepare for more eyeballs WIP: bug: work on to_public_inputs WIP feat: private public inputs WIP feat: set pv targets WIP experiment: public input WIP refactor: clean up WIP feat: 1-level aggregation working WIP forgot: private public inputs WIP: use agg child structure WIP: split into IVC and binop WIP: split part2 into IVC and binop WIP: split part3 into IVC and binop WIP: ivc structure done WIP: wip wip WIP: ivc+binop WIP: after talking to Linda WIP: adjust num_public_inputs WIP: VirtualTarget index: 5 was set twice feat: assert on input values length experiment: minimize failing circuit feat: add selector for public values WIP: bug: add methods from branch `no_dummy_segment_no_pis` WIP: bug: first draft feat: verify 4-block aggregation test: add more tests * cleanup(tests) * cleanup(tests): obey Clippy * cleanup: remove unneeded experiment * cleanup: remove vector to public inputs * cleanup: remove IVC and re-add two_to_one_block * cleanup: fix de/serialization * cleanup: add comments * cleanup: remove checks * cleanup: remove unrelated change * cleanup: remove unused parameter and todo * feat: enable caching as default * cleanup: remove previous block aggregation implementation * refactor: simplify naming * refactor: improve naming * cleanup: remove custom build config * cleanup: undo this change * cleanup: obey Clippy * cleanup: remove two-to-one aggregation * review: resolve small issues * fixup! cleanup: remove two-to-one aggregation * review: make order consistent * fixup! review: make order consistent * review: merge aggregation children * review: rename `evm_proof` to `base_proof` * review: squash tests * review: investigate padding length * review: investigate padding length part 2 * review: remove magic numbers * review: remove HasCircuit trait and pass in CircuitData field directly * review: rework `set_dummy_if_necessary` * review: remove logging in test * review: remove legacy test * review: remove all `debug_assert!` * review: obey Clippy and fmt * review: impl Merklet tree test * WIP review: fix hashing mechanism and make hash public input * review: remove VK from inputs * review: test Merkle tree working * review: refactor: remove scaffolding * review: fix ascii art * review: clippy * review: remove logging * review: fmt * review: remove redundant computations * fmt * review: implement feedback from Hamy * fmt * Add necessary methods for proof_gen * Update comment * Fix comment --------- Co-authored-by: wborgeaud Co-authored-by: Einar Rasmussen --- proof_gen/src/proof_gen.rs | 26 +++++++++++++- proof_gen/src/proof_types.rs | 69 ++++++++++++++++++++++++++++++++++-- proof_gen/src/types.rs | 7 +++- 3 files changed, 98 insertions(+), 4 deletions(-) diff --git a/proof_gen/src/proof_gen.rs b/proof_gen/src/proof_gen.rs index f41167490..e2a1f0daa 100644 --- a/proof_gen/src/proof_gen.rs +++ b/proof_gen/src/proof_gen.rs @@ -12,7 +12,10 @@ use plonky2::{ }; use crate::{ - proof_types::{AggregatableProof, GeneratedAggProof, GeneratedBlockProof, GeneratedTxnProof}, + proof_types::{ + AggregatableBlockProof, AggregatableProof, GeneratedAggBlockProof, GeneratedAggProof, + GeneratedBlockProof, GeneratedTxnProof, + }, prover_state::ProverState, types::{Config, Field, PlonkyProofIntern, EXTENSION_DEGREE}, }; @@ -114,6 +117,27 @@ pub fn generate_block_proof( }) } +/// Generates an aggregation block proof from two child proofs. +/// +/// Note that the child proofs may be either block or aggregation proofs. +pub fn generate_agg_block_proof( + p_state: &ProverState, + lhs_child: &AggregatableBlockProof, + rhs_child: &AggregatableBlockProof, +) -> ProofGenResult { + let intern = p_state + .state + .prove_two_to_one_block( + lhs_child.intern(), + lhs_child.is_agg(), + rhs_child.intern(), + rhs_child.is_agg(), + ) + .map_err(|err| err.to_string())?; + + Ok(GeneratedAggBlockProof { intern }) +} + /// Generates a dummy proof for a dummy circuit doing nothing. /// This is useful for testing purposes only. pub fn dummy_proof() -> ProofGenResult { diff --git a/proof_gen/src/proof_types.rs b/proof_gen/src/proof_types.rs index 49d3b25f3..037daa1c1 100644 --- a/proof_gen/src/proof_types.rs +++ b/proof_gen/src/proof_types.rs @@ -1,10 +1,15 @@ //! This module defines the various proof types used throughout the block proof //! generation process. -use evm_arithmetization::{proof::PublicValues, BlockHeight}; +use evm_arithmetization::{ + fixed_recursive_verifier::{extract_block_public_values, extract_two_to_one_block_hash}, + proof::PublicValues, + BlockHeight, +}; +use plonky2::plonk::config::Hasher as _; use serde::{Deserialize, Serialize}; -use crate::types::PlonkyProofIntern; +use crate::types::{Hash, Hasher, PlonkyProofIntern}; /// A transaction proof along with its public values, for proper connection with /// contiguous proofs. @@ -39,6 +44,17 @@ pub struct GeneratedBlockProof { pub intern: PlonkyProofIntern, } +/// An aggregation block proof along with its hashed public values, for proper +/// connection with other proofs. +/// +/// Aggregation block proofs can represent any aggregation of independent +/// blocks. +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct GeneratedAggBlockProof { + /// Underlying plonky2 proof. + pub intern: PlonkyProofIntern, +} + /// Sometimes we don't care about the underlying proof type and instead only if /// we can combine it into an agg proof. For these cases, we want to abstract /// away whether or not the proof was a txn or agg proof. @@ -84,3 +100,52 @@ impl From for AggregatableProof { Self::Agg(v) } } + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub enum AggregatableBlockProof { + /// The underlying proof is a single block proof. + Block(GeneratedBlockProof), + /// The underlying proof is an aggregated proof. + Agg(GeneratedAggBlockProof), +} + +impl AggregatableBlockProof { + pub fn pv_hash(&self) -> Hash { + match self { + AggregatableBlockProof::Block(info) => { + let pv = extract_block_public_values(&info.intern.public_inputs); + Hasher::hash_no_pad(pv) + } + AggregatableBlockProof::Agg(info) => { + let hash = extract_two_to_one_block_hash(&info.intern.public_inputs); + Hash::from_partial(hash) + } + } + } + + pub(crate) const fn is_agg(&self) -> bool { + match self { + AggregatableBlockProof::Block(_) => false, + AggregatableBlockProof::Agg(_) => true, + } + } + + pub(crate) const fn intern(&self) -> &PlonkyProofIntern { + match self { + AggregatableBlockProof::Block(info) => &info.intern, + AggregatableBlockProof::Agg(info) => &info.intern, + } + } +} + +impl From for AggregatableBlockProof { + fn from(v: GeneratedBlockProof) -> Self { + Self::Block(v) + } +} + +impl From for AggregatableBlockProof { + fn from(v: GeneratedAggBlockProof) -> Self { + Self::Agg(v) + } +} diff --git a/proof_gen/src/types.rs b/proof_gen/src/types.rs index e3238e00b..bf1b4185c 100644 --- a/proof_gen/src/types.rs +++ b/proof_gen/src/types.rs @@ -3,7 +3,8 @@ use plonky2::{ field::goldilocks_field::GoldilocksField, - plonk::{config::PoseidonGoldilocksConfig, proof::ProofWithPublicInputs}, + hash::poseidon::PoseidonHash, + plonk::{self, config::PoseidonGoldilocksConfig, proof::ProofWithPublicInputs}, }; /// The base field on which statements are being proven. @@ -17,6 +18,10 @@ pub const EXTENSION_DEGREE: usize = 2; /// A type alias for proofs generated by the zkEVM. pub type PlonkyProofIntern = ProofWithPublicInputs; +pub type Hasher = PoseidonHash; + +pub type Hash = >::Hash; + /// A type alias for the set of preprocessed circuits necessary to generate /// succinct block proofs. pub type AllRecursiveCircuits = evm_arithmetization::fixed_recursive_verifier::AllRecursiveCircuits<