Skip to content

Commit 5b862b5

Browse files
committed
Merge #827: satisfy: change lookup_tap_key_spend_sig to take the public key
1c2800e satisfy: change `lookup_tap_key_spend_sig` to take the public key (Andrew Poelstra) 97ef17a psbt: make PsbtInputSatisfier internals private (Andrew Poelstra) 8a93d06 psbt: add accessor to PsbtInputSatisfier for the input it holds (Andrew Poelstra) Pull request description: 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 ACKs for top commit: sanket1729: ACK 1c2800e. Tree-SHA512: c1d1a8128823e4fa70f2dd671400825c7d3ee5d45d35b19a60cce221379373bd6ad099847246d93d62f6f10886e84e5c09a57a2f00435257af4cc8ee97348395
2 parents a9888de + 1c2800e commit 5b862b5

File tree

5 files changed

+50
-36
lines changed

5 files changed

+50
-36
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: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -243,35 +243,46 @@ impl From<bitcoin::key::FromSliceError> for InputError {
243243
/// is more than number of inputs in pbst
244244
pub struct PsbtInputSatisfier<'psbt> {
245245
/// pbst
246-
pub psbt: &'psbt Psbt,
246+
psbt: &'psbt Psbt,
247247
/// input index
248-
pub index: usize,
248+
index: usize,
249249
}
250250

251251
impl<'psbt> PsbtInputSatisfier<'psbt> {
252252
/// create a new PsbtInputsatisfier from
253253
/// psbt and index
254254
pub fn new(psbt: &'psbt Psbt, index: usize) -> Self { Self { psbt, index } }
255+
256+
/// Accessor for the PSBT this satisfier is associated with.
257+
pub fn psbt(&self) -> &'psbt Psbt { self.psbt }
258+
259+
/// Accessor for the input this satisfier is associated with.
260+
pub fn psbt_input(&self) -> &psbt::Input { &self.psbt.inputs[self.index] }
255261
}
256262

257263
impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for PsbtInputSatisfier<'_> {
258-
fn lookup_tap_key_spend_sig(&self) -> Option<bitcoin::taproot::Signature> {
259-
self.psbt.inputs[self.index].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
260271
}
261272

262273
fn lookup_tap_leaf_script_sig(
263274
&self,
264275
pk: &Pk,
265276
lh: &TapLeafHash,
266277
) -> Option<bitcoin::taproot::Signature> {
267-
self.psbt.inputs[self.index]
278+
self.psbt_input()
268279
.tap_script_sigs
269280
.get(&(pk.to_x_only_pubkey(), *lh))
270281
.copied()
271282
}
272283

273284
fn lookup_raw_pkh_pk(&self, pkh: &hash160::Hash) -> Option<bitcoin::PublicKey> {
274-
self.psbt.inputs[self.index]
285+
self.psbt_input()
275286
.bip32_derivation
276287
.iter()
277288
.find(|&(pubkey, _)| pubkey.to_pubkeyhash(SigType::Ecdsa) == *pkh)
@@ -281,14 +292,14 @@ impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for PsbtInputSatisfier<'_> {
281292
fn lookup_tap_control_block_map(
282293
&self,
283294
) -> Option<&BTreeMap<ControlBlock, (bitcoin::ScriptBuf, LeafVersion)>> {
284-
Some(&self.psbt.inputs[self.index].tap_scripts)
295+
Some(&self.psbt_input().tap_scripts)
285296
}
286297

287298
fn lookup_raw_pkh_tap_leaf_script_sig(
288299
&self,
289300
pkh: &(hash160::Hash, TapLeafHash),
290301
) -> Option<(bitcoin::secp256k1::XOnlyPublicKey, bitcoin::taproot::Signature)> {
291-
self.psbt.inputs[self.index]
302+
self.psbt_input()
292303
.tap_script_sigs
293304
.iter()
294305
.find(|&((pubkey, lh), _sig)| {
@@ -298,7 +309,7 @@ impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for PsbtInputSatisfier<'_> {
298309
}
299310

300311
fn lookup_ecdsa_sig(&self, pk: &Pk) -> Option<bitcoin::ecdsa::Signature> {
301-
self.psbt.inputs[self.index]
312+
self.psbt_input()
302313
.partial_sigs
303314
.get(&pk.to_public_key())
304315
.copied()
@@ -308,7 +319,7 @@ impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for PsbtInputSatisfier<'_> {
308319
&self,
309320
pkh: &hash160::Hash,
310321
) -> Option<(bitcoin::PublicKey, bitcoin::ecdsa::Signature)> {
311-
self.psbt.inputs[self.index]
322+
self.psbt_input()
312323
.partial_sigs
313324
.iter()
314325
.find(|&(pubkey, _sig)| pubkey.to_pubkeyhash(SigType::Ecdsa) == *pkh)
@@ -337,28 +348,28 @@ impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for PsbtInputSatisfier<'_> {
337348
}
338349

339350
fn lookup_hash160(&self, h: &Pk::Hash160) -> Option<Preimage32> {
340-
self.psbt.inputs[self.index]
351+
self.psbt_input()
341352
.hash160_preimages
342353
.get(&Pk::to_hash160(h))
343354
.and_then(|x: &Vec<u8>| <[u8; 32]>::try_from(&x[..]).ok())
344355
}
345356

346357
fn lookup_sha256(&self, h: &Pk::Sha256) -> Option<Preimage32> {
347-
self.psbt.inputs[self.index]
358+
self.psbt_input()
348359
.sha256_preimages
349360
.get(&Pk::to_sha256(h))
350361
.and_then(|x: &Vec<u8>| <[u8; 32]>::try_from(&x[..]).ok())
351362
}
352363

353364
fn lookup_hash256(&self, h: &Pk::Hash256) -> Option<Preimage32> {
354-
self.psbt.inputs[self.index]
365+
self.psbt_input()
355366
.hash256_preimages
356367
.get(&sha256d::Hash::from_byte_array(Pk::to_hash256(h).to_byte_array())) // upstream psbt operates on hash256
357368
.and_then(|x: &Vec<u8>| <[u8; 32]>::try_from(&x[..]).ok())
358369
}
359370

360371
fn lookup_ripemd160(&self, h: &Pk::Ripemd160) -> Option<Preimage32> {
361-
self.psbt.inputs[self.index]
372+
self.psbt_input()
362373
.ripemd160_preimages
363374
.get(&Pk::to_ripemd160(h))
364375
.and_then(|x: &Vec<u8>| <[u8; 32]>::try_from(&x[..]).ok())

0 commit comments

Comments
 (0)