Skip to content

Commit 5179e36

Browse files
committed
Correctly clamp Curve25519 secret keys
1 parent 8b755bf commit 5179e36

File tree

3 files changed

+93
-86
lines changed

3 files changed

+93
-86
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ version = "3.0.0-pre.2"
1313

1414
[features]
1515
argon2 = ["dep:argon2"]
16-
curve25519 = ["dep:curve25519-dalek", "curve25519-dalek?/precomputed-tables"]
16+
curve25519 = ["dep:curve25519-dalek"]
1717
default = ["ristretto255-voprf", "serde"]
1818
ristretto255 = ["dep:curve25519-dalek", "voprf/ristretto255"]
1919
ristretto255-voprf = ["ristretto255", "voprf/ristretto255-ciphersuite"]

src/key_exchange/group/curve25519.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
//! Key Exchange group implementation for Curve25519
99
10-
use curve25519_dalek::constants::ED25519_BASEPOINT_TABLE;
10+
use curve25519_dalek::constants::X25519_BASEPOINT;
1111
use curve25519_dalek::montgomery::MontgomeryPoint;
1212
use curve25519_dalek::scalar::Scalar;
1313
use curve25519_dalek::traits::Identity;
@@ -47,7 +47,10 @@ impl KeGroup for Curve25519 {
4747

4848
fn random_sk<R: RngCore + CryptoRng>(rng: &mut R) -> Self::Sk {
4949
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);
5154

5255
if scalar != Scalar::ZERO {
5356
break scalar;
@@ -68,6 +71,7 @@ impl KeGroup for Curve25519 {
6871
.fill_bytes(&mut uniform_bytes);
6972

7073
let scalar = Scalar::from_bytes_mod_order_wide(&uniform_bytes.into());
74+
let scalar = Scalar::from_bits_clamped(scalar.to_bytes());
7175

7276
if scalar == Scalar::ZERO {
7377
Err(InternalError::HashToScalar)
@@ -81,7 +85,7 @@ impl KeGroup for Curve25519 {
8185
}
8286

8387
fn public_key(sk: Self::Sk) -> Self::Pk {
84-
(ED25519_BASEPOINT_TABLE * &sk).to_montgomery()
88+
X25519_BASEPOINT * sk
8589
}
8690

8791
fn diffie_hellman(pk: Self::Pk, sk: Self::Sk) -> GenericArray<u8, Self::PkLen> {
@@ -96,7 +100,10 @@ impl KeGroup for Curve25519 {
96100
bytes
97101
.try_into()
98102
.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+
})
100107
.filter(|scalar| scalar != &Scalar::ZERO)
101108
.ok_or(InternalError::PointError)
102109
}

0 commit comments

Comments
 (0)