crypto: Run the formatter

Run `cargo +nightly fmt`, no other manual changes.
This commit is contained in:
Tobin C. Harding 2022-12-06 10:39:56 +11:00
parent c8a3c58786
commit 3ec8a12428
No known key found for this signature in database
GPG Key ID: 40BF9E4C269D6607
4 changed files with 205 additions and 262 deletions

View File

@ -8,14 +8,14 @@
use core::str::FromStr; use core::str::FromStr;
use core::{fmt, iter}; use core::{fmt, iter};
use bitcoin_internals::write_err;
use bitcoin_internals::hex::display::DisplayHex; use bitcoin_internals::hex::display::DisplayHex;
use bitcoin_internals::write_err;
use secp256k1; use secp256k1;
use crate::prelude::*;
use crate::hashes::hex::{self, FromHex}; use crate::hashes::hex::{self, FromHex};
use crate::sighash::{EcdsaSighashType, NonStandardSighashType}; use crate::prelude::*;
use crate::script::PushBytes; use crate::script::PushBytes;
use crate::sighash::{EcdsaSighashType, NonStandardSighashType};
const MAX_SIG_LEN: usize = 73; const MAX_SIG_LEN: usize = 73;
@ -33,20 +33,15 @@ pub struct Signature {
impl Signature { impl Signature {
/// Constructs an ECDSA bitcoin signature for [`EcdsaSighashType::All`]. /// Constructs an ECDSA bitcoin signature for [`EcdsaSighashType::All`].
pub fn sighash_all(sig: secp256k1::ecdsa::Signature) -> Signature { pub fn sighash_all(sig: secp256k1::ecdsa::Signature) -> Signature {
Signature { Signature { sig, hash_ty: EcdsaSighashType::All }
sig,
hash_ty: EcdsaSighashType::All
}
} }
/// Deserializes from slice following the standardness rules for [`EcdsaSighashType`]. /// Deserializes from slice following the standardness rules for [`EcdsaSighashType`].
pub fn from_slice(sl: &[u8]) -> Result<Self, Error> { pub fn from_slice(sl: &[u8]) -> Result<Self, Error> {
let (hash_ty, sig) = sl.split_last() let (hash_ty, sig) = sl.split_last().ok_or(Error::EmptySignature)?;
.ok_or(Error::EmptySignature)?;
let hash_ty = EcdsaSighashType::from_standard(*hash_ty as u32) let hash_ty = EcdsaSighashType::from_standard(*hash_ty as u32)
.map_err(|_| Error::NonStandardSighashType(*hash_ty as u32))?; .map_err(|_| Error::NonStandardSighashType(*hash_ty as u32))?;
let sig = secp256k1::ecdsa::Signature::from_der(sig) let sig = secp256k1::ecdsa::Signature::from_der(sig).map_err(Error::Secp256k1)?;
.map_err(Error::Secp256k1)?;
Ok(Signature { sig, hash_ty }) Ok(Signature { sig, hash_ty })
} }
@ -58,10 +53,7 @@ impl Signature {
let signature = self.sig.serialize_der(); let signature = self.sig.serialize_der();
buf[..signature.len()].copy_from_slice(&signature); buf[..signature.len()].copy_from_slice(&signature);
buf[signature.len()] = self.hash_ty as u8; buf[signature.len()] = self.hash_ty as u8;
SerializedSignature { SerializedSignature { data: buf, len: signature.len() + 1 }
data: buf,
len: signature.len() + 1,
}
} }
/// Serializes an ECDSA signature (inner secp256k1 signature in DER format) into `Vec`. /// Serializes an ECDSA signature (inner secp256k1 signature in DER format) into `Vec`.
@ -70,10 +62,7 @@ impl Signature {
/// [`serialize`](Self::serialize) method instead. /// [`serialize`](Self::serialize) method instead.
pub fn to_vec(self) -> Vec<u8> { pub fn to_vec(self) -> Vec<u8> {
// TODO: add support to serialize to a writer to SerializedSig // TODO: add support to serialize to a writer to SerializedSig
self.sig.serialize_der() self.sig.serialize_der().iter().copied().chain(iter::once(self.hash_ty as u8)).collect()
.iter().copied()
.chain(iter::once(self.hash_ty as u8))
.collect()
} }
} }
@ -89,11 +78,10 @@ impl FromStr for Signature {
fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
let bytes = Vec::from_hex(s)?; let bytes = Vec::from_hex(s)?;
let (sighash_byte, signature) = bytes.split_last() let (sighash_byte, signature) = bytes.split_last().ok_or(Error::EmptySignature)?;
.ok_or(Error::EmptySignature)?;
Ok(Signature { Ok(Signature {
sig: secp256k1::ecdsa::Signature::from_der(signature)?, sig: secp256k1::ecdsa::Signature::from_der(signature)?,
hash_ty: EcdsaSighashType::from_standard(*sighash_byte as u32)? hash_ty: EcdsaSighashType::from_standard(*sighash_byte as u32)?,
}) })
} }
} }
@ -114,60 +102,44 @@ pub struct SerializedSignature {
impl SerializedSignature { impl SerializedSignature {
/// Returns an iterator over bytes of the signature. /// Returns an iterator over bytes of the signature.
#[inline] #[inline]
pub fn iter(&self) -> core::slice::Iter<'_, u8> { pub fn iter(&self) -> core::slice::Iter<'_, u8> { self.into_iter() }
self.into_iter()
}
} }
impl core::ops::Deref for SerializedSignature { impl core::ops::Deref for SerializedSignature {
type Target = [u8]; type Target = [u8];
#[inline] #[inline]
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target { &self.data[..self.len] }
&self.data[..self.len]
}
} }
impl core::ops::DerefMut for SerializedSignature { impl core::ops::DerefMut for SerializedSignature {
#[inline] #[inline]
fn deref_mut(&mut self) -> &mut Self::Target { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.data[..self.len] }
&mut self.data[..self.len]
}
} }
impl AsRef<[u8]> for SerializedSignature { impl AsRef<[u8]> for SerializedSignature {
#[inline] #[inline]
fn as_ref(&self) -> &[u8] { fn as_ref(&self) -> &[u8] { self }
self
}
} }
impl AsMut<[u8]> for SerializedSignature { impl AsMut<[u8]> for SerializedSignature {
#[inline] #[inline]
fn as_mut(&mut self) -> &mut [u8] { fn as_mut(&mut self) -> &mut [u8] { self }
self
}
} }
impl AsRef<PushBytes> for SerializedSignature { impl AsRef<PushBytes> for SerializedSignature {
#[inline] #[inline]
fn as_ref(&self) -> &PushBytes { fn as_ref(&self) -> &PushBytes { &<&PushBytes>::from(&self.data)[..self.len()] }
&<&PushBytes>::from(&self.data)[..self.len()]
}
} }
impl core::borrow::Borrow<[u8]> for SerializedSignature { impl core::borrow::Borrow<[u8]> for SerializedSignature {
#[inline] #[inline]
fn borrow(&self) -> &[u8] { fn borrow(&self) -> &[u8] { self }
self
}
} }
impl core::borrow::BorrowMut<[u8]> for SerializedSignature { impl core::borrow::BorrowMut<[u8]> for SerializedSignature {
#[inline] #[inline]
fn borrow_mut(&mut self) -> &mut [u8] { fn borrow_mut(&mut self) -> &mut [u8] { self }
self
}
} }
impl fmt::Debug for SerializedSignature { impl fmt::Debug for SerializedSignature {
@ -202,9 +174,7 @@ impl PartialEq for SerializedSignature {
impl Eq for SerializedSignature {} impl Eq for SerializedSignature {}
impl core::hash::Hash for SerializedSignature { impl core::hash::Hash for SerializedSignature {
fn hash<H: core::hash::Hasher>(&self, state: &mut H) { fn hash<H: core::hash::Hasher>(&self, state: &mut H) { core::hash::Hash::hash(&**self, state) }
core::hash::Hash::hash(&**self, state)
}
} }
impl<'a> IntoIterator for &'a SerializedSignature { impl<'a> IntoIterator for &'a SerializedSignature {
@ -212,9 +182,7 @@ impl<'a> IntoIterator for &'a SerializedSignature {
type Item = &'a u8; type Item = &'a u8;
#[inline] #[inline]
fn into_iter(self) -> Self::IntoIter { fn into_iter(self) -> Self::IntoIter { (*self).iter() }
(*self).iter()
}
} }
/// A key-related error. /// A key-related error.
@ -231,18 +199,14 @@ pub enum Error {
Secp256k1(secp256k1::Error), Secp256k1(secp256k1::Error),
} }
impl fmt::Display for Error { impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self { match *self {
Error::HexEncoding(ref e) => Error::HexEncoding(ref e) => write_err!(f, "Signature hex encoding error"; e),
write_err!(f, "Signature hex encoding error"; e),
Error::NonStandardSighashType(hash_ty) => Error::NonStandardSighashType(hash_ty) =>
write!(f, "Non standard signature hash type {}", hash_ty), write!(f, "Non standard signature hash type {}", hash_ty),
Error::EmptySignature => Error::EmptySignature => write!(f, "Empty ECDSA signature"),
write!(f, "Empty ECDSA signature"), Error::Secp256k1(ref e) => write_err!(f, "invalid ECDSA signature"; e),
Error::Secp256k1(ref e) =>
write_err!(f, "invalid ECDSA signature"; e),
} }
} }
} }
@ -262,19 +226,13 @@ impl std::error::Error for Error {
} }
impl From<secp256k1::Error> for Error { impl From<secp256k1::Error> for Error {
fn from(e: secp256k1::Error) -> Error { fn from(e: secp256k1::Error) -> Error { Error::Secp256k1(e) }
Error::Secp256k1(e)
}
} }
impl From<NonStandardSighashType> for Error { impl From<NonStandardSighashType> for Error {
fn from(err: NonStandardSighashType) -> Self { fn from(err: NonStandardSighashType) -> Self { Error::NonStandardSighashType(err.0) }
Error::NonStandardSighashType(err.0)
}
} }
impl From<hex::Error> for Error { impl From<hex::Error> for Error {
fn from(err: hex::Error) -> Self { fn from(err: hex::Error) -> Self { Error::HexEncoding(err) }
Error::HexEncoding(err)
}
} }

