Split raw_ecdsa_sign_recoverable function to PrivateKeyExt
What changed, and why it matters
This commit is a routine internal code reorganization. It moves a low-level ECDSA signing helper method from the main PrivateKey implementation into a new extension trait called PrivateKeyExt, and updates the one place that uses it to import the trait. There is no change to what the code does or any security fix.
No security action needed. Treat as normal refactoring.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch refactors PrivateKey::raw_ecdsa_sign_recoverable into a PrivateKeyExt extension trait gated behind the secp-recovery feature. It also adds PrivateKey to a sealed trait (likely to satisfy the macro’s requirements) and updates sign_message.rs to import PrivateKeyExt. The function body, visibility, and feature gating remain identical; only the API surface location changes.
Changed components
bitcoin/src/crypto/key.rsbitcoin/src/sign_message.rsInspect captured patch +27 / −19
diff --git a/bitcoin/src/crypto/key.rs b/bitcoin/src/crypto/key.rs
index 671915c1..0cf3a58d 100644
--- a/bitcoin/src/crypto/key.rs
+++ b/bitcoin/src/crypto/key.rs
@@ -1089,6 +1089,7 @@ mod sealed {
pub trait Sealed {}
impl Sealed for super::FullPublicKey {}
impl Sealed for super::LegacyPublicKey {}
+ impl Sealed for super::PrivateKey {}
}
impl PrivateKey {
@@ -1166,25 +1167,6 @@ impl PrivateKey {
}
}
- /// ECDSA signs a [`Message`] with this private key.
- ///
- /// This produces an ECDSA signature with a recovery ID for pubkey recovery.
- /// See [`RecoverableSignature::sign_ecdsa_recoverable`] for details.
- ///
- /// [`Message`]: secp256k1::Message
- /// [`RecoverableSignature::sign_ecdsa_recoverable`]: secp256k1::ecdsa::RecoverableSignature::sign_ecdsa_recoverable
- #[inline]
- #[cfg(feature = "secp-recovery")]
- pub fn raw_ecdsa_sign_recoverable(
- &self,
- msg: impl Into<secp256k1::Message>,
- ) -> MessageSignature {
- MessageSignature::new(
- secp256k1::ecdsa::RecoverableSignature::sign_ecdsa_recoverable(msg, self.as_inner()),
- self.compressed(),
- )
- }
-
/// ECDSA signs a [`Message`] with this private key.
///
/// This functions grinds the nonce to produce a signature less than 71 bytes and compatible
@@ -1202,6 +1184,30 @@ impl PrivateKey {
}
}
+#[cfg(feature = "secp-recovery")]
+define_extension_trait! {
+ /// Extension functionality for the [`PrivateKey`] type.
+ pub trait PrivateKeyExt impl for PrivateKey {
+ /// ECDSA signs a [`Message`] with this private key.
+ ///
+ /// This produces an ECDSA signature with a recovery ID for pubkey recovery.
+ /// See [`RecoverableSignature::sign_ecdsa_recoverable`] for details.
+ ///
+ /// [`Message`]: secp256k1::Message
+ /// [`RecoverableSignature::sign_ecdsa_recoverable`]: secp256k1::ecdsa::RecoverableSignature::sign_ecdsa_recoverable
+ #[inline]
+ fn raw_ecdsa_sign_recoverable(
+ &self,
+ msg: impl Into<secp256k1::Message>,
+ ) -> MessageSignature {
+ MessageSignature::new(
+ secp256k1::ecdsa::RecoverableSignature::sign_ecdsa_recoverable(msg, self.as_inner()),
+ self.compressed(),
+ )
+ }
+ }
+}
+
/// A Bitcoin ECDSA private key with known network for WIF.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct WifKey {
diff --git a/bitcoin/src/sign_message.rs b/bitcoin/src/sign_message.rs
index bc27a33e..5c6d1201 100644
--- a/bitcoin/src/sign_message.rs
+++ b/bitcoin/src/sign_message.rs
@@ -9,6 +9,8 @@ use hashes::{sha256d, HashEngine};
use crate::consensus::encode::WriteExt;
#[cfg(feature = "secp-recovery")]
+use crate::key::PrivateKeyExt as _;
+#[cfg(feature = "secp-recovery")]
use crate::PrivateKey;
#[rustfmt::skip]
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.