1use crate::analysis::Cost;
4use crate::jet::Elements;
5use crate::node::{ConstructNode, Hiding, RedeemNode};
6use crate::policy::ToXOnlyPubkey;
7use crate::types;
8use crate::{Cmr, Policy, Value};
9
10use elements::bitcoin;
11use elements::locktime::Height;
12use elements::taproot::TapLeafHash;
13use hashes::Hash;
14
15use crate::jet::elements::ElementsEnv;
16use std::convert::TryFrom;
17use std::sync::Arc;
18
19pub type Preimage32 = [u8; 32];
21
22pub trait Satisfier<Pk: ToXOnlyPubkey> {
28 fn lookup_tap_leaf_script_sig(&self, _: &Pk, _: &TapLeafHash) -> Option<elements::SchnorrSig> {
30 None
31 }
32
33 fn lookup_sha256(&self, _: &Pk::Sha256) -> Option<Preimage32> {
35 None
36 }
37
38 fn check_older(&self, _: elements::Sequence) -> bool {
40 false
41 }
42
43 fn check_after(&self, _: elements::LockTime) -> bool {
45 false
46 }
47
48 fn lookup_asm_program(&self, _: Cmr) -> Option<Arc<ConstructNode<Elements>>> {
61 None
62 }
63}
64
65impl<Pk: ToXOnlyPubkey> Satisfier<Pk> for elements::Sequence {
66 fn check_older(&self, n: elements::Sequence) -> bool {
67 use elements::bitcoin::locktime::relative::LockTime::*;
68
69 let this = match bitcoin::Sequence(self.0).to_relative_lock_time() {
70 Some(x) => x,
71 None => return false,
72 };
73 let n = match bitcoin::Sequence(n.0).to_relative_lock_time() {
74 Some(x) => x,
75 None => return false,
76 };
77
78 match (n, this) {
79 (Blocks(n), Blocks(lock_time)) => n <= lock_time,
80 (Time(n), Time(lock_time)) => n <= lock_time,
81 _ => false, }
83 }
84}
85
86impl<Pk: ToXOnlyPubkey> Satisfier<Pk> for elements::LockTime {
87 fn check_after(&self, n: elements::LockTime) -> bool {
88 use elements::LockTime::*;
89
90 match (n, *self) {
91 (Blocks(n), Blocks(lock_time)) => n <= lock_time,
92 (Seconds(n), Seconds(lock_time)) => n <= lock_time,
93 _ => false, }
95 }
96}
97
98#[derive(Debug)]
99pub enum SatisfierError {
100 Unsatisfiable,
102 AssemblyFailed(crate::bit_machine::ExecutionError),
106}
107
108type SatResult = Hiding<Arc<ConstructNode<Elements>>>;
109
110fn ok_if(condition: bool, expr: SatResult) -> SatResult {
111 match condition {
112 true => expr,
113 false => expr.hide(),
114 }
115}
116
117impl<Pk: ToXOnlyPubkey> Policy<Pk> {
118 fn satisfy_internal<S: Satisfier<Pk>>(
119 &self,
120 inference_context: &types::Context,
121 satisfier: &S,
122 ) -> Result<SatResult, SatisfierError> {
123 let node: SatResult = match *self {
124 Policy::Unsatisfiable(entropy) => {
125 super::serialize::unsatisfiable::<SatResult>(inference_context, entropy).hide()
126 }
127 Policy::Trivial => super::serialize::trivial(inference_context),
128 Policy::Key(ref key) => {
129 let signature = satisfier
130 .lookup_tap_leaf_script_sig(key, &TapLeafHash::all_zeros())
131 .map(|sig| sig.sig.serialize())
132 .map(Value::u512);
133 ok_if(
134 signature.is_some(),
135 super::serialize::key(inference_context, key, signature),
136 )
137 }
138 Policy::After(n) => {
139 let height = Height::from_consensus(n).expect("timelock is valid");
140 ok_if(
141 satisfier.check_after(elements::LockTime::Blocks(height)),
142 super::serialize::after(inference_context, n),
143 )
144 }
145 Policy::Older(n) => ok_if(
146 satisfier.check_older(elements::Sequence(n.into())),
147 super::serialize::older(inference_context, n),
148 ),
149 Policy::Sha256(ref hash) => {
150 let preimage = satisfier.lookup_sha256(hash).map(Value::u256);
151 ok_if(
152 preimage.is_some(),
153 super::serialize::sha256::<Pk, _, _>(inference_context, hash, preimage),
154 )
155 }
156 Policy::And {
157 ref left,
158 ref right,
159 } => {
160 let left_res = left.satisfy_internal(inference_context, satisfier)?;
161 let right_res = right.satisfy_internal(inference_context, satisfier)?;
162 super::serialize::and(&left_res, &right_res)
163 }
164 Policy::Or {
165 ref left,
166 ref right,
167 } => {
168 let left_res = left.satisfy_internal(inference_context, satisfier)?;
169 let right_res = right.satisfy_internal(inference_context, satisfier)?;
170 let take_right = match (left_res.as_node(), right_res.as_node()) {
171 (Some(left), Some(right)) => {
172 let left_cost = left
173 .finalize_unpruned()
174 .expect("serialization should be sound")
175 .bounds()
176 .cost;
177 let right_cost = right
178 .finalize_unpruned()
179 .expect("serialization should be sound")
180 .bounds()
181 .cost;
182 right_cost < left_cost
183 }
184 (None, Some(..)) => true,
185 (Some(..), None) => false,
186 (None, None) => false,
189 };
190
191 let ret = if take_right {
192 super::serialize::or(&left_res, &right_res, Some(Value::u1(1)))
193 } else {
194 super::serialize::or(&left_res, &right_res, Some(Value::u1(0)))
195 };
196 ok_if(
197 left_res.as_node().is_some() || right_res.as_node().is_some(),
198 ret,
199 )
200 }
201 Policy::Threshold(k, ref subs) => {
202 let subs_res: Vec<SatResult> = subs
203 .iter()
204 .map(|sub| sub.satisfy_internal(inference_context, satisfier))
205 .collect::<Result<_, SatisfierError>>()?;
206 let costs: Vec<Cost> = subs_res
207 .iter()
208 .map(|result| match result.as_node() {
209 Some(node) => node
210 .finalize_unpruned()
211 .map(|redeem| redeem.bounds().cost)
212 .unwrap_or(Cost::CONSENSUS_MAX),
213 None => Cost::CONSENSUS_MAX,
214 })
215 .collect();
216 let selected_node_indices = {
217 let mut indices: Vec<usize> = (0..costs.len()).collect();
218 indices.sort_by_key(|&i| costs[i]);
219 indices.truncate(k);
220 indices
221 };
222 let all_selected_ok = selected_node_indices
223 .iter()
224 .all(|&i| subs_res[i].as_node().is_some());
225 let witness_bits: Vec<Option<Value>> = (0..subs_res.len())
226 .map(|i| Some(Value::u1(u8::from(selected_node_indices.contains(&i)))))
227 .collect();
228 let k = u32::try_from(k).expect("k should be less than 2^32");
229 ok_if(
230 all_selected_ok,
231 super::serialize::threshold(k, &subs_res, &witness_bits),
232 )
233 }
234 Policy::Assembly(cmr) => match satisfier.lookup_asm_program(cmr) {
235 Some(program) => Hiding::from(program),
236 None => Hiding::hidden(cmr, inference_context.shallow_clone()),
237 },
238 };
239 Ok(node)
240 }
241
242 pub fn satisfy<S: Satisfier<Pk>>(
247 &self,
248 satisfier: &S,
249 env: &ElementsEnv<Arc<elements::Transaction>>,
250 ) -> Result<Arc<RedeemNode<Elements>>, SatisfierError> {
251 let result = self.satisfy_internal(&types::Context::new(), satisfier)?;
252 match result.get_node() {
253 Some(program) => program
254 .finalize_unpruned()
255 .expect("serialization should be sound")
256 .prune(env)
257 .map_err(SatisfierError::AssemblyFailed), None => Err(SatisfierError::Unsatisfiable),
259 }
260 }
261}
262
263#[cfg(test)]
264mod tests {
265 use super::*;
266 use crate::bit_encoding::BitCollector;
267 use crate::dag::{DagLike, NoSharing};
268 use crate::jet::elements::ElementsEnv;
269 use crate::node::{CoreConstructible, JetConstructible, SimpleFinalizer, WitnessConstructible};
270 use crate::policy::serialize;
271 use crate::{BitMachine, FailEntropy, SimplicityKey};
272 use elements::bitcoin::key::{Keypair, XOnlyPublicKey};
273 use elements::secp256k1_zkp;
274 use hashes::{sha256, Hash};
275 use std::collections::HashMap;
276 use std::sync::Arc;
277
278 pub struct PolicySatisfier<'a, Pk: SimplicityKey> {
279 pub preimages: HashMap<Pk::Sha256, Preimage32>,
280 pub signatures: HashMap<Pk, elements::SchnorrSig>,
281 pub assembly: HashMap<Cmr, Arc<ConstructNode<Elements>>>,
282 pub tx: &'a elements::Transaction,
283 pub index: usize,
284 }
285
286 impl<Pk: ToXOnlyPubkey> Satisfier<Pk> for PolicySatisfier<'_, Pk> {
287 fn lookup_tap_leaf_script_sig(
288 &self,
289 pk: &Pk,
290 _: &TapLeafHash,
291 ) -> Option<elements::SchnorrSig> {
292 self.signatures.get(pk).copied()
293 }
294
295 fn lookup_sha256(&self, hash: &Pk::Sha256) -> Option<Preimage32> {
296 self.preimages.get(hash).copied()
297 }
298
299 fn check_older(&self, sequence: elements::Sequence) -> bool {
300 let self_sequence = self.tx.input[self.index].sequence;
301 <elements::Sequence as Satisfier<Pk>>::check_older(&self_sequence, sequence)
302 }
303
304 fn check_after(&self, locktime: elements::LockTime) -> bool {
305 <elements::LockTime as Satisfier<Pk>>::check_after(&self.tx.lock_time, locktime)
306 }
307
308 fn lookup_asm_program(&self, cmr: Cmr) -> Option<Arc<ConstructNode<Elements>>> {
309 self.assembly.get(&cmr).cloned()
310 }
311 }
312
313 fn get_satisfier(
314 env: &ElementsEnv<Arc<elements::Transaction>>,
315 ) -> PolicySatisfier<XOnlyPublicKey> {
316 let mut preimages = HashMap::new();
317
318 for i in 0..3 {
319 let preimage = [i; 32];
320 preimages.insert(sha256::Hash::hash(&preimage), preimage);
321 }
322
323 let secp = secp256k1_zkp::Secp256k1::new();
324 let mut rng = secp256k1_zkp::rand::rngs::ThreadRng::default();
325 let mut signatures = HashMap::new();
326
327 for _ in 0..3 {
328 let keypair = Keypair::new(&secp, &mut rng);
329 let xonly = keypair.x_only_public_key().0;
330
331 let sighash = env.c_tx_env().sighash_all();
332 let msg = secp256k1_zkp::Message::from_digest(sighash.to_byte_array());
333 let sig = elements::SchnorrSig {
334 sig: keypair.sign_schnorr(msg),
335 hash_ty: elements::SchnorrSighashType::All,
336 };
337
338 signatures.insert(xonly, sig);
339 }
340
341 PolicySatisfier {
342 preimages,
343 signatures,
344 assembly: HashMap::new(),
345 tx: env.tx(),
346 index: env.ix() as usize,
347 }
348 }
349
350 fn execute_successful(
351 program: Arc<RedeemNode<Elements>>,
352 env: &ElementsEnv<Arc<elements::Transaction>>,
353 ) {
354 let mut mac = BitMachine::for_program(&program).unwrap();
355 assert!(mac.exec(&program, env).is_ok());
356 }
357
358 fn execute_unsuccessful(
359 program: Arc<RedeemNode<Elements>>,
360 env: &ElementsEnv<Arc<elements::Transaction>>,
361 ) {
362 let mut mac = BitMachine::for_program(&program).unwrap();
363 assert!(mac.exec(&program, env).is_err());
364 }
365
366 fn to_witness(program: &RedeemNode<Elements>) -> Vec<&Value> {
367 program
368 .post_order_iter::<NoSharing>()
369 .into_witnesses()
370 .collect()
371 }
372
373 #[test]
374 fn satisfy_unsatisfiable() {
375 let env = ElementsEnv::dummy();
376 let satisfier = get_satisfier(&env);
377 let policy = Policy::Unsatisfiable(FailEntropy::ZERO);
378
379 assert!(policy.satisfy(&satisfier, &env).is_err());
380
381 let commit = policy.commit().expect("no asm");
382 let program = commit
383 .finalize(&mut SimpleFinalizer::new(std::iter::empty()))
384 .expect("finalize");
385
386 execute_unsuccessful(program, &env);
387 }
388
389 #[test]
390 fn satisfy_trivial() {
391 let env = ElementsEnv::dummy();
392 let satisfier = get_satisfier(&env);
393 let policy = Policy::Trivial;
394
395 let program = policy.satisfy(&satisfier, &env).expect("satisfiable");
396 let witness = to_witness(&program);
397 assert!(witness.is_empty());
398
399 execute_successful(program, &env);
400 }
401
402 #[test]
403 fn satisfy_pk() {
404 let env = ElementsEnv::dummy();
405 let satisfier = get_satisfier(&env);
406 let mut it = satisfier.signatures.keys();
407 let xonly = it.next().unwrap();
408 let policy = Policy::Key(*xonly);
409
410 let program = policy.satisfy(&satisfier, &env).expect("satisfiable");
411 let witness = to_witness(&program);
412 assert_eq!(1, witness.len());
413
414 let sighash = env.c_tx_env().sighash_all();
415 let message = secp256k1_zkp::Message::from_digest(sighash.to_byte_array());
416 let signature_bytes = witness[0]
417 .iter_padded()
418 .try_collect_bytes()
419 .expect("to bytes");
420 let signature =
421 secp256k1_zkp::schnorr::Signature::from_slice(&signature_bytes).expect("to signature");
422 assert!(signature.verify(&message, xonly).is_ok());
423
424 execute_successful(program, &env);
425 }
426
427 #[test]
428 fn satisfy_sha256() {
429 let env = ElementsEnv::dummy();
430 let satisfier = get_satisfier(&env);
431 let mut it = satisfier.preimages.keys();
432 let image = *it.next().unwrap();
433 let policy = Policy::Sha256(image);
434
435 let program = policy.satisfy(&satisfier, &env).expect("satisfiable");
436 let witness = to_witness(&program);
437 assert_eq!(1, witness.len());
438
439 let witness_bytes = witness[0]
440 .iter_padded()
441 .try_collect_bytes()
442 .expect("to bytes");
443 let witness_preimage = Preimage32::try_from(witness_bytes.as_slice()).expect("to array");
444 let preimage = *satisfier.preimages.get(&image).unwrap();
445 assert_eq!(preimage, witness_preimage);
446
447 execute_successful(program, &env);
448 }
449
450 #[test]
451 fn satisfy_after() {
452 let height = Height::from_consensus(42).unwrap();
453 let env =
454 ElementsEnv::dummy_with(elements::LockTime::Blocks(height), elements::Sequence::ZERO);
455 let satisfier = get_satisfier(&env);
456
457 let policy0 = Policy::After(41);
458 let program = policy0.satisfy(&satisfier, &env).expect("satisfiable");
459 let witness = to_witness(&program);
460 assert!(witness.is_empty());
461 execute_successful(program, &env);
462
463 let policy1 = Policy::After(42);
464 let program = policy1.satisfy(&satisfier, &env).expect("satisfiable");
465 let witness = to_witness(&program);
466 assert!(witness.is_empty());
467 execute_successful(program, &env);
468
469 let policy2 = Policy::After(43);
470 assert!(policy2.satisfy(&satisfier, &env).is_err(), "unsatisfiable");
471 }
472
473 #[test]
474 fn satisfy_older() {
475 let env = ElementsEnv::dummy_with(
476 elements::LockTime::ZERO,
477 elements::Sequence::from_consensus(42),
478 );
479 let satisfier = get_satisfier(&env);
480
481 let policy0 = Policy::Older(41);
482 let program = policy0.satisfy(&satisfier, &env).expect("satisfiable");
483 let witness = to_witness(&program);
484 assert!(witness.is_empty());
485 execute_successful(program, &env);
486
487 let policy1 = Policy::Older(42);
488 let program = policy1.satisfy(&satisfier, &env).expect("satisfiable");
489 let witness = to_witness(&program);
490 assert!(witness.is_empty());
491 execute_successful(program, &env);
492
493 let policy2 = Policy::Older(43);
494 assert!(policy2.satisfy(&satisfier, &env).is_err(), "unsatisfiable");
495 }
496
497 #[test]
498 fn satisfy_and() {
499 let env = ElementsEnv::dummy();
500 let satisfier = get_satisfier(&env);
501 let images: Vec<_> = satisfier.preimages.keys().copied().collect();
502 let preimages: Vec<_> = images
503 .iter()
504 .map(|x| satisfier.preimages.get(x).unwrap())
505 .collect();
506
507 let policy0 = Policy::And {
510 left: Arc::new(Policy::Sha256(images[0])),
511 right: Arc::new(Policy::Sha256(images[1])),
512 };
513 let program = policy0.satisfy(&satisfier, &env).expect("satisfiable");
514 let witness = to_witness(&program);
515 assert_eq!(2, witness.len());
516
517 for i in 0..2 {
518 let preimage_bytes = witness[i]
519 .iter_padded()
520 .try_collect_bytes()
521 .expect("to bytes");
522 let witness_preimage =
523 Preimage32::try_from(preimage_bytes.as_slice()).expect("to array");
524 assert_eq!(preimages[i], &witness_preimage);
525 }
526
527 execute_successful(program, &env);
528
529 let policy1 = Policy::And {
532 left: Arc::new(Policy::Sha256(sha256::Hash::from_byte_array([0; 32]))),
533 right: Arc::new(Policy::Sha256(images[1])),
534 };
535 assert!(policy1.satisfy(&satisfier, &env).is_err());
536
537 let policy2 = Policy::And {
540 left: Arc::new(Policy::Sha256(images[0])),
541 right: Arc::new(Policy::Sha256(sha256::Hash::from_byte_array([0; 32]))),
542 };
543 assert!(policy2.satisfy(&satisfier, &env).is_err());
544 }
545
546 #[test]
547 fn satisfy_or() {
548 let env = ElementsEnv::dummy();
549 let satisfier = get_satisfier(&env);
550 let images: Vec<_> = satisfier.preimages.keys().copied().collect();
551 let preimages: Vec<_> = images.iter().map(|x| satisfier.preimages[x]).collect();
552
553 let assert_branch = |policy: &Policy<XOnlyPublicKey>, bit: bool| {
554 let program = policy.satisfy(&satisfier, &env).expect("satisfiable");
555 let witness = to_witness(&program);
556 assert_eq!(2, witness.len());
557
558 assert_eq!(Value::u1(bit as u8), *witness[0]);
559 let preimage_bytes = witness[1]
560 .iter_padded()
561 .try_collect_bytes()
562 .expect("to bytes");
563 let witness_preimage =
564 Preimage32::try_from(preimage_bytes.as_slice()).expect("to array");
565 assert_eq!(preimages[bit as usize], witness_preimage);
566
567 execute_successful(program, &env);
568 };
569
570 let policy0 = Policy::Or {
573 left: Arc::new(Policy::Sha256(images[0])),
574 right: Arc::new(Policy::Sha256(images[1])),
575 };
576 assert_branch(&policy0, false);
577
578 let policy1 = Policy::Or {
581 left: Arc::new(Policy::Sha256(images[0])),
582 right: Arc::new(Policy::Sha256(sha256::Hash::from_byte_array([1; 32]))),
583 };
584 assert_branch(&policy1, false);
585
586 let policy2 = Policy::Or {
589 left: Arc::new(Policy::Sha256(sha256::Hash::from_byte_array([0; 32]))),
590 right: Arc::new(Policy::Sha256(images[1])),
591 };
592 assert_branch(&policy2, true);
593
594 let policy3 = Policy::Or {
597 left: Arc::new(Policy::Sha256(sha256::Hash::from_byte_array([0; 32]))),
598 right: Arc::new(Policy::Sha256(sha256::Hash::from_byte_array([1; 32]))),
599 };
600 assert!(policy3.satisfy(&satisfier, &env).is_err());
601 }
602
603 #[test]
604 fn satisfy_thresh() {
605 let env = ElementsEnv::dummy();
606 let satisfier = get_satisfier(&env);
607 let images: Vec<_> = satisfier.preimages.keys().copied().collect();
608 let preimages: Vec<_> = images
609 .iter()
610 .map(|x| satisfier.preimages.get(x).unwrap())
611 .collect();
612
613 let assert_branches = |policy: &Policy<XOnlyPublicKey>, bits: &[bool]| {
614 let program = policy.satisfy(&satisfier, &env).expect("satisfiable");
615 let witness = to_witness(&program);
616 assert_eq!(
617 witness.len(),
618 bits.len() + bits.iter().filter(|b| **b).count(),
619 );
620
621 let mut witidx = 0;
622 for (bit_n, bit) in bits.iter().copied().enumerate() {
623 assert_eq!(*witness[witidx], Value::u1(bit.into()));
624 witidx += 1;
625 if bit {
626 let preimage_bytes = witness[witidx]
627 .iter_padded()
628 .try_collect_bytes()
629 .expect("to bytes");
630 let witness_preimage =
631 Preimage32::try_from(preimage_bytes.as_slice()).expect("to array");
632 assert_eq!(preimages[bit_n], &witness_preimage);
633 witidx += 1;
634 }
635 }
636
637 execute_successful(program, &env);
638 };
639
640 let image_from_bit = |bit: bool, j: u8| {
641 if bit {
642 images[j as usize]
643 } else {
644 sha256::Hash::from_byte_array([j; 32])
645 }
646 };
647
648 for &bit0 in &[true, false] {
649 let image0 = image_from_bit(bit0, 0);
650
651 for &bit1 in &[true, false] {
652 let image1 = image_from_bit(bit1, 1);
653
654 for &bit2 in &[true, false] {
655 let image2 = image_from_bit(bit2, 2);
656
657 let policy = Policy::Threshold(
658 2,
659 vec![
660 Policy::Sha256(image0),
661 Policy::Sha256(image1),
662 Policy::Sha256(image2),
663 ],
664 );
665
666 match bit0 as u8 + bit1 as u8 + bit2 as u8 {
667 3 => assert_branches(&policy, &[bit0, bit1, false]),
668 2 => assert_branches(&policy, &[bit0, bit1, bit2]),
669 _ => assert!(policy.satisfy(&satisfier, &env).is_err()),
670 }
671 }
672 }
673 }
674 }
675
676 #[test]
677 fn satisfy_asm() {
678 let ctx = types::Context::new();
679 let env = ElementsEnv::dummy();
680 let mut satisfier = get_satisfier(&env);
681
682 let mut assert_branch = |witness0: Value, witness1: Value| {
683 let asm_program = serialize::verify_bexp(
684 &Arc::<ConstructNode<Elements>>::pair(
685 &Arc::<ConstructNode<Elements>>::witness(&ctx, Some(witness0.clone())),
686 &Arc::<ConstructNode<Elements>>::witness(&ctx, Some(witness1.clone())),
687 )
688 .expect("sound types"),
689 &Arc::<ConstructNode<Elements>>::jet(&ctx, Elements::Eq8),
690 );
691 let cmr = asm_program.cmr();
692 satisfier.assembly.insert(cmr, asm_program);
693
694 let policy = Policy::Assembly(cmr);
695 let result = policy.satisfy(&satisfier, &env);
696
697 if witness0 == witness1 {
698 let program = result.expect("policy should be satisfiable");
699 let witness = to_witness(&program);
700
701 assert_eq!(2, witness.len());
702 assert_eq!(&witness0, witness[0]);
703 assert_eq!(&witness1, witness[1]);
704
705 execute_successful(program, &env);
706 } else {
707 assert!(matches!(result, Err(SatisfierError::AssemblyFailed(..))));
708 }
709 };
710
711 for a in 0..2 {
712 for b in 0..2 {
713 assert_branch(Value::u8(a), Value::u8(b))
714 }
715 }
716 }
717}