1
1
#![ no_std]
2
2
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
+ } ;
5
7
use rand_core:: { CryptoRng , RngCore } ;
6
8
use zeroize:: Zeroize ;
7
9
@@ -20,24 +22,26 @@ impl From<[u8; 56]> for Secret {
20
22
/// XXX: Waiting for upstream PR to use pre-computation
21
23
impl From < & Secret > for PublicKey {
22
24
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 ( ) )
25
28
}
26
29
}
27
30
28
31
/// A PublicKey is a point on Curve448.
29
- pub struct PublicKey ( MontgomeryPoint ) ;
32
+ #[ derive( Debug , PartialEq , Eq , Copy , Clone ) ]
33
+ pub struct PublicKey ( MontgomeryXpoint ) ;
30
34
31
35
/// A Secret is a Scalar on Curve448.
32
- #[ derive( Zeroize ) ]
36
+ #[ derive( Clone , Zeroize ) ]
33
37
#[ zeroize( drop) ]
34
38
pub struct Secret ( [ u8 ; 56 ] ) ;
35
39
36
40
/// A SharedSecret is a point on Curve448.
37
41
/// This point is the result of a Diffie-Hellman key exchange.
38
42
#[ derive( Zeroize ) ]
39
43
#[ zeroize( drop) ]
40
- pub struct SharedSecret ( MontgomeryPoint ) ;
44
+ pub struct SharedSecret ( MontgomeryXpoint ) ;
41
45
42
46
impl PublicKey {
43
47
/// Converts a bytes slice into a Public key
@@ -62,7 +66,7 @@ impl PublicKey {
62
66
63
67
// Check if the point has low order
64
68
let arr = slice_to_array ( bytes) ;
65
- let point = MontgomeryPoint ( arr) ;
69
+ let point = MontgomeryXpoint ( arr) ;
66
70
67
71
Some ( PublicKey ( point) )
68
72
}
@@ -85,7 +89,7 @@ impl Secret {
85
89
// Taken from dalek-x25519
86
90
pub fn new < T > ( csprng : & mut T ) -> Self
87
91
where
88
- T : RngCore + CryptoRng ,
92
+ T : RngCore + CryptoRng + ? Sized ,
89
93
{
90
94
let mut bytes = [ 0u8 ; 56 ] ;
91
95
@@ -101,8 +105,9 @@ impl Secret {
101
105
}
102
106
103
107
/// 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)
106
111
}
107
112
108
113
/// Performs a Diffie-hellman key exchange between the secret key and an external public key
@@ -112,7 +117,7 @@ impl Secret {
112
117
return None ;
113
118
}
114
119
let shared_key = & public_key. 0 * & self . as_scalar ( ) ;
115
- Some ( SharedSecret ( shared_key) )
120
+ Some ( SharedSecret ( shared_key. to_affine ( ) ) )
116
121
}
117
122
118
123
/// 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] {
152
157
pub fn x448 ( scalar_bytes : [ u8 ; 56 ] , point_bytes : [ u8 ; 56 ] ) -> Option < [ u8 ; 56 ] > {
153
158
let point = PublicKey :: from_bytes ( & point_bytes) ?;
154
159
let scalar = Secret :: from ( scalar_bytes) . as_scalar ( ) ;
155
- Some ( ( & point. 0 * & scalar) . 0 )
160
+ Some ( ( & point. 0 * & scalar) . to_affine ( ) . 0 )
156
161
}
157
162
/// An unchecked version of the x448 function defined in RFC448
158
163
/// No checks are made on the points.
159
164
pub 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) ;
161
166
let scalar = Secret :: from ( scalar_bytes) . as_scalar ( ) ;
162
- ( & point * & scalar) . 0
167
+ ( & point * & scalar) . to_affine ( ) . 0
163
168
}
164
169
165
- pub const X448_BASEPOINT_BYTES : [ u8 ; 56 ] = MontgomeryPoint :: GENERATOR . 0 ;
170
+ pub const X448_BASEPOINT_BYTES : [ u8 ; 56 ] = MontgomeryXpoint :: GENERATOR . 0 ;
166
171
167
172
#[ cfg( test) ]
168
173
mod test {
@@ -173,38 +178,18 @@ mod test {
173
178
174
179
#[ test]
175
180
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
181
// Notice, that this is the only way to add low order points into the system
197
182
// 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 ) ;
200
185
assert ! ( checked_bad_key_a. is_none( ) ) ;
201
186
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 ) ;
204
189
assert ! ( checked_bad_key_b. is_none( ) ) ;
205
190
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 ) ;
208
193
assert ! ( checked_bad_key_c. is_none( ) ) ;
209
194
210
195
let mut rng = rand:: rng ( ) ;
@@ -392,8 +377,8 @@ mod test {
392
377
0xda , 0x8d , 0x52 , 0x4d , 0xe3 , 0xd6 , 0x9b , 0xd9 , 0xd9 , 0xd6 , 0x6b , 0x99 , 0x7e , 0x37 ,
393
378
] ;
394
379
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 ;
397
382
let mut result = [ 0u8 ; 56 ] ;
398
383
399
384
// Iterate 1 time then check value on 1st iteration
0 commit comments