Introduce taproot hash type extension traits
Introduce three extension traits for the taproot hash types. All logic for the hash types is now within the extension traits.
This commit is contained in:
parent
c30ef617fb
commit
24e944ed82
|
@ -14,7 +14,7 @@ use crate::opcodes::all::*;
|
||||||
use crate::opcodes::{self, Opcode};
|
use crate::opcodes::{self, Opcode};
|
||||||
use crate::policy::DUST_RELAY_TX_FEE;
|
use crate::policy::DUST_RELAY_TX_FEE;
|
||||||
use crate::prelude::{sink, DisplayHex, String, ToString};
|
use crate::prelude::{sink, DisplayHex, String, ToString};
|
||||||
use crate::taproot::{LeafVersion, TapLeafHash};
|
use crate::taproot::{LeafVersion, TapLeafHash, TapLeafHashExt as _};
|
||||||
use crate::FeeRate;
|
use crate::FeeRate;
|
||||||
|
|
||||||
#[rustfmt::skip] // Keep public re-exports separate.
|
#[rustfmt::skip] // Keep public re-exports separate.
|
||||||
|
|
|
@ -20,7 +20,7 @@ use crate::internal_macros::impl_asref_push_bytes;
|
||||||
use crate::network::NetworkKind;
|
use crate::network::NetworkKind;
|
||||||
use crate::prelude::{DisplayHex, String, Vec};
|
use crate::prelude::{DisplayHex, String, Vec};
|
||||||
use crate::script::{self, ScriptBuf};
|
use crate::script::{self, ScriptBuf};
|
||||||
use crate::taproot::{TapNodeHash, TapTweakHash};
|
use crate::taproot::{TapNodeHash, TapTweakHash, TapTweakHashExt as _};
|
||||||
|
|
||||||
#[rustfmt::skip] // Keep public re-exports separate.
|
#[rustfmt::skip] // Keep public re-exports separate.
|
||||||
pub use secp256k1::{constants, Keypair, Parity, Secp256k1, Verification, XOnlyPublicKey};
|
pub use secp256k1::{constants, Keypair, Parity, Secp256k1, Verification, XOnlyPublicKey};
|
||||||
|
|
|
@ -1509,6 +1509,7 @@ mod tests {
|
||||||
use crate::consensus::deserialize;
|
use crate::consensus::deserialize;
|
||||||
use crate::locktime::absolute;
|
use crate::locktime::absolute;
|
||||||
use crate::script::ScriptBufExt as _;
|
use crate::script::ScriptBufExt as _;
|
||||||
|
use crate::taproot::TapTweakHashExt as _;
|
||||||
|
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
|
|
||||||
|
|
|
@ -62,10 +62,12 @@ hash_newtype! {
|
||||||
pub struct TapTweakHash(sha256t::Hash<TapTweakTag>);
|
pub struct TapTweakHash(sha256t::Hash<TapTweakTag>);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TapTweakHash {
|
crate::internal_macros::define_extension_trait! {
|
||||||
|
/// Extension functionality for the [`TapTweakHash`] type.
|
||||||
|
pub trait TapTweakHashExt impl for TapTweakHash {
|
||||||
/// Creates a new BIP341 [`TapTweakHash`] from key and tweak. Produces `H_taptweak(P||R)` where
|
/// Creates a new BIP341 [`TapTweakHash`] from key and tweak. Produces `H_taptweak(P||R)` where
|
||||||
/// `P` is the internal key and `R` is the Merkle root.
|
/// `P` is the internal key and `R` is the Merkle root.
|
||||||
pub fn from_key_and_tweak(
|
fn from_key_and_tweak(
|
||||||
internal_key: UntweakedPublicKey,
|
internal_key: UntweakedPublicKey,
|
||||||
merkle_root: Option<TapNodeHash>,
|
merkle_root: Option<TapNodeHash>,
|
||||||
) -> TapTweakHash {
|
) -> TapTweakHash {
|
||||||
|
@ -82,15 +84,18 @@ impl TapTweakHash {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a `TapTweakHash` into a `Scalar` ready for use with key tweaking API.
|
/// Converts a `TapTweakHash` into a `Scalar` ready for use with key tweaking API.
|
||||||
pub fn to_scalar(self) -> Scalar {
|
fn to_scalar(self) -> Scalar {
|
||||||
// This is statistically extremely unlikely to panic.
|
// This is statistically extremely unlikely to panic.
|
||||||
Scalar::from_be_bytes(self.to_byte_array()).expect("hash value greater than curve order")
|
Scalar::from_be_bytes(self.to_byte_array()).expect("hash value greater than curve order")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl TapLeafHash {
|
crate::internal_macros::define_extension_trait! {
|
||||||
|
/// Extension functionality for the [`TapLeafHash`] type.
|
||||||
|
pub trait TapLeafHashExt impl for TapLeafHash {
|
||||||
/// Computes the leaf hash from components.
|
/// Computes the leaf hash from components.
|
||||||
pub fn from_script(script: &Script, ver: LeafVersion) -> TapLeafHash {
|
fn from_script(script: &Script, ver: LeafVersion) -> TapLeafHash {
|
||||||
let mut eng = sha256t::Hash::<TapLeafTag>::engine();
|
let mut eng = sha256t::Hash::<TapLeafTag>::engine();
|
||||||
ver.to_consensus().consensus_encode(&mut eng).expect("engines don't error");
|
ver.to_consensus().consensus_encode(&mut eng).expect("engines don't error");
|
||||||
script.consensus_encode(&mut eng).expect("engines don't error");
|
script.consensus_encode(&mut eng).expect("engines don't error");
|
||||||
|
@ -98,6 +103,7 @@ impl TapLeafHash {
|
||||||
TapLeafHash::from_byte_array(inner.to_byte_array())
|
TapLeafHash::from_byte_array(inner.to_byte_array())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<LeafNode> for TapNodeHash {
|
impl From<LeafNode> for TapNodeHash {
|
||||||
fn from(leaf: LeafNode) -> TapNodeHash { leaf.node_hash() }
|
fn from(leaf: LeafNode) -> TapNodeHash { leaf.node_hash() }
|
||||||
|
@ -107,9 +113,11 @@ impl From<&LeafNode> for TapNodeHash {
|
||||||
fn from(leaf: &LeafNode) -> TapNodeHash { leaf.node_hash() }
|
fn from(leaf: &LeafNode) -> TapNodeHash { leaf.node_hash() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TapNodeHash {
|
crate::internal_macros::define_extension_trait! {
|
||||||
|
/// Extension functionality for the [`TapNodeHash`] type.
|
||||||
|
pub trait TapNodeHashExt impl for TapNodeHash {
|
||||||
/// Computes branch hash given two hashes of the nodes underneath it.
|
/// Computes branch hash given two hashes of the nodes underneath it.
|
||||||
pub fn from_node_hashes(a: TapNodeHash, b: TapNodeHash) -> TapNodeHash {
|
fn from_node_hashes(a: TapNodeHash, b: TapNodeHash) -> TapNodeHash {
|
||||||
combine_node_hashes(a, b).0
|
combine_node_hashes(a, b).0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,13 +126,14 @@ impl TapNodeHash {
|
||||||
/// Similar to [`TapLeafHash::from_byte_array`], but explicitly conveys that the
|
/// Similar to [`TapLeafHash::from_byte_array`], but explicitly conveys that the
|
||||||
/// hash is constructed from a hidden node. This also has better ergonomics
|
/// hash is constructed from a hidden node. This also has better ergonomics
|
||||||
/// because it does not require the caller to import the Hash trait.
|
/// because it does not require the caller to import the Hash trait.
|
||||||
pub fn assume_hidden(hash: [u8; 32]) -> TapNodeHash { TapNodeHash::from_byte_array(hash) }
|
fn assume_hidden(hash: [u8; 32]) -> TapNodeHash { TapNodeHash::from_byte_array(hash) }
|
||||||
|
|
||||||
/// Computes the [`TapNodeHash`] from a script and a leaf version.
|
/// Computes the [`TapNodeHash`] from a script and a leaf version.
|
||||||
pub fn from_script(script: &Script, ver: LeafVersion) -> TapNodeHash {
|
fn from_script(script: &Script, ver: LeafVersion) -> TapNodeHash {
|
||||||
TapNodeHash::from(TapLeafHash::from_script(script, ver))
|
TapNodeHash::from(TapLeafHash::from_script(script, ver))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<TapLeafHash> for TapNodeHash {
|
impl From<TapLeafHash> for TapNodeHash {
|
||||||
fn from(leaf: TapLeafHash) -> TapNodeHash { TapNodeHash::from_byte_array(leaf.to_byte_array()) }
|
fn from(leaf: TapLeafHash) -> TapNodeHash { TapNodeHash::from_byte_array(leaf.to_byte_array()) }
|
||||||
|
|
Loading…
Reference in New Issue