Use NetworkKind in PrivateKey

We only use the network to serialize and deserialize from WIF.
For this we only really need network kind since WIF only differentiates
between mainnet and non-mainnet.
This commit is contained in:
Tobin C. Harding 2023-11-28 10:28:55 +11:00
parent d22f3828f6
commit 35bbfcded7
No known key found for this signature in database
GPG Key ID: 40BF9E4C269D6607
3 changed files with 25 additions and 22 deletions

View File

@ -575,7 +575,7 @@ impl Xpriv {
/// 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) -> PrivateKey { pub fn to_priv(self) -> PrivateKey {
PrivateKey { compressed: true, network: self.network, inner: self.private_key } PrivateKey { compressed: true, network: self.network.into(), inner: self.private_key }
} }
/// Constructs BIP340 keypair for Schnorr signatures and Taproot use matching the internal /// Constructs BIP340 keypair for Schnorr signatures and Taproot use matching the internal

View File

@ -16,7 +16,7 @@ use io::{Read, Write};
use crate::crypto::ecdsa; use crate::crypto::ecdsa;
use crate::internal_macros::impl_asref_push_bytes; use crate::internal_macros::impl_asref_push_bytes;
use crate::network::Network; use crate::network::NetworkKind;
use crate::prelude::*; use crate::prelude::*;
use crate::taproot::{TapNodeHash, TapTweakHash}; use crate::taproot::{TapNodeHash, TapTweakHash};
use crate::{base58, io}; use crate::{base58, io};
@ -390,8 +390,8 @@ impl From<&CompressedPublicKey> for WPubkeyHash {
pub struct PrivateKey { pub struct PrivateKey {
/// Whether this private key should be serialized as compressed /// Whether this private key should be serialized as compressed
pub compressed: bool, pub compressed: bool,
/// The network on which this key should be used /// The network kind on which this key should be used
pub network: Network, pub network: NetworkKind,
/// The actual ECDSA key /// The actual ECDSA key
pub inner: secp256k1::SecretKey, pub inner: secp256k1::SecretKey,
} }
@ -400,20 +400,23 @@ impl PrivateKey {
/// Constructs new compressed ECDSA private key using the secp256k1 algorithm and /// Constructs new compressed ECDSA private key using the secp256k1 algorithm and
/// a secure random number generator. /// a secure random number generator.
#[cfg(feature = "rand-std")] #[cfg(feature = "rand-std")]
pub fn generate(network: Network) -> PrivateKey { pub fn generate(network: impl Into<NetworkKind>) -> PrivateKey {
let secret_key = secp256k1::SecretKey::new(&mut rand::thread_rng()); let secret_key = secp256k1::SecretKey::new(&mut rand::thread_rng());
PrivateKey::new(secret_key, network) PrivateKey::new(secret_key, network.into())
} }
/// Constructs compressed ECDSA private key from the provided generic Secp256k1 private key /// Constructs compressed ECDSA private key from the provided generic Secp256k1 private key
/// and the specified network /// and the specified network
pub fn new(key: secp256k1::SecretKey, network: Network) -> PrivateKey { pub fn new(key: secp256k1::SecretKey, network: impl Into<NetworkKind>) -> PrivateKey {
PrivateKey { compressed: true, network, inner: key } PrivateKey { compressed: true, network: network.into(), inner: key }
} }
/// Constructs uncompressed (legacy) ECDSA private key from the provided generic Secp256k1 /// Constructs uncompressed (legacy) ECDSA private key from the provided generic Secp256k1
/// private key and the specified network /// private key and the specified network
pub fn new_uncompressed(key: secp256k1::SecretKey, network: Network) -> PrivateKey { pub fn new_uncompressed(
PrivateKey { compressed: false, network, inner: key } key: secp256k1::SecretKey,
network: impl Into<NetworkKind>,
) -> PrivateKey {
PrivateKey { compressed: false, network: network.into(), inner: key }
} }
/// Creates a public key from this private key /// Creates a public key from this private key
@ -428,17 +431,16 @@ impl PrivateKey {
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 /// Deserialize a private key from a slice
pub fn from_slice(data: &[u8], network: Network) -> Result<PrivateKey, Error> { pub fn from_slice(data: &[u8], network: impl Into<NetworkKind>) -> Result<PrivateKey, Error> {
Ok(PrivateKey::new(secp256k1::SecretKey::from_slice(data)?, network)) Ok(PrivateKey::new(secp256k1::SecretKey::from_slice(data)?, network))
} }
/// Format the private key to WIF format. /// Format the private key to WIF format.
#[rustfmt::skip]
pub fn fmt_wif(&self, fmt: &mut dyn fmt::Write) -> fmt::Result { pub fn fmt_wif(&self, fmt: &mut dyn fmt::Write) -> fmt::Result {
let mut ret = [0; 34]; let mut ret = [0; 34];
ret[0] = match self.network { ret[0] = if self.network.is_mainnet() { 128 } else { 239 };
Network::Bitcoin => 128,
Network::Testnet | Network::Signet | Network::Regtest => 239,
};
ret[1..33].copy_from_slice(&self.inner[..]); ret[1..33].copy_from_slice(&self.inner[..]);
let privkey = if self.compressed { let privkey = if self.compressed {
ret[33] = 1; ret[33] = 1;
@ -470,8 +472,8 @@ impl PrivateKey {
}; };
let network = match data[0] { let network = match data[0] {
128 => Network::Bitcoin, 128 => NetworkKind::Main,
239 => Network::Testnet, 239 => NetworkKind::Test,
x => { x => {
return Err(Error::Base58(base58::Error::InvalidAddressVersion(x))); return Err(Error::Base58(base58::Error::InvalidAddressVersion(x)));
} }
@ -953,14 +955,14 @@ mod tests {
use super::*; use super::*;
use crate::address::Address; use crate::address::Address;
use crate::network::Network::{Bitcoin, Testnet}; use crate::network::NetworkKind;
#[test] #[test]
fn test_key_derivation() { fn test_key_derivation() {
// testnet compressed // testnet compressed
let sk = let sk =
PrivateKey::from_wif("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy").unwrap(); PrivateKey::from_wif("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy").unwrap();
assert_eq!(sk.network, Testnet); assert_eq!(sk.network, NetworkKind::Test);
assert!(sk.compressed); assert!(sk.compressed);
assert_eq!(&sk.to_wif(), "cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy"); assert_eq!(&sk.to_wif(), "cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy");
@ -977,7 +979,7 @@ mod tests {
// mainnet uncompressed // mainnet uncompressed
let sk = let sk =
PrivateKey::from_wif("5JYkZjmN7PVMjJUfJWfRFwtuXTGB439XV6faajeHPAM9Z2PT2R3").unwrap(); PrivateKey::from_wif("5JYkZjmN7PVMjJUfJWfRFwtuXTGB439XV6faajeHPAM9Z2PT2R3").unwrap();
assert_eq!(sk.network, Bitcoin); assert_eq!(sk.network, NetworkKind::Main);
assert!(!sk.compressed); assert!(!sk.compressed);
assert_eq!(&sk.to_wif(), "5JYkZjmN7PVMjJUfJWfRFwtuXTGB439XV6faajeHPAM9Z2PT2R3"); assert_eq!(&sk.to_wif(), "5JYkZjmN7PVMjJUfJWfRFwtuXTGB439XV6faajeHPAM9Z2PT2R3");
@ -1295,7 +1297,7 @@ mod tests {
fn private_key_debug_is_obfuscated() { fn private_key_debug_is_obfuscated() {
let sk = let sk =
PrivateKey::from_str("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy").unwrap(); PrivateKey::from_str("cVt4o7BGAig1UXywgGSmARhxMdzP5qvQsxKkSsc1XEkw3tDTQFpy").unwrap();
let want = "PrivateKey { compressed: true, network: Testnet, inner: SecretKey(#32014e414fdce702) }"; let want = "PrivateKey { compressed: true, network: Test, inner: SecretKey(#32014e414fdce702) }";
let got = format!("{:?}", sk); let got = format!("{:?}", sk);
assert_eq!(got, want) assert_eq!(got, want)
} }

View File

@ -1015,6 +1015,7 @@ mod tests {
use crate::blockdata::transaction::{self, OutPoint, Sequence, Transaction, TxIn, TxOut}; use crate::blockdata::transaction::{self, OutPoint, Sequence, Transaction, TxIn, TxOut};
use crate::blockdata::witness::Witness; use crate::blockdata::witness::Witness;
use crate::network::Network::Bitcoin; use crate::network::Network::Bitcoin;
use crate::network::NetworkKind;
use crate::psbt::map::{Input, Output}; use crate::psbt::map::{Input, Output};
use crate::psbt::raw; use crate::psbt::raw;
use crate::psbt::serialize::{Deserialize, Serialize}; use crate::psbt::serialize::{Deserialize, Serialize};
@ -1926,7 +1927,7 @@ mod tests {
let secp = Secp256k1::new(); let secp = Secp256k1::new();
let sk = SecretKey::new(&mut thread_rng()); let sk = SecretKey::new(&mut thread_rng());
let priv_key = PrivateKey::new(sk, crate::Network::Regtest); let priv_key = PrivateKey::new(sk, NetworkKind::Test);
let pk = PublicKey::from_private_key(&secp, &priv_key); let pk = PublicKey::from_private_key(&secp, &priv_key);
(priv_key, pk, secp) (priv_key, pk, secp)