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