From 96a14a9d964cf752fe1ec3cb93f7f255c520c9a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Garillot?= Date: Fri, 3 Nov 2023 12:31:36 -0400 Subject: [PATCH 1/3] 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. - Ported use of commitment key hint to Supernova, closing #53. - This PR puts Arecibo in line with https://github.com/microsoft/Nova/pull/203 --- benches/compressed-snark.rs | 8 ++--- benches/compute-digest.rs | 4 +-- benches/recursive-snark-supernova.rs | 4 +-- benches/recursive-snark.rs | 2 +- benches/sha256.rs | 2 +- examples/minroot.rs | 2 +- examples/minroot_serde.rs | 4 +-- src/bellpepper/mod.rs | 2 +- src/bellpepper/r1cs.rs | 7 ++--- src/circuit.rs | 4 +-- src/gadgets/ecc.rs | 6 ++-- src/lib.rs | 45 +++++++++++++++------------- src/nifs.rs | 4 +-- src/r1cs/mod.rs | 13 ++++---- src/spartan/direct.rs | 2 +- src/supernova/mod.rs | 22 ++++++++++---- src/supernova/test.rs | 10 +++---- 17 files changed, 75 insertions(+), 66 deletions(-) diff --git a/benches/compressed-snark.rs b/benches/compressed-snark.rs index 4e08aee99..9c4341a71 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::::new( &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::::new( &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 41ba9be04..adceb8550 100644 --- a/benches/compute-digest.rs +++ b/benches/compute-digest.rs @@ -30,8 +30,8 @@ fn bench_compute_digest(c: &mut Criterion) { PublicParams::::new( 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-supernova.rs b/benches/recursive-snark-supernova.rs index e7bcf51c6..c05824240 100644 --- a/benches/recursive-snark-supernova.rs +++ b/benches/recursive-snark-supernova.rs @@ -104,7 +104,7 @@ fn bench_one_augmented_circuit_recursive_snark(c: &mut Criterion) { let bench: NonUniformBench::Scalar>> = NonUniformBench::new(1, num_cons); - let pp = PublicParams::new(&bench); + let pp = PublicParams::new(&bench, &(|_| 0), &(|_| 0)); // Bench time to produce a recursive SNARK; // we execute a certain number of warm-up steps since executing @@ -206,7 +206,7 @@ fn bench_two_augmented_circuit_recursive_snark(c: &mut Criterion) { let bench: NonUniformBench::Scalar>> = NonUniformBench::new(2, num_cons); - let pp = PublicParams::new(&bench); + let pp = PublicParams::new(&bench, &(|_| 0), &(|_| 0)); // Bench time to produce a recursive SNARK; // we execute a certain number of warm-up steps since executing diff --git a/benches/recursive-snark.rs b/benches/recursive-snark.rs index bfcc2d624..7520ddcf9 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::::new(&c_primary, &c_secondary, None, None); + let pp = PublicParams::::new(&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 e802e83c8..c2fb45755 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::::new(&circuit_primary, &ttc, None, None); + let pp = PublicParams::::new(&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 7cc1e0c6e..0c0900ff9 100644 --- a/examples/minroot.rs +++ b/examples/minroot.rs @@ -169,7 +169,7 @@ fn main() { G2, MinRootCircuit<::Scalar>, TrivialCircuit<::Scalar>, - >::new(&circuit_primary, &circuit_secondary, None, None); + >::new(&circuit_primary, &circuit_secondary, &(|_| 0), &(|_| 0)); println!("PublicParams::setup, took {:?} ", start.elapsed()); println!( diff --git a/examples/minroot_serde.rs b/examples/minroot_serde.rs index 5bd805150..83a5c030c 100644 --- a/examples/minroot_serde.rs +++ b/examples/minroot_serde.rs @@ -167,7 +167,7 @@ fn main() { G2, MinRootCircuit<::Scalar>, TrivialCircuit<::Scalar>, - >::new(&circuit_primary, &circuit_secondary, None, None); + >::new(&circuit_primary, &circuit_secondary, &(|_| 0), &(|_| 0)); println!("PublicParams::setup, took {:?} ", start.elapsed()); encode(&pp, &mut file).unwrap() }; @@ -193,7 +193,7 @@ fn main() { G2, MinRootCircuit<::Scalar>, TrivialCircuit<::Scalar>, - >::new(&circuit_primary, &circuit_secondary, None, None); + >::new(&circuit_primary, &circuit_secondary, &(|_| 0), &(|_| 0)); assert!(result.clone() == pp, "not equal!"); assert!(remaining.is_empty()); } else { diff --git a/src/bellpepper/mod.rs b/src/bellpepper/mod.rs index ff1a51c89..ad9751092 100644 --- a/src/bellpepper/mod.rs +++ b/src/bellpepper/mod.rs @@ -50,7 +50,7 @@ mod tests { // First create the shape let mut cs: ShapeCS = ShapeCS::new(); let _ = synthesize_alloc_bit(&mut cs); - let (shape, ck) = cs.r1cs_shape_and_key(None); + let (shape, ck) = cs.r1cs_shape_and_key(&(|_| 0)); // Now get the assignment let mut cs: SatisfyingAssignment = SatisfyingAssignment::new(); diff --git a/src/bellpepper/r1cs.rs b/src/bellpepper/r1cs.rs index 3fa69c1cd..eb80bb54f 100644 --- a/src/bellpepper/r1cs.rs +++ b/src/bellpepper/r1cs.rs @@ -28,12 +28,9 @@ pub trait NovaShape { /// 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_and_key( - &self, - optfn: Option>, - ) -> (R1CSShape, CommitmentKey) { + fn r1cs_shape_and_key(&self, ck_hint: &CommitmentKeyHint) -> (R1CSShape, CommitmentKey) { let S = self.r1cs_shape(); - let ck = commitment_key(&S, optfn); + let ck = commitment_key(&S, ck_hint); (S, ck) } diff --git a/src/circuit.rs b/src/circuit.rs index 7307e1359..e95470c40 100644 --- a/src/circuit.rs +++ b/src/circuit.rs @@ -393,7 +393,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_and_key(None); + let (shape1, ck1) = cs.r1cs_shape_and_key(&(|_| 0)); assert_eq!(cs.num_constraints(), num_constraints_primary); let tc2 = TrivialCircuit::default(); @@ -402,7 +402,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_and_key(None); + let (shape2, ck2) = cs.r1cs_shape_and_key(&(|_| 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 3edbfea75..d75be5240 100644 --- a/src/gadgets/ecc.rs +++ b/src/gadgets/ecc.rs @@ -1001,7 +1001,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_and_key(None); + let (shape, ck) = cs.r1cs_shape_and_key(&(|_| 0)); // Then the satisfying assignment let mut cs: SatisfyingAssignment = SatisfyingAssignment::new(); @@ -1057,7 +1057,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_and_key(None); + let (shape, ck) = cs.r1cs_shape_and_key(&(|_| 0)); // Then the satisfying assignment let mut cs: SatisfyingAssignment = SatisfyingAssignment::new(); @@ -1117,7 +1117,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_and_key(None); + let (shape, ck) = cs.r1cs_shape_and_key(&(|_| 0)); // Then the satisfying assignment let mut cs: SatisfyingAssignment = SatisfyingAssignment::new(); diff --git a/src/lib.rs b/src/lib.rs index de65caa33..53990bae1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -140,18 +140,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 compressing 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 + /// * `ck_hint1`: 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. + /// * `ck_hint2`: A `CommitmentKeyHint` for `G2`, similar to `ck_hint1`, but for the secondary circuit. /// /// # Example /// @@ -169,17 +172,17 @@ 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()); + /// // Only relevant for a SNARK using computational commitments, pass &(|_| 0) otherwise. + /// let pp_hint1 = &*SPrime::::commitment_key_floor(); + /// let pp_hint2 = &*SPrime::::commitment_key_floor(); /// /// let pp = PublicParams::new(&circuit1, &circuit2, pp_hint1, pp_hint2); /// ``` pub fn new( c_primary: &C1, c_secondary: &C2, - optfn1: Option>, - optfn2: Option>, + ck_hint1: &CommitmentKeyHint, + ck_hint2: &CommitmentKeyHint, ) -> Self { let augmented_circuit_params_primary = NovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, true); @@ -205,7 +208,7 @@ where ); let mut cs: ShapeCS = ShapeCS::new(); let _ = circuit_primary.synthesize(&mut cs); - let (r1cs_shape_primary, ck_primary) = cs.r1cs_shape_and_key(optfn1); + let (r1cs_shape_primary, ck_primary) = cs.r1cs_shape_and_key(ck_hint1); let circuit_shape_primary = CircuitShape::new(r1cs_shape_primary, F_arity_primary); // Initialize ck for the secondary @@ -217,7 +220,7 @@ where ); let mut cs: ShapeCS = ShapeCS::new(); let _ = circuit_secondary.synthesize(&mut cs); - let (r1cs_shape_secondary, ck_secondary) = cs.r1cs_shape_and_key(optfn2); + let (r1cs_shape_secondary, ck_secondary) = cs.r1cs_shape_and_key(ck_hint2); let circuit_shape_secondary = CircuitShape::new(r1cs_shape_secondary, F_arity_secondary); PublicParams { @@ -1029,8 +1032,8 @@ mod tests { ::Repr: Abomonation, { // 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::::new(circuit1, circuit2, pp_hint1, pp_hint2); let digest_str = pp @@ -1111,7 +1114,7 @@ mod tests { G2, TrivialCircuit<::Scalar>, TrivialCircuit<::Scalar>, - >::new(&test_circuit1, &test_circuit2, None, None); + >::new(&test_circuit1, &test_circuit2, &(|_| 0), &(|_| 0)); let num_steps = 1; // produce a recursive SNARK @@ -1162,7 +1165,7 @@ mod tests { G2, TrivialCircuit<::Scalar>, CubicCircuit<::Scalar>, - >::new(&circuit_primary, &circuit_secondary, None, None); + >::new(&circuit_primary, &circuit_secondary, &(|_| 0), &(|_| 0)); let num_steps = 3; @@ -1245,7 +1248,7 @@ mod tests { G2, TrivialCircuit<::Scalar>, CubicCircuit<::Scalar>, - >::new(&circuit_primary, &circuit_secondary, None, None); + >::new(&circuit_primary, &circuit_secondary, &(|_| 0), &(|_| 0)); let num_steps = 3; @@ -1340,8 +1343,8 @@ mod tests { >::new( &circuit_primary, &circuit_secondary, - Some(SPrime::<_, E1>::commitment_key_floor()), - Some(SPrime::<_, E2>::commitment_key_floor()), + &*SPrime::<_, E1>::commitment_key_floor(), + &*SPrime::<_, E2>::commitment_key_floor(), ); let num_steps = 3; @@ -1509,7 +1512,7 @@ mod tests { G2, FifthRootCheckingCircuit<::Scalar>, TrivialCircuit<::Scalar>, - >::new(&circuit_primary, &circuit_secondary, None, None); + >::new(&circuit_primary, &circuit_secondary, &(|_| 0), &(|_| 0)); let num_steps = 3; @@ -1584,7 +1587,7 @@ mod tests { G2, TrivialCircuit<::Scalar>, CubicCircuit<::Scalar>, - >::new(&test_circuit1, &test_circuit2, None, None); + >::new(&test_circuit1, &test_circuit2, &(|_| 0), &(|_| 0)); let num_steps = 1; diff --git a/src/nifs.rs b/src/nifs.rs index d2b8872a0..9dfbfbfac 100644 --- a/src/nifs.rs +++ b/src/nifs.rs @@ -171,7 +171,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_and_key(None); + let (shape, ck) = cs.r1cs_shape_and_key(&(|_| 0)); let ro_consts = <::RO as ROTrait<::Base, ::Scalar>>::Constants::default(); @@ -332,7 +332,7 @@ mod tests { }; // generate generators and ro constants - let ck = commitment_key(&S, None); + let ck = 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 83b260dd9..7df41175c 100644 --- a/src/r1cs/mod.rs +++ b/src/r1cs/mod.rs @@ -76,7 +76,7 @@ pub struct RelaxedR1CSInstance { } /// A type for functions that hints commitment key sizing by returning the floor of the number of required generators. -pub type CommitmentKeyHint = Box) -> usize>; +pub type CommitmentKeyHint = dyn Fn(&R1CSShape) -> usize; /// Generates public parameters for a Rank-1 Constraint System (R1CS). /// @@ -86,13 +86,12 @@ pub type CommitmentKeyHint = Box) -> usize>; /// # 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 floor 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 in the trait `RelaxedR1CSSNARKTrait`. /// pub fn commitment_key( S: &R1CSShape, - commitment_key_floor: Option>, + commitment_key_floor: &CommitmentKeyHint, ) -> CommitmentKey { let size = commitment_key_size(S, commitment_key_floor); G::CE::setup(b"ck", size) @@ -101,11 +100,11 @@ pub fn commitment_key( /// Computes the number of generators required for the commitment key corresponding to shape `S`. pub fn commitment_key_size( S: &R1CSShape, - commitment_key_floor: Option>, + commitment_key_floor: &CommitmentKeyHint, ) -> usize { let num_cons = S.num_cons; let num_vars = S.num_vars; - let generators_hint = commitment_key_floor.map_or(0, |f| f(S)); + let generators_hint = commitment_key_floor(S); max(max(num_cons, num_vars), generators_hint) } diff --git a/src/spartan/direct.rs b/src/spartan/direct.rs index c736d6e3c..001717e9a 100644 --- a/src/spartan/direct.rs +++ b/src/spartan/direct.rs @@ -97,7 +97,7 @@ impl, C: StepCircuit> DirectSNA let mut cs: ShapeCS = ShapeCS::new(); let _ = circuit.synthesize(&mut cs); - let (shape, ck) = cs.r1cs_shape_and_key(Some(S::commitment_key_floor())); + let (shape, ck) = cs.r1cs_shape_and_key(&*S::commitment_key_floor()); let (pk, vk) = S::setup(&ck, &shape)?; diff --git a/src/supernova/mod.rs b/src/supernova/mod.rs index 56413b1a2..8b2d2a969 100644 --- a/src/supernova/mod.rs +++ b/src/supernova/mod.rs @@ -8,7 +8,10 @@ use crate::{ constants::{BN_LIMB_WIDTH, BN_N_LIMBS, NUM_HASH_BITS}, digest::{DigestComputer, SimpleDigestible}, errors::NovaError, - r1cs::{commitment_key_size, R1CSInstance, R1CSWitness, RelaxedR1CSInstance, RelaxedR1CSWitness}, + r1cs::{ + commitment_key_size, CommitmentKeyHint, R1CSInstance, R1CSWitness, RelaxedR1CSInstance, + RelaxedR1CSWitness, + }, scalar_as_base, traits::{ circuit_supernova::StepCircuit, @@ -168,7 +171,11 @@ where C2: StepCircuit, { /// Construct a new [PublicParams] - pub fn new>(non_uniform_circuit: &NC) -> Self { + pub fn new>( + non_uniform_circuit: &NC, + ck_hint1: &CommitmentKeyHint, + ck_hint2: &CommitmentKeyHint, + ) -> Self { let num_circuits = non_uniform_circuit.num_circuits(); let augmented_circuit_params_primary = @@ -198,7 +205,7 @@ where }) .collect::>(); - let ck_primary = Self::compute_primary_ck(&circuit_shapes); + let ck_primary = Self::compute_primary_ck(&circuit_shapes, ck_hint1); let augmented_circuit_params_secondary = SuperNovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, false); @@ -216,7 +223,7 @@ where ); let mut cs: ShapeCS = ShapeCS::new(); let _ = circuit_secondary.synthesize(&mut cs); - let (r1cs_shape_secondary, ck_secondary) = cs.r1cs_shape_and_key(None); + let (r1cs_shape_secondary, ck_secondary) = cs.r1cs_shape_and_key(ck_hint2); let circuit_shape_secondary = CircuitShape::new(r1cs_shape_secondary, F_arity_secondary); let pp = PublicParams { @@ -323,10 +330,13 @@ where /// Compute primary and secondary commitment keys sized to handle the largest of the circuits in the provided /// `CircuitShape`. - fn compute_primary_ck(circuit_params: &[CircuitShape]) -> CommitmentKey { + fn compute_primary_ck( + circuit_params: &[CircuitShape], + ck_hint1: &CommitmentKeyHint, + ) -> CommitmentKey { let size_primary = circuit_params .iter() - .map(|circuit| commitment_key_size(&circuit.r1cs_shape, None)) + .map(|circuit| commitment_key_size(&circuit.r1cs_shape, ck_hint1)) .max() .unwrap(); diff --git a/src/supernova/test.rs b/src/supernova/test.rs index bdad3a0d1..0af701862 100644 --- a/src/supernova/test.rs +++ b/src/supernova/test.rs @@ -448,7 +448,7 @@ where let test_rom = TestROM::>::new(rom); let num_steps = test_rom.num_steps(); - let pp = PublicParams::new(&test_rom); + let pp = PublicParams::new(&test_rom, &(|_| 0), &(|_| 0)); let initial_program_counter = test_rom.initial_program_counter(); @@ -571,7 +571,7 @@ fn test_recursive_circuit_with( if let Err(e) = circuit1.synthesize(&mut cs) { panic!("{}", e) } - let (shape1, ck1) = cs.r1cs_shape_and_key(None); + let (shape1, ck1) = cs.r1cs_shape_and_key(&(|_| 0)); assert_eq!(cs.num_constraints(), num_constraints_primary); // Initialize the shape and ck for the secondary @@ -589,7 +589,7 @@ fn test_recursive_circuit_with( if let Err(e) = circuit2.synthesize(&mut cs) { panic!("{}", e) } - let (shape2, ck2) = cs.r1cs_shape_and_key(None); + let (shape2, ck2) = cs.r1cs_shape_and_key(&(|_| 0)); assert_eq!(cs.num_constraints(), num_constraints_secondary); // Execute the base case for the primary @@ -673,7 +673,7 @@ where // // 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 = PublicParams::::new(non_uniform_circuit); + let pp = PublicParams::::new(non_uniform_circuit, &(|_| 0), &(|_| 0)); let digest_str = pp .digest() @@ -944,7 +944,7 @@ where G2, RootCheckingCircuit<::Scalar>, TrivialSecondaryCircuit<::Scalar>, - >::new(&roots[0]); + >::new(&roots[0], &(|_| 0), &(|_| 0)); // produce a recursive SNARK let circuit_primary = &roots[0]; From 4c70d31ccff925a8a1d2f919b08b1e13d0f9d920 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Garillot?= Date: Fri, 3 Nov 2023 12:31:40 -0400 Subject: [PATCH 2/3] doc: document Supernova Public Parameters - Enhanced the `PublicParams` struct within `./src/supernova/mod.rs` with detailed comments --- src/supernova/mod.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/supernova/mod.rs b/src/supernova/mod.rs index 8b2d2a969..2b3f13b32 100644 --- a/src/supernova/mod.rs +++ b/src/supernova/mod.rs @@ -171,6 +171,23 @@ where C2: StepCircuit, { /// Construct a new [PublicParams] + /// + /// # Note + /// + /// Public parameters set up a number of bases for the homomorphic commitment scheme of Nova. + /// + /// Some final compressing 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 `&(|_| 0)` instead. + /// + /// # Arguments + /// + /// * `non_uniform_circuit`: The non-uniform circuit of type `NC`. + /// * `ck_hint1`: 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. + /// * `ck_hint2`: A `CommitmentKeyHint` for `G2`, similar to `ck_hint1`, but for the secondary circuit. pub fn new>( non_uniform_circuit: &NC, ck_hint1: &CommitmentKeyHint, From 92c50236ed529f379b872bbd840848c57fbb64a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Garillot?= Date: Fri, 3 Nov 2023 12:31:43 -0400 Subject: [PATCH 3/3] feat: Refactor to use `default_commitment_key_hint` across codebase - Introduced a new function `default_commitment_key_hint` in `nova_snark` package to provide a clearer default sizing hint for the commitment key, - Replaced hard-coded zero values throughout the codebase with calls to `default_commitment_key_hint` function, --- benches/compute-digest.rs | 5 ++-- benches/recursive-snark-supernova.rs | 13 ++++++++-- benches/recursive-snark.rs | 8 +++++- benches/sha256.rs | 8 +++++- examples/minroot.rs | 8 +++++- examples/minroot_serde.rs | 15 +++++++++-- src/bellpepper/mod.rs | 4 +-- src/bellpepper/r1cs.rs | 5 ++-- src/circuit.rs | 5 ++-- src/gadgets/ecc.rs | 17 ++++++++----- src/lib.rs | 38 +++++++++++++++++++++++----- src/nifs.rs | 5 ++-- src/supernova/test.rs | 23 +++++++++++++---- src/traits/snark.rs | 11 +++++++- 14 files changed, 128 insertions(+), 37 deletions(-) diff --git a/benches/compute-digest.rs b/benches/compute-digest.rs index adceb8550..f5403a7b2 100644 --- a/benches/compute-digest.rs +++ b/benches/compute-digest.rs @@ -6,6 +6,7 @@ use ff::PrimeField; use nova_snark::{ traits::{ circuit::{StepCircuit, TrivialCircuit}, + snark::default_commitment_key_hint, Group, }, PublicParams, @@ -30,8 +31,8 @@ fn bench_compute_digest(c: &mut Criterion) { PublicParams::::new( black_box(&C1::new(10)), black_box(&C2::default()), - black_box(&(|_| 0)), - black_box(&(|_| 0)), + black_box(&*default_commitment_key_hint()), + black_box(&*default_commitment_key_hint()), ) }) }); diff --git a/benches/recursive-snark-supernova.rs b/benches/recursive-snark-supernova.rs index c05824240..0bedc9f35 100644 --- a/benches/recursive-snark-supernova.rs +++ b/benches/recursive-snark-supernova.rs @@ -9,6 +9,7 @@ use nova_snark::{ supernova::{PublicParams, RecursiveSNARK}, traits::{ circuit_supernova::{StepCircuit, TrivialTestCircuit}, + snark::default_commitment_key_hint, Group, }, }; @@ -104,7 +105,11 @@ fn bench_one_augmented_circuit_recursive_snark(c: &mut Criterion) { let bench: NonUniformBench::Scalar>> = NonUniformBench::new(1, num_cons); - let pp = PublicParams::new(&bench, &(|_| 0), &(|_| 0)); + let pp = PublicParams::new( + &bench, + &*default_commitment_key_hint(), + &*default_commitment_key_hint(), + ); // Bench time to produce a recursive SNARK; // we execute a certain number of warm-up steps since executing @@ -206,7 +211,11 @@ fn bench_two_augmented_circuit_recursive_snark(c: &mut Criterion) { let bench: NonUniformBench::Scalar>> = NonUniformBench::new(2, num_cons); - let pp = PublicParams::new(&bench, &(|_| 0), &(|_| 0)); + let pp = PublicParams::new( + &bench, + &*default_commitment_key_hint(), + &*default_commitment_key_hint(), + ); // Bench time to produce a recursive SNARK; // we execute a certain number of warm-up steps since executing diff --git a/benches/recursive-snark.rs b/benches/recursive-snark.rs index 7520ddcf9..49c5879e5 100644 --- a/benches/recursive-snark.rs +++ b/benches/recursive-snark.rs @@ -7,6 +7,7 @@ use ff::PrimeField; use nova_snark::{ traits::{ circuit::{StepCircuit, TrivialCircuit}, + snark::default_commitment_key_hint, Group, }, PublicParams, RecursiveSNARK, @@ -56,7 +57,12 @@ fn bench_recursive_snark(c: &mut Criterion) { let c_secondary = TrivialCircuit::default(); // Produce public parameters - let pp = PublicParams::::new(&c_primary, &c_secondary, &(|_| 0), &(|_| 0)); + let pp = PublicParams::::new( + &c_primary, + &c_secondary, + &*default_commitment_key_hint(), + &*default_commitment_key_hint(), + ); // 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 c2fb45755..c0ecb7519 100644 --- a/benches/sha256.rs +++ b/benches/sha256.rs @@ -17,6 +17,7 @@ use ff::{PrimeField, PrimeFieldBits}; use nova_snark::{ traits::{ circuit::{StepCircuit, TrivialCircuit}, + snark::default_commitment_key_hint, Group, }, PublicParams, RecursiveSNARK, @@ -155,7 +156,12 @@ fn bench_recursive_snark(c: &mut Criterion) { // Produce public parameters let ttc = TrivialCircuit::default(); - let pp = PublicParams::::new(&circuit_primary, &ttc, &(|_| 0), &(|_| 0)); + let pp = PublicParams::::new( + &circuit_primary, + &ttc, + &*default_commitment_key_hint(), + &*default_commitment_key_hint(), + ); let circuit_secondary = TrivialCircuit::default(); let z0_primary = vec![::Scalar::from(2u64)]; diff --git a/examples/minroot.rs b/examples/minroot.rs index 0c0900ff9..c9b7c7f29 100644 --- a/examples/minroot.rs +++ b/examples/minroot.rs @@ -9,6 +9,7 @@ use flate2::{write::ZlibEncoder, Compression}; use nova_snark::{ traits::{ circuit::{StepCircuit, TrivialCircuit}, + snark::default_commitment_key_hint, Group, }, CompressedSNARK, PublicParams, RecursiveSNARK, @@ -169,7 +170,12 @@ fn main() { G2, MinRootCircuit<::Scalar>, TrivialCircuit<::Scalar>, - >::new(&circuit_primary, &circuit_secondary, &(|_| 0), &(|_| 0)); + >::new( + &circuit_primary, + &circuit_secondary, + &*default_commitment_key_hint(), + &*default_commitment_key_hint(), + ); println!("PublicParams::setup, took {:?} ", start.elapsed()); println!( diff --git a/examples/minroot_serde.rs b/examples/minroot_serde.rs index 83a5c030c..76aefbb3f 100644 --- a/examples/minroot_serde.rs +++ b/examples/minroot_serde.rs @@ -12,6 +12,7 @@ use ff::PrimeField; use nova_snark::{ traits::{ circuit::{StepCircuit, TrivialCircuit}, + snark::default_commitment_key_hint, Group, }, PublicParams, @@ -167,7 +168,12 @@ fn main() { G2, MinRootCircuit<::Scalar>, TrivialCircuit<::Scalar>, - >::new(&circuit_primary, &circuit_secondary, &(|_| 0), &(|_| 0)); + >::new( + &circuit_primary, + &circuit_secondary, + &*default_commitment_key_hint(), + &*default_commitment_key_hint(), + ); println!("PublicParams::setup, took {:?} ", start.elapsed()); encode(&pp, &mut file).unwrap() }; @@ -193,7 +199,12 @@ fn main() { G2, MinRootCircuit<::Scalar>, TrivialCircuit<::Scalar>, - >::new(&circuit_primary, &circuit_secondary, &(|_| 0), &(|_| 0)); + >::new( + &circuit_primary, + &circuit_secondary, + &*default_commitment_key_hint(), + &*default_commitment_key_hint(), + ); assert!(result.clone() == pp, "not equal!"); assert!(remaining.is_empty()); } else { diff --git a/src/bellpepper/mod.rs b/src/bellpepper/mod.rs index ad9751092..405ae78e7 100644 --- a/src/bellpepper/mod.rs +++ b/src/bellpepper/mod.rs @@ -15,7 +15,7 @@ mod tests { shape_cs::ShapeCS, solver::SatisfyingAssignment, }, - traits::Group, + traits::{snark::default_commitment_key_hint, Group}, }; use bellpepper_core::{num::AllocatedNum, ConstraintSystem, SynthesisError}; use ff::PrimeField; @@ -50,7 +50,7 @@ mod tests { // First create the shape let mut cs: ShapeCS = ShapeCS::new(); let _ = synthesize_alloc_bit(&mut cs); - let (shape, ck) = cs.r1cs_shape_and_key(&(|_| 0)); + let (shape, ck) = cs.r1cs_shape_and_key(&*default_commitment_key_hint()); // Now get the assignment let mut cs: SatisfyingAssignment = SatisfyingAssignment::new(); diff --git a/src/bellpepper/r1cs.rs b/src/bellpepper/r1cs.rs index eb80bb54f..594bc93cf 100644 --- a/src/bellpepper/r1cs.rs +++ b/src/bellpepper/r1cs.rs @@ -25,9 +25,8 @@ 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`. + /// 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_and_key(&self, ck_hint: &CommitmentKeyHint) -> (R1CSShape, CommitmentKey) { let S = self.r1cs_shape(); let ck = commitment_key(&S, ck_hint); diff --git a/src/circuit.rs b/src/circuit.rs index e95470c40..13c9a375a 100644 --- a/src/circuit.rs +++ b/src/circuit.rs @@ -368,6 +368,7 @@ mod tests { use crate::constants::{BN_LIMB_WIDTH, BN_N_LIMBS}; use crate::provider; + use crate::traits::snark::default_commitment_key_hint; use crate::{ bellpepper::r1cs::{NovaShape, NovaWitness}, gadgets::utils::scalar_as_base, @@ -393,7 +394,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_and_key(&(|_| 0)); + let (shape1, ck1) = cs.r1cs_shape_and_key(&*default_commitment_key_hint()); assert_eq!(cs.num_constraints(), num_constraints_primary); let tc2 = TrivialCircuit::default(); @@ -402,7 +403,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_and_key(&(|_| 0)); + let (shape2, ck2) = cs.r1cs_shape_and_key(&*default_commitment_key_hint()); 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 d75be5240..c764b7bf5 100644 --- a/src/gadgets/ecc.rs +++ b/src/gadgets/ecc.rs @@ -748,14 +748,17 @@ where #[cfg(test)] mod tests { use super::*; - use crate::bellpepper::{ - r1cs::{NovaShape, NovaWitness}, - {solver::SatisfyingAssignment, test_shape_cs::TestShapeCS}, - }; use crate::provider::{ bn256_grumpkin::{bn256, grumpkin}, secp_secq::{secp256k1, secq256k1}, }; + use crate::{ + bellpepper::{ + r1cs::{NovaShape, NovaWitness}, + {solver::SatisfyingAssignment, test_shape_cs::TestShapeCS}, + }, + traits::snark::default_commitment_key_hint, + }; use ff::{Field, PrimeFieldBits}; use pasta_curves::{arithmetic::CurveAffine, group::Curve, pallas, vesta}; use rand::rngs::OsRng; @@ -1001,7 +1004,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_and_key(&(|_| 0)); + let (shape, ck) = cs.r1cs_shape_and_key(&*default_commitment_key_hint()); // Then the satisfying assignment let mut cs: SatisfyingAssignment = SatisfyingAssignment::new(); @@ -1057,7 +1060,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_and_key(&(|_| 0)); + let (shape, ck) = cs.r1cs_shape_and_key(&*default_commitment_key_hint()); // Then the satisfying assignment let mut cs: SatisfyingAssignment = SatisfyingAssignment::new(); @@ -1117,7 +1120,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_and_key(&(|_| 0)); + let (shape, ck) = cs.r1cs_shape_and_key(&*default_commitment_key_hint()); // Then the satisfying assignment let mut cs: SatisfyingAssignment = SatisfyingAssignment::new(); diff --git a/src/lib.rs b/src/lib.rs index 53990bae1..50124f8ea 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -146,7 +146,7 @@ where /// 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 `&(|_| 0)` instead. + /// If you're not using such a SNARK, pass `nova_snark::traits::snark::default_commitment_key_hint()` instead. /// /// # Arguments /// @@ -954,6 +954,7 @@ mod tests { use crate::provider::bn256_grumpkin::{bn256, grumpkin}; use crate::provider::secp_secq::{secp256k1, secq256k1}; use crate::traits::evaluation::EvaluationEngineTrait; + use crate::traits::snark::default_commitment_key_hint; use core::fmt::Write; use super::*; @@ -1114,7 +1115,12 @@ mod tests { G2, TrivialCircuit<::Scalar>, TrivialCircuit<::Scalar>, - >::new(&test_circuit1, &test_circuit2, &(|_| 0), &(|_| 0)); + >::new( + &test_circuit1, + &test_circuit2, + &*default_commitment_key_hint(), + &*default_commitment_key_hint(), + ); let num_steps = 1; // produce a recursive SNARK @@ -1165,7 +1171,12 @@ mod tests { G2, TrivialCircuit<::Scalar>, CubicCircuit<::Scalar>, - >::new(&circuit_primary, &circuit_secondary, &(|_| 0), &(|_| 0)); + >::new( + &circuit_primary, + &circuit_secondary, + &*default_commitment_key_hint(), + &*default_commitment_key_hint(), + ); let num_steps = 3; @@ -1248,7 +1259,12 @@ mod tests { G2, TrivialCircuit<::Scalar>, CubicCircuit<::Scalar>, - >::new(&circuit_primary, &circuit_secondary, &(|_| 0), &(|_| 0)); + >::new( + &circuit_primary, + &circuit_secondary, + &*default_commitment_key_hint(), + &*default_commitment_key_hint(), + ); let num_steps = 3; @@ -1512,7 +1528,12 @@ mod tests { G2, FifthRootCheckingCircuit<::Scalar>, TrivialCircuit<::Scalar>, - >::new(&circuit_primary, &circuit_secondary, &(|_| 0), &(|_| 0)); + >::new( + &circuit_primary, + &circuit_secondary, + &*default_commitment_key_hint(), + &*default_commitment_key_hint(), + ); let num_steps = 3; @@ -1587,7 +1608,12 @@ mod tests { G2, TrivialCircuit<::Scalar>, CubicCircuit<::Scalar>, - >::new(&test_circuit1, &test_circuit2, &(|_| 0), &(|_| 0)); + >::new( + &test_circuit1, + &test_circuit2, + &*default_commitment_key_hint(), + &*default_commitment_key_hint(), + ); let num_steps = 1; diff --git a/src/nifs.rs b/src/nifs.rs index 9dfbfbfac..d2a6befbe 100644 --- a/src/nifs.rs +++ b/src/nifs.rs @@ -117,6 +117,7 @@ mod tests { use super::*; use crate::{ r1cs::{commitment_key, SparseMatrix}, + traits::snark::default_commitment_key_hint, traits::Group, }; use ::bellpepper_core::{num::AllocatedNum, ConstraintSystem, SynthesisError}; @@ -171,7 +172,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_and_key(&(|_| 0)); + let (shape, ck) = cs.r1cs_shape_and_key(&*default_commitment_key_hint()); let ro_consts = <::RO as ROTrait<::Base, ::Scalar>>::Constants::default(); @@ -332,7 +333,7 @@ mod tests { }; // generate generators and ro constants - let ck = commitment_key(&S, &(|_| 0)); + let ck = commitment_key(&S, &*default_commitment_key_hint()); let ro_consts = <::RO as ROTrait<::Base, ::Scalar>>::Constants::default(); diff --git a/src/supernova/test.rs b/src/supernova/test.rs index 0af701862..6b89e9a84 100644 --- a/src/supernova/test.rs +++ b/src/supernova/test.rs @@ -11,6 +11,7 @@ use crate::provider::secp_secq::secq256k1; use crate::traits::circuit_supernova::{ EnforcingStepCircuit, StepCircuit, TrivialSecondaryCircuit, TrivialTestCircuit, }; +use crate::traits::snark::default_commitment_key_hint; use bellpepper::gadgets::{boolean::Boolean, Assignment}; use bellpepper_core::num::AllocatedNum; use bellpepper_core::{ConstraintSystem, LinearCombination, SynthesisError}; @@ -448,7 +449,11 @@ where let test_rom = TestROM::>::new(rom); let num_steps = test_rom.num_steps(); - let pp = PublicParams::new(&test_rom, &(|_| 0), &(|_| 0)); + let pp = PublicParams::new( + &test_rom, + &*default_commitment_key_hint(), + &*default_commitment_key_hint(), + ); let initial_program_counter = test_rom.initial_program_counter(); @@ -571,7 +576,7 @@ fn test_recursive_circuit_with( if let Err(e) = circuit1.synthesize(&mut cs) { panic!("{}", e) } - let (shape1, ck1) = cs.r1cs_shape_and_key(&(|_| 0)); + let (shape1, ck1) = cs.r1cs_shape_and_key(&*default_commitment_key_hint()); assert_eq!(cs.num_constraints(), num_constraints_primary); // Initialize the shape and ck for the secondary @@ -589,7 +594,7 @@ fn test_recursive_circuit_with( if let Err(e) = circuit2.synthesize(&mut cs) { panic!("{}", e) } - let (shape2, ck2) = cs.r1cs_shape_and_key(&(|_| 0)); + let (shape2, ck2) = cs.r1cs_shape_and_key(&*default_commitment_key_hint()); assert_eq!(cs.num_constraints(), num_constraints_secondary); // Execute the base case for the primary @@ -673,7 +678,11 @@ where // // 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 = PublicParams::::new(non_uniform_circuit, &(|_| 0), &(|_| 0)); + let pp = PublicParams::::new( + non_uniform_circuit, + &*default_commitment_key_hint(), + &*default_commitment_key_hint(), + ); let digest_str = pp .digest() @@ -944,7 +953,11 @@ where G2, RootCheckingCircuit<::Scalar>, TrivialSecondaryCircuit<::Scalar>, - >::new(&roots[0], &(|_| 0), &(|_| 0)); + >::new( + &roots[0], + &*default_commitment_key_hint(), + &*default_commitment_key_hint(), + ); // produce a recursive SNARK let circuit_primary = &roots[0]; diff --git a/src/traits/snark.rs b/src/traits/snark.rs index 280999511..dd90a3881 100644 --- a/src/traits/snark.rs +++ b/src/traits/snark.rs @@ -9,6 +9,15 @@ use crate::{ use abomonation::Abomonation; use serde::{Deserialize, Serialize}; +/// Public parameter creation takes a size hint. This size hint carries the particular requirements of +/// the final compressing SNARK the user expected to use with these public parameters, and the below +/// is a sensible default, which is to not require any more bases then the usual (maximum of the number of +/// variables and constraints of the involved R1CS circuit). +pub fn default_commitment_key_hint() -> Box Fn(&'a R1CSShape) -> usize> { + // The default is to not put an additional floor on the size of the commitment key + Box::new(|_shape: &R1CSShape| 0) +} + /// A trait that defines the behavior of a `zkSNARK` pub trait RelaxedR1CSSNARKTrait: Send + Sync + Serialize + for<'de> Deserialize<'de> @@ -25,7 +34,7 @@ pub trait RelaxedR1CSSNARKTrait: /// be at least as large as this hint. fn commitment_key_floor() -> Box Fn(&'a R1CSShape) -> usize> { // The default is to not put an additional floor on the size of the commitment key - Box::new(|_shape: &R1CSShape| 0) + default_commitment_key_hint() } /// Produces the keys for the prover and the verifier