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 #[allow(unused_imports)]
197 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
249impl ControlBlock {
250 pub fn new(
258 internal_key: [u8; 32],
259 tree: &TapTree,
260 leaf: &TapLeaf,
261 output_key_parity: bool,
262 ) -> Option<Self> {
263 let merkle_path = tree.merkle_proof(leaf)?;
264 let parity_bit = if output_key_parity { 1u8 } else { 0u8 };
265 Some(ControlBlock {
266 leaf_version_and_parity: (leaf.version & 0xFE) | parity_bit,
267 internal_key,
268 merkle_path,
269 })
270 }
271
272 pub fn to_bytes(&self) -> Vec<u8> {
276 let mut bytes = Vec::with_capacity(33 + self.merkle_path.len() * 32);
277 bytes.push(self.leaf_version_and_parity);
278 bytes.extend_from_slice(&self.internal_key);
279 for hash in &self.merkle_path {
280 bytes.extend_from_slice(hash);
281 }
282 bytes
283 }
284
285 pub fn from_bytes(data: &[u8]) -> Option<Self> {
287 if data.len() < 33 || (data.len() - 33) % 32 != 0 {
288 return None;
289 }
290 let control_byte = data[0];
291 let mut internal_key = [0u8; 32];
292 internal_key.copy_from_slice(&data[1..33]);
293 let path_count = (data.len() - 33) / 32;
294 let mut merkle_path = Vec::with_capacity(path_count);
295 for i in 0..path_count {
296 let mut hash = [0u8; 32];
297 hash.copy_from_slice(&data[33 + i * 32..33 + (i + 1) * 32]);
298 merkle_path.push(hash);
299 }
300 Some(ControlBlock {
301 leaf_version_and_parity: control_byte,
302 internal_key,
303 merkle_path,
304 })
305 }
306
307 pub fn verify(&self, output_key: &[u8; 32], leaf: &TapLeaf) -> bool {
312 let mut current = leaf.leaf_hash();
314
315 for sibling in &self.merkle_path {
317 current = tap_branch_hash(¤t, sibling);
318 }
319
320 let Ok((tweaked, parity)) = taproot_tweak(&self.internal_key, Some(¤t)) else {
322 return false;
323 };
324 let expected_parity = (self.leaf_version_and_parity & 1) == 1;
325
326 tweaked == *output_key && parity == expected_parity
327 }
328}
329
330pub fn taproot_address(
339 internal_key: &[u8; 32],
340 tree: Option<&TapTree>,
341 hrp: &str,
342) -> Result<String, SignerError> {
343 let (output_key, _parity) = taproot_output_key(internal_key, tree)?;
344 encoding::bech32_encode(hrp, 1, &output_key)
345}
346
347#[cfg(test)]
350#[allow(clippy::unwrap_used, clippy::expect_used)]
351mod tests {
352 use super::*;
353
354 #[test]
355 fn test_tap_leaf_hash_deterministic() {
356 let leaf = TapLeaf::tapscript(vec![0x51]); let h1 = leaf.leaf_hash();
358 let h2 = leaf.leaf_hash();
359 assert_eq!(h1, h2);
360 }
361
362 #[test]
363 fn test_tap_leaf_hash_different_scripts() {
364 let l1 = TapLeaf::tapscript(vec![0x51]); let l2 = TapLeaf::tapscript(vec![0x00]); assert_ne!(l1.leaf_hash(), l2.leaf_hash());
367 }
368
369 #[test]
370 fn test_tap_leaf_hash_different_versions() {
371 let l1 = TapLeaf::new(0xC0, vec![0x51]);
372 let l2 = TapLeaf::new(0xC2, vec![0x51]);
373 assert_ne!(l1.leaf_hash(), l2.leaf_hash());
374 }
375
376 #[test]
377 fn test_tap_branch_hash_commutative() {
378 let a = [0xAA; 32];
379 let b = [0xBB; 32];
380 assert_eq!(tap_branch_hash(&a, &b), tap_branch_hash(&b, &a));
382 }
383
384 #[test]
385 fn test_tap_tree_single_leaf() {
386 let leaf = TapLeaf::tapscript(vec![0x51]);
387 let tree = TapTree::leaf(leaf.clone());
388 assert_eq!(tree.leaf_count(), 1);
389 assert_eq!(tree.depth(), 0);
390 assert_eq!(tree.merkle_root(), leaf.leaf_hash());
391 }
392
393 #[test]
394 fn test_tap_tree_two_leaves() {
395 let l1 = TapLeaf::tapscript(vec![0x51]);
396 let l2 = TapLeaf::tapscript(vec![0x00]);
397 let tree = TapTree::branch(TapTree::leaf(l1.clone()), TapTree::leaf(l2.clone()));
398 assert_eq!(tree.leaf_count(), 2);
399 assert_eq!(tree.depth(), 1);
400 let expected = tap_branch_hash(&l1.leaf_hash(), &l2.leaf_hash());
401 assert_eq!(tree.merkle_root(), expected);
402 }
403
404 #[test]
405 fn test_tap_tree_three_leaves() {
406 let l1 = TapLeaf::tapscript(vec![0x51]);
407 let l2 = TapLeaf::tapscript(vec![0x00]);
408 let l3 = TapLeaf::tapscript(vec![0x52]); let tree = TapTree::branch(
410 TapTree::leaf(l1),
411 TapTree::branch(TapTree::leaf(l2), TapTree::leaf(l3)),
412 );
413 assert_eq!(tree.leaf_count(), 3);
414 assert_eq!(tree.depth(), 2);
415 }
416
417 #[test]
418 fn test_tap_tree_merkle_proof() {
419 let l1 = TapLeaf::tapscript(vec![0x51]);
420 let l2 = TapLeaf::tapscript(vec![0x00]);
421 let tree = TapTree::branch(TapTree::leaf(l1.clone()), TapTree::leaf(l2.clone()));
422
423 let proof1 = tree.merkle_proof(&l1).expect("leaf found");
425 assert_eq!(proof1.len(), 1);
426 assert_eq!(proof1[0], l2.leaf_hash());
427
428 let proof2 = tree.merkle_proof(&l2).expect("leaf found");
430 assert_eq!(proof2.len(), 1);
431 assert_eq!(proof2[0], l1.leaf_hash());
432 }
433
434 #[test]
435 fn test_tap_tree_merkle_proof_not_found() {
436 let l1 = TapLeaf::tapscript(vec![0x51]);
437 let l2 = TapLeaf::tapscript(vec![0x00]);
438 let unknown = TapLeaf::tapscript(vec![0xFF]);
439 let tree = TapTree::branch(TapTree::leaf(l1), TapTree::leaf(l2));
440 assert!(tree.merkle_proof(&unknown).is_none());
441 }
442
443 #[test]
444 fn test_taproot_tweak_key_path_only() {
445 let internal_key = [0x01; 32];
447 let result = taproot_tweak(&internal_key, None);
448 match result {
451 Ok((tweaked, _parity)) => {
452 assert_ne!(tweaked, internal_key); assert_ne!(tweaked, [0u8; 32]); let (tweaked2, _) = taproot_tweak(&internal_key, None).unwrap();
457 assert_eq!(tweaked, tweaked2);
458 }
459 Err(_) => {
460 }
462 }
463 }
464
465 #[test]
466 fn test_taproot_tweak_with_merkle_root() {
467 let internal_key_hex = "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798";
469 let internal_key_bytes = hex::decode(internal_key_hex).unwrap();
470 let mut internal_key = [0u8; 32];
471 internal_key.copy_from_slice(&internal_key_bytes);
472
473 let merkle_root = [0xAA; 32];
474 let (tweaked1, _) = taproot_tweak(&internal_key, Some(&merkle_root)).unwrap();
475 let (tweaked2, _) = taproot_tweak(&internal_key, None).unwrap();
476 assert_ne!(tweaked1, tweaked2);
478 }
479
480 #[test]
481 fn test_taproot_output_key_with_tree() {
482 let internal_key_hex = "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798";
483 let internal_key_bytes = hex::decode(internal_key_hex).unwrap();
484 let mut internal_key = [0u8; 32];
485 internal_key.copy_from_slice(&internal_key_bytes);
486 let l1 = TapLeaf::tapscript(vec![0x51]);
487 let tree = TapTree::leaf(l1);
488 let (output_key, _parity) = taproot_output_key(&internal_key, Some(&tree)).unwrap();
489 assert_ne!(output_key, [0u8; 32]);
490 }
491
492 #[test]
493 fn test_control_block_serialization() {
494 let l1 = TapLeaf::tapscript(vec![0x51]);
495 let l2 = TapLeaf::tapscript(vec![0x00]);
496 let tree = TapTree::branch(TapTree::leaf(l1.clone()), TapTree::leaf(l2.clone()));
497 let internal_key = [0x01; 32];
498 let (_, parity) = taproot_output_key(&internal_key, Some(&tree)).unwrap();
499
500 let cb = ControlBlock::new(internal_key, &tree, &l1, parity).expect("ok");
501 let bytes = cb.to_bytes();
502
503 assert_eq!(bytes.len(), 65);
505
506 let parsed = ControlBlock::from_bytes(&bytes).expect("valid");
508 assert_eq!(parsed.internal_key, internal_key);
509 assert_eq!(parsed.merkle_path.len(), 1);
510 }
511
512 #[test]
513 fn test_control_block_verify() {
514 let l1 = TapLeaf::tapscript(vec![0x51]);
515 let l2 = TapLeaf::tapscript(vec![0x00]);
516 let tree = TapTree::branch(TapTree::leaf(l1.clone()), TapTree::leaf(l2.clone()));
517
518 let internal_key_hex = "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798";
520 let internal_key_bytes = hex::decode(internal_key_hex).unwrap();
521 let mut internal_key = [0u8; 32];
522 internal_key.copy_from_slice(&internal_key_bytes);
523
524 let (output_key, parity) = taproot_output_key(&internal_key, Some(&tree)).unwrap();
525 let cb = ControlBlock::new(internal_key, &tree, &l1, parity).expect("ok");
526
527 assert!(cb.verify(&output_key, &l1));
528 assert!(!cb.verify(&output_key, &l2));
530 }
531
532 #[test]
533 fn test_control_block_from_bytes_invalid() {
534 assert!(ControlBlock::from_bytes(&[0x00; 10]).is_none());
536 assert!(ControlBlock::from_bytes(&[0x00; 34]).is_none());
538 assert!(ControlBlock::from_bytes(&[0x00; 33]).is_some());
540 assert!(ControlBlock::from_bytes(&[0x00; 65]).is_some());
542 }
543
544 #[test]
545 fn test_taproot_address_key_path_only() {
546 let internal_key_hex = "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798";
547 let internal_key_bytes = hex::decode(internal_key_hex).unwrap();
548 let mut internal_key = [0u8; 32];
549 internal_key.copy_from_slice(&internal_key_bytes);
550
551 let addr = taproot_address(&internal_key, None, "bc").expect("ok");
552 assert!(addr.starts_with("bc1p"));
553 }
554
555 #[test]
556 fn test_taproot_tweak_invalid_key() {
557 let invalid_key = [0u8; 32];
559 let result = taproot_tweak(&invalid_key, None);
560 assert!(result.is_err(), "zeroed key should not be valid");
561 }
562
563 #[test]
564 fn test_taproot_address_with_tree() {
565 let internal_key_hex = "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798";
566 let internal_key_bytes = hex::decode(internal_key_hex).unwrap();
567 let mut internal_key = [0u8; 32];
568 internal_key.copy_from_slice(&internal_key_bytes);
569
570 let leaf = TapLeaf::tapscript(vec![0x51]);
571 let tree = TapTree::leaf(leaf);
572
573 let addr = taproot_address(&internal_key, Some(&tree), "bc").expect("ok");
574 assert!(addr.starts_with("bc1p"));
575
576 let addr_no_tree = taproot_address(&internal_key, None, "bc").expect("ok");
578 assert_ne!(addr, addr_no_tree);
579 }
580
581 #[test]
582 fn test_taproot_address_testnet() {
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 let addr = taproot_address(&internal_key, None, "tb").expect("ok");
588 assert!(addr.starts_with("tb1p"));
589 }
590}