From d0201cf2e510b674afe251d163433e6951798d89 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sun, 27 Oct 2024 08:51:19 -0400 Subject: [PATCH] Remove potentially vartime (due to cache side-channel attacks) table access in dalek-ff-group and minimal-ed448 --- LICENSE | 2 +- crypto/dalek-ff-group/src/field.rs | 11 ++++++++++- crypto/dalek-ff-group/src/lib.rs | 11 ++++++++++- crypto/ed448/src/backend.rs | 11 ++++++++++- crypto/ed448/src/point.rs | 11 ++++++++++- 5 files changed, 41 insertions(+), 5 deletions(-) diff --git a/LICENSE b/LICENSE index 34f2feb2..03c8975a 100644 --- a/LICENSE +++ b/LICENSE @@ -5,4 +5,4 @@ a full copy of the AGPL-3.0 License is included in the root of this repository as a reference text. This copy should be provided with any distribution of a crate licensed under the AGPL-3.0, as per its terms. -The GitHub actions (`.github/actions`) are licensed under the MIT license. +The GitHub actions/workflows (`.github`) are licensed under the MIT license. diff --git a/crypto/dalek-ff-group/src/field.rs b/crypto/dalek-ff-group/src/field.rs index b1af2711..60c6c9ea 100644 --- a/crypto/dalek-ff-group/src/field.rs +++ b/crypto/dalek-ff-group/src/field.rs @@ -244,7 +244,16 @@ impl FieldElement { res *= res; } } - res *= table[usize::from(bits)]; + + let mut scale_by = FieldElement::ONE; + #[allow(clippy::needless_range_loop)] + for i in 0 .. 16 { + #[allow(clippy::cast_possible_truncation)] // Safe since 0 .. 16 + { + scale_by = <_>::conditional_select(&scale_by, &table[i], bits.ct_eq(&(i as u8))); + } + } + res *= scale_by; bits = 0; } } diff --git a/crypto/dalek-ff-group/src/lib.rs b/crypto/dalek-ff-group/src/lib.rs index dcbcacc0..e6aad5b2 100644 --- a/crypto/dalek-ff-group/src/lib.rs +++ b/crypto/dalek-ff-group/src/lib.rs @@ -208,7 +208,16 @@ impl Scalar { res *= res; } } - res *= table[usize::from(bits)]; + + let mut scale_by = Scalar::ONE; + #[allow(clippy::needless_range_loop)] + for i in 0 .. 16 { + #[allow(clippy::cast_possible_truncation)] // Safe since 0 .. 16 + { + scale_by = <_>::conditional_select(&scale_by, &table[i], bits.ct_eq(&(i as u8))); + } + } + res *= scale_by; bits = 0; } } diff --git a/crypto/ed448/src/backend.rs b/crypto/ed448/src/backend.rs index db41e811..327fcf97 100644 --- a/crypto/ed448/src/backend.rs +++ b/crypto/ed448/src/backend.rs @@ -161,7 +161,16 @@ macro_rules! field { res *= res; } } - res *= table[usize::from(bits)]; + + let mut scale_by = $FieldName(Residue::ONE); + #[allow(clippy::needless_range_loop)] + for i in 0 .. 16 { + #[allow(clippy::cast_possible_truncation)] // Safe since 0 .. 16 + { + scale_by = <_>::conditional_select(&scale_by, &table[i], bits.ct_eq(&(i as u8))); + } + } + res *= scale_by; bits = 0; } } diff --git a/crypto/ed448/src/point.rs b/crypto/ed448/src/point.rs index c3b10f79..cd49023f 100644 --- a/crypto/ed448/src/point.rs +++ b/crypto/ed448/src/point.rs @@ -242,7 +242,16 @@ impl Mul for Point { res = res.double(); } } - res += table[usize::from(bits)]; + + let mut add_by = Point::identity(); + #[allow(clippy::needless_range_loop)] + for i in 0 .. 16 { + #[allow(clippy::cast_possible_truncation)] // Safe since 0 .. 16 + { + add_by = <_>::conditional_select(&add_by, &table[i], bits.ct_eq(&(i as u8))); + } + } + res += add_by; bits = 0; } }