From 8891ce7348a4e7c4cd64dbcc783d2ca968746636 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Garillot?= Date: Fri, 3 Nov 2023 09:00:51 -0400 Subject: [PATCH] refactor: Refactor public parameters setup to remove optionality of commitment key size hint - Converted `CommitmentKeyHint` from a boxed dynamic trait object to a direct dynamic trait object in `r1cs/mod.rs`. - Changed the `commitment_key` function to always require a commitment key floor, eliminating the need for default behavior when a floor function isn't provided. - Updated the `r1cs_shape` function across various files to take in a `CommitmentKeyHint` instead of it being optional and introduce a closure as an argument. - Relevant modifications and updates were made in the `r1cs_shape` and `commitment_key` function calls within the test functions for various modules. --- benches/compressed-snark.rs | 8 ++++---- benches/compute-digest.rs | 4 ++-- benches/recursive-snark.rs | 2 +- benches/sha256.rs | 2 +- examples/minroot.rs | 2 +- src/bellpepper/mod.rs | 2 +- src/bellpepper/r1cs.rs | 10 +++++----- src/circuit.rs | 4 ++-- src/gadgets/ecc.rs | 6 +++--- src/lib.rs | 39 ++++++++++++++++++++----------------- src/nifs.rs | 4 ++-- src/r1cs/mod.rs | 11 +++++------ src/spartan/direct.rs | 2 +- 13 files changed, 49 insertions(+), 47 deletions(-) diff --git a/benches/compressed-snark.rs b/benches/compressed-snark.rs index 83906f6fa..d624f2348 100644 --- a/benches/compressed-snark.rs +++ b/benches/compressed-snark.rs @@ -69,8 +69,8 @@ fn bench_compressed_snark(c: &mut Criterion) { let pp = PublicParams::::setup( &c_primary, &c_secondary, - Some(S1::commitment_key_floor()), - Some(S2::commitment_key_floor()), + &*S1::commitment_key_floor(), + &*S2::commitment_key_floor(), ); // Produce prover and verifier keys for CompressedSNARK @@ -156,8 +156,8 @@ fn bench_compressed_snark_with_computational_commitments(c: &mut Criterion) { let pp = PublicParams::::setup( &c_primary, &c_secondary, - Some(SS1::commitment_key_floor()), - Some(SS2::commitment_key_floor()), + &*SS1::commitment_key_floor(), + &*SS2::commitment_key_floor(), ); // Produce prover and verifier keys for CompressedSNARK let (pk, vk) = CompressedSNARK::<_, _, _, _, SS1, SS2>::setup(&pp).unwrap(); diff --git a/benches/compute-digest.rs b/benches/compute-digest.rs index 9bff6c104..249d7bd9e 100644 --- a/benches/compute-digest.rs +++ b/benches/compute-digest.rs @@ -30,8 +30,8 @@ fn bench_compute_digest(c: &mut Criterion) { PublicParams::::setup( black_box(&C1::new(10)), black_box(&C2::default()), - black_box(None), - black_box(None), + black_box(&(|_| 0)), + black_box(&(|_| 0)), ) }) }); diff --git a/benches/recursive-snark.rs b/benches/recursive-snark.rs index c2e15412f..c59c8c86c 100644 --- a/benches/recursive-snark.rs +++ b/benches/recursive-snark.rs @@ -56,7 +56,7 @@ fn bench_recursive_snark(c: &mut Criterion) { let c_secondary = TrivialCircuit::default(); // Produce public parameters - let pp = PublicParams::::setup(&c_primary, &c_secondary, None, None); + let pp = PublicParams::::setup(&c_primary, &c_secondary, &(|_| 0), &(|_| 0)); // Bench time to produce a recursive SNARK; // we execute a certain number of warm-up steps since executing diff --git a/benches/sha256.rs b/benches/sha256.rs index 9b43d73ea..192ae3d77 100644 --- a/benches/sha256.rs +++ b/benches/sha256.rs @@ -155,7 +155,7 @@ fn bench_recursive_snark(c: &mut Criterion) { // Produce public parameters let ttc = TrivialCircuit::default(); - let pp = PublicParams::::setup(&circuit_primary, &ttc, None, None); + let pp = PublicParams::::setup(&circuit_primary, &ttc, &(|_| 0), &(|_| 0)); let circuit_secondary = TrivialCircuit::default(); let z0_primary = vec![::Scalar::from(2u64)]; diff --git a/examples/minroot.rs b/examples/minroot.rs index 7d0bc8018..66809af8b 100644 --- a/examples/minroot.rs +++ b/examples/minroot.rs @@ -161,7 +161,7 @@ fn main() { G2, MinRootCircuit<::Scalar>, TrivialCircuit<::Scalar>, - >::setup(&circuit_primary, &circuit_secondary, None, None); + >::setup(&circuit_primary, &circuit_secondary, &(|_| 0), &(|_| 0)); println!("PublicParams::setup, took {:?} ", start.elapsed()); println!( diff --git a/src/bellpepper/mod.rs b/src/bellpepper/mod.rs index 50159c71a..4809786d3 100644 --- a/src/bellpepper/mod.rs +++ b/src/bellpepper/mod.rs @@ -47,7 +47,7 @@ mod tests { // First create the shape let mut cs: ShapeCS = ShapeCS::new(); synthesize_alloc_bit(&mut cs); - let (shape, ck) = cs.r1cs_shape(None); + let (shape, ck) = cs.r1cs_shape(&(|_| 0)); // Now get the assignment let mut cs: SatisfyingAssignment = SatisfyingAssignment::new(); diff --git a/src/bellpepper/r1cs.rs b/src/bellpepper/r1cs.rs index d4a0603bf..2e235d787 100644 --- a/src/bellpepper/r1cs.rs +++ b/src/bellpepper/r1cs.rs @@ -25,9 +25,9 @@ pub trait NovaWitness { /// `NovaShape` provides methods for acquiring `R1CSShape` and `CommitmentKey` from implementers. pub trait NovaShape { /// Return an appropriate `R1CSShape` and `CommitmentKey` structs. - /// Optionally, a `CommitmentKeyHint` can be provided to help guide the - /// construction of the `CommitmentKey`. This parameter is documented in `r1cs::R1CS::commitment_key`. - fn r1cs_shape(&self, optfn: Option>) -> (R1CSShape, CommitmentKey); + /// A `CommitmentKeyHint` should be provided to help guide the construction of the `CommitmentKey`. + /// This parameter is documented in `r1cs::R1CS::commitment_key`. + fn r1cs_shape(&self, ck_hint: &CommitmentKeyHint) -> (R1CSShape, CommitmentKey); } impl NovaWitness for SatisfyingAssignment { @@ -55,7 +55,7 @@ macro_rules! impl_nova_shape { { fn r1cs_shape( &self, - optfn: Option>, + ck_hint: &CommitmentKeyHint, ) -> (R1CSShape, CommitmentKey) { let mut A = SparseMatrix::::empty(); let mut B = SparseMatrix::::empty(); @@ -84,7 +84,7 @@ macro_rules! impl_nova_shape { // Don't count One as an input for shape's purposes. let S = R1CSShape::new(num_constraints, num_vars, num_inputs - 1, A, B, C).unwrap(); - let ck = R1CS::::commitment_key(&S, optfn); + let ck = R1CS::::commitment_key(&S, ck_hint); (S, ck) } diff --git a/src/circuit.rs b/src/circuit.rs index dae64db3c..1ed2bab64 100644 --- a/src/circuit.rs +++ b/src/circuit.rs @@ -392,7 +392,7 @@ mod tests { NovaAugmentedCircuit::new(primary_params, None, &tc1, ro_consts1.clone()); let mut cs: TestShapeCS = TestShapeCS::new(); let _ = circuit1.synthesize(&mut cs); - let (shape1, ck1) = cs.r1cs_shape(None); + let (shape1, ck1) = cs.r1cs_shape(&(|_| 0)); assert_eq!(cs.num_constraints(), num_constraints_primary); let tc2 = TrivialCircuit::default(); @@ -401,7 +401,7 @@ mod tests { NovaAugmentedCircuit::new(secondary_params, None, &tc2, ro_consts2.clone()); let mut cs: TestShapeCS = TestShapeCS::new(); let _ = circuit2.synthesize(&mut cs); - let (shape2, ck2) = cs.r1cs_shape(None); + let (shape2, ck2) = cs.r1cs_shape(&(|_| 0)); assert_eq!(cs.num_constraints(), num_constraints_secondary); // Execute the base case for the primary diff --git a/src/gadgets/ecc.rs b/src/gadgets/ecc.rs index 975e2f7a7..a85434f82 100644 --- a/src/gadgets/ecc.rs +++ b/src/gadgets/ecc.rs @@ -1000,7 +1000,7 @@ mod tests { let mut cs: TestShapeCS = TestShapeCS::new(); let _ = synthesize_smul::(cs.namespace(|| "synthesize")); println!("Number of constraints: {}", cs.num_constraints()); - let (shape, ck) = cs.r1cs_shape(None); + let (shape, ck) = cs.r1cs_shape(&(|_| 0)); // Then the satisfying assignment let mut cs: SatisfyingAssignment = SatisfyingAssignment::new(); @@ -1056,7 +1056,7 @@ mod tests { let mut cs: TestShapeCS = TestShapeCS::new(); let _ = synthesize_add_equal::(cs.namespace(|| "synthesize add equal")); println!("Number of constraints: {}", cs.num_constraints()); - let (shape, ck) = cs.r1cs_shape(None); + let (shape, ck) = cs.r1cs_shape(&(|_| 0)); // Then the satisfying assignment let mut cs: SatisfyingAssignment = SatisfyingAssignment::new(); @@ -1116,7 +1116,7 @@ mod tests { let mut cs: TestShapeCS = TestShapeCS::new(); let _ = synthesize_add_negation::(cs.namespace(|| "synthesize add equal")); println!("Number of constraints: {}", cs.num_constraints()); - let (shape, ck) = cs.r1cs_shape(None); + let (shape, ck) = cs.r1cs_shape(&(|_| 0)); // Then the satisfying assignment let mut cs: SatisfyingAssignment = SatisfyingAssignment::new(); diff --git a/src/lib.rs b/src/lib.rs index cdad725cf..545736bb7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -99,18 +99,21 @@ where /// /// # Note /// - /// Some SNARKs, like variants of Spartan, use computation commitments that require - /// larger sizes for some parameters. These SNARKs provide a hint for these values by + /// Public parameters set up a number of bases for the homomorphic commitment scheme of Nova. + /// + /// Some final ocmpressing SNARKs, like variants of Spartan, use computation commitments that require + /// larger sizes for these parameters. These SNARKs provide a hint for these values by /// implementing `RelaxedR1CSSNARKTrait::commitment_key_floor()`, which can be passed to this function. - /// If you're not using such a SNARK, pass `None` instead. + /// + /// If you're not using such a SNARK, pass `&(|_| 0)` instead. /// /// # Arguments /// /// * `c_primary`: The primary circuit of type `C1`. /// * `c_secondary`: The secondary circuit of type `C2`. - /// * `optfn1`: An optional `CommitmentKeyHint` for `G1`, which is a function that provides a hint + /// * `optfn1`: A `CommitmentKeyHint` for `G1`, which is a function that provides a hint /// for the number of generators required in the commitment scheme for the primary circuit. - /// * `optfn2`: An optional `CommitmentKeyHint` for `G2`, similar to `optfn1`, but for the secondary circuit. + /// * `optfn2`: A `CommitmentKeyHint` for `G2`, similar to `optfn1`, but for the secondary circuit. /// /// # Example /// @@ -129,16 +132,16 @@ where /// let circuit1 = TrivialCircuit::<::Scalar>::default(); /// let circuit2 = TrivialCircuit::<::Scalar>::default(); /// // Only relevant for a SNARK using computational commitments, pass None otherwise. - /// let pp_hint1 = Some(SPrime::::commitment_key_floor()); - /// let pp_hint2 = Some(SPrime::::commitment_key_floor()); + /// let pp_hint1 = &*SPrime::::commitment_key_floor(); + /// let pp_hint2 = &*SPrime::::commitment_key_floor(); /// /// let pp = PublicParams::setup(&circuit1, &circuit2, pp_hint1, pp_hint2); /// ``` pub fn setup( c_primary: &C1, c_secondary: &C2, - optfn1: Option>, - optfn2: Option>, + optfn1: &CommitmentKeyHint, + optfn2: &CommitmentKeyHint, ) -> Self { let augmented_circuit_params_primary = NovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, true); @@ -940,8 +943,8 @@ mod tests { >::CommitmentKey: CommitmentKeyExtTrait, { // this tests public parameters with a size specifically intended for a spark-compressed SNARK - let pp_hint1 = Some(SPrime::>::commitment_key_floor()); - let pp_hint2 = Some(SPrime::>::commitment_key_floor()); + let pp_hint1 = &*SPrime::>::commitment_key_floor(); + let pp_hint2 = &*SPrime::>::commitment_key_floor(); let pp = PublicParams::::setup(circuit1, circuit2, pp_hint1, pp_hint2); let digest_str = pp @@ -1021,7 +1024,7 @@ mod tests { G2, TrivialCircuit<::Scalar>, TrivialCircuit<::Scalar>, - >::setup(&test_circuit1, &test_circuit2, None, None); + >::setup(&test_circuit1, &test_circuit2, &(|_| 0), &(|_| 0)); let num_steps = 1; @@ -1073,7 +1076,7 @@ mod tests { G2, TrivialCircuit<::Scalar>, CubicCircuit<::Scalar>, - >::setup(&circuit_primary, &circuit_secondary, None, None); + >::setup(&circuit_primary, &circuit_secondary, &(|_| 0), &(|_| 0)); let num_steps = 3; @@ -1153,7 +1156,7 @@ mod tests { G2, TrivialCircuit<::Scalar>, CubicCircuit<::Scalar>, - >::setup(&circuit_primary, &circuit_secondary, None, None); + >::setup(&circuit_primary, &circuit_secondary, &(|_| 0), &(|_| 0)); let num_steps = 3; @@ -1245,8 +1248,8 @@ mod tests { >::setup( &circuit_primary, &circuit_secondary, - Some(SPrime::::commitment_key_floor()), - Some(SPrime::::commitment_key_floor()), + &*SPrime::::commitment_key_floor(), + &*SPrime::::commitment_key_floor(), ); let num_steps = 3; @@ -1411,7 +1414,7 @@ mod tests { G2, FifthRootCheckingCircuit<::Scalar>, TrivialCircuit<::Scalar>, - >::setup(&circuit_primary, &circuit_secondary, None, None); + >::setup(&circuit_primary, &circuit_secondary, &(|_| 0), &(|_| 0)); let num_steps = 3; @@ -1486,7 +1489,7 @@ mod tests { G2, TrivialCircuit<::Scalar>, CubicCircuit<::Scalar>, - >::setup(&test_circuit1, &test_circuit2, None, None); + >::setup(&test_circuit1, &test_circuit2, &(|_| 0), &(|_| 0)); let num_steps = 1; diff --git a/src/nifs.rs b/src/nifs.rs index f97cdeb49..f05cb315a 100644 --- a/src/nifs.rs +++ b/src/nifs.rs @@ -166,7 +166,7 @@ mod tests { // First create the shape let mut cs: TestShapeCS = TestShapeCS::new(); let _ = synthesize_tiny_r1cs_bellpepper(&mut cs, None); - let (shape, ck) = cs.r1cs_shape(None); + let (shape, ck) = cs.r1cs_shape(&(|_| 0)); let ro_consts = <::RO as ROTrait<::Base, ::Scalar>>::Constants::default(); @@ -327,7 +327,7 @@ mod tests { }; // generate generators and ro constants - let ck = R1CS::::commitment_key(&S, None); + let ck = R1CS::::commitment_key(&S, &(|_| 0)); let ro_consts = <::RO as ROTrait<::Base, ::Scalar>>::Constants::default(); diff --git a/src/r1cs/mod.rs b/src/r1cs/mod.rs index d5b3ffac5..2297ee149 100644 --- a/src/r1cs/mod.rs +++ b/src/r1cs/mod.rs @@ -78,7 +78,7 @@ pub struct RelaxedR1CSInstance { pub(crate) u: G::Scalar, } -pub type CommitmentKeyHint = Box) -> usize>; +pub type CommitmentKeyHint = dyn Fn(&R1CSShape) -> usize; impl R1CS { /// Generates public parameters for a Rank-1 Constraint System (R1CS). @@ -89,17 +89,16 @@ impl R1CS { /// # Arguments /// /// * `S`: The shape of the R1CS matrices. - /// * `commitment_key_hint`: An optional function that provides a floor for the number of - /// generators. A good function to provide is the commitment_key_floor field in the trait `RelaxedR1CSSNARKTrait`. - /// If no floot function is provided, the default number of generators will be max(S.num_cons, S.num_vars). + /// * `commitment_key_hint`: A function that provides a floor for the number of generators. A good function + /// to provide is the commitment_key_floor field defined in the trait `RelaxedR1CSSNARKTrait`. /// pub fn commitment_key( S: &R1CSShape, - commitment_key_floor: Option>, + commitment_key_floor: &CommitmentKeyHint, ) -> CommitmentKey { let num_cons = S.num_cons; let num_vars = S.num_vars; - let generators_hint = commitment_key_floor.map(|f| f(S)).unwrap_or(0); + let generators_hint = commitment_key_floor(S); G::CE::setup(b"ck", max(max(num_cons, num_vars), generators_hint)) } } diff --git a/src/spartan/direct.rs b/src/spartan/direct.rs index ed3314ea5..cc9fa38b9 100644 --- a/src/spartan/direct.rs +++ b/src/spartan/direct.rs @@ -109,7 +109,7 @@ impl, C: StepCircuit> DirectSNA let mut cs: ShapeCS = ShapeCS::new(); let _ = circuit.synthesize(&mut cs); - let (shape, ck) = cs.r1cs_shape(Some(S::commitment_key_floor())); + let (shape, ck) = cs.r1cs_shape(&*S::commitment_key_floor()); let (pk, vk) = S::setup(&ck, &shape)?;