policy: Consider tap_key_origins
when looking for sigs in PSBTs
We used to only look at `bip32_derivations` which is only used for ECDSA keys.
This commit is contained in:
parent
572c3ee70d
commit
c67116fb55
@ -44,7 +44,6 @@ use serde::ser::SerializeMap;
|
|||||||
use serde::{Serialize, Serializer};
|
use serde::{Serialize, Serializer};
|
||||||
|
|
||||||
use bitcoin::hashes::*;
|
use bitcoin::hashes::*;
|
||||||
use bitcoin::secp256k1;
|
|
||||||
use bitcoin::util::bip32::Fingerprint;
|
use bitcoin::util::bip32::Fingerprint;
|
||||||
use bitcoin::{PublicKey, XOnlyPublicKey};
|
use bitcoin::{PublicKey, XOnlyPublicKey};
|
||||||
|
|
||||||
@ -766,27 +765,25 @@ fn make_generic_signature<M: Fn() -> SatisfiableItem, F: Fn(&Psbt) -> bool>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn generic_sig_in_psbt<
|
fn generic_sig_in_psbt<
|
||||||
|
// C is for "check", it's a closure we use to *check* if a psbt input contains the signature
|
||||||
|
// for a specific key
|
||||||
C: Fn(&PsbtInput, &SinglePubKey) -> bool,
|
C: Fn(&PsbtInput, &SinglePubKey) -> bool,
|
||||||
M: Fn(&secp256k1::PublicKey) -> SinglePubKey,
|
// E is for "extract", it extracts a key from the bip32 derivations found in the psbt input
|
||||||
|
E: Fn(&PsbtInput, Fingerprint) -> Option<SinglePubKey>,
|
||||||
>(
|
>(
|
||||||
psbt: &Psbt,
|
psbt: &Psbt,
|
||||||
key: &DescriptorPublicKey,
|
key: &DescriptorPublicKey,
|
||||||
secp: &SecpCtx,
|
secp: &SecpCtx,
|
||||||
map: M,
|
|
||||||
check: C,
|
check: C,
|
||||||
|
extract: E,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
//TODO check signature validity
|
//TODO check signature validity
|
||||||
psbt.inputs.iter().all(|input| match key {
|
psbt.inputs.iter().all(|input| match key {
|
||||||
DescriptorPublicKey::SinglePub(DescriptorSinglePub { key, .. }) => check(input, key),
|
DescriptorPublicKey::SinglePub(DescriptorSinglePub { key, .. }) => check(input, key),
|
||||||
DescriptorPublicKey::XPub(xpub) => {
|
DescriptorPublicKey::XPub(xpub) => {
|
||||||
let pubkey = input
|
|
||||||
.bip32_derivation
|
|
||||||
.iter()
|
|
||||||
.find(|(_, (f, _))| *f == xpub.root_fingerprint(secp))
|
|
||||||
.map(|(p, _)| p);
|
|
||||||
//TODO check actual derivation matches
|
//TODO check actual derivation matches
|
||||||
match pubkey {
|
match extract(input, xpub.root_fingerprint(secp)) {
|
||||||
Some(pubkey) => check(input, &map(pubkey)),
|
Some(pubkey) => check(input, &pubkey),
|
||||||
None => false,
|
None => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -838,7 +835,6 @@ impl<T: ScriptContext + 'static> SigExt for T {
|
|||||||
psbt,
|
psbt,
|
||||||
key,
|
key,
|
||||||
secp,
|
secp,
|
||||||
|pk| SinglePubKey::XOnly((*pk).into()),
|
|
||||||
|input, pk| {
|
|input, pk| {
|
||||||
let pk = match pk {
|
let pk = match pk {
|
||||||
SinglePubKey::XOnly(pk) => pk,
|
SinglePubKey::XOnly(pk) => pk,
|
||||||
@ -851,17 +847,30 @@ impl<T: ScriptContext + 'static> SigExt for T {
|
|||||||
input.tap_script_sigs.keys().any(|(sk, _)| sk == pk)
|
input.tap_script_sigs.keys().any(|(sk, _)| sk == pk)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|input, fing| {
|
||||||
|
input
|
||||||
|
.tap_key_origins
|
||||||
|
.iter()
|
||||||
|
.find(|(_, (_, (f, _)))| f == &fing)
|
||||||
|
.map(|(pk, _)| SinglePubKey::XOnly(*pk))
|
||||||
|
},
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
generic_sig_in_psbt(
|
generic_sig_in_psbt(
|
||||||
psbt,
|
psbt,
|
||||||
key,
|
key,
|
||||||
secp,
|
secp,
|
||||||
|pk| SinglePubKey::FullKey(PublicKey::new(*pk)),
|
|
||||||
|input, pk| match pk {
|
|input, pk| match pk {
|
||||||
SinglePubKey::FullKey(pk) => input.partial_sigs.contains_key(pk),
|
SinglePubKey::FullKey(pk) => input.partial_sigs.contains_key(pk),
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
|
|input, fing| {
|
||||||
|
input
|
||||||
|
.bip32_derivation
|
||||||
|
.iter()
|
||||||
|
.find(|(_, (f, _))| f == &fing)
|
||||||
|
.map(|(pk, _)| SinglePubKey::FullKey(PublicKey::new(*pk)))
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user