From b480ad25b14683654144aef7075187cc117b3500 Mon Sep 17 00:00:00 2001 From: Hanting Zhang Date: Wed, 31 Jan 2024 18:09:33 +0000 Subject: [PATCH] organize structs --- src/lib.rs | 229 ++++++++++++++++++++++++------------------- src/supernova/mod.rs | 138 ++++++++------------------ 2 files changed, 169 insertions(+), 198 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index f492f560a..5d8aced27 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,6 +28,7 @@ pub mod traits; pub mod supernova; use once_cell::sync::OnceCell; +use traits::commitment::Len; use crate::digest::{DigestComputer, SimpleDigestible}; use crate::{ @@ -87,130 +88,76 @@ impl R1CSWithArity { } } -/// A type that holds public parameters of Nova +/// A helper struct for holding [`CommitmentKey`]s #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(bound = "")] -pub struct PublicParams +pub struct CommitmentKeyParams where E1: Engine::Scalar>, E2: Engine::Scalar>, - C1: StepCircuit, - C2: StepCircuit, { - F_arity_primary: usize, - F_arity_secondary: usize, - ro_consts_primary: ROConstants, - ro_consts_circuit_primary: ROConstantsCircuit, - ck_primary: Arc>, - circuit_shape_primary: R1CSWithArity, - ro_consts_secondary: ROConstants, - ro_consts_circuit_secondary: ROConstantsCircuit, - ck_secondary: Arc>, - circuit_shape_secondary: R1CSWithArity, - augmented_circuit_params_primary: NovaAugmentedCircuitParams, - augmented_circuit_params_secondary: NovaAugmentedCircuitParams, - #[serde(skip, default = "OnceCell::new")] - digest: OnceCell, - _p: PhantomData<(C1, C2)>, + /// Primary key + pub primary: CommitmentKey, + /// Secondary key + pub secondary: CommitmentKey, } -// Ensure to include necessary crates and features in your Cargo.toml -// e.g., abomonation, serde, etc., with the appropriate feature flags. - -/// A version of [`crate::PublicParams`] that is amenable to fast ser/de using Abomonation -#[cfg(feature = "abomonate")] +/// Auxiliary [PublicParams] information about constants of the primary and +/// secondary circuit. This is used as a helper struct when reconstructing +/// [PublicParams] downstream in lurk. #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Abomonation)] #[serde(bound = "")] -#[abomonation_bounds( -where +#[abomonation_bounds(where E1: Engine::Scalar>, E2: Engine::Scalar>, - C1: StepCircuit, - C2: StepCircuit, - ::Repr: Abomonation, - ::Repr: Abomonation, + <::Scalar as ff::PrimeField>::Repr: Abomonation, + <::Scalar as ff::PrimeField>::Repr: Abomonation, )] -pub struct FlatPublicParams +pub struct AuxParams where E1: Engine::Scalar>, E2: Engine::Scalar>, - C1: StepCircuit, - C2: StepCircuit, { - F_arity_primary: usize, - F_arity_secondary: usize, + /// Hint for how long `ck_primary` should be + pub ck_primary_len: usize, ro_consts_primary: ROConstants, ro_consts_circuit_primary: ROConstantsCircuit, - ck_primary: CommitmentKey, - circuit_shape_primary: R1CSWithArity, + augmented_circuit_params_primary: NovaAugmentedCircuitParams, + + /// Hint for how long `ck_secondary` should be + pub ck_secondary_len: usize, ro_consts_secondary: ROConstants, ro_consts_circuit_secondary: ROConstantsCircuit, - ck_secondary: CommitmentKey, circuit_shape_secondary: R1CSWithArity, - augmented_circuit_params_primary: NovaAugmentedCircuitParams, augmented_circuit_params_secondary: NovaAugmentedCircuitParams, - _p: PhantomData<(C1, C2)>, -} -#[cfg(feature = "abomonate")] -impl TryFrom> for FlatPublicParams -where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - C1: StepCircuit, - C2: StepCircuit, -{ - type Error = &'static str; - - fn try_from(value: PublicParams) -> Result { - let ck_primary = - Arc::try_unwrap(value.ck_primary).map_err(|_| "Failed to unwrap Arc for ck_primary")?; - let ck_secondary = - Arc::try_unwrap(value.ck_secondary).map_err(|_| "Failed to unwrap Arc for ck_secondary")?; - Ok(Self { - F_arity_primary: value.F_arity_primary, - F_arity_secondary: value.F_arity_secondary, - ro_consts_primary: value.ro_consts_primary, - ro_consts_circuit_primary: value.ro_consts_circuit_primary, - ck_primary, - circuit_shape_primary: value.circuit_shape_primary, - ro_consts_secondary: value.ro_consts_secondary, - ro_consts_circuit_secondary: value.ro_consts_circuit_secondary, - ck_secondary, - circuit_shape_secondary: value.circuit_shape_secondary, - augmented_circuit_params_primary: value.augmented_circuit_params_primary, - augmented_circuit_params_secondary: value.augmented_circuit_params_secondary, - _p: PhantomData, - }) - } + #[abomonate_with(::Repr)] + digest: E1::Scalar, } -#[cfg(feature = "abomonate")] -impl From> for PublicParams +/// A type that holds public parameters of Nova +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(bound = "")] +pub struct PublicParams where E1: Engine::Scalar>, E2: Engine::Scalar>, C1: StepCircuit, C2: StepCircuit, { - fn from(value: FlatPublicParams) -> Self { - Self { - F_arity_primary: value.F_arity_primary, - F_arity_secondary: value.F_arity_secondary, - ro_consts_primary: value.ro_consts_primary, - ro_consts_circuit_primary: value.ro_consts_circuit_primary, - ck_primary: Arc::new(value.ck_primary), - circuit_shape_primary: value.circuit_shape_primary, - ro_consts_secondary: value.ro_consts_secondary, - ro_consts_circuit_secondary: value.ro_consts_circuit_secondary, - ck_secondary: Arc::new(value.ck_secondary), - circuit_shape_secondary: value.circuit_shape_secondary, - augmented_circuit_params_primary: value.augmented_circuit_params_primary, - augmented_circuit_params_secondary: value.augmented_circuit_params_secondary, - digest: OnceCell::new(), - _p: PhantomData, - } - } + ro_consts_primary: ROConstants, + ro_consts_circuit_primary: ROConstantsCircuit, + ck_primary: Arc>, + circuit_shape_primary: R1CSWithArity, + ro_consts_secondary: ROConstants, + ro_consts_circuit_secondary: ROConstantsCircuit, + ck_secondary: Arc>, + circuit_shape_secondary: R1CSWithArity, + augmented_circuit_params_primary: NovaAugmentedCircuitParams, + augmented_circuit_params_secondary: NovaAugmentedCircuitParams, + #[serde(skip, default = "OnceCell::new")] + digest: OnceCell, + _p: PhantomData<(C1, C2)>, } impl SimpleDigestible for PublicParams @@ -320,8 +267,6 @@ where let circuit_shape_secondary = R1CSWithArity::new(r1cs_shape_secondary, F_arity_secondary); Self { - F_arity_primary, - F_arity_secondary, ro_consts_primary, ro_consts_circuit_primary, ck_primary, @@ -361,6 +306,84 @@ where self.circuit_shape_secondary.r1cs_shape.num_vars, ) } + + /// Breaks down an instance of [PublicParams] into the circuit params and auxiliary params. + pub fn into_parts( + self, + ) -> ( + R1CSWithArity, + CommitmentKeyParams, + AuxParams, + ) { + let digest = self.digest(); + + let Self { + ro_consts_primary, + ro_consts_circuit_primary, + ck_primary, + circuit_shape_primary, + ro_consts_secondary, + ro_consts_circuit_secondary, + ck_secondary, + circuit_shape_secondary, + augmented_circuit_params_primary, + augmented_circuit_params_secondary, + digest: _digest, + _p, + } = self; + + let ck_primary_len = ck_primary.length(); + let ck_secondary_len = ck_secondary.length(); + let ck_params = CommitmentKeyParams { + primary: Arc::try_unwrap(ck_primary).unwrap_or_else(|arc| (*arc).clone()), + secondary: Arc::try_unwrap(ck_secondary).unwrap_or_else(|arc| (*arc).clone()), + }; + + let aux_params = AuxParams { + ck_primary_len, + ro_consts_primary, + ro_consts_circuit_primary, + augmented_circuit_params_primary, + ck_secondary_len, + ro_consts_secondary, + ro_consts_circuit_secondary, + circuit_shape_secondary, + augmented_circuit_params_secondary, + digest, + }; + + (circuit_shape_primary, ck_params, aux_params) + } + + /// Create a [PublicParams] from a raw [R1CSWithArity] and auxiliary params. + pub fn from_parts( + circuit_shape: R1CSWithArity, + ck_params: CommitmentKeyParams, + aux_params: AuxParams, + ) -> Self { + assert_eq!(ck_params.primary.length(), aux_params.ck_primary_len, "incorrect primary key length"); + assert_eq!(ck_params.secondary.length(), aux_params.ck_secondary_len, "incorrect secondary key length"); + let pp = Self { + ro_consts_primary: aux_params.ro_consts_primary, + ro_consts_circuit_primary: aux_params.ro_consts_circuit_primary, + ck_primary: Arc::new(ck_params.primary), + circuit_shape_primary: circuit_shape, + augmented_circuit_params_primary: aux_params.augmented_circuit_params_primary, + ro_consts_secondary: aux_params.ro_consts_secondary, + ro_consts_circuit_secondary: aux_params.ro_consts_circuit_secondary, + ck_secondary: Arc::new(ck_params.secondary), + circuit_shape_secondary: aux_params.circuit_shape_secondary, + augmented_circuit_params_secondary: aux_params.augmented_circuit_params_secondary, + digest: OnceCell::new(), + _p: PhantomData, + }; + assert_eq!( + aux_params.digest, + pp.digest(), + "param data is invalid; aux_params contained the incorrect digest" + ); + pp + } } /// A resource buffer for [`RecursiveSNARK`] for storing scratch values that are computed by `prove_step`, @@ -423,7 +446,9 @@ where z0_primary: &[E1::Scalar], z0_secondary: &[E2::Scalar], ) -> Result { - if z0_primary.len() != pp.F_arity_primary || z0_secondary.len() != pp.F_arity_secondary { + if z0_primary.len() != pp.circuit_shape_primary.F_arity + || z0_secondary.len() != pp.circuit_shape_secondary.F_arity + { return Err(NovaError::InvalidInitialInputLength); } @@ -490,7 +515,8 @@ where let r_U_secondary = RelaxedR1CSInstance::::default(&pp.ck_secondary, r1cs_secondary); assert!( - !(zi_primary.len() != pp.F_arity_primary || zi_secondary.len() != pp.F_arity_secondary), + !(zi_primary.len() != pp.circuit_shape_primary.F_arity + || zi_secondary.len() != pp.circuit_shape_secondary.F_arity), "Invalid step length" ); @@ -693,7 +719,7 @@ where let (hash_primary, hash_secondary) = { let mut hasher = ::RO::new( pp.ro_consts_secondary.clone(), - NUM_FE_WITHOUT_IO_FOR_CRHF + 2 * pp.F_arity_primary, + NUM_FE_WITHOUT_IO_FOR_CRHF + 2 * pp.circuit_shape_primary.F_arity, ); hasher.absorb(pp.digest()); hasher.absorb(E1::Scalar::from(num_steps as u64)); @@ -707,7 +733,7 @@ where let mut hasher2 = ::RO::new( pp.ro_consts_primary.clone(), - NUM_FE_WITHOUT_IO_FOR_CRHF + 2 * pp.F_arity_secondary, + NUM_FE_WITHOUT_IO_FOR_CRHF + 2 * pp.circuit_shape_secondary.F_arity, ); hasher2.absorb(scalar_as_base::(pp.digest())); hasher2.absorb(E2::Scalar::from(num_steps as u64)); @@ -876,8 +902,8 @@ where }; let vk = VerifierKey { - F_arity_primary: pp.F_arity_primary, - F_arity_secondary: pp.F_arity_secondary, + F_arity_primary: pp.circuit_shape_primary.F_arity, + F_arity_secondary: pp.circuit_shape_secondary.F_arity, ro_consts_primary: pp.ro_consts_primary.clone(), ro_consts_secondary: pp.ro_consts_secondary.clone(), pp_digest: pp.digest(), @@ -1062,7 +1088,8 @@ pub fn circuit_digest< cs.r1cs_shape().digest() } -type CommitmentKey = <::CE as CommitmentEngineTrait>::CommitmentKey; +/// must fix later +pub type CommitmentKey = <::CE as CommitmentEngineTrait>::CommitmentKey; type Commitment = <::CE as CommitmentEngineTrait>::Commitment; type CompressedCommitment = <<::CE as CommitmentEngineTrait>::Commitment as CommitmentTrait>::CompressedCommitment; type CE = ::CE; diff --git a/src/supernova/mod.rs b/src/supernova/mod.rs index 77f022f1a..540788808 100644 --- a/src/supernova/mod.rs +++ b/src/supernova/mod.rs @@ -14,20 +14,16 @@ use crate::{ }, scalar_as_base, traits::{ - commitment::{CommitmentEngineTrait, CommitmentTrait}, + commitment::{CommitmentEngineTrait, CommitmentTrait, Len}, AbsorbInROTrait, Engine, ROConstants, ROConstantsCircuit, ROTrait, }, - Commitment, CommitmentKey, R1CSWithArity, + Commitment, CommitmentKey, CommitmentKeyParams, R1CSWithArity, }; -#[cfg(feature = "abomonate")] use abomonation::Abomonation; -#[cfg(feature = "abomonate")] use abomonation_derive::Abomonation; use bellpepper_core::SynthesisError; use ff::Field; -#[cfg(feature = "abomonate")] -use ff::PrimeField; use itertools::Itertools as _; use once_cell::sync::OnceCell; use rayon::prelude::*; @@ -109,111 +105,39 @@ where _p: PhantomData<(C1, C2)>, } -/// Auxiliary [PublicParams] information about the commitment keys and +/// Auxiliary [PublicParams] information about constants of the primary /// secondary circuit. This is used as a helper struct when reconstructing /// [PublicParams] downstream in lurk. -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -#[serde(bound = "")] -pub struct AuxParams -where - E1: Engine::Scalar>, - E2: Engine::Scalar>, -{ - ro_consts_primary: ROConstants, - ro_consts_circuit_primary: ROConstantsCircuit, - ck_primary: Arc>, // This is shared between all circuit params - augmented_circuit_params_primary: SuperNovaAugmentedCircuitParams, - - ro_consts_secondary: ROConstants, - ro_consts_circuit_secondary: ROConstantsCircuit, - ck_secondary: Arc>, - circuit_shape_secondary: R1CSWithArity, - augmented_circuit_params_secondary: SuperNovaAugmentedCircuitParams, - - digest: E1::Scalar, -} - -/// A variant of [`crate::supernova::AuxParams`] that is suitable for fast ser/de using Abomonation -#[cfg(feature = "abomonate")] #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Abomonation)] #[serde(bound = "")] -#[abomonation_bounds( -where +#[abomonation_bounds(where E1: Engine::Scalar>, E2: Engine::Scalar>, - ::Repr: Abomonation, - ::Repr: Abomonation, + <::Scalar as ff::PrimeField>::Repr: Abomonation, + <::Scalar as ff::PrimeField>::Repr: Abomonation, )] -pub struct FlatAuxParams +pub struct AuxParams where E1: Engine::Scalar>, E2: Engine::Scalar>, { + /// Hint for how long `ck_primary` should be + pub ck_primary_len: usize, ro_consts_primary: ROConstants, ro_consts_circuit_primary: ROConstantsCircuit, - ck_primary: CommitmentKey, // This is shared between all circuit params augmented_circuit_params_primary: SuperNovaAugmentedCircuitParams, + /// Hint for how long `ck_secondary` should be + pub ck_secondary_len: usize, ro_consts_secondary: ROConstants, ro_consts_circuit_secondary: ROConstantsCircuit, - ck_secondary: CommitmentKey, circuit_shape_secondary: R1CSWithArity, augmented_circuit_params_secondary: SuperNovaAugmentedCircuitParams, - #[abomonate_with(::Repr)] + #[abomonate_with(::Repr)] digest: E1::Scalar, } -#[cfg(feature = "abomonate")] -impl TryFrom> for FlatAuxParams -where - E1: Engine::Scalar>, - E2: Engine::Scalar>, -{ - type Error = &'static str; - - fn try_from(value: AuxParams) -> Result { - let ck_primary = - Arc::try_unwrap(value.ck_primary).map_err(|_| "Failed to unwrap Arc for ck_primary")?; - let ck_secondary = - Arc::try_unwrap(value.ck_secondary).map_err(|_| "Failed to unwrap Arc for ck_secondary")?; - Ok(Self { - ro_consts_primary: value.ro_consts_primary, - ro_consts_circuit_primary: value.ro_consts_circuit_primary, - ck_primary, - augmented_circuit_params_primary: value.augmented_circuit_params_primary, - ro_consts_secondary: value.ro_consts_secondary, - ro_consts_circuit_secondary: value.ro_consts_circuit_secondary, - ck_secondary, - circuit_shape_secondary: value.circuit_shape_secondary, - augmented_circuit_params_secondary: value.augmented_circuit_params_secondary, - digest: value.digest, - }) - } -} - -#[cfg(feature = "abomonate")] -impl From> for AuxParams -where - E1: Engine::Scalar>, - E2: Engine::Scalar>, -{ - fn from(value: FlatAuxParams) -> Self { - Self { - ro_consts_primary: value.ro_consts_primary, - ro_consts_circuit_primary: value.ro_consts_circuit_primary, - ck_primary: Arc::new(value.ck_primary), - augmented_circuit_params_primary: value.augmented_circuit_params_primary, - ro_consts_secondary: value.ro_consts_secondary, - ro_consts_circuit_secondary: value.ro_consts_circuit_secondary, - ck_secondary: Arc::new(value.ck_secondary), - circuit_shape_secondary: value.circuit_shape_secondary, - augmented_circuit_params_secondary: value.augmented_circuit_params_secondary, - digest: value.digest, - } - } -} - impl Index for PublicParams where E1: Engine::Scalar>, @@ -345,7 +269,13 @@ where } /// Breaks down an instance of [PublicParams] into the circuit params and auxiliary params. - pub fn into_parts(self) -> (Vec>, AuxParams) { + pub fn into_parts( + self, + ) -> ( + Vec>, + CommitmentKeyParams, + AuxParams, + ) { let digest = self.digest(); let Self { @@ -363,33 +293,46 @@ where _p, } = self; + let ck_primary_len = ck_primary.length(); + let ck_secondary_len = ck_secondary.length(); + let ck_params = CommitmentKeyParams { + primary: Arc::try_unwrap(ck_primary).unwrap_or_else(|arc| (*arc).clone()), + secondary: Arc::try_unwrap(ck_secondary).unwrap_or_else(|arc| (*arc).clone()), + }; + let aux_params = AuxParams { + ck_primary_len, ro_consts_primary, ro_consts_circuit_primary, - ck_primary, augmented_circuit_params_primary, + ck_secondary_len, ro_consts_secondary, ro_consts_circuit_secondary, - ck_secondary, circuit_shape_secondary, augmented_circuit_params_secondary, digest, }; - (circuit_shapes, aux_params) + (circuit_shapes, ck_params, aux_params) } /// Create a [PublicParams] from a vector of raw [R1CSWithArity] and auxiliary params. - pub fn from_parts(circuit_shapes: Vec>, aux_params: AuxParams) -> Self { + pub fn from_parts( + circuit_shapes: Vec>, + ck_params: CommitmentKeyParams, + aux_params: AuxParams, + ) -> Self { + assert_eq!(ck_params.primary.length(), aux_params.ck_primary_len, "incorrect primary key length"); + assert_eq!(ck_params.secondary.length(), aux_params.ck_secondary_len, "incorrect secondary key length"); let pp = Self { circuit_shapes, ro_consts_primary: aux_params.ro_consts_primary, ro_consts_circuit_primary: aux_params.ro_consts_circuit_primary, - ck_primary: aux_params.ck_primary, + ck_primary: Arc::new(ck_params.primary), augmented_circuit_params_primary: aux_params.augmented_circuit_params_primary, ro_consts_secondary: aux_params.ro_consts_secondary, ro_consts_circuit_secondary: aux_params.ro_consts_circuit_secondary, - ck_secondary: aux_params.ck_secondary, + ck_secondary: Arc::new(ck_params.secondary), circuit_shape_secondary: aux_params.circuit_shape_secondary, augmented_circuit_params_secondary: aux_params.augmented_circuit_params_secondary, digest: OnceCell::new(), @@ -407,17 +350,18 @@ where /// We don't check that the `aux_params.digest` is a valid digest for the created params. pub fn from_parts_unchecked( circuit_shapes: Vec>, + ck_params: CommitmentKeyParams, aux_params: AuxParams, ) -> Self { Self { circuit_shapes, ro_consts_primary: aux_params.ro_consts_primary, ro_consts_circuit_primary: aux_params.ro_consts_circuit_primary, - ck_primary: aux_params.ck_primary, + ck_primary: Arc::new(ck_params.primary), augmented_circuit_params_primary: aux_params.augmented_circuit_params_primary, ro_consts_secondary: aux_params.ro_consts_secondary, ro_consts_circuit_secondary: aux_params.ro_consts_circuit_secondary, - ck_secondary: aux_params.ck_secondary, + ck_secondary: Arc::new(ck_params.secondary), circuit_shape_secondary: aux_params.circuit_shape_secondary, augmented_circuit_params_secondary: aux_params.augmented_circuit_params_secondary, digest: aux_params.digest.into(),