From 6e2060a8f61312240671e3ef416aa9222753c4ad Mon Sep 17 00:00:00 2001
From: Tony Arcieri <bascule@gmail.com>
Date: Thu, 1 Feb 2024 20:05:02 -0700
Subject: [PATCH] Bump `elliptic-curve` to v0.14.0-pre.5

Also bumps `ecdsa` to v0.17.0-pre.5

This includes upgrades to the new `LinearCombination` trait
---
 Cargo.lock                    | 57 ++++++++++++++++++-----------------
 Cargo.toml                    |  3 --
 bign256/Cargo.toml            |  8 ++---
 bign256/src/dsa/verifying.rs  | 10 +++---
 bp256/Cargo.toml              |  6 ++--
 bp384/Cargo.toml              |  6 ++--
 k256/Cargo.toml               | 12 ++++----
 k256/benches/scalar.rs        |  2 +-
 k256/src/arithmetic/mul.rs    | 21 +++++--------
 k256/src/schnorr/verifying.rs | 10 +++---
 p192/Cargo.toml               |  6 ++--
 p224/Cargo.toml               |  8 ++---
 p256/Cargo.toml               |  8 ++---
 p384/Cargo.toml               |  8 ++---
 p521/Cargo.toml               |  8 ++---
 primeorder/Cargo.toml         |  2 +-
 primeorder/src/projective.rs  | 11 ++++++-
 sm2/Cargo.toml                |  8 ++---
 sm2/src/dsa/verifying.rs      | 10 +++---
 19 files changed, 100 insertions(+), 104 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 0545d9a5..c9cd8954 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -40,9 +40,9 @@ checksum = "d9aa1eef3994e2ccd304a78fe3fea4a73e5792007f85f09b79bb82143ca5f82b"
 
 [[package]]
 name = "belt-hash"
