From b8bf18098df482ab44da01951e31c7fd9bb21364 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 4 Dec 2021 12:17:36 -0700 Subject: [PATCH] k256+p256: use revised `LinearCombination` trait See RustCrypto/traits#835 --- Cargo.lock | 8 ++++---- k256/Cargo.toml | 2 +- k256/bench/scalar.rs | 4 ++-- k256/src/arithmetic/mul.rs | 18 ++++++------------ k256/src/ecdsa/recoverable.rs | 24 ++++++++++++------------ k256/src/ecdsa/verify.rs | 2 +- p256/Cargo.toml | 2 +- p256/src/arithmetic.rs | 4 ---- p256/src/arithmetic/projective.rs | 3 +++ 9 files changed, 30 insertions(+), 37 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 80824f60..47920edf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -310,9 +310,9 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c53b3bbf1444521719a1d36fb4aaac127522cd7bc8f2a6556b705cf81103a0a8" +checksum = "e91ae02c7618ee05108cd86a0be2f5586d1f0d965bede7ecfd46815f1b860227" dependencies = [ "der", "elliptic-curve", @@ -328,9 +328,9 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "elliptic-curve" -version = "0.11.4" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9be7b065e66163fd97787a4cadc56625f948e22e914a0deab1d22b1f48fde25" +checksum = "1f01ff20862362c34074072c8be2de97399633d6b1d2114afa56bf77a8b7f0a4" dependencies = [ "base64ct", "crypto-bigint", diff --git a/k256/Cargo.toml b/k256/Cargo.toml index 5dbb338c..eda2388a 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.4", default-features = false, features = ["hazmat", "sec1"] } +elliptic-curve = { version = "0.11.5", default-features = false, features = ["hazmat", "sec1"] } sec1 = { version = "0.2", default-features = false } # optional dependencies diff --git a/k256/bench/scalar.rs b/k256/bench/scalar.rs index e84cfa41..5f5abe49 100644 --- a/k256/bench/scalar.rs +++ b/k256/bench/scalar.rs @@ -6,7 +6,7 @@ use criterion::{ use hex_literal::hex; use k256::{ elliptic_curve::{generic_array::arr, group::ff::PrimeField, ops::LinearCombination}, - ProjectivePoint, Scalar, Secp256k1, + ProjectivePoint, Scalar, }; fn test_scalar_x() -> Scalar { @@ -40,7 +40,7 @@ fn bench_point_lincomb<'a, M: Measurement>(group: &mut BenchmarkGroup<'a, M>) { let s = Scalar::from_repr(m.into()).unwrap(); group.bench_function("lincomb via mul+add", |b| b.iter(|| &p * &s + &p * &s)); group.bench_function("lincomb()", |b| { - b.iter(|| Secp256k1::lincomb(&p, &s, &p, &s)) + b.iter(|| ProjectivePoint::lincomb(&p, &s, &p, &s)) }); } diff --git a/k256/src/arithmetic/mul.rs b/k256/src/arithmetic/mul.rs index 732d5056..d9fc4405 100644 --- a/k256/src/arithmetic/mul.rs +++ b/k256/src/arithmetic/mul.rs @@ -65,12 +65,9 @@ //! 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, - }, - Secp256k1, +use crate::arithmetic::{ + scalar::{Scalar, WideScalar}, + ProjectivePoint, }; use core::ops::{Mul, MulAssign}; use elliptic_curve::{ @@ -305,7 +302,7 @@ fn mul(x: &ProjectivePoint, k: &Scalar) -> ProjectivePoint { lincomb_generic(&[*x], &[*k]) } -impl LinearCombination for Secp256k1 { +impl LinearCombination for ProjectivePoint { fn lincomb( x: &ProjectivePoint, k: &Scalar, @@ -354,10 +351,7 @@ impl MulAssign<&Scalar> for ProjectivePoint { #[cfg(test)] mod tests { - use crate::{ - arithmetic::{ProjectivePoint, Scalar}, - Secp256k1, - }; + use crate::arithmetic::{ProjectivePoint, Scalar}; use elliptic_curve::{ops::LinearCombination, rand_core::OsRng, Field, Group}; #[test] @@ -368,7 +362,7 @@ mod tests { let l = Scalar::random(&mut OsRng); let reference = &x * &k + &y * &l; - let test = Secp256k1::lincomb(&x, &k, &y, &l); + let test = ProjectivePoint::lincomb(&x, &k, &y, &l); assert_eq!(reference, test); } } diff --git a/k256/src/ecdsa/recoverable.rs b/k256/src/ecdsa/recoverable.rs index 861ee075..ff494357 100644 --- a/k256/src/ecdsa/recoverable.rs +++ b/k256/src/ecdsa/recoverable.rs @@ -51,7 +51,7 @@ use crate::{ ops::{Invert, LinearCombination, Reduce}, DecompressPoint, }, - AffinePoint, FieldBytes, NonZeroScalar, ProjectivePoint, Scalar, Secp256k1, + AffinePoint, FieldBytes, NonZeroScalar, ProjectivePoint, Scalar, }; #[cfg(feature = "keccak256")] @@ -176,18 +176,18 @@ impl Signature { let z = >::from_be_bytes_reduced(*digest_bytes); let R = AffinePoint::decompress(&r.to_bytes(), self.recovery_id().is_y_odd()); - if R.is_some().into() { - let R = ProjectivePoint::from(R.unwrap()); - let r_inv = r.invert().unwrap(); - let u1 = -(r_inv * z); - let u2 = r_inv * *s; - let pk = Secp256k1::lincomb(&ProjectivePoint::generator(), &u1, &R, &u2).to_affine(); - - // TODO(tarcieri): ensure the signature verifies? - Ok(VerifyingKey::from(&pk)) - } else { - Err(Error::new()) + if R.is_none().into() { + return Err(Error::new()); } + + let R = ProjectivePoint::from(R.unwrap()); + let r_inv = r.invert().unwrap(); + let u1 = -(r_inv * z); + let u2 = r_inv * *s; + let pk = ProjectivePoint::lincomb(&ProjectivePoint::generator(), &u1, &R, &u2).to_affine(); + + // TODO(tarcieri): ensure the signature verifies? + Ok(VerifyingKey::from(&pk)) } /// Parse the `r` component of this signature to a [`NonZeroScalar`] diff --git a/k256/src/ecdsa/verify.rs b/k256/src/ecdsa/verify.rs index b0a35545..3bed0571 100644 --- a/k256/src/ecdsa/verify.rs +++ b/k256/src/ecdsa/verify.rs @@ -110,7 +110,7 @@ impl VerifyPrimitive for AffinePoint { let u1 = z * s_inv; let u2 = *r * s_inv; - let x = Secp256k1::lincomb( + let x = ProjectivePoint::lincomb( &ProjectivePoint::generator(), &u1, &ProjectivePoint::from(*self), diff --git a/p256/Cargo.toml b/p256/Cargo.toml index 77ad524e..b779bf51 100644 --- a/p256/Cargo.toml +++ b/p256/Cargo.toml @@ -17,7 +17,7 @@ edition = "2021" rust-version = "1.56" [dependencies] -elliptic-curve = { version = "0.11", default-features = false, features = ["hazmat", "sec1"] } +elliptic-curve = { version = "0.11.5", default-features = false, features = ["hazmat", "sec1"] } sec1 = { version = "0.2", default-features = false } # optional dependencies diff --git a/p256/src/arithmetic.rs b/p256/src/arithmetic.rs index bd986558..9a89d08b 100644 --- a/p256/src/arithmetic.rs +++ b/p256/src/arithmetic.rs @@ -6,9 +6,7 @@ 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; @@ -27,8 +25,6 @@ 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}; diff --git a/p256/src/arithmetic/projective.rs b/p256/src/arithmetic/projective.rs index 81b1354c..6ab5a3b7 100644 --- a/p256/src/arithmetic/projective.rs +++ b/p256/src/arithmetic/projective.rs @@ -13,6 +13,7 @@ use elliptic_curve::{ prime::{PrimeCurve, PrimeCurveAffine, PrimeGroup}, Curve, Group, GroupEncoding, }, + ops::LinearCombination, rand_core::RngCore, sec1::{FromEncodedPoint, ToEncodedPoint}, subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}, @@ -93,6 +94,8 @@ impl PrimeCurve for ProjectivePoint { type Affine = AffinePoint; } +impl LinearCombination for ProjectivePoint {} + impl From for ProjectivePoint { fn from(p: AffinePoint) -> Self { let projective = ProjectivePoint {