Make to_inner on public key types pub(super)
What changed, and why it matters
This commit narrows the visibility of internal helper methods named to_inner on Bitcoin public-key types. Previously any outside code could call these methods to extract the raw underlying secp256k1 key objects; now only code inside the same module can do so. This is a defensive encapsulation change that reduces the public API surface and makes future misuse or accidental exposure of internal cryptographic details less likely. It is not a fix for an active vulnerability.
No urgent action required. Downstream users relying on `to_inner` should migrate to the supported public APIs (e.g., `with_compressedness`). Monitor release notes for API-breaking changes.
Security signals we found
Reduction of public API surface for cryptographic key types
Encapsulation of inner secp256k1 key objects
Defensive hardening against misuse of raw public-key internals
No memory-safety, cryptographic, or authentication bug is fixed
Evidence from the diff
The patch changes pub fn to_inner(...) to pub(super) fn to_inner(...) on XOnlyPublicKey, PublicKey, and LegacyPublicKey in crypto/src/key.rs, and updates one test in bitcoin/src/crypto/key.rs to use a new public with_compressedness API instead of from_secp(pk.to_inner()). The change restricts access to the inner secp256k1 types to the parent module, continuing an earlier effort to stop exposing raw secp256k1 types publicly. It is a hardening/API-cleanup commit, not a patch for a known exploit.
Changed components
crypto/src/key.rsbitcoin/src/crypto/key.rsXOnlyPublicKeyPublicKeyLegacyPublicKeyInspect captured patch +4 / −4
diff --git a/bitcoin/src/crypto/key.rs b/bitcoin/src/crypto/key.rs
index 3bcd92ba..bb0bd457 100644
--- a/bitcoin/src/crypto/key.rs
+++ b/bitcoin/src/crypto/key.rs
@@ -238,7 +238,7 @@ mod tests {
.parse::<LegacyPublicKey>().unwrap());
let addr = Address::p2pkh(pk, sk.network_kind);
assert_eq!(&addr.to_string(), "1GhQvF6dL8xa6wBxLnWmHcQsurx9RxiMc8");
- pk = LegacyPublicKey::from_secp(pk.to_inner());
+ pk = pk.with_compressedness(true);
assert_eq!(
&pk.to_string(),
"032e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af"
diff --git a/crypto/src/key.rs b/crypto/src/key.rs
index ecf1973b..57dc5a74 100644
--- a/crypto/src/key.rs
+++ b/crypto/src/key.rs
@@ -85,7 +85,7 @@ mod encapsulate {
/// Returns the inner secp256k1 x-only public key.
#[inline]
- pub fn to_inner(self) -> secp256k1::XOnlyPublicKey { self.inner }
+ pub(super) fn to_inner(self) -> secp256k1::XOnlyPublicKey { self.inner }
/// Returns the inner secp256k1 x-only public key.
#[inline]
@@ -147,7 +147,7 @@ mod encapsulate {
/// Returns the inner secp256k1 public key.
#[inline]
- pub fn to_inner(self) -> secp256k1::PublicKey { self.inner }
+ pub(super) fn to_inner(self) -> secp256k1::PublicKey { self.inner }
/// Returns whether this public key should be serialized as compressed.
#[inline]
@@ -165,7 +165,7 @@ mod encapsulate {
/// Returns the inner [`secp256k1::PublicKey`].
#[inline]
- pub fn to_inner(self) -> secp256k1::PublicKey { self.0 }
+ pub(super) fn to_inner(self) -> secp256k1::PublicKey { self.0 }
}
/// A Bitcoin ECDSA private key.
Why this scored 23/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.