Skip to content

Commit d19d50f

Browse files
authored
elliptic-curve: add Invert::invert_vartime (RustCrypto#1239)
Adds support for optimized variable-time inversions via the `Invert` trait. By default, the implementation uses a constant-time inversion by calling `Invert::invert`.
1 parent 771f5df commit d19d50f

File tree

3 files changed

+28
-1
lines changed

3 files changed

+28
-1
lines changed

elliptic-curve/src/ops.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,17 @@ pub trait Invert {
1212

1313
/// Invert a field element.
1414
fn invert(&self) -> Self::Output;
15+
16+
/// Invert a field element in variable time.
17+
///
18+
/// ⚠️ WARNING!
19+
///
20+
/// This method should not be used with secret values, as its variable-time
21+
/// operation can potentially leak secrets through sidechannels.
22+
fn invert_vartime(&self) -> Self::Output {
23+
// Fall back on constant-time implementation by default.
24+
self.invert()
25+
}
1526
}
1627

1728
impl<F: ff::Field> Invert for F {

elliptic-curve/src/scalar/invert.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ use subtle::CtOption;
88
/// Returns none if the scalar is zero.
99
///
1010
/// <https://link.springer.com/article/10.1007/s13389-016-0135-4>
11+
///
12+
/// ⚠️ WARNING!
13+
///
14+
/// This generic implementation relies on special properties of the scalar
15+
/// field implementation and may not work correctly! Please ensure your use
16+
/// cases are well-tested!
17+
///
18+
/// USE AT YOUR OWN RISK!
1119
#[allow(non_snake_case)]
1220
pub fn invert_vartime<C>(scalar: &Scalar<C>) -> CtOption<Scalar<C>>
1321
where

elliptic-curve/src/scalar/nonzero.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,13 +184,21 @@ where
184184
impl<C> Invert for NonZeroScalar<C>
185185
where
186186
C: CurveArithmetic,
187+
Scalar<C>: Invert<Output = CtOption<Scalar<C>>>,
187188
{
188189
type Output = Self;
189190

190191
fn invert(&self) -> Self {
191192
Self {
192193
// This will always succeed since `scalar` will never be 0
193-
scalar: ff::Field::invert(&self.scalar).unwrap(),
194+
scalar: Invert::invert(&self.scalar).unwrap(),
195+
}
196+
}
197+
198+
fn invert_vartime(&self) -> Self::Output {
199+
Self {
200+
// This will always succeed since `scalar` will never be 0
201+
scalar: Invert::invert_vartime(&self.scalar).unwrap(),
194202
}
195203
}
196204
}

0 commit comments

Comments
 (0)