From 088ed3b08700b4c7403ada5c76ceaaaa8432a8de Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 10 Apr 2026 17:56:47 -0600 Subject: [PATCH] elliptic-curve: add `MulByGeneratorVartime` trait Closes #2375 We now have variable-time precomputed basepoint tables that use wNAF when the `basepoint-table` and `alloc` features are enabled, which can be opportunistically used when these features are enabled to accelerate this operation. We use `Group::mul_by_generator` for the constant-time basepoint tables, however for an extension trait this is captured as `MulByGeneratorVartime::mul_by_generator_vartime`. As discussed in the above issue, and inspired by `curve25519-dalek`'s `EdwardsPoint::vartime_double_scalar_mul_basepoint` function, this adds `MulByGeneratorVartime::mul_by_generator_and_mul_add_point_vartime` as a provided method. This function is the core of many signature algorithms, and when the basepoint tables and alloc are unavailable it can fall back to a linear combination and still provide better performance than the naive constant time version. --- elliptic-curve/src/ops.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/elliptic-curve/src/ops.rs b/elliptic-curve/src/ops.rs index c8c344b10..e5c1a2c9f 100644 --- a/elliptic-curve/src/ops.rs +++ b/elliptic-curve/src/ops.rs @@ -6,6 +6,7 @@ pub use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Shr, ShrAssign, Sub, Su use crate::CurveGroup; use core::iter; use ff::Field; +use group::Group; use subtle::{Choice, CtOption}; #[cfg(feature = "alloc")] @@ -198,6 +199,35 @@ pub trait MulVartime: Mul { fn mul_vartime(self, rhs: Rhs) -> >::Output; } +/// Variable-time multiplication by the generator of the curve group. +/// +///
+/// Security Warning +/// +/// Variable-time operations should only be used on non-secret values, and may potentially leak +/// secret values! +///
+pub trait MulByGeneratorVartime: Group + for<'a> MulVartime<&'a Self::Scalar> { + /// Multiply by the generator of the prime-order subgroup. + /// + /// Variable-time equivalent of [`Group::mul_by_generator`]. + fn mul_by_generator_vartime(scalar: &Self::Scalar) -> Self { + Self::generator().mul_vartime(scalar) + } + + /// Multiply `a` by the generator of the prime-order subgroup, adding the result to the point + /// `B` multiplied by the scalar `b`, i.e. compute `aG + bB`. + /// + /// This operation is the core of many signature verification algorithms. + fn mul_by_generator_and_mul_add_point_vartime( + a: &Self::Scalar, + b_scalar: &Self::Scalar, + b_point: &Self, + ) -> Self { + Self::mul_by_generator_vartime(a) + b_point.mul_vartime(b_scalar) + } +} + /// Modular reduction to a non-zero output. /// /// This trait is primarily intended for use by curve implementations such