Merge rust-bitcoin/rust-bitcoin#1208: Move bip32 module to crate root

8bed2ddffe Run formmater on bip32 (Tobin C. Harding)
34113c9558 Move bip32 module to crate root (Tobin C. Harding)

Pull request description:

  We are attempting to flatten the `util` module.

  Move the `bip32` module to the crate root out of `util`.

  Currently `src/util/` is ignored by the formatter so this move requires `bip32` module to be formatted. Formatting is done as a separate patch so reviewers can run `cargo +nightly fmt` and compare the diffs if so desired.

ACKs for top commit:
  apoelstra:
    ACK 8bed2ddffe
  Kixunil:
    ACK 8bed2ddffe

Tree-SHA512: dadea31be0459fd10e71927bd21dc44b59428f695a6df7093052ca7257b6590d5dd5b1343a89869ac9f4d7805dbca7558b475048ea9387c36265f14246cc6852
This commit is contained in:
Andrew Poelstra 2022-09-21 16:45:42 +00:00
commit b1869803bf
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
3 changed files with 147 additions and 158 deletions

View File

@ -7,22 +7,24 @@
//! at <https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki>.
//!
use crate::prelude::*;
use crate::io::Write;
use core::{fmt, str::FromStr, default::Default};
use core::default::Default;
use core::fmt;
use core::ops::Index;
#[cfg(feature = "serde")] use serde;
use core::str::FromStr;
use bitcoin_internals::write_err;
use crate::hash_types::XpubIdentifier;
use crate::hashes::{sha512, Hash, HashEngine, Hmac, HmacEngine, hex};
use secp256k1::{self, Secp256k1, XOnlyPublicKey};
#[cfg(feature = "serde")]
use serde;
use crate::network::constants::Network;
use crate::util::{base58, endian, key};
use crate::util::key::{PublicKey, PrivateKey, KeyPair};
use crate::hash_types::XpubIdentifier;
use crate::hashes::{hex, sha512, Hash, HashEngine, Hmac, HmacEngine};
use crate::internal_macros::{impl_array_newtype, impl_bytes_newtype, serde_string_impl};
use crate::io::Write;
use crate::network::constants::Network;
use crate::prelude::*;
use crate::util::key::{KeyPair, PrivateKey, PublicKey};
use crate::util::{base58, endian, key};
/// A chain code
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
@ -51,7 +53,7 @@ pub struct ExtendedPrivKey {
/// Private key
pub private_key: secp256k1::SecretKey,
/// Chain code
pub chain_code: ChainCode
pub chain_code: ChainCode,
}
serde_string_impl!(ExtendedPrivKey, "a BIP-32 extended private key");
@ -84,7 +86,7 @@ pub struct ExtendedPubKey {
/// Public key
pub public_key: secp256k1::PublicKey,
/// Chain code
pub chain_code: ChainCode
pub chain_code: ChainCode,
}
serde_string_impl!(ExtendedPubKey, "a BIP-32 extended public key");
@ -94,12 +96,12 @@ pub enum ChildNumber {
/// Non-hardened key
Normal {
/// Key index, within [0, 2^31 - 1]
index: u32
index: u32,
},
/// Hardened key
Hardened {
/// Key index, within [0, 2^31 - 1]
index: u32
index: u32,
},
}
@ -131,25 +133,23 @@ impl ChildNumber {
/// Returns `true` if the child number is a [`Normal`] value.
///
/// [`Normal`]: #variant.Normal
pub fn is_normal(&self) -> bool {
!self.is_hardened()
}
pub fn is_normal(&self) -> bool { !self.is_hardened() }
/// Returns `true` if the child number is a [`Hardened`] value.
///
/// [`Hardened`]: #variant.Hardened
pub fn is_hardened(&self) -> bool {
match self {
ChildNumber::Hardened {..} => true,
ChildNumber::Normal {..} => false,
ChildNumber::Hardened { .. } => true,
ChildNumber::Normal { .. } => false,
}
}
/// Returns the child number that is a single increment from this one.
pub fn increment(self) -> Result<ChildNumber, Error> {
match self {
ChildNumber::Normal{ index: idx } => ChildNumber::from_normal_idx(idx+1),
ChildNumber::Hardened{ index: idx } => ChildNumber::from_hardened_idx(idx+1),
ChildNumber::Normal { index: idx } => ChildNumber::from_normal_idx(idx + 1),
ChildNumber::Hardened { index: idx } => ChildNumber::from_hardened_idx(idx + 1),
}
}
}
@ -180,7 +180,7 @@ impl fmt::Display for ChildNumber {
fmt::Display::fmt(&index, f)?;
let alt = f.alternate();
f.write_str(if alt { "h" } else { "'" })
},
}
ChildNumber::Normal { index } => fmt::Display::fmt(&index, f),
}
}
@ -192,7 +192,9 @@ impl FromStr for ChildNumber {
fn from_str(inp: &str) -> Result<ChildNumber, Error> {
let is_hardened = inp.chars().last().map_or(false, |l| l == '\'' || l == 'h');
Ok(if is_hardened {
ChildNumber::from_hardened_idx(inp[0..inp.len() - 1].parse().map_err(|_| Error::InvalidChildNumberFormat)?)?
ChildNumber::from_hardened_idx(
inp[0..inp.len() - 1].parse().map_err(|_| Error::InvalidChildNumberFormat)?,
)?
} else {
ChildNumber::from_normal_idx(inp.parse().map_err(|_| Error::InvalidChildNumberFormat)?)?
})
@ -240,55 +242,45 @@ where
type Output = <Vec<ChildNumber> as Index<I>>::Output;
#[inline]
fn index(&self, index: I) -> &Self::Output {
&self.0[index]
}
fn index(&self, index: I) -> &Self::Output { &self.0[index] }
}
impl Default for DerivationPath {
fn default() -> DerivationPath {
DerivationPath::master()
}
fn default() -> DerivationPath { DerivationPath::master() }
}
impl<T> IntoDerivationPath for T where T: Into<DerivationPath> {
fn into_derivation_path(self) -> Result<DerivationPath, Error> {
Ok(self.into())
}
impl<T> IntoDerivationPath for T
where
T: Into<DerivationPath>,
{
fn into_derivation_path(self) -> Result<DerivationPath, Error> { Ok(self.into()) }
}
impl IntoDerivationPath for String {
fn into_derivation_path(self) -> Result<DerivationPath, Error> {
self.parse()
}
fn into_derivation_path(self) -> Result<DerivationPath, Error> { self.parse() }
}
impl<'a> IntoDerivationPath for &'a str {
fn into_derivation_path(self) -> Result<DerivationPath, Error> {
self.parse()
}
fn into_derivation_path(self) -> Result<DerivationPath, Error> { self.parse() }
}
impl From<Vec<ChildNumber>> for DerivationPath {
fn from(numbers: Vec<ChildNumber>) -> Self {
DerivationPath(numbers)
}
fn from(numbers: Vec<ChildNumber>) -> Self { DerivationPath(numbers) }
}
impl From<DerivationPath> for Vec<ChildNumber> {
fn from(path: DerivationPath) -> Self {
path.0
}
fn from(path: DerivationPath) -> Self { path.0 }
}
impl<'a> From<&'a [ChildNumber]> for DerivationPath {
fn from(numbers: &'a [ChildNumber]) -> Self {
DerivationPath(numbers.to_vec())
}
fn from(numbers: &'a [ChildNumber]) -> Self { DerivationPath(numbers.to_vec()) }
}
impl core::iter::FromIterator<ChildNumber> for DerivationPath {
fn from_iter<T>(iter: T) -> Self where T: IntoIterator<Item=ChildNumber> {
fn from_iter<T>(iter: T) -> Self
where
T: IntoIterator<Item = ChildNumber>,
{
DerivationPath(Vec::from_iter(iter))
}
}
@ -296,15 +288,11 @@ impl core::iter::FromIterator<ChildNumber> for DerivationPath {
impl<'a> core::iter::IntoIterator for &'a DerivationPath {
type Item = &'a ChildNumber;
type IntoIter = slice::Iter<'a, ChildNumber>;
fn into_iter(self) -> Self::IntoIter {
self.0.iter()
}
fn into_iter(self) -> Self::IntoIter { self.0.iter() }
}
impl AsRef<[ChildNumber]> for DerivationPath {
fn as_ref(&self) -> &[ChildNumber] {
&self.0
}
fn as_ref(&self) -> &[ChildNumber] { &self.0 }
}
impl FromStr for DerivationPath {
@ -334,10 +322,7 @@ pub struct DerivationPathIterator<'a> {
impl<'a> DerivationPathIterator<'a> {
/// Start a new [DerivationPathIterator] at the given child.
pub fn start_from(path: &'a DerivationPath, start: ChildNumber) -> DerivationPathIterator<'a> {
DerivationPathIterator {
base: path,
next_child: Some(start),
}
DerivationPathIterator { base: path, next_child: Some(start) }
}
}
@ -353,25 +338,17 @@ impl<'a> Iterator for DerivationPathIterator<'a> {
impl DerivationPath {
/// Returns length of the derivation path
pub fn len(&self) -> usize {
self.0.len()
}
pub fn len(&self) -> usize { self.0.len() }
/// Returns `true` if the derivation path is empty
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn is_empty(&self) -> bool { self.0.is_empty() }
/// Returns derivation path for a master key (i.e. empty derivation path)
pub fn master() -> DerivationPath {
DerivationPath(vec![])
}
pub fn master() -> DerivationPath { DerivationPath(vec![]) }
/// Returns whether derivation path represents master key (i.e. it's length
/// is empty). True for `m` path.
pub fn is_master(&self) -> bool {
self.0.is_empty()
}
pub fn is_master(&self) -> bool { self.0.is_empty() }
/// Create a new [DerivationPath] that is a child of this one.
pub fn child(&self, cn: ChildNumber) -> DerivationPath {
@ -395,12 +372,12 @@ impl DerivationPath {
/// Get an [Iterator] over the unhardened children of this [DerivationPath].
pub fn normal_children(&self) -> DerivationPathIterator {
DerivationPathIterator::start_from(self, ChildNumber::Normal{ index: 0 })
DerivationPathIterator::start_from(self, ChildNumber::Normal { index: 0 })
}
/// Get an [Iterator] over the hardened children of this [DerivationPath].
pub fn hardened_children(&self) -> DerivationPathIterator {
DerivationPathIterator::start_from(self, ChildNumber::Hardened{ index: 0 })
DerivationPathIterator::start_from(self, ChildNumber::Hardened { index: 0 })
}
/// Concatenate `self` with `path` and return the resulting new path.
@ -438,9 +415,7 @@ impl fmt::Display for DerivationPath {
}
impl fmt::Debug for DerivationPath {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&self, f)
}
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&self, f) }
}
/// Full information on the used extended public key: fingerprint of the
@ -468,19 +443,23 @@ pub enum Error {
/// Base58 encoding error
Base58(base58::Error),
/// Hexadecimal decoding error
Hex(hex::Error)
Hex(hex::Error),
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Error::CannotDeriveFromHardenedKey => f.write_str("cannot derive hardened key from public key"),
Error::CannotDeriveFromHardenedKey =>
f.write_str("cannot derive hardened key from public key"),
Error::Secp256k1(ref e) => write_err!(f, "secp256k1 error"; e),
Error::InvalidChildNumber(ref n) => write!(f, "child number {} is invalid (not within [0, 2^31 - 1])", n),
Error::InvalidChildNumber(ref n) =>
write!(f, "child number {} is invalid (not within [0, 2^31 - 1])", n),
Error::InvalidChildNumberFormat => f.write_str("invalid child number format"),
Error::InvalidDerivationPathFormat => f.write_str("invalid derivation path format"),
Error::UnknownVersion(ref bytes) => write!(f, "unknown version magic bytes: {:?}", bytes),
Error::WrongExtendedKeyLength(ref len) => write!(f, "encoded extended key data has wrong length {}", len),
Error::UnknownVersion(ref bytes) =>
write!(f, "unknown version magic bytes: {:?}", bytes),
Error::WrongExtendedKeyLength(ref len) =>
write!(f, "encoded extended key data has wrong length {}", len),
Error::Base58(ref e) => write_err!(f, "base58 encoding error"; e),
Error::Hex(ref e) => write_err!(f, "Hexadecimal decoding error"; e),
}
@ -513,7 +492,7 @@ impl From<key::Error> for Error {
key::Error::Base58(e) => Error::Base58(e),
key::Error::Secp256k1(e) => Error::Secp256k1(e),
key::Error::InvalidKeyPrefix(_) => Error::Secp256k1(secp256k1::Error::InvalidPublicKey),
key::Error::Hex(e) => Error::Hex(e)
key::Error::Hex(e) => Error::Hex(e),
}
}
}
@ -523,9 +502,7 @@ impl From<secp256k1::Error> for Error {
}
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 {
@ -547,17 +524,14 @@ impl ExtendedPrivKey {
/// Constructs ECDSA compressed private key matching internal secret key representation.
pub fn to_priv(self) -> PrivateKey {
PrivateKey {
compressed: true,
network: self.network,
inner: self.private_key
}
PrivateKey { compressed: true, network: self.network, inner: 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>) -> KeyPair {
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.
@ -576,12 +550,18 @@ impl ExtendedPrivKey {
}
/// Private->Private child key derivation
pub fn ckd_priv<C: secp256k1::Signing>(&self, secp: &Secp256k1<C>, i: ChildNumber) -> Result<ExtendedPrivKey, Error> {
pub fn ckd_priv<C: secp256k1::Signing>(
&self,
secp: &Secp256k1<C>,
i: ChildNumber,
) -> Result<ExtendedPrivKey, Error> {
let mut hmac_engine: HmacEngine<sha512::Hash> = HmacEngine::new(&self.chain_code[..]);
match i {
ChildNumber::Normal { .. } => {
// Non-hardened key: compute public data and use that
hmac_engine.input(&secp256k1::PublicKey::from_secret_key(secp, &self.private_key).serialize()[..]);
hmac_engine.input(
&secp256k1::PublicKey::from_secret_key(secp, &self.private_key).serialize()[..],
);
}
ChildNumber::Hardened { .. } => {
// Hardened key: use only secret data to prevent public derivation
@ -592,8 +572,10 @@ impl ExtendedPrivKey {
hmac_engine.input(&endian::u32_to_array_be(u32::from(i)));
let hmac_result: Hmac<sha512::Hash> = Hmac::from_engine(hmac_engine);
let sk = secp256k1::SecretKey::from_slice(&hmac_result[..32]).expect("statistically impossible to hit");
let tweaked = sk.add_tweak(&self.private_key.into()).expect("statistically impossible to hit");
let sk = secp256k1::SecretKey::from_slice(&hmac_result[..32])
.expect("statistically impossible to hit");
let tweaked =
sk.add_tweak(&self.private_key.into()).expect("statistically impossible to hit");
Ok(ExtendedPrivKey {
network: self.network,
@ -601,14 +583,14 @@ impl ExtendedPrivKey {
parent_fingerprint: self.fingerprint(secp),
child_number: i,
private_key: tweaked,
chain_code: ChainCode::from(&hmac_result[32..])
chain_code: ChainCode::from(&hmac_result[32..]),
})
}
/// Decoding extended private key from binary data according to BIP 32
pub fn decode(data: &[u8]) -> Result<ExtendedPrivKey, Error> {
if data.len() != 78 {
return Err(Error::WrongExtendedKeyLength(data.len()))
return Err(Error::WrongExtendedKeyLength(data.len()));
}
let network = if data[0..4] == [0x04u8, 0x88, 0xAD, 0xE4] {
@ -634,10 +616,12 @@ impl ExtendedPrivKey {
/// Extended private key binary encoding according to BIP 32
pub fn encode(&self) -> [u8; 78] {
let mut ret = [0; 78];
ret[0..4].copy_from_slice(&match self.network {
ret[0..4].copy_from_slice(
&match self.network {
Network::Bitcoin => [0x04, 0x88, 0xAD, 0xE4],
Network::Testnet | Network::Signet | Network::Regtest => [0x04, 0x35, 0x83, 0x94],
}[..]);
}[..],
);
ret[4] = self.depth as u8;
ret[5..9].copy_from_slice(&self.parent_fingerprint[..]);
ret[9..13].copy_from_slice(&endian::u32_to_array_be(u32::from(self.child_number)));
@ -660,30 +644,26 @@ impl ExtendedPrivKey {
impl ExtendedPubKey {
/// Derives a public key from a private key
pub fn from_priv<C: secp256k1::Signing>(secp: &Secp256k1<C>, sk: &ExtendedPrivKey) -> ExtendedPubKey {
pub fn from_priv<C: secp256k1::Signing>(
secp: &Secp256k1<C>,
sk: &ExtendedPrivKey,
) -> ExtendedPubKey {
ExtendedPubKey {
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
chain_code: sk.chain_code,
}
}
/// Constructs ECDSA compressed public key matching internal public key representation.
pub fn to_pub(self) -> PublicKey {
PublicKey {
compressed: true,
inner: self.public_key
}
}
pub fn to_pub(self) -> PublicKey { PublicKey { compressed: true, inner: 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)
}
pub fn to_x_only_pub(self) -> XOnlyPublicKey { XOnlyPublicKey::from(self.public_key) }
/// Attempts to derive an extended public key from a path.
///
@ -701,13 +681,15 @@ impl ExtendedPubKey {
}
/// Compute the scalar tweak added to this key to get a child key
pub fn ckd_pub_tweak(&self, i: ChildNumber) -> Result<(secp256k1::SecretKey, ChainCode), Error> {
pub fn ckd_pub_tweak(
&self,
i: ChildNumber,
) -> Result<(secp256k1::SecretKey, ChainCode), Error> {
match i {
ChildNumber::Hardened { .. } => {
Err(Error::CannotDeriveFromHardenedKey)
}
ChildNumber::Hardened { .. } => Err(Error::CannotDeriveFromHardenedKey),
ChildNumber::Normal { index: n } => {
let mut hmac_engine: HmacEngine<sha512::Hash> = HmacEngine::new(&self.chain_code[..]);
let mut hmac_engine: HmacEngine<sha512::Hash> =
HmacEngine::new(&self.chain_code[..]);
hmac_engine.input(&self.public_key.serialize()[..]);
hmac_engine.input(&endian::u32_to_array_be(n));
@ -742,7 +724,7 @@ impl ExtendedPubKey {
/// Decoding extended public key from binary data according to BIP 32
pub fn decode(data: &[u8]) -> Result<ExtendedPubKey, Error> {
if data.len() != 78 {
return Err(Error::WrongExtendedKeyLength(data.len()))
return Err(Error::WrongExtendedKeyLength(data.len()));
}
Ok(ExtendedPubKey {
@ -766,10 +748,12 @@ impl ExtendedPubKey {
/// Extended public key binary encoding according to BIP 32
pub fn encode(&self) -> [u8; 78] {
let mut ret = [0; 78];
ret[0..4].copy_from_slice(&match self.network {
ret[0..4].copy_from_slice(
&match self.network {
Network::Bitcoin => [0x04u8, 0x88, 0xB2, 0x1E],
Network::Testnet | Network::Signet | Network::Regtest => [0x04u8, 0x35, 0x87, 0xCF],
}[..]);
}[..],
);
ret[4] = self.depth as u8;
ret[5..9].copy_from_slice(&self.parent_fingerprint[..]);
ret[9..13].copy_from_slice(&endian::u32_to_array_be(u32::from(self.child_number)));
@ -786,9 +770,7 @@ impl ExtendedPubKey {
}
/// Returns the first four bytes of the identifier
pub fn fingerprint(&self) -> Fingerprint {
Fingerprint::from(&self.identifier()[0..4])
}
pub fn fingerprint(&self) -> Fingerprint { Fingerprint::from(&self.identifier()[0..4]) }
}
impl fmt::Display for ExtendedPrivKey {
@ -832,27 +814,22 @@ impl FromStr for ExtendedPubKey {
}
impl From<ExtendedPubKey> for XpubIdentifier {
fn from(key: ExtendedPubKey) -> XpubIdentifier {
key.identifier()
}
fn from(key: ExtendedPubKey) -> XpubIdentifier { key.identifier() }
}
impl From<&ExtendedPubKey> for XpubIdentifier {
fn from(key: &ExtendedPubKey) -> XpubIdentifier {
key.identifier()
}
fn from(key: &ExtendedPubKey) -> XpubIdentifier { key.identifier() }
}
#[cfg(test)]
mod tests {
use super::*;
use super::ChildNumber::{Hardened, Normal};
use core::str::FromStr;
use secp256k1::{self, Secp256k1};
use crate::hashes::hex::FromHex;
use super::ChildNumber::{Hardened, Normal};
use super::*;
use crate::hashes::hex::FromHex;
use crate::network::constants::Network::{self, Bitcoin};
#[test]
@ -862,7 +839,10 @@ mod tests {
assert_eq!(DerivationPath::from_str("4/m/5"), Err(Error::InvalidDerivationPathFormat));
assert_eq!(DerivationPath::from_str("m//3/0'"), Err(Error::InvalidChildNumberFormat));
assert_eq!(DerivationPath::from_str("m/0h/0x"), Err(Error::InvalidChildNumberFormat));
assert_eq!(DerivationPath::from_str("m/2147483648"), Err(Error::InvalidChildNumber(2147483648)));
assert_eq!(
DerivationPath::from_str("m/2147483648"),
Err(Error::InvalidChildNumber(2147483648))
);
assert_eq!(DerivationPath::master(), DerivationPath::from_str("m").unwrap());
assert_eq!(DerivationPath::master(), DerivationPath::default());
@ -873,7 +853,11 @@ mod tests {
);
assert_eq!(
DerivationPath::from_str("m/0'/1"),
Ok(vec![ChildNumber::from_hardened_idx(0).unwrap(), ChildNumber::from_normal_idx(1).unwrap()].into())
Ok(vec![
ChildNumber::from_hardened_idx(0).unwrap(),
ChildNumber::from_normal_idx(1).unwrap()
]
.into())
);
assert_eq!(
DerivationPath::from_str("m/0h/1/2'"),
@ -881,7 +865,8 @@ mod tests {
ChildNumber::from_hardened_idx(0).unwrap(),
ChildNumber::from_normal_idx(1).unwrap(),
ChildNumber::from_hardened_idx(2).unwrap(),
].into())
]
.into())
);
assert_eq!(
DerivationPath::from_str("m/0'/1/2h/2"),
@ -890,7 +875,8 @@ mod tests {
ChildNumber::from_normal_idx(1).unwrap(),
ChildNumber::from_hardened_idx(2).unwrap(),
ChildNumber::from_normal_idx(2).unwrap(),
].into())
]
.into())
);
assert_eq!(
DerivationPath::from_str("m/0'/1/2'/2/1000000000"),
@ -900,7 +886,8 @@ mod tests {
ChildNumber::from_hardened_idx(2).unwrap(),
ChildNumber::from_normal_idx(2).unwrap(),
ChildNumber::from_normal_idx(1000000000).unwrap(),
].into())
]
.into())
);
let s = "m/0'/50/3'/5/545456";
assert_eq!(DerivationPath::from_str(s), s.into_derivation_path());
@ -913,7 +900,10 @@ mod tests {
let numbers: Vec<ChildNumber> = path.clone().into();
let path2: DerivationPath = numbers.into();
assert_eq!(path, path2);
assert_eq!(&path[..2], &[ChildNumber::from_hardened_idx(0).unwrap(), ChildNumber::from_normal_idx(1).unwrap()]);
assert_eq!(
&path[..2],
&[ChildNumber::from_hardened_idx(0).unwrap(), ChildNumber::from_normal_idx(1).unwrap()]
);
let indexed: DerivationPath = path[..2].into();
assert_eq!(indexed, DerivationPath::from_str("m/0h/1").unwrap());
assert_eq!(indexed.child(ChildNumber::from_hardened_idx(2).unwrap()), path);
@ -925,8 +915,8 @@ mod tests {
seed: &[u8],
path: DerivationPath,
expected_sk: &str,
expected_pk: &str)
{
expected_pk: &str,
) {
let mut sk = ExtendedPrivKey::new_master(network, seed).unwrap();
let mut pk = ExtendedPubKey::from_priv(secp, &sk);
@ -945,16 +935,13 @@ mod tests {
for &num in path.0.iter() {
sk = sk.ckd_priv(secp, num).unwrap();
match num {
Normal {..} => {
Normal { .. } => {
let pk2 = pk.ckd_pub(secp, num).unwrap();
pk = ExtendedPubKey::from_priv(secp, &sk);
assert_eq!(pk, pk2);
}
Hardened {..} => {
assert_eq!(
pk.ckd_pub(secp, num),
Err(Error::CannotDeriveFromHardenedKey)
);
Hardened { .. } => {
assert_eq!(pk.ckd_pub(secp, num), Err(Error::CannotDeriveFromHardenedKey));
pk = ExtendedPubKey::from_priv(secp, &sk);
}
}
@ -974,15 +961,15 @@ mod tests {
fn test_increment() {
let idx = 9345497; // randomly generated, I promise
let cn = ChildNumber::from_normal_idx(idx).unwrap();
assert_eq!(cn.increment().ok(), Some(ChildNumber::from_normal_idx(idx+1).unwrap()));
assert_eq!(cn.increment().ok(), Some(ChildNumber::from_normal_idx(idx + 1).unwrap()));
let cn = ChildNumber::from_hardened_idx(idx).unwrap();
assert_eq!(cn.increment().ok(), Some(ChildNumber::from_hardened_idx(idx+1).unwrap()));
assert_eq!(cn.increment().ok(), Some(ChildNumber::from_hardened_idx(idx + 1).unwrap()));
let max = (1<<31)-1;
let max = (1 << 31) - 1;
let cn = ChildNumber::from_normal_idx(max).unwrap();
assert_eq!(cn.increment().err(), Some(Error::InvalidChildNumber(1<<31)));
assert_eq!(cn.increment().err(), Some(Error::InvalidChildNumber(1 << 31)));
let cn = ChildNumber::from_hardened_idx(max).unwrap();
assert_eq!(cn.increment().err(), Some(Error::InvalidChildNumber(1<<31)));
assert_eq!(cn.increment().err(), Some(Error::InvalidChildNumber(1 << 31)));
let cn = ChildNumber::from_normal_idx(350).unwrap();
let path = DerivationPath::from_str("m/42'").unwrap();
@ -1099,7 +1086,6 @@ mod tests {
test_path(&secp, Bitcoin, &seed, "m/0h".parse().unwrap(),
"xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L",
"xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y");
}
#[test]
@ -1117,7 +1103,8 @@ mod tests {
#[cfg(feature = "serde")]
pub fn encode_fingerprint_chaincode() {
use serde_json;
let fp = Fingerprint::from(&[1u8,2,3,42][..]);
let fp = Fingerprint::from(&[1u8, 2, 3, 42][..]);
#[rustfmt::skip]
let cc = ChainCode::from(
&[1u8,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2][..]
);
@ -1175,7 +1162,6 @@ mod tests {
ExtendedPrivKey::from_str(xpriv_str).unwrap();
}
#[test]
#[should_panic(expected = "Secp256k1(InvalidSecretKey)")]
fn schnorr_broken_privkey_ffs() {

View File

@ -81,6 +81,7 @@ mod serde_utils;
pub mod network;
pub mod address;
pub mod bip158;
pub mod bip32;
pub mod blockdata;
pub mod consensus;
pub mod error;

View File

@ -11,7 +11,6 @@ pub mod ecdsa;
pub mod schnorr;
pub mod amount;
pub mod base58;
pub mod bip32;
pub mod bip152;
pub mod hash;
pub mod merkleblock;
@ -117,5 +116,8 @@ pub mod address {
pub use crate::address::*;
}
#[deprecated(since = "0.30.0", note = "Please use crate::bip32")]
pub use crate::bip32;
#[deprecated(since = "0.30.0", note = "Please use crate::bip158")]
pub use crate::bip158;