diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 804ad324..0cea2dce 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -32,7 +32,7 @@ jobs: - uses: actions-rs/cargo@v1 with: command: build - args: --target wasm32-unknown-unknown + args: --no-default-features --target wasm32-unknown-unknown test: runs-on: ubuntu-latest diff --git a/Cargo.toml b/Cargo.toml index e3dfd93c..dc725f01 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ subtle = "2.5" pasta_curves = { version = "0.5", features = ["repr-c", "serde"] } halo2curves = { version = "0.6.0", features = ["bits", "derive_serde"] } neptune = { version = "13.0.0", default-features = false } -generic-array = "0.14" +generic-array = "1.0.0" num-bigint = { version = "0.4", features = ["serde", "rand"] } num-traits = "0.2" num-integer = "0.1" @@ -41,14 +41,13 @@ itertools = "0.12.0" pasta-msm = { version = "0.1.4" } [target.'cfg(target_arch = "wasm32")'.dependencies] -# see https://github.com/rust-random/rand/pull/948 getrandom = { version = "0.2.0", default-features = false, features = ["js"] } [dev-dependencies] -criterion = { version = "0.4", features = ["html_reports"] } +criterion = { version = "0.5", features = ["html_reports"] } flate2 = "1.0" hex = "0.4.3" -pprof = { version = "0.11" } +pprof = { version = "0.13" } cfg-if = "1.0.0" sha2 = "0.10.7" proptest = "1.2.0" @@ -76,8 +75,7 @@ name = "ppsnark" harness = false [features] -default = [] -asm = ["halo2curves/asm"] +default = ["halo2curves/asm"] # Compiles in portable mode, w/o ISA extensions => binary can be executed on all systems. portable = ["pasta-msm/portable"] cuda = ["neptune/cuda", "neptune/pasta", "neptune/arity24"] diff --git a/README.md b/README.md index 423e9ee7..9e006212 100644 --- a/README.md +++ b/README.md @@ -32,12 +32,14 @@ A front-end is a tool to take a high-level program and turn it into an intermedi In the future, we plan to support [Noir](https://noir-lang.org/), a Rust-like DSL and a compiler to transform those programs into an IR. See [this](https://github.com/microsoft/Nova/issues/275) GitHub issue for details. ## Tests and examples +By default, we enable the `asm` feature of an underlying library (which boosts performance by up to 50\%). If the library fails to build or run, one can pass `--no-default-features` to `cargo` commands noted below. + To run tests (we recommend the release mode to drastically shorten run times): ```text cargo test --release ``` -To run example: +To run an example: ```text cargo run --release --example minroot ``` diff --git a/benches/compressed-snark.rs b/benches/compressed-snark.rs index 7d7482bc..ab6614b4 100644 --- a/benches/compressed-snark.rs +++ b/benches/compressed-snark.rs @@ -5,7 +5,7 @@ use core::marker::PhantomData; use criterion::{measurement::WallTime, *}; use ff::PrimeField; use nova_snark::{ - provider::{PallasEngine, VestaEngine}, + provider::{Bn256EngineKZG, GrumpkinEngine}, traits::{ circuit::{StepCircuit, TrivialCircuit}, snark::RelaxedR1CSSNARKTrait, @@ -15,9 +15,9 @@ use nova_snark::{ }; use std::time::Duration; -type E1 = PallasEngine; -type E2 = VestaEngine; -type EE1 = nova_snark::provider::ipa_pc::EvaluationEngine; +type E1 = Bn256EngineKZG; +type E2 = GrumpkinEngine; +type EE1 = nova_snark::provider::hyperkzg::EvaluationEngine; type EE2 = nova_snark::provider::ipa_pc::EvaluationEngine; // SNARKs without computational commitments type S1 = nova_snark::spartan::snark::RelaxedR1CSSNARK; @@ -50,8 +50,8 @@ cfg_if::cfg_if! { criterion_main!(compressed_snark); -// This should match the value for the primary in test_recursive_circuit_pasta -const NUM_CONS_VERIFIER_CIRCUIT_PRIMARY: usize = 9817; +// This should match the value for the primary in test_recursive_circuit_bn256_grumpkin +const NUM_CONS_VERIFIER_CIRCUIT_PRIMARY: usize = 9985; const NUM_SAMPLES: usize = 10; /// Benchmarks the compressed SNARK at a provided number of constraints diff --git a/benches/compute-digest.rs b/benches/compute-digest.rs index 2bc62f32..64cc4851 100644 --- a/benches/compute-digest.rs +++ b/benches/compute-digest.rs @@ -4,7 +4,7 @@ use bellpepper_core::{num::AllocatedNum, ConstraintSystem, SynthesisError}; use criterion::{black_box, criterion_group, criterion_main, Criterion}; use ff::PrimeField; use nova_snark::{ - provider::{PallasEngine, VestaEngine}, + provider::{Bn256EngineKZG, GrumpkinEngine}, traits::{ circuit::{StepCircuit, TrivialCircuit}, snark::default_ck_hint, @@ -13,8 +13,8 @@ use nova_snark::{ PublicParams, }; -type E1 = PallasEngine; -type E2 = VestaEngine; +type E1 = Bn256EngineKZG; +type E2 = GrumpkinEngine; type C1 = NonTrivialCircuit<::Scalar>; type C2 = TrivialCircuit<::Scalar>; diff --git a/benches/ppsnark.rs b/benches/ppsnark.rs index a04fb7ad..56a24ac0 100644 --- a/benches/ppsnark.rs +++ b/benches/ppsnark.rs @@ -5,7 +5,7 @@ use core::marker::PhantomData; use criterion::*; use ff::PrimeField; use nova_snark::{ - provider::hyperkzg::Bn256EngineKZG, + provider::Bn256EngineKZG, spartan::direct::DirectSNARK, traits::{circuit::StepCircuit, Engine}, }; diff --git a/benches/recursive-snark.rs b/benches/recursive-snark.rs index 5b16faa1..254ee1da 100644 --- a/benches/recursive-snark.rs +++ b/benches/recursive-snark.rs @@ -5,7 +5,7 @@ use core::marker::PhantomData; use criterion::*; use ff::PrimeField; use nova_snark::{ - provider::{PallasEngine, VestaEngine}, + provider::{Bn256EngineKZG, GrumpkinEngine}, traits::{ circuit::{StepCircuit, TrivialCircuit}, snark::default_ck_hint, @@ -15,8 +15,8 @@ use nova_snark::{ }; use std::time::Duration; -type E1 = PallasEngine; -type E2 = VestaEngine; +type E1 = Bn256EngineKZG; +type E2 = GrumpkinEngine; type C1 = NonTrivialCircuit<::Scalar>; type C2 = TrivialCircuit<::Scalar>; @@ -42,8 +42,8 @@ cfg_if::cfg_if! { criterion_main!(recursive_snark); -// This should match the value for the primary in test_recursive_circuit_pasta -const NUM_CONS_VERIFIER_CIRCUIT_PRIMARY: usize = 9817; +// This should match the value for the primary in test_recursive_circuit_bn256_grumpkin +const NUM_CONS_VERIFIER_CIRCUIT_PRIMARY: usize = 9985; const NUM_SAMPLES: usize = 10; fn bench_recursive_snark(c: &mut Criterion) { diff --git a/benches/sha256.rs b/benches/sha256.rs index d2becf8b..c4f41038 100644 --- a/benches/sha256.rs +++ b/benches/sha256.rs @@ -14,7 +14,7 @@ use core::time::Duration; use criterion::*; use ff::{PrimeField, PrimeFieldBits}; use nova_snark::{ - provider::{PallasEngine, VestaEngine}, + provider::{Bn256EngineKZG, GrumpkinEngine}, traits::{ circuit::{StepCircuit, TrivialCircuit}, snark::default_ck_hint, @@ -24,8 +24,8 @@ use nova_snark::{ }; use sha2::{Digest, Sha256}; -type E1 = PallasEngine; -type E2 = VestaEngine; +type E1 = Bn256EngineKZG; +type E2 = GrumpkinEngine; #[derive(Clone, Debug)] struct Sha256Circuit { diff --git a/examples/and.rs b/examples/and.rs index 5e8b9b2e..6755bc1b 100644 --- a/examples/and.rs +++ b/examples/and.rs @@ -9,7 +9,7 @@ use ff::Field; use ff::{PrimeField, PrimeFieldBits}; use flate2::{write::ZlibEncoder, Compression}; use nova_snark::{ - provider::{hyperkzg::Bn256EngineKZG, GrumpkinEngine}, + provider::{Bn256EngineKZG, GrumpkinEngine}, traits::{ circuit::{StepCircuit, TrivialCircuit}, snark::RelaxedR1CSSNARKTrait, diff --git a/examples/minroot.rs b/examples/minroot.rs index abca2164..914b80a9 100644 --- a/examples/minroot.rs +++ b/examples/minroot.rs @@ -5,7 +5,7 @@ use bellpepper_core::{num::AllocatedNum, ConstraintSystem, SynthesisError}; use ff::Field; use flate2::{write::ZlibEncoder, Compression}; use nova_snark::{ - provider::{hyperkzg::Bn256EngineKZG, GrumpkinEngine}, + provider::{Bn256EngineKZG, GrumpkinEngine}, traits::{ circuit::{StepCircuit, TrivialCircuit}, snark::RelaxedR1CSSNARKTrait, diff --git a/src/bellpepper/mod.rs b/src/bellpepper/mod.rs index 1309fe23..7b0aaf07 100644 --- a/src/bellpepper/mod.rs +++ b/src/bellpepper/mod.rs @@ -15,7 +15,7 @@ mod tests { shape_cs::ShapeCS, solver::SatisfyingAssignment, }, - provider::{Bn256Engine, PallasEngine, Secp256k1Engine}, + provider::{Bn256EngineKZG, PallasEngine, Secp256k1Engine}, traits::{snark::default_ck_hint, Engine}, }; use bellpepper_core::{num::AllocatedNum, ConstraintSystem}; @@ -59,7 +59,7 @@ mod tests { #[test] fn test_alloc_bit() { test_alloc_bit_with::(); - test_alloc_bit_with::(); + test_alloc_bit_with::(); test_alloc_bit_with::(); } } diff --git a/src/bellpepper/r1cs.rs b/src/bellpepper/r1cs.rs index 278390bd..3a7fd535 100644 --- a/src/bellpepper/r1cs.rs +++ b/src/bellpepper/r1cs.rs @@ -111,17 +111,20 @@ fn add_constraint( assert_eq!(n + 1, C.indptr.len(), "C: invalid shape"); let add_constraint_component = |index: Index, coeff: &S, M: &mut SparseMatrix| { - match index { - Index::Input(idx) => { - // Inputs come last, with input 0, representing 'one', - // at position num_vars within the witness vector. - let idx = idx + num_vars; - M.data.push(*coeff); - M.indices.push(idx); - } - Index::Aux(idx) => { - M.data.push(*coeff); - M.indices.push(idx); + // we add constraints to the matrix only if the associated coefficient is non-zero + if *coeff != S::ZERO { + match index { + Index::Input(idx) => { + // Inputs come last, with input 0, representing 'one', + // at position num_vars within the witness vector. + let idx = idx + num_vars; + M.data.push(*coeff); + M.indices.push(idx); + } + Index::Aux(idx) => { + M.data.push(*coeff); + M.indices.push(idx); + } } } }; diff --git a/src/bellpepper/test_shape_cs.rs b/src/bellpepper/test_shape_cs.rs index ca95ebba..61cb9679 100644 --- a/src/bellpepper/test_shape_cs.rs +++ b/src/bellpepper/test_shape_cs.rs @@ -14,6 +14,7 @@ use ff::{Field, PrimeField}; #[derive(Clone, Copy)] struct OrderedVariable(Variable); +#[allow(unused)] #[derive(Debug)] enum NamedObject { Constraint(usize), diff --git a/src/circuit.rs b/src/circuit.rs index 6e655593..1402e934 100644 --- a/src/circuit.rs +++ b/src/circuit.rs @@ -372,7 +372,7 @@ mod tests { gadgets::utils::scalar_as_base, provider::{ poseidon::PoseidonConstantsCircuit, - {Bn256Engine, GrumpkinEngine}, {PallasEngine, VestaEngine}, + {Bn256EngineKZG, GrumpkinEngine}, {PallasEngine, VestaEngine}, {Secp256k1Engine, Secq256k1Engine}, }, traits::{circuit::TrivialCircuit, snark::default_ck_hint}, @@ -461,19 +461,19 @@ mod tests { } #[test] - fn test_recursive_circuit_grumpkin() { + fn test_recursive_circuit_bn256_grumpkin() { let params1 = NovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, true); let params2 = NovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, false); let ro_consts1: ROConstantsCircuit = PoseidonConstantsCircuit::default(); - let ro_consts2: ROConstantsCircuit = PoseidonConstantsCircuit::default(); + let ro_consts2: ROConstantsCircuit = PoseidonConstantsCircuit::default(); - test_recursive_circuit_with::( + test_recursive_circuit_with::( ¶ms1, ¶ms2, ro_consts1, ro_consts2, 9985, 10538, ); } #[test] - fn test_recursive_circuit_secp() { + fn test_recursive_circuit_secpq() { let params1 = NovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, true); let params2 = NovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, false); let ro_consts1: ROConstantsCircuit = PoseidonConstantsCircuit::default(); diff --git a/src/gadgets/ecc.rs b/src/gadgets/ecc.rs index 0a1e5e79..ebb8f2de 100644 --- a/src/gadgets/ecc.rs +++ b/src/gadgets/ecc.rs @@ -790,7 +790,8 @@ mod tests { provider::{ bn256_grumpkin::{bn256, grumpkin}, secp_secq::{secp256k1, secq256k1}, - Bn256Engine, GrumpkinEngine, Secp256k1Engine, Secq256k1Engine, {PallasEngine, VestaEngine}, + Bn256EngineKZG, GrumpkinEngine, Secp256k1Engine, Secq256k1Engine, + {PallasEngine, VestaEngine}, }, traits::snark::default_ck_hint, }; @@ -929,7 +930,7 @@ mod tests { test_ecc_ops_with::(); test_ecc_ops_with::(); - test_ecc_ops_with::(); + test_ecc_ops_with::(); test_ecc_ops_with::(); test_ecc_ops_with::(); @@ -1016,8 +1017,8 @@ mod tests { test_ecc_circuit_ops_with::(); test_ecc_circuit_ops_with::(); - test_ecc_circuit_ops_with::(); - test_ecc_circuit_ops_with::(); + test_ecc_circuit_ops_with::(); + test_ecc_circuit_ops_with::(); test_ecc_circuit_ops_with::(); test_ecc_circuit_ops_with::(); @@ -1072,8 +1073,8 @@ mod tests { test_ecc_circuit_add_equal_with::(); test_ecc_circuit_add_equal_with::(); - test_ecc_circuit_add_equal_with::(); - test_ecc_circuit_add_equal_with::(); + test_ecc_circuit_add_equal_with::(); + test_ecc_circuit_add_equal_with::(); test_ecc_circuit_add_equal_with::(); test_ecc_circuit_add_equal_with::(); @@ -1132,8 +1133,8 @@ mod tests { test_ecc_circuit_add_negation_with::(); test_ecc_circuit_add_negation_with::(); - test_ecc_circuit_add_negation_with::(); - test_ecc_circuit_add_negation_with::(); + test_ecc_circuit_add_negation_with::(); + test_ecc_circuit_add_negation_with::(); test_ecc_circuit_add_negation_with::(); test_ecc_circuit_add_negation_with::(); diff --git a/src/lib.rs b/src/lib.rs index f35b8074..522bec21 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -846,7 +846,7 @@ mod tests { use super::*; use crate::{ provider::{ - hyperkzg::Bn256EngineKZG, pedersen::CommitmentKeyExtTrait, traits::DlogGroup, Bn256Engine, + pedersen::CommitmentKeyExtTrait, traits::DlogGroup, Bn256EngineIPA, Bn256EngineKZG, GrumpkinEngine, PallasEngine, Secp256k1Engine, Secq256k1Engine, VestaEngine, }, traits::{circuit::TrivialCircuit, evaluation::EvaluationEngineTrait, snark::default_ck_hint}, @@ -857,6 +857,7 @@ mod tests { use ff::PrimeField; type EE = provider::ipa_pc::EvaluationEngine; + type EEPrime = provider::hyperkzg::EvaluationEngine; type S = spartan::snark::RelaxedR1CSSNARK; type SPrime = spartan::ppsnark::RelaxedR1CSSNARK; @@ -939,51 +940,22 @@ mod tests { #[test] fn test_pp_digest() { - let trivial_circuit1 = TrivialCircuit::<::Scalar>::default(); - let trivial_circuit2 = TrivialCircuit::<::Scalar>::default(); - let cubic_circuit1 = CubicCircuit::<::Scalar>::default(); - - test_pp_digest_with::( - &trivial_circuit1, - &trivial_circuit2, - &expect!["9bc7ad2ab3f2a12455fdd21527598e365a14619c7f1e09f5cc3c78caa2fdd602"], - ); - test_pp_digest_with::( - &cubic_circuit1, - &trivial_circuit2, - &expect!["8dea023ed642fd2d1a7bedb536cd96d22c0d25ea40961a4fe4a865169bf6ee01"], + &TrivialCircuit::<_>::default(), + &TrivialCircuit::<_>::default(), + &expect!["a69d6cf6d014c3a5cc99b77afc86691f7460faa737207dd21b30e8241fae8002"], ); - let trivial_circuit1_grumpkin = TrivialCircuit::<::Scalar>::default(); - let trivial_circuit2_grumpkin = TrivialCircuit::<::Scalar>::default(); - let cubic_circuit1_grumpkin = CubicCircuit::<::Scalar>::default(); - - test_pp_digest_with::( - &trivial_circuit1_grumpkin, - &trivial_circuit2_grumpkin, - &expect!["89e746ed5055445a4aceb2b6fb0413fe0bf4d2efec387dee85613922a972a701"], - ); - - test_pp_digest_with::( - &cubic_circuit1_grumpkin, - &trivial_circuit2_grumpkin, - &expect!["941f55146ac21a3b4ff9863546bea95df48cb0069d2fa9e8249f8d0a00560401"], + test_pp_digest_with::( + &TrivialCircuit::<_>::default(), + &TrivialCircuit::<_>::default(), + &expect!["b22ab3456df4bd391804a39fae582b37ed4a8d90ace377337940ac956d87f701"], ); - let trivial_circuit1_secp = TrivialCircuit::<::Scalar>::default(); - let trivial_circuit2_secp = TrivialCircuit::<::Scalar>::default(); - let cubic_circuit1_secp = CubicCircuit::<::Scalar>::default(); - test_pp_digest_with::( - &trivial_circuit1_secp, - &trivial_circuit2_secp, - &expect!["c70782c49d3de831b3822081655cf61c7d53533f0effcd5c4166cd4fbe651e00"], - ); - test_pp_digest_with::( - &cubic_circuit1_secp, - &trivial_circuit2_secp, - &expect!["148c5994c443174b67699cb6169aa4489babebb360ae5145bb4b09d77a3a9a01"], + &TrivialCircuit::<_>::default(), + &TrivialCircuit::<_>::default(), + &expect!["c8aec89a3ea90317a0ecdc9150f4fc3648ca33f6660924a192cafd82e2939b02"], ); } @@ -1037,7 +1009,7 @@ mod tests { #[test] fn test_ivc_trivial() { test_ivc_trivial_with::(); - test_ivc_trivial_with::(); + test_ivc_trivial_with::(); test_ivc_trivial_with::(); } @@ -1117,7 +1089,7 @@ mod tests { #[test] fn test_ivc_nontrivial() { test_ivc_nontrivial_with::(); - test_ivc_nontrivial_with::(); + test_ivc_nontrivial_with::(); test_ivc_nontrivial_with::(); } @@ -1208,7 +1180,8 @@ mod tests { #[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::, EE<_>>(); test_ivc_nontrivial_with_spark_compression_with::< @@ -1311,7 +1284,12 @@ mod tests { #[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::< + Bn256EngineKZG, + GrumpkinEngine, + EEPrime<_>, + EE<_>, + >(); test_ivc_nontrivial_with_spark_compression_with::, EE<_>>( ); } @@ -1451,7 +1429,7 @@ 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<_>>(); } @@ -1516,7 +1494,7 @@ mod tests { #[test] fn test_ivc_base() { test_ivc_base_with::(); - test_ivc_base_with::(); + test_ivc_base_with::(); test_ivc_base_with::(); } } diff --git a/src/nifs.rs b/src/nifs.rs index de8054c2..0329d38b 100644 --- a/src/nifs.rs +++ b/src/nifs.rs @@ -123,7 +123,7 @@ mod tests { solver::SatisfyingAssignment, test_shape_cs::TestShapeCS, }, - provider::{Bn256Engine, PallasEngine, Secp256k1Engine}, + provider::{Bn256EngineKZG, PallasEngine, Secp256k1Engine}, r1cs::{SparseMatrix, R1CS}, traits::{snark::default_ck_hint, Engine}, }; @@ -204,7 +204,7 @@ mod tests { #[test] fn test_tiny_r1cs_bellpepper() { test_tiny_r1cs_bellpepper_with::(); - test_tiny_r1cs_bellpepper_with::(); + test_tiny_r1cs_bellpepper_with::(); test_tiny_r1cs_bellpepper_with::(); } @@ -387,7 +387,7 @@ mod tests { #[test] fn test_tiny_r1cs() { test_tiny_r1cs_with::(); - test_tiny_r1cs_with::(); + test_tiny_r1cs_with::(); test_tiny_r1cs_with::(); } } diff --git a/src/provider/hyperkzg.rs b/src/provider/hyperkzg.rs index 22b7c074..04f955ec 100644 --- a/src/provider/hyperkzg.rs +++ b/src/provider/hyperkzg.rs @@ -1,5 +1,5 @@ //! This module implements Nova's evaluation engine using `HyperKZG`, a KZG-based polynomial commitment for multilinear polynomials -//! HyperKZG is based on the transformation from univariate PCS to multilinear PCS in the Gemini paper (section 2.4.2 in https://eprint.iacr.org/2022/420.pdf). +//! HyperKZG is based on the transformation from univariate PCS to multilinear PCS in the Gemini paper (section 2.4.2 in ). //! However, there are some key differences: //! (1) HyperKZG works with multilinear polynomials represented in evaluation form (rather than in coefficient form in Gemini's transformation). //! This means that Spartan's polynomial IOP can use commit to its polynomials as-is without incurring any interpolations or FFTs. @@ -8,11 +8,7 @@ #![allow(non_snake_case)] use crate::{ errors::NovaError, - provider::{ - keccak::Keccak256Transcript, - poseidon::{PoseidonRO, PoseidonROCircuit}, - traits::{CompressedGroup, DlogGroup, PairingGroup}, - }, + provider::traits::{CompressedGroup, DlogGroup, PairingGroup}, traits::{ commitment::{CommitmentEngineTrait, CommitmentTrait, Len}, evaluation::EvaluationEngineTrait, @@ -25,7 +21,6 @@ use core::{ ops::{Add, Mul, MulAssign}, }; use ff::Field; -use halo2curves::bn256::{Fq as Bn256Fq, Fr as Bn256Fr, G1 as Bn256G1}; use itertools::Itertools; use rand_core::OsRng; use rayon::prelude::*; @@ -667,25 +662,12 @@ where } } -/// An implementation of Nova traits with HyperKZG over the BN256 curve -#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)] -pub struct Bn256EngineKZG; - -impl Engine for Bn256EngineKZG { - type Base = Bn256Fq; - type Scalar = Bn256Fr; - type GE = Bn256G1; - type RO = PoseidonRO; - type ROCircuit = PoseidonROCircuit; - type TE = Keccak256Transcript; - type CE = CommitmentEngine; -} - #[cfg(test)] mod tests { use super::*; use crate::{ - provider::keccak::Keccak256Transcript, spartan::polys::multilinear::MultilinearPolynomial, + provider::{keccak::Keccak256Transcript, Bn256EngineKZG}, + spartan::polys::multilinear::MultilinearPolynomial, }; use bincode::Options; use group::Curve; diff --git a/src/provider/keccak.rs b/src/provider/keccak.rs index 92e1b17e..f9e6116c 100644 --- a/src/provider/keccak.rs +++ b/src/provider/keccak.rs @@ -101,7 +101,7 @@ mod tests { use crate::{ provider::keccak::Keccak256Transcript, provider::{ - Bn256Engine, GrumpkinEngine, PallasEngine, Secp256k1Engine, Secq256k1Engine, VestaEngine, + Bn256EngineKZG, GrumpkinEngine, PallasEngine, Secp256k1Engine, Secq256k1Engine, VestaEngine, }, traits::{Engine, PrimeFieldExt, TranscriptEngineTrait, TranscriptReprTrait}, }; @@ -142,7 +142,7 @@ mod tests { "4d4bf42c065870395749fa1c4fb641df1e0d53f05309b03d5b1db7f0be3aa13d", ); - test_keccak_transcript_with::( + test_keccak_transcript_with::( "9fb71e3b74bfd0b60d97349849b895595779a240b92a6fae86bd2812692b6b0e", "bfd4c50b7d6317e9267d5d65c985eb455a3561129c0b3beef79bfc8461a84f18", ); @@ -246,7 +246,7 @@ mod tests { fn test_keccak_transcript_incremental_vs_explicit() { test_keccak_transcript_incremental_vs_explicit_with::(); test_keccak_transcript_incremental_vs_explicit_with::(); - test_keccak_transcript_incremental_vs_explicit_with::(); + test_keccak_transcript_incremental_vs_explicit_with::(); test_keccak_transcript_incremental_vs_explicit_with::(); test_keccak_transcript_incremental_vs_explicit_with::(); test_keccak_transcript_incremental_vs_explicit_with::(); diff --git a/src/provider/mod.rs b/src/provider/mod.rs index 0507cc50..dd94c657 100644 --- a/src/provider/mod.rs +++ b/src/provider/mod.rs @@ -18,6 +18,7 @@ mod keccak; use crate::{ provider::{ bn256_grumpkin::{bn256, grumpkin}, + hyperkzg::CommitmentEngine as HyperKZGCommitmentEngine, keccak::Keccak256Transcript, pedersen::CommitmentEngine as PedersenCommitmentEngine, poseidon::{PoseidonRO, PoseidonROCircuit}, @@ -28,15 +29,29 @@ use crate::{ use pasta_curves::{pallas, vesta}; use serde::{Deserialize, Serialize}; -/// An implementation of the Nova `Engine` trait with BN254 curve and Pedersen commitment scheme +/// An implementation of Nova traits with HyperKZG over the BN256 curve #[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)] -pub struct Bn256Engine; +pub struct Bn256EngineKZG; /// An implementation of the Nova `Engine` trait with Grumpkin curve and Pedersen commitment scheme #[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)] pub struct GrumpkinEngine; -impl Engine for Bn256Engine { +/// An implementation of the Nova `Engine` trait with BN254 curve and Pedersen commitment scheme +#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)] +pub struct Bn256EngineIPA; + +impl Engine for Bn256EngineKZG { + type Base = bn256::Base; + type Scalar = bn256::Scalar; + type GE = bn256::Point; + type RO = PoseidonRO; + type ROCircuit = PoseidonROCircuit; + type TE = Keccak256Transcript; + type CE = HyperKZGCommitmentEngine; +} + +impl Engine for Bn256EngineIPA { type Base = bn256::Base; type Scalar = bn256::Scalar; type GE = bn256::Point; diff --git a/src/provider/poseidon.rs b/src/provider/poseidon.rs index 912129fe..b9e433a8 100644 --- a/src/provider/poseidon.rs +++ b/src/provider/poseidon.rs @@ -192,7 +192,7 @@ where mod tests { use super::*; use crate::provider::{ - Bn256Engine, GrumpkinEngine, PallasEngine, Secp256k1Engine, Secq256k1Engine, VestaEngine, + Bn256EngineKZG, GrumpkinEngine, PallasEngine, Secp256k1Engine, Secq256k1Engine, VestaEngine, }; use crate::{ bellpepper::solver::SatisfyingAssignment, constants::NUM_CHALLENGE_BITS, @@ -237,7 +237,7 @@ mod tests { fn test_poseidon_ro() { test_poseidon_ro_with::(); test_poseidon_ro_with::(); - test_poseidon_ro_with::(); + test_poseidon_ro_with::(); test_poseidon_ro_with::(); test_poseidon_ro_with::(); test_poseidon_ro_with::(); diff --git a/src/r1cs/mod.rs b/src/r1cs/mod.rs index b5871a22..39d6ec84 100644 --- a/src/r1cs/mod.rs +++ b/src/r1cs/mod.rs @@ -1,8 +1,4 @@ //! This module defines R1CS related types and a folding scheme for Relaxed R1CS -mod sparse; -#[cfg(test)] -mod util; - use crate::{ constants::{BN_LIMB_WIDTH, BN_N_LIMBS}, digest::{DigestComputer, SimpleDigestible}, @@ -23,7 +19,8 @@ use once_cell::sync::OnceCell; use rayon::prelude::*; use serde::{Deserialize, Serialize}; -pub(crate) use self::sparse::SparseMatrix; +mod sparse; +pub(crate) use sparse::SparseMatrix; /// Public parameters for a given R1CS #[derive(Clone, Serialize, Deserialize)] @@ -569,7 +566,7 @@ mod tests { use super::*; use crate::{ - provider::{Bn256Engine, PallasEngine, Secp256k1Engine}, + provider::{Bn256EngineKZG, PallasEngine, Secp256k1Engine}, r1cs::sparse::SparseMatrix, traits::Engine, }; @@ -652,7 +649,7 @@ mod tests { #[test] fn test_pad_tiny_r1cs() { test_pad_tiny_r1cs_with::(); - test_pad_tiny_r1cs_with::(); + test_pad_tiny_r1cs_with::(); test_pad_tiny_r1cs_with::(); } } diff --git a/src/r1cs/sparse.rs b/src/r1cs/sparse.rs index 5c62cd31..075b158d 100644 --- a/src/r1cs/sparse.rs +++ b/src/r1cs/sparse.rs @@ -162,12 +162,12 @@ impl<'a, F: PrimeField> Iterator for Iter<'a, F> { #[cfg(test)] mod tests { - use super::SparseMatrix; + use super::*; use crate::{ provider::PallasEngine, - r1cs::util::FWrap, traits::{Engine, Group}, }; + use ff::PrimeField; use proptest::{ prelude::*, strategy::{BoxedStrategy, Just, Strategy}, @@ -176,6 +176,29 @@ mod tests { type G = ::GE; type Fr = ::Scalar; + /// Wrapper struct around a field element that implements additional traits + #[derive(Clone, Debug, PartialEq, Eq)] + pub struct FWrap(pub F); + + impl Copy for FWrap {} + + #[cfg(not(target_arch = "wasm32"))] + /// Trait implementation for generating `FWrap` instances with proptest + impl Arbitrary for FWrap { + type Parameters = (); + type Strategy = BoxedStrategy; + + fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy { + use rand::rngs::StdRng; + use rand_core::SeedableRng; + + let strategy = any::<[u8; 32]>() + .prop_map(|seed| FWrap(F::random(StdRng::from_seed(seed)))) + .no_shrink(); + strategy.boxed() + } + } + #[test] fn test_matrix_creation() { let matrix_data = vec![ diff --git a/src/r1cs/util.rs b/src/r1cs/util.rs deleted file mode 100644 index 49cb5865..00000000 --- a/src/r1cs/util.rs +++ /dev/null @@ -1,26 +0,0 @@ -use ff::PrimeField; -#[cfg(not(target_arch = "wasm32"))] -use proptest::prelude::*; - -/// Wrapper struct around a field element that implements additional traits -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct FWrap(pub F); - -impl Copy for FWrap {} - -#[cfg(not(target_arch = "wasm32"))] -/// Trait implementation for generating `FWrap` instances with proptest -impl Arbitrary for FWrap { - type Parameters = (); - type Strategy = BoxedStrategy; - - fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy { - use rand::rngs::StdRng; - use rand_core::SeedableRng; - - let strategy = any::<[u8; 32]>() - .prop_map(|seed| FWrap(F::random(StdRng::from_seed(seed)))) - .no_shrink(); - strategy.boxed() - } -} diff --git a/src/spartan/direct.rs b/src/spartan/direct.rs index 046a5c4d..80986a2a 100644 --- a/src/spartan/direct.rs +++ b/src/spartan/direct.rs @@ -165,7 +165,7 @@ impl, C: StepCircuit> DirectSN #[cfg(test)] mod tests { use super::*; - use crate::provider::{Bn256Engine, PallasEngine, Secp256k1Engine}; + use crate::provider::{Bn256EngineKZG, PallasEngine, Secp256k1Engine}; use ::bellpepper_core::{num::AllocatedNum, ConstraintSystem, SynthesisError}; use core::marker::PhantomData; use ff::PrimeField; @@ -228,8 +228,8 @@ mod tests { type Spp = crate::spartan::ppsnark::RelaxedR1CSSNARK; test_direct_snark_with::(); - type E2 = Bn256Engine; - type EE2 = crate::provider::ipa_pc::EvaluationEngine; + type E2 = Bn256EngineKZG; + type EE2 = crate::provider::hyperkzg::EvaluationEngine; type S2 = crate::spartan::snark::RelaxedR1CSSNARK; test_direct_snark_with::();