Merge rust-bitcoin/rust-bitcoin#3358: Add Xpriv::to_xpub and improve related method names
e215a39dba
Improve documentation of Xpub::from_xpriv (Jiri Jakes)0dcba98382
Add Xpriv::to_xpub (Jiri Jakes)5a9341bfc5
Improve naming of methods on Xpub and Xpriv (Jiri Jakes) Pull request description: Adds `Xpriv::to_xpub` and makes naming of methods related to extended and non-extended keys on `Xpub` and `Xpriv` consistent and easier to discover: - if method takes or returns extended key, its name uses `xpriv` or `xpub` - if method takes or returns non-extended key, its name uses `public_key` or `private_key` Previous naming of the methods was confusing and unclear and this PR deprecates them. Closes #3327. ### Notes for reviewers - `xpriv` and `xpub` could be without `x`, I opted for this version to remove any ambiguity - also considered `raw` or similar name (as suggested) for methods with non-extended keys, however `raw` is usually not used in this context and `to_public_key` vs. `to_x_only_public_key` did not look alright with any other name - if splitting this PR into two would be desirable, please let me know - is there a reason why `ckd_priv` is private and `ckd_pub` is public? ACKs for top commit: apoelstra: ACKe215a39dba
successfully ran local tests tcharding: ACKe215a39dba
Tree-SHA512: f76b22740b06df80dd9d01fbb991149243e47619e0bd5f1699b446456259cc6e97ecb9fca7b4881e921a9d7341ca92c6ee2dae90a417f702aff5eb760439ca42
This commit is contained in:
commit
0b8c45ff8e
|
@ -40,15 +40,15 @@ fn main() {
|
|||
|
||||
// derive child xpub
|
||||
let path = "84h/0h/0h".parse::<DerivationPath>().unwrap();
|
||||
let child = root.derive_priv(&secp, &path);
|
||||
let child = root.derive_xpriv(&secp, &path);
|
||||
println!("Child at {}: {}", path, child);
|
||||
let xpub = Xpub::from_priv(&secp, &child);
|
||||
let xpub = Xpub::from_xpriv(&secp, &child);
|
||||
println!("Public key at {}: {}", path, xpub);
|
||||
|
||||
// generate first receiving address at m/0/0
|
||||
// manually creating indexes this time
|
||||
let zero = ChildNumber::ZERO_NORMAL;
|
||||
let public_key = xpub.derive_pub(&secp, &[zero, zero]).unwrap().public_key;
|
||||
let public_key = xpub.derive_xpub(&secp, &[zero, zero]).unwrap().public_key;
|
||||
let address = Address::p2wpkh(CompressedPublicKey(public_key), KnownHrp::Mainnet);
|
||||
println!("First receiving address: {}", address);
|
||||
}
|
||||
|
|
|
@ -60,11 +60,11 @@ fn get_external_address_xpriv<C: Signing>(
|
|||
) -> Xpriv {
|
||||
let derivation_path =
|
||||
BIP84_DERIVATION_PATH.into_derivation_path().expect("valid derivation path");
|
||||
let child_xpriv = master_xpriv.derive_priv(secp, &derivation_path);
|
||||
let child_xpriv = master_xpriv.derive_xpriv(secp, &derivation_path);
|
||||
let external_index = ChildNumber::ZERO_NORMAL;
|
||||
let idx = ChildNumber::from_normal_idx(index).expect("valid index number");
|
||||
|
||||
child_xpriv.derive_priv(secp, &[external_index, idx])
|
||||
child_xpriv.derive_xpriv(secp, &[external_index, idx])
|
||||
}
|
||||
|
||||
// Derive the internal address xpriv.
|
||||
|
@ -75,11 +75,11 @@ fn get_internal_address_xpriv<C: Signing>(
|
|||
) -> Xpriv {
|
||||
let derivation_path =
|
||||
BIP84_DERIVATION_PATH.into_derivation_path().expect("valid derivation path");
|
||||
let child_xpriv = master_xpriv.derive_priv(secp, &derivation_path);
|
||||
let child_xpriv = master_xpriv.derive_xpriv(secp, &derivation_path);
|
||||
let internal_index = ChildNumber::ONE_NORMAL;
|
||||
let idx = ChildNumber::from_normal_idx(index).expect("valid index number");
|
||||
|
||||
child_xpriv.derive_priv(secp, &[internal_index, idx])
|
||||
child_xpriv.derive_xpriv(secp, &[internal_index, idx])
|
||||
}
|
||||
|
||||
// The address to send to.
|
||||
|
@ -133,10 +133,10 @@ fn main() {
|
|||
let xpriv_change = get_internal_address_xpriv(&secp, master_xpriv, 1);
|
||||
|
||||
// Get the PKs
|
||||
let pk_input_1 = Xpub::from_priv(&secp, &xpriv_input_1).to_pub();
|
||||
let pk_input_2 = Xpub::from_priv(&secp, &xpriv_input_2).to_pub();
|
||||
let pk_input_1 = Xpub::from_xpriv(&secp, &xpriv_input_1).to_public_key();
|
||||
let pk_input_2 = Xpub::from_xpriv(&secp, &xpriv_input_2).to_public_key();
|
||||
let pk_inputs = [pk_input_1, pk_input_2];
|
||||
let pk_change = Xpub::from_priv(&secp, &xpriv_change).to_pub();
|
||||
let pk_change = Xpub::from_xpriv(&secp, &xpriv_change).to_public_key();
|
||||
|
||||
// Get the Witness Public Key Hashes (WPKHs)
|
||||
let wpkhs: Vec<WPubkeyHash> = pk_inputs.iter().map(|pk| pk.wpubkey_hash()).collect();
|
||||
|
|
|
@ -112,17 +112,17 @@ impl ColdStorage {
|
|||
/// 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> {
|
||||
let master_xpriv = xpriv.parse::<Xpriv>()?;
|
||||
let master_xpub = Xpub::from_priv(secp, &master_xpriv);
|
||||
let master_xpub = Xpub::from_xpriv(secp, &master_xpriv);
|
||||
|
||||
// Hardened children require secret data to derive.
|
||||
|
||||
let path = "84h/0h/0h".into_derivation_path()?;
|
||||
let account_0_xpriv = master_xpriv.derive_priv(secp, &path);
|
||||
let account_0_xpub = Xpub::from_priv(secp, &account_0_xpriv);
|
||||
let account_0_xpriv = master_xpriv.derive_xpriv(secp, &path);
|
||||
let account_0_xpub = Xpub::from_xpriv(secp, &account_0_xpriv);
|
||||
|
||||
let path = INPUT_UTXO_DERIVATION_PATH.into_derivation_path()?;
|
||||
let input_xpriv = master_xpriv.derive_priv(secp, &path);
|
||||
let input_xpub = Xpub::from_priv(secp, &input_xpriv);
|
||||
let input_xpriv = master_xpriv.derive_xpriv(secp, &path);
|
||||
let input_xpub = Xpub::from_xpriv(secp, &input_xpriv);
|
||||
|
||||
let wallet = ColdStorage { master_xpriv, master_xpub };
|
||||
let fingerprint = wallet.master_fingerprint();
|
||||
|
@ -205,7 +205,7 @@ impl WatchOnly {
|
|||
fn update_psbt(&self, mut psbt: Psbt) -> Result<Psbt> {
|
||||
let mut input = Input { witness_utxo: Some(previous_output()), ..Default::default() };
|
||||
|
||||
let pk = self.input_xpub.to_pub();
|
||||
let pk = self.input_xpub.to_public_key();
|
||||
let wpkh = pk.wpubkey_hash();
|
||||
|
||||
let redeem_script = ScriptBuf::new_p2wpkh(wpkh);
|
||||
|
@ -235,7 +235,7 @@ impl WatchOnly {
|
|||
let sigs: Vec<_> = psbt.inputs[0].partial_sigs.values().collect();
|
||||
let mut script_witness: Witness = Witness::new();
|
||||
script_witness.push(sigs[0].serialize());
|
||||
script_witness.push(self.input_xpub.to_pub().to_bytes());
|
||||
script_witness.push(self.input_xpub.to_public_key().to_bytes());
|
||||
|
||||
psbt.inputs[0].final_script_witness = Some(script_witness);
|
||||
|
||||
|
@ -258,9 +258,9 @@ impl WatchOnly {
|
|||
secp: &Secp256k1<C>,
|
||||
) -> Result<(CompressedPublicKey, Address, DerivationPath)> {
|
||||
let path = [ChildNumber::ONE_NORMAL, ChildNumber::ZERO_NORMAL];
|
||||
let derived = self.account_0_xpub.derive_pub(secp, &path)?;
|
||||
let derived = self.account_0_xpub.derive_xpub(secp, &path)?;
|
||||
|
||||
let pk = derived.to_pub();
|
||||
let pk = derived.to_public_key();
|
||||
let addr = Address::p2wpkh(pk, NETWORK);
|
||||
let path = path.into_derivation_path()?;
|
||||
|
||||
|
|
|
@ -59,11 +59,11 @@ fn get_external_address_xpriv<C: Signing>(
|
|||
) -> Xpriv {
|
||||
let derivation_path =
|
||||
BIP86_DERIVATION_PATH.into_derivation_path().expect("valid derivation path");
|
||||
let child_xpriv = master_xpriv.derive_priv(secp, &derivation_path);
|
||||
let child_xpriv = master_xpriv.derive_xpriv(secp, &derivation_path);
|
||||
let external_index = ChildNumber::ZERO_NORMAL;
|
||||
let idx = ChildNumber::from_normal_idx(index).expect("valid index number");
|
||||
|
||||
child_xpriv.derive_priv(secp, &[external_index, idx])
|
||||
child_xpriv.derive_xpriv(secp, &[external_index, idx])
|
||||
}
|
||||
|
||||
// Derive the internal address xpriv.
|
||||
|
@ -74,11 +74,11 @@ fn get_internal_address_xpriv<C: Signing>(
|
|||
) -> Xpriv {
|
||||
let derivation_path =
|
||||
BIP86_DERIVATION_PATH.into_derivation_path().expect("valid derivation path");
|
||||
let child_xpriv = master_xpriv.derive_priv(secp, &derivation_path);
|
||||
let child_xpriv = master_xpriv.derive_xpriv(secp, &derivation_path);
|
||||
let internal_index = ChildNumber::ONE_NORMAL;
|
||||
let idx = ChildNumber::from_normal_idx(index).expect("valid index number");
|
||||
|
||||
child_xpriv.derive_priv(secp, &[internal_index, idx])
|
||||
child_xpriv.derive_xpriv(secp, &[internal_index, idx])
|
||||
}
|
||||
|
||||
// Get the Taproot Key Origin.
|
||||
|
@ -143,9 +143,9 @@ fn main() {
|
|||
let xpriv_change = get_internal_address_xpriv(&secp, master_xpriv, 1);
|
||||
|
||||
// Get the PKs
|
||||
let (pk_input_1, _) = Xpub::from_priv(&secp, &xpriv_input_1).public_key.x_only_public_key();
|
||||
let (pk_input_2, _) = Xpub::from_priv(&secp, &xpriv_input_2).public_key.x_only_public_key();
|
||||
let (pk_change, _) = Xpub::from_priv(&secp, &xpriv_change).public_key.x_only_public_key();
|
||||
let (pk_input_1, _) = Xpub::from_xpriv(&secp, &xpriv_input_1).public_key.x_only_public_key();
|
||||
let (pk_input_2, _) = Xpub::from_xpriv(&secp, &xpriv_input_2).public_key.x_only_public_key();
|
||||
let (pk_change, _) = Xpub::from_xpriv(&secp, &xpriv_change).public_key.x_only_public_key();
|
||||
|
||||
// Get the Tap Key Origins
|
||||
// Map of tap root X-only keys to origin info and leaf hashes contained in it.
|
||||
|
|
|
@ -297,7 +297,7 @@ fn generate_bip86_key_spend_tx(
|
|||
.get(&input.tap_internal_key.ok_or("internal key missing in PSBT")?)
|
||||
.ok_or("missing Taproot key origin")?;
|
||||
|
||||
let secret_key = master_xpriv.derive_priv(secp, &derivation_path).to_priv().inner;
|
||||
let secret_key = master_xpriv.derive_xpriv(secp, &derivation_path).to_private_key().inner;
|
||||
sign_psbt_taproot(
|
||||
secret_key,
|
||||
input.tap_internal_key.unwrap(),
|
||||
|
@ -392,9 +392,9 @@ impl BenefactorWallet {
|
|||
// that we use an unhardened path so we can make use of xpubs.
|
||||
let derivation_path = format!("101/1/0/0/{}", self.next).parse::<DerivationPath>()?;
|
||||
let internal_keypair =
|
||||
self.master_xpriv.derive_priv(&self.secp, &derivation_path).to_keypair(&self.secp);
|
||||
self.master_xpriv.derive_xpriv(&self.secp, &derivation_path).to_keypair(&self.secp);
|
||||
let beneficiary_key =
|
||||
self.beneficiary_xpub.derive_pub(&self.secp, &derivation_path)?.to_x_only_pub();
|
||||
self.beneficiary_xpub.derive_xpub(&self.secp, &derivation_path)?.to_x_only_public_key();
|
||||
|
||||
// Build up the leaf script and combine with internal key into a Taproot commitment
|
||||
let script = Self::time_lock_script(lock_time, beneficiary_key);
|
||||
|
@ -482,10 +482,10 @@ impl BenefactorWallet {
|
|||
format!("101/1/0/0/{}", self.next).parse::<DerivationPath>()?;
|
||||
let new_internal_keypair = self
|
||||
.master_xpriv
|
||||
.derive_priv(&self.secp, &new_derivation_path)
|
||||
.derive_xpriv(&self.secp, &new_derivation_path)
|
||||
.to_keypair(&self.secp);
|
||||
let beneficiary_key =
|
||||
self.beneficiary_xpub.derive_pub(&self.secp, &new_derivation_path)?.to_x_only_pub();
|
||||
self.beneficiary_xpub.derive_xpub(&self.secp, &new_derivation_path)?.to_x_only_public_key();
|
||||
|
||||
// Build up the leaf script and combine with internal key into a Taproot commitment
|
||||
let lock_time = absolute::LockTime::from_height(
|
||||
|
@ -531,7 +531,7 @@ impl BenefactorWallet {
|
|||
.get(&input.tap_internal_key.ok_or("internal key missing in PSBT")?)
|
||||
.ok_or("missing Taproot key origin")?;
|
||||
let secret_key =
|
||||
self.master_xpriv.derive_priv(&self.secp, &derivation_path).to_priv().inner;
|
||||
self.master_xpriv.derive_xpriv(&self.secp, &derivation_path).to_private_key().inner;
|
||||
sign_psbt_taproot(
|
||||
secret_key,
|
||||
spend_info.internal_key(),
|
||||
|
@ -628,7 +628,7 @@ impl BeneficiaryWallet {
|
|||
Ok(Self { master_xpriv, secp: Secp256k1::new() })
|
||||
}
|
||||
|
||||
fn master_xpub(&self) -> Xpub { Xpub::from_priv(&self.secp, &self.master_xpriv) }
|
||||
fn master_xpub(&self) -> Xpub { Xpub::from_xpriv(&self.secp, &self.master_xpriv) }
|
||||
|
||||
fn spend_inheritance(
|
||||
&self,
|
||||
|
@ -652,7 +652,7 @@ impl BeneficiaryWallet {
|
|||
&psbt.inputs[0].tap_key_origins.clone()
|
||||
{
|
||||
let secret_key =
|
||||
self.master_xpriv.derive_priv(&self.secp, &derivation_path).to_priv().inner;
|
||||
self.master_xpriv.derive_xpriv(&self.secp, &derivation_path).to_private_key().inner;
|
||||
for lh in leaf_hashes {
|
||||
let sighash_type = TapSighashType::All;
|
||||
let hash = SighashCache::new(&unsigned_tx).taproot_script_spend_signature_hash(
|
||||
|
|
|
@ -592,10 +592,21 @@ impl Xpriv {
|
|||
}
|
||||
|
||||
/// Constructs ECDSA compressed private key matching internal secret key representation.
|
||||
#[deprecated(since = "TBD", note = "use `to_private_key()`")]
|
||||
pub fn to_priv(self) -> PrivateKey {
|
||||
self.to_private_key()
|
||||
}
|
||||
|
||||
/// Constructs ECDSA compressed private key matching internal secret key representation.
|
||||
pub fn to_private_key(self) -> PrivateKey {
|
||||
PrivateKey { compressed: true, network: self.network, inner: self.private_key }
|
||||
}
|
||||
|
||||
/// Creates new extended public key from this extended private key.
|
||||
pub fn to_xpub<C: secp256k1::Signing>(&self, secp: &Secp256k1<C>,) -> Xpub {
|
||||
Xpub::from_xpriv(secp, self)
|
||||
}
|
||||
|
||||
/// Constructs BIP340 keypair for Schnorr signatures and Taproot use matching the internal
|
||||
/// secret key representation.
|
||||
pub fn to_keypair<C: secp256k1::Signing>(self, secp: &Secp256k1<C>) -> Keypair {
|
||||
|
@ -606,10 +617,22 @@ impl Xpriv {
|
|||
/// Derives an extended private key from a path.
|
||||
///
|
||||
/// The `path` argument can be both of type `DerivationPath` or `Vec<ChildNumber>`.
|
||||
#[deprecated(since = "TBD", note = "use `derive_xpriv()`")]
|
||||
pub fn derive_priv<C: secp256k1::Signing, P: AsRef<[ChildNumber]>>(
|
||||
&self,
|
||||
secp: &Secp256k1<C>,
|
||||
path: &P,
|
||||
) -> Xpriv {
|
||||
self.derive_xpriv(secp, path)
|
||||
}
|
||||
|
||||
/// Derives an extended private key from a path.
|
||||
///
|
||||
/// The `path` argument can be both of type `DerivationPath` or `Vec<ChildNumber>`.
|
||||
pub fn derive_xpriv<C: secp256k1::Signing, P: AsRef<[ChildNumber]>>(
|
||||
&self,
|
||||
secp: &Secp256k1<C>,
|
||||
path: &P,
|
||||
) -> Xpriv {
|
||||
let mut sk: Xpriv = *self;
|
||||
for cnum in path.as_ref() {
|
||||
|
@ -699,7 +722,7 @@ impl Xpriv {
|
|||
|
||||
/// Returns the HASH160 of the public key belonging to the xpriv
|
||||
pub fn identifier<C: secp256k1::Signing>(&self, secp: &Secp256k1<C>) -> XKeyIdentifier {
|
||||
Xpub::from_priv(secp, self).identifier()
|
||||
Xpub::from_xpriv(secp, self).identifier()
|
||||
}
|
||||
|
||||
/// Returns the first four bytes of the identifier
|
||||
|
@ -709,33 +732,61 @@ impl Xpriv {
|
|||
}
|
||||
|
||||
impl Xpub {
|
||||
/// Derives a public key from a private key
|
||||
/// Creates extended public key from an extended private key.
|
||||
#[deprecated(since = "TBD", note = "use `from_xpriv()`")]
|
||||
pub fn from_priv<C: secp256k1::Signing>(secp: &Secp256k1<C>, sk: &Xpriv) -> Xpub {
|
||||
Self::from_xpriv(secp, sk)
|
||||
}
|
||||
|
||||
/// Creates extended public key from an extended private key.
|
||||
pub fn from_xpriv<C: secp256k1::Signing>(secp: &Secp256k1<C>, xpriv: &Xpriv) -> Xpub {
|
||||
Xpub {
|
||||
network: sk.network,
|
||||
depth: sk.depth,
|
||||
parent_fingerprint: sk.parent_fingerprint,
|
||||
child_number: sk.child_number,
|
||||
public_key: secp256k1::PublicKey::from_secret_key(secp, &sk.private_key),
|
||||
chain_code: sk.chain_code,
|
||||
network: xpriv.network,
|
||||
depth: xpriv.depth,
|
||||
parent_fingerprint: xpriv.parent_fingerprint,
|
||||
child_number: xpriv.child_number,
|
||||
public_key: secp256k1::PublicKey::from_secret_key(secp, &xpriv.private_key),
|
||||
chain_code: xpriv.chain_code,
|
||||
}
|
||||
}
|
||||
|
||||
/// Constructs ECDSA compressed public key matching internal public key representation.
|
||||
pub fn to_pub(self) -> CompressedPublicKey { CompressedPublicKey(self.public_key) }
|
||||
#[deprecated(since = "TBD", note = "use `to_public_key()`")]
|
||||
pub fn to_pub(self) -> CompressedPublicKey { self.to_public_key() }
|
||||
|
||||
/// Constructs ECDSA compressed public key matching internal public key representation.
|
||||
pub fn to_public_key(self) -> CompressedPublicKey { CompressedPublicKey(self.public_key) }
|
||||
|
||||
/// Constructs BIP340 x-only public key for BIP-340 signatures and Taproot use matching
|
||||
/// the internal public key representation.
|
||||
pub fn to_x_only_pub(self) -> XOnlyPublicKey { XOnlyPublicKey::from(self.public_key) }
|
||||
#[deprecated(since = "TBD", note = "use `to_x_only_public_key()`")]
|
||||
pub fn to_x_only_pub(self) -> XOnlyPublicKey { self.to_x_only_public_key() }
|
||||
|
||||
/// Constructs BIP340 x-only public key for BIP-340 signatures and Taproot use matching
|
||||
/// the internal public key representation.
|
||||
pub fn to_x_only_public_key(self) -> XOnlyPublicKey { XOnlyPublicKey::from(self.public_key) }
|
||||
|
||||
/// Attempts to derive an extended public key from a path.
|
||||
///
|
||||
/// The `path` argument can be any type implementing `AsRef<ChildNumber>`, such as `DerivationPath`, for instance.
|
||||
#[deprecated(since = "TBD", note = "use `derive_xpub()`")]
|
||||
pub fn derive_pub<C: secp256k1::Verification, P: AsRef<[ChildNumber]>>(
|
||||
&self,
|
||||
secp: &Secp256k1<C>,
|
||||
path: &P,
|
||||
) -> Result<Xpub, Error> {
|
||||
|
||||
self.derive_xpub(secp, path)
|
||||
}
|
||||
|
||||
/// Attempts to derive an extended public key from a path.
|
||||
///
|
||||
/// The `path` argument can be any type implementing `AsRef<ChildNumber>`, such as `DerivationPath`, for instance.
|
||||
pub fn derive_xpub<C: secp256k1::Verification, P: AsRef<[ChildNumber]>>(
|
||||
&self,
|
||||
secp: &Secp256k1<C>,
|
||||
path: &P,
|
||||
) -> Result<Xpub, Error> {
|
||||
let mut pk: Xpub = *self;
|
||||
for cnum in path.as_ref() {
|
||||
pk = pk.ckd_pub(secp, *cnum)?
|
||||
|
@ -1004,17 +1055,17 @@ mod tests {
|
|||
expected_pk: &str,
|
||||
) {
|
||||
let mut sk = Xpriv::new_master(network, seed).unwrap();
|
||||
let mut pk = Xpub::from_priv(secp, &sk);
|
||||
let mut pk = Xpub::from_xpriv(secp, &sk);
|
||||
|
||||
// Check derivation convenience method for Xpriv
|
||||
assert_eq!(&sk.derive_priv(secp, &path).to_string()[..], expected_sk);
|
||||
assert_eq!(&sk.derive_xpriv(secp, &path).to_string()[..], expected_sk);
|
||||
|
||||
// Check derivation convenience method for Xpub, should error
|
||||
// appropriately if any ChildNumber 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_xpub(secp, &path), Err(Error::CannotDeriveFromHardenedKey));
|
||||
} else {
|
||||
assert_eq!(&pk.derive_pub(secp, &path).unwrap().to_string()[..], expected_pk);
|
||||
assert_eq!(&pk.derive_xpub(secp, &path).unwrap().to_string()[..], expected_pk);
|
||||
}
|
||||
|
||||
// Derive keys, checking hardened and non-hardened derivation one-by-one
|
||||
|
@ -1023,12 +1074,12 @@ mod tests {
|
|||
match num {
|
||||
Normal { .. } => {
|
||||
let pk2 = pk.ckd_pub(secp, num).unwrap();
|
||||
pk = Xpub::from_priv(secp, &sk);
|
||||
pk = Xpub::from_xpriv(secp, &sk);
|
||||
assert_eq!(pk, pk2);
|
||||
}
|
||||
Hardened { .. } => {
|
||||
assert_eq!(pk.ckd_pub(secp, num), Err(Error::CannotDeriveFromHardenedKey));
|
||||
pk = Xpub::from_priv(secp, &sk);
|
||||
pk = Xpub::from_xpriv(secp, &sk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -762,15 +762,15 @@ impl GetKey for Xpriv {
|
|||
KeyRequest::Pubkey(_) => Err(GetKeyError::NotSupported),
|
||||
KeyRequest::Bip32((fingerprint, path)) => {
|
||||
let key = if self.fingerprint(secp) == *fingerprint {
|
||||
let k = self.derive_priv(secp, &path);
|
||||
Some(k.to_priv())
|
||||
let k = self.derive_xpriv(secp, &path);
|
||||
Some(k.to_private_key())
|
||||
} else if self.parent_fingerprint == *fingerprint
|
||||
&& !path.is_empty()
|
||||
&& path[0] == self.child_number
|
||||
{
|
||||
let path = DerivationPath::from_iter(path.into_iter().skip(1).copied());
|
||||
let k = self.derive_priv(secp, &path);
|
||||
Some(k.to_priv())
|
||||
let k = self.derive_xpriv(secp, &path);
|
||||
Some(k.to_private_key())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
@ -1369,9 +1369,9 @@ mod tests {
|
|||
ChildNumber::from_normal_idx(31337).unwrap(),
|
||||
];
|
||||
|
||||
sk = sk.derive_priv(secp, &dpath);
|
||||
sk = sk.derive_xpriv(secp, &dpath);
|
||||
|
||||
let pk = Xpub::from_priv(secp, &sk);
|
||||
let pk = Xpub::from_xpriv(secp, &sk);
|
||||
|
||||
hd_keypaths.insert(pk.public_key, (fprint, dpath.into()));
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ fn bip174_psbt_workflow() {
|
|||
//
|
||||
|
||||
let ext_priv = build_extended_private_key();
|
||||
let ext_pub = Xpub::from_priv(&secp, &ext_priv);
|
||||
let ext_pub = Xpub::from_xpriv(&secp, &ext_priv);
|
||||
let parent_fingerprint = ext_pub.fingerprint();
|
||||
|
||||
//
|
||||
|
@ -315,7 +315,7 @@ fn parse_and_verify_keys(
|
|||
|
||||
let path =
|
||||
derivation_path.into_derivation_path().expect("failed to convert derivation path");
|
||||
let derived_priv = ext_priv.derive_priv(secp, &path).to_priv();
|
||||
let derived_priv = ext_priv.derive_xpriv(secp, &path).to_private_key();
|
||||
assert_eq!(wif_priv, derived_priv);
|
||||
let derived_pub = derived_priv.public_key(secp);
|
||||
key_map.insert(derived_pub, derived_priv);
|
||||
|
|
Loading…
Reference in New Issue