1pub mod merkle_branch;
9pub mod serialized_signature;
10
11use core::cmp::Reverse;
12use core::convert::Infallible;
13use core::fmt;
14use core::iter::FusedIterator;
15
16use hashes::{sha256t_hash_newtype, Hash, HashEngine};
17use io::Write;
18use secp256k1::{Scalar, Secp256k1};
19
20use crate::consensus::Encodable;
21use crate::crypto::key::{TapTweak, TweakedPublicKey, UntweakedPublicKey, XOnlyPublicKey};
22use crate::internal_macros::write_err;
23use crate::prelude::*;
24use crate::{Script, ScriptBuf};
25
26#[rustfmt::skip]
28#[doc(inline)]
29pub use crate::crypto::taproot::{SigFromSliceError, Signature};
30#[doc(inline)]
31pub use merkle_branch::TaprootMerkleBranch;
32
33sha256t_hash_newtype! {
35 pub struct TapLeafTag = hash_str("TapLeaf");
36
37 #[hash_newtype(forward)]
41 pub struct TapLeafHash(_);
42
43 pub struct TapBranchTag = hash_str("TapBranch");
44
45 #[hash_newtype(forward)]
49 pub struct TapNodeHash(_);
50
51 pub struct TapTweakTag = hash_str("TapTweak");
52
53 #[hash_newtype(forward)]
57 pub struct TapTweakHash(_);
58}
59
60impl TapTweakHash {
61 pub fn from_key_and_tweak(
64 internal_key: UntweakedPublicKey,
65 merkle_root: Option<TapNodeHash>,
66 ) -> TapTweakHash {
67 let mut eng = TapTweakHash::engine();
68 eng.input(&internal_key.serialize());
70 if let Some(h) = merkle_root {
71 eng.input(h.as_ref());
72 } else {
73 }
75 TapTweakHash::from_engine(eng)
76 }
77
78 pub fn to_scalar(self) -> Scalar {
80 Scalar::from_be_bytes(self.to_byte_array()).expect("hash value greater than curve order")
82 }
83}
84
85impl TapLeafHash {
86 pub fn from_script(script: &Script, ver: LeafVersion) -> TapLeafHash {
88 let mut eng = TapLeafHash::engine();
89 ver.to_consensus().consensus_encode(&mut eng).expect("engines don't error");
90 script.consensus_encode(&mut eng).expect("engines don't error");
91 TapLeafHash::from_engine(eng)
92 }
93}
94
95impl From<LeafNode> for TapNodeHash {
96 fn from(leaf: LeafNode) -> TapNodeHash { leaf.node_hash() }
97}
98
99impl From<&LeafNode> for TapNodeHash {
100 fn from(leaf: &LeafNode) -> TapNodeHash { leaf.node_hash() }
101}
102
103impl TapNodeHash {
104 pub fn from_node_hashes(a: TapNodeHash, b: TapNodeHash) -> TapNodeHash {
106 Self::combine_node_hashes(a, b).0
107 }
108
109 fn combine_node_hashes(a: TapNodeHash, b: TapNodeHash) -> (TapNodeHash, bool) {
112 let mut eng = TapNodeHash::engine();
113 if a < b {
114 eng.input(a.as_ref());
115 eng.input(b.as_ref());
116 } else {
117 eng.input(b.as_ref());
118 eng.input(a.as_ref());
119 };
120 (TapNodeHash::from_engine(eng), a < b)
121 }
122
123 pub fn assume_hidden(hash: [u8; 32]) -> TapNodeHash { TapNodeHash::from_byte_array(hash) }
129
130 pub fn from_script(script: &Script, ver: LeafVersion) -> TapNodeHash {
132 TapNodeHash::from(TapLeafHash::from_script(script, ver))
133 }
134}
135
136impl From<TapLeafHash> for TapNodeHash {
137 fn from(leaf: TapLeafHash) -> TapNodeHash { TapNodeHash::from_byte_array(leaf.to_byte_array()) }
138}
139
140pub const TAPROOT_CONTROL_MAX_NODE_COUNT: usize = 128;
143pub const TAPROOT_CONTROL_NODE_SIZE: usize = 32;
146pub const TAPROOT_LEAF_MASK: u8 = 0xfe;
149pub const TAPROOT_LEAF_TAPSCRIPT: u8 = 0xc0;
152pub const TAPROOT_ANNEX_PREFIX: u8 = 0x50;
154pub const TAPROOT_CONTROL_BASE_SIZE: usize = 33;
157pub const TAPROOT_CONTROL_MAX_SIZE: usize =
160 TAPROOT_CONTROL_BASE_SIZE + TAPROOT_CONTROL_NODE_SIZE * TAPROOT_CONTROL_MAX_NODE_COUNT;
161
162#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
164pub struct LeafScript<S> {
165 pub version: LeafVersion,
167 pub script: S,
169}
170
171type ScriptMerkleProofMap = BTreeMap<(ScriptBuf, LeafVersion), BTreeSet<TaprootMerkleBranch>>;
173
174#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
194pub struct TaprootSpendInfo {
195 internal_key: UntweakedPublicKey,
197 merkle_root: Option<TapNodeHash>,
199 output_key_parity: secp256k1::Parity,
201 output_key: TweakedPublicKey,
203 script_map: ScriptMerkleProofMap,
208}
209
210impl TaprootSpendInfo {
211 pub fn with_huffman_tree<C, I>(
216 secp: &Secp256k1<C>,
217 internal_key: UntweakedPublicKey,
218 script_weights: I,
219 ) -> Result<Self, TaprootBuilderError>
220 where
221 I: IntoIterator<Item = (u32, ScriptBuf)>,
222 C: secp256k1::Verification,
223 {
224 let builder = TaprootBuilder::with_huffman_tree(script_weights)?;
225 Ok(builder.finalize(secp, internal_key).expect("Huffman Tree is always complete"))
226 }
227
228 pub fn new_key_spend<C: secp256k1::Verification>(
240 secp: &Secp256k1<C>,
241 internal_key: UntweakedPublicKey,
242 merkle_root: Option<TapNodeHash>,
243 ) -> Self {
244 let (output_key, parity) = internal_key.tap_tweak(secp, merkle_root);
245 Self {
246 internal_key,
247 merkle_root,
248 output_key_parity: parity,
249 output_key,
250 script_map: BTreeMap::new(),
251 }
252 }
253
254 pub fn tap_tweak(&self) -> TapTweakHash {
257 TapTweakHash::from_key_and_tweak(self.internal_key, self.merkle_root)
258 }
259
260 pub fn internal_key(&self) -> UntweakedPublicKey { self.internal_key }
262
263 pub fn merkle_root(&self) -> Option<TapNodeHash> { self.merkle_root }
265
266 pub fn output_key(&self) -> TweakedPublicKey { self.output_key }
268
269 pub fn output_key_parity(&self) -> secp256k1::Parity { self.output_key_parity }
271
272 pub fn script_map(&self) -> &ScriptMerkleProofMap { &self.script_map }
274
275 pub fn from_node_info<C: secp256k1::Verification>(
280 secp: &Secp256k1<C>,
281 internal_key: UntweakedPublicKey,
282 node: NodeInfo,
283 ) -> TaprootSpendInfo {
284 let root_hash = Some(node.hash);
286 let mut info = TaprootSpendInfo::new_key_spend(secp, internal_key, root_hash);
287
288 for leaves in node.leaves {
289 match leaves.leaf {
290 TapLeaf::Hidden(_) => {
291 }
293 TapLeaf::Script(script, ver) => {
294 let key = (script, ver);
295 let value = leaves.merkle_branch;
296 match info.script_map.get_mut(&key) {
297 None => {
298 let mut set = BTreeSet::new();
299 set.insert(value);
300 info.script_map.insert(key, set);
301 }
302 Some(set) => {
303 set.insert(value);
304 }
305 }
306 }
307 }
308 }
309 info
310 }
311
312 pub fn control_block(&self, script_ver: &(ScriptBuf, LeafVersion)) -> Option<ControlBlock> {
319 let merkle_branch_set = self.script_map.get(script_ver)?;
320 let smallest = merkle_branch_set
322 .iter()
323 .min_by(|x, y| x.len().cmp(&y.len()))
324 .expect("Invariant: ScriptBuf map key must contain non-empty set value");
325 Some(ControlBlock {
326 internal_key: self.internal_key,
327 output_key_parity: self.output_key_parity,
328 leaf_version: script_ver.1,
329 merkle_branch: smallest.clone(),
330 })
331 }
332}
333
334impl From<TaprootSpendInfo> for TapTweakHash {
335 fn from(spend_info: TaprootSpendInfo) -> TapTweakHash { spend_info.tap_tweak() }
336}
337
338impl From<&TaprootSpendInfo> for TapTweakHash {
339 fn from(spend_info: &TaprootSpendInfo) -> TapTweakHash { spend_info.tap_tweak() }
340}
341
342#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
348pub struct TaprootBuilder {
349 branch: Vec<Option<NodeInfo>>,
382}
383
384impl TaprootBuilder {
385 pub fn new() -> Self { TaprootBuilder { branch: vec![] } }
387
388 pub fn with_capacity(size: usize) -> Self {
392 TaprootBuilder { branch: Vec::with_capacity(size) }
393 }
394
395 pub fn with_huffman_tree<I>(script_weights: I) -> Result<Self, TaprootBuilderError>
417 where
418 I: IntoIterator<Item = (u32, ScriptBuf)>,
419 {
420 let mut node_weights = BinaryHeap::<(Reverse<u32>, NodeInfo)>::new();
421 for (p, leaf) in script_weights {
422 node_weights
423 .push((Reverse(p), NodeInfo::new_leaf_with_ver(leaf, LeafVersion::TapScript)));
424 }
425 if node_weights.is_empty() {
426 return Err(TaprootBuilderError::EmptyTree);
427 }
428 while node_weights.len() > 1 {
429 let (p1, s1) = node_weights.pop().expect("len must be at least two");
431 let (p2, s2) = node_weights.pop().expect("len must be at least two");
432 let p = Reverse(p1.0.saturating_add(p2.0));
437 node_weights.push((p, NodeInfo::combine(s1, s2)?));
438 }
439 debug_assert_eq!(node_weights.len(), 1);
442 let node = node_weights.pop().expect("huffman tree algorithm is broken").1;
443 Ok(TaprootBuilder { branch: vec![Some(node)] })
444 }
445
446 pub fn add_leaf_with_ver(
449 self,
450 depth: u8,
451 script: ScriptBuf,
452 ver: LeafVersion,
453 ) -> Result<Self, TaprootBuilderError> {
454 let leaf = NodeInfo::new_leaf_with_ver(script, ver);
455 self.insert(leaf, depth)
456 }
457
458 pub fn add_leaf(self, depth: u8, script: ScriptBuf) -> Result<Self, TaprootBuilderError> {
463 self.add_leaf_with_ver(depth, script, LeafVersion::TapScript)
464 }
465
466 pub fn add_hidden_node(
469 self,
470 depth: u8,
471 hash: TapNodeHash,
472 ) -> Result<Self, TaprootBuilderError> {
473 let node = NodeInfo::new_hidden_node(hash);
474 self.insert(node, depth)
475 }
476
477 pub fn is_finalizable(&self) -> bool { self.branch.len() == 1 && self.branch[0].is_some() }
479
480 pub fn try_into_node_info(mut self) -> Result<NodeInfo, IncompleteBuilderError> {
488 if self.branch().len() != 1 {
489 return Err(IncompleteBuilderError::NotFinalized(self));
490 }
491 Ok(self
492 .branch
493 .pop()
494 .expect("length checked above")
495 .expect("invariant guarantees node info exists"))
496 }
497
498 pub fn try_into_taptree(self) -> Result<TapTree, IncompleteBuilderError> {
501 let node = self.try_into_node_info()?;
502 if node.has_hidden_nodes {
503 return Err(IncompleteBuilderError::HiddenParts(TaprootBuilder {
505 branch: vec![Some(node)],
506 }));
507 }
508 Ok(TapTree(node))
509 }
510
511 pub fn has_hidden_nodes(&self) -> bool {
513 self.branch.iter().flatten().any(|node| node.has_hidden_nodes)
514 }
515
516 pub fn finalize<C: secp256k1::Verification>(
521 mut self,
522 secp: &Secp256k1<C>,
523 internal_key: UntweakedPublicKey,
524 ) -> Result<TaprootSpendInfo, TaprootBuilder> {
525 match self.branch.len() {
526 0 => Ok(TaprootSpendInfo::new_key_spend(secp, internal_key, None)),
527 1 =>
528 if let Some(Some(node)) = self.branch.pop() {
529 Ok(TaprootSpendInfo::from_node_info(secp, internal_key, node))
530 } else {
531 unreachable!("Size checked above. Builder guarantees the last element is Some")
532 },
533 _ => Err(self),
534 }
535 }
536
537 pub(crate) fn branch(&self) -> &[Option<NodeInfo>] { &self.branch }
538
539 fn insert(mut self, mut node: NodeInfo, mut depth: u8) -> Result<Self, TaprootBuilderError> {
541 if depth as usize > TAPROOT_CONTROL_MAX_NODE_COUNT {
544 return Err(TaprootBuilderError::InvalidMerkleTreeDepth(depth as usize));
545 }
546 if (depth as usize + 1) < self.branch.len() {
550 return Err(TaprootBuilderError::NodeNotInDfsOrder);
551 }
552
553 while self.branch.len() == depth as usize + 1 {
554 let child = match self.branch.pop() {
555 None => unreachable!("Len of branch checked to be >= 1"),
556 Some(Some(child)) => child,
557 Some(None) => {
560 self.branch.push(None);
561 break;
562 } };
564 if depth == 0 {
565 return Err(TaprootBuilderError::OverCompleteTree);
568 }
569 node = NodeInfo::combine(node, child)?;
570 depth -= 1;
572 }
573
574 if self.branch.len() < depth as usize + 1 {
575 let num_extra_nodes = depth as usize + 1 - self.branch.len();
577 self.branch.extend((0..num_extra_nodes).map(|_| None));
578 }
579 self.branch[depth as usize] = Some(node);
581 Ok(self)
582 }
583}
584
585impl Default for TaprootBuilder {
586 fn default() -> Self { Self::new() }
587}
588
589#[derive(Debug, Clone, PartialEq, Eq)]
592#[non_exhaustive]
593pub enum IncompleteBuilderError {
594 NotFinalized(TaprootBuilder),
596 HiddenParts(TaprootBuilder),
598}
599
600impl From<Infallible> for IncompleteBuilderError {
601 fn from(never: Infallible) -> Self { match never {} }
602}
603
604impl IncompleteBuilderError {
605 pub fn into_builder(self) -> TaprootBuilder {
607 use IncompleteBuilderError::*;
608
609 match self {
610 NotFinalized(builder) | HiddenParts(builder) => builder,
611 }
612 }
613}
614
615impl core::fmt::Display for IncompleteBuilderError {
616 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
617 use IncompleteBuilderError::*;
618
619 f.write_str(match self {
620 NotFinalized(_) =>
621 "an attempt to construct a tap tree from a builder containing incomplete branches.",
622 HiddenParts(_) =>
623 "an attempt to construct a tap tree from a builder containing hidden parts.",
624 })
625 }
626}
627
628#[cfg(feature = "std")]
629impl std::error::Error for IncompleteBuilderError {
630 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
631 use IncompleteBuilderError::*;
632
633 match *self {
634 NotFinalized(_) | HiddenParts(_) => None,
635 }
636 }
637}
638
639#[derive(Debug, Clone, PartialEq, Eq)]
642#[non_exhaustive]
643pub enum HiddenNodesError {
644 HiddenParts(NodeInfo),
646}
647
648impl From<Infallible> for HiddenNodesError {
649 fn from(never: Infallible) -> Self { match never {} }
650}
651
652impl HiddenNodesError {
653 pub fn into_node_info(self) -> NodeInfo {
655 use HiddenNodesError::*;
656
657 match self {
658 HiddenParts(node_info) => node_info,
659 }
660 }
661}
662
663impl core::fmt::Display for HiddenNodesError {
664 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
665 use HiddenNodesError::*;
666
667 f.write_str(match self {
668 HiddenParts(_) =>
669 "an attempt to construct a tap tree from a node_info containing hidden parts.",
670 })
671 }
672}
673
674#[cfg(feature = "std")]
675impl std::error::Error for HiddenNodesError {
676 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
677 use HiddenNodesError::*;
678
679 match self {
680 HiddenParts(_) => None,
681 }
682 }
683}
684
685#[derive(Clone, Debug, Eq, PartialEq, Hash)]
693#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
694#[cfg_attr(feature = "serde", serde(crate = "actual_serde"))]
695#[cfg_attr(feature = "serde", serde(into = "NodeInfo"))]
696#[cfg_attr(feature = "serde", serde(try_from = "NodeInfo"))]
697pub struct TapTree(NodeInfo);
698
699impl From<TapTree> for NodeInfo {
700 #[inline]
701 fn from(tree: TapTree) -> Self { tree.into_node_info() }
702}
703
704impl TapTree {
705 pub fn node_info(&self) -> &NodeInfo { &self.0 }
707
708 pub fn into_node_info(self) -> NodeInfo { self.0 }
710
711 pub fn script_leaves(&self) -> ScriptLeaves<'_> {
714 ScriptLeaves { leaf_iter: self.0.leaf_nodes() }
715 }
716
717 pub fn root_hash(&self) -> TapNodeHash { self.0.hash }
719}
720
721impl TryFrom<TaprootBuilder> for TapTree {
722 type Error = IncompleteBuilderError;
723
724 fn try_from(builder: TaprootBuilder) -> Result<Self, Self::Error> { builder.try_into_taptree() }
731}
732
733impl TryFrom<NodeInfo> for TapTree {
734 type Error = HiddenNodesError;
735
736 fn try_from(node_info: NodeInfo) -> Result<Self, Self::Error> {
743 if node_info.has_hidden_nodes {
744 Err(HiddenNodesError::HiddenParts(node_info))
745 } else {
746 Ok(TapTree(node_info))
747 }
748 }
749}
750
751pub struct ScriptLeaves<'tree> {
756 leaf_iter: LeafNodes<'tree>,
757}
758
759impl<'tree> Iterator for ScriptLeaves<'tree> {
760 type Item = ScriptLeaf<'tree>;
761
762 #[inline]
763 fn next(&mut self) -> Option<Self::Item> { ScriptLeaf::from_leaf_node(self.leaf_iter.next()?) }
764
765 fn size_hint(&self) -> (usize, Option<usize>) { self.leaf_iter.size_hint() }
766}
767
768impl<'tree> ExactSizeIterator for ScriptLeaves<'tree> {}
769
770impl<'tree> FusedIterator for ScriptLeaves<'tree> {}
771
772impl<'tree> DoubleEndedIterator for ScriptLeaves<'tree> {
773 #[inline]
774 fn next_back(&mut self) -> Option<Self::Item> {
775 ScriptLeaf::from_leaf_node(self.leaf_iter.next_back()?)
776 }
777}
778pub struct LeafNodes<'a> {
782 leaf_iter: core::slice::Iter<'a, LeafNode>,
783}
784
785impl<'a> Iterator for LeafNodes<'a> {
786 type Item = &'a LeafNode;
787
788 #[inline]
789 fn next(&mut self) -> Option<Self::Item> { self.leaf_iter.next() }
790
791 fn size_hint(&self) -> (usize, Option<usize>) { self.leaf_iter.size_hint() }
792}
793
794impl<'tree> ExactSizeIterator for LeafNodes<'tree> {}
795
796impl<'tree> FusedIterator for LeafNodes<'tree> {}
797
798impl<'tree> DoubleEndedIterator for LeafNodes<'tree> {
799 #[inline]
800 fn next_back(&mut self) -> Option<Self::Item> { self.leaf_iter.next_back() }
801}
802#[derive(Debug, Clone, PartialOrd, Ord)]
812pub struct NodeInfo {
813 pub(crate) hash: TapNodeHash,
815 pub(crate) leaves: Vec<LeafNode>,
817 pub(crate) has_hidden_nodes: bool,
819}
820
821impl PartialEq for NodeInfo {
822 fn eq(&self, other: &Self) -> bool { self.hash.eq(&other.hash) }
823}
824
825impl core::hash::Hash for NodeInfo {
826 fn hash<H: core::hash::Hasher>(&self, state: &mut H) { self.hash.hash(state) }
827}
828
829impl Eq for NodeInfo {}
830
831impl NodeInfo {
832 pub fn new_hidden_node(hash: TapNodeHash) -> Self {
834 Self { hash, leaves: vec![], has_hidden_nodes: true }
835 }
836
837 pub fn new_leaf_with_ver(script: ScriptBuf, ver: LeafVersion) -> Self {
839 Self {
840 hash: TapNodeHash::from_script(&script, ver),
841 leaves: vec![LeafNode::new_script(script, ver)],
842 has_hidden_nodes: false,
843 }
844 }
845
846 pub fn combine(a: Self, b: Self) -> Result<Self, TaprootBuilderError> {
848 let mut all_leaves = Vec::with_capacity(a.leaves.len() + b.leaves.len());
849 let (hash, left_first) = TapNodeHash::combine_node_hashes(a.hash, b.hash);
850 let (a, b) = if left_first { (a, b) } else { (b, a) };
851 for mut a_leaf in a.leaves {
852 a_leaf.merkle_branch.push(b.hash)?; all_leaves.push(a_leaf);
854 }
855 for mut b_leaf in b.leaves {
856 b_leaf.merkle_branch.push(a.hash)?; all_leaves.push(b_leaf);
858 }
859 Ok(Self {
860 hash,
861 leaves: all_leaves,
862 has_hidden_nodes: a.has_hidden_nodes || b.has_hidden_nodes,
863 })
864 }
865
866 pub fn leaf_nodes(&self) -> LeafNodes<'_> { LeafNodes { leaf_iter: self.leaves.iter() } }
868
869 pub fn node_hash(&self) -> TapNodeHash { self.hash }
871}
872
873impl TryFrom<TaprootBuilder> for NodeInfo {
874 type Error = IncompleteBuilderError;
875
876 fn try_from(builder: TaprootBuilder) -> Result<Self, Self::Error> {
877 builder.try_into_node_info()
878 }
879}
880
881#[cfg(feature = "serde")]
882impl serde::Serialize for NodeInfo {
883 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
884 where
885 S: serde::Serializer,
886 {
887 use serde::ser::SerializeSeq;
888 let mut seq = serializer.serialize_seq(Some(self.leaves.len() * 2))?;
889 for tap_leaf in self.leaves.iter() {
890 seq.serialize_element(&tap_leaf.merkle_branch().len())?;
891 seq.serialize_element(&tap_leaf.leaf)?;
892 }
893 seq.end()
894 }
895}
896
897#[cfg(feature = "serde")]
898impl<'de> serde::Deserialize<'de> for NodeInfo {
899 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
900 where
901 D: serde::Deserializer<'de>,
902 {
903 struct SeqVisitor;
904 impl<'de> serde::de::Visitor<'de> for SeqVisitor {
905 type Value = NodeInfo;
906
907 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
908 formatter.write_str("Taproot tree in DFS walk order")
909 }
910
911 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
912 where
913 A: serde::de::SeqAccess<'de>,
914 {
915 let size = seq
916 .size_hint()
917 .map(|x| core::mem::size_of::<usize>() * 8 - x.leading_zeros() as usize)
918 .map(|x| x / 2) .unwrap_or(0)
920 .min(TAPROOT_CONTROL_MAX_NODE_COUNT); let mut builder = TaprootBuilder::with_capacity(size);
922 while let Some(depth) = seq.next_element()? {
923 let tap_leaf: TapLeaf = seq
924 .next_element()?
925 .ok_or_else(|| serde::de::Error::custom("Missing tap_leaf"))?;
926 match tap_leaf {
927 TapLeaf::Script(script, ver) => {
928 builder =
929 builder.add_leaf_with_ver(depth, script, ver).map_err(|e| {
930 serde::de::Error::custom(format!("Leaf insertion error: {}", e))
931 })?;
932 }
933 TapLeaf::Hidden(h) => {
934 builder = builder.add_hidden_node(depth, h).map_err(|e| {
935 serde::de::Error::custom(format!(
936 "Hidden node insertion error: {}",
937 e
938 ))
939 })?;
940 }
941 }
942 }
943 NodeInfo::try_from(builder).map_err(|e| {
944 serde::de::Error::custom(format!("Incomplete taproot tree: {}", e))
945 })
946 }
947 }
948
949 deserializer.deserialize_seq(SeqVisitor)
950 }
951}
952
953#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
955#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
956#[cfg_attr(feature = "serde", serde(crate = "actual_serde"))]
957pub enum TapLeaf {
958 Script(ScriptBuf, LeafVersion),
960 Hidden(TapNodeHash),
962}
963
964impl TapLeaf {
965 pub fn as_hidden(&self) -> Option<&TapNodeHash> {
967 if let Self::Hidden(v) = self {
968 Some(v)
969 } else {
970 None
971 }
972 }
973
974 pub fn as_script(&self) -> Option<(&Script, LeafVersion)> {
976 if let Self::Script(script, ver) = self {
977 Some((script, *ver))
978 } else {
979 None
980 }
981 }
982}
983
984#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
986pub struct LeafNode {
987 leaf: TapLeaf,
989 merkle_branch: TaprootMerkleBranch,
991}
992
993impl LeafNode {
994 pub fn new_script(script: ScriptBuf, ver: LeafVersion) -> Self {
996 Self { leaf: TapLeaf::Script(script, ver), merkle_branch: Default::default() }
997 }
998
999 pub fn new_hidden(hash: TapNodeHash) -> Self {
1001 Self { leaf: TapLeaf::Hidden(hash), merkle_branch: Default::default() }
1002 }
1003
1004 #[inline]
1006 pub fn depth(&self) -> u8 {
1007 u8::try_from(self.merkle_branch().len()).expect("depth is guaranteed to fit in a u8")
1009 }
1010
1011 #[inline]
1018 pub fn leaf_hash(&self) -> Option<TapLeafHash> {
1019 let (script, ver) = self.leaf.as_script()?;
1020 Some(TapLeafHash::from_script(script, ver))
1021 }
1022
1023 #[inline]
1028 pub fn node_hash(&self) -> TapNodeHash {
1029 match self.leaf {
1030 TapLeaf::Script(ref script, ver) => TapLeafHash::from_script(script, ver).into(),
1031 TapLeaf::Hidden(ref hash) => *hash,
1032 }
1033 }
1034
1035 #[inline]
1037 pub fn script(&self) -> Option<&Script> { self.leaf.as_script().map(|x| x.0) }
1038
1039 #[inline]
1041 pub fn leaf_version(&self) -> Option<LeafVersion> { self.leaf.as_script().map(|x| x.1) }
1042
1043 #[inline]
1046 pub fn merkle_branch(&self) -> &TaprootMerkleBranch { &self.merkle_branch }
1047
1048 #[inline]
1050 pub fn leaf(&self) -> &TapLeaf { &self.leaf }
1051}
1052
1053#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1056pub struct ScriptLeaf<'leaf> {
1057 version: LeafVersion,
1059 script: &'leaf Script,
1061 merkle_branch: &'leaf TaprootMerkleBranch,
1063}
1064
1065impl<'leaf> ScriptLeaf<'leaf> {
1066 pub fn version(&self) -> LeafVersion { self.version }
1068
1069 pub fn script(&self) -> &Script { self.script }
1071
1072 pub fn merkle_branch(&self) -> &TaprootMerkleBranch { self.merkle_branch }
1074
1075 pub fn from_leaf_node(leaf_node: &'leaf LeafNode) -> Option<Self> {
1077 let (script, ver) = leaf_node.leaf.as_script()?;
1078 Some(Self { version: ver, script, merkle_branch: &leaf_node.merkle_branch })
1079 }
1080}
1081
1082#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1084#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1085#[cfg_attr(feature = "serde", serde(crate = "actual_serde"))]
1086pub struct ControlBlock {
1087 pub leaf_version: LeafVersion,
1089 pub output_key_parity: secp256k1::Parity,
1091 pub internal_key: UntweakedPublicKey,
1093 pub merkle_branch: TaprootMerkleBranch,
1095}
1096
1097impl ControlBlock {
1098 pub fn decode(sl: &[u8]) -> Result<ControlBlock, TaprootError> {
1111 if sl.len() < TAPROOT_CONTROL_BASE_SIZE
1112 || (sl.len() - TAPROOT_CONTROL_BASE_SIZE) % TAPROOT_CONTROL_NODE_SIZE != 0
1113 {
1114 return Err(TaprootError::InvalidControlBlockSize(sl.len()));
1115 }
1116 let output_key_parity = match sl[0] & 1 {
1117 0 => secp256k1::Parity::Even,
1118 _ => secp256k1::Parity::Odd,
1119 };
1120
1121 let leaf_version = LeafVersion::from_consensus(sl[0] & TAPROOT_LEAF_MASK)?;
1122 let internal_key = UntweakedPublicKey::from_slice(&sl[1..TAPROOT_CONTROL_BASE_SIZE])
1123 .map_err(TaprootError::InvalidInternalKey)?;
1124 let merkle_branch = TaprootMerkleBranch::decode(&sl[TAPROOT_CONTROL_BASE_SIZE..])?;
1125 Ok(ControlBlock { leaf_version, output_key_parity, internal_key, merkle_branch })
1126 }
1127
1128 pub fn size(&self) -> usize {
1131 TAPROOT_CONTROL_BASE_SIZE + TAPROOT_CONTROL_NODE_SIZE * self.merkle_branch.len()
1132 }
1133
1134 pub fn encode<W: Write + ?Sized>(&self, writer: &mut W) -> io::Result<usize> {
1140 let first_byte: u8 =
1141 i32::from(self.output_key_parity) as u8 | self.leaf_version.to_consensus();
1142 writer.write_all(&[first_byte])?;
1143 writer.write_all(&self.internal_key.serialize())?;
1144 self.merkle_branch.encode(writer)?;
1145 Ok(self.size())
1146 }
1147
1148 pub fn serialize(&self) -> Vec<u8> {
1154 let mut buf = Vec::with_capacity(self.size());
1155 self.encode(&mut buf).expect("writers don't error");
1156 buf
1157 }
1158
1159 pub fn verify_taproot_commitment<C: secp256k1::Verification>(
1164 &self,
1165 secp: &Secp256k1<C>,
1166 output_key: XOnlyPublicKey,
1167 script: &Script,
1168 ) -> bool {
1169 let mut curr_hash = TapNodeHash::from_script(script, self.leaf_version);
1172 for elem in &self.merkle_branch {
1174 curr_hash = TapNodeHash::from_node_hashes(curr_hash, *elem);
1176 }
1177 let tweak =
1179 TapTweakHash::from_key_and_tweak(self.internal_key, Some(curr_hash)).to_scalar();
1180 self.internal_key.tweak_add_check(secp, &output_key, self.output_key_parity, tweak)
1181 }
1182}
1183
1184#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
1189pub struct FutureLeafVersion(u8);
1190
1191impl FutureLeafVersion {
1192 pub(self) fn from_consensus(version: u8) -> Result<FutureLeafVersion, TaprootError> {
1193 match version {
1194 TAPROOT_LEAF_TAPSCRIPT => unreachable!(
1195 "FutureLeafVersion::from_consensus should be never called for 0xC0 value"
1196 ),
1197 TAPROOT_ANNEX_PREFIX =>
1198 Err(TaprootError::InvalidTaprootLeafVersion(TAPROOT_ANNEX_PREFIX)),
1199 odd if odd & 0xFE != odd => Err(TaprootError::InvalidTaprootLeafVersion(odd)),
1200 even => Ok(FutureLeafVersion(even)),
1201 }
1202 }
1203
1204 #[inline]
1206 pub fn to_consensus(self) -> u8 { self.0 }
1207}
1208
1209impl fmt::Display for FutureLeafVersion {
1210 #[inline]
1211 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(&self.0, f) }
1212}
1213
1214impl fmt::LowerHex for FutureLeafVersion {
1215 #[inline]
1216 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::LowerHex::fmt(&self.0, f) }
1217}
1218
1219impl fmt::UpperHex for FutureLeafVersion {
1220 #[inline]
1221 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::UpperHex::fmt(&self.0, f) }
1222}
1223
1224#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
1226pub enum LeafVersion {
1227 TapScript,
1229
1230 Future(FutureLeafVersion),
1232}
1233
1234impl LeafVersion {
1235 pub fn from_consensus(version: u8) -> Result<Self, TaprootError> {
1242 match version {
1243 TAPROOT_LEAF_TAPSCRIPT => Ok(LeafVersion::TapScript),
1244 TAPROOT_ANNEX_PREFIX =>
1245 Err(TaprootError::InvalidTaprootLeafVersion(TAPROOT_ANNEX_PREFIX)),
1246 future => FutureLeafVersion::from_consensus(future).map(LeafVersion::Future),
1247 }
1248 }
1249
1250 pub fn to_consensus(self) -> u8 {
1252 match self {
1253 LeafVersion::TapScript => TAPROOT_LEAF_TAPSCRIPT,
1254 LeafVersion::Future(version) => version.to_consensus(),
1255 }
1256 }
1257}
1258
1259impl fmt::Display for LeafVersion {
1260 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1261 match (self, f.alternate()) {
1262 (LeafVersion::TapScript, true) => f.write_str("tapscript"),
1263 (LeafVersion::TapScript, false) => fmt::Display::fmt(&TAPROOT_LEAF_TAPSCRIPT, f),
1264 (LeafVersion::Future(version), true) => write!(f, "future_script_{:#04x}", version.0),
1265 (LeafVersion::Future(version), false) => fmt::Display::fmt(version, f),
1266 }
1267 }
1268}
1269
1270impl fmt::LowerHex for LeafVersion {
1271 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1272 fmt::LowerHex::fmt(&self.to_consensus(), f)
1273 }
1274}
1275
1276impl fmt::UpperHex for LeafVersion {
1277 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1278 fmt::UpperHex::fmt(&self.to_consensus(), f)
1279 }
1280}
1281
1282#[cfg(feature = "serde")]
1284impl serde::Serialize for LeafVersion {
1285 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1286 where
1287 S: serde::Serializer,
1288 {
1289 serializer.serialize_u8(self.to_consensus())
1290 }
1291}
1292
1293#[cfg(feature = "serde")]
1295impl<'de> serde::Deserialize<'de> for LeafVersion {
1296 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1297 where
1298 D: serde::Deserializer<'de>,
1299 {
1300 struct U8Visitor;
1301 impl<'de> serde::de::Visitor<'de> for U8Visitor {
1302 type Value = LeafVersion;
1303
1304 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1305 formatter.write_str("a valid consensus-encoded taproot leaf version")
1306 }
1307
1308 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
1309 where
1310 E: serde::de::Error,
1311 {
1312 let value = u8::try_from(value).map_err(|_| {
1313 E::invalid_value(
1314 serde::de::Unexpected::Unsigned(value),
1315 &"consensus-encoded leaf version as u8",
1316 )
1317 })?;
1318 LeafVersion::from_consensus(value).map_err(|_| {
1319 E::invalid_value(
1320 ::serde::de::Unexpected::Unsigned(value as u64),
1321 &"consensus-encoded leaf version as u8",
1322 )
1323 })
1324 }
1325 }
1326
1327 deserializer.deserialize_u8(U8Visitor)
1328 }
1329}
1330
1331#[derive(Debug, Clone, PartialEq, Eq)]
1333#[non_exhaustive]
1334pub enum TaprootBuilderError {
1335 InvalidMerkleTreeDepth(usize),
1337 NodeNotInDfsOrder,
1339 OverCompleteTree,
1341 InvalidInternalKey(secp256k1::Error),
1343 EmptyTree,
1345}
1346
1347impl From<Infallible> for TaprootBuilderError {
1348 fn from(never: Infallible) -> Self { match never {} }
1349}
1350
1351impl fmt::Display for TaprootBuilderError {
1352 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1353 use TaprootBuilderError::*;
1354
1355 match *self {
1356 InvalidMerkleTreeDepth(d) => {
1357 write!(
1358 f,
1359 "Merkle Tree depth({}) must be less than {}",
1360 d, TAPROOT_CONTROL_MAX_NODE_COUNT
1361 )
1362 }
1363 NodeNotInDfsOrder => {
1364 write!(f, "add_leaf/add_hidden must be called in DFS walk order",)
1365 }
1366 OverCompleteTree => write!(
1367 f,
1368 "Attempted to create a tree with two nodes at depth 0. There must\
1369 only be a exactly one node at depth 0",
1370 ),
1371 InvalidInternalKey(ref e) => {
1372 write_err!(f, "invalid internal x-only key"; e)
1373 }
1374 EmptyTree => {
1375 write!(f, "Called finalize on an empty tree")
1376 }
1377 }
1378 }
1379}
1380
1381#[cfg(feature = "std")]
1382impl std::error::Error for TaprootBuilderError {
1383 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
1384 use TaprootBuilderError::*;
1385
1386 match self {
1387 InvalidInternalKey(e) => Some(e),
1388 InvalidMerkleTreeDepth(_) | NodeNotInDfsOrder | OverCompleteTree | EmptyTree => None,
1389 }
1390 }
1391}
1392
1393#[derive(Debug, Clone, PartialEq, Eq)]
1395#[non_exhaustive]
1396pub enum TaprootError {
1397 InvalidMerkleBranchSize(usize),
1399 InvalidMerkleTreeDepth(usize),
1401 InvalidTaprootLeafVersion(u8),
1403 InvalidControlBlockSize(usize),
1405 InvalidInternalKey(secp256k1::Error),
1407 EmptyTree,
1409}
1410
1411impl From<Infallible> for TaprootError {
1412 fn from(never: Infallible) -> Self { match never {} }
1413}
1414
1415impl fmt::Display for TaprootError {
1416 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1417 use TaprootError::*;
1418
1419 match *self {
1420 InvalidMerkleBranchSize(sz) => write!(
1421 f,
1422 "Merkle branch size({}) must be a multiple of {}",
1423 sz, TAPROOT_CONTROL_NODE_SIZE
1424 ),
1425 InvalidMerkleTreeDepth(d) => write!(
1426 f,
1427 "Merkle Tree depth({}) must be less than {}",
1428 d, TAPROOT_CONTROL_MAX_NODE_COUNT
1429 ),
1430 InvalidTaprootLeafVersion(v) => {
1431 write!(f, "Leaf version({}) must have the least significant bit 0", v)
1432 }
1433 InvalidControlBlockSize(sz) => write!(
1434 f,
1435 "Control Block size({}) must be of the form 33 + 32*m where 0 <= m <= {} ",
1436 sz, TAPROOT_CONTROL_MAX_NODE_COUNT
1437 ),
1438 InvalidInternalKey(ref e) => {
1439 write_err!(f, "invalid internal x-only key"; e)
1440 }
1441 EmptyTree => write!(f, "Taproot Tree must contain at least one script"),
1442 }
1443 }
1444}
1445
1446#[cfg(feature = "std")]
1447impl std::error::Error for TaprootError {
1448 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
1449 use TaprootError::*;
1450
1451 match self {
1452 InvalidInternalKey(e) => Some(e),
1453 InvalidMerkleBranchSize(_)
1454 | InvalidMerkleTreeDepth(_)
1455 | InvalidTaprootLeafVersion(_)
1456 | InvalidControlBlockSize(_)
1457 | EmptyTree => None,
1458 }
1459 }
1460}
1461
1462#[cfg(test)]
1463mod test {
1464 use core::str::FromStr;
1465
1466 use hashes::sha256;
1467 use hashes::sha256t::Tag;
1468 use hex::FromHex;
1469 use secp256k1::VerifyOnly;
1470
1471 use super::*;
1472 use crate::sighash::{TapSighash, TapSighashTag};
1473 use crate::{Address, KnownHrp};
1474 extern crate serde_json;
1475
1476 #[cfg(feature = "serde")]
1477 use {
1478 hex::test_hex_unwrap as hex,
1479 serde_test::Configure,
1480 serde_test::{assert_tokens, Token},
1481 };
1482
1483 fn tag_engine(tag_name: &str) -> sha256::HashEngine {
1484 let mut engine = sha256::Hash::engine();
1485 let tag_hash = sha256::Hash::hash(tag_name.as_bytes());
1486 engine.input(tag_hash.as_ref());
1487 engine.input(tag_hash.as_ref());
1488 engine
1489 }
1490
1491 #[test]
1492 fn test_midstates() {
1493 assert_eq!(tag_engine("TapLeaf").midstate(), TapLeafTag::engine().midstate());
1495 assert_eq!(tag_engine("TapBranch").midstate(), TapBranchTag::engine().midstate());
1496 assert_eq!(tag_engine("TapTweak").midstate(), TapTweakTag::engine().midstate());
1497 assert_eq!(tag_engine("TapSighash").midstate(), TapSighashTag::engine().midstate());
1498
1499 fn empty_hash(tag_name: &str) -> [u8; 32] {
1501 let mut e = tag_engine(tag_name);
1502 e.input(&[]);
1503 TapNodeHash::from_engine(e).to_byte_array()
1504 }
1505 assert_eq!(empty_hash("TapLeaf"), TapLeafHash::hash(&[]).to_byte_array());
1506 assert_eq!(empty_hash("TapBranch"), TapNodeHash::hash(&[]).to_byte_array());
1507 assert_eq!(empty_hash("TapTweak"), TapTweakHash::hash(&[]).to_byte_array());
1508 assert_eq!(empty_hash("TapSighash"), TapSighash::hash(&[]).to_byte_array());
1509 }
1510
1511 #[test]
1512 fn test_vectors_core() {
1513 assert_eq!(
1519 TapLeafHash::from_engine(TapLeafTag::engine()).to_string(),
1520 "5212c288a377d1f8164962a5a13429f9ba6a7b84e59776a52c6637df2106facb"
1521 );
1522 assert_eq!(
1523 TapNodeHash::from_engine(TapBranchTag::engine()).to_string(),
1524 "53c373ec4d6f3c53c1f5fb2ff506dcefe1a0ed74874f93fa93c8214cbe9ffddf"
1525 );
1526 assert_eq!(
1527 TapTweakHash::from_engine(TapTweakTag::engine()).to_string(),
1528 "8aa4229474ab0100b2d6f0687f031d1fc9d8eef92a042ad97d279bff456b15e4"
1529 );
1530 assert_eq!(
1531 TapSighash::from_engine(TapSighashTag::engine()).to_string(),
1532 "dabc11914abcd8072900042a2681e52f8dba99ce82e224f97b5fdb7cd4b9c803"
1533 );
1534
1535 assert_eq!(
1541 TapLeafHash::hash(&[0]).to_string(),
1542 "ed1382037800c9dd938dd8854f1a8863bcdeb6705069b4b56a66ec22519d5829"
1543 );
1544 assert_eq!(
1545 TapNodeHash::hash(&[0]).to_string(),
1546 "92534b1960c7e6245af7d5fda2588db04aa6d646abc2b588dab2b69e5645eb1d"
1547 );
1548 assert_eq!(
1549 TapTweakHash::hash(&[0]).to_string(),
1550 "cd8737b5e6047fc3f16f03e8b9959e3440e1bdf6dd02f7bb899c352ad490ea1e"
1551 );
1552 assert_eq!(
1553 TapSighash::hash(&[0]).to_string(),
1554 "c2fd0de003889a09c4afcf676656a0d8a1fb706313ff7d509afb00c323c010cd"
1555 );
1556 }
1557
1558 fn _verify_tap_commitments(
1559 secp: &Secp256k1<VerifyOnly>,
1560 out_spk_hex: &str,
1561 script_hex: &str,
1562 control_block_hex: &str,
1563 ) {
1564 let out_pk = XOnlyPublicKey::from_str(&out_spk_hex[4..]).unwrap();
1565 let out_pk = TweakedPublicKey::dangerous_assume_tweaked(out_pk);
1566 let script = ScriptBuf::from_hex(script_hex).unwrap();
1567 let control_block =
1568 ControlBlock::decode(&Vec::<u8>::from_hex(control_block_hex).unwrap()).unwrap();
1569 assert_eq!(control_block_hex, control_block.serialize().to_lower_hex_string());
1570 assert!(control_block.verify_taproot_commitment(
1571 secp,
1572 out_pk.to_x_only_public_key(),
1573 &script
1574 ));
1575 }
1576
1577 #[test]
1578 fn control_block_verify() {
1579 let secp = Secp256k1::verification_only();
1580 _verify_tap_commitments(&secp, "51205dc8e62b15e0ebdf44751676be35ba32eed2e84608b290d4061bbff136cd7ba9", "6a", "c1a9d6f66cd4b25004f526bfa873e56942f98e8e492bd79ed6532b966104817c2bda584e7d32612381cf88edc1c02e28a296e807c16ad22f591ee113946e48a71e0641e660d1e5392fb79d64838c2b84faf04b7f5f283c9d8bf83e39e177b64372a0cd22eeab7e093873e851e247714eff762d8a30be699ba4456cfe6491b282e193a071350ae099005a5950d74f73ba13077a57bc478007fb0e4d1099ce9cf3d4");
1582 _verify_tap_commitments(&secp, "5120e208c869c40d8827101c5ad3238018de0f3f5183d77a0c53d18ac28ddcbcd8ad", "f4", "c0a0eb12e60a52614986c623cbb6621dcdba3a47e3be6b37e032b7a11c7b98f40090ab1f4890d51115998242ebce636efb9ede1b516d9eb8952dc1068e0335306199aaf103cceb41d9bc37ec231aca89b984b5fd3c65977ce764d51033ac65adb4da14e029b1e154a85bfd9139e7aa2720b6070a4ceba8264ca61d5d3ac27aceb9ef4b54cd43c2d1fd5e11b5c2e93cf29b91ea3dc5b832201f02f7473a28c63246");
1583 _verify_tap_commitments(
1584 &secp,
1585 "5120567666e7df90e0450bb608e17c01ed3fbcfa5355a5f8273e34e583bfaa70ce09",
1586 "203455139bf238a3067bd72ed77e0ab8db590330f55ed58dba7366b53bf4734279ac",
1587 "c1a0eb12e60a52614986c623cbb6621dcdba3a47e3be6b37e032b7a11c7b98f400",
1588 );
1589 _verify_tap_commitments(&secp, "5120580a19e47269414a55eb86d5d0c6c9b371455d9fd2154412a57dec840df99fe1", "6a", "bca0eb12e60a52614986c623cbb6621dcdba3a47e3be6b37e032b7a11c7b98f40042ba1bd1c63c03ccff60d4c4d53a653f87909eb3358e7fa45c9d805231fb08c933e1f4e0f9d17f591df1419df7d5b7eb5f744f404c5ef9ecdb1b89b18cafa3a816d8b5dba3205f9a9c05f866d91f40d2793a7586d502cb42f46c7a11f66ad4aa");
1590 _verify_tap_commitments(&secp, "5120228b94a4806254a38d6efa8a134c28ebc89546209559dfe40b2b0493bafacc5b", "6a50", "c0a0eb12e60a52614986c623cbb6621dcdba3a47e3be6b37e032b7a11c7b98f4009c9aed3dfd11ab0e78bf87ef3bf296269dc4b0f7712140386d6980992bab4b45");
1591 _verify_tap_commitments(
1592 &secp,
1593 "5120567666e7df90e0450bb608e17c01ed3fbcfa5355a5f8273e34e583bfaa70ce09",
1594 "203455139bf238a3067bd72ed77e0ab8db590330f55ed58dba7366b53bf4734279ac",
1595 "c1a0eb12e60a52614986c623cbb6621dcdba3a47e3be6b37e032b7a11c7b98f400",
1596 );
1597 _verify_tap_commitments(
1598 &secp,
1599 "5120b0a79103c31fe51eea61d2873bad8a25a310da319d7e7a85f825fa7a00ea3f85",
1600 "203455139bf238a3067bd72ed77e0ab8db590330f55ed58dba7366b53bf4734279ad51",
1601 "c1a0eb12e60a52614986c623cbb6621dcdba3a47e3be6b37e032b7a11c7b98f400",
1602 );
1603 _verify_tap_commitments(&secp, "5120f2f62e854a0012aeba78cd4ba4a0832447a5262d4c6eb4f1c95c7914b536fc6c", "6a86", "c1a0eb12e60a52614986c623cbb6621dcdba3a47e3be6b37e032b7a11c7b98f4009ad3d30479f0689dbdf59a6b840d60ad485b2effbed1825a75ce19a44e460e09056f60ea686d79cfa4fb79f197b2e905ac857a983be4a5a41a4873e865aa950780c0237de279dc063e67deec46ef8e1bc351bf12c4d67a6d568001faf097e797e6ee620f53cfe0f8acaddf2063c39c3577853bb46d61ffcba5a024c3e1216837");
1604 _verify_tap_commitments(&secp, "51202a4772070b49bae68b44315032cdbf9c40c7c2f896781b32b931b73dbfb26d7e", "6af8", "c0a0eb12e60a52614986c623cbb6621dcdba3a47e3be6b37e032b7a11c7b98f4006f183944a14618fc7fe9ceade0f58e43a19d3c3b179ea6c43c29616413b6971c99aaf103cceb41d9bc37ec231aca89b984b5fd3c65977ce764d51033ac65adb4c3462adec78cd04f3cc156bdadec50def99feae0dc6a23664e8a2b0d42d6ca9eb968dfdf46c23af642b2688351904e0a0630e71ffac5bcaba33b9b2c8a7495ec");
1605 _verify_tap_commitments(&secp, "5120a32b0b8cfafe0f0f8d5870030ba4d19a8725ad345cb3c8420f86ac4e0dff6207", "4c", "e8a0eb12e60a52614986c623cbb6621dcdba3a47e3be6b37e032b7a11c7b98f400615da7ac8d078e5fc7f4690fc2127ba40f0f97cc070ade5b3a7919783d91ef3f13734aab908ae998e57848a01268fe8217d70bc3ee8ea8ceae158ae964a4b5f3af20b50d7019bf47fde210eee5c52f1cfe71cfca78f2d3e7c1fd828c80351525");
1606 _verify_tap_commitments(
1607 &secp,
1608 "5120b0a79103c31fe51eea61d2873bad8a25a310da319d7e7a85f825fa7a00ea3f85",
1609 "203455139bf238a3067bd72ed77e0ab8db590330f55ed58dba7366b53bf4734279ad51",
1610 "c1a0eb12e60a52614986c623cbb6621dcdba3a47e3be6b37e032b7a11c7b98f400",
1611 );
1612 _verify_tap_commitments(&secp, "51208678459f1fa0f80e9b89b8ffdcaf46a022bdf60aa45f1fed9a96145edf4ec400", "6a50", "c0a0eb12e60a52614986c623cbb6621dcdba3a47e3be6b37e032b7a11c7b98f4001eff29e1a89e650076b8d3c56302881d09c9df215774ed99993aaed14acd6615");
1613 _verify_tap_commitments(&secp, "5120017316303aed02bcdec424c851c9eacbe192b013139bd9634c4e19b3475b06e1", "61", "02a0eb12e60a52614986c623cbb6621dcdba3a47e3be6b37e032b7a11c7b98f40050462265ca552b23cbb4fe021b474313c8cb87d4a18b3f7bdbeb2b418279ba31fc6509d829cd42336f563363cb3538d78758e0876c71e13012eb2b656eb0edb051a2420a840d5c8c6c762abc7410af2c311f606b20ca2ace56a8139f84b1379a");
1614 _verify_tap_commitments(&secp, "5120896d4d5d2236e86c6e9320e86d1a7822e652907cbd508360e8c71aefc127c77d", "61", "14a0eb12e60a52614986c623cbb6621dcdba3a47e3be6b37e032b7a11c7b98f4001ab0e9d9a4858a0e69605fe9c5a42d739fbe26fa79650e7074f462b02645f7ea1c91802b298cd91e6b5af57c6a013d93397cd2ecbd5569382cc27becf44ff4fff8960b20f846160c159c58350f6b6072cf1b3daa5185b7a42524fb72cbc252576ae46732b8e31ac24bfa7d72f4c3713e8696f99d8ac6c07e4c820a03f249f144");
1615 _verify_tap_commitments(&secp, "512093c7378d96518a75448821c4f7c8f4bae7ce60f804d03d1f0628dd5dd0f5de51", "04ffffffff203455139bf238a3067bd72ed77e0ab8db590330f55ed58dba7366b53bf4734279ba04feffffff87ab", "c1a0eb12e60a52614986c623cbb6621dcdba3a47e3be6b37e032b7a11c7b98f400c9a5cd1f6c8a81f5648e39f9810591df1c9a8f1fe97c92e03ecd7c0c016c951983e05473c6e8238cb4c780ea2ce62552b2a3eee068ceffc00517cd7b97e10dad");
1616 _verify_tap_commitments(&secp, "5120b28d75a7179de6feb66b8bb0bfa2b2c739d1a41cf7366a1b393804a844db8a28", "61", "c4a0eb12e60a52614986c623cbb6621dcdba3a47e3be6b37e032b7a11c7b98f400eebc95ded88fb8050094e8dfa958c3be0894eaff0fafae678206b26918d8d7ac47039d40fe34d04b4155df7f1be7f2a49253c7e87812ea9e569e683ac27459e652d6503aa32d64734d00adfee8798b2eed28858abf3bd038e8fa58eb7df4a2d9");
1617 _verify_tap_commitments(&secp, "512043e4aa733fc6f43c78a31c2b3c192623acf5cc8c01199ebcc4de88067baca83e", "bd4c", "c1a0eb12e60a52614986c623cbb6621dcdba3a47e3be6b37e032b7a11c7b98f4003f7be6f8848b5bddf332c4d7bd83077f73701e2479f70e02b5730e841234d082b8b41ebea96ffd937715d9faeaa6895e6ef3b22919c554b75df12b3371d328023e443d1df50634ecc1cd169803a1e546f0d44304d8fc5056c408e597fed469b8437d6660eaad3cf72e35ba6e5ff7ddd5e293c1e7e813c871df4f46508e9946ec");
1618 _verify_tap_commitments(&secp, "5120ee9aecb28f5f35ce1f8b5ec80275ac0f81bca4a21b29b4632fb4bcbef8823e6a", "2021a5981b13be29c9d4ea179ea44a8b773ea8c02d68f6f6eefd98de20d4bd055fac", "c13359c284c196b6e80f0cf1d93b6a397cf7ee722f0427b705bd954b88ada8838bd2622fd0e104fc50aa763b43c6a792d7d117029983abd687223b4344a9402c618bba7f5fc3fa8a57491f6842acde88c1e675ca35caea3b1a69ee2c2d9b10f615");
1619 _verify_tap_commitments(&secp, "5120885274df2252b44764dcef53c21f21154e8488b7e79fafbc96b9ebb22ad0200d", "6a50", "c1a0eb12e60a52614986c623cbb6621dcdba3a47e3be6b37e032b7a11c7b98f4000793597254158918e3369507f2d6fdbef17d18b1028bbb0719450ded0f42c58f");
1620 _verify_tap_commitments(&secp, "512066f6f6f91d47674d198a28388e1eb05ec24e6ddbba10f16396b1a80c08675121", "6a50", "c1a0eb12e60a52614986c623cbb6621dcdba3a47e3be6b37e032b7a11c7b98f400fe92aff70a2e8e2a4f34a913b99612468a41e0f8ecaff9a729a173d11013c27e");
1621 _verify_tap_commitments(&secp, "5120868ed9307bd4637491ff03e3aa2c216a08fe213cac8b6cedbb9ab31dbfa6512c", "61", "a2a0eb12e60a52614986c623cbb6621dcdba3a47e3be6b37e032b7a11c7b98f400da584e7d32612381cf88edc1c02e28a296e807c16ad22f591ee113946e48a71e46c7eccffefd2d573ec014130e508f0c9963ccebd7830409f7b1b1301725e9fa759d4ef857ec8e0bb42d6d31609d3c7e77de3bfa28c38f93393a6ddbabe819ec560ed4f061fbe742a5fd2a648d5209469420434c8753da3fa7067cc2bb4c172a");
1622 _verify_tap_commitments(&secp, "5120c1a00a9baa82888fd7d30291135a7eaa9e9966a5f16db2b10460572f8b108d8d", "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "5ba0eb12e60a52614986c623cbb6621dcdba3a47e3be6b37e032b7a11c7b98f4007960d7b37dd1361aee34510e77acb4d27ddca17648a17e28475032538c1eb500f5a747f2c0893f79fe153ae918ac3d696de9322aa679aae62051ff5ed83aa502b338bd907346abd4cd9cf06117cb35d55a5a8dd950843522f8de7b5c7fba1804c38b0778d3d76b383f6db6fdf9d6e770da8fffbfa5152c0b8b38129885bcdee6");
1623 _verify_tap_commitments(&secp, "5120bb9abeff7286b76dfc61800c548fe2621ff47506e47201a85c543b4a9a96fead", "75203455139bf238a3067bd72ed77e0ab8db590330f55ed58dba7366b53bf47342796ead6ead6ead6ead6ead6ead6ead6ead6ead6ead6ead6ead6eadac", "c0a0eb12e60a52614986c623cbb6621dcdba3a47e3be6b37e032b7a11c7b98f4003eb5cdc419e0a6a800f34583ce750f387be34879c26f4230991bd61da743ad9d34d288e79397b709ac22ad8cc57645d593af3e15b97a876362117177ab2519c000000000000000000000000000000000000000000000000000000000000000007160c3a48c8b17bc3aeaf01db9e0a96ac47a5a9fa329e046856e7765e89c8a93ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff07feb9aa7cd72c78e66a85414cd19289f8b0ab1415013dc2a007666aa9248ec1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001fccc8bea662a9442a94f7ba0643c1d7ee7cc689f3b3506b7c8c99fd3f3b3d7772972dcdf2550cf95b65098aea67f72fef10abdcf1cef9815af8f4c4644b060e0000000000000000000000000000000000000000000000000000000000000000");
1624 _verify_tap_commitments(&secp, "5120afddc189ea51094b4cbf463806792e9c8b35dfdc5e01228c78376380d0046b00", "4d09024747703eb9f759ce5ecd839109fecc40974ab16f5173ea390daaa5a78f7abe898165c90990062af998c5dc7989818393158a2c62b7ece727e7f5400d2efd33db8732599f6d1dce6b5b68d2d47317f2de6c9df118f61227f98453225036618aaf058140f2415d134fa69ba041c724ad81387f8c568d12ddc49eb32a71532096181b3f85fd465b8e9a176bb19f45c070baad47a2cc4505414b88c31cb5b0a192b2d2d56c404a37070b04d42c875c4ac351224f5b254f9ad0b820f43cad292d6565f796bf083173e14723f1e543c85a61689ddd5cb6666b240c15c38ce3320bf0c3be9e0322e5ef72366c294d3a2d7e8b8e7db875e7ae814537554f10b91c72b8b413e026bd5d5e917de4b54fa8f43f38771a7f242aa32dcb7ca1b0588dbf54af7ab9455047fbb894cdfdd242166db784276430eb47d4df092a6b8cb160eb982fe7d14a44283bdb4a9861ca65c06fd8b2546cfbfe38bc77f527de1b9bfd2c95a3e283b7b1d1d2b2fa291256a90a7003aefcef47ceabf113865a494af43e96a38b0b00919855eb7722ea2363e0ddfc9c51c08631d01e2a2d56e786b4ff6f1e5d415facc9c2619c285d9ad43001878294157cb025f639fb954271fd1d6173f6bc16535672f6abdd72b0284b4ff3eaf5b7247719d7c39365622610efae6562bef6e08a0b370fba75bb04dbdb90a482d8417e057f8bd021ea6ac32d0d48b08be9f77833b11e5e739960c9837d7583", "c0a0eb12e60a52614986c623cbb6621dcdba3a47e3be6b37e032b7a11c7b98f400ff698adfda0327f188e2ee35f7aecc0f90c9138a350d450648d968c2b5dd7ef94ddd3ec418dc0d03ee4956feb708d838ed2b20e5a193465a6a1467fd3054e1ea141ea4c4c503a6271e19a090e2a69a24282e3be04c4f98720f7a0eb274d9693d13a8e3c139aa625fa2aefd09854570527f9ac545bda1b689719f5cb715612c07");
1625 _verify_tap_commitments(&secp, "5120afddc189ea51094b4cbf463806792e9c8b35dfdc5e01228c78376380d0046b00", "83", "c0a0eb12e60a52614986c623cbb6621dcdba3a47e3be6b37e032b7a11c7b98f4007388cda01113397d4cd00bcfbd08fd68c3cfe3a42cbfe3a7651c1d5e6dacf1ad99aaf103cceb41d9bc37ec231aca89b984b5fd3c65977ce764d51033ac65adb4b59764bec92507e4a4c3f01a06f05980163ca10f1c549bfe01f85fa4f109a1295e607f5ed9f1008048474de336f11f67a1fbf2012f58944dede0ab19a3ca81f5");
1626 _verify_tap_commitments(&secp, "512093c7378d96518a75448821c4f7c8f4bae7ce60f804d03d1f0628dd5dd0f5de51", "04ffffffff203455139bf238a3067bd72ed77e0ab8db590330f55ed58dba7366b53bf4734279ba04feffffff87ab", "c1a0eb12e60a52614986c623cbb6621dcdba3a47e3be6b37e032b7a11c7b98f400c9a5cd1f6c8a81f5648e39f9810591df1c9a8f1fe97c92e03ecd7c0c016c951983e05473c6e8238cb4c780ea2ce62552b2a3eee068ceffc00517cd7b97e10dad");
1627 }
1628
1629 #[test]
1630 fn build_huffman_tree() {
1631 let secp = Secp256k1::verification_only();
1632 let internal_key = UntweakedPublicKey::from_str(
1633 "93c7378d96518a75448821c4f7c8f4bae7ce60f804d03d1f0628dd5dd0f5de51",
1634 )
1635 .unwrap();
1636
1637 let script_weights = vec![
1638 (10, ScriptBuf::from_hex("51").unwrap()), (20, ScriptBuf::from_hex("52").unwrap()),
1640 (20, ScriptBuf::from_hex("53").unwrap()),
1641 (30, ScriptBuf::from_hex("54").unwrap()),
1642 (19, ScriptBuf::from_hex("55").unwrap()),
1643 ];
1644 let tree_info =
1645 TaprootSpendInfo::with_huffman_tree(&secp, internal_key, script_weights.clone())
1646 .unwrap();
1647
1648 for (script, length) in [("51", 3), ("52", 2), ("53", 2), ("54", 2), ("55", 3)].iter() {
1659 assert_eq!(
1660 *length,
1661 tree_info
1662 .script_map
1663 .get(&(ScriptBuf::from_hex(script).unwrap(), LeafVersion::TapScript))
1664 .expect("Present Key")
1665 .iter()
1666 .next()
1667 .expect("Present Path")
1668 .len()
1669 );
1670 }
1671
1672 let output_key = tree_info.output_key();
1674
1675 for (_weights, script) in script_weights {
1677 let ver_script = (script, LeafVersion::TapScript);
1678 let ctrl_block = tree_info.control_block(&ver_script).unwrap();
1679 assert!(ctrl_block.verify_taproot_commitment(
1680 &secp,
1681 output_key.to_x_only_public_key(),
1682 &ver_script.0
1683 ))
1684 }
1685 }
1686
1687 #[test]
1688 fn taptree_builder() {
1689 let secp = Secp256k1::verification_only();
1690 let internal_key = UntweakedPublicKey::from_str(
1691 "93c7378d96518a75448821c4f7c8f4bae7ce60f804d03d1f0628dd5dd0f5de51",
1692 )
1693 .unwrap();
1694
1695 let builder = TaprootBuilder::new();
1696 let a = ScriptBuf::from_hex("51").unwrap();
1706 let b = ScriptBuf::from_hex("52").unwrap();
1707 let c = ScriptBuf::from_hex("53").unwrap();
1708 let d = ScriptBuf::from_hex("54").unwrap();
1709 let e = ScriptBuf::from_hex("55").unwrap();
1710 let builder = builder.add_leaf(2, a.clone()).unwrap();
1711 let builder = builder.add_leaf(2, b.clone()).unwrap();
1712 let builder = builder.add_leaf(2, c.clone()).unwrap();
1713 let builder = builder.add_leaf(3, d.clone()).unwrap();
1714
1715 let builder = builder.finalize(&secp, internal_key).unwrap_err();
1717 let builder = builder.add_leaf(3, e.clone()).unwrap();
1718
1719 #[cfg(feature = "serde")]
1720 {
1721 let tree = TapTree::try_from(builder.clone()).unwrap();
1722 #[rustfmt::skip]
1724 assert_tokens(&tree.readable(), &[
1725 Token::Seq { len: Some(10) },
1726 Token::U64(2), Token::TupleVariant { name: "TapLeaf", variant: "Script", len: 2}, Token::Str("51"), Token::U8(192), Token::TupleVariantEnd,
1727 Token::U64(2), Token::TupleVariant { name: "TapLeaf", variant: "Script", len: 2}, Token::Str("52"), Token::U8(192), Token::TupleVariantEnd,
1728 Token::U64(3), Token::TupleVariant { name: "TapLeaf", variant: "Script", len: 2}, Token::Str("55"), Token::U8(192), Token::TupleVariantEnd,
1729 Token::U64(3), Token::TupleVariant { name: "TapLeaf", variant: "Script", len: 2}, Token::Str("54"), Token::U8(192), Token::TupleVariantEnd,
1730 Token::U64(2), Token::TupleVariant { name: "TapLeaf", variant: "Script", len: 2}, Token::Str("53"), Token::U8(192), Token::TupleVariantEnd,
1731 Token::SeqEnd,
1732 ],);
1733
1734 let node_info = TapTree::try_from(builder.clone()).unwrap().into_node_info();
1735 #[rustfmt::skip]
1737 assert_tokens(&node_info.readable(), &[
1738 Token::Seq { len: Some(10) },
1739 Token::U64(2), Token::TupleVariant { name: "TapLeaf", variant: "Script", len: 2}, Token::Str("51"), Token::U8(192), Token::TupleVariantEnd,
1740 Token::U64(2), Token::TupleVariant { name: "TapLeaf", variant: "Script", len: 2}, Token::Str("52"), Token::U8(192), Token::TupleVariantEnd,
1741 Token::U64(3), Token::TupleVariant { name: "TapLeaf", variant: "Script", len: 2}, Token::Str("55"), Token::U8(192), Token::TupleVariantEnd,
1742 Token::U64(3), Token::TupleVariant { name: "TapLeaf", variant: "Script", len: 2}, Token::Str("54"), Token::U8(192), Token::TupleVariantEnd,
1743 Token::U64(2), Token::TupleVariant { name: "TapLeaf", variant: "Script", len: 2}, Token::Str("53"), Token::U8(192), Token::TupleVariantEnd,
1744 Token::SeqEnd,
1745 ],);
1746 }
1747
1748 let tree_info = builder.finalize(&secp, internal_key).unwrap();
1749 let output_key = tree_info.output_key();
1750
1751 for script in [a, b, c, d, e] {
1752 let ver_script = (script, LeafVersion::TapScript);
1753 let ctrl_block = tree_info.control_block(&ver_script).unwrap();
1754 assert!(ctrl_block.verify_taproot_commitment(
1755 &secp,
1756 output_key.to_x_only_public_key(),
1757 &ver_script.0
1758 ))
1759 }
1760 }
1761
1762 #[test]
1763 #[cfg(feature = "serde")]
1764 fn test_leaf_version_serde() {
1765 let leaf_version = LeafVersion::TapScript;
1766 assert_tokens(&leaf_version, &[Token::U8(192)]);
1768
1769 let json = serde_json::to_string(&leaf_version).unwrap();
1770 let leaf_version2 = serde_json::from_str(&json).unwrap();
1771 assert_eq!(leaf_version, leaf_version2);
1772 }
1773
1774 #[test]
1775 #[cfg(feature = "serde")]
1776 fn test_merkle_branch_serde() {
1777 let dummy_hash = hex!("03ba2a4dcd914fed29a1c630c7e811271b081a0e2f2f52cf1c197583dfd46c1b");
1778 let hash1 = TapNodeHash::from_slice(&dummy_hash).unwrap();
1779 let dummy_hash = hex!("8d79dedc2fa0b55167b5d28c61dbad9ce1191a433f3a1a6c8ee291631b2c94c9");
1780 let hash2 = TapNodeHash::from_slice(&dummy_hash).unwrap();
1781 let merkle_branch = TaprootMerkleBranch::from([hash1, hash2]);
1782 serde_test::assert_tokens(
1784 &merkle_branch.readable(),
1785 &[
1786 Token::Seq { len: Some(2) },
1787 Token::Str("03ba2a4dcd914fed29a1c630c7e811271b081a0e2f2f52cf1c197583dfd46c1b"),
1788 Token::Str("8d79dedc2fa0b55167b5d28c61dbad9ce1191a433f3a1a6c8ee291631b2c94c9"),
1789 Token::SeqEnd,
1790 ],
1791 );
1792 }
1793
1794 #[test]
1795 fn bip_341_tests() {
1796 fn process_script_trees(
1797 v: &serde_json::Value,
1798 mut builder: TaprootBuilder,
1799 leaves: &mut Vec<(ScriptBuf, LeafVersion)>,
1800 depth: u8,
1801 ) -> TaprootBuilder {
1802 if v.is_null() {
1803 } else if v.is_array() {
1805 for leaf in v.as_array().unwrap() {
1806 builder = process_script_trees(leaf, builder, leaves, depth + 1);
1807 }
1808 } else {
1809 let script = ScriptBuf::from_hex(v["script"].as_str().unwrap()).unwrap();
1810 let ver =
1811 LeafVersion::from_consensus(v["leafVersion"].as_u64().unwrap() as u8).unwrap();
1812 leaves.push((script.clone(), ver));
1813 builder = builder.add_leaf_with_ver(depth, script, ver).unwrap();
1814 }
1815 builder
1816 }
1817
1818 let data = bip_341_read_json();
1819 assert!(data["version"] == 1);
1821 let secp = &secp256k1::Secp256k1::verification_only();
1822
1823 for arr in data["scriptPubKey"].as_array().unwrap() {
1824 let internal_key =
1825 XOnlyPublicKey::from_str(arr["given"]["internalPubkey"].as_str().unwrap()).unwrap();
1826 let script_tree = &arr["given"]["scriptTree"];
1828 let mut merkle_root = None;
1829 if script_tree.is_null() {
1830 assert!(arr["intermediary"]["merkleRoot"].is_null());
1831 } else {
1832 merkle_root = Some(
1833 TapNodeHash::from_str(arr["intermediary"]["merkleRoot"].as_str().unwrap())
1834 .unwrap(),
1835 );
1836 let leaf_hashes = arr["intermediary"]["leafHashes"].as_array().unwrap();
1837 let ctrl_blks = arr["expected"]["scriptPathControlBlocks"].as_array().unwrap();
1838 let mut builder = TaprootBuilder::new();
1839 let mut leaves = vec![];
1840 builder = process_script_trees(script_tree, builder, &mut leaves, 0);
1841 let spend_info = builder.finalize(secp, internal_key).unwrap();
1842 for (i, script_ver) in leaves.iter().enumerate() {
1843 let expected_leaf_hash = leaf_hashes[i].as_str().unwrap();
1844 let expected_ctrl_blk = ControlBlock::decode(
1845 &Vec::<u8>::from_hex(ctrl_blks[i].as_str().unwrap()).unwrap(),
1846 )
1847 .unwrap();
1848
1849 let leaf_hash = TapLeafHash::from_script(&script_ver.0, script_ver.1);
1850 let ctrl_blk = spend_info.control_block(script_ver).unwrap();
1851 assert_eq!(leaf_hash.to_string(), expected_leaf_hash);
1852 assert_eq!(ctrl_blk, expected_ctrl_blk);
1853 }
1854 }
1855 let expected_output_key =
1856 XOnlyPublicKey::from_str(arr["intermediary"]["tweakedPubkey"].as_str().unwrap())
1857 .unwrap();
1858 let expected_tweak =
1859 TapTweakHash::from_str(arr["intermediary"]["tweak"].as_str().unwrap()).unwrap();
1860 let expected_spk =
1861 ScriptBuf::from_hex(arr["expected"]["scriptPubKey"].as_str().unwrap()).unwrap();
1862 let expected_addr =
1863 Address::from_str(arr["expected"]["bip350Address"].as_str().unwrap())
1864 .unwrap()
1865 .assume_checked();
1866
1867 let tweak = TapTweakHash::from_key_and_tweak(internal_key, merkle_root);
1868 let (output_key, _parity) = internal_key.tap_tweak(secp, merkle_root);
1869 let addr = Address::p2tr(secp, internal_key, merkle_root, KnownHrp::Mainnet);
1870 let spk = addr.script_pubkey();
1871
1872 assert_eq!(expected_output_key, output_key.to_x_only_public_key());
1873 assert_eq!(expected_tweak, tweak);
1874 assert_eq!(expected_addr, addr);
1875 assert_eq!(expected_spk, spk);
1876 }
1877 }
1878
1879 fn bip_341_read_json() -> serde_json::Value {
1880 let json_str = include_str!("../../tests/data/bip341_tests.json");
1881 serde_json::from_str(json_str).expect("JSON was not well-formatted")
1882 }
1883
1884 #[test]
1885 fn leaf_version_future_fmt() {
1886 let v = LeafVersion::Future(FutureLeafVersion(1));
1887 assert_eq!(format!("{:#}", v), "future_script_0x01");
1888 }
1889}