From bed4a5d78e8cbaaaeae2d470736ddc66845ab898 Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Thu, 10 Dec 2020 22:23:54 +0700 Subject: [PATCH 1/5] Expose test_for_all_curves --- .travis.yml | 8 +++++-- Cargo.toml | 5 ++++ src/lib.rs | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 79 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7b3372c3..51735ca4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,10 +3,14 @@ cache: cargo rust: - stable +env: + global: + - FEATURES=testing-utils + before_script: - rustup component add rustfmt-preview - cargo fmt --all -- --check script: - - cargo build --verbose - - cargo test --verbose + - cargo build --features $FEATURES --verbose + - cargo test --features $FEATURES --verbose diff --git a/Cargo.toml b/Cargo.toml index 8a79e4a7..cc4327ec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,11 @@ repository = "https://github.com/ZenGo-X/curv" [lib] crate-type = ["lib"] +[features] +default = [] +# Exposes utils useful for testing +testing-utils = [] + [dependencies] rand = "0.6" serde = "1.0" diff --git a/src/lib.rs b/src/lib.rs index cdf391cb..087678f1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,7 +24,74 @@ pub enum ErrorSS { VerifyShareError, } -#[cfg(test)] +/// Helps write tests generic over choice of elliptic curve +/// +/// As input it expects name of a function which takes one generic parameter: +/// curve implementation. Function restricted to have no arguments and return `()`. +/// Macro outputs several tests each one runs given function with specific curve implementation. +/// +/// ## Example +/// Suppose you have following generic test: +/// ```rust +/// # use curv::elliptic::curves::traits::*; +/// # use curv::test_for_all_curves; +/// test_for_all_curves!(test_dh); +/// fn test_dh() +/// where P: ECPoint + Clone, +/// P::Scalar: Clone, +/// { +/// let party_a_secret: P::Scalar = ECScalar::new_random(); +/// let party_a_public = P::generator() * party_a_secret.clone(); +/// +/// let party_b_secret: P::Scalar = ECScalar::new_random(); +/// let party_b_public = P::generator() * party_b_secret.clone(); +/// +/// let party_a_share = party_b_public * party_a_secret; +/// let party_b_share = party_a_public * party_b_secret; +/// +/// assert!(party_a_share == party_b_share, "Parties share expected to be the same") +/// } +/// # test_dh::(); +/// ``` +/// +/// Macro will generate this code for you: +/// ```rust +/// # use curv::elliptic::curves::traits::*; +/// # fn test_dh() { /* see code snippet above */ } +/// #[test] +/// fn test_dh_secp256k1() { +/// test_dh::() +/// } +/// #[test] +/// fn test_dh_ristretto() { +/// test_dh::() +/// } +/// #[test] +/// fn test_dh_ed25519() { +/// test_dh::() +/// } +/// #[test] +/// fn test_dh_bls12_381() { +/// test_dh::() +/// } +/// #[test] +/// fn test_dh_p256() { +/// test_dh::() +/// } +/// ``` +/// +/// ## Attributes +/// You can also pass `#[should_panic]` attribute: +/// ```rust +/// # use curv::elliptic::curves::traits::*; +/// # use curv::test_for_all_curves; +/// test_for_all_curves!(#[should_panic] failure_test); +/// fn failure_test() { /* ... */ } +/// ``` +/// +/// This will require every produced test to panic. +#[cfg(any(test, feature = "testing-utils"))] +#[cfg_attr(docsrs, doc(cfg(feature = "testing-utils")))] #[macro_export] macro_rules! test_for_all_curves { (#[should_panic] $fn: ident) => { From 4e67c1f2c552ad695ebe5de6596660228e230d57 Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Sun, 6 Dec 2020 19:37:46 +0700 Subject: [PATCH 2/5] Fix macro --- src/lib.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 087678f1..a21aca34 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -95,37 +95,37 @@ pub enum ErrorSS { #[macro_export] macro_rules! test_for_all_curves { (#[should_panic] $fn: ident) => { - crate::test_for_all_curves!([#[should_panic]] $fn); + $crate::test_for_all_curves!([#[should_panic]] $fn); }; ($fn: ident) => { - crate::test_for_all_curves!([] $fn); + $crate::test_for_all_curves!([] $fn); }; ([$($attrs:tt)*] $fn: ident) => { paste::paste!{ #[test] $($attrs)* fn [<$fn _secp256k1>]() { - $fn::() + $fn::<$crate::elliptic::curves::secp256_k1::GE>() } #[test] $($attrs)* fn [<$fn _ristretto>]() { - $fn::() + $fn::<$crate::elliptic::curves::curve_ristretto::GE>() } #[test] $($attrs)* fn [<$fn _ed25519>]() { - $fn::() + $fn::<$crate::elliptic::curves::ed25519::GE>() } #[test] $($attrs)* fn [<$fn _bls12_381>]() { - $fn::() + $fn::<$crate::elliptic::curves::bls12_381::GE>() } #[test] $($attrs)* fn [<$fn _p256>]() { - $fn::() + $fn::<$crate::elliptic::curves::p256::GE>() } } }; From 62da5737e82340cfd5f924b9b53fbec2f9079c42 Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Fri, 11 Dec 2020 12:51:21 +0700 Subject: [PATCH 3/5] Fix test leading zeroes in the hash lead to test failure --- src/cryptographic_primitives/commitments/hash_commitment.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cryptographic_primitives/commitments/hash_commitment.rs b/src/cryptographic_primitives/commitments/hash_commitment.rs index c70f2ab5..01f607fe 100644 --- a/src/cryptographic_primitives/commitments/hash_commitment.rs +++ b/src/cryptographic_primitives/commitments/hash_commitment.rs @@ -80,7 +80,7 @@ mod tests { let (_commitment, blind_factor) = HashCommitment::create_commitment(&message); let commitment2 = HashCommitment::create_commitment_with_user_defined_randomness(&message, &blind_factor); - assert_eq!(commitment2.to_str_radix(16).len(), SECURITY_BITS / 4); + assert!(commitment2.to_str_radix(16).len() / 2 <= SECURITY_BITS / 8); } #[test] From a7b5511139c1582c8d81797f44132fae485cce78 Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Sat, 12 Dec 2020 16:05:16 +0700 Subject: [PATCH 4/5] Don't require to depend directly on `paste` crate --- Cargo.toml | 3 ++- src/lib.rs | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index cc4327ec..893550e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ crate-type = ["lib"] [features] default = [] # Exposes utils useful for testing -testing-utils = [] +testing-utils = ["paste"] [dependencies] rand = "0.6" @@ -27,6 +27,7 @@ digest = "0.8.1" hex = "^0.3" blake2b_simd = "0.5.7" derivative = "2.1.1" +paste = { version = "1.0.2", optional = true } [dependencies.rust-gmp-kzen] version = "0.5.0" diff --git a/src/lib.rs b/src/lib.rs index a21aca34..6624ac81 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -101,7 +101,7 @@ macro_rules! test_for_all_curves { $crate::test_for_all_curves!([] $fn); }; ([$($attrs:tt)*] $fn: ident) => { - paste::paste!{ + $crate::paste!{ #[test] $($attrs)* fn [<$fn _secp256k1>]() { @@ -130,3 +130,8 @@ macro_rules! test_for_all_curves { } }; } + +/// Re-exporting macro to use in `test_for_all_curves!` +#[cfg(any(test, feature = "testing-utils"))] +#[doc(hidden)] +pub use paste::paste; From b37c6ec6b09c34465ff93b43a3a7740ea595d528 Mon Sep 17 00:00:00 2001 From: Denis Varlakov Date: Thu, 17 Dec 2020 13:27:00 +0700 Subject: [PATCH 5/5] Fix comparing p256 point --- src/elliptic/curves/p256.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/elliptic/curves/p256.rs b/src/elliptic/curves/p256.rs index 75ea2445..de230337 100644 --- a/src/elliptic/curves/p256.rs +++ b/src/elliptic/curves/p256.rs @@ -28,7 +28,7 @@ pub struct Secp256r1Scalar { fe: SK, } -#[derive(Clone, Copy, Debug, PartialEq)] +#[derive(Clone, Copy, Debug)] pub struct Secp256r1Point { purpose: &'static str, ge: PK, @@ -228,6 +228,12 @@ impl PartialEq for Secp256r1Scalar { } } +impl PartialEq for Secp256r1Point { + fn eq(&self, other: &GE) -> bool { + self.ge == other.ge + } +} + impl Zeroize for Secp256r1Point { fn zeroize(&mut self) { unsafe { ptr::write_volatile(self, GE::generator()) };