diff --git a/Cargo.lock b/Cargo.lock index 6cf4ab9b9..a76461658 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -328,9 +328,9 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "elliptic-curve" -version = "0.11.3" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c4c31bb557a73d165c838b614521f888112f9d4fcff7421d35646376dd17caf" +checksum = "d9be7b065e66163fd97787a4cadc56625f948e22e914a0deab1d22b1f48fde25" dependencies = [ "base64ct", "crypto-bigint", diff --git a/k256/Cargo.toml b/k256/Cargo.toml index 6c45b5626..5dbb338c4 100644 --- a/k256/Cargo.toml +++ b/k256/Cargo.toml @@ -19,7 +19,7 @@ rust-version = "1.56" [dependencies] cfg-if = "1.0" -elliptic-curve = { version = "0.11.3", default-features = false, features = ["hazmat", "sec1"] } +elliptic-curve = { version = "0.11.4", default-features = false, features = ["hazmat", "sec1"] } sec1 = { version = "0.2", default-features = false } # optional dependencies diff --git a/k256/src/arithmetic.rs b/k256/src/arithmetic.rs index 0163e2bd8..152c73fcc 100644 --- a/k256/src/arithmetic.rs +++ b/k256/src/arithmetic.rs @@ -10,7 +10,6 @@ pub(crate) mod scalar; mod dev; pub use field::FieldElement; -pub use mul::lincomb; use affine::AffinePoint; use projective::ProjectivePoint; diff --git a/k256/src/arithmetic/mul.rs b/k256/src/arithmetic/mul.rs index 331f2e7c0..732d50566 100644 --- a/k256/src/arithmetic/mul.rs +++ b/k256/src/arithmetic/mul.rs @@ -65,12 +65,16 @@ //! In experiments, I was not able to detect any case where they would go outside the 128 bit bound, //! but I cannot be sure that it cannot happen. -use crate::arithmetic::{ - scalar::{Scalar, WideScalar}, - ProjectivePoint, +use crate::{ + arithmetic::{ + scalar::{Scalar, WideScalar}, + ProjectivePoint, + }, + Secp256k1, }; use core::ops::{Mul, MulAssign}; use elliptic_curve::{ + ops::LinearCombination, subtle::{Choice, ConditionallySelectable, ConstantTimeEq}, IsHigh, }; @@ -301,14 +305,15 @@ fn mul(x: &ProjectivePoint, k: &Scalar) -> ProjectivePoint { lincomb_generic(&[*x], &[*k]) } -/// Calculates `x * k + y * l`. -pub fn lincomb( - x: &ProjectivePoint, - k: &Scalar, - y: &ProjectivePoint, - l: &Scalar, -) -> ProjectivePoint { - lincomb_generic(&[*x, *y], &[*k, *l]) +impl LinearCombination for Secp256k1 { + fn lincomb( + x: &ProjectivePoint, + k: &Scalar, + y: &ProjectivePoint, + l: &Scalar, + ) -> ProjectivePoint { + lincomb_generic(&[*x, *y], &[*k, *l]) + } } impl Mul for ProjectivePoint { @@ -349,10 +354,11 @@ impl MulAssign<&Scalar> for ProjectivePoint { #[cfg(test)] mod tests { - use super::lincomb; - use crate::arithmetic::{ProjectivePoint, Scalar}; - use elliptic_curve::rand_core::OsRng; - use elliptic_curve::{Field, Group}; + use crate::{ + arithmetic::{ProjectivePoint, Scalar}, + Secp256k1, + }; + use elliptic_curve::{ops::LinearCombination, rand_core::OsRng, Field, Group}; #[test] fn test_lincomb() { @@ -362,7 +368,7 @@ mod tests { let l = Scalar::random(&mut OsRng); let reference = &x * &k + &y * &l; - let test = lincomb(&x, &k, &y, &l); + let test = Secp256k1::lincomb(&x, &k, &y, &l); assert_eq!(reference, test); } } diff --git a/k256/src/ecdsa/recoverable.rs b/k256/src/ecdsa/recoverable.rs index cf3de0653..861ee075a 100644 --- a/k256/src/ecdsa/recoverable.rs +++ b/k256/src/ecdsa/recoverable.rs @@ -48,10 +48,10 @@ use crate::{ elliptic_curve::{ bigint::U256, consts::U32, - ops::{Invert, Reduce}, + ops::{Invert, LinearCombination, Reduce}, DecompressPoint, }, - lincomb, AffinePoint, FieldBytes, NonZeroScalar, ProjectivePoint, Scalar, + AffinePoint, FieldBytes, NonZeroScalar, ProjectivePoint, Scalar, Secp256k1, }; #[cfg(feature = "keccak256")] @@ -181,7 +181,7 @@ impl Signature { let r_inv = r.invert().unwrap(); let u1 = -(r_inv * z); let u2 = r_inv * *s; - let pk = lincomb(&ProjectivePoint::generator(), &u1, &R, &u2).to_affine(); + let pk = Secp256k1::lincomb(&ProjectivePoint::generator(), &u1, &R, &u2).to_affine(); // TODO(tarcieri): ensure the signature verifies? Ok(VerifyingKey::from(&pk)) diff --git a/k256/src/ecdsa/verify.rs b/k256/src/ecdsa/verify.rs index 4657646d7..b0a35545a 100644 --- a/k256/src/ecdsa/verify.rs +++ b/k256/src/ecdsa/verify.rs @@ -2,14 +2,13 @@ use super::{recoverable, Error, Signature}; use crate::{ - lincomb, AffinePoint, CompressedPoint, EncodedPoint, ProjectivePoint, PublicKey, Scalar, - Secp256k1, + AffinePoint, CompressedPoint, EncodedPoint, ProjectivePoint, PublicKey, Scalar, Secp256k1, }; use ecdsa_core::{hazmat::VerifyPrimitive, signature}; use elliptic_curve::{ bigint::U256, consts::U32, - ops::{Invert, Reduce}, + ops::{Invert, LinearCombination, Reduce}, sec1::ToEncodedPoint, IsHigh, }; @@ -111,7 +110,7 @@ impl VerifyPrimitive for AffinePoint { let u1 = z * s_inv; let u2 = *r * s_inv; - let x = lincomb( + let x = Secp256k1::lincomb( &ProjectivePoint::generator(), &u1, &ProjectivePoint::from(*self), diff --git a/k256/src/lib.rs b/k256/src/lib.rs index 8147e8518..d0c7abd74 100644 --- a/k256/src/lib.rs +++ b/k256/src/lib.rs @@ -39,7 +39,7 @@ pub mod test_vectors; pub use elliptic_curve::{self, bigint::U256}; #[cfg(feature = "arithmetic")] -pub use arithmetic::{affine::AffinePoint, lincomb, projective::ProjectivePoint, scalar::Scalar}; +pub use arithmetic::{affine::AffinePoint, projective::ProjectivePoint, scalar::Scalar}; #[cfg(feature = "expose-field")] pub use arithmetic::FieldElement; diff --git a/p256/src/arithmetic.rs b/p256/src/arithmetic.rs index 87c42b3d0..bd9865588 100644 --- a/p256/src/arithmetic.rs +++ b/p256/src/arithmetic.rs @@ -1,4 +1,4 @@ -//! A pure-Rust implementation of group operations on secp256r1. +//! Pure Rust implementation of group operations on secp256r1. pub(crate) mod affine; mod field; @@ -6,7 +6,9 @@ pub(crate) mod projective; pub(crate) mod scalar; pub(crate) mod util; +use crate::NistP256; use affine::AffinePoint; +use elliptic_curve::ops::LinearCombination; use field::{FieldElement, MODULUS}; use projective::ProjectivePoint; use scalar::Scalar; @@ -25,6 +27,8 @@ const CURVE_EQUATION_B: FieldElement = FieldElement([ 0xdc30_061d_0487_4834, ]); +impl LinearCombination for NistP256 {} + #[cfg(test)] mod tests { use super::{CURVE_EQUATION_A, CURVE_EQUATION_B};