From aa8d8731da6f8dde3ec2130330f753b0c10f32be Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 17 Jan 2024 18:20:31 -0700 Subject: [PATCH] ecdsa: remove `SignPrimitive`/`VerifyPrimitive` traits These were removed upstream in RustCrypto/signatures#793. The ECDSA implementation is fully generic now. These traits were originally for per-curve implementations, but those are no-longer needed. The upstream implementation now has native support for low-S normalization by way of `EcdsaCurve::NORMALIZE_S`. --- Cargo.lock | 4 +- k256/benches/ecdsa.rs | 55 ++++++++++++--------------- k256/src/ecdsa.rs | 86 ------------------------------------------- p192/src/ecdsa.rs | 6 --- p224/src/ecdsa.rs | 12 ------ p256/src/ecdsa.rs | 34 +---------------- p384/src/ecdsa.rs | 12 ------ p521/src/ecdsa.rs | 12 ------ 8 files changed, 27 insertions(+), 194 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 83e667e4..e1d02282 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -363,7 +363,7 @@ dependencies = [ [[package]] name = "ecdsa" version = "0.17.0-pre.3" -source = "git+https://github.com/rustcrypto/signatures.git#56b8b7acdf6d76291f8cbff56241fb15063befd3" +source = "git+https://github.com/rustcrypto/signatures.git#3ed9867409ddb392ddc6787168ca32150a897161" dependencies = [ "der", "digest", @@ -1033,7 +1033,7 @@ dependencies = [ [[package]] name = "rfc6979" version = "0.5.0-pre.2" -source = "git+https://github.com/rustcrypto/signatures.git#56b8b7acdf6d76291f8cbff56241fb15063befd3" +source = "git+https://github.com/rustcrypto/signatures.git#3ed9867409ddb392ddc6787168ca32150a897161" dependencies = [ "hmac", "subtle", diff --git a/k256/benches/ecdsa.rs b/k256/benches/ecdsa.rs index 572d42b8..8a098267 100644 --- a/k256/benches/ecdsa.rs +++ b/k256/benches/ecdsa.rs @@ -1,32 +1,26 @@ //! secp256k1 scalar arithmetic benchmarks use criterion::{black_box, criterion_group, criterion_main, Criterion}; -use ecdsa_core::{ - elliptic_curve::group::prime::PrimeCurveAffine, - hazmat::{SignPrimitive, VerifyPrimitive}, +use k256::{ + ecdsa::{ + signature::hazmat::{PrehashSigner, PrehashVerifier}, + Signature, SigningKey, + }, + elliptic_curve::group::ff::PrimeField, + FieldBytes, NonZeroScalar, Scalar, }; -use k256::{elliptic_curve::group::ff::PrimeField, AffinePoint, FieldBytes, Scalar}; -fn test_scalar_d() -> Scalar { - Scalar::from_repr( - [ - 0xbb, 0x48, 0x8a, 0xef, 0x41, 0x6a, 0x41, 0xd7, 0x68, 0x0d, 0x1c, 0xf0, 0x1d, 0x70, - 0xf5, 0x9b, 0x60, 0xd7, 0xf5, 0xf7, 0x7e, 0x30, 0xe7, 0x8b, 0x8b, 0xf9, 0xd2, 0xd8, - 0x82, 0xf1, 0x56, 0xa6, - ] - .into(), - ) - .unwrap() -} - -fn test_scalar_k() -> Scalar { - Scalar::from_repr( - [ - 0x67, 0xe2, 0xf6, 0x80, 0x71, 0xed, 0x82, 0x81, 0xe8, 0xae, 0xd6, 0xbc, 0xf1, 0xc5, - 0x20, 0x7c, 0x5e, 0x63, 0x37, 0x22, 0xd9, 0x20, 0xaf, 0xd6, 0xae, 0x22, 0xd0, 0x6e, - 0xeb, 0x80, 0x35, 0xe3, - ] - .into(), +fn test_scalar_d() -> NonZeroScalar { + NonZeroScalar::new( + Scalar::from_repr( + [ + 0xbb, 0x48, 0x8a, 0xef, 0x41, 0x6a, 0x41, 0xd7, 0x68, 0x0d, 0x1c, 0xf0, 0x1d, 0x70, + 0xf5, 0x9b, 0x60, 0xd7, 0xf5, 0xf7, 0x7e, 0x30, 0xe7, 0x8b, 0x8b, 0xf9, 0xd2, 0xd8, + 0x82, 0xf1, 0x56, 0xa6, + ] + .into(), + ) + .unwrap(), ) .unwrap() } @@ -43,25 +37,22 @@ fn test_scalar_z() -> FieldBytes { fn bench_ecdsa(c: &mut Criterion) { let mut group = c.benchmark_group("ecdsa"); - let d = test_scalar_d(); - let k = test_scalar_k(); + let d = SigningKey::from(test_scalar_d()); let z = test_scalar_z(); group.bench_function("try_sign_prehashed", |b| { b.iter(|| { - black_box(d) - .try_sign_prehashed(black_box(k), &black_box(z)) - .unwrap() + let _: Signature = black_box(&d).sign_prehash(&black_box(z)).unwrap(); }) }); - let q = (AffinePoint::generator() * d).to_affine(); - let s = d.try_sign_prehashed(k, &z).unwrap().0; + let q = d.verifying_key(); + let s: Signature = d.sign_prehash(&z).unwrap(); group.bench_function("verify_prehashed", |b| { b.iter(|| { black_box(q) - .verify_prehashed(&black_box(z), &black_box(s)) + .verify_prehash(&black_box(z), &black_box(s)) .unwrap() }) }); diff --git a/k256/src/ecdsa.rs b/k256/src/ecdsa.rs index bef73828..f6d894e6 100644 --- a/k256/src/ecdsa.rs +++ b/k256/src/ecdsa.rs @@ -58,56 +58,6 @@ //! //! One common application of signature recovery with secp256k1 is Ethereum. //! -//! ### Upgrading recoverable signature code from earlier versions of `k256` -//! -//! The v0.12 release of `k256` contains a brand new recoverable signature API -//! from previous releases. Functionality has been upstreamed from `k256` to a -//! generic implementation in the [`ecdsa`](`ecdsa_core`) crate. -//! -//! If you previously used `k256::ecdsa::recoverable::Signature`, the old -//! functionality now uses a "detached" [`Signature`] and [`RecoveryId`]. -//! Here is where the various functionality went: -//! -//! - Signing now requires the use of the [`hazmat::SignPrimitive`] trait -//! (see examples immediately below). -//! - Signature recovery is now implemented as methods of the [`VerifyingKey`] -//! type (i.e. `::recover_from_*`). -//! - Trial recovery is now defined on the [`RecoveryId`] type -//! (i.e. `::trial_recovery_from_*`). -//! -//! ### Computing a signature with a [`RecoveryId`]. -//! -//! This example shows how to compute a signature and its associated -//! [`RecoveryId`] in a manner which is byte-for-byte compatible with -//! Ethereum libraries, leveraging the [`SigningKey::sign_digest_recoverable`] -//! API: -//! -#![cfg_attr(feature = "std", doc = "```")] -#![cfg_attr(not(feature = "std"), doc = "```ignore")] -//! # fn main() -> Result<(), Box> { -//! use hex_literal::hex; -//! use k256::ecdsa::{hazmat::SignPrimitive, RecoveryId, Signature, SigningKey}; -//! use sha2::Sha256; -//! use sha3::{Keccak256, Digest}; -//! -//! let signing_key = SigningKey::from_bytes(&hex!( -//! "4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318" -//! ).into())?; -//! -//! let msg = hex!("e9808504e3b29200831e848094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca0080018080"); -//! let digest = Keccak256::new_with_prefix(msg); -//! let (signature, recid) = signing_key.sign_digest_recoverable(digest)?; -//! -//! assert_eq!( -//! signature.to_bytes().as_slice(), -//! &hex!("c9cf86333bcb065d140032ecaab5d9281bde80f21b9687b3e94161de42d51895727a108a0b8d101465414033c3f705a9c7b826e596766046ee1183dbc8aeaa68") -//! ); -//! -//! assert_eq!(recid, RecoveryId::try_from(0u8).unwrap()); -//! # Ok(()) -//! # } -//! ``` -//! //! ### Recovering a [`VerifyingKey`] from a signature //! #![cfg_attr(feature = "std", doc = "```")] @@ -152,13 +102,6 @@ pub use ecdsa_core::hazmat; use crate::Secp256k1; -#[cfg(feature = "ecdsa")] -use { - crate::{AffinePoint, FieldBytes, Scalar}, - ecdsa_core::hazmat::{SignPrimitive, VerifyPrimitive}, - elliptic_curve::{ops::Invert, scalar::IsHigh, subtle::CtOption}, -}; - /// ECDSA/secp256k1 signature (fixed-size) pub type Signature = ecdsa_core::Signature; @@ -182,35 +125,6 @@ impl hazmat::DigestPrimitive for Secp256k1 { type Digest = sha2::Sha256; } -#[cfg(feature = "ecdsa")] -impl SignPrimitive for Scalar { - #[allow(non_snake_case, clippy::many_single_char_names)] - fn try_sign_prehashed( - &self, - k: K, - z: &FieldBytes, - ) -> Result<(Signature, Option), Error> - where - K: AsRef + Invert>, - { - let (sig, recid) = hazmat::sign_prehashed::(self, k, z)?; - let is_y_odd = recid.is_y_odd() ^ bool::from(sig.s().is_high()); - let recid = RecoveryId::new(is_y_odd, recid.is_x_reduced()); - Ok((sig.normalize_s(), Some(recid))) - } -} - -#[cfg(feature = "ecdsa")] -impl VerifyPrimitive for AffinePoint { - fn verify_prehashed(&self, z: &FieldBytes, sig: &Signature) -> Result<(), Error> { - if sig.s().is_high().into() { - return Err(Error::new()); - } - - hazmat::verify_prehashed(&self.into(), z, sig) - } -} - #[cfg(all(test, feature = "ecdsa", feature = "arithmetic"))] mod tests { mod normalize { diff --git a/p192/src/ecdsa.rs b/p192/src/ecdsa.rs index bd88fe23..666022fd 100644 --- a/p192/src/ecdsa.rs +++ b/p192/src/ecdsa.rs @@ -36,9 +36,6 @@ pub use ecdsa_core::signature::{self, Error}; use super::NistP192; use ecdsa_core::EcdsaCurve; -#[cfg(feature = "ecdsa")] -use {crate::AffinePoint, ecdsa_core::hazmat::VerifyPrimitive}; - /// ECDSA/P-192 signature (fixed-size) pub type Signature = ecdsa_core::Signature; @@ -53,9 +50,6 @@ impl EcdsaCurve for NistP192 { #[cfg(feature = "ecdsa")] pub type VerifyingKey = ecdsa_core::VerifyingKey; -#[cfg(feature = "ecdsa")] -impl VerifyPrimitive for AffinePoint {} - #[cfg(all(test, feature = "ecdsa"))] mod tests { mod verify { diff --git a/p224/src/ecdsa.rs b/p224/src/ecdsa.rs index 6a776f37..4b978315 100644 --- a/p224/src/ecdsa.rs +++ b/p224/src/ecdsa.rs @@ -42,12 +42,6 @@ pub use ecdsa_core::signature::{self, Error}; use super::NistP224; use ecdsa_core::EcdsaCurve; -#[cfg(feature = "ecdsa")] -use { - crate::{AffinePoint, Scalar}, - ecdsa_core::hazmat::{SignPrimitive, VerifyPrimitive}, -}; - /// ECDSA/P-224 signature (fixed-size) pub type Signature = ecdsa_core::Signature; @@ -71,12 +65,6 @@ impl ecdsa_core::hazmat::DigestPrimitive for NistP224 { type Digest = sha2::Sha224; } -#[cfg(feature = "ecdsa")] -impl SignPrimitive for Scalar {} - -#[cfg(feature = "ecdsa")] -impl VerifyPrimitive for AffinePoint {} - #[cfg(all(test, feature = "ecdsa"))] mod tests { use crate::ecdsa::{signature::Signer, Signature, SigningKey}; diff --git a/p256/src/ecdsa.rs b/p256/src/ecdsa.rs index 1b150c25..b396c68f 100644 --- a/p256/src/ecdsa.rs +++ b/p256/src/ecdsa.rs @@ -44,12 +44,6 @@ pub use ecdsa_core::signature::{self, Error}; use super::NistP256; use ecdsa_core::EcdsaCurve; -#[cfg(feature = "ecdsa")] -use { - crate::{AffinePoint, Scalar}, - ecdsa_core::hazmat::{SignPrimitive, VerifyPrimitive}, -}; - /// ECDSA/P-256 signature (fixed-size) pub type Signature = ecdsa_core::Signature; @@ -72,13 +66,6 @@ pub type VerifyingKey = ecdsa_core::VerifyingKey; impl ecdsa_core::hazmat::DigestPrimitive for NistP256 { type Digest = sha2::Sha256; } - -#[cfg(feature = "ecdsa")] -impl SignPrimitive for Scalar {} - -#[cfg(feature = "ecdsa")] -impl VerifyPrimitive for AffinePoint {} - #[cfg(all(test, feature = "ecdsa"))] mod tests { use crate::{ @@ -87,13 +74,9 @@ mod tests { signature::Signer, Signature, SigningKey, VerifyingKey, }, - test_vectors::ecdsa::ECDSA_TEST_VECTORS, - AffinePoint, BlindedScalar, EncodedPoint, Scalar, - }; - use ecdsa_core::hazmat::SignPrimitive; - use elliptic_curve::{ - array::Array, group::ff::PrimeField, rand_core::OsRng, sec1::FromEncodedPoint, + AffinePoint, EncodedPoint, }; + use elliptic_curve::{array::Array, sec1::FromEncodedPoint}; use hex_literal::hex; use sha2::Digest; @@ -172,19 +155,6 @@ mod tests { assert!(result.is_ok()); } - #[test] - fn scalar_blinding() { - let vector = &ECDSA_TEST_VECTORS[0]; - let d = Scalar::from_repr(Array::clone_from_slice(vector.d)).unwrap(); - let k = Scalar::from_repr(Array::clone_from_slice(vector.k)).unwrap(); - let k_blinded = BlindedScalar::new(k, &mut OsRng); - let z = Array::clone_from_slice(vector.m); - let sig = d.try_sign_prehashed(k_blinded, &z).unwrap().0; - - assert_eq!(vector.r, sig.r().to_bytes().as_slice()); - assert_eq!(vector.s, sig.s().to_bytes().as_slice()); - } - mod sign { use crate::{test_vectors::ecdsa::ECDSA_TEST_VECTORS, NistP256}; ecdsa_core::new_signing_test!(NistP256, ECDSA_TEST_VECTORS); diff --git a/p384/src/ecdsa.rs b/p384/src/ecdsa.rs index 078c80c2..a6854bb8 100644 --- a/p384/src/ecdsa.rs +++ b/p384/src/ecdsa.rs @@ -42,12 +42,6 @@ pub use ecdsa_core::signature::{self, Error}; use super::NistP384; use ecdsa_core::EcdsaCurve; -#[cfg(feature = "ecdsa")] -use { - crate::{AffinePoint, Scalar}, - ecdsa_core::hazmat::{SignPrimitive, VerifyPrimitive}, -}; - /// ECDSA/P-384 signature (fixed-size) pub type Signature = ecdsa_core::Signature; @@ -71,12 +65,6 @@ impl ecdsa_core::hazmat::DigestPrimitive for NistP384 { type Digest = sha2::Sha384; } -#[cfg(feature = "ecdsa")] -impl SignPrimitive for Scalar {} - -#[cfg(feature = "ecdsa")] -impl VerifyPrimitive for AffinePoint {} - #[cfg(all(test, feature = "ecdsa"))] mod tests { use crate::{ diff --git a/p521/src/ecdsa.rs b/p521/src/ecdsa.rs index 9719202f..5ef9493d 100644 --- a/p521/src/ecdsa.rs +++ b/p521/src/ecdsa.rs @@ -42,12 +42,6 @@ pub use ecdsa_core::signature::{self, Error}; use super::NistP521; use ecdsa_core::EcdsaCurve; -#[cfg(feature = "ecdsa")] -use { - crate::{AffinePoint, Scalar}, - ecdsa_core::hazmat::{SignPrimitive, VerifyPrimitive}, -}; - /// ECDSA/P-521 signature (fixed-size) pub type Signature = ecdsa_core::Signature; @@ -71,12 +65,6 @@ impl ecdsa_core::hazmat::DigestPrimitive for NistP521 { type Digest = sha2::Sha512; } -#[cfg(feature = "ecdsa")] -impl SignPrimitive for Scalar {} - -#[cfg(feature = "ecdsa")] -impl VerifyPrimitive for AffinePoint {} - #[cfg(all(test, feature = "ecdsa"))] mod tests { use crate::ecdsa::{signature::Signer, Signature, SigningKey};