miniscript_debug/miniscript/
satisfy.rs

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