11#![ no_std]
22
3- use ed448_goldilocks:: MontgomeryPoint ;
4- use ed448_goldilocks:: Scalar ;
3+ use ed448_goldilocks:: MontgomeryScalar ;
4+ use ed448_goldilocks:: MontgomeryXpoint ;
5+ use ed448_goldilocks:: elliptic_curve:: { bigint:: U448 , scalar:: FromUintUnchecked } ;
56use rand_core:: { CryptoRng , RngCore } ;
67use zeroize:: Zeroize ;
78
@@ -20,24 +21,26 @@ impl From<[u8; 56]> for Secret {
2021/// XXX: Waiting for upstream PR to use pre-computation
2122impl From < & Secret > for PublicKey {
2223 fn from ( secret : & Secret ) -> PublicKey {
23- let point = & MontgomeryPoint :: GENERATOR * & Scalar :: from_bytes ( & secret. 0 ) ;
24- PublicKey ( point)
24+ let secret = secret. as_scalar ( ) ;
25+ let point = & MontgomeryXpoint :: GENERATOR * & secret;
26+ PublicKey ( point. to_affine ( ) )
2527 }
2628}
2729
2830/// A PublicKey is a point on Curve448.
29- pub struct PublicKey ( MontgomeryPoint ) ;
31+ #[ derive( Debug , PartialEq , Eq , Copy , Clone ) ]
32+ pub struct PublicKey ( MontgomeryXpoint ) ;
3033
3134/// A Secret is a Scalar on Curve448.
32- #[ derive( Zeroize ) ]
35+ #[ derive( Clone , Zeroize ) ]
3336#[ zeroize( drop) ]
3437pub struct Secret ( [ u8 ; 56 ] ) ;
3538
3639/// A SharedSecret is a point on Curve448.
3740/// This point is the result of a Diffie-Hellman key exchange.
3841#[ derive( Zeroize ) ]
3942#[ zeroize( drop) ]
40- pub struct SharedSecret ( MontgomeryPoint ) ;
43+ pub struct SharedSecret ( MontgomeryXpoint ) ;
4144
4245impl PublicKey {
4346 /// Converts a bytes slice into a Public key
@@ -62,7 +65,7 @@ impl PublicKey {
6265
6366 // Check if the point has low order
6467 let arr = slice_to_array ( bytes) ;
65- let point = MontgomeryPoint ( arr) ;
68+ let point = MontgomeryXpoint ( arr) ;
6669
6770 Some ( PublicKey ( point) )
6871 }
@@ -85,7 +88,7 @@ impl Secret {
8588 // Taken from dalek-x25519
8689 pub fn new < T > ( csprng : & mut T ) -> Self
8790 where
88- T : RngCore + CryptoRng ,
91+ T : RngCore + CryptoRng + ? Sized ,
8992 {
9093 let mut bytes = [ 0u8 ; 56 ] ;
9194
@@ -101,8 +104,9 @@ impl Secret {
101104 }
102105
103106 /// Views a Secret as a Scalar
104- fn as_scalar ( & self ) -> Scalar {
105- Scalar :: from_bytes ( & self . 0 )
107+ fn as_scalar ( & self ) -> MontgomeryScalar {
108+ let secret = U448 :: from_le_slice ( & self . 0 ) ;
109+ MontgomeryScalar :: from_uint_unchecked ( secret)
106110 }
107111
108112 /// Performs a Diffie-hellman key exchange between the secret key and an external public key
@@ -112,7 +116,7 @@ impl Secret {
112116 return None ;
113117 }
114118 let shared_key = & public_key. 0 * & self . as_scalar ( ) ;
115- Some ( SharedSecret ( shared_key) )
119+ Some ( SharedSecret ( shared_key. to_affine ( ) ) )
116120 }
117121
118122 /// Performs a Diffie-hellman key exchange once between the secret key and an external public key
@@ -152,17 +156,17 @@ fn slice_to_array(bytes: &[u8]) -> [u8; 56] {
152156pub fn x448 ( scalar_bytes : [ u8 ; 56 ] , point_bytes : [ u8 ; 56 ] ) -> Option < [ u8 ; 56 ] > {
153157 let point = PublicKey :: from_bytes ( & point_bytes) ?;
154158 let scalar = Secret :: from ( scalar_bytes) . as_scalar ( ) ;
155- Some ( ( & point. 0 * & scalar) . 0 )
159+ Some ( ( & point. 0 * & scalar) . to_affine ( ) . 0 )
156160}
157161/// An unchecked version of the x448 function defined in RFC448
158162/// No checks are made on the points.
159163pub fn x448_unchecked ( scalar_bytes : [ u8 ; 56 ] , point_bytes : [ u8 ; 56 ] ) -> [ u8 ; 56 ] {
160- let point = MontgomeryPoint ( point_bytes) ;
164+ let point = MontgomeryXpoint ( point_bytes) ;
161165 let scalar = Secret :: from ( scalar_bytes) . as_scalar ( ) ;
162- ( & point * & scalar) . 0
166+ ( & point * & scalar) . to_affine ( ) . 0
163167}
164168
165- pub const X448_BASEPOINT_BYTES : [ u8 ; 56 ] = MontgomeryPoint :: GENERATOR . 0 ;
169+ pub const X448_BASEPOINT_BYTES : [ u8 ; 56 ] = MontgomeryXpoint :: GENERATOR . 0 ;
166170
167171#[ cfg( test) ]
168172mod test {
@@ -173,38 +177,18 @@ mod test {
173177
174178 #[ test]
175179 fn test_low_order ( ) {
176- // These are also in ed448-goldilocks. We could export them, but I cannot see any use except for this test.
177- const LOW_A : MontgomeryPoint = MontgomeryPoint ( [
178- 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
179- 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
180- 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
181- 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
182- ] ) ;
183- const LOW_B : MontgomeryPoint = MontgomeryPoint ( [
184- 0x01 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
185- 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
186- 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
187- 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
188- ] ) ;
189- const LOW_C : MontgomeryPoint = MontgomeryPoint ( [
190- 0xfe , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
191- 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
192- 0xfe , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
193- 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff , 0xff ,
194- ] ) ;
195-
196180 // Notice, that this is the only way to add low order points into the system
197181 // and this is not exposed to the user. The user will use `from_bytes` which will check for low order points.
198- let bad_key_a = PublicKey ( LOW_A ) ;
199- let checked_bad_key_a = PublicKey :: from_bytes ( & LOW_A . 0 ) ;
182+ let bad_key_a = PublicKey ( MontgomeryXpoint :: LOW_A ) ;
183+ let checked_bad_key_a = PublicKey :: from_bytes ( & MontgomeryXpoint :: LOW_A . 0 ) ;
200184 assert ! ( checked_bad_key_a. is_none( ) ) ;
201185
202- let bad_key_b = PublicKey ( LOW_B ) ;
203- let checked_bad_key_b = PublicKey :: from_bytes ( & LOW_B . 0 ) ;
186+ let bad_key_b = PublicKey ( MontgomeryXpoint :: LOW_B ) ;
187+ let checked_bad_key_b = PublicKey :: from_bytes ( & MontgomeryXpoint :: LOW_B . 0 ) ;
204188 assert ! ( checked_bad_key_b. is_none( ) ) ;
205189
206- let bad_key_c = PublicKey ( LOW_C ) ;
207- let checked_bad_key_c = PublicKey :: from_bytes ( & LOW_C . 0 ) ;
190+ let bad_key_c = PublicKey ( MontgomeryXpoint :: LOW_C ) ;
191+ let checked_bad_key_c = PublicKey :: from_bytes ( & MontgomeryXpoint :: LOW_C . 0 ) ;
208192 assert ! ( checked_bad_key_c. is_none( ) ) ;
209193
210194 let mut rng = rand:: rng ( ) ;
@@ -392,8 +376,8 @@ mod test {
392376 0xda , 0x8d , 0x52 , 0x4d , 0xe3 , 0xd6 , 0x9b , 0xd9 , 0xd9 , 0xd6 , 0x6b , 0x99 , 0x7e , 0x37 ,
393377 ] ;
394378
395- let mut point = MontgomeryPoint :: GENERATOR . 0 ;
396- let mut scalar = MontgomeryPoint :: GENERATOR . 0 ;
379+ let mut point = MontgomeryXpoint :: GENERATOR . 0 ;
380+ let mut scalar = MontgomeryXpoint :: GENERATOR . 0 ;
397381 let mut result = [ 0u8 ; 56 ] ;
398382
399383 // Iterate 1 time then check value on 1st iteration
0 commit comments