Skip to content

Commit

Permalink
refactor: Refactor public parameters setup to remove optionality of c…
Browse files Browse the repository at this point in the history
…ommitment key size hint

- Converted `CommitmentKeyHint<G>` 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 microsoft/Nova#203
  • Loading branch information
huitseeker committed Nov 3, 2023
1 parent f81bd4c commit 7ae327b
Show file tree
Hide file tree
Showing 17 changed files with 62 additions and 60 deletions.
8 changes: 4 additions & 4 deletions benches/compressed-snark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ fn bench_compressed_snark(c: &mut Criterion) {
let pp = PublicParams::<G1, G2, C1, C2>::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
Expand Down Expand Up @@ -156,8 +156,8 @@ fn bench_compressed_snark_with_computational_commitments(c: &mut Criterion) {
let pp = PublicParams::<G1, G2, C1, C2>::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();
Expand Down
4 changes: 2 additions & 2 deletions benches/compute-digest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ fn bench_compute_digest(c: &mut Criterion) {
PublicParams::<G1, G2, C1, C2>::new(
black_box(&C1::new(10)),
black_box(&C2::default()),
black_box(None),
black_box(None),
black_box(&(|_| 0)),
black_box(&(|_| 0)),
)
})
});
Expand Down
4 changes: 2 additions & 2 deletions benches/recursive-snark-supernova.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ fn bench_one_augmented_circuit_recursive_snark(c: &mut Criterion) {

let bench: NonUniformBench<G1, G2, TrivialTestCircuit<<G2 as Group>::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
Expand Down Expand Up @@ -206,7 +206,7 @@ fn bench_two_augmented_circuit_recursive_snark(c: &mut Criterion) {

let bench: NonUniformBench<G1, G2, TrivialTestCircuit<<G2 as Group>::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
Expand Down
2 changes: 1 addition & 1 deletion benches/recursive-snark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ fn bench_recursive_snark(c: &mut Criterion) {
let c_secondary = TrivialCircuit::default();

// Produce public parameters
let pp = PublicParams::<G1, G2, C1, C2>::new(&c_primary, &c_secondary, None, None);
let pp = PublicParams::<G1, G2, C1, C2>::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
Expand Down
2 changes: 1 addition & 1 deletion benches/sha256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ fn bench_recursive_snark(c: &mut Criterion) {

// Produce public parameters
let ttc = TrivialCircuit::default();
let pp = PublicParams::<G1, G2, C1, C2>::new(&circuit_primary, &ttc, None, None);
let pp = PublicParams::<G1, G2, C1, C2>::new(&circuit_primary, &ttc, &(|_| 0), &(|_| 0));

let circuit_secondary = TrivialCircuit::default();
let z0_primary = vec![<G1 as Group>::Scalar::from(2u64)];
Expand Down
2 changes: 1 addition & 1 deletion examples/minroot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ fn main() {
G2,
MinRootCircuit<<G1 as Group>::Scalar>,
TrivialCircuit<<G2 as Group>::Scalar>,
>::new(&circuit_primary, &circuit_secondary, None, None);
>::new(&circuit_primary, &circuit_secondary, &(|_| 0), &(|_| 0));
println!("PublicParams::setup, took {:?} ", start.elapsed());

println!(
Expand Down
4 changes: 2 additions & 2 deletions examples/minroot_serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ fn main() {
G2,
MinRootCircuit<<G1 as Group>::Scalar>,
TrivialCircuit<<G2 as Group>::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()
};
Expand All @@ -193,7 +193,7 @@ fn main() {
G2,
MinRootCircuit<<G1 as Group>::Scalar>,
TrivialCircuit<<G2 as Group>::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 {
Expand Down
2 changes: 1 addition & 1 deletion src/bellpepper/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ mod tests {
// First create the shape
let mut cs: ShapeCS<G> = 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<G> = SatisfyingAssignment::new();
Expand Down
4 changes: 2 additions & 2 deletions src/bellpepper/r1cs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ pub trait NovaShape<G: Group> {
/// `r1cs::R1CS::commitment_key`.
fn r1cs_shape_and_key(
&self,
optfn: Option<CommitmentKeyHint<G>>,
ck_hint: &CommitmentKeyHint<G>,
) -> (R1CSShape<G>, CommitmentKey<G>) {
let S = self.r1cs_shape();
let ck = commitment_key(&S, optfn);
let ck = commitment_key(&S, ck_hint);

(S, ck)
}
Expand Down
4 changes: 2 additions & 2 deletions src/circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ mod tests {
NovaAugmentedCircuit::new(primary_params, None, &tc1, ro_consts1.clone());
let mut cs: TestShapeCS<G1> = 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();
Expand All @@ -402,7 +402,7 @@ mod tests {
NovaAugmentedCircuit::new(secondary_params, None, &tc2, ro_consts2.clone());
let mut cs: TestShapeCS<G2> = 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
Expand Down
6 changes: 3 additions & 3 deletions src/gadgets/ecc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1001,7 +1001,7 @@ mod tests {
let mut cs: TestShapeCS<G2> = TestShapeCS::new();
let _ = synthesize_smul::<G1, _>(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<G2> = SatisfyingAssignment::new();
Expand Down Expand Up @@ -1057,7 +1057,7 @@ mod tests {
let mut cs: TestShapeCS<G2> = TestShapeCS::new();
let _ = synthesize_add_equal::<G1, _>(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<G2> = SatisfyingAssignment::new();
Expand Down Expand Up @@ -1117,7 +1117,7 @@ mod tests {
let mut cs: TestShapeCS<G2> = TestShapeCS::new();
let _ = synthesize_add_negation::<G1, _>(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<G2> = SatisfyingAssignment::new();
Expand Down
41 changes: 22 additions & 19 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 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
///
Expand All @@ -169,17 +172,17 @@ where
///
/// let circuit1 = TrivialCircuit::<<G1 as Group>::Scalar>::default();
/// let circuit2 = TrivialCircuit::<<G2 as Group>::Scalar>::default();
/// // Only relevant for a SNARK using computational commitments, pass None otherwise.
/// let pp_hint1 = Some(SPrime::<G1>::commitment_key_floor());
/// let pp_hint2 = Some(SPrime::<G2>::commitment_key_floor());
/// // Only relevant for a SNARK using computational commitments, pass &(|_| 0) otherwise.
/// let pp_hint1 = &*SPrime::<G1>::commitment_key_floor();
/// let pp_hint2 = &*SPrime::<G2>::commitment_key_floor();
///
/// let pp = PublicParams::new(&circuit1, &circuit2, pp_hint1, pp_hint2);
/// ```
pub fn new(
c_primary: &C1,
c_secondary: &C2,
optfn1: Option<CommitmentKeyHint<G1>>,
optfn2: Option<CommitmentKeyHint<G2>>,
optfn1: &CommitmentKeyHint<G1>,
optfn2: &CommitmentKeyHint<G2>,
) -> Self {
let augmented_circuit_params_primary =
NovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, true);
Expand Down Expand Up @@ -1029,8 +1032,8 @@ mod tests {
<G2::Scalar as PrimeField>::Repr: Abomonation,
{
// this tests public parameters with a size specifically intended for a spark-compressed SNARK
let pp_hint1 = Some(SPrime::<G1, E1>::commitment_key_floor());
let pp_hint2 = Some(SPrime::<G2, E2>::commitment_key_floor());
let pp_hint1 = &*SPrime::<G1, E1>::commitment_key_floor();
let pp_hint2 = &*SPrime::<G2, E2>::commitment_key_floor();
let pp = PublicParams::<G1, G2, T1, T2>::new(circuit1, circuit2, pp_hint1, pp_hint2);

let digest_str = pp
Expand Down Expand Up @@ -1111,7 +1114,7 @@ mod tests {
G2,
TrivialCircuit<<G1 as Group>::Scalar>,
TrivialCircuit<<G2 as Group>::Scalar>,
>::new(&test_circuit1, &test_circuit2, None, None);
>::new(&test_circuit1, &test_circuit2, &(|_| 0), &(|_| 0));
let num_steps = 1;

// produce a recursive SNARK
Expand Down Expand Up @@ -1162,7 +1165,7 @@ mod tests {
G2,
TrivialCircuit<<G1 as Group>::Scalar>,
CubicCircuit<<G2 as Group>::Scalar>,
>::new(&circuit_primary, &circuit_secondary, None, None);
>::new(&circuit_primary, &circuit_secondary, &(|_| 0), &(|_| 0));

let num_steps = 3;

Expand Down Expand Up @@ -1245,7 +1248,7 @@ mod tests {
G2,
TrivialCircuit<<G1 as Group>::Scalar>,
CubicCircuit<<G2 as Group>::Scalar>,
>::new(&circuit_primary, &circuit_secondary, None, None);
>::new(&circuit_primary, &circuit_secondary, &(|_| 0), &(|_| 0));

let num_steps = 3;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -1509,7 +1512,7 @@ mod tests {
G2,
FifthRootCheckingCircuit<<G1 as Group>::Scalar>,
TrivialCircuit<<G2 as Group>::Scalar>,
>::new(&circuit_primary, &circuit_secondary, None, None);
>::new(&circuit_primary, &circuit_secondary, &(|_| 0), &(|_| 0));

let num_steps = 3;

Expand Down Expand Up @@ -1584,7 +1587,7 @@ mod tests {
G2,
TrivialCircuit<<G1 as Group>::Scalar>,
CubicCircuit<<G2 as Group>::Scalar>,
>::new(&test_circuit1, &test_circuit2, None, None);
>::new(&test_circuit1, &test_circuit2, &(|_| 0), &(|_| 0));

let num_steps = 1;

Expand Down
4 changes: 2 additions & 2 deletions src/nifs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ mod tests {
// First create the shape
let mut cs: TestShapeCS<G> = 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 =
<<G as Group>::RO as ROTrait<<G as Group>::Base, <G as Group>::Scalar>>::Constants::default();

Expand Down Expand Up @@ -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 =
<<G as Group>::RO as ROTrait<<G as Group>::Base, <G as Group>::Scalar>>::Constants::default();

Expand Down
13 changes: 6 additions & 7 deletions src/r1cs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ pub struct RelaxedR1CSInstance<G: Group> {
}

/// A type for functions that hints commitment key sizing by returning the floor of the number of required generators.
pub type CommitmentKeyHint<G> = Box<dyn Fn(&R1CSShape<G>) -> usize>;
pub type CommitmentKeyHint<G> = dyn Fn(&R1CSShape<G>) -> usize;

/// Generates public parameters for a Rank-1 Constraint System (R1CS).
///
Expand All @@ -86,13 +86,12 @@ pub type CommitmentKeyHint<G> = Box<dyn Fn(&R1CSShape<G>) -> 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<G: Group>(
S: &R1CSShape<G>,
commitment_key_floor: Option<CommitmentKeyHint<G>>,
commitment_key_floor: &CommitmentKeyHint<G>,
) -> CommitmentKey<G> {
let size = commitment_key_size(S, commitment_key_floor);
G::CE::setup(b"ck", size)
Expand All @@ -101,11 +100,11 @@ pub fn commitment_key<G: Group>(
/// Computes the number of generators required for the commitment key corresponding to shape `S`.
pub fn commitment_key_size<G: Group>(
S: &R1CSShape<G>,
commitment_key_floor: Option<CommitmentKeyHint<G>>,
commitment_key_floor: &CommitmentKeyHint<G>,
) -> 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)
}

Expand Down
2 changes: 1 addition & 1 deletion src/spartan/direct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ impl<G: Group, S: RelaxedR1CSSNARKTrait<G>, C: StepCircuit<G::Scalar>> DirectSNA

let mut cs: ShapeCS<G> = 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)?;

Expand Down
12 changes: 6 additions & 6 deletions src/supernova/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ 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, R1CSInstance, R1CSWitness, RelaxedR1CSInstance, RelaxedR1CSWitness, CommitmentKeyHint},
scalar_as_base,
traits::{
circuit_supernova::StepCircuit,
Expand Down Expand Up @@ -168,7 +168,7 @@ where
C2: StepCircuit<G2::Scalar>,
{
/// Construct a new [PublicParams]
pub fn new<NC: NonUniformCircuit<G1, G2, C1, C2>>(non_unifrom_circuit: &NC) -> Self {
pub fn new<NC: NonUniformCircuit<G1, G2, C1, C2>>(non_unifrom_circuit: &NC, ck_hint1: &CommitmentKeyHint<G1>, ck_hint2: &CommitmentKeyHint<G2>) -> Self {
let num_circuits = non_unifrom_circuit.num_circuits();

let augmented_circuit_params_primary =
Expand Down Expand Up @@ -197,7 +197,7 @@ where
})
.collect::<Vec<_>>();

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);
Expand All @@ -215,7 +215,7 @@ where
);
let mut cs: ShapeCS<G2> = 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 {
Expand Down Expand Up @@ -322,10 +322,10 @@ 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<G1>]) -> CommitmentKey<G1> {
fn compute_primary_ck(circuit_params: &[CircuitShape<G1>], ck_hint1: &CommitmentKeyHint<G1>) -> CommitmentKey<G1> {
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();

Expand Down
Loading

0 comments on commit 7ae327b

Please sign in to comment.