#[macro_export]
macro_rules! curve_test {
($test_name:ident, $field:ident, $affine:ident, $projective:ident, $iter_times:expr) => {
use super::*;
use paste::paste;
use rand_core::OsRng;
curve_operation_test!($test_name, affine, $affine, $field, $iter_times);
curve_operation_test!($test_name, projective, $projective, $field, $iter_times);
paste! {
#[test]
fn [< $test_name _coordinate_transformation_test >]() {
for _ in 0..$iter_times {
let a = $affine::from($affine::random(OsRng));
let b = $projective::from(a);
let projective = $projective::from(a);
let affine = $affine::from(b);
assert!(affine.is_on_curve());
assert!(projective.is_on_curve());
assert_eq!(a, affine);
assert_eq!(b, projective);
}
}
}
paste! {
#[test]
fn [< $test_name _mix_addition_test >]() {
let a = $affine::random(OsRng);
let b = $affine::random(OsRng);
let c = $affine::random(OsRng);
let d = $projective::from(a);
let e = $projective::from(b);
let f = $projective::from(c);
let abc = a + b + c;
let cab = c + a + b;
let def = d + e + f;
let fde = f + d + e;
let double_ab = (a + b).double();
let aabb = a.double() + b.double();
let double_de = (d + e).double();
let ddee = d.double() + e.double();
assert_eq!(abc, cab);
assert_eq!(def, fde);
assert_eq!(double_ab, aabb);
assert_eq!(double_de, ddee);
assert_eq!($projective::from(abc), fde);
assert_eq!($projective::from(cab), def);
assert_eq!($projective::from(double_ab), ddee);
assert_eq!($projective::from(aabb), double_de);
}
}
paste! {
#[test]
fn [< $test_name _mix_doubling_test >]() {
for _ in 0..$iter_times {
let a = $affine::random(OsRng);
let b = $projective::from(a);
let s = $field::from(8 as u64);
let scalared_a = a * s;
let a_8 = a.double().double().double();
let scalared_b = b * s;
let b_8 = b.double().double().double();
assert_eq!(scalared_a, a_8);
assert_eq!(scalared_b, b_8);
assert_eq!($projective::from(scalared_a), b_8);
assert_eq!($projective::from(a_8), scalared_b);
}
}
}
paste! {
#[test]
fn [< $test_name _mix_scalar_test >]() {
for _ in 0..$iter_times {
let g = $affine::random(OsRng);
let h = $projective::from(g);
let ag = g * $field::from(7 as u64);
let bg = g * $field::from(16 as u64);
let agbg = (ag + bg).double();
let abg = g * $field::from(46 as u64);
let ah = h * $field::from(7 as u64);
let bh = h * $field::from(16 as u64);
let ahbh = (ah + bh).double();
let abh = h * $field::from(46 as u64);
assert_eq!(agbg, abg);
assert_eq!(ahbh, abh);
assert_eq!($projective::from(agbg), abh);
assert_eq!($projective::from(abg), ahbh);
}
}
}
};
}
#[macro_export]
macro_rules! curve_operation_test {
($test_name:ident, $curve_name:ident, $curve:ident, $field:ident, $iter_times:expr) => {
paste! {
#[test]
fn [< $test_name _ $curve_name _is_on_curve_test >]() {
assert!($curve::ADDITIVE_GENERATOR.is_on_curve());
assert!($curve::ADDITIVE_IDENTITY.is_on_curve());
}
}
paste! {
#[test]
fn [< $test_name _ $curve_name _identity_test >]() {
let a = $curve::random(OsRng);
let a_prime = a + $curve::ADDITIVE_IDENTITY;
assert_eq!(a_prime.to_affine(), a.into());
}
}
paste! {
#[test]
fn [< $test_name _ $curve_name _addition_test >]() {
for _ in 0..$iter_times {
let a = $curve::random(OsRng);
let b = $curve::random(OsRng);
let c = $curve::random(OsRng);
let ab = a + b;
let abc = ab + c;
let ca = c + a;
let cab = ca + b;
let double_ab = ab.double();
let aa = a.double();
let bb = b.double();
let aabb = aa + bb;
assert!(abc.is_on_curve());
assert!(cab.is_on_curve());
assert!(double_ab.is_on_curve());
assert!(aabb.is_on_curve());
assert_eq!(abc, cab);
assert_eq!(double_ab, aabb);
}
}
}
paste! {
#[test]
fn [< $test_name _ $curve_name _doubling_test >]() {
for _ in 0..$iter_times {
let a = $curve::random(OsRng);
let scalared_a = a * $field::from(8 as u64);
let a_8 = a.double().double().double();
assert!(scalared_a.is_on_curve());
assert!(a_8.is_on_curve());
assert_eq!(scalared_a, a_8);
}
}
}
paste! {
#[test]
fn [< $test_name _ $curve_name _scalar_test >]() {
for _ in 0..$iter_times {
let g = $curve::random(OsRng);
let ag = g * $field::from(7 as u64);
let bg = g * $field::from(16 as u64);
let agbg = ag + bg;
let abg = g * $field::from(23 as u64);
assert!(agbg.is_on_curve());
assert!(abg.is_on_curve());
assert_eq!(agbg, abg);
}
}
}
};
}
pub use {curve_operation_test, curve_test};