diff --git a/src/curve.rs b/src/curve.rs index 1d60559..fef11b7 100644 --- a/src/curve.rs +++ b/src/curve.rs @@ -85,8 +85,10 @@ use core::cmp::{PartialEq, Eq}; use constants; use field::FieldElement; use scalar::Scalar; +use util::arrays_equal_ct; use util::bytes_equal_ct; use util::CTAssignable; +use util::CTEq; use util::CTNegatable; // ------------------------------------------------------------------------ @@ -227,7 +229,7 @@ pub struct CachedPoint { // Constructors // ------------------------------------------------------------------------ -/// Trait for curve point types that have an identity constructor. +/// Trait for curve point types which have an identity constructor. pub trait Identity { /// Returns the identity element of the curve. /// Can be used as a constructor. @@ -292,6 +294,37 @@ impl CTAssignable for PreComputedPoint { } } +// ------------------------------------------------------------------------ +// Constant-time Equality +// ------------------------------------------------------------------------ + +impl CTEq for ExtendedPoint { + fn ct_eq(&self, other: &ExtendedPoint) -> u8 { + arrays_equal_ct(&self.compress().0, &other.compress().0) + } +} + +/// Trait for testing if a curve point is equivalent to the identity point. +pub trait IsIdentity { + /// Return true if this element is the identity element of the curve. + fn is_identity(&self) -> bool; +} + +/// Implement generic identity equality testing for a point representations +/// which have constant-time equality testing and a defined identity +/// constructor. +impl IsIdentity for T where T: CTEq + Identity { + fn is_identity(&self) -> bool { + let identity: T = T::identity(); + + if self.ct_eq(&identity) == 1u8 { + return true; + } else { + return false; + } + } +} + // ------------------------------------------------------------------------ // Point conversions // ------------------------------------------------------------------------ @@ -1073,6 +1106,11 @@ mod test { assert!(p2.is_small_order() == false); } + #[test] + fn test_is_identity() { + assert!(ExtendedPoint::identity().is_identity()); + } + #[bench] fn bench_basepoint_mult(b: &mut Bencher) { b.iter(|| ExtendedPoint::basepoint_mult(&A_SCALAR));