Change Witness::p2wpkh to take bitcoin PublicKey
What changed, and why it matters
This commit is a routine internal API cleanup in the rust-bitcoin library. It changes one function so it accepts the project's own public-key type instead of a lower-level secp256k1 public-key type, removing unnecessary conversions at call sites. There is no indication this fixes a security bug or introduces a vulnerability.
No security action required. Treat as a normal refactoring/API-consistency change.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch modifies Witness::p2wpkh to accept bitcoin::CompressedPublicKey (the crate’s own compressed public-key newtype) rather than secp256k1::PublicKey. Call sites in two examples are updated to pass the bitcoin type directly, and one example now explicitly calls force_compressed() to obtain a compressed key. The witness serialization path remains functionally equivalent: the signature is serialized and the public key is converted to bytes. No cryptographic logic, validation, or consensus-critical behavior is changed.
Changed components
bitcoin/src/blockdata/witness.rsbitcoin/examples/ecdsa-psbt-simple.rsbitcoin/examples/sign-tx-segwit-v0.rsInspect captured patch +6 / −6
diff --git a/bitcoin/examples/ecdsa-psbt-simple.rs b/bitcoin/examples/ecdsa-psbt-simple.rs
index a0339d6f..72442950 100644
--- a/bitcoin/examples/ecdsa-psbt-simple.rs
+++ b/bitcoin/examples/ecdsa-psbt-simple.rs
@@ -217,7 +217,7 @@ fn main() {
.enumerate()
.map(|(idx, input)| {
let (_, sig) = input.partial_sigs.iter().next().expect("we have one sig");
- Witness::p2wpkh(*sig, pk_inputs[idx].to_inner())
+ Witness::p2wpkh(*sig, pk_inputs[idx])
})
.collect();
psbt.inputs.iter_mut().enumerate().for_each(|(idx, input)| {
diff --git a/bitcoin/examples/sign-tx-segwit-v0.rs b/bitcoin/examples/sign-tx-segwit-v0.rs
index fc5397d1..2f0a918a 100644
--- a/bitcoin/examples/sign-tx-segwit-v0.rs
+++ b/bitcoin/examples/sign-tx-segwit-v0.rs
@@ -69,8 +69,8 @@ fn main() {
let signature = ecdsa::Signature { signature: sk.raw_ecdsa_sign(sighash), sighash_type };
// Update the witness stack.
- let pk = sk.public_key();
- *sighasher.witness_mut(input_index).unwrap() = Witness::p2wpkh(signature, pk.to_inner());
+ let pk = sk.public_key().force_compressed();
+ *sighasher.witness_mut(input_index).unwrap() = Witness::p2wpkh(signature, pk);
// Get the signed transaction.
let tx = sighasher.into_transaction();
diff --git a/bitcoin/src/blockdata/witness.rs b/bitcoin/src/blockdata/witness.rs
index 8558a0ff..93d5395f 100644
--- a/bitcoin/src/blockdata/witness.rs
+++ b/bitcoin/src/blockdata/witness.rs
@@ -9,7 +9,7 @@ use io::{BufRead, Write};
use crate::consensus::encode::{self, Error, ParseError, WriteExt};
use crate::consensus::{Decodable, Encodable};
use crate::crypto::ecdsa;
-use crate::crypto::key::SerializedXOnlyPublicKey;
+use crate::crypto::key::{CompressedPublicKey, SerializedXOnlyPublicKey};
use crate::taproot::{self, ControlBlock, LeafScript, TaprootMerkleBranch, TAPROOT_ANNEX_PREFIX};
use crate::{internal_macros, TapScript, WitnessScript};
@@ -49,10 +49,10 @@ internal_macros::define_extension_trait! {
/// serialized public key. Also useful for spending a P2SH-P2WPKH output.
///
/// It is expected that `pubkey` is related to the secret key used to create `signature`.
- fn p2wpkh(signature: ecdsa::Signature, pubkey: secp256k1::PublicKey) -> Self {
+ fn p2wpkh(signature: ecdsa::Signature, pubkey: CompressedPublicKey) -> Self {
let mut witness = Witness::new();
witness.push(signature.serialize());
- witness.push(pubkey.serialize());
+ witness.push(pubkey.to_bytes());
witness
}
Why this scored 18/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.