From d23e05e3252aa9a10404a23453fe73ad32419b61 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 27 Sep 2020 08:46:11 -0700 Subject: [PATCH] Revert "ecdsa: remove RecoverableSignPrimitive" This reverts commit a03cda2372b3d931f44db2c65634c89441e9204c (#146) Revives `RecoverableSignPrimitive` since there have been some requests/use cases for it. First, there was interest in supporting such a primitive for `p256`: https://github.com/RustCrypto/elliptic-curves/pull/184 Second, it would be helpful for Ethereum, since it seems implementations often use (HMAC-DRBG-)SHA-256 for RFC6979, but Keccak256 as the message digest function. Exposing this interface would allow for such combinations which aren't possible otherwise. --- ecdsa/src/hazmat.rs | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/ecdsa/src/hazmat.rs b/ecdsa/src/hazmat.rs index 7c5b7832..82560fc6 100644 --- a/ecdsa/src/hazmat.rs +++ b/ecdsa/src/hazmat.rs @@ -58,6 +58,45 @@ where ) -> Result, Error>; } +/// [`SignPrimitive`] for signature implementations that can provide public key +/// recovery implementation. +pub trait RecoverableSignPrimitive +where + C: Curve + Arithmetic, + SignatureSize: ArrayLength, +{ + /// Type for recoverable signatures + type RecoverableSignature: signature::Signature + Into>; + + /// Try to sign the prehashed message. + /// + /// Accepts the same arguments as [`SignPrimitive::try_sign_prehashed`] + /// but returns a boolean flag which indicates whether or not the + /// y-coordinate of the computed 𝐑 = 𝑘×𝑮 point is odd, which can be + /// incorporated into recoverable signatures. + fn try_sign_recoverable_prehashed + Invert>( + &self, + ephemeral_scalar: &K, + hashed_msg: &C::Scalar, + ) -> Result; +} + +impl SignPrimitive for T +where + C: Curve + Arithmetic, + T: RecoverableSignPrimitive, + SignatureSize: ArrayLength, +{ + fn try_sign_prehashed + Invert>( + &self, + ephemeral_scalar: &K, + hashed_msg: &C::Scalar, + ) -> Result, Error> { + self.try_sign_recoverable_prehashed(ephemeral_scalar, hashed_msg) + .map(Into::into) + } +} + /// Verify the given prehashed message using ECDSA. /// /// This trait is intended to be implemented on type which can access