Skip to content

Commit 1c2800e

Browse files
committed
satisfy: change lookup_tap_key_spend_sig to take the public key
There is only one public key possible, but this makes the API more consistent between keyspends and script-spends, and makes it much easier for users who have a key->sig lookup table to implement satisfiers. Fixes #825
1 parent 97ef17a commit 1c2800e

File tree

5 files changed

+32
-24
lines changed

5 files changed

+32
-24
lines changed

fuzz/fuzz_targets/miniscript_satisfy.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ impl FuzzSatisfier<'_> {
2323
}
2424

2525
impl Satisfier<FuzzPk> for FuzzSatisfier<'_> {
26-
fn lookup_tap_key_spend_sig(&self) -> Option<Signature> {
26+
fn lookup_tap_key_spend_sig(&self, _: &FuzzPk) -> Option<Signature> {
2727
let b = self.read_byte()?;
2828
if b & 1 == 1 {
2929
// FIXME in later version of rust-secp we can use from_byte_array
@@ -34,8 +34,8 @@ impl Satisfier<FuzzPk> for FuzzSatisfier<'_> {
3434
}
3535
}
3636

37-
fn lookup_tap_leaf_script_sig(&self, _: &FuzzPk, _: &TapLeafHash) -> Option<Signature> {
38-
self.lookup_tap_key_spend_sig()
37+
fn lookup_tap_leaf_script_sig(&self, pk: &FuzzPk, _: &TapLeafHash) -> Option<Signature> {
38+
self.lookup_tap_key_spend_sig(pk)
3939
}
4040

4141
// todo
@@ -85,7 +85,7 @@ impl Satisfier<FuzzPk> for FuzzSatisfier<'_> {
8585
(h, _): &(hash160::Hash, TapLeafHash),
8686
) -> Option<(XOnlyPublicKey, Signature)> {
8787
self.lookup_raw_pkh_x_only_pk(h)
88-
.zip(self.lookup_tap_key_spend_sig())
88+
.zip(self.lookup_tap_key_spend_sig(&FuzzPk::new_from_control_byte(0)))
8989
}
9090

9191
fn lookup_sha256(&self, b: &u8) -> Option<[u8; 32]> {

src/miniscript/satisfy.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ pub trait Satisfier<Pk: MiniscriptKey + ToPublicKey> {
3535
fn lookup_ecdsa_sig(&self, _: &Pk) -> Option<bitcoin::ecdsa::Signature> { None }
3636

3737
/// Lookup the tap key spend sig
38-
fn lookup_tap_key_spend_sig(&self) -> Option<bitcoin::taproot::Signature> { None }
38+
fn lookup_tap_key_spend_sig(&self, _: &Pk) -> Option<bitcoin::taproot::Signature> { None }
3939

4040
/// Given a public key and a associated leaf hash, look up an schnorr signature with that key
4141
fn lookup_tap_leaf_script_sig(
@@ -290,8 +290,8 @@ impl<Pk: MiniscriptKey + ToPublicKey, S: Satisfier<Pk>> Satisfier<Pk> for &S {
290290
(**self).lookup_raw_pkh_ecdsa_sig(pkh)
291291
}
292292

293-
fn lookup_tap_key_spend_sig(&self) -> Option<bitcoin::taproot::Signature> {
294-
(**self).lookup_tap_key_spend_sig()
293+
fn lookup_tap_key_spend_sig(&self, pk: &Pk) -> Option<bitcoin::taproot::Signature> {
294+
(**self).lookup_tap_key_spend_sig(pk)
295295
}
296296

297297
fn lookup_raw_pkh_tap_leaf_script_sig(
@@ -335,8 +335,8 @@ impl<Pk: MiniscriptKey + ToPublicKey, S: Satisfier<Pk>> Satisfier<Pk> for &mut S
335335
(**self).lookup_tap_leaf_script_sig(p, h)
336336
}
337337

338-
fn lookup_tap_key_spend_sig(&self) -> Option<bitcoin::taproot::Signature> {
339-
(**self).lookup_tap_key_spend_sig()
338+
fn lookup_tap_key_spend_sig(&self, pk: &Pk) -> Option<bitcoin::taproot::Signature> {
339+
(**self).lookup_tap_key_spend_sig(pk)
340340
}
341341

342342
fn lookup_raw_pkh_pk(&self, pkh: &hash160::Hash) -> Option<bitcoin::PublicKey> {
@@ -400,10 +400,10 @@ macro_rules! impl_tuple_satisfier {
400400
None
401401
}
402402

403-
fn lookup_tap_key_spend_sig(&self) -> Option<bitcoin::taproot::Signature> {
403+
fn lookup_tap_key_spend_sig(&self, pk: &Pk) -> Option<bitcoin::taproot::Signature> {
404404
let &($(ref $ty,)*) = self;
405405
$(
406-
if let Some(result) = $ty.lookup_tap_key_spend_sig() {
406+
if let Some(result) = $ty.lookup_tap_key_spend_sig(pk) {
407407
return Some(result);
408408
}
409409
)*
@@ -678,12 +678,13 @@ impl<Pk: MiniscriptKey + ToPublicKey> Placeholder<Pk> {
678678
debug_assert!(s.len() == *size);
679679
s
680680
}),
681-
Placeholder::SchnorrSigPk(_, _, size) => {
682-
sat.lookup_tap_key_spend_sig().map(|s| s.to_vec()).map(|s| {
681+
Placeholder::SchnorrSigPk(pk, _, size) => sat
682+
.lookup_tap_key_spend_sig(pk)
683+
.map(|s| s.to_vec())
684+
.map(|s| {
683685
debug_assert!(s.len() == *size);
684686
s
685-
})
686-
}
687+
}),
687688
Placeholder::SchnorrSigPkHash(pkh, tap_leaf_hash, size) => sat
688689
.lookup_raw_pkh_tap_leaf_script_sig(&(*pkh, *tap_leaf_hash))
689690
.map(|(_, s)| {

src/plan.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,8 @@ where
147147
Satisfier::lookup_ecdsa_sig(self, pk).is_some()
148148
}
149149

150-
fn provider_lookup_tap_key_spend_sig(&self, _: &Pk) -> Option<usize> {
151-
Satisfier::lookup_tap_key_spend_sig(self).map(|s| s.to_vec().len())
150+
fn provider_lookup_tap_key_spend_sig(&self, pk: &Pk) -> Option<usize> {
151+
Satisfier::lookup_tap_key_spend_sig(self, pk).map(|s| s.to_vec().len())
152152
}
153153

154154
fn provider_lookup_tap_leaf_script_sig(

src/psbt/finalizer.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,13 @@ fn construct_tap_witness(
5353
}
5454
assert!(spk.is_p2tr());
5555

56-
// try the key spend path first
57-
if let Some(sig) =
58-
<PsbtInputSatisfier as Satisfier<XOnlyPublicKey>>::lookup_tap_key_spend_sig(sat)
59-
{
60-
return Ok(vec![sig.to_vec()]);
56+
// try the key spend path firsti
57+
if let Some(ref key) = sat.psbt_input().tap_internal_key {
58+
if let Some(sig) =
59+
<PsbtInputSatisfier as Satisfier<XOnlyPublicKey>>::lookup_tap_key_spend_sig(sat, key)
60+
{
61+
return Ok(vec![sig.to_vec()]);
62+
}
6163
}
6264
// Next script spends
6365
let (mut min_wit, mut min_wit_len) = (None, None);

src/psbt/mod.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,8 +261,13 @@ impl<'psbt> PsbtInputSatisfier<'psbt> {
261261
}
262262

263263
impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for PsbtInputSatisfier<'_> {
264-
fn lookup_tap_key_spend_sig(&self) -> Option<bitcoin::taproot::Signature> {
265-
self.psbt_input().tap_key_sig
264+
fn lookup_tap_key_spend_sig(&self, pk: &Pk) -> Option<bitcoin::taproot::Signature> {
265+
if let Some(key) = self.psbt_input().tap_internal_key {
266+
if pk.to_x_only_pubkey() == key {
267+
return self.psbt_input().tap_key_sig;
268+
}
269+
}
270+
None
266271
}
267272

268273
fn lookup_tap_leaf_script_sig(

0 commit comments

Comments
 (0)