Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose test_for_all_curves! macro #96

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ repository = "https://github.com/ZenGo-X/curv"
[lib]
crate-type = ["lib"]

[features]
default = []
# Exposes utils useful for testing
testing-utils = ["paste"]

[dependencies]
rand = "0.6"
serde = "1.0"
Expand All @@ -22,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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
8 changes: 7 additions & 1 deletion src/elliptic/curves/p256.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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()) };
Expand Down
90 changes: 81 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,42 +24,114 @@ 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<P: ECPoint>()
/// 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::<curv::elliptic::curves::secp256_k1::GE>();
/// ```
///
/// Macro will generate this code for you:
/// ```rust
/// # use curv::elliptic::curves::traits::*;
/// # fn test_dh<P: ECPoint>() { /* see code snippet above */ }
/// #[test]
/// fn test_dh_secp256k1() {
/// test_dh::<curv::elliptic::curves::secp256_k1::GE>()
/// }
/// #[test]
/// fn test_dh_ristretto() {
/// test_dh::<curv::elliptic::curves::curve_ristretto::GE>()
/// }
/// #[test]
/// fn test_dh_ed25519() {
/// test_dh::<curv::elliptic::curves::ed25519::GE>()
/// }
/// #[test]
/// fn test_dh_bls12_381() {
/// test_dh::<curv::elliptic::curves::bls12_381::GE>()
/// }
/// #[test]
/// fn test_dh_p256() {
/// test_dh::<curv::elliptic::curves::p256::GE>()
/// }
/// ```
///
/// ## 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<P: ECPoint>() { /* ... */ }
/// ```
///
/// 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) => {
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!{
$crate::paste!{
#[test]
$($attrs)*
fn [<$fn _secp256k1>]() {
$fn::<crate::elliptic::curves::secp256_k1::GE>()
$fn::<$crate::elliptic::curves::secp256_k1::GE>()
}
#[test]
$($attrs)*
fn [<$fn _ristretto>]() {
$fn::<crate::elliptic::curves::curve_ristretto::GE>()
$fn::<$crate::elliptic::curves::curve_ristretto::GE>()
}
#[test]
$($attrs)*
fn [<$fn _ed25519>]() {
$fn::<crate::elliptic::curves::ed25519::GE>()
$fn::<$crate::elliptic::curves::ed25519::GE>()
}
#[test]
$($attrs)*
fn [<$fn _bls12_381>]() {
$fn::<crate::elliptic::curves::bls12_381::GE>()
$fn::<$crate::elliptic::curves::bls12_381::GE>()
}
#[test]
$($attrs)*
fn [<$fn _p256>]() {
$fn::<crate::elliptic::curves::p256::GE>()
$fn::<$crate::elliptic::curves::p256::GE>()
}
}
};
}

/// Re-exporting macro to use in `test_for_all_curves!`
#[cfg(any(test, feature = "testing-utils"))]
#[doc(hidden)]
pub use paste::paste;