qtum/
bip32.rs

1// Written in 2014 by Andrew Poelstra <apoelstra@wpsoftware.net>
2// SPDX-License-Identifier: CC0-1.0
3
4//! BIP32 implementation.
5//!
6//! Implementation of BIP32 hierarchical deterministic wallets, as defined
7//! at <https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki>.
8//!
9
10use core::convert::TryInto;
11use core::default::Default;
12use core::fmt;
13use core::ops::Index;
14use core::str::FromStr;
15
16use bitcoin_internals::{impl_array_newtype, write_err};
17use secp256k1::{self, Secp256k1, XOnlyPublicKey};
18#[cfg(feature = "serde")]
19use serde;
20
21use crate::base58;
22use crate::crypto::key::{self, KeyPair, PrivateKey, PublicKey};
23use crate::hash_types::XpubIdentifier;
24use crate::hashes::{hex, sha512, Hash, HashEngine, Hmac, HmacEngine};
25use crate::internal_macros::impl_bytes_newtype;
26use crate::io::Write;
27use crate::network::constants::Network;
28use crate::prelude::*;
29
30/// A chain code
31#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
32pub struct ChainCode([u8; 32]);
33impl_array_newtype!(ChainCode, u8, 32);
34impl_bytes_newtype!(ChainCode, 32);
35
36impl ChainCode {
37    fn from_hmac(hmac: Hmac<sha512::Hash>) -> Self {
38        hmac[32..].try_into().expect("half of hmac is guaranteed to be 32 bytes")
39    }
40}
41
42/// A fingerprint
43#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
44pub struct Fingerprint([u8; 4]);
45impl_array_newtype!(Fingerprint, u8, 4);
46impl_bytes_newtype!(Fingerprint, 4);
47
48/// Extended private key
49#[derive(Copy, Clone, PartialEq, Eq)]
50#[cfg_attr(feature = "std", derive(Debug))]
51pub struct ExtendedPrivKey {
52    /// The network this key is to be used on
53    pub network: Network,
54    /// How many derivations this key is from the master (which is 0)
55    pub depth: u8,
56    /// Fingerprint of the parent key (0 for master)
57    pub parent_fingerprint: Fingerprint,
58    /// Child number of the key used to derive from parent (0 for master)
59    pub child_number: ChildNumber,
60    /// Private key
61    pub private_key: secp256k1::SecretKey,
62    /// Chain code
63    pub chain_code: ChainCode,
64}
65#[cfg(feature = "serde")]
66crate::serde_utils::serde_string_impl!(ExtendedPrivKey, "a BIP-32 extended private key");
67
68#[cfg(not(feature = "std"))]
69#[cfg_attr(docsrs, doc(cfg(not(feature = "std"))))]
70impl fmt::Debug for ExtendedPrivKey {
71    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
72        f.debug_struct("ExtendedPrivKey")
73            .field("network", &self.network)
74            .field("depth", &self.depth)
75            .field("parent_fingerprint", &self.parent_fingerprint)
76            .field("child_number", &self.child_number)
77            .field("chain_code", &self.chain_code)
78            .field("private_key", &"[SecretKey]")
79            .finish()
80    }
81}
82
83/// Extended public key
84#[derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord, Hash)]
85pub struct ExtendedPubKey {
86    /// The network this key is to be used on
87    pub network: Network,
88    /// How many derivations this key is from the master (which is 0)
89    pub depth: u8,
90    /// Fingerprint of the parent key
91    pub parent_fingerprint: Fingerprint,
92    /// Child number of the key used to derive from parent (0 for master)
93    pub child_number: ChildNumber,
94    /// Public key
95    pub public_key: secp256k1::PublicKey,
96    /// Chain code
97    pub chain_code: ChainCode,
98}
99#[cfg(feature = "serde")]
100crate::serde_utils::serde_string_impl!(ExtendedPubKey, "a BIP-32 extended public key");
101
102/// A child number for a derived key
103#[derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord, Hash)]
104pub enum ChildNumber {
105    /// Non-hardened key
106    Normal {
107        /// Key index, within [0, 2^31 - 1]
108        index: u32,
109    },
110    /// Hardened key
111    Hardened {
112        /// Key index, within [0, 2^31 - 1]
113        index: u32,
114    },
115}
116
117impl ChildNumber {
118    /// Create a [`Normal`] from an index, returns an error if the index is not within
119    /// [0, 2^31 - 1].
120    ///
121    /// [`Normal`]: #variant.Normal
122    pub fn from_normal_idx(index: u32) -> Result<Self, Error> {
123        if index & (1 << 31) == 0 {
124            Ok(ChildNumber::Normal { index })
125        } else {
126            Err(Error::InvalidChildNumber(index))
127        }
128    }
129
130    /// Create a [`Hardened`] from an index, returns an error if the index is not within
131    /// [0, 2^31 - 1].
132    ///
133    /// [`Hardened`]: #variant.Hardened
134    pub fn from_hardened_idx(index: u32) -> Result<Self, Error> {
135        if index & (1 << 31) == 0 {
136            Ok(ChildNumber::Hardened { index })
137        } else {
138            Err(Error::InvalidChildNumber(index))
139        }
140    }
141
142    /// Returns `true` if the child number is a [`Normal`] value.
143    ///
144    /// [`Normal`]: #variant.Normal
145    pub fn is_normal(&self) -> bool { !self.is_hardened() }
146
147    /// Returns `true` if the child number is a [`Hardened`] value.
148    ///
149    /// [`Hardened`]: #variant.Hardened
150    pub fn is_hardened(&self) -> bool {
151        match self {
152            ChildNumber::Hardened { .. } => true,
153            ChildNumber::Normal { .. } => false,
154        }
155    }
156
157    /// Returns the child number that is a single increment from this one.
158    pub fn increment(self) -> Result<ChildNumber, Error> {
159        match self {
160            ChildNumber::Normal { index: idx } => ChildNumber::from_normal_idx(idx + 1),
161            ChildNumber::Hardened { index: idx } => ChildNumber::from_hardened_idx(idx + 1),
162        }
163    }
164}
165
166impl From<u32> for ChildNumber {
167    fn from(number: u32) -> Self {
168        if number & (1 << 31) != 0 {
169            ChildNumber::Hardened { index: number ^ (1 << 31) }
170        } else {
171            ChildNumber::Normal { index: number }
172        }
173    }
174}
175
176impl From<ChildNumber> for u32 {
177    fn from(cnum: ChildNumber) -> Self {
178        match cnum {
179            ChildNumber::Normal { index } => index,
180            ChildNumber::Hardened { index } => index | (1 << 31),
181        }
182    }
183}
184
185impl fmt::Display for ChildNumber {
186    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
187        match *self {
188            ChildNumber::Hardened { index } => {
189                fmt::Display::fmt(&index, f)?;
190                let alt = f.alternate();
191                f.write_str(if alt { "h" } else { "'" })
192            }
193            ChildNumber::Normal { index } => fmt::Display::fmt(&index, f),
194        }
195    }
196}
197
198impl FromStr for ChildNumber {
199    type Err = Error;
200
201    fn from_str(inp: &str) -> Result<ChildNumber, Error> {
202        let is_hardened = inp.chars().last().map_or(false, |l| l == '\'' || l == 'h');
203        Ok(if is_hardened {
204            ChildNumber::from_hardened_idx(
205                inp[0..inp.len() - 1].parse().map_err(|_| Error::InvalidChildNumberFormat)?,
206            )?
207        } else {
208            ChildNumber::from_normal_idx(inp.parse().map_err(|_| Error::InvalidChildNumberFormat)?)?
209        })
210    }
211}
212
213#[cfg(feature = "serde")]
214#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
215impl<'de> serde::Deserialize<'de> for ChildNumber {
216    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
217    where
218        D: serde::Deserializer<'de>,
219    {
220        u32::deserialize(deserializer).map(ChildNumber::from)
221    }
222}
223
224#[cfg(feature = "serde")]
225#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
226impl serde::Serialize for ChildNumber {
227    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
228    where
229        S: serde::Serializer,
230    {
231        u32::from(*self).serialize(serializer)
232    }
233}
234
235/// Trait that allows possibly failable conversion from a type into a
236/// derivation path
237pub trait IntoDerivationPath {
238    /// Convers a given type into a [`DerivationPath`] with possible error
239    fn into_derivation_path(self) -> Result<DerivationPath, Error>;
240}
241
242/// A BIP-32 derivation path.
243#[derive(Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
244pub struct DerivationPath(Vec<ChildNumber>);
245
246#[cfg(feature = "serde")]
247crate::serde_utils::serde_string_impl!(DerivationPath, "a BIP-32 derivation path");
248
249impl<I> Index<I> for DerivationPath
250where
251    Vec<ChildNumber>: Index<I>,
252{
253    type Output = <Vec<ChildNumber> as Index<I>>::Output;
254
255    #[inline]
256    fn index(&self, index: I) -> &Self::Output { &self.0[index] }
257}
258
259impl Default for DerivationPath {
260    fn default() -> DerivationPath { DerivationPath::master() }
261}
262
263impl<T> IntoDerivationPath for T
264where
265    T: Into<DerivationPath>,
266{
267    fn into_derivation_path(self) -> Result<DerivationPath, Error> { Ok(self.into()) }
268}
269
270impl IntoDerivationPath for String {
271    fn into_derivation_path(self) -> Result<DerivationPath, Error> { self.parse() }
272}
273
274impl<'a> IntoDerivationPath for &'a str {
275    fn into_derivation_path(self) -> Result<DerivationPath, Error> { self.parse() }
276}
277
278impl From<Vec<ChildNumber>> for DerivationPath {
279    fn from(numbers: Vec<ChildNumber>) -> Self { DerivationPath(numbers) }
280}
281
282impl From<DerivationPath> for Vec<ChildNumber> {
283    fn from(path: DerivationPath) -> Self { path.0 }
284}
285
286impl<'a> From<&'a [ChildNumber]> for DerivationPath {
287    fn from(numbers: &'a [ChildNumber]) -> Self { DerivationPath(numbers.to_vec()) }
288}
289
290impl core::iter::FromIterator<ChildNumber> for DerivationPath {
291    fn from_iter<T>(iter: T) -> Self
292    where
293        T: IntoIterator<Item = ChildNumber>,
294    {
295        DerivationPath(Vec::from_iter(iter))
296    }
297}
298
299impl<'a> core::iter::IntoIterator for &'a DerivationPath {
300    type Item = &'a ChildNumber;
301    type IntoIter = slice::Iter<'a, ChildNumber>;
302    fn into_iter(self) -> Self::IntoIter { self.0.iter() }
303}
304
305impl AsRef<[ChildNumber]> for DerivationPath {
306    fn as_ref(&self) -> &[ChildNumber] { &self.0 }
307}
308
309impl FromStr for DerivationPath {
310    type Err = Error;
311
312    fn from_str(path: &str) -> Result<DerivationPath, Error> {
313        let mut parts = path.split('/');
314        // First parts must be `m`.
315        if parts.next().unwrap() != "m" {
316            return Err(Error::InvalidDerivationPathFormat);
317        }
318
319        let ret: Result<Vec<ChildNumber>, Error> = parts.map(str::parse).collect();
320        Ok(DerivationPath(ret?))
321    }
322}
323
324/// An iterator over children of a [DerivationPath].
325///
326/// It is returned by the methods [DerivationPath::children_from],
327/// [DerivationPath::normal_children] and [DerivationPath::hardened_children].
328pub struct DerivationPathIterator<'a> {
329    base: &'a DerivationPath,
330    next_child: Option<ChildNumber>,
331}
332
333impl<'a> DerivationPathIterator<'a> {
334    /// Start a new [DerivationPathIterator] at the given child.
335    pub fn start_from(path: &'a DerivationPath, start: ChildNumber) -> DerivationPathIterator<'a> {
336        DerivationPathIterator { base: path, next_child: Some(start) }
337    }
338}
339
340impl<'a> Iterator for DerivationPathIterator<'a> {
341    type Item = DerivationPath;
342
343    fn next(&mut self) -> Option<Self::Item> {
344        let ret = self.next_child?;
345        self.next_child = ret.increment().ok();
346        Some(self.base.child(ret))
347    }
348}
349
350impl DerivationPath {
351    /// Returns length of the derivation path
352    pub fn len(&self) -> usize { self.0.len() }
353
354    /// Returns `true` if the derivation path is empty
355    pub fn is_empty(&self) -> bool { self.0.is_empty() }
356
357    /// Returns derivation path for a master key (i.e. empty derivation path)
358    pub fn master() -> DerivationPath { DerivationPath(vec![]) }
359
360    /// Returns whether derivation path represents master key (i.e. it's length
361    /// is empty). True for `m` path.
362    pub fn is_master(&self) -> bool { self.0.is_empty() }
363
364    /// Create a new [DerivationPath] that is a child of this one.
365    pub fn child(&self, cn: ChildNumber) -> DerivationPath {
366        let mut path = self.0.clone();
367        path.push(cn);
368        DerivationPath(path)
369    }
370
371    /// Convert into a [DerivationPath] that is a child of this one.
372    pub fn into_child(self, cn: ChildNumber) -> DerivationPath {
373        let mut path = self.0;
374        path.push(cn);
375        DerivationPath(path)
376    }
377
378    /// Get an [Iterator] over the children of this [DerivationPath]
379    /// starting with the given [ChildNumber].
380    pub fn children_from(&self, cn: ChildNumber) -> DerivationPathIterator {
381        DerivationPathIterator::start_from(self, cn)
382    }
383
384    /// Get an [Iterator] over the unhardened children of this [DerivationPath].
385    pub fn normal_children(&self) -> DerivationPathIterator {
386        DerivationPathIterator::start_from(self, ChildNumber::Normal { index: 0 })
387    }
388
389    /// Get an [Iterator] over the hardened children of this [DerivationPath].
390    pub fn hardened_children(&self) -> DerivationPathIterator {
391        DerivationPathIterator::start_from(self, ChildNumber::Hardened { index: 0 })
392    }
393
394    /// Concatenate `self` with `path` and return the resulting new path.
395    ///
396    /// ```
397    /// use bitcoin::bip32::{DerivationPath, ChildNumber};
398    /// use std::str::FromStr;
399    ///
400    /// let base = DerivationPath::from_str("m/42").unwrap();
401    ///
402    /// let deriv_1 = base.extend(DerivationPath::from_str("m/0/1").unwrap());
403    /// let deriv_2 = base.extend(&[
404    ///     ChildNumber::from_normal_idx(0).unwrap(),
405    ///     ChildNumber::from_normal_idx(1).unwrap()
406    /// ]);
407    ///
408    /// assert_eq!(deriv_1, deriv_2);
409    /// ```
410    pub fn extend<T: AsRef<[ChildNumber]>>(&self, path: T) -> DerivationPath {
411        let mut new_path = self.clone();
412        new_path.0.extend_from_slice(path.as_ref());
413        new_path
414    }
415}
416
417impl fmt::Display for DerivationPath {
418    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
419        f.write_str("m")?;
420        for cn in self.0.iter() {
421            f.write_str("/")?;
422            fmt::Display::fmt(cn, f)?;
423        }
424        Ok(())
425    }
426}
427
428impl fmt::Debug for DerivationPath {
429    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(&self, f) }
430}
431
432/// Full information on the used extended public key: fingerprint of the
433/// master extended public key and a derivation path from it.
434pub type KeySource = (Fingerprint, DerivationPath);
435
436/// A BIP32 error
437#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
438#[non_exhaustive]
439pub enum Error {
440    /// A pk->pk derivation was attempted on a hardened key
441    CannotDeriveFromHardenedKey,
442    /// A secp256k1 error occurred
443    Secp256k1(secp256k1::Error),
444    /// A child number was provided that was out of range
445    InvalidChildNumber(u32),
446    /// Invalid childnumber format.
447    InvalidChildNumberFormat,
448    /// Invalid derivation path format.
449    InvalidDerivationPathFormat,
450    /// Unknown version magic bytes
451    UnknownVersion([u8; 4]),
452    /// Encoded extended key data has wrong length
453    WrongExtendedKeyLength(usize),
454    /// Base58 encoding error
455    Base58(base58::Error),
456    /// Hexadecimal decoding error
457    Hex(hex::Error),
458    /// `PublicKey` hex should be 66 or 130 digits long.
459    InvalidPublicKeyHexLength(usize),
460}
461
462impl fmt::Display for Error {
463    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
464        match *self {
465            Error::CannotDeriveFromHardenedKey =>
466                f.write_str("cannot derive hardened key from public key"),
467            Error::Secp256k1(ref e) => write_err!(f, "secp256k1 error"; e),
468            Error::InvalidChildNumber(ref n) =>
469                write!(f, "child number {} is invalid (not within [0, 2^31 - 1])", n),
470            Error::InvalidChildNumberFormat => f.write_str("invalid child number format"),
471            Error::InvalidDerivationPathFormat => f.write_str("invalid derivation path format"),
472            Error::UnknownVersion(ref bytes) =>
473                write!(f, "unknown version magic bytes: {:?}", bytes),
474            Error::WrongExtendedKeyLength(ref len) =>
475                write!(f, "encoded extended key data has wrong length {}", len),
476            Error::Base58(ref e) => write_err!(f, "base58 encoding error"; e),
477            Error::Hex(ref e) => write_err!(f, "Hexadecimal decoding error"; e),
478            Error::InvalidPublicKeyHexLength(got) =>
479                write!(f, "PublicKey hex should be 66 or 130 digits long, got: {}", got),
480        }
481    }
482}
483
484#[cfg(feature = "std")]
485#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
486impl std::error::Error for Error {
487    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
488        use self::Error::*;
489
490        match self {
491            Secp256k1(e) => Some(e),
492            Base58(e) => Some(e),
493            Hex(e) => Some(e),
494            CannotDeriveFromHardenedKey
495            | InvalidChildNumber(_)
496            | InvalidChildNumberFormat
497            | InvalidDerivationPathFormat
498            | UnknownVersion(_)
499            | WrongExtendedKeyLength(_)
500            | InvalidPublicKeyHexLength(_) => None,
501        }
502    }
503}
504
505impl From<key::Error> for Error {
506    fn from(err: key::Error) -> Self {
507        match err {
508            key::Error::Base58(e) => Error::Base58(e),
509            key::Error::Secp256k1(e) => Error::Secp256k1(e),
510            key::Error::InvalidKeyPrefix(_) => Error::Secp256k1(secp256k1::Error::InvalidPublicKey),
511            key::Error::Hex(e) => Error::Hex(e),
512            key::Error::InvalidHexLength(got) => Error::InvalidPublicKeyHexLength(got),
513        }
514    }
515}
516
517impl From<secp256k1::Error> for Error {
518    fn from(e: secp256k1::Error) -> Error { Error::Secp256k1(e) }
519}
520
521impl From<base58::Error> for Error {
522    fn from(err: base58::Error) -> Self { Error::Base58(err) }
523}
524
525impl ExtendedPrivKey {
526    /// Construct a new master key from a seed value
527    pub fn new_master(network: Network, seed: &[u8]) -> Result<ExtendedPrivKey, Error> {
528        let mut hmac_engine: HmacEngine<sha512::Hash> = HmacEngine::new(b"Bitcoin seed");
529        hmac_engine.input(seed);
530        let hmac_result: Hmac<sha512::Hash> = Hmac::from_engine(hmac_engine);
531
532        Ok(ExtendedPrivKey {
533            network,
534            depth: 0,
535            parent_fingerprint: Default::default(),
536            child_number: ChildNumber::from_normal_idx(0)?,
537            private_key: secp256k1::SecretKey::from_slice(&hmac_result[..32])?,
538            chain_code: ChainCode::from_hmac(hmac_result),
539        })
540    }
541
542    /// Constructs ECDSA compressed private key matching internal secret key representation.
543    pub fn to_priv(self) -> PrivateKey {
544        PrivateKey { compressed: true, network: self.network, inner: self.private_key }
545    }
546
547    /// Constructs BIP340 keypair for Schnorr signatures and Taproot use matching the internal
548    /// secret key representation.
549    pub fn to_keypair<C: secp256k1::Signing>(self, secp: &Secp256k1<C>) -> KeyPair {
550        KeyPair::from_seckey_slice(secp, &self.private_key[..])
551            .expect("BIP32 internal private key representation is broken")
552    }
553
554    /// Attempts to derive an extended private key from a path.
555    ///
556    /// The `path` argument can be both of type `DerivationPath` or `Vec<ChildNumber>`.
557    pub fn derive_priv<C: secp256k1::Signing, P: AsRef<[ChildNumber]>>(
558        &self,
559        secp: &Secp256k1<C>,
560        path: &P,
561    ) -> Result<ExtendedPrivKey, Error> {
562        let mut sk: ExtendedPrivKey = *self;
563        for cnum in path.as_ref() {
564            sk = sk.ckd_priv(secp, *cnum)?;
565        }
566        Ok(sk)
567    }
568
569    /// Private->Private child key derivation
570    pub fn ckd_priv<C: secp256k1::Signing>(
571        &self,
572        secp: &Secp256k1<C>,
573        i: ChildNumber,
574    ) -> Result<ExtendedPrivKey, Error> {
575        let mut hmac_engine: HmacEngine<sha512::Hash> = HmacEngine::new(&self.chain_code[..]);
576        match i {
577            ChildNumber::Normal { .. } => {
578                // Non-hardened key: compute public data and use that
579                hmac_engine.input(
580                    &secp256k1::PublicKey::from_secret_key(secp, &self.private_key).serialize()[..],
581                );
582            }
583            ChildNumber::Hardened { .. } => {
584                // Hardened key: use only secret data to prevent public derivation
585                hmac_engine.input(&[0u8]);
586                hmac_engine.input(&self.private_key[..]);
587            }
588        }
589
590        hmac_engine.input(&u32::from(i).to_be_bytes());
591        let hmac_result: Hmac<sha512::Hash> = Hmac::from_engine(hmac_engine);
592        let sk = secp256k1::SecretKey::from_slice(&hmac_result[..32])
593            .expect("statistically impossible to hit");
594        let tweaked =
595            sk.add_tweak(&self.private_key.into()).expect("statistically impossible to hit");
596
597        Ok(ExtendedPrivKey {
598            network: self.network,
599            depth: self.depth + 1,
600            parent_fingerprint: self.fingerprint(secp),
601            child_number: i,
602            private_key: tweaked,
603            chain_code: ChainCode::from_hmac(hmac_result),
604        })
605    }
606
607    /// Decoding extended private key from binary data according to BIP 32
608    pub fn decode(data: &[u8]) -> Result<ExtendedPrivKey, Error> {
609        if data.len() != 78 {
610            return Err(Error::WrongExtendedKeyLength(data.len()));
611        }
612
613        let network = if data[0..4] == [0x04u8, 0x88, 0xAD, 0xE4] {
614            Network::Qtum
615        } else if data[0..4] == [0x04u8, 0x35, 0x83, 0x94] {
616            Network::Testnet
617        } else {
618            let mut ver = [0u8; 4];
619            ver.copy_from_slice(&data[0..4]);
620            return Err(Error::UnknownVersion(ver));
621        };
622
623        Ok(ExtendedPrivKey {
624            network,
625            depth: data[4],
626            parent_fingerprint: data[5..9]
627                .try_into()
628                .expect("9 - 5 == 4, which is the Fingerprint length"),
629            child_number: u32::from_be_bytes(data[9..13].try_into().expect("4 byte slice")).into(),
630            chain_code: data[13..45]
631                .try_into()
632                .expect("45 - 13 == 32, which is the ChainCode length"),
633            private_key: secp256k1::SecretKey::from_slice(&data[46..78])?,
634        })
635    }
636
637    /// Extended private key binary encoding according to BIP 32
638    pub fn encode(&self) -> [u8; 78] {
639        let mut ret = [0; 78];
640        ret[0..4].copy_from_slice(
641            &match self.network {
642                Network::Qtum => [0x04, 0x88, 0xAD, 0xE4],
643                Network::Testnet | Network::Signet | Network::Regtest => [0x04, 0x35, 0x83, 0x94],
644            }[..],
645        );
646        ret[4] = self.depth;
647        ret[5..9].copy_from_slice(&self.parent_fingerprint[..]);
648        ret[9..13].copy_from_slice(&u32::from(self.child_number).to_be_bytes());
649        ret[13..45].copy_from_slice(&self.chain_code[..]);
650        ret[45] = 0;
651        ret[46..78].copy_from_slice(&self.private_key[..]);
652        ret
653    }
654
655    /// Returns the HASH160 of the public key belonging to the xpriv
656    pub fn identifier<C: secp256k1::Signing>(&self, secp: &Secp256k1<C>) -> XpubIdentifier {
657        ExtendedPubKey::from_priv(secp, self).identifier()
658    }
659
660    /// Returns the first four bytes of the identifier
661    pub fn fingerprint<C: secp256k1::Signing>(&self, secp: &Secp256k1<C>) -> Fingerprint {
662        self.identifier(secp)[0..4].try_into().expect("4 is the fingerprint length")
663    }
664}
665
666impl ExtendedPubKey {
667    /// Derives a public key from a private key
668    pub fn from_priv<C: secp256k1::Signing>(
669        secp: &Secp256k1<C>,
670        sk: &ExtendedPrivKey,
671    ) -> ExtendedPubKey {
672        ExtendedPubKey {
673            network: sk.network,
674            depth: sk.depth,
675            parent_fingerprint: sk.parent_fingerprint,
676            child_number: sk.child_number,
677            public_key: secp256k1::PublicKey::from_secret_key(secp, &sk.private_key),
678            chain_code: sk.chain_code,
679        }
680    }
681
682    /// Constructs ECDSA compressed public key matching internal public key representation.
683    pub fn to_pub(self) -> PublicKey { PublicKey { compressed: true, inner: self.public_key } }
684
685    /// Constructs BIP340 x-only public key for BIP-340 signatures and Taproot use matching
686    /// the internal public key representation.
687    pub fn to_x_only_pub(self) -> XOnlyPublicKey { XOnlyPublicKey::from(self.public_key) }
688
689    /// Attempts to derive an extended public key from a path.
690    ///
691    /// The `path` argument can be any type implementing `AsRef<ChildNumber>`, such as `DerivationPath`, for instance.
692    pub fn derive_pub<C: secp256k1::Verification, P: AsRef<[ChildNumber]>>(
693        &self,
694        secp: &Secp256k1<C>,
695        path: &P,
696    ) -> Result<ExtendedPubKey, Error> {
697        let mut pk: ExtendedPubKey = *self;
698        for cnum in path.as_ref() {
699            pk = pk.ckd_pub(secp, *cnum)?
700        }
701        Ok(pk)
702    }
703
704    /// Compute the scalar tweak added to this key to get a child key
705    pub fn ckd_pub_tweak(
706        &self,
707        i: ChildNumber,
708    ) -> Result<(secp256k1::SecretKey, ChainCode), Error> {
709        match i {
710            ChildNumber::Hardened { .. } => Err(Error::CannotDeriveFromHardenedKey),
711            ChildNumber::Normal { index: n } => {
712                let mut hmac_engine: HmacEngine<sha512::Hash> =
713                    HmacEngine::new(&self.chain_code[..]);
714                hmac_engine.input(&self.public_key.serialize()[..]);
715                hmac_engine.input(&n.to_be_bytes());
716
717                let hmac_result: Hmac<sha512::Hash> = Hmac::from_engine(hmac_engine);
718
719                let private_key = secp256k1::SecretKey::from_slice(&hmac_result[..32])?;
720                let chain_code = ChainCode::from_hmac(hmac_result);
721                Ok((private_key, chain_code))
722            }
723        }
724    }
725
726    /// Public->Public child key derivation
727    pub fn ckd_pub<C: secp256k1::Verification>(
728        &self,
729        secp: &Secp256k1<C>,
730        i: ChildNumber,
731    ) -> Result<ExtendedPubKey, Error> {
732        let (sk, chain_code) = self.ckd_pub_tweak(i)?;
733        let tweaked = self.public_key.add_exp_tweak(secp, &sk.into())?;
734
735        Ok(ExtendedPubKey {
736            network: self.network,
737            depth: self.depth + 1,
738            parent_fingerprint: self.fingerprint(),
739            child_number: i,
740            public_key: tweaked,
741            chain_code,
742        })
743    }
744
745    /// Decoding extended public key from binary data according to BIP 32
746    pub fn decode(data: &[u8]) -> Result<ExtendedPubKey, Error> {
747        if data.len() != 78 {
748            return Err(Error::WrongExtendedKeyLength(data.len()));
749        }
750
751        Ok(ExtendedPubKey {
752            network: if data[0..4] == [0x04u8, 0x88, 0xB2, 0x1E] {
753                Network::Qtum
754            } else if data[0..4] == [0x04u8, 0x35, 0x87, 0xCF] {
755                Network::Testnet
756            } else {
757                let mut ver = [0u8; 4];
758                ver.copy_from_slice(&data[0..4]);
759                return Err(Error::UnknownVersion(ver));
760            },
761            depth: data[4],
762            parent_fingerprint: data[5..9]
763                .try_into()
764                .expect("9 - 5 == 4, which is the Fingerprint length"),
765            child_number: u32::from_be_bytes(data[9..13].try_into().expect("4 byte slice")).into(),
766            chain_code: data[13..45]
767                .try_into()
768                .expect("45 - 13 == 32, which is the ChainCode length"),
769            public_key: secp256k1::PublicKey::from_slice(&data[45..78])?,
770        })
771    }
772
773    /// Extended public key binary encoding according to BIP 32
774    pub fn encode(&self) -> [u8; 78] {
775        let mut ret = [0; 78];
776        ret[0..4].copy_from_slice(
777            &match self.network {
778                Network::Qtum => [0x04u8, 0x88, 0xB2, 0x1E],
779                Network::Testnet | Network::Signet | Network::Regtest => [0x04u8, 0x35, 0x87, 0xCF],
780            }[..],
781        );
782        ret[4] = self.depth;
783        ret[5..9].copy_from_slice(&self.parent_fingerprint[..]);
784        ret[9..13].copy_from_slice(&u32::from(self.child_number).to_be_bytes());
785        ret[13..45].copy_from_slice(&self.chain_code[..]);
786        ret[45..78].copy_from_slice(&self.public_key.serialize()[..]);
787        ret
788    }
789
790    /// Returns the HASH160 of the chaincode
791    pub fn identifier(&self) -> XpubIdentifier {
792        let mut engine = XpubIdentifier::engine();
793        engine.write_all(&self.public_key.serialize()).expect("engines don't error");
794        XpubIdentifier::from_engine(engine)
795    }
796
797    /// Returns the first four bytes of the identifier
798    pub fn fingerprint(&self) -> Fingerprint {
799        self.identifier()[0..4].try_into().expect("4 is the fingerprint length")
800    }
801}
802
803impl fmt::Display for ExtendedPrivKey {
804    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
805        base58::encode_check_to_fmt(fmt, &self.encode()[..])
806    }
807}
808
809impl FromStr for ExtendedPrivKey {
810    type Err = Error;
811
812    fn from_str(inp: &str) -> Result<ExtendedPrivKey, Error> {
813        let data = base58::decode_check(inp)?;
814
815        if data.len() != 78 {
816            return Err(base58::Error::InvalidLength(data.len()).into());
817        }
818
819        ExtendedPrivKey::decode(&data)
820    }
821}
822
823impl fmt::Display for ExtendedPubKey {
824    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
825        base58::encode_check_to_fmt(fmt, &self.encode()[..])
826    }
827}
828
829impl FromStr for ExtendedPubKey {
830    type Err = Error;
831
832    fn from_str(inp: &str) -> Result<ExtendedPubKey, Error> {
833        let data = base58::decode_check(inp)?;
834
835        if data.len() != 78 {
836            return Err(base58::Error::InvalidLength(data.len()).into());
837        }
838
839        ExtendedPubKey::decode(&data)
840    }
841}
842
843impl From<ExtendedPubKey> for XpubIdentifier {
844    fn from(key: ExtendedPubKey) -> XpubIdentifier { key.identifier() }
845}
846
847impl From<&ExtendedPubKey> for XpubIdentifier {
848    fn from(key: &ExtendedPubKey) -> XpubIdentifier { key.identifier() }
849}
850
851#[cfg(test)]
852mod tests {
853    use core::str::FromStr;
854
855    use secp256k1::{self, Secp256k1};
856
857    use super::ChildNumber::{Hardened, Normal};
858    use super::*;
859    use crate::internal_macros::hex;
860    use crate::network::constants::Network::{self, Qtum};
861
862    #[test]
863    fn test_parse_derivation_path() {
864        assert_eq!(DerivationPath::from_str("42"), Err(Error::InvalidDerivationPathFormat));
865        assert_eq!(DerivationPath::from_str("n/0'/0"), Err(Error::InvalidDerivationPathFormat));
866        assert_eq!(DerivationPath::from_str("4/m/5"), Err(Error::InvalidDerivationPathFormat));
867        assert_eq!(DerivationPath::from_str("m//3/0'"), Err(Error::InvalidChildNumberFormat));
868        assert_eq!(DerivationPath::from_str("m/0h/0x"), Err(Error::InvalidChildNumberFormat));
869        assert_eq!(
870            DerivationPath::from_str("m/2147483648"),
871            Err(Error::InvalidChildNumber(2147483648))
872        );
873
874        assert_eq!(DerivationPath::master(), DerivationPath::from_str("m").unwrap());
875        assert_eq!(DerivationPath::master(), DerivationPath::default());
876        assert_eq!(DerivationPath::from_str("m"), Ok(vec![].into()));
877        assert_eq!(
878            DerivationPath::from_str("m/0'"),
879            Ok(vec![ChildNumber::from_hardened_idx(0).unwrap()].into())
880        );
881        assert_eq!(
882            DerivationPath::from_str("m/0'/1"),
883            Ok(vec![
884                ChildNumber::from_hardened_idx(0).unwrap(),
885                ChildNumber::from_normal_idx(1).unwrap()
886            ]
887            .into())
888        );
889        assert_eq!(
890            DerivationPath::from_str("m/0h/1/2'"),
891            Ok(vec![
892                ChildNumber::from_hardened_idx(0).unwrap(),
893                ChildNumber::from_normal_idx(1).unwrap(),
894                ChildNumber::from_hardened_idx(2).unwrap(),
895            ]
896            .into())
897        );
898        assert_eq!(
899            DerivationPath::from_str("m/0'/1/2h/2"),
900            Ok(vec![
901                ChildNumber::from_hardened_idx(0).unwrap(),
902                ChildNumber::from_normal_idx(1).unwrap(),
903                ChildNumber::from_hardened_idx(2).unwrap(),
904                ChildNumber::from_normal_idx(2).unwrap(),
905            ]
906            .into())
907        );
908        assert_eq!(
909            DerivationPath::from_str("m/0'/1/2'/2/1000000000"),
910            Ok(vec![
911                ChildNumber::from_hardened_idx(0).unwrap(),
912                ChildNumber::from_normal_idx(1).unwrap(),
913                ChildNumber::from_hardened_idx(2).unwrap(),
914                ChildNumber::from_normal_idx(2).unwrap(),
915                ChildNumber::from_normal_idx(1000000000).unwrap(),
916            ]
917            .into())
918        );
919        let s = "m/0'/50/3'/5/545456";
920        assert_eq!(DerivationPath::from_str(s), s.into_derivation_path());
921        assert_eq!(DerivationPath::from_str(s), s.to_string().into_derivation_path());
922    }
923
924    #[test]
925    fn test_derivation_path_conversion_index() {
926        let path = DerivationPath::from_str("m/0h/1/2'").unwrap();
927        let numbers: Vec<ChildNumber> = path.clone().into();
928        let path2: DerivationPath = numbers.into();
929        assert_eq!(path, path2);
930        assert_eq!(
931            &path[..2],
932            &[ChildNumber::from_hardened_idx(0).unwrap(), ChildNumber::from_normal_idx(1).unwrap()]
933        );
934        let indexed: DerivationPath = path[..2].into();
935        assert_eq!(indexed, DerivationPath::from_str("m/0h/1").unwrap());
936        assert_eq!(indexed.child(ChildNumber::from_hardened_idx(2).unwrap()), path);
937    }
938
939    fn test_path<C: secp256k1::Signing + secp256k1::Verification>(
940        secp: &Secp256k1<C>,
941        network: Network,
942        seed: &[u8],
943        path: DerivationPath,
944        expected_sk: &str,
945        expected_pk: &str,
946    ) {
947        let mut sk = ExtendedPrivKey::new_master(network, seed).unwrap();
948        let mut pk = ExtendedPubKey::from_priv(secp, &sk);
949
950        // Check derivation convenience method for ExtendedPrivKey
951        assert_eq!(&sk.derive_priv(secp, &path).unwrap().to_string()[..], expected_sk);
952
953        // Check derivation convenience method for ExtendedPubKey, should error
954        // appropriately if any ChildNumber is hardened
955        if path.0.iter().any(|cnum| cnum.is_hardened()) {
956            assert_eq!(pk.derive_pub(secp, &path), Err(Error::CannotDeriveFromHardenedKey));
957        } else {
958            assert_eq!(&pk.derive_pub(secp, &path).unwrap().to_string()[..], expected_pk);
959        }
960
961        // Derive keys, checking hardened and non-hardened derivation one-by-one
962        for &num in path.0.iter() {
963            sk = sk.ckd_priv(secp, num).unwrap();
964            match num {
965                Normal { .. } => {
966                    let pk2 = pk.ckd_pub(secp, num).unwrap();
967                    pk = ExtendedPubKey::from_priv(secp, &sk);
968                    assert_eq!(pk, pk2);
969                }
970                Hardened { .. } => {
971                    assert_eq!(pk.ckd_pub(secp, num), Err(Error::CannotDeriveFromHardenedKey));
972                    pk = ExtendedPubKey::from_priv(secp, &sk);
973                }
974            }
975        }
976
977        // Check result against expected base58
978        assert_eq!(&sk.to_string()[..], expected_sk);
979        assert_eq!(&pk.to_string()[..], expected_pk);
980        // Check decoded base58 against result
981        let decoded_sk = ExtendedPrivKey::from_str(expected_sk);
982        let decoded_pk = ExtendedPubKey::from_str(expected_pk);
983        assert_eq!(Ok(sk), decoded_sk);
984        assert_eq!(Ok(pk), decoded_pk);
985    }
986
987    #[test]
988    fn test_increment() {
989        let idx = 9345497; // randomly generated, I promise
990        let cn = ChildNumber::from_normal_idx(idx).unwrap();
991        assert_eq!(cn.increment().ok(), Some(ChildNumber::from_normal_idx(idx + 1).unwrap()));
992        let cn = ChildNumber::from_hardened_idx(idx).unwrap();
993        assert_eq!(cn.increment().ok(), Some(ChildNumber::from_hardened_idx(idx + 1).unwrap()));
994
995        let max = (1 << 31) - 1;
996        let cn = ChildNumber::from_normal_idx(max).unwrap();
997        assert_eq!(cn.increment().err(), Some(Error::InvalidChildNumber(1 << 31)));
998        let cn = ChildNumber::from_hardened_idx(max).unwrap();
999        assert_eq!(cn.increment().err(), Some(Error::InvalidChildNumber(1 << 31)));
1000
1001        let cn = ChildNumber::from_normal_idx(350).unwrap();
1002        let path = DerivationPath::from_str("m/42'").unwrap();
1003        let mut iter = path.children_from(cn);
1004        assert_eq!(iter.next(), Some("m/42'/350".parse().unwrap()));
1005        assert_eq!(iter.next(), Some("m/42'/351".parse().unwrap()));
1006
1007        let path = DerivationPath::from_str("m/42'/350'").unwrap();
1008        let mut iter = path.normal_children();
1009        assert_eq!(iter.next(), Some("m/42'/350'/0".parse().unwrap()));
1010        assert_eq!(iter.next(), Some("m/42'/350'/1".parse().unwrap()));
1011
1012        let path = DerivationPath::from_str("m/42'/350'").unwrap();
1013        let mut iter = path.hardened_children();
1014        assert_eq!(iter.next(), Some("m/42'/350'/0'".parse().unwrap()));
1015        assert_eq!(iter.next(), Some("m/42'/350'/1'".parse().unwrap()));
1016
1017        let cn = ChildNumber::from_hardened_idx(42350).unwrap();
1018        let path = DerivationPath::from_str("m/42'").unwrap();
1019        let mut iter = path.children_from(cn);
1020        assert_eq!(iter.next(), Some("m/42'/42350'".parse().unwrap()));
1021        assert_eq!(iter.next(), Some("m/42'/42351'".parse().unwrap()));
1022
1023        let cn = ChildNumber::from_hardened_idx(max).unwrap();
1024        let path = DerivationPath::from_str("m/42'").unwrap();
1025        let mut iter = path.children_from(cn);
1026        assert!(iter.next().is_some());
1027        assert!(iter.next().is_none());
1028    }
1029
1030    #[test]
1031    fn test_vector_1() {
1032        let secp = Secp256k1::new();
1033        let seed = hex!("000102030405060708090a0b0c0d0e0f");
1034
1035        // m
1036        test_path(&secp, Qtum, &seed, "m".parse().unwrap(),
1037                  "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi",
1038                  "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8");
1039
1040        // m/0h
1041        test_path(&secp, Qtum, &seed, "m/0h".parse().unwrap(),
1042                  "xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7",
1043                  "xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw");
1044
1045        // m/0h/1
1046        test_path(&secp, Qtum, &seed, "m/0h/1".parse().unwrap(),
1047                   "xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs",
1048                   "xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ");
1049
1050        // m/0h/1/2h
1051        test_path(&secp, Qtum, &seed, "m/0h/1/2h".parse().unwrap(),
1052                  "xprv9z4pot5VBttmtdRTWfWQmoH1taj2axGVzFqSb8C9xaxKymcFzXBDptWmT7FwuEzG3ryjH4ktypQSAewRiNMjANTtpgP4mLTj34bhnZX7UiM",
1053                  "xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5");
1054
1055        // m/0h/1/2h/2
1056        test_path(&secp, Qtum, &seed, "m/0h/1/2h/2".parse().unwrap(),
1057                  "xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334",
1058                  "xpub6FHa3pjLCk84BayeJxFW2SP4XRrFd1JYnxeLeU8EqN3vDfZmbqBqaGJAyiLjTAwm6ZLRQUMv1ZACTj37sR62cfN7fe5JnJ7dh8zL4fiyLHV");
1059
1060        // m/0h/1/2h/2/1000000000
1061        test_path(&secp, Qtum, &seed, "m/0h/1/2h/2/1000000000".parse().unwrap(),
1062                  "xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76",
1063                  "xpub6H1LXWLaKsWFhvm6RVpEL9P4KfRZSW7abD2ttkWP3SSQvnyA8FSVqNTEcYFgJS2UaFcxupHiYkro49S8yGasTvXEYBVPamhGW6cFJodrTHy");
1064    }
1065
1066    #[test]
1067    fn test_vector_2() {
1068        let secp = Secp256k1::new();
1069        let seed = hex!("fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542");
1070
1071        // m
1072        test_path(&secp, Qtum, &seed, "m".parse().unwrap(),
1073                  "xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U",
1074                  "xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB");
1075
1076        // m/0
1077        test_path(&secp, Qtum, &seed, "m/0".parse().unwrap(),
1078                  "xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt",
1079                  "xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH");
1080
1081        // m/0/2147483647h
1082        test_path(&secp, Qtum, &seed, "m/0/2147483647h".parse().unwrap(),
1083                  "xprv9wSp6B7kry3Vj9m1zSnLvN3xH8RdsPP1Mh7fAaR7aRLcQMKTR2vidYEeEg2mUCTAwCd6vnxVrcjfy2kRgVsFawNzmjuHc2YmYRmagcEPdU9",
1084                  "xpub6ASAVgeehLbnwdqV6UKMHVzgqAG8Gr6riv3Fxxpj8ksbH9ebxaEyBLZ85ySDhKiLDBrQSARLq1uNRts8RuJiHjaDMBU4Zn9h8LZNnBC5y4a");
1085
1086        // m/0/2147483647h/1
1087        test_path(&secp, Qtum, &seed, "m/0/2147483647h/1".parse().unwrap(),
1088                  "xprv9zFnWC6h2cLgpmSA46vutJzBcfJ8yaJGg8cX1e5StJh45BBciYTRXSd25UEPVuesF9yog62tGAQtHjXajPPdbRCHuWS6T8XA2ECKADdw4Ef",
1089                  "xpub6DF8uhdarytz3FWdA8TvFSvvAh8dP3283MY7p2V4SeE2wyWmG5mg5EwVvmdMVCQcoNJxGoWaU9DCWh89LojfZ537wTfunKau47EL2dhHKon");
1090
1091        // m/0/2147483647h/1/2147483646h
1092        test_path(&secp, Qtum, &seed, "m/0/2147483647h/1/2147483646h".parse().unwrap(),
1093                  "xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc",
1094                  "xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL");
1095
1096        // m/0/2147483647h/1/2147483646h/2
1097        test_path(&secp, Qtum, &seed, "m/0/2147483647h/1/2147483646h/2".parse().unwrap(),
1098                  "xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j",
1099                  "xpub6FnCn6nSzZAw5Tw7cgR9bi15UV96gLZhjDstkXXxvCLsUXBGXPdSnLFbdpq8p9HmGsApME5hQTZ3emM2rnY5agb9rXpVGyy3bdW6EEgAtqt");
1100    }
1101
1102    #[test]
1103    fn test_vector_3() {
1104        let secp = Secp256k1::new();
1105        let seed = hex!("4b381541583be4423346c643850da4b320e46a87ae3d2a4e6da11eba819cd4acba45d239319ac14f863b8d5ab5a0d0c64d2e8a1e7d1457df2e5a3c51c73235be");
1106
1107        // m
1108        test_path(&secp, Qtum, &seed, "m".parse().unwrap(),
1109                  "xprv9s21ZrQH143K25QhxbucbDDuQ4naNntJRi4KUfWT7xo4EKsHt2QJDu7KXp1A3u7Bi1j8ph3EGsZ9Xvz9dGuVrtHHs7pXeTzjuxBrCmmhgC6",
1110                  "xpub661MyMwAqRbcEZVB4dScxMAdx6d4nFc9nvyvH3v4gJL378CSRZiYmhRoP7mBy6gSPSCYk6SzXPTf3ND1cZAceL7SfJ1Z3GC8vBgp2epUt13");
1111
1112        // m/0h
1113        test_path(&secp, Qtum, &seed, "m/0h".parse().unwrap(),
1114                  "xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L",
1115                  "xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y");
1116    }
1117
1118    #[test]
1119    #[cfg(feature = "serde")]
1120    pub fn encode_decode_childnumber() {
1121        serde_round_trip!(ChildNumber::from_normal_idx(0).unwrap());
1122        serde_round_trip!(ChildNumber::from_normal_idx(1).unwrap());
1123        serde_round_trip!(ChildNumber::from_normal_idx((1 << 31) - 1).unwrap());
1124        serde_round_trip!(ChildNumber::from_hardened_idx(0).unwrap());
1125        serde_round_trip!(ChildNumber::from_hardened_idx(1).unwrap());
1126        serde_round_trip!(ChildNumber::from_hardened_idx((1 << 31) - 1).unwrap());
1127    }
1128
1129    #[test]
1130    #[cfg(feature = "serde")]
1131    pub fn encode_fingerprint_chaincode() {
1132        use serde_json;
1133        let fp = Fingerprint::from([1u8, 2, 3, 42]);
1134        #[rustfmt::skip]
1135        let cc = ChainCode::from(
1136            [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]
1137        );
1138
1139        serde_round_trip!(fp);
1140        serde_round_trip!(cc);
1141
1142        assert_eq!("\"0102032a\"", serde_json::to_string(&fp).unwrap());
1143        assert_eq!(
1144            "\"0102030405060708090001020304050607080900010203040506070809000102\"",
1145            serde_json::to_string(&cc).unwrap()
1146        );
1147        assert_eq!("0102032a", fp.to_string());
1148        assert_eq!(
1149            "0102030405060708090001020304050607080900010203040506070809000102",
1150            cc.to_string()
1151        );
1152    }
1153
1154    #[test]
1155    fn fmt_child_number() {
1156        assert_eq!("000005h", &format!("{:#06}", ChildNumber::from_hardened_idx(5).unwrap()));
1157        assert_eq!("5h", &format!("{:#}", ChildNumber::from_hardened_idx(5).unwrap()));
1158        assert_eq!("000005'", &format!("{:06}", ChildNumber::from_hardened_idx(5).unwrap()));
1159        assert_eq!("5'", &format!("{}", ChildNumber::from_hardened_idx(5).unwrap()));
1160        assert_eq!("42", &format!("{}", ChildNumber::from_normal_idx(42).unwrap()));
1161        assert_eq!("000042", &format!("{:06}", ChildNumber::from_normal_idx(42).unwrap()));
1162    }
1163
1164    #[test]
1165    #[should_panic(expected = "Secp256k1(InvalidSecretKey)")]
1166    fn schnorr_broken_privkey_zeros() {
1167        /* this is how we generate key:
1168        let mut sk = secp256k1::key::ONE_KEY;
1169
1170        let zeros = [0u8; 32];
1171        unsafe {
1172            sk.as_mut_ptr().copy_from(zeros.as_ptr(), 32);
1173        }
1174
1175        let xpriv = ExtendedPrivKey {
1176            network: Network::Qtum,
1177            depth: 0,
1178            parent_fingerprint: Default::default(),
1179            child_number: ChildNumber::Normal { index: 0 },
1180            private_key: sk,
1181            chain_code: ChainCode::from([0u8; 32])
1182        };
1183
1184        println!("{}", xpriv);
1185         */
1186
1187        // Xpriv having secret key set to all zeros
1188        let xpriv_str = "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzF93Y5wvzdUayhgkkFoicQZcP3y52uPPxFnfoLZB21Teqt1VvEHx";
1189        ExtendedPrivKey::from_str(xpriv_str).unwrap();
1190    }
1191
1192    #[test]
1193    #[should_panic(expected = "Secp256k1(InvalidSecretKey)")]
1194    fn schnorr_broken_privkey_ffs() {
1195        // Xpriv having secret key set to all 0xFF's
1196        let xpriv_str = "xprv9s21ZrQH143K24Mfq5zL5MhWK9hUhhGbd45hLXo2Pq2oqzMMo63oStZzFAzHGBP2UuGCqWLTAPLcMtD9y5gkZ6Eq3Rjuahrv17fENZ3QzxW";
1197        ExtendedPrivKey::from_str(xpriv_str).unwrap();
1198    }
1199}