miniscript/miniscript/
satisfy.rs

1// SPDX-License-Identifier: CC0-1.0
2
3//! # Satisfaction and Dissatisfaction
4//!
5//! Traits and implementations to support producing witnesses for Miniscript
6//! scriptpubkeys.
7//!
8
9use core::{cmp, fmt, mem};
10
11use bitcoin::hashes::hash160;
12use bitcoin::key::XOnlyPublicKey;
13use bitcoin::taproot::{ControlBlock, LeafVersion, TapLeafHash, TapNodeHash};
14use bitcoin::{absolute, relative, ScriptBuf, Sequence};
15use sync::Arc;
16
17use super::context::SigType;
18use crate::plan::AssetProvider;
19use crate::prelude::*;
20use crate::util::witness_size;
21use crate::{
22    AbsLockTime, Miniscript, MiniscriptKey, RelLockTime, ScriptContext, Terminal, Threshold,
23    ToPublicKey,
24};
25
26/// Type alias for 32 byte Preimage.
27pub type Preimage32 = [u8; 32];
28/// Trait describing a lookup table for signatures, hash preimages, etc.
29/// Every method has a default implementation that simply returns `None`
30/// on every query. Users are expected to override the methods that they
31/// have data for.
32pub trait Satisfier<Pk: MiniscriptKey + ToPublicKey> {
33    /// Given a public key, look up an ECDSA signature with that key
34    fn lookup_ecdsa_sig(&self, _: &Pk) -> Option<bitcoin::ecdsa::Signature> { None }
35
36    /// Lookup the tap key spend sig
37    fn lookup_tap_key_spend_sig(&self) -> Option<bitcoin::taproot::Signature> { None }
38
39    /// Given a public key and a associated leaf hash, look up an schnorr signature with that key
40    fn lookup_tap_leaf_script_sig(
41        &self,
42        _: &Pk,
43        _: &TapLeafHash,
44    ) -> Option<bitcoin::taproot::Signature> {
45        None
46    }
47
48    /// Obtain a reference to the control block for a ver and script
49    fn lookup_tap_control_block_map(
50        &self,
51    ) -> Option<&BTreeMap<ControlBlock, (bitcoin::ScriptBuf, LeafVersion)>> {
52        None
53    }
54
55    /// Given a raw `Pkh`, lookup corresponding [`bitcoin::PublicKey`]
56    fn lookup_raw_pkh_pk(&self, _: &hash160::Hash) -> Option<bitcoin::PublicKey> { None }
57
58    /// Given a raw `Pkh`, lookup corresponding [`bitcoin::secp256k1::XOnlyPublicKey`]
59    fn lookup_raw_pkh_x_only_pk(&self, _: &hash160::Hash) -> Option<XOnlyPublicKey> { None }
60
61    /// Given a keyhash, look up the EC signature and the associated key
62    /// Even if signatures for public key Hashes are not available, the users
63    /// can use this map to provide pkh -> pk mapping which can be useful
64    /// for dissatisfying pkh.
65    fn lookup_raw_pkh_ecdsa_sig(
66        &self,
67        _: &hash160::Hash,
68    ) -> Option<(bitcoin::PublicKey, bitcoin::ecdsa::Signature)> {
69        None
70    }
71
72    /// Given a keyhash, look up the schnorr signature and the associated key
73    /// Even if signatures for public key Hashes are not available, the users
74    /// can use this map to provide pkh -> pk mapping which can be useful
75    /// for dissatisfying pkh.
76    fn lookup_raw_pkh_tap_leaf_script_sig(
77        &self,
78        _: &(hash160::Hash, TapLeafHash),
79    ) -> Option<(XOnlyPublicKey, bitcoin::taproot::Signature)> {
80        None
81    }
82
83    /// Given a SHA256 hash, look up its preimage
84    fn lookup_sha256(&self, _: &Pk::Sha256) -> Option<Preimage32> { None }
85
86    /// Given a HASH256 hash, look up its preimage
87    fn lookup_hash256(&self, _: &Pk::Hash256) -> Option<Preimage32> { None }
88
89    /// Given a RIPEMD160 hash, look up its preimage
90    fn lookup_ripemd160(&self, _: &Pk::Ripemd160) -> Option<Preimage32> { None }
91
92    /// Given a HASH160 hash, look up its preimage
93    fn lookup_hash160(&self, _: &Pk::Hash160) -> Option<Preimage32> { None }
94
95    /// Assert whether an relative locktime is satisfied
96    ///
97    /// NOTE: If a descriptor mixes time-based and height-based timelocks, the implementation of
98    /// this method MUST only allow timelocks of either unit, but not both. Allowing both could cause
99    /// miniscript to construct an invalid witness.
100    fn check_older(&self, _: relative::LockTime) -> bool { false }
101
102    /// Assert whether a absolute locktime is satisfied
103    ///
104    /// NOTE: If a descriptor mixes time-based and height-based timelocks, the implementation of
105    /// this method MUST only allow timelocks of either unit, but not both. Allowing both could cause
106    /// miniscript to construct an invalid witness.
107    fn check_after(&self, _: absolute::LockTime) -> bool { false }
108}
109
110// Allow use of `()` as a "no conditions available" satisfier
111impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for () {}
112
113impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for Sequence {
114    fn check_older(&self, n: relative::LockTime) -> bool {
115        if let Some(lt) = self.to_relative_lock_time() {
116            Satisfier::<Pk>::check_older(&lt, n)
117        } else {
118            false
119        }
120    }
121}
122
123impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for RelLockTime {
124    fn check_older(&self, n: relative::LockTime) -> bool {
125        <relative::LockTime as Satisfier<Pk>>::check_older(&(*self).into(), n)
126    }
127}
128
129impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for relative::LockTime {
130    fn check_older(&self, n: relative::LockTime) -> bool { n.is_implied_by(*self) }
131}
132
133impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for absolute::LockTime {
134    fn check_after(&self, n: absolute::LockTime) -> bool { n.is_implied_by(*self) }
135}
136
137macro_rules! impl_satisfier_for_map_key_to_ecdsa_sig {
138    ($(#[$($attr:meta)*])* impl Satisfier<Pk> for $map:ident<$key:ty, $val:ty>) => {
139        $(#[$($attr)*])*
140        impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk>
141            for $map<Pk, bitcoin::ecdsa::Signature>
142        {
143            fn lookup_ecdsa_sig(&self, key: &Pk) -> Option<bitcoin::ecdsa::Signature> {
144                self.get(key).copied()
145            }
146        }
147    };
148}
149
150impl_satisfier_for_map_key_to_ecdsa_sig! {
151    impl Satisfier<Pk> for BTreeMap<Pk, bitcoin::ecdsa::Signature>
152}
153
154impl_satisfier_for_map_key_to_ecdsa_sig! {
155    #[cfg(feature = "std")]
156    impl Satisfier<Pk> for HashMap<Pk, bitcoin::ecdsa::Signature>
157}
158
159macro_rules! impl_satisfier_for_map_key_hash_to_taproot_sig {
160    ($(#[$($attr:meta)*])* impl Satisfier<Pk> for $map:ident<$key:ty, $val:ty>) => {
161        $(#[$($attr)*])*
162        impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk>
163            for $map<(Pk, TapLeafHash), bitcoin::taproot::Signature>
164        {
165            fn lookup_tap_leaf_script_sig(
166                &self,
167                key: &Pk,
168                h: &TapLeafHash,
169            ) -> Option<bitcoin::taproot::Signature> {
170                // Unfortunately, there is no way to get a &(a, b) from &a and &b without allocating
171                // If we change the signature the of lookup_tap_leaf_script_sig to accept a tuple. We would
172                // face the same problem while satisfying PkK.
173                // We use this signature to optimize for the psbt common use case.
174                self.get(&(key.clone(), *h)).copied()
175            }
176        }
177    };
178}
179
180impl_satisfier_for_map_key_hash_to_taproot_sig! {
181    impl Satisfier<Pk> for BTreeMap<(Pk, TapLeafHash), bitcoin::taproot::Signature>
182}
183
184impl_satisfier_for_map_key_hash_to_taproot_sig! {
185    #[cfg(feature = "std")]
186    impl Satisfier<Pk> for HashMap<(Pk, TapLeafHash), bitcoin::taproot::Signature>
187}
188
189macro_rules! impl_satisfier_for_map_hash_to_key_ecdsa_sig {
190    ($(#[$($attr:meta)*])* impl Satisfier<Pk> for $map:ident<$key:ty, $val:ty>) => {
191        $(#[$($attr)*])*
192        impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk>
193            for $map<hash160::Hash, (Pk, bitcoin::ecdsa::Signature)>
194        where
195            Pk: MiniscriptKey + ToPublicKey,
196        {
197            fn lookup_ecdsa_sig(&self, key: &Pk) -> Option<bitcoin::ecdsa::Signature> {
198                self.get(&key.to_pubkeyhash(SigType::Ecdsa)).map(|x| x.1)
199            }
200
201            fn lookup_raw_pkh_pk(&self, pk_hash: &hash160::Hash) -> Option<bitcoin::PublicKey> {
202                self.get(pk_hash).map(|x| x.0.to_public_key())
203            }
204
205            fn lookup_raw_pkh_ecdsa_sig(
206                &self,
207                pk_hash: &hash160::Hash,
208            ) -> Option<(bitcoin::PublicKey, bitcoin::ecdsa::Signature)> {
209                self.get(pk_hash)
210                    .map(|&(ref pk, sig)| (pk.to_public_key(), sig))
211            }
212        }
213    };
214}
215
216impl_satisfier_for_map_hash_to_key_ecdsa_sig! {
217    impl Satisfier<Pk> for BTreeMap<hash160::Hash, (Pk, bitcoin::ecdsa::Signature)>
218}
219
220impl_satisfier_for_map_hash_to_key_ecdsa_sig! {
221    #[cfg(feature = "std")]
222    impl Satisfier<Pk> for HashMap<hash160::Hash, (Pk, bitcoin::ecdsa::Signature)>
223}
224
225macro_rules! impl_satisfier_for_map_hash_tapleafhash_to_key_taproot_sig {
226    ($(#[$($attr:meta)*])* impl Satisfier<Pk> for $map:ident<$key:ty, $val:ty>) => {
227        $(#[$($attr)*])*
228        impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk>
229            for $map<(hash160::Hash, TapLeafHash), (Pk, bitcoin::taproot::Signature)>
230        where
231            Pk: MiniscriptKey + ToPublicKey,
232        {
233            fn lookup_tap_leaf_script_sig(
234                &self,
235                key: &Pk,
236                h: &TapLeafHash,
237            ) -> Option<bitcoin::taproot::Signature> {
238                self.get(&(key.to_pubkeyhash(SigType::Schnorr), *h))
239                    .map(|x| x.1)
240            }
241
242            fn lookup_raw_pkh_tap_leaf_script_sig(
243                &self,
244                pk_hash: &(hash160::Hash, TapLeafHash),
245            ) -> Option<(XOnlyPublicKey, bitcoin::taproot::Signature)> {
246                self.get(pk_hash)
247                    .map(|&(ref pk, sig)| (pk.to_x_only_pubkey(), sig))
248            }
249        }
250    };
251}
252
253impl_satisfier_for_map_hash_tapleafhash_to_key_taproot_sig! {
254    impl Satisfier<Pk> for BTreeMap<(hash160::Hash, TapLeafHash), (Pk, bitcoin::taproot::Signature)>
255}
256
257impl_satisfier_for_map_hash_tapleafhash_to_key_taproot_sig! {
258    #[cfg(feature = "std")]
259    impl Satisfier<Pk> for HashMap<(hash160::Hash, TapLeafHash), (Pk, bitcoin::taproot::Signature)>
260}
261
262impl<'a, Pk: MiniscriptKey + ToPublicKey, S: Satisfier<Pk>> Satisfier<Pk> for &'a S {
263    fn lookup_ecdsa_sig(&self, p: &Pk) -> Option<bitcoin::ecdsa::Signature> {
264        (**self).lookup_ecdsa_sig(p)
265    }
266
267    fn lookup_tap_leaf_script_sig(
268        &self,
269        p: &Pk,
270        h: &TapLeafHash,
271    ) -> Option<bitcoin::taproot::Signature> {
272        (**self).lookup_tap_leaf_script_sig(p, h)
273    }
274
275    fn lookup_raw_pkh_pk(&self, pkh: &hash160::Hash) -> Option<bitcoin::PublicKey> {
276        (**self).lookup_raw_pkh_pk(pkh)
277    }
278
279    fn lookup_raw_pkh_x_only_pk(&self, pkh: &hash160::Hash) -> Option<XOnlyPublicKey> {
280        (**self).lookup_raw_pkh_x_only_pk(pkh)
281    }
282
283    fn lookup_raw_pkh_ecdsa_sig(
284        &self,
285        pkh: &hash160::Hash,
286    ) -> Option<(bitcoin::PublicKey, bitcoin::ecdsa::Signature)> {
287        (**self).lookup_raw_pkh_ecdsa_sig(pkh)
288    }
289
290    fn lookup_tap_key_spend_sig(&self) -> Option<bitcoin::taproot::Signature> {
291        (**self).lookup_tap_key_spend_sig()
292    }
293
294    fn lookup_raw_pkh_tap_leaf_script_sig(
295        &self,
296        pkh: &(hash160::Hash, TapLeafHash),
297    ) -> Option<(XOnlyPublicKey, bitcoin::taproot::Signature)> {
298        (**self).lookup_raw_pkh_tap_leaf_script_sig(pkh)
299    }
300
301    fn lookup_tap_control_block_map(
302        &self,
303    ) -> Option<&BTreeMap<ControlBlock, (bitcoin::ScriptBuf, LeafVersion)>> {
304        (**self).lookup_tap_control_block_map()
305    }
306
307    fn lookup_sha256(&self, h: &Pk::Sha256) -> Option<Preimage32> { (**self).lookup_sha256(h) }
308
309    fn lookup_hash256(&self, h: &Pk::Hash256) -> Option<Preimage32> { (**self).lookup_hash256(h) }
310
311    fn lookup_ripemd160(&self, h: &Pk::Ripemd160) -> Option<Preimage32> {
312        (**self).lookup_ripemd160(h)
313    }
314
315    fn lookup_hash160(&self, h: &Pk::Hash160) -> Option<Preimage32> { (**self).lookup_hash160(h) }
316
317    fn check_older(&self, t: relative::LockTime) -> bool { (**self).check_older(t) }
318
319    fn check_after(&self, n: absolute::LockTime) -> bool { (**self).check_after(n) }
320}
321
322impl<'a, Pk: MiniscriptKey + ToPublicKey, S: Satisfier<Pk>> Satisfier<Pk> for &'a mut S {
323    fn lookup_ecdsa_sig(&self, p: &Pk) -> Option<bitcoin::ecdsa::Signature> {
324        (**self).lookup_ecdsa_sig(p)
325    }
326
327    fn lookup_tap_leaf_script_sig(
328        &self,
329        p: &Pk,
330        h: &TapLeafHash,
331    ) -> Option<bitcoin::taproot::Signature> {
332        (**self).lookup_tap_leaf_script_sig(p, h)
333    }
334
335    fn lookup_tap_key_spend_sig(&self) -> Option<bitcoin::taproot::Signature> {
336        (**self).lookup_tap_key_spend_sig()
337    }
338
339    fn lookup_raw_pkh_pk(&self, pkh: &hash160::Hash) -> Option<bitcoin::PublicKey> {
340        (**self).lookup_raw_pkh_pk(pkh)
341    }
342
343    fn lookup_raw_pkh_x_only_pk(&self, pkh: &hash160::Hash) -> Option<XOnlyPublicKey> {
344        (**self).lookup_raw_pkh_x_only_pk(pkh)
345    }
346
347    fn lookup_raw_pkh_ecdsa_sig(
348        &self,
349        pkh: &hash160::Hash,
350    ) -> Option<(bitcoin::PublicKey, bitcoin::ecdsa::Signature)> {
351        (**self).lookup_raw_pkh_ecdsa_sig(pkh)
352    }
353
354    fn lookup_raw_pkh_tap_leaf_script_sig(
355        &self,
356        pkh: &(hash160::Hash, TapLeafHash),
357    ) -> Option<(XOnlyPublicKey, bitcoin::taproot::Signature)> {
358        (**self).lookup_raw_pkh_tap_leaf_script_sig(pkh)
359    }
360
361    fn lookup_tap_control_block_map(
362        &self,
363    ) -> Option<&BTreeMap<ControlBlock, (bitcoin::ScriptBuf, LeafVersion)>> {
364        (**self).lookup_tap_control_block_map()
365    }
366
367    fn lookup_sha256(&self, h: &Pk::Sha256) -> Option<Preimage32> { (**self).lookup_sha256(h) }
368
369    fn lookup_hash256(&self, h: &Pk::Hash256) -> Option<Preimage32> { (**self).lookup_hash256(h) }
370
371    fn lookup_ripemd160(&self, h: &Pk::Ripemd160) -> Option<Preimage32> {
372        (**self).lookup_ripemd160(h)
373    }
374
375    fn lookup_hash160(&self, h: &Pk::Hash160) -> Option<Preimage32> { (**self).lookup_hash160(h) }
376
377    fn check_older(&self, t: relative::LockTime) -> bool { (**self).check_older(t) }
378
379    fn check_after(&self, n: absolute::LockTime) -> bool { (**self).check_after(n) }
380}
381
382macro_rules! impl_tuple_satisfier {
383    ($($ty:ident),*) => {
384        #[allow(non_snake_case)]
385        impl<$($ty,)* Pk> Satisfier<Pk> for ($($ty,)*)
386        where
387            Pk: MiniscriptKey + ToPublicKey,
388            $($ty: Satisfier< Pk>,)*
389        {
390            fn lookup_ecdsa_sig(&self, key: &Pk) -> Option<bitcoin::ecdsa::Signature> {
391                let &($(ref $ty,)*) = self;
392                $(
393                    if let Some(result) = $ty.lookup_ecdsa_sig(key) {
394                        return Some(result);
395                    }
396                )*
397                None
398            }
399
400            fn lookup_tap_key_spend_sig(&self) -> Option<bitcoin::taproot::Signature> {
401                let &($(ref $ty,)*) = self;
402                $(
403                    if let Some(result) = $ty.lookup_tap_key_spend_sig() {
404                        return Some(result);
405                    }
406                )*
407                None
408            }
409
410            fn lookup_tap_leaf_script_sig(&self, key: &Pk, h: &TapLeafHash) -> Option<bitcoin::taproot::Signature> {
411                let &($(ref $ty,)*) = self;
412                $(
413                    if let Some(result) = $ty.lookup_tap_leaf_script_sig(key, h) {
414                        return Some(result);
415                    }
416                )*
417                None
418            }
419
420            fn lookup_raw_pkh_ecdsa_sig(
421                &self,
422                key_hash: &hash160::Hash,
423            ) -> Option<(bitcoin::PublicKey, bitcoin::ecdsa::Signature)> {
424                let &($(ref $ty,)*) = self;
425                $(
426                    if let Some(result) = $ty.lookup_raw_pkh_ecdsa_sig(key_hash) {
427                        return Some(result);
428                    }
429                )*
430                None
431            }
432
433            fn lookup_raw_pkh_tap_leaf_script_sig(
434                &self,
435                key_hash: &(hash160::Hash, TapLeafHash),
436            ) -> Option<(XOnlyPublicKey, bitcoin::taproot::Signature)> {
437                let &($(ref $ty,)*) = self;
438                $(
439                    if let Some(result) = $ty.lookup_raw_pkh_tap_leaf_script_sig(key_hash) {
440                        return Some(result);
441                    }
442                )*
443                None
444            }
445
446            fn lookup_raw_pkh_pk(
447                &self,
448                key_hash: &hash160::Hash,
449            ) -> Option<bitcoin::PublicKey> {
450                let &($(ref $ty,)*) = self;
451                $(
452                    if let Some(result) = $ty.lookup_raw_pkh_pk(key_hash) {
453                        return Some(result);
454                    }
455                )*
456                None
457            }
458            fn lookup_raw_pkh_x_only_pk(
459                &self,
460                key_hash: &hash160::Hash,
461            ) -> Option<XOnlyPublicKey> {
462                let &($(ref $ty,)*) = self;
463                $(
464                    if let Some(result) = $ty.lookup_raw_pkh_x_only_pk(key_hash) {
465                        return Some(result);
466                    }
467                )*
468                None
469            }
470
471            fn lookup_tap_control_block_map(
472                &self,
473            ) -> Option<&BTreeMap<ControlBlock, (bitcoin::ScriptBuf, LeafVersion)>> {
474                let &($(ref $ty,)*) = self;
475                $(
476                    if let Some(result) = $ty.lookup_tap_control_block_map() {
477                        return Some(result);
478                    }
479                )*
480                None
481            }
482
483            fn lookup_sha256(&self, h: &Pk::Sha256) -> Option<Preimage32> {
484                let &($(ref $ty,)*) = self;
485                $(
486                    if let Some(result) = $ty.lookup_sha256(h) {
487                        return Some(result);
488                    }
489                )*
490                None
491            }
492
493            fn lookup_hash256(&self, h: &Pk::Hash256) -> Option<Preimage32> {
494                let &($(ref $ty,)*) = self;
495                $(
496                    if let Some(result) = $ty.lookup_hash256(h) {
497                        return Some(result);
498                    }
499                )*
500                None
501            }
502
503            fn lookup_ripemd160(&self, h: &Pk::Ripemd160) -> Option<Preimage32> {
504                let &($(ref $ty,)*) = self;
505                $(
506                    if let Some(result) = $ty.lookup_ripemd160(h) {
507                        return Some(result);
508                    }
509                )*
510                None
511            }
512
513            fn lookup_hash160(&self, h: &Pk::Hash160) -> Option<Preimage32> {
514                let &($(ref $ty,)*) = self;
515                $(
516                    if let Some(result) = $ty.lookup_hash160(h) {
517                        return Some(result);
518                    }
519                )*
520                None
521            }
522
523            fn check_older(&self, n: relative::LockTime) -> bool {
524                let &($(ref $ty,)*) = self;
525                $(
526                    if $ty.check_older(n) {
527                        return true;
528                    }
529                )*
530                false
531            }
532
533            fn check_after(&self, n: absolute::LockTime) -> bool {
534                let &($(ref $ty,)*) = self;
535                $(
536                    if $ty.check_after(n) {
537                        return true;
538                    }
539                )*
540                false
541            }
542        }
543    }
544}
545
546impl_tuple_satisfier!(A);
547impl_tuple_satisfier!(A, B);
548impl_tuple_satisfier!(A, B, C);
549impl_tuple_satisfier!(A, B, C, D);
550impl_tuple_satisfier!(A, B, C, D, E);
551impl_tuple_satisfier!(A, B, C, D, E, F);
552impl_tuple_satisfier!(A, B, C, D, E, F, G);
553impl_tuple_satisfier!(A, B, C, D, E, F, G, H);
554
555#[derive(Debug, Clone, PartialEq, Eq, Hash)]
556/// Type of schnorr signature to produce
557pub enum SchnorrSigType {
558    /// Key spend signature
559    KeySpend {
560        /// Merkle root to tweak the key, if present
561        merkle_root: Option<TapNodeHash>,
562    },
563    /// Script spend signature
564    ScriptSpend {
565        /// Leaf hash of the script
566        leaf_hash: TapLeafHash,
567    },
568}
569
570#[derive(Debug, Clone, PartialEq, Eq, Hash)]
571/// Placeholder for some data in a [`Plan`]
572///
573/// [`Plan`]: crate::plan::Plan
574pub enum Placeholder<Pk: MiniscriptKey> {
575    /// Public key and its size
576    Pubkey(Pk, usize),
577    /// Public key hash and public key size
578    PubkeyHash(hash160::Hash, usize),
579    /// ECDSA signature given the raw pubkey
580    EcdsaSigPk(Pk),
581    /// ECDSA signature given the pubkey hash
582    EcdsaSigPkHash(hash160::Hash),
583    /// Schnorr signature and its size
584    SchnorrSigPk(Pk, SchnorrSigType, usize),
585    /// Schnorr signature given the pubkey hash, the tapleafhash, and the sig size
586    SchnorrSigPkHash(hash160::Hash, TapLeafHash, usize),
587    /// SHA-256 preimage
588    Sha256Preimage(Pk::Sha256),
589    /// HASH256 preimage
590    Hash256Preimage(Pk::Hash256),
591    /// RIPEMD160 preimage
592    Ripemd160Preimage(Pk::Ripemd160),
593    /// HASH160 preimage
594    Hash160Preimage(Pk::Hash160),
595    /// Hash dissatisfaction (32 bytes of 0x00)
596    HashDissatisfaction,
597    /// OP_1
598    PushOne,
599    /// \<empty item\>
600    PushZero,
601    /// Taproot leaf script
602    TapScript(ScriptBuf),
603    /// Taproot control block
604    TapControlBlock(ControlBlock),
605}
606
607impl<Pk: MiniscriptKey> fmt::Display for Placeholder<Pk> {
608    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
609        use Placeholder::*;
610        match self {
611            Pubkey(pk, size) => write!(f, "Pubkey(pk: {}, size: {})", pk, size),
612            PubkeyHash(hash, size) => write!(f, "PubkeyHash(hash: {}, size: {})", hash, size),
613            EcdsaSigPk(pk) => write!(f, "EcdsaSigPk(pk: {})", pk),
614            EcdsaSigPkHash(hash) => write!(f, "EcdsaSigPkHash(pkh: {})", hash),
615            SchnorrSigPk(pk, tap_leaf_hash, size) => write!(
616                f,
617                "SchnorrSig(pk: {}, tap_leaf_hash: {:?}, size: {})",
618                pk, tap_leaf_hash, size
619            ),
620            SchnorrSigPkHash(pkh, tap_leaf_hash, size) => write!(
621                f,
622                "SchnorrSigPkHash(pkh: {}, tap_leaf_hash: {:?}, size: {})",
623                pkh, tap_leaf_hash, size
624            ),
625            Sha256Preimage(hash) => write!(f, "Sha256Preimage(hash: {})", hash),
626            Hash256Preimage(hash) => write!(f, "Hash256Preimage(hash: {})", hash),
627            Ripemd160Preimage(hash) => write!(f, "Ripemd160Preimage(hash: {})", hash),
628            Hash160Preimage(hash) => write!(f, "Hash160Preimage(hash: {})", hash),
629            HashDissatisfaction => write!(f, "HashDissatisfaction"),
630            PushOne => write!(f, "PushOne"),
631            PushZero => write!(f, "PushZero"),
632            TapScript(script) => write!(f, "TapScript(script: {})", script),
633            TapControlBlock(control_block) => write!(
634                f,
635                "TapControlBlock(control_block: {})",
636                bitcoin::consensus::encode::serialize_hex(&control_block.serialize())
637            ),
638        }
639    }
640}
641
642impl<Pk: MiniscriptKey + ToPublicKey> Placeholder<Pk> {
643    /// Replaces the placeholders with the information given by the satisfier
644    pub fn satisfy_self<Sat: Satisfier<Pk>>(&self, sat: &Sat) -> Option<Vec<u8>> {
645        match self {
646            Placeholder::Pubkey(pk, size) => {
647                if *size == 33 {
648                    Some(pk.to_x_only_pubkey().serialize().to_vec())
649                } else {
650                    Some(pk.to_public_key().to_bytes())
651                }
652            }
653            Placeholder::PubkeyHash(pkh, size) => sat
654                .lookup_raw_pkh_pk(pkh)
655                .map(|p| p.to_public_key())
656                .or(sat.lookup_raw_pkh_ecdsa_sig(pkh).map(|(p, _)| p))
657                .map(|pk| {
658                    let pk = pk.to_bytes();
659                    // We have to add a 1-byte OP_PUSH
660                    debug_assert!(1 + pk.len() == *size);
661                    pk
662                }),
663            Placeholder::Hash256Preimage(h) => sat.lookup_hash256(h).map(|p| p.to_vec()),
664            Placeholder::Sha256Preimage(h) => sat.lookup_sha256(h).map(|p| p.to_vec()),
665            Placeholder::Hash160Preimage(h) => sat.lookup_hash160(h).map(|p| p.to_vec()),
666            Placeholder::Ripemd160Preimage(h) => sat.lookup_ripemd160(h).map(|p| p.to_vec()),
667            Placeholder::EcdsaSigPk(pk) => sat.lookup_ecdsa_sig(pk).map(|s| s.to_vec()),
668            Placeholder::EcdsaSigPkHash(pkh) => {
669                sat.lookup_raw_pkh_ecdsa_sig(pkh).map(|(_, s)| s.to_vec())
670            }
671            Placeholder::SchnorrSigPk(pk, SchnorrSigType::ScriptSpend { leaf_hash }, size) => sat
672                .lookup_tap_leaf_script_sig(pk, leaf_hash)
673                .map(|s| s.to_vec())
674                .map(|s| {
675                    debug_assert!(s.len() == *size);
676                    s
677                }),
678            Placeholder::SchnorrSigPk(_, _, size) => {
679                sat.lookup_tap_key_spend_sig().map(|s| s.to_vec()).map(|s| {
680                    debug_assert!(s.len() == *size);
681                    s
682                })
683            }
684            Placeholder::SchnorrSigPkHash(pkh, tap_leaf_hash, size) => sat
685                .lookup_raw_pkh_tap_leaf_script_sig(&(*pkh, *tap_leaf_hash))
686                .map(|(_, s)| {
687                    let sig = s.to_vec();
688                    debug_assert!(sig.len() == *size);
689                    sig
690                }),
691            Placeholder::HashDissatisfaction => Some(vec![0; 32]),
692            Placeholder::PushZero => Some(vec![]),
693            Placeholder::PushOne => Some(vec![1]),
694            Placeholder::TapScript(s) => Some(s.to_bytes()),
695            Placeholder::TapControlBlock(cb) => Some(cb.serialize()),
696        }
697    }
698}
699
700/// A witness, if available, for a Miniscript fragment
701#[derive(Clone, PartialEq, Eq, Debug, Hash)]
702pub enum Witness<T> {
703    /// Witness Available and the value of the witness
704    Stack(Vec<T>),
705    /// Third party can possibly satisfy the fragment but we cannot
706    /// Witness Unavailable
707    Unavailable,
708    /// No third party can produce a satisfaction without private key
709    /// Witness Impossible
710    Impossible,
711}
712
713impl<Pk: MiniscriptKey> PartialOrd for Witness<Placeholder<Pk>> {
714    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { Some(self.cmp(other)) }
715}
716
717impl<Pk: MiniscriptKey> Ord for Witness<Placeholder<Pk>> {
718    fn cmp(&self, other: &Self) -> cmp::Ordering {
719        match (self, other) {
720            (Witness::Stack(v1), Witness::Stack(v2)) => {
721                let w1 = witness_size(v1);
722                let w2 = witness_size(v2);
723                w1.cmp(&w2)
724            }
725            (Witness::Stack(_), _) => cmp::Ordering::Less,
726            (_, Witness::Stack(_)) => cmp::Ordering::Greater,
727            (Witness::Impossible, Witness::Unavailable) => cmp::Ordering::Less,
728            (Witness::Unavailable, Witness::Impossible) => cmp::Ordering::Greater,
729            (Witness::Impossible, Witness::Impossible) => cmp::Ordering::Equal,
730            (Witness::Unavailable, Witness::Unavailable) => cmp::Ordering::Equal,
731        }
732    }
733}
734
735impl<Pk: MiniscriptKey + ToPublicKey> Witness<Placeholder<Pk>> {
736    /// Turn a signature into (part of) a satisfaction
737    fn signature<S: AssetProvider<Pk>, Ctx: ScriptContext>(
738        sat: &S,
739        pk: &Pk,
740        leaf_hash: &TapLeafHash,
741    ) -> Self {
742        match Ctx::sig_type() {
743            super::context::SigType::Ecdsa => {
744                if sat.provider_lookup_ecdsa_sig(pk) {
745                    Witness::Stack(vec![Placeholder::EcdsaSigPk(pk.clone())])
746                } else {
747                    // Signatures cannot be forged
748                    Witness::Impossible
749                }
750            }
751            super::context::SigType::Schnorr => {
752                match sat.provider_lookup_tap_leaf_script_sig(pk, leaf_hash) {
753                    Some(size) => Witness::Stack(vec![Placeholder::SchnorrSigPk(
754                        pk.clone(),
755                        SchnorrSigType::ScriptSpend { leaf_hash: *leaf_hash },
756                        size,
757                    )]),
758                    // Signatures cannot be forged
759                    None => Witness::Impossible,
760                }
761            }
762        }
763    }
764
765    /// Turn a public key related to a pkh into (part of) a satisfaction
766    fn pkh_public_key<S: AssetProvider<Pk>, Ctx: ScriptContext>(
767        sat: &S,
768        pkh: &hash160::Hash,
769    ) -> Self {
770        // public key hashes are assumed to be unavailable
771        // instead of impossible since it is the same as pub-key hashes
772        match Ctx::sig_type() {
773            SigType::Ecdsa => match sat.provider_lookup_raw_pkh_pk(pkh) {
774                Some(pk) => Witness::Stack(vec![Placeholder::PubkeyHash(*pkh, Ctx::pk_len(&pk))]),
775                None => Witness::Unavailable,
776            },
777            SigType::Schnorr => match sat.provider_lookup_raw_pkh_x_only_pk(pkh) {
778                Some(pk) => Witness::Stack(vec![Placeholder::PubkeyHash(*pkh, Ctx::pk_len(&pk))]),
779                None => Witness::Unavailable,
780            },
781        }
782    }
783
784    /// Turn a key/signature pair related to a pkh into (part of) a satisfaction
785    fn pkh_signature<S: AssetProvider<Pk>, Ctx: ScriptContext>(
786        sat: &S,
787        pkh: &hash160::Hash,
788        leaf_hash: &TapLeafHash,
789    ) -> Self {
790        match Ctx::sig_type() {
791            SigType::Ecdsa => match sat.provider_lookup_raw_pkh_ecdsa_sig(pkh) {
792                Some(pk) => Witness::Stack(vec![
793                    Placeholder::EcdsaSigPkHash(*pkh),
794                    Placeholder::PubkeyHash(*pkh, Ctx::pk_len(&pk)),
795                ]),
796                None => Witness::Impossible,
797            },
798            SigType::Schnorr => {
799                match sat.provider_lookup_raw_pkh_tap_leaf_script_sig(&(*pkh, *leaf_hash)) {
800                    Some((pk, size)) => Witness::Stack(vec![
801                        Placeholder::SchnorrSigPkHash(*pkh, *leaf_hash, size),
802                        Placeholder::PubkeyHash(*pkh, Ctx::pk_len(&pk)),
803                    ]),
804                    None => Witness::Impossible,
805                }
806            }
807        }
808    }
809
810    /// Turn a hash preimage into (part of) a satisfaction
811    fn ripemd160_preimage<S: AssetProvider<Pk>>(sat: &S, h: &Pk::Ripemd160) -> Self {
812        if sat.provider_lookup_ripemd160(h) {
813            Witness::Stack(vec![Placeholder::Ripemd160Preimage(h.clone())])
814        // Note hash preimages are unavailable instead of impossible
815        } else {
816            Witness::Unavailable
817        }
818    }
819
820    /// Turn a hash preimage into (part of) a satisfaction
821    fn hash160_preimage<S: AssetProvider<Pk>>(sat: &S, h: &Pk::Hash160) -> Self {
822        if sat.provider_lookup_hash160(h) {
823            Witness::Stack(vec![Placeholder::Hash160Preimage(h.clone())])
824        // Note hash preimages are unavailable instead of impossible
825        } else {
826            Witness::Unavailable
827        }
828    }
829
830    /// Turn a hash preimage into (part of) a satisfaction
831    fn sha256_preimage<S: AssetProvider<Pk>>(sat: &S, h: &Pk::Sha256) -> Self {
832        if sat.provider_lookup_sha256(h) {
833            Witness::Stack(vec![Placeholder::Sha256Preimage(h.clone())])
834        // Note hash preimages are unavailable instead of impossible
835        } else {
836            Witness::Unavailable
837        }
838    }
839
840    /// Turn a hash preimage into (part of) a satisfaction
841    fn hash256_preimage<S: AssetProvider<Pk>>(sat: &S, h: &Pk::Hash256) -> Self {
842        if sat.provider_lookup_hash256(h) {
843            Witness::Stack(vec![Placeholder::Hash256Preimage(h.clone())])
844        // Note hash preimages are unavailable instead of impossible
845        } else {
846            Witness::Unavailable
847        }
848    }
849}
850
851impl<Pk: MiniscriptKey> Witness<Placeholder<Pk>> {
852    /// Produce something like a 32-byte 0 push
853    fn hash_dissatisfaction() -> Self { Witness::Stack(vec![Placeholder::HashDissatisfaction]) }
854
855    /// Construct a satisfaction equivalent to an empty stack
856    fn empty() -> Self { Witness::Stack(vec![]) }
857
858    /// Construct a satisfaction equivalent to `OP_1`
859    fn push_1() -> Self { Witness::Stack(vec![Placeholder::PushOne]) }
860
861    /// Construct a satisfaction equivalent to a single empty push
862    fn push_0() -> Self { Witness::Stack(vec![Placeholder::PushZero]) }
863
864    /// Concatenate, or otherwise combine, two satisfactions
865    fn combine(one: Self, two: Self) -> Self {
866        match (one, two) {
867            (Witness::Impossible, _) | (_, Witness::Impossible) => Witness::Impossible,
868            (Witness::Unavailable, _) | (_, Witness::Unavailable) => Witness::Unavailable,
869            (Witness::Stack(mut a), Witness::Stack(b)) => {
870                a.extend(b);
871                Witness::Stack(a)
872            }
873        }
874    }
875}
876
877/// A (dis)satisfaction of a Miniscript fragment
878#[derive(Clone, PartialEq, Eq, Debug, Hash)]
879pub struct Satisfaction<T> {
880    /// The actual witness stack
881    pub stack: Witness<T>,
882    /// Whether or not this (dis)satisfaction has a signature somewhere
883    /// in it
884    pub has_sig: bool,
885    /// The absolute timelock used by this satisfaction
886    pub absolute_timelock: Option<AbsLockTime>,
887    /// The relative timelock used by this satisfaction
888    pub relative_timelock: Option<RelLockTime>,
889}
890
891impl<Pk: MiniscriptKey + ToPublicKey> Satisfaction<Placeholder<Pk>> {
892    /// The empty satisfaction.
893    ///
894    /// This has the property that, when concatenated on either side with another satisfaction
895    /// X, the result will be X.
896    fn empty() -> Self {
897        Satisfaction {
898            has_sig: false,
899            relative_timelock: None,
900            absolute_timelock: None,
901            stack: Witness::Stack(vec![]),
902        }
903    }
904
905    /// Forms a satisfaction which is the concatenation of two satisfactions, with `other`'s
906    /// stack before `self`'s.
907    ///
908    /// This order allows callers to write `left.concatenate_rev(right)` which feels more
909    /// natural than the opposite order, and more importantly, allows this method to be
910    /// used when folding over an iterator of multiple satisfactions.
911    fn concatenate_rev(self, other: Self) -> Self {
912        Satisfaction {
913            has_sig: self.has_sig || other.has_sig,
914            relative_timelock: cmp::max(self.relative_timelock, other.relative_timelock),
915            absolute_timelock: cmp::max(self.absolute_timelock, other.absolute_timelock),
916            stack: Witness::combine(other.stack, self.stack),
917        }
918    }
919
920    pub(crate) fn build_template<P, Ctx>(
921        term: &Terminal<Pk, Ctx>,
922        provider: &P,
923        root_has_sig: bool,
924        leaf_hash: &TapLeafHash,
925    ) -> Self
926    where
927        Ctx: ScriptContext,
928        P: AssetProvider<Pk>,
929    {
930        Self::satisfy_helper(
931            term,
932            provider,
933            root_has_sig,
934            leaf_hash,
935            &mut Satisfaction::minimum,
936            &mut Satisfaction::thresh,
937        )
938    }
939
940    pub(crate) fn build_template_mall<P, Ctx>(
941        term: &Terminal<Pk, Ctx>,
942        provider: &P,
943        root_has_sig: bool,
944        leaf_hash: &TapLeafHash,
945    ) -> Self
946    where
947        Ctx: ScriptContext,
948        P: AssetProvider<Pk>,
949    {
950        Self::satisfy_helper(
951            term,
952            provider,
953            root_has_sig,
954            leaf_hash,
955            &mut Satisfaction::minimum_mall,
956            &mut Satisfaction::thresh_mall,
957        )
958    }
959
960    // produce a non-malleable satisafaction for thesh frag
961    fn thresh<Ctx, Sat, F>(
962        thresh: &Threshold<Arc<Miniscript<Pk, Ctx>>, 0>,
963        stfr: &Sat,
964        root_has_sig: bool,
965        leaf_hash: &TapLeafHash,
966        min_fn: &mut F,
967    ) -> Self
968    where
969        Ctx: ScriptContext,
970        Sat: AssetProvider<Pk>,
971        F: FnMut(
972            Satisfaction<Placeholder<Pk>>,
973            Satisfaction<Placeholder<Pk>>,
974        ) -> Satisfaction<Placeholder<Pk>>,
975    {
976        let mut sats = thresh
977            .iter()
978            .map(|s| {
979                Self::satisfy_helper(
980                    &s.node,
981                    stfr,
982                    root_has_sig,
983                    leaf_hash,
984                    min_fn,
985                    &mut Self::thresh,
986                )
987            })
988            .collect::<Vec<_>>();
989        // Start with the to-return stack set to all dissatisfactions
990        let mut ret_stack = thresh
991            .iter()
992            .map(|s| {
993                Self::dissatisfy_helper(
994                    &s.node,
995                    stfr,
996                    root_has_sig,
997                    leaf_hash,
998                    min_fn,
999                    &mut Self::thresh,
1000                )
1001            })
1002            .collect::<Vec<_>>();
1003
1004        // Sort everything by (sat cost - dissat cost), except that
1005        // satisfactions without signatures beat satisfactions with
1006        // signatures
1007        let mut sat_indices = (0..thresh.n()).collect::<Vec<_>>();
1008        sat_indices.sort_by_key(|&i| {
1009            let stack_weight = match (&sats[i].stack, &ret_stack[i].stack) {
1010                (&Witness::Unavailable, _) | (&Witness::Impossible, _) => i64::MAX,
1011                // This can only be the case when we have PkH without the corresponding
1012                // Pubkey.
1013                (_, &Witness::Unavailable) | (_, &Witness::Impossible) => i64::MIN,
1014                (Witness::Stack(s), Witness::Stack(d)) => {
1015                    witness_size(s) as i64 - witness_size(d) as i64
1016                }
1017            };
1018            let is_impossible = sats[i].stack == Witness::Impossible;
1019            // First consider the candidates that are not impossible to satisfy
1020            // by any party. Among those first consider the ones that have no sig
1021            // because third party can malleate them if they are not chosen.
1022            // Lastly, choose by weight.
1023            (is_impossible, sats[i].has_sig, stack_weight)
1024        });
1025
1026        for i in 0..thresh.k() {
1027            mem::swap(&mut ret_stack[sat_indices[i]], &mut sats[sat_indices[i]]);
1028        }
1029
1030        // We preferably take satisfactions that are not impossible
1031        // If we cannot find `k` satisfactions that are not impossible
1032        // then the threshold branch is impossible to satisfy
1033        // For example, the fragment thresh(2, hash, 0, 0, 0)
1034        // is has an impossible witness
1035        if sats[sat_indices[thresh.k() - 1]].stack == Witness::Impossible {
1036            Satisfaction {
1037                stack: Witness::Impossible,
1038                // If the witness is impossible, we don't care about the
1039                // has_sig flag, nor about the timelocks
1040                has_sig: false,
1041                relative_timelock: None,
1042                absolute_timelock: None,
1043            }
1044        }
1045        // We are now guaranteed that all elements in `k` satisfactions
1046        // are not impossible(we sort by is_impossible bool).
1047        // The above loop should have taken everything without a sig
1048        // (since those were sorted higher than non-sigs). If there
1049        // are remaining non-sig satisfactions this indicates a
1050        // malleability vector
1051        // For example, the fragment thresh(2, hash, hash, 0, 0)
1052        // is uniquely satisfyiable because there is no satisfaction
1053        // for the 0 fragment
1054        else if !sats[sat_indices[thresh.k()]].has_sig
1055            && sats[sat_indices[thresh.k()]].stack != Witness::Impossible
1056        {
1057            // All arguments should be `d`, so dissatisfactions have no
1058            // signatures; and in this branch we assume too many weak
1059            // arguments, so none of the satisfactions should have
1060            // signatures either.
1061            for sat in &ret_stack {
1062                assert!(!sat.has_sig);
1063            }
1064            Satisfaction {
1065                stack: Witness::Unavailable,
1066                has_sig: false,
1067                relative_timelock: None,
1068                absolute_timelock: None,
1069            }
1070        } else {
1071            // Otherwise flatten everything out
1072            ret_stack
1073                .into_iter()
1074                .fold(Satisfaction::empty(), Satisfaction::concatenate_rev)
1075        }
1076    }
1077
1078    // produce a possily malleable satisafaction for thesh frag
1079    fn thresh_mall<Ctx, Sat, F>(
1080        thresh: &Threshold<Arc<Miniscript<Pk, Ctx>>, 0>,
1081        stfr: &Sat,
1082        root_has_sig: bool,
1083        leaf_hash: &TapLeafHash,
1084        min_fn: &mut F,
1085    ) -> Self
1086    where
1087        Ctx: ScriptContext,
1088        Sat: AssetProvider<Pk>,
1089        F: FnMut(
1090            Satisfaction<Placeholder<Pk>>,
1091            Satisfaction<Placeholder<Pk>>,
1092        ) -> Satisfaction<Placeholder<Pk>>,
1093    {
1094        let mut sats = thresh
1095            .iter()
1096            .map(|s| {
1097                Self::satisfy_helper(
1098                    &s.node,
1099                    stfr,
1100                    root_has_sig,
1101                    leaf_hash,
1102                    min_fn,
1103                    &mut Self::thresh_mall,
1104                )
1105            })
1106            .collect::<Vec<_>>();
1107        // Start with the to-return stack set to all dissatisfactions
1108        let mut ret_stack = thresh
1109            .iter()
1110            .map(|s| {
1111                Self::dissatisfy_helper(
1112                    &s.node,
1113                    stfr,
1114                    root_has_sig,
1115                    leaf_hash,
1116                    min_fn,
1117                    &mut Self::thresh_mall,
1118                )
1119            })
1120            .collect::<Vec<_>>();
1121
1122        // Sort everything by (sat cost - dissat cost), except that
1123        // satisfactions without signatures beat satisfactions with
1124        // signatures
1125        let mut sat_indices = (0..thresh.n()).collect::<Vec<_>>();
1126        sat_indices.sort_by_key(|&i| {
1127            // For malleable satifactions, directly choose smallest weights
1128            match (&sats[i].stack, &ret_stack[i].stack) {
1129                (&Witness::Unavailable, _) | (&Witness::Impossible, _) => i64::MAX,
1130                // This is only possible when one of the branches has PkH
1131                (_, &Witness::Unavailable) | (_, &Witness::Impossible) => i64::MIN,
1132                (Witness::Stack(s), Witness::Stack(d)) => {
1133                    witness_size(s) as i64 - witness_size(d) as i64
1134                }
1135            }
1136        });
1137
1138        // swap the satisfactions
1139        for i in 0..thresh.k() {
1140            mem::swap(&mut ret_stack[sat_indices[i]], &mut sats[sat_indices[i]]);
1141        }
1142
1143        // combine the witness
1144        // no non-malleability checks needed
1145        ret_stack
1146            .into_iter()
1147            .fold(Satisfaction::empty(), Satisfaction::concatenate_rev)
1148    }
1149
1150    fn minimum(sat1: Self, sat2: Self) -> Self {
1151        // If there is only one available satisfaction, we must choose that
1152        // regardless of has_sig marker.
1153        // This handles the case where both are impossible.
1154        match (&sat1.stack, &sat2.stack) {
1155            (&Witness::Impossible, _) => return sat2,
1156            (_, &Witness::Impossible) => return sat1,
1157            _ => {}
1158        }
1159        match (sat1.has_sig, sat2.has_sig) {
1160            // If neither option has a signature, this is a malleability
1161            // vector, so choose neither one.
1162            (false, false) => Satisfaction {
1163                stack: Witness::Unavailable,
1164                has_sig: false,
1165                relative_timelock: None,
1166                absolute_timelock: None,
1167            },
1168            // If only one has a signature, take the one that doesn't; a
1169            // third party could malleate by removing the signature, but
1170            // can't malleate if he'd have to add it
1171            (false, true) => Satisfaction {
1172                stack: sat1.stack,
1173                has_sig: false,
1174                relative_timelock: sat1.relative_timelock,
1175                absolute_timelock: sat1.absolute_timelock,
1176            },
1177            (true, false) => Satisfaction {
1178                stack: sat2.stack,
1179                has_sig: false,
1180                relative_timelock: sat2.relative_timelock,
1181                absolute_timelock: sat2.absolute_timelock,
1182            },
1183            // If both have a signature associated with them, choose the
1184            // cheaper one (where "cheaper" is defined such that available
1185            // things are cheaper than unavailable ones)
1186            (true, true) if sat1.stack < sat2.stack => Satisfaction {
1187                stack: sat1.stack,
1188                has_sig: true,
1189                relative_timelock: sat1.relative_timelock,
1190                absolute_timelock: sat1.absolute_timelock,
1191            },
1192            (true, true) => Satisfaction {
1193                stack: sat2.stack,
1194                has_sig: true,
1195                relative_timelock: sat2.relative_timelock,
1196                absolute_timelock: sat2.absolute_timelock,
1197            },
1198        }
1199    }
1200
1201    // calculate the minimum witness allowing witness malleability
1202    fn minimum_mall(sat1: Self, sat2: Self) -> Self {
1203        match (&sat1.stack, &sat2.stack) {
1204            // If there is only one possible satisfaction, use it regardless
1205            // of the other one
1206            (&Witness::Impossible, _) | (&Witness::Unavailable, _) => return sat2,
1207            (_, &Witness::Impossible) | (_, &Witness::Unavailable) => return sat1,
1208            _ => {}
1209        }
1210        let (stack, absolute_timelock, relative_timelock) = if sat1.stack < sat2.stack {
1211            (sat1.stack, sat1.absolute_timelock, sat1.relative_timelock)
1212        } else {
1213            (sat2.stack, sat2.absolute_timelock, sat2.relative_timelock)
1214        };
1215        Satisfaction {
1216            stack,
1217            // The fragment is has_sig only if both of the
1218            // fragments are has_sig
1219            has_sig: sat1.has_sig && sat2.has_sig,
1220            relative_timelock,
1221            absolute_timelock,
1222        }
1223    }
1224
1225    // produce a non-malleable satisfaction
1226    fn satisfy_helper<Ctx, Sat, F, G>(
1227        term: &Terminal<Pk, Ctx>,
1228        stfr: &Sat,
1229        root_has_sig: bool,
1230        leaf_hash: &TapLeafHash,
1231        min_fn: &mut F,
1232        thresh_fn: &mut G,
1233    ) -> Self
1234    where
1235        Ctx: ScriptContext,
1236        Sat: AssetProvider<Pk>,
1237        F: FnMut(
1238            Satisfaction<Placeholder<Pk>>,
1239            Satisfaction<Placeholder<Pk>>,
1240        ) -> Satisfaction<Placeholder<Pk>>,
1241        G: FnMut(
1242            &Threshold<Arc<Miniscript<Pk, Ctx>>, 0>,
1243            &Sat,
1244            bool,
1245            &TapLeafHash,
1246            &mut F,
1247        ) -> Satisfaction<Placeholder<Pk>>,
1248    {
1249        match *term {
1250            Terminal::PkK(ref pk) => Satisfaction {
1251                stack: Witness::signature::<_, Ctx>(stfr, pk, leaf_hash),
1252                has_sig: true,
1253                relative_timelock: None,
1254                absolute_timelock: None,
1255            },
1256            Terminal::PkH(ref pk) => {
1257                let wit = Witness::signature::<_, Ctx>(stfr, pk, leaf_hash);
1258                Satisfaction {
1259                    stack: Witness::combine(
1260                        wit,
1261                        Witness::Stack(vec![Placeholder::Pubkey(pk.clone(), Ctx::pk_len(pk))]),
1262                    ),
1263                    has_sig: true,
1264                    relative_timelock: None,
1265                    absolute_timelock: None,
1266                }
1267            }
1268            Terminal::RawPkH(ref pkh) => Satisfaction {
1269                stack: Witness::pkh_signature::<_, Ctx>(stfr, pkh, leaf_hash),
1270                has_sig: true,
1271                relative_timelock: None,
1272                absolute_timelock: None,
1273            },
1274            Terminal::After(t) => {
1275                let (stack, absolute_timelock) = if stfr.check_after(t.into()) {
1276                    (Witness::empty(), Some(t))
1277                } else if root_has_sig {
1278                    // If the root terminal has signature, the
1279                    // signature covers the nLockTime and nSequence
1280                    // values. The sender of the transaction should
1281                    // take care that it signs the value such that the
1282                    // timelock is not met
1283                    (Witness::Impossible, None)
1284                } else {
1285                    (Witness::Unavailable, None)
1286                };
1287                Satisfaction { stack, has_sig: false, relative_timelock: None, absolute_timelock }
1288            }
1289            Terminal::Older(t) => {
1290                let (stack, relative_timelock) = if stfr.check_older(t.into()) {
1291                    (Witness::empty(), Some(t))
1292                } else if root_has_sig {
1293                    // If the root terminal has signature, the
1294                    // signature covers the nLockTime and nSequence
1295                    // values. The sender of the transaction should
1296                    // take care that it signs the value such that the
1297                    // timelock is not met
1298                    (Witness::Impossible, None)
1299                } else {
1300                    (Witness::Unavailable, None)
1301                };
1302                Satisfaction { stack, has_sig: false, relative_timelock, absolute_timelock: None }
1303            }
1304            Terminal::Ripemd160(ref h) => Satisfaction {
1305                stack: Witness::ripemd160_preimage(stfr, h),
1306                has_sig: false,
1307                relative_timelock: None,
1308                absolute_timelock: None,
1309            },
1310            Terminal::Hash160(ref h) => Satisfaction {
1311                stack: Witness::hash160_preimage(stfr, h),
1312                has_sig: false,
1313                relative_timelock: None,
1314                absolute_timelock: None,
1315            },
1316            Terminal::Sha256(ref h) => Satisfaction {
1317                stack: Witness::sha256_preimage(stfr, h),
1318                has_sig: false,
1319                relative_timelock: None,
1320                absolute_timelock: None,
1321            },
1322            Terminal::Hash256(ref h) => Satisfaction {
1323                stack: Witness::hash256_preimage(stfr, h),
1324                has_sig: false,
1325                relative_timelock: None,
1326                absolute_timelock: None,
1327            },
1328            Terminal::True => Satisfaction {
1329                stack: Witness::empty(),
1330                has_sig: false,
1331                relative_timelock: None,
1332                absolute_timelock: None,
1333            },
1334            Terminal::False => Satisfaction {
1335                stack: Witness::Impossible,
1336                has_sig: false,
1337                relative_timelock: None,
1338                absolute_timelock: None,
1339            },
1340            Terminal::Alt(ref sub)
1341            | Terminal::Swap(ref sub)
1342            | Terminal::Check(ref sub)
1343            | Terminal::Verify(ref sub)
1344            | Terminal::NonZero(ref sub)
1345            | Terminal::ZeroNotEqual(ref sub) => {
1346                Self::satisfy_helper(&sub.node, stfr, root_has_sig, leaf_hash, min_fn, thresh_fn)
1347            }
1348            Terminal::DupIf(ref sub) => {
1349                let sat = Self::satisfy_helper(
1350                    &sub.node,
1351                    stfr,
1352                    root_has_sig,
1353                    leaf_hash,
1354                    min_fn,
1355                    thresh_fn,
1356                );
1357                Satisfaction {
1358                    stack: Witness::combine(sat.stack, Witness::push_1()),
1359                    has_sig: sat.has_sig,
1360                    relative_timelock: sat.relative_timelock,
1361                    absolute_timelock: sat.absolute_timelock,
1362                }
1363            }
1364            Terminal::AndV(ref l, ref r) | Terminal::AndB(ref l, ref r) => {
1365                let l_sat =
1366                    Self::satisfy_helper(&l.node, stfr, root_has_sig, leaf_hash, min_fn, thresh_fn);
1367                let r_sat =
1368                    Self::satisfy_helper(&r.node, stfr, root_has_sig, leaf_hash, min_fn, thresh_fn);
1369                l_sat.concatenate_rev(r_sat)
1370            }
1371            Terminal::AndOr(ref a, ref b, ref c) => {
1372                let a_sat =
1373                    Self::satisfy_helper(&a.node, stfr, root_has_sig, leaf_hash, min_fn, thresh_fn);
1374                let a_nsat = Self::dissatisfy_helper(
1375                    &a.node,
1376                    stfr,
1377                    root_has_sig,
1378                    leaf_hash,
1379                    min_fn,
1380                    thresh_fn,
1381                );
1382                let b_sat =
1383                    Self::satisfy_helper(&b.node, stfr, root_has_sig, leaf_hash, min_fn, thresh_fn);
1384                let c_sat =
1385                    Self::satisfy_helper(&c.node, stfr, root_has_sig, leaf_hash, min_fn, thresh_fn);
1386
1387                min_fn(a_sat.concatenate_rev(b_sat), a_nsat.concatenate_rev(c_sat))
1388            }
1389            Terminal::OrB(ref l, ref r) => {
1390                let l_sat =
1391                    Self::satisfy_helper(&l.node, stfr, root_has_sig, leaf_hash, min_fn, thresh_fn);
1392                let r_sat =
1393                    Self::satisfy_helper(&r.node, stfr, root_has_sig, leaf_hash, min_fn, thresh_fn);
1394                let l_nsat = Self::dissatisfy_helper(
1395                    &l.node,
1396                    stfr,
1397                    root_has_sig,
1398                    leaf_hash,
1399                    min_fn,
1400                    thresh_fn,
1401                );
1402                let r_nsat = Self::dissatisfy_helper(
1403                    &r.node,
1404                    stfr,
1405                    root_has_sig,
1406                    leaf_hash,
1407                    min_fn,
1408                    thresh_fn,
1409                );
1410
1411                assert!(!l_nsat.has_sig);
1412                assert!(!r_nsat.has_sig);
1413
1414                min_fn(
1415                    Satisfaction::concatenate_rev(l_nsat, r_sat),
1416                    Satisfaction::concatenate_rev(l_sat, r_nsat),
1417                )
1418            }
1419            Terminal::OrD(ref l, ref r) | Terminal::OrC(ref l, ref r) => {
1420                let l_sat =
1421                    Self::satisfy_helper(&l.node, stfr, root_has_sig, leaf_hash, min_fn, thresh_fn);
1422                let r_sat =
1423                    Self::satisfy_helper(&r.node, stfr, root_has_sig, leaf_hash, min_fn, thresh_fn);
1424                let l_nsat = Self::dissatisfy_helper(
1425                    &l.node,
1426                    stfr,
1427                    root_has_sig,
1428                    leaf_hash,
1429                    min_fn,
1430                    thresh_fn,
1431                );
1432
1433                assert!(!l_nsat.has_sig);
1434
1435                min_fn(l_sat, Satisfaction::concatenate_rev(l_nsat, r_sat))
1436            }
1437            Terminal::OrI(ref l, ref r) => {
1438                let l_sat =
1439                    Self::satisfy_helper(&l.node, stfr, root_has_sig, leaf_hash, min_fn, thresh_fn);
1440                let r_sat =
1441                    Self::satisfy_helper(&r.node, stfr, root_has_sig, leaf_hash, min_fn, thresh_fn);
1442                min_fn(
1443                    Satisfaction {
1444                        stack: Witness::combine(l_sat.stack, Witness::push_1()),
1445                        has_sig: l_sat.has_sig,
1446                        relative_timelock: l_sat.relative_timelock,
1447                        absolute_timelock: l_sat.absolute_timelock,
1448                    },
1449                    Satisfaction {
1450                        stack: Witness::combine(r_sat.stack, Witness::push_0()),
1451                        has_sig: r_sat.has_sig,
1452                        relative_timelock: r_sat.relative_timelock,
1453                        absolute_timelock: r_sat.absolute_timelock,
1454                    },
1455                )
1456            }
1457            Terminal::Thresh(ref thresh) => {
1458                if thresh.k() == thresh.n() {
1459                    // this is just an and
1460                    thresh
1461                        .iter()
1462                        .map(|s| {
1463                            Self::satisfy_helper(
1464                                &s.node,
1465                                stfr,
1466                                root_has_sig,
1467                                leaf_hash,
1468                                min_fn,
1469                                thresh_fn,
1470                            )
1471                        })
1472                        .fold(Satisfaction::empty(), Satisfaction::concatenate_rev)
1473                } else {
1474                    thresh_fn(thresh, stfr, root_has_sig, leaf_hash, min_fn)
1475                }
1476            }
1477            Terminal::Multi(ref thresh) => {
1478                // Collect all available signatures
1479                let mut sig_count = 0;
1480                let mut sigs = Vec::with_capacity(thresh.k());
1481                for pk in thresh.data() {
1482                    match Witness::signature::<_, Ctx>(stfr, pk, leaf_hash) {
1483                        Witness::Stack(sig) => {
1484                            sigs.push(sig);
1485                            sig_count += 1;
1486                        }
1487                        Witness::Impossible => {}
1488                        Witness::Unavailable => unreachable!(
1489                            "Signature satisfaction without witness must be impossible"
1490                        ),
1491                    }
1492                }
1493
1494                if sig_count < thresh.k() {
1495                    Satisfaction {
1496                        stack: Witness::Impossible,
1497                        has_sig: false,
1498                        relative_timelock: None,
1499                        absolute_timelock: None,
1500                    }
1501                } else {
1502                    // Throw away the most expensive ones
1503                    for _ in 0..sig_count - thresh.k() {
1504                        let max_idx = sigs
1505                            .iter()
1506                            .enumerate()
1507                            .max_by_key(|&(_, v)| v.len())
1508                            .unwrap()
1509                            .0;
1510                        sigs[max_idx] = vec![];
1511                    }
1512
1513                    Satisfaction {
1514                        stack: sigs.into_iter().fold(Witness::push_0(), |acc, sig| {
1515                            Witness::combine(acc, Witness::Stack(sig))
1516                        }),
1517                        has_sig: true,
1518                        relative_timelock: None,
1519                        absolute_timelock: None,
1520                    }
1521                }
1522            }
1523            Terminal::MultiA(ref thresh) => {
1524                // Collect all available signatures
1525                let mut sig_count = 0;
1526                let mut sigs = vec![vec![Placeholder::PushZero]; thresh.n()];
1527                for (i, pk) in thresh.iter().rev().enumerate() {
1528                    match Witness::signature::<_, Ctx>(stfr, pk, leaf_hash) {
1529                        Witness::Stack(sig) => {
1530                            sigs[i] = sig;
1531                            sig_count += 1;
1532                            // This a privacy issue, we are only selecting the first available
1533                            // sigs. Incase pk at pos 1 is not selected, we know we did not have access to it
1534                            // bitcoin core also implements the same logic for MULTISIG, so I am not bothering
1535                            // permuting the sigs for now
1536                            if sig_count == thresh.k() {
1537                                break;
1538                            }
1539                        }
1540                        Witness::Impossible => {}
1541                        Witness::Unavailable => unreachable!(
1542                            "Signature satisfaction without witness must be impossible"
1543                        ),
1544                    }
1545                }
1546
1547                if sig_count < thresh.k() {
1548                    Satisfaction {
1549                        stack: Witness::Impossible,
1550                        has_sig: false,
1551                        relative_timelock: None,
1552                        absolute_timelock: None,
1553                    }
1554                } else {
1555                    Satisfaction {
1556                        stack: sigs.into_iter().fold(Witness::empty(), |acc, sig| {
1557                            Witness::combine(acc, Witness::Stack(sig))
1558                        }),
1559                        has_sig: true,
1560                        relative_timelock: None,
1561                        absolute_timelock: None,
1562                    }
1563                }
1564            }
1565        }
1566    }
1567
1568    // Helper function to produce a dissatisfaction
1569    fn dissatisfy_helper<Ctx, Sat, F, G>(
1570        term: &Terminal<Pk, Ctx>,
1571        stfr: &Sat,
1572        root_has_sig: bool,
1573        leaf_hash: &TapLeafHash,
1574        min_fn: &mut F,
1575        thresh_fn: &mut G,
1576    ) -> Self
1577    where
1578        Ctx: ScriptContext,
1579        Sat: AssetProvider<Pk>,
1580        F: FnMut(
1581            Satisfaction<Placeholder<Pk>>,
1582            Satisfaction<Placeholder<Pk>>,
1583        ) -> Satisfaction<Placeholder<Pk>>,
1584        G: FnMut(
1585            &Threshold<Arc<Miniscript<Pk, Ctx>>, 0>,
1586            &Sat,
1587            bool,
1588            &TapLeafHash,
1589            &mut F,
1590        ) -> Satisfaction<Placeholder<Pk>>,
1591    {
1592        match *term {
1593            Terminal::PkK(..) => Satisfaction {
1594                stack: Witness::push_0(),
1595                has_sig: false,
1596                relative_timelock: None,
1597                absolute_timelock: None,
1598            },
1599            Terminal::PkH(ref pk) => Satisfaction {
1600                stack: Witness::combine(
1601                    Witness::push_0(),
1602                    Witness::Stack(vec![Placeholder::Pubkey(pk.clone(), Ctx::pk_len(pk))]),
1603                ),
1604                has_sig: false,
1605                relative_timelock: None,
1606                absolute_timelock: None,
1607            },
1608            Terminal::RawPkH(ref pkh) => Satisfaction {
1609                stack: Witness::combine(
1610                    Witness::push_0(),
1611                    Witness::pkh_public_key::<_, Ctx>(stfr, pkh),
1612                ),
1613                has_sig: false,
1614                relative_timelock: None,
1615                absolute_timelock: None,
1616            },
1617            Terminal::False => Satisfaction {
1618                stack: Witness::empty(),
1619                has_sig: false,
1620                relative_timelock: None,
1621                absolute_timelock: None,
1622            },
1623            Terminal::True
1624            | Terminal::Older(_)
1625            | Terminal::After(_)
1626            | Terminal::Verify(_)
1627            | Terminal::OrC(..) => Satisfaction {
1628                stack: Witness::Impossible,
1629                has_sig: false,
1630                relative_timelock: None,
1631                absolute_timelock: None,
1632            },
1633            Terminal::Sha256(_)
1634            | Terminal::Hash256(_)
1635            | Terminal::Ripemd160(_)
1636            | Terminal::Hash160(_) => Satisfaction {
1637                stack: Witness::hash_dissatisfaction(),
1638                has_sig: false,
1639                relative_timelock: None,
1640                absolute_timelock: None,
1641            },
1642            Terminal::Alt(ref sub)
1643            | Terminal::Swap(ref sub)
1644            | Terminal::Check(ref sub)
1645            | Terminal::ZeroNotEqual(ref sub) => {
1646                Self::dissatisfy_helper(&sub.node, stfr, root_has_sig, leaf_hash, min_fn, thresh_fn)
1647            }
1648            Terminal::DupIf(_) | Terminal::NonZero(_) => Satisfaction {
1649                stack: Witness::push_0(),
1650                has_sig: false,
1651                relative_timelock: None,
1652                absolute_timelock: None,
1653            },
1654            Terminal::AndV(ref v, ref other) => {
1655                let vsat =
1656                    Self::satisfy_helper(&v.node, stfr, root_has_sig, leaf_hash, min_fn, thresh_fn);
1657                let odissat = Self::dissatisfy_helper(
1658                    &other.node,
1659                    stfr,
1660                    root_has_sig,
1661                    leaf_hash,
1662                    min_fn,
1663                    thresh_fn,
1664                );
1665                vsat.concatenate_rev(odissat)
1666            }
1667            Terminal::AndB(ref l, ref r)
1668            | Terminal::OrB(ref l, ref r)
1669            | Terminal::OrD(ref l, ref r)
1670            | Terminal::AndOr(ref l, _, ref r) => {
1671                let lnsat = Self::dissatisfy_helper(
1672                    &l.node,
1673                    stfr,
1674                    root_has_sig,
1675                    leaf_hash,
1676                    min_fn,
1677                    thresh_fn,
1678                );
1679                let rnsat = Self::dissatisfy_helper(
1680                    &r.node,
1681                    stfr,
1682                    root_has_sig,
1683                    leaf_hash,
1684                    min_fn,
1685                    thresh_fn,
1686                );
1687                lnsat.concatenate_rev(rnsat)
1688            }
1689            Terminal::OrI(ref l, ref r) => {
1690                let lnsat = Self::dissatisfy_helper(
1691                    &l.node,
1692                    stfr,
1693                    root_has_sig,
1694                    leaf_hash,
1695                    min_fn,
1696                    thresh_fn,
1697                );
1698                let dissat_1 = Satisfaction {
1699                    stack: Witness::combine(lnsat.stack, Witness::push_1()),
1700                    has_sig: lnsat.has_sig,
1701                    relative_timelock: None,
1702                    absolute_timelock: None,
1703                };
1704
1705                let rnsat = Self::dissatisfy_helper(
1706                    &r.node,
1707                    stfr,
1708                    root_has_sig,
1709                    leaf_hash,
1710                    min_fn,
1711                    thresh_fn,
1712                );
1713                let dissat_2 = Satisfaction {
1714                    stack: Witness::combine(rnsat.stack, Witness::push_0()),
1715                    has_sig: rnsat.has_sig,
1716                    relative_timelock: None,
1717                    absolute_timelock: None,
1718                };
1719
1720                // Dissatisfactions don't need to non-malleable. Use minimum_mall always
1721                Satisfaction::minimum_mall(dissat_1, dissat_2)
1722            }
1723            Terminal::Thresh(ref thresh) => thresh
1724                .iter()
1725                .map(|s| {
1726                    Self::dissatisfy_helper(
1727                        &s.node,
1728                        stfr,
1729                        root_has_sig,
1730                        leaf_hash,
1731                        min_fn,
1732                        thresh_fn,
1733                    )
1734                })
1735                .fold(Satisfaction::empty(), Satisfaction::concatenate_rev),
1736            Terminal::Multi(ref thresh) => Satisfaction {
1737                stack: Witness::Stack(vec![Placeholder::PushZero; thresh.k() + 1]),
1738                has_sig: false,
1739                relative_timelock: None,
1740                absolute_timelock: None,
1741            },
1742            Terminal::MultiA(ref thresh) => Satisfaction {
1743                stack: Witness::Stack(vec![Placeholder::PushZero; thresh.n()]),
1744                has_sig: false,
1745                relative_timelock: None,
1746                absolute_timelock: None,
1747            },
1748        }
1749    }
1750
1751    /// Try creating the final witness using a [`Satisfier`]
1752    pub fn try_completing<Sat: Satisfier<Pk>>(&self, stfr: &Sat) -> Option<Satisfaction<Vec<u8>>> {
1753        let Satisfaction { stack, has_sig, relative_timelock, absolute_timelock } = self;
1754        let stack = match stack {
1755            Witness::Stack(stack) => Witness::Stack(
1756                stack
1757                    .iter()
1758                    .map(|placeholder| placeholder.satisfy_self(stfr))
1759                    .collect::<Option<_>>()?,
1760            ),
1761            Witness::Unavailable => Witness::Unavailable,
1762            Witness::Impossible => Witness::Impossible,
1763        };
1764        Some(Satisfaction {
1765            stack,
1766            has_sig: *has_sig,
1767            relative_timelock: *relative_timelock,
1768            absolute_timelock: *absolute_timelock,
1769        })
1770    }
1771}
1772
1773impl Satisfaction<Vec<u8>> {
1774    /// Produce a satisfaction non-malleable satisfaction
1775    pub(super) fn satisfy<Ctx, Pk, Sat>(
1776        term: &Terminal<Pk, Ctx>,
1777        stfr: &Sat,
1778        root_has_sig: bool,
1779        leaf_hash: &TapLeafHash,
1780    ) -> Self
1781    where
1782        Ctx: ScriptContext,
1783        Pk: MiniscriptKey + ToPublicKey,
1784        Sat: Satisfier<Pk>,
1785    {
1786        Satisfaction::<Placeholder<Pk>>::build_template(term, &stfr, root_has_sig, leaf_hash)
1787            .try_completing(stfr)
1788            .expect("the same satisfier should manage to complete the template")
1789    }
1790
1791    /// Produce a satisfaction(possibly malleable)
1792    pub(super) fn satisfy_mall<Ctx, Pk, Sat>(
1793        term: &Terminal<Pk, Ctx>,
1794        stfr: &Sat,
1795        root_has_sig: bool,
1796        leaf_hash: &TapLeafHash,
1797    ) -> Self
1798    where
1799        Ctx: ScriptContext,
1800        Pk: MiniscriptKey + ToPublicKey,
1801        Sat: Satisfier<Pk>,
1802    {
1803        Satisfaction::<Placeholder<Pk>>::build_template_mall(term, &stfr, root_has_sig, leaf_hash)
1804            .try_completing(stfr)
1805            .expect("the same satisfier should manage to complete the template")
1806    }
1807}