From a27a93073b2ce6101ee6fb2d39aea6333ed7f954 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 17 Nov 2021 14:25:51 -0700 Subject: [PATCH] ecdsa: remove `NormalizeLow` trait The available curve arithmetic is now expressive enough that it's possible to implement `Signature::normalize_s` generically for all curves with a `ScalarArithmetic` backend. Because of that, we no longer need a special "helper trait" for this purpose, and so `NormalizeLow` can be removed. --- Cargo.lock | 8 ++++---- ecdsa/src/lib.rs | 37 ++++++++++++------------------------- 2 files changed, 16 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ba02b52c..68ee60b4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -87,9 +87,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "476ecdba12db8402a1664482de8c37fff7dc96241258bd0de1f0d70e760a45fd" +checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" dependencies = [ "generic-array", "rand_core 0.6.3", @@ -221,9 +221,9 @@ dependencies = [ [[package]] name = "elliptic-curve" version = "0.11.0-pre" -source = "git+https://github.com/RustCrypto/traits.git#31436a2eaf8bd3fb5292e11e9a0b1f93056a7817" +source = "git+https://github.com/RustCrypto/traits.git#f484ed6326282dc834451ae5a51cda4e60f275bf" dependencies = [ - "crypto-bigint 0.3.0", + "crypto-bigint 0.3.2", "der 0.5.1", "ff", "generic-array", diff --git a/ecdsa/src/lib.rs b/ecdsa/src/lib.rs index e8a153cf..b2698ff8 100644 --- a/ecdsa/src/lib.rs +++ b/ecdsa/src/lib.rs @@ -106,7 +106,7 @@ use elliptic_curve::{ }; #[cfg(feature = "arithmetic")] -use elliptic_curve::{group::ff::PrimeField, NonZeroScalar, ProjectiveArithmetic, Scalar}; +use elliptic_curve::{ff::PrimeField, IsHigh, NonZeroScalar, ScalarArithmetic}; /// Size of a fixed sized signature for the given elliptic curve. pub type SignatureSize = as Add>::Output; @@ -184,7 +184,7 @@ where #[cfg_attr(docsrs, doc(cfg(feature = "arithmetic")))] impl Signature where - C: PrimeCurve + ProjectiveArithmetic, + C: PrimeCurve + ScalarArithmetic, SignatureSize: ArrayLength, { /// Get the `r` component of this signature @@ -208,15 +208,17 @@ where /// [BIP 0062: Dealing with Malleability][1]. /// /// [1]: https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki - pub fn normalize_s(&self) -> Option - where - Scalar: NormalizeLow, - { - self.s().normalize_low().map(|s_low| { + pub fn normalize_s(&self) -> Option { + let s = self.s(); + + if s.is_high().into() { + let neg_s = -s; let mut result = self.clone(); - result.bytes[C::UInt::BYTE_SIZE..].copy_from_slice(&s_low.to_repr()); - result - }) + result.bytes[C::UInt::BYTE_SIZE..].copy_from_slice(&neg_s.to_repr()); + Some(result) + } else { + None + } } } @@ -288,18 +290,3 @@ where }) } } - -/// Normalize a scalar (i.e. ECDSA S) to the lower half the field, as described -/// in [BIP 0062: Dealing with Malleability][1]. -/// -/// [1]: https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki -pub trait NormalizeLow: Sized { - /// Normalize scalar to the lower half of the field (i.e. negate it if it's - /// larger than half the curve's order). - /// - /// Returns an `Option` with a new scalar if the original wasn't already - /// low-normalized. - /// - /// May be implemented to work in variable time. - fn normalize_low(&self) -> Option; -}