diff --git a/Cargo.lock b/Cargo.lock index 6f524ee64..e40a12328 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -502,8 +502,7 @@ checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "elliptic-curve" version = "0.14.0-rc.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda94f31325c4275e9706adecbb6f0650dee2f904c915a98e3d81adaaaa757aa" +source = "git+http://github.com/RustCrypto/traits.git#95838a01bd186da138211685a338cac7185f950e" dependencies = [ "base16ct", "crypto-bigint", @@ -1473,7 +1472,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.4.2", + "getrandom 0.3.4", "once_cell", "rustix", "windows-sys", diff --git a/Cargo.toml b/Cargo.toml index dfd952412..e8808e0c0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,4 +27,5 @@ hash2curve = { path = "hash2curve" } primefield = { path = "primefield" } primeorder = { path = "primeorder" } +elliptic-curve = { git = "http://github.com/RustCrypto/traits.git" } rustcrypto-group = { git = "https://github.com/RustCrypto/group" } diff --git a/p256/src/arithmetic.rs b/p256/src/arithmetic.rs index c02987ad4..b045539a1 100644 --- a/p256/src/arithmetic.rs +++ b/p256/src/arithmetic.rs @@ -68,4 +68,13 @@ impl PrimeCurveParams for NistP256 { fn mul_by_generator_vartime(k: &Scalar) -> ProjectivePoint { tables::BASEPOINT_TABLE_VARTIME.mul(k) } + + #[cfg(all(feature = "alloc", feature = "precomputed-tables"))] + fn mul_by_generator_and_mul_add_vartime( + a: &Scalar, + b_scalar: &Scalar, + b_point: &ProjectivePoint, + ) -> ProjectivePoint { + tables::BASEPOINT_TABLE_VARTIME.lincomb(a, &[(*b_point, *b_scalar)]) + } } diff --git a/p384/src/arithmetic.rs b/p384/src/arithmetic.rs index 1554bfb80..ccc1cdf3c 100644 --- a/p384/src/arithmetic.rs +++ b/p384/src/arithmetic.rs @@ -72,4 +72,13 @@ impl PrimeCurveParams for NistP384 { fn mul_by_generator_vartime(k: &Scalar) -> ProjectivePoint { tables::BASEPOINT_TABLE_VARTIME.mul(k) } + + #[cfg(all(feature = "alloc", feature = "precomputed-tables"))] + fn mul_by_generator_and_mul_add_vartime( + a: &Scalar, + b_scalar: &Scalar, + b_point: &ProjectivePoint, + ) -> ProjectivePoint { + tables::BASEPOINT_TABLE_VARTIME.lincomb(a, &[(*b_point, *b_scalar)]) + } } diff --git a/p521/src/arithmetic.rs b/p521/src/arithmetic.rs index 71fa8aa39..57e384e1b 100644 --- a/p521/src/arithmetic.rs +++ b/p521/src/arithmetic.rs @@ -77,4 +77,13 @@ impl PrimeCurveParams for NistP521 { fn mul_by_generator_vartime(k: &Scalar) -> ProjectivePoint { tables::BASEPOINT_TABLE_VARTIME.mul(k) } + + #[cfg(all(feature = "alloc", feature = "precomputed-tables"))] + fn mul_by_generator_and_mul_add_vartime( + a: &Scalar, + b_scalar: &Scalar, + b_point: &ProjectivePoint, + ) -> ProjectivePoint { + tables::BASEPOINT_TABLE_VARTIME.lincomb(a, &[(*b_point, *b_scalar)]) + } } diff --git a/primeorder/src/lib.rs b/primeorder/src/lib.rs index 55c5344f5..dcbe89a10 100644 --- a/primeorder/src/lib.rs +++ b/primeorder/src/lib.rs @@ -29,7 +29,7 @@ pub use elliptic_curve::{ use elliptic_curve::{ CurveArithmetic, Generate, - ops::{Invert, MulVartime}, + ops::{Invert, LinearCombination, MulVartime}, subtle::CtOption, }; @@ -73,6 +73,19 @@ pub trait PrimeCurveParams: fn mul_by_generator_vartime(k: &Scalar) -> ProjectivePoint { ProjectivePoint::GENERATOR.mul_vartime(k) } + + /// Multiply `a` by the generator of the prime-order subgroup, adding the result to the point + /// `P` multiplied by the scalar `b`, i.e. compute `aG + bP`. + fn mul_by_generator_and_mul_add_vartime( + a: &Scalar, + b_scalar: &Scalar, + b_point: &ProjectivePoint, + ) -> ProjectivePoint { + ProjectivePoint::::lincomb_vartime(&[ + (ProjectivePoint::GENERATOR, *a), + (*b_point, *b_scalar), + ]) + } } /// Trait which allows curves to specify a variable-time basepoint table. diff --git a/primeorder/src/projective.rs b/primeorder/src/projective.rs index 0c169b71b..0baacc57e 100644 --- a/primeorder/src/projective.rs +++ b/primeorder/src/projective.rs @@ -970,16 +970,13 @@ where C::mul_by_generator_vartime(scalar) } - // When we're guaranteed *not* to have basepoint tables available (because they need `alloc`) - // use linear combinations for this computation, but they're slower when they are available - // TODO(tarcieri): `WnafBase::multiscalar_mul` w\ basepoint table when `alloc` *is* available - #[cfg(not(feature = "alloc"))] + #[inline] fn mul_by_generator_and_mul_add_vartime( a: &Self::Scalar, b_scalar: &Self::Scalar, b_point: &Self, ) -> Self { - Self::lincomb(&[(Self::GENERATOR, *a), (*b_point, *b_scalar)]) + C::mul_by_generator_and_mul_add_vartime(a, b_scalar, b_point) } } diff --git a/sm2/src/arithmetic.rs b/sm2/src/arithmetic.rs index 0a75d2d9b..da34f25d9 100644 --- a/sm2/src/arithmetic.rs +++ b/sm2/src/arithmetic.rs @@ -68,4 +68,13 @@ impl PrimeCurveParams for Sm2 { fn mul_by_generator_vartime(k: &Scalar) -> ProjectivePoint { tables::BASEPOINT_TABLE_VARTIME.mul(k) } + + #[cfg(all(feature = "alloc", feature = "precomputed-tables"))] + fn mul_by_generator_and_mul_add_vartime( + a: &Scalar, + b_scalar: &Scalar, + b_point: &ProjectivePoint, + ) -> ProjectivePoint { + tables::BASEPOINT_TABLE_VARTIME.lincomb(a, &[(*b_point, *b_scalar)]) + } }