From 8645f1c097c01c75a437f3c1bfa363bc95a9d430 Mon Sep 17 00:00:00 2001 From: Dan Cline <6798349+Rjected@users.noreply.github.com> Date: Tue, 19 Nov 2024 20:52:17 -0500 Subject: [PATCH] feat: impl recoverable RandomizedPrehashSigner for SigningKey --- ecdsa/src/recovery.rs | 55 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/ecdsa/src/recovery.rs b/ecdsa/src/recovery.rs index f1a96415..88ba735f 100644 --- a/ecdsa/src/recovery.rs +++ b/ecdsa/src/recovery.rs @@ -5,8 +5,13 @@ use crate::{Error, Result}; #[cfg(feature = "signing")] use { crate::{hazmat::sign_prehashed_rfc6979, SigningKey}, - elliptic_curve::subtle::CtOption, - signature::{hazmat::PrehashSigner, DigestSigner, Signer}, + elliptic_curve::{subtle::CtOption, FieldBytes}, + signature::{ + digest::FixedOutput, + hazmat::{PrehashSigner, RandomizedPrehashSigner}, + rand_core::CryptoRngCore, + DigestSigner, RandomizedDigestSigner, Signer, + }, }; #[cfg(feature = "verifying")] @@ -178,6 +183,19 @@ where Scalar: Invert>>, SignatureSize: ArraySize, { + /// Sign the given message prehash, using the given rng for the RFC6979 Section 3.6 "additional + /// data", returning a signature and recovery ID. + pub fn sign_prehash_recoverable_with_rng( + &self, + rng: &mut impl CryptoRngCore, + prehash: &[u8], + ) -> Result<(Signature, RecoveryId)> { + let z = bits2field::(prehash)?; + let mut ad = FieldBytes::::default(); + rng.fill_bytes(&mut ad); + sign_prehashed_rfc6979::(self.as_nonzero_scalar(), &z, &ad) + } + /// Sign the given message prehash, returning a signature and recovery ID. pub fn sign_prehash_recoverable(&self, prehash: &[u8]) -> Result<(Signature, RecoveryId)> { let z = bits2field::(prehash)?; @@ -212,6 +230,39 @@ where } } +#[cfg(feature = "signing")] +impl RandomizedPrehashSigner<(Signature, RecoveryId)> for SigningKey +where + C: EcdsaCurve + CurveArithmetic + DigestPrimitive, + Scalar: Invert>>, + SignatureSize: ArraySize, +{ + fn sign_prehash_with_rng( + &self, + rng: &mut impl CryptoRngCore, + prehash: &[u8], + ) -> Result<(Signature, RecoveryId)> { + self.sign_prehash_recoverable_with_rng(rng, prehash) + } +} + +#[cfg(feature = "signing")] +impl RandomizedDigestSigner, RecoveryId)> for SigningKey +where + C: EcdsaCurve + CurveArithmetic + DigestPrimitive, + D: Digest + FixedOutput, + Scalar: Invert>>, + SignatureSize: ArraySize, +{ + fn try_sign_digest_with_rng( + &self, + rng: &mut impl CryptoRngCore, + msg_digest: D, + ) -> Result<(Signature, RecoveryId)> { + self.sign_prehash_with_rng(rng, &msg_digest.finalize_fixed()) + } +} + #[cfg(feature = "signing")] impl PrehashSigner<(Signature, RecoveryId)> for SigningKey where