From 6b40aec4d15789ac28fed5caa37a58104324f6fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Garillot?= Date: Fri, 2 Feb 2024 14:15:09 -0500 Subject: [PATCH 1/8] refactor: Reorder generic parameters across all SNARK methods and structs TL;DR: This is deinterleaving, i.e. E1, E2, C1, C2 .. becomes E1, C1, .. E2, C2, ... - Reorganized order of generic parameters across various rust function calls and implementations, affecting structures such as `PublicParams`, `RecursiveSNARK`, and `CompressedSNARK`, among others. - Updated all relevant unit tests to align with the new ordering of parameters. --- benches/common/supernova/bench.rs | 6 +-- benches/common/supernova/mod.rs | 2 +- benches/compressed-snark.rs | 10 ++-- benches/compute-digest.rs | 2 +- benches/recursive-snark.rs | 4 +- benches/sha256.rs | 2 +- examples/and.rs | 10 ++-- examples/minroot.rs | 10 ++-- src/lib.rs | 89 +++++++++++++++---------------- src/supernova/mod.rs | 24 ++++----- src/supernova/snark.rs | 32 +++++------ src/supernova/test.rs | 20 +++---- 12 files changed, 103 insertions(+), 108 deletions(-) diff --git a/benches/common/supernova/bench.rs b/benches/common/supernova/bench.rs index 4ccf243d1..524d8e072 100644 --- a/benches/common/supernova/bench.rs +++ b/benches/common/supernova/bench.rs @@ -97,11 +97,11 @@ pub fn bench_snark_internal_with_arity< match snark_type { SnarkType::Compressed => { - let (prover_key, verifier_key) = CompressedSNARK::<_, _, _, _, S1, S2>::setup(&pp).unwrap(); + let (prover_key, verifier_key) = CompressedSNARK::<_, _, S1, _, _, S2>::setup(&pp).unwrap(); // Benchmark the prove time group.bench_function(bench_params.bench_id("Prove"), |b| { b.iter(|| { - assert!(CompressedSNARK::<_, _, _, _, S1, S2>::prove( + assert!(CompressedSNARK::<_, _, S1, _, _, S2>::prove( black_box(&pp), black_box(&prover_key), black_box(&recursive_snark) @@ -110,7 +110,7 @@ pub fn bench_snark_internal_with_arity< }) }); - let res = CompressedSNARK::<_, _, _, _, S1, S2>::prove(&pp, &prover_key, &recursive_snark); + let res = CompressedSNARK::<_, _, S1, _, _, S2>::prove(&pp, &prover_key, &recursive_snark); assert!(res.is_ok()); let compressed_snark = res.unwrap(); // Benchmark the verification time diff --git a/benches/common/supernova/mod.rs b/benches/common/supernova/mod.rs index 64d1b84d0..5ade9db57 100644 --- a/benches/common/supernova/mod.rs +++ b/benches/common/supernova/mod.rs @@ -95,7 +95,7 @@ where } impl - NonUniformCircuit, TrivialTestCircuit> + NonUniformCircuit, E2, TrivialTestCircuit> for NonUniformBench where E1: Engine::Scalar>, diff --git a/benches/compressed-snark.rs b/benches/compressed-snark.rs index c3eab2a17..c6ec1b08a 100644 --- a/benches/compressed-snark.rs +++ b/benches/compressed-snark.rs @@ -69,7 +69,7 @@ fn bench_compressed_snark_internal, S2: RelaxedR1C let c_secondary = TrivialCircuit::default(); // Produce public parameters - let pp = PublicParams::::setup( + let pp = PublicParams::::setup( &c_primary, &c_secondary, &*S1::ck_floor(), @@ -77,11 +77,11 @@ fn bench_compressed_snark_internal, S2: RelaxedR1C ); // Produce prover and verifier keys for CompressedSNARK - let (pk, vk) = CompressedSNARK::<_, _, _, _, S1, S2>::setup(&pp).unwrap(); + let (pk, vk) = CompressedSNARK::<_, _, S1, _, _, S2>::setup(&pp).unwrap(); // produce a recursive SNARK let num_steps = 3; - let mut recursive_snark: RecursiveSNARK = RecursiveSNARK::new( + let mut recursive_snark: RecursiveSNARK = RecursiveSNARK::new( &pp, &c_primary, &c_secondary, @@ -113,7 +113,7 @@ fn bench_compressed_snark_internal, S2: RelaxedR1C // Bench time to produce a compressed SNARK group.bench_function(bench_params.bench_id("Prove"), |b| { b.iter(|| { - assert!(CompressedSNARK::<_, _, _, _, S1, S2>::prove( + assert!(CompressedSNARK::<_, _, S1, _, _, S2>::prove( black_box(&pp), black_box(&pk), black_box(&recursive_snark) @@ -121,7 +121,7 @@ fn bench_compressed_snark_internal, S2: RelaxedR1C .is_ok()); }) }); - let res = CompressedSNARK::<_, _, _, _, S1, S2>::prove(&pp, &pk, &recursive_snark); + let res = CompressedSNARK::<_, _, S1, _, _, S2>::prove(&pp, &pk, &recursive_snark); assert!(res.is_ok()); let compressed_snark = res.unwrap(); diff --git a/benches/compute-digest.rs b/benches/compute-digest.rs index aa5608ae3..fe390e5a0 100644 --- a/benches/compute-digest.rs +++ b/benches/compute-digest.rs @@ -29,7 +29,7 @@ criterion_main!(compute_digest); fn bench_compute_digest(c: &mut Criterion) { c.bench_function("compute_digest", |b| { b.iter(|| { - PublicParams::::setup( + PublicParams::::setup( black_box(&C1::new(10)), black_box(&C2::default()), black_box(&*default_ck_hint()), diff --git a/benches/recursive-snark.rs b/benches/recursive-snark.rs index 08d3ffac4..323de02bb 100644 --- a/benches/recursive-snark.rs +++ b/benches/recursive-snark.rs @@ -73,7 +73,7 @@ fn bench_recursive_snark(c: &mut Criterion) { let c_secondary = TrivialCircuit::default(); // Produce public parameters - let pp = PublicParams::::setup( + let pp = PublicParams::::setup( &c_primary, &c_secondary, &*default_ck_hint(), @@ -85,7 +85,7 @@ fn bench_recursive_snark(c: &mut Criterion) { // the first step is cheaper than other steps owing to the presence of // a lot of zeros in the satisfying assignment let num_warmup_steps = 10; - let mut recursive_snark: RecursiveSNARK = RecursiveSNARK::new( + let mut recursive_snark: RecursiveSNARK = RecursiveSNARK::new( &pp, &c_primary, &c_secondary, diff --git a/benches/sha256.rs b/benches/sha256.rs index 9e927278c..2209566c9 100644 --- a/benches/sha256.rs +++ b/benches/sha256.rs @@ -158,7 +158,7 @@ fn bench_recursive_snark(c: &mut Criterion) { // Produce public parameters let ttc = TrivialCircuit::default(); - let pp = PublicParams::::setup( + let pp = PublicParams::::setup( &circuit_primary, &ttc, &*default_ck_hint(), diff --git a/examples/and.rs b/examples/and.rs index c0fb0ece4..b71aaf594 100644 --- a/examples/and.rs +++ b/examples/and.rs @@ -224,8 +224,8 @@ fn main() { println!("Producing public parameters..."); let pp = PublicParams::< E1, - E2, AndCircuit<::GE>, + E2, TrivialCircuit<::Scalar>, >::setup( &circuit_primary, @@ -263,8 +263,8 @@ fn main() { // produce a recursive SNARK println!("Generating a RecursiveSNARK..."); - let mut recursive_snark: RecursiveSNARK = - RecursiveSNARK::::new( + let mut recursive_snark: RecursiveSNARK = + RecursiveSNARK::::new( &pp, &circuits[0], &circuit_secondary, @@ -297,11 +297,11 @@ fn main() { // produce a compressed SNARK println!("Generating a CompressedSNARK using Spartan with multilinear KZG..."); - let (pk, vk) = CompressedSNARK::<_, _, _, _, S1, S2>::setup(&pp).unwrap(); + let (pk, vk) = CompressedSNARK::<_, _, S1, _, _, S2>::setup(&pp).unwrap(); let start = Instant::now(); - let res = CompressedSNARK::<_, _, _, _, S1, S2>::prove(&pp, &pk, &recursive_snark); + let res = CompressedSNARK::<_, _, S1, _, _, S2>::prove(&pp, &pk, &recursive_snark); println!( "CompressedSNARK::prove: {:?}, took {:?}", res.is_ok(), diff --git a/examples/minroot.rs b/examples/minroot.rs index 1ded8795d..5a737cd3b 100644 --- a/examples/minroot.rs +++ b/examples/minroot.rs @@ -223,8 +223,8 @@ fn main() { println!("Producing public parameters..."); let pp = PublicParams::< E1, - E2, MinRootCircuit<::GE>, + E2, TrivialCircuit<::Scalar>, >::setup( &circuit_primary, @@ -316,8 +316,8 @@ fn main() { type C2 = TrivialCircuit<::Scalar>; // produce a recursive SNARK println!("Generating a RecursiveSNARK..."); - let mut recursive_snark: RecursiveSNARK = - RecursiveSNARK::::new( + let mut recursive_snark: RecursiveSNARK = + RecursiveSNARK::::new( &pp, &minroot_circuits[0], &circuit_secondary, @@ -351,7 +351,7 @@ fn main() { // produce a compressed SNARK println!("Generating a CompressedSNARK using Spartan with multilinear KZG..."); - let (pk, vk) = CompressedSNARK::<_, _, _, _, S1, S2>::setup(&pp).unwrap(); + let (pk, vk) = CompressedSNARK::<_, _, S1, _, _, S2>::setup(&pp).unwrap(); let start = Instant::now(); type E1 = Bn256EngineKZG; @@ -361,7 +361,7 @@ fn main() { type S1 = arecibo::spartan::ppsnark::RelaxedR1CSSNARK; // non-preprocessing SNARK type S2 = arecibo::spartan::ppsnark::RelaxedR1CSSNARK; // non-preprocessing SNARK - let res = CompressedSNARK::<_, _, _, _, S1, S2>::prove(&pp, &pk, &recursive_snark); + let res = CompressedSNARK::<_, _, S1, _, _, S2>::prove(&pp, &pk, &recursive_snark); println!( "CompressedSNARK::prove: {:?}, took {:?}", res.is_ok(), diff --git a/src/lib.rs b/src/lib.rs index e535e04d0..4f58d3d12 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -90,7 +90,7 @@ impl R1CSWithArity { /// A type that holds public parameters of Nova #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(bound = "")] -pub struct PublicParams +pub struct PublicParams where E1: Engine::Scalar>, E2: Engine::Scalar>, @@ -130,7 +130,7 @@ where ::Repr: Abomonation, ::Repr: Abomonation, )] -pub struct FlatPublicParams +pub struct FlatPublicParams where E1: Engine::Scalar>, E2: Engine::Scalar>, @@ -153,7 +153,7 @@ where } #[cfg(feature = "abomonate")] -impl TryFrom> for FlatPublicParams +impl TryFrom> for FlatPublicParams where E1: Engine::Scalar>, E2: Engine::Scalar>, @@ -162,7 +162,7 @@ where { type Error = &'static str; - fn try_from(value: PublicParams) -> Result { + 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 = @@ -186,14 +186,14 @@ where } #[cfg(feature = "abomonate")] -impl From> for PublicParams +impl From> for PublicParams where E1: Engine::Scalar>, E2: Engine::Scalar>, C1: StepCircuit, C2: StepCircuit, { - fn from(value: FlatPublicParams) -> Self { + fn from(value: FlatPublicParams) -> Self { Self { F_arity_primary: value.F_arity_primary, F_arity_secondary: value.F_arity_secondary, @@ -213,7 +213,7 @@ where } } -impl SimpleDigestible for PublicParams +impl SimpleDigestible for PublicParams where E1: Engine::Scalar>, E2: Engine::Scalar>, @@ -222,7 +222,7 @@ where { } -impl PublicParams +impl PublicParams where E1: Engine::Scalar>, E2: Engine::Scalar>, @@ -381,7 +381,7 @@ pub struct ResourceBuffer { /// A SNARK that proves the correct execution of an incremental computation #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(bound = "")] -pub struct RecursiveSNARK +pub struct RecursiveSNARK where E1: Engine::Scalar>, E2: Engine::Scalar>, @@ -408,7 +408,7 @@ where _p: PhantomData<(C1, C2)>, } -impl RecursiveSNARK +impl RecursiveSNARK where E1: Engine::Scalar>, E2: Engine::Scalar>, @@ -417,7 +417,7 @@ where { /// Create new instance of recursive SNARK pub fn new( - pp: &PublicParams, + pp: &PublicParams, c_primary: &C1, c_secondary: &C2, z0_primary: &[E1::Scalar], @@ -544,7 +544,7 @@ where #[tracing::instrument(skip_all, name = "nova::RecursiveSNARK::prove_step")] pub fn prove_step( &mut self, - pp: &PublicParams, + pp: &PublicParams, c_primary: &C1, c_secondary: &C2, ) -> Result<(), NovaError> { @@ -662,7 +662,7 @@ where /// Verify the correctness of the `RecursiveSNARK` pub fn verify( &self, - pp: &PublicParams, + pp: &PublicParams, num_steps: usize, z0_primary: &[E1::Scalar], z0_secondary: &[E2::Scalar], @@ -781,7 +781,7 @@ where /// A type that holds the prover key for `CompressedSNARK` #[derive(Clone, Debug)] -pub struct ProverKey +pub struct ProverKey where E1: Engine::Scalar>, E2: Engine::Scalar>, @@ -798,7 +798,7 @@ where /// A type that holds the verifier key for `CompressedSNARK` #[derive(Debug, Clone, Serialize)] #[serde(bound = "")] -pub struct VerifierKey +pub struct VerifierKey where E1: Engine::Scalar>, E2: Engine::Scalar>, @@ -820,7 +820,7 @@ where /// A SNARK that proves the knowledge of a valid `RecursiveSNARK` #[derive(Debug, Serialize, Deserialize)] #[serde(bound = "")] -pub struct CompressedSNARK +pub struct CompressedSNARK where E1: Engine::Scalar>, E2: Engine::Scalar>, @@ -843,7 +843,7 @@ where _p: PhantomData<(C1, C2)>, } -impl CompressedSNARK +impl CompressedSNARK where E1: Engine::Scalar>, E2: Engine::Scalar>, @@ -854,11 +854,11 @@ where { /// Creates prover and verifier keys for `CompressedSNARK` pub fn setup( - pp: &PublicParams, + pp: &PublicParams, ) -> Result< ( - ProverKey, - VerifierKey, + ProverKey, + VerifierKey, ), NovaError, > { @@ -891,9 +891,9 @@ where /// Create a new `CompressedSNARK` pub fn prove( - pp: &PublicParams, - pk: &ProverKey, - recursive_snark: &RecursiveSNARK, + pp: &PublicParams, + pk: &ProverKey, + recursive_snark: &RecursiveSNARK, ) -> Result { // fold the secondary circuit's instance with its running instance let (nifs_secondary, (f_U_secondary, f_W_secondary)) = NIFS::prove( @@ -948,7 +948,7 @@ where /// Verify the correctness of the `CompressedSNARK` pub fn verify( &self, - vk: &VerifierKey, + vk: &VerifierKey, num_steps: usize, z0_primary: &[E1::Scalar], z0_secondary: &[E2::Scalar], @@ -1153,7 +1153,7 @@ mod tests { // this tests public parameters with a size specifically intended for a spark-compressed SNARK let ck_hint1 = &*SPrime::::ck_floor(); let ck_hint2 = &*SPrime::::ck_floor(); - let pp = PublicParams::::setup(circuit1, circuit2, ck_hint1, ck_hint2); + let pp = PublicParams::::setup(circuit1, circuit2, ck_hint1, ck_hint2); let digest_str = pp .digest() @@ -1241,8 +1241,8 @@ mod tests { // produce public parameters let pp = PublicParams::< E1, - E2, TrivialCircuit<::Scalar>, + E2, TrivialCircuit<::Scalar>, >::setup( &test_circuit1, @@ -1294,8 +1294,8 @@ mod tests { // produce public parameters let pp = PublicParams::< E1, - E2, TrivialCircuit<::Scalar>, + E2, CubicCircuit<::Scalar>, >::setup( &circuit_primary, @@ -1309,8 +1309,8 @@ mod tests { // produce a recursive SNARK let mut recursive_snark = RecursiveSNARK::< E1, - E2, TrivialCircuit<::Scalar>, + E2, CubicCircuit<::Scalar>, >::new( &pp, @@ -1379,8 +1379,8 @@ mod tests { // produce public parameters let pp = PublicParams::< E1, - E2, TrivialCircuit<::Scalar>, + E2, CubicCircuit<::Scalar>, >::setup( &circuit_primary, @@ -1394,8 +1394,8 @@ mod tests { // produce a recursive SNARK let mut recursive_snark = RecursiveSNARK::< E1, - E2, TrivialCircuit<::Scalar>, + E2, CubicCircuit<::Scalar>, >::new( &pp, @@ -1432,11 +1432,11 @@ mod tests { assert_eq!(zn_secondary, vec![::Scalar::from(2460515u64)]); // produce the prover and verifier keys for compressed snark - let (pk, vk) = CompressedSNARK::<_, _, _, _, S, S>::setup(&pp).unwrap(); + let (pk, vk) = CompressedSNARK::<_, _, S, _, _, S>::setup(&pp).unwrap(); // produce a compressed SNARK let res = - CompressedSNARK::<_, _, _, _, S, S>::prove(&pp, &pk, &recursive_snark); + CompressedSNARK::<_, _, S, _, _, S>::prove(&pp, &pk, &recursive_snark); assert!(res.is_ok()); let compressed_snark = res.unwrap(); @@ -1486,8 +1486,8 @@ mod tests { // produce public parameters, which we'll use with a spark-compressed SNARK let pp = PublicParams::< E1, - E2, TrivialCircuit<::Scalar>, + E2, CubicCircuit<::Scalar>, >::setup( &circuit_primary, @@ -1501,8 +1501,8 @@ mod tests { // produce a recursive SNARK let mut recursive_snark = RecursiveSNARK::< E1, - E2, TrivialCircuit<::Scalar>, + E2, CubicCircuit<::Scalar>, >::new( &pp, @@ -1541,10 +1541,10 @@ mod tests { // run the compressed snark with Spark compiler // produce the prover and verifier keys for compressed snark let (pk, vk) = - CompressedSNARK::<_, _, _, _, SPrime, SPrime>::setup(&pp).unwrap(); + CompressedSNARK::<_, _, SPrime, _, _, SPrime>::setup(&pp).unwrap(); // produce a compressed SNARK - let res = CompressedSNARK::<_, _, _, _, SPrime, SPrime>::prove( + let res = CompressedSNARK::<_, _, SPrime, _, _, SPrime>::prove( &pp, &pk, &recursive_snark, @@ -1652,8 +1652,8 @@ mod tests { // produce public parameters let pp = PublicParams::< E1, - E2, FifthRootCheckingCircuit<::Scalar>, + E2, TrivialCircuit<::Scalar>, >::setup( &circuit_primary, @@ -1669,15 +1669,10 @@ mod tests { let z0_secondary = vec![::Scalar::ZERO]; // produce a recursive SNARK - let mut recursive_snark: RecursiveSNARK< + let mut recursive_snark = RecursiveSNARK::< E1, - E2, FifthRootCheckingCircuit<::Scalar>, - TrivialCircuit<::Scalar>, - > = RecursiveSNARK::< - E1, E2, - FifthRootCheckingCircuit<::Scalar>, TrivialCircuit<::Scalar>, >::new( &pp, @@ -1698,11 +1693,11 @@ mod tests { assert!(res.is_ok()); // produce the prover and verifier keys for compressed snark - let (pk, vk) = CompressedSNARK::<_, _, _, _, S, S>::setup(&pp).unwrap(); + let (pk, vk) = CompressedSNARK::<_, _, S, _, _, S>::setup(&pp).unwrap(); // produce a compressed SNARK let res = - CompressedSNARK::<_, _, _, _, S, S>::prove(&pp, &pk, &recursive_snark); + CompressedSNARK::<_, _, S, _, _, S>::prove(&pp, &pk, &recursive_snark); assert!(res.is_ok()); let compressed_snark = res.unwrap(); @@ -1731,8 +1726,8 @@ mod tests { // produce public parameters let pp = PublicParams::< E1, - E2, TrivialCircuit<::Scalar>, + E2, CubicCircuit<::Scalar>, >::setup( &test_circuit1, @@ -1746,8 +1741,8 @@ mod tests { // produce a recursive SNARK let mut recursive_snark = RecursiveSNARK::< E1, - E2, TrivialCircuit<::Scalar>, + E2, CubicCircuit<::Scalar>, >::new( &pp, diff --git a/src/supernova/mod.rs b/src/supernova/mod.rs index c4ad641b0..ab28c36e9 100644 --- a/src/supernova/mod.rs +++ b/src/supernova/mod.rs @@ -82,7 +82,7 @@ impl CircuitDigests { /// A vector of [`R1CSWithArity`] adjoined to a set of [`PublicParams`] #[derive(Debug, Serialize)] #[serde(bound = "")] -pub struct PublicParams +pub struct PublicParams where E1: Engine::Scalar>, E2: Engine::Scalar>, @@ -213,7 +213,7 @@ where } } -impl Index for PublicParams +impl Index for PublicParams where E1: Engine::Scalar>, E2: Engine::Scalar>, @@ -227,7 +227,7 @@ where } } -impl SimpleDigestible for PublicParams +impl SimpleDigestible for PublicParams where E1: Engine::Scalar>, E2: Engine::Scalar>, @@ -236,7 +236,7 @@ where { } -impl PublicParams +impl PublicParams where E1: Engine::Scalar>, E2: Engine::Scalar>, @@ -261,7 +261,7 @@ where /// * `ck_hint1`: A `CommitmentKeyHint` for `E1`, 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 `E2`, similar to `ck_hint1`, but for the secondary circuit. - pub fn setup>( + pub fn setup>( non_uniform_circuit: &NC, ck_hint1: &CommitmentKeyHint, ck_hint2: &CommitmentKeyHint, @@ -538,11 +538,11 @@ where /// iterate base step to get new instance of recursive SNARK #[allow(clippy::too_many_arguments)] pub fn new< - C0: NonUniformCircuit, + C0: NonUniformCircuit, C1: StepCircuit, C2: StepCircuit, >( - pp: &PublicParams, + pp: &PublicParams, non_uniform_circuit: &C0, c_primary: &C1, c_secondary: &C2, @@ -746,7 +746,7 @@ where #[tracing::instrument(skip_all, name = "supernova::RecursiveSNARK::prove_step")] pub fn prove_step, C2: StepCircuit>( &mut self, - pp: &PublicParams, + pp: &PublicParams, c_primary: &C1, c_secondary: &C2, ) -> Result<(), SuperNovaError> { @@ -933,7 +933,7 @@ where /// verify recursive snark pub fn verify, C2: StepCircuit>( &self, - pp: &PublicParams, + pp: &PublicParams, z0_primary: &[E1::Scalar], z0_secondary: &[E2::Scalar], ) -> Result<(Vec, Vec), SuperNovaError> { @@ -1131,7 +1131,7 @@ where /// SuperNova helper trait, for implementors that provide sets of sub-circuits to be proved via NIVC. `C1` must be a /// type (likely an `Enum`) for which a potentially-distinct instance can be supplied for each `index` below /// `self.num_circuits()`. -pub trait NonUniformCircuit +pub trait NonUniformCircuit where E1: Engine::Scalar>, E2: Engine::Scalar>, @@ -1154,7 +1154,7 @@ where } /// Extension trait to simplify getting scalar form of initial circuit index. -trait InitialProgramCounter: NonUniformCircuit +trait InitialProgramCounter: NonUniformCircuit where E1: Engine::Scalar>, E2: Engine::Scalar>, @@ -1167,7 +1167,7 @@ where } } -impl> InitialProgramCounter +impl> InitialProgramCounter for T where E1: Engine::Scalar>, diff --git a/src/supernova/snark.rs b/src/supernova/snark.rs index b71f1db66..fc6407b6e 100644 --- a/src/supernova/snark.rs +++ b/src/supernova/snark.rs @@ -18,7 +18,7 @@ use std::marker::PhantomData; /// A type that holds the prover key for `CompressedSNARK` #[derive(Debug)] -pub struct ProverKey +pub struct ProverKey where E1: Engine::Scalar>, E2: Engine::Scalar>, @@ -34,7 +34,7 @@ where /// A type that holds the verifier key for `CompressedSNARK` #[derive(Debug)] -pub struct VerifierKey +pub struct VerifierKey where E1: Engine::Scalar>, E2: Engine::Scalar>, @@ -51,7 +51,7 @@ where /// A SNARK that proves the knowledge of a valid `RecursiveSNARK` #[derive(Debug, Serialize, Deserialize)] #[serde(bound = "")] -pub struct CompressedSNARK +pub struct CompressedSNARK where E1: Engine::Scalar>, E2: Engine::Scalar>, @@ -73,10 +73,10 @@ where zn_primary: Vec, zn_secondary: Vec, - _p: PhantomData<(E1, E2, C1, C2, S1, S2)>, + _p: PhantomData<(E1, C1, S1, E2, C2, S2)>, } -impl CompressedSNARK +impl CompressedSNARK where E1: Engine::Scalar>, E2: Engine::Scalar>, @@ -87,11 +87,11 @@ where { /// Creates prover and verifier keys for `CompressedSNARK` pub fn setup( - pp: &PublicParams, + pp: &PublicParams, ) -> Result< ( - ProverKey, - VerifierKey, + ProverKey, + VerifierKey, ), SuperNovaError, > { @@ -118,8 +118,8 @@ where /// Create a new `CompressedSNARK` pub fn prove( - pp: &PublicParams, - pk: &ProverKey, + pp: &PublicParams, + pk: &ProverKey, recursive_snark: &RecursiveSNARK, ) -> Result { // fold the secondary circuit's instance @@ -204,8 +204,8 @@ where /// Verify the correctness of the `CompressedSNARK` pub fn verify( &self, - pp: &PublicParams, - vk: &VerifierKey, + pp: &PublicParams, + vk: &VerifierKey, z0_primary: &[E1::Scalar], z0_secondary: &[E2::Scalar], ) -> Result<(Vec, Vec), SuperNovaError> { @@ -466,7 +466,7 @@ mod test { } } - impl NonUniformCircuit> + impl NonUniformCircuit> for TestCircuit where E1: Engine::Scalar>, @@ -527,7 +527,7 @@ mod test { assert!(verify_res.is_ok()); } - let (prover_key, verifier_key) = CompressedSNARK::<_, _, _, _, S1, S2>::setup(&pp).unwrap(); + let (prover_key, verifier_key) = CompressedSNARK::<_, _, S1, _, _, S2>::setup(&pp).unwrap(); let compressed_prove_res = CompressedSNARK::prove(&pp, &prover_key, &recursive_snark); @@ -652,7 +652,7 @@ mod test { } } - impl NonUniformCircuit> + impl NonUniformCircuit> for BigTestCircuit where E1: Engine::Scalar>, @@ -713,7 +713,7 @@ mod test { assert!(verify_res.is_ok()); } - let (prover_key, verifier_key) = CompressedSNARK::<_, _, _, _, S1, S2>::setup(&pp).unwrap(); + let (prover_key, verifier_key) = CompressedSNARK::<_, _, S1, _, _, S2>::setup(&pp).unwrap(); let compressed_prove_res = CompressedSNARK::prove(&pp, &prover_key, &recursive_snark); diff --git a/src/supernova/test.rs b/src/supernova/test.rs index 6660b06f9..e08ffb2ef 100644 --- a/src/supernova/test.rs +++ b/src/supernova/test.rs @@ -226,9 +226,9 @@ where } } -fn print_constraints_name_on_error_index( +fn print_constraints_name_on_error_index( err: &SuperNovaError, - pp: &PublicParams, + pp: &PublicParams, c_primary: &C1, c_secondary: &C2, num_augmented_circuits: usize, @@ -318,7 +318,7 @@ impl StepCircuit for TestROMCircuit { } impl - NonUniformCircuit, TrivialSecondaryCircuit> + NonUniformCircuit, E2, TrivialSecondaryCircuit> for TestROM> where E1: Engine::Scalar>, @@ -575,19 +575,19 @@ fn test_recursive_circuit() { ); } -fn test_pp_digest_with(non_uniform_circuit: &NC, expected: &Expect) +fn test_pp_digest_with(non_uniform_circuit: &NC, expected: &Expect) where E1: Engine::Scalar>, E2: Engine::Scalar>, - T1: StepCircuit, - T2: StepCircuit, - NC: NonUniformCircuit, + C1: StepCircuit, + C2: StepCircuit, + NC: NonUniformCircuit, { // TODO: add back in https://github.com/lurk-lab/arecibo/issues/53 // // 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::::setup( + let pp = PublicParams::::setup( non_uniform_circuit, &*default_ck_hint(), &*default_ck_hint(), @@ -816,7 +816,7 @@ where } } -impl NonUniformCircuit> +impl NonUniformCircuit> for RootCheckingCircuit where E1: Engine::Scalar>, @@ -859,8 +859,8 @@ where // produce public parameters let pp = PublicParams::< E1, - E2, RootCheckingCircuit<::Scalar>, + E2, TrivialSecondaryCircuit<::Scalar>, >::setup(&roots[0], &*default_ck_hint(), &*default_ck_hint()); // produce a recursive SNARK From aea857aeb7ad4d284ae534829d800aa5bea6c158 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Garillot?= Date: Fri, 2 Feb 2024 14:15:12 -0500 Subject: [PATCH 2/8] feat: Implement CurveCycleEquipped for various engines - Introduced a new convenience trait to pair engines with fields in a curve cycle relationship, extending mod.rs traits. - Added CurveCycleEquipped to the provider mod.rs traits list. - Implemented CurveCycleEquipped to Bn256Engine, Bn256EngineKZG, Bn256EngineZM, Secp256k1Engine, and PallasEngine, setting respective secondary types accordingly. - Expanded functionality for multiple engine systems with the addition of a secondary engine of 'Self'. --- src/provider/mod.rs | 22 +++++++++++++++++++++- src/traits/mod.rs | 9 +++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/provider/mod.rs b/src/provider/mod.rs index c52b517fd..5e4724485 100644 --- a/src/provider/mod.rs +++ b/src/provider/mod.rs @@ -28,7 +28,7 @@ use crate::{ poseidon::{PoseidonRO, PoseidonROCircuit}, secp_secq::{secp256k1, secq256k1}, }, - traits::Engine, + traits::{CurveCycleEquipped, Engine}, }; use halo2curves::bn256::Bn256; use pasta_curves::{pallas, vesta}; @@ -90,6 +90,18 @@ impl Engine for Bn256EngineKZG { type CE = KZGCommitmentEngine; } +impl CurveCycleEquipped for Bn256Engine { + type Secondary = GrumpkinEngine; +} + +impl CurveCycleEquipped for Bn256EngineKZG { + type Secondary = GrumpkinEngine; +} + +impl CurveCycleEquipped for Bn256EngineZM { + type Secondary = GrumpkinEngine; +} + /// An implementation of the Nova `Engine` trait with Secp256k1 curve and Pedersen commitment scheme #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct Secp256k1Engine; @@ -118,6 +130,10 @@ impl Engine for Secq256k1Engine { type CE = PedersenCommitmentEngine; } +impl CurveCycleEquipped for Secp256k1Engine { + type Secondary = Secq256k1Engine; +} + /// An implementation of the Nova `Engine` trait with Pallas curve and Pedersen commitment scheme #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct PallasEngine; @@ -146,6 +162,10 @@ impl Engine for VestaEngine { type CE = PedersenCommitmentEngine; } +impl CurveCycleEquipped for PallasEngine { + type Secondary = VestaEngine; +} + #[cfg(test)] mod tests { use crate::provider::{ diff --git a/src/traits/mod.rs b/src/traits/mod.rs index fb48ebdcf..8cf9c66ca 100644 --- a/src/traits/mod.rs +++ b/src/traits/mod.rs @@ -55,6 +55,15 @@ pub trait Engine: Clone + Copy + Debug + Send + Sync + Sized + Eq + PartialEq { type CE: CommitmentEngineTrait; } +/// This is a convenience trait to pair engines which fields are in a curve cycle relationship +pub trait CurveCycleEquipped: Engine { + /// The secondary Engine of `Self` + type Secondary: Engine::Scalar, Scalar = ::Base>; +} + +/// Convenience projection to the Secondary Engine of a CurveCycleEquipped +pub type SecEngine = <::Secondary as Engine>::Scalar; + /// A helper trait to absorb different objects in RO pub trait AbsorbInROTrait { /// Absorbs the value in the provided RO From 8bb8989cab0d3d796d3f3b9b0def40500425340d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Garillot?= Date: Fri, 2 Feb 2024 14:15:15 -0500 Subject: [PATCH 3/8] refactor: Refactor SNARK parameters and update related functions - Refactored the bench, examples, and source files to simplify `PublicParams`, `CompressedSNARK`, and `RecursiveSNARK` setup by removing the redundant secondary engine type and circuit parameters. - Modified all functions, methods, and type definitions that depend on the `PublicParams`, `CompressedSNARK`, and `RecursiveSNARK` setup to reflect these changes. - Removed all (default) instances of `TrivialCircuit` parameters from the codebase, simplifying the setup process. - Renamed `SecEngine` to `SecEng`, - Adjustments were made to functions to reflect the updated parameters without changing the functionality or behavior of the code. --- benches/compressed-snark.rs | 16 +- benches/compute-digest.rs | 2 +- benches/recursive-snark.rs | 4 +- benches/sha256.rs | 2 +- examples/and.rs | 28 +-- examples/minroot.rs | 41 ++- src/lib.rs | 482 ++++++++++++++++-------------------- src/traits/mod.rs | 2 +- 8 files changed, 253 insertions(+), 324 deletions(-) diff --git a/benches/compressed-snark.rs b/benches/compressed-snark.rs index c6ec1b08a..98f1288b8 100644 --- a/benches/compressed-snark.rs +++ b/benches/compressed-snark.rs @@ -69,19 +69,15 @@ fn bench_compressed_snark_internal, S2: RelaxedR1C let c_secondary = TrivialCircuit::default(); // Produce public parameters - let pp = PublicParams::::setup( - &c_primary, - &c_secondary, - &*S1::ck_floor(), - &*S2::ck_floor(), - ); + let pp = + PublicParams::::setup(&c_primary, &c_secondary, &*S1::ck_floor(), &*S2::ck_floor()); // Produce prover and verifier keys for CompressedSNARK - let (pk, vk) = CompressedSNARK::<_, _, S1, _, _, S2>::setup(&pp).unwrap(); + let (pk, vk) = CompressedSNARK::<_, _, S1, _, S2>::setup(&pp).unwrap(); // produce a recursive SNARK let num_steps = 3; - let mut recursive_snark: RecursiveSNARK = RecursiveSNARK::new( + let mut recursive_snark: RecursiveSNARK = RecursiveSNARK::new( &pp, &c_primary, &c_secondary, @@ -113,7 +109,7 @@ fn bench_compressed_snark_internal, S2: RelaxedR1C // Bench time to produce a compressed SNARK group.bench_function(bench_params.bench_id("Prove"), |b| { b.iter(|| { - assert!(CompressedSNARK::<_, _, S1, _, _, S2>::prove( + assert!(CompressedSNARK::<_, _, S1, _, S2>::prove( black_box(&pp), black_box(&pk), black_box(&recursive_snark) @@ -121,7 +117,7 @@ fn bench_compressed_snark_internal, S2: RelaxedR1C .is_ok()); }) }); - let res = CompressedSNARK::<_, _, S1, _, _, S2>::prove(&pp, &pk, &recursive_snark); + let res = CompressedSNARK::<_, _, S1, _, S2>::prove(&pp, &pk, &recursive_snark); assert!(res.is_ok()); let compressed_snark = res.unwrap(); diff --git a/benches/compute-digest.rs b/benches/compute-digest.rs index fe390e5a0..e9bf01ef8 100644 --- a/benches/compute-digest.rs +++ b/benches/compute-digest.rs @@ -29,7 +29,7 @@ criterion_main!(compute_digest); fn bench_compute_digest(c: &mut Criterion) { c.bench_function("compute_digest", |b| { b.iter(|| { - PublicParams::::setup( + PublicParams::::setup( black_box(&C1::new(10)), black_box(&C2::default()), black_box(&*default_ck_hint()), diff --git a/benches/recursive-snark.rs b/benches/recursive-snark.rs index 323de02bb..b3b954ef0 100644 --- a/benches/recursive-snark.rs +++ b/benches/recursive-snark.rs @@ -73,7 +73,7 @@ fn bench_recursive_snark(c: &mut Criterion) { let c_secondary = TrivialCircuit::default(); // Produce public parameters - let pp = PublicParams::::setup( + let pp = PublicParams::::setup( &c_primary, &c_secondary, &*default_ck_hint(), @@ -85,7 +85,7 @@ fn bench_recursive_snark(c: &mut Criterion) { // the first step is cheaper than other steps owing to the presence of // a lot of zeros in the satisfying assignment let num_warmup_steps = 10; - let mut recursive_snark: RecursiveSNARK = RecursiveSNARK::new( + let mut recursive_snark: RecursiveSNARK = RecursiveSNARK::new( &pp, &c_primary, &c_secondary, diff --git a/benches/sha256.rs b/benches/sha256.rs index 2209566c9..16b7aa71c 100644 --- a/benches/sha256.rs +++ b/benches/sha256.rs @@ -158,7 +158,7 @@ fn bench_recursive_snark(c: &mut Criterion) { // Produce public parameters let ttc = TrivialCircuit::default(); - let pp = PublicParams::::setup( + let pp = PublicParams::::setup( &circuit_primary, &ttc, &*default_ck_hint(), diff --git a/examples/and.rs b/examples/and.rs index b71aaf594..d168d37d4 100644 --- a/examples/and.rs +++ b/examples/and.rs @@ -222,12 +222,7 @@ fn main() { // produce public parameters let start = Instant::now(); println!("Producing public parameters..."); - let pp = PublicParams::< - E1, - AndCircuit<::GE>, - E2, - TrivialCircuit<::Scalar>, - >::setup( + let pp = PublicParams::::GE>>::setup( &circuit_primary, &circuit_secondary, &*S1::ck_floor(), @@ -263,15 +258,14 @@ fn main() { // produce a recursive SNARK println!("Generating a RecursiveSNARK..."); - let mut recursive_snark: RecursiveSNARK = - RecursiveSNARK::::new( - &pp, - &circuits[0], - &circuit_secondary, - &[::Scalar::zero()], - &[::Scalar::zero()], - ) - .unwrap(); + let mut recursive_snark: RecursiveSNARK = RecursiveSNARK::::new( + &pp, + &circuits[0], + &circuit_secondary, + &[::Scalar::zero()], + &[::Scalar::zero()], + ) + .unwrap(); let start = Instant::now(); for circuit_primary in circuits.iter() { @@ -297,11 +291,11 @@ fn main() { // produce a compressed SNARK println!("Generating a CompressedSNARK using Spartan with multilinear KZG..."); - let (pk, vk) = CompressedSNARK::<_, _, S1, _, _, S2>::setup(&pp).unwrap(); + let (pk, vk) = CompressedSNARK::<_, _, S1, _, S2>::setup(&pp).unwrap(); let start = Instant::now(); - let res = CompressedSNARK::<_, _, S1, _, _, S2>::prove(&pp, &pk, &recursive_snark); + let res = CompressedSNARK::<_, _, S1, _, S2>::prove(&pp, &pk, &recursive_snark); println!( "CompressedSNARK::prove: {:?}, took {:?}", res.is_ok(), diff --git a/examples/minroot.rs b/examples/minroot.rs index 5a737cd3b..c35d120e4 100644 --- a/examples/minroot.rs +++ b/examples/minroot.rs @@ -221,12 +221,7 @@ fn main() { // produce public parameters let start = Instant::now(); println!("Producing public parameters..."); - let pp = PublicParams::< - E1, - MinRootCircuit<::GE>, - E2, - TrivialCircuit<::Scalar>, - >::setup( + let pp = PublicParams::::GE>>::setup( &circuit_primary, &circuit_secondary, &*S1::ck_floor(), @@ -272,16 +267,9 @@ fn main() { let mut reader = std::io::BufReader::new(file); let mut bytes = Vec::new(); reader.read_to_end(&mut bytes).unwrap(); - if let Some((result, remaining)) = unsafe { - decode::< - FlatPublicParams< - E1, - E2, - MinRootCircuit<::GE>, - TrivialCircuit<::Scalar>, - >, - >(&mut bytes) - } { + if let Some((result, remaining)) = + unsafe { decode::::GE>>>(&mut bytes) } + { let result_pp = PublicParams::from(result.clone()); assert!(result_pp == pp, "decoded parameters not equal to original!"); assert!(remaining.is_empty()); @@ -316,15 +304,14 @@ fn main() { type C2 = TrivialCircuit<::Scalar>; // produce a recursive SNARK println!("Generating a RecursiveSNARK..."); - let mut recursive_snark: RecursiveSNARK = - RecursiveSNARK::::new( - &pp, - &minroot_circuits[0], - &circuit_secondary, - &z0_primary, - &z0_secondary, - ) - .unwrap(); + let mut recursive_snark: RecursiveSNARK = RecursiveSNARK::::new( + &pp, + &minroot_circuits[0], + &circuit_secondary, + &z0_primary, + &z0_secondary, + ) + .unwrap(); for (i, circuit_primary) in minroot_circuits.iter().enumerate() { let start = Instant::now(); @@ -351,7 +338,7 @@ fn main() { // produce a compressed SNARK println!("Generating a CompressedSNARK using Spartan with multilinear KZG..."); - let (pk, vk) = CompressedSNARK::<_, _, S1, _, _, S2>::setup(&pp).unwrap(); + let (pk, vk) = CompressedSNARK::<_, _, S1, _, S2>::setup(&pp).unwrap(); let start = Instant::now(); type E1 = Bn256EngineKZG; @@ -361,7 +348,7 @@ fn main() { type S1 = arecibo::spartan::ppsnark::RelaxedR1CSSNARK; // non-preprocessing SNARK type S2 = arecibo::spartan::ppsnark::RelaxedR1CSSNARK; // non-preprocessing SNARK - let res = CompressedSNARK::<_, _, S1, _, _, S2>::prove(&pp, &pk, &recursive_snark); + let res = CompressedSNARK::<_, _, S1, _, S2>::prove(&pp, &pk, &recursive_snark); println!( "CompressedSNARK::prove: {:?}, took {:?}", res.is_ok(), diff --git a/src/lib.rs b/src/lib.rs index 4f58d3d12..9e4c57d56 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,6 +28,8 @@ pub mod traits; pub mod supernova; use once_cell::sync::OnceCell; +use traits::circuit::TrivialCircuit; +use traits::{CurveCycleEquipped, SecEng}; use crate::digest::{DigestComputer, SimpleDigestible}; use crate::{ @@ -90,27 +92,26 @@ impl R1CSWithArity { /// A type that holds public parameters of Nova #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(bound = "")] -pub struct PublicParams +pub struct PublicParams as Engine>::Scalar>> where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - C1: StepCircuit, - C2: StepCircuit, + E: CurveCycleEquipped, + C1: StepCircuit, + C2: StepCircuit< as Engine>::Scalar>, { 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, + 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, + digest: OnceCell, _p: PhantomData<(C1, C2)>, } @@ -123,46 +124,37 @@ where #[serde(bound = "")] #[abomonation_bounds( where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - C1: StepCircuit, - C2: StepCircuit, + E1: CurveCycleEquipped, ::Repr: Abomonation, - ::Repr: Abomonation, + < as Engine>::Scalar as PrimeField>::Repr: Abomonation, )] -pub struct FlatPublicParams +pub struct FlatPublicParams where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - C1: StepCircuit, - C2: StepCircuit, + E1: CurveCycleEquipped, { F_arity_primary: usize, F_arity_secondary: usize, ro_consts_primary: ROConstants, - ro_consts_circuit_primary: ROConstantsCircuit, + ro_consts_circuit_primary: ROConstantsCircuit>, ck_primary: CommitmentKey, circuit_shape_primary: R1CSWithArity, - ro_consts_secondary: ROConstants, + ro_consts_secondary: ROConstants>, ro_consts_circuit_secondary: ROConstantsCircuit, - ck_secondary: CommitmentKey, - circuit_shape_secondary: R1CSWithArity, + 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 +impl TryFrom> for FlatPublicParams where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - C1: StepCircuit, - C2: StepCircuit, + E1: CurveCycleEquipped, { type Error = &'static str; - fn try_from(value: PublicParams) -> Result { + 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 = @@ -186,14 +178,11 @@ where } #[cfg(feature = "abomonate")] -impl From> for PublicParams +impl From> for PublicParams where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - C1: StepCircuit, - C2: StepCircuit, + E1: CurveCycleEquipped, { - fn from(value: FlatPublicParams) -> Self { + fn from(value: FlatPublicParams) -> Self { Self { F_arity_primary: value.F_arity_primary, F_arity_secondary: value.F_arity_secondary, @@ -213,21 +202,19 @@ where } } -impl SimpleDigestible for PublicParams +impl SimpleDigestible for PublicParams where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E1: CurveCycleEquipped, C1: StepCircuit, - C2: StepCircuit, + C2: StepCircuit< as Engine>::Scalar>, { } -impl PublicParams +impl PublicParams where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E1: CurveCycleEquipped, C1: StepCircuit, - C2: StepCircuit, + C2: StepCircuit< as Engine>::Scalar>, { /// Set up builder to create `PublicParams` for a pair of circuits `C1` and `C2`. /// @@ -276,7 +263,7 @@ where c_primary: &C1, c_secondary: &C2, ck_hint1: &CommitmentKeyHint, - ck_hint2: &CommitmentKeyHint, + ck_hint2: &CommitmentKeyHint>, ) -> Self { let augmented_circuit_params_primary = NovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, true); @@ -284,17 +271,18 @@ where NovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, false); let ro_consts_primary: ROConstants = ROConstants::::default(); - let ro_consts_secondary: ROConstants = ROConstants::::default(); + let ro_consts_secondary: ROConstants> = ROConstants::>::default(); let F_arity_primary = c_primary.arity(); let F_arity_secondary = c_secondary.arity(); // ro_consts_circuit_primary are parameterized by E2 because the type alias uses E2::Base = E1::Scalar - let ro_consts_circuit_primary: ROConstantsCircuit = ROConstantsCircuit::::default(); + let ro_consts_circuit_primary: ROConstantsCircuit> = + ROConstantsCircuit::>::default(); let ro_consts_circuit_secondary: ROConstantsCircuit = ROConstantsCircuit::::default(); // Initialize ck for the primary - let circuit_primary: NovaAugmentedCircuit<'_, E2, C1> = NovaAugmentedCircuit::new( + let circuit_primary: NovaAugmentedCircuit<'_, SecEng, C1> = NovaAugmentedCircuit::new( &augmented_circuit_params_primary, None, c_primary, @@ -313,7 +301,7 @@ where c_secondary, ro_consts_circuit_secondary.clone(), ); - let mut cs: ShapeCS = ShapeCS::new(); + let mut cs: ShapeCS> = ShapeCS::new(); let _ = circuit_secondary.synthesize(&mut cs); let (r1cs_shape_secondary, ck_secondary) = cs.r1cs_shape_and_key(ck_hint2); let ck_secondary = Arc::new(ck_secondary); @@ -381,47 +369,45 @@ pub struct ResourceBuffer { /// A SNARK that proves the correct execution of an incremental computation #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(bound = "")] -pub struct RecursiveSNARK +pub struct RecursiveSNARK as Engine>::Scalar>> where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E1: CurveCycleEquipped, C1: StepCircuit, - C2: StepCircuit, + C2: StepCircuit< as Engine>::Scalar>, { z0_primary: Vec, - z0_secondary: Vec, + z0_secondary: Vec< as Engine>::Scalar>, r_W_primary: RelaxedR1CSWitness, r_U_primary: RelaxedR1CSInstance, - r_W_secondary: RelaxedR1CSWitness, - r_U_secondary: RelaxedR1CSInstance, - l_w_secondary: R1CSWitness, - l_u_secondary: R1CSInstance, + r_W_secondary: RelaxedR1CSWitness>, + r_U_secondary: RelaxedR1CSInstance>, + l_w_secondary: R1CSWitness>, + l_u_secondary: R1CSInstance>, /// Buffer for memory needed by the primary fold-step buffer_primary: ResourceBuffer, /// Buffer for memory needed by the secondary fold-step - buffer_secondary: ResourceBuffer, + buffer_secondary: ResourceBuffer>, i: usize, zi_primary: Vec, - zi_secondary: Vec, + zi_secondary: Vec< as Engine>::Scalar>, _p: PhantomData<(C1, C2)>, } -impl RecursiveSNARK +impl RecursiveSNARK where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E1: CurveCycleEquipped, C1: StepCircuit, - C2: StepCircuit, + C2: StepCircuit< as Engine>::Scalar>, { /// Create new instance of recursive SNARK pub fn new( - pp: &PublicParams, + pp: &PublicParams, c_primary: &C1, c_secondary: &C2, z0_primary: &[E1::Scalar], - z0_secondary: &[E2::Scalar], + z0_secondary: &[ as Engine>::Scalar], ) -> Result { if z0_primary.len() != pp.F_arity_primary || z0_secondary.len() != pp.F_arity_secondary { return Err(NovaError::InvalidInitialInputLength); @@ -432,7 +418,7 @@ where // base case for the primary let mut cs_primary = SatisfyingAssignment::::new(); - let inputs_primary: NovaAugmentedCircuitInputs = NovaAugmentedCircuitInputs::new( + let inputs_primary: NovaAugmentedCircuitInputs> = NovaAugmentedCircuitInputs::new( scalar_as_base::(pp.digest()), E1::Scalar::ZERO, z0_primary.to_vec(), @@ -442,7 +428,7 @@ where None, ); - let circuit_primary: NovaAugmentedCircuit<'_, E2, C1> = NovaAugmentedCircuit::new( + let circuit_primary: NovaAugmentedCircuit<'_, SecEng, C1> = NovaAugmentedCircuit::new( &pp.augmented_circuit_params_primary, Some(inputs_primary), c_primary, @@ -453,10 +439,10 @@ where cs_primary.r1cs_instance_and_witness(r1cs_primary, &pp.ck_primary)?; // base case for the secondary - let mut cs_secondary = SatisfyingAssignment::::new(); + let mut cs_secondary = SatisfyingAssignment::>::new(); let inputs_secondary: NovaAugmentedCircuitInputs = NovaAugmentedCircuitInputs::new( pp.digest(), - E2::Scalar::ZERO, + as Engine>::Scalar::ZERO, z0_secondary.to_vec(), None, None, @@ -486,8 +472,9 @@ where // IVC proof for the secondary circuit let l_w_secondary = w_secondary; let l_u_secondary = u_secondary; - let r_W_secondary = RelaxedR1CSWitness::::default(r1cs_secondary); - let r_U_secondary = RelaxedR1CSInstance::::default(&pp.ck_secondary, r1cs_secondary); + let r_W_secondary = RelaxedR1CSWitness::>::default(r1cs_secondary); + 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), @@ -502,7 +489,7 @@ where let zi_secondary = zi_secondary .iter() .map(|v| v.get_value().ok_or(SynthesisError::AssignmentMissing)) - .collect::::Scalar>, _>>()?; + .collect:: as Engine>::Scalar>, _>>()?; let buffer_primary = ResourceBuffer { l_w: None, @@ -517,7 +504,7 @@ where l_u: None, ABC_Z_1: R1CSResult::default(r1cs_secondary.num_cons), ABC_Z_2: R1CSResult::default(r1cs_secondary.num_cons), - T: r1cs::default_T::(r1cs_secondary.num_cons), + T: r1cs::default_T::>(r1cs_secondary.num_cons), }; Ok(Self { @@ -544,7 +531,7 @@ where #[tracing::instrument(skip_all, name = "nova::RecursiveSNARK::prove_step")] pub fn prove_step( &mut self, - pp: &PublicParams, + pp: &PublicParams, c_primary: &C1, c_secondary: &C2, ) -> Result<(), NovaError> { @@ -578,17 +565,19 @@ where pp.circuit_shape_primary.r1cs_shape.num_io + 1, pp.circuit_shape_primary.r1cs_shape.num_vars, ); - let inputs_primary: NovaAugmentedCircuitInputs = NovaAugmentedCircuitInputs::new( + let inputs_primary: NovaAugmentedCircuitInputs> = NovaAugmentedCircuitInputs::new( scalar_as_base::(pp.digest()), E1::Scalar::from(self.i as u64), self.z0_primary.to_vec(), Some(self.zi_primary.clone()), Some(r_U_secondary_i), Some(l_u_secondary_i), - Some(Commitment::::decompress(&nifs_secondary.comm_T)?), + Some(Commitment::>::decompress( + &nifs_secondary.comm_T, + )?), ); - let circuit_primary: NovaAugmentedCircuit<'_, E2, C1> = NovaAugmentedCircuit::new( + let circuit_primary: NovaAugmentedCircuit<'_, SecEng, C1> = NovaAugmentedCircuit::new( &pp.augmented_circuit_params_primary, Some(inputs_primary), c_primary, @@ -615,13 +604,13 @@ where &mut self.buffer_primary.ABC_Z_2, )?; - let mut cs_secondary = SatisfyingAssignment::::with_capacity( + let mut cs_secondary = SatisfyingAssignment::>::with_capacity( pp.circuit_shape_secondary.r1cs_shape.num_io + 1, pp.circuit_shape_secondary.r1cs_shape.num_vars, ); let inputs_secondary: NovaAugmentedCircuitInputs = NovaAugmentedCircuitInputs::new( pp.digest(), - E2::Scalar::from(self.i as u64), + as Engine>::Scalar::from(self.i as u64), self.z0_secondary.to_vec(), Some(self.zi_secondary.clone()), Some(r_U_primary_i), @@ -649,7 +638,7 @@ where self.zi_secondary = zi_secondary .iter() .map(|v| v.get_value().ok_or(SynthesisError::AssignmentMissing)) - .collect::::Scalar>, _>>()?; + .collect:: as Engine>::Scalar>, _>>()?; self.l_u_secondary = l_u_secondary; self.l_w_secondary = l_w_secondary; @@ -662,11 +651,11 @@ where /// Verify the correctness of the `RecursiveSNARK` pub fn verify( &self, - pp: &PublicParams, + pp: &PublicParams, num_steps: usize, z0_primary: &[E1::Scalar], - z0_secondary: &[E2::Scalar], - ) -> Result<(Vec, Vec), NovaError> { + z0_secondary: &[ as Engine>::Scalar], + ) -> Result<(Vec, Vec< as Engine>::Scalar>), NovaError> { // number of steps cannot be zero let is_num_steps_zero = num_steps == 0; @@ -691,7 +680,7 @@ where // check if the output hashes in R1CS instances point to the right running instances let (hash_primary, hash_secondary) = { - let mut hasher = ::RO::new( + let mut hasher = as Engine>::RO::new( pp.ro_consts_secondary.clone(), NUM_FE_WITHOUT_IO_FOR_CRHF + 2 * pp.F_arity_primary, ); @@ -710,7 +699,7 @@ where NUM_FE_WITHOUT_IO_FOR_CRHF + 2 * pp.F_arity_secondary, ); hasher2.absorb(scalar_as_base::(pp.digest())); - hasher2.absorb(E2::Scalar::from(num_steps as u64)); + hasher2.absorb( as Engine>::Scalar::from(num_steps as u64)); for e in z0_secondary { hasher2.absorb(*e); } @@ -726,7 +715,7 @@ where }; if hash_primary != self.l_u_secondary.X[0] - || hash_secondary != scalar_as_base::(self.l_u_secondary.X[1]) + || hash_secondary != scalar_as_base::>(self.l_u_secondary.X[1]) { return Err(NovaError::ProofVerifyError); } @@ -769,7 +758,7 @@ where } /// Get the outputs after the last step of computation. - pub fn outputs(&self) -> (&[E1::Scalar], &[E2::Scalar]) { + pub fn outputs(&self) -> (&[E1::Scalar], &[ as Engine>::Scalar]) { (&self.zi_primary, &self.zi_secondary) } @@ -781,14 +770,13 @@ where /// A type that holds the prover key for `CompressedSNARK` #[derive(Clone, Debug)] -pub struct ProverKey +pub struct ProverKey where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E1: CurveCycleEquipped, C1: StepCircuit, - C2: StepCircuit, + C2: StepCircuit< as Engine>::Scalar>, S1: RelaxedR1CSSNARKTrait, - S2: RelaxedR1CSSNARKTrait, + S2: RelaxedR1CSSNARKTrait>, { pk_primary: S1::ProverKey, pk_secondary: S2::ProverKey, @@ -798,19 +786,18 @@ where /// A type that holds the verifier key for `CompressedSNARK` #[derive(Debug, Clone, Serialize)] #[serde(bound = "")] -pub struct VerifierKey +pub struct VerifierKey where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E1: CurveCycleEquipped, C1: StepCircuit, - C2: StepCircuit, + C2: StepCircuit< as Engine>::Scalar>, S1: RelaxedR1CSSNARKTrait, - S2: RelaxedR1CSSNARKTrait, + S2: RelaxedR1CSSNARKTrait>, { F_arity_primary: usize, F_arity_secondary: usize, ro_consts_primary: ROConstants, - ro_consts_secondary: ROConstants, + ro_consts_secondary: ROConstants>, pp_digest: E1::Scalar, vk_primary: S1::VerifierKey, vk_secondary: S2::VerifierKey, @@ -820,45 +807,43 @@ where /// A SNARK that proves the knowledge of a valid `RecursiveSNARK` #[derive(Debug, Serialize, Deserialize)] #[serde(bound = "")] -pub struct CompressedSNARK +pub struct CompressedSNARK where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E1: CurveCycleEquipped, C1: StepCircuit, - C2: StepCircuit, + C2: StepCircuit< as Engine>::Scalar>, S1: RelaxedR1CSSNARKTrait, - S2: RelaxedR1CSSNARKTrait, + S2: RelaxedR1CSSNARKTrait>, { r_U_primary: RelaxedR1CSInstance, r_W_snark_primary: S1, - r_U_secondary: RelaxedR1CSInstance, - l_u_secondary: R1CSInstance, - nifs_secondary: NIFS, + r_U_secondary: RelaxedR1CSInstance>, + l_u_secondary: R1CSInstance>, + nifs_secondary: NIFS>, f_W_snark_secondary: S2, zn_primary: Vec, - zn_secondary: Vec, + zn_secondary: Vec< as Engine>::Scalar>, _p: PhantomData<(C1, C2)>, } -impl CompressedSNARK +impl CompressedSNARK where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E1: CurveCycleEquipped, C1: StepCircuit, - C2: StepCircuit, + C2: StepCircuit< as Engine>::Scalar>, S1: RelaxedR1CSSNARKTrait, - S2: RelaxedR1CSSNARKTrait, + S2: RelaxedR1CSSNARKTrait>, { /// Creates prover and verifier keys for `CompressedSNARK` pub fn setup( - pp: &PublicParams, + pp: &PublicParams, ) -> Result< ( - ProverKey, - VerifierKey, + ProverKey, + VerifierKey, ), NovaError, > { @@ -891,9 +876,9 @@ where /// Create a new `CompressedSNARK` pub fn prove( - pp: &PublicParams, - pk: &ProverKey, - recursive_snark: &RecursiveSNARK, + pp: &PublicParams, + pk: &ProverKey, + recursive_snark: &RecursiveSNARK, ) -> Result { // fold the secondary circuit's instance with its running instance let (nifs_secondary, (f_U_secondary, f_W_secondary)) = NIFS::prove( @@ -948,11 +933,11 @@ where /// Verify the correctness of the `CompressedSNARK` pub fn verify( &self, - vk: &VerifierKey, + vk: &VerifierKey, num_steps: usize, z0_primary: &[E1::Scalar], - z0_secondary: &[E2::Scalar], - ) -> Result<(Vec, Vec), NovaError> { + z0_secondary: &[ as Engine>::Scalar], + ) -> Result<(Vec, Vec< as Engine>::Scalar>), NovaError> { // the number of steps cannot be zero if num_steps == 0 { return Err(NovaError::ProofVerifyError); @@ -968,7 +953,7 @@ where // check if the output hashes in R1CS instances point to the right running instances let (hash_primary, hash_secondary) = { - let mut hasher = ::RO::new( + let mut hasher = as Engine>::RO::new( vk.ro_consts_secondary.clone(), NUM_FE_WITHOUT_IO_FOR_CRHF + 2 * vk.F_arity_primary, ); @@ -987,7 +972,7 @@ where NUM_FE_WITHOUT_IO_FOR_CRHF + 2 * vk.F_arity_secondary, ); hasher2.absorb(scalar_as_base::(vk.pp_digest)); - hasher2.absorb(E2::Scalar::from(num_steps as u64)); + hasher2.absorb( as Engine>::Scalar::from(num_steps as u64)); for e in z0_secondary { hasher2.absorb(*e); } @@ -1003,7 +988,7 @@ where }; if hash_primary != self.l_u_secondary.X[0] - || hash_secondary != scalar_as_base::(self.l_u_secondary.X[1]) + || hash_secondary != scalar_as_base::>(self.l_u_secondary.X[1]) { return Err(NovaError::ProofVerifyError); } @@ -1138,22 +1123,21 @@ mod tests { fn test_pp_digest_with(circuit1: &T1, circuit2: &T2, expected: &Expect) where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E1: CurveCycleEquipped, E1::GE: DlogGroup, - E2::GE: DlogGroup, + as Engine>::GE: DlogGroup, T1: StepCircuit, - T2: StepCircuit, + T2: StepCircuit< as Engine>::Scalar>, EE1: EvaluationEngineTrait, - EE2: EvaluationEngineTrait, + EE2: EvaluationEngineTrait>, // this is due to the reliance on Abomonation ::Repr: Abomonation, - ::Repr: Abomonation, + < as Engine>::Scalar as PrimeField>::Repr: Abomonation, { // this tests public parameters with a size specifically intended for a spark-compressed SNARK let ck_hint1 = &*SPrime::::ck_floor(); - let ck_hint2 = &*SPrime::::ck_floor(); - let pp = PublicParams::::setup(circuit1, circuit2, ck_hint1, ck_hint2); + let ck_hint2 = &*SPrime::, EE2>::ck_floor(); + let pp = PublicParams::::setup(circuit1, circuit2, ck_hint1, ck_hint2); let digest_str = pp .digest() @@ -1232,19 +1216,13 @@ mod tests { fn test_ivc_trivial_with() where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E1: CurveCycleEquipped, { let test_circuit1 = TrivialCircuit::<::Scalar>::default(); - let test_circuit2 = TrivialCircuit::<::Scalar>::default(); + let test_circuit2 = TrivialCircuit::< as Engine>::Scalar>::default(); // produce public parameters - let pp = PublicParams::< - E1, - TrivialCircuit<::Scalar>, - E2, - TrivialCircuit<::Scalar>, - >::setup( + let pp = PublicParams::::Scalar>>::setup( &test_circuit1, &test_circuit2, &*default_ck_hint(), @@ -1258,7 +1236,7 @@ mod tests { &test_circuit1, &test_circuit2, &[::Scalar::ZERO], - &[::Scalar::ZERO], + &[ as Engine>::Scalar::ZERO], ) .unwrap(); @@ -1271,7 +1249,7 @@ mod tests { &pp, num_steps, &[::Scalar::ZERO], - &[::Scalar::ZERO], + &[ as Engine>::Scalar::ZERO], ); assert!(res.is_ok()); } @@ -1283,10 +1261,9 @@ mod tests { test_ivc_trivial_with::(); } - fn test_ivc_nontrivial_with() + fn test_ivc_nontrivial_with() where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E1: CurveCycleEquipped, { let circuit_primary = TrivialCircuit::default(); let circuit_secondary = CubicCircuit::default(); @@ -1295,8 +1272,7 @@ mod tests { let pp = PublicParams::< E1, TrivialCircuit<::Scalar>, - E2, - CubicCircuit<::Scalar>, + CubicCircuit< as Engine>::Scalar>, >::setup( &circuit_primary, &circuit_secondary, @@ -1310,14 +1286,13 @@ mod tests { let mut recursive_snark = RecursiveSNARK::< E1, TrivialCircuit<::Scalar>, - E2, - CubicCircuit<::Scalar>, + CubicCircuit< as Engine>::Scalar>, >::new( &pp, &circuit_primary, &circuit_secondary, &[::Scalar::ONE], - &[::Scalar::ZERO], + &[ as Engine>::Scalar::ZERO], ) .unwrap(); @@ -1330,7 +1305,7 @@ mod tests { &pp, i + 1, &[::Scalar::ONE], - &[::Scalar::ZERO], + &[ as Engine>::Scalar::ZERO], ); assert!(res.is_ok()); } @@ -1340,7 +1315,7 @@ mod tests { &pp, num_steps, &[::Scalar::ONE], - &[::Scalar::ZERO], + &[ as Engine>::Scalar::ZERO], ); assert!(res.is_ok()); @@ -1348,30 +1323,32 @@ mod tests { // sanity: check the claimed output with a direct computation of the same assert_eq!(zn_primary, vec![::Scalar::ONE]); - let mut zn_secondary_direct = vec![::Scalar::ZERO]; + let mut zn_secondary_direct = vec![ as Engine>::Scalar::ZERO]; for _i in 0..num_steps { zn_secondary_direct = circuit_secondary.clone().output(&zn_secondary_direct); } assert_eq!(zn_secondary, zn_secondary_direct); - assert_eq!(zn_secondary, vec![::Scalar::from(2460515u64)]); + assert_eq!( + zn_secondary, + vec![ as Engine>::Scalar::from(2460515u64)] + ); } #[test] fn test_ivc_nontrivial() { - test_ivc_nontrivial_with::(); - test_ivc_nontrivial_with::(); - test_ivc_nontrivial_with::(); + test_ivc_nontrivial_with::(); + test_ivc_nontrivial_with::(); + test_ivc_nontrivial_with::(); } - fn test_ivc_nontrivial_with_compression_with() + fn test_ivc_nontrivial_with_compression_with() where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E1: CurveCycleEquipped, EE1: EvaluationEngineTrait, - EE2: EvaluationEngineTrait, + EE2: EvaluationEngineTrait>, // this is due to the reliance on Abomonation ::Repr: Abomonation, - ::Repr: Abomonation, + < as Engine>::Scalar as PrimeField>::Repr: Abomonation, { let circuit_primary = TrivialCircuit::default(); let circuit_secondary = CubicCircuit::default(); @@ -1380,8 +1357,7 @@ mod tests { let pp = PublicParams::< E1, TrivialCircuit<::Scalar>, - E2, - CubicCircuit<::Scalar>, + CubicCircuit< as Engine>::Scalar>, >::setup( &circuit_primary, &circuit_secondary, @@ -1395,14 +1371,13 @@ mod tests { let mut recursive_snark = RecursiveSNARK::< E1, TrivialCircuit<::Scalar>, - E2, - CubicCircuit<::Scalar>, + CubicCircuit< as Engine>::Scalar>, >::new( &pp, &circuit_primary, &circuit_secondary, &[::Scalar::ONE], - &[::Scalar::ZERO], + &[ as Engine>::Scalar::ZERO], ) .unwrap(); @@ -1416,7 +1391,7 @@ mod tests { &pp, num_steps, &[::Scalar::ONE], - &[::Scalar::ZERO], + &[ as Engine>::Scalar::ZERO], ); assert!(res.is_ok()); @@ -1424,19 +1399,21 @@ mod tests { // sanity: check the claimed output with a direct computation of the same assert_eq!(zn_primary, vec![::Scalar::ONE]); - let mut zn_secondary_direct = vec![::Scalar::ZERO]; + let mut zn_secondary_direct = vec![ as Engine>::Scalar::ZERO]; for _i in 0..num_steps { zn_secondary_direct = circuit_secondary.clone().output(&zn_secondary_direct); } assert_eq!(zn_secondary, zn_secondary_direct); - assert_eq!(zn_secondary, vec![::Scalar::from(2460515u64)]); + assert_eq!( + zn_secondary, + vec![ as Engine>::Scalar::from(2460515u64)] + ); // produce the prover and verifier keys for compressed snark - let (pk, vk) = CompressedSNARK::<_, _, S, _, _, S>::setup(&pp).unwrap(); + let (pk, vk) = CompressedSNARK::<_, _, S, _, S<_, EE2>>::setup(&pp).unwrap(); // produce a compressed SNARK - let res = - CompressedSNARK::<_, _, S, _, _, S>::prove(&pp, &pk, &recursive_snark); + let res = CompressedSNARK::<_, _, S, _, S<_, EE2>>::prove(&pp, &pk, &recursive_snark); assert!(res.is_ok()); let compressed_snark = res.unwrap(); @@ -1445,40 +1422,33 @@ mod tests { &vk, num_steps, &[::Scalar::ONE], - &[::Scalar::ZERO], + &[ as Engine>::Scalar::ZERO], ); assert!(res.is_ok()); } #[test] fn test_ivc_nontrivial_with_compression() { - test_ivc_nontrivial_with_compression_with::, EE<_>>(); - test_ivc_nontrivial_with_compression_with::, EE<_>>(); - test_ivc_nontrivial_with_compression_with::, EE<_>>(); - test_ivc_nontrivial_with_compression_with::< - Bn256EngineZM, - GrumpkinEngine, - ZMPCS, - EE<_>, - >(); + test_ivc_nontrivial_with_compression_with::, EE<_>>(); + test_ivc_nontrivial_with_compression_with::, EE<_>>(); + test_ivc_nontrivial_with_compression_with::, EE<_>>(); + test_ivc_nontrivial_with_compression_with::, EE<_>>(); test_ivc_nontrivial_with_spark_compression_with::< Bn256EngineKZG, - GrumpkinEngine, provider::hyperkzg::EvaluationEngine, EE<_>, >(); } - fn test_ivc_nontrivial_with_spark_compression_with() + fn test_ivc_nontrivial_with_spark_compression_with() where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E1: CurveCycleEquipped, EE1: EvaluationEngineTrait, - EE2: EvaluationEngineTrait, + EE2: EvaluationEngineTrait>, // this is due to the reliance on Abomonation ::Repr: Abomonation, - ::Repr: Abomonation, + < as Engine>::Scalar as PrimeField>::Repr: Abomonation, { let circuit_primary = TrivialCircuit::default(); let circuit_secondary = CubicCircuit::default(); @@ -1487,13 +1457,12 @@ mod tests { let pp = PublicParams::< E1, TrivialCircuit<::Scalar>, - E2, - CubicCircuit<::Scalar>, + CubicCircuit< as Engine>::Scalar>, >::setup( &circuit_primary, &circuit_secondary, &*SPrime::::ck_floor(), - &*SPrime::::ck_floor(), + &*SPrime::<_, EE2>::ck_floor(), ); let num_steps = 3; @@ -1502,14 +1471,13 @@ mod tests { let mut recursive_snark = RecursiveSNARK::< E1, TrivialCircuit<::Scalar>, - E2, - CubicCircuit<::Scalar>, + CubicCircuit< as Engine>::Scalar>, >::new( &pp, &circuit_primary, &circuit_secondary, &[::Scalar::ONE], - &[::Scalar::ZERO], + &[ as Engine>::Scalar::ZERO], ) .unwrap(); @@ -1523,7 +1491,7 @@ mod tests { &pp, num_steps, &[::Scalar::ONE], - &[::Scalar::ZERO], + &[ as Engine>::Scalar::ZERO], ); assert!(res.is_ok()); @@ -1531,20 +1499,22 @@ mod tests { // sanity: check the claimed output with a direct computation of the same assert_eq!(zn_primary, vec![::Scalar::ONE]); - let mut zn_secondary_direct = vec![::Scalar::ZERO]; + let mut zn_secondary_direct = vec![ as Engine>::Scalar::ZERO]; for _i in 0..num_steps { zn_secondary_direct = CubicCircuit::default().output(&zn_secondary_direct); } assert_eq!(zn_secondary, zn_secondary_direct); - assert_eq!(zn_secondary, vec![::Scalar::from(2460515u64)]); + assert_eq!( + zn_secondary, + vec![ as Engine>::Scalar::from(2460515u64)] + ); // run the compressed snark with Spark compiler // produce the prover and verifier keys for compressed snark - let (pk, vk) = - CompressedSNARK::<_, _, SPrime, _, _, SPrime>::setup(&pp).unwrap(); + let (pk, vk) = CompressedSNARK::<_, _, SPrime, _, SPrime<_, EE2>>::setup(&pp).unwrap(); // produce a compressed SNARK - let res = CompressedSNARK::<_, _, SPrime, _, _, SPrime>::prove( + let res = CompressedSNARK::<_, _, SPrime, _, SPrime<_, EE2>>::prove( &pp, &pk, &recursive_snark, @@ -1557,34 +1527,27 @@ mod tests { &vk, num_steps, &[::Scalar::ONE], - &[::Scalar::ZERO], + &[ as Engine>::Scalar::ZERO], ); assert!(res.is_ok()); } #[test] fn test_ivc_nontrivial_with_spark_compression() { - test_ivc_nontrivial_with_spark_compression_with::, EE<_>>(); - test_ivc_nontrivial_with_spark_compression_with::, EE<_>>(); - test_ivc_nontrivial_with_spark_compression_with::, EE<_>>( - ); - test_ivc_nontrivial_with_spark_compression_with::< - Bn256EngineZM, - GrumpkinEngine, - ZMPCS, - EE<_>, - >(); + test_ivc_nontrivial_with_spark_compression_with::, EE<_>>(); + test_ivc_nontrivial_with_spark_compression_with::, EE<_>>(); + test_ivc_nontrivial_with_spark_compression_with::, EE<_>>(); + test_ivc_nontrivial_with_spark_compression_with::, EE<_>>(); } - fn test_ivc_nondet_with_compression_with() + fn test_ivc_nondet_with_compression_with() where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E1: CurveCycleEquipped, EE1: EvaluationEngineTrait, - EE2: EvaluationEngineTrait, + EE2: EvaluationEngineTrait>, // this is due to the reliance on Abomonation ::Repr: Abomonation, - ::Repr: Abomonation, + < as Engine>::Scalar as PrimeField>::Repr: Abomonation, { // y is a non-deterministic advice representing the fifth root of the input at a step. #[derive(Clone, Debug)] @@ -1650,12 +1613,7 @@ mod tests { let circuit_secondary = TrivialCircuit::default(); // produce public parameters - let pp = PublicParams::< - E1, - FifthRootCheckingCircuit<::Scalar>, - E2, - TrivialCircuit<::Scalar>, - >::setup( + let pp = PublicParams::::Scalar>>::setup( &circuit_primary, &circuit_secondary, &*default_ck_hint(), @@ -1666,22 +1624,18 @@ mod tests { // produce non-deterministic advice let (z0_primary, roots) = FifthRootCheckingCircuit::new(num_steps); - let z0_secondary = vec![::Scalar::ZERO]; + let z0_secondary = vec![ as Engine>::Scalar::ZERO]; // produce a recursive SNARK - let mut recursive_snark = RecursiveSNARK::< - E1, - FifthRootCheckingCircuit<::Scalar>, - E2, - TrivialCircuit<::Scalar>, - >::new( - &pp, - &roots[0], - &circuit_secondary, - &z0_primary, - &z0_secondary, - ) - .unwrap(); + let mut recursive_snark = + RecursiveSNARK::::Scalar>>::new( + &pp, + &roots[0], + &circuit_secondary, + &z0_primary, + &z0_secondary, + ) + .unwrap(); for circuit_primary in roots.iter().take(num_steps) { let res = recursive_snark.prove_step(&pp, circuit_primary, &circuit_secondary); @@ -1693,11 +1647,10 @@ mod tests { assert!(res.is_ok()); // produce the prover and verifier keys for compressed snark - let (pk, vk) = CompressedSNARK::<_, _, S, _, _, S>::setup(&pp).unwrap(); + let (pk, vk) = CompressedSNARK::<_, _, S, _, S<_, EE2>>::setup(&pp).unwrap(); // produce a compressed SNARK - let res = - CompressedSNARK::<_, _, S, _, _, S>::prove(&pp, &pk, &recursive_snark); + let res = CompressedSNARK::<_, _, S, _, S<_, EE2>>::prove(&pp, &pk, &recursive_snark); assert!(res.is_ok()); let compressed_snark = res.unwrap(); @@ -1708,27 +1661,24 @@ mod tests { #[test] fn test_ivc_nondet_with_compression() { - test_ivc_nondet_with_compression_with::, EE<_>>(); - test_ivc_nondet_with_compression_with::, EE<_>>(); - test_ivc_nondet_with_compression_with::, EE<_>>(); - test_ivc_nondet_with_compression_with::, EE<_>>( - ); + test_ivc_nondet_with_compression_with::, EE<_>>(); + test_ivc_nondet_with_compression_with::, EE<_>>(); + test_ivc_nondet_with_compression_with::, EE<_>>(); + test_ivc_nondet_with_compression_with::, EE<_>>(); } - fn test_ivc_base_with() + fn test_ivc_base_with() where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E1: CurveCycleEquipped, { let test_circuit1 = TrivialCircuit::<::Scalar>::default(); - let test_circuit2 = CubicCircuit::<::Scalar>::default(); + let test_circuit2 = CubicCircuit::< as Engine>::Scalar>::default(); // produce public parameters let pp = PublicParams::< E1, TrivialCircuit<::Scalar>, - E2, - CubicCircuit<::Scalar>, + CubicCircuit< as Engine>::Scalar>, >::setup( &test_circuit1, &test_circuit2, @@ -1742,14 +1692,13 @@ mod tests { let mut recursive_snark = RecursiveSNARK::< E1, TrivialCircuit<::Scalar>, - E2, - CubicCircuit<::Scalar>, + CubicCircuit< as Engine>::Scalar>, >::new( &pp, &test_circuit1, &test_circuit2, &[::Scalar::ONE], - &[::Scalar::ZERO], + &[ as Engine>::Scalar::ZERO], ) .unwrap(); @@ -1763,20 +1712,23 @@ mod tests { &pp, num_steps, &[::Scalar::ONE], - &[::Scalar::ZERO], + &[ as Engine>::Scalar::ZERO], ); assert!(res.is_ok()); let (zn_primary, zn_secondary) = res.unwrap(); assert_eq!(zn_primary, vec![::Scalar::ONE]); - assert_eq!(zn_secondary, vec![::Scalar::from(5u64)]); + assert_eq!( + zn_secondary, + vec![ as Engine>::Scalar::from(5u64)] + ); } #[test] fn test_ivc_base() { - test_ivc_base_with::(); - test_ivc_base_with::(); - test_ivc_base_with::(); + test_ivc_base_with::(); + test_ivc_base_with::(); + test_ivc_base_with::(); } } diff --git a/src/traits/mod.rs b/src/traits/mod.rs index 8cf9c66ca..ed67d0d68 100644 --- a/src/traits/mod.rs +++ b/src/traits/mod.rs @@ -62,7 +62,7 @@ pub trait CurveCycleEquipped: Engine { } /// Convenience projection to the Secondary Engine of a CurveCycleEquipped -pub type SecEngine = <::Secondary as Engine>::Scalar; +pub type SecEng = ::Secondary; /// A helper trait to absorb different objects in RO pub trait AbsorbInROTrait { From 9ab0a44b9cb1bb84170ee63cb509e953a0a368df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Garillot?= Date: Fri, 2 Feb 2024 16:07:02 -0500 Subject: [PATCH 4/8] chore: remove type boilerplate --- benches/compressed-snark.rs | 13 +-- benches/compute-digest.rs | 2 +- benches/recursive-snark.rs | 6 +- benches/sha256.rs | 5 +- examples/and.rs | 20 ++-- examples/minroot.rs | 19 ++-- src/lib.rs | 201 +++++++++++------------------------- 7 files changed, 90 insertions(+), 176 deletions(-) diff --git a/benches/compressed-snark.rs b/benches/compressed-snark.rs index 98f1288b8..b25232e2d 100644 --- a/benches/compressed-snark.rs +++ b/benches/compressed-snark.rs @@ -27,8 +27,6 @@ type S2 = arecibo::spartan::snark::RelaxedR1CSSNARK; // SNARKs with computation commitmnets type SS1 = arecibo::spartan::ppsnark::RelaxedR1CSSNARK; type SS2 = arecibo::spartan::ppsnark::RelaxedR1CSSNARK; -type C1 = NonTrivialCircuit<::Scalar>; -type C2 = TrivialCircuit<::Scalar>; // To run these benchmarks, first download `criterion` with `cargo install cargo-criterion`. // Then `cargo criterion --bench compressed-snark`. The results are located in `target/criterion/data/`. @@ -69,15 +67,14 @@ fn bench_compressed_snark_internal, S2: RelaxedR1C let c_secondary = TrivialCircuit::default(); // Produce public parameters - let pp = - PublicParams::::setup(&c_primary, &c_secondary, &*S1::ck_floor(), &*S2::ck_floor()); + let pp = PublicParams::::setup(&c_primary, &c_secondary, &*S1::ck_floor(), &*S2::ck_floor()); // Produce prover and verifier keys for CompressedSNARK - let (pk, vk) = CompressedSNARK::<_, _, S1, _, S2>::setup(&pp).unwrap(); + let (pk, vk) = CompressedSNARK::<_, S1, S2>::setup(&pp).unwrap(); // produce a recursive SNARK let num_steps = 3; - let mut recursive_snark: RecursiveSNARK = RecursiveSNARK::new( + let mut recursive_snark: RecursiveSNARK = RecursiveSNARK::new( &pp, &c_primary, &c_secondary, @@ -109,7 +106,7 @@ fn bench_compressed_snark_internal, S2: RelaxedR1C // Bench time to produce a compressed SNARK group.bench_function(bench_params.bench_id("Prove"), |b| { b.iter(|| { - assert!(CompressedSNARK::<_, _, S1, _, S2>::prove( + assert!(CompressedSNARK::<_, S1, S2>::prove( black_box(&pp), black_box(&pk), black_box(&recursive_snark) @@ -117,7 +114,7 @@ fn bench_compressed_snark_internal, S2: RelaxedR1C .is_ok()); }) }); - let res = CompressedSNARK::<_, _, S1, _, S2>::prove(&pp, &pk, &recursive_snark); + let res = CompressedSNARK::<_, S1, S2>::prove(&pp, &pk, &recursive_snark); assert!(res.is_ok()); let compressed_snark = res.unwrap(); diff --git a/benches/compute-digest.rs b/benches/compute-digest.rs index e9bf01ef8..b90a70b56 100644 --- a/benches/compute-digest.rs +++ b/benches/compute-digest.rs @@ -29,7 +29,7 @@ criterion_main!(compute_digest); fn bench_compute_digest(c: &mut Criterion) { c.bench_function("compute_digest", |b| { b.iter(|| { - PublicParams::::setup( + PublicParams::::setup( black_box(&C1::new(10)), black_box(&C2::default()), black_box(&*default_ck_hint()), diff --git a/benches/recursive-snark.rs b/benches/recursive-snark.rs index b3b954ef0..3686fcc00 100644 --- a/benches/recursive-snark.rs +++ b/benches/recursive-snark.rs @@ -19,8 +19,6 @@ use common::{noise_threshold_env, BenchParams}; type E1 = PallasEngine; type E2 = VestaEngine; -type C1 = NonTrivialCircuit<::Scalar>; -type C2 = TrivialCircuit<::Scalar>; // To run these benchmarks, first download `criterion` with `cargo install cargo-criterion`. // Then `cargo criterion --bench recursive-snark`. The results are located in `target/criterion/data/`. @@ -73,7 +71,7 @@ fn bench_recursive_snark(c: &mut Criterion) { let c_secondary = TrivialCircuit::default(); // Produce public parameters - let pp = PublicParams::::setup( + let pp = PublicParams::::setup( &c_primary, &c_secondary, &*default_ck_hint(), @@ -85,7 +83,7 @@ fn bench_recursive_snark(c: &mut Criterion) { // the first step is cheaper than other steps owing to the presence of // a lot of zeros in the satisfying assignment let num_warmup_steps = 10; - let mut recursive_snark: RecursiveSNARK = RecursiveSNARK::new( + let mut recursive_snark: RecursiveSNARK = RecursiveSNARK::new( &pp, &c_primary, &c_secondary, diff --git a/benches/sha256.rs b/benches/sha256.rs index 16b7aa71c..8ce83ac28 100644 --- a/benches/sha256.rs +++ b/benches/sha256.rs @@ -122,9 +122,6 @@ impl StepCircuit for Sha256Circuit< } } -type C1 = Sha256Circuit<::Scalar>; -type C2 = TrivialCircuit<::Scalar>; - criterion_group! { name = recursive_snark; config = Criterion::default().warm_up_time(Duration::from_millis(3000)); @@ -158,7 +155,7 @@ fn bench_recursive_snark(c: &mut Criterion) { // Produce public parameters let ttc = TrivialCircuit::default(); - let pp = PublicParams::::setup( + let pp = PublicParams::::setup( &circuit_primary, &ttc, &*default_ck_hint(), diff --git a/examples/and.rs b/examples/and.rs index d168d37d4..4622ddd0c 100644 --- a/examples/and.rs +++ b/examples/and.rs @@ -208,11 +208,14 @@ fn main() { println!("Nova-based 64-bit bitwise AND example"); println!("========================================================="); + type C1 = AndCircuit<::GE>; + type C2 = TrivialCircuit<::Scalar>; + let num_steps = 32; for num_ops_per_step in [1024, 2048, 4096, 8192, 16384, 32768, 65536] { // number of instances of AND per Nova's recursive step - let circuit_primary = AndCircuit::new(num_ops_per_step); - let circuit_secondary = TrivialCircuit::default(); + let circuit_primary = C1::new(num_ops_per_step); + let circuit_secondary = C2::default(); println!( "Proving {} AND ops ({num_ops_per_step} instances per step and {num_steps} steps)", @@ -222,7 +225,7 @@ fn main() { // produce public parameters let start = Instant::now(); println!("Producing public parameters..."); - let pp = PublicParams::::GE>>::setup( + let pp = PublicParams::::setup( &circuit_primary, &circuit_secondary, &*S1::ck_floor(), @@ -250,15 +253,12 @@ fn main() { // produce non-deterministic advice let circuits = (0..num_steps) - .map(|_| AndCircuit::new(num_ops_per_step)) + .map(|_| C1::new(num_ops_per_step)) .collect::>(); - type C1 = AndCircuit<::GE>; - type C2 = TrivialCircuit<::Scalar>; - // produce a recursive SNARK println!("Generating a RecursiveSNARK..."); - let mut recursive_snark: RecursiveSNARK = RecursiveSNARK::::new( + let mut recursive_snark: RecursiveSNARK = RecursiveSNARK::::new( &pp, &circuits[0], &circuit_secondary, @@ -291,11 +291,11 @@ fn main() { // produce a compressed SNARK println!("Generating a CompressedSNARK using Spartan with multilinear KZG..."); - let (pk, vk) = CompressedSNARK::<_, _, S1, _, S2>::setup(&pp).unwrap(); + let (pk, vk) = CompressedSNARK::<_, S1, S2>::setup(&pp).unwrap(); let start = Instant::now(); - let res = CompressedSNARK::<_, _, S1, _, S2>::prove(&pp, &pk, &recursive_snark); + let res = CompressedSNARK::<_, S1, S2>::prove(&pp, &pk, &recursive_snark); println!( "CompressedSNARK::prove: {:?}, took {:?}", res.is_ok(), diff --git a/examples/minroot.rs b/examples/minroot.rs index c35d120e4..144b531cb 100644 --- a/examples/minroot.rs +++ b/examples/minroot.rs @@ -195,6 +195,7 @@ fn main() { .with(EnvFilter::from_default_env()) .with(TeXRayLayer::new()); tracing::subscriber::set_global_default(subscriber).unwrap(); + type C1 = MinRootCircuit<::GE>; println!("Nova-based VDF with MinRoot delay function"); println!("========================================================="); @@ -202,7 +203,7 @@ fn main() { let num_steps = 10; for num_iters_per_step in [1024, 2048, 4096, 8192, 16384, 32768, 65536] { // number of iterations of MinRoot per Nova's recursive step - let circuit_primary = MinRootCircuit { + let circuit_primary = C1 { seq: vec![ MinRootIteration { x_i: ::Scalar::zero(), @@ -221,7 +222,7 @@ fn main() { // produce public parameters let start = Instant::now(); println!("Producing public parameters..."); - let pp = PublicParams::::GE>>::setup( + let pp = PublicParams::::setup( &circuit_primary, &circuit_secondary, &*S1::ck_floor(), @@ -267,9 +268,7 @@ fn main() { let mut reader = std::io::BufReader::new(file); let mut bytes = Vec::new(); reader.read_to_end(&mut bytes).unwrap(); - if let Some((result, remaining)) = - unsafe { decode::::GE>>>(&mut bytes) } - { + if let Some((result, remaining)) = unsafe { decode::>(&mut bytes) } { let result_pp = PublicParams::from(result.clone()); assert!(result_pp == pp, "decoded parameters not equal to original!"); assert!(remaining.is_empty()); @@ -286,7 +285,7 @@ fn main() { &::Scalar::one(), ); let minroot_circuits = (0..num_steps) - .map(|i| MinRootCircuit { + .map(|i| C1 { seq: (0..num_iters_per_step) .map(|j| MinRootIteration { x_i: minroot_iterations[i * num_iters_per_step + j].x_i, @@ -300,11 +299,9 @@ fn main() { let z0_secondary = vec![::Scalar::zero()]; - type C1 = MinRootCircuit<::GE>; - type C2 = TrivialCircuit<::Scalar>; // produce a recursive SNARK println!("Generating a RecursiveSNARK..."); - let mut recursive_snark: RecursiveSNARK = RecursiveSNARK::::new( + let mut recursive_snark = RecursiveSNARK::::new( &pp, &minroot_circuits[0], &circuit_secondary, @@ -338,7 +335,7 @@ fn main() { // produce a compressed SNARK println!("Generating a CompressedSNARK using Spartan with multilinear KZG..."); - let (pk, vk) = CompressedSNARK::<_, _, S1, _, S2>::setup(&pp).unwrap(); + let (pk, vk) = CompressedSNARK::<_, S1, S2>::setup(&pp).unwrap(); let start = Instant::now(); type E1 = Bn256EngineKZG; @@ -348,7 +345,7 @@ fn main() { type S1 = arecibo::spartan::ppsnark::RelaxedR1CSSNARK; // non-preprocessing SNARK type S2 = arecibo::spartan::ppsnark::RelaxedR1CSSNARK; // non-preprocessing SNARK - let res = CompressedSNARK::<_, _, S1, _, S2>::prove(&pp, &pk, &recursive_snark); + let res = CompressedSNARK::<_, S1, S2>::prove(&pp, &pk, &recursive_snark); println!( "CompressedSNARK::prove: {:?}, took {:?}", res.is_ok(), diff --git a/src/lib.rs b/src/lib.rs index 9e4c57d56..19b2547df 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,7 +28,6 @@ pub mod traits; pub mod supernova; use once_cell::sync::OnceCell; -use traits::circuit::TrivialCircuit; use traits::{CurveCycleEquipped, SecEng}; use crate::digest::{DigestComputer, SimpleDigestible}; @@ -45,7 +44,6 @@ use abomonation_derive::Abomonation; use bellpepper_core::{ConstraintSystem, SynthesisError}; use circuit::{NovaAugmentedCircuit, NovaAugmentedCircuitInputs, NovaAugmentedCircuitParams}; use constants::{BN_LIMB_WIDTH, BN_N_LIMBS, NUM_FE_WITHOUT_IO_FOR_CRHF, NUM_HASH_BITS}; -use core::marker::PhantomData; use errors::NovaError; use ff::{Field, PrimeField}; use gadgets::utils::scalar_as_base; @@ -92,11 +90,9 @@ impl R1CSWithArity { /// A type that holds public parameters of Nova #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(bound = "")] -pub struct PublicParams as Engine>::Scalar>> +pub struct PublicParams where E: CurveCycleEquipped, - C1: StepCircuit, - C2: StepCircuit< as Engine>::Scalar>, { F_arity_primary: usize, F_arity_secondary: usize, @@ -112,7 +108,6 @@ where augmented_circuit_params_secondary: NovaAugmentedCircuitParams, #[serde(skip, default = "OnceCell::new")] digest: OnceCell, - _p: PhantomData<(C1, C2)>, } // Ensure to include necessary crates and features in your Cargo.toml @@ -202,19 +197,11 @@ where } } -impl SimpleDigestible for PublicParams -where - E1: CurveCycleEquipped, - C1: StepCircuit, - C2: StepCircuit< as Engine>::Scalar>, -{ -} +impl SimpleDigestible for PublicParams where E1: CurveCycleEquipped {} -impl PublicParams +impl PublicParams where E1: CurveCycleEquipped, - C1: StepCircuit, - C2: StepCircuit< as Engine>::Scalar>, { /// Set up builder to create `PublicParams` for a pair of circuits `C1` and `C2`. /// @@ -259,7 +246,7 @@ where /// /// let pp = PublicParams::setup(&circuit1, &circuit2, ck_hint1, ck_hint2); /// ``` - pub fn setup( + pub fn setup, C2: StepCircuit< as Engine>::Scalar>>( c_primary: &C1, c_secondary: &C2, ck_hint1: &CommitmentKeyHint, @@ -321,7 +308,6 @@ where augmented_circuit_params_primary, augmented_circuit_params_secondary, digest: OnceCell::new(), - _p: Default::default(), } } @@ -369,11 +355,9 @@ pub struct ResourceBuffer { /// A SNARK that proves the correct execution of an incremental computation #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(bound = "")] -pub struct RecursiveSNARK as Engine>::Scalar>> +pub struct RecursiveSNARK where E1: CurveCycleEquipped, - C1: StepCircuit, - C2: StepCircuit< as Engine>::Scalar>, { z0_primary: Vec, z0_secondary: Vec< as Engine>::Scalar>, @@ -392,18 +376,15 @@ where i: usize, zi_primary: Vec, zi_secondary: Vec< as Engine>::Scalar>, - _p: PhantomData<(C1, C2)>, } -impl RecursiveSNARK +impl RecursiveSNARK where E1: CurveCycleEquipped, - C1: StepCircuit, - C2: StepCircuit< as Engine>::Scalar>, { /// Create new instance of recursive SNARK - pub fn new( - pp: &PublicParams, + pub fn new, C2: StepCircuit< as Engine>::Scalar>>( + pp: &PublicParams, c_primary: &C1, c_secondary: &C2, z0_primary: &[E1::Scalar], @@ -522,16 +503,18 @@ where i: 0, zi_primary, zi_secondary, - _p: Default::default(), }) } /// Create a new `RecursiveSNARK` (or updates the provided `RecursiveSNARK`) /// by executing a step of the incremental computation #[tracing::instrument(skip_all, name = "nova::RecursiveSNARK::prove_step")] - pub fn prove_step( + pub fn prove_step< + C1: StepCircuit, + C2: StepCircuit< as Engine>::Scalar>, + >( &mut self, - pp: &PublicParams, + pp: &PublicParams, c_primary: &C1, c_secondary: &C2, ) -> Result<(), NovaError> { @@ -651,7 +634,7 @@ where /// Verify the correctness of the `RecursiveSNARK` pub fn verify( &self, - pp: &PublicParams, + pp: &PublicParams, num_steps: usize, z0_primary: &[E1::Scalar], z0_secondary: &[ as Engine>::Scalar], @@ -770,27 +753,22 @@ where /// A type that holds the prover key for `CompressedSNARK` #[derive(Clone, Debug)] -pub struct ProverKey +pub struct ProverKey where E1: CurveCycleEquipped, - C1: StepCircuit, - C2: StepCircuit< as Engine>::Scalar>, S1: RelaxedR1CSSNARKTrait, S2: RelaxedR1CSSNARKTrait>, { pk_primary: S1::ProverKey, pk_secondary: S2::ProverKey, - _p: PhantomData<(C1, C2)>, } /// A type that holds the verifier key for `CompressedSNARK` #[derive(Debug, Clone, Serialize)] #[serde(bound = "")] -pub struct VerifierKey +pub struct VerifierKey where E1: CurveCycleEquipped, - C1: StepCircuit, - C2: StepCircuit< as Engine>::Scalar>, S1: RelaxedR1CSSNARKTrait, S2: RelaxedR1CSSNARKTrait>, { @@ -801,17 +779,14 @@ where pp_digest: E1::Scalar, vk_primary: S1::VerifierKey, vk_secondary: S2::VerifierKey, - _p: PhantomData<(C1, C2)>, } /// A SNARK that proves the knowledge of a valid `RecursiveSNARK` #[derive(Debug, Serialize, Deserialize)] #[serde(bound = "")] -pub struct CompressedSNARK +pub struct CompressedSNARK where E1: CurveCycleEquipped, - C1: StepCircuit, - C2: StepCircuit< as Engine>::Scalar>, S1: RelaxedR1CSSNARKTrait, S2: RelaxedR1CSSNARKTrait>, { @@ -825,28 +800,18 @@ where zn_primary: Vec, zn_secondary: Vec< as Engine>::Scalar>, - - _p: PhantomData<(C1, C2)>, } -impl CompressedSNARK +impl CompressedSNARK where E1: CurveCycleEquipped, - C1: StepCircuit, - C2: StepCircuit< as Engine>::Scalar>, S1: RelaxedR1CSSNARKTrait, S2: RelaxedR1CSSNARKTrait>, { /// Creates prover and verifier keys for `CompressedSNARK` pub fn setup( - pp: &PublicParams, - ) -> Result< - ( - ProverKey, - VerifierKey, - ), - NovaError, - > { + pp: &PublicParams, + ) -> Result<(ProverKey, VerifierKey), NovaError> { let (pk_primary, vk_primary) = S1::setup(pp.ck_primary.clone(), &pp.circuit_shape_primary.r1cs_shape)?; let (pk_secondary, vk_secondary) = S2::setup( @@ -857,7 +822,6 @@ where let pk = ProverKey { pk_primary, pk_secondary, - _p: Default::default(), }; let vk = VerifierKey { @@ -868,7 +832,6 @@ where pp_digest: pp.digest(), vk_primary, vk_secondary, - _p: Default::default(), }; Ok((pk, vk)) @@ -876,9 +839,9 @@ where /// Create a new `CompressedSNARK` pub fn prove( - pp: &PublicParams, - pk: &ProverKey, - recursive_snark: &RecursiveSNARK, + pp: &PublicParams, + pk: &ProverKey, + recursive_snark: &RecursiveSNARK, ) -> Result { // fold the secondary circuit's instance with its running instance let (nifs_secondary, (f_U_secondary, f_W_secondary)) = NIFS::prove( @@ -925,15 +888,13 @@ where zn_primary: recursive_snark.zi_primary.clone(), zn_secondary: recursive_snark.zi_secondary.clone(), - - _p: Default::default(), }) } /// Verify the correctness of the `CompressedSNARK` pub fn verify( &self, - vk: &VerifierKey, + vk: &VerifierKey, num_steps: usize, z0_primary: &[E1::Scalar], z0_secondary: &[ as Engine>::Scalar], @@ -1121,7 +1082,7 @@ mod tests { } } - fn test_pp_digest_with(circuit1: &T1, circuit2: &T2, expected: &Expect) + fn test_pp_digest_with(circuit1: &T1, circuit2: &T2, expected: &Expect) where E1: CurveCycleEquipped, E1::GE: DlogGroup, @@ -1137,7 +1098,7 @@ mod tests { // this tests public parameters with a size specifically intended for a spark-compressed SNARK let ck_hint1 = &*SPrime::::ck_floor(); let ck_hint2 = &*SPrime::, EE2>::ck_floor(); - let pp = PublicParams::::setup(circuit1, circuit2, ck_hint1, ck_hint2); + let pp = PublicParams::::setup(circuit1, circuit2, ck_hint1, ck_hint2); let digest_str = pp .digest() @@ -1158,13 +1119,13 @@ mod tests { let trivial_circuit2 = TrivialCircuit::<::Scalar>::default(); let cubic_circuit1 = CubicCircuit::<::Scalar>::default(); - test_pp_digest_with::, EE<_>>( + test_pp_digest_with::, EE<_>>( &trivial_circuit1, &trivial_circuit2, &expect!["492fd902cd7174159bc9a6f827d92eb54ff25efa9d0673dffdb0efd02995df01"], ); - test_pp_digest_with::, EE<_>>( + test_pp_digest_with::, EE<_>>( &cubic_circuit1, &trivial_circuit2, &expect!["9b0701d9422658e3f74a85ab3e485c06f3ecca9c2b1800aab80004034d754f01"], @@ -1177,22 +1138,22 @@ mod tests { // These tests should not need be different on the "asm" feature for bn256. // See https://github.com/privacy-scaling-explorations/halo2curves/issues/100 for why they are - closing the issue there // should eliminate the discrepancy here. - test_pp_digest_with::, EE<_>>( + test_pp_digest_with::, EE<_>>( &trivial_circuit1_grumpkin, &trivial_circuit2_grumpkin, &expect!["1267235eb3d139e466dd9c814eaf73f01b063ccb4cad04848c0eb62f079a9601"], ); - test_pp_digest_with::, EE<_>>( + test_pp_digest_with::, EE<_>>( &cubic_circuit1_grumpkin, &trivial_circuit2_grumpkin, &expect!["57afac2edd20d39b202151906e41154ba186c9dde497448d1332dc6de2f76302"], ); - test_pp_digest_with::, EE<_>>( + test_pp_digest_with::, EE<_>>( &trivial_circuit1_grumpkin, &trivial_circuit2_grumpkin, &expect!["070d247d83e17411d65c12260980ebcc59df88d3882d84eb62e6ab466e381503"], ); - test_pp_digest_with::, EE<_>>( + test_pp_digest_with::, EE<_>>( &cubic_circuit1_grumpkin, &trivial_circuit2_grumpkin, &expect!["47c2caa008323b588b47ab8b6c0e94f980599188abe117c4d21ffff81494f303"], @@ -1202,19 +1163,19 @@ mod tests { let trivial_circuit2_secp = TrivialCircuit::<::Scalar>::default(); let cubic_circuit1_secp = CubicCircuit::<::Scalar>::default(); - test_pp_digest_with::, EE<_>>( + test_pp_digest_with::, EE<_>>( &trivial_circuit1_secp, &trivial_circuit2_secp, &expect!["04b5d1798be6d74b3701390b87078e70ebf3ddaad80c375319f320cedf8bca00"], ); - test_pp_digest_with::, EE<_>>( + test_pp_digest_with::, EE<_>>( &cubic_circuit1_secp, &trivial_circuit2_secp, &expect!["346b5f27cf24c79386f4de7a8bfb58970181ae7f0de7d2e3f10ad5dfd8fc2302"], ); } - fn test_ivc_trivial_with() + fn test_ivc_trivial_with() where E1: CurveCycleEquipped, { @@ -1222,7 +1183,7 @@ mod tests { let test_circuit2 = TrivialCircuit::< as Engine>::Scalar>::default(); // produce public parameters - let pp = PublicParams::::Scalar>>::setup( + let pp = PublicParams::::setup( &test_circuit1, &test_circuit2, &*default_ck_hint(), @@ -1256,9 +1217,9 @@ mod tests { #[test] fn test_ivc_trivial() { - test_ivc_trivial_with::(); - test_ivc_trivial_with::(); - test_ivc_trivial_with::(); + test_ivc_trivial_with::(); + test_ivc_trivial_with::(); + test_ivc_trivial_with::(); } fn test_ivc_nontrivial_with() @@ -1269,11 +1230,7 @@ mod tests { let circuit_secondary = CubicCircuit::default(); // produce public parameters - let pp = PublicParams::< - E1, - TrivialCircuit<::Scalar>, - CubicCircuit< as Engine>::Scalar>, - >::setup( + let pp = PublicParams::::setup( &circuit_primary, &circuit_secondary, &*default_ck_hint(), @@ -1283,11 +1240,7 @@ mod tests { let num_steps = 3; // produce a recursive SNARK - let mut recursive_snark = RecursiveSNARK::< - E1, - TrivialCircuit<::Scalar>, - CubicCircuit< as Engine>::Scalar>, - >::new( + let mut recursive_snark = RecursiveSNARK::::new( &pp, &circuit_primary, &circuit_secondary, @@ -1354,11 +1307,7 @@ mod tests { let circuit_secondary = CubicCircuit::default(); // produce public parameters - let pp = PublicParams::< - E1, - TrivialCircuit<::Scalar>, - CubicCircuit< as Engine>::Scalar>, - >::setup( + let pp = PublicParams::::setup( &circuit_primary, &circuit_secondary, &*default_ck_hint(), @@ -1368,11 +1317,7 @@ mod tests { let num_steps = 3; // produce a recursive SNARK - let mut recursive_snark = RecursiveSNARK::< - E1, - TrivialCircuit<::Scalar>, - CubicCircuit< as Engine>::Scalar>, - >::new( + let mut recursive_snark = RecursiveSNARK::::new( &pp, &circuit_primary, &circuit_secondary, @@ -1410,10 +1355,10 @@ mod tests { ); // produce the prover and verifier keys for compressed snark - let (pk, vk) = CompressedSNARK::<_, _, S, _, S<_, EE2>>::setup(&pp).unwrap(); + let (pk, vk) = CompressedSNARK::<_, S, S<_, EE2>>::setup(&pp).unwrap(); // produce a compressed SNARK - let res = CompressedSNARK::<_, _, S, _, S<_, EE2>>::prove(&pp, &pk, &recursive_snark); + let res = CompressedSNARK::<_, S, S<_, EE2>>::prove(&pp, &pk, &recursive_snark); assert!(res.is_ok()); let compressed_snark = res.unwrap(); @@ -1454,11 +1399,7 @@ mod tests { let circuit_secondary = CubicCircuit::default(); // produce public parameters, which we'll use with a spark-compressed SNARK - let pp = PublicParams::< - E1, - TrivialCircuit<::Scalar>, - CubicCircuit< as Engine>::Scalar>, - >::setup( + let pp = PublicParams::::setup( &circuit_primary, &circuit_secondary, &*SPrime::::ck_floor(), @@ -1468,11 +1409,7 @@ mod tests { let num_steps = 3; // produce a recursive SNARK - let mut recursive_snark = RecursiveSNARK::< - E1, - TrivialCircuit<::Scalar>, - CubicCircuit< as Engine>::Scalar>, - >::new( + let mut recursive_snark = RecursiveSNARK::::new( &pp, &circuit_primary, &circuit_secondary, @@ -1511,14 +1448,11 @@ mod tests { // run the compressed snark with Spark compiler // produce the prover and verifier keys for compressed snark - let (pk, vk) = CompressedSNARK::<_, _, SPrime, _, SPrime<_, EE2>>::setup(&pp).unwrap(); + let (pk, vk) = CompressedSNARK::<_, SPrime, SPrime<_, EE2>>::setup(&pp).unwrap(); // produce a compressed SNARK - let res = CompressedSNARK::<_, _, SPrime, _, SPrime<_, EE2>>::prove( - &pp, - &pk, - &recursive_snark, - ); + let res = + CompressedSNARK::<_, SPrime, SPrime<_, EE2>>::prove(&pp, &pk, &recursive_snark); assert!(res.is_ok()); let compressed_snark = res.unwrap(); @@ -1613,7 +1547,7 @@ mod tests { let circuit_secondary = TrivialCircuit::default(); // produce public parameters - let pp = PublicParams::::Scalar>>::setup( + let pp = PublicParams::::setup( &circuit_primary, &circuit_secondary, &*default_ck_hint(), @@ -1627,15 +1561,14 @@ mod tests { let z0_secondary = vec![ as Engine>::Scalar::ZERO]; // produce a recursive SNARK - let mut recursive_snark = - RecursiveSNARK::::Scalar>>::new( - &pp, - &roots[0], - &circuit_secondary, - &z0_primary, - &z0_secondary, - ) - .unwrap(); + let mut recursive_snark = RecursiveSNARK::::new( + &pp, + &roots[0], + &circuit_secondary, + &z0_primary, + &z0_secondary, + ) + .unwrap(); for circuit_primary in roots.iter().take(num_steps) { let res = recursive_snark.prove_step(&pp, circuit_primary, &circuit_secondary); @@ -1647,10 +1580,10 @@ mod tests { assert!(res.is_ok()); // produce the prover and verifier keys for compressed snark - let (pk, vk) = CompressedSNARK::<_, _, S, _, S<_, EE2>>::setup(&pp).unwrap(); + let (pk, vk) = CompressedSNARK::<_, S, S<_, EE2>>::setup(&pp).unwrap(); // produce a compressed SNARK - let res = CompressedSNARK::<_, _, S, _, S<_, EE2>>::prove(&pp, &pk, &recursive_snark); + let res = CompressedSNARK::<_, S, S<_, EE2>>::prove(&pp, &pk, &recursive_snark); assert!(res.is_ok()); let compressed_snark = res.unwrap(); @@ -1675,11 +1608,7 @@ mod tests { let test_circuit2 = CubicCircuit::< as Engine>::Scalar>::default(); // produce public parameters - let pp = PublicParams::< - E1, - TrivialCircuit<::Scalar>, - CubicCircuit< as Engine>::Scalar>, - >::setup( + let pp = PublicParams::::setup( &test_circuit1, &test_circuit2, &*default_ck_hint(), @@ -1689,11 +1618,7 @@ mod tests { let num_steps = 1; // produce a recursive SNARK - let mut recursive_snark = RecursiveSNARK::< - E1, - TrivialCircuit<::Scalar>, - CubicCircuit< as Engine>::Scalar>, - >::new( + let mut recursive_snark = RecursiveSNARK::::new( &pp, &test_circuit1, &test_circuit2, From 452e54edb71a7ab141ca74b6f60d50aa56546815 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Garillot?= Date: Fri, 2 Feb 2024 18:52:01 -0500 Subject: [PATCH 5/8] refactor: Refactor supernova for single engine parameters and simplified testing TL;DR : use CurveCycle and remove Phantom parameters - Altered and simplified generic parameter restrictions for `NonUniformBench` and `NonUniformCircuit`. - Refactored import statements in `benches/common/supernova/mod.rs` for a cleaner and simplified codebase. - Refactored the use of `TrivialTestCircuit` from the `benches/common/supernova/bench.rs` file. - Revised the `RecursiveSNARK` type in `bench.rs`, - Refactored and simplified function signatures in `test.rs`, - Made significant changes to the `TestROM` structure and adjusted related function implementations within `src/supernova/test.rs`. - Overall, improved the use of generics. --- benches/common/supernova/bench.rs | 16 +- benches/common/supernova/mod.rs | 36 ++-- src/lib.rs | 3 - src/supernova/mod.rs | 304 +++++++++++++----------------- src/supernova/snark.rs | 180 +++++++----------- src/supernova/test.rs | 147 ++++++--------- 6 files changed, 282 insertions(+), 404 deletions(-) diff --git a/benches/common/supernova/bench.rs b/benches/common/supernova/bench.rs index 524d8e072..0cdb62773 100644 --- a/benches/common/supernova/bench.rs +++ b/benches/common/supernova/bench.rs @@ -8,7 +8,6 @@ use crate::common::{noise_threshold_env, BenchParams}; use arecibo::{ provider::{PallasEngine, VestaEngine}, supernova::NonUniformCircuit, - supernova::TrivialTestCircuit, supernova::{snark::CompressedSNARK, PublicParams, RecursiveSNARK}, traits::{ snark::RelaxedR1CSSNARKTrait, @@ -33,10 +32,9 @@ pub fn bench_snark_internal_with_arity< num_cons: usize, snark_type: SnarkType, ) { - let bench: NonUniformBench::Scalar>> = match snark_type - { - SnarkType::Recursive => NonUniformBench::new(2, num_cons), - SnarkType::Compressed => NonUniformBench::new(num_augmented_circuits, num_cons), + let bench: NonUniformBench = match snark_type { + SnarkType::Recursive => NonUniformBench::::new(2, num_cons), + SnarkType::Compressed => NonUniformBench::::new(num_augmented_circuits, num_cons), }; let pp = match snark_type { SnarkType::Recursive => PublicParams::setup(&bench, &*default_ck_hint(), &*default_ck_hint()), @@ -50,7 +48,7 @@ pub fn bench_snark_internal_with_arity< }; let z0_primary = vec![::Scalar::from(2u64)]; let z0_secondary = vec![::Scalar::from(2u64)]; - let mut recursive_snark_option: Option> = None; + let mut recursive_snark_option: Option> = None; let mut selected_augmented_circuit = 0; for _ in 0..num_warmup_steps { @@ -97,11 +95,11 @@ pub fn bench_snark_internal_with_arity< match snark_type { SnarkType::Compressed => { - let (prover_key, verifier_key) = CompressedSNARK::<_, _, S1, _, _, S2>::setup(&pp).unwrap(); + let (prover_key, verifier_key) = CompressedSNARK::<_, S1, S2>::setup(&pp).unwrap(); // Benchmark the prove time group.bench_function(bench_params.bench_id("Prove"), |b| { b.iter(|| { - assert!(CompressedSNARK::<_, _, S1, _, _, S2>::prove( + assert!(CompressedSNARK::<_, S1, S2>::prove( black_box(&pp), black_box(&prover_key), black_box(&recursive_snark) @@ -110,7 +108,7 @@ pub fn bench_snark_internal_with_arity< }) }); - let res = CompressedSNARK::<_, _, S1, _, _, S2>::prove(&pp, &prover_key, &recursive_snark); + let res = CompressedSNARK::<_, S1, S2>::prove(&pp, &prover_key, &recursive_snark); assert!(res.is_ok()); let compressed_snark = res.unwrap(); // Benchmark the verification time diff --git a/benches/common/supernova/mod.rs b/benches/common/supernova/mod.rs index 5ade9db57..27e9155cc 100644 --- a/benches/common/supernova/mod.rs +++ b/benches/common/supernova/mod.rs @@ -6,9 +6,8 @@ pub mod targets; use anyhow::anyhow; use arecibo::{ - supernova::NonUniformCircuit, - supernova::{StepCircuit, TrivialTestCircuit}, - traits::Engine, + supernova::{NonUniformCircuit, StepCircuit, TrivialTestCircuit}, + traits::{CurveCycleEquipped, Engine, SecEng}, }; use bellpepper_core::{num::AllocatedNum, ConstraintSystem, SynthesisError}; use core::marker::PhantomData; @@ -68,45 +67,40 @@ fn num_cons_env() -> anyhow::Result> { }) } -pub struct NonUniformBench +pub struct NonUniformBench where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - S: StepCircuit + Default, + E1: CurveCycleEquipped, { num_circuits: usize, num_cons: usize, - _p: PhantomData<(E1, E2, S)>, + _p: PhantomData, } -impl NonUniformBench +impl NonUniformBench where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - S: StepCircuit + Default, + E1: CurveCycleEquipped, { fn new(num_circuits: usize, num_cons: usize) -> Self { Self { num_circuits, num_cons, - _p: Default::default(), + _p: PhantomData, } } } -impl - NonUniformCircuit, E2, TrivialTestCircuit> - for NonUniformBench +impl NonUniformCircuit for NonUniformBench where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - S: StepCircuit + Default, + E1: CurveCycleEquipped, { + type C1 = NonTrivialTestCircuit; + type C2 = TrivialTestCircuit< as Engine>::Scalar>; + fn num_circuits(&self) -> usize { self.num_circuits } - fn primary_circuit(&self, circuit_index: usize) -> NonTrivialTestCircuit { + fn primary_circuit(&self, circuit_index: usize) -> Self::C1 { assert!( circuit_index < self.num_circuits, "Circuit index out of bounds: asked for {circuit_index}, but there are only {} circuits.", @@ -116,7 +110,7 @@ where NonTrivialTestCircuit::new(self.num_cons) } - fn secondary_circuit(&self) -> TrivialTestCircuit { + fn secondary_circuit(&self) -> Self::C2 { Default::default() } } diff --git a/src/lib.rs b/src/lib.rs index 19b2547df..36eaefcae 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -139,7 +139,6 @@ where circuit_shape_secondary: R1CSWithArity>, augmented_circuit_params_primary: NovaAugmentedCircuitParams, augmented_circuit_params_secondary: NovaAugmentedCircuitParams, - _p: PhantomData<(C1, C2)>, } #[cfg(feature = "abomonate")] @@ -167,7 +166,6 @@ where 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, }) } } @@ -192,7 +190,6 @@ where augmented_circuit_params_primary: value.augmented_circuit_params_primary, augmented_circuit_params_secondary: value.augmented_circuit_params_secondary, digest: OnceCell::new(), - _p: PhantomData, } } } diff --git a/src/supernova/mod.rs b/src/supernova/mod.rs index ab28c36e9..723f19633 100644 --- a/src/supernova/mod.rs +++ b/src/supernova/mod.rs @@ -1,6 +1,5 @@ #![doc = include_str!("./Readme.md")] -use std::marker::PhantomData; use std::ops::Index; use crate::{ @@ -15,7 +14,7 @@ use crate::{ scalar_as_base, traits::{ commitment::{CommitmentEngineTrait, CommitmentTrait}, - AbsorbInROTrait, Engine, ROConstants, ROConstantsCircuit, ROTrait, + AbsorbInROTrait, CurveCycleEquipped, Engine, ROConstants, ROConstantsCircuit, ROTrait, SecEng, }, Commitment, CommitmentKey, R1CSWithArity, }; @@ -82,31 +81,27 @@ impl CircuitDigests { /// A vector of [`R1CSWithArity`] adjoined to a set of [`PublicParams`] #[derive(Debug, Serialize)] #[serde(bound = "")] -pub struct PublicParams +pub struct PublicParams where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - C1: StepCircuit, - C2: StepCircuit, + E1: CurveCycleEquipped, { /// The internal circuit shapes circuit_shapes: Vec>, ro_consts_primary: ROConstants, - ro_consts_circuit_primary: ROConstantsCircuit, + 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_secondary: ROConstants>, ro_consts_circuit_secondary: ROConstantsCircuit, - ck_secondary: Arc>, - circuit_shape_secondary: R1CSWithArity, + ck_secondary: Arc>>, + circuit_shape_secondary: R1CSWithArity>, augmented_circuit_params_secondary: SuperNovaAugmentedCircuitParams, /// Digest constructed from this `PublicParams`' parameters #[serde(skip, default = "OnceCell::new")] digest: OnceCell, - _p: PhantomData<(C1, C2)>, } /// Auxiliary [`PublicParams`] information about the commitment keys and @@ -114,20 +109,19 @@ where /// [`PublicParams`] downstream in lurk. #[derive(Debug, Clone, PartialEq, Serialize)] #[serde(bound = "")] -pub struct AuxParams +pub struct AuxParams where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E1: CurveCycleEquipped, { ro_consts_primary: ROConstants, - ro_consts_circuit_primary: ROConstantsCircuit, + 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_secondary: ROConstants>, ro_consts_circuit_secondary: ROConstantsCircuit, - ck_secondary: Arc>, - circuit_shape_secondary: R1CSWithArity, + ck_secondary: Arc>>, + circuit_shape_secondary: R1CSWithArity>, augmented_circuit_params_secondary: SuperNovaAugmentedCircuitParams, digest: E1::Scalar, @@ -138,25 +132,23 @@ where #[derive(Debug, Clone, PartialEq, Abomonation)] #[abomonation_bounds( where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E1: CurveCycleEquipped, ::Repr: Abomonation, - ::Repr: Abomonation, + < as Engine>::Scalar as PrimeField>::Repr: Abomonation, )] -pub struct FlatAuxParams +pub struct FlatAuxParams where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E1: CurveCycleEquipped, { ro_consts_primary: ROConstants, - ro_consts_circuit_primary: ROConstantsCircuit, + ro_consts_circuit_primary: ROConstantsCircuit>, ck_primary: CommitmentKey, // This is shared between all circuit params augmented_circuit_params_primary: SuperNovaAugmentedCircuitParams, - ro_consts_secondary: ROConstants, + ro_consts_secondary: ROConstants>, ro_consts_circuit_secondary: ROConstantsCircuit, - ck_secondary: CommitmentKey, - circuit_shape_secondary: R1CSWithArity, + ck_secondary: CommitmentKey>, + circuit_shape_secondary: R1CSWithArity>, augmented_circuit_params_secondary: SuperNovaAugmentedCircuitParams, #[abomonate_with(::Repr)] @@ -164,14 +156,13 @@ where } #[cfg(feature = "abomonate")] -impl TryFrom> for FlatAuxParams +impl TryFrom> for FlatAuxParams where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E1: CurveCycleEquipped, { type Error = &'static str; - fn try_from(value: AuxParams) -> Result { + 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 = @@ -192,12 +183,11 @@ where } #[cfg(feature = "abomonate")] -impl From> for AuxParams +impl From> for AuxParams where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E1: CurveCycleEquipped, { - fn from(value: FlatAuxParams) -> Self { + fn from(value: FlatAuxParams) -> Self { Self { ro_consts_primary: value.ro_consts_primary, ro_consts_circuit_primary: value.ro_consts_circuit_primary, @@ -213,12 +203,9 @@ where } } -impl Index for PublicParams +impl Index for PublicParams where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - C1: StepCircuit, - C2: StepCircuit, + E1: CurveCycleEquipped, { type Output = R1CSWithArity; @@ -227,21 +214,11 @@ where } } -impl SimpleDigestible for PublicParams -where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - C1: StepCircuit, - C2: StepCircuit, -{ -} +impl SimpleDigestible for PublicParams where E1: CurveCycleEquipped {} -impl PublicParams +impl PublicParams where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - C1: StepCircuit, - C2: StepCircuit, + E1: CurveCycleEquipped, { /// Construct a new [`PublicParams`] /// @@ -261,10 +238,10 @@ where /// * `ck_hint1`: A `CommitmentKeyHint` for `E1`, 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 `E2`, similar to `ck_hint1`, but for the secondary circuit. - pub fn setup>( + pub fn setup>( non_uniform_circuit: &NC, ck_hint1: &CommitmentKeyHint, - ck_hint2: &CommitmentKeyHint, + ck_hint2: &CommitmentKeyHint>, ) -> Self { let num_circuits = non_uniform_circuit.num_circuits(); @@ -272,20 +249,22 @@ where SuperNovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, true); let ro_consts_primary: ROConstants = ROConstants::::default(); // ro_consts_circuit_primary are parameterized by E2 because the type alias uses E2::Base = E1::Scalar - let ro_consts_circuit_primary: ROConstantsCircuit = ROConstantsCircuit::::default(); + let ro_consts_circuit_primary: ROConstantsCircuit> = + ROConstantsCircuit::>::default(); let circuit_shapes = (0..num_circuits) .map(|i| { let c_primary = non_uniform_circuit.primary_circuit(i); let F_arity = c_primary.arity(); // Initialize ck for the primary - let circuit_primary: SuperNovaAugmentedCircuit<'_, E2, C1> = SuperNovaAugmentedCircuit::new( - &augmented_circuit_params_primary, - None, - &c_primary, - ro_consts_circuit_primary.clone(), - num_circuits, - ); + let circuit_primary: SuperNovaAugmentedCircuit<'_, SecEng, NC::C1> = + SuperNovaAugmentedCircuit::new( + &augmented_circuit_params_primary, + None, + &c_primary, + ro_consts_circuit_primary.clone(), + num_circuits, + ); let mut cs: ShapeCS = ShapeCS::new(); circuit_primary .synthesize(&mut cs) @@ -302,19 +281,20 @@ where let augmented_circuit_params_secondary = SuperNovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, false); - let ro_consts_secondary: ROConstants = ROConstants::::default(); + let ro_consts_secondary = ROConstants::>::default(); let c_secondary = non_uniform_circuit.secondary_circuit(); let F_arity_secondary = c_secondary.arity(); let ro_consts_circuit_secondary: ROConstantsCircuit = ROConstantsCircuit::::default(); - let circuit_secondary: SuperNovaAugmentedCircuit<'_, E1, C2> = SuperNovaAugmentedCircuit::new( - &augmented_circuit_params_secondary, - None, - &c_secondary, - ro_consts_circuit_secondary.clone(), - num_circuits, - ); - let mut cs: ShapeCS = ShapeCS::new(); + let circuit_secondary: SuperNovaAugmentedCircuit<'_, E1, NC::C2> = + SuperNovaAugmentedCircuit::new( + &augmented_circuit_params_secondary, + None, + &c_secondary, + ro_consts_circuit_secondary.clone(), + num_circuits, + ); + let mut cs: ShapeCS> = ShapeCS::new(); circuit_secondary .synthesize(&mut cs) .expect("circuit synthesis failed"); @@ -334,7 +314,6 @@ where circuit_shape_secondary, augmented_circuit_params_secondary, digest: OnceCell::new(), - _p: PhantomData, }; // make sure to initialize the `OnceCell` and compute the digest @@ -344,7 +323,7 @@ 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>, AuxParams) { let digest = self.digest(); let Self { @@ -359,7 +338,6 @@ where circuit_shape_secondary, augmented_circuit_params_secondary, digest: _digest, - _p, } = self; let aux_params = AuxParams { @@ -379,7 +357,7 @@ where } /// 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>, aux_params: AuxParams) -> Self { let pp = Self { circuit_shapes, ro_consts_primary: aux_params.ro_consts_primary, @@ -392,7 +370,6 @@ where 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, @@ -406,7 +383,7 @@ 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>, - aux_params: AuxParams, + aux_params: AuxParams, ) -> Self { Self { circuit_shapes, @@ -420,7 +397,6 @@ where circuit_shape_secondary: aux_params.circuit_shape_secondary, augmented_circuit_params_secondary: aux_params.augmented_circuit_params_secondary, digest: aux_params.digest.into(), - _p: PhantomData, } } @@ -489,10 +465,9 @@ struct ResourceBuffer { /// A SNARK that proves the correct execution of an non-uniform incremental computation #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(bound = "")] -pub struct RecursiveSNARK +pub struct RecursiveSNARK where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E1: CurveCycleEquipped, { // Cached digest of the public parameters pp_digest: E1::Scalar, @@ -512,7 +487,7 @@ where /// Buffer for memory needed by the primary fold-step buffer_primary: ResourceBuffer, /// Buffer for memory needed by the secondary fold-step - buffer_secondary: ResourceBuffer, + buffer_secondary: ResourceBuffer>, // Relaxed instances for the primary circuits // Entries are `None` if the circuit has not been executed yet @@ -520,34 +495,29 @@ where r_U_primary: Vec>>, // Inputs and outputs of the secondary circuit - z0_secondary: Vec, - zi_secondary: Vec, + z0_secondary: Vec< as Engine>::Scalar>, + zi_secondary: Vec< as Engine>::Scalar>, // Relaxed instance for the secondary circuit - r_W_secondary: RelaxedR1CSWitness, - r_U_secondary: RelaxedR1CSInstance, + r_W_secondary: RelaxedR1CSWitness>, + r_U_secondary: RelaxedR1CSInstance>, // Proof for the secondary circuit to be accumulated into r_secondary in the next iteration - l_w_secondary: R1CSWitness, - l_u_secondary: R1CSInstance, + l_w_secondary: R1CSWitness>, + l_u_secondary: R1CSInstance>, } -impl RecursiveSNARK +impl RecursiveSNARK where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E1: CurveCycleEquipped, { /// iterate base step to get new instance of recursive SNARK #[allow(clippy::too_many_arguments)] - pub fn new< - C0: NonUniformCircuit, - C1: StepCircuit, - C2: StepCircuit, - >( - pp: &PublicParams, + pub fn new>( + pp: &PublicParams, non_uniform_circuit: &C0, - c_primary: &C1, - c_secondary: &C2, + c_primary: &C0::C1, + c_secondary: &C0::C2, z0_primary: &[E1::Scalar], - z0_secondary: &[E2::Scalar], + z0_secondary: &[ as Engine>::Scalar], ) -> Result { let num_augmented_circuits = non_uniform_circuit.num_circuits(); let circuit_index = non_uniform_circuit.initial_circuit_index(); @@ -574,7 +544,7 @@ where // base case for the primary let mut cs_primary = SatisfyingAssignment::::new(); let program_counter = E1::Scalar::from(circuit_index as u64); - let inputs_primary: SuperNovaAugmentedCircuitInputs<'_, E2> = + let inputs_primary: SuperNovaAugmentedCircuitInputs<'_, SecEng> = SuperNovaAugmentedCircuitInputs::new( scalar_as_base::(pp.digest()), E1::Scalar::ZERO, @@ -587,13 +557,14 @@ where E1::Scalar::ZERO, // u_index is always zero for the primary circuit ); - let circuit_primary: SuperNovaAugmentedCircuit<'_, E2, C1> = SuperNovaAugmentedCircuit::new( - &pp.augmented_circuit_params_primary, - Some(inputs_primary), - c_primary, - pp.ro_consts_circuit_primary.clone(), - num_augmented_circuits, - ); + let circuit_primary: SuperNovaAugmentedCircuit<'_, SecEng, C0::C1> = + SuperNovaAugmentedCircuit::new( + &pp.augmented_circuit_params_primary, + Some(inputs_primary), + c_primary, + pp.ro_consts_circuit_primary.clone(), + num_augmented_circuits, + ); let (zi_primary_pc_next, zi_primary) = circuit_primary.synthesize(&mut cs_primary).map_err(|err| { @@ -613,12 +584,12 @@ where })?; // base case for the secondary - let mut cs_secondary = SatisfyingAssignment::::new(); - let u_primary_index = E2::Scalar::from(circuit_index as u64); + let mut cs_secondary = SatisfyingAssignment::>::new(); + let u_primary_index = as Engine>::Scalar::from(circuit_index as u64); let inputs_secondary: SuperNovaAugmentedCircuitInputs<'_, E1> = SuperNovaAugmentedCircuitInputs::new( pp.digest(), - E2::Scalar::ZERO, + as Engine>::Scalar::ZERO, z0_secondary, None, // zi = None for basecase None, // U = Empty list of accumulators for the primary circuits @@ -627,13 +598,15 @@ where None, // program_counter is always None for secondary circuit u_primary_index, // index of the circuit proof u_primary ); - let circuit_secondary: SuperNovaAugmentedCircuit<'_, E1, C2> = SuperNovaAugmentedCircuit::new( - &pp.augmented_circuit_params_secondary, - Some(inputs_secondary), - c_secondary, - pp.ro_consts_circuit_secondary.clone(), - num_augmented_circuits, - ); + + let circuit_secondary: SuperNovaAugmentedCircuit<'_, E1, C0::C2> = + SuperNovaAugmentedCircuit::new( + &pp.augmented_circuit_params_secondary, + Some(inputs_secondary), + c_secondary, + pp.ro_consts_circuit_secondary.clone(), + num_augmented_circuits, + ); let (_, zi_secondary) = circuit_secondary .synthesize(&mut cs_secondary) .map_err(NovaError::from)?; @@ -661,7 +634,7 @@ where let l_u_secondary = u_secondary; // Initialize relaxed instance/witness pair for the secondary circuit proofs - let r_W_secondary: RelaxedR1CSWitness = RelaxedR1CSWitness::::default(r1cs_secondary); + let r_W_secondary = RelaxedR1CSWitness::>::default(r1cs_secondary); let r_U_secondary = RelaxedR1CSInstance::default(&*pp.ck_secondary, r1cs_secondary); // Outputs of the two circuits and next program counter thus far. @@ -682,7 +655,7 @@ where v.get_value() .ok_or(NovaError::from(SynthesisError::AssignmentMissing).into()) }) - .collect::::Scalar>, SuperNovaError>>()?; + .collect:: as Engine>::Scalar>, SuperNovaError>>()?; // handle the base case by initialize U_next in next round let r_W_primary_initial_list = (0..num_augmented_circuits) @@ -714,7 +687,7 @@ where l_u: None, ABC_Z_1: R1CSResult::default(r1cs_secondary.num_cons), ABC_Z_2: R1CSResult::default(r1cs_secondary.num_cons), - T: r1cs::default_T::(r1cs_secondary.num_cons), + T: r1cs::default_T::>(r1cs_secondary.num_cons), }; Ok(Self { @@ -744,9 +717,12 @@ where /// executing a step of the incremental computation #[allow(clippy::too_many_arguments)] #[tracing::instrument(skip_all, name = "supernova::RecursiveSNARK::prove_step")] - pub fn prove_step, C2: StepCircuit>( + pub fn prove_step< + C1: StepCircuit, + C2: StepCircuit< as Engine>::Scalar>, + >( &mut self, - pp: &PublicParams, + pp: &PublicParams, c_primary: &C1, c_secondary: &C2, ) -> Result<(), SuperNovaError> { @@ -785,9 +761,9 @@ where pp[circuit_index].r1cs_shape.num_io + 1, pp[circuit_index].r1cs_shape.num_vars, ); - let T: <::CE as CommitmentEngineTrait>::Commitment = - Commitment::::decompress(&nifs_secondary.comm_T).map_err(SuperNovaError::NovaError)?; - let inputs_primary: SuperNovaAugmentedCircuitInputs<'_, E2> = + let T = Commitment::>::decompress(&nifs_secondary.comm_T) + .map_err(SuperNovaError::NovaError)?; + let inputs_primary: SuperNovaAugmentedCircuitInputs<'_, SecEng> = SuperNovaAugmentedCircuitInputs::new( scalar_as_base::(self.pp_digest), E1::Scalar::from(self.i as u64), @@ -800,13 +776,14 @@ where E1::Scalar::ZERO, ); - let circuit_primary: SuperNovaAugmentedCircuit<'_, E2, C1> = SuperNovaAugmentedCircuit::new( - &pp.augmented_circuit_params_primary, - Some(inputs_primary), - c_primary, - pp.ro_consts_circuit_primary.clone(), - self.num_augmented_circuits, - ); + let circuit_primary: SuperNovaAugmentedCircuit<'_, SecEng, C1> = + SuperNovaAugmentedCircuit::new( + &pp.augmented_circuit_params_primary, + Some(inputs_primary), + c_primary, + pp.ro_consts_circuit_primary.clone(), + self.num_augmented_circuits, + ); let (zi_primary_pc_next, zi_primary) = circuit_primary .synthesize(&mut cs_primary) @@ -854,7 +831,7 @@ where ) .map_err(SuperNovaError::NovaError)?; - let mut cs_secondary = SatisfyingAssignment::::with_capacity( + let mut cs_secondary = SatisfyingAssignment::>::with_capacity( pp.circuit_shape_secondary.r1cs_shape.num_io + 1, pp.circuit_shape_secondary.r1cs_shape.num_vars, ); @@ -863,14 +840,14 @@ where let inputs_secondary: SuperNovaAugmentedCircuitInputs<'_, E1> = SuperNovaAugmentedCircuitInputs::new( self.pp_digest, - E2::Scalar::from(self.i as u64), + as Engine>::Scalar::from(self.i as u64), &self.z0_secondary, Some(&self.zi_secondary), Some(&r_U_primary_i), Some(&l_u_primary), Some(&binding), None, // pc is always None for secondary circuit - E2::Scalar::from(circuit_index as u64), + as Engine>::Scalar::from(circuit_index as u64), ); let circuit_secondary: SuperNovaAugmentedCircuit<'_, E1, C2> = SuperNovaAugmentedCircuit::new( @@ -910,7 +887,7 @@ where v.get_value() .ok_or(NovaError::from(SynthesisError::AssignmentMissing).into()) }) - .collect::::Scalar>, SuperNovaError>>()?; + .collect:: as Engine>::Scalar>, SuperNovaError>>()?; if zi_primary.len() != pp[circuit_index].F_arity || zi_secondary.len() != pp.circuit_shape_secondary.F_arity @@ -931,12 +908,12 @@ where } /// verify recursive snark - pub fn verify, C2: StepCircuit>( + pub fn verify( &self, - pp: &PublicParams, + pp: &PublicParams, z0_primary: &[E1::Scalar], - z0_secondary: &[E2::Scalar], - ) -> Result<(Vec, Vec), SuperNovaError> { + z0_secondary: &[ as Engine>::Scalar], + ) -> Result<(Vec, Vec< as Engine>::Scalar>), SuperNovaError> { // number of steps cannot be zero if self.i == 0 { debug!("must verify on valid RecursiveSNARK where i > 0"); @@ -1016,7 +993,7 @@ where true, // is_primary ); - let mut hasher = ::RO::new(pp.ro_consts_secondary.clone(), num_absorbs); + let mut hasher = as Engine>::RO::new(pp.ro_consts_secondary.clone(), num_absorbs); hasher.absorb(self.pp_digest); hasher.absorb(E1::Scalar::from(self.i as u64)); hasher.absorb(self.program_counter); @@ -1041,7 +1018,7 @@ where ); let mut hasher = ::RO::new(pp.ro_consts_primary.clone(), num_absorbs); hasher.absorb(scalar_as_base::(self.pp_digest)); - hasher.absorb(E2::Scalar::from(self.i as u64)); + hasher.absorb( as Engine>::Scalar::from(self.i as u64)); for e in z0_secondary { hasher.absorb(*e); @@ -1068,7 +1045,7 @@ where ); return Err(SuperNovaError::NovaError(NovaError::ProofVerifyError)); } - if hash_secondary != scalar_as_base::(self.l_u_secondary.X[1]) { + if hash_secondary != scalar_as_base::>(self.l_u_secondary.X[1]) { debug!( "hash_secondary {:?} not equal l_u_secondary.X[1] {:?}", hash_secondary, self.l_u_secondary.X[1] @@ -1131,13 +1108,15 @@ where /// SuperNova helper trait, for implementors that provide sets of sub-circuits to be proved via NIVC. `C1` must be a /// type (likely an `Enum`) for which a potentially-distinct instance can be supplied for each `index` below /// `self.num_circuits()`. -pub trait NonUniformCircuit +pub trait NonUniformCircuit where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - C1: StepCircuit, - C2: StepCircuit, + E1: CurveCycleEquipped, { + /// The type of the step-circuits on the primary + type C1: StepCircuit; + /// The type of the step-circuits on the secondary + type C2: StepCircuit< as Engine>::Scalar>; + /// Initial circuit index, defaults to zero. fn initial_circuit_index(&self) -> usize { 0 @@ -1147,19 +1126,16 @@ where fn num_circuits(&self) -> usize; /// Return a new instance of the primary circuit at `index`. - fn primary_circuit(&self, circuit_index: usize) -> C1; + fn primary_circuit(&self, circuit_index: usize) -> Self::C1; /// Return a new instance of the secondary circuit. - fn secondary_circuit(&self) -> C2; + fn secondary_circuit(&self) -> Self::C2; } /// Extension trait to simplify getting scalar form of initial circuit index. -trait InitialProgramCounter: NonUniformCircuit +trait InitialProgramCounter: NonUniformCircuit where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - C1: StepCircuit, - C2: StepCircuit, + E1: CurveCycleEquipped, { /// Initial program counter is the initial circuit index as a `Scalar`. fn initial_program_counter(&self) -> E1::Scalar { @@ -1167,15 +1143,7 @@ where } } -impl> InitialProgramCounter - for T -where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - C1: StepCircuit, - C2: StepCircuit, -{ -} +impl> InitialProgramCounter for T {} /// Compute the circuit digest of a supernova [`StepCircuit`]. /// diff --git a/src/supernova/snark.rs b/src/supernova/snark.rs index fc6407b6e..f681e16d5 100644 --- a/src/supernova/snark.rs +++ b/src/supernova/snark.rs @@ -4,97 +4,74 @@ use super::{error::SuperNovaError, PublicParams, RecursiveSNARK}; use crate::{ constants::NUM_HASH_BITS, r1cs::{R1CSInstance, RelaxedR1CSWitness}, - supernova::StepCircuit, traits::{ snark::{BatchedRelaxedR1CSSNARKTrait, RelaxedR1CSSNARKTrait}, - AbsorbInROTrait, Engine, ROTrait, + AbsorbInROTrait, CurveCycleEquipped, Engine, ROTrait, SecEng, }, }; use crate::{errors::NovaError, scalar_as_base, RelaxedR1CSInstance, NIFS}; use ff::PrimeField; use serde::{Deserialize, Serialize}; -use std::marker::PhantomData; /// A type that holds the prover key for `CompressedSNARK` #[derive(Debug)] -pub struct ProverKey +pub struct ProverKey where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - C1: StepCircuit, - C2: StepCircuit, + E1: CurveCycleEquipped, S1: BatchedRelaxedR1CSSNARKTrait, - S2: RelaxedR1CSSNARKTrait, + S2: RelaxedR1CSSNARKTrait>, { pk_primary: S1::ProverKey, pk_secondary: S2::ProverKey, - _p: PhantomData<(C1, C2)>, } /// A type that holds the verifier key for `CompressedSNARK` #[derive(Debug)] -pub struct VerifierKey +pub struct VerifierKey where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - C1: StepCircuit, - C2: StepCircuit, + E1: CurveCycleEquipped, S1: BatchedRelaxedR1CSSNARKTrait, - S2: RelaxedR1CSSNARKTrait, + S2: RelaxedR1CSSNARKTrait>, { vk_primary: S1::VerifierKey, vk_secondary: S2::VerifierKey, - _p: PhantomData<(C1, C2)>, } /// A SNARK that proves the knowledge of a valid `RecursiveSNARK` #[derive(Debug, Serialize, Deserialize)] #[serde(bound = "")] -pub struct CompressedSNARK +pub struct CompressedSNARK where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - C1: StepCircuit, - C2: StepCircuit, + E1: CurveCycleEquipped, S1: BatchedRelaxedR1CSSNARKTrait, - S2: RelaxedR1CSSNARKTrait, + S2: RelaxedR1CSSNARKTrait>, { r_U_primary: Vec>, r_W_snark_primary: S1, - r_U_secondary: RelaxedR1CSInstance, - l_u_secondary: R1CSInstance, - nifs_secondary: NIFS, + r_U_secondary: RelaxedR1CSInstance>, + l_u_secondary: R1CSInstance>, + nifs_secondary: NIFS>, f_W_snark_secondary: S2, num_steps: usize, program_counter: E1::Scalar, zn_primary: Vec, - zn_secondary: Vec, - _p: PhantomData<(E1, C1, S1, E2, C2, S2)>, + zn_secondary: Vec< as Engine>::Scalar>, } -impl CompressedSNARK +impl CompressedSNARK where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - C1: StepCircuit, - C2: StepCircuit, + E1: CurveCycleEquipped, S1: BatchedRelaxedR1CSSNARKTrait, - S2: RelaxedR1CSSNARKTrait, + S2: RelaxedR1CSSNARKTrait>, { /// Creates prover and verifier keys for `CompressedSNARK` pub fn setup( - pp: &PublicParams, - ) -> Result< - ( - ProverKey, - VerifierKey, - ), - SuperNovaError, - > { + pp: &PublicParams, + ) -> Result<(ProverKey, VerifierKey), SuperNovaError> { let (pk_primary, vk_primary) = S1::setup(pp.ck_primary.clone(), pp.primary_r1cs_shapes())?; let (pk_secondary, vk_secondary) = S2::setup( @@ -105,12 +82,10 @@ where let prover_key = ProverKey { pk_primary, pk_secondary, - _p: PhantomData, }; let verifier_key = VerifierKey { vk_primary, vk_secondary, - _p: PhantomData, }; Ok((prover_key, verifier_key)) @@ -118,9 +93,9 @@ where /// Create a new `CompressedSNARK` pub fn prove( - pp: &PublicParams, - pk: &ProverKey, - recursive_snark: &RecursiveSNARK, + pp: &PublicParams, + pk: &ProverKey, + recursive_snark: &RecursiveSNARK, ) -> Result { // fold the secondary circuit's instance let res_secondary = NIFS::prove( @@ -194,8 +169,6 @@ where zn_primary: recursive_snark.zi_primary.clone(), zn_secondary: recursive_snark.zi_secondary.clone(), - - _p: PhantomData, }; Ok(compressed_snark) @@ -204,11 +177,11 @@ where /// Verify the correctness of the `CompressedSNARK` pub fn verify( &self, - pp: &PublicParams, - vk: &VerifierKey, + pp: &PublicParams, + vk: &VerifierKey, z0_primary: &[E1::Scalar], - z0_secondary: &[E2::Scalar], - ) -> Result<(Vec, Vec), SuperNovaError> { + z0_secondary: &[ as Engine>::Scalar], + ) -> Result<(Vec, Vec< as Engine>::Scalar>), SuperNovaError> { let last_circuit_idx = field_as_usize(self.program_counter); let num_field_primary_ro = 3 // params_next, i_new, program_counter_new @@ -226,7 +199,7 @@ where // witnesses provided by the prover let (hash_primary, hash_secondary) = { let mut hasher = - ::RO::new(pp.ro_consts_secondary.clone(), num_field_primary_ro); + as Engine>::RO::new(pp.ro_consts_secondary.clone(), num_field_primary_ro); hasher.absorb(pp.digest()); hasher.absorb(E1::Scalar::from(self.num_steps as u64)); @@ -246,7 +219,7 @@ where ::RO::new(pp.ro_consts_primary.clone(), num_field_secondary_ro); hasher2.absorb(scalar_as_base::(pp.digest())); - hasher2.absorb(E2::Scalar::from(self.num_steps as u64)); + hasher2.absorb( as Engine>::Scalar::from(self.num_steps as u64)); for e in z0_secondary { hasher2.absorb(*e); @@ -271,7 +244,7 @@ where return Err(NovaError::ProofVerifyError.into()); } - if hash_secondary != scalar_as_base::(self.l_u_secondary.X[1]) { + if hash_secondary != scalar_as_base::>(self.l_u_secondary.X[1]) { return Err(NovaError::ProofVerifyError.into()); } @@ -309,17 +282,15 @@ fn field_as_usize(x: F) -> usize { mod test { use super::*; use crate::{ - provider::{ - ipa_pc, Bn256Engine, GrumpkinEngine, PallasEngine, Secp256k1Engine, Secq256k1Engine, - VestaEngine, - }, + provider::{ipa_pc, Bn256Engine, PallasEngine, Secp256k1Engine}, spartan::{batched, batched_ppsnark, snark::RelaxedR1CSSNARK}, - supernova::{circuit::TrivialSecondaryCircuit, NonUniformCircuit}, + supernova::{circuit::TrivialSecondaryCircuit, NonUniformCircuit, StepCircuit}, }; use abomonation::Abomonation; use bellpepper_core::{num::AllocatedNum, ConstraintSystem, SynthesisError}; use ff::{Field, PrimeField}; + use std::marker::PhantomData; type EE = ipa_pc::EvaluationEngine; type S1 = batched::BatchedRelaxedR1CSSNARK>; @@ -466,12 +437,10 @@ mod test { } } - impl NonUniformCircuit> - for TestCircuit - where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - { + impl NonUniformCircuit for TestCircuit { + type C1 = Self; + type C2 = TrivialSecondaryCircuit< as Engine>::Scalar>; + fn num_circuits(&self) -> usize { 2 } @@ -484,19 +453,18 @@ mod test { } } - fn secondary_circuit(&self) -> TrivialSecondaryCircuit { + fn secondary_circuit(&self) -> Self::C2 { Default::default() } } - fn test_nivc_trivial_with_compression_with() + fn test_nivc_trivial_with_compression_with() where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E1: CurveCycleEquipped, S1: BatchedRelaxedR1CSSNARKTrait, - S2: RelaxedR1CSSNARKTrait, + S2: RelaxedR1CSSNARKTrait>, ::Repr: Abomonation, - ::Repr: Abomonation, + < as Engine>::Scalar as PrimeField>::Repr: Abomonation, { const NUM_STEPS: usize = 6; @@ -506,7 +474,7 @@ mod test { let pp = PublicParams::setup(&test_circuits[0], &*S1::ck_floor(), &*S2::ck_floor()); let z0_primary = vec![E1::Scalar::from(17u64)]; - let z0_secondary = vec![::Scalar::ZERO]; + let z0_secondary = vec![ as Engine>::Scalar::ZERO]; let mut recursive_snark = RecursiveSNARK::new( &pp, @@ -527,7 +495,7 @@ mod test { assert!(verify_res.is_ok()); } - let (prover_key, verifier_key) = CompressedSNARK::<_, _, S1, _, _, S2>::setup(&pp).unwrap(); + let (prover_key, verifier_key) = CompressedSNARK::<_, S1, S2>::setup(&pp).unwrap(); let compressed_prove_res = CompressedSNARK::prove(&pp, &prover_key, &recursive_snark); @@ -544,13 +512,13 @@ mod test { #[test] fn test_nivc_trivial_with_compression() { // ppSNARK - test_nivc_trivial_with_compression_with::, S2<_>>(); - test_nivc_trivial_with_compression_with::, S2<_>>(); - test_nivc_trivial_with_compression_with::, S2<_>>(); + test_nivc_trivial_with_compression_with::, S2<_>>(); + test_nivc_trivial_with_compression_with::, S2<_>>(); + test_nivc_trivial_with_compression_with::, S2<_>>(); // classic SNARK - test_nivc_trivial_with_compression_with::, S2<_>>(); - test_nivc_trivial_with_compression_with::, S2<_>>(); - test_nivc_trivial_with_compression_with::, S2<_>>(); + test_nivc_trivial_with_compression_with::, S2<_>>(); + test_nivc_trivial_with_compression_with::, S2<_>>(); + test_nivc_trivial_with_compression_with::, S2<_>>(); } #[derive(Clone)] @@ -652,12 +620,10 @@ mod test { } } - impl NonUniformCircuit> - for BigTestCircuit - where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - { + impl NonUniformCircuit for BigTestCircuit { + type C1 = Self; + type C2 = TrivialSecondaryCircuit< as Engine>::Scalar>; + fn num_circuits(&self) -> usize { 2 } @@ -670,19 +636,18 @@ mod test { } } - fn secondary_circuit(&self) -> TrivialSecondaryCircuit { + fn secondary_circuit(&self) -> Self::C2 { Default::default() } } - fn test_compression_with_circuit_size_difference_with() + fn test_compression_with_circuit_size_difference_with() where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E1: CurveCycleEquipped, S1: BatchedRelaxedR1CSSNARKTrait, - S2: RelaxedR1CSSNARKTrait, + S2: RelaxedR1CSSNARKTrait>, ::Repr: Abomonation, - ::Repr: Abomonation, + < as Engine>::Scalar as PrimeField>::Repr: Abomonation, { const NUM_STEPS: usize = 4; @@ -692,7 +657,7 @@ mod test { let pp = PublicParams::setup(&test_circuits[0], &*S1::ck_floor(), &*S2::ck_floor()); let z0_primary = vec![E1::Scalar::from(17u64)]; - let z0_secondary = vec![::Scalar::ZERO]; + let z0_secondary = vec![ as Engine>::Scalar::ZERO]; let mut recursive_snark = RecursiveSNARK::new( &pp, @@ -713,7 +678,7 @@ mod test { assert!(verify_res.is_ok()); } - let (prover_key, verifier_key) = CompressedSNARK::<_, _, S1, _, _, S2>::setup(&pp).unwrap(); + let (prover_key, verifier_key) = CompressedSNARK::<_, S1, S2>::setup(&pp).unwrap(); let compressed_prove_res = CompressedSNARK::prove(&pp, &prover_key, &recursive_snark); @@ -730,25 +695,12 @@ mod test { #[test] fn test_compression_with_circuit_size_difference() { // ppSNARK - test_compression_with_circuit_size_difference_with::, S2<_>>( - ); - test_compression_with_circuit_size_difference_with::, S2<_>>( - ); - test_compression_with_circuit_size_difference_with::< - Secp256k1Engine, - Secq256k1Engine, - S1PP<_>, - S2<_>, - >(); + test_compression_with_circuit_size_difference_with::, S2<_>>(); + test_compression_with_circuit_size_difference_with::, S2<_>>(); + test_compression_with_circuit_size_difference_with::, S2<_>>(); // classic SNARK - test_compression_with_circuit_size_difference_with::, S2<_>>(); - test_compression_with_circuit_size_difference_with::, S2<_>>( - ); - test_compression_with_circuit_size_difference_with::< - Secp256k1Engine, - Secq256k1Engine, - S1<_>, - S2<_>, - >(); + test_compression_with_circuit_size_difference_with::, S2<_>>(); + test_compression_with_circuit_size_difference_with::, S2<_>>(); + test_compression_with_circuit_size_difference_with::, S2<_>>(); } } diff --git a/src/supernova/test.rs b/src/supernova/test.rs index e08ffb2ef..6f833f1b1 100644 --- a/src/supernova/test.rs +++ b/src/supernova/test.rs @@ -1,14 +1,10 @@ use crate::gadgets::utils::alloc_zero; use crate::provider::poseidon::PoseidonConstantsCircuit; use crate::provider::Bn256Engine; -use crate::provider::GrumpkinEngine; use crate::provider::PallasEngine; use crate::provider::Secp256k1Engine; -use crate::provider::Secq256k1Engine; use crate::provider::VestaEngine; -use crate::supernova::circuit::{ - EnforcingStepCircuit, StepCircuit, TrivialSecondaryCircuit, TrivialTestCircuit, -}; +use crate::supernova::circuit::{StepCircuit, TrivialSecondaryCircuit, TrivialTestCircuit}; use crate::traits::snark::default_ck_hint; use crate::{bellpepper::test_shape_cs::TestShapeCS, gadgets::utils::alloc_one}; use abomonation::Abomonation; @@ -226,27 +222,29 @@ where } } -fn print_constraints_name_on_error_index( +fn print_constraints_name_on_error_index< + E1, + C1: StepCircuit, + C2: StepCircuit< as Engine>::Scalar>, +>( err: &SuperNovaError, - pp: &PublicParams, + pp: &PublicParams, c_primary: &C1, c_secondary: &C2, num_augmented_circuits: usize, ) where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - C1: EnforcingStepCircuit, - C2: EnforcingStepCircuit, + E1: CurveCycleEquipped, { match err { SuperNovaError::UnSatIndex(msg, index) if *msg == "r_primary" => { - let circuit_primary: SuperNovaAugmentedCircuit<'_, E2, C1> = SuperNovaAugmentedCircuit::new( - &pp.augmented_circuit_params_primary, - None, - c_primary, - pp.ro_consts_circuit_primary.clone(), - num_augmented_circuits, - ); + let circuit_primary: SuperNovaAugmentedCircuit<'_, SecEng, C1> = + SuperNovaAugmentedCircuit::new( + &pp.augmented_circuit_params_primary, + None, + c_primary, + pp.ro_consts_circuit_primary.clone(), + num_augmented_circuits, + ); let mut cs: TestShapeCS = TestShapeCS::new(); let _ = circuit_primary.synthesize(&mut cs); cs.constraints @@ -261,7 +259,7 @@ fn print_constraints_name_on_error_index( pp.ro_consts_circuit_secondary.clone(), num_augmented_circuits, ); - let mut cs: TestShapeCS = TestShapeCS::new(); + let mut cs: TestShapeCS> = TestShapeCS::new(); let _ = circuit_secondary.synthesize(&mut cs); cs.constraints .get(*index) @@ -274,13 +272,9 @@ fn print_constraints_name_on_error_index( const OPCODE_0: usize = 0; const OPCODE_1: usize = 1; -struct TestROM -where - E1: Engine::Scalar>, - E2: Engine::Scalar>, -{ +struct TestROM { rom: Vec, - _p: PhantomData<(E1, E2, S)>, + _p: PhantomData, } #[derive(Debug, Clone)] @@ -317,18 +311,18 @@ impl StepCircuit for TestROMCircuit { } } -impl - NonUniformCircuit, E2, TrivialSecondaryCircuit> - for TestROM> +impl NonUniformCircuit for TestROM where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E1: CurveCycleEquipped, { + type C1 = TestROMCircuit; + type C2 = TrivialSecondaryCircuit< as Engine>::Scalar>; + fn num_circuits(&self) -> usize { 2 } - fn primary_circuit(&self, circuit_index: usize) -> TestROMCircuit { + fn primary_circuit(&self, circuit_index: usize) -> Self::C1 { match circuit_index { 0 => TestROMCircuit::Cubic(CubicCircuit::new(circuit_index, self.rom.len())), 1 => TestROMCircuit::Square(SquareCircuit::new(circuit_index, self.rom.len())), @@ -336,7 +330,7 @@ where } } - fn secondary_circuit(&self) -> TrivialSecondaryCircuit { + fn secondary_circuit(&self) -> Self::C2 { Default::default() } @@ -345,11 +339,7 @@ where } } -impl TestROM -where - E1: Engine::Scalar>, - E2: Engine::Scalar>, -{ +impl TestROM { fn new(rom: Vec) -> Self { Self { rom, @@ -358,10 +348,9 @@ where } } -fn test_trivial_nivc_with() +fn test_trivial_nivc_with() where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E1: CurveCycleEquipped, { // Here demo a simple RAM machine // - with 2 argumented circuit @@ -382,7 +371,7 @@ where OPCODE_1, ]; // Rom can be arbitrary length. - let test_rom = TestROM::>::new(rom); + let test_rom = TestROM::::new(rom); let pp = PublicParams::setup(&test_rom, &*default_ck_hint(), &*default_ck_hint()); @@ -395,9 +384,9 @@ where .iter() .map(|opcode| ::Scalar::from(*opcode as u64)), ); - let z0_secondary = vec![::Scalar::ONE]; + let z0_secondary = vec![ as Engine>::Scalar::ONE]; - let mut recursive_snark_option: Option> = None; + let mut recursive_snark_option: Option> = None; for &op_code in test_rom.rom.iter() { let circuit_primary = test_rom.primary_circuit(op_code); @@ -456,7 +445,7 @@ where #[tracing_test::traced_test] fn test_trivial_nivc() { // Experimenting with selecting the running claims for nifs - test_trivial_nivc_with::(); + test_trivial_nivc_with::(); } // In the following we use 1 to refer to the primary, and 2 to refer to the secondary circuit @@ -575,19 +564,16 @@ fn test_recursive_circuit() { ); } -fn test_pp_digest_with(non_uniform_circuit: &NC, expected: &Expect) +fn test_pp_digest_with(non_uniform_circuit: &NC, expected: &Expect) where - E1: Engine::Scalar>, - E2: Engine::Scalar>, - C1: StepCircuit, - C2: StepCircuit, - NC: NonUniformCircuit, + E1: CurveCycleEquipped, + NC: NonUniformCircuit, { // TODO: add back in https://github.com/lurk-lab/arecibo/issues/53 // // 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::::setup( + let pp = PublicParams::::setup( non_uniform_circuit, &*default_ck_hint(), &*default_ck_hint(), @@ -611,13 +597,9 @@ fn test_supernova_pp_digest() { OPCODE_1, OPCODE_1, OPCODE_0, OPCODE_0, OPCODE_1, OPCODE_1, OPCODE_0, OPCODE_0, OPCODE_1, OPCODE_1, ]; // Rom can be arbitrary length. - let test_rom = TestROM::< - PallasEngine, - VestaEngine, - TrivialSecondaryCircuit<::Scalar>, - >::new(rom); + let test_rom = TestROM::::new(rom); - test_pp_digest_with::( + test_pp_digest_with::( &test_rom, &expect!["95f57227c5d62d13b9fe55deac13b8bd099b068bcc785d7b3a054bf376f68e00"], ); @@ -626,13 +608,9 @@ fn test_supernova_pp_digest() { OPCODE_1, OPCODE_1, OPCODE_0, OPCODE_0, OPCODE_1, OPCODE_1, OPCODE_0, OPCODE_0, OPCODE_1, OPCODE_1, ]; // Rom can be arbitrary length. - let test_rom_grumpkin = TestROM::< - Bn256Engine, - GrumpkinEngine, - TrivialSecondaryCircuit<::Scalar>, - >::new(rom); + let test_rom_grumpkin = TestROM::::new(rom); - test_pp_digest_with::( + test_pp_digest_with::( &test_rom_grumpkin, &expect!["d439e957618eb071360f9c87c0014fd0cfa21f1271813004d18f967355912a01"], ); @@ -641,13 +619,9 @@ fn test_supernova_pp_digest() { OPCODE_1, OPCODE_1, OPCODE_0, OPCODE_0, OPCODE_1, OPCODE_1, OPCODE_0, OPCODE_0, OPCODE_1, OPCODE_1, ]; // Rom can be arbitrary length. - let test_rom_secp = TestROM::< - Secp256k1Engine, - Secq256k1Engine, - TrivialSecondaryCircuit<::Scalar>, - >::new(rom); + let test_rom_secp = TestROM::::new(rom); - test_pp_digest_with::( + test_pp_digest_with::( &test_rom_secp, &expect!["5dfc2cc21f0a29a67ec3b3cbb7fbff535c876ef51e655f4abf4c00e058175103"], ); @@ -816,12 +790,13 @@ where } } -impl NonUniformCircuit> - for RootCheckingCircuit +impl NonUniformCircuit for RootCheckingCircuit where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E1: CurveCycleEquipped, { + type C1 = Self; + type C2 = TrivialSecondaryCircuit< as Engine>::Scalar>; + fn num_circuits(&self) -> usize { 2 } @@ -834,18 +809,17 @@ where } } - fn secondary_circuit(&self) -> TrivialSecondaryCircuit { + fn secondary_circuit(&self) -> Self::C2 { TrivialSecondaryCircuit::::default() } } -fn test_nivc_nondet_with() +fn test_nivc_nondet_with() where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E1: CurveCycleEquipped, // this is due to the reliance on Abomonation <::Scalar as PrimeField>::Repr: Abomonation, - <::Scalar as PrimeField>::Repr: Abomonation, + < as Engine>::Scalar as PrimeField>::Repr: Abomonation, { let circuit_secondary = TrivialSecondaryCircuit::default(); @@ -854,20 +828,15 @@ where // produce non-deterministic hint let (z0_primary, roots) = RootCheckingCircuit::new(num_steps); assert_eq!(num_steps, roots.len()); - let z0_secondary = vec![::Scalar::ZERO]; + let z0_secondary = vec![ as Engine>::Scalar::ZERO]; // produce public parameters - let pp = PublicParams::< - E1, - RootCheckingCircuit<::Scalar>, - E2, - TrivialSecondaryCircuit<::Scalar>, - >::setup(&roots[0], &*default_ck_hint(), &*default_ck_hint()); + let pp = PublicParams::::setup(&roots[0], &*default_ck_hint(), &*default_ck_hint()); // produce a recursive SNARK let circuit_primary = &roots[0]; - let mut recursive_snark = RecursiveSNARK::::new( + let mut recursive_snark = RecursiveSNARK::::new( &pp, circuit_primary, circuit_primary, @@ -900,7 +869,7 @@ where #[test] fn test_nivc_nondet() { - test_nivc_nondet_with::(); - test_nivc_nondet_with::(); - test_nivc_nondet_with::(); + test_nivc_nondet_with::(); + test_nivc_nondet_with::(); + test_nivc_nondet_with::(); } From faca1e6fe8f204d1610d403bcb3023216ad1ef80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Garillot?= Date: Sat, 3 Feb 2024 07:09:56 -0500 Subject: [PATCH 6/8] refactor: Refactor engine parameterization in circuit tests - Simplified engine parameterization by replacing dual `E1` and `E2` variables with a single `E1` in relevant function definitions. - Enhanced code readability by changing type constraints to `CurveCycleEquipped` and implementing the `SecEng` projection across multiple function modules. - Updated calls and variable assignments to align with the new engine parameterization. - Retained original functionalities of the affected functions even with the considerable code modifications and simplifications. --- src/circuit.rs | 44 +++++++++++--------- src/lib.rs | 11 ++--- src/supernova/circuit.rs | 87 +++++++++++++++++++++------------------- src/supernova/mod.rs | 23 +++++------ src/supernova/test.rs | 54 ++++++++++++++----------- 5 files changed, 114 insertions(+), 105 deletions(-) diff --git a/src/circuit.rs b/src/circuit.rs index d84cabd63..b51445fc2 100644 --- a/src/circuit.rs +++ b/src/circuit.rs @@ -372,30 +372,31 @@ mod tests { constants::{BN_LIMB_WIDTH, BN_N_LIMBS}, gadgets::utils::scalar_as_base, provider::{ - poseidon::PoseidonConstantsCircuit, - {Bn256Engine, GrumpkinEngine}, {PallasEngine, VestaEngine}, - {Secp256k1Engine, Secq256k1Engine}, + poseidon::PoseidonConstantsCircuit, Bn256Engine, GrumpkinEngine, PallasEngine, + Secp256k1Engine, Secq256k1Engine, VestaEngine, }, - traits::{circuit::TrivialCircuit, snark::default_ck_hint}, + traits::{circuit::TrivialCircuit, snark::default_ck_hint, CurveCycleEquipped, SecEng}, }; use expect_test::{expect, Expect}; // In the following we use 1 to refer to the primary, and 2 to refer to the secondary circuit - fn test_recursive_circuit_with( + fn test_recursive_circuit_with( primary_params: &NovaAugmentedCircuitParams, secondary_params: &NovaAugmentedCircuitParams, - ro_consts1: ROConstantsCircuit, + ro_consts1: ROConstantsCircuit>, ro_consts2: ROConstantsCircuit, expected_num_constraints_primary: &Expect, expected_num_constraints_secondary: &Expect, ) where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E1: CurveCycleEquipped, { let tc1 = TrivialCircuit::default(); // Initialize the shape and ck for the primary - let circuit1: NovaAugmentedCircuit<'_, E2, TrivialCircuit<::Base>> = - NovaAugmentedCircuit::new(primary_params, None, &tc1, ro_consts1.clone()); + let circuit1: NovaAugmentedCircuit< + '_, + SecEng, + TrivialCircuit< as Engine>::Base>, + > = 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(&*default_ck_hint()); @@ -406,16 +407,16 @@ mod tests { // Initialize the shape and ck for the secondary let circuit2: NovaAugmentedCircuit<'_, E1, TrivialCircuit<::Base>> = NovaAugmentedCircuit::new(secondary_params, None, &tc2, ro_consts2.clone()); - let mut cs: TestShapeCS = TestShapeCS::new(); + let mut cs: TestShapeCS> = TestShapeCS::new(); let _ = circuit2.synthesize(&mut cs); let (shape2, ck2) = cs.r1cs_shape_and_key(&*default_ck_hint()); expected_num_constraints_secondary.assert_eq(&cs.num_constraints().to_string()); // Execute the base case for the primary - let zero1 = <::Base as Field>::ZERO; + let zero1 = < as Engine>::Base as Field>::ZERO; let mut cs1 = SatisfyingAssignment::::new(); - let inputs1: NovaAugmentedCircuitInputs = NovaAugmentedCircuitInputs::new( + let inputs1: NovaAugmentedCircuitInputs> = NovaAugmentedCircuitInputs::new( scalar_as_base::(zero1), // pass zero for testing zero1, vec![zero1], @@ -424,8 +425,11 @@ mod tests { None, None, ); - let circuit1: NovaAugmentedCircuit<'_, E2, TrivialCircuit<::Base>> = - NovaAugmentedCircuit::new(primary_params, Some(inputs1), &tc1, ro_consts1); + let circuit1: NovaAugmentedCircuit< + '_, + SecEng, + TrivialCircuit< as Engine>::Base>, + > = NovaAugmentedCircuit::new(primary_params, Some(inputs1), &tc1, ro_consts1); let _ = circuit1.synthesize(&mut cs1); let (inst1, witness1) = cs1.r1cs_instance_and_witness(&shape1, &ck1).unwrap(); // Make sure that this is satisfiable @@ -433,9 +437,9 @@ mod tests { // Execute the base case for the secondary let zero2 = <::Base as Field>::ZERO; - let mut cs2 = SatisfyingAssignment::::new(); + let mut cs2 = SatisfyingAssignment::>::new(); let inputs2: NovaAugmentedCircuitInputs = NovaAugmentedCircuitInputs::new( - scalar_as_base::(zero2), // pass zero for testing + scalar_as_base::>(zero2), // pass zero for testing zero2, vec![zero2], None, @@ -459,7 +463,7 @@ mod tests { let ro_consts1: ROConstantsCircuit = PoseidonConstantsCircuit::default(); let ro_consts2: ROConstantsCircuit = PoseidonConstantsCircuit::default(); - test_recursive_circuit_with::( + test_recursive_circuit_with::( ¶ms1, ¶ms2, ro_consts1, @@ -476,7 +480,7 @@ mod tests { let ro_consts1: ROConstantsCircuit = PoseidonConstantsCircuit::default(); let ro_consts2: ROConstantsCircuit = PoseidonConstantsCircuit::default(); - test_recursive_circuit_with::( + test_recursive_circuit_with::( ¶ms1, ¶ms2, ro_consts1, @@ -493,7 +497,7 @@ mod tests { let ro_consts1: ROConstantsCircuit = PoseidonConstantsCircuit::default(); let ro_consts2: ROConstantsCircuit = PoseidonConstantsCircuit::default(); - test_recursive_circuit_with::( + test_recursive_circuit_with::( ¶ms1, ¶ms2, ro_consts1, diff --git a/src/lib.rs b/src/lib.rs index 36eaefcae..fc67a0c2e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -985,20 +985,17 @@ where /// /// Note for callers: This function should be called with its performance characteristics in mind. /// It will synthesize and digest the full `circuit` given. -pub fn circuit_digest< - E1: Engine::Scalar>, - E2: Engine::Scalar>, - C: StepCircuit, ->( +pub fn circuit_digest>( circuit: &C, ) -> E1::Scalar { let augmented_circuit_params = NovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, true); // ro_consts_circuit are parameterized by G2 because the type alias uses G2::Base = G1::Scalar - let ro_consts_circuit: ROConstantsCircuit = ROConstantsCircuit::::default(); + let ro_consts_circuit: ROConstantsCircuit> = + ROConstantsCircuit::>::default(); // Initialize ck for the primary - let augmented_circuit: NovaAugmentedCircuit<'_, E2, C> = + let augmented_circuit: NovaAugmentedCircuit<'_, SecEng, C> = NovaAugmentedCircuit::new(&augmented_circuit_params, None, circuit, ro_consts_circuit); let mut cs: ShapeCS = ShapeCS::new(); let _ = augmented_circuit.synthesize(&mut cs); diff --git a/src/supernova/circuit.rs b/src/supernova/circuit.rs index 3a1042725..b1e062342 100644 --- a/src/supernova/circuit.rs +++ b/src/supernova/circuit.rs @@ -709,38 +709,39 @@ mod tests { constants::{BN_LIMB_WIDTH, BN_N_LIMBS}, gadgets::utils::scalar_as_base, provider::{ - poseidon::PoseidonConstantsCircuit, - {Bn256Engine, GrumpkinEngine}, {PallasEngine, VestaEngine}, - {Secp256k1Engine, Secq256k1Engine}, + poseidon::PoseidonConstantsCircuit, Bn256Engine, GrumpkinEngine, PallasEngine, + Secp256k1Engine, Secq256k1Engine, VestaEngine, }, supernova::circuit::TrivialTestCircuit, - traits::snark::default_ck_hint, + traits::{snark::default_ck_hint, CurveCycleEquipped, SecEng}, }; use expect_test::{expect, Expect}; // In the following we use 1 to refer to the primary, and 2 to refer to the secondary circuit - fn test_supernova_recursive_circuit_with( + fn test_supernova_recursive_circuit_with( primary_params: &SuperNovaAugmentedCircuitParams, secondary_params: &SuperNovaAugmentedCircuitParams, - ro_consts1: ROConstantsCircuit, + ro_consts1: ROConstantsCircuit>, ro_consts2: ROConstantsCircuit, num_constraints_primary: &Expect, num_constraints_secondary: &Expect, num_augmented_circuits: usize, ) where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E1: CurveCycleEquipped, { let tc1 = TrivialTestCircuit::default(); // Initialize the shape and ck for the primary - let circuit1: SuperNovaAugmentedCircuit<'_, E2, TrivialTestCircuit<::Base>> = - SuperNovaAugmentedCircuit::new( - primary_params, - None, - &tc1, - ro_consts1.clone(), - num_augmented_circuits, - ); + let circuit1: SuperNovaAugmentedCircuit< + '_, + SecEng, + TrivialTestCircuit< as Engine>::Base>, + > = SuperNovaAugmentedCircuit::new( + primary_params, + None, + &tc1, + ro_consts1.clone(), + num_augmented_circuits, + ); let mut cs: TestShapeCS = TestShapeCS::new(); let _ = circuit1.synthesize(&mut cs); let (shape1, ck1) = cs.r1cs_shape_and_key(&*default_ck_hint()); @@ -757,35 +758,39 @@ mod tests { ro_consts2.clone(), num_augmented_circuits, ); - let mut cs: TestShapeCS = TestShapeCS::new(); + let mut cs: TestShapeCS> = TestShapeCS::new(); let _ = circuit2.synthesize(&mut cs); let (shape2, ck2) = cs.r1cs_shape_and_key(&*default_ck_hint()); num_constraints_secondary.assert_eq(&cs.num_constraints().to_string()); // Execute the base case for the primary - let zero1 = <::Base as Field>::ZERO; + let zero1 = < as Engine>::Base as Field>::ZERO; let mut cs1 = SatisfyingAssignment::::new(); let vzero1 = vec![zero1]; - let inputs1: SuperNovaAugmentedCircuitInputs<'_, E2> = SuperNovaAugmentedCircuitInputs::new( - scalar_as_base::(zero1), // pass zero for testing - zero1, - &vzero1, - None, - None, - None, - None, - Some(zero1), - zero1, - ); - let circuit1: SuperNovaAugmentedCircuit<'_, E2, TrivialTestCircuit<::Base>> = - SuperNovaAugmentedCircuit::new( - primary_params, - Some(inputs1), - &tc1, - ro_consts1, - num_augmented_circuits, + let inputs1: SuperNovaAugmentedCircuitInputs<'_, SecEng> = + SuperNovaAugmentedCircuitInputs::new( + scalar_as_base::(zero1), // pass zero for testing + zero1, + &vzero1, + None, + None, + None, + None, + Some(zero1), + zero1, ); + let circuit1: SuperNovaAugmentedCircuit< + '_, + SecEng, + TrivialTestCircuit< as Engine>::Base>, + > = SuperNovaAugmentedCircuit::new( + primary_params, + Some(inputs1), + &tc1, + ro_consts1, + num_augmented_circuits, + ); let _ = circuit1.synthesize(&mut cs1); let (inst1, witness1) = cs1.r1cs_instance_and_witness(&shape1, &ck1).unwrap(); // Make sure that this is satisfiable @@ -793,10 +798,10 @@ mod tests { // Execute the base case for the secondary let zero2 = <::Base as Field>::ZERO; - let mut cs2 = SatisfyingAssignment::::new(); + let mut cs2 = SatisfyingAssignment::>::new(); let vzero2 = vec![zero2]; let inputs2: SuperNovaAugmentedCircuitInputs<'_, E1> = SuperNovaAugmentedCircuitInputs::new( - scalar_as_base::(zero2), // pass zero for testing + scalar_as_base::>(zero2), // pass zero for testing zero2, &vzero2, None, @@ -828,7 +833,7 @@ mod tests { let ro_consts1: ROConstantsCircuit = PoseidonConstantsCircuit::default(); let ro_consts2: ROConstantsCircuit = PoseidonConstantsCircuit::default(); - test_supernova_recursive_circuit_with::( + test_supernova_recursive_circuit_with::( ¶ms1, ¶ms2, ro_consts1, @@ -847,7 +852,7 @@ mod tests { let ro_consts1: ROConstantsCircuit = PoseidonConstantsCircuit::default(); let ro_consts2: ROConstantsCircuit = PoseidonConstantsCircuit::default(); - test_supernova_recursive_circuit_with::( + test_supernova_recursive_circuit_with::( ¶ms1, ¶ms2, ro_consts1, @@ -866,7 +871,7 @@ mod tests { let ro_consts1: ROConstantsCircuit = PoseidonConstantsCircuit::default(); let ro_consts2: ROConstantsCircuit = PoseidonConstantsCircuit::default(); - test_supernova_recursive_circuit_with::( + test_supernova_recursive_circuit_with::( ¶ms1, ¶ms2, ro_consts1, diff --git a/src/supernova/mod.rs b/src/supernova/mod.rs index 723f19633..9343acb67 100644 --- a/src/supernova/mod.rs +++ b/src/supernova/mod.rs @@ -1149,11 +1149,7 @@ impl> InitialProgramCounter /// /// Note for callers: This function should be called with its performance characteristics in mind. /// It will synthesize and digest the full `circuit` given. -pub fn circuit_digest< - E1: Engine::Scalar>, - E2: Engine::Scalar>, - C: StepCircuit, ->( +pub fn circuit_digest>( circuit: &C, num_augmented_circuits: usize, ) -> E1::Scalar { @@ -1161,16 +1157,17 @@ pub fn circuit_digest< SuperNovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, true); // ro_consts_circuit are parameterized by E2 because the type alias uses E2::Base = E1::Scalar - let ro_consts_circuit: ROConstantsCircuit = ROConstantsCircuit::::default(); + let ro_consts_circuit = ROConstantsCircuit::>::default(); // Initialize ck for the primary - let augmented_circuit: SuperNovaAugmentedCircuit<'_, E2, C> = SuperNovaAugmentedCircuit::new( - &augmented_circuit_params, - None, - circuit, - ro_consts_circuit, - num_augmented_circuits, - ); + let augmented_circuit: SuperNovaAugmentedCircuit<'_, SecEng, C> = + SuperNovaAugmentedCircuit::new( + &augmented_circuit_params, + None, + circuit, + ro_consts_circuit, + num_augmented_circuits, + ); let mut cs: ShapeCS = ShapeCS::new(); let _ = augmented_circuit.synthesize(&mut cs); diff --git a/src/supernova/test.rs b/src/supernova/test.rs index 6f833f1b1..9b481cfb6 100644 --- a/src/supernova/test.rs +++ b/src/supernova/test.rs @@ -449,22 +449,24 @@ fn test_trivial_nivc() { } // In the following we use 1 to refer to the primary, and 2 to refer to the secondary circuit -fn test_recursive_circuit_with( +fn test_recursive_circuit_with( primary_params: &SuperNovaAugmentedCircuitParams, secondary_params: &SuperNovaAugmentedCircuitParams, - ro_consts1: ROConstantsCircuit, + ro_consts1: ROConstantsCircuit>, ro_consts2: ROConstantsCircuit, num_constraints_primary: &Expect, num_constraints_secondary: &Expect, ) where - E1: Engine::Scalar>, - E2: Engine::Scalar>, + E1: CurveCycleEquipped, { // Initialize the shape and ck for the primary let step_circuit1 = TrivialTestCircuit::default(); let arity1 = step_circuit1.arity(); - let circuit1: SuperNovaAugmentedCircuit<'_, E2, TrivialTestCircuit<::Base>> = - SuperNovaAugmentedCircuit::new(primary_params, None, &step_circuit1, ro_consts1.clone(), 2); + let circuit1: SuperNovaAugmentedCircuit< + '_, + SecEng, + TrivialTestCircuit< as Engine>::Base>, + > = SuperNovaAugmentedCircuit::new(primary_params, None, &step_circuit1, ro_consts1.clone(), 2); let mut cs: ShapeCS = ShapeCS::new(); if let Err(e) = circuit1.synthesize(&mut cs) { panic!("{}", e) @@ -483,7 +485,7 @@ fn test_recursive_circuit_with( ro_consts2.clone(), 2, ); - let mut cs: ShapeCS = ShapeCS::new(); + let mut cs: ShapeCS> = ShapeCS::new(); if let Err(e) = circuit2.synthesize(&mut cs) { panic!("{}", e) } @@ -491,23 +493,27 @@ fn test_recursive_circuit_with( num_constraints_secondary.assert_eq(&cs.num_constraints().to_string()); // Execute the base case for the primary - let zero1 = <::Base as Field>::ZERO; + let zero1 = < as Engine>::Base as Field>::ZERO; let z0 = vec![zero1; arity1]; let mut cs1 = SatisfyingAssignment::::new(); - let inputs1: SuperNovaAugmentedCircuitInputs<'_, E2> = SuperNovaAugmentedCircuitInputs::new( - scalar_as_base::(zero1), // pass zero for testing - zero1, - &z0, - None, - None, - None, - None, - Some(zero1), - zero1, - ); + let inputs1: SuperNovaAugmentedCircuitInputs<'_, SecEng> = + SuperNovaAugmentedCircuitInputs::new( + scalar_as_base::(zero1), // pass zero for testing + zero1, + &z0, + None, + None, + None, + None, + Some(zero1), + zero1, + ); let step_circuit = TrivialTestCircuit::default(); - let circuit1: SuperNovaAugmentedCircuit<'_, E2, TrivialTestCircuit<::Base>> = - SuperNovaAugmentedCircuit::new(primary_params, Some(inputs1), &step_circuit, ro_consts1, 2); + let circuit1: SuperNovaAugmentedCircuit< + '_, + SecEng, + TrivialTestCircuit< as Engine>::Base>, + > = SuperNovaAugmentedCircuit::new(primary_params, Some(inputs1), &step_circuit, ro_consts1, 2); if let Err(e) = circuit1.synthesize(&mut cs1) { panic!("{}", e) } @@ -518,9 +524,9 @@ fn test_recursive_circuit_with( // Execute the base case for the secondary let zero2 = <::Base as Field>::ZERO; let z0 = vec![zero2; arity2]; - let mut cs2 = SatisfyingAssignment::::new(); + let mut cs2 = SatisfyingAssignment::>::new(); let inputs2: SuperNovaAugmentedCircuitInputs<'_, E1> = SuperNovaAugmentedCircuitInputs::new( - scalar_as_base::(zero2), // pass zero for testing + scalar_as_base::>(zero2), // pass zero for testing zero2, &z0, None, @@ -554,7 +560,7 @@ fn test_recursive_circuit() { let ro_consts1: ROConstantsCircuit = PoseidonConstantsCircuit::default(); let ro_consts2: ROConstantsCircuit = PoseidonConstantsCircuit::default(); - test_recursive_circuit_with::( + test_recursive_circuit_with::( ¶ms1, ¶ms2, ro_consts1, From 696c96f7e8b688ef9fadf958e7263d688c58868e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Garillot?= Date: Mon, 5 Feb 2024 15:03:23 -0500 Subject: [PATCH 7/8] chore: rename SecEng -> Dual --- benches/common/supernova/mod.rs | 4 +- src/circuit.rs | 22 ++-- src/lib.rs | 196 ++++++++++++++++---------------- src/supernova/circuit.rs | 22 ++-- src/supernova/mod.rs | 104 ++++++++--------- src/supernova/snark.rs | 44 +++---- src/supernova/test.rs | 36 +++--- src/traits/mod.rs | 2 +- 8 files changed, 215 insertions(+), 215 deletions(-) diff --git a/benches/common/supernova/mod.rs b/benches/common/supernova/mod.rs index 27e9155cc..6deee3622 100644 --- a/benches/common/supernova/mod.rs +++ b/benches/common/supernova/mod.rs @@ -7,7 +7,7 @@ pub mod targets; use anyhow::anyhow; use arecibo::{ supernova::{NonUniformCircuit, StepCircuit, TrivialTestCircuit}, - traits::{CurveCycleEquipped, Engine, SecEng}, + traits::{CurveCycleEquipped, Engine, Dual}, }; use bellpepper_core::{num::AllocatedNum, ConstraintSystem, SynthesisError}; use core::marker::PhantomData; @@ -94,7 +94,7 @@ where E1: CurveCycleEquipped, { type C1 = NonTrivialTestCircuit; - type C2 = TrivialTestCircuit< as Engine>::Scalar>; + type C2 = TrivialTestCircuit< as Engine>::Scalar>; fn num_circuits(&self) -> usize { self.num_circuits diff --git a/src/circuit.rs b/src/circuit.rs index b51445fc2..7a051a763 100644 --- a/src/circuit.rs +++ b/src/circuit.rs @@ -375,7 +375,7 @@ mod tests { poseidon::PoseidonConstantsCircuit, Bn256Engine, GrumpkinEngine, PallasEngine, Secp256k1Engine, Secq256k1Engine, VestaEngine, }, - traits::{circuit::TrivialCircuit, snark::default_ck_hint, CurveCycleEquipped, SecEng}, + traits::{circuit::TrivialCircuit, snark::default_ck_hint, CurveCycleEquipped, Dual}, }; use expect_test::{expect, Expect}; @@ -383,7 +383,7 @@ mod tests { fn test_recursive_circuit_with( primary_params: &NovaAugmentedCircuitParams, secondary_params: &NovaAugmentedCircuitParams, - ro_consts1: ROConstantsCircuit>, + ro_consts1: ROConstantsCircuit>, ro_consts2: ROConstantsCircuit, expected_num_constraints_primary: &Expect, expected_num_constraints_secondary: &Expect, @@ -394,8 +394,8 @@ mod tests { // Initialize the shape and ck for the primary let circuit1: NovaAugmentedCircuit< '_, - SecEng, - TrivialCircuit< as Engine>::Base>, + Dual, + TrivialCircuit< as Engine>::Base>, > = NovaAugmentedCircuit::new(primary_params, None, &tc1, ro_consts1.clone()); let mut cs: TestShapeCS = TestShapeCS::new(); let _ = circuit1.synthesize(&mut cs); @@ -407,16 +407,16 @@ mod tests { // Initialize the shape and ck for the secondary let circuit2: NovaAugmentedCircuit<'_, E1, TrivialCircuit<::Base>> = NovaAugmentedCircuit::new(secondary_params, None, &tc2, ro_consts2.clone()); - let mut cs: TestShapeCS> = TestShapeCS::new(); + let mut cs: TestShapeCS> = TestShapeCS::new(); let _ = circuit2.synthesize(&mut cs); let (shape2, ck2) = cs.r1cs_shape_and_key(&*default_ck_hint()); expected_num_constraints_secondary.assert_eq(&cs.num_constraints().to_string()); // Execute the base case for the primary - let zero1 = < as Engine>::Base as Field>::ZERO; + let zero1 = < as Engine>::Base as Field>::ZERO; let mut cs1 = SatisfyingAssignment::::new(); - let inputs1: NovaAugmentedCircuitInputs> = NovaAugmentedCircuitInputs::new( + let inputs1: NovaAugmentedCircuitInputs> = NovaAugmentedCircuitInputs::new( scalar_as_base::(zero1), // pass zero for testing zero1, vec![zero1], @@ -427,8 +427,8 @@ mod tests { ); let circuit1: NovaAugmentedCircuit< '_, - SecEng, - TrivialCircuit< as Engine>::Base>, + Dual, + TrivialCircuit< as Engine>::Base>, > = NovaAugmentedCircuit::new(primary_params, Some(inputs1), &tc1, ro_consts1); let _ = circuit1.synthesize(&mut cs1); let (inst1, witness1) = cs1.r1cs_instance_and_witness(&shape1, &ck1).unwrap(); @@ -437,9 +437,9 @@ mod tests { // Execute the base case for the secondary let zero2 = <::Base as Field>::ZERO; - let mut cs2 = SatisfyingAssignment::>::new(); + let mut cs2 = SatisfyingAssignment::>::new(); let inputs2: NovaAugmentedCircuitInputs = NovaAugmentedCircuitInputs::new( - scalar_as_base::>(zero2), // pass zero for testing + scalar_as_base::>(zero2), // pass zero for testing zero2, vec![zero2], None, diff --git a/src/lib.rs b/src/lib.rs index fc67a0c2e..94abee6d3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,7 +28,7 @@ pub mod traits; pub mod supernova; use once_cell::sync::OnceCell; -use traits::{CurveCycleEquipped, SecEng}; +use traits::{CurveCycleEquipped, Dual}; use crate::digest::{DigestComputer, SimpleDigestible}; use crate::{ @@ -97,13 +97,13 @@ where F_arity_primary: usize, F_arity_secondary: usize, ro_consts_primary: ROConstants, - ro_consts_circuit_primary: ROConstantsCircuit>, + ro_consts_circuit_primary: ROConstantsCircuit>, ck_primary: Arc>, circuit_shape_primary: R1CSWithArity, - ro_consts_secondary: ROConstants>, + ro_consts_secondary: ROConstants>, ro_consts_circuit_secondary: ROConstantsCircuit, - ck_secondary: Arc>>, - circuit_shape_secondary: R1CSWithArity>, + ck_secondary: Arc>>, + circuit_shape_secondary: R1CSWithArity>, augmented_circuit_params_primary: NovaAugmentedCircuitParams, augmented_circuit_params_secondary: NovaAugmentedCircuitParams, #[serde(skip, default = "OnceCell::new")] @@ -121,7 +121,7 @@ where where E1: CurveCycleEquipped, ::Repr: Abomonation, - < as Engine>::Scalar as PrimeField>::Repr: Abomonation, + < as Engine>::Scalar as PrimeField>::Repr: Abomonation, )] pub struct FlatPublicParams where @@ -130,13 +130,13 @@ where F_arity_primary: usize, F_arity_secondary: usize, ro_consts_primary: ROConstants, - ro_consts_circuit_primary: ROConstantsCircuit>, + ro_consts_circuit_primary: ROConstantsCircuit>, ck_primary: CommitmentKey, circuit_shape_primary: R1CSWithArity, - ro_consts_secondary: ROConstants>, + ro_consts_secondary: ROConstants>, ro_consts_circuit_secondary: ROConstantsCircuit, - ck_secondary: CommitmentKey>, - circuit_shape_secondary: R1CSWithArity>, + ck_secondary: CommitmentKey>, + circuit_shape_secondary: R1CSWithArity>, augmented_circuit_params_primary: NovaAugmentedCircuitParams, augmented_circuit_params_secondary: NovaAugmentedCircuitParams, } @@ -243,11 +243,11 @@ where /// /// let pp = PublicParams::setup(&circuit1, &circuit2, ck_hint1, ck_hint2); /// ``` - pub fn setup, C2: StepCircuit< as Engine>::Scalar>>( + pub fn setup, C2: StepCircuit< as Engine>::Scalar>>( c_primary: &C1, c_secondary: &C2, ck_hint1: &CommitmentKeyHint, - ck_hint2: &CommitmentKeyHint>, + ck_hint2: &CommitmentKeyHint>, ) -> Self { let augmented_circuit_params_primary = NovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, true); @@ -255,18 +255,18 @@ where NovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, false); let ro_consts_primary: ROConstants = ROConstants::::default(); - let ro_consts_secondary: ROConstants> = ROConstants::>::default(); + let ro_consts_secondary: ROConstants> = ROConstants::>::default(); let F_arity_primary = c_primary.arity(); let F_arity_secondary = c_secondary.arity(); // ro_consts_circuit_primary are parameterized by E2 because the type alias uses E2::Base = E1::Scalar - let ro_consts_circuit_primary: ROConstantsCircuit> = - ROConstantsCircuit::>::default(); + let ro_consts_circuit_primary: ROConstantsCircuit> = + ROConstantsCircuit::>::default(); let ro_consts_circuit_secondary: ROConstantsCircuit = ROConstantsCircuit::::default(); // Initialize ck for the primary - let circuit_primary: NovaAugmentedCircuit<'_, SecEng, C1> = NovaAugmentedCircuit::new( + let circuit_primary: NovaAugmentedCircuit<'_, Dual, C1> = NovaAugmentedCircuit::new( &augmented_circuit_params_primary, None, c_primary, @@ -285,7 +285,7 @@ where c_secondary, ro_consts_circuit_secondary.clone(), ); - let mut cs: ShapeCS> = ShapeCS::new(); + let mut cs: ShapeCS> = ShapeCS::new(); let _ = circuit_secondary.synthesize(&mut cs); let (r1cs_shape_secondary, ck_secondary) = cs.r1cs_shape_and_key(ck_hint2); let ck_secondary = Arc::new(ck_secondary); @@ -357,22 +357,22 @@ where E1: CurveCycleEquipped, { z0_primary: Vec, - z0_secondary: Vec< as Engine>::Scalar>, + z0_secondary: Vec< as Engine>::Scalar>, r_W_primary: RelaxedR1CSWitness, r_U_primary: RelaxedR1CSInstance, - r_W_secondary: RelaxedR1CSWitness>, - r_U_secondary: RelaxedR1CSInstance>, - l_w_secondary: R1CSWitness>, - l_u_secondary: R1CSInstance>, + r_W_secondary: RelaxedR1CSWitness>, + r_U_secondary: RelaxedR1CSInstance>, + l_w_secondary: R1CSWitness>, + l_u_secondary: R1CSInstance>, /// Buffer for memory needed by the primary fold-step buffer_primary: ResourceBuffer, /// Buffer for memory needed by the secondary fold-step - buffer_secondary: ResourceBuffer>, + buffer_secondary: ResourceBuffer>, i: usize, zi_primary: Vec, - zi_secondary: Vec< as Engine>::Scalar>, + zi_secondary: Vec< as Engine>::Scalar>, } impl RecursiveSNARK @@ -380,12 +380,12 @@ where E1: CurveCycleEquipped, { /// Create new instance of recursive SNARK - pub fn new, C2: StepCircuit< as Engine>::Scalar>>( + pub fn new, C2: StepCircuit< as Engine>::Scalar>>( pp: &PublicParams, c_primary: &C1, c_secondary: &C2, z0_primary: &[E1::Scalar], - z0_secondary: &[ as Engine>::Scalar], + z0_secondary: &[ as Engine>::Scalar], ) -> Result { if z0_primary.len() != pp.F_arity_primary || z0_secondary.len() != pp.F_arity_secondary { return Err(NovaError::InvalidInitialInputLength); @@ -396,7 +396,7 @@ where // base case for the primary let mut cs_primary = SatisfyingAssignment::::new(); - let inputs_primary: NovaAugmentedCircuitInputs> = NovaAugmentedCircuitInputs::new( + let inputs_primary: NovaAugmentedCircuitInputs> = NovaAugmentedCircuitInputs::new( scalar_as_base::(pp.digest()), E1::Scalar::ZERO, z0_primary.to_vec(), @@ -406,7 +406,7 @@ where None, ); - let circuit_primary: NovaAugmentedCircuit<'_, SecEng, C1> = NovaAugmentedCircuit::new( + let circuit_primary: NovaAugmentedCircuit<'_, Dual, C1> = NovaAugmentedCircuit::new( &pp.augmented_circuit_params_primary, Some(inputs_primary), c_primary, @@ -417,10 +417,10 @@ where cs_primary.r1cs_instance_and_witness(r1cs_primary, &pp.ck_primary)?; // base case for the secondary - let mut cs_secondary = SatisfyingAssignment::>::new(); + let mut cs_secondary = SatisfyingAssignment::>::new(); let inputs_secondary: NovaAugmentedCircuitInputs = NovaAugmentedCircuitInputs::new( pp.digest(), - as Engine>::Scalar::ZERO, + as Engine>::Scalar::ZERO, z0_secondary.to_vec(), None, None, @@ -450,9 +450,9 @@ where // IVC proof for the secondary circuit let l_w_secondary = w_secondary; let l_u_secondary = u_secondary; - let r_W_secondary = RelaxedR1CSWitness::>::default(r1cs_secondary); + let r_W_secondary = RelaxedR1CSWitness::>::default(r1cs_secondary); let r_U_secondary = - RelaxedR1CSInstance::>::default(&pp.ck_secondary, r1cs_secondary); + RelaxedR1CSInstance::>::default(&pp.ck_secondary, r1cs_secondary); assert!( !(zi_primary.len() != pp.F_arity_primary || zi_secondary.len() != pp.F_arity_secondary), @@ -467,7 +467,7 @@ where let zi_secondary = zi_secondary .iter() .map(|v| v.get_value().ok_or(SynthesisError::AssignmentMissing)) - .collect:: as Engine>::Scalar>, _>>()?; + .collect:: as Engine>::Scalar>, _>>()?; let buffer_primary = ResourceBuffer { l_w: None, @@ -482,7 +482,7 @@ where l_u: None, ABC_Z_1: R1CSResult::default(r1cs_secondary.num_cons), ABC_Z_2: R1CSResult::default(r1cs_secondary.num_cons), - T: r1cs::default_T::>(r1cs_secondary.num_cons), + T: r1cs::default_T::>(r1cs_secondary.num_cons), }; Ok(Self { @@ -508,7 +508,7 @@ where #[tracing::instrument(skip_all, name = "nova::RecursiveSNARK::prove_step")] pub fn prove_step< C1: StepCircuit, - C2: StepCircuit< as Engine>::Scalar>, + C2: StepCircuit< as Engine>::Scalar>, >( &mut self, pp: &PublicParams, @@ -545,19 +545,19 @@ where pp.circuit_shape_primary.r1cs_shape.num_io + 1, pp.circuit_shape_primary.r1cs_shape.num_vars, ); - let inputs_primary: NovaAugmentedCircuitInputs> = NovaAugmentedCircuitInputs::new( + let inputs_primary: NovaAugmentedCircuitInputs> = NovaAugmentedCircuitInputs::new( scalar_as_base::(pp.digest()), E1::Scalar::from(self.i as u64), self.z0_primary.to_vec(), Some(self.zi_primary.clone()), Some(r_U_secondary_i), Some(l_u_secondary_i), - Some(Commitment::>::decompress( + Some(Commitment::>::decompress( &nifs_secondary.comm_T, )?), ); - let circuit_primary: NovaAugmentedCircuit<'_, SecEng, C1> = NovaAugmentedCircuit::new( + let circuit_primary: NovaAugmentedCircuit<'_, Dual, C1> = NovaAugmentedCircuit::new( &pp.augmented_circuit_params_primary, Some(inputs_primary), c_primary, @@ -584,13 +584,13 @@ where &mut self.buffer_primary.ABC_Z_2, )?; - let mut cs_secondary = SatisfyingAssignment::>::with_capacity( + let mut cs_secondary = SatisfyingAssignment::>::with_capacity( pp.circuit_shape_secondary.r1cs_shape.num_io + 1, pp.circuit_shape_secondary.r1cs_shape.num_vars, ); let inputs_secondary: NovaAugmentedCircuitInputs = NovaAugmentedCircuitInputs::new( pp.digest(), - as Engine>::Scalar::from(self.i as u64), + as Engine>::Scalar::from(self.i as u64), self.z0_secondary.to_vec(), Some(self.zi_secondary.clone()), Some(r_U_primary_i), @@ -618,7 +618,7 @@ where self.zi_secondary = zi_secondary .iter() .map(|v| v.get_value().ok_or(SynthesisError::AssignmentMissing)) - .collect:: as Engine>::Scalar>, _>>()?; + .collect:: as Engine>::Scalar>, _>>()?; self.l_u_secondary = l_u_secondary; self.l_w_secondary = l_w_secondary; @@ -634,8 +634,8 @@ where pp: &PublicParams, num_steps: usize, z0_primary: &[E1::Scalar], - z0_secondary: &[ as Engine>::Scalar], - ) -> Result<(Vec, Vec< as Engine>::Scalar>), NovaError> { + z0_secondary: &[ as Engine>::Scalar], + ) -> Result<(Vec, Vec< as Engine>::Scalar>), NovaError> { // number of steps cannot be zero let is_num_steps_zero = num_steps == 0; @@ -660,7 +660,7 @@ where // check if the output hashes in R1CS instances point to the right running instances let (hash_primary, hash_secondary) = { - let mut hasher = as Engine>::RO::new( + let mut hasher = as Engine>::RO::new( pp.ro_consts_secondary.clone(), NUM_FE_WITHOUT_IO_FOR_CRHF + 2 * pp.F_arity_primary, ); @@ -679,7 +679,7 @@ where NUM_FE_WITHOUT_IO_FOR_CRHF + 2 * pp.F_arity_secondary, ); hasher2.absorb(scalar_as_base::(pp.digest())); - hasher2.absorb( as Engine>::Scalar::from(num_steps as u64)); + hasher2.absorb( as Engine>::Scalar::from(num_steps as u64)); for e in z0_secondary { hasher2.absorb(*e); } @@ -695,7 +695,7 @@ where }; if hash_primary != self.l_u_secondary.X[0] - || hash_secondary != scalar_as_base::>(self.l_u_secondary.X[1]) + || hash_secondary != scalar_as_base::>(self.l_u_secondary.X[1]) { return Err(NovaError::ProofVerifyError); } @@ -738,7 +738,7 @@ where } /// Get the outputs after the last step of computation. - pub fn outputs(&self) -> (&[E1::Scalar], &[ as Engine>::Scalar]) { + pub fn outputs(&self) -> (&[E1::Scalar], &[ as Engine>::Scalar]) { (&self.zi_primary, &self.zi_secondary) } @@ -754,7 +754,7 @@ pub struct ProverKey where E1: CurveCycleEquipped, S1: RelaxedR1CSSNARKTrait, - S2: RelaxedR1CSSNARKTrait>, + S2: RelaxedR1CSSNARKTrait>, { pk_primary: S1::ProverKey, pk_secondary: S2::ProverKey, @@ -767,12 +767,12 @@ pub struct VerifierKey where E1: CurveCycleEquipped, S1: RelaxedR1CSSNARKTrait, - S2: RelaxedR1CSSNARKTrait>, + S2: RelaxedR1CSSNARKTrait>, { F_arity_primary: usize, F_arity_secondary: usize, ro_consts_primary: ROConstants, - ro_consts_secondary: ROConstants>, + ro_consts_secondary: ROConstants>, pp_digest: E1::Scalar, vk_primary: S1::VerifierKey, vk_secondary: S2::VerifierKey, @@ -785,25 +785,25 @@ pub struct CompressedSNARK where E1: CurveCycleEquipped, S1: RelaxedR1CSSNARKTrait, - S2: RelaxedR1CSSNARKTrait>, + S2: RelaxedR1CSSNARKTrait>, { r_U_primary: RelaxedR1CSInstance, r_W_snark_primary: S1, - r_U_secondary: RelaxedR1CSInstance>, - l_u_secondary: R1CSInstance>, - nifs_secondary: NIFS>, + r_U_secondary: RelaxedR1CSInstance>, + l_u_secondary: R1CSInstance>, + nifs_secondary: NIFS>, f_W_snark_secondary: S2, zn_primary: Vec, - zn_secondary: Vec< as Engine>::Scalar>, + zn_secondary: Vec< as Engine>::Scalar>, } impl CompressedSNARK where E1: CurveCycleEquipped, S1: RelaxedR1CSSNARKTrait, - S2: RelaxedR1CSSNARKTrait>, + S2: RelaxedR1CSSNARKTrait>, { /// Creates prover and verifier keys for `CompressedSNARK` pub fn setup( @@ -894,8 +894,8 @@ where vk: &VerifierKey, num_steps: usize, z0_primary: &[E1::Scalar], - z0_secondary: &[ as Engine>::Scalar], - ) -> Result<(Vec, Vec< as Engine>::Scalar>), NovaError> { + z0_secondary: &[ as Engine>::Scalar], + ) -> Result<(Vec, Vec< as Engine>::Scalar>), NovaError> { // the number of steps cannot be zero if num_steps == 0 { return Err(NovaError::ProofVerifyError); @@ -911,7 +911,7 @@ where // check if the output hashes in R1CS instances point to the right running instances let (hash_primary, hash_secondary) = { - let mut hasher = as Engine>::RO::new( + let mut hasher = as Engine>::RO::new( vk.ro_consts_secondary.clone(), NUM_FE_WITHOUT_IO_FOR_CRHF + 2 * vk.F_arity_primary, ); @@ -930,7 +930,7 @@ where NUM_FE_WITHOUT_IO_FOR_CRHF + 2 * vk.F_arity_secondary, ); hasher2.absorb(scalar_as_base::(vk.pp_digest)); - hasher2.absorb( as Engine>::Scalar::from(num_steps as u64)); + hasher2.absorb( as Engine>::Scalar::from(num_steps as u64)); for e in z0_secondary { hasher2.absorb(*e); } @@ -946,7 +946,7 @@ where }; if hash_primary != self.l_u_secondary.X[0] - || hash_secondary != scalar_as_base::>(self.l_u_secondary.X[1]) + || hash_secondary != scalar_as_base::>(self.l_u_secondary.X[1]) { return Err(NovaError::ProofVerifyError); } @@ -991,11 +991,11 @@ pub fn circuit_digest>( let augmented_circuit_params = NovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, true); // ro_consts_circuit are parameterized by G2 because the type alias uses G2::Base = G1::Scalar - let ro_consts_circuit: ROConstantsCircuit> = - ROConstantsCircuit::>::default(); + let ro_consts_circuit: ROConstantsCircuit> = + ROConstantsCircuit::>::default(); // Initialize ck for the primary - let augmented_circuit: NovaAugmentedCircuit<'_, SecEng, C> = + let augmented_circuit: NovaAugmentedCircuit<'_, Dual, C> = NovaAugmentedCircuit::new(&augmented_circuit_params, None, circuit, ro_consts_circuit); let mut cs: ShapeCS = ShapeCS::new(); let _ = augmented_circuit.synthesize(&mut cs); @@ -1080,18 +1080,18 @@ mod tests { where E1: CurveCycleEquipped, E1::GE: DlogGroup, - as Engine>::GE: DlogGroup, + as Engine>::GE: DlogGroup, T1: StepCircuit, - T2: StepCircuit< as Engine>::Scalar>, + T2: StepCircuit< as Engine>::Scalar>, EE1: EvaluationEngineTrait, - EE2: EvaluationEngineTrait>, + EE2: EvaluationEngineTrait>, // this is due to the reliance on Abomonation ::Repr: Abomonation, - < as Engine>::Scalar as PrimeField>::Repr: Abomonation, + < as Engine>::Scalar as PrimeField>::Repr: Abomonation, { // this tests public parameters with a size specifically intended for a spark-compressed SNARK let ck_hint1 = &*SPrime::::ck_floor(); - let ck_hint2 = &*SPrime::, EE2>::ck_floor(); + let ck_hint2 = &*SPrime::, EE2>::ck_floor(); let pp = PublicParams::::setup(circuit1, circuit2, ck_hint1, ck_hint2); let digest_str = pp @@ -1174,7 +1174,7 @@ mod tests { E1: CurveCycleEquipped, { let test_circuit1 = TrivialCircuit::<::Scalar>::default(); - let test_circuit2 = TrivialCircuit::< as Engine>::Scalar>::default(); + let test_circuit2 = TrivialCircuit::< as Engine>::Scalar>::default(); // produce public parameters let pp = PublicParams::::setup( @@ -1191,7 +1191,7 @@ mod tests { &test_circuit1, &test_circuit2, &[::Scalar::ZERO], - &[ as Engine>::Scalar::ZERO], + &[ as Engine>::Scalar::ZERO], ) .unwrap(); @@ -1204,7 +1204,7 @@ mod tests { &pp, num_steps, &[::Scalar::ZERO], - &[ as Engine>::Scalar::ZERO], + &[ as Engine>::Scalar::ZERO], ); assert!(res.is_ok()); } @@ -1239,7 +1239,7 @@ mod tests { &circuit_primary, &circuit_secondary, &[::Scalar::ONE], - &[ as Engine>::Scalar::ZERO], + &[ as Engine>::Scalar::ZERO], ) .unwrap(); @@ -1252,7 +1252,7 @@ mod tests { &pp, i + 1, &[::Scalar::ONE], - &[ as Engine>::Scalar::ZERO], + &[ as Engine>::Scalar::ZERO], ); assert!(res.is_ok()); } @@ -1262,7 +1262,7 @@ mod tests { &pp, num_steps, &[::Scalar::ONE], - &[ as Engine>::Scalar::ZERO], + &[ as Engine>::Scalar::ZERO], ); assert!(res.is_ok()); @@ -1270,14 +1270,14 @@ mod tests { // sanity: check the claimed output with a direct computation of the same assert_eq!(zn_primary, vec![::Scalar::ONE]); - let mut zn_secondary_direct = vec![ as Engine>::Scalar::ZERO]; + let mut zn_secondary_direct = vec![ as Engine>::Scalar::ZERO]; for _i in 0..num_steps { zn_secondary_direct = circuit_secondary.clone().output(&zn_secondary_direct); } assert_eq!(zn_secondary, zn_secondary_direct); assert_eq!( zn_secondary, - vec![ as Engine>::Scalar::from(2460515u64)] + vec![ as Engine>::Scalar::from(2460515u64)] ); } @@ -1292,10 +1292,10 @@ mod tests { where E1: CurveCycleEquipped, EE1: EvaluationEngineTrait, - EE2: EvaluationEngineTrait>, + EE2: EvaluationEngineTrait>, // this is due to the reliance on Abomonation ::Repr: Abomonation, - < as Engine>::Scalar as PrimeField>::Repr: Abomonation, + < as Engine>::Scalar as PrimeField>::Repr: Abomonation, { let circuit_primary = TrivialCircuit::default(); let circuit_secondary = CubicCircuit::default(); @@ -1316,7 +1316,7 @@ mod tests { &circuit_primary, &circuit_secondary, &[::Scalar::ONE], - &[ as Engine>::Scalar::ZERO], + &[ as Engine>::Scalar::ZERO], ) .unwrap(); @@ -1330,7 +1330,7 @@ mod tests { &pp, num_steps, &[::Scalar::ONE], - &[ as Engine>::Scalar::ZERO], + &[ as Engine>::Scalar::ZERO], ); assert!(res.is_ok()); @@ -1338,14 +1338,14 @@ mod tests { // sanity: check the claimed output with a direct computation of the same assert_eq!(zn_primary, vec![::Scalar::ONE]); - let mut zn_secondary_direct = vec![ as Engine>::Scalar::ZERO]; + let mut zn_secondary_direct = vec![ as Engine>::Scalar::ZERO]; for _i in 0..num_steps { zn_secondary_direct = circuit_secondary.clone().output(&zn_secondary_direct); } assert_eq!(zn_secondary, zn_secondary_direct); assert_eq!( zn_secondary, - vec![ as Engine>::Scalar::from(2460515u64)] + vec![ as Engine>::Scalar::from(2460515u64)] ); // produce the prover and verifier keys for compressed snark @@ -1361,7 +1361,7 @@ mod tests { &vk, num_steps, &[::Scalar::ONE], - &[ as Engine>::Scalar::ZERO], + &[ as Engine>::Scalar::ZERO], ); assert!(res.is_ok()); } @@ -1384,10 +1384,10 @@ mod tests { where E1: CurveCycleEquipped, EE1: EvaluationEngineTrait, - EE2: EvaluationEngineTrait>, + EE2: EvaluationEngineTrait>, // this is due to the reliance on Abomonation ::Repr: Abomonation, - < as Engine>::Scalar as PrimeField>::Repr: Abomonation, + < as Engine>::Scalar as PrimeField>::Repr: Abomonation, { let circuit_primary = TrivialCircuit::default(); let circuit_secondary = CubicCircuit::default(); @@ -1408,7 +1408,7 @@ mod tests { &circuit_primary, &circuit_secondary, &[::Scalar::ONE], - &[ as Engine>::Scalar::ZERO], + &[ as Engine>::Scalar::ZERO], ) .unwrap(); @@ -1422,7 +1422,7 @@ mod tests { &pp, num_steps, &[::Scalar::ONE], - &[ as Engine>::Scalar::ZERO], + &[ as Engine>::Scalar::ZERO], ); assert!(res.is_ok()); @@ -1430,14 +1430,14 @@ mod tests { // sanity: check the claimed output with a direct computation of the same assert_eq!(zn_primary, vec![::Scalar::ONE]); - let mut zn_secondary_direct = vec![ as Engine>::Scalar::ZERO]; + let mut zn_secondary_direct = vec![ as Engine>::Scalar::ZERO]; for _i in 0..num_steps { zn_secondary_direct = CubicCircuit::default().output(&zn_secondary_direct); } assert_eq!(zn_secondary, zn_secondary_direct); assert_eq!( zn_secondary, - vec![ as Engine>::Scalar::from(2460515u64)] + vec![ as Engine>::Scalar::from(2460515u64)] ); // run the compressed snark with Spark compiler @@ -1455,7 +1455,7 @@ mod tests { &vk, num_steps, &[::Scalar::ONE], - &[ as Engine>::Scalar::ZERO], + &[ as Engine>::Scalar::ZERO], ); assert!(res.is_ok()); } @@ -1472,10 +1472,10 @@ mod tests { where E1: CurveCycleEquipped, EE1: EvaluationEngineTrait, - EE2: EvaluationEngineTrait>, + EE2: EvaluationEngineTrait>, // this is due to the reliance on Abomonation ::Repr: Abomonation, - < as Engine>::Scalar as PrimeField>::Repr: Abomonation, + < as Engine>::Scalar as PrimeField>::Repr: Abomonation, { // y is a non-deterministic advice representing the fifth root of the input at a step. #[derive(Clone, Debug)] @@ -1552,7 +1552,7 @@ mod tests { // produce non-deterministic advice let (z0_primary, roots) = FifthRootCheckingCircuit::new(num_steps); - let z0_secondary = vec![ as Engine>::Scalar::ZERO]; + let z0_secondary = vec![ as Engine>::Scalar::ZERO]; // produce a recursive SNARK let mut recursive_snark = RecursiveSNARK::::new( @@ -1599,7 +1599,7 @@ mod tests { E1: CurveCycleEquipped, { let test_circuit1 = TrivialCircuit::<::Scalar>::default(); - let test_circuit2 = CubicCircuit::< as Engine>::Scalar>::default(); + let test_circuit2 = CubicCircuit::< as Engine>::Scalar>::default(); // produce public parameters let pp = PublicParams::::setup( @@ -1617,7 +1617,7 @@ mod tests { &test_circuit1, &test_circuit2, &[::Scalar::ONE], - &[ as Engine>::Scalar::ZERO], + &[ as Engine>::Scalar::ZERO], ) .unwrap(); @@ -1631,7 +1631,7 @@ mod tests { &pp, num_steps, &[::Scalar::ONE], - &[ as Engine>::Scalar::ZERO], + &[ as Engine>::Scalar::ZERO], ); assert!(res.is_ok()); @@ -1640,7 +1640,7 @@ mod tests { assert_eq!(zn_primary, vec![::Scalar::ONE]); assert_eq!( zn_secondary, - vec![ as Engine>::Scalar::from(5u64)] + vec![ as Engine>::Scalar::from(5u64)] ); } diff --git a/src/supernova/circuit.rs b/src/supernova/circuit.rs index b1e062342..f9f27c934 100644 --- a/src/supernova/circuit.rs +++ b/src/supernova/circuit.rs @@ -713,7 +713,7 @@ mod tests { Secp256k1Engine, Secq256k1Engine, VestaEngine, }, supernova::circuit::TrivialTestCircuit, - traits::{snark::default_ck_hint, CurveCycleEquipped, SecEng}, + traits::{snark::default_ck_hint, CurveCycleEquipped, Dual}, }; use expect_test::{expect, Expect}; @@ -721,7 +721,7 @@ mod tests { fn test_supernova_recursive_circuit_with( primary_params: &SuperNovaAugmentedCircuitParams, secondary_params: &SuperNovaAugmentedCircuitParams, - ro_consts1: ROConstantsCircuit>, + ro_consts1: ROConstantsCircuit>, ro_consts2: ROConstantsCircuit, num_constraints_primary: &Expect, num_constraints_secondary: &Expect, @@ -733,8 +733,8 @@ mod tests { // Initialize the shape and ck for the primary let circuit1: SuperNovaAugmentedCircuit< '_, - SecEng, - TrivialTestCircuit< as Engine>::Base>, + Dual, + TrivialTestCircuit< as Engine>::Base>, > = SuperNovaAugmentedCircuit::new( primary_params, None, @@ -758,17 +758,17 @@ mod tests { ro_consts2.clone(), num_augmented_circuits, ); - let mut cs: TestShapeCS> = TestShapeCS::new(); + let mut cs: TestShapeCS> = TestShapeCS::new(); let _ = circuit2.synthesize(&mut cs); let (shape2, ck2) = cs.r1cs_shape_and_key(&*default_ck_hint()); num_constraints_secondary.assert_eq(&cs.num_constraints().to_string()); // Execute the base case for the primary - let zero1 = < as Engine>::Base as Field>::ZERO; + let zero1 = < as Engine>::Base as Field>::ZERO; let mut cs1 = SatisfyingAssignment::::new(); let vzero1 = vec![zero1]; - let inputs1: SuperNovaAugmentedCircuitInputs<'_, SecEng> = + let inputs1: SuperNovaAugmentedCircuitInputs<'_, Dual> = SuperNovaAugmentedCircuitInputs::new( scalar_as_base::(zero1), // pass zero for testing zero1, @@ -782,8 +782,8 @@ mod tests { ); let circuit1: SuperNovaAugmentedCircuit< '_, - SecEng, - TrivialTestCircuit< as Engine>::Base>, + Dual, + TrivialTestCircuit< as Engine>::Base>, > = SuperNovaAugmentedCircuit::new( primary_params, Some(inputs1), @@ -798,10 +798,10 @@ mod tests { // Execute the base case for the secondary let zero2 = <::Base as Field>::ZERO; - let mut cs2 = SatisfyingAssignment::>::new(); + let mut cs2 = SatisfyingAssignment::>::new(); let vzero2 = vec![zero2]; let inputs2: SuperNovaAugmentedCircuitInputs<'_, E1> = SuperNovaAugmentedCircuitInputs::new( - scalar_as_base::>(zero2), // pass zero for testing + scalar_as_base::>(zero2), // pass zero for testing zero2, &vzero2, None, diff --git a/src/supernova/mod.rs b/src/supernova/mod.rs index 9343acb67..c2d702656 100644 --- a/src/supernova/mod.rs +++ b/src/supernova/mod.rs @@ -14,7 +14,7 @@ use crate::{ scalar_as_base, traits::{ commitment::{CommitmentEngineTrait, CommitmentTrait}, - AbsorbInROTrait, CurveCycleEquipped, Engine, ROConstants, ROConstantsCircuit, ROTrait, SecEng, + AbsorbInROTrait, CurveCycleEquipped, Engine, ROConstants, ROConstantsCircuit, ROTrait, Dual, }, Commitment, CommitmentKey, R1CSWithArity, }; @@ -89,14 +89,14 @@ where circuit_shapes: Vec>, ro_consts_primary: ROConstants, - ro_consts_circuit_primary: ROConstantsCircuit>, + 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_secondary: ROConstants>, ro_consts_circuit_secondary: ROConstantsCircuit, - ck_secondary: Arc>>, - circuit_shape_secondary: R1CSWithArity>, + ck_secondary: Arc>>, + circuit_shape_secondary: R1CSWithArity>, augmented_circuit_params_secondary: SuperNovaAugmentedCircuitParams, /// Digest constructed from this `PublicParams`' parameters @@ -114,14 +114,14 @@ where E1: CurveCycleEquipped, { ro_consts_primary: ROConstants, - ro_consts_circuit_primary: ROConstantsCircuit>, + 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_secondary: ROConstants>, ro_consts_circuit_secondary: ROConstantsCircuit, - ck_secondary: Arc>>, - circuit_shape_secondary: R1CSWithArity>, + ck_secondary: Arc>>, + circuit_shape_secondary: R1CSWithArity>, augmented_circuit_params_secondary: SuperNovaAugmentedCircuitParams, digest: E1::Scalar, @@ -134,21 +134,21 @@ where where E1: CurveCycleEquipped, ::Repr: Abomonation, - < as Engine>::Scalar as PrimeField>::Repr: Abomonation, + < as Engine>::Scalar as PrimeField>::Repr: Abomonation, )] pub struct FlatAuxParams where E1: CurveCycleEquipped, { ro_consts_primary: ROConstants, - ro_consts_circuit_primary: ROConstantsCircuit>, + ro_consts_circuit_primary: ROConstantsCircuit>, ck_primary: CommitmentKey, // This is shared between all circuit params augmented_circuit_params_primary: SuperNovaAugmentedCircuitParams, - ro_consts_secondary: ROConstants>, + ro_consts_secondary: ROConstants>, ro_consts_circuit_secondary: ROConstantsCircuit, - ck_secondary: CommitmentKey>, - circuit_shape_secondary: R1CSWithArity>, + ck_secondary: CommitmentKey>, + circuit_shape_secondary: R1CSWithArity>, augmented_circuit_params_secondary: SuperNovaAugmentedCircuitParams, #[abomonate_with(::Repr)] @@ -241,7 +241,7 @@ where pub fn setup>( non_uniform_circuit: &NC, ck_hint1: &CommitmentKeyHint, - ck_hint2: &CommitmentKeyHint>, + ck_hint2: &CommitmentKeyHint>, ) -> Self { let num_circuits = non_uniform_circuit.num_circuits(); @@ -249,15 +249,15 @@ where SuperNovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, true); let ro_consts_primary: ROConstants = ROConstants::::default(); // ro_consts_circuit_primary are parameterized by E2 because the type alias uses E2::Base = E1::Scalar - let ro_consts_circuit_primary: ROConstantsCircuit> = - ROConstantsCircuit::>::default(); + let ro_consts_circuit_primary: ROConstantsCircuit> = + ROConstantsCircuit::>::default(); let circuit_shapes = (0..num_circuits) .map(|i| { let c_primary = non_uniform_circuit.primary_circuit(i); let F_arity = c_primary.arity(); // Initialize ck for the primary - let circuit_primary: SuperNovaAugmentedCircuit<'_, SecEng, NC::C1> = + let circuit_primary: SuperNovaAugmentedCircuit<'_, Dual, NC::C1> = SuperNovaAugmentedCircuit::new( &augmented_circuit_params_primary, None, @@ -281,7 +281,7 @@ where let augmented_circuit_params_secondary = SuperNovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, false); - let ro_consts_secondary = ROConstants::>::default(); + let ro_consts_secondary = ROConstants::>::default(); let c_secondary = non_uniform_circuit.secondary_circuit(); let F_arity_secondary = c_secondary.arity(); let ro_consts_circuit_secondary: ROConstantsCircuit = ROConstantsCircuit::::default(); @@ -294,7 +294,7 @@ where ro_consts_circuit_secondary.clone(), num_circuits, ); - let mut cs: ShapeCS> = ShapeCS::new(); + let mut cs: ShapeCS> = ShapeCS::new(); circuit_secondary .synthesize(&mut cs) .expect("circuit synthesis failed"); @@ -487,7 +487,7 @@ where /// Buffer for memory needed by the primary fold-step buffer_primary: ResourceBuffer, /// Buffer for memory needed by the secondary fold-step - buffer_secondary: ResourceBuffer>, + buffer_secondary: ResourceBuffer>, // Relaxed instances for the primary circuits // Entries are `None` if the circuit has not been executed yet @@ -495,14 +495,14 @@ where r_U_primary: Vec>>, // Inputs and outputs of the secondary circuit - z0_secondary: Vec< as Engine>::Scalar>, - zi_secondary: Vec< as Engine>::Scalar>, + z0_secondary: Vec< as Engine>::Scalar>, + zi_secondary: Vec< as Engine>::Scalar>, // Relaxed instance for the secondary circuit - r_W_secondary: RelaxedR1CSWitness>, - r_U_secondary: RelaxedR1CSInstance>, + r_W_secondary: RelaxedR1CSWitness>, + r_U_secondary: RelaxedR1CSInstance>, // Proof for the secondary circuit to be accumulated into r_secondary in the next iteration - l_w_secondary: R1CSWitness>, - l_u_secondary: R1CSInstance>, + l_w_secondary: R1CSWitness>, + l_u_secondary: R1CSInstance>, } impl RecursiveSNARK @@ -517,7 +517,7 @@ where c_primary: &C0::C1, c_secondary: &C0::C2, z0_primary: &[E1::Scalar], - z0_secondary: &[ as Engine>::Scalar], + z0_secondary: &[ as Engine>::Scalar], ) -> Result { let num_augmented_circuits = non_uniform_circuit.num_circuits(); let circuit_index = non_uniform_circuit.initial_circuit_index(); @@ -544,7 +544,7 @@ where // base case for the primary let mut cs_primary = SatisfyingAssignment::::new(); let program_counter = E1::Scalar::from(circuit_index as u64); - let inputs_primary: SuperNovaAugmentedCircuitInputs<'_, SecEng> = + let inputs_primary: SuperNovaAugmentedCircuitInputs<'_, Dual> = SuperNovaAugmentedCircuitInputs::new( scalar_as_base::(pp.digest()), E1::Scalar::ZERO, @@ -557,7 +557,7 @@ where E1::Scalar::ZERO, // u_index is always zero for the primary circuit ); - let circuit_primary: SuperNovaAugmentedCircuit<'_, SecEng, C0::C1> = + let circuit_primary: SuperNovaAugmentedCircuit<'_, Dual, C0::C1> = SuperNovaAugmentedCircuit::new( &pp.augmented_circuit_params_primary, Some(inputs_primary), @@ -584,12 +584,12 @@ where })?; // base case for the secondary - let mut cs_secondary = SatisfyingAssignment::>::new(); - let u_primary_index = as Engine>::Scalar::from(circuit_index as u64); + let mut cs_secondary = SatisfyingAssignment::>::new(); + let u_primary_index = as Engine>::Scalar::from(circuit_index as u64); let inputs_secondary: SuperNovaAugmentedCircuitInputs<'_, E1> = SuperNovaAugmentedCircuitInputs::new( pp.digest(), - as Engine>::Scalar::ZERO, + as Engine>::Scalar::ZERO, z0_secondary, None, // zi = None for basecase None, // U = Empty list of accumulators for the primary circuits @@ -634,7 +634,7 @@ where let l_u_secondary = u_secondary; // Initialize relaxed instance/witness pair for the secondary circuit proofs - let r_W_secondary = RelaxedR1CSWitness::>::default(r1cs_secondary); + let r_W_secondary = RelaxedR1CSWitness::>::default(r1cs_secondary); let r_U_secondary = RelaxedR1CSInstance::default(&*pp.ck_secondary, r1cs_secondary); // Outputs of the two circuits and next program counter thus far. @@ -655,7 +655,7 @@ where v.get_value() .ok_or(NovaError::from(SynthesisError::AssignmentMissing).into()) }) - .collect:: as Engine>::Scalar>, SuperNovaError>>()?; + .collect:: as Engine>::Scalar>, SuperNovaError>>()?; // handle the base case by initialize U_next in next round let r_W_primary_initial_list = (0..num_augmented_circuits) @@ -687,7 +687,7 @@ where l_u: None, ABC_Z_1: R1CSResult::default(r1cs_secondary.num_cons), ABC_Z_2: R1CSResult::default(r1cs_secondary.num_cons), - T: r1cs::default_T::>(r1cs_secondary.num_cons), + T: r1cs::default_T::>(r1cs_secondary.num_cons), }; Ok(Self { @@ -719,7 +719,7 @@ where #[tracing::instrument(skip_all, name = "supernova::RecursiveSNARK::prove_step")] pub fn prove_step< C1: StepCircuit, - C2: StepCircuit< as Engine>::Scalar>, + C2: StepCircuit< as Engine>::Scalar>, >( &mut self, pp: &PublicParams, @@ -761,9 +761,9 @@ where pp[circuit_index].r1cs_shape.num_io + 1, pp[circuit_index].r1cs_shape.num_vars, ); - let T = Commitment::>::decompress(&nifs_secondary.comm_T) + let T = Commitment::>::decompress(&nifs_secondary.comm_T) .map_err(SuperNovaError::NovaError)?; - let inputs_primary: SuperNovaAugmentedCircuitInputs<'_, SecEng> = + let inputs_primary: SuperNovaAugmentedCircuitInputs<'_, Dual> = SuperNovaAugmentedCircuitInputs::new( scalar_as_base::(self.pp_digest), E1::Scalar::from(self.i as u64), @@ -776,7 +776,7 @@ where E1::Scalar::ZERO, ); - let circuit_primary: SuperNovaAugmentedCircuit<'_, SecEng, C1> = + let circuit_primary: SuperNovaAugmentedCircuit<'_, Dual, C1> = SuperNovaAugmentedCircuit::new( &pp.augmented_circuit_params_primary, Some(inputs_primary), @@ -831,7 +831,7 @@ where ) .map_err(SuperNovaError::NovaError)?; - let mut cs_secondary = SatisfyingAssignment::>::with_capacity( + let mut cs_secondary = SatisfyingAssignment::>::with_capacity( pp.circuit_shape_secondary.r1cs_shape.num_io + 1, pp.circuit_shape_secondary.r1cs_shape.num_vars, ); @@ -840,14 +840,14 @@ where let inputs_secondary: SuperNovaAugmentedCircuitInputs<'_, E1> = SuperNovaAugmentedCircuitInputs::new( self.pp_digest, - as Engine>::Scalar::from(self.i as u64), + as Engine>::Scalar::from(self.i as u64), &self.z0_secondary, Some(&self.zi_secondary), Some(&r_U_primary_i), Some(&l_u_primary), Some(&binding), None, // pc is always None for secondary circuit - as Engine>::Scalar::from(circuit_index as u64), + as Engine>::Scalar::from(circuit_index as u64), ); let circuit_secondary: SuperNovaAugmentedCircuit<'_, E1, C2> = SuperNovaAugmentedCircuit::new( @@ -887,7 +887,7 @@ where v.get_value() .ok_or(NovaError::from(SynthesisError::AssignmentMissing).into()) }) - .collect:: as Engine>::Scalar>, SuperNovaError>>()?; + .collect:: as Engine>::Scalar>, SuperNovaError>>()?; if zi_primary.len() != pp[circuit_index].F_arity || zi_secondary.len() != pp.circuit_shape_secondary.F_arity @@ -912,8 +912,8 @@ where &self, pp: &PublicParams, z0_primary: &[E1::Scalar], - z0_secondary: &[ as Engine>::Scalar], - ) -> Result<(Vec, Vec< as Engine>::Scalar>), SuperNovaError> { + z0_secondary: &[ as Engine>::Scalar], + ) -> Result<(Vec, Vec< as Engine>::Scalar>), SuperNovaError> { // number of steps cannot be zero if self.i == 0 { debug!("must verify on valid RecursiveSNARK where i > 0"); @@ -993,7 +993,7 @@ where true, // is_primary ); - let mut hasher = as Engine>::RO::new(pp.ro_consts_secondary.clone(), num_absorbs); + let mut hasher = as Engine>::RO::new(pp.ro_consts_secondary.clone(), num_absorbs); hasher.absorb(self.pp_digest); hasher.absorb(E1::Scalar::from(self.i as u64)); hasher.absorb(self.program_counter); @@ -1018,7 +1018,7 @@ where ); let mut hasher = ::RO::new(pp.ro_consts_primary.clone(), num_absorbs); hasher.absorb(scalar_as_base::(self.pp_digest)); - hasher.absorb( as Engine>::Scalar::from(self.i as u64)); + hasher.absorb( as Engine>::Scalar::from(self.i as u64)); for e in z0_secondary { hasher.absorb(*e); @@ -1045,7 +1045,7 @@ where ); return Err(SuperNovaError::NovaError(NovaError::ProofVerifyError)); } - if hash_secondary != scalar_as_base::>(self.l_u_secondary.X[1]) { + if hash_secondary != scalar_as_base::>(self.l_u_secondary.X[1]) { debug!( "hash_secondary {:?} not equal l_u_secondary.X[1] {:?}", hash_secondary, self.l_u_secondary.X[1] @@ -1115,7 +1115,7 @@ where /// The type of the step-circuits on the primary type C1: StepCircuit; /// The type of the step-circuits on the secondary - type C2: StepCircuit< as Engine>::Scalar>; + type C2: StepCircuit< as Engine>::Scalar>; /// Initial circuit index, defaults to zero. fn initial_circuit_index(&self) -> usize { @@ -1157,10 +1157,10 @@ pub fn circuit_digest>( SuperNovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, true); // ro_consts_circuit are parameterized by E2 because the type alias uses E2::Base = E1::Scalar - let ro_consts_circuit = ROConstantsCircuit::>::default(); + let ro_consts_circuit = ROConstantsCircuit::>::default(); // Initialize ck for the primary - let augmented_circuit: SuperNovaAugmentedCircuit<'_, SecEng, C> = + let augmented_circuit: SuperNovaAugmentedCircuit<'_, Dual, C> = SuperNovaAugmentedCircuit::new( &augmented_circuit_params, None, diff --git a/src/supernova/snark.rs b/src/supernova/snark.rs index f681e16d5..c32babe0f 100644 --- a/src/supernova/snark.rs +++ b/src/supernova/snark.rs @@ -6,7 +6,7 @@ use crate::{ r1cs::{R1CSInstance, RelaxedR1CSWitness}, traits::{ snark::{BatchedRelaxedR1CSSNARKTrait, RelaxedR1CSSNARKTrait}, - AbsorbInROTrait, CurveCycleEquipped, Engine, ROTrait, SecEng, + AbsorbInROTrait, CurveCycleEquipped, Engine, ROTrait, Dual, }, }; use crate::{errors::NovaError, scalar_as_base, RelaxedR1CSInstance, NIFS}; @@ -20,7 +20,7 @@ pub struct ProverKey where E1: CurveCycleEquipped, S1: BatchedRelaxedR1CSSNARKTrait, - S2: RelaxedR1CSSNARKTrait>, + S2: RelaxedR1CSSNARKTrait>, { pk_primary: S1::ProverKey, pk_secondary: S2::ProverKey, @@ -32,7 +32,7 @@ pub struct VerifierKey where E1: CurveCycleEquipped, S1: BatchedRelaxedR1CSSNARKTrait, - S2: RelaxedR1CSSNARKTrait>, + S2: RelaxedR1CSSNARKTrait>, { vk_primary: S1::VerifierKey, vk_secondary: S2::VerifierKey, @@ -45,28 +45,28 @@ pub struct CompressedSNARK where E1: CurveCycleEquipped, S1: BatchedRelaxedR1CSSNARKTrait, - S2: RelaxedR1CSSNARKTrait>, + S2: RelaxedR1CSSNARKTrait>, { r_U_primary: Vec>, r_W_snark_primary: S1, - r_U_secondary: RelaxedR1CSInstance>, - l_u_secondary: R1CSInstance>, - nifs_secondary: NIFS>, + r_U_secondary: RelaxedR1CSInstance>, + l_u_secondary: R1CSInstance>, + nifs_secondary: NIFS>, f_W_snark_secondary: S2, num_steps: usize, program_counter: E1::Scalar, zn_primary: Vec, - zn_secondary: Vec< as Engine>::Scalar>, + zn_secondary: Vec< as Engine>::Scalar>, } impl CompressedSNARK where E1: CurveCycleEquipped, S1: BatchedRelaxedR1CSSNARKTrait, - S2: RelaxedR1CSSNARKTrait>, + S2: RelaxedR1CSSNARKTrait>, { /// Creates prover and verifier keys for `CompressedSNARK` pub fn setup( @@ -180,8 +180,8 @@ where pp: &PublicParams, vk: &VerifierKey, z0_primary: &[E1::Scalar], - z0_secondary: &[ as Engine>::Scalar], - ) -> Result<(Vec, Vec< as Engine>::Scalar>), SuperNovaError> { + z0_secondary: &[ as Engine>::Scalar], + ) -> Result<(Vec, Vec< as Engine>::Scalar>), SuperNovaError> { let last_circuit_idx = field_as_usize(self.program_counter); let num_field_primary_ro = 3 // params_next, i_new, program_counter_new @@ -199,7 +199,7 @@ where // witnesses provided by the prover let (hash_primary, hash_secondary) = { let mut hasher = - as Engine>::RO::new(pp.ro_consts_secondary.clone(), num_field_primary_ro); + as Engine>::RO::new(pp.ro_consts_secondary.clone(), num_field_primary_ro); hasher.absorb(pp.digest()); hasher.absorb(E1::Scalar::from(self.num_steps as u64)); @@ -219,7 +219,7 @@ where ::RO::new(pp.ro_consts_primary.clone(), num_field_secondary_ro); hasher2.absorb(scalar_as_base::(pp.digest())); - hasher2.absorb( as Engine>::Scalar::from(self.num_steps as u64)); + hasher2.absorb( as Engine>::Scalar::from(self.num_steps as u64)); for e in z0_secondary { hasher2.absorb(*e); @@ -244,7 +244,7 @@ where return Err(NovaError::ProofVerifyError.into()); } - if hash_secondary != scalar_as_base::>(self.l_u_secondary.X[1]) { + if hash_secondary != scalar_as_base::>(self.l_u_secondary.X[1]) { return Err(NovaError::ProofVerifyError.into()); } @@ -439,7 +439,7 @@ mod test { impl NonUniformCircuit for TestCircuit { type C1 = Self; - type C2 = TrivialSecondaryCircuit< as Engine>::Scalar>; + type C2 = TrivialSecondaryCircuit< as Engine>::Scalar>; fn num_circuits(&self) -> usize { 2 @@ -462,9 +462,9 @@ mod test { where E1: CurveCycleEquipped, S1: BatchedRelaxedR1CSSNARKTrait, - S2: RelaxedR1CSSNARKTrait>, + S2: RelaxedR1CSSNARKTrait>, ::Repr: Abomonation, - < as Engine>::Scalar as PrimeField>::Repr: Abomonation, + < as Engine>::Scalar as PrimeField>::Repr: Abomonation, { const NUM_STEPS: usize = 6; @@ -474,7 +474,7 @@ mod test { let pp = PublicParams::setup(&test_circuits[0], &*S1::ck_floor(), &*S2::ck_floor()); let z0_primary = vec![E1::Scalar::from(17u64)]; - let z0_secondary = vec![ as Engine>::Scalar::ZERO]; + let z0_secondary = vec![ as Engine>::Scalar::ZERO]; let mut recursive_snark = RecursiveSNARK::new( &pp, @@ -622,7 +622,7 @@ mod test { impl NonUniformCircuit for BigTestCircuit { type C1 = Self; - type C2 = TrivialSecondaryCircuit< as Engine>::Scalar>; + type C2 = TrivialSecondaryCircuit< as Engine>::Scalar>; fn num_circuits(&self) -> usize { 2 @@ -645,9 +645,9 @@ mod test { where E1: CurveCycleEquipped, S1: BatchedRelaxedR1CSSNARKTrait, - S2: RelaxedR1CSSNARKTrait>, + S2: RelaxedR1CSSNARKTrait>, ::Repr: Abomonation, - < as Engine>::Scalar as PrimeField>::Repr: Abomonation, + < as Engine>::Scalar as PrimeField>::Repr: Abomonation, { const NUM_STEPS: usize = 4; @@ -657,7 +657,7 @@ mod test { let pp = PublicParams::setup(&test_circuits[0], &*S1::ck_floor(), &*S2::ck_floor()); let z0_primary = vec![E1::Scalar::from(17u64)]; - let z0_secondary = vec![ as Engine>::Scalar::ZERO]; + let z0_secondary = vec![ as Engine>::Scalar::ZERO]; let mut recursive_snark = RecursiveSNARK::new( &pp, diff --git a/src/supernova/test.rs b/src/supernova/test.rs index 9b481cfb6..c0d8e3939 100644 --- a/src/supernova/test.rs +++ b/src/supernova/test.rs @@ -225,7 +225,7 @@ where fn print_constraints_name_on_error_index< E1, C1: StepCircuit, - C2: StepCircuit< as Engine>::Scalar>, + C2: StepCircuit< as Engine>::Scalar>, >( err: &SuperNovaError, pp: &PublicParams, @@ -237,7 +237,7 @@ fn print_constraints_name_on_error_index< { match err { SuperNovaError::UnSatIndex(msg, index) if *msg == "r_primary" => { - let circuit_primary: SuperNovaAugmentedCircuit<'_, SecEng, C1> = + let circuit_primary: SuperNovaAugmentedCircuit<'_, Dual, C1> = SuperNovaAugmentedCircuit::new( &pp.augmented_circuit_params_primary, None, @@ -259,7 +259,7 @@ fn print_constraints_name_on_error_index< pp.ro_consts_circuit_secondary.clone(), num_augmented_circuits, ); - let mut cs: TestShapeCS> = TestShapeCS::new(); + let mut cs: TestShapeCS> = TestShapeCS::new(); let _ = circuit_secondary.synthesize(&mut cs); cs.constraints .get(*index) @@ -316,7 +316,7 @@ where E1: CurveCycleEquipped, { type C1 = TestROMCircuit; - type C2 = TrivialSecondaryCircuit< as Engine>::Scalar>; + type C2 = TrivialSecondaryCircuit< as Engine>::Scalar>; fn num_circuits(&self) -> usize { 2 @@ -384,7 +384,7 @@ where .iter() .map(|opcode| ::Scalar::from(*opcode as u64)), ); - let z0_secondary = vec![ as Engine>::Scalar::ONE]; + let z0_secondary = vec![ as Engine>::Scalar::ONE]; let mut recursive_snark_option: Option> = None; @@ -452,7 +452,7 @@ fn test_trivial_nivc() { fn test_recursive_circuit_with( primary_params: &SuperNovaAugmentedCircuitParams, secondary_params: &SuperNovaAugmentedCircuitParams, - ro_consts1: ROConstantsCircuit>, + ro_consts1: ROConstantsCircuit>, ro_consts2: ROConstantsCircuit, num_constraints_primary: &Expect, num_constraints_secondary: &Expect, @@ -464,8 +464,8 @@ fn test_recursive_circuit_with( let arity1 = step_circuit1.arity(); let circuit1: SuperNovaAugmentedCircuit< '_, - SecEng, - TrivialTestCircuit< as Engine>::Base>, + Dual, + TrivialTestCircuit< as Engine>::Base>, > = SuperNovaAugmentedCircuit::new(primary_params, None, &step_circuit1, ro_consts1.clone(), 2); let mut cs: ShapeCS = ShapeCS::new(); if let Err(e) = circuit1.synthesize(&mut cs) { @@ -485,7 +485,7 @@ fn test_recursive_circuit_with( ro_consts2.clone(), 2, ); - let mut cs: ShapeCS> = ShapeCS::new(); + let mut cs: ShapeCS> = ShapeCS::new(); if let Err(e) = circuit2.synthesize(&mut cs) { panic!("{}", e) } @@ -493,10 +493,10 @@ fn test_recursive_circuit_with( num_constraints_secondary.assert_eq(&cs.num_constraints().to_string()); // Execute the base case for the primary - let zero1 = < as Engine>::Base as Field>::ZERO; + let zero1 = < as Engine>::Base as Field>::ZERO; let z0 = vec![zero1; arity1]; let mut cs1 = SatisfyingAssignment::::new(); - let inputs1: SuperNovaAugmentedCircuitInputs<'_, SecEng> = + let inputs1: SuperNovaAugmentedCircuitInputs<'_, Dual> = SuperNovaAugmentedCircuitInputs::new( scalar_as_base::(zero1), // pass zero for testing zero1, @@ -511,8 +511,8 @@ fn test_recursive_circuit_with( let step_circuit = TrivialTestCircuit::default(); let circuit1: SuperNovaAugmentedCircuit< '_, - SecEng, - TrivialTestCircuit< as Engine>::Base>, + Dual, + TrivialTestCircuit< as Engine>::Base>, > = SuperNovaAugmentedCircuit::new(primary_params, Some(inputs1), &step_circuit, ro_consts1, 2); if let Err(e) = circuit1.synthesize(&mut cs1) { panic!("{}", e) @@ -524,9 +524,9 @@ fn test_recursive_circuit_with( // Execute the base case for the secondary let zero2 = <::Base as Field>::ZERO; let z0 = vec![zero2; arity2]; - let mut cs2 = SatisfyingAssignment::>::new(); + let mut cs2 = SatisfyingAssignment::>::new(); let inputs2: SuperNovaAugmentedCircuitInputs<'_, E1> = SuperNovaAugmentedCircuitInputs::new( - scalar_as_base::>(zero2), // pass zero for testing + scalar_as_base::>(zero2), // pass zero for testing zero2, &z0, None, @@ -801,7 +801,7 @@ where E1: CurveCycleEquipped, { type C1 = Self; - type C2 = TrivialSecondaryCircuit< as Engine>::Scalar>; + type C2 = TrivialSecondaryCircuit< as Engine>::Scalar>; fn num_circuits(&self) -> usize { 2 @@ -825,7 +825,7 @@ where E1: CurveCycleEquipped, // this is due to the reliance on Abomonation <::Scalar as PrimeField>::Repr: Abomonation, - < as Engine>::Scalar as PrimeField>::Repr: Abomonation, + < as Engine>::Scalar as PrimeField>::Repr: Abomonation, { let circuit_secondary = TrivialSecondaryCircuit::default(); @@ -834,7 +834,7 @@ where // produce non-deterministic hint let (z0_primary, roots) = RootCheckingCircuit::new(num_steps); assert_eq!(num_steps, roots.len()); - let z0_secondary = vec![ as Engine>::Scalar::ZERO]; + let z0_secondary = vec![ as Engine>::Scalar::ZERO]; // produce public parameters let pp = PublicParams::::setup(&roots[0], &*default_ck_hint(), &*default_ck_hint()); diff --git a/src/traits/mod.rs b/src/traits/mod.rs index ed67d0d68..8f2c46653 100644 --- a/src/traits/mod.rs +++ b/src/traits/mod.rs @@ -62,7 +62,7 @@ pub trait CurveCycleEquipped: Engine { } /// Convenience projection to the Secondary Engine of a CurveCycleEquipped -pub type SecEng = ::Secondary; +pub type Dual = ::Secondary; /// A helper trait to absorb different objects in RO pub trait AbsorbInROTrait { From 0dc08a97700137073b806a290cd9b4940e6d8ae1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Garillot?= Date: Mon, 5 Feb 2024 15:04:16 -0500 Subject: [PATCH 8/8] docs: Improve code readability and testing robustness - Improved readability of CurveCycleEquipped function comment in traits module by adding backticks around function name. --- benches/common/supernova/mod.rs | 2 +- src/circuit.rs | 14 ++++---------- src/lib.rs | 20 +++++--------------- src/supernova/mod.rs | 7 ++----- src/supernova/snark.rs | 2 +- src/supernova/test.rs | 23 +++++++++++------------ src/traits/mod.rs | 4 ++-- 7 files changed, 26 insertions(+), 46 deletions(-) diff --git a/benches/common/supernova/mod.rs b/benches/common/supernova/mod.rs index 6deee3622..8ba58dd7f 100644 --- a/benches/common/supernova/mod.rs +++ b/benches/common/supernova/mod.rs @@ -7,7 +7,7 @@ pub mod targets; use anyhow::anyhow; use arecibo::{ supernova::{NonUniformCircuit, StepCircuit, TrivialTestCircuit}, - traits::{CurveCycleEquipped, Engine, Dual}, + traits::{CurveCycleEquipped, Dual, Engine}, }; use bellpepper_core::{num::AllocatedNum, ConstraintSystem, SynthesisError}; use core::marker::PhantomData; diff --git a/src/circuit.rs b/src/circuit.rs index 7a051a763..ebb1c2fe1 100644 --- a/src/circuit.rs +++ b/src/circuit.rs @@ -392,11 +392,8 @@ mod tests { { let tc1 = TrivialCircuit::default(); // Initialize the shape and ck for the primary - let circuit1: NovaAugmentedCircuit< - '_, - Dual, - TrivialCircuit< as Engine>::Base>, - > = NovaAugmentedCircuit::new(primary_params, None, &tc1, ro_consts1.clone()); + let circuit1: NovaAugmentedCircuit<'_, Dual, TrivialCircuit< as Engine>::Base>> = + 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(&*default_ck_hint()); @@ -425,11 +422,8 @@ mod tests { None, None, ); - let circuit1: NovaAugmentedCircuit< - '_, - Dual, - TrivialCircuit< as Engine>::Base>, - > = NovaAugmentedCircuit::new(primary_params, Some(inputs1), &tc1, ro_consts1); + let circuit1: NovaAugmentedCircuit<'_, Dual, TrivialCircuit< as Engine>::Base>> = + NovaAugmentedCircuit::new(primary_params, Some(inputs1), &tc1, ro_consts1); let _ = circuit1.synthesize(&mut cs1); let (inst1, witness1) = cs1.r1cs_instance_and_witness(&shape1, &ck1).unwrap(); // Make sure that this is satisfiable diff --git a/src/lib.rs b/src/lib.rs index 94abee6d3..d00386fc1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -451,8 +451,7 @@ where let l_w_secondary = w_secondary; let l_u_secondary = u_secondary; let r_W_secondary = RelaxedR1CSWitness::>::default(r1cs_secondary); - let r_U_secondary = - RelaxedR1CSInstance::>::default(&pp.ck_secondary, r1cs_secondary); + 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), @@ -506,10 +505,7 @@ where /// Create a new `RecursiveSNARK` (or updates the provided `RecursiveSNARK`) /// by executing a step of the incremental computation #[tracing::instrument(skip_all, name = "nova::RecursiveSNARK::prove_step")] - pub fn prove_step< - C1: StepCircuit, - C2: StepCircuit< as Engine>::Scalar>, - >( + pub fn prove_step, C2: StepCircuit< as Engine>::Scalar>>( &mut self, pp: &PublicParams, c_primary: &C1, @@ -552,9 +548,7 @@ where Some(self.zi_primary.clone()), Some(r_U_secondary_i), Some(l_u_secondary_i), - Some(Commitment::>::decompress( - &nifs_secondary.comm_T, - )?), + Some(Commitment::>::decompress(&nifs_secondary.comm_T)?), ); let circuit_primary: NovaAugmentedCircuit<'_, Dual, C1> = NovaAugmentedCircuit::new( @@ -991,8 +985,7 @@ pub fn circuit_digest>( let augmented_circuit_params = NovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, true); // ro_consts_circuit are parameterized by G2 because the type alias uses G2::Base = G1::Scalar - let ro_consts_circuit: ROConstantsCircuit> = - ROConstantsCircuit::>::default(); + let ro_consts_circuit: ROConstantsCircuit> = ROConstantsCircuit::>::default(); // Initialize ck for the primary let augmented_circuit: NovaAugmentedCircuit<'_, Dual, C> = @@ -1638,10 +1631,7 @@ mod tests { let (zn_primary, zn_secondary) = res.unwrap(); assert_eq!(zn_primary, vec![::Scalar::ONE]); - assert_eq!( - zn_secondary, - vec![ as Engine>::Scalar::from(5u64)] - ); + assert_eq!(zn_secondary, vec![ as Engine>::Scalar::from(5u64)]); } #[test] diff --git a/src/supernova/mod.rs b/src/supernova/mod.rs index c2d702656..d3dcd0475 100644 --- a/src/supernova/mod.rs +++ b/src/supernova/mod.rs @@ -14,7 +14,7 @@ use crate::{ scalar_as_base, traits::{ commitment::{CommitmentEngineTrait, CommitmentTrait}, - AbsorbInROTrait, CurveCycleEquipped, Engine, ROConstants, ROConstantsCircuit, ROTrait, Dual, + AbsorbInROTrait, CurveCycleEquipped, Dual, Engine, ROConstants, ROConstantsCircuit, ROTrait, }, Commitment, CommitmentKey, R1CSWithArity, }; @@ -717,10 +717,7 @@ where /// executing a step of the incremental computation #[allow(clippy::too_many_arguments)] #[tracing::instrument(skip_all, name = "supernova::RecursiveSNARK::prove_step")] - pub fn prove_step< - C1: StepCircuit, - C2: StepCircuit< as Engine>::Scalar>, - >( + pub fn prove_step, C2: StepCircuit< as Engine>::Scalar>>( &mut self, pp: &PublicParams, c_primary: &C1, diff --git a/src/supernova/snark.rs b/src/supernova/snark.rs index c32babe0f..72b3c62cb 100644 --- a/src/supernova/snark.rs +++ b/src/supernova/snark.rs @@ -6,7 +6,7 @@ use crate::{ r1cs::{R1CSInstance, RelaxedR1CSWitness}, traits::{ snark::{BatchedRelaxedR1CSSNARKTrait, RelaxedR1CSSNARKTrait}, - AbsorbInROTrait, CurveCycleEquipped, Engine, ROTrait, Dual, + AbsorbInROTrait, CurveCycleEquipped, Dual, Engine, ROTrait, }, }; use crate::{errors::NovaError, scalar_as_base, RelaxedR1CSInstance, NIFS}; diff --git a/src/supernova/test.rs b/src/supernova/test.rs index c0d8e3939..6d43ef1e5 100644 --- a/src/supernova/test.rs +++ b/src/supernova/test.rs @@ -496,18 +496,17 @@ fn test_recursive_circuit_with( let zero1 = < as Engine>::Base as Field>::ZERO; let z0 = vec![zero1; arity1]; let mut cs1 = SatisfyingAssignment::::new(); - let inputs1: SuperNovaAugmentedCircuitInputs<'_, Dual> = - SuperNovaAugmentedCircuitInputs::new( - scalar_as_base::(zero1), // pass zero for testing - zero1, - &z0, - None, - None, - None, - None, - Some(zero1), - zero1, - ); + let inputs1: SuperNovaAugmentedCircuitInputs<'_, Dual> = SuperNovaAugmentedCircuitInputs::new( + scalar_as_base::(zero1), // pass zero for testing + zero1, + &z0, + None, + None, + None, + None, + Some(zero1), + zero1, + ); let step_circuit = TrivialTestCircuit::default(); let circuit1: SuperNovaAugmentedCircuit< '_, diff --git a/src/traits/mod.rs b/src/traits/mod.rs index 8f2c46653..1786f734f 100644 --- a/src/traits/mod.rs +++ b/src/traits/mod.rs @@ -57,11 +57,11 @@ pub trait Engine: Clone + Copy + Debug + Send + Sync + Sized + Eq + PartialEq { /// This is a convenience trait to pair engines which fields are in a curve cycle relationship pub trait CurveCycleEquipped: Engine { - /// The secondary Engine of `Self` + /// The secondary `Engine` of `Self` type Secondary: Engine::Scalar, Scalar = ::Base>; } -/// Convenience projection to the Secondary Engine of a CurveCycleEquipped +/// Convenience projection to the secondary `Engine` of a `CurveCycleEquipped` pub type Dual = ::Secondary; /// A helper trait to absorb different objects in RO