Skip to content

Commit 5a5a768

Browse files
committed
Use a variable time multiplication for the torsion check
As the group order is anyway public, there is no reason to prevent it from leaking to a side channel.
1 parent 56bf398 commit 5a5a768

File tree

5 files changed

+106
-4
lines changed

5 files changed

+106
-4
lines changed

curve25519-dalek/benches/dalek_benchmarks.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ mod edwards_benches {
2929
});
3030
}
3131

32+
fn is_torsion_free<M: Measurement>(c: &mut BenchmarkGroup<M>) {
33+
let B = &constants::ED25519_BASEPOINT_POINT;
34+
c.bench_function("EdwardsPoint is_torsion_free", move |b| {
35+
b.iter(|| B.is_torsion_free())
36+
});
37+
}
38+
3239
fn consttime_fixed_base_scalar_mul<M: Measurement>(c: &mut BenchmarkGroup<M>) {
3340
let s = Scalar::from(897987897u64).invert();
3441
c.bench_function("Constant-time fixed-base scalar mul", move |b| {
@@ -62,6 +69,7 @@ mod edwards_benches {
6269

6370
compress(&mut g);
6471
decompress(&mut g);
72+
is_torsion_free(&mut g);
6573
consttime_fixed_base_scalar_mul(&mut g);
6674
consttime_variable_base_scalar_mul(&mut g);
6775
vartime_double_base_scalar_mul(&mut g);

curve25519-dalek/src/backend/mod.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,21 @@ pub fn variable_base_mul(point: &EdwardsPoint, scalar: &Scalar) -> EdwardsPoint
236236
}
237237
}
238238

239+
/// Perform variable-time, variable-base scalar multiplication.
240+
pub fn vartime_variable_base_mul(point: &EdwardsPoint, scalar: &Scalar) -> EdwardsPoint {
241+
match get_selected_backend() {
242+
#[cfg(curve25519_dalek_backend = "simd")]
243+
BackendKind::Avx2 => {
244+
vector::scalar_mul::variable_base::spec_avx2::vartime_mul(point, scalar)
245+
}
246+
#[cfg(all(curve25519_dalek_backend = "simd", nightly))]
247+
BackendKind::Avx512 => {
248+
vector::scalar_mul::variable_base::spec_avx512ifma_avx512vl::vartime_mul(point, scalar)
249+
}
250+
BackendKind::Serial => serial::scalar_mul::variable_base::vartime_mul(point, scalar),
251+
}
252+
}
253+
239254
/// Compute \\(aA + bB\\) in variable time, where \\(B\\) is the Ed25519 basepoint.
240255
#[allow(non_snake_case)]
241256
pub fn vartime_double_base_mul(a: &Scalar, A: &EdwardsPoint, b: &Scalar) -> EdwardsPoint {

curve25519-dalek/src/backend/serial/scalar_mul/variable_base.rs

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
#![allow(non_snake_case)]
22

3-
use crate::backend::serial::curve_models::ProjectiveNielsPoint;
3+
use core::cmp::Ordering;
4+
5+
use crate::backend::serial::curve_models::{ProjectiveNielsPoint, ProjectivePoint};
46
use crate::edwards::EdwardsPoint;
57
use crate::scalar::Scalar;
68
use crate::traits::Identity;
7-
use crate::window::LookupTable;
9+
use crate::window::{LookupTable, NafLookupTable5};
810

911
/// Perform constant-time, variable-base scalar multiplication.
1012
#[rustfmt::skip] // keep alignment of explanatory comments
@@ -46,3 +48,39 @@ pub(crate) fn mul(point: &EdwardsPoint, scalar: &Scalar) -> EdwardsPoint {
4648
}
4749
tmp1.as_extended()
4850
}
51+
52+
/// Perform variable-time, variable-base scalar multiplication.
53+
pub fn vartime_mul(point: &EdwardsPoint, scalar: &Scalar) -> EdwardsPoint {
54+
let naf = scalar.non_adjacent_form(5);
55+
let table = NafLookupTable5::<ProjectiveNielsPoint>::from(point);
56+
57+
// Find starting index
58+
let mut i: usize = 255;
59+
for j in (0..256).rev() {
60+
i = j;
61+
if naf[i] != 0 {
62+
break;
63+
}
64+
}
65+
66+
let mut r = ProjectivePoint::identity();
67+
68+
loop {
69+
let mut t = r.double();
70+
71+
match naf[i].cmp(&0) {
72+
Ordering::Greater => t = &t.as_extended() + &table.select(naf[i] as usize),
73+
Ordering::Less => t = &t.as_extended() - &table.select(-naf[i] as usize),
74+
Ordering::Equal => {}
75+
}
76+
77+
r = t.as_projective();
78+
79+
if i == 0 {
80+
break;
81+
}
82+
i -= 1;
83+
}
84+
85+
r.as_extended()
86+
}

curve25519-dalek/src/backend/vector/scalar_mul/variable_base.rs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
)]
77
pub mod spec {
88

9+
use core::cmp::Ordering;
10+
911
#[for_target_feature("avx2")]
1012
use crate::backend::vector::avx2::{CachedPoint, ExtendedPoint};
1113

@@ -15,7 +17,7 @@ pub mod spec {
1517
use crate::edwards::EdwardsPoint;
1618
use crate::scalar::Scalar;
1719
use crate::traits::Identity;
18-
use crate::window::LookupTable;
20+
use crate::window::{LookupTable, NafLookupTable5};
1921

2022
/// Perform constant-time, variable-base scalar multiplication.
2123
pub fn mul(point: &EdwardsPoint, scalar: &Scalar) -> EdwardsPoint {
@@ -41,4 +43,42 @@ pub mod spec {
4143
}
4244
Q.into()
4345
}
46+
47+
/// Perform variable-time, variable-base scalar multiplication.
48+
pub fn vartime_mul(point: &EdwardsPoint, scalar: &Scalar) -> EdwardsPoint {
49+
let naf = scalar.non_adjacent_form(5);
50+
let table = NafLookupTable5::<CachedPoint>::from(point);
51+
52+
// Find starting index
53+
let mut i: usize = 255;
54+
for j in (0..256).rev() {
55+
i = j;
56+
if naf[i] != 0 {
57+
break;
58+
}
59+
}
60+
61+
let mut Q = ExtendedPoint::identity();
62+
63+
loop {
64+
Q = Q.double();
65+
66+
match naf[i].cmp(&0) {
67+
Ordering::Greater => {
68+
Q = &Q + &table.select(naf[i] as usize);
69+
}
70+
Ordering::Less => {
71+
Q = &Q - &table.select(-naf[i] as usize);
72+
}
73+
Ordering::Equal => {}
74+
}
75+
76+
if i == 0 {
77+
break;
78+
}
79+
i -= 1;
80+
}
81+
82+
Q.into()
83+
}
4484
}

curve25519-dalek/src/edwards.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1255,7 +1255,8 @@ impl EdwardsPoint {
12551255
/// assert_eq!((P+Q).is_torsion_free(), false);
12561256
/// ```
12571257
pub fn is_torsion_free(&self) -> bool {
1258-
(self * constants::BASEPOINT_ORDER_PRIVATE).is_identity()
1258+
crate::backend::vartime_variable_base_mul(self, &constants::BASEPOINT_ORDER_PRIVATE)
1259+
.is_identity()
12591260
}
12601261
}
12611262

0 commit comments

Comments
 (0)