BIP32 extended key `to_ecdsa()` and `to_schnorr()` methods
This commit is contained in:
parent
b72f56c4ae
commit
e6a3d603c9
|
@ -49,7 +49,7 @@ fn main() {
|
||||||
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_private(&secp, &child);
|
let xpub = ExtendedPubKey::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
|
||||||
|
|
|
@ -25,11 +25,11 @@ use core::{fmt, str::FromStr, default::Default};
|
||||||
|
|
||||||
use hash_types::XpubIdentifier;
|
use hash_types::XpubIdentifier;
|
||||||
use hashes::{sha512, Hash, HashEngine, Hmac, HmacEngine};
|
use hashes::{sha512, Hash, HashEngine, Hmac, HmacEngine};
|
||||||
use secp256k1::{self, Secp256k1};
|
use secp256k1::{self, Secp256k1, XOnlyPublicKey};
|
||||||
|
|
||||||
use network::constants::Network;
|
use network::constants::Network;
|
||||||
use util::{base58, endian};
|
use util::{base58, endian};
|
||||||
use util::key;
|
use util::{key, ecdsa, schnorr};
|
||||||
use io::Write;
|
use io::Write;
|
||||||
|
|
||||||
/// A chain code
|
/// A chain code
|
||||||
|
@ -527,6 +527,21 @@ impl ExtendedPrivKey {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Constructs ECDSA compressed private key matching internal secret key representation.
|
||||||
|
pub fn to_priv(&self) -> ecdsa::PrivateKey {
|
||||||
|
ecdsa::PrivateKey {
|
||||||
|
compressed: true,
|
||||||
|
network: self.network,
|
||||||
|
key: self.private_key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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>) -> schnorr::KeyPair {
|
||||||
|
schnorr::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.
|
||||||
///
|
///
|
||||||
/// The `path` argument can be both of type `DerivationPath` or `Vec<ChildNumber>`.
|
/// The `path` argument can be both of type `DerivationPath` or `Vec<ChildNumber>`.
|
||||||
|
@ -616,7 +631,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_private(secp, self).identifier()
|
ExtendedPubKey::from_priv(secp, self).identifier()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the first four bytes of the identifier
|
/// Returns the first four bytes of the identifier
|
||||||
|
@ -627,7 +642,13 @@ impl ExtendedPrivKey {
|
||||||
|
|
||||||
impl ExtendedPubKey {
|
impl ExtendedPubKey {
|
||||||
/// Derives a public key from a private key
|
/// Derives a public key from a private key
|
||||||
|
#[deprecated(since = "0.28.0", note = "use ExtendedPubKey::from_priv")]
|
||||||
pub fn from_private<C: secp256k1::Signing>(secp: &Secp256k1<C>, sk: &ExtendedPrivKey) -> ExtendedPubKey {
|
pub fn from_private<C: secp256k1::Signing>(secp: &Secp256k1<C>, sk: &ExtendedPrivKey) -> ExtendedPubKey {
|
||||||
|
ExtendedPubKey::from_priv(secp, sk)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Derives a public key from a private key
|
||||||
|
pub fn from_priv<C: secp256k1::Signing>(secp: &Secp256k1<C>, sk: &ExtendedPrivKey) -> ExtendedPubKey {
|
||||||
ExtendedPubKey {
|
ExtendedPubKey {
|
||||||
network: sk.network,
|
network: sk.network,
|
||||||
depth: sk.depth,
|
depth: sk.depth,
|
||||||
|
@ -638,6 +659,20 @@ impl ExtendedPubKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Constructs ECDSA compressed public key matching internal public key representation.
|
||||||
|
pub fn to_pub(&self) -> ecdsa::PublicKey {
|
||||||
|
ecdsa::PublicKey {
|
||||||
|
compressed: true,
|
||||||
|
key: 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)
|
||||||
|
}
|
||||||
|
|
||||||
/// Attempts to derive an extended public key from a path.
|
/// Attempts to derive an extended public key from a path.
|
||||||
///
|
///
|
||||||
/// The `path` argument can be both of type `DerivationPath` or `Vec<ChildNumber>`.
|
/// The `path` argument can be both of type `DerivationPath` or `Vec<ChildNumber>`.
|
||||||
|
@ -869,7 +904,7 @@ mod tests {
|
||||||
expected_pk: &str) {
|
expected_pk: &str) {
|
||||||
|
|
||||||
let mut sk = ExtendedPrivKey::new_master(network, seed).unwrap();
|
let mut sk = ExtendedPrivKey::new_master(network, seed).unwrap();
|
||||||
let mut pk = ExtendedPubKey::from_private(secp, &sk);
|
let mut pk = ExtendedPubKey::from_priv(secp, &sk);
|
||||||
|
|
||||||
// Check derivation convenience method for ExtendedPrivKey
|
// Check derivation convenience method for ExtendedPrivKey
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -897,7 +932,7 @@ 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_private(secp, &sk);
|
pk = ExtendedPubKey::from_priv(secp, &sk);
|
||||||
assert_eq!(pk, pk2);
|
assert_eq!(pk, pk2);
|
||||||
}
|
}
|
||||||
Hardened {..} => {
|
Hardened {..} => {
|
||||||
|
@ -905,7 +940,7 @@ mod tests {
|
||||||
pk.ckd_pub(secp, num),
|
pk.ckd_pub(secp, num),
|
||||||
Err(Error::CannotDeriveFromHardenedKey)
|
Err(Error::CannotDeriveFromHardenedKey)
|
||||||
);
|
);
|
||||||
pk = ExtendedPubKey::from_private(secp, &sk);
|
pk = ExtendedPubKey::from_priv(secp, &sk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -310,7 +310,7 @@ mod tests {
|
||||||
|
|
||||||
sk = sk.derive_priv(secp, &dpath).unwrap();
|
sk = sk.derive_priv(secp, &dpath).unwrap();
|
||||||
|
|
||||||
let pk: ExtendedPubKey = ExtendedPubKey::from_private(&secp, &sk);
|
let pk: ExtendedPubKey = ExtendedPubKey::from_priv(&secp, &sk);
|
||||||
|
|
||||||
hd_keypaths.insert(pk.public_key, (fprint, dpath.into()));
|
hd_keypaths.insert(pk.public_key, (fprint, dpath.into()));
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue