1use crate::crypto::tagged_hash;
19use crate::encoding;
20use crate::error::SignerError;
21
22#[derive(Clone, Debug, PartialEq, Eq)]
26pub struct TapLeaf {
27 pub version: u8,
29 pub script: Vec<u8>,
31}
32
33impl TapLeaf {
34 pub fn new(version: u8, script: Vec<u8>) -> Self {
36 Self { version, script }
37 }
38
39 pub fn tapscript(script: Vec<u8>) -> Self {
41 Self {
42 version: 0xC0,
43 script,
44 }
45 }
46
47 pub fn leaf_hash(&self) -> [u8; 32] {
49 let mut data = Vec::new();
50 data.push(self.version);
51 encoding::encode_compact_size(&mut data, self.script.len() as u64);
52 data.extend_from_slice(&self.script);
53 tagged_hash(b"TapLeaf", &data)
54 }
55}
56
57#[derive(Clone, Debug)]
61pub enum TapTree {
62 Leaf(TapLeaf),
64 Branch(Box<TapTree>, Box<TapTree>),
66}
67
68impl TapTree {
69 pub fn leaf(tap_leaf: TapLeaf) -> Self {
71 TapTree::Leaf(tap_leaf)
72 }
73
74 pub fn branch(left: TapTree, right: TapTree) -> Self {
76 TapTree::Branch(Box::new(left), Box::new(right))
77 }
78
79 pub fn merkle_root(&self) -> [u8; 32] {
84 match self {
85 TapTree::Leaf(leaf) => leaf.leaf_hash(),
86 TapTree::Branch(left, right) => {
87 let left_hash = left.merkle_root();
88 let right_hash = right.merkle_root();
89 tap_branch_hash(&left_hash, &right_hash)
90 }
91 }
92 }
93
94 pub fn merkle_proof(&self, target_leaf: &TapLeaf) -> Option<Vec<[u8; 32]>> {
99 self.find_proof(target_leaf)
100 }
101
102 fn find_proof(&self, target: &TapLeaf) -> Option<Vec<[u8; 32]>> {
103 match self {
104 TapTree::Leaf(leaf) => {
105 if leaf == target {
106 Some(Vec::new())
107 } else {
108 None
109 }
110 }
111 TapTree::Branch(left, right) => {
112 if let Some(mut path) = left.find_proof(target) {
114 path.push(right.merkle_root());
115 return Some(path);
116 }
117 if let Some(mut path) = right.find_proof(target) {
119 path.push(left.merkle_root());
120 return Some(path);
121 }
122 None
123 }
124 }
125 }
126
127 pub fn leaf_count(&self) -> usize {
129 match self {
130 TapTree::Leaf(_) => 1,
131 TapTree::Branch(left, right) => left.leaf_count() + right.leaf_count(),
132 }
133 }
134
135 pub fn depth(&self) -> usize {
137 match self {
138 TapTree::Leaf(_) => 0,
139 TapTree::Branch(left, right) => 1 + left.depth().max(right.depth()),
140 }
141 }
142}
143
144pub fn tap_branch_hash(a: &[u8; 32], b: &[u8; 32]) -> [u8; 32] {
150 let mut data = Vec::with_capacity(64);
151 if a <= b {
153 data.extend_from_slice(a);
154 data.extend_from_slice(b);
155 } else {
156 data.extend_from_slice(b);
157 data.extend_from_slice(a);
158 }
159 tagged_hash(b"TapBranch", &data)
160}
161
162pub fn taproot_tweak(
176 internal_key: &[u8; 32],
177 merkle_root: Option<&[u8; 32]>,
178) -> Result<([u8; 32], bool), SignerError> {
179 let mut tweak_data = Vec::with_capacity(64);
181 tweak_data.extend_from_slice(internal_key);
182 if let Some(root) = merkle_root {
183 tweak_data.extend_from_slice(root);
184 }
185 let tweak = tagged_hash(b"TapTweak", &tweak_data);
186
187 use k256::elliptic_curve::ops::Reduce;
189 use k256::{ProjectivePoint, Scalar};
190
191 let mut pk_sec1 = [0u8; 33];
192 pk_sec1[0] = 0x02; pk_sec1[1..].copy_from_slice(internal_key);
194
195 use k256::elliptic_curve::group::GroupEncoding;
198 use k256::AffinePoint;
199
200 let pk_ct = AffinePoint::from_bytes((&pk_sec1).into());
201 let pk_point: ProjectivePoint =
202 Option::from(pk_ct.map(ProjectivePoint::from)).ok_or_else(|| {
203 SignerError::InvalidPublicKey("taproot internal key is not a valid curve point".into())
204 })?;
205
206 let t_wide = k256::U256::from_be_slice(&tweak);
208 let t_scalar = <Scalar as Reduce<k256::U256>>::reduce(t_wide);
209 let tweaked = pk_point + ProjectivePoint::GENERATOR * t_scalar;
210
211 use k256::elliptic_curve::sec1::ToEncodedPoint;
213 let tweaked_affine = tweaked.to_affine();
214 let encoded = tweaked_affine.to_encoded_point(true);
215 let bytes = encoded.as_bytes();
216
217 let mut x_only = [0u8; 32];
218 x_only.copy_from_slice(&bytes[1..33]);
219
220 let parity = bytes[0] == 0x03;
221
222 Ok((x_only, parity))
223}
224
225pub fn taproot_output_key(
229 internal_key: &[u8; 32],
230 tree: Option<&TapTree>,
231) -> Result<([u8; 32], bool), SignerError> {
232 let merkle_root = tree.map(|t| t.merkle_root());
233 taproot_tweak(internal_key, merkle_root.as_ref())
234}
235
236#[derive(Clone, Debug)]
240pub struct ControlBlock {
241 pub leaf_version_and_parity: u8,
243 pub internal_key: [u8; 32],
245 pub merkle_path: Vec<[u8; 32]>,
247}
248
249const MAX_CONTROL_BLOCK_DEPTH: usize = 128;
251
252impl ControlBlock {
253 pub fn new(
261 internal_key: [u8; 32],
262 tree: &TapTree,
263 leaf: &TapLeaf,
264 output_key_parity: bool,
265 ) -> Option<Self> {
266 let merkle_path = tree.merkle_proof(leaf)?;
267 let parity_bit = if output_key_parity { 1u8 } else { 0u8 };
268 Some(ControlBlock {
269 leaf_version_and_parity: (leaf.version & 0xFE) | parity_bit,
270 internal_key,
271 merkle_path,
272 })
273 }
274
275 pub fn to_bytes(&self) -> Vec<u8> {
279 let mut bytes = Vec::with_capacity(33 + self.merkle_path.len() * 32);
280 bytes.push(self.leaf_version_and_parity);
281 bytes.extend_from_slice(&self.internal_key);
282 for hash in &self.merkle_path {
283 bytes.extend_from_slice(hash);
284 }
285 bytes
286 }
287
288 pub fn from_bytes(data: &[u8]) -> Option<Self> {
290 if data.len() < 33 || (data.len() - 33) % 32 != 0 {
291 return None;
292 }
293 let control_byte = data[0];
294 let mut internal_key = [0u8; 32];
295 internal_key.copy_from_slice(&data[1..33]);
296 let path_count = (data.len() - 33) / 32;
297 if path_count > MAX_CONTROL_BLOCK_DEPTH {
298 return None;
299 }
300 let mut merkle_path = Vec::with_capacity(path_count);
301 for i in 0..path_count {
302 let mut hash = [0u8; 32];
303 hash.copy_from_slice(&data[33 + i * 32..33 + (i + 1) * 32]);
304 merkle_path.push(hash);
305 }
306 Some(ControlBlock {
307 leaf_version_and_parity: control_byte,
308 internal_key,
309 merkle_path,
310 })
311 }
312
313 pub fn verify(&self, output_key: &[u8; 32], leaf: &TapLeaf) -> bool {
318 let control_leaf_version = self.leaf_version_and_parity & 0xFE;
319 if control_leaf_version != (leaf.version & 0xFE) {
320 return false;
321 }
322
323 let mut current = leaf.leaf_hash();
325
326 for sibling in &self.merkle_path {
328 current = tap_branch_hash(¤t, sibling);
329 }
330
331 let Ok((tweaked, parity)) = taproot_tweak(&self.internal_key, Some(¤t)) else {
333 return false;
334 };
335 let expected_parity = (self.leaf_version_and_parity & 1) == 1;
336
337 tweaked == *output_key && parity == expected_parity
338 }
339}
340
341pub fn taproot_address(
350 internal_key: &[u8; 32],
351 tree: Option<&TapTree>,
352 hrp: &str,
353) -> Result<String, SignerError> {
354 let (output_key, _parity) = taproot_output_key(internal_key, tree)?;
355 encoding::bech32_encode(hrp, 1, &output_key)
356}
357
358#[cfg(test)]
361#[allow(clippy::unwrap_used, clippy::expect_used)]
362mod tests {
363 use super::*;
364
365 #[test]
366 fn test_tap_leaf_hash_deterministic() {
367 let leaf = TapLeaf::tapscript(vec![0x51]); let h1 = leaf.leaf_hash();
369 let h2 = leaf.leaf_hash();
370 assert_eq!(h1, h2);
371 }
372
373 #[test]
374 fn test_tap_leaf_hash_different_scripts() {
375 let l1 = TapLeaf::tapscript(vec![0x51]); let l2 = TapLeaf::tapscript(vec![0x00]); assert_ne!(l1.leaf_hash(), l2.leaf_hash());
378 }
379
380 #[test]
381 fn test_tap_leaf_hash_different_versions() {
382 let l1 = TapLeaf::new(0xC0, vec![0x51]);
383 let l2 = TapLeaf::new(0xC2, vec![0x51]);
384 assert_ne!(l1.leaf_hash(), l2.leaf_hash());
385 }
386
387 #[test]
388 fn test_tap_branch_hash_commutative() {
389 let a = [0xAA; 32];
390 let b = [0xBB; 32];
391 assert_eq!(tap_branch_hash(&a, &b), tap_branch_hash(&b, &a));
393 }
394
395 #[test]
396 fn test_tap_tree_single_leaf() {
397 let leaf = TapLeaf::tapscript(vec![0x51]);
398 let tree = TapTree::leaf(leaf.clone());
399 assert_eq!(tree.leaf_count(), 1);
400 assert_eq!(tree.depth(), 0);
401 assert_eq!(tree.merkle_root(), leaf.leaf_hash());
402 }
403
404 #[test]
405 fn test_tap_tree_two_leaves() {
406 let l1 = TapLeaf::tapscript(vec![0x51]);
407 let l2 = TapLeaf::tapscript(vec![0x00]);
408 let tree = TapTree::branch(TapTree::leaf(l1.clone()), TapTree::leaf(l2.clone()));
409 assert_eq!(tree.leaf_count(), 2);
410 assert_eq!(tree.depth(), 1);
411 let expected = tap_branch_hash(&l1.leaf_hash(), &l2.leaf_hash());
412 assert_eq!(tree.merkle_root(), expected);
413 }
414
415 #[test]
416 fn test_tap_tree_three_leaves() {
417 let l1 = TapLeaf::tapscript(vec![0x51]);
418 let l2 = TapLeaf::tapscript(vec![0x00]);
419 let l3 = TapLeaf::tapscript(vec![0x52]); let tree = TapTree::branch(
421 TapTree::leaf(l1),
422 TapTree::branch(TapTree::leaf(l2), TapTree::leaf(l3)),
423 );
424 assert_eq!(tree.leaf_count(), 3);
425 assert_eq!(tree.depth(), 2);
426 }
427
428 #[test]
429 fn test_tap_tree_merkle_proof() {
430 let l1 = TapLeaf::tapscript(vec![0x51]);
431 let l2 = TapLeaf::tapscript(vec![0x00]);
432 let tree = TapTree::branch(TapTree::leaf(l1.clone()), TapTree::leaf(l2.clone()));
433
434 let proof1 = tree.merkle_proof(&l1).expect("leaf found");
436 assert_eq!(proof1.len(), 1);
437 assert_eq!(proof1[0], l2.leaf_hash());
438
439 let proof2 = tree.merkle_proof(&l2).expect("leaf found");
441 assert_eq!(proof2.len(), 1);
442 assert_eq!(proof2[0], l1.leaf_hash());
443 }
444
445 #[test]
446 fn test_tap_tree_merkle_proof_not_found() {
447 let l1 = TapLeaf::tapscript(vec![0x51]);
448 let l2 = TapLeaf::tapscript(vec![0x00]);
449 let unknown = TapLeaf::tapscript(vec![0xFF]);
450 let tree = TapTree::branch(TapTree::leaf(l1), TapTree::leaf(l2));
451 assert!(tree.merkle_proof(&unknown).is_none());
452 }
453
454 #[test]
455 fn test_taproot_tweak_key_path_only() {
456 let internal_key = [0x01; 32];
458 let result = taproot_tweak(&internal_key, None);
459 match result {
462 Ok((tweaked, _parity)) => {
463 assert_ne!(tweaked, internal_key); assert_ne!(tweaked, [0u8; 32]); let (tweaked2, _) = taproot_tweak(&internal_key, None).unwrap();
468 assert_eq!(tweaked, tweaked2);
469 }
470 Err(_) => {
471 }
473 }
474 }
475
476 #[test]
477 fn test_taproot_tweak_with_merkle_root() {
478 let internal_key_hex = "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798";
480 let internal_key_bytes = hex::decode(internal_key_hex).unwrap();
481 let mut internal_key = [0u8; 32];
482 internal_key.copy_from_slice(&internal_key_bytes);
483
484 let merkle_root = [0xAA; 32];
485 let (tweaked1, _) = taproot_tweak(&internal_key, Some(&merkle_root)).unwrap();
486 let (tweaked2, _) = taproot_tweak(&internal_key, None).unwrap();
487 assert_ne!(tweaked1, tweaked2);
489 }
490
491 #[test]
492 fn test_taproot_output_key_with_tree() {
493 let internal_key_hex = "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798";
494 let internal_key_bytes = hex::decode(internal_key_hex).unwrap();
495 let mut internal_key = [0u8; 32];
496 internal_key.copy_from_slice(&internal_key_bytes);
497 let l1 = TapLeaf::tapscript(vec![0x51]);
498 let tree = TapTree::leaf(l1);
499 let (output_key, _parity) = taproot_output_key(&internal_key, Some(&tree)).unwrap();
500 assert_ne!(output_key, [0u8; 32]);
501 }
502
503 #[test]
504 fn test_control_block_serialization() {
505 let l1 = TapLeaf::tapscript(vec![0x51]);
506 let l2 = TapLeaf::tapscript(vec![0x00]);
507 let tree = TapTree::branch(TapTree::leaf(l1.clone()), TapTree::leaf(l2.clone()));
508 let internal_key = [0x01; 32];
509 let (_, parity) = taproot_output_key(&internal_key, Some(&tree)).unwrap();
510
511 let cb = ControlBlock::new(internal_key, &tree, &l1, parity).expect("ok");
512 let bytes = cb.to_bytes();
513
514 assert_eq!(bytes.len(), 65);
516
517 let parsed = ControlBlock::from_bytes(&bytes).expect("valid");
519 assert_eq!(parsed.internal_key, internal_key);
520 assert_eq!(parsed.merkle_path.len(), 1);
521 }
522
523 #[test]
524 fn test_control_block_verify() {
525 let l1 = TapLeaf::tapscript(vec![0x51]);
526 let l2 = TapLeaf::tapscript(vec![0x00]);
527 let tree = TapTree::branch(TapTree::leaf(l1.clone()), TapTree::leaf(l2.clone()));
528
529 let internal_key_hex = "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798";
531 let internal_key_bytes = hex::decode(internal_key_hex).unwrap();
532 let mut internal_key = [0u8; 32];
533 internal_key.copy_from_slice(&internal_key_bytes);
534
535 let (output_key, parity) = taproot_output_key(&internal_key, Some(&tree)).unwrap();
536 let cb = ControlBlock::new(internal_key, &tree, &l1, parity).expect("ok");
537
538 assert!(cb.verify(&output_key, &l1));
539 assert!(!cb.verify(&output_key, &l2));
541
542 let mut bad_cb = cb.clone();
544 bad_cb.leaf_version_and_parity ^= 0x02; assert!(!bad_cb.verify(&output_key, &l1));
546 }
547
548 #[test]
549 fn test_control_block_from_bytes_invalid() {
550 assert!(ControlBlock::from_bytes(&[0x00; 10]).is_none());
552 assert!(ControlBlock::from_bytes(&[0x00; 34]).is_none());
554 assert!(ControlBlock::from_bytes(&vec![0x00; 33 + 32 * 129]).is_none());
556 assert!(ControlBlock::from_bytes(&[0x00; 33]).is_some());
558 assert!(ControlBlock::from_bytes(&[0x00; 65]).is_some());
560 }
561
562 #[test]
563 fn test_taproot_address_key_path_only() {
564 let internal_key_hex = "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798";
565 let internal_key_bytes = hex::decode(internal_key_hex).unwrap();
566 let mut internal_key = [0u8; 32];
567 internal_key.copy_from_slice(&internal_key_bytes);
568
569 let addr = taproot_address(&internal_key, None, "bc").expect("ok");
570 assert!(addr.starts_with("bc1p"));
571 }
572
573 #[test]
574 fn test_taproot_tweak_invalid_key() {
575 let invalid_key = [0u8; 32];
577 let result = taproot_tweak(&invalid_key, None);
578 assert!(result.is_err(), "zeroed key should not be valid");
579 }
580
581 #[test]
582 fn test_taproot_address_with_tree() {
583 let internal_key_hex = "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798";
584 let internal_key_bytes = hex::decode(internal_key_hex).unwrap();
585 let mut internal_key = [0u8; 32];
586 internal_key.copy_from_slice(&internal_key_bytes);
587
588 let leaf = TapLeaf::tapscript(vec![0x51]);
589 let tree = TapTree::leaf(leaf);
590
591 let addr = taproot_address(&internal_key, Some(&tree), "bc").expect("ok");
592 assert!(addr.starts_with("bc1p"));
593
594 let addr_no_tree = taproot_address(&internal_key, None, "bc").expect("ok");
596 assert_ne!(addr, addr_no_tree);
597 }
598
599 #[test]
600 fn test_taproot_address_testnet() {
601 let internal_key_hex = "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798";
602 let internal_key_bytes = hex::decode(internal_key_hex).unwrap();
603 let mut internal_key = [0u8; 32];
604 internal_key.copy_from_slice(&internal_key_bytes);
605 let addr = taproot_address(&internal_key, None, "tb").expect("ok");
606 assert!(addr.starts_with("tb1p"));
607 }
608}