1
1
#![ no_std]
2
2
3
- use ed448_goldilocks:: MontgomeryPoint ;
4
- use ed448_goldilocks:: Scalar ;
3
+ use ed448_goldilocks:: {
4
+ MontgomeryPoint ,
5
+ elliptic_curve:: { bigint:: U448 , scalar:: FromUintUnchecked } ,
6
+ } ;
5
7
use rand_core:: { CryptoRng , RngCore } ;
6
8
use zeroize:: Zeroize ;
7
9
10
+ type MontgomeryScalar = ed448_goldilocks:: Scalar < ed448_goldilocks:: Ed448 > ;
11
+
8
12
/// Computes a Scalar according to RFC7748
9
13
/// given a byte array of length 56
10
14
impl From < [ u8 ; 56 ] > for Secret {
@@ -20,16 +24,18 @@ impl From<[u8; 56]> for Secret {
20
24
/// XXX: Waiting for upstream PR to use pre-computation
21
25
impl From < & Secret > for PublicKey {
22
26
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;
24
29
PublicKey ( point)
25
30
}
26
31
}
27
32
28
33
/// A PublicKey is a point on Curve448.
34
+ #[ derive( Debug , PartialEq , Eq , Copy , Clone ) ]
29
35
pub struct PublicKey ( MontgomeryPoint ) ;
30
36
31
37
/// A Secret is a Scalar on Curve448.
32
- #[ derive( Zeroize ) ]
38
+ #[ derive( Clone , Zeroize ) ]
33
39
#[ zeroize( drop) ]
34
40
pub struct Secret ( [ u8 ; 56 ] ) ;
35
41
@@ -85,7 +91,7 @@ impl Secret {
85
91
// Taken from dalek-x25519
86
92
pub fn new < T > ( csprng : & mut T ) -> Self
87
93
where
88
- T : RngCore + CryptoRng ,
94
+ T : RngCore + CryptoRng + ? Sized ,
89
95
{
90
96
let mut bytes = [ 0u8 ; 56 ] ;
91
97
@@ -101,8 +107,9 @@ impl Secret {
101
107
}
102
108
103
109
/// 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)
106
113
}
107
114
108
115
/// Performs a Diffie-hellman key exchange between the secret key and an external public key
@@ -173,38 +180,18 @@ mod test {
173
180
174
181
#[ test]
175
182
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
-
196
183
// Notice, that this is the only way to add low order points into the system
197
184
// 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 ) ;
200
187
assert ! ( checked_bad_key_a. is_none( ) ) ;
201
188
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 ) ;
204
191
assert ! ( checked_bad_key_b. is_none( ) ) ;
205
192
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 ) ;
208
195
assert ! ( checked_bad_key_c. is_none( ) ) ;
209
196
210
197
let mut rng = rand:: rng ( ) ;
0 commit comments