-version = "0.2.0-pre.2"
+version = "0.2.0-pre.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc652cc2553b19afcdcb890c9fa22e315f759d87b195fe1924f97692fd20ecce"
+checksum = "4f27c3b1a850b9948ab73e1f8064ac701716cad53259d43d173017f7dd4b0ec6"
 dependencies = [
  "belt-block",
  "digest",
@@ -111,9 +111,9 @@ checksum = "847495c209977a90e8aad588b959d0ca9f5dc228096d29a6bd3defd53f35eaec"
 
 [[package]]
 name = "block-buffer"
-version = "0.11.0-pre.4"
+version = "0.11.0-pre.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0edadbde8e0243b49d434f9a23ec0590af201f400a34d7d51049284e4a77c568"
+checksum = "3ded684142010808eb980d9974ef794da2bcf97d13396143b1515e9f0fb4a10e"
 dependencies = [
  "crypto-common",
 ]
@@ -330,9 +330,9 @@ dependencies = [
 
 [[package]]
 name = "crypto-common"
-version = "0.2.0-pre.4"
+version = "0.2.0-pre.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "806e4e3731d44f1340b069551225b44c2056c105cad9e67f0c46266db8a3a6b9"
+checksum = "b7aa2ec04f5120b830272a481e8d9d8ba4dda140d2cda59b0f1110d5eb93c38e"
 dependencies = [
  "hybrid-array",
 ]
@@ -350,9 +350,9 @@ dependencies = [
 
 [[package]]
 name = "digest"
-version = "0.11.0-pre.7"
+version = "0.11.0-pre.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "957713a19ffdda287c63772e607f848512f67ba948f17d8e42cb8d50fd98a786"
+checksum = "065d93ead7c220b85d5b4be4795d8398eac4ff68b5ee63895de0a3c1fb6edf25"
 dependencies = [
  "block-buffer",
  "const-oid",
@@ -362,9 +362,9 @@ dependencies = [
 
 [[package]]
 name = "ecdsa"
-version = "0.17.0-pre.4"
+version = "0.17.0-pre.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12cc615703dcff86386153ad5dabbf2544f2ed8fbacb881e1ea440410220660f"
+checksum = "d7e045ee5c360512162782f3d4cb07d2f4ce8c4ef9bf7c77ec16d1cf60b3d5ca"
 dependencies = [
  "der",
  "digest",
@@ -383,9 +383,9 @@ checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
 
 [[package]]
 name = "elliptic-curve"
-version = "0.14.0-pre.3"
+version = "0.14.0-pre.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5a28b26e8b4a94186ac649acffa41ba13ca853bd33e44b00fc1c3bd30bfeebe"
+checksum = "4a1775af172997a40c14854c3a9fde9e03e5772084b334b6a0bb18bf7f93ac16"
 dependencies = [
  "base16ct",
  "base64ct",
@@ -517,27 +517,27 @@ checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46"
 
 [[package]]
 name = "hkdf"
-version = "0.13.0-pre.2"
+version = "0.13.0-pre.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c524b31a8b37d9561e29293b5931461f0bb72a75101f3916e1480525113da8e9"
+checksum = "fd5d615ab5c462f96c309b3a00b19f373025a4981312f717f9df5bbd0201530c"
 dependencies = [
  "hmac",
 ]
 
 [[package]]
 name = "hmac"
-version = "0.13.0-pre.2"
+version = "0.13.0-pre.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1fac01891f12d968a2737928c9af2532abdc750e56a890fdbcafdfff17017678"
+checksum = "ffd790a0795ee332ed3e8959e5b177beb70d7112eb7d345428ec17427897d5ce"
 dependencies = [
  "digest",
 ]
 
 [[package]]
 name = "hybrid-array"
-version = "0.2.0-rc.3"
+version = "0.2.0-rc.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8856b3db5eb76328f03589feb25c7a3166bfa0ae3b38b1408d546b097fa7947"
+checksum = "18e63b66aee2df5599ba69b17a48113dfc68d2e143ea387ef836509e433bbd7e"
 dependencies = [
  "typenum",
  "zeroize",
@@ -1023,9 +1023,9 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
 
 [[package]]
 name = "rfc6979"
-version = "0.5.0-pre.2"
+version = "0.5.0-pre.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ca433f6da88ec508578cac524a1602a437964cf049ffb39f1509e8696d43e79"
+checksum = "045972f2f66b9467a2f6834b7fd0f9b23ca214b4a8700b880c36edb726e96da6"
 dependencies = [
  "hmac",
  "subtle",
@@ -1160,8 +1160,9 @@ dependencies = [
 
 [[package]]
 name = "sha2"
-version = "0.11.0-pre.2"
-source = "git+https://github.com/RustCrypto/hashes.git#9130e96e88908905e2c1b6afbbd34c27f85adac6"
+version = "0.11.0-pre.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f33549bf3064b62478926aa89cbfc7c109aab66ae8f0d5d2ef839e482cc30d6"
 dependencies = [
  "cfg-if",
  "cpufeatures",
@@ -1170,9 +1171,9 @@ dependencies = [
 
 [[package]]
 name = "sha3"
-version = "0.11.0-pre.2"
+version = "0.11.0-pre.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9cecb44e361133b3304a1b3e325a1d8c999339fec8c19762b55e1509a17d6806"
+checksum = "f32c02b9987a647a3d6af14c3e88df86594e4283050d9d8ee3a035df247785b9"
 dependencies = [
  "digest",
  "keccak",
@@ -1180,9 +1181,9 @@ dependencies = [
 
 [[package]]
 name = "signature"
-version = "2.3.0-pre.2"
+version = "2.3.0-pre.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "017ea2f120415e4bf9c6177425b40386f207284147564e19d196c7bc90483c08"
+checksum = "1700c22ba9ce32c7b0a1495068a906c3552e7db386af7cf865162e0dea498523"
 dependencies = [
  "digest",
  "rand_core",
@@ -1205,9 +1206,9 @@ dependencies = [
 
 [[package]]
 name = "sm3"
-version = "0.5.0-pre.2"
+version = "0.5.0-pre.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2321118e4564a21e290428343d8cb9ae4728fbd837fed928ab990a595b1f545b"
+checksum = "a6f18e1b896a93beea148524bdfd4b7c58034de3b3edcacc6be1bec9d9fe043d"
 dependencies = [
  "digest",
 ]
diff --git a/Cargo.toml b/Cargo.toml
index 9e04cc27..126bda12 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -17,6 +17,3 @@ members = [
 
 [profile.dev]
 opt-level = 2
-
-[patch.crates-io.sha2]
-git = "https://github.com/RustCrypto/hashes.git"
diff --git a/bign256/Cargo.toml b/bign256/Cargo.toml
index b8f5b0fb..23350900 100644
--- a/bign256/Cargo.toml
+++ b/bign256/Cargo.toml
@@ -17,13 +17,13 @@ edition = "2021"
 rust-version = "1.73"
 
 [dependencies]
-elliptic-curve = { version = "=0.14.0-pre.3", features = ["hazmat", "sec1"] }
+elliptic-curve = { version = "=0.14.0-pre.5", features = ["hazmat", "sec1"] }
 
 # optional dependencies
 primeorder = { version = "=0.14.0-pre.0", optional = true, path = "../primeorder" }
-signature = { version = "=2.3.0-pre.2", optional = true }
-belt-hash = { version = "=0.2.0-pre.2", optional = true, default-features = false }
-rfc6979 = { version = "=0.5.0-pre.2", optional = true }
+signature = { version = "=2.3.0-pre.3", optional = true }
+belt-hash = { version = "=0.2.0-pre.3", optional = true, default-features = false }
+rfc6979 = { version = "=0.5.0-pre.3", optional = true }
 
 [dev-dependencies]
 criterion = "0.5"
diff --git a/bign256/src/dsa/verifying.rs b/bign256/src/dsa/verifying.rs
index b3dd4b53..64ce212f 100644
--- a/bign256/src/dsa/verifying.rs
+++ b/bign256/src/dsa/verifying.rs
@@ -130,12 +130,10 @@ impl PrehashVerifier<Signature> for VerifyingKey {
         let right = s0.add(&Scalar::from_u64(2).pow([128, 0, 0, 0]));
 
         // 5. Set 𝑅 ← (︀(𝑆1 + 𝐻) mod 𝑞)︀𝐺 + (𝑆0 + 2𝑙)𝑄.
-        let r = ProjectivePoint::lincomb(
-            &ProjectivePoint::generator(),
-            &left,
-            &self.public_key.to_projective(),
-            &right,
-        );
+        let r = ProjectivePoint::lincomb(&[
+            (ProjectivePoint::generator(), left),
+            (self.public_key.to_projective(), right),
+        ]);
 
         // 6. If 𝑅 = 𝑂, return NO.
         if r.is_identity().into() {
diff --git a/bp256/Cargo.toml b/bp256/Cargo.toml
index 91cf3891..c0c95b1b 100644
--- a/bp256/Cargo.toml
+++ b/bp256/Cargo.toml
@@ -13,12 +13,12 @@ edition = "2021"
 rust-version = "1.73"
 
 [dependencies]
-elliptic-curve = { version = "=0.14.0-pre.3", default-features = false, features = ["hazmat", "sec1"] }
+elliptic-curve = { version = "=0.14.0-pre.5", default-features = false, features = ["hazmat", "sec1"] }
 
 # optional dependencies
-ecdsa = { version = "=0.17.0-pre.4", optional = true, default-features = false, features = ["der"] }
+ecdsa = { version = "=0.17.0-pre.5", optional = true, default-features = false, features = ["der"] }
 primeorder = { version = "=0.14.0-pre.0", optional = true, path = "../primeorder" }
-sha2 = { version = "=0.11.0-pre.2", optional = true, default-features = false }
+sha2 = { version = "=0.11.0-pre.3", optional = true, default-features = false }
 
 [features]
 default = ["pkcs8", "std"]
diff --git a/bp384/Cargo.toml b/bp384/Cargo.toml
index 967aa008..1d4ea135 100644
--- a/bp384/Cargo.toml
+++ b/bp384/Cargo.toml
@@ -13,12 +13,12 @@ edition = "2021"
 rust-version = "1.73"
 
 [dependencies]
-elliptic-curve = { version = "=0.14.0-pre.3", default-features = false, features = ["hazmat", "sec1"] }
+elliptic-curve = { version = "=0.14.0-pre.5", default-features = false, features = ["hazmat", "sec1"] }
 
 # optional dependencies
-ecdsa = { version = "=0.17.0-pre.4", optional = true, default-features = false, features = ["der"] }
+ecdsa = { version = "=0.17.0-pre.5", optional = true, default-features = false, features = ["der"] }
 primeorder = { version = "=0.14.0-pre.0", optional = true, path = "../primeorder" }
-sha2 = { version = "=0.11.0-pre.2", optional = true, default-features = false }
+sha2 = { version = "=0.11.0-pre.3", optional = true, default-features = false }
 
 [features]
 default = ["pkcs8", "std"]
diff --git a/k256/Cargo.toml b/k256/Cargo.toml
index 8d4efcda..1bb823a0 100644
--- a/k256/Cargo.toml
+++ b/k256/Cargo.toml
@@ -19,26 +19,26 @@ rust-version = "1.73"
 
 [dependencies]
 cfg-if = "1.0"
-elliptic-curve = { version = "=0.14.0-pre.3", default-features = false, features = ["hazmat", "sec1"] }
+elliptic-curve = { version = "=0.14.0-pre.5", default-features = false, features = ["hazmat", "sec1"] }
 
 # optional dependencies
 once_cell = { version = "1.19", optional = true, default-features = false }
-ecdsa-core = { version = "=0.17.0-pre.4", package = "ecdsa", optional = true, default-features = false, features = ["der"] }
+ecdsa-core = { version = "=0.17.0-pre.5", package = "ecdsa", optional = true, default-features = false, features = ["der"] }
 hex-literal = { version = "0.4", optional = true }
 serdect = { version = "0.2", optional = true, default-features = false }
-sha2 = { version = "=0.11.0-pre.2", optional = true, default-features = false }
-signature = { version = "=2.3.0-pre.2", optional = true }
+sha2 = { version = "=0.11.0-pre.3", optional = true, default-features = false }
+signature = { version = "=2.3.0-pre.3", optional = true }
 
 [dev-dependencies]
 blobby = "0.3"
 criterion = "0.5"
-ecdsa-core = { version = "=0.17.0-pre.4", package = "ecdsa", default-features = false, features = ["dev"] }
+ecdsa-core = { version = "=0.17.0-pre.5", package = "ecdsa", default-features = false, features = ["dev"] }
 hex-literal = "0.4"
 num-bigint = "0.4"
 num-traits = "0.2"
 proptest = "1.4"
 rand_core = { version = "0.6", features = ["getrandom"] }
-sha3 = { version = "=0.11.0-pre.2", default-features = false }
+sha3 = { version = "=0.11.0-pre.3", default-features = false }
 
 [features]
 default = ["arithmetic", "ecdsa", "pkcs8", "precomputed-tables", "schnorr", "std"]
diff --git a/k256/benches/scalar.rs b/k256/benches/scalar.rs
index d7bc7f9e..b700f39e 100644
--- a/k256/benches/scalar.rs
+++ b/k256/benches/scalar.rs
@@ -51,7 +51,7 @@ fn bench_point_lincomb<'a, M: Measurement>(group: &mut BenchmarkGroup<'a, M>) {
     });
     group.bench_function("lincomb()", |b| {
         b.iter(|| {
-            ProjectivePoint::lincomb(&black_box(p), &black_box(s), &black_box(p), &black_box(s))
+            ProjectivePoint::lincomb(&[(black_box(p), black_box(s)), (black_box(p), black_box(s))])
         })
     });
 }
diff --git a/k256/src/arithmetic/mul.rs b/k256/src/arithmetic/mul.rs
index 6354a7d2..162229f7 100644
--- a/k256/src/arithmetic/mul.rs
+++ b/k256/src/arithmetic/mul.rs
@@ -46,9 +46,8 @@ use crate::arithmetic::{
 };
 
 use core::ops::{Mul, MulAssign};
-use elliptic_curve::ops::LinearCombinationExt as LinearCombination;
 use elliptic_curve::{
-    ops::MulByGenerator,
+    ops::{LinearCombination, MulByGenerator},
     scalar::IsHigh,
     subtle::{Choice, ConditionallySelectable, ConstantTimeEq},
 };
@@ -281,7 +280,7 @@ impl<const D: usize> Default for Radix16Decomposition<D> {
 }
 
 impl<const N: usize> LinearCombination<[(ProjectivePoint, Scalar); N]> for ProjectivePoint {
-    fn lincomb_ext(points_and_scalars: &[(ProjectivePoint, Scalar); N]) -> Self {
+    fn lincomb(points_and_scalars: &[(ProjectivePoint, Scalar); N]) -> Self {
         let mut tables = [(LookupTable::default(), LookupTable::default()); N];
         let mut digits = [(
             Radix16Decomposition::<33>::default(),
@@ -292,9 +291,9 @@ impl<const N: usize> LinearCombination<[(ProjectivePoint, Scalar); N]> for Proje
     }
 }
 
-#[cfg(feature = "alloc")]
 impl LinearCombination<[(ProjectivePoint, Scalar)]> for ProjectivePoint {
-    fn lincomb_ext(points_and_scalars: &[(ProjectivePoint, Scalar)]) -> Self {
+    #[cfg(feature = "alloc")]
+    fn lincomb(points_and_scalars: &[(ProjectivePoint, Scalar)]) -> Self {
         let mut tables =
             vec![(LookupTable::default(), LookupTable::default()); points_and_scalars.len()];
         let mut digits = vec![
@@ -411,7 +410,7 @@ impl MulByGenerator for ProjectivePoint {
 
 #[inline(always)]
 fn mul(x: &ProjectivePoint, k: &Scalar) -> ProjectivePoint {
-    ProjectivePoint::lincomb_ext(&[(*x, *k)])
+    ProjectivePoint::lincomb(&[(*x, *k)])
 }
 
 impl Mul<Scalar> for ProjectivePoint {
@@ -454,11 +453,7 @@ impl MulAssign<&Scalar> for ProjectivePoint {
 mod tests {
     use super::*;
     use crate::arithmetic::{ProjectivePoint, Scalar};
-    use elliptic_curve::{
-        ops::{LinearCombination as _, MulByGenerator},
-        rand_core::OsRng,
-        Field, Group,
-    };
+    use elliptic_curve::{ops::MulByGenerator, rand_core::OsRng, Field, Group};
 
     #[test]
     fn test_lincomb() {
@@ -468,7 +463,7 @@ mod tests {
         let l = Scalar::random(&mut OsRng);
 
         let reference = &x * &k + &y * &l;
-        let test = ProjectivePoint::lincomb(&x, &k, &y, &l);
+        let test = ProjectivePoint::lincomb(&[(x, k), (y, l)]);
         assert_eq!(reference, test);
     }
 
@@ -491,7 +486,7 @@ mod tests {
         let reference = &x * &k + &y * &l;
         let points_and_scalars = vec![(x, k), (y, l)];
 
-        let test = ProjectivePoint::lincomb_ext(points_and_scalars.as_slice());
+        let test = ProjectivePoint::lincomb(points_and_scalars.as_slice());
         assert_eq!(reference, test);
     }
 }
diff --git a/k256/src/schnorr/verifying.rs b/k256/src/schnorr/verifying.rs
index e35130e2..f3b02a61 100644
--- a/k256/src/schnorr/verifying.rs
+++ b/k256/src/schnorr/verifying.rs
@@ -75,12 +75,10 @@ impl PrehashVerifier<Signature> for VerifyingKey {
                 .finalize(),
         );
 
-        let R = ProjectivePoint::lincomb(
-            &ProjectivePoint::GENERATOR,
-            s,
-            &self.inner.to_projective(),
-            &-e,
-        )
+        let R = ProjectivePoint::lincomb(&[
+            (ProjectivePoint::GENERATOR, **s),
+            (self.inner.to_projective(), -e),
+        ])
         .to_affine();
 
         if R.is_identity().into() || R.y.normalize().is_odd().into() || R.x.normalize() != *r {
diff --git a/p192/Cargo.toml b/p192/Cargo.toml
index 67c3ae8a..439fa5bc 100644
--- a/p192/Cargo.toml
+++ b/p192/Cargo.toml
@@ -16,17 +16,17 @@ edition = "2021"
 rust-version = "1.73"
 
 [dependencies]
-elliptic-curve = { version = "=0.14.0-pre.3", default-features = false, features = ["hazmat", "sec1"] }
+elliptic-curve = { version = "=0.14.0-pre.5", default-features = false, features = ["hazmat", "sec1"] }
 sec1 = { version = "=0.8.0-pre.1", default-features = false }
 
 # optional dependencies
-ecdsa-core = { version = "=0.17.0-pre.4", package = "ecdsa", optional = true, default-features = false, features = ["der"] }
+ecdsa-core = { version = "=0.17.0-pre.5", package = "ecdsa", optional = true, default-features = false, features = ["der"] }
 hex-literal = { version = "0.4", optional = true }
 primeorder = { version = "=0.14.0-pre.0", optional = true, path = "../primeorder" }
 serdect = { version = "0.2", optional = true, default-features = false }
 
 [dev-dependencies]
-ecdsa-core = { version = "=0.17.0-pre.4", package = "ecdsa", default-features = false, features = ["dev"] }
+ecdsa-core = { version = "=0.17.0-pre.5", package = "ecdsa", default-features = false, features = ["dev"] }
 hex-literal = "0.4"
 primeorder = { version = "=0.14.0-pre.0", features = ["dev"], path = "../primeorder" }
 
diff --git a/p224/Cargo.toml b/p224/Cargo.toml
index 71d8f274..c2510a59 100644
--- a/p224/Cargo.toml
+++ b/p224/Cargo.toml
@@ -16,18 +16,18 @@ edition = "2021"
 rust-version = "1.73"
 
 [dependencies]
-elliptic-curve = { version = "=0.14.0-pre.3", default-features = false, features = ["hazmat", "sec1"] }
+elliptic-curve = { version = "=0.14.0-pre.5", default-features = false, features = ["hazmat", "sec1"] }
 
 # optional dependencies
-ecdsa-core = { version = "=0.17.0-pre.4", package = "ecdsa", optional = true, default-features = false, features = ["der"] }
+ecdsa-core = { version = "=0.17.0-pre.5", package = "ecdsa", optional = true, default-features = false, features = ["der"] }
 hex-literal = { version = "0.4", optional = true }
 primeorder = { version = "=0.14.0-pre.0", optional = true, path = "../primeorder" }
 serdect = { version = "0.2", optional = true, default-features = false }
-sha2 = { version = "=0.11.0-pre.2", optional = true, default-features = false }
+sha2 = { version = "=0.11.0-pre.3", optional = true, default-features = false }
 
 [dev-dependencies]
 blobby = "0.3"
-ecdsa-core = { version = "=0.17.0-pre.4", package = "ecdsa", default-features = false, features = ["dev"] }
+ecdsa-core = { version = "=0.17.0-pre.5", package = "ecdsa", default-features = false, features = ["dev"] }
 hex-literal = "0.4"
 primeorder = { version = "=0.14.0-pre.0", features = ["dev"], path = "../primeorder" }
 rand_core = { version = "0.6", features = ["getrandom"] }
diff --git a/p256/Cargo.toml b/p256/Cargo.toml
index b1db7839..92406c15 100644
--- a/p256/Cargo.toml
+++ b/p256/Cargo.toml
@@ -17,19 +17,19 @@ edition = "2021"
 rust-version = "1.73"
 
 [dependencies]
-elliptic-curve = { version = "=0.14.0-pre.3", default-features = false, features = ["hazmat", "sec1"] }
+elliptic-curve = { version = "=0.14.0-pre.5", default-features = false, features = ["hazmat", "sec1"] }
 
 # optional dependencies
-ecdsa-core = { version = "=0.17.0-pre.4", package = "ecdsa", optional = true, default-features = false, features = ["der"] }
+ecdsa-core = { version = "=0.17.0-pre.5", package = "ecdsa", optional = true, default-features = false, features = ["der"] }
 hex-literal = { version = "0.4", optional = true }
 primeorder = { version = "=0.14.0-pre.0", optional = true, path = "../primeorder" }
 serdect = { version = "0.2", optional = true, default-features = false }
-sha2 = { version = "=0.11.0-pre.2", optional = true, default-features = false }
+sha2 = { version = "=0.11.0-pre.3", optional = true, default-features = false }
 
 [dev-dependencies]
 blobby = "0.3"
 criterion = "0.5"
-ecdsa-core = { version = "=0.17.0-pre.4", package = "ecdsa", default-features = false, features = ["dev"] }
+ecdsa-core = { version = "=0.17.0-pre.5", package = "ecdsa", default-features = false, features = ["dev"] }
 hex-literal = "0.4"
 primeorder = { version = "=0.14.0-pre.0", features = ["dev"], path = "../primeorder" }
 proptest = "1"
diff --git a/p384/Cargo.toml b/p384/Cargo.toml
index 1bbbeae7..062a3b16 100644
--- a/p384/Cargo.toml
+++ b/p384/Cargo.toml
@@ -17,19 +17,19 @@ edition = "2021"
 rust-version = "1.73"
 
 [dependencies]
-elliptic-curve = { version = "=0.14.0-pre.3", default-features = false, features = ["hazmat", "sec1"] }
+elliptic-curve = { version = "=0.14.0-pre.5", default-features = false, features = ["hazmat", "sec1"] }
 
 # optional dependencies
-ecdsa-core = { version = "=0.17.0-pre.4", package = "ecdsa", optional = true, default-features = false, features = ["der"] }
+ecdsa-core = { version = "=0.17.0-pre.5", package = "ecdsa", optional = true, default-features = false, features = ["der"] }
 hex-literal = { version = "0.4", optional = true }
 primeorder = { version = "=0.14.0-pre.0", optional = true, path = "../primeorder" }
 serdect = { version = "0.2", optional = true, default-features = false }
-sha2 = { version = "=0.11.0-pre.2", optional = true, default-features = false }
+sha2 = { version = "=0.11.0-pre.3", optional = true, default-features = false }
 
 [dev-dependencies]
 blobby = "0.3"
 criterion = "0.5"
-ecdsa-core = { version = "=0.17.0-pre.4", package = "ecdsa", default-features = false, features = ["dev"] }
+ecdsa-core = { version = "=0.17.0-pre.5", package = "ecdsa", default-features = false, features = ["dev"] }
 hex-literal = "0.4"
 primeorder = { version = "=0.14.0-pre.0", features = ["dev"], path = "../primeorder" }
 proptest = "1.4"
diff --git a/p521/Cargo.toml b/p521/Cargo.toml
index 7edbf108..a49fb4fd 100644
--- a/p521/Cargo.toml
+++ b/p521/Cargo.toml
@@ -17,20 +17,20 @@ rust-version = "1.73"
 
 [dependencies]
 base16ct = "0.2"
-elliptic-curve = { version = "=0.14.0-pre.3", default-features = false, features = ["hazmat", "sec1"] }
+elliptic-curve = { version = "=0.14.0-pre.5", default-features = false, features = ["hazmat", "sec1"] }
 
 # optional dependencies
-ecdsa-core = { version = "=0.17.0-pre.4", package = "ecdsa", optional = true, default-features = false, features = ["der"] }
+ecdsa-core = { version = "=0.17.0-pre.5", package = "ecdsa", optional = true, default-features = false, features = ["der"] }
 hex-literal = { version = "0.4", optional = true }
 primefield = { version = "=0.14.0-pre", optional = true, path = "../primefield" }
 primeorder = { version = "=0.14.0-pre.0", optional = true, path = "../primeorder" }
 rand_core = { version = "0.6", optional = true, default-features = false }
 serdect = { version = "0.2", optional = true, default-features = false }
-sha2 = { version = "=0.11.0-pre.2", optional = true, default-features = false }
+sha2 = { version = "=0.11.0-pre.3", optional = true, default-features = false }
 
 [dev-dependencies]
 blobby = "0.3"
-ecdsa-core = { version = "=0.17.0-pre.4", package = "ecdsa", default-features = false, features = ["dev"] }
+ecdsa-core = { version = "=0.17.0-pre.5", package = "ecdsa", default-features = false, features = ["dev"] }
 hex-literal = "0.4"
 primeorder = { version = "=0.14.0-pre.0", features = ["dev"], path = "../primeorder" }
 proptest = "1.4"
diff --git a/primeorder/Cargo.toml b/primeorder/Cargo.toml
index c154d1ac..8339cf05 100644
--- a/primeorder/Cargo.toml
+++ b/primeorder/Cargo.toml
@@ -17,7 +17,7 @@ edition = "2021"
 rust-version = "1.73"
 
 [dependencies]
-elliptic-curve = { version = "=0.14.0-pre.3", default-features = false, features = ["arithmetic", "sec1"] }
+elliptic-curve = { version = "=0.14.0-pre.5", default-features = false, features = ["arithmetic", "sec1"] }
 
 # optional dependencies
 serdect = { version = "0.2", optional = true, default-features = false }
diff --git a/primeorder/src/projective.rs b/primeorder/src/projective.rs
index 729ffe66..806b7afa 100644
--- a/primeorder/src/projective.rs
+++ b/primeorder/src/projective.rs
@@ -410,11 +410,20 @@ where
     }
 }
 
-impl<C> LinearCombination for ProjectivePoint<C>
+impl<C> LinearCombination<[(Self, Scalar<C>)]> for ProjectivePoint<C>
 where
     Self: Double,
     C: PrimeCurveParams,
 {
+    // TODO(tarcieri): optimized implementation
+}
+
+impl<C, const N: usize> LinearCombination<[(Self, Scalar<C>); N]> for ProjectivePoint<C>
+where
+    Self: Double,
+    C: PrimeCurveParams,
+{
+    // TODO(tarcieri): optimized implementation
 }
 
 impl<C> MulByGenerator for ProjectivePoint<C>
diff --git a/sm2/Cargo.toml b/sm2/Cargo.toml
index 3787919b..58e4ed81 100644
--- a/sm2/Cargo.toml
+++ b/sm2/Cargo.toml
@@ -17,14 +17,14 @@ edition = "2021"
 rust-version = "1.73"
 
 [dependencies]
-elliptic-curve = { version = "=0.14.0-pre.3", default-features = false, features = ["hazmat", "sec1"] }
+elliptic-curve = { version = "=0.14.0-pre.5", default-features = false, features = ["hazmat", "sec1"] }
 
 # optional dependencies
 primeorder = { version = "=0.14.0-pre.0", optional = true, path = "../primeorder" }
-rfc6979 = { version = "=0.5.0-pre.2", optional = true }
+rfc6979 = { version = "=0.5.0-pre.3", optional = true }
 serdect = { version = "0.2", optional = true, default-features = false }
-signature = { version = "=2.3.0-pre.2", optional = true, features = ["rand_core"] }
-sm3 = { version = "=0.5.0-pre.2", optional = true, default-features = false }
+signature = { version = "=2.3.0-pre.3", optional = true, features = ["rand_core"] }
+sm3 = { version = "=0.5.0-pre.3", optional = true, default-features = false }
 
 [dev-dependencies]
 hex-literal = "0.4"
diff --git a/sm2/src/dsa/verifying.rs b/sm2/src/dsa/verifying.rs
index 12fd2c84..9c6e824c 100644
--- a/sm2/src/dsa/verifying.rs
+++ b/sm2/src/dsa/verifying.rs
@@ -149,12 +149,10 @@ impl PrehashVerifier<Signature> for VerifyingKey {
         }
 
         // B6: calculate the point (x1', y1')=[s']G + [t]PA
-        let x = ProjectivePoint::lincomb(
-            &ProjectivePoint::generator(),
-            &s,
-            &ProjectivePoint::from(&self.public_key),
-            &t,
-        )
+        let x = ProjectivePoint::lincomb(&[
+            (ProjectivePoint::generator(), *s),
+            (ProjectivePoint::from(&self.public_key), t),
+        ])
         .to_affine()
         .x();