11#![ no_std]
22
3- use ed448_goldilocks:: MontgomeryPoint ;
4- use ed448_goldilocks:: Scalar ;
3+ use ed448_goldilocks:: {
4+ MontgomeryPoint ,
5+ elliptic_curve:: { bigint:: U448 , scalar:: FromUintUnchecked } ,
6+ } ;
57use rand_core:: { CryptoRng , RngCore } ;
68use zeroize:: Zeroize ;
79
10+ type MontgomeryScalar = ed448_goldilocks:: Scalar < ed448_goldilocks:: Ed448 > ;
11+
812/// Computes a Scalar according to RFC7748
913/// given a byte array of length 56
1014impl From < [ u8 ; 56 ] > for Secret {
@@ -20,16 +24,18 @@ impl From<[u8; 56]> for Secret {
2024/// XXX: Waiting for upstream PR to use pre-computation
2125impl From < & Secret > for PublicKey {
2226 fn from ( secret : & Secret ) -> PublicKey {
23- let point = & MontgomeryPoint :: GENERATOR * & Scalar :: from_bytes ( & secret. 0 ) ;
27+ let secret = secret. as_scalar ( ) ;
28+ let point = & MontgomeryPoint :: GENERATOR * & secret;
2429 PublicKey ( point)
2530 }
2631}
2732
2833/// A PublicKey is a point on Curve448.
34+ #[ derive( Debug , PartialEq , Eq , Copy , Clone ) ]
2935pub struct PublicKey ( MontgomeryPoint ) ;
3036
3137/// A Secret is a Scalar on Curve448.
32- #[ derive( Zeroize ) ]
38+ #[ derive( Clone , Zeroize ) ]
3339#[ zeroize( drop) ]
3440pub struct Secret ( [ u8 ; 56 ] ) ;
3541
@@ -85,7 +91,7 @@ impl Secret {
8591 // Taken from dalek-x25519
8692 pub fn new < T > ( csprng : & mut T ) -> Self
8793 where
88- T : RngCore + CryptoRng ,
94+ T : RngCore + CryptoRng + ? Sized ,
8995 {
9096 let mut bytes = [ 0u8 ; 56 ] ;
9197
@@ -101,8 +107,9 @@ impl Secret {
101107 }
102108
103109 /// Views a Secret as a Scalar
104- fn as_scalar ( & self ) -> Scalar {
105- Scalar :: from_bytes ( & self . 0 )
110+ fn as_scalar ( & self ) -> MontgomeryScalar {
111+ let secret = U448 :: from_le_slice ( & self . 0 ) ;
112+ MontgomeryScalar :: from_uint_unchecked ( secret)
106113 }
107114
108115 /// Performs a Diffie-hellman key exchange between the secret key and an external public key
@@ -173,38 +180,18 @@ mod test {
173180
174181 #[ test]
175182 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-
196183 // Notice, that this is the only way to add low order points into the system
197184 // 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 ) ;
185+ let bad_key_a = PublicKey ( MontgomeryPoint :: LOW_A ) ;
186+ let checked_bad_key_a = PublicKey :: from_bytes ( & MontgomeryPoint :: LOW_A . 0 ) ;
200187 assert ! ( checked_bad_key_a. is_none( ) ) ;
201188
202- let bad_key_b = PublicKey ( LOW_B ) ;
203- let checked_bad_key_b = PublicKey :: from_bytes ( & LOW_B . 0 ) ;
189+ let bad_key_b = PublicKey ( MontgomeryPoint :: LOW_B ) ;
190+ let checked_bad_key_b = PublicKey :: from_bytes ( & MontgomeryPoint :: LOW_B . 0 ) ;
204191 assert ! ( checked_bad_key_b. is_none( ) ) ;
205192
206- let bad_key_c = PublicKey ( LOW_C ) ;
207- let checked_bad_key_c = PublicKey :: from_bytes ( & LOW_C . 0 ) ;
193+ let bad_key_c = PublicKey ( MontgomeryPoint :: LOW_C ) ;
194+ let checked_bad_key_c = PublicKey :: from_bytes ( & MontgomeryPoint :: LOW_C . 0 ) ;
208195 assert ! ( checked_bad_key_c. is_none( ) ) ;
209196
210197 let mut rng = rand:: rng ( ) ;
0 commit comments