diff --git a/halo2-base/Cargo.toml b/halo2-base/Cargo.toml index 3fca55a3..d957cb39 100644 --- a/halo2-base/Cargo.toml +++ b/halo2-base/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "halo2-base" -version = "0.4.0" +version = "0.4.1" edition = "2021" [dependencies] diff --git a/halo2-base/src/utils/halo2.rs b/halo2-base/src/utils/halo2.rs index a3781342..c6053292 100644 --- a/halo2-base/src/utils/halo2.rs +++ b/halo2-base/src/utils/halo2.rs @@ -3,7 +3,7 @@ use std::collections::hash_map::Entry; use crate::ff::Field; use crate::halo2_proofs::{ circuit::{AssignedCell, Cell, Region, Value}, - plonk::{Advice, Assigned, Column, Fixed}, + plonk::{Advice, Assigned, Circuit, Column, Fixed}, }; use crate::virtual_region::copy_constraints::{CopyConstraintManager, EXTERNAL_CELL_TYPE_ID}; use crate::AssignedValue; @@ -106,3 +106,70 @@ pub fn constrain_virtual_equals_external( } } } + +/// This trait should be implemented on the minimal circuit configuration data necessary to +/// completely determine a circuit (independent of circuit inputs). +/// This is used to generate a _dummy_ instantiation of a concrete `Circuit` type for the purposes of key generation. +/// This dummy instantiation just needs to have the correct arithmetization format, but the witnesses do not need to +/// satisfy constraints. +pub trait KeygenCircuitIntent { + /// Concrete circuit type + type ConcreteCircuit: Circuit; + /// Additional data that "pins" down the circuit. These can always to deterministically rederived from `Self`, but + /// storing the `Pinning` saves recomputations in future proof generations. + type Pinning; + + /// The intent must include the log_2 domain size of the circuit. + /// This is used to get the correct trusted setup file. + fn get_k(&self) -> u32; + + /// Builds a _dummy_ instantiation of `Self::ConcreteCircuit` for the purposes of key generation. + /// This dummy instantiation just needs to have the correct arithmetization format, but the witnesses do not need to + /// satisfy constraints. + fn build_keygen_circuit(self) -> Self::ConcreteCircuit; + + /// Pinning is only fully computed after `synthesize` has been run during keygen + fn get_pinning_after_keygen(circuit: &Self::ConcreteCircuit) -> Self::Pinning; +} + +pub use keygen::ProvingKeyGenerator; + +mod keygen { + use crate::halo2_proofs::{ + halo2curves::bn256::{Bn256, Fr, G1Affine}, + plonk::{self, ProvingKey}, + poly::kzg::commitment::ParamsKZG, + }; + + use super::KeygenCircuitIntent; + + /// Trait for creating a proving key and a pinning for a circuit from minimal circuit configuration data. + pub trait ProvingKeyGenerator { + /// Create proving key and pinning. + fn create_pk_and_pinning( + self, + kzg_params: &ParamsKZG, + ) -> (ProvingKey, serde_json::Value); + } + + impl> ProvingKeyGenerator for CI + where + CI::Pinning: serde::Serialize, + { + fn create_pk_and_pinning( + self, + kzg_params: &ParamsKZG, + ) -> (ProvingKey, serde_json::Value) { + let circuit = self.build_keygen_circuit(); + #[cfg(feature = "halo2-axiom")] + let pk = plonk::keygen_pk2(kzg_params, &circuit, false).unwrap(); + #[cfg(not(feature = "halo2-axiom"))] + let pk = { + let vk = plonk::keygen_vk_custom(kzg_params, &circuit, false).unwrap(); + plonk::keygen_pk(kzg_params, vk, &circuit).unwrap() + }; + let pinning = CI::get_pinning_after_keygen(&circuit); + (pk, serde_json::to_value(pinning).unwrap()) + } + } +} diff --git a/halo2-ecc/Cargo.toml b/halo2-ecc/Cargo.toml index 2caa7e96..5a041b5c 100644 --- a/halo2-ecc/Cargo.toml +++ b/halo2-ecc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "halo2-ecc" -version = "0.4.0" +version = "0.4.1" edition = "2021" [dependencies]