#![allow(unused)]
|
|
use ark_ec::{
|
|
AffineCurve, MontgomeryModelParameters, ProjectiveCurve, SWModelParameters, TEModelParameters,
|
|
};
|
|
use ark_ff::{Field, One, PrimeField, UniformRand, Zero};
|
|
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, SWFlags, SerializationError};
|
|
use ark_std::{io::Cursor, vec::Vec};
|
|
use rand::SeedableRng;
|
|
use rand_xorshift::XorShiftRng;
|
|
|
|
pub const ITERATIONS: usize = 10;
|
|
|
|
fn random_addition_test<G: ProjectiveCurve>() {
|
|
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|
|
|
for _ in 0..ITERATIONS {
|
|
let a = G::rand(&mut rng);
|
|
let b = G::rand(&mut rng);
|
|
let c = G::rand(&mut rng);
|
|
let a_affine = a.into_affine();
|
|
let b_affine = b.into_affine();
|
|
let c_affine = c.into_affine();
|
|
|
|
// a + a should equal the doubling
|
|
{
|
|
let mut aplusa = a;
|
|
aplusa.add_assign(&a);
|
|
|
|
let mut aplusamixed = a;
|
|
aplusamixed.add_assign_mixed(&a.into_affine());
|
|
|
|
let mut adouble = a;
|
|
adouble.double_in_place();
|
|
|
|
assert_eq!(aplusa, adouble);
|
|
assert_eq!(aplusa, aplusamixed);
|
|
}
|
|
|
|
let mut tmp = vec![G::zero(); 6];
|
|
|
|
// (a + b) + c
|
|
tmp[0] = (a + &b) + &c;
|
|
|
|
// a + (b + c)
|
|
tmp[1] = a + &(b + &c);
|
|
|
|
// (a + c) + b
|
|
tmp[2] = (a + &c) + &b;
|
|
|
|
// Mixed addition
|
|
|
|
// (a + b) + c
|
|
tmp[3] = a_affine.into_projective();
|
|
tmp[3].add_assign_mixed(&b_affine);
|
|
tmp[3].add_assign_mixed(&c_affine);
|
|
|
|
// a + (b + c)
|
|
tmp[4] = b_affine.into_projective();
|
|
tmp[4].add_assign_mixed(&c_affine);
|
|
tmp[4].add_assign_mixed(&a_affine);
|
|
|
|
// (a + c) + b
|
|
tmp[5] = a_affine.into_projective();
|
|
tmp[5].add_assign_mixed(&c_affine);
|
|
tmp[5].add_assign_mixed(&b_affine);
|
|
|
|
// Comparisons
|
|
for i in 0..6 {
|
|
for j in 0..6 {
|
|
if tmp[i] != tmp[j] {
|
|
println!("{} \n{}", tmp[i], tmp[j]);
|
|
}
|
|
assert_eq!(tmp[i], tmp[j], "Associativity failed {} {}", i, j);
|
|
assert_eq!(
|
|
tmp[i].into_affine(),
|
|
tmp[j].into_affine(),
|
|
"Associativity failed"
|
|
);
|
|
}
|
|
|
|
assert!(tmp[i] != a);
|
|
assert!(tmp[i] != b);
|
|
assert!(tmp[i] != c);
|
|
|
|
assert!(a != tmp[i]);
|
|
assert!(b != tmp[i]);
|
|
assert!(c != tmp[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn random_multiplication_test<G: ProjectiveCurve>() {
|
|
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|
|
|
for _ in 0..ITERATIONS {
|
|
let mut a = G::rand(&mut rng);
|
|
let mut b = G::rand(&mut rng);
|
|
let a_affine = a.into_affine();
|
|
let b_affine = b.into_affine();
|
|
|
|
let s = G::ScalarField::rand(&mut rng);
|
|
|
|
// s ( a + b )
|
|
let mut tmp1 = a;
|
|
tmp1.add_assign(&b);
|
|
tmp1.mul_assign(s);
|
|
|
|
// sa + sb
|
|
a.mul_assign(s);
|
|
b.mul_assign(s);
|
|
|
|
let mut tmp2 = a;
|
|
tmp2.add_assign(&b);
|
|
|
|
// Affine multiplication
|
|
let mut tmp3 = a_affine.mul(s.into_repr());
|
|
tmp3.add_assign(&b_affine.mul(s.into_repr()));
|
|
|
|
assert_eq!(tmp1, tmp2);
|
|
assert_eq!(tmp1, tmp3);
|
|
}
|
|
}
|
|
|
|
fn random_doubling_test<G: ProjectiveCurve>() {
|
|
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|
|
|
for _ in 0..ITERATIONS {
|
|
let mut a = G::rand(&mut rng);
|
|
let mut b = G::rand(&mut rng);
|
|
|
|
// 2(a + b)
|
|
let mut tmp1 = a;
|
|
tmp1.add_assign(&b);
|
|
tmp1.double_in_place();
|
|
|
|
// 2a + 2b
|
|
a.double_in_place();
|
|
b.double_in_place();
|
|
|
|
let mut tmp2 = a;
|
|
tmp2.add_assign(&b);
|
|
|
|
let mut tmp3 = a;
|
|
tmp3.add_assign_mixed(&b.into_affine());
|
|
|
|
assert_eq!(tmp1, tmp2);
|
|
assert_eq!(tmp1, tmp3);
|
|
}
|
|
}
|
|
|
|
fn random_negation_test<G: ProjectiveCurve>() {
|
|
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|
|
|
for _ in 0..ITERATIONS {
|
|
let r = G::rand(&mut rng);
|
|
|
|
let s = G::ScalarField::rand(&mut rng);
|
|
let sneg = -s;
|
|
assert!((s + &sneg).is_zero());
|
|
|
|
let mut t1 = r;
|
|
t1.mul_assign(s);
|
|
|
|
let mut t2 = r;
|
|
t2.mul_assign(sneg);
|
|
|
|
let mut t3 = t1;
|
|
t3.add_assign(&t2);
|
|
assert!(t3.is_zero());
|
|
|
|
let mut t4 = t1;
|
|
t4.add_assign_mixed(&t2.into_affine());
|
|
assert!(t4.is_zero());
|
|
|
|
t1 = -t1;
|
|
assert_eq!(t1, t2);
|
|
}
|
|
}
|
|
|
|
fn random_transformation_test<G: ProjectiveCurve>() {
|
|
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|
|
|
for _ in 0..ITERATIONS {
|
|
let g = G::rand(&mut rng);
|
|
let g_affine = g.into_affine();
|
|
let g_projective = g_affine.into_projective();
|
|
assert_eq!(g, g_projective);
|
|
}
|
|
|
|
// Batch normalization
|
|
for _ in 0..10 {
|
|
let mut v = (0..ITERATIONS)
|
|
.map(|_| G::rand(&mut rng))
|
|
.collect::<Vec<_>>();
|
|
|
|
for i in &v {
|
|
assert!(!i.is_normalized());
|
|
}
|
|
|
|
use rand::distributions::{Distribution, Uniform};
|
|
let between = Uniform::from(0..ITERATIONS);
|
|
// Sprinkle in some normalized points
|
|
for _ in 0..5 {
|
|
v[between.sample(&mut rng)] = G::zero();
|
|
}
|
|
for _ in 0..5 {
|
|
let s = between.sample(&mut rng);
|
|
v[s] = v[s].into_affine().into_projective();
|
|
}
|
|
|
|
let expected_v = v
|
|
.iter()
|
|
.map(|v| v.into_affine().into_projective())
|
|
.collect::<Vec<_>>();
|
|
G::batch_normalization(&mut v);
|
|
|
|
for i in &v {
|
|
assert!(i.is_normalized());
|
|
}
|
|
|
|
assert_eq!(v, expected_v);
|
|
}
|
|
}
|
|
|
|
pub fn curve_tests<G: ProjectiveCurve>() {
|
|
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|
|
|
// Negation edge case with zero.
|
|
{
|
|
let z = -G::zero();
|
|
assert!(z.is_zero());
|
|
}
|
|
|
|
// Doubling edge case with zero.
|
|
{
|
|
let mut z = -G::zero();
|
|
z.double_in_place();
|
|
assert!(z.is_zero());
|
|
}
|
|
|
|
// Addition edge cases with zero
|
|
{
|
|
let mut r = G::rand(&mut rng);
|
|
let rcopy = r;
|
|
r.add_assign(&G::zero());
|
|
assert_eq!(r, rcopy);
|
|
r.add_assign_mixed(&G::Affine::zero());
|
|
assert_eq!(r, rcopy);
|
|
|
|
let mut z = G::zero();
|
|
z.add_assign(&G::zero());
|
|
assert!(z.is_zero());
|
|
z.add_assign_mixed(&G::Affine::zero());
|
|
assert!(z.is_zero());
|
|
|
|
let mut z2 = z;
|
|
z2.add_assign(&r);
|
|
|
|
z.add_assign_mixed(&r.into_affine());
|
|
|
|
assert_eq!(z, z2);
|
|
assert_eq!(z, r);
|
|
}
|
|
|
|
// Transformations
|
|
{
|
|
let a = G::rand(&mut rng);
|
|
let b = a.into_affine().into_projective();
|
|
let c = a
|
|
.into_affine()
|
|
.into_projective()
|
|
.into_affine()
|
|
.into_projective();
|
|
assert_eq!(a, b);
|
|
assert_eq!(b, c);
|
|
}
|
|
|
|
// Test COFACTOR and COFACTOR_INV
|
|
{
|
|
let a = G::rand(&mut rng);
|
|
let b = a.into_affine();
|
|
let c = b.mul_by_cofactor_inv().mul_by_cofactor();
|
|
assert_eq!(b, c);
|
|
}
|
|
|
|
random_addition_test::<G>();
|
|
random_multiplication_test::<G>();
|
|
random_doubling_test::<G>();
|
|
random_negation_test::<G>();
|
|
random_transformation_test::<G>();
|
|
}
|
|
|
|
pub fn sw_tests<P: SWModelParameters>() {
|
|
sw_curve_serialization_test::<P>();
|
|
sw_from_random_bytes::<P>();
|
|
}
|
|
|
|
pub fn sw_from_random_bytes<P: SWModelParameters>() {
|
|
use ark_ec::models::short_weierstrass_jacobian::{GroupAffine, GroupProjective};
|
|
|
|
let buf_size = GroupAffine::<P>::zero().serialized_size();
|
|
|
|
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|
|
|
for _ in 0..ITERATIONS {
|
|
let a = GroupProjective::<P>::rand(&mut rng);
|
|
let mut a = a.into_affine();
|
|
{
|
|
let mut serialized = vec![0; buf_size];
|
|
let mut cursor = Cursor::new(&mut serialized[..]);
|
|
a.serialize(&mut cursor).unwrap();
|
|
|
|
let mut cursor = Cursor::new(&serialized[..]);
|
|
let p1 = GroupAffine::<P>::deserialize(&mut cursor).unwrap();
|
|
let p2 = GroupAffine::<P>::from_random_bytes(&serialized).unwrap();
|
|
assert_eq!(p1, p2);
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn sw_curve_serialization_test<P: SWModelParameters>() {
|
|
use ark_ec::models::short_weierstrass_jacobian::{GroupAffine, GroupProjective};
|
|
|
|
let buf_size = GroupAffine::<P>::zero().serialized_size();
|
|
|
|
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|
|
|
for _ in 0..ITERATIONS {
|
|
let a = GroupProjective::<P>::rand(&mut rng);
|
|
let mut a = a.into_affine();
|
|
{
|
|
let mut serialized = vec![0; buf_size];
|
|
let mut cursor = Cursor::new(&mut serialized[..]);
|
|
a.serialize(&mut cursor).unwrap();
|
|
|
|
let mut cursor = Cursor::new(&serialized[..]);
|
|
let b = GroupAffine::<P>::deserialize(&mut cursor).unwrap();
|
|
assert_eq!(a, b);
|
|
}
|
|
|
|
{
|
|
a.y = -a.y;
|
|
let mut serialized = vec![0; buf_size];
|
|
let mut cursor = Cursor::new(&mut serialized[..]);
|
|
a.serialize(&mut cursor).unwrap();
|
|
let mut cursor = Cursor::new(&serialized[..]);
|
|
let b = GroupAffine::<P>::deserialize(&mut cursor).unwrap();
|
|
assert_eq!(a, b);
|
|
}
|
|
|
|
{
|
|
let a = GroupAffine::<P>::zero();
|
|
let mut serialized = vec![0; buf_size];
|
|
let mut cursor = Cursor::new(&mut serialized[..]);
|
|
a.serialize(&mut cursor).unwrap();
|
|
let mut cursor = Cursor::new(&serialized[..]);
|
|
let b = GroupAffine::<P>::deserialize(&mut cursor).unwrap();
|
|
assert_eq!(a, b);
|
|
}
|
|
|
|
{
|
|
let a = GroupAffine::<P>::zero();
|
|
let mut serialized = vec![0; buf_size - 1];
|
|
let mut cursor = Cursor::new(&mut serialized[..]);
|
|
a.serialize(&mut cursor).unwrap_err();
|
|
}
|
|
|
|
{
|
|
let serialized = vec![0; buf_size - 1];
|
|
let mut cursor = Cursor::new(&serialized[..]);
|
|
GroupAffine::<P>::deserialize(&mut cursor).unwrap_err();
|
|
}
|
|
|
|
{
|
|
let mut serialized = vec![0; a.uncompressed_size()];
|
|
let mut cursor = Cursor::new(&mut serialized[..]);
|
|
a.serialize_uncompressed(&mut cursor).unwrap();
|
|
|
|
let mut cursor = Cursor::new(&serialized[..]);
|
|
let b = GroupAffine::<P>::deserialize_uncompressed(&mut cursor).unwrap();
|
|
assert_eq!(a, b);
|
|
}
|
|
|
|
{
|
|
a.y = -a.y;
|
|
let mut serialized = vec![0; a.uncompressed_size()];
|
|
let mut cursor = Cursor::new(&mut serialized[..]);
|
|
a.serialize_uncompressed(&mut cursor).unwrap();
|
|
let mut cursor = Cursor::new(&serialized[..]);
|
|
let b = GroupAffine::<P>::deserialize_uncompressed(&mut cursor).unwrap();
|
|
assert_eq!(a, b);
|
|
}
|
|
|
|
{
|
|
let a = GroupAffine::<P>::zero();
|
|
let mut serialized = vec![0; a.uncompressed_size()];
|
|
let mut cursor = Cursor::new(&mut serialized[..]);
|
|
a.serialize_uncompressed(&mut cursor).unwrap();
|
|
let mut cursor = Cursor::new(&serialized[..]);
|
|
let b = GroupAffine::<P>::deserialize_uncompressed(&mut cursor).unwrap();
|
|
assert_eq!(a, b);
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn montgomery_conversion_test<P>()
|
|
where
|
|
P: TEModelParameters,
|
|
{
|
|
// A = 2 * (a + d) / (a - d)
|
|
let a = P::BaseField::one().double()
|
|
* &(P::COEFF_A + &P::COEFF_D)
|
|
* &(P::COEFF_A - &P::COEFF_D).inverse().unwrap();
|
|
// B = 4 / (a - d)
|
|
let b = P::BaseField::one().double().double() * &(P::COEFF_A - &P::COEFF_D).inverse().unwrap();
|
|
|
|
assert_eq!(a, P::MontgomeryModelParameters::COEFF_A);
|
|
assert_eq!(b, P::MontgomeryModelParameters::COEFF_B);
|
|
}
|
|
|
|
pub fn edwards_tests<P: TEModelParameters>()
|
|
where
|
|
P::BaseField: PrimeField,
|
|
{
|
|
edwards_curve_serialization_test::<P>();
|
|
edwards_from_random_bytes::<P>();
|
|
}
|
|
|
|
pub fn edwards_from_random_bytes<P: TEModelParameters>()
|
|
where
|
|
P::BaseField: PrimeField,
|
|
{
|
|
use ark_ec::models::twisted_edwards_extended::{GroupAffine, GroupProjective};
|
|
use ark_ff::{to_bytes, ToBytes};
|
|
|
|
let buf_size = GroupAffine::<P>::zero().serialized_size();
|
|
|
|
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|
|
|
for _ in 0..ITERATIONS {
|
|
let a = GroupProjective::<P>::rand(&mut rng);
|
|
let mut a = a.into_affine();
|
|
{
|
|
let mut serialized = vec![0; buf_size];
|
|
let mut cursor = Cursor::new(&mut serialized[..]);
|
|
a.serialize(&mut cursor).unwrap();
|
|
|
|
let mut cursor = Cursor::new(&serialized[..]);
|
|
let p1 = GroupAffine::<P>::deserialize(&mut cursor).unwrap();
|
|
let p2 = GroupAffine::<P>::from_random_bytes(&serialized).unwrap();
|
|
assert_eq!(p1, p2);
|
|
}
|
|
}
|
|
|
|
for _ in 0..ITERATIONS {
|
|
let mut biginteger =
|
|
<<GroupAffine<P> as AffineCurve>::BaseField as PrimeField>::BigInt::rand(&mut rng);
|
|
let mut bytes = to_bytes![biginteger].unwrap();
|
|
let mut g = GroupAffine::<P>::from_random_bytes(&bytes);
|
|
while g.is_none() {
|
|
bytes.iter_mut().for_each(|i| *i = i.wrapping_sub(1));
|
|
g = GroupAffine::<P>::from_random_bytes(&bytes);
|
|
}
|
|
let _g = g.unwrap();
|
|
}
|
|
}
|
|
|
|
pub fn edwards_curve_serialization_test<P: TEModelParameters>() {
|
|
use ark_ec::models::twisted_edwards_extended::{GroupAffine, GroupProjective};
|
|
|
|
let buf_size = GroupAffine::<P>::zero().serialized_size();
|
|
|
|
let mut rng = XorShiftRng::seed_from_u64(1231275789u64);
|
|
|
|
for _ in 0..ITERATIONS {
|
|
let a = GroupProjective::<P>::rand(&mut rng);
|
|
let a = a.into_affine();
|
|
{
|
|
let mut serialized = vec![0; buf_size];
|
|
let mut cursor = Cursor::new(&mut serialized[..]);
|
|
a.serialize(&mut cursor).unwrap();
|
|
|
|
let mut cursor = Cursor::new(&serialized[..]);
|
|
let b = GroupAffine::<P>::deserialize(&mut cursor).unwrap();
|
|
assert_eq!(a, b);
|
|
}
|
|
|
|
{
|
|
let a = GroupAffine::<P>::zero();
|
|
let mut serialized = vec![0; buf_size];
|
|
let mut cursor = Cursor::new(&mut serialized[..]);
|
|
a.serialize(&mut cursor).unwrap();
|
|
let mut cursor = Cursor::new(&serialized[..]);
|
|
let b = GroupAffine::<P>::deserialize(&mut cursor).unwrap();
|
|
assert_eq!(a, b);
|
|
}
|
|
|
|
{
|
|
let a = GroupAffine::<P>::zero();
|
|
let mut serialized = vec![0; buf_size - 1];
|
|
let mut cursor = Cursor::new(&mut serialized[..]);
|
|
a.serialize(&mut cursor).unwrap_err();
|
|
}
|
|
|
|
{
|
|
let serialized = vec![0; buf_size - 1];
|
|
let mut cursor = Cursor::new(&serialized[..]);
|
|
GroupAffine::<P>::deserialize(&mut cursor).unwrap_err();
|
|
}
|
|
|
|
{
|
|
let mut serialized = vec![0; a.uncompressed_size()];
|
|
let mut cursor = Cursor::new(&mut serialized[..]);
|
|
a.serialize_uncompressed(&mut cursor).unwrap();
|
|
|
|
let mut cursor = Cursor::new(&serialized[..]);
|
|
let b = GroupAffine::<P>::deserialize_uncompressed(&mut cursor).unwrap();
|
|
assert_eq!(a, b);
|
|
}
|
|
|
|
{
|
|
let a = GroupAffine::<P>::zero();
|
|
let mut serialized = vec![0; a.uncompressed_size()];
|
|
let mut cursor = Cursor::new(&mut serialized[..]);
|
|
a.serialize_uncompressed(&mut cursor).unwrap();
|
|
let mut cursor = Cursor::new(&serialized[..]);
|
|
let b = GroupAffine::<P>::deserialize_uncompressed(&mut cursor).unwrap();
|
|
assert_eq!(a, b);
|
|
}
|
|
}
|
|
}
|