Re-org keys and ecdsa mods - pt.1
This commit tries to achieve separation of signature- and key-related types, previously mixed in a single ECDSA module. Rationale: bitcoin key types are not specific for signature algorithm. This is achieved through - Remove key mod with its content moved to ecdsa mod - Re-export keys under key module in util mod - to make git generate diff for the rename of ecdsa mod in the next commit correctly.
This commit is contained in:
parent
2d9de78725
commit
b9170162d5
|
@ -39,7 +39,7 @@ use policy::DUST_RELAY_TX_FEE;
|
||||||
#[cfg(feature="bitcoinconsensus")] use core::convert::From;
|
#[cfg(feature="bitcoinconsensus")] use core::convert::From;
|
||||||
#[cfg(feature="bitcoinconsensus")] use OutPoint;
|
#[cfg(feature="bitcoinconsensus")] use OutPoint;
|
||||||
|
|
||||||
use util::ecdsa::PublicKey;
|
use util::key::PublicKey;
|
||||||
use util::address::WitnessVersion;
|
use util::address::WitnessVersion;
|
||||||
use util::taproot::{LeafVersion, TapBranchHash, TapLeafHash};
|
use util::taproot::{LeafVersion, TapBranchHash, TapLeafHash};
|
||||||
use secp256k1::{Secp256k1, Verification};
|
use secp256k1::{Secp256k1, Verification};
|
||||||
|
@ -1031,7 +1031,7 @@ mod test {
|
||||||
use hashes::hex::{FromHex, ToHex};
|
use hashes::hex::{FromHex, ToHex};
|
||||||
use consensus::encode::{deserialize, serialize};
|
use consensus::encode::{deserialize, serialize};
|
||||||
use blockdata::opcodes;
|
use blockdata::opcodes;
|
||||||
use util::ecdsa::PublicKey;
|
use util::key::PublicKey;
|
||||||
use util::psbt::serialize::Serialize;
|
use util::psbt::serialize::Serialize;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -20,13 +20,13 @@
|
||||||
//! ```rust
|
//! ```rust
|
||||||
//! use bitcoin::network::constants::Network;
|
//! use bitcoin::network::constants::Network;
|
||||||
//! use bitcoin::util::address::Address;
|
//! use bitcoin::util::address::Address;
|
||||||
//! use bitcoin::util::ecdsa;
|
//! use bitcoin::PublicKey;
|
||||||
//! use bitcoin::secp256k1::Secp256k1;
|
//! use bitcoin::secp256k1::Secp256k1;
|
||||||
//! use bitcoin::secp256k1::rand::thread_rng;
|
//! use bitcoin::secp256k1::rand::thread_rng;
|
||||||
//!
|
//!
|
||||||
//! // Generate random key pair.
|
//! // Generate random key pair.
|
||||||
//! let s = Secp256k1::new();
|
//! let s = Secp256k1::new();
|
||||||
//! let public_key = ecdsa::PublicKey::new(s.generate_keypair(&mut thread_rng()).1);
|
//! let public_key = PublicKey::new(s.generate_keypair(&mut thread_rng()).1);
|
||||||
//!
|
//!
|
||||||
//! // Generate pay-to-pubkey-hash address.
|
//! // Generate pay-to-pubkey-hash address.
|
||||||
//! let address = Address::p2pkh(&public_key, Network::Bitcoin);
|
//! let address = Address::p2pkh(&public_key, Network::Bitcoin);
|
||||||
|
@ -47,8 +47,8 @@ use blockdata::{script, opcodes};
|
||||||
use blockdata::constants::{PUBKEY_ADDRESS_PREFIX_MAIN, SCRIPT_ADDRESS_PREFIX_MAIN, PUBKEY_ADDRESS_PREFIX_TEST, SCRIPT_ADDRESS_PREFIX_TEST, MAX_SCRIPT_ELEMENT_SIZE};
|
use blockdata::constants::{PUBKEY_ADDRESS_PREFIX_MAIN, SCRIPT_ADDRESS_PREFIX_MAIN, PUBKEY_ADDRESS_PREFIX_TEST, SCRIPT_ADDRESS_PREFIX_TEST, MAX_SCRIPT_ELEMENT_SIZE};
|
||||||
use network::constants::Network;
|
use network::constants::Network;
|
||||||
use util::base58;
|
use util::base58;
|
||||||
use util::ecdsa;
|
|
||||||
use util::taproot::TapBranchHash;
|
use util::taproot::TapBranchHash;
|
||||||
|
use util::key::PublicKey;
|
||||||
use blockdata::script::Instruction;
|
use blockdata::script::Instruction;
|
||||||
use util::schnorr::{TapTweak, UntweakedPublicKey, TweakedPublicKey};
|
use util::schnorr::{TapTweak, UntweakedPublicKey, TweakedPublicKey};
|
||||||
|
|
||||||
|
@ -408,7 +408,7 @@ impl Payload {
|
||||||
|
|
||||||
/// Creates a pay to (compressed) public key hash payload from a public key
|
/// Creates a pay to (compressed) public key hash payload from a public key
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn p2pkh(pk: &ecdsa::PublicKey) -> Payload {
|
pub fn p2pkh(pk: &PublicKey) -> Payload {
|
||||||
Payload::PubkeyHash(pk.pubkey_hash())
|
Payload::PubkeyHash(pk.pubkey_hash())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -422,7 +422,7 @@ impl Payload {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a witness pay to public key payload from a public key
|
/// Create a witness pay to public key payload from a public key
|
||||||
pub fn p2wpkh(pk: &ecdsa::PublicKey) -> Result<Payload, Error> {
|
pub fn p2wpkh(pk: &PublicKey) -> Result<Payload, Error> {
|
||||||
Ok(Payload::WitnessProgram {
|
Ok(Payload::WitnessProgram {
|
||||||
version: WitnessVersion::V0,
|
version: WitnessVersion::V0,
|
||||||
program: pk.wpubkey_hash().ok_or(Error::UncompressedPubkey)?.to_vec(),
|
program: pk.wpubkey_hash().ok_or(Error::UncompressedPubkey)?.to_vec(),
|
||||||
|
@ -430,7 +430,7 @@ impl Payload {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a pay to script payload that embeds a witness pay to public key
|
/// Create a pay to script payload that embeds a witness pay to public key
|
||||||
pub fn p2shwpkh(pk: &ecdsa::PublicKey) -> Result<Payload, Error> {
|
pub fn p2shwpkh(pk: &PublicKey) -> Result<Payload, Error> {
|
||||||
let builder = script::Builder::new()
|
let builder = script::Builder::new()
|
||||||
.push_int(0)
|
.push_int(0)
|
||||||
.push_slice(&pk.wpubkey_hash().ok_or(Error::UncompressedPubkey)?);
|
.push_slice(&pk.wpubkey_hash().ok_or(Error::UncompressedPubkey)?);
|
||||||
|
@ -543,7 +543,7 @@ impl Address {
|
||||||
///
|
///
|
||||||
/// This is the preferred non-witness type address.
|
/// This is the preferred non-witness type address.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn p2pkh(pk: &ecdsa::PublicKey, network: Network) -> Address {
|
pub fn p2pkh(pk: &PublicKey, network: Network) -> Address {
|
||||||
Address {
|
Address {
|
||||||
network,
|
network,
|
||||||
payload: Payload::p2pkh(pk),
|
payload: Payload::p2pkh(pk),
|
||||||
|
@ -568,7 +568,7 @@ impl Address {
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// Will only return an error if an uncompressed public key is provided.
|
/// Will only return an error if an uncompressed public key is provided.
|
||||||
pub fn p2wpkh(pk: &ecdsa::PublicKey, network: Network) -> Result<Address, Error> {
|
pub fn p2wpkh(pk: &PublicKey, network: Network) -> Result<Address, Error> {
|
||||||
Ok(Address {
|
Ok(Address {
|
||||||
network,
|
network,
|
||||||
payload: Payload::p2wpkh(pk)?,
|
payload: Payload::p2wpkh(pk)?,
|
||||||
|
@ -581,7 +581,7 @@ impl Address {
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// Will only return an Error if an uncompressed public key is provided.
|
/// Will only return an Error if an uncompressed public key is provided.
|
||||||
pub fn p2shwpkh(pk: &ecdsa::PublicKey, network: Network) -> Result<Address, Error> {
|
pub fn p2shwpkh(pk: &PublicKey, network: Network) -> Result<Address, Error> {
|
||||||
Ok(Address {
|
Ok(Address {
|
||||||
network,
|
network,
|
||||||
payload: Payload::p2shwpkh(pk)?,
|
payload: Payload::p2shwpkh(pk)?,
|
||||||
|
@ -878,7 +878,7 @@ mod tests {
|
||||||
|
|
||||||
use blockdata::script::Script;
|
use blockdata::script::Script;
|
||||||
use network::constants::Network::{Bitcoin, Testnet};
|
use network::constants::Network::{Bitcoin, Testnet};
|
||||||
use util::ecdsa::PublicKey;
|
use util::key::PublicKey;
|
||||||
use secp256k1::XOnlyPublicKey;
|
use secp256k1::XOnlyPublicKey;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -194,7 +194,7 @@ mod tests {
|
||||||
use consensus::encode::deserialize;
|
use consensus::encode::deserialize;
|
||||||
use network::constants::Network;
|
use network::constants::Network;
|
||||||
use util::address::Address;
|
use util::address::Address;
|
||||||
use util::ecdsa::PublicKey;
|
use util::key::PublicKey;
|
||||||
use hashes::hex::FromHex;
|
use hashes::hex::FromHex;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
use prelude::*;
|
use prelude::*;
|
||||||
|
|
||||||
|
use io::Write;
|
||||||
use core::{fmt, str::FromStr, default::Default};
|
use core::{fmt, str::FromStr, default::Default};
|
||||||
#[cfg(feature = "std")] use std::error;
|
#[cfg(feature = "std")] use std::error;
|
||||||
#[cfg(feature = "serde")] use serde;
|
#[cfg(feature = "serde")] use serde;
|
||||||
|
@ -28,9 +29,8 @@ use hashes::{sha512, Hash, HashEngine, Hmac, HmacEngine};
|
||||||
use secp256k1::{self, Secp256k1, XOnlyPublicKey};
|
use secp256k1::{self, Secp256k1, XOnlyPublicKey};
|
||||||
|
|
||||||
use network::constants::Network;
|
use network::constants::Network;
|
||||||
use util::{base58, endian};
|
use util::{base58, endian, key};
|
||||||
use util::{key, ecdsa, schnorr};
|
use util::key::{PublicKey, PrivateKey, KeyPair};
|
||||||
use io::Write;
|
|
||||||
|
|
||||||
/// A chain code
|
/// A chain code
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
@ -528,8 +528,8 @@ impl ExtendedPrivKey {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs ECDSA compressed private key matching internal secret key representation.
|
/// Constructs ECDSA compressed private key matching internal secret key representation.
|
||||||
pub fn to_priv(&self) -> ecdsa::PrivateKey {
|
pub fn to_priv(&self) -> PrivateKey {
|
||||||
ecdsa::PrivateKey {
|
PrivateKey {
|
||||||
compressed: true,
|
compressed: true,
|
||||||
network: self.network,
|
network: self.network,
|
||||||
inner: self.private_key
|
inner: self.private_key
|
||||||
|
@ -538,8 +538,8 @@ impl ExtendedPrivKey {
|
||||||
|
|
||||||
/// Constructs BIP340 keypair for Schnorr signatures and Taproot use matching the internal
|
/// Constructs BIP340 keypair for Schnorr signatures and Taproot use matching the internal
|
||||||
/// secret key representation.
|
/// secret key representation.
|
||||||
pub fn to_keypair<C: secp256k1::Signing>(&self, secp: &Secp256k1<C>) -> schnorr::KeyPair {
|
pub fn to_keypair<C: secp256k1::Signing>(&self, secp: &Secp256k1<C>) -> KeyPair {
|
||||||
schnorr::KeyPair::from_seckey_slice(secp, &self.private_key[..]).expect("BIP32 internal private key representation is broken")
|
KeyPair::from_seckey_slice(secp, &self.private_key[..]).expect("BIP32 internal private key representation is broken")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempts to derive an extended private key from a path.
|
/// Attempts to derive an extended private key from a path.
|
||||||
|
@ -660,8 +660,8 @@ impl ExtendedPubKey {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs ECDSA compressed public key matching internal public key representation.
|
/// Constructs ECDSA compressed public key matching internal public key representation.
|
||||||
pub fn to_pub(&self) -> ecdsa::PublicKey {
|
pub fn to_pub(&self) -> PublicKey {
|
||||||
ecdsa::PublicKey {
|
PublicKey {
|
||||||
compressed: true,
|
compressed: true,
|
||||||
inner: self.public_key
|
inner: self.public_key
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,13 +15,15 @@
|
||||||
//!
|
//!
|
||||||
//! This module provides ECDSA keys used in Bitcoin that can be roundtrip
|
//! This module provides ECDSA keys used in Bitcoin that can be roundtrip
|
||||||
//! (de)serialized.
|
//! (de)serialized.
|
||||||
//!
|
|
||||||
|
pub use secp256k1::{XOnlyPublicKey, KeyPair};
|
||||||
|
|
||||||
use prelude::*;
|
use prelude::*;
|
||||||
|
|
||||||
use core::{ops, str::FromStr};
|
use core::{ops, str::FromStr};
|
||||||
use core::fmt::{self, Write as _fmtWrite};
|
use core::fmt::{self, Write as _fmtWrite};
|
||||||
use io;
|
use io;
|
||||||
|
#[cfg(feature = "std")] use std::error;
|
||||||
|
|
||||||
use secp256k1::{self, Secp256k1};
|
use secp256k1::{self, Secp256k1};
|
||||||
use network::constants::Network;
|
use network::constants::Network;
|
||||||
|
@ -29,10 +31,54 @@ use hashes::{Hash, hash160, hex};
|
||||||
use hashes::hex::FromHex;
|
use hashes::hex::FromHex;
|
||||||
use hash_types::{PubkeyHash, WPubkeyHash};
|
use hash_types::{PubkeyHash, WPubkeyHash};
|
||||||
use util::base58;
|
use util::base58;
|
||||||
use util::key::Error;
|
|
||||||
use blockdata::transaction::{EcdsaSigHashType, NonStandardSigHashType};
|
use blockdata::transaction::{EcdsaSigHashType, NonStandardSigHashType};
|
||||||
|
|
||||||
|
|
||||||
|
/// A key-related error.
|
||||||
|
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
/// Base58 encoding error
|
||||||
|
Base58(base58::Error),
|
||||||
|
/// secp256k1-related error
|
||||||
|
Secp256k1(secp256k1::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl fmt::Display for Error {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match *self {
|
||||||
|
Error::Base58(ref e) => write!(f, "Key base58 error: {}", e),
|
||||||
|
Error::Secp256k1(ref e) => write!(f, "Key secp256k1 error: {}", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
||||||
|
impl ::std::error::Error for Error {
|
||||||
|
fn cause(&self) -> Option<&dyn error::Error> {
|
||||||
|
match *self {
|
||||||
|
Error::Base58(ref e) => Some(e),
|
||||||
|
Error::Secp256k1(ref e) => Some(e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
impl From<base58::Error> for Error {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// 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 {
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
// Rust Bitcoin Library
|
|
||||||
// Written in 2014 by
|
|
||||||
// Andrew Poelstra <apoelstra@wpsoftware.net>
|
|
||||||
// To the extent possible under law, the author(s) have dedicated all
|
|
||||||
// copyright and related and neighboring rights to this software to
|
|
||||||
// the public domain worldwide. This software is distributed without
|
|
||||||
// any warranty.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the CC0 Public Domain Dedication
|
|
||||||
// along with this software.
|
|
||||||
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
|
||||||
//
|
|
||||||
|
|
||||||
//! Bitcoin keys.
|
|
||||||
//!
|
|
||||||
//! This module provides keys used in Bitcoin that can be roundtrip (de)serialized.
|
|
||||||
//!
|
|
||||||
|
|
||||||
pub use util::ecdsa::{PrivateKey, PublicKey};
|
|
||||||
pub use secp256k1::{XOnlyPublicKey, KeyPair};
|
|
||||||
|
|
||||||
use core::fmt;
|
|
||||||
#[cfg(feature = "std")] use std::error;
|
|
||||||
|
|
||||||
use secp256k1;
|
|
||||||
use util::base58;
|
|
||||||
|
|
||||||
/// A key-related error.
|
|
||||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
|
||||||
pub enum Error {
|
|
||||||
/// Base58 encoding error
|
|
||||||
Base58(base58::Error),
|
|
||||||
/// secp256k1-related error
|
|
||||||
Secp256k1(secp256k1::Error),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
match *self {
|
|
||||||
Error::Base58(ref e) => write!(f, "Key base58 error: {}", e),
|
|
||||||
Error::Secp256k1(ref e) => write!(f, "Key secp256k1 error: {}", e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
|
|
||||||
impl ::std::error::Error for Error {
|
|
||||||
fn cause(&self) -> Option<&dyn error::Error> {
|
|
||||||
match *self {
|
|
||||||
Error::Base58(ref e) => Some(e),
|
|
||||||
Error::Secp256k1(ref e) => Some(e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
impl From<base58::Error> for Error {
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -42,7 +42,7 @@ mod message_signing {
|
||||||
use secp256k1;
|
use secp256k1;
|
||||||
use secp256k1::ecdsa::{RecoveryId, RecoverableSignature};
|
use secp256k1::ecdsa::{RecoveryId, RecoverableSignature};
|
||||||
|
|
||||||
use util::ecdsa::PublicKey;
|
use util::key::PublicKey;
|
||||||
use util::address::{Address, AddressType};
|
use util::address::{Address, AddressType};
|
||||||
|
|
||||||
/// An error used for dealing with Bitcoin Signed Messages.
|
/// An error used for dealing with Bitcoin Signed Messages.
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
//!
|
//!
|
||||||
|
|
||||||
pub mod ecdsa;
|
pub mod ecdsa;
|
||||||
pub mod key;
|
|
||||||
pub mod schnorr;
|
pub mod schnorr;
|
||||||
pub mod address;
|
pub mod address;
|
||||||
pub mod amount;
|
pub mod amount;
|
||||||
|
@ -37,6 +36,14 @@ pub mod sighash;
|
||||||
|
|
||||||
pub(crate) mod endian;
|
pub(crate) mod endian;
|
||||||
|
|
||||||
|
pub mod key {
|
||||||
|
//! Bitcoin keys.
|
||||||
|
//!
|
||||||
|
//! This module provides keys used in Bitcoin that can be roundtrip (de)serialized.
|
||||||
|
|
||||||
|
pub use super::ecdsa::{XOnlyPublicKey, PublicKey, PrivateKey, KeyPair, Error};
|
||||||
|
}
|
||||||
|
|
||||||
use prelude::*;
|
use prelude::*;
|
||||||
use io;
|
use io;
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
|
|
Loading…
Reference in New Issue