7
7
8
8
//! Key Exchange group implementation for Curve25519
9
9
10
- use curve25519_dalek:: constants:: ED25519_BASEPOINT_TABLE ;
10
+ use curve25519_dalek:: constants:: X25519_BASEPOINT ;
11
11
use curve25519_dalek:: montgomery:: MontgomeryPoint ;
12
12
use curve25519_dalek:: scalar:: Scalar ;
13
13
use curve25519_dalek:: traits:: Identity ;
@@ -47,7 +47,10 @@ impl KeGroup for Curve25519 {
47
47
48
48
fn random_sk < R : RngCore + CryptoRng > ( rng : & mut R ) -> Self :: Sk {
49
49
loop {
50
- let scalar = Scalar :: random ( rng) ;
50
+ // Sample 32 random bytes and then clamp, as described in https://cr.yp.to/ecdh.html
51
+ let mut scalar_bytes = [ 0u8 ; 32 ] ;
52
+ rng. fill_bytes ( & mut scalar_bytes) ;
53
+ let scalar = Scalar :: from_bits_clamped ( scalar_bytes) ;
51
54
52
55
if scalar != Scalar :: ZERO {
53
56
break scalar;
@@ -68,6 +71,7 @@ impl KeGroup for Curve25519 {
68
71
. fill_bytes ( & mut uniform_bytes) ;
69
72
70
73
let scalar = Scalar :: from_bytes_mod_order_wide ( & uniform_bytes. into ( ) ) ;
74
+ let scalar = Scalar :: from_bits_clamped ( scalar. to_bytes ( ) ) ;
71
75
72
76
if scalar == Scalar :: ZERO {
73
77
Err ( InternalError :: HashToScalar )
@@ -81,7 +85,7 @@ impl KeGroup for Curve25519 {
81
85
}
82
86
83
87
fn public_key ( sk : Self :: Sk ) -> Self :: Pk {
84
- ( ED25519_BASEPOINT_TABLE * & sk ) . to_montgomery ( )
88
+ X25519_BASEPOINT * sk
85
89
}
86
90
87
91
fn diffie_hellman ( pk : Self :: Pk , sk : Self :: Sk ) -> GenericArray < u8 , Self :: PkLen > {
@@ -96,7 +100,10 @@ impl KeGroup for Curve25519 {
96
100
bytes
97
101
. try_into ( )
98
102
. ok ( )
99
- . and_then ( |bytes| Scalar :: from_canonical_bytes ( bytes) . into ( ) )
103
+ . and_then ( |bytes| {
104
+ let scalar = Scalar :: from_bits_clamped ( bytes) ;
105
+ ( scalar. as_bytes ( ) == & bytes) . then_some ( scalar)
106
+ } )
100
107
. filter ( |scalar| scalar != & Scalar :: ZERO )
101
108
. ok_or ( InternalError :: PointError )
102
109
}
0 commit comments