diff --git a/src/codec.rs b/src/codec.rs index bbb803e..49bfe6b 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -139,10 +139,8 @@ pub fn scalar_decode(buf: &[u8]) -> ScalarField { #[cfg(test)] mod tests { - use crate::testing::{ - suite::{Public, Secret}, - TEST_SEED, - }; + use crate::suites::testing::{Public, Secret}; + use crate::testing::TEST_SEED; use ark_serialize::{CanonicalDeserialize, CanonicalSerialize}; #[test] diff --git a/src/ietf.rs b/src/ietf.rs index bfad65c..dbdcdd1 100644 --- a/src/ietf.rs +++ b/src/ietf.rs @@ -136,6 +136,19 @@ pub mod testing { use super::*; use crate::testing as common; + pub fn prove_verify() { + use ietf::{Prover, Verifier}; + + let secret = Secret::::from_seed(common::TEST_SEED); + let public = secret.public(); + let input = Input::from(common::random_val(None)); + let output = secret.output(input); + + let proof = secret.prove(input, output, b"foo"); + let result = public.verify(input, output, b"foo", &proof); + assert!(result.is_ok()); + } + pub struct TestVector { pub base: common::TestVector, pub c: ScalarField, @@ -211,40 +224,23 @@ pub mod testing { } } -#[cfg(test)] -mod tests { - use super::*; - use crate::testing::{ - random_val, - suite::{AffinePoint, Input, ScalarField, Secret, TestSuite}, - TEST_SEED, - }; - - #[test] - fn prove_verify_works() { - let secret = Secret::from_seed(TEST_SEED); - let public = secret.public(); - let input = Input::from(random_val::(None)); - let output = secret.output(input); - - let proof = secret.prove(input, output, b"foo"); - - let result = public.verify(input, output, b"foo", &proof); - assert!(result.is_ok()); - } - - #[test] - fn proof_encode_decode() { - let c = hex::decode("d091c00b0f5c3619d10ecea44363b5a5").unwrap(); - let c = ScalarField::from_be_bytes_mod_order(&c[..]); - let s = hex::decode("99cadc5b2957e223fec62e81f7b4825fc799a771a3d7334b9186bdbee87316b1") - .unwrap(); - let s = ScalarField::from_be_bytes_mod_order(&s[..]); - - let proof = Proof:: { c, s }; - - let mut buf = Vec::new(); - proof.serialize_compressed(&mut buf).unwrap(); - assert_eq!(buf.len(), TestSuite::CHALLENGE_LEN + 32); - } -} +// #[cfg(test)] +// pub(crate) mod test { +// use super::*; +// use crate::testing::suite::{ScalarField, TestSuite}; + +// #[test] +// fn proof_encode_decode() { +// let c = hex::decode("d091c00b0f5c3619d10ecea44363b5a5").unwrap(); +// let c = ScalarField::from_be_bytes_mod_order(&c[..]); +// let s = hex::decode("99cadc5b2957e223fec62e81f7b4825fc799a771a3d7334b9186bdbee87316b1") +// .unwrap(); +// let s = ScalarField::from_be_bytes_mod_order(&s[..]); + +// let proof = Proof:: { c, s }; + +// let mut buf = Vec::new(); +// proof.serialize_compressed(&mut buf).unwrap(); +// assert_eq!(buf.len(), TestSuite::CHALLENGE_LEN + 32); +// } +// } diff --git a/src/lib.rs b/src/lib.rs index 9d4ed23..da70439 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -277,11 +277,8 @@ impl Output { #[cfg(test)] mod tests { - use crate::testing::{ - random_val, - suite::{Input, Secret}, - TEST_SEED, - }; + use crate::suites::testing::{Input, Secret}; + use crate::testing::{random_val, TEST_SEED}; #[test] fn vrf_output_check() { diff --git a/src/pedersen.rs b/src/pedersen.rs index a0d626a..64def68 100644 --- a/src/pedersen.rs +++ b/src/pedersen.rs @@ -142,49 +142,26 @@ impl Verifier for Public { } #[cfg(test)] -mod tests { +pub(crate) mod testing { use super::*; - use crate::testing::{ - random_val, - suite::{AffinePoint, BaseField, Input, Secret, TestSuite}, - TEST_SEED, - }; - use ark_ff::MontFp; + use crate::testing::{self as common, random_val, TEST_SEED}; - impl PedersenSuite for TestSuite { - const BLINDING_BASE: AffinePoint = { - const X: BaseField = MontFp!( - "1181072390894490040170698195029164902368238760122173135634802939739986120753" - ); - const Y: BaseField = MontFp!( - "16819438535150625131748701663066892288775529055803151482550035706857354997714" - ); - AffinePoint::new_unchecked(X, Y) - }; - } + pub fn pedersen_prove_verify() { + use pedersen::{Prover, Verifier}; - #[test] - fn prove_verify_works() { - let secret = Secret::from_seed(TEST_SEED); + let secret = Secret::::from_seed(TEST_SEED); let input = Input::from(random_val(None)); let output = secret.output(input); let (proof, blinding) = secret.prove(input, output, b"foo"); - let result = Public::verify(input, output, b"foo", &proof); assert!(result.is_ok()); assert_eq!( proof.key_commitment(), - secret.public().0 + TestSuite::BLINDING_BASE * blinding + (secret.public().0 + S::BLINDING_BASE * blinding).into() ); } -} - -#[cfg(test)] -pub mod testing { - use super::*; - use crate::testing as common; pub struct TestVector { pub base: common::TestVector, diff --git a/src/ring.rs b/src/ring.rs index a3836b7..2046ed0 100644 --- a/src/ring.rs +++ b/src/ring.rs @@ -305,3 +305,71 @@ where self.pcs_params.check() } } + +#[cfg(test)] +pub(crate) mod test { + use super::*; + use crate::testing::*; + + pub fn ring_prove_verify() + where + BaseField: ark_ff::PrimeField, + CurveConfig: ark_ec::short_weierstrass::SWCurveConfig + Clone, + AffinePoint: utils::te_sw_map::SWMapping>, + { + use ring::{Prover, RingContext, Verifier}; + + let rng = &mut ark_std::test_rng(); + let ring_ctx = RingContext::::from_rand(512, rng); + + let secret = Secret::::from_seed(TEST_SEED); + let public = secret.public(); + let input = Input::from(random_val(Some(rng))); + let output = secret.output(input); + + let ring_size = ring_ctx.max_ring_size(); + + let prover_idx = 3; + let mut pks = random_vec::>(ring_size, Some(rng)); + pks[prover_idx] = public.0; + + let prover_key = ring_ctx.prover_key(&pks); + let prover = ring_ctx.prover(prover_key, prover_idx); + let proof = secret.prove(input, output, b"foo", &prover); + + let verifier_key = ring_ctx.verifier_key(&pks); + let verifier = ring_ctx.verifier(verifier_key); + let result = Public::verify(input, output, b"foo", &proof, &verifier); + assert!(result.is_ok()); + } + + pub fn check_complement_point() + where + BaseField: ark_ff::PrimeField, + CurveConfig: ark_ec::short_weierstrass::SWCurveConfig + Clone, + AffinePoint: utils::te_sw_map::SWMapping>, + { + use utils::te_sw_map::SWMapping; + let pt = S::COMPLEMENT_POINT.into_sw(); + assert!(pt.is_on_curve()); + assert!(!pt.is_in_correct_subgroup_assuming_on_curve()); + } + + #[macro_export] + macro_rules! ring_suite_tests { + ($suite:ident, true) => { + #[cfg(feature = "ring")] + #[test] + fn ring_prove_verify() { + $crate::ring::test::ring_prove_verify::<$suite>() + } + + #[cfg(feature = "ring")] + #[test] + fn check_complement_point() { + $crate::ring::test::check_complement_point::<$suite>() + } + }; + ($suite:ident, false) => {}; + } +} diff --git a/src/suites/mod.rs b/src/suites/mod.rs index 9a99203..407c073 100644 --- a/src/suites/mod.rs +++ b/src/suites/mod.rs @@ -1,3 +1,6 @@ +#[cfg(test)] +pub(crate) mod testing; + #[cfg(feature = "ed25519")] pub mod ed25519; diff --git a/src/suites/testing.rs b/src/suites/testing.rs new file mode 100644 index 0000000..09410b9 --- /dev/null +++ b/src/suites/testing.rs @@ -0,0 +1,35 @@ +//! Suite for testing + +use crate::testing as common; +use crate::{pedersen::PedersenSuite, *}; +use ark_ff::MontFp; + +#[derive(Debug, Copy, Clone, PartialEq)] +pub struct TestSuite; + +impl Suite for TestSuite { + const SUITE_ID: &'static [u8] = b"ark-ec-vrfs-testing"; + const CHALLENGE_LEN: usize = 16; + + type Affine = ark_ed25519::EdwardsAffine; + type Hasher = sha2::Sha256; + type Codec = codec::ArkworksCodec; + + fn nonce(_sk: &ScalarField, _pt: Input) -> ScalarField { + common::random_val(None) + } +} + +impl PedersenSuite for TestSuite { + const BLINDING_BASE: AffinePoint = { + const X: BaseField = + MontFp!("1181072390894490040170698195029164902368238760122173135634802939739986120753"); + const Y: BaseField = MontFp!( + "16819438535150625131748701663066892288775529055803151482550035706857354997714" + ); + AffinePoint::new_unchecked(X, Y) + }; +} + +suite_types!(TestSuite); +suite_tests!(TestSuite); diff --git a/src/testing.rs b/src/testing.rs index 7404cf7..664d784 100644 --- a/src/testing.rs +++ b/src/testing.rs @@ -7,116 +7,20 @@ use ark_std::{rand::RngCore, UniformRand}; pub const TEST_SEED: &[u8] = b"seed"; -pub(crate) mod suite { - use super::*; - - #[derive(Debug, Copy, Clone, PartialEq)] - pub struct TestSuite; - - impl Suite for TestSuite { - const SUITE_ID: &'static [u8] = b"ark-ec-vrfs-testing"; - const CHALLENGE_LEN: usize = 16; - - type Affine = ark_ed25519::EdwardsAffine; - type Hasher = sha2::Sha256; - type Codec = codec::ArkworksCodec; - - fn nonce(_sk: &ScalarField, _pt: Input) -> ScalarField { - random_val(None) - } - } - - suite_types!(TestSuite); -} - +/// Generate a vector of random values. pub fn random_vec(n: usize, rng: Option<&mut dyn RngCore>) -> Vec { let mut local_rng = ark_std::test_rng(); let rng = rng.unwrap_or(&mut local_rng); (0..n).map(|_| T::rand(rng)).collect() } +/// Generate a vector of random values. pub fn random_val(rng: Option<&mut dyn RngCore>) -> T { let mut local_rng = ark_std::test_rng(); let rng = rng.unwrap_or(&mut local_rng); T::rand(rng) } -pub fn ietf_prove_verify() { - use ietf::{Prover, Verifier}; - - let secret = Secret::::from_seed(TEST_SEED); - let public = secret.public(); - let input = Input::from(random_val(None)); - let output = secret.output(input); - - let proof = secret.prove(input, output, b"foo"); - let result = public.verify(input, output, b"foo", &proof); - assert!(result.is_ok()); -} - -pub fn pedersen_prove_verify() { - use pedersen::{Prover, Verifier}; - - let secret = Secret::::from_seed(TEST_SEED); - let input = Input::from(random_val(None)); - let output = secret.output(input); - - let (proof, blinding) = secret.prove(input, output, b"foo"); - let result = Public::verify(input, output, b"foo", &proof); - assert!(result.is_ok()); - - assert_eq!( - proof.key_commitment(), - (secret.public().0 + S::BLINDING_BASE * blinding).into() - ); -} - -#[cfg(feature = "ring")] -pub fn ring_prove_verify() -where - BaseField: ark_ff::PrimeField, - CurveConfig: ark_ec::short_weierstrass::SWCurveConfig + Clone, - AffinePoint: utils::te_sw_map::SWMapping>, -{ - use ring::{Prover, RingContext, Verifier}; - - let rng = &mut ark_std::test_rng(); - let ring_ctx = RingContext::::from_rand(512, rng); - - let secret = Secret::::from_seed(TEST_SEED); - let public = secret.public(); - let input = Input::from(random_val(Some(rng))); - let output = secret.output(input); - - let ring_size = ring_ctx.max_ring_size(); - - let prover_idx = 3; - let mut pks = random_vec::>(ring_size, Some(rng)); - pks[prover_idx] = public.0; - - let prover_key = ring_ctx.prover_key(&pks); - let prover = ring_ctx.prover(prover_key, prover_idx); - let proof = secret.prove(input, output, b"foo", &prover); - - let verifier_key = ring_ctx.verifier_key(&pks); - let verifier = ring_ctx.verifier(verifier_key); - let result = Public::verify(input, output, b"foo", &proof, &verifier); - assert!(result.is_ok()); -} - -#[cfg(feature = "ring")] -pub fn check_complement_point() -where - BaseField: ark_ff::PrimeField, - CurveConfig: ark_ec::short_weierstrass::SWCurveConfig + Clone, - AffinePoint: utils::te_sw_map::SWMapping>, -{ - use utils::te_sw_map::SWMapping; - let pt = S::COMPLEMENT_POINT.into_sw(); - assert!(pt.is_on_curve()); - assert!(!pt.is_in_correct_subgroup_assuming_on_curve()); -} - #[macro_export] macro_rules! suite_tests { ($suite:ident, $build_ring:ident) => { @@ -126,56 +30,16 @@ macro_rules! suite_tests { ($suite:ident) => { #[test] fn ietf_prove_verify() { - $crate::testing::ietf_prove_verify::<$suite>(); + $crate::ietf::testing::prove_verify::<$suite>(); } #[test] fn pedersen_prove_verify() { - $crate::testing::pedersen_prove_verify::<$suite>(); + $crate::pedersen::testing::pedersen_prove_verify::<$suite>(); } }; } -#[macro_export] -macro_rules! ring_suite_tests { - ($suite:ident, true) => { - #[cfg(feature = "ring")] - #[test] - fn ring_prove_verify() { - $crate::testing::ring_prove_verify::<$suite>() - } - - #[cfg(feature = "ring")] - #[test] - fn check_complement_point() { - $crate::testing::check_complement_point::<$suite>() - } - }; - ($suite:ident, false) => {}; -} - -impl core::fmt::Debug for TestVector { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let sk = hex::encode(codec::scalar_encode::(&self.sk)); - let pk = hex::encode(codec::point_encode::(&self.pk)); - let alpha = hex::encode(&self.alpha); - let ad = hex::encode(&self.ad); - let h = hex::encode(codec::point_encode::(&self.h)); - let gamma = hex::encode(codec::point_encode::(&self.gamma)); - let beta = hex::encode(&self.beta); - f.debug_struct("TestVector") - .field("comment", &self.comment) - .field("sk", &sk) - .field("pk", &pk) - .field("alpha", &alpha) - .field("ad", &ad) - .field("h", &h) - .field("gamma", &gamma) - .field("beta", &beta) - .finish() - } -} - #[derive(Debug, serde::Serialize, serde::Deserialize)] pub struct TestVectorMap(pub indexmap::IndexMap); @@ -206,6 +70,28 @@ pub struct TestVector { pub beta: Vec, } +impl core::fmt::Debug for TestVector { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let sk = hex::encode(codec::scalar_encode::(&self.sk)); + let pk = hex::encode(codec::point_encode::(&self.pk)); + let alpha = hex::encode(&self.alpha); + let ad = hex::encode(&self.ad); + let h = hex::encode(codec::point_encode::(&self.h)); + let gamma = hex::encode(codec::point_encode::(&self.gamma)); + let beta = hex::encode(&self.beta); + f.debug_struct("TestVector") + .field("comment", &self.comment) + .field("sk", &sk) + .field("pk", &pk) + .field("alpha", &alpha) + .field("ad", &ad) + .field("h", &h) + .field("gamma", &gamma) + .field("beta", &beta) + .finish() + } +} + impl TestVectorTrait for TestVector { fn new(comment: &str, seed: &[u8], alpha: &[u8], salt: Option<&[u8]>, ad: &[u8]) -> Self { let sk = Secret::::from_seed(seed); diff --git a/src/utils.rs b/src/utils.rs index 4107926..3756751 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -242,7 +242,7 @@ where #[cfg(test)] mod tests { use super::*; - use crate::testing::suite::TestSuite; + use crate::suites::testing::TestSuite; #[test] fn hash_to_curve_tai_works() {