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::{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) }
}

View File

@ -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,26 +67,19 @@ 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)]
pub struct PublicKey {
@ -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
@ -249,26 +235,25 @@ impl PublicKey {
let compressed = match data.len() {
33 => true,
65 => false,
len => {
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> {
@ -395,7 +368,7 @@ impl PrivateKey {
let network = match data[0] {
128 => Network::Bitcoin,
239 => Network::Testnet,
x => {
x => {
return Err(Error::Base58(base58::Error::InvalidAddressVersion(x)));
}
};
@ -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

View File

@ -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,
doc="Taproot-tagged hash with tag \"TapSighash\".
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,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.
// nSequence (4): nSequence of this input.
if anyone_can_pay {
let txin = &self.tx.borrow().input.get(input_index).ok_or(Error::IndexOutOfInputsBounds {
index: input_index,
inputs_size: self.tx.borrow().input.len(),
})?;
let txin =
&self.tx.borrow().input.get(input_index).ok_or(Error::IndexOutOfInputsBounds {
index: input_index,
inputs_size: self.tx.borrow().input.len(),
})?;
let previous_output = prevouts.get(input_index)?;
txin.previous_output.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 {
index: input_index,
inputs_size: self.tx.borrow().input.len(),
})?;
let txin =
&self.tx.borrow().input.get(input_index).ok_or(Error::IndexOutOfInputsBounds {
index: input_index,
inputs_size: self.tx.borrow().input.len(),
})?;
txin.previous_output.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 {
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()[..],
);
}
}

View File

@ -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) }
}