crypto: Run the formatter
Run `cargo +nightly fmt`, no other manual changes.
This commit is contained in:
parent
c8a3c58786
commit
3ec8a12428
|
@ -8,14 +8,14 @@
|
|||
use core::str::FromStr;
|
||||
use core::{fmt, iter};
|
||||
|
||||
use bitcoin_internals::write_err;
|
||||
use bitcoin_internals::hex::display::DisplayHex;
|
||||
use bitcoin_internals::write_err;
|
||||
use secp256k1;
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::hashes::hex::{self, FromHex};
|
||||
use crate::sighash::{EcdsaSighashType, NonStandardSighashType};
|
||||
use crate::prelude::*;
|
||||
use crate::script::PushBytes;
|
||||
use crate::sighash::{EcdsaSighashType, NonStandardSighashType};
|
||||
|
||||
const MAX_SIG_LEN: usize = 73;
|
||||
|
||||
|
@ -33,20 +33,15 @@ pub struct Signature {
|
|||
impl Signature {
|
||||
/// Constructs an ECDSA bitcoin signature for [`EcdsaSighashType::All`].
|
||||
pub fn sighash_all(sig: secp256k1::ecdsa::Signature) -> Signature {
|
||||
Signature {
|
||||
sig,
|
||||
hash_ty: EcdsaSighashType::All
|
||||
}
|
||||
Signature { sig, hash_ty: EcdsaSighashType::All }
|
||||
}
|
||||
|
||||
/// Deserializes from slice following the standardness rules for [`EcdsaSighashType`].
|
||||
pub fn from_slice(sl: &[u8]) -> Result<Self, Error> {
|
||||
let (hash_ty, sig) = sl.split_last()
|
||||
.ok_or(Error::EmptySignature)?;
|
||||
let (hash_ty, sig) = sl.split_last().ok_or(Error::EmptySignature)?;
|
||||
let hash_ty = EcdsaSighashType::from_standard(*hash_ty as u32)
|
||||
.map_err(|_| Error::NonStandardSighashType(*hash_ty as u32))?;
|
||||
let sig = secp256k1::ecdsa::Signature::from_der(sig)
|
||||
.map_err(Error::Secp256k1)?;
|
||||
let sig = secp256k1::ecdsa::Signature::from_der(sig).map_err(Error::Secp256k1)?;
|
||||
Ok(Signature { sig, hash_ty })
|
||||
}
|
||||
|
||||
|
@ -58,10 +53,7 @@ impl Signature {
|
|||
let signature = self.sig.serialize_der();
|
||||
buf[..signature.len()].copy_from_slice(&signature);
|
||||
buf[signature.len()] = self.hash_ty as u8;
|
||||
SerializedSignature {
|
||||
data: buf,
|
||||
len: signature.len() + 1,
|
||||
}
|
||||
SerializedSignature { data: buf, len: signature.len() + 1 }
|
||||
}
|
||||
|
||||
/// Serializes an ECDSA signature (inner secp256k1 signature in DER format) into `Vec`.
|
||||
|
@ -70,10 +62,7 @@ impl Signature {
|
|||
/// [`serialize`](Self::serialize) method instead.
|
||||
pub fn to_vec(self) -> Vec<u8> {
|
||||
// TODO: add support to serialize to a writer to SerializedSig
|
||||
self.sig.serialize_der()
|
||||
.iter().copied()
|
||||
.chain(iter::once(self.hash_ty as u8))
|
||||
.collect()
|
||||
self.sig.serialize_der().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> {
|
||||
let bytes = Vec::from_hex(s)?;
|
||||
let (sighash_byte, signature) = bytes.split_last()
|
||||
.ok_or(Error::EmptySignature)?;
|
||||
let (sighash_byte, signature) = bytes.split_last().ok_or(Error::EmptySignature)?;
|
||||
Ok(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 {
|
||||
/// Returns an iterator over bytes of the signature.
|
||||
#[inline]
|
||||
pub fn iter(&self) -> core::slice::Iter<'_, u8> {
|
||||
self.into_iter()
|
||||
}
|
||||
pub fn iter(&self) -> core::slice::Iter<'_, u8> { self.into_iter() }
|
||||
}
|
||||
|
||||
impl core::ops::Deref for SerializedSignature {
|
||||
type Target = [u8];
|
||||
|
||||
#[inline]
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.data[..self.len]
|
||||
}
|
||||
fn deref(&self) -> &Self::Target { &self.data[..self.len] }
|
||||
}
|
||||
|
||||
impl core::ops::DerefMut for SerializedSignature {
|
||||
#[inline]
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.data[..self.len]
|
||||
}
|
||||
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.data[..self.len] }
|
||||
}
|
||||
|
||||
impl AsRef<[u8]> for SerializedSignature {
|
||||
#[inline]
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
self
|
||||
}
|
||||
fn as_ref(&self) -> &[u8] { self }
|
||||
}
|
||||
|
||||
impl AsMut<[u8]> for SerializedSignature {
|
||||
#[inline]
|
||||
fn as_mut(&mut self) -> &mut [u8] {
|
||||
self
|
||||
}
|
||||
fn as_mut(&mut self) -> &mut [u8] { self }
|
||||
}
|
||||
|
||||
impl AsRef<PushBytes> for SerializedSignature {
|
||||
#[inline]
|
||||
fn as_ref(&self) -> &PushBytes {
|
||||
&<&PushBytes>::from(&self.data)[..self.len()]
|
||||
}
|
||||
fn as_ref(&self) -> &PushBytes { &<&PushBytes>::from(&self.data)[..self.len()] }
|
||||
}
|
||||
|
||||
impl core::borrow::Borrow<[u8]> for SerializedSignature {
|
||||
#[inline]
|
||||
fn borrow(&self) -> &[u8] {
|
||||
self
|
||||
}
|
||||
fn borrow(&self) -> &[u8] { self }
|
||||
}
|
||||
|
||||
impl core::borrow::BorrowMut<[u8]> for SerializedSignature {
|
||||
#[inline]
|
||||
fn borrow_mut(&mut self) -> &mut [u8] {
|
||||
self
|
||||
}
|
||||
fn borrow_mut(&mut self) -> &mut [u8] { self }
|
||||
}
|
||||
|
||||
impl fmt::Debug for SerializedSignature {
|
||||
|
@ -202,9 +174,7 @@ impl PartialEq for SerializedSignature {
|
|||
impl Eq for SerializedSignature {}
|
||||
|
||||
impl core::hash::Hash for SerializedSignature {
|
||||
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
||||
core::hash::Hash::hash(&**self, state)
|
||||
}
|
||||
fn hash<H: core::hash::Hasher>(&self, state: &mut H) { core::hash::Hash::hash(&**self, state) }
|
||||
}
|
||||
|
||||
impl<'a> IntoIterator for &'a SerializedSignature {
|
||||
|
@ -212,9 +182,7 @@ impl<'a> IntoIterator for &'a SerializedSignature {
|
|||
type Item = &'a u8;
|
||||
|
||||
#[inline]
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
(*self).iter()
|
||||
}
|
||||
fn into_iter(self) -> Self::IntoIter { (*self).iter() }
|
||||
}
|
||||
|
||||
/// A key-related error.
|
||||
|
@ -231,18 +199,14 @@ pub enum Error {
|
|||
Secp256k1(secp256k1::Error),
|
||||
}
|
||||
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Error::HexEncoding(ref e) =>
|
||||
write_err!(f, "Signature hex encoding error"; e),
|
||||
Error::HexEncoding(ref e) => write_err!(f, "Signature hex encoding error"; e),
|
||||
Error::NonStandardSighashType(hash_ty) =>
|
||||
write!(f, "Non standard signature hash type {}", hash_ty),
|
||||
Error::EmptySignature =>
|
||||
write!(f, "Empty ECDSA signature"),
|
||||
Error::Secp256k1(ref e) =>
|
||||
write_err!(f, "invalid ECDSA signature"; e),
|
||||
Error::EmptySignature => write!(f, "Empty ECDSA signature"),
|
||||
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 {
|
||||
fn from(e: secp256k1::Error) -> Error {
|
||||
Error::Secp256k1(e)
|
||||
}
|
||||
fn from(e: secp256k1::Error) -> Error { Error::Secp256k1(e) }
|
||||
}
|
||||
|
||||
impl From<NonStandardSighashType> for Error {
|
||||
fn from(err: NonStandardSighashType) -> Self {
|
||||
Error::NonStandardSighashType(err.0)
|
||||
}
|
||||
fn from(err: NonStandardSighashType) -> Self { Error::NonStandardSighashType(err.0) }
|
||||
}
|
||||
|
||||
impl From<hex::Error> for Error {
|
||||
fn from(err: hex::Error) -> Self {
|
||||
Error::HexEncoding(err)
|
||||
}
|
||||
fn from(err: hex::Error) -> Self { Error::HexEncoding(err) }
|
||||
}
|
||||
|
|
|
@ -6,20 +6,20 @@
|
|||
//! This module provides keys used in Bitcoin that can be roundtrip
|
||||
//! (de)serialized.
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
use core::{ops, str::FromStr};
|
||||
use core::fmt::{self, Write};
|
||||
use core::ops;
|
||||
use core::str::FromStr;
|
||||
|
||||
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::hashes::hex::FromHex;
|
||||
use crate::hashes::{hash160, hex, Hash};
|
||||
use crate::network::constants::Network;
|
||||
use crate::prelude::*;
|
||||
use crate::taproot::{TapNodeHash, TapTweakHash};
|
||||
use crate::{base58, io};
|
||||
|
||||
/// A key-related error.
|
||||
#[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::InvalidKeyPrefix(ref b) => write!(f, "key prefix invalid: {}", b),
|
||||
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,25 +67,18 @@ impl std::error::Error for Error {
|
|||
|
||||
#[doc(hidden)]
|
||||
impl From<base58::Error> for Error {
|
||||
fn from(e: base58::Error) -> Error {
|
||||
Error::Base58(e)
|
||||
}
|
||||
fn from(e: base58::Error) -> Error { Error::Base58(e) }
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
impl From<secp256k1::Error> for Error {
|
||||
fn from(e: secp256k1::Error) -> Error {
|
||||
Error::Secp256k1(e)
|
||||
}
|
||||
fn from(e: secp256k1::Error) -> Error { Error::Secp256k1(e) }
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
impl From<hex::Error> for Error {
|
||||
fn from(e: hex::Error) -> Self {
|
||||
Error::Hex(e)
|
||||
fn from(e: hex::Error) -> Self { Error::Hex(e) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// A Bitcoin ECDSA public key
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
|
@ -98,19 +92,13 @@ pub struct PublicKey {
|
|||
impl PublicKey {
|
||||
/// Constructs compressed ECDSA public key from the provided generic Secp256k1 public key
|
||||
pub fn new(key: impl Into<secp256k1::PublicKey>) -> PublicKey {
|
||||
PublicKey {
|
||||
compressed: true,
|
||||
inner: key.into(),
|
||||
}
|
||||
PublicKey { compressed: true, inner: key.into() }
|
||||
}
|
||||
|
||||
/// Constructs uncompressed (legacy) ECDSA public key from the provided generic Secp256k1
|
||||
/// public key
|
||||
pub fn new_uncompressed(key: impl Into<secp256k1::PublicKey>) -> PublicKey {
|
||||
PublicKey {
|
||||
compressed: false,
|
||||
inner: key.into(),
|
||||
}
|
||||
PublicKey { compressed: false, inner: key.into() }
|
||||
}
|
||||
|
||||
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
|
||||
pub fn pubkey_hash(&self) -> PubkeyHash {
|
||||
self.with_serialized(PubkeyHash::hash)
|
||||
}
|
||||
pub fn pubkey_hash(&self) -> PubkeyHash { self.with_serialized(PubkeyHash::hash) }
|
||||
|
||||
/// Returns bitcoin 160-bit hash of the public key for witness program
|
||||
pub fn wpubkey_hash(&self) -> Option<WPubkeyHash> {
|
||||
if self.compressed {
|
||||
Some(WPubkeyHash::from_byte_array(
|
||||
hash160::Hash::hash(&self.inner.serialize()).to_byte_array()
|
||||
hash160::Hash::hash(&self.inner.serialize()).to_byte_array(),
|
||||
))
|
||||
} else {
|
||||
// We can't create witness pubkey hashes for an uncompressed
|
||||
|
@ -251,24 +237,23 @@ impl PublicKey {
|
|||
65 => false,
|
||||
len => {
|
||||
return Err(base58::Error::InvalidLength(len).into());
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
if !compressed && data[0] != 0x04 {
|
||||
return Err(Error::InvalidKeyPrefix(data[0]))
|
||||
return Err(Error::InvalidKeyPrefix(data[0]));
|
||||
}
|
||||
|
||||
Ok(PublicKey {
|
||||
compressed,
|
||||
inner: secp256k1::PublicKey::from_slice(data)?,
|
||||
})
|
||||
Ok(PublicKey { compressed, inner: secp256k1::PublicKey::from_slice(data)? })
|
||||
}
|
||||
|
||||
/// 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)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// An opaque return type for PublicKey::to_sort_key
|
||||
|
@ -299,9 +284,7 @@ impl FromStr for PublicKey {
|
|||
}
|
||||
|
||||
impl From<PublicKey> for PubkeyHash {
|
||||
fn from(key: PublicKey) -> PubkeyHash {
|
||||
key.pubkey_hash()
|
||||
}
|
||||
fn from(key: PublicKey) -> PubkeyHash { key.pubkey_hash() }
|
||||
}
|
||||
|
||||
/// A Bitcoin ECDSA private key
|
||||
|
@ -320,35 +303,25 @@ impl PrivateKey {
|
|||
/// Constructs compressed ECDSA private key from the provided generic Secp256k1 private key
|
||||
/// and the specified network
|
||||
pub fn new(key: secp256k1::SecretKey, network: Network) -> PrivateKey {
|
||||
PrivateKey {
|
||||
compressed: true,
|
||||
network,
|
||||
inner: key,
|
||||
}
|
||||
PrivateKey { compressed: true, network, inner: key }
|
||||
}
|
||||
|
||||
/// Constructs uncompressed (legacy) ECDSA private key from the provided generic Secp256k1
|
||||
/// private key and the specified network
|
||||
pub fn new_uncompressed(key: secp256k1::SecretKey, network: Network) -> PrivateKey {
|
||||
PrivateKey {
|
||||
compressed: false,
|
||||
network,
|
||||
inner: key,
|
||||
}
|
||||
PrivateKey { compressed: false, network, inner: key }
|
||||
}
|
||||
|
||||
/// Creates a public key from this private key
|
||||
pub fn public_key<C: secp256k1::Signing>(&self, secp: &Secp256k1<C>) -> PublicKey {
|
||||
PublicKey {
|
||||
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
|
||||
pub fn to_bytes(self) -> Vec<u8> {
|
||||
self.inner[..].to_vec()
|
||||
}
|
||||
pub fn to_bytes(self) -> Vec<u8> { self.inner[..].to_vec() }
|
||||
|
||||
/// Deserialize a private key from a slice
|
||||
pub fn from_slice(data: &[u8], network: Network) -> Result<PrivateKey, Error> {
|
||||
|
@ -409,30 +382,22 @@ impl PrivateKey {
|
|||
}
|
||||
|
||||
impl fmt::Display for PrivateKey {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
self.fmt_wif(f)
|
||||
}
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.fmt_wif(f) }
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
impl fmt::Debug for PrivateKey {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "[private key data]")
|
||||
}
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "[private key data]") }
|
||||
}
|
||||
|
||||
impl FromStr for PrivateKey {
|
||||
type Err = Error;
|
||||
fn from_str(s: &str) -> Result<PrivateKey, Error> {
|
||||
PrivateKey::from_wif(s)
|
||||
}
|
||||
fn from_str(s: &str) -> Result<PrivateKey, Error> { PrivateKey::from_wif(s) }
|
||||
}
|
||||
|
||||
impl ops::Index<ops::RangeFull> for PrivateKey {
|
||||
type Output = [u8];
|
||||
fn index(&self, _: ops::RangeFull) -> &[u8] {
|
||||
&self.inner[..]
|
||||
}
|
||||
fn index(&self, _: ops::RangeFull) -> &[u8] { &self.inner[..] }
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
|
@ -559,15 +524,11 @@ pub type UntweakedPublicKey = XOnlyPublicKey;
|
|||
pub struct TweakedPublicKey(XOnlyPublicKey);
|
||||
|
||||
impl fmt::LowerHex for TweakedPublicKey {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::LowerHex::fmt(&self.0, f)
|
||||
}
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(&self.0, f) }
|
||||
}
|
||||
|
||||
impl fmt::Display for TweakedPublicKey {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt::Display::fmt(&self.0, f)
|
||||
}
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&self.0, f) }
|
||||
}
|
||||
|
||||
/// Untweaked BIP-340 key pair
|
||||
|
@ -613,7 +574,11 @@ pub trait TapTweak {
|
|||
///
|
||||
/// # Returns
|
||||
/// 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`]
|
||||
///
|
||||
|
@ -638,7 +603,11 @@ impl TapTweak for UntweakedPublicKey {
|
|||
///
|
||||
/// # Returns
|
||||
/// 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 (output_key, parity) = self.add_tweak(secp, &tweak).expect("Tap tweak failed");
|
||||
|
||||
|
@ -646,9 +615,7 @@ impl TapTweak for UntweakedPublicKey {
|
|||
(TweakedPublicKey(output_key), parity)
|
||||
}
|
||||
|
||||
fn dangerous_assume_tweaked(self) -> TweakedPublicKey {
|
||||
TweakedPublicKey(self)
|
||||
}
|
||||
fn dangerous_assume_tweaked(self) -> TweakedPublicKey { TweakedPublicKey(self) }
|
||||
}
|
||||
|
||||
impl TapTweak for UntweakedKeyPair {
|
||||
|
@ -667,16 +634,18 @@ impl TapTweak for UntweakedKeyPair {
|
|||
///
|
||||
/// # Returns
|
||||
/// 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 tweak = TapTweakHash::from_key_and_tweak(pubkey, merkle_root).to_scalar();
|
||||
let tweaked = self.add_xonly_tweak(secp, &tweak).expect("Tap tweak failed");
|
||||
TweakedKeyPair(tweaked)
|
||||
}
|
||||
|
||||
fn dangerous_assume_tweaked(self) -> TweakedKeyPair {
|
||||
TweakedKeyPair(self)
|
||||
}
|
||||
fn dangerous_assume_tweaked(self) -> TweakedKeyPair { TweakedKeyPair(self) }
|
||||
}
|
||||
|
||||
impl TweakedPublicKey {
|
||||
|
@ -698,17 +667,13 @@ impl TweakedPublicKey {
|
|||
}
|
||||
|
||||
/// Returns the underlying public key.
|
||||
pub fn to_inner(self) -> XOnlyPublicKey {
|
||||
self.0
|
||||
}
|
||||
pub fn to_inner(self) -> XOnlyPublicKey { self.0 }
|
||||
|
||||
/// 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
|
||||
/// it up to one bit.
|
||||
#[inline]
|
||||
pub fn serialize(&self) -> [u8; constants::SCHNORR_PUBLIC_KEY_SIZE] {
|
||||
self.0.serialize()
|
||||
}
|
||||
pub fn serialize(&self) -> [u8; constants::SCHNORR_PUBLIC_KEY_SIZE] { self.0.serialize() }
|
||||
}
|
||||
|
||||
impl TweakedKeyPair {
|
||||
|
@ -718,15 +683,11 @@ impl TweakedKeyPair {
|
|||
/// 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.
|
||||
#[inline]
|
||||
pub fn dangerous_assume_tweaked(pair: KeyPair) -> TweakedKeyPair {
|
||||
TweakedKeyPair(pair)
|
||||
}
|
||||
pub fn dangerous_assume_tweaked(pair: KeyPair) -> TweakedKeyPair { TweakedKeyPair(pair) }
|
||||
|
||||
/// Returns the underlying key pair.
|
||||
#[inline]
|
||||
pub fn to_inner(self) -> KeyPair {
|
||||
self.0
|
||||
}
|
||||
pub fn to_inner(self) -> KeyPair { self.0 }
|
||||
|
||||
/// Returns the [`TweakedPublicKey`] and its [`Parity`] for this [`TweakedKeyPair`].
|
||||
#[inline]
|
||||
|
@ -738,43 +699,36 @@ impl TweakedKeyPair {
|
|||
|
||||
impl From<TweakedPublicKey> for XOnlyPublicKey {
|
||||
#[inline]
|
||||
fn from(pair: TweakedPublicKey) -> Self {
|
||||
pair.0
|
||||
}
|
||||
fn from(pair: TweakedPublicKey) -> Self { pair.0 }
|
||||
}
|
||||
|
||||
impl From<TweakedKeyPair> for KeyPair {
|
||||
#[inline]
|
||||
fn from(pair: TweakedKeyPair) -> Self {
|
||||
pair.0
|
||||
}
|
||||
fn from(pair: TweakedKeyPair) -> Self { pair.0 }
|
||||
}
|
||||
|
||||
impl From<TweakedKeyPair> for TweakedPublicKey {
|
||||
#[inline]
|
||||
fn from(pair: TweakedKeyPair) -> Self {
|
||||
TweakedPublicKey::from_keypair(pair)
|
||||
}
|
||||
fn from(pair: TweakedKeyPair) -> Self { TweakedPublicKey::from_keypair(pair) }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use std::str::FromStr;
|
||||
|
||||
use secp256k1::Secp256k1;
|
||||
|
||||
use super::*;
|
||||
use crate::address::Address;
|
||||
use crate::hashes::hex::FromHex;
|
||||
use crate::io;
|
||||
use crate::network::constants::Network::Testnet;
|
||||
use crate::network::constants::Network::Bitcoin;
|
||||
use crate::network::constants::Network::{Bitcoin, Testnet};
|
||||
|
||||
#[test]
|
||||
fn test_key_derivation() {
|
||||
// testnet compressed
|
||||
let sk = PrivateKey::from_wif("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy").unwrap();
|
||||
let sk =
|
||||
PrivateKey::from_wif("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy").unwrap();
|
||||
assert_eq!(sk.network, Testnet);
|
||||
assert!(sk.compressed);
|
||||
assert_eq!(&sk.to_wif(), "cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy");
|
||||
|
@ -790,7 +744,8 @@ mod tests {
|
|||
assert_eq!(&sk.to_wif(), &sk_str.to_wif());
|
||||
|
||||
// mainnet uncompressed
|
||||
let sk = PrivateKey::from_wif("5JYkZjmN7PVMjJUfJWfRFwtuXTGB439XV6faajeHPAM9Z2PT2R3").unwrap();
|
||||
let sk =
|
||||
PrivateKey::from_wif("5JYkZjmN7PVMjJUfJWfRFwtuXTGB439XV6faajeHPAM9Z2PT2R3").unwrap();
|
||||
assert_eq!(sk.network, Bitcoin);
|
||||
assert!(!sk.compressed);
|
||||
assert_eq!(&sk.to_wif(), "5JYkZjmN7PVMjJUfJWfRFwtuXTGB439XV6faajeHPAM9Z2PT2R3");
|
||||
|
@ -803,13 +758,25 @@ mod tests {
|
|||
let addr = Address::p2pkh(&pk, sk.network);
|
||||
assert_eq!(&addr.to_string(), "1GhQvF6dL8xa6wBxLnWmHcQsurx9RxiMc8");
|
||||
pk.compressed = true;
|
||||
assert_eq!(&pk.to_string(), "032e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af");
|
||||
assert_eq!(pk, PublicKey::from_str("032e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af").unwrap());
|
||||
assert_eq!(
|
||||
&pk.to_string(),
|
||||
"032e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af"
|
||||
);
|
||||
assert_eq!(
|
||||
pk,
|
||||
PublicKey::from_str(
|
||||
"032e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af"
|
||||
)
|
||||
.unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
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();
|
||||
assert_eq!(pk.pubkey_hash().to_string(), "9511aa27ef39bbfa4e4f3dd15f4d66ea57f475b4");
|
||||
assert_eq!(upk.pubkey_hash().to_string(), "ac2e7daf42d2c97418fd9f78af2de552bb9c6a7a");
|
||||
|
@ -817,16 +784,22 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
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();
|
||||
assert_eq!(pk.wpubkey_hash().unwrap().to_string(), "9511aa27ef39bbfa4e4f3dd15f4d66ea57f475b4");
|
||||
assert_eq!(
|
||||
pk.wpubkey_hash().unwrap().to_string(),
|
||||
"9511aa27ef39bbfa4e4f3dd15f4d66ea57f475b4"
|
||||
);
|
||||
assert_eq!(upk.wpubkey_hash(), None);
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
#[test]
|
||||
fn test_key_serde() {
|
||||
use serde_test::{Configure, Token, assert_tokens};
|
||||
use serde_test::{assert_tokens, Configure, Token};
|
||||
|
||||
static KEY_WIF: &str = "cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy";
|
||||
static PK_STR: &str = "039b6347398505f5ec93826dc61c19f47c66c0283ee9be980e29ce325a0f4679ef";
|
||||
|
@ -859,10 +832,7 @@ mod tests {
|
|||
let s = Secp256k1::new();
|
||||
let sk = PrivateKey::from_str(KEY_WIF).unwrap();
|
||||
let pk = PublicKey::from_private_key(&s, &sk);
|
||||
let pk_u = PublicKey {
|
||||
inner: pk.inner,
|
||||
compressed: false,
|
||||
};
|
||||
let pk_u = PublicKey { inner: pk.inner, compressed: false };
|
||||
|
||||
assert_tokens(&sk, &[Token::BorrowedStr(KEY_WIF)]);
|
||||
assert_tokens(&pk.compact(), &[Token::BorrowedBytes(&PK_BYTES[..])]);
|
||||
|
@ -922,26 +892,29 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn pubkey_to_sort_key() {
|
||||
let key1 = PublicKey::from_str("02ff12471208c14bd580709cb2358d98975247d8765f92bc25eab3b2763ed605f8").unwrap();
|
||||
let key2 = PublicKey {
|
||||
inner: key1.inner,
|
||||
compressed: false,
|
||||
};
|
||||
let key1 = PublicKey::from_str(
|
||||
"02ff12471208c14bd580709cb2358d98975247d8765f92bc25eab3b2763ed605f8",
|
||||
)
|
||||
.unwrap();
|
||||
let key2 = PublicKey { inner: key1.inner, compressed: false };
|
||||
let expected1 = SortKey(
|
||||
2,
|
||||
<[u8; 32]>::from_hex(
|
||||
"ff12471208c14bd580709cb2358d98975247d8765f92bc25eab3b2763ed605f8",
|
||||
).unwrap(),
|
||||
)
|
||||
.unwrap(),
|
||||
[0_u8; 32],
|
||||
);
|
||||
let expected2 = SortKey(
|
||||
4,
|
||||
<[u8; 32]>::from_hex(
|
||||
"ff12471208c14bd580709cb2358d98975247d8765f92bc25eab3b2763ed605f8",
|
||||
).unwrap(),
|
||||
)
|
||||
.unwrap(),
|
||||
<[u8; 32]>::from_hex(
|
||||
"1794e7f3d5e420641a3bc690067df5541470c966cbca8c694bf39aa16d836918",
|
||||
).unwrap(),
|
||||
)
|
||||
.unwrap(),
|
||||
);
|
||||
assert_eq!(key1.to_sort_key(), expected1);
|
||||
assert_eq!(key2.to_sort_key(), expected2);
|
||||
|
@ -953,9 +926,8 @@ mod tests {
|
|||
input: Vec<PublicKey>,
|
||||
expect: Vec<PublicKey>,
|
||||
}
|
||||
let fmt = |v: Vec<_>| v.into_iter()
|
||||
.map(|s| PublicKey::from_str(s).unwrap())
|
||||
.collect::<Vec<_>>();
|
||||
let fmt =
|
||||
|v: Vec<_>| v.into_iter().map(|s| PublicKey::from_str(s).unwrap()).collect::<Vec<_>>();
|
||||
let vectors = vec![
|
||||
// Start BIP67 vectors
|
||||
// Vector 1
|
||||
|
|
|
@ -14,14 +14,14 @@
|
|||
use core::borrow::{Borrow, BorrowMut};
|
||||
use core::{fmt, str};
|
||||
|
||||
use crate::{io, Script, ScriptBuf, Transaction, TxIn, TxOut, Sequence};
|
||||
use crate::blockdata::transaction::EncodeSigningDataResult;
|
||||
use crate::blockdata::witness::Witness;
|
||||
use crate::consensus::{encode, Encodable};
|
||||
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::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.
|
||||
#[rustfmt::skip]
|
||||
|
@ -44,7 +44,7 @@ macro_rules! impl_thirty_two_byte_hash {
|
|||
impl secp256k1::ThirtyTwoByteHash for $ty {
|
||||
fn into_32(self) -> [u8; 32] { self.to_byte_array() }
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
hash_newtype! {
|
||||
|
@ -60,10 +60,15 @@ hash_newtype! {
|
|||
impl_thirty_two_byte_hash!(LegacySighash);
|
||||
impl_thirty_two_byte_hash!(SegwitV0Sighash);
|
||||
|
||||
sha256t_hash_newtype!(TapSighash, TapSighashTag, MIDSTATE_TAPSIGHASH, 64,
|
||||
sha256t_hash_newtype!(
|
||||
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);
|
||||
|
@ -559,14 +564,10 @@ impl<R: Borrow<Transaction>> SighashCache<R> {
|
|||
}
|
||||
|
||||
/// Returns the reference to the cached transaction.
|
||||
pub fn transaction(&self) -> &Transaction {
|
||||
self.tx.borrow()
|
||||
}
|
||||
pub fn transaction(&self) -> &Transaction { self.tx.borrow() }
|
||||
|
||||
/// Destroys the cache and recovers the stored transaction.
|
||||
pub fn into_transaction(self) -> R {
|
||||
self.tx
|
||||
}
|
||||
pub fn into_transaction(self) -> R { self.tx }
|
||||
|
||||
/// Encodes the BIP341 signing data for any flag type into a given object implementing a
|
||||
/// [`io::Write`] trait.
|
||||
|
@ -633,7 +634,8 @@ 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.
|
||||
// nSequence (4): nSequence of this input.
|
||||
if anyone_can_pay {
|
||||
let txin = &self.tx.borrow().input.get(input_index).ok_or(Error::IndexOutOfInputsBounds {
|
||||
let txin =
|
||||
&self.tx.borrow().input.get(input_index).ok_or(Error::IndexOutOfInputsBounds {
|
||||
index: input_index,
|
||||
inputs_size: self.tx.borrow().input.len(),
|
||||
})?;
|
||||
|
@ -782,7 +784,8 @@ impl<R: Borrow<Transaction>> SighashCache<R> {
|
|||
}
|
||||
|
||||
{
|
||||
let txin = &self.tx.borrow().input.get(input_index).ok_or(Error::IndexOutOfInputsBounds {
|
||||
let txin =
|
||||
&self.tx.borrow().input.get(input_index).ok_or(Error::IndexOutOfInputsBounds {
|
||||
index: input_index,
|
||||
inputs_size: self.tx.borrow().input.len(),
|
||||
})?;
|
||||
|
@ -795,7 +798,8 @@ impl<R: Borrow<Transaction>> SighashCache<R> {
|
|||
|
||||
if sighash != EcdsaSighashType::Single && sighash != EcdsaSighashType::None {
|
||||
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();
|
||||
self.tx.borrow().output[input_index].consensus_encode(&mut 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();
|
||||
|
||||
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
|
||||
// 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
|
||||
|
@ -1197,8 +1205,7 @@ mod tests {
|
|||
#[test]
|
||||
fn test_tap_sighash_hash() {
|
||||
let bytes = hex!("00011b96877db45ffa23b307e9f0ac87b80ef9a80b4c5f0db3fbe734422453e83cc5576f3d542c5d4898fb2b696c15d43332534a7c1d1255fda38993545882df92c3e353ff6d36fbfadc4d168452afd8467f02fe53d71714fcea5dfe2ea759bd00185c4cb02bc76d42620393ca358a1a713f4997f9fc222911890afb3fe56c6a19b202df7bffdcfad08003821294279043746631b00e2dc5e52a111e213bbfe6ef09a19428d418dab0d50000000000");
|
||||
let expected =
|
||||
hex!("04e808aad07a40b3767a1442fead79af6ef7e7c9316d82dec409bb31e77699b0");
|
||||
let expected = hex!("04e808aad07a40b3767a1442fead79af6ef7e7c9316d82dec409bb31e77699b0");
|
||||
let mut enc = TapSighash::engine();
|
||||
enc.input(&bytes);
|
||||
let hash = TapSighash::from_engine(enc);
|
||||
|
@ -1690,22 +1697,27 @@ mod tests {
|
|||
let mut cache = SighashCache::new(&tx);
|
||||
assert_eq!(
|
||||
cache.segwit_signature_hash(1, &witness_script, value, EcdsaSighashType::All).unwrap(),
|
||||
"c37af31116d1b27caf68aae9e3ac82f1477929014d5b917657d0eb49478cb670".parse::<SegwitV0Sighash>().unwrap(),
|
||||
"c37af31116d1b27caf68aae9e3ac82f1477929014d5b917657d0eb49478cb670"
|
||||
.parse::<SegwitV0Sighash>()
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
let cache = cache.segwit_cache();
|
||||
// Parse hex into Vec because BIP143 test vector displays forwards but our sha256d::Hash displays backwards.
|
||||
assert_eq!(
|
||||
cache.prevouts.as_byte_array(),
|
||||
&Vec::from_hex("96b827c8483d4e9b96712b6713a7b68d6e8003a781feba36c31143470b4efd37").unwrap()[..],
|
||||
&Vec::from_hex("96b827c8483d4e9b96712b6713a7b68d6e8003a781feba36c31143470b4efd37")
|
||||
.unwrap()[..],
|
||||
);
|
||||
assert_eq!(
|
||||
cache.sequences.as_byte_array(),
|
||||
&Vec::from_hex("52b0a642eea2fb7ae638c36f6252b6750293dbe574a806984b8e4d8548339a3b").unwrap()[..],
|
||||
&Vec::from_hex("52b0a642eea2fb7ae638c36f6252b6750293dbe574a806984b8e4d8548339a3b")
|
||||
.unwrap()[..],
|
||||
);
|
||||
assert_eq!(
|
||||
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);
|
||||
assert_eq!(
|
||||
cache.segwit_signature_hash(0, &witness_script, value, EcdsaSighashType::All).unwrap(),
|
||||
"64f3b0f4dd2bb3aa1ce8566d220cc74dda9df97d8490cc81d89d735c92e59fb6".parse::<SegwitV0Sighash>().unwrap(),
|
||||
"64f3b0f4dd2bb3aa1ce8566d220cc74dda9df97d8490cc81d89d735c92e59fb6"
|
||||
.parse::<SegwitV0Sighash>()
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
let cache = cache.segwit_cache();
|
||||
// Parse hex into Vec because BIP143 test vector displays forwards but our sha256d::Hash displays backwards.
|
||||
assert_eq!(
|
||||
cache.prevouts.as_byte_array(),
|
||||
&Vec::from_hex("b0287b4a252ac05af83d2dcef00ba313af78a3e9c329afa216eb3aa2a7b4613a").unwrap()[..],
|
||||
&Vec::from_hex("b0287b4a252ac05af83d2dcef00ba313af78a3e9c329afa216eb3aa2a7b4613a")
|
||||
.unwrap()[..],
|
||||
);
|
||||
assert_eq!(
|
||||
cache.sequences.as_byte_array(),
|
||||
&Vec::from_hex("18606b350cd8bf565266bc352f0caddcf01e8fa789dd8a15386327cf8cabe198").unwrap()[..],
|
||||
&Vec::from_hex("18606b350cd8bf565266bc352f0caddcf01e8fa789dd8a15386327cf8cabe198")
|
||||
.unwrap()[..],
|
||||
);
|
||||
assert_eq!(
|
||||
cache.outputs.as_byte_array(),
|
||||
&Vec::from_hex("de984f44532e2173ca0d64314fcefe6d30da6f8cf27bafa706da61df8a226c83").unwrap()[..],
|
||||
&Vec::from_hex("de984f44532e2173ca0d64314fcefe6d30da6f8cf27bafa706da61df8a226c83")
|
||||
.unwrap()[..],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bip143_p2wsh_nested_in_p2sh() {
|
||||
let tx = deserialize::<Transaction>(
|
||||
&hex!(
|
||||
let tx = deserialize::<Transaction>(&hex!(
|
||||
"010000000136641869ca081e70f394c6948e8af409e18b619df2ed74aa106c1ca29787b96e0100000000\
|
||||
ffffffff0200e9a435000000001976a914389ffce9cd9ae88dcc0631e88a821ffdbe9bfe2688acc0832f\
|
||||
05000000001976a9147480a33f950689af511e6e84c138dbbd3c3ee41588ac00000000"),
|
||||
).unwrap();
|
||||
05000000001976a9147480a33f950689af511e6e84c138dbbd3c3ee41588ac00000000"
|
||||
))
|
||||
.unwrap();
|
||||
|
||||
let witness_script = ScriptBuf::from_hex(
|
||||
"56210307b8ae49ac90a048e9b53357a2354b3334e9c8bee813ecb98e99a7e07e8c3ba32103b28f0c28\
|
||||
|
@ -1760,29 +1777,35 @@ mod tests {
|
|||
9781957b8c0ac1dfe69f492580ca4195f50376ba4a21033400f6afecb833092a9a21cfdf1ed1376e58\
|
||||
c5d1f47de74683123987e967a8f42103a6d48b1131e94ba04d9737d61acdaa1322008af9602b3b1486\
|
||||
2c07a1789aac162102d8b661b0b3302ee2f162b09e07a55ad5dfbe673a9f01d9f0c19617681024306b\
|
||||
56ae"
|
||||
).unwrap();
|
||||
56ae",
|
||||
)
|
||||
.unwrap();
|
||||
let value = 987654321;
|
||||
|
||||
let mut cache = SighashCache::new(&tx);
|
||||
assert_eq!(
|
||||
cache.segwit_signature_hash(0, &witness_script, value, EcdsaSighashType::All).unwrap(),
|
||||
"185c0be5263dce5b4bb50a047973c1b6272bfbd0103a89444597dc40b248ee7c".parse::<SegwitV0Sighash>().unwrap(),
|
||||
"185c0be5263dce5b4bb50a047973c1b6272bfbd0103a89444597dc40b248ee7c"
|
||||
.parse::<SegwitV0Sighash>()
|
||||
.unwrap(),
|
||||
);
|
||||
|
||||
let cache = cache.segwit_cache();
|
||||
// Parse hex into Vec because BIP143 test vector displays forwards but our sha256d::Hash displays backwards.
|
||||
assert_eq!(
|
||||
cache.prevouts.as_byte_array(),
|
||||
&Vec::from_hex("74afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aaa0").unwrap()[..],
|
||||
&Vec::from_hex("74afdc312af5183c4198a40ca3c1a275b485496dd3929bca388c4b5e31f7aaa0")
|
||||
.unwrap()[..],
|
||||
);
|
||||
assert_eq!(
|
||||
cache.sequences.as_byte_array(),
|
||||
&Vec::from_hex("3bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e70665044").unwrap()[..],
|
||||
&Vec::from_hex("3bb13029ce7b1f559ef5e747fcac439f1455a2ec7c5f09b72290795e70665044")
|
||||
.unwrap()[..],
|
||||
);
|
||||
assert_eq!(
|
||||
cache.outputs.as_byte_array(),
|
||||
&Vec::from_hex("bc4d309071414bed932f98832b27b4d76dad7e6c1346f487a8fdbb8eb90307cc").unwrap()[..],
|
||||
&Vec::from_hex("bc4d309071414bed932f98832b27b4d76dad7e6c1346f487a8fdbb8eb90307cc")
|
||||
.unwrap()[..],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,11 +9,9 @@
|
|||
use core::fmt;
|
||||
|
||||
use bitcoin_internals::write_err;
|
||||
|
||||
pub use secp256k1::{self, constants, Secp256k1, KeyPair, XOnlyPublicKey, Verification, Parity};
|
||||
pub use secp256k1::{self, constants, KeyPair, Parity, Secp256k1, Verification, XOnlyPublicKey};
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
use crate::sighash::TapSighashType;
|
||||
|
||||
/// A BIP340-341 serialized taproot signature with the corresponding hash type.
|
||||
|
@ -33,21 +31,19 @@ impl Signature {
|
|||
match sl.len() {
|
||||
64 => {
|
||||
// default type
|
||||
let sig = secp256k1::schnorr::Signature::from_slice(sl)
|
||||
.map_err(Error::Secp256k1)?;
|
||||
let sig =
|
||||
secp256k1::schnorr::Signature::from_slice(sl).map_err(Error::Secp256k1)?;
|
||||
Ok(Signature { sig, hash_ty: TapSighashType::Default })
|
||||
},
|
||||
}
|
||||
65 => {
|
||||
let (hash_ty, sig) = sl.split_last().expect("Slice len checked == 65");
|
||||
let hash_ty = TapSighashType::from_consensus_u8(*hash_ty)
|
||||
.map_err(|_| Error::InvalidSighashType(*hash_ty))?;
|
||||
let sig = secp256k1::schnorr::Signature::from_slice(sig)
|
||||
.map_err(Error::Secp256k1)?;
|
||||
let sig =
|
||||
secp256k1::schnorr::Signature::from_slice(sig).map_err(Error::Secp256k1)?;
|
||||
Ok(Signature { sig, hash_ty })
|
||||
}
|
||||
len => {
|
||||
Err(Error::InvalidSignatureSize(len))
|
||||
}
|
||||
len => Err(Error::InvalidSignatureSize(len)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,7 +58,6 @@ impl Signature {
|
|||
}
|
||||
ser_sig
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// A taproot sig related error.
|
||||
|
@ -77,7 +72,6 @@ pub enum Error {
|
|||
InvalidSignatureSize(usize),
|
||||
}
|
||||
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
|
@ -85,8 +79,7 @@ impl fmt::Display for Error {
|
|||
write!(f, "invalid signature hash type {}", hash_ty),
|
||||
Error::Secp256k1(ref e) =>
|
||||
write_err!(f, "taproot signature has correct len but is malformed"; e),
|
||||
Error::InvalidSignatureSize(sz) =>
|
||||
write!(f, "invalid taproot signature size: {}", sz),
|
||||
Error::InvalidSignatureSize(sz) => write!(f, "invalid taproot signature size: {}", sz),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -105,8 +98,5 @@ impl std::error::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) }
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue