From 2407f241e4dd165b122f3776fe40beb3dfd3b817 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Mon, 23 Jan 2023 13:57:30 +1100 Subject: [PATCH 1/2] Remove sep256k1 path from Parity The `Parity` type is unambiguous, no need to use the `secp256k1` path all the time just import the type. Refactor only, no logic changes. --- bitcoin/src/crypto/schnorr.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bitcoin/src/crypto/schnorr.rs b/bitcoin/src/crypto/schnorr.rs index 8e0addc2..16b83e00 100644 --- a/bitcoin/src/crypto/schnorr.rs +++ b/bitcoin/src/crypto/schnorr.rs @@ -11,7 +11,7 @@ use core::fmt; use bitcoin_internals::write_err; -pub use secp256k1::{self, constants, Secp256k1, KeyPair, XOnlyPublicKey, Verification}; +pub use secp256k1::{self, constants, Secp256k1, KeyPair, XOnlyPublicKey, Verification, Parity}; use crate::prelude::*; @@ -79,7 +79,7 @@ pub trait TapTweak { } impl TapTweak for UntweakedPublicKey { - type TweakedAux = (TweakedPublicKey, secp256k1::Parity); + type TweakedAux = (TweakedPublicKey, Parity); type TweakedKey = TweakedPublicKey; /// Tweaks an untweaked public key with corresponding public key value and optional script tree @@ -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, 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"); From facaefc49c60dcd0656ae51764aec180363a88f6 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Mon, 23 Jan 2023 14:07:50 +1100 Subject: [PATCH 2/2] Add conversions for TweakedKeyPair -> TweakedPublicKey It is trivially possible to get `TweakedPublicKey` from a `TweakedKeyPair`, add conversion methods for doing so. --- bitcoin/src/crypto/schnorr.rs | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/bitcoin/src/crypto/schnorr.rs b/bitcoin/src/crypto/schnorr.rs index 16b83e00..5cf9cec8 100644 --- a/bitcoin/src/crypto/schnorr.rs +++ b/bitcoin/src/crypto/schnorr.rs @@ -44,6 +44,20 @@ impl fmt::Display for TweakedPublicKey { pub type UntweakedKeyPair = KeyPair; /// Tweaked BIP-340 key pair +/// +/// # Examples +/// ``` +/// # #[cfg(feature = "rand-std")] { +/// # use bitcoin::schnorr::{TweakedKeyPair, TweakedPublicKey}; +/// # use bitcoin::secp256k1::{rand, Secp256k1}; +/// # let secp = Secp256k1::new(); +/// # let keypair = TweakedKeyPair::dangerous_assume_tweaked(KeyPair::new(&secp, &mut rand::thread_rng())); +/// // There are various conversion methods available to get a tweaked pubkey from a tweaked keypair. +/// let (_pk, _parity) = keypair.public_parts(); +/// let _pk = TweakedPublicKey::from_keypair(keypair); +/// let _pk = TweakedPublicKey::from(keypair); +/// # } +/// ``` #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", serde(crate = "actual_serde"))] @@ -136,6 +150,13 @@ impl TapTweak for UntweakedKeyPair { } impl TweakedPublicKey { + /// Returns the [`TweakedPublicKey`] for `keypair`. + #[inline] + pub fn from_keypair(keypair: TweakedKeyPair) -> Self { + let (xonly, _parity) = keypair.0.x_only_public_key(); + TweakedPublicKey(xonly) + } + /// Creates a new [`TweakedPublicKey`] from a [`XOnlyPublicKey`]. No tweak is applied, consider /// calling `tap_tweak` on an [`UntweakedPublicKey`] instead of using this constructor. /// @@ -176,6 +197,13 @@ impl TweakedKeyPair { pub fn to_inner(self) -> KeyPair { self.0 } + + /// Returns the [`TweakedPublicKey`] and its [`Parity`] for this [`TweakedKeyPair`]. + #[inline] + pub fn public_parts(&self) -> (TweakedPublicKey, Parity) { + let (xonly, parity) = self.0.x_only_public_key(); + (TweakedPublicKey(xonly), parity) + } } impl From for XOnlyPublicKey { @@ -192,6 +220,13 @@ impl From for KeyPair { } } +impl From for TweakedPublicKey { + #[inline] + fn from(pair: TweakedKeyPair) -> Self { + TweakedPublicKey::from_keypair(pair) + } +} + /// A BIP340-341 serialized schnorr signature with the corresponding hash type. #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]