From 2cef5fcecdefed6a78c41d2ecfa032e5cb815c3a Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Wed, 22 Feb 2017 22:08:18 -0800 Subject: [PATCH 1/5] Add CompressedEdwardsY::as_bytes --- src/curve.rs | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/curve.rs b/src/curve.rs index 34085d4..ec9c093 100644 --- a/src/curve.rs +++ b/src/curve.rs @@ -79,7 +79,7 @@ use core::fmt::Debug; use core::iter::Iterator; -use core::ops::{Add, Sub, Neg, Index}; +use core::ops::{Add, Sub, Neg}; use core::cmp::{PartialEq, Eq}; use constants; @@ -106,21 +106,18 @@ pub struct CompressedEdwardsY(pub [u8; 32]); impl Debug for CompressedEdwardsY { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "CompressedPoint: {:?}", &self.0[..]) - } -} - -impl Index for CompressedEdwardsY { - type Output = u8; - - fn index<'a>(&'a self, _index: usize) -> &'a u8 { - let ret: &'a u8 = &(self.0[_index]); - ret + write!(f, "CompressedPoint: {:?}", self.as_bytes()) } } impl CompressedEdwardsY { /// View this `CompressedEdwardsY` as an array of bytes. + pub fn as_bytes<'a>(&'a self) -> &'a [u8;32] { + &self.0 + } + + /// Copy this `CompressedEdwardsY` to an array of bytes. + /// XXX is this useful? pub fn to_bytes(&self) -> [u8;32] { self.0 } @@ -130,7 +127,7 @@ impl CompressedEdwardsY { /// Returns `None` if the input is not the `y`-coordinate of a /// curve point. pub fn decompress(&self) -> Option { // FromBytes() - let Y = FieldElement::from_bytes(&self.0); + let Y = FieldElement::from_bytes(self.as_bytes()); let Z = FieldElement::one(); let YY = Y.square(); let u = &YY - &Z; // u = y²-1 @@ -140,7 +137,7 @@ impl CompressedEdwardsY { if is_nonzero_square != 1u8 { return None; } // Flip the sign of X if it's not correct - let compressed_sign_bit = self[31] >> 7; + let compressed_sign_bit = self.as_bytes()[31] >> 7; let current_sign_bit = X.is_negative_ed25519(); X.conditional_negate(current_sign_bit ^ compressed_sign_bit); @@ -317,7 +314,8 @@ impl CTAssignable for AffineNielsPoint { impl CTEq for ExtendedPoint { fn ct_eq(&self, other: &ExtendedPoint) -> u8 { - arrays_equal_ct(&self.compress().0, &other.compress().0) + arrays_equal_ct( self.compress().as_bytes(), + other.compress().as_bytes()) } } @@ -977,7 +975,7 @@ mod test { /// Test sign handling in decompression #[test] fn test_decompression_sign_handling() { - let mut m_bp_bytes: [u8;32] = BASE_CMPRSSD.to_bytes().clone(); + let mut m_bp_bytes: [u8;32] = BASE_CMPRSSD.as_bytes().clone(); // Set the high bit of the last byte to flip the sign m_bp_bytes[31] |= 1 << 7; let m_bp = CompressedEdwardsY(m_bp_bytes).decompress().unwrap(); From f39566cf16d48b90a6c0793631ebc49a5956a5a2 Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Wed, 22 Feb 2017 22:12:57 -0800 Subject: [PATCH 2/5] Change CompressedDecaf::to_bytes to ::as_bytes --- src/decaf.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/decaf.rs b/src/decaf.rs index 1b777c9..2537fbb 100644 --- a/src/decaf.rs +++ b/src/decaf.rs @@ -50,15 +50,15 @@ pub struct CompressedDecaf(pub [u8; 32]); /// The result of compressing a `DecafPoint`. impl CompressedDecaf { /// View this `CompressedDecaf` as an array of bytes. - pub fn to_bytes(&self) -> [u8;32] { - self.0 + pub fn as_bytes<'a>(&'a self) -> &'a [u8;32] { + &self.0 } /// Attempt to decompress to an `DecafPoint`. pub fn decompress(&self) -> Option { // XXX should decoding be CT ? // XXX need to check that xy is nonnegative and reject otherwise - let s = FieldElement::from_bytes(&self.0); + let s = FieldElement::from_bytes(self.as_bytes()); // Check that s = |s| and reject otherwise. let mut abs_s = s; @@ -267,7 +267,7 @@ impl BasepointMult for DecafPoint { impl Debug for CompressedDecaf { fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { - write!(f, "CompressedDecaf: {:?}", &self.0[..]) + write!(f, "CompressedDecaf: {:?}", self.as_bytes()) } } From 1dac2f53bb8f6edf233a064f17ade13923268c26 Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Wed, 22 Feb 2017 23:06:59 -0800 Subject: [PATCH 3/5] Implement Identity for CompressedEdwardsY --- src/curve.rs | 15 +++++++++++++++ src/decaf.rs | 4 +--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/curve.rs b/src/curve.rs index ec9c093..8130d24 100644 --- a/src/curve.rs +++ b/src/curve.rs @@ -218,6 +218,15 @@ pub trait Identity { fn identity() -> Self; } +impl Identity for CompressedEdwardsY { + fn identity() -> CompressedEdwardsY { + CompressedEdwardsY([1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0]) + } +} + impl Identity for ExtendedPoint { fn identity() -> ExtendedPoint { ExtendedPoint{ X: FieldElement::zero(), @@ -1161,6 +1170,12 @@ mod test { assert!(p2.is_small_order() == false); } + #[test] + fn test_compressed_identity() { + assert_eq!(ExtendedPoint::identity().compress(), + CompressedEdwardsY::identity()); + } + #[test] fn test_is_identity() { assert!(ExtendedPoint::identity().is_identity()); diff --git a/src/decaf.rs b/src/decaf.rs index 2537fbb..93f22e2 100644 --- a/src/decaf.rs +++ b/src/decaf.rs @@ -308,9 +308,7 @@ mod test { fn test_decaf_decompress_id() { let compressed_id = CompressedDecaf::identity(); let id = compressed_id.decompress().unwrap(); - // This should compress (as ed25519) to the following: - let mut bytes = [0u8; 32]; bytes[0] = 1; - assert_eq!(id.0.compress(), CompressedEdwardsY(bytes)); + assert_eq!(id.0.compress(), CompressedEdwardsY::identity()); } #[test] From 950519b97b4c631525245d7d5bdd37c606fc7bcd Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Thu, 23 Feb 2017 03:15:55 -0800 Subject: [PATCH 4/5] Implement Debug for Scalar --- src/scalar.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/scalar.rs b/src/scalar.rs index 85c77be..228294c 100644 --- a/src/scalar.rs +++ b/src/scalar.rs @@ -30,8 +30,8 @@ //! limbs. use core::cmp::{Eq, PartialEq}; -use core::ops::{Index, IndexMut}; -use core::ops::{Neg}; +use core::ops::{Neg, Index, IndexMut}; +use core::fmt::Debug; #[cfg(feature = "std")] use rand::Rng; @@ -50,6 +50,12 @@ use subtle::arrays_equal_ct; #[derive(Copy, Clone)] pub struct Scalar(pub [u8; 32]); +impl Debug for Scalar { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { + write!(f, "Scalar: {:?}", &self.0[..]) + } +} + impl Eq for Scalar{} impl PartialEq for Scalar { /// Test equality between two `Scalar`s. From e5c0d789fde40ad5046e49310fc178dba766e9f3 Mon Sep 17 00:00:00 2001 From: Henry de Valence Date: Thu, 23 Feb 2017 03:26:57 -0800 Subject: [PATCH 5/5] Add a Scalar::as_bytes() method. --- src/scalar.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/scalar.rs b/src/scalar.rs index 228294c..ed10297 100644 --- a/src/scalar.rs +++ b/src/scalar.rs @@ -165,6 +165,11 @@ impl Scalar { Scalar::reduce(&scalar_bytes) } + /// View this `Scalar` as a sequence of bytes. + pub fn as_bytes<'a>(&'a self) -> &'a [u8;32] { + &self.0 + } + /// Construct the additive identity pub fn zero() -> Self { Scalar([0u8; 32])