11#![ no_std]
22
3- use ed448_goldilocks:: MontgomeryPoint ;
4- use ed448_goldilocks:: Scalar ;
3+ use ed448_goldilocks:: {
4+ MontgomeryScalar , MontgomeryXpoint ,
5+ elliptic_curve:: { bigint:: U448 , scalar:: FromUintUnchecked } ,
6+ } ;
57use rand_core:: { CryptoRng , RngCore } ;
68use zeroize:: Zeroize ;
79
@@ -20,24 +22,26 @@ impl From<[u8; 56]> for Secret {
2022/// XXX: Waiting for upstream PR to use pre-computation
2123impl From < & Secret > for PublicKey {
2224 fn from ( secret : & Secret ) -> PublicKey {
23- let point = & MontgomeryPoint :: GENERATOR * & Scalar :: from_bytes ( & secret. 0 ) ;
24- PublicKey ( point)
25+ let secret = secret. as_scalar ( ) ;
26+ let point = & MontgomeryXpoint :: GENERATOR * & secret;
27+ PublicKey ( point. to_affine ( ) )
2528 }
2629}
2730
2831/// A PublicKey is a point on Curve448.
29- pub struct PublicKey ( MontgomeryPoint ) ;
32+ #[ derive( Debug , PartialEq , Eq , Copy , Clone ) ]
33+ pub struct PublicKey ( MontgomeryXpoint ) ;
3034
3135/// A Secret is a Scalar on Curve448.
32- #[ derive( Zeroize ) ]
36+ #[ derive( Clone , Zeroize ) ]
3337#[ zeroize( drop) ]
3438pub struct Secret ( [ u8 ; 56 ] ) ;
3539
3640/// A SharedSecret is a point on Curve448.
3741/// This point is the result of a Diffie-Hellman key exchange.
3842#[ derive( Zeroize ) ]
3943#[ zeroize( drop) ]
40- pub struct SharedSecret ( MontgomeryPoint ) ;
44+ pub struct SharedSecret ( MontgomeryXpoint ) ;
4145
4246impl PublicKey {
4347 /// Converts a bytes slice into a Public key
@@ -62,7 +66,7 @@ impl PublicKey {
6266
6367 // Check if the point has low order
6468 let arr = slice_to_array ( bytes) ;
65- let point = MontgomeryPoint ( arr) ;
69+ let point = MontgomeryXpoint ( arr) ;
6670
6771 Some ( PublicKey ( point) )
6872 }
@@ -85,7 +89,7 @@ impl Secret {
8589 // Taken from dalek-x25519
8690 pub fn new < T > ( csprng : & mut T ) -> Self
8791 where
88- T : RngCore + CryptoRng ,
92+ T : RngCore + CryptoRng + ? Sized ,
8993 {
9094 let mut bytes = [ 0u8 ; 56 ] ;
9195
@@ -101,8 +105,9 @@ impl Secret {
101105 }
102106
103107 /// Views a Secret as a Scalar
104- fn as_scalar ( & self ) -> Scalar {
105- Scalar :: from_bytes ( & self . 0 )
108+ fn as_scalar ( & self ) -> MontgomeryScalar {
109+ let secret = U448 :: from_le_slice ( & self . 0 ) ;
110+ MontgomeryScalar :: from_uint_unchecked ( secret)
106111 }
107112
108113 /// Performs a Diffie-hellman key exchange between the secret key and an external public key
@@ -112,7 +117,7 @@ impl Secret {
112117 return None ;
113118 }
114119 let shared_key = & public_key. 0 * & self . as_scalar ( ) ;
115- Some ( SharedSecret ( shared_key) )
120+ Some ( SharedSecret ( shared_key. to_affine ( ) ) )
116121 }
117122
118123 /// Performs a Diffie-hellman key exchange once between the secret key and an external public key
@@ -152,17 +157,17 @@ fn slice_to_array(bytes: &[u8]) -> [u8; 56] {
152157pub fn x448 ( scalar_bytes : [ u8 ; 56 ] , point_bytes : [ u8 ; 56 ] ) -> Option < [ u8 ; 56 ] > {
153158 let point = PublicKey :: from_bytes ( & point_bytes) ?;
154159 let scalar = Secret :: from ( scalar_bytes) . as_scalar ( ) ;
155- Some ( ( & point. 0 * & scalar) . 0 )
160+ Some ( ( & point. 0 * & scalar) . to_affine ( ) . 0 )
156161}
157162/// An unchecked version of the x448 function defined in RFC448
158163/// No checks are made on the points.
159164pub fn x448_unchecked ( scalar_bytes : [ u8 ; 56 ] , point_bytes : [ u8 ; 56 ] ) -> [ u8 ; 56 ] {
160- let point = MontgomeryPoint ( point_bytes) ;
165+ let point = MontgomeryXpoint ( point_bytes) ;
161166 let scalar = Secret :: from ( scalar_bytes) . as_scalar ( ) ;
162- ( & point * & scalar) . 0
167+ ( & point * & scalar) . to_affine ( ) . 0
163168}
164169
165- pub const X448_BASEPOINT_BYTES : [ u8 ; 56 ] = MontgomeryPoint :: GENERATOR . 0 ;
170+ pub const X448_BASEPOINT_BYTES : [ u8 ; 56 ] = MontgomeryXpoint :: GENERATOR . 0 ;
166171
167172#[ cfg( test) ]
168173mod test {
@@ -173,38 +178,18 @@ mod test {
173178
174179 #[ test]
175180 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-
196181 // Notice, that this is the only way to add low order points into the system
197182 // 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 ) ;
183+ let bad_key_a = PublicKey ( MontgomeryXpoint :: LOW_A ) ;
184+ let checked_bad_key_a = PublicKey :: from_bytes ( & MontgomeryXpoint :: LOW_A . 0 ) ;
200185 assert ! ( checked_bad_key_a. is_none( ) ) ;
201186
202- let bad_key_b = PublicKey ( LOW_B ) ;
203- let checked_bad_key_b = PublicKey :: from_bytes ( & LOW_B . 0 ) ;
187+ let bad_key_b = PublicKey ( MontgomeryXpoint :: LOW_B ) ;
188+ let checked_bad_key_b = PublicKey :: from_bytes ( & MontgomeryXpoint :: LOW_B . 0 ) ;
204189 assert ! ( checked_bad_key_b. is_none( ) ) ;
205190
206- let bad_key_c = PublicKey ( LOW_C ) ;
207- let checked_bad_key_c = PublicKey :: from_bytes ( & LOW_C . 0 ) ;
191+ let bad_key_c = PublicKey ( MontgomeryXpoint :: LOW_C ) ;
192+ let checked_bad_key_c = PublicKey :: from_bytes ( & MontgomeryXpoint :: LOW_C . 0 ) ;
208193 assert ! ( checked_bad_key_c. is_none( ) ) ;
209194
210195 let mut rng = rand:: rng ( ) ;
@@ -392,8 +377,8 @@ mod test {
392377 0xda , 0x8d , 0x52 , 0x4d , 0xe3 , 0xd6 , 0x9b , 0xd9 , 0xd9 , 0xd6 , 0x6b , 0x99 , 0x7e , 0x37 ,
393378 ] ;
394379
395- let mut point = MontgomeryPoint :: GENERATOR . 0 ;
396- let mut scalar = MontgomeryPoint :: GENERATOR . 0 ;
380+ let mut point = MontgomeryXpoint :: GENERATOR . 0 ;
381+ let mut scalar = MontgomeryXpoint :: GENERATOR . 0 ;
397382 let mut result = [ 0u8 ; 56 ] ;
398383
399384 // Iterate 1 time then check value on 1st iteration
0 commit comments