[test-only] More genericity in tests (#171)

* refactor: make circuit tests generic wrt curves

- Improve modularity by introducing generic `test_recursive_circuit_with` function in `src/circuit.rs`
- Refactor `test_recursive_circuit` to utilize the new function
- Implement type constraints for `test_recursive_circuit_with` function

* refactor: make bellperson tests generic in type of group

- Introduce `test_alloc_bit_with` function utilizing generic types
- Adapt existing `test_alloc_bit` function to use the new `test_alloc_bit_with` function with correct types

* refactor: make the nifs test generic in the type of group

* refactor: make the ivc tests generic in the type of curve

* refactor: simplify generics in tests

* make the keccak tests generic

* make the poseidon tests generic

* make the spartan tests generic
This commit is contained in:
François Garillot
2023-05-26 22:43:35 +02:00
committed by GitHub
parent 58fc746c0b
commit 54f758eef3
8 changed files with 227 additions and 96 deletions

View File

@@ -787,13 +787,16 @@ fn compute_digest<G: Group, T: Serialize>(o: &T) -> G::Scalar {
#[cfg(test)]
mod tests {
use crate::provider::pedersen::CommitmentKeyExtTrait;
use super::*;
type G1 = pasta_curves::pallas::Point;
type G2 = pasta_curves::vesta::Point;
type EE1 = provider::ipa_pc::EvaluationEngine<G1>;
type EE2 = provider::ipa_pc::EvaluationEngine<G2>;
type S1 = spartan::RelaxedR1CSSNARK<G1, EE1>;
type S2 = spartan::RelaxedR1CSSNARK<G2, EE2>;
type EE1<G1> = provider::ipa_pc::EvaluationEngine<G1>;
type EE2<G2> = provider::ipa_pc::EvaluationEngine<G2>;
type S1<G1> = spartan::RelaxedR1CSSNARK<G1, EE1<G1>>;
type S2<G2> = spartan::RelaxedR1CSSNARK<G2, EE2<G2>>;
type S1Prime<G1> = spartan::pp::RelaxedR1CSSNARK<G1, EE1<G1>>;
type S2Prime<G2> = spartan::pp::RelaxedR1CSSNARK<G2, EE2<G2>>;
use ::bellperson::{gadgets::num::AllocatedNum, ConstraintSystem, SynthesisError};
use core::marker::PhantomData;
use ff::PrimeField;
@@ -848,15 +851,21 @@ mod tests {
}
}
#[test]
fn test_ivc_trivial() {
fn test_ivc_trivial_with<G1, G2>()
where
G1: Group<Base = <G2 as Group>::Scalar>,
G2: Group<Base = <G1 as Group>::Scalar>,
{
let test_circuit1 = TrivialTestCircuit::<<G1 as Group>::Scalar>::default();
let test_circuit2 = TrivialTestCircuit::<<G2 as Group>::Scalar>::default();
// produce public parameters
let pp = PublicParams::<
G1,
G2,
TrivialTestCircuit<<G1 as Group>::Scalar>,
TrivialTestCircuit<<G2 as Group>::Scalar>,
>::setup(TrivialTestCircuit::default(), TrivialTestCircuit::default());
>::setup(test_circuit1.clone(), test_circuit2.clone());
let num_steps = 1;
@@ -864,8 +873,8 @@ mod tests {
let res = RecursiveSNARK::prove_step(
&pp,
None,
TrivialTestCircuit::default(),
TrivialTestCircuit::default(),
test_circuit1,
test_circuit2,
vec![<G1 as Group>::Scalar::ZERO],
vec![<G2 as Group>::Scalar::ZERO],
);
@@ -883,7 +892,17 @@ mod tests {
}
#[test]
fn test_ivc_nontrivial() {
fn test_ivc_trivial() {
type G1 = pasta_curves::pallas::Point;
type G2 = pasta_curves::vesta::Point;
test_ivc_trivial_with::<G1, G2>();
}
fn test_ivc_nontrivial_with<G1, G2>()
where
G1: Group<Base = <G2 as Group>::Scalar>,
G2: Group<Base = <G1 as Group>::Scalar>,
{
let circuit_primary = TrivialTestCircuit::default();
let circuit_secondary = CubicCircuit::default();
@@ -950,14 +969,30 @@ mod tests {
assert_eq!(zn_primary, vec![<G1 as Group>::Scalar::ONE]);
let mut zn_secondary_direct = vec![<G2 as Group>::Scalar::ZERO];
for _i in 0..num_steps {
zn_secondary_direct = CubicCircuit::default().output(&zn_secondary_direct);
zn_secondary_direct = circuit_secondary.clone().output(&zn_secondary_direct);
}
assert_eq!(zn_secondary, zn_secondary_direct);
assert_eq!(zn_secondary, vec![<G2 as Group>::Scalar::from(2460515u64)]);
}
#[test]
fn test_ivc_nontrivial_with_compression() {
fn test_ivc_nontrivial() {
type G1 = pasta_curves::pallas::Point;
type G2 = pasta_curves::vesta::Point;
test_ivc_nontrivial_with::<G1, G2>();
}
fn test_ivc_nontrivial_with_compression_with<G1, G2>()
where
G1: Group<Base = <G2 as Group>::Scalar>,
G2: Group<Base = <G1 as Group>::Scalar>,
// this is due to the reliance on CommitmentKeyExtTrait as a bound in ipa_pc
<G1::CE as CommitmentEngineTrait<G1>>::CommitmentKey:
CommitmentKeyExtTrait<G1, CE = <G1 as Group>::CE>,
<G2::CE as CommitmentEngineTrait<G2>>::CommitmentKey:
CommitmentKeyExtTrait<G2, CE = <G2 as Group>::CE>,
{
let circuit_primary = TrivialTestCircuit::default();
let circuit_secondary = CubicCircuit::default();
@@ -1012,16 +1047,16 @@ mod tests {
assert_eq!(zn_primary, vec![<G1 as Group>::Scalar::ONE]);
let mut zn_secondary_direct = vec![<G2 as Group>::Scalar::ZERO];
for _i in 0..num_steps {
zn_secondary_direct = CubicCircuit::default().output(&zn_secondary_direct);
zn_secondary_direct = circuit_secondary.clone().output(&zn_secondary_direct);
}
assert_eq!(zn_secondary, zn_secondary_direct);
assert_eq!(zn_secondary, vec![<G2 as Group>::Scalar::from(2460515u64)]);
// produce the prover and verifier keys for compressed snark
let (pk, vk) = CompressedSNARK::<_, _, _, _, S1, S2>::setup(&pp).unwrap();
let (pk, vk) = CompressedSNARK::<_, _, _, _, S1<G1>, S2<G2>>::setup(&pp).unwrap();
// produce a compressed SNARK
let res = CompressedSNARK::<_, _, _, _, S1, S2>::prove(&pp, &pk, &recursive_snark);
let res = CompressedSNARK::<_, _, _, _, S1<G1>, S2<G2>>::prove(&pp, &pk, &recursive_snark);
assert!(res.is_ok());
let compressed_snark = res.unwrap();
@@ -1036,7 +1071,23 @@ mod tests {
}
#[test]
fn test_ivc_nontrivial_with_spark_compression() {
fn test_ivc_nontrivial_with_compression() {
type G1 = pasta_curves::pallas::Point;
type G2 = pasta_curves::vesta::Point;
test_ivc_nontrivial_with_compression_with::<G1, G2>();
}
fn test_ivc_nontrivial_with_spark_compression_with<G1, G2>()
where
G1: Group<Base = <G2 as Group>::Scalar>,
G2: Group<Base = <G1 as Group>::Scalar>,
// this is due to the reliance on CommitmentKeyExtTrait as a bound in ipa_pc
<G1::CE as CommitmentEngineTrait<G1>>::CommitmentKey:
CommitmentKeyExtTrait<G1, CE = <G1 as Group>::CE>,
<G2::CE as CommitmentEngineTrait<G2>>::CommitmentKey:
CommitmentKeyExtTrait<G2, CE = <G2 as Group>::CE>,
{
let circuit_primary = TrivialTestCircuit::default();
let circuit_secondary = CubicCircuit::default();
@@ -1097,14 +1148,13 @@ mod tests {
assert_eq!(zn_secondary, vec![<G2 as Group>::Scalar::from(2460515u64)]);
// run the compressed snark with Spark compiler
type S1Prime = spartan::pp::RelaxedR1CSSNARK<G1, EE1>;
type S2Prime = spartan::pp::RelaxedR1CSSNARK<G2, EE2>;
// produce the prover and verifier keys for compressed snark
let (pk, vk) = CompressedSNARK::<_, _, _, _, S1Prime, S2Prime>::setup(&pp).unwrap();
let (pk, vk) = CompressedSNARK::<_, _, _, _, S1Prime<G1>, S2Prime<G2>>::setup(&pp).unwrap();
// produce a compressed SNARK
let res = CompressedSNARK::<_, _, _, _, S1Prime, S2Prime>::prove(&pp, &pk, &recursive_snark);
let res =
CompressedSNARK::<_, _, _, _, S1Prime<G1>, S2Prime<G2>>::prove(&pp, &pk, &recursive_snark);
assert!(res.is_ok());
let compressed_snark = res.unwrap();
@@ -1119,7 +1169,23 @@ mod tests {
}
#[test]
fn test_ivc_nondet_with_compression() {
fn test_ivc_nontrivial_with_spark_compression() {
type G1 = pasta_curves::pallas::Point;
type G2 = pasta_curves::vesta::Point;
test_ivc_nontrivial_with_spark_compression_with::<G1, G2>();
}
fn test_ivc_nondet_with_compression_with<G1, G2>()
where
G1: Group<Base = <G2 as Group>::Scalar>,
G2: Group<Base = <G1 as Group>::Scalar>,
// this is due to the reliance on CommitmentKeyExtTrait as a bound in ipa_pc
<G1::CE as CommitmentEngineTrait<G1>>::CommitmentKey:
CommitmentKeyExtTrait<G1, CE = <G1 as Group>::CE>,
<G2::CE as CommitmentEngineTrait<G2>>::CommitmentKey:
CommitmentKeyExtTrait<G2, CE = <G2 as Group>::CE>,
{
// y is a non-deterministic advice representing the fifth root of the input at a step.
#[derive(Clone, Debug)]
struct FifthRootCheckingCircuit<F: PrimeField> {
@@ -1252,10 +1318,10 @@ mod tests {
assert!(res.is_ok());
// produce the prover and verifier keys for compressed snark
let (pk, vk) = CompressedSNARK::<_, _, _, _, S1, S2>::setup(&pp).unwrap();
let (pk, vk) = CompressedSNARK::<_, _, _, _, S1<G1>, S2<G2>>::setup(&pp).unwrap();
// produce a compressed SNARK
let res = CompressedSNARK::<_, _, _, _, S1, S2>::prove(&pp, &pk, &recursive_snark);
let res = CompressedSNARK::<_, _, _, _, S1<G1>, S2<G2>>::prove(&pp, &pk, &recursive_snark);
assert!(res.is_ok());
let compressed_snark = res.unwrap();
@@ -1265,7 +1331,18 @@ mod tests {
}
#[test]
fn test_ivc_base() {
fn test_ivc_nondet_with_compression() {
type G1 = pasta_curves::pallas::Point;
type G2 = pasta_curves::vesta::Point;
test_ivc_nondet_with_compression_with::<G1, G2>();
}
fn test_ivc_base_with<G1, G2>()
where
G1: Group<Base = <G2 as Group>::Scalar>,
G2: Group<Base = <G1 as Group>::Scalar>,
{
// produce public parameters
let pp = PublicParams::<
G1,
@@ -1302,4 +1379,12 @@ mod tests {
assert_eq!(zn_primary, vec![<G1 as Group>::Scalar::ONE]);
assert_eq!(zn_secondary, vec![<G2 as Group>::Scalar::from(5u64)]);
}
#[test]
fn test_ivc_base() {
type G1 = pasta_curves::pallas::Point;
type G2 = pasta_curves::vesta::Point;
test_ivc_base_with::<G1, G2>();
}
}