Move taproot hash types to primitives

Move the three `taproot` hash types and their associated tags over to
the `primitives` crate.
This commit is contained in:
Tobin C. Harding 2024-10-22 13:44:02 +11:00
parent 24e944ed82
commit 1b521dce99
No known key found for this signature in database
GPG Key ID: 40BF9E4C269D6607
3 changed files with 61 additions and 43 deletions

View File

@ -11,7 +11,7 @@ use core::cmp::Reverse;
use core::fmt; use core::fmt;
use core::iter::FusedIterator; use core::iter::FusedIterator;
use hashes::{hash_newtype, sha256t, sha256t_tag, HashEngine}; use hashes::{sha256t, HashEngine};
use internals::{impl_to_hex_from_lower_hex, write_err}; use internals::{impl_to_hex_from_lower_hex, write_err};
use io::Write; use io::Write;
use secp256k1::{Scalar, Secp256k1}; use secp256k1::{Scalar, Secp256k1};
@ -27,40 +27,7 @@ use crate::{Script, ScriptBuf};
pub use crate::crypto::taproot::{SigFromSliceError, Signature}; pub use crate::crypto::taproot::{SigFromSliceError, Signature};
#[doc(inline)] #[doc(inline)]
pub use merkle_branch::TaprootMerkleBranch; pub use merkle_branch::TaprootMerkleBranch;
pub use primitives::taproot::{TapLeafTag, TapLeafHash, TapBranchTag, TapNodeHash, TapTweakTag, TapTweakHash};
// Taproot test vectors from BIP-341 state the hashes without any reversing
sha256t_tag! {
pub struct TapLeafTag = hash_str("TapLeaf");
}
hash_newtype! {
/// Taproot-tagged hash with tag \"TapLeaf\".
///
/// This is used for computing tapscript script spend hash.
pub struct TapLeafHash(sha256t::Hash<TapLeafTag>);
}
sha256t_tag! {
pub struct TapBranchTag = hash_str("TapBranch");
}
hash_newtype! {
/// Tagged hash used in Taproot trees.
///
/// See BIP-340 for tagging rules.
pub struct TapNodeHash(sha256t::Hash<TapBranchTag>);
}
sha256t_tag! {
pub struct TapTweakTag = hash_str("TapTweak");
}
hash_newtype! {
/// Taproot-tagged hash with tag \"TapTweak\".
///
/// This hash type is used while computing the tweaked public key.
pub struct TapTweakHash(sha256t::Hash<TapTweakTag>);
}
crate::internal_macros::define_extension_trait! { crate::internal_macros::define_extension_trait! {
/// Extension functionality for the [`TapTweakHash`] type. /// Extension functionality for the [`TapTweakHash`] type.
@ -135,10 +102,6 @@ crate::internal_macros::define_extension_trait! {
} }
} }
impl From<TapLeafHash> for TapNodeHash {
fn from(leaf: TapLeafHash) -> TapNodeHash { TapNodeHash::from_byte_array(leaf.to_byte_array()) }
}
/// Computes branch hash given two hashes of the nodes underneath it and returns /// Computes branch hash given two hashes of the nodes underneath it and returns
/// whether the left node was the one hashed first. /// whether the left node was the one hashed first.
fn combine_node_hashes(a: TapNodeHash, b: TapNodeHash) -> (TapNodeHash, bool) { fn combine_node_hashes(a: TapNodeHash, b: TapNodeHash) -> (TapNodeHash, bool) {
@ -1554,6 +1517,13 @@ impl fmt::Display for InvalidControlBlockSizeError {
#[cfg(feature = "std")] #[cfg(feature = "std")]
impl std::error::Error for InvalidControlBlockSizeError {} impl std::error::Error for InvalidControlBlockSizeError {}
mod sealed {
pub trait Sealed {}
impl Sealed for super::TapTweakHash {}
impl Sealed for super::TapLeafHash {}
impl Sealed for super::TapNodeHash {}
}
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use hashes::sha256; use hashes::sha256;
@ -1863,15 +1833,17 @@ mod test {
#[test] #[test]
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
fn test_merkle_branch_serde() { fn test_merkle_branch_serde() {
let hash1 = TapNodeHash( let hash1 = TapNodeHash::from_byte_array(
"03ba2a4dcd914fed29a1c630c7e811271b081a0e2f2f52cf1c197583dfd46c1b" "03ba2a4dcd914fed29a1c630c7e811271b081a0e2f2f52cf1c197583dfd46c1b"
.parse::<sha256t::Hash<TapBranchTag>>() .parse::<sha256t::Hash<TapBranchTag>>()
.unwrap(), .unwrap()
.to_byte_array(),
); );
let hash2 = TapNodeHash( let hash2 = TapNodeHash::from_byte_array(
"8d79dedc2fa0b55167b5d28c61dbad9ce1191a433f3a1a6c8ee291631b2c94c9" "8d79dedc2fa0b55167b5d28c61dbad9ce1191a433f3a1a6c8ee291631b2c94c9"
.parse::<sha256t::Hash<TapBranchTag>>() .parse::<sha256t::Hash<TapBranchTag>>()
.unwrap(), .unwrap()
.to_byte_array(),
); );
let merkle_branch = TaprootMerkleBranch::from([hash1, hash2]); let merkle_branch = TaprootMerkleBranch::from([hash1, hash2]);
// use serde_test to test serialization and deserialization // use serde_test to test serialization and deserialization

View File

@ -39,6 +39,7 @@ pub mod pow;
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
pub mod script; pub mod script;
pub mod sequence; pub mod sequence;
pub mod taproot;
pub mod transaction; pub mod transaction;
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
pub mod witness; pub mod witness;

45
primitives/src/taproot.rs Normal file
View File

@ -0,0 +1,45 @@
// SPDX-License-Identifier: CC0-1.0
//! Bitcoin Taproot.
//!
//! This module provides support for Taproot tagged hashes.
use hashes::{hash_newtype, sha256t, sha256t_tag};
// Taproot test vectors from BIP-341 state the hashes without any reversing
sha256t_tag! {
pub struct TapLeafTag = hash_str("TapLeaf");
}
hash_newtype! {
/// Taproot-tagged hash with tag \"TapLeaf\".
///
/// This is used for computing tapscript script spend hash.
pub struct TapLeafHash(sha256t::Hash<TapLeafTag>);
}
sha256t_tag! {
pub struct TapBranchTag = hash_str("TapBranch");
}
hash_newtype! {
/// Tagged hash used in Taproot trees.
///
/// See BIP-340 for tagging rules.
pub struct TapNodeHash(sha256t::Hash<TapBranchTag>);
}
sha256t_tag! {
pub struct TapTweakTag = hash_str("TapTweak");
}
hash_newtype! {
/// Taproot-tagged hash with tag \"TapTweak\".
///
/// This hash type is used while computing the tweaked public key.
pub struct TapTweakHash(sha256t::Hash<TapTweakTag>);
}
impl From<TapLeafHash> for TapNodeHash {
fn from(leaf: TapLeafHash) -> TapNodeHash { TapNodeHash::from_byte_array(leaf.to_byte_array()) }
}