Use un/tweaked public key types

We have two types for tweaked/untweaked schnorr public keys to help
users of the taproot API not mix these two keys up. Currently the
`taproot` module uses 'raw' `schnoor::PublicKey`s.

Use the `schnoor` module's tweak/untweaked public key types for the
`taproot` API.
This commit is contained in:
Tobin Harding 2021-11-29 13:19:21 +11:00
parent 402bd993b2
commit b60db79a3b
1 changed files with 19 additions and 17 deletions

View File

@ -25,7 +25,7 @@ use core::cmp::Reverse;
use std::error; use std::error;
use hashes::{sha256, sha256t, Hash, HashEngine}; use hashes::{sha256, sha256t, Hash, HashEngine};
use schnorr; use schnorr::{TweakedPublicKey, UntweakedPublicKey};
use Script; use Script;
use consensus::Encodable; use consensus::Encodable;
@ -101,7 +101,7 @@ impl TapTweakHash {
/// Create a new BIP341 [`TapTweakHash`] from key and tweak /// Create a new BIP341 [`TapTweakHash`] from key and tweak
/// Produces H_taptweak(P||R) where P is internal key and R is the merkle root /// Produces H_taptweak(P||R) where P is internal key and R is the merkle root
pub fn from_key_and_tweak( pub fn from_key_and_tweak(
internal_key: schnorr::PublicKey, internal_key: UntweakedPublicKey,
merkle_root: Option<TapBranchHash>, merkle_root: Option<TapBranchHash>,
) -> TapTweakHash { ) -> TapTweakHash {
let mut eng = TapTweakHash::engine(); let mut eng = TapTweakHash::engine();
@ -171,13 +171,13 @@ type ScriptMerkleProofMap = BTreeMap<(Script, LeafVersion), BTreeSet<TaprootMerk
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct TaprootSpendInfo { pub struct TaprootSpendInfo {
/// The BIP341 internal key. /// The BIP341 internal key.
internal_key: schnorr::PublicKey, internal_key: UntweakedPublicKey,
/// The Merkle root of the script tree (None if there are no scripts) /// The Merkle root of the script tree (None if there are no scripts)
merkle_root: Option<TapBranchHash>, merkle_root: Option<TapBranchHash>,
/// The sign final output pubkey as per BIP 341 /// The sign final output pubkey as per BIP 341
output_key_parity: bool, output_key_parity: bool,
/// The tweaked output key /// The tweaked output key
output_key: schnorr::PublicKey, output_key: TweakedPublicKey,
/// Map from (script, leaf_version) to (sets of) [`TaprootMerkleBranch`]. /// Map from (script, leaf_version) to (sets of) [`TaprootMerkleBranch`].
/// More than one control block for a given script is only possible if it /// More than one control block for a given script is only possible if it
/// appears in multiple branches of the tree. In all cases, keeping one should /// appears in multiple branches of the tree. In all cases, keeping one should
@ -204,7 +204,7 @@ impl TaprootSpendInfo {
/// dealing with numbers close to 2^64. /// dealing with numbers close to 2^64.
pub fn with_huffman_tree<C, I>( pub fn with_huffman_tree<C, I>(
secp: &Secp256k1<C>, secp: &Secp256k1<C>,
internal_key: schnorr::PublicKey, internal_key: UntweakedPublicKey,
script_weights: I, script_weights: I,
) -> Result<Self, TaprootBuilderError> ) -> Result<Self, TaprootBuilderError>
where where
@ -250,7 +250,7 @@ impl TaprootSpendInfo {
/// ///
pub fn new_key_spend<C: secp256k1::Verification>( pub fn new_key_spend<C: secp256k1::Verification>(
secp: &Secp256k1<C>, secp: &Secp256k1<C>,
internal_key: schnorr::PublicKey, internal_key: UntweakedPublicKey,
merkle_root: Option<TapBranchHash>, merkle_root: Option<TapBranchHash>,
) -> Self { ) -> Self {
let tweak = TapTweakHash::from_key_and_tweak(internal_key, merkle_root); let tweak = TapTweakHash::from_key_and_tweak(internal_key, merkle_root);
@ -268,7 +268,7 @@ impl TaprootSpendInfo {
internal_key: internal_key, internal_key: internal_key,
merkle_root: merkle_root, merkle_root: merkle_root,
output_key_parity: parity, output_key_parity: parity,
output_key: output_key, output_key: TweakedPublicKey::new(output_key),
script_map: BTreeMap::new(), script_map: BTreeMap::new(),
} }
} }
@ -279,7 +279,7 @@ impl TaprootSpendInfo {
} }
/// Obtain the internal key /// Obtain the internal key
pub fn internal_key(&self) -> schnorr::PublicKey { pub fn internal_key(&self) -> UntweakedPublicKey {
self.internal_key self.internal_key
} }
@ -290,7 +290,7 @@ impl TaprootSpendInfo {
/// Output key(the key used in script pubkey) from Spend data. See also /// Output key(the key used in script pubkey) from Spend data. See also
/// [`TaprootSpendInfo::output_key_parity`] /// [`TaprootSpendInfo::output_key_parity`]
pub fn output_key(&self) -> schnorr::PublicKey { pub fn output_key(&self) -> TweakedPublicKey {
self.output_key self.output_key
} }
@ -302,7 +302,7 @@ impl TaprootSpendInfo {
// Internal function to compute [`TaprootSpendInfo`] from NodeInfo // Internal function to compute [`TaprootSpendInfo`] from NodeInfo
fn from_node_info<C: secp256k1::Verification>( fn from_node_info<C: secp256k1::Verification>(
secp: &Secp256k1<C>, secp: &Secp256k1<C>,
internal_key: schnorr::PublicKey, internal_key: UntweakedPublicKey,
node: NodeInfo, node: NodeInfo,
) -> TaprootSpendInfo { ) -> TaprootSpendInfo {
// Create as if it is a key spend path with the given merkle root // Create as if it is a key spend path with the given merkle root
@ -430,7 +430,7 @@ impl TaprootBuilder {
pub fn finalize<C: secp256k1::Verification>( pub fn finalize<C: secp256k1::Verification>(
mut self, mut self,
secp: &Secp256k1<C>, secp: &Secp256k1<C>,
internal_key: schnorr::PublicKey, internal_key: UntweakedPublicKey,
) -> Result<TaprootSpendInfo, TaprootBuilderError> { ) -> Result<TaprootSpendInfo, TaprootBuilderError> {
if self.branch.len() > 1 { if self.branch.len() > 1 {
return Err(TaprootBuilderError::IncompleteTree); return Err(TaprootBuilderError::IncompleteTree);
@ -652,7 +652,7 @@ pub struct ControlBlock {
/// The parity of the output key (NOT THE INTERNAL KEY WHICH IS ALWAYS XONLY) /// The parity of the output key (NOT THE INTERNAL KEY WHICH IS ALWAYS XONLY)
pub output_key_parity: bool, pub output_key_parity: bool,
/// The internal key /// The internal key
pub internal_key: schnorr::PublicKey, pub internal_key: UntweakedPublicKey,
/// The merkle proof of a script associated with this leaf /// The merkle proof of a script associated with this leaf
pub merkle_branch: TaprootMerkleBranch, pub merkle_branch: TaprootMerkleBranch,
} }
@ -674,7 +674,7 @@ impl ControlBlock {
} }
let output_key_parity = (sl[0] & 1) == 1; let output_key_parity = (sl[0] & 1) == 1;
let leaf_version = LeafVersion::from_u8(sl[0] & TAPROOT_LEAF_MASK)?; let leaf_version = LeafVersion::from_u8(sl[0] & TAPROOT_LEAF_MASK)?;
let internal_key = schnorr::PublicKey::from_slice(&sl[1..TAPROOT_CONTROL_BASE_SIZE]) let internal_key = UntweakedPublicKey::from_slice(&sl[1..TAPROOT_CONTROL_BASE_SIZE])
.map_err(TaprootError::InvalidInternalKey)?; .map_err(TaprootError::InvalidInternalKey)?;
let merkle_branch = TaprootMerkleBranch::from_slice(&sl[TAPROOT_CONTROL_BASE_SIZE..])?; let merkle_branch = TaprootMerkleBranch::from_slice(&sl[TAPROOT_CONTROL_BASE_SIZE..])?;
Ok(ControlBlock { Ok(ControlBlock {
@ -719,7 +719,7 @@ impl ControlBlock {
pub fn verify_taproot_commitment<C: secp256k1::Verification>( pub fn verify_taproot_commitment<C: secp256k1::Verification>(
&self, &self,
secp: &Secp256k1<C>, secp: &Secp256k1<C>,
output_key: &schnorr::PublicKey, output_key: &TweakedPublicKey,
script: &Script, script: &Script,
) -> bool { ) -> bool {
// compute the script hash // compute the script hash
@ -743,7 +743,7 @@ impl ControlBlock {
let tweak = TapTweakHash::from_key_and_tweak(self.internal_key, Some(curr_hash)); let tweak = TapTweakHash::from_key_and_tweak(self.internal_key, Some(curr_hash));
self.internal_key.tweak_add_check( self.internal_key.tweak_add_check(
secp, secp,
output_key, output_key.as_inner(),
self.output_key_parity, self.output_key_parity,
tweak.into_inner(), tweak.into_inner(),
) )
@ -900,6 +900,7 @@ mod test {
use hashes::{sha256, Hash, HashEngine}; use hashes::{sha256, Hash, HashEngine};
use secp256k1::VerifyOnly; use secp256k1::VerifyOnly;
use core::str::FromStr; use core::str::FromStr;
use schnorr;
fn tag_engine(tag_name: &str) -> sha256::HashEngine { fn tag_engine(tag_name: &str) -> sha256::HashEngine {
let mut engine = sha256::Hash::engine(); let mut engine = sha256::Hash::engine();
@ -984,6 +985,7 @@ mod test {
fn _verify_tap_commitments(secp: &Secp256k1<VerifyOnly>, out_spk_hex: &str, script_hex : &str, control_block_hex: &str) { fn _verify_tap_commitments(secp: &Secp256k1<VerifyOnly>, out_spk_hex: &str, script_hex : &str, control_block_hex: &str) {
let out_pk = schnorr::PublicKey::from_str(&out_spk_hex[4..]).unwrap(); let out_pk = schnorr::PublicKey::from_str(&out_spk_hex[4..]).unwrap();
let out_pk = TweakedPublicKey::new(out_pk);
let script = Script::from_hex(script_hex).unwrap(); let script = Script::from_hex(script_hex).unwrap();
let control_block = ControlBlock::from_slice(&Vec::<u8>::from_hex(control_block_hex).unwrap()).unwrap(); let control_block = ControlBlock::from_slice(&Vec::<u8>::from_hex(control_block_hex).unwrap()).unwrap();
assert_eq!(control_block_hex, control_block.serialize().to_hex()); assert_eq!(control_block_hex, control_block.serialize().to_hex());
@ -1025,7 +1027,7 @@ mod test {
#[test] #[test]
fn build_huffman_tree() { fn build_huffman_tree() {
let secp = Secp256k1::verification_only(); let secp = Secp256k1::verification_only();
let internal_key = schnorr::PublicKey::from_str("93c7378d96518a75448821c4f7c8f4bae7ce60f804d03d1f0628dd5dd0f5de51").unwrap(); let internal_key = UntweakedPublicKey::from_str("93c7378d96518a75448821c4f7c8f4bae7ce60f804d03d1f0628dd5dd0f5de51").unwrap();
let script_weights = vec![ let script_weights = vec![
(10, Script::from_hex("51").unwrap()), // semantics of script don't matter for this test (10, Script::from_hex("51").unwrap()), // semantics of script don't matter for this test
@ -1075,7 +1077,7 @@ mod test {
#[test] #[test]
fn taptree_builder() { fn taptree_builder() {
let secp = Secp256k1::verification_only(); let secp = Secp256k1::verification_only();
let internal_key = schnorr::PublicKey::from_str("93c7378d96518a75448821c4f7c8f4bae7ce60f804d03d1f0628dd5dd0f5de51").unwrap(); let internal_key = UntweakedPublicKey::from_str("93c7378d96518a75448821c4f7c8f4bae7ce60f804d03d1f0628dd5dd0f5de51").unwrap();
let builder = TaprootBuilder::new(); let builder = TaprootBuilder::new();
// Create a tree as shown below // Create a tree as shown below