Merge branch 'develop'

This commit is contained in:
Jack Grigg
2020-03-14 10:36:58 +13:00
124 changed files with 15961 additions and 2084 deletions

View File

@@ -5,16 +5,46 @@ use ff::{PrimeField, PrimeFieldDecodingError, ScalarEngine, SqrtField};
use rand::RngCore;
use std::error::Error;
use std::fmt;
use std::ops::{Add, AddAssign, Neg, Sub, SubAssign};
pub mod tests;
mod wnaf;
pub use self::wnaf::Wnaf;
/// A helper trait for types implementing group addition.
pub trait CurveOps<Rhs = Self, Output = Self>:
Add<Rhs, Output = Output> + Sub<Rhs, Output = Output> + AddAssign<Rhs> + SubAssign<Rhs>
{
}
impl<T, Rhs, Output> CurveOps<Rhs, Output> for T where
T: Add<Rhs, Output = Output> + Sub<Rhs, Output = Output> + AddAssign<Rhs> + SubAssign<Rhs>
{
}
/// A helper trait for references implementing group addition.
pub trait CurveOpsOwned<Rhs = Self, Output = Self>: for<'r> CurveOps<&'r Rhs, Output> {}
impl<T, Rhs, Output> CurveOpsOwned<Rhs, Output> for T where T: for<'r> CurveOps<&'r Rhs, Output> {}
/// Projective representation of an elliptic curve point guaranteed to be
/// in the correct prime order subgroup.
pub trait CurveProjective:
PartialEq + Eq + Sized + Copy + Clone + Send + Sync + fmt::Debug + fmt::Display + 'static
PartialEq
+ Eq
+ Sized
+ Copy
+ Clone
+ Send
+ Sync
+ fmt::Debug
+ fmt::Display
+ 'static
+ Neg<Output = Self>
+ CurveOps
+ CurveOpsOwned
+ CurveOps<<Self as CurveProjective>::Affine>
+ CurveOpsOwned<<Self as CurveProjective>::Affine>
{
type Engine: ScalarEngine<Fr = Self::Scalar>;
type Scalar: PrimeField + SqrtField;
@@ -44,22 +74,6 @@ pub trait CurveProjective:
/// Doubles this element.
fn double(&mut self);
/// Adds another element to this element.
fn add_assign(&mut self, other: &Self);
/// Subtracts another element from this element.
fn sub_assign(&mut self, other: &Self) {
let mut tmp = *other;
tmp.negate();
self.add_assign(&tmp);
}
/// Adds an affine element to this element.
fn add_assign_mixed(&mut self, other: &Self::Affine);
/// Negates this element.
fn negate(&mut self);
/// Performs scalar multiplication of this element.
fn mul_assign<S: Into<<Self::Scalar as PrimeField>::Repr>>(&mut self, other: S);
@@ -78,7 +92,17 @@ pub trait CurveProjective:
/// Affine representation of an elliptic curve point guaranteed to be
/// in the correct prime order subgroup.
pub trait CurveAffine:
Copy + Clone + Sized + Send + Sync + fmt::Debug + fmt::Display + PartialEq + Eq + 'static
Copy
+ Clone
+ Sized
+ Send
+ Sync
+ fmt::Debug
+ fmt::Display
+ PartialEq
+ Eq
+ 'static
+ Neg<Output = Self>
{
type Engine: ScalarEngine<Fr = Self::Scalar>;
type Scalar: PrimeField + SqrtField;
@@ -97,9 +121,6 @@ pub trait CurveAffine:
/// additive identity.
fn is_zero(&self) -> bool;
/// Negates this element.
fn negate(&mut self);
/// Performs scalar multiplication of this element with mixed addition.
fn mul<S: Into<<Self::Scalar as PrimeField>::Repr>>(&self, other: S) -> Self::Projective;

View File

@@ -1,6 +1,7 @@
use ff::{Field, PrimeField};
use rand::SeedableRng;
use rand_xorshift::XorShiftRng;
use std::ops::Neg;
use crate::{CurveAffine, CurveProjective, EncodedPoint};
@@ -12,8 +13,7 @@ pub fn curve_tests<G: CurveProjective>() {
// Negation edge case with zero.
{
let mut z = G::zero();
z.negate();
let z = G::zero().neg();
assert!(z.is_zero());
}
@@ -30,19 +30,19 @@ pub fn curve_tests<G: CurveProjective>() {
let rcopy = r;
r.add_assign(&G::zero());
assert_eq!(r, rcopy);
r.add_assign_mixed(&G::Affine::zero());
r.add_assign(&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());
z.add_assign(&G::Affine::zero());
assert!(z.is_zero());
let mut z2 = z;
z2.add_assign(&r);
z.add_assign_mixed(&r.into_affine());
z.add_assign(&r.into_affine());
assert_eq!(z, z2);
assert_eq!(z, r);
@@ -67,7 +67,7 @@ pub fn curve_tests<G: CurveProjective>() {
random_negation_tests::<G>();
random_transformation_tests::<G>();
random_wnaf_tests::<G>();
random_encoding_tests::<G::Affine>();
random_encoding_tests::<G>();
}
fn random_wnaf_tests<G: CurveProjective>() {
@@ -199,8 +199,7 @@ fn random_negation_tests<G: CurveProjective>() {
let r = G::random(&mut rng);
let s = G::Scalar::random(&mut rng);
let mut sneg = s;
sneg.negate();
let sneg = s.neg();
let mut t1 = r;
t1.mul_assign(s);
@@ -213,11 +212,10 @@ fn random_negation_tests<G: CurveProjective>() {
assert!(t3.is_zero());
let mut t4 = t1;
t4.add_assign_mixed(&t2.into_affine());
t4.add_assign(&t2.into_affine());
assert!(t4.is_zero());
t1.negate();
assert_eq!(t1, t2);
assert_eq!(t1.neg(), t2);
}
}
@@ -244,7 +242,7 @@ fn random_doubling_tests<G: CurveProjective>() {
tmp2.add_assign(&b);
let mut tmp3 = a;
tmp3.add_assign_mixed(&b.into_affine());
tmp3.add_assign(&b.into_affine());
assert_eq!(tmp1, tmp2);
assert_eq!(tmp1, tmp3);
@@ -306,7 +304,7 @@ fn random_addition_tests<G: CurveProjective>() {
aplusa.add_assign(&a);
let mut aplusamixed = a;
aplusamixed.add_assign_mixed(&a.into_affine());
aplusamixed.add_assign(&a.into_affine());
let mut adouble = a;
adouble.double();
@@ -336,18 +334,18 @@ fn random_addition_tests<G: CurveProjective>() {
// (a + b) + c
tmp[3] = a_affine.into_projective();
tmp[3].add_assign_mixed(&b_affine);
tmp[3].add_assign_mixed(&c_affine);
tmp[3].add_assign(&b_affine);
tmp[3].add_assign(&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);
tmp[4].add_assign(&c_affine);
tmp[4].add_assign(&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);
tmp[5].add_assign(&c_affine);
tmp[5].add_assign(&b_affine);
// Comparisons
for i in 0..6 {
@@ -413,24 +411,24 @@ fn random_transformation_tests<G: CurveProjective>() {
}
}
fn random_encoding_tests<G: CurveAffine>() {
fn random_encoding_tests<G: CurveProjective>() {
let mut rng = XorShiftRng::from_seed([
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
0xe5,
]);
assert_eq!(
G::zero().into_uncompressed().into_affine().unwrap(),
G::zero()
G::Affine::zero().into_uncompressed().into_affine().unwrap(),
G::Affine::zero()
);
assert_eq!(
G::zero().into_compressed().into_affine().unwrap(),
G::zero()
G::Affine::zero().into_compressed().into_affine().unwrap(),
G::Affine::zero()
);
for _ in 0..1000 {
let mut r = G::Projective::random(&mut rng).into_affine();
let mut r = G::random(&mut rng).into_affine();
let uncompressed = r.into_uncompressed();
let de_uncompressed = uncompressed.into_affine().unwrap();
@@ -440,7 +438,7 @@ fn random_encoding_tests<G: CurveAffine>() {
let de_compressed = compressed.into_affine().unwrap();
assert_eq!(de_compressed, r);
r.negate();
r = r.neg();
let compressed = r.into_compressed();
let de_compressed = compressed.into_affine().unwrap();