diff --git a/Cargo.lock b/Cargo.lock index 3cb0426da..ba3167679 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -569,8 +569,7 @@ dependencies = [ [[package]] name = "rustcrypto-group" version = "0.14.0-rc.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "369f9b61aa45933c062c9f6b5c3c50ab710687eca83dd3802653b140b43f85ed" +source = "git+https://github.com/RustCrypto/group#d5ef2775cb66a10085c9ec48432c51cad4e7b3ee" dependencies = [ "rand_core", "rustcrypto-ff", diff --git a/Cargo.toml b/Cargo.toml index 79c85b5b2..ec248c5ba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,3 +57,5 @@ unused_qualifications = "warn" crypto-common = { path = "crypto-common" } digest = { path = "digest" } signature = { path = "signature" } + +rustcrypto-group = { git = "https://github.com/RustCrypto/group" } diff --git a/elliptic-curve/src/point/basepoint_table.rs b/elliptic-curve/src/point/basepoint_table.rs index fe3d88ea1..125dd20ef 100644 --- a/elliptic-curve/src/point/basepoint_table.rs +++ b/elliptic-curve/src/point/basepoint_table.rs @@ -98,6 +98,7 @@ impl Deref for BasepointTable Point { self.table.mul(&WnafScalar::new(scalar)) } + + /// Multiply `Point::generator` by the given scalar in variable-time, then compute a linear + /// combination of the remaining points and scalars, i.e. + /// + /// ```text + /// scalar * G + scalars[0] * Points[0] + ... + /// ``` + pub fn lincomb( + &self, + scalar: &Point::Scalar, + points_and_scalars: &[(Point, Point::Scalar)], + ) -> Point { + let mut bases = Vec::with_capacity(points_and_scalars.len() + 1); + bases.push(self.table.clone()); + bases.extend( + points_and_scalars + .iter() + .map(|(point, _)| WnafBase::new(*point)), + ); + + let mut scalars = Vec::with_capacity(points_and_scalars.len() + 1); + scalars.push(WnafScalar::new(scalar)); + scalars.extend( + points_and_scalars + .iter() + .map(|(_, scalar)| WnafScalar::new(scalar)), + ); + + WnafBase::multiscalar_mul(scalars.iter(), bases.iter()) + } } impl Default for BasepointTableVartime {