Rename xpub and xpriv types

The BIP-32 extended public key and extended private key exist in the
Bitcoin vernacular as xpub and xpriv. We can use these terms with no
loss of clarity.

Rename our current BIP-32 types

- `ExtendedPubKey` to `Xpub`
- `ExtendedPrivKey` to `Xpriv`

This patch is a mechanical search-and-replace, followed by running the
formatter, no other manual changes.
This commit is contained in:
Tobin C. Harding 2023-08-22 08:03:55 +10:00
parent 5bf2117dc4
commit be05f9d852
No known key found for this signature in database
GPG Key ID: 40BF9E4C269D6607
9 changed files with 100 additions and 114 deletions

View File

@ -4,7 +4,7 @@ use std::str::FromStr;
use std::{env, process}; use std::{env, process};
use bitcoin::address::Address; use bitcoin::address::Address;
use bitcoin::bip32::{ChildNumber, DerivationPath, ExtendedPrivKey, ExtendedPubKey}; use bitcoin::bip32::{ChildNumber, DerivationPath, Xpriv, Xpub};
use bitcoin::hex::FromHex; use bitcoin::hex::FromHex;
use bitcoin::secp256k1::ffi::types::AlignedType; use bitcoin::secp256k1::ffi::types::AlignedType;
use bitcoin::secp256k1::Secp256k1; use bitcoin::secp256k1::Secp256k1;
@ -39,14 +39,14 @@ fn main() {
let secp = Secp256k1::preallocated_new(buf.as_mut_slice()).unwrap(); let secp = Secp256k1::preallocated_new(buf.as_mut_slice()).unwrap();
// calculate root key from seed // calculate root key from seed
let root = ExtendedPrivKey::new_master(network, &seed).unwrap(); let root = Xpriv::new_master(network, &seed).unwrap();
println!("Root key: {}", root); println!("Root key: {}", root);
// derive child xpub // derive child xpub
let path = DerivationPath::from_str("m/84h/0h/0h").unwrap(); let path = DerivationPath::from_str("m/84h/0h/0h").unwrap();
let child = root.derive_priv(&secp, &path).unwrap(); let child = root.derive_priv(&secp, &path).unwrap();
println!("Child at {}: {}", path, child); println!("Child at {}: {}", path, child);
let xpub = ExtendedPubKey::from_priv(&secp, &child); let xpub = Xpub::from_priv(&secp, &child);
println!("Public key at {}: {}", path, xpub); println!("Public key at {}: {}", path, xpub);
// generate first receiving address at m/0/0 // generate first receiving address at m/0/0

View File

@ -33,9 +33,7 @@ use std::collections::BTreeMap;
use std::fmt; use std::fmt;
use std::str::FromStr; use std::str::FromStr;
use bitcoin::bip32::{ use bitcoin::bip32::{ChildNumber, DerivationPath, Fingerprint, IntoDerivationPath, Xpriv, Xpub};
ChildNumber, DerivationPath, ExtendedPrivKey, ExtendedPubKey, Fingerprint, IntoDerivationPath,
};
use bitcoin::consensus::encode; use bitcoin::consensus::encode;
use bitcoin::locktime::absolute; use bitcoin::locktime::absolute;
use bitcoin::psbt::{self, Input, Psbt, PsbtSighashType}; use bitcoin::psbt::{self, Input, Psbt, PsbtSighashType};
@ -97,14 +95,14 @@ fn main() -> Result<()> {
/// An example of an offline signer i.e., a cold-storage device. /// An example of an offline signer i.e., a cold-storage device.
struct ColdStorage { struct ColdStorage {
/// The master extended private key. /// The master extended private key.
master_xpriv: ExtendedPrivKey, master_xpriv: Xpriv,
/// The master extended public key. /// The master extended public key.
master_xpub: ExtendedPubKey, master_xpub: Xpub,
} }
/// The data exported from an offline wallet to enable creation of a watch-only online wallet. /// The data exported from an offline wallet to enable creation of a watch-only online wallet.
/// (wallet, fingerprint, account_0_xpub, input_utxo_xpub) /// (wallet, fingerprint, account_0_xpub, input_utxo_xpub)
type ExportData = (ColdStorage, Fingerprint, ExtendedPubKey, ExtendedPubKey); type ExportData = (ColdStorage, Fingerprint, Xpub, Xpub);
impl ColdStorage { impl ColdStorage {
/// Constructs a new `ColdStorage` signer. /// Constructs a new `ColdStorage` signer.
@ -113,18 +111,18 @@ impl ColdStorage {
/// ///
/// The newly created signer along with the data needed to configure a watch-only wallet. /// The newly created signer along with the data needed to configure a watch-only wallet.
fn new<C: Signing>(secp: &Secp256k1<C>, xpriv: &str) -> Result<ExportData> { fn new<C: Signing>(secp: &Secp256k1<C>, xpriv: &str) -> Result<ExportData> {
let master_xpriv = ExtendedPrivKey::from_str(xpriv)?; let master_xpriv = Xpriv::from_str(xpriv)?;
let master_xpub = ExtendedPubKey::from_priv(secp, &master_xpriv); let master_xpub = Xpub::from_priv(secp, &master_xpriv);
// Hardened children require secret data to derive. // Hardened children require secret data to derive.
let path = "m/84h/0h/0h".into_derivation_path()?; let path = "m/84h/0h/0h".into_derivation_path()?;
let account_0_xpriv = master_xpriv.derive_priv(secp, &path)?; let account_0_xpriv = master_xpriv.derive_priv(secp, &path)?;
let account_0_xpub = ExtendedPubKey::from_priv(secp, &account_0_xpriv); let account_0_xpub = Xpub::from_priv(secp, &account_0_xpriv);
let path = INPUT_UTXO_DERIVATION_PATH.into_derivation_path()?; let path = INPUT_UTXO_DERIVATION_PATH.into_derivation_path()?;
let input_xpriv = master_xpriv.derive_priv(secp, &path)?; let input_xpriv = master_xpriv.derive_priv(secp, &path)?;
let input_xpub = ExtendedPubKey::from_priv(secp, &input_xpriv); let input_xpub = Xpub::from_priv(secp, &input_xpriv);
let wallet = ColdStorage { master_xpriv, master_xpub }; let wallet = ColdStorage { master_xpriv, master_xpub };
let fingerprint = wallet.master_fingerprint(); let fingerprint = wallet.master_fingerprint();
@ -151,9 +149,9 @@ impl ColdStorage {
/// An example of an watch-only online wallet. /// An example of an watch-only online wallet.
struct WatchOnly { struct WatchOnly {
/// The xpub for account 0 derived from derivation path "m/84h/0h/0h". /// The xpub for account 0 derived from derivation path "m/84h/0h/0h".
account_0_xpub: ExtendedPubKey, account_0_xpub: Xpub,
/// The xpub derived from `INPUT_UTXO_DERIVATION_PATH`. /// The xpub derived from `INPUT_UTXO_DERIVATION_PATH`.
input_xpub: ExtendedPubKey, input_xpub: Xpub,
/// The master extended pubkey fingerprint. /// The master extended pubkey fingerprint.
master_fingerprint: Fingerprint, master_fingerprint: Fingerprint,
} }
@ -166,11 +164,7 @@ impl WatchOnly {
/// ///
/// The reason for importing the `input_xpub` is so one can use bitcoind to grab a valid input /// The reason for importing the `input_xpub` is so one can use bitcoind to grab a valid input
/// to verify the workflow presented in this file. /// to verify the workflow presented in this file.
fn new( fn new(account_0_xpub: Xpub, input_xpub: Xpub, master_fingerprint: Fingerprint) -> Self {
account_0_xpub: ExtendedPubKey,
input_xpub: ExtendedPubKey,
master_fingerprint: Fingerprint,
) -> Self {
WatchOnly { account_0_xpub, input_xpub, master_fingerprint } WatchOnly { account_0_xpub, input_xpub, master_fingerprint }
} }

View File

@ -78,7 +78,7 @@ const UTXO_3: P2trUtxo = P2trUtxo {
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::str::FromStr; use std::str::FromStr;
use bitcoin::bip32::{ChildNumber, DerivationPath, ExtendedPrivKey, ExtendedPubKey, Fingerprint}; use bitcoin::bip32::{ChildNumber, DerivationPath, Fingerprint, Xpriv, Xpub};
use bitcoin::consensus::encode; use bitcoin::consensus::encode;
use bitcoin::key::{TapTweak, XOnlyPublicKey}; use bitcoin::key::{TapTweak, XOnlyPublicKey};
use bitcoin::opcodes::all::{OP_CHECKSIG, OP_CLTV, OP_DROP}; use bitcoin::opcodes::all::{OP_CHECKSIG, OP_CLTV, OP_DROP};
@ -114,7 +114,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let tx_hex_string = encode::serialize_hex(&generate_bip86_key_spend_tx( let tx_hex_string = encode::serialize_hex(&generate_bip86_key_spend_tx(
&secp, &secp,
// The master extended private key from the descriptor in step 4 // The master extended private key from the descriptor in step 4
ExtendedPrivKey::from_str(BENEFACTOR_XPRIV_STR)?, Xpriv::from_str(BENEFACTOR_XPRIV_STR)?,
// Set these fields with valid data for the UTXO from step 5 above // Set these fields with valid data for the UTXO from step 5 above
UTXO_1, UTXO_1,
vec![ vec![
@ -133,11 +133,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("START EXAMPLE 2 - Script path spending of inheritance UTXO\n"); println!("START EXAMPLE 2 - Script path spending of inheritance UTXO\n");
{ {
let beneficiary = let beneficiary = BeneficiaryWallet::new(Xpriv::from_str(BENEFICIARY_XPRIV_STR)?)?;
BeneficiaryWallet::new(ExtendedPrivKey::from_str(BENEFICIARY_XPRIV_STR)?)?;
let mut benefactor = BenefactorWallet::new( let mut benefactor = BenefactorWallet::new(
ExtendedPrivKey::from_str(BENEFACTOR_XPRIV_STR)?, Xpriv::from_str(BENEFACTOR_XPRIV_STR)?,
beneficiary.master_xpub(), beneficiary.master_xpub(),
)?; )?;
let (tx, psbt) = benefactor.create_inheritance_funding_tx( let (tx, psbt) = benefactor.create_inheritance_funding_tx(
@ -172,11 +171,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("START EXAMPLE 3 - Key path spending of inheritance UTXO\n"); println!("START EXAMPLE 3 - Key path spending of inheritance UTXO\n");
{ {
let beneficiary = let beneficiary = BeneficiaryWallet::new(Xpriv::from_str(BENEFICIARY_XPRIV_STR)?)?;
BeneficiaryWallet::new(ExtendedPrivKey::from_str(BENEFICIARY_XPRIV_STR)?)?;
let mut benefactor = BenefactorWallet::new( let mut benefactor = BenefactorWallet::new(
ExtendedPrivKey::from_str(BENEFACTOR_XPRIV_STR)?, Xpriv::from_str(BENEFACTOR_XPRIV_STR)?,
beneficiary.master_xpub(), beneficiary.master_xpub(),
)?; )?;
let (tx, _) = benefactor.create_inheritance_funding_tx( let (tx, _) = benefactor.create_inheritance_funding_tx(
@ -221,7 +219,7 @@ struct P2trUtxo<'a> {
fn generate_bip86_key_spend_tx( fn generate_bip86_key_spend_tx(
secp: &secp256k1::Secp256k1<secp256k1::All>, secp: &secp256k1::Secp256k1<secp256k1::All>,
master_xpriv: ExtendedPrivKey, master_xpriv: Xpriv,
input_utxo: P2trUtxo, input_utxo: P2trUtxo,
outputs: Vec<TxOut>, outputs: Vec<TxOut>,
) -> Result<Transaction, Box<dyn std::error::Error>> { ) -> Result<Transaction, Box<dyn std::error::Error>> {
@ -335,8 +333,8 @@ fn generate_bip86_key_spend_tx(
/// A wallet that allows creating and spending from an inheritance directly via the key path for purposes /// A wallet that allows creating and spending from an inheritance directly via the key path for purposes
/// of refreshing the inheritance timelock or changing other spending conditions. /// of refreshing the inheritance timelock or changing other spending conditions.
struct BenefactorWallet { struct BenefactorWallet {
master_xpriv: ExtendedPrivKey, master_xpriv: Xpriv,
beneficiary_xpub: ExtendedPubKey, beneficiary_xpub: Xpub,
current_spend_info: Option<TaprootSpendInfo>, current_spend_info: Option<TaprootSpendInfo>,
next_psbt: Option<Psbt>, next_psbt: Option<Psbt>,
secp: Secp256k1<secp256k1::All>, secp: Secp256k1<secp256k1::All>,
@ -345,8 +343,8 @@ struct BenefactorWallet {
impl BenefactorWallet { impl BenefactorWallet {
fn new( fn new(
master_xpriv: ExtendedPrivKey, master_xpriv: Xpriv,
beneficiary_xpub: ExtendedPubKey, beneficiary_xpub: Xpub,
) -> Result<Self, Box<dyn std::error::Error>> { ) -> Result<Self, Box<dyn std::error::Error>> {
Ok(Self { Ok(Self {
master_xpriv, master_xpriv,
@ -615,18 +613,16 @@ impl BenefactorWallet {
/// A wallet that allows spending from an inheritance locked to a P2TR UTXO via a script path /// A wallet that allows spending from an inheritance locked to a P2TR UTXO via a script path
/// after some expiry using CLTV. /// after some expiry using CLTV.
struct BeneficiaryWallet { struct BeneficiaryWallet {
master_xpriv: ExtendedPrivKey, master_xpriv: Xpriv,
secp: secp256k1::Secp256k1<secp256k1::All>, secp: secp256k1::Secp256k1<secp256k1::All>,
} }
impl BeneficiaryWallet { impl BeneficiaryWallet {
fn new(master_xpriv: ExtendedPrivKey) -> Result<Self, Box<dyn std::error::Error>> { fn new(master_xpriv: Xpriv) -> Result<Self, Box<dyn std::error::Error>> {
Ok(Self { master_xpriv, secp: Secp256k1::new() }) Ok(Self { master_xpriv, secp: Secp256k1::new() })
} }
fn master_xpub(&self) -> ExtendedPubKey { fn master_xpub(&self) -> Xpub { Xpub::from_priv(&self.secp, &self.master_xpriv) }
ExtendedPubKey::from_priv(&self.secp, &self.master_xpriv)
}
fn spend_inheritance( fn spend_inheritance(
&self, &self,

View File

@ -47,7 +47,7 @@ impl_bytes_newtype!(Fingerprint, 4);
/// Extended private key /// Extended private key
#[derive(Copy, Clone, PartialEq, Eq)] #[derive(Copy, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "std", derive(Debug))] #[cfg_attr(feature = "std", derive(Debug))]
pub struct ExtendedPrivKey { pub struct Xpriv {
/// The network this key is to be used on /// The network this key is to be used on
pub network: Network, pub network: Network,
/// How many derivations this key is from the master (which is 0) /// How many derivations this key is from the master (which is 0)
@ -62,12 +62,12 @@ pub struct ExtendedPrivKey {
pub chain_code: ChainCode, pub chain_code: ChainCode,
} }
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
crate::serde_utils::serde_string_impl!(ExtendedPrivKey, "a BIP-32 extended private key"); crate::serde_utils::serde_string_impl!(Xpriv, "a BIP-32 extended private key");
#[cfg(not(feature = "std"))] #[cfg(not(feature = "std"))]
impl fmt::Debug for ExtendedPrivKey { impl fmt::Debug for Xpriv {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("ExtendedPrivKey") f.debug_struct("Xpriv")
.field("network", &self.network) .field("network", &self.network)
.field("depth", &self.depth) .field("depth", &self.depth)
.field("parent_fingerprint", &self.parent_fingerprint) .field("parent_fingerprint", &self.parent_fingerprint)
@ -80,7 +80,7 @@ impl fmt::Debug for ExtendedPrivKey {
/// Extended public key /// Extended public key
#[derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord, Hash)] #[derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord, Hash)]
pub struct ExtendedPubKey { pub struct Xpub {
/// The network this key is to be used on /// The network this key is to be used on
pub network: Network, pub network: Network,
/// How many derivations this key is from the master (which is 0) /// How many derivations this key is from the master (which is 0)
@ -95,7 +95,7 @@ pub struct ExtendedPubKey {
pub chain_code: ChainCode, pub chain_code: ChainCode,
} }
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
crate::serde_utils::serde_string_impl!(ExtendedPubKey, "a BIP-32 extended public key"); crate::serde_utils::serde_string_impl!(Xpub, "a BIP-32 extended public key");
/// A child number for a derived key /// A child number for a derived key
#[derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord, Hash)] #[derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord, Hash)]
@ -535,14 +535,14 @@ impl From<base58::Error> for Error {
fn from(err: base58::Error) -> Self { Error::Base58(err) } fn from(err: base58::Error) -> Self { Error::Base58(err) }
} }
impl ExtendedPrivKey { impl Xpriv {
/// Construct a new master key from a seed value /// Construct a new master key from a seed value
pub fn new_master(network: Network, seed: &[u8]) -> Result<ExtendedPrivKey, Error> { pub fn new_master(network: Network, seed: &[u8]) -> Result<Xpriv, Error> {
let mut hmac_engine: HmacEngine<sha512::Hash> = HmacEngine::new(b"Bitcoin seed"); let mut hmac_engine: HmacEngine<sha512::Hash> = HmacEngine::new(b"Bitcoin seed");
hmac_engine.input(seed); hmac_engine.input(seed);
let hmac_result: Hmac<sha512::Hash> = Hmac::from_engine(hmac_engine); let hmac_result: Hmac<sha512::Hash> = Hmac::from_engine(hmac_engine);
Ok(ExtendedPrivKey { Ok(Xpriv {
network, network,
depth: 0, depth: 0,
parent_fingerprint: Default::default(), parent_fingerprint: Default::default(),
@ -571,8 +571,8 @@ impl ExtendedPrivKey {
&self, &self,
secp: &Secp256k1<C>, secp: &Secp256k1<C>,
path: &P, path: &P,
) -> Result<ExtendedPrivKey, Error> { ) -> Result<Xpriv, Error> {
let mut sk: ExtendedPrivKey = *self; let mut sk: Xpriv = *self;
for cnum in path.as_ref() { for cnum in path.as_ref() {
sk = sk.ckd_priv(secp, *cnum)?; sk = sk.ckd_priv(secp, *cnum)?;
} }
@ -584,7 +584,7 @@ impl ExtendedPrivKey {
&self, &self,
secp: &Secp256k1<C>, secp: &Secp256k1<C>,
i: ChildNumber, i: ChildNumber,
) -> Result<ExtendedPrivKey, Error> { ) -> Result<Xpriv, Error> {
let mut hmac_engine: HmacEngine<sha512::Hash> = HmacEngine::new(&self.chain_code[..]); let mut hmac_engine: HmacEngine<sha512::Hash> = HmacEngine::new(&self.chain_code[..]);
match i { match i {
ChildNumber::Normal { .. } => { ChildNumber::Normal { .. } => {
@ -607,7 +607,7 @@ impl ExtendedPrivKey {
let tweaked = let tweaked =
sk.add_tweak(&self.private_key.into()).expect("statistically impossible to hit"); sk.add_tweak(&self.private_key.into()).expect("statistically impossible to hit");
Ok(ExtendedPrivKey { Ok(Xpriv {
network: self.network, network: self.network,
depth: self.depth + 1, depth: self.depth + 1,
parent_fingerprint: self.fingerprint(secp), parent_fingerprint: self.fingerprint(secp),
@ -618,7 +618,7 @@ impl ExtendedPrivKey {
} }
/// Decoding extended private key from binary data according to BIP 32 /// Decoding extended private key from binary data according to BIP 32
pub fn decode(data: &[u8]) -> Result<ExtendedPrivKey, Error> { pub fn decode(data: &[u8]) -> Result<Xpriv, Error> {
if data.len() != 78 { if data.len() != 78 {
return Err(Error::WrongExtendedKeyLength(data.len())); return Err(Error::WrongExtendedKeyLength(data.len()));
} }
@ -630,7 +630,7 @@ impl ExtendedPrivKey {
_ => unreachable!("length checked above"), _ => unreachable!("length checked above"),
}; };
Ok(ExtendedPrivKey { Ok(Xpriv {
network, network,
depth: data[4], depth: data[4],
parent_fingerprint: data[5..9] parent_fingerprint: data[5..9]
@ -664,7 +664,7 @@ impl ExtendedPrivKey {
/// Returns the HASH160 of the public key belonging to the xpriv /// Returns the HASH160 of the public key belonging to the xpriv
pub fn identifier<C: secp256k1::Signing>(&self, secp: &Secp256k1<C>) -> XpubIdentifier { pub fn identifier<C: secp256k1::Signing>(&self, secp: &Secp256k1<C>) -> XpubIdentifier {
ExtendedPubKey::from_priv(secp, self).identifier() Xpub::from_priv(secp, self).identifier()
} }
/// Returns the first four bytes of the identifier /// Returns the first four bytes of the identifier
@ -673,13 +673,10 @@ impl ExtendedPrivKey {
} }
} }
impl ExtendedPubKey { impl Xpub {
/// Derives a public key from a private key /// Derives a public key from a private key
pub fn from_priv<C: secp256k1::Signing>( pub fn from_priv<C: secp256k1::Signing>(secp: &Secp256k1<C>, sk: &Xpriv) -> Xpub {
secp: &Secp256k1<C>, Xpub {
sk: &ExtendedPrivKey,
) -> ExtendedPubKey {
ExtendedPubKey {
network: sk.network, network: sk.network,
depth: sk.depth, depth: sk.depth,
parent_fingerprint: sk.parent_fingerprint, parent_fingerprint: sk.parent_fingerprint,
@ -703,8 +700,8 @@ impl ExtendedPubKey {
&self, &self,
secp: &Secp256k1<C>, secp: &Secp256k1<C>,
path: &P, path: &P,
) -> Result<ExtendedPubKey, Error> { ) -> Result<Xpub, Error> {
let mut pk: ExtendedPubKey = *self; let mut pk: Xpub = *self;
for cnum in path.as_ref() { for cnum in path.as_ref() {
pk = pk.ckd_pub(secp, *cnum)? pk = pk.ckd_pub(secp, *cnum)?
} }
@ -738,11 +735,11 @@ impl ExtendedPubKey {
&self, &self,
secp: &Secp256k1<C>, secp: &Secp256k1<C>,
i: ChildNumber, i: ChildNumber,
) -> Result<ExtendedPubKey, Error> { ) -> Result<Xpub, Error> {
let (sk, chain_code) = self.ckd_pub_tweak(i)?; let (sk, chain_code) = self.ckd_pub_tweak(i)?;
let tweaked = self.public_key.add_exp_tweak(secp, &sk.into())?; let tweaked = self.public_key.add_exp_tweak(secp, &sk.into())?;
Ok(ExtendedPubKey { Ok(Xpub {
network: self.network, network: self.network,
depth: self.depth + 1, depth: self.depth + 1,
parent_fingerprint: self.fingerprint(), parent_fingerprint: self.fingerprint(),
@ -753,7 +750,7 @@ impl ExtendedPubKey {
} }
/// Decoding extended public key from binary data according to BIP 32 /// Decoding extended public key from binary data according to BIP 32
pub fn decode(data: &[u8]) -> Result<ExtendedPubKey, Error> { pub fn decode(data: &[u8]) -> Result<Xpub, Error> {
if data.len() != 78 { if data.len() != 78 {
return Err(Error::WrongExtendedKeyLength(data.len())); return Err(Error::WrongExtendedKeyLength(data.len()));
} }
@ -765,7 +762,7 @@ impl ExtendedPubKey {
_ => unreachable!("length checked above"), _ => unreachable!("length checked above"),
}; };
Ok(ExtendedPubKey { Ok(Xpub {
network, network,
depth: data[4], depth: data[4],
parent_fingerprint: data[5..9] parent_fingerprint: data[5..9]
@ -809,52 +806,52 @@ impl ExtendedPubKey {
} }
} }
impl fmt::Display for ExtendedPrivKey { impl fmt::Display for Xpriv {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
base58::encode_check_to_fmt(fmt, &self.encode()[..]) base58::encode_check_to_fmt(fmt, &self.encode()[..])
} }
} }
impl FromStr for ExtendedPrivKey { impl FromStr for Xpriv {
type Err = Error; type Err = Error;
fn from_str(inp: &str) -> Result<ExtendedPrivKey, Error> { fn from_str(inp: &str) -> Result<Xpriv, Error> {
let data = base58::decode_check(inp)?; let data = base58::decode_check(inp)?;
if data.len() != 78 { if data.len() != 78 {
return Err(base58::Error::InvalidLength(data.len()).into()); return Err(base58::Error::InvalidLength(data.len()).into());
} }
ExtendedPrivKey::decode(&data) Xpriv::decode(&data)
} }
} }
impl fmt::Display for ExtendedPubKey { impl fmt::Display for Xpub {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
base58::encode_check_to_fmt(fmt, &self.encode()[..]) base58::encode_check_to_fmt(fmt, &self.encode()[..])
} }
} }
impl FromStr for ExtendedPubKey { impl FromStr for Xpub {
type Err = Error; type Err = Error;
fn from_str(inp: &str) -> Result<ExtendedPubKey, Error> { fn from_str(inp: &str) -> Result<Xpub, Error> {
let data = base58::decode_check(inp)?; let data = base58::decode_check(inp)?;
if data.len() != 78 { if data.len() != 78 {
return Err(base58::Error::InvalidLength(data.len()).into()); return Err(base58::Error::InvalidLength(data.len()).into());
} }
ExtendedPubKey::decode(&data) Xpub::decode(&data)
} }
} }
impl From<ExtendedPubKey> for XpubIdentifier { impl From<Xpub> for XpubIdentifier {
fn from(key: ExtendedPubKey) -> XpubIdentifier { key.identifier() } fn from(key: Xpub) -> XpubIdentifier { key.identifier() }
} }
impl From<&ExtendedPubKey> for XpubIdentifier { impl From<&Xpub> for XpubIdentifier {
fn from(key: &ExtendedPubKey) -> XpubIdentifier { key.identifier() } fn from(key: &Xpub) -> XpubIdentifier { key.identifier() }
} }
#[cfg(test)] #[cfg(test)]
@ -953,13 +950,13 @@ mod tests {
expected_sk: &str, expected_sk: &str,
expected_pk: &str, expected_pk: &str,
) { ) {
let mut sk = ExtendedPrivKey::new_master(network, seed).unwrap(); let mut sk = Xpriv::new_master(network, seed).unwrap();
let mut pk = ExtendedPubKey::from_priv(secp, &sk); let mut pk = Xpub::from_priv(secp, &sk);
// Check derivation convenience method for ExtendedPrivKey // Check derivation convenience method for Xpriv
assert_eq!(&sk.derive_priv(secp, &path).unwrap().to_string()[..], expected_sk); assert_eq!(&sk.derive_priv(secp, &path).unwrap().to_string()[..], expected_sk);
// Check derivation convenience method for ExtendedPubKey, should error // Check derivation convenience method for Xpub, should error
// appropriately if any ChildNumber is hardened // appropriately if any ChildNumber is hardened
if path.0.iter().any(|cnum| cnum.is_hardened()) { if path.0.iter().any(|cnum| cnum.is_hardened()) {
assert_eq!(pk.derive_pub(secp, &path), Err(Error::CannotDeriveFromHardenedKey)); assert_eq!(pk.derive_pub(secp, &path), Err(Error::CannotDeriveFromHardenedKey));
@ -973,12 +970,12 @@ mod tests {
match num { match num {
Normal { .. } => { Normal { .. } => {
let pk2 = pk.ckd_pub(secp, num).unwrap(); let pk2 = pk.ckd_pub(secp, num).unwrap();
pk = ExtendedPubKey::from_priv(secp, &sk); pk = Xpub::from_priv(secp, &sk);
assert_eq!(pk, pk2); assert_eq!(pk, pk2);
} }
Hardened { .. } => { Hardened { .. } => {
assert_eq!(pk.ckd_pub(secp, num), Err(Error::CannotDeriveFromHardenedKey)); assert_eq!(pk.ckd_pub(secp, num), Err(Error::CannotDeriveFromHardenedKey));
pk = ExtendedPubKey::from_priv(secp, &sk); pk = Xpub::from_priv(secp, &sk);
} }
} }
} }
@ -987,8 +984,8 @@ mod tests {
assert_eq!(&sk.to_string()[..], expected_sk); assert_eq!(&sk.to_string()[..], expected_sk);
assert_eq!(&pk.to_string()[..], expected_pk); assert_eq!(&pk.to_string()[..], expected_pk);
// Check decoded base58 against result // Check decoded base58 against result
let decoded_sk = ExtendedPrivKey::from_str(expected_sk); let decoded_sk = Xpriv::from_str(expected_sk);
let decoded_pk = ExtendedPubKey::from_str(expected_pk); let decoded_pk = Xpub::from_str(expected_pk);
assert_eq!(Ok(sk), decoded_sk); assert_eq!(Ok(sk), decoded_sk);
assert_eq!(Ok(pk), decoded_pk); assert_eq!(Ok(pk), decoded_pk);
} }
@ -1181,7 +1178,7 @@ mod tests {
sk.as_mut_ptr().copy_from(zeros.as_ptr(), 32); sk.as_mut_ptr().copy_from(zeros.as_ptr(), 32);
} }
let xpriv = ExtendedPrivKey { let xpriv = Xpriv {
network: Network::Bitcoin, network: Network::Bitcoin,
depth: 0, depth: 0,
parent_fingerprint: Default::default(), parent_fingerprint: Default::default(),
@ -1195,7 +1192,7 @@ mod tests {
// Xpriv having secret key set to all zeros // Xpriv having secret key set to all zeros
let xpriv_str = "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzF93Y5wvzdUayhgkkFoicQZcP3y52uPPxFnfoLZB21Teqt1VvEHx"; let xpriv_str = "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzF93Y5wvzdUayhgkkFoicQZcP3y52uPPxFnfoLZB21Teqt1VvEHx";
ExtendedPrivKey::from_str(xpriv_str).unwrap(); Xpriv::from_str(xpriv_str).unwrap();
} }
#[test] #[test]
@ -1203,6 +1200,6 @@ mod tests {
fn schnorr_broken_privkey_ffs() { fn schnorr_broken_privkey_ffs() {
// Xpriv having secret key set to all 0xFF's // Xpriv having secret key set to all 0xFF's
let xpriv_str = "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFAzHGBP2UuGCqWLTAPLcMtD9y5gkZ6Eq3Rjuahrv17fENZ3QzxW"; let xpriv_str = "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFAzHGBP2UuGCqWLTAPLcMtD9y5gkZ6Eq3Rjuahrv17fENZ3QzxW";
ExtendedPrivKey::from_str(xpriv_str).unwrap(); Xpriv::from_str(xpriv_str).unwrap();
} }
} }

View File

@ -4,7 +4,7 @@ use core::fmt;
use internals::write_err; use internals::write_err;
use crate::bip32::ExtendedPubKey; use crate::bip32::Xpub;
use crate::blockdata::transaction::Transaction; use crate::blockdata::transaction::Transaction;
use crate::consensus::encode; use crate::consensus::encode;
use crate::prelude::*; use crate::prelude::*;
@ -69,7 +69,7 @@ pub enum Error {
}, },
/// Conflicting data during combine procedure: /// Conflicting data during combine procedure:
/// global extended public key has inconsistent key sources /// global extended public key has inconsistent key sources
CombineInconsistentKeySources(Box<ExtendedPubKey>), CombineInconsistentKeySources(Box<Xpub>),
/// Serialization error in bitcoin consensus-encoded structures /// Serialization error in bitcoin consensus-encoded structures
ConsensusEncoding(encode::Error), ConsensusEncoding(encode::Error),
/// Negative fee /// Negative fee

View File

@ -2,7 +2,7 @@
use core::convert::TryFrom; use core::convert::TryFrom;
use crate::bip32::{ChildNumber, DerivationPath, ExtendedPubKey, Fingerprint}; use crate::bip32::{ChildNumber, DerivationPath, Fingerprint, Xpub};
use crate::blockdata::transaction::Transaction; use crate::blockdata::transaction::Transaction;
use crate::consensus::encode::MAX_VEC_SIZE; use crate::consensus::encode::MAX_VEC_SIZE;
use crate::consensus::{encode, Decodable}; use crate::consensus::{encode, Decodable};
@ -76,8 +76,7 @@ impl Psbt {
let mut tx: Option<Transaction> = None; let mut tx: Option<Transaction> = None;
let mut version: Option<u32> = None; let mut version: Option<u32> = None;
let mut unknowns: BTreeMap<raw::Key, Vec<u8>> = Default::default(); let mut unknowns: BTreeMap<raw::Key, Vec<u8>> = Default::default();
let mut xpub_map: BTreeMap<ExtendedPubKey, (Fingerprint, DerivationPath)> = let mut xpub_map: BTreeMap<Xpub, (Fingerprint, DerivationPath)> = Default::default();
Default::default();
let mut proprietary: BTreeMap<raw::ProprietaryKey, Vec<u8>> = Default::default(); let mut proprietary: BTreeMap<raw::ProprietaryKey, Vec<u8>> = Default::default();
loop { loop {
@ -114,7 +113,7 @@ impl Psbt {
} }
PSBT_GLOBAL_XPUB => { PSBT_GLOBAL_XPUB => {
if !pair.key.key.is_empty() { if !pair.key.key.is_empty() {
let xpub = ExtendedPubKey::decode(&pair.key.key) let xpub = Xpub::decode(&pair.key.key)
.map_err(|_| Error::XPubKey( .map_err(|_| Error::XPubKey(
"Can't deserialize ExtendedPublicKey from global XPUB key data" "Can't deserialize ExtendedPublicKey from global XPUB key data"
))?; ))?;

View File

@ -14,7 +14,7 @@ use std::collections::{HashMap, HashSet};
use internals::write_err; use internals::write_err;
use secp256k1::{Message, Secp256k1, Signing}; use secp256k1::{Message, Secp256k1, Signing};
use crate::bip32::{self, ExtendedPrivKey, ExtendedPubKey, KeySource}; use crate::bip32::{self, KeySource, Xpriv, Xpub};
use crate::blockdata::transaction::{Transaction, TxOut}; use crate::blockdata::transaction::{Transaction, TxOut};
use crate::crypto::ecdsa; use crate::crypto::ecdsa;
use crate::crypto::key::{PrivateKey, PublicKey}; use crate::crypto::key::{PrivateKey, PublicKey};
@ -44,7 +44,7 @@ pub struct Psbt {
pub version: u32, pub version: u32,
/// A global map from extended public keys to the used key fingerprint and /// A global map from extended public keys to the used key fingerprint and
/// derivation path as defined by BIP 32. /// derivation path as defined by BIP 32.
pub xpub: BTreeMap<ExtendedPubKey, KeySource>, pub xpub: BTreeMap<Xpub, KeySource>,
/// Global proprietary key-value pairs. /// Global proprietary key-value pairs.
#[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq_byte_values"))] #[cfg_attr(feature = "serde", serde(with = "crate::serde_utils::btreemap_as_seq_byte_values"))]
pub proprietary: BTreeMap<raw::ProprietaryKey, Vec<u8>>, pub proprietary: BTreeMap<raw::ProprietaryKey, Vec<u8>>,
@ -487,7 +487,7 @@ pub trait GetKey {
) -> Result<Option<PrivateKey>, Self::Error>; ) -> Result<Option<PrivateKey>, Self::Error>;
} }
impl GetKey for ExtendedPrivKey { impl GetKey for Xpriv {
type Error = GetKeyError; type Error = GetKeyError;
fn get_key<C: Signing>( fn get_key<C: Signing>(
@ -520,7 +520,7 @@ pub type SigningErrors = BTreeMap<usize, SignError>;
macro_rules! impl_get_key_for_set { macro_rules! impl_get_key_for_set {
($set:ident) => { ($set:ident) => {
impl GetKey for $set<ExtendedPrivKey> { impl GetKey for $set<Xpriv> {
type Error = GetKeyError; type Error = GetKeyError;
fn get_key<C: Signing>( fn get_key<C: Signing>(
@ -810,7 +810,7 @@ mod tests {
use secp256k1::{All, SecretKey}; use secp256k1::{All, SecretKey};
use super::*; use super::*;
use crate::bip32::{ChildNumber, ExtendedPrivKey, ExtendedPubKey, KeySource}; use crate::bip32::{ChildNumber, KeySource, Xpriv, Xpub};
use crate::blockdata::locktime::absolute; use crate::blockdata::locktime::absolute;
use crate::blockdata::script::ScriptBuf; use crate::blockdata::script::ScriptBuf;
use crate::blockdata::transaction::{OutPoint, Sequence, Transaction, TxIn, TxOut}; use crate::blockdata::transaction::{OutPoint, Sequence, Transaction, TxIn, TxOut};
@ -857,7 +857,7 @@ mod tests {
let mut hd_keypaths: BTreeMap<secp256k1::PublicKey, KeySource> = Default::default(); let mut hd_keypaths: BTreeMap<secp256k1::PublicKey, KeySource> = Default::default();
let mut sk: ExtendedPrivKey = ExtendedPrivKey::new_master(Bitcoin, &seed).unwrap(); let mut sk: Xpriv = Xpriv::new_master(Bitcoin, &seed).unwrap();
let fprint = sk.fingerprint(secp); let fprint = sk.fingerprint(secp);
@ -874,7 +874,7 @@ mod tests {
sk = sk.derive_priv(secp, &dpath).unwrap(); sk = sk.derive_priv(secp, &dpath).unwrap();
let pk = ExtendedPubKey::from_priv(secp, &sk); let pk = Xpub::from_priv(secp, &sk);
hd_keypaths.insert(pk.public_key, (fprint, dpath.into())); hd_keypaths.insert(pk.public_key, (fprint, dpath.into()));
@ -1019,7 +1019,7 @@ mod tests {
let psbt = Psbt { let psbt = Psbt {
version: 0, version: 0,
xpub: { xpub: {
let xpub: ExtendedPubKey = let xpub: Xpub =
"xpub661MyMwAqRbcGoRVtwfvzZsq2VBJR1LAHfQstHUoxqDorV89vRoMxUZ27kLrraAj6MPi\ "xpub661MyMwAqRbcGoRVtwfvzZsq2VBJR1LAHfQstHUoxqDorV89vRoMxUZ27kLrraAj6MPi\
QfrDb27gigC1VS1dBXi5jGpxmMeBXEkKkcXUTg4".parse().unwrap(); QfrDb27gigC1VS1dBXi5jGpxmMeBXEkKkcXUTg4".parse().unwrap();
vec![(xpub, key_source)].into_iter().collect() vec![(xpub, key_source)].into_iter().collect()

View File

@ -5,7 +5,7 @@ use core::convert::TryFrom;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::str::FromStr; use std::str::FromStr;
use bitcoin::bip32::{ExtendedPrivKey, ExtendedPubKey, Fingerprint, IntoDerivationPath, KeySource}; use bitcoin::bip32::{Fingerprint, IntoDerivationPath, KeySource, Xpriv, Xpub};
use bitcoin::blockdata::opcodes::OP_0; use bitcoin::blockdata::opcodes::OP_0;
use bitcoin::blockdata::script; use bitcoin::blockdata::script;
use bitcoin::consensus::encode::{deserialize, serialize_hex}; use bitcoin::consensus::encode::{deserialize, serialize_hex};
@ -41,7 +41,7 @@ fn bip174_psbt_workflow() {
// //
let ext_priv = build_extended_private_key(); let ext_priv = build_extended_private_key();
let ext_pub = ExtendedPubKey::from_priv(&secp, &ext_priv); let ext_pub = Xpub::from_priv(&secp, &ext_priv);
let parent_fingerprint = ext_pub.fingerprint(); let parent_fingerprint = ext_pub.fingerprint();
// //
@ -120,15 +120,15 @@ fn bip174_psbt_workflow() {
} }
/// Attempts to build an extended private key from seed and also directly from a string. /// Attempts to build an extended private key from seed and also directly from a string.
fn build_extended_private_key() -> ExtendedPrivKey { fn build_extended_private_key() -> Xpriv {
// Strings from BIP 174 test vector. // Strings from BIP 174 test vector.
let extended_private_key = "tprv8ZgxMBicQKsPd9TeAdPADNnSyH9SSUUbTVeFszDE23Ki6TBB5nCefAdHkK8Fm3qMQR6sHwA56zqRmKmxnHk37JkiFzvncDqoKmPWubu7hDF"; let extended_private_key = "tprv8ZgxMBicQKsPd9TeAdPADNnSyH9SSUUbTVeFszDE23Ki6TBB5nCefAdHkK8Fm3qMQR6sHwA56zqRmKmxnHk37JkiFzvncDqoKmPWubu7hDF";
let seed = "cUkG8i1RFfWGWy5ziR11zJ5V4U4W3viSFCfyJmZnvQaUsd1xuF3T"; let seed = "cUkG8i1RFfWGWy5ziR11zJ5V4U4W3viSFCfyJmZnvQaUsd1xuF3T";
let xpriv = ExtendedPrivKey::from_str(extended_private_key).unwrap(); let xpriv = Xpriv::from_str(extended_private_key).unwrap();
let sk = PrivateKey::from_wif(seed).unwrap(); let sk = PrivateKey::from_wif(seed).unwrap();
let seeded = ExtendedPrivKey::new_master(NETWORK, &sk.inner.secret_bytes()).unwrap(); let seeded = Xpriv::new_master(NETWORK, &sk.inner.secret_bytes()).unwrap();
assert_eq!(xpriv, seeded); assert_eq!(xpriv, seeded);
xpriv xpriv
@ -224,7 +224,7 @@ fn update_psbt(mut psbt: Psbt, fingerprint: Fingerprint) -> Psbt {
let redeem_script_1 = "00208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903"; let redeem_script_1 = "00208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903";
let witness_script = "522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae"; let witness_script = "522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae";
// Public key and its derivation path (these are the child pubkeys for our `ExtendedPrivKey`, // Public key and its derivation path (these are the child pubkeys for our `Xpriv`,
// can be verified by deriving the key using this derivation path). // can be verified by deriving the key using this derivation path).
let pk_path = vec![ let pk_path = vec![
("029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f", "m/0h/0h/0h"), ("029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f", "m/0h/0h/0h"),
@ -310,7 +310,7 @@ fn update_psbt_with_sighash_all(mut psbt: Psbt) -> Psbt {
/// Verifies the keys in the test vector are valid for the extended private key and derivation path. /// Verifies the keys in the test vector are valid for the extended private key and derivation path.
fn parse_and_verify_keys( fn parse_and_verify_keys(
ext_priv: &ExtendedPrivKey, ext_priv: &Xpriv,
sk_path: &[(&str, &str)], sk_path: &[(&str, &str)],
) -> BTreeMap<PublicKey, PrivateKey> { ) -> BTreeMap<PublicKey, PrivateKey> {
let secp = &Secp256k1::new(); let secp = &Secp256k1::new();

View File

@ -27,7 +27,7 @@ use std::convert::TryFrom;
use std::str::FromStr; use std::str::FromStr;
use bincode::serialize; use bincode::serialize;
use bitcoin::bip32::{ChildNumber, ExtendedPrivKey, ExtendedPubKey, KeySource}; use bitcoin::bip32::{ChildNumber, KeySource, Xpriv, Xpub};
use bitcoin::blockdata::locktime::{absolute, relative}; use bitcoin::blockdata::locktime::{absolute, relative};
use bitcoin::blockdata::witness::Witness; use bitcoin::blockdata::witness::Witness;
use bitcoin::consensus::encode::deserialize; use bitcoin::consensus::encode::deserialize;
@ -155,7 +155,7 @@ fn serde_regression_address() {
#[test] #[test]
fn serde_regression_extended_priv_key() { fn serde_regression_extended_priv_key() {
let s = include_str!("data/serde/extended_priv_key"); let s = include_str!("data/serde/extended_priv_key");
let key = ExtendedPrivKey::from_str(s.trim()).unwrap(); let key = Xpriv::from_str(s.trim()).unwrap();
let got = serialize(&key).unwrap(); let got = serialize(&key).unwrap();
let want = include_bytes!("data/serde/extended_priv_key_bincode") as &[_]; let want = include_bytes!("data/serde/extended_priv_key_bincode") as &[_];
assert_eq!(got, want) assert_eq!(got, want)
@ -164,7 +164,7 @@ fn serde_regression_extended_priv_key() {
#[test] #[test]
fn serde_regression_extended_pub_key() { fn serde_regression_extended_pub_key() {
let s = include_str!("data/serde/extended_pub_key"); let s = include_str!("data/serde/extended_pub_key");
let key = ExtendedPubKey::from_str(s.trim()).unwrap(); let key = Xpub::from_str(s.trim()).unwrap();
let got = serialize(&key).unwrap(); let got = serialize(&key).unwrap();
let want = include_bytes!("data/serde/extended_pub_key_bincode") as &[_]; let want = include_bytes!("data/serde/extended_pub_key_bincode") as &[_];
assert_eq!(got, want) assert_eq!(got, want)
@ -269,7 +269,7 @@ fn serde_regression_psbt() {
version: 0, version: 0,
xpub: { xpub: {
let s = include_str!("data/serde/extended_pub_key"); let s = include_str!("data/serde/extended_pub_key");
let xpub = ExtendedPubKey::from_str(s.trim()).unwrap(); let xpub = Xpub::from_str(s.trim()).unwrap();
vec![(xpub, key_source)].into_iter().collect() vec![(xpub, key_source)].into_iter().collect()
}, },
unsigned_tx: { unsigned_tx: {