1use std::default::Default;
20use std::{error, fmt};
21use std::str::FromStr;
22#[cfg(feature = "serde")] use serde;
23
24use hash_types::XpubIdentifier;
25use hashes::{sha512, Hash, HashEngine, Hmac, HmacEngine};
26use secp256k1::{self, Secp256k1};
27
28use network::constants::Network;
29use util::{base58, endian};
30use util::key::{self, PublicKey, PrivateKey};
31
32#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
34pub struct ChainCode([u8; 32]);
35impl_array_newtype!(ChainCode, u8, 32);
36impl_bytes_newtype!(ChainCode, 32);
37
38#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
40pub struct Fingerprint([u8; 4]);
41impl_array_newtype!(Fingerprint, u8, 4);
42impl_bytes_newtype!(Fingerprint, 4);
43
44impl Default for Fingerprint {
45 fn default() -> Fingerprint { Fingerprint([0; 4]) }
46}
47
48#[derive(Copy, Clone, PartialEq, Eq, Debug)]
50pub struct ExtendedPrivKey {
51 pub network: Network,
53 pub depth: u8,
55 pub parent_fingerprint: Fingerprint,
57 pub child_number: ChildNumber,
59 pub private_key: PrivateKey,
61 pub chain_code: ChainCode
63}
64serde_string_impl!(ExtendedPrivKey, "a BIP-32 extended private key");
65
66#[derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord, Hash)]
68pub struct ExtendedPubKey {
69 pub network: Network,
71 pub depth: u8,
73 pub parent_fingerprint: Fingerprint,
75 pub child_number: ChildNumber,
77 pub public_key: PublicKey,
79 pub chain_code: ChainCode
81}
82serde_string_impl!(ExtendedPubKey, "a BIP-32 extended public key");
83
84#[derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord, Hash)]
86pub enum ChildNumber {
87 Normal {
89 index: u32
91 },
92 Hardened {
94 index: u32
96 },
97}
98
99impl ChildNumber {
100 pub fn from_normal_idx(index: u32) -> Result<Self, Error> {
105 if index & (1 << 31) == 0 {
106 Ok(ChildNumber::Normal { index: index })
107 } else {
108 Err(Error::InvalidChildNumber(index))
109 }
110 }
111
112 pub fn from_hardened_idx(index: u32) -> Result<Self, Error> {
117 if index & (1 << 31) == 0 {
118 Ok(ChildNumber::Hardened { index: index })
119 } else {
120 Err(Error::InvalidChildNumber(index))
121 }
122 }
123
124 pub fn is_normal(&self) -> bool {
128 !self.is_hardened()
129 }
130
131 pub fn is_hardened(&self) -> bool {
135 match self {
136 ChildNumber::Hardened {..} => true,
137 ChildNumber::Normal {..} => false,
138 }
139 }
140
141 pub fn increment(self) -> Result<ChildNumber, Error> {
143 match self {
144 ChildNumber::Normal{ index: idx } => ChildNumber::from_normal_idx(idx+1),
145 ChildNumber::Hardened{ index: idx } => ChildNumber::from_hardened_idx(idx+1),
146 }
147 }
148}
149
150impl From<u32> for ChildNumber {
151 fn from(number: u32) -> Self {
152 if number & (1 << 31) != 0 {
153 ChildNumber::Hardened { index: number ^ (1 << 31) }
154 } else {
155 ChildNumber::Normal { index: number }
156 }
157 }
158}
159
160impl From<ChildNumber> for u32 {
161 fn from(cnum: ChildNumber) -> Self {
162 match cnum {
163 ChildNumber::Normal { index } => index,
164 ChildNumber::Hardened { index } => index | (1 << 31),
165 }
166 }
167}
168
169impl fmt::Display for ChildNumber {
170 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
171 match *self {
172 ChildNumber::Hardened { index } => {
173 fmt::Display::fmt(&index, f)?;
174 let alt = f.alternate();
175 f.write_str(if alt { "'" } else { "h" })
176 },
177 ChildNumber::Normal { index } => fmt::Display::fmt(&index, f),
178 }
179 }
180}
181
182impl FromStr for ChildNumber {
183 type Err = Error;
184
185 fn from_str(inp: &str) -> Result<ChildNumber, Error> {
186 let is_hardened = inp.chars().last().map_or(false, |l| l == '\'' || l == 'h');
187 Ok(if is_hardened {
188 ChildNumber::from_hardened_idx(inp[0..inp.len() - 1].parse().map_err(|_| Error::InvalidChildNumberFormat)?)?
189 } else {
190 ChildNumber::from_normal_idx(inp.parse().map_err(|_| Error::InvalidChildNumberFormat)?)?
191 })
192 }
193}
194
195#[cfg(feature = "serde")]
196impl<'de> serde::Deserialize<'de> for ChildNumber {
197 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
198 where
199 D: serde::Deserializer<'de>,
200 {
201 u32::deserialize(deserializer).map(ChildNumber::from)
202 }
203}
204
205#[cfg(feature = "serde")]
206impl serde::Serialize for ChildNumber {
207 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
208 where
209 S: serde::Serializer,
210 {
211 u32::from(*self).serialize(serializer)
212 }
213}
214
215pub trait IntoDerivationPath {
218 fn into_derivation_path(self) -> Result<DerivationPath, Error>;
220}
221
222#[derive(Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
224pub struct DerivationPath(Vec<ChildNumber>);
225impl_index_newtype!(DerivationPath, ChildNumber);
226serde_string_impl!(DerivationPath, "a BIP-32 derivation path");
227
228impl Default for DerivationPath {
229 fn default() -> DerivationPath {
230 DerivationPath::master()
231 }
232}
233
234impl<T> IntoDerivationPath for T where T: Into<DerivationPath> {
235 fn into_derivation_path(self) -> Result<DerivationPath, Error> {
236 Ok(self.into())
237 }
238}
239
240impl IntoDerivationPath for String {
241 fn into_derivation_path(self) -> Result<DerivationPath, Error> {
242 self.parse()
243 }
244}
245
246impl<'a> IntoDerivationPath for &'a str {
247 fn into_derivation_path(self) -> Result<DerivationPath, Error> {
248 self.parse()
249 }
250}
251
252impl From<Vec<ChildNumber>> for DerivationPath {
253 fn from(numbers: Vec<ChildNumber>) -> Self {
254 DerivationPath(numbers)
255 }
256}
257
258impl Into<Vec<ChildNumber>> for DerivationPath {
259 fn into(self) -> Vec<ChildNumber> {
260 self.0
261 }
262}
263
264impl<'a> From<&'a [ChildNumber]> for DerivationPath {
265 fn from(numbers: &'a [ChildNumber]) -> Self {
266 DerivationPath(numbers.to_vec())
267 }
268}
269
270impl ::std::iter::FromIterator<ChildNumber> for DerivationPath {
271 fn from_iter<T>(iter: T) -> Self where T: IntoIterator<Item = ChildNumber> {
272 DerivationPath(Vec::from_iter(iter))
273 }
274}
275
276impl<'a> ::std::iter::IntoIterator for &'a DerivationPath {
277 type Item = &'a ChildNumber;
278 type IntoIter = ::std::slice::Iter<'a, ChildNumber>;
279 fn into_iter(self) -> Self::IntoIter {
280 self.0.iter()
281 }
282}
283
284impl AsRef<[ChildNumber]> for DerivationPath {
285 fn as_ref(&self) -> &[ChildNumber] {
286 &self.0
287 }
288}
289
290impl FromStr for DerivationPath {
291 type Err = Error;
292
293 fn from_str(path: &str) -> Result<DerivationPath, Error> {
294 let mut parts = path.split('/');
295 if parts.next().unwrap() != "m" {
297 return Err(Error::InvalidDerivationPathFormat);
298 }
299
300 let ret: Result<Vec<ChildNumber>, Error> = parts.map(str::parse).collect();
301 Ok(DerivationPath(ret?))
302 }
303}
304
305pub struct DerivationPathIterator<'a> {
310 base: &'a DerivationPath,
311 next_child: Option<ChildNumber>,
312}
313
314impl<'a> DerivationPathIterator<'a> {
315 pub fn start_from(path: &'a DerivationPath, start: ChildNumber) -> DerivationPathIterator<'a> {
317 DerivationPathIterator {
318 base: path,
319 next_child: Some(start),
320 }
321 }
322}
323
324impl<'a> Iterator for DerivationPathIterator<'a> {
325 type Item = DerivationPath;
326
327 fn next(&mut self) -> Option<Self::Item> {
328 let ret = self.next_child?;
329 self.next_child = ret.increment().ok();
330 Some(self.base.child(ret))
331 }
332}
333
334impl DerivationPath {
335 pub fn len(&self) -> usize {
337 self.0.len()
338 }
339
340 pub fn master() -> DerivationPath {
342 DerivationPath(vec![])
343 }
344
345 pub fn is_master(&self) -> bool {
348 self.0.is_empty()
349 }
350
351 pub fn child(&self, cn: ChildNumber) -> DerivationPath {
353 let mut path = self.0.clone();
354 path.push(cn);
355 DerivationPath(path)
356 }
357
358 pub fn into_child(self, cn: ChildNumber) -> DerivationPath {
360 let mut path = self.0;
361 path.push(cn);
362 DerivationPath(path)
363 }
364
365 pub fn children_from(&self, cn: ChildNumber) -> DerivationPathIterator {
368 DerivationPathIterator::start_from(&self, cn)
369 }
370
371 pub fn normal_children(&self) -> DerivationPathIterator {
373 DerivationPathIterator::start_from(&self, ChildNumber::Normal{ index: 0 })
374 }
375
376 pub fn hardened_children(&self) -> DerivationPathIterator {
378 DerivationPathIterator::start_from(&self, ChildNumber::Hardened{ index: 0 })
379 }
380
381 pub fn extend<T: AsRef<[ChildNumber]>>(&self, path: T) -> DerivationPath {
398 let mut new_path = self.clone();
399 new_path.0.extend_from_slice(path.as_ref());
400 new_path
401 }
402}
403
404impl fmt::Display for DerivationPath {
405 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
406 f.write_str("m")?;
407 for cn in self.0.iter() {
408 f.write_str("/")?;
409 fmt::Display::fmt(cn, f)?;
410 }
411 Ok(())
412 }
413}
414
415impl fmt::Debug for DerivationPath {
416 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
417 fmt::Display::fmt(&self, f)
418 }
419}
420
421pub type KeySource = (Fingerprint, DerivationPath);
424
425#[derive(Clone, PartialEq, Eq, Debug)]
427pub enum Error {
428 CannotDeriveFromHardenedKey,
430 Ecdsa(secp256k1::Error),
432 InvalidChildNumber(u32),
434 RngError(String),
436 InvalidChildNumberFormat,
438 InvalidDerivationPathFormat,
440 UnknownVersion([u8; 4]),
442 WrongExtendedKeyLength(usize),
444 Base58(base58::Error)
446}
447
448impl fmt::Display for Error {
449 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
450 match *self {
451 Error::CannotDeriveFromHardenedKey => f.write_str("cannot derive hardened key from public key"),
452 Error::Ecdsa(ref e) => fmt::Display::fmt(e, f),
453 Error::InvalidChildNumber(ref n) => write!(f, "child number {} is invalid (not within [0, 2^31 - 1])", n),
454 Error::RngError(ref s) => write!(f, "rng error {}", s),
455 Error::InvalidChildNumberFormat => f.write_str("invalid child number format"),
456 Error::InvalidDerivationPathFormat => f.write_str("invalid derivation path format"),
457 Error::UnknownVersion(ref bytes) => write!(f, "unknown version magic bytes: {:?}", bytes),
458 Error::WrongExtendedKeyLength(ref len) => write!(f, "encoded extended key data has wrong length {}", len),
459 Error::Base58(ref err) => write!(f, "base58 encoding error: {}", err),
460 }
461 }
462}
463
464impl error::Error for Error {
465 fn cause(&self) -> Option<&dyn error::Error> {
466 if let Error::Ecdsa(ref e) = *self {
467 Some(e)
468 } else {
469 None
470 }
471 }
472}
473
474impl From<key::Error> for Error {
475 fn from(err: key::Error) -> Self {
476 match err {
477 key::Error::Base58(e) => Error::Base58(e),
478 key::Error::Secp256k1(e) => Error::Ecdsa(e),
479 }
480 }
481}
482
483impl From<secp256k1::Error> for Error {
484 fn from(e: secp256k1::Error) -> Error { Error::Ecdsa(e) }
485}
486
487impl From<base58::Error> for Error {
488 fn from(err: base58::Error) -> Self {
489 Error::Base58(err)
490 }
491}
492
493impl ExtendedPrivKey {
494 pub fn new_master(network: Network, seed: &[u8]) -> Result<ExtendedPrivKey, Error> {
496 let mut hmac_engine: HmacEngine<sha512::Hash> = HmacEngine::new(b"Digibyte seed");
497 hmac_engine.input(seed);
498 let hmac_result: Hmac<sha512::Hash> = Hmac::from_engine(hmac_engine);
499
500 Ok(ExtendedPrivKey {
501 network: network,
502 depth: 0,
503 parent_fingerprint: Default::default(),
504 child_number: ChildNumber::from_normal_idx(0)?,
505 private_key: PrivateKey {
506 compressed: true,
507 network: network,
508 key: secp256k1::SecretKey::from_slice(
509 &hmac_result[..32]
510 ).map_err(Error::Ecdsa)?,
511 },
512 chain_code: ChainCode::from(&hmac_result[32..]),
513 })
514 }
515
516 pub fn derive_priv<C: secp256k1::Signing, P: AsRef<[ChildNumber]>>(
520 &self,
521 secp: &Secp256k1<C>,
522 path: &P,
523 ) -> Result<ExtendedPrivKey, Error> {
524 let mut sk: ExtendedPrivKey = *self;
525 for cnum in path.as_ref() {
526 sk = sk.ckd_priv(secp, *cnum)?;
527 }
528 Ok(sk)
529 }
530
531 pub fn ckd_priv<C: secp256k1::Signing>(&self, secp: &Secp256k1<C>, i: ChildNumber) -> Result<ExtendedPrivKey, Error> {
533 let mut hmac_engine: HmacEngine<sha512::Hash> = HmacEngine::new(&self.chain_code[..]);
534 match i {
535 ChildNumber::Normal { .. } => {
536 hmac_engine.input(&PublicKey::from_private_key(secp, &self.private_key).key.serialize()[..]);
538 }
539 ChildNumber::Hardened { .. } => {
540 hmac_engine.input(&[0u8]);
542 hmac_engine.input(&self.private_key[..]);
543 }
544 }
545
546 hmac_engine.input(&endian::u32_to_array_be(u32::from(i)));
547 let hmac_result: Hmac<sha512::Hash> = Hmac::from_engine(hmac_engine);
548 let mut sk = PrivateKey {
549 compressed: true,
550 network: self.network,
551 key: secp256k1::SecretKey::from_slice(&hmac_result[..32]).map_err(Error::Ecdsa)?,
552 };
553 sk.key.add_assign(&self.private_key[..]).map_err(Error::Ecdsa)?;
554
555 Ok(ExtendedPrivKey {
556 network: self.network,
557 depth: self.depth + 1,
558 parent_fingerprint: self.fingerprint(secp),
559 child_number: i,
560 private_key: sk,
561 chain_code: ChainCode::from(&hmac_result[32..])
562 })
563 }
564
565 pub fn decode(data: &[u8]) -> Result<ExtendedPrivKey, Error> {
567 if data.len() != 78 {
568 return Err(Error::WrongExtendedKeyLength(data.len()))
569 }
570
571 let network = if data[0..4] == [0x04u8, 0x88, 0xAD, 0xE4] {
572 Network::Digibyte
573 } else if data[0..4] == [0x04u8, 0x35, 0x83, 0x94] {
574 Network::Testnet
575 } else {
576 let mut ver = [0u8; 4];
577 ver.copy_from_slice(&data[0..4]);
578 return Err(Error::UnknownVersion(ver));
579 };
580
581 Ok(ExtendedPrivKey {
582 network: network,
583 depth: data[4],
584 parent_fingerprint: Fingerprint::from(&data[5..9]),
585 child_number: endian::slice_to_u32_be(&data[9..13]).into(),
586 chain_code: ChainCode::from(&data[13..45]),
587 private_key: PrivateKey {
588 compressed: true,
589 network: network,
590 key: secp256k1::SecretKey::from_slice(
591 &data[46..78]
592 ).map_err(Error::Ecdsa)?,
593 },
594 })
595 }
596
597 pub fn encode(&self) -> [u8; 78] {
599 let mut ret = [0; 78];
600 ret[0..4].copy_from_slice(&match self.network {
601 Network::Digibyte => [0x04, 0x88, 0xAD, 0xE4],
602 Network::Testnet | Network::Signet | Network::Regtest => [0x04, 0x35, 0x83, 0x94],
603 }[..]);
604 ret[4] = self.depth as u8;
605 ret[5..9].copy_from_slice(&self.parent_fingerprint[..]);
606 ret[9..13].copy_from_slice(&endian::u32_to_array_be(u32::from(self.child_number)));
607 ret[13..45].copy_from_slice(&self.chain_code[..]);
608 ret[45] = 0;
609 ret[46..78].copy_from_slice(&self.private_key[..]);
610 ret
611 }
612
613 pub fn identifier<C: secp256k1::Signing>(&self, secp: &Secp256k1<C>) -> XpubIdentifier {
615 ExtendedPubKey::from_private(secp, self).identifier()
616 }
617
618 pub fn fingerprint<C: secp256k1::Signing>(&self, secp: &Secp256k1<C>) -> Fingerprint {
620 Fingerprint::from(&self.identifier(secp)[0..4])
621 }
622}
623
624impl ExtendedPubKey {
625 pub fn from_private<C: secp256k1::Signing>(secp: &Secp256k1<C>, sk: &ExtendedPrivKey) -> ExtendedPubKey {
627 ExtendedPubKey {
628 network: sk.network,
629 depth: sk.depth,
630 parent_fingerprint: sk.parent_fingerprint,
631 child_number: sk.child_number,
632 public_key: PublicKey::from_private_key(secp, &sk.private_key),
633 chain_code: sk.chain_code
634 }
635 }
636
637 pub fn derive_pub<C: secp256k1::Verification, P: AsRef<[ChildNumber]>>(
641 &self,
642 secp: &Secp256k1<C>,
643 path: &P,
644 ) -> Result<ExtendedPubKey, Error> {
645 let mut pk: ExtendedPubKey = *self;
646 for cnum in path.as_ref() {
647 pk = pk.ckd_pub(secp, *cnum)?
648 }
649 Ok(pk)
650 }
651
652 pub fn ckd_pub_tweak(&self, i: ChildNumber) -> Result<(PrivateKey, ChainCode), Error> {
654 match i {
655 ChildNumber::Hardened { .. } => {
656 Err(Error::CannotDeriveFromHardenedKey)
657 }
658 ChildNumber::Normal { index: n } => {
659 let mut hmac_engine: HmacEngine<sha512::Hash> = HmacEngine::new(&self.chain_code[..]);
660 hmac_engine.input(&self.public_key.key.serialize()[..]);
661 hmac_engine.input(&endian::u32_to_array_be(n));
662
663 let hmac_result: Hmac<sha512::Hash> = Hmac::from_engine(hmac_engine);
664
665 let private_key = PrivateKey {
666 compressed: true,
667 network: self.network,
668 key: secp256k1::SecretKey::from_slice(&hmac_result[..32])?,
669 };
670 let chain_code = ChainCode::from(&hmac_result[32..]);
671 Ok((private_key, chain_code))
672 }
673 }
674 }
675
676 pub fn ckd_pub<C: secp256k1::Verification>(
678 &self,
679 secp: &Secp256k1<C>,
680 i: ChildNumber,
681 ) -> Result<ExtendedPubKey, Error> {
682 let (sk, chain_code) = self.ckd_pub_tweak(i)?;
683 let mut pk = self.public_key;
684 pk.key.add_exp_assign(secp, &sk[..]).map_err(Error::Ecdsa)?;
685
686 Ok(ExtendedPubKey {
687 network: self.network,
688 depth: self.depth + 1,
689 parent_fingerprint: self.fingerprint(),
690 child_number: i,
691 public_key: pk,
692 chain_code: chain_code
693 })
694 }
695
696 pub fn decode(data: &[u8]) -> Result<ExtendedPubKey, Error> {
698 if data.len() != 78 {
699 return Err(Error::WrongExtendedKeyLength(data.len()))
700 }
701
702 Ok(ExtendedPubKey {
703 network: if data[0..4] == [0x04u8, 0x88, 0xB2, 0x1E] {
704 Network::Digibyte
705 } else if data[0..4] == [0x04u8, 0x35, 0x87, 0xCF] {
706 Network::Testnet
707 } else {
708 let mut ver = [0u8; 4];
709 ver.copy_from_slice(&data[0..4]);
710 return Err(Error::UnknownVersion(ver));
711 },
712 depth: data[4],
713 parent_fingerprint: Fingerprint::from(&data[5..9]),
714 child_number: endian::slice_to_u32_be(&data[9..13]).into(),
715 chain_code: ChainCode::from(&data[13..45]),
716 public_key: PublicKey::from_slice(&data[45..78])?,
717 })
718 }
719
720 pub fn encode(&self) -> [u8; 78] {
722 let mut ret = [0; 78];
723 ret[0..4].copy_from_slice(&match self.network {
724 Network::Digibyte => [0x04u8, 0x88, 0xB2, 0x1E],
725 Network::Testnet | Network::Signet | Network::Regtest => [0x04u8, 0x35, 0x87, 0xCF],
726 }[..]);
727 ret[4] = self.depth as u8;
728 ret[5..9].copy_from_slice(&self.parent_fingerprint[..]);
729 ret[9..13].copy_from_slice(&endian::u32_to_array_be(u32::from(self.child_number)));
730 ret[13..45].copy_from_slice(&self.chain_code[..]);
731 ret[45..78].copy_from_slice(&self.public_key.key.serialize()[..]);
732 ret
733 }
734
735 pub fn identifier(&self) -> XpubIdentifier {
737 let mut engine = XpubIdentifier::engine();
738 self.public_key.write_into(&mut engine).expect("engines don't error");
739 XpubIdentifier::from_engine(engine)
740 }
741
742 pub fn fingerprint(&self) -> Fingerprint {
744 Fingerprint::from(&self.identifier()[0..4])
745 }
746}
747
748impl fmt::Display for ExtendedPrivKey {
749 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
750 base58::check_encode_slice_to_fmt(fmt, &self.encode()[..])
751 }
752}
753
754impl FromStr for ExtendedPrivKey {
755 type Err = Error;
756
757 fn from_str(inp: &str) -> Result<ExtendedPrivKey, Error> {
758 let data = base58::from_check(inp)?;
759
760 if data.len() != 78 {
761 return Err(base58::Error::InvalidLength(data.len()).into());
762 }
763
764 Ok(ExtendedPrivKey::decode(&data[..])?)
765 }
766}
767
768impl fmt::Display for ExtendedPubKey {
769 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
770 base58::check_encode_slice_to_fmt(fmt, &self.encode()[..])
771 }
772}
773
774impl FromStr for ExtendedPubKey {
775 type Err = Error;
776
777 fn from_str(inp: &str) -> Result<ExtendedPubKey, Error> {
778 let data = base58::from_check(inp)?;
779
780 if data.len() != 78 {
781 return Err(base58::Error::InvalidLength(data.len()).into());
782 }
783
784 Ok(ExtendedPubKey::decode(&data[..])?)
785 }
786}
787
788#[cfg(test)]
789mod tests {
790 use super::*;
791 use super::ChildNumber::{Hardened, Normal};
792
793 use std::str::FromStr;
794 use std::string::ToString;
795
796 use secp256k1::{self, Secp256k1};
797 use hashes::hex::FromHex;
798
799 use network::constants::Network::{self, Digibyte};
800
801 #[test]
802 fn test_parse_derivation_path() {
803 assert_eq!(DerivationPath::from_str("42"), Err(Error::InvalidDerivationPathFormat));
804 assert_eq!(DerivationPath::from_str("n/0'/0"), Err(Error::InvalidDerivationPathFormat));
805 assert_eq!(DerivationPath::from_str("4/m/5"), Err(Error::InvalidDerivationPathFormat));
806 assert_eq!(DerivationPath::from_str("m//3/0'"), Err(Error::InvalidChildNumberFormat));
807 assert_eq!(DerivationPath::from_str("m/0h/0x"), Err(Error::InvalidChildNumberFormat));
808 assert_eq!(DerivationPath::from_str("m/2147483648"), Err(Error::InvalidChildNumber(2147483648)));
809
810 assert_eq!(DerivationPath::master(), DerivationPath::from_str("m").unwrap());
811 assert_eq!(DerivationPath::master(), DerivationPath::default());
812 assert_eq!(DerivationPath::from_str("m"), Ok(vec![].into()));
813 assert_eq!(
814 DerivationPath::from_str("m/0'"),
815 Ok(vec![ChildNumber::from_hardened_idx(0).unwrap()].into())
816 );
817 assert_eq!(
818 DerivationPath::from_str("m/0'/1"),
819 Ok(vec![ChildNumber::from_hardened_idx(0).unwrap(), ChildNumber::from_normal_idx(1).unwrap()].into())
820 );
821 assert_eq!(
822 DerivationPath::from_str("m/0h/1/2'"),
823 Ok(vec![
824 ChildNumber::from_hardened_idx(0).unwrap(),
825 ChildNumber::from_normal_idx(1).unwrap(),
826 ChildNumber::from_hardened_idx(2).unwrap(),
827 ].into())
828 );
829 assert_eq!(
830 DerivationPath::from_str("m/0'/1/2h/2"),
831 Ok(vec![
832 ChildNumber::from_hardened_idx(0).unwrap(),
833 ChildNumber::from_normal_idx(1).unwrap(),
834 ChildNumber::from_hardened_idx(2).unwrap(),
835 ChildNumber::from_normal_idx(2).unwrap(),
836 ].into())
837 );
838 assert_eq!(
839 DerivationPath::from_str("m/0'/1/2'/2/1000000000"),
840 Ok(vec![
841 ChildNumber::from_hardened_idx(0).unwrap(),
842 ChildNumber::from_normal_idx(1).unwrap(),
843 ChildNumber::from_hardened_idx(2).unwrap(),
844 ChildNumber::from_normal_idx(2).unwrap(),
845 ChildNumber::from_normal_idx(1000000000).unwrap(),
846 ].into())
847 );
848 let s = "m/0'/50/3'/5/545456";
849 assert_eq!(DerivationPath::from_str(s), s.into_derivation_path());
850 assert_eq!(DerivationPath::from_str(s), s.to_string().into_derivation_path());
851 }
852
853 #[test]
854 fn test_derivation_path_conversion_index() {
855 let path = DerivationPath::from_str("m/0h/1/2'").unwrap();
856 let numbers: Vec<ChildNumber> = path.clone().into();
857 let path2: DerivationPath = numbers.into();
858 assert_eq!(path, path2);
859 assert_eq!(&path[..2], &[ChildNumber::from_hardened_idx(0).unwrap(), ChildNumber::from_normal_idx(1).unwrap()]);
860 let indexed: DerivationPath = path[..2].into();
861 assert_eq!(indexed, DerivationPath::from_str("m/0h/1").unwrap());
862 assert_eq!(indexed.child(ChildNumber::from_hardened_idx(2).unwrap()), path);
863 }
864
865 fn test_path<C: secp256k1::Signing + secp256k1::Verification>(secp: &Secp256k1<C>,
866 network: Network,
867 seed: &[u8],
868 path: DerivationPath,
869 expected_sk: &str,
870 expected_pk: &str) {
871
872 let mut sk = ExtendedPrivKey::new_master(network, seed).unwrap();
873 let mut pk = ExtendedPubKey::from_private(secp, &sk);
874
875 assert_eq!(
877 &sk.derive_priv(secp, &path).unwrap().to_string()[..],
878 expected_sk
879 );
880
881 if path.0.iter().any(|cnum| cnum.is_hardened()) {
884 assert_eq!(
885 pk.derive_pub(secp, &path),
886 Err(Error::CannotDeriveFromHardenedKey)
887 );
888 } else {
889 assert_eq!(
890 &pk.derive_pub(secp, &path).unwrap().to_string()[..],
891 expected_pk
892 );
893 }
894
895 for &num in path.0.iter() {
897 sk = sk.ckd_priv(secp, num).unwrap();
898 match num {
899 Normal {..} => {
900 let pk2 = pk.ckd_pub(secp, num).unwrap();
901 pk = ExtendedPubKey::from_private(secp, &sk);
902 assert_eq!(pk, pk2);
903 }
904 Hardened {..} => {
905 assert_eq!(
906 pk.ckd_pub(secp, num),
907 Err(Error::CannotDeriveFromHardenedKey)
908 );
909 pk = ExtendedPubKey::from_private(secp, &sk);
910 }
911 }
912 }
913
914 assert_eq!(&sk.to_string()[..], expected_sk);
916 assert_eq!(&pk.to_string()[..], expected_pk);
917 let decoded_sk = ExtendedPrivKey::from_str(expected_sk);
919 let decoded_pk = ExtendedPubKey::from_str(expected_pk);
920 assert_eq!(Ok(sk), decoded_sk);
921 assert_eq!(Ok(pk), decoded_pk);
922 }
923
924 #[test]
925 fn test_increment() {
926 let idx = 9345497; let cn = ChildNumber::from_normal_idx(idx).unwrap();
928 assert_eq!(cn.increment().ok(), Some(ChildNumber::from_normal_idx(idx+1).unwrap()));
929 let cn = ChildNumber::from_hardened_idx(idx).unwrap();
930 assert_eq!(cn.increment().ok(), Some(ChildNumber::from_hardened_idx(idx+1).unwrap()));
931
932 let max = (1<<31)-1;
933 let cn = ChildNumber::from_normal_idx(max).unwrap();
934 assert_eq!(cn.increment().err(), Some(Error::InvalidChildNumber(1<<31)));
935 let cn = ChildNumber::from_hardened_idx(max).unwrap();
936 assert_eq!(cn.increment().err(), Some(Error::InvalidChildNumber(1<<31)));
937
938 let cn = ChildNumber::from_normal_idx(350).unwrap();
939 let path = DerivationPath::from_str("m/42'").unwrap();
940 let mut iter = path.children_from(cn);
941 assert_eq!(iter.next(), Some("m/42'/350".parse().unwrap()));
942 assert_eq!(iter.next(), Some("m/42'/351".parse().unwrap()));
943
944 let path = DerivationPath::from_str("m/42'/350'").unwrap();
945 let mut iter = path.normal_children();
946 assert_eq!(iter.next(), Some("m/42'/350'/0".parse().unwrap()));
947 assert_eq!(iter.next(), Some("m/42'/350'/1".parse().unwrap()));
948
949 let path = DerivationPath::from_str("m/42'/350'").unwrap();
950 let mut iter = path.hardened_children();
951 assert_eq!(iter.next(), Some("m/42'/350'/0'".parse().unwrap()));
952 assert_eq!(iter.next(), Some("m/42'/350'/1'".parse().unwrap()));
953
954 let cn = ChildNumber::from_hardened_idx(42350).unwrap();
955 let path = DerivationPath::from_str("m/42'").unwrap();
956 let mut iter = path.children_from(cn);
957 assert_eq!(iter.next(), Some("m/42'/42350'".parse().unwrap()));
958 assert_eq!(iter.next(), Some("m/42'/42351'".parse().unwrap()));
959
960 let cn = ChildNumber::from_hardened_idx(max).unwrap();
961 let path = DerivationPath::from_str("m/42'").unwrap();
962 let mut iter = path.children_from(cn);
963 assert!(iter.next().is_some());
964 assert!(iter.next().is_none());
965 }
966
967 #[test]
968 fn test_vector_1() {
969 let secp = Secp256k1::new();
970 let seed = Vec::from_hex("000102030405060708090a0b0c0d0e0f").unwrap();
971
972 test_path(&secp, Digibyte, &seed, "m".parse().unwrap(),
974 "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi",
975 "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8");
976
977 test_path(&secp, Digibyte, &seed, "m/0h".parse().unwrap(),
979 "xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7",
980 "xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw");
981
982 test_path(&secp, Digibyte, &seed, "m/0h/1".parse().unwrap(),
984 "xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs",
985 "xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ");
986
987 test_path(&secp, Digibyte, &seed, "m/0h/1/2h".parse().unwrap(),
989 "xprv9z4pot5VBttmtdRTWfWQmoH1taj2axGVzFqSb8C9xaxKymcFzXBDptWmT7FwuEzG3ryjH4ktypQSAewRiNMjANTtpgP4mLTj34bhnZX7UiM",
990 "xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5");
991
992 test_path(&secp, Digibyte, &seed, "m/0h/1/2h/2".parse().unwrap(),
994 "xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334",
995 "xpub6FHa3pjLCk84BayeJxFW2SP4XRrFd1JYnxeLeU8EqN3vDfZmbqBqaGJAyiLjTAwm6ZLRQUMv1ZACTj37sR62cfN7fe5JnJ7dh8zL4fiyLHV");
996
997 test_path(&secp, Digibyte, &seed, "m/0h/1/2h/2/1000000000".parse().unwrap(),
999 "xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76",
1000 "xpub6H1LXWLaKsWFhvm6RVpEL9P4KfRZSW7abD2ttkWP3SSQvnyA8FSVqNTEcYFgJS2UaFcxupHiYkro49S8yGasTvXEYBVPamhGW6cFJodrTHy");
1001 }
1002
1003 #[test]
1004 fn test_vector_2() {
1005 let secp = Secp256k1::new();
1006 let seed = Vec::from_hex("fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542").unwrap();
1007
1008 test_path(&secp, Digibyte, &seed, "m".parse().unwrap(),
1010 "xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U",
1011 "xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB");
1012
1013 test_path(&secp, Digibyte, &seed, "m/0".parse().unwrap(),
1015 "xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt",
1016 "xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH");
1017
1018 test_path(&secp, Digibyte, &seed, "m/0/2147483647h".parse().unwrap(),
1020 "xprv9wSp6B7kry3Vj9m1zSnLvN3xH8RdsPP1Mh7fAaR7aRLcQMKTR2vidYEeEg2mUCTAwCd6vnxVrcjfy2kRgVsFawNzmjuHc2YmYRmagcEPdU9",
1021 "xpub6ASAVgeehLbnwdqV6UKMHVzgqAG8Gr6riv3Fxxpj8ksbH9ebxaEyBLZ85ySDhKiLDBrQSARLq1uNRts8RuJiHjaDMBU4Zn9h8LZNnBC5y4a");
1022
1023 test_path(&secp, Digibyte, &seed, "m/0/2147483647h/1".parse().unwrap(),
1025 "xprv9zFnWC6h2cLgpmSA46vutJzBcfJ8yaJGg8cX1e5StJh45BBciYTRXSd25UEPVuesF9yog62tGAQtHjXajPPdbRCHuWS6T8XA2ECKADdw4Ef",
1026 "xpub6DF8uhdarytz3FWdA8TvFSvvAh8dP3283MY7p2V4SeE2wyWmG5mg5EwVvmdMVCQcoNJxGoWaU9DCWh89LojfZ537wTfunKau47EL2dhHKon");
1027
1028 test_path(&secp, Digibyte, &seed, "m/0/2147483647h/1/2147483646h".parse().unwrap(),
1030 "xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc",
1031 "xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL");
1032
1033 test_path(&secp, Digibyte, &seed, "m/0/2147483647h/1/2147483646h/2".parse().unwrap(),
1035 "xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j",
1036 "xpub6FnCn6nSzZAw5Tw7cgR9bi15UV96gLZhjDstkXXxvCLsUXBGXPdSnLFbdpq8p9HmGsApME5hQTZ3emM2rnY5agb9rXpVGyy3bdW6EEgAtqt");
1037 }
1038
1039 #[test]
1040 fn test_vector_3() {
1041 let secp = Secp256k1::new();
1042 let seed = Vec::from_hex("4b381541583be4423346c643850da4b320e46a87ae3d2a4e6da11eba819cd4acba45d239319ac14f863b8d5ab5a0d0c64d2e8a1e7d1457df2e5a3c51c73235be").unwrap();
1043
1044 test_path(&secp, Digibyte, &seed, "m".parse().unwrap(),
1046 "xprv9s21ZrQH143K25QhxbucbDDuQ4naNntJRi4KUfWT7xo4EKsHt2QJDu7KXp1A3u7Bi1j8ph3EGsZ9Xvz9dGuVrtHHs7pXeTzjuxBrCmmhgC6",
1047 "xpub661MyMwAqRbcEZVB4dScxMAdx6d4nFc9nvyvH3v4gJL378CSRZiYmhRoP7mBy6gSPSCYk6SzXPTf3ND1cZAceL7SfJ1Z3GC8vBgp2epUt13");
1048
1049 test_path(&secp, Digibyte, &seed, "m/0h".parse().unwrap(),
1051 "xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L",
1052 "xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y");
1053
1054 }
1055
1056 #[test]
1057 #[cfg(feature = "serde")]
1058 pub fn encode_decode_childnumber() {
1059 serde_round_trip!(ChildNumber::from_normal_idx(0).unwrap());
1060 serde_round_trip!(ChildNumber::from_normal_idx(1).unwrap());
1061 serde_round_trip!(ChildNumber::from_normal_idx((1 << 31) - 1).unwrap());
1062 serde_round_trip!(ChildNumber::from_hardened_idx(0).unwrap());
1063 serde_round_trip!(ChildNumber::from_hardened_idx(1).unwrap());
1064 serde_round_trip!(ChildNumber::from_hardened_idx((1 << 31) - 1).unwrap());
1065 }
1066
1067 #[test]
1068 #[cfg(feature = "serde")]
1069 pub fn encode_fingerprint_chaincode() {
1070 use serde_json;
1071 let fp = Fingerprint::from(&[1u8,2,3,42][..]);
1072 let cc = ChainCode::from(
1073 &[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][..]
1074 );
1075
1076 serde_round_trip!(fp);
1077 serde_round_trip!(cc);
1078
1079 assert_eq!("\"0102032a\"", serde_json::to_string(&fp).unwrap());
1080 assert_eq!(
1081 "\"0102030405060708090001020304050607080900010203040506070809000102\"",
1082 serde_json::to_string(&cc).unwrap()
1083 );
1084 assert_eq!("0102032a", fp.to_string());
1085 assert_eq!(
1086 "0102030405060708090001020304050607080900010203040506070809000102",
1087 cc.to_string()
1088 );
1089 }
1090
1091 #[test]
1092 fn fmt_child_number() {
1093 assert_eq!("000005'", &format!("{:#06}", ChildNumber::from_hardened_idx(5).unwrap()));
1094 assert_eq!("5'", &format!("{:#}", ChildNumber::from_hardened_idx(5).unwrap()));
1095 assert_eq!("000005h", &format!("{:06}", ChildNumber::from_hardened_idx(5).unwrap()));
1096 assert_eq!("5h", &format!("{}", ChildNumber::from_hardened_idx(5).unwrap()));
1097 assert_eq!("42", &format!("{}", ChildNumber::from_normal_idx(42).unwrap()));
1098 assert_eq!("000042", &format!("{:06}", ChildNumber::from_normal_idx(42).unwrap()));
1099 }
1100}
1101