From 5ff2635585fdd8211ebb698e3f58be8c6fc2bc05 Mon Sep 17 00:00:00 2001 From: sanket1729 Date: Thu, 15 Dec 2022 07:54:32 -0800 Subject: [PATCH 1/2] Rename TapBranchHash -> TapNodeHash --- bitcoin/src/address.rs | 6 ++-- bitcoin/src/blockdata/script.rs | 6 ++-- bitcoin/src/crypto/schnorr.rs | 8 +++--- bitcoin/src/psbt/map/input.rs | 6 ++-- bitcoin/src/psbt/serialize.rs | 4 +-- bitcoin/src/sighash.rs | 4 +-- bitcoin/src/taproot.rs | 51 +++++++++++++++++++-------------- 7 files changed, 46 insertions(+), 39 deletions(-) diff --git a/bitcoin/src/address.rs b/bitcoin/src/address.rs index b1d1460d..507edc1a 100644 --- a/bitcoin/src/address.rs +++ b/bitcoin/src/address.rs @@ -50,7 +50,7 @@ use crate::hash_types::{PubkeyHash, ScriptHash}; use crate::hashes::{sha256, Hash, HashEngine}; use crate::network::constants::Network; use crate::prelude::*; -use crate::taproot::TapBranchHash; +use crate::taproot::TapNodeHash; /// Address error. #[derive(Debug, PartialEq, Eq, Clone)] @@ -479,7 +479,7 @@ impl Payload { pub fn p2tr( secp: &Secp256k1, internal_key: UntweakedPublicKey, - merkle_root: Option, + merkle_root: Option, ) -> Payload { let (output_key, _parity) = internal_key.tap_tweak(secp, merkle_root); Payload::WitnessProgram { @@ -627,7 +627,7 @@ impl Address { pub fn p2tr( secp: &Secp256k1, internal_key: UntweakedPublicKey, - merkle_root: Option, + merkle_root: Option, network: Network, ) -> Address { Address { network, payload: Payload::p2tr(secp, internal_key, merkle_root) } diff --git a/bitcoin/src/blockdata/script.rs b/bitcoin/src/blockdata/script.rs index 360ed744..d056d84b 100644 --- a/bitcoin/src/blockdata/script.rs +++ b/bitcoin/src/blockdata/script.rs @@ -76,7 +76,7 @@ use crate::OutPoint; use crate::key::PublicKey; use crate::address::WitnessVersion; -use crate::taproot::{LeafVersion, TapBranchHash, TapLeafHash}; +use crate::taproot::{LeafVersion, TapNodeHash, TapLeafHash}; use secp256k1::{Secp256k1, Verification, XOnlyPublicKey}; use crate::schnorr::{TapTweak, TweakedPublicKey, UntweakedPublicKey}; @@ -245,7 +245,7 @@ impl Script { #[inline] pub fn to_v1_p2tr(&self, secp: &Secp256k1, internal_key: UntweakedPublicKey) -> ScriptBuf { let leaf_hash = self.tapscript_leaf_hash(); - let merkle_root = TapBranchHash::from_inner(leaf_hash.into_inner()); + let merkle_root = TapNodeHash::from(leaf_hash); ScriptBuf::new_v1_p2tr(secp, internal_key, Some(merkle_root)) } @@ -1133,7 +1133,7 @@ impl ScriptBuf { /// Generates P2TR for script spending path using an internal public key and some optional /// script tree merkle root. - pub fn new_v1_p2tr(secp: &Secp256k1, internal_key: UntweakedPublicKey, merkle_root: Option) -> Self { + pub fn new_v1_p2tr(secp: &Secp256k1, internal_key: UntweakedPublicKey, merkle_root: Option) -> Self { let (output_key, _) = internal_key.tap_tweak(secp, merkle_root); ScriptBuf::new_witness_program(WitnessVersion::V1, &output_key.serialize()) } diff --git a/bitcoin/src/crypto/schnorr.rs b/bitcoin/src/crypto/schnorr.rs index d17a56a0..8e0addc2 100644 --- a/bitcoin/src/crypto/schnorr.rs +++ b/bitcoin/src/crypto/schnorr.rs @@ -15,7 +15,7 @@ pub use secp256k1::{self, constants, Secp256k1, KeyPair, XOnlyPublicKey, Verific use crate::prelude::*; -use crate::taproot::{TapBranchHash, TapTweakHash}; +use crate::taproot::{TapNodeHash, TapTweakHash}; use crate::sighash::SchnorrSighashType; /// Untweaked BIP-340 X-coord-only public key @@ -69,7 +69,7 @@ pub trait TapTweak { /// /// # Returns /// The tweaked key and its parity. - fn tap_tweak(self, secp: &Secp256k1, merkle_root: Option) -> Self::TweakedAux; + fn tap_tweak(self, secp: &Secp256k1, merkle_root: Option) -> Self::TweakedAux; /// Directly converts an [`UntweakedPublicKey`] to a [`TweakedPublicKey`] /// @@ -94,7 +94,7 @@ impl TapTweak for UntweakedPublicKey { /// /// # Returns /// The tweaked key and its parity. - fn tap_tweak(self, secp: &Secp256k1, merkle_root: Option) -> (TweakedPublicKey, secp256k1::Parity) { + fn tap_tweak(self, secp: &Secp256k1, merkle_root: Option) -> (TweakedPublicKey, secp256k1::Parity) { let tweak = TapTweakHash::from_key_and_tweak(self, merkle_root).to_scalar(); let (output_key, parity) = self.add_tweak(secp, &tweak).expect("Tap tweak failed"); @@ -123,7 +123,7 @@ impl TapTweak for UntweakedKeyPair { /// /// # Returns /// The tweaked key and its parity. - fn tap_tweak(self, secp: &Secp256k1, merkle_root: Option) -> TweakedKeyPair { + fn tap_tweak(self, secp: &Secp256k1, merkle_root: Option) -> TweakedKeyPair { let (pubkey, _parity) = XOnlyPublicKey::from_keypair(&self); let tweak = TapTweakHash::from_key_and_tweak(pubkey, merkle_root).to_scalar(); let tweaked = self.add_xonly_tweak(secp, &tweak).expect("Tap tweak failed"); diff --git a/bitcoin/src/psbt/map/input.rs b/bitcoin/src/psbt/map/input.rs index fcc18538..0e69fcea 100644 --- a/bitcoin/src/psbt/map/input.rs +++ b/bitcoin/src/psbt/map/input.rs @@ -20,7 +20,7 @@ use crate::psbt::map::Map; use crate::psbt::serialize::Deserialize; use crate::psbt::{self, error, raw, Error}; use crate::sighash::{self, NonStandardSighashType, SighashTypeParseError, EcdsaSighashType, SchnorrSighashType}; -use crate::taproot::{ControlBlock, LeafVersion, TapLeafHash, TapBranchHash}; +use crate::taproot::{ControlBlock, LeafVersion, TapLeafHash, TapNodeHash}; /// Type: Non-Witness UTXO PSBT_IN_NON_WITNESS_UTXO = 0x00 const PSBT_IN_NON_WITNESS_UTXO: u8 = 0x00; @@ -124,7 +124,7 @@ pub struct Input { /// Taproot Internal key. pub tap_internal_key: Option, /// Taproot Merkle root. - pub tap_merkle_root: Option, + pub tap_merkle_root: Option, /// Proprietary key-value pairs for this input. #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq_byte_values"))] pub proprietary: BTreeMap>, @@ -338,7 +338,7 @@ impl Input { } PSBT_IN_TAP_MERKLE_ROOT => { impl_psbt_insert_pair! { - self.tap_merkle_root <= |< raw_value: TapBranchHash> + self.tap_merkle_root <= |< raw_value: TapNodeHash> } } PSBT_IN_PROPRIETARY => { diff --git a/bitcoin/src/psbt/serialize.rs b/bitcoin/src/psbt/serialize.rs index ddbe2ec8..784d59e1 100644 --- a/bitcoin/src/psbt/serialize.rs +++ b/bitcoin/src/psbt/serialize.rs @@ -21,7 +21,7 @@ use crate::bip32::{ChildNumber, Fingerprint, KeySource}; use crate::hashes::{hash160, ripemd160, sha256, sha256d, Hash}; use crate::crypto::{ecdsa, schnorr}; use crate::psbt::{self, Error, PartiallySignedTransaction}; -use crate::taproot::{TapBranchHash, TapLeafHash, ControlBlock, LeafVersion}; +use crate::taproot::{TapNodeHash, TapLeafHash, ControlBlock, LeafVersion}; use crate::crypto::key::PublicKey; use super::map::{Map, Input, Output, TapTree, PsbtSighashType}; @@ -123,7 +123,7 @@ impl_psbt_de_serialize!(Witness); impl_psbt_hash_de_serialize!(ripemd160::Hash); impl_psbt_hash_de_serialize!(sha256::Hash); impl_psbt_hash_de_serialize!(TapLeafHash); -impl_psbt_hash_de_serialize!(TapBranchHash); +impl_psbt_hash_de_serialize!(TapNodeHash); impl_psbt_hash_de_serialize!(hash160::Hash); impl_psbt_hash_de_serialize!(sha256d::Hash); diff --git a/bitcoin/src/sighash.rs b/bitcoin/src/sighash.rs index 657fb3f5..ce1061a4 100644 --- a/bitcoin/src/sighash.rs +++ b/bitcoin/src/sighash.rs @@ -1391,7 +1391,7 @@ mod tests { use secp256k1::{self, SecretKey, XOnlyPublicKey}; use crate::consensus::serde as con_serde; - use crate::taproot::{TapBranchHash, TapTweakHash}; + use crate::taproot::{TapNodeHash, TapTweakHash}; #[derive(serde::Deserialize)] #[serde(crate = "actual_serde")] @@ -1428,7 +1428,7 @@ mod tests { struct KpsInputSpendingGiven { txin_index: usize, internal_privkey: SecretKey, - merkle_root: Option, + merkle_root: Option, #[serde(deserialize_with = "sighash_deser_numeric")] hash_type: SchnorrSighashType, } diff --git a/bitcoin/src/taproot.rs b/bitcoin/src/taproot.rs index 36dcf3cd..f0b242b7 100644 --- a/bitcoin/src/taproot.rs +++ b/bitcoin/src/taproot.rs @@ -49,19 +49,22 @@ const MIDSTATE_TAPSIGHASH: [u8; 32] = [ // Taproot test vectors from BIP-341 state the hashes without any reversing #[rustfmt::skip] sha256t_hash_newtype!(TapLeafHash, TapLeafTag, MIDSTATE_TAPLEAF, 64, - doc="Taproot-tagged hash for tapscript Merkle tree leafs", false + doc="Taproot-tagged hash with tag \"TapLeaf\". + This is used for computing tapscript script spend hash.", false ); #[rustfmt::skip] -sha256t_hash_newtype!(TapBranchHash, TapBranchTag, MIDSTATE_TAPBRANCH, 64, - doc="Taproot-tagged hash for tapscript Merkle tree branches", false +sha256t_hash_newtype!(TapNodeHash, TapBranchTag, MIDSTATE_TAPBRANCH, 64, + doc="Tagged hash used in taproot trees; see BIP-340 for tagging rules", false ); #[rustfmt::skip] sha256t_hash_newtype!(TapTweakHash, TapTweakTag, MIDSTATE_TAPTWEAK, 64, - doc="Taproot-tagged hash for public key tweaks", false + doc="Taproot-tagged hash with tag \"TapTweak\". + This hash type is used while computing the tweaked public key", false ); #[rustfmt::skip] sha256t_hash_newtype!(TapSighashHash, TapSighashTag, MIDSTATE_TAPSIGHASH, 64, - doc="Taproot-tagged hash for the taproot signature hash", false + doc="Taproot-tagged hash with tag \"TapSighash\". + This hash type is used for computing taproot signature hash.", false ); impl secp256k1::ThirtyTwoByteHash for TapSighashHash { @@ -73,7 +76,7 @@ impl TapTweakHash { /// `P` is the internal key and `R` is the merkle root. pub fn from_key_and_tweak( internal_key: UntweakedPublicKey, - merkle_root: Option, + merkle_root: Option, ) -> TapTweakHash { let mut eng = TapTweakHash::engine(); // always hash the key @@ -111,10 +114,10 @@ impl From<&ScriptLeaf> for TapLeafHash { fn from(leaf: &ScriptLeaf) -> TapLeafHash { leaf.leaf_hash() } } -impl TapBranchHash { +impl TapNodeHash { /// Computes branch hash given two hashes of the nodes underneath it. - pub fn from_node_hashes(a: sha256::Hash, b: sha256::Hash) -> TapBranchHash { - let mut eng = TapBranchHash::engine(); + pub fn from_node_hashes(a: sha256::Hash, b: sha256::Hash) -> TapNodeHash { + let mut eng = TapNodeHash::engine(); if a < b { eng.input(a.as_ref()); eng.input(b.as_ref()); @@ -122,10 +125,14 @@ impl TapBranchHash { eng.input(b.as_ref()); eng.input(a.as_ref()); }; - TapBranchHash::from_engine(eng) + TapNodeHash::from_engine(eng) } } +impl From for TapNodeHash { + fn from(leaf: TapLeafHash) -> TapNodeHash { TapNodeHash::from_inner(leaf.into_inner()) } +} + /// Maximum depth of a taproot tree script spend path. // https://github.com/bitcoin/bitcoin/blob/e826b22da252e0599c61d21c98ff89f366b3120f/src/script/interpreter.h#L229 pub const TAPROOT_CONTROL_MAX_NODE_COUNT: usize = 128; @@ -177,7 +184,7 @@ pub struct TaprootSpendInfo { /// The BIP341 internal key. internal_key: UntweakedPublicKey, /// The merkle root of the script tree (None if there are no scripts). - merkle_root: Option, + merkle_root: Option, /// The sign final output pubkey as per BIP 341. output_key_parity: secp256k1::Parity, /// The tweaked output key. @@ -221,7 +228,7 @@ impl TaprootSpendInfo { pub fn new_key_spend( secp: &Secp256k1, internal_key: UntweakedPublicKey, - merkle_root: Option, + merkle_root: Option, ) -> Self { let (output_key, parity) = internal_key.tap_tweak(secp, merkle_root); Self { @@ -243,7 +250,7 @@ impl TaprootSpendInfo { pub fn internal_key(&self) -> UntweakedPublicKey { self.internal_key } /// Returns the merkle root for this [`TaprootSpendInfo`]. - pub fn merkle_root(&self) -> Option { self.merkle_root } + pub fn merkle_root(&self) -> Option { self.merkle_root } /// Returns the output key (the key used in script pubkey) for this [`TaprootSpendInfo`]. pub fn output_key(&self) -> TweakedPublicKey { self.output_key } @@ -261,7 +268,7 @@ impl TaprootSpendInfo { node: NodeInfo, ) -> TaprootSpendInfo { // Create as if it is a key spend path with the given merkle root - let root_hash = Some(TapBranchHash::from_inner(node.hash.into_inner())); + let root_hash = Some(TapNodeHash::from_inner(node.hash.into_inner())); let mut info = TaprootSpendInfo::new_key_spend(secp, internal_key, root_hash); for leaves in node.leaves { let key = (leaves.script, leaves.ver); @@ -568,7 +575,7 @@ impl NodeInfo { b_leaf.merkle_branch.push(a.hash)?; // add hashing partner all_leaves.push(b_leaf); } - let hash = TapBranchHash::from_node_hashes(a.hash, b.hash); + let hash = TapNodeHash::from_node_hashes(a.hash, b.hash); Ok(Self { hash: sha256::Hash::from_inner(hash.into_inner()), leaves: all_leaves, @@ -622,7 +629,7 @@ impl ScriptLeaf { } /// The merkle proof for inclusion of a tree in a taptree hash. -// The type of hash is `sha256::Hash` because the vector might contain both `TapBranchHash` and +// The type of hash is `sha256::Hash` because the vector might contain both `TapNodeHash` and // `TapLeafHash`. #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] @@ -802,11 +809,11 @@ impl ControlBlock { // compute the script hash // Initially the curr_hash is the leaf hash let leaf_hash = TapLeafHash::from_script(script, self.leaf_version); - let mut curr_hash = TapBranchHash::from_inner(leaf_hash.into_inner()); + let mut curr_hash = TapNodeHash::from_inner(leaf_hash.into_inner()); // Verify the proof for elem in self.merkle_branch.as_inner() { // Recalculate the curr hash as parent hash - curr_hash = TapBranchHash::from_node_hashes( + curr_hash = TapNodeHash::from_node_hashes( sha256::Hash::from_inner(curr_hash.into_inner()), *elem, ); @@ -1137,7 +1144,7 @@ mod test { sha256::Hash::from_engine(e).into_inner() } assert_eq!(empty_hash("TapLeaf"), TapLeafHash::hash(&[]).into_inner()); - assert_eq!(empty_hash("TapBranch"), TapBranchHash::hash(&[]).into_inner()); + assert_eq!(empty_hash("TapBranch"), TapNodeHash::hash(&[]).into_inner()); assert_eq!(empty_hash("TapTweak"), TapTweakHash::hash(&[]).into_inner()); assert_eq!(empty_hash("TapSighash"), TapSighashHash::hash(&[]).into_inner()); } @@ -1154,7 +1161,7 @@ mod test { "5212c288a377d1f8164962a5a13429f9ba6a7b84e59776a52c6637df2106facb" ); assert_eq!( - TapBranchHash::from_engine(TapBranchTag::engine()).to_string(), + TapNodeHash::from_engine(TapBranchTag::engine()).to_string(), "53c373ec4d6f3c53c1f5fb2ff506dcefe1a0ed74874f93fa93c8214cbe9ffddf" ); assert_eq!( @@ -1176,7 +1183,7 @@ mod test { "ed1382037800c9dd938dd8854f1a8863bcdeb6705069b4b56a66ec22519d5829" ); assert_eq!( - TapBranchHash::hash(&[0]).to_string(), + TapNodeHash::hash(&[0]).to_string(), "92534b1960c7e6245af7d5fda2588db04aa6d646abc2b588dab2b69e5645eb1d" ); assert_eq!( @@ -1412,7 +1419,7 @@ mod test { assert!(arr["intermediary"]["merkleRoot"].is_null()); } else { merkle_root = Some( - TapBranchHash::from_str(arr["intermediary"]["merkleRoot"].as_str().unwrap()) + TapNodeHash::from_str(arr["intermediary"]["merkleRoot"].as_str().unwrap()) .unwrap(), ); let leaf_hashes = arr["intermediary"]["leafHashes"].as_array().unwrap(); From f39cd88f5f711ff306f3e2272350a8ea07af6b35 Mon Sep 17 00:00:00 2001 From: sanket1729 Date: Thu, 15 Dec 2022 08:17:39 -0800 Subject: [PATCH 2/2] Use TapNodeHash in NodeInfo This cleans up some ugly code where we had to use sha256::Hash for combining TapLeafHash and TapBranchHash --- bitcoin/src/psbt/serialize.rs | 2 +- bitcoin/src/taproot.rs | 66 +++++++++++++++++------------------ 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/bitcoin/src/psbt/serialize.rs b/bitcoin/src/psbt/serialize.rs index 784d59e1..4ff7f3b1 100644 --- a/bitcoin/src/psbt/serialize.rs +++ b/bitcoin/src/psbt/serialize.rs @@ -460,7 +460,7 @@ mod tests { fn taptree_hidden() { let mut builder = compose_taproot_builder(0x51, &[2, 2, 2]); builder = builder.add_leaf_with_ver(3, ScriptBuf::from_hex("b9").unwrap(), LeafVersion::from_consensus(0xC2).unwrap()).unwrap(); - builder = builder.add_hidden_node(3, sha256::Hash::all_zeros()).unwrap(); + builder = builder.add_hidden_node(3, TapNodeHash::all_zeros()).unwrap(); assert!(TapTree::try_from(builder).is_err()); } diff --git a/bitcoin/src/taproot.rs b/bitcoin/src/taproot.rs index f0b242b7..e3fd0506 100644 --- a/bitcoin/src/taproot.rs +++ b/bitcoin/src/taproot.rs @@ -14,7 +14,7 @@ use secp256k1::{self, Scalar, Secp256k1}; use crate::consensus::Encodable; use crate::crypto::schnorr::{TapTweak, TweakedPublicKey, UntweakedPublicKey, XOnlyPublicKey}; -use crate::hashes::{sha256, sha256t_hash_newtype, Hash, HashEngine}; +use crate::hashes::{sha256t_hash_newtype, Hash, HashEngine}; use crate::prelude::*; use crate::{io, Script, ScriptBuf}; @@ -116,7 +116,7 @@ impl From<&ScriptLeaf> for TapLeafHash { impl TapNodeHash { /// Computes branch hash given two hashes of the nodes underneath it. - pub fn from_node_hashes(a: sha256::Hash, b: sha256::Hash) -> TapNodeHash { + pub fn from_node_hashes(a: TapNodeHash, b: TapNodeHash) -> TapNodeHash { let mut eng = TapNodeHash::engine(); if a < b { eng.input(a.as_ref()); @@ -127,6 +127,11 @@ impl TapNodeHash { }; TapNodeHash::from_engine(eng) } + + /// Computes the [`TapNodeHash`] from a script and a leaf version. + pub fn from_script(script: &Script, ver: LeafVersion) -> TapNodeHash { + TapNodeHash::from(TapLeafHash::from_script(script, ver)) + } } impl From for TapNodeHash { @@ -268,7 +273,7 @@ impl TaprootSpendInfo { node: NodeInfo, ) -> TaprootSpendInfo { // Create as if it is a key spend path with the given merkle root - let root_hash = Some(TapNodeHash::from_inner(node.hash.into_inner())); + let root_hash = Some(node.hash); let mut info = TaprootSpendInfo::new_key_spend(secp, internal_key, root_hash); for leaves in node.leaves { let key = (leaves.script, leaves.ver); @@ -441,7 +446,7 @@ impl TaprootBuilder { pub fn add_hidden_node( self, depth: u8, - hash: sha256::Hash, + hash: TapNodeHash, ) -> Result { let node = NodeInfo::new_hidden_node(hash); self.insert(node, depth) @@ -541,7 +546,7 @@ impl Default for TaprootBuilder { #[cfg_attr(feature = "serde", serde(crate = "actual_serde"))] pub struct NodeInfo { /// Merkle hash for this node. - pub(crate) hash: sha256::Hash, + pub(crate) hash: TapNodeHash, /// Information about leaves inside this node. pub(crate) leaves: Vec, /// Tracks information on hidden nodes below this node. @@ -550,16 +555,15 @@ pub struct NodeInfo { impl NodeInfo { /// Creates a new [`NodeInfo`] with omitted/hidden info. - pub fn new_hidden_node(hash: sha256::Hash) -> Self { + pub fn new_hidden_node(hash: TapNodeHash) -> Self { Self { hash, leaves: vec![], has_hidden_nodes: true } } /// Creates a new leaf [`NodeInfo`] with given [`ScriptBuf`] and [`LeafVersion`]. pub fn new_leaf_with_ver(script: ScriptBuf, ver: LeafVersion) -> Self { - let leaf = ScriptLeaf::new(script, ver); Self { - hash: sha256::Hash::from_inner(leaf.leaf_hash().into_inner()), - leaves: vec![leaf], + hash: TapNodeHash::from_script(&script, ver), + leaves: vec![ScriptLeaf::new(script, ver)], has_hidden_nodes: false, } } @@ -577,7 +581,7 @@ impl NodeInfo { } let hash = TapNodeHash::from_node_hashes(a.hash, b.hash); Ok(Self { - hash: sha256::Hash::from_inner(hash.into_inner()), + hash, leaves: all_leaves, has_hidden_nodes: a.has_hidden_nodes || b.has_hidden_nodes, }) @@ -629,16 +633,14 @@ impl ScriptLeaf { } /// The merkle proof for inclusion of a tree in a taptree hash. -// The type of hash is `sha256::Hash` because the vector might contain both `TapNodeHash` and -// `TapLeafHash`. #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(crate = "actual_serde"))] -pub struct TaprootMerkleBranch(Vec); +pub struct TaprootMerkleBranch(Vec); impl TaprootMerkleBranch { /// Returns a reference to the inner vector of hashes. - pub fn as_inner(&self) -> &[sha256::Hash] { &self.0 } + pub fn as_inner(&self) -> &[TapNodeHash] { &self.0 } /// Creates a merkle proof from raw data representing a list of hashes. pub fn from_slice(sl: &[u8]) -> Result { @@ -650,7 +652,7 @@ impl TaprootMerkleBranch { let inner = sl .chunks_exact(TAPROOT_CONTROL_NODE_SIZE) .map(|chunk| { - sha256::Hash::from_slice(chunk) + TapNodeHash::from_slice(chunk) .expect("chunks_exact always returns the correct size") }) .collect(); @@ -663,7 +665,7 @@ impl TaprootMerkleBranch { /// /// # Errors /// If inner proof length is more than [`TAPROOT_CONTROL_MAX_NODE_COUNT`] (128). - fn from_collection + Into>>( + fn from_collection + Into>>( collection: T, ) -> Result { if collection.as_ref().len() > TAPROOT_CONTROL_MAX_NODE_COUNT { @@ -682,7 +684,7 @@ impl TaprootMerkleBranch { for hash in self.0.iter() { writer.write_all(hash.as_ref())?; } - Ok(self.0.len() * sha256::Hash::LEN) + Ok(self.0.len() * TapNodeHash::LEN) } /// Serializes `self` as bytes. @@ -691,7 +693,7 @@ impl TaprootMerkleBranch { } /// Appends elements to proof. - fn push(&mut self, h: sha256::Hash) -> Result<(), TaprootBuilderError> { + fn push(&mut self, h: TapNodeHash) -> Result<(), TaprootBuilderError> { if self.0.len() >= TAPROOT_CONTROL_MAX_NODE_COUNT { Err(TaprootBuilderError::InvalidMerkleTreeDepth(self.0.len())) } else { @@ -701,7 +703,7 @@ impl TaprootMerkleBranch { } /// Returns the inner list of hashes. - pub fn into_inner(self) -> Vec { self.0 } + pub fn into_inner(self) -> Vec { self.0 } } macro_rules! impl_try_from { @@ -719,9 +721,9 @@ macro_rules! impl_try_from { } }; } -impl_try_from!(&[sha256::Hash]); -impl_try_from!(Vec); -impl_try_from!(Box<[sha256::Hash]>); +impl_try_from!(&[TapNodeHash]); +impl_try_from!(Vec); +impl_try_from!(Box<[TapNodeHash]>); /// Control block data structure used in Tapscript satisfaction. #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -808,15 +810,11 @@ impl ControlBlock { ) -> bool { // compute the script hash // Initially the curr_hash is the leaf hash - let leaf_hash = TapLeafHash::from_script(script, self.leaf_version); - let mut curr_hash = TapNodeHash::from_inner(leaf_hash.into_inner()); + let mut curr_hash = TapNodeHash::from_script(script, self.leaf_version); // Verify the proof for elem in self.merkle_branch.as_inner() { // Recalculate the curr hash as parent hash - curr_hash = TapNodeHash::from_node_hashes( - sha256::Hash::from_inner(curr_hash.into_inner()), - *elem, - ); + curr_hash = TapNodeHash::from_node_hashes(curr_hash, *elem); } // compute the taptweak let tweak = @@ -1064,15 +1062,17 @@ impl fmt::Display for TaprootError { "Merkle Tree depth({}) must be less than {}", d, TAPROOT_CONTROL_MAX_NODE_COUNT ), - TaprootError::InvalidTaprootLeafVersion(v) => - write!(f, "Leaf version({}) must have the least significant bit 0", v), + TaprootError::InvalidTaprootLeafVersion(v) => { + write!(f, "Leaf version({}) must have the least significant bit 0", v) + } TaprootError::InvalidControlBlockSize(sz) => write!( f, "Control Block size({}) must be of the form 33 + 32*m where 0 <= m <= {} ", sz, TAPROOT_CONTROL_MAX_NODE_COUNT ), - TaprootError::InvalidInternalKey(ref e) => - write_err!(f, "invalid internal x-only key"; e), + TaprootError::InvalidInternalKey(ref e) => { + write_err!(f, "invalid internal x-only key"; e) + } TaprootError::InvalidParity(_) => write!(f, "invalid parity value for internal key"), TaprootError::EmptyTree => write!(f, "Taproot Tree must contain at least one script"), } @@ -1141,7 +1141,7 @@ mod test { fn empty_hash(tag_name: &str) -> [u8; 32] { let mut e = tag_engine(tag_name); e.input(&[]); - sha256::Hash::from_engine(e).into_inner() + TapNodeHash::from_engine(e).into_inner() } assert_eq!(empty_hash("TapLeaf"), TapLeafHash::hash(&[]).into_inner()); assert_eq!(empty_hash("TapBranch"), TapNodeHash::hash(&[]).into_inner());