11#![ no_std]
22
3+ use ed448_goldilocks:: Ed448 ;
34use ed448_goldilocks:: MontgomeryPoint ;
4- use ed448_goldilocks:: Scalar ;
5+ use ed448_goldilocks:: elliptic_curve :: { bigint :: U448 , scalar :: FromUintUnchecked } ;
56use rand_core:: { CryptoRng , RngCore } ;
67use zeroize:: Zeroize ;
78
9+ type Scalar = ed448_goldilocks:: Scalar < Ed448 > ;
10+
811/// Computes a Scalar according to RFC7748
912/// given a byte array of length 56
1013impl From < [ u8 ; 56 ] > for Secret {
@@ -20,16 +23,18 @@ impl From<[u8; 56]> for Secret {
2023/// XXX: Waiting for upstream PR to use pre-computation
2124impl From < & Secret > for PublicKey {
2225 fn from ( secret : & Secret ) -> PublicKey {
23- let point = & MontgomeryPoint :: GENERATOR * & Scalar :: from_bytes ( & secret. 0 ) ;
26+ let secret = secret. as_scalar ( ) ;
27+ let point = & MontgomeryPoint :: GENERATOR * & secret;
2428 PublicKey ( point)
2529 }
2630}
2731
2832/// A PublicKey is a point on Curve448.
33+ #[ derive( Debug , PartialEq , Eq , Copy , Clone ) ]
2934pub struct PublicKey ( MontgomeryPoint ) ;
3035
3136/// A Secret is a Scalar on Curve448.
32- #[ derive( Zeroize ) ]
37+ #[ derive( Clone , Zeroize ) ]
3338#[ zeroize( drop) ]
3439pub struct Secret ( [ u8 ; 56 ] ) ;
3540
@@ -85,7 +90,7 @@ impl Secret {
8590 // Taken from dalek-x25519
8691 pub fn new < T > ( csprng : & mut T ) -> Self
8792 where
88- T : RngCore + CryptoRng ,
93+ T : RngCore + CryptoRng + ? Sized ,
8994 {
9095 let mut bytes = [ 0u8 ; 56 ] ;
9196
@@ -102,7 +107,8 @@ impl Secret {
102107
103108 /// Views a Secret as a Scalar
104109 fn as_scalar ( & self ) -> Scalar {
105- Scalar :: from_bytes ( & self . 0 )
110+ let secret = U448 :: from_le_slice ( & self . 0 ) ;
111+ Scalar :: from_uint_unchecked ( secret)
106112 }
107113
108114 /// Performs a Diffie-hellman key exchange between the secret key and an external public key
@@ -171,28 +177,10 @@ mod test {
171177 use super :: * ;
172178 use alloc:: vec;
173179
180+ use ed448_goldilocks:: { LOW_A , LOW_B , LOW_C } ;
181+
174182 #[ test]
175183 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-
196184 // Notice, that this is the only way to add low order points into the system
197185 // and this is not exposed to the user. The user will use `from_bytes` which will check for low order points.
198186 let bad_key_a = PublicKey ( LOW_A ) ;
0 commit comments