View File

@ -6,20 +6,20 @@
//! This module provides keys used in Bitcoin that can be roundtrip //! This module provides keys used in Bitcoin that can be roundtrip
//! (de)serialized. //! (de)serialized.
use crate::prelude::*;
use core::{ops, str::FromStr};
use core::fmt::{self, Write}; use core::fmt::{self, Write};
use core::ops;
use core::str::FromStr;
use bitcoin_internals::write_err; use bitcoin_internals::write_err;
pub use secp256k1::{self, constants, KeyPair, Parity, Secp256k1, Verification, XOnlyPublicKey};
pub use secp256k1::{self, constants, Secp256k1, KeyPair, XOnlyPublicKey, Verification, Parity};
use crate::{base58, io};
use crate::network::constants::Network;
use crate::hashes::{Hash, hash160, hex, hex::FromHex};
use crate::hash_types::{PubkeyHash, WPubkeyHash}; use crate::hash_types::{PubkeyHash, WPubkeyHash};
use crate::hashes::hex::FromHex;
use crate::hashes::{hash160, hex, Hash};
use crate::network::constants::Network;
use crate::prelude::*;
use crate::taproot::{TapNodeHash, TapTweakHash}; use crate::taproot::{TapNodeHash, TapTweakHash};
use crate::{base58, io};
/// A key-related error. /// A key-related error.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
@ -44,7 +44,8 @@ impl fmt::Display for Error {
Error::Secp256k1(ref e) => write_err!(f, "key secp256k1 error"; e), Error::Secp256k1(ref e) => write_err!(f, "key secp256k1 error"; e),
Error::InvalidKeyPrefix(ref b) => write!(f, "key prefix invalid: {}", b), Error::InvalidKeyPrefix(ref b) => write!(f, "key prefix invalid: {}", b),
Error::Hex(ref e) => write_err!(f, "key hex decoding error"; e), Error::Hex(ref e) => write_err!(f, "key hex decoding error"; e),
Error::InvalidHexLength(got) => write!(f, "PublicKey hex should be 66 or 130 digits long, got: {}", got), Error::InvalidHexLength(got) =>
write!(f, "PublicKey hex should be 66 or 130 digits long, got: {}", got),
} }
} }
} }
@ -66,26 +67,19 @@ impl std::error::Error for Error {
#[doc(hidden)] #[doc(hidden)]
impl From<base58::Error> for Error { impl From<base58::Error> for Error {
fn from(e: base58::Error) -> Error { fn from(e: base58::Error) -> Error { Error::Base58(e) }
Error::Base58(e)
}
} }
#[doc(hidden)] #[doc(hidden)]
impl From<secp256k1::Error> for Error { impl From<secp256k1::Error> for Error {
fn from(e: secp256k1::Error) -> Error { fn from(e: secp256k1::Error) -> Error { Error::Secp256k1(e) }
Error::Secp256k1(e)
}
} }
#[doc(hidden)] #[doc(hidden)]
impl From<hex::Error> for Error { impl From<hex::Error> for Error {
fn from(e: hex::Error) -> Self { fn from(e: hex::Error) -> Self { Error::Hex(e) }
Error::Hex(e)
}
} }
/// A Bitcoin ECDSA public key /// A Bitcoin ECDSA public key
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct PublicKey { pub struct PublicKey {
@ -98,19 +92,13 @@ pub struct PublicKey {
impl PublicKey { impl PublicKey {
/// Constructs compressed ECDSA public key from the provided generic Secp256k1 public key /// Constructs compressed ECDSA public key from the provided generic Secp256k1 public key
pub fn new(key: impl Into<secp256k1::PublicKey>) -> PublicKey { pub fn new(key: impl Into<secp256k1::PublicKey>) -> PublicKey {
PublicKey { PublicKey { compressed: true, inner: key.into() }
compressed: true,
inner: key.into(),
}
} }
/// Constructs uncompressed (legacy) ECDSA public key from the provided generic Secp256k1 /// Constructs uncompressed (legacy) ECDSA public key from the provided generic Secp256k1
/// public key /// public key
pub fn new_uncompressed(key: impl Into<secp256k1::PublicKey>) -> PublicKey { pub fn new_uncompressed(key: impl Into<secp256k1::PublicKey>) -> PublicKey {
PublicKey { PublicKey { compressed: false, inner: key.into() }
compressed: false,
inner: key.into(),
}
} }
fn with_serialized<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R { fn with_serialized<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
@ -122,15 +110,13 @@ impl PublicKey {
} }
/// Returns bitcoin 160-bit hash of the public key /// Returns bitcoin 160-bit hash of the public key
pub fn pubkey_hash(&self) -> PubkeyHash { pub fn pubkey_hash(&self) -> PubkeyHash { self.with_serialized(PubkeyHash::hash) }
self.with_serialized(PubkeyHash::hash)
}
/// Returns bitcoin 160-bit hash of the public key for witness program /// Returns bitcoin 160-bit hash of the public key for witness program
pub fn wpubkey_hash(&self) -> Option<WPubkeyHash> { pub fn wpubkey_hash(&self) -> Option<WPubkeyHash> {
if self.compressed { if self.compressed {
Some(WPubkeyHash::from_byte_array( Some(WPubkeyHash::from_byte_array(
hash160::Hash::hash(&self.inner.serialize()).to_byte_array() hash160::Hash::hash(&self.inner.serialize()).to_byte_array(),
)) ))
} else { } else {
// We can't create witness pubkey hashes for an uncompressed // We can't create witness pubkey hashes for an uncompressed
@ -249,26 +235,25 @@ impl PublicKey {
let compressed = match data.len() { let compressed = match data.len() {
33 => true, 33 => true,
65 => false, 65 => false,
len => { len => {
return Err(base58::Error::InvalidLength(len).into()); return Err(base58::Error::InvalidLength(len).into());
}, }
}; };
if !compressed && data[0] != 0x04 { if !compressed && data[0] != 0x04 {
return Err(Error::InvalidKeyPrefix(data[0])) return Err(Error::InvalidKeyPrefix(data[0]));
} }
Ok(PublicKey { Ok(PublicKey { compressed, inner: secp256k1::PublicKey::from_slice(data)? })
compressed,
inner: secp256k1::PublicKey::from_slice(data)?,
})
} }
/// Computes the public key as supposed to be used with this secret /// Computes the public key as supposed to be used with this secret
pub fn from_private_key<C: secp256k1::Signing>(secp: &Secp256k1<C>, sk: &PrivateKey) -> PublicKey { pub fn from_private_key<C: secp256k1::Signing>(
secp: &Secp256k1<C>,
sk: &PrivateKey,
) -> PublicKey {
sk.public_key(secp) sk.public_key(secp)
} }
} }
/// An opaque return type for PublicKey::to_sort_key /// An opaque return type for PublicKey::to_sort_key
@ -299,9 +284,7 @@ impl FromStr for PublicKey {
} }
impl From<PublicKey> for PubkeyHash { impl From<PublicKey> for PubkeyHash {
fn from(key: PublicKey) -> PubkeyHash { fn from(key: PublicKey) -> PubkeyHash { key.pubkey_hash() }
key.pubkey_hash()
}
} }
/// A Bitcoin ECDSA private key /// A Bitcoin ECDSA private key
@ -320,35 +303,25 @@ impl PrivateKey {
/// Constructs compressed ECDSA private key from the provided generic Secp256k1 private key /// Constructs compressed ECDSA private key from the provided generic Secp256k1 private key
/// and the specified network /// and the specified network
pub fn new(key: secp256k1::SecretKey, network: Network) -> PrivateKey { pub fn new(key: secp256k1::SecretKey, network: Network) -> PrivateKey {
PrivateKey { PrivateKey { compressed: true, network, inner: key }
compressed: true,
network,
inner: key,
}
} }
/// Constructs uncompressed (legacy) ECDSA private key from the provided generic Secp256k1 /// Constructs uncompressed (legacy) ECDSA private key from the provided generic Secp256k1
/// private key and the specified network /// private key and the specified network
pub fn new_uncompressed(key: secp256k1::SecretKey, network: Network) -> PrivateKey { pub fn new_uncompressed(key: secp256k1::SecretKey, network: Network) -> PrivateKey {
PrivateKey { PrivateKey { compressed: false, network, inner: key }
compressed: false,
network,
inner: key,
}
} }
/// Creates a public key from this private key /// Creates a public key from this private key
pub fn public_key<C: secp256k1::Signing>(&self, secp: &Secp256k1<C>) -> PublicKey { pub fn public_key<C: secp256k1::Signing>(&self, secp: &Secp256k1<C>) -> PublicKey {
PublicKey { PublicKey {
compressed: self.compressed, compressed: self.compressed,
inner: secp256k1::PublicKey::from_secret_key(secp, &self.inner) inner: secp256k1::PublicKey::from_secret_key(secp, &self.inner),
} }
} }
/// Serialize the private key to bytes /// Serialize the private key to bytes
pub fn to_bytes(self) -> Vec<u8> { pub fn to_bytes(self) -> Vec<u8> { self.inner[..].to_vec() }
self.inner[..].to_vec()
}
/// Deserialize a private key from a slice /// Deserialize a private key from a slice
pub fn from_slice(data: &[u8], network: Network) -> Result<PrivateKey, Error> { pub fn from_slice(data: &[u8], network: Network) -> Result<PrivateKey, Error> {
@ -395,7 +368,7 @@ impl PrivateKey {
let network = match data[0] { let network = match data[0] {
128 => Network::Bitcoin, 128 => Network::Bitcoin,
239 => Network::Testnet, 239 => Network::Testnet,
x => { x => {
return Err(Error::Base58(base58::Error::InvalidAddressVersion(x))); return Err(Error::Base58(base58::Error::InvalidAddressVersion(x)));
} }
}; };
@ -409,30 +382,22 @@ impl PrivateKey {
} }
impl fmt::Display for PrivateKey { impl fmt::Display for PrivateKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.fmt_wif(f) }
self.fmt_wif(f)
}
} }
#[cfg(not(feature = "std"))] #[cfg(not(feature = "std"))]
impl fmt::Debug for PrivateKey { impl fmt::Debug for PrivateKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "[private key data]") }
write!(f, "[private key data]")
}
} }
impl FromStr for PrivateKey { impl FromStr for PrivateKey {
type Err = Error; type Err = Error;
fn from_str(s: &str) -> Result<PrivateKey, Error> { fn from_str(s: &str) -> Result<PrivateKey, Error> { PrivateKey::from_wif(s) }
PrivateKey::from_wif(s)
}
} }
impl ops::Index<ops::RangeFull> for PrivateKey { impl ops::Index<ops::RangeFull> for PrivateKey {
type Output = [u8]; type Output = [u8];
fn index(&self, _: ops::RangeFull) -> &[u8] { fn index(&self, _: ops::RangeFull) -> &[u8] { &self.inner[..] }
&self.inner[..]
}
} }
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
@ -559,15 +524,11 @@ pub type UntweakedPublicKey = XOnlyPublicKey;
pub struct TweakedPublicKey(XOnlyPublicKey); pub struct TweakedPublicKey(XOnlyPublicKey);
impl fmt::LowerHex for TweakedPublicKey { impl fmt::LowerHex for TweakedPublicKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(&self.0, f) }
fmt::LowerHex::fmt(&self.0, f)
}
} }
impl fmt::Display for TweakedPublicKey { impl fmt::Display for TweakedPublicKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&self.0, f) }
fmt::Display::fmt(&self.0, f)
}
} }
/// Untweaked BIP-340 key pair /// Untweaked BIP-340 key pair
@ -613,7 +574,11 @@ pub trait TapTweak {
/// ///
/// # Returns /// # Returns
/// The tweaked key and its parity. /// The tweaked key and its parity.
fn tap_tweak<C: Verification>(self, secp: &Secp256k1<C>, merkle_root: Option<TapNodeHash>) -> Self::TweakedAux; fn tap_tweak<C: Verification>(
self,
secp: &Secp256k1<C>,
merkle_root: Option<TapNodeHash>,
) -> Self::TweakedAux;
/// Directly converts an [`UntweakedPublicKey`] to a [`TweakedPublicKey`] /// Directly converts an [`UntweakedPublicKey`] to a [`TweakedPublicKey`]
/// ///
@ -638,7 +603,11 @@ impl TapTweak for UntweakedPublicKey {
/// ///
/// # Returns /// # Returns
/// The tweaked key and its parity. /// The tweaked key and its parity.
fn tap_tweak<C: Verification>(self, secp: &Secp256k1<C>, merkle_root: Option<TapNodeHash>) -> (TweakedPublicKey, Parity) { fn tap_tweak<C: Verification>(
self,
secp: &Secp256k1<C>,
merkle_root: Option<TapNodeHash>,
) -> (TweakedPublicKey, Parity) {
let tweak = TapTweakHash::from_key_and_tweak(self, merkle_root).to_scalar(); 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"); let (output_key, parity) = self.add_tweak(secp, &tweak).expect("Tap tweak failed");
@ -646,9 +615,7 @@ impl TapTweak for UntweakedPublicKey {
(TweakedPublicKey(output_key), parity) (TweakedPublicKey(output_key), parity)
} }
fn dangerous_assume_tweaked(self) -> TweakedPublicKey { fn dangerous_assume_tweaked(self) -> TweakedPublicKey { TweakedPublicKey(self) }
TweakedPublicKey(self)
}
} }
impl TapTweak for UntweakedKeyPair { impl TapTweak for UntweakedKeyPair {
@ -667,16 +634,18 @@ impl TapTweak for UntweakedKeyPair {
/// ///
/// # Returns /// # Returns
/// The tweaked key and its parity. /// The tweaked key and its parity.
fn tap_tweak<C: Verification>(self, secp: &Secp256k1<C>, merkle_root: Option<TapNodeHash>) -> TweakedKeyPair { fn tap_tweak<C: Verification>(
self,
secp: &Secp256k1<C>,
merkle_root: Option<TapNodeHash>,
) -> TweakedKeyPair {
let (pubkey, _parity) = XOnlyPublicKey::from_keypair(&self); let (pubkey, _parity) = XOnlyPublicKey::from_keypair(&self);
let tweak = TapTweakHash::from_key_and_tweak(pubkey, merkle_root).to_scalar(); let tweak = TapTweakHash::from_key_and_tweak(pubkey, merkle_root).to_scalar();
let tweaked = self.add_xonly_tweak(secp, &tweak).expect("Tap tweak failed"); let tweaked = self.add_xonly_tweak(secp, &tweak).expect("Tap tweak failed");
TweakedKeyPair(tweaked) TweakedKeyPair(tweaked)
} }
fn dangerous_assume_tweaked(self) -> TweakedKeyPair { fn dangerous_assume_tweaked(self) -> TweakedKeyPair { TweakedKeyPair(self) }
TweakedKeyPair(self)
}
} }
impl TweakedPublicKey { impl TweakedPublicKey {
@ -698,17 +667,13 @@ impl TweakedPublicKey {
} }
/// Returns the underlying public key. /// Returns the underlying public key.
pub fn to_inner(self) -> XOnlyPublicKey { pub fn to_inner(self) -> XOnlyPublicKey { self.0 }
self.0
}
/// Serialize the key as a byte-encoded pair of values. In compressed form /// Serialize the key as a byte-encoded pair of values. In compressed form
/// the y-coordinate is represented by only a single bit, as x determines /// the y-coordinate is represented by only a single bit, as x determines
/// it up to one bit. /// it up to one bit.
#[inline] #[inline]
pub fn serialize(&self) -> [u8; constants::SCHNORR_PUBLIC_KEY_SIZE] { pub fn serialize(&self) -> [u8; constants::SCHNORR_PUBLIC_KEY_SIZE] { self.0.serialize() }
self.0.serialize()
}
} }
impl TweakedKeyPair { impl TweakedKeyPair {
@ -718,15 +683,11 @@ impl TweakedKeyPair {
/// This method is dangerous and can lead to loss of funds if used incorrectly. /// This method is dangerous and can lead to loss of funds if used incorrectly.
/// Specifically, in multi-party protocols a peer can provide a value that allows them to steal. /// Specifically, in multi-party protocols a peer can provide a value that allows them to steal.
#[inline] #[inline]
pub fn dangerous_assume_tweaked(pair: KeyPair) -> TweakedKeyPair { pub fn dangerous_assume_tweaked(pair: KeyPair) -> TweakedKeyPair { TweakedKeyPair(pair) }
TweakedKeyPair(pair)
}
/// Returns the underlying key pair. /// Returns the underlying key pair.
#[inline] #[inline]
pub fn to_inner(self) -> KeyPair { pub fn to_inner(self) -> KeyPair { self.0 }
self.0
}
/// Returns the [`TweakedPublicKey`] and its [`Parity`] for this [`TweakedKeyPair`]. /// Returns the [`TweakedPublicKey`] and its [`Parity`] for this [`TweakedKeyPair`].
#[inline] #[inline]
@ -738,43 +699,36 @@ impl TweakedKeyPair {
impl From<TweakedPublicKey> for XOnlyPublicKey { impl From<TweakedPublicKey> for XOnlyPublicKey {
#[inline] #[inline]
fn from(pair: TweakedPublicKey) -> Self { fn from(pair: TweakedPublicKey) -> Self { pair.0 }
pair.0
}
} }
impl From<TweakedKeyPair> for KeyPair { impl From<TweakedKeyPair> for KeyPair {
#[inline] #[inline]
fn from(pair: TweakedKeyPair) -> Self { fn from(pair: TweakedKeyPair) -> Self { pair.0 }
pair.0
}
} }
impl From<TweakedKeyPair> for TweakedPublicKey { impl From<TweakedKeyPair> for TweakedPublicKey {
#[inline] #[inline]
fn from(pair: TweakedKeyPair) -> Self { fn from(pair: TweakedKeyPair) -> Self { TweakedPublicKey::from_keypair(pair) }
TweakedPublicKey::from_keypair(pair)
}
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*;
use std::str::FromStr; use std::str::FromStr;
use secp256k1::Secp256k1; use secp256k1::Secp256k1;
use super::*;
use crate::address::Address; use crate::address::Address;
use crate::hashes::hex::FromHex; use crate::hashes::hex::FromHex;
use crate::io; use crate::io;
use crate::network::constants::Network::Testnet; use crate::network::constants::Network::{Bitcoin, Testnet};
use crate::network::constants::Network::Bitcoin;
#[test] #[test]
fn test_key_derivation() { fn test_key_derivation() {
// testnet compressed // testnet compressed
let sk = PrivateKey::from_wif("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy").unwrap(); let sk =
PrivateKey::from_wif("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy").unwrap();
assert_eq!(sk.network, Testnet); assert_eq!(sk.network, Testnet);
assert!(sk.compressed); assert!(sk.compressed);
assert_eq!(&sk.to_wif(), "cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy"); assert_eq!(&sk.to_wif(), "cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy");
@ -790,7 +744,8 @@ mod tests {
assert_eq!(&sk.to_wif(), &sk_str.to_wif()); assert_eq!(&sk.to_wif(), &sk_str.to_wif());
// mainnet uncompressed // mainnet uncompressed
let sk = PrivateKey::from_wif("5JYkZjmN7PVMjJUfJWfRFwtuXTGB439XV6faajeHPAM9Z2PT2R3").unwrap(); let sk =
PrivateKey::from_wif("5JYkZjmN7PVMjJUfJWfRFwtuXTGB439XV6faajeHPAM9Z2PT2R3").unwrap();
assert_eq!(sk.network, Bitcoin); assert_eq!(sk.network, Bitcoin);
assert!(!sk.compressed); assert!(!sk.compressed);
assert_eq!(&sk.to_wif(), "5JYkZjmN7PVMjJUfJWfRFwtuXTGB439XV6faajeHPAM9Z2PT2R3"); assert_eq!(&sk.to_wif(), "5JYkZjmN7PVMjJUfJWfRFwtuXTGB439XV6faajeHPAM9Z2PT2R3");
@ -803,13 +758,25 @@ mod tests {
let addr = Address::p2pkh(&pk, sk.network); let addr = Address::p2pkh(&pk, sk.network);
assert_eq!(&addr.to_string(), "1GhQvF6dL8xa6wBxLnWmHcQsurx9RxiMc8"); assert_eq!(&addr.to_string(), "1GhQvF6dL8xa6wBxLnWmHcQsurx9RxiMc8");
pk.compressed = true; pk.compressed = true;
assert_eq!(&pk.to_string(), "032e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af"); assert_eq!(
assert_eq!(pk, PublicKey::from_str("032e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af").unwrap()); &pk.to_string(),
"032e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af"
);
assert_eq!(
pk,
PublicKey::from_str(
"032e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af"
)
.unwrap()
);
} }
#[test] #[test]
fn test_pubkey_hash() { fn test_pubkey_hash() {
let pk = PublicKey::from_str("032e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af").unwrap(); let pk = PublicKey::from_str(
"032e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af",
)
.unwrap();
let upk = PublicKey::from_str("042e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af191923a2964c177f5b5923ae500fca49e99492d534aa3759d6b25a8bc971b133").unwrap(); let upk = PublicKey::from_str("042e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af191923a2964c177f5b5923ae500fca49e99492d534aa3759d6b25a8bc971b133").unwrap();
assert_eq!(pk.pubkey_hash().to_string(), "9511aa27ef39bbfa4e4f3dd15f4d66ea57f475b4"); assert_eq!(pk.pubkey_hash().to_string(), "9511aa27ef39bbfa4e4f3dd15f4d66ea57f475b4");
assert_eq!(upk.pubkey_hash().to_string(), "ac2e7daf42d2c97418fd9f78af2de552bb9c6a7a"); assert_eq!(upk.pubkey_hash().to_string(), "ac2e7daf42d2c97418fd9f78af2de552bb9c6a7a");
@ -817,16 +784,22 @@ mod tests {
#[test] #[test]
fn test_wpubkey_hash() { fn test_wpubkey_hash() {
let pk = PublicKey::from_str("032e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af").unwrap(); let pk = PublicKey::from_str(
"032e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af",
)
.unwrap();
let upk = PublicKey::from_str("042e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af191923a2964c177f5b5923ae500fca49e99492d534aa3759d6b25a8bc971b133").unwrap(); let upk = PublicKey::from_str("042e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af191923a2964c177f5b5923ae500fca49e99492d534aa3759d6b25a8bc971b133").unwrap();
assert_eq!(pk.wpubkey_hash().unwrap().to_string(), "9511aa27ef39bbfa4e4f3dd15f4d66ea57f475b4"); assert_eq!(
pk.wpubkey_hash().unwrap().to_string(),
"9511aa27ef39bbfa4e4f3dd15f4d66ea57f475b4"
);
assert_eq!(upk.wpubkey_hash(), None); assert_eq!(upk.wpubkey_hash(), None);
} }
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
#[test] #[test]
fn test_key_serde() { fn test_key_serde() {
use serde_test::{Configure, Token, assert_tokens}; use serde_test::{assert_tokens, Configure, Token};
static KEY_WIF: &str = "cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy"; static KEY_WIF: &str = "cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy";
static PK_STR: &str = "039b6347398505f5ec93826dc61c19f47c66c0283ee9be980e29ce325a0f4679ef"; static PK_STR: &str = "039b6347398505f5ec93826dc61c19f47c66c0283ee9be980e29ce325a0f4679ef";
@ -859,10 +832,7 @@ mod tests {
let s = Secp256k1::new(); let s = Secp256k1::new();
let sk = PrivateKey::from_str(KEY_WIF).unwrap(); let sk = PrivateKey::from_str(KEY_WIF).unwrap();
let pk = PublicKey::from_private_key(&s, &sk); let pk = PublicKey::from_private_key(&s, &sk);
let pk_u = PublicKey { let pk_u = PublicKey { inner: pk.inner, compressed: false };
inner: pk.inner,
compressed: false,
};
assert_tokens(&sk, &[Token::BorrowedStr(KEY_WIF)]); assert_tokens(&sk, &[Token::BorrowedStr(KEY_WIF)]);
assert_tokens(&pk.compact(), &[Token::BorrowedBytes(&PK_BYTES[..])]); assert_tokens(&pk.compact(), &[Token::BorrowedBytes(&PK_BYTES[..])]);
@ -922,26 +892,29 @@ mod tests {
#[test] #[test]
fn pubkey_to_sort_key() { fn pubkey_to_sort_key() {
let key1 = PublicKey::from_str("02ff12471208c14bd580709cb2358d98975247d8765f92bc25eab3b2763ed605f8").unwrap(); let key1 = PublicKey::from_str(
let key2 = PublicKey { "02ff12471208c14bd580709cb2358d98975247d8765f92bc25eab3b2763ed605f8",
inner: key1.inner, )
compressed: false, .unwrap();
}; let key2 = PublicKey { inner: key1.inner, compressed: false };
let expected1 = SortKey( let expected1 = SortKey(
2, 2,
<[u8; 32]>::from_hex( <[u8; 32]>::from_hex(
"ff12471208c14bd580709cb2358d98975247d8765f92bc25eab3b2763ed605f8", "ff12471208c14bd580709cb2358d98975247d8765f92bc25eab3b2763ed605f8",
).unwrap(), )
.unwrap(),
[0_u8; 32], [0_u8; 32],
); );
let expected2 = SortKey( let expected2 = SortKey(
4, 4,
<[u8; 32]>::from_hex( <[u8; 32]>::from_hex(
"ff12471208c14bd580709cb2358d98975247d8765f92bc25eab3b2763ed605f8", "ff12471208c14bd580709cb2358d98975247d8765f92bc25eab3b2763ed605f8",
).unwrap(), )
.unwrap(),
<[u8; 32]>::from_hex( <[u8; 32]>::from_hex(
"1794e7f3d5e420641a3bc690067df5541470c966cbca8c694bf39aa16d836918", "1794e7f3d5e420641a3bc690067df5541470c966cbca8c694bf39aa16d836918",
).unwrap(), )
.unwrap(),
); );
assert_eq!(key1.to_sort_key(), expected1); assert_eq!(key1.to_sort_key(), expected1);
assert_eq!(key2.to_sort_key(), expected2); assert_eq!(key2.to_sort_key(), expected2);
@ -953,9 +926,8 @@ mod tests {
input: Vec<PublicKey>, input: Vec<PublicKey>,
expect: Vec<PublicKey>, expect: Vec<PublicKey>,
} }
let fmt = |v: Vec<_>| v.into_iter() let fmt =
.map(|s| PublicKey::from_str(s).unwrap()) |v: Vec<_>| v.into_iter().map(|s| PublicKey::from_str(s).unwrap()).collect::<Vec<_>>();
.collect::<Vec<_>>();
let vectors = vec![ let vectors = vec![
// Start BIP67 vectors // Start BIP67 vectors
// Vector 1 // Vector 1

View File

@ -14,14 +14,14 @@
use core::borrow::{Borrow, BorrowMut}; use core::borrow::{Borrow, BorrowMut};
use core::{fmt, str}; use core::{fmt, str};
use crate::{io, Script, ScriptBuf, Transaction, TxIn, TxOut, Sequence};
use crate::blockdata::transaction::EncodeSigningDataResult; use crate::blockdata::transaction::EncodeSigningDataResult;
use crate::blockdata::witness::Witness; use crate::blockdata::witness::Witness;
use crate::consensus::{encode, Encodable}; use crate::consensus::{encode, Encodable};
use crate::error::impl_std_error; use crate::error::impl_std_error;
use crate::hashes::{hash_newtype, sha256, sha256t_hash_newtype, sha256d, Hash}; use crate::hashes::{hash_newtype, sha256, sha256d, sha256t_hash_newtype, Hash};
use crate::prelude::*; use crate::prelude::*;
use crate::taproot::{LeafVersion, TapLeafHash, TAPROOT_ANNEX_PREFIX}; use crate::taproot::{LeafVersion, TapLeafHash, TAPROOT_ANNEX_PREFIX};
use crate::{io, Script, ScriptBuf, Sequence, Transaction, TxIn, TxOut};
/// Used for signature hash for invalid use of SIGHASH_SINGLE. /// Used for signature hash for invalid use of SIGHASH_SINGLE.
#[rustfmt::skip] #[rustfmt::skip]
@ -44,7 +44,7 @@ macro_rules! impl_thirty_two_byte_hash {
impl secp256k1::ThirtyTwoByteHash for $ty { impl secp256k1::ThirtyTwoByteHash for $ty {
fn into_32(self) -> [u8; 32] { self.to_byte_array() } fn into_32(self) -> [u8; 32] { self.to_byte_array() }
} }
} };
} }
hash_newtype! { hash_newtype! {
@ -60,10 +60,15 @@ hash_newtype! {
impl_thirty_two_byte_hash!(LegacySighash); impl_thirty_two_byte_hash!(LegacySighash);
impl_thirty_two_byte_hash!(SegwitV0Sighash); impl_thirty_two_byte_hash!(SegwitV0Sighash);
sha256t_hash_newtype!(TapSighash, TapSighashTag, MIDSTATE_TAPSIGHASH, 64, sha256t_hash_newtype!(
doc="Taproot-tagged hash with tag \"TapSighash\". TapSighash,
TapSighashTag,
MIDSTATE_TAPSIGHASH,
64,
doc = "Taproot-tagged hash with tag \"TapSighash\".
This hash type is used for computing taproot signature hash.", forward This hash type is used for computing taproot signature hash.",
forward
); );
impl_thirty_two_byte_hash!(TapSighash); impl_thirty_two_byte_hash!(TapSighash);
@ -559,14 +564,10 @@ impl<R: Borrow<Transaction>> SighashCache<R> {
} }
/// Returns the reference to the cached transaction. /// Returns the reference to the cached transaction.
pub fn transaction(&self) -> &Transaction { pub fn transaction(&self) -> &Transaction { self.tx.borrow() }
self.tx.borrow()
}
/// Destroys the cache and recovers the stored transaction. /// Destroys the cache and recovers the stored transaction.
pub fn into_transaction(self) -> R { pub fn into_transaction(self) -> R { self.tx }
self.tx
}
/// Encodes the BIP341 signing data for any flag type into a given object implementing a /// Encodes the BIP341 signing data for any flag type into a given object implementing a
/// [`io::Write`] trait. /// [`io::Write`] trait.
@ -633,10 +634,11 @@ impl<R: Borrow<Transaction>> SighashCache<R> {
// scriptPubKey (35): scriptPubKey of the previous output spent by this input, serialized as script inside CTxOut. Its size is always 35 bytes. // scriptPubKey (35): scriptPubKey of the previous output spent by this input, serialized as script inside CTxOut. Its size is always 35 bytes.
// nSequence (4): nSequence of this input. // nSequence (4): nSequence of this input.
if anyone_can_pay { if anyone_can_pay {
let txin = &self.tx.borrow().input.get(input_index).ok_or(Error::IndexOutOfInputsBounds { let txin =
index: input_index, &self.tx.borrow().input.get(input_index).ok_or(Error::IndexOutOfInputsBounds {
inputs_size: self.tx.borrow().input.len(), index: input_index,
})?; inputs_size: self.tx.borrow().input.len(),
})?;
let previous_output = prevouts.get(input_index)?; let previous_output = prevouts.get(input_index)?;
txin.previous_output.consensus_encode(&mut writer)?; txin.previous_output.consensus_encode(&mut writer)?;
previous_output.value.consensus_encode(&mut writer)?; previous_output.value.consensus_encode(&mut writer)?;
@ -782,10 +784,11 @@ impl<R: Borrow<Transaction>> SighashCache<R> {
} }
{ {
let txin = &self.tx.borrow().input.get(input_index).ok_or(Error::IndexOutOfInputsBounds { let txin =
index: input_index, &self.tx.borrow().input.get(input_index).ok_or(Error::IndexOutOfInputsBounds {
inputs_size: self.tx.borrow().input.len(), index: input_index,
})?; inputs_size: self.tx.borrow().input.len(),
})?;
txin.previous_output.consensus_encode(&mut writer)?; txin.previous_output.consensus_encode(&mut writer)?;
script_code.consensus_encode(&mut writer)?; script_code.consensus_encode(&mut writer)?;
@ -795,7 +798,8 @@ impl<R: Borrow<Transaction>> SighashCache<R> {
if sighash != EcdsaSighashType::Single && sighash != EcdsaSighashType::None { if sighash != EcdsaSighashType::Single && sighash != EcdsaSighashType::None {
self.segwit_cache().outputs.consensus_encode(&mut writer)?; self.segwit_cache().outputs.consensus_encode(&mut writer)?;
} else if sighash == EcdsaSighashType::Single && input_index < self.tx.borrow().output.len() { } else if sighash == EcdsaSighashType::Single && input_index < self.tx.borrow().output.len()
{
let mut single_enc = LegacySighash::engine(); let mut single_enc = LegacySighash::engine();
self.tx.borrow().output[input_index].consensus_encode(&mut single_enc)?; self.tx.borrow().output[input_index].consensus_encode(&mut single_enc)?;
let hash = LegacySighash::from_engine(single_enc); let hash = LegacySighash::from_engine(single_enc);
@ -865,7 +869,11 @@ impl<R: Borrow<Transaction>> SighashCache<R> {
} }
let sighash_type: u32 = sighash_type.into(); let sighash_type: u32 = sighash_type.into();
if is_invalid_use_of_sighash_single(sighash_type, input_index, self.tx.borrow().output.len()) { if is_invalid_use_of_sighash_single(
sighash_type,
input_index,
self.tx.borrow().output.len(),
) {
// We cannot correctly handle the SIGHASH_SINGLE bug here because usage of this function // We cannot correctly handle the SIGHASH_SINGLE bug here because usage of this function
// will result in the data written to the writer being hashed, however the correct // will result in the data written to the writer being hashed, however the correct
// handling of the SIGHASH_SINGLE bug is to return the 'one array' - either implement // handling of the SIGHASH_SINGLE bug is to return the 'one array' - either implement
@ -1197,8 +1205,7 @@ mod tests {
#[test] #[test]
fn test_tap_sighash_hash() { fn test_tap_sighash_hash() {
let bytes = hex!("00011b96877db45ffa23b307e9f0ac87b80ef9a80b4c5f0db3fbe734422453e83cc5576f3d542c5d4898fb2b696c15d43332534a7c1d1255fda38993545882df92c3e353ff6d36fbfadc4d168452afd8467f02fe53d71714fcea5dfe2ea759bd00185c4cb02bc76d42620393ca358a1a713f4997f9fc222911890afb3fe56c6a19b202df7bffdcfad08003821294279043746631b00e2dc5e52a111e213bbfe6ef09a19428d418dab0d50000000000"); let bytes = hex!("00011b96877db45ffa23b307e9f0ac87b80ef9a80b4c5f0db3fbe734422453e83cc5576f3d542c5d4898fb2b696c15d43332534a7c1d1255fda38993545882df92c3e353ff6d36fbfadc4d168452afd8467f02fe53d71714fcea5dfe2ea759bd00185c4cb02bc76d42620393ca358a1a713f4997f9fc222911890afb3fe56c6a19b202df7bffdcfad08003821294279043746631b00e2dc5e52a111e213bbfe6ef09a19428d418dab0d50000000000");
let expected = let expected = hex!("04e808aad07a40b3767a1442fead79af6ef7e7c9316d82dec409bb31e77699b0");
hex!("04e808aad07a40b3767a1442fead79af6ef7e7c9316d82dec409bb31e77699b0");
let mut enc = TapSighash::engine(); let mut enc = TapSighash::engine();
enc.input(&bytes); enc.input(&bytes);
let hash = TapSighash::from_engine(enc); let hash = TapSighash::from_engine(enc);
@ -1690,22 +1697,27 @@ mod tests {
let mut cache = SighashCache::new(&tx); let mut cache = SighashCache::new(&tx);
assert_eq!( assert_eq!(
cache.segwit_signature_hash(1, &witness_script, value, EcdsaSighashType::All).unwrap(), cache.segwit_signature_hash(1, &witness_script, value, EcdsaSighashType::All).unwrap(),
"c37af31116d1b27caf68aae9e3ac82f1477929014d5b917657d0eb49478cb670".parse::<SegwitV0Sighash>().unwrap(), "c37af31116d1b27caf68aae9e3ac82f1477929014d5b917657d0eb49478cb670"
.parse::<SegwitV0Sighash>()
.unwrap(),
); );
let cache = cache.segwit_cache(); let cache = cache.segwit_cache();
// Parse hex into Vec because BIP143 test vector displays forwards but our sha256d::Hash displays backwards. // Parse hex into Vec because BIP143 test vector displays forwards but our sha256d::Hash displays backwards.
assert_eq!( assert_eq!(
cache.prevouts.as_byte_array(), cache.prevouts.as_byte_array(),
&Vec::from_hex("96b827c8483d4e9b96712b6713a7b68d6e8003a781feba36c31143470b4efd37").unwrap()[..], &Vec::from_hex("96b827c8483d4e9b96712b6713a7b68d6e8003a781feba36c31143470b4efd37")
.unwrap()[..],
); );
assert_eq!( assert_eq!(
cache.sequences.as_byte_array(), cache.sequences.as_byte_array(),
&Vec::from_hex("52b0a642eea2fb7ae638c36f6252b6750293dbe574a806984b8e4d8548339a3b").unwrap()[..], &Vec::from_hex("52b0a642eea2fb7ae638c36f6252b6750293dbe574a806984b8e4d8548339a3b")
.unwrap()[..],
); );
assert_eq!( assert_eq!(
cache.outputs.as_byte_array(), cache.outputs.as_byte_array(),
&Vec::from_hex("863ef3e1a92afbfdb97f31ad0fc7683ee943e9abcf2501590ff8f6551f47e5e5").unwrap()[..], &Vec::from_hex("863ef3e1a92afbfdb97f31ad0fc7683ee943e9abcf2501590ff8f6551f47e5e5")
.unwrap()[..],
); );
} }
@ -1726,33 +1738,38 @@ mod tests {
let mut cache = SighashCache::new(&tx); let mut cache = SighashCache::new(&tx);
assert_eq!( assert_eq!(
cache.segwit_signature_hash(0, &witness_script, value, EcdsaSighashType::All).unwrap(), cache.segwit_signature_hash(0, &witness_script, value, EcdsaSighashType::All).unwrap(),
"64f3b0f4dd2bb3aa1ce8566d220cc74dda9df97d8490cc81d89d735c92e59fb6".parse::<SegwitV0Sighash>().unwrap(), "64f3b0f4dd2bb3aa1ce8566d220cc74dda9df97d8490cc81d89d735c92e59fb6"
.parse::<SegwitV0Sighash>()
.unwrap(),
); );
let cache = cache.segwit_cache(); let cache = cache.segwit_cache();
// Parse hex into Vec because BIP143 test vector displays forwards but our sha256d::Hash displays backwards. // Parse hex into Vec because BIP143 test vector displays forwards but our sha256d::Hash displays backwards.
assert_eq!( assert_eq!(
cache.prevouts.as_byte_array(), cache.prevouts.as_byte_array(),
&Vec::from_hex("b0287b4a252ac05af83d2dcef00ba313af78a3e9c329afa216eb3aa2a7b4613a").unwrap()[..], &Vec::from_hex("b0287b4a252ac05af83d2dcef00ba313af78a3e9c329afa216eb3aa2a7b4613a")
.unwrap()[..],
); );
assert_eq!( assert_eq!(
cache.sequences.as_byte_array(), cache.sequences.as_byte_array(),
&Vec::from_hex("18606b350cd8bf565266bc352f0caddcf01e8fa789dd8a15386327cf8cabe198").unwrap()[..], &Vec::from_hex("18606b350cd8bf565266bc352f0caddcf01e8fa789dd8a15386327cf8cabe198")
.unwrap()[..],
); );
assert_eq!( assert_eq!(
cache.outputs.as_byte_array(), cache.outputs.as_byte_array(),
&Vec::from_hex("de984f44532e2173ca0d64314fcefe6d30da6f8cf27bafa706da61df8a226c83").unwrap()[..], &Vec::from_hex("de984f44532e2173ca0d64314fcefe6d30da6f8cf27bafa706da61df8a226c83")
.unwrap()[..],
); );
} }
#[test] #[test]
fn bip143_p2wsh_nested_in_p2sh() { fn bip143_p2wsh_nested_in_p2sh() {
let tx = deserialize::<Transaction>( let tx = deserialize::<Transaction>(&hex!(
&hex!(
"010000000136641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e0100000000\ "010000000136641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e0100000000\
ffffffff0200e9a435000000001976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688acc0832f\ ffffffff0200e9a435000000001976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688acc0832f\
05000000001976a9147480a33f950689af511e6e84c138dbbd3c3ee41588ac00000000"), 05000000001976a9147480a33f950689af511e6e84c138dbbd3c3ee41588ac00000000"
).unwrap(); ))
.unwrap();
let witness_script = ScriptBuf::from_hex( let witness_script = ScriptBuf::from_hex(
"56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28\ "56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28\
@ -1760,29 +1777,35 @@ mod tests {
9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58\ 9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58\
c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b1486\ c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b1486\
2c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b\ 2c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b\
56ae" 56ae",
).unwrap(); )
.unwrap();
let value = 987654321; let value = 987654321;
let mut cache = SighashCache::new(&tx); let mut cache = SighashCache::new(&tx);
assert_eq!( assert_eq!(
cache.segwit_signature_hash(0, &witness_script, value, EcdsaSighashType::All).unwrap(), cache.segwit_signature_hash(0, &witness_script, value, EcdsaSighashType::All).unwrap(),
"185c0be5263dce5b4bb50a047973c1b6272bfbd0103a89444597dc40b248ee7c".parse::<SegwitV0Sighash>().unwrap(), "185c0be5263dce5b4bb50a047973c1b6272bfbd0103a89444597dc40b248ee7c"
.parse::<SegwitV0Sighash>()
.unwrap(),
); );
let cache = cache.segwit_cache(); let cache = cache.segwit_cache();
// Parse hex into Vec because BIP143 test vector displays forwards but our sha256d::Hash displays backwards. // Parse hex into Vec because BIP143 test vector displays forwards but our sha256d::Hash displays backwards.
assert_eq!( assert_eq!(
cache.prevouts.as_byte_array(), cache.prevouts.as_byte_array(),
&Vec::from_hex("74afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aaa0").unwrap()[..], &Vec::from_hex("74afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aaa0")
.unwrap()[..],
); );
assert_eq!( assert_eq!(
cache.sequences.as_byte_array(), cache.sequences.as_byte_array(),
&Vec::from_hex("3bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e70665044").unwrap()[..], &Vec::from_hex("3bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e70665044")
.unwrap()[..],
); );
assert_eq!( assert_eq!(
cache.outputs.as_byte_array(), cache.outputs.as_byte_array(),
&Vec::from_hex("bc4d309071414bed932f98832b27b4d76dad7e6c1346f487a8fdbb8eb90307cc").unwrap()[..], &Vec::from_hex("bc4d309071414bed932f98832b27b4d76dad7e6c1346f487a8fdbb8eb90307cc")
.unwrap()[..],
); );
} }
} }

View File

@ -9,11 +9,9 @@
use core::fmt; use core::fmt;
use bitcoin_internals::write_err; use bitcoin_internals::write_err;
pub use secp256k1::{self, constants, KeyPair, Parity, Secp256k1, Verification, XOnlyPublicKey};
pub use secp256k1::{self, constants, Secp256k1, KeyPair, XOnlyPublicKey, Verification, Parity};
use crate::prelude::*; use crate::prelude::*;
use crate::sighash::TapSighashType; use crate::sighash::TapSighashType;
/// A BIP340-341 serialized taproot signature with the corresponding hash type. /// A BIP340-341 serialized taproot signature with the corresponding hash type.
@ -33,21 +31,19 @@ impl Signature {
match sl.len() { match sl.len() {
64 => { 64 => {
// default type // default type
let sig = secp256k1::schnorr::Signature::from_slice(sl) let sig =
.map_err(Error::Secp256k1)?; secp256k1::schnorr::Signature::from_slice(sl).map_err(Error::Secp256k1)?;
Ok(Signature { sig, hash_ty: TapSighashType::Default }) Ok(Signature { sig, hash_ty: TapSighashType::Default })
}, }
65 => { 65 => {
let (hash_ty, sig) = sl.split_last().expect("Slice len checked == 65"); let (hash_ty, sig) = sl.split_last().expect("Slice len checked == 65");
let hash_ty = TapSighashType::from_consensus_u8(*hash_ty) let hash_ty = TapSighashType::from_consensus_u8(*hash_ty)
.map_err(|_| Error::InvalidSighashType(*hash_ty))?; .map_err(|_| Error::InvalidSighashType(*hash_ty))?;
let sig = secp256k1::schnorr::Signature::from_slice(sig) let sig =
.map_err(Error::Secp256k1)?; secp256k1::schnorr::Signature::from_slice(sig).map_err(Error::Secp256k1)?;
Ok(Signature { sig, hash_ty }) Ok(Signature { sig, hash_ty })
} }
len => { len => Err(Error::InvalidSignatureSize(len)),
Err(Error::InvalidSignatureSize(len))
}
} }
} }
@ -62,7 +58,6 @@ impl Signature {
} }
ser_sig ser_sig
} }
} }
/// A taproot sig related error. /// A taproot sig related error.
@ -77,7 +72,6 @@ pub enum Error {
InvalidSignatureSize(usize), InvalidSignatureSize(usize),
} }
impl fmt::Display for Error { impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self { match *self {
@ -85,8 +79,7 @@ impl fmt::Display for Error {
write!(f, "invalid signature hash type {}", hash_ty), write!(f, "invalid signature hash type {}", hash_ty),
Error::Secp256k1(ref e) => Error::Secp256k1(ref e) =>
write_err!(f, "taproot signature has correct len but is malformed"; e), write_err!(f, "taproot signature has correct len but is malformed"; e),
Error::InvalidSignatureSize(sz) => Error::InvalidSignatureSize(sz) => write!(f, "invalid taproot signature size: {}", sz),
write!(f, "invalid taproot signature size: {}", sz),
} }
} }
} }
@ -105,8 +98,5 @@ impl std::error::Error for Error {
} }
impl From<secp256k1::Error> for Error { impl From<secp256k1::Error> for Error {
fn from(e: secp256k1::Error) -> Error { Error::Secp256k1(e) }
fn from(e: secp256k1::Error) -> Error {
Error::Secp256k1(e)
}
} }