Rename {PreComputed,Cached}Point → {Affine,Projective}NielsPoint.

* FIXES Issue #28: https://github.com/isislovecruft/curve25519-dalek/issues/28
This commit is contained in:
Isis Lovecruft 2017-02-25 00:47:06 +00:00
parent f8139da0b6
commit a649ea38ee
Failed to extract signature
2 changed files with 327 additions and 325 deletions

File diff suppressed because it is too large Load diff

View file

@ -56,8 +56,8 @@
//! in ["Twisted Edwards Curves"](https://eprint.iacr.org/2008/013). //! in ["Twisted Edwards Curves"](https://eprint.iacr.org/2008/013).
//! //!
//! Following the implementation strategy in the ref10 reference //! Following the implementation strategy in the ref10 reference
//! implementation for Ed25519, we use several different models for //! implementation for [Ed25519](https://ed25519.cr.yp.to/ed25519-20110926.pdf),
//! curve points: //! we use several different models for curve points:
//! //!
//! * CompletedPoint: points in 𝗣^1 x 𝗣^1; //! * CompletedPoint: points in 𝗣^1 x 𝗣^1;
//! * ExtendedPoint: points in 𝗣^3; //! * ExtendedPoint: points in 𝗣^3;
@ -66,8 +66,8 @@
//! Finally, to accelerate additions, we use two cached point formats, //! Finally, to accelerate additions, we use two cached point formats,
//! one for the affine model and one for the 𝗣^3 model: //! one for the affine model and one for the 𝗣^3 model:
//! //!
//! * PreComputedPoint: `(y+x, y-x, 2dxy)` //! * AffineNielsPoint: `(y+x, y-x, 2dxy)`
//! * CachedPoint: `(Y+X, Y-X, Z, 2dXY)` //! * ProjectiveNielsPoint: `(Y+X, Y-X, Z, 2dXY)`
//! //!
//! [1]: https://moderncrypto.org/mail-archive/curves/2016/000807.html //! [1]: https://moderncrypto.org/mail-archive/curves/2016/000807.html
@ -206,23 +206,25 @@ pub struct CompletedPoint {
T: FieldElement, T: FieldElement,
} }
/// A pre-computed point in the affine model for the curve, /// A pre-computed point in the affine model for the curve, represented as
/// represented as (y+x, y-x, 2dxy). These precomputations /// (y+x, y-x, 2dxy). These precomputations accelerate addition and
/// accelerate addition and subtraction. /// subtraction, and were introduced by Niels Duif in the ed25519 paper
/// ["High-Speed High-Security Signatures"](https://ed25519.cr.yp.to/ed25519-20110926.pdf).
// Safe to derive Eq because affine coordinates. // Safe to derive Eq because affine coordinates.
#[derive(Copy, Clone, Eq, PartialEq)] #[derive(Copy, Clone, Eq, PartialEq)]
#[allow(missing_docs)] #[allow(missing_docs)]
pub struct PreComputedPoint { pub struct AffineNielsPoint {
pub y_plus_x: FieldElement, pub y_plus_x: FieldElement,
pub y_minus_x: FieldElement, pub y_minus_x: FieldElement,
pub xy2d: FieldElement, pub xy2d: FieldElement,
} }
/// A pre-computed point in the P³(𝔽ₚ) model for the curve, /// A pre-computed point in the P³(𝔽ₚ) model for the curve, represented as
/// represented as (Y+X, Y-X, Z, 2dXY). These precomputations /// (Y+X, Y-X, Z, 2dXY). These precomputations accelerate addition and
/// accelerate addition and subtraction. /// subtraction, and were introduced by Niels Duif in the ed25519 paper
/// ["High-Speed High-Security Signatures"](https://ed25519.cr.yp.to/ed25519-20110926.pdf).
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct CachedPoint { pub struct ProjectiveNielsPoint {
Y_plus_X: FieldElement, Y_plus_X: FieldElement,
Y_minus_X: FieldElement, Y_minus_X: FieldElement,
Z: FieldElement, Z: FieldElement,
@ -257,18 +259,18 @@ impl Identity for ProjectivePoint {
} }
} }
impl Identity for CachedPoint { impl Identity for ProjectiveNielsPoint {
fn identity() -> CachedPoint { fn identity() -> ProjectiveNielsPoint {
CachedPoint{ Y_plus_X: FieldElement::one(), ProjectiveNielsPoint{ Y_plus_X: FieldElement::one(),
Y_minus_X: FieldElement::one(), Y_minus_X: FieldElement::one(),
Z: FieldElement::one(), Z: FieldElement::one(),
T2d: FieldElement::zero() } T2d: FieldElement::zero() }
} }
} }
impl Identity for PreComputedPoint { impl Identity for AffineNielsPoint {
fn identity() -> PreComputedPoint { fn identity() -> AffineNielsPoint {
PreComputedPoint{ AffineNielsPoint{
y_plus_x: FieldElement::one(), y_plus_x: FieldElement::one(),
y_minus_x: FieldElement::one(), y_minus_x: FieldElement::one(),
xy2d: FieldElement::zero(), xy2d: FieldElement::zero(),
@ -312,8 +314,8 @@ impl ValidityCheck for ExtendedPoint {
// Constant-time assignment // Constant-time assignment
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
impl CTAssignable for CachedPoint { impl CTAssignable for ProjectiveNielsPoint {
fn conditional_assign(&mut self, other: &CachedPoint, choice: u8) { fn conditional_assign(&mut self, other: &ProjectiveNielsPoint, choice: u8) {
self.Y_plus_X.conditional_assign(&other.Y_plus_X, choice); self.Y_plus_X.conditional_assign(&other.Y_plus_X, choice);
self.Y_minus_X.conditional_assign(&other.Y_minus_X, choice); self.Y_minus_X.conditional_assign(&other.Y_minus_X, choice);
self.Z.conditional_assign(&other.Z, choice); self.Z.conditional_assign(&other.Z, choice);
@ -321,8 +323,8 @@ impl CTAssignable for CachedPoint {
} }
} }
impl CTAssignable for PreComputedPoint { impl CTAssignable for AffineNielsPoint {
fn conditional_assign(&mut self, other: &PreComputedPoint, choice: u8) { fn conditional_assign(&mut self, other: &AffineNielsPoint, choice: u8) {
// PreComputedGroupElementCMove() // PreComputedGroupElementCMove()
self.y_plus_x.conditional_assign(&other.y_plus_x, choice); self.y_plus_x.conditional_assign(&other.y_plus_x, choice);
self.y_minus_x.conditional_assign(&other.y_minus_x, choice); self.y_minus_x.conditional_assign(&other.y_minus_x, choice);
@ -398,9 +400,9 @@ impl ProjectivePoint {
} }
impl ExtendedPoint { impl ExtendedPoint {
/// Convert to a CachedPoint /// Convert to a ProjectiveNielsPoint
pub fn to_cached(&self) -> CachedPoint { pub fn to_cached(&self) -> ProjectiveNielsPoint {
CachedPoint{ ProjectiveNielsPoint{
Y_plus_X: &self.Y + &self.X, Y_plus_X: &self.Y + &self.X,
Y_minus_X: &self.Y - &self.X, Y_minus_X: &self.Y - &self.X,
Z: self.Z, Z: self.Z,
@ -426,14 +428,14 @@ impl ExtendedPoint {
self.to_projective().compress() self.to_projective().compress()
} }
/// Dehomogenize to a PreComputedPoint. /// Dehomogenize to a AffineNielsPoint.
/// Mainly for testing. /// Mainly for testing.
pub fn to_precomputed(&self) -> PreComputedPoint { pub fn to_precomputed(&self) -> AffineNielsPoint {
let recip = self.Z.invert(); let recip = self.Z.invert();
let x = &self.X * &recip; let x = &self.X * &recip;
let y = &self.Y * &recip; let y = &self.Y * &recip;
let xy2d = &(&x * &y) * &constants::d2; let xy2d = &(&x * &y) * &constants::d2;
PreComputedPoint{ AffineNielsPoint{
y_plus_x: &y + &x, y_plus_x: &y + &x,
y_minus_x: &y - &x, y_minus_x: &y - &x,
xy2d: xy2d xy2d: xy2d
@ -497,10 +499,10 @@ impl ExtendedPoint {
// Addition and Subtraction // Addition and Subtraction
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
impl<'a,'b> Add<&'b CachedPoint> for &'a ExtendedPoint { impl<'a,'b> Add<&'b ProjectiveNielsPoint> for &'a ExtendedPoint {
type Output = CompletedPoint; type Output = CompletedPoint;
fn add(self, other: &'b CachedPoint) -> CompletedPoint { fn add(self, other: &'b ProjectiveNielsPoint) -> CompletedPoint {
let Y_plus_X = &self.Y + &self.X; let Y_plus_X = &self.Y + &self.X;
let Y_minus_X = &self.Y - &self.X; let Y_minus_X = &self.Y - &self.X;
let PP = &Y_plus_X * &other.Y_plus_X; let PP = &Y_plus_X * &other.Y_plus_X;
@ -518,10 +520,10 @@ impl<'a,'b> Add<&'b CachedPoint> for &'a ExtendedPoint {
} }
} }
impl<'a,'b> Sub<&'b CachedPoint> for &'a ExtendedPoint { impl<'a,'b> Sub<&'b ProjectiveNielsPoint> for &'a ExtendedPoint {
type Output = CompletedPoint; type Output = CompletedPoint;
fn sub(self, other: &'b CachedPoint) -> CompletedPoint { fn sub(self, other: &'b ProjectiveNielsPoint) -> CompletedPoint {
let Y_plus_X = &self.Y + &self.X; let Y_plus_X = &self.Y + &self.X;
let Y_minus_X = &self.Y - &self.X; let Y_minus_X = &self.Y - &self.X;
let PM = &Y_plus_X * &other.Y_minus_X; let PM = &Y_plus_X * &other.Y_minus_X;
@ -539,10 +541,10 @@ impl<'a,'b> Sub<&'b CachedPoint> for &'a ExtendedPoint {
} }
} }
impl<'a,'b> Add<&'b PreComputedPoint> for &'a ExtendedPoint { impl<'a,'b> Add<&'b AffineNielsPoint> for &'a ExtendedPoint {
type Output = CompletedPoint; type Output = CompletedPoint;
fn add(self, other: &'b PreComputedPoint) -> CompletedPoint { fn add(self, other: &'b AffineNielsPoint) -> CompletedPoint {
let Y_plus_X = &self.Y + &self.X; let Y_plus_X = &self.Y + &self.X;
let Y_minus_X = &self.Y - &self.X; let Y_minus_X = &self.Y - &self.X;
let PP = &Y_plus_X * &other.y_plus_x; let PP = &Y_plus_X * &other.y_plus_x;
@ -559,10 +561,10 @@ impl<'a,'b> Add<&'b PreComputedPoint> for &'a ExtendedPoint {
} }
} }
impl<'a,'b> Sub<&'b PreComputedPoint> for &'a ExtendedPoint { impl<'a,'b> Sub<&'b AffineNielsPoint> for &'a ExtendedPoint {
type Output = CompletedPoint; type Output = CompletedPoint;
fn sub(self, other: &'b PreComputedPoint) -> CompletedPoint { fn sub(self, other: &'b AffineNielsPoint) -> CompletedPoint {
let Y_plus_X = &self.Y + &self.X; let Y_plus_X = &self.Y + &self.X;
let Y_minus_X = &self.Y - &self.X; let Y_minus_X = &self.Y - &self.X;
let PM = &Y_plus_X * &other.y_minus_x; let PM = &Y_plus_X * &other.y_minus_x;
@ -606,11 +608,11 @@ impl<'a> Neg for &'a ExtendedPoint {
} }
} }
impl<'a> Neg for &'a CachedPoint { impl<'a> Neg for &'a ProjectiveNielsPoint {
type Output = CachedPoint; type Output = ProjectiveNielsPoint;
fn neg(self) -> CachedPoint { fn neg(self) -> ProjectiveNielsPoint {
CachedPoint{ ProjectiveNielsPoint{
Y_plus_X: self.Y_minus_X, Y_plus_X: self.Y_minus_X,
Y_minus_X: self.Y_plus_X, Y_minus_X: self.Y_plus_X,
Z: self.Z, Z: self.Z,
@ -620,11 +622,11 @@ impl<'a> Neg for &'a CachedPoint {
} }
impl<'a> Neg for &'a PreComputedPoint { impl<'a> Neg for &'a AffineNielsPoint {
type Output = PreComputedPoint; type Output = AffineNielsPoint;
fn neg(self) -> PreComputedPoint { fn neg(self) -> AffineNielsPoint {
PreComputedPoint{ AffineNielsPoint{
y_plus_x: self.y_minus_x, y_plus_x: self.y_minus_x,
y_minus_x: self.y_plus_x, y_minus_x: self.y_plus_x,
xy2d: -(&self.xy2d) xy2d: -(&self.xy2d)
@ -649,7 +651,7 @@ impl ScalarMult<Scalar> for ExtendedPoint {
/// the basepoint, `basepoint_mult` is approximately 4x faster. /// the basepoint, `basepoint_mult` is approximately 4x faster.
fn scalar_mult(&self, scalar: &Scalar) -> ExtendedPoint { fn scalar_mult(&self, scalar: &Scalar) -> ExtendedPoint {
let A = self.to_cached(); let A = self.to_cached();
let mut As: [CachedPoint; 8] = [A; 8]; let mut As: [ProjectiveNielsPoint; 8] = [A; 8];
for i in 0..7 { for i in 0..7 {
As[i+1] = (self + &As[i]).to_extended().to_cached(); As[i+1] = (self + &As[i]).to_extended().to_cached();
} }
@ -780,7 +782,7 @@ pub fn double_scalar_mult_vartime(a: &Scalar, A: &ExtendedPoint, b: &Scalar) ->
let b_naf = b.non_adjacent_form(); let b_naf = b.non_adjacent_form();
// Build a lookup table of odd multiples of A // Build a lookup table of odd multiples of A
let mut Ai = [CachedPoint::identity(); 8]; let mut Ai = [ProjectiveNielsPoint::identity(); 8];
let A2 = A.double(); let A2 = A.double();
Ai[0] = A.to_cached(); Ai[0] = A.to_cached();
for i in 0..7 { for i in 0..7 {
@ -900,16 +902,16 @@ impl Debug for CompletedPoint {
} }
} }
impl Debug for PreComputedPoint { impl Debug for AffineNielsPoint {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "PreComputedPoint(\n\ty_plus_x: {:?},\n\ty_minus_x: {:?},\n\txy2d: {:?}\n)", write!(f, "AffineNielsPoint(\n\ty_plus_x: {:?},\n\ty_minus_x: {:?},\n\txy2d: {:?}\n)",
&self.y_plus_x, &self.y_minus_x, &self.xy2d) &self.y_plus_x, &self.y_minus_x, &self.xy2d)
} }
} }
impl Debug for CachedPoint { impl Debug for ProjectiveNielsPoint {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "CachedPoint(\n\tY_plus_X: {:?},\n\tY_minus_X: {:?},\n\tZ: {:?},\n\tT2d: {:?}\n)", write!(f, "ProjectiveNielsPoint(\n\tY_plus_X: {:?},\n\tY_minus_X: {:?},\n\tZ: {:?},\n\tT2d: {:?}\n)",
&self.Y_plus_X, &self.Y_minus_X, &self.Z, &self.T2d) &self.Y_plus_X, &self.Y_minus_X, &self.Z, &self.T2d)
} }
} }
@ -1024,7 +1026,7 @@ mod test {
assert_eq!( bp_added.compress(), BASE2_CMPRSSD); assert_eq!( bp_added.compress(), BASE2_CMPRSSD);
} }
/// Test `impl Add<CachedPoint> for ExtendedPoint` /// Test `impl Add<ProjectiveNielsPoint> for ExtendedPoint`
/// using the basepoint, basepoint2 constants /// using the basepoint, basepoint2 constants
#[test] #[test]
fn test_basepoint_plus_basepoint_cached() { fn test_basepoint_plus_basepoint_cached() {
@ -1033,13 +1035,13 @@ mod test {
assert_eq!( bp_added.compress(), BASE2_CMPRSSD); assert_eq!( bp_added.compress(), BASE2_CMPRSSD);
} }
/// Test `impl Add<PreComputedPoint> for ExtendedPoint` /// Test `impl Add<AffineNielsPoint> for ExtendedPoint`
/// using the basepoint, basepoint2 constants /// using the basepoint, basepoint2 constants
#[test] #[test]
fn test_basepoint_plus_basepoint_precomputed() { fn test_basepoint_plus_basepoint_precomputed() {
let bp = BASE_CMPRSSD.decompress().unwrap(); let bp = BASE_CMPRSSD.decompress().unwrap();
// on decode, Z =1, so x = X/Z = X, y = Y/Z = Y, xy = T // on decode, Z =1, so x = X/Z = X, y = Y/Z = Y, xy = T
let bp_precomputed = PreComputedPoint{ let bp_precomputed = AffineNielsPoint{
y_plus_x: &bp.Y + &bp.X, y_plus_x: &bp.Y + &bp.X,
y_minus_x: &bp.Y - &bp.X, y_minus_x: &bp.Y - &bp.X,
xy2d: &bp.T * &constants::d2, xy2d: &bp.T * &constants::d2,
@ -1154,10 +1156,10 @@ mod test {
} }
#[test] #[test]
fn test_PreComputedPoint_conditional_assign() { fn test_AffineNielsPoint_conditional_assign() {
let id = PreComputedPoint::identity(); let id = AffineNielsPoint::identity();
let mut p1 = PreComputedPoint::identity(); let mut p1 = AffineNielsPoint::identity();
let p2: PreComputedPoint = PreComputedPoint{ let p2: AffineNielsPoint = AffineNielsPoint{
y_plus_x: FieldElement([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), y_plus_x: FieldElement([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]),
y_minus_x: FieldElement([11, 22, 33, 44, 55, 66, 77, 88, 99, 100]), y_minus_x: FieldElement([11, 22, 33, 44, 55, 66, 77, 88, 99, 100]),
xy2d: FieldElement([10, 20, 30, 40, 50, 60, 70, 80, 90, 101]), xy2d: FieldElement([10, 20, 30, 40, 50, 60, 70, 80, 90, 101]),