cs_mwc_bch/wallet/
extended_key.rs

1use byteorder::{BigEndian, WriteBytesExt};
2use network::Network;
3use ring::hmac;
4use rust_base58::base58::{FromBase58, ToBase58};
5use secp256k1::{PublicKey, Secp256k1, SecretKey};
6use std::fmt;
7use std::io;
8use std::io::{Cursor, Read, Write};
9use std::slice;
10use util::{hash160, sha256d, Error, Result, Serializable};
11
12/// Maximum private key value (exclusive)
13const SECP256K1_CURVE_ORDER: [u8; 32] = [
14    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
15    0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41,
16];
17
18/// Index which begins the derived hardened keys
19pub const HARDENED_KEY: u32 = 2147483648;
20
21/// "xpub" prefix for public extended keys on mainnet
22pub const MAINNET_PUBLIC_EXTENDED_KEY: u32 = 0x0488B21E;
23/// "xprv" prefix for private extended keys on mainnet
24pub const MAINNET_PRIVATE_EXTENDED_KEY: u32 = 0x0488ADE4;
25/// "tpub" prefix for public extended keys on testnet
26pub const TESTNET_PUBLIC_EXTENDED_KEY: u32 = 0x043587C;
27/// "tprv" prefix for private extended keys on testnet
28pub const TESTNET_PRIVATE_EXTENDED_KEY: u32 = 0x04358394;
29
30/// Public or private key type
31#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
32pub enum ExtendedKeyType {
33    Public,
34    Private,
35}
36
37/// A private or public key in an hierarchical deterministic wallet
38#[derive(Clone, Copy)]
39pub struct ExtendedKey(pub [u8; 78]);
40
41impl ExtendedKey {
42    /// Creates a new extended public key
43    pub fn new_public_key(
44        network: Network,
45        depth: u8,
46        parent_fingerprint: &[u8],
47        index: u32,
48        chain_code: &[u8],
49        public_key: &[u8],
50    ) -> Result<ExtendedKey> {
51        if parent_fingerprint.len() != 4 {
52            return Err(Error::BadArgument("Fingerprint must be len 4".to_string()));
53        }
54        if chain_code.len() != 32 {
55            return Err(Error::BadArgument("Chain code must be len 32".to_string()));
56        }
57        if public_key.len() != 33 {
58            return Err(Error::BadArgument("Public key must be len 33".to_string()));
59        }
60        let mut extended_key = ExtendedKey([0; 78]);
61        {
62            let mut c = Cursor::new(&mut extended_key.0 as &mut [u8]);
63            match network {
64                Network::Mainnet => c
65                    .write_u32::<BigEndian>(MAINNET_PUBLIC_EXTENDED_KEY)
66                    .unwrap(),
67                Network::Testnet => c
68                    .write_u32::<BigEndian>(TESTNET_PUBLIC_EXTENDED_KEY)
69                    .unwrap(),
70            }
71            c.write_u8(depth).unwrap();
72            c.write(parent_fingerprint).unwrap();
73            c.write_u32::<BigEndian>(index).unwrap();
74            c.write(chain_code).unwrap();
75            c.write(public_key).unwrap();
76        }
77        Ok(extended_key)
78    }
79
80    /// Creates a new extended private key
81    pub fn new_private_key(
82        network: Network,
83        depth: u8,
84        parent_fingerprint: &[u8],
85        index: u32,
86        chain_code: &[u8],
87        private_key: &[u8],
88    ) -> Result<ExtendedKey> {
89        if parent_fingerprint.len() != 4 {
90            return Err(Error::BadArgument("Fingerprint must be len 4".to_string()));
91        }
92        if chain_code.len() != 32 {
93            return Err(Error::BadArgument("Chain code must be len 32".to_string()));
94        }
95        if private_key.len() != 32 {
96            return Err(Error::BadArgument("Private key must be len 32".to_string()));
97        }
98        let mut extended_key = ExtendedKey([0; 78]);
99        {
100            let mut c = Cursor::new(&mut extended_key.0 as &mut [u8]);
101            match network {
102                Network::Mainnet => c
103                    .write_u32::<BigEndian>(MAINNET_PRIVATE_EXTENDED_KEY)
104                    .unwrap(),
105                Network::Testnet => c
106                    .write_u32::<BigEndian>(TESTNET_PRIVATE_EXTENDED_KEY)
107                    .unwrap(),
108            }
109            c.write_u8(depth).unwrap();
110            c.write(parent_fingerprint).unwrap();
111            c.write_u32::<BigEndian>(index).unwrap();
112            c.write(chain_code).unwrap();
113            c.write_u8(0).unwrap();
114            c.write(private_key).unwrap();
115        }
116        Ok(extended_key)
117    }
118
119    /// Gets the extended key version byte prefix
120    pub fn version(&self) -> u32 {
121        ((self.0[0] as u32) << 24)
122            | ((self.0[1] as u32) << 16)
123            | ((self.0[2] as u32) << 8)
124            | ((self.0[3] as u32) << 0)
125    }
126
127    /// Gets the network
128    pub fn network(&self) -> Result<Network> {
129        let ver = self.version();
130        if ver == MAINNET_PUBLIC_EXTENDED_KEY || ver == MAINNET_PRIVATE_EXTENDED_KEY {
131            return Ok(Network::Mainnet);
132        } else if ver == TESTNET_PUBLIC_EXTENDED_KEY || ver == TESTNET_PRIVATE_EXTENDED_KEY {
133            return Ok(Network::Testnet);
134        } else {
135            let msg = format!("Unknown extended key version {:?}", ver);
136            return Err(Error::BadData(msg));
137        }
138    }
139
140    /// Gets the key type
141    pub fn key_type(&self) -> Result<ExtendedKeyType> {
142        let ver = self.version();
143        if ver == MAINNET_PUBLIC_EXTENDED_KEY || ver == TESTNET_PUBLIC_EXTENDED_KEY {
144            return Ok(ExtendedKeyType::Public);
145        } else if ver == MAINNET_PRIVATE_EXTENDED_KEY || ver == TESTNET_PRIVATE_EXTENDED_KEY {
146            return Ok(ExtendedKeyType::Private);
147        } else {
148            let msg = format!("Unknown extended key version {:?}", ver);
149            return Err(Error::BadData(msg));
150        }
151    }
152
153    /// Gets the depth
154    pub fn depth(&self) -> u8 {
155        self.0[4]
156    }
157
158    /// Gets the first 4 bytes of the parent key, or 0 if this is the master key
159    pub fn parent_fingerprint(&self) -> [u8; 4] {
160        [self.0[5], self.0[6], self.0[7], self.0[8]]
161    }
162
163    /// Get the index of this key as derived from the parent
164    pub fn index(&self) -> u32 {
165        ((self.0[9] as u32) << 24)
166            | ((self.0[10] as u32) << 16)
167            | ((self.0[11] as u32) << 8)
168            | ((self.0[12] as u32) << 0)
169    }
170
171    /// Gets the chain code
172    pub fn chain_code(&self) -> [u8; 32] {
173        let mut chain_code = [0; 32];
174        chain_code.clone_from_slice(&self.0[13..45]);
175        chain_code
176    }
177
178    /// Gets the public key if this is an extended public key
179    pub fn public_key(&self) -> Result<[u8; 33]> {
180        match self.key_type()? {
181            ExtendedKeyType::Public => {
182                let mut public_key = [0; 33];
183                public_key.clone_from_slice(&self.0[45..]);
184                Ok(public_key)
185            }
186            ExtendedKeyType::Private => {
187                let secp = Secp256k1::signing_only();
188                let secp_secret_key = SecretKey::from_slice(&self.0[46..])?;
189                let secp_public_key = PublicKey::from_secret_key(&secp, &secp_secret_key);
190                Ok(secp_public_key.serialize())
191            }
192        }
193    }
194
195    /// Gets the private key if this is an extended private key
196    pub fn private_key(&self) -> Result<[u8; 32]> {
197        if self.key_type()? == ExtendedKeyType::Private {
198            let mut private_key = [0; 32];
199            private_key.clone_from_slice(&self.0[46..]);
200            Ok(private_key)
201        } else {
202            let msg = "Cannot get private key of public extended key";
203            Err(Error::BadData(msg.to_string()))
204        }
205    }
206
207    /// Gets the fingerprint of the public key hash
208    pub fn fingerprint(&self) -> Result<[u8; 4]> {
209        let mut fingerprint = [0; 4];
210        let public_key_hash = hash160(&self.public_key()?);
211        fingerprint.clone_from_slice(&public_key_hash.0[..4]);
212        Ok(fingerprint)
213    }
214
215    /// Gets the extenced public key for this key
216    pub fn extended_public_key(&self) -> Result<ExtendedKey> {
217        match self.key_type()? {
218            ExtendedKeyType::Public => Ok(self.clone()),
219            ExtendedKeyType::Private => {
220                let private_key = &self.0[46..];
221                let secp = Secp256k1::signing_only();
222                let secp_secret_key = SecretKey::from_slice(&private_key)?;
223                let secp_public_key = PublicKey::from_secret_key(&secp, &secp_secret_key);
224                let public_key = secp_public_key.serialize();
225
226                ExtendedKey::new_public_key(
227                    self.network()?,
228                    self.depth(),
229                    &self.0[5..9],
230                    self.index(),
231                    &self.0[13..45],
232                    &public_key,
233                )
234            }
235        }
236    }
237
238    /// Derives an extended child private key from an extended parent private key
239    pub fn derive_private_key(&self, index: u32) -> Result<ExtendedKey> {
240        if self.key_type()? == ExtendedKeyType::Public {
241            let msg = "Cannot derive private key from public key";
242            return Err(Error::BadData(msg.to_string()));
243        }
244        let network = self.network()?;
245        if self.depth() == 255 {
246            let msg = "Cannot derive extended key. Depth already at max.";
247            return Err(Error::BadData(msg.to_string()));
248        }
249
250        let secp = Secp256k1::signing_only();
251        let private_key = &self.0[46..];
252        let secp_par_secret_key = SecretKey::from_slice(&private_key)?;
253        let chain_code = &self.0[13..45];
254        let key = hmac::Key::new(hmac::HMAC_SHA512, chain_code);
255
256        let hmac = if index >= HARDENED_KEY {
257            let mut v = Vec::<u8>::with_capacity(37);
258            v.push(0);
259            v.extend_from_slice(&private_key);
260            v.write_u32::<BigEndian>(index)?;
261            hmac::sign(&key, &v)
262        } else {
263            let mut v = Vec::<u8>::with_capacity(37);
264            let secp_public_key = PublicKey::from_secret_key(&secp, &secp_par_secret_key);
265            let public_key = secp_public_key.serialize();
266            v.extend_from_slice(&public_key);
267            v.write_u32::<BigEndian>(index)?;
268            hmac::sign(&key, &v)
269        };
270
271        if hmac.as_ref().len() != 64 {
272            return Err(Error::IllegalState("HMAC invalid length".to_string()));
273        }
274
275        if !is_private_key_valid(&hmac.as_ref()[..32]) {
276            let msg = "Invalid key. Try next index.".to_string();
277            return Err(Error::IllegalState(msg));
278        }
279
280        let mut secp_child_secret_key = SecretKey::from_slice(&hmac.as_ref()[..32])?;
281        secp_child_secret_key.add_assign(&private_key)?;
282
283        let child_chain_code = &hmac.as_ref()[32..];
284        let fingerprint = self.fingerprint()?;
285        let child_private_key =
286            unsafe { slice::from_raw_parts(secp_child_secret_key.as_ptr(), 32) };
287
288        ExtendedKey::new_private_key(
289            network,
290            self.depth() + 1,
291            &fingerprint,
292            index,
293            child_chain_code,
294            child_private_key,
295        )
296    }
297
298    /// Derives an extended child public key from an extended parent public key
299    pub fn derive_public_key(&self, index: u32) -> Result<ExtendedKey> {
300        if index >= HARDENED_KEY {
301            return Err(Error::BadArgument("i cannot be hardened".to_string()));
302        }
303        let network = self.network()?;
304        if self.depth() == 255 {
305            let msg = "Cannot derive extended key. Depth already at max.";
306            return Err(Error::BadData(msg.to_string()));
307        }
308
309        let chain_code = &self.0[13..45];
310        let key = hmac::Key::new(hmac::HMAC_SHA512, chain_code);
311        let mut v = Vec::<u8>::with_capacity(65);
312        let public_key = self.public_key()?;
313        v.extend_from_slice(&public_key);
314        v.write_u32::<BigEndian>(index)?;
315        let hmac = hmac::sign(&key, &v);
316
317        if hmac.as_ref().len() != 64 {
318            return Err(Error::IllegalState("HMAC invalid length".to_string()));
319        }
320
321        if !is_private_key_valid(&hmac.as_ref()[..32]) {
322            let msg = "Invalid key. Try next index.".to_string();
323            return Err(Error::IllegalState(msg));
324        }
325
326        let secp = Secp256k1::signing_only();
327        let child_offset = SecretKey::from_slice(&hmac.as_ref()[..32])?;
328        let child_offset = PublicKey::from_secret_key(&secp, &child_offset);
329        let secp_par_public_key = PublicKey::from_slice(&public_key)?;
330        let secp_child_public_key = secp_par_public_key.combine(&child_offset)?;
331        let child_public_key = secp_child_public_key.serialize();
332
333        let child_chain_code = &hmac.as_ref()[32..];
334        let fingerprint = self.fingerprint()?;
335
336        ExtendedKey::new_public_key(
337            network,
338            self.depth() + 1,
339            &fingerprint,
340            index,
341            child_chain_code,
342            &child_public_key,
343        )
344    }
345
346    /// Encodes an extended key into a string
347    pub fn encode(&self) -> String {
348        let checksum = sha256d(&self.0);
349        let mut v = Vec::with_capacity(82);
350        v.extend_from_slice(&self.0);
351        v.extend_from_slice(&checksum.0[..4]);
352        v.to_base58()
353    }
354
355    /// Decodes an extended key from a string
356    pub fn decode(s: &str) -> Result<ExtendedKey> {
357        let v = s.from_base58()?;
358        let checksum = sha256d(&v[..78]);
359        if checksum.0[..4] != v[78..] {
360            return Err(Error::BadArgument("Invalid checksum".to_string()));
361        }
362        let mut extended_key = ExtendedKey([0; 78]);
363        extended_key.0.clone_from_slice(&v[..78]);
364        Ok(extended_key)
365    }
366}
367
368impl Serializable<ExtendedKey> for ExtendedKey {
369    fn read(reader: &mut dyn Read) -> Result<ExtendedKey> {
370        let mut k = ExtendedKey([0; 78]);
371        reader.read(&mut k.0)?;
372        Ok(k)
373    }
374
375    fn write(&self, writer: &mut dyn Write) -> io::Result<()> {
376        writer.write(&self.0)?;
377        Ok(())
378    }
379}
380
381impl fmt::Debug for ExtendedKey {
382    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
383        write!(f, "{}", self.encode())
384    }
385}
386
387impl PartialEq for ExtendedKey {
388    fn eq(&self, other: &ExtendedKey) -> bool {
389        self.0.to_vec() == other.0.to_vec()
390    }
391}
392
393impl Eq for ExtendedKey {}
394
395/// Derives a key using the BIP-32 and BIP-44 shortened key notation
396pub fn derive_extended_key(master: &ExtendedKey, path: &str) -> Result<ExtendedKey> {
397    let parts: Vec<&str> = path.split('/').collect();
398    let mut key_type = ExtendedKeyType::Public;
399
400    if parts[0] == "m" {
401        if master.key_type()? == ExtendedKeyType::Public {
402            let msg = "Cannot derive private key from public master";
403            return Err(Error::BadArgument(msg.to_string()));
404        }
405        key_type = ExtendedKeyType::Private;
406    } else if parts[0] != "M" {
407        let msg = "Path must start with m or M";
408        return Err(Error::BadArgument(msg.to_string()));
409    }
410
411    let mut key = master.clone();
412
413    for part in parts[1..].iter() {
414        if part.len() == 0 {
415            let msg = "Empty part";
416            return Err(Error::BadArgument(msg.to_string()));
417        }
418
419        let index = if part.ends_with("'") || part.ends_with("h") || part.ends_with("H") {
420            let index: u32 = part
421                .trim_end_matches("'")
422                .trim_end_matches("h")
423                .trim_end_matches("H")
424                .parse()?;
425            if index >= HARDENED_KEY {
426                let msg = "Key index is already hardened";
427                return Err(Error::BadArgument(msg.to_string()));
428            }
429            index + HARDENED_KEY
430        } else {
431            part.parse()?
432        };
433
434        key = match key_type {
435            ExtendedKeyType::Public => key.derive_public_key(index)?,
436            ExtendedKeyType::Private => key.derive_private_key(index)?,
437        };
438    }
439
440    Ok(key)
441}
442
443/// Checks that a private key is in valid SECP256K1 range
444pub fn is_private_key_valid(key: &[u8]) -> bool {
445    let mut is_below_order = false;
446    if key.len() != 32 {
447        return false;
448    }
449    for i in 0..32 {
450        if key[i] < SECP256K1_CURVE_ORDER[i] {
451            is_below_order = true;
452            break;
453        }
454    }
455    if !is_below_order {
456        return false;
457    }
458    for i in 0..32 {
459        if key[i] != 0 {
460            return true;
461        }
462    }
463    return false;
464}
465
466#[cfg(test)]
467mod tests {
468    use super::*;
469    use hex;
470
471    #[test]
472    fn private_key_range() {
473        // Valid
474        let mut max = SECP256K1_CURVE_ORDER.clone();
475        max[31] = max[31] - 1;
476        assert!(is_private_key_valid(&max));
477        assert!(is_private_key_valid(&[0x01; 32]));
478
479        // Invalid
480        assert!(!is_private_key_valid(&[0x00; 32]));
481        assert!(!is_private_key_valid(&[0xff; 32]));
482        assert!(!is_private_key_valid(&SECP256K1_CURVE_ORDER));
483    }
484
485    #[test]
486    fn path() {
487        // BIP-32 test vector 1
488        let m = master_private_key("000102030405060708090a0b0c0d0e0f");
489        assert!(derive_extended_key(&m, "m").unwrap().encode() == "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi");
490        assert!(derive_extended_key(&m, "m").unwrap().extended_public_key().unwrap().encode() == "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8");
491        assert!(derive_extended_key(&m, "m/0H").unwrap().encode() == "xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7");
492        assert!(derive_extended_key(&m, "m/0H").unwrap().extended_public_key().unwrap().encode() == "xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw");
493        assert!(derive_extended_key(&m, "m/0h/1").unwrap().encode() == "xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs");
494        assert!(
495            derive_extended_key(&m, "m/0h/1")
496                .unwrap()
497                .extended_public_key()
498                .unwrap()
499                .encode()
500                == "xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ"
501        );
502        assert!(derive_extended_key(&m, "m/0h/1/2'").unwrap().encode() == "xprv9z4pot5VBttmtdRTWfWQmoH1taj2axGVzFqSb8C9xaxKymcFzXBDptWmT7FwuEzG3ryjH4ktypQSAewRiNMjANTtpgP4mLTj34bhnZX7UiM");
503        assert!(
504            derive_extended_key(&m, "m/0h/1/2'")
505                .unwrap()
506                .extended_public_key()
507                .unwrap()
508                .encode()
509                == "xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5"
510        );
511        assert!(derive_extended_key(&m, "m/0H/1/2H/2").unwrap().encode() == "xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334");
512        assert!(
513            derive_extended_key(&m, "m/0H/1/2H/2")
514                .unwrap()
515                .extended_public_key()
516                .unwrap()
517                .encode()
518                == "xpub6FHa3pjLCk84BayeJxFW2SP4XRrFd1JYnxeLeU8EqN3vDfZmbqBqaGJAyiLjTAwm6ZLRQUMv1ZACTj37sR62cfN7fe5JnJ7dh8zL4fiyLHV"
519        );
520        assert!(
521            derive_extended_key(&m, "m/0H/1/2H/2/1000000000")
522                .unwrap()
523                .encode()
524                == "xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76"
525        );
526        assert!(
527            derive_extended_key(&m, "m/0H/1/2H/2/1000000000")
528                .unwrap()
529                .extended_public_key()
530                .unwrap()
531                .encode()
532                == "xpub6H1LXWLaKsWFhvm6RVpEL9P4KfRZSW7abD2ttkWP3SSQvnyA8FSVqNTEcYFgJS2UaFcxupHiYkro49S8yGasTvXEYBVPamhGW6cFJodrTHy"
533        );
534
535        // BIP-32 test vector 2
536        let m = master_private_key("fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542");
537        assert!(derive_extended_key(&m, "m").unwrap().encode() == "xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U");
538        assert!(derive_extended_key(&m, "m").unwrap().extended_public_key().unwrap().encode() == "xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB");
539        assert!(derive_extended_key(&m, "m/0").unwrap().encode() == "xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt");
540        assert!(derive_extended_key(&m, "m/0").unwrap().extended_public_key().unwrap().encode() == "xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH");
541        assert!(derive_extended_key(&m, "m/0/2147483647H").unwrap().encode() == "xprv9wSp6B7kry3Vj9m1zSnLvN3xH8RdsPP1Mh7fAaR7aRLcQMKTR2vidYEeEg2mUCTAwCd6vnxVrcjfy2kRgVsFawNzmjuHc2YmYRmagcEPdU9");
542        assert!(derive_extended_key(&m, "m/0/2147483647H").unwrap().extended_public_key().unwrap().encode() == "xpub6ASAVgeehLbnwdqV6UKMHVzgqAG8Gr6riv3Fxxpj8ksbH9ebxaEyBLZ85ySDhKiLDBrQSARLq1uNRts8RuJiHjaDMBU4Zn9h8LZNnBC5y4a");
543        assert!(derive_extended_key(&m, "m/0/2147483647H/1").unwrap().encode() == "xprv9zFnWC6h2cLgpmSA46vutJzBcfJ8yaJGg8cX1e5StJh45BBciYTRXSd25UEPVuesF9yog62tGAQtHjXajPPdbRCHuWS6T8XA2ECKADdw4Ef");
544        assert!(derive_extended_key(&m, "m/0/2147483647H/1").unwrap().extended_public_key().unwrap().encode() == "xpub6DF8uhdarytz3FWdA8TvFSvvAh8dP3283MY7p2V4SeE2wyWmG5mg5EwVvmdMVCQcoNJxGoWaU9DCWh89LojfZ537wTfunKau47EL2dhHKon");
545        assert!(derive_extended_key(&m, "m/0/2147483647H/1/2147483646H").unwrap().encode() == "xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc");
546        assert!(derive_extended_key(&m, "m/0/2147483647H/1/2147483646H").unwrap().extended_public_key().unwrap().encode() == "xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL");
547        assert!(derive_extended_key(&m, "m/0/2147483647H/1/2147483646H/2").unwrap().encode() == "xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j");
548        assert!(derive_extended_key(&m, "m/0/2147483647H/1/2147483646H/2").unwrap().extended_public_key().unwrap().encode() == "xpub6FnCn6nSzZAw5Tw7cgR9bi15UV96gLZhjDstkXXxvCLsUXBGXPdSnLFbdpq8p9HmGsApME5hQTZ3emM2rnY5agb9rXpVGyy3bdW6EEgAtqt");
549
550        // BIP-32 test vector 3
551        let m = master_private_key("4b381541583be4423346c643850da4b320e46a87ae3d2a4e6da11eba819cd4acba45d239319ac14f863b8d5ab5a0d0c64d2e8a1e7d1457df2e5a3c51c73235be");
552        assert!(derive_extended_key(&m, "m").unwrap().encode() == "xprv9s21ZrQH143K25QhxbucbDDuQ4naNntJRi4KUfWT7xo4EKsHt2QJDu7KXp1A3u7Bi1j8ph3EGsZ9Xvz9dGuVrtHHs7pXeTzjuxBrCmmhgC6");
553        assert!(derive_extended_key(&m, "m").unwrap().extended_public_key().unwrap().encode() == "xpub661MyMwAqRbcEZVB4dScxMAdx6d4nFc9nvyvH3v4gJL378CSRZiYmhRoP7mBy6gSPSCYk6SzXPTf3ND1cZAceL7SfJ1Z3GC8vBgp2epUt13");
554        assert!(derive_extended_key(&m, "m/0H").unwrap().encode() == "xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L");
555        assert!(derive_extended_key(&m, "m/0H").unwrap().extended_public_key().unwrap().encode() == "xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y");
556    }
557
558    #[test]
559    fn new_public_key() {
560        let key = ExtendedKey::new_public_key(
561            Network::Testnet,
562            111,
563            &[0, 1, 2, 3],
564            44,
565            &[5; 32],
566            &[6; 33],
567        )
568        .unwrap();
569        assert!(key.network().unwrap() == Network::Testnet);
570        assert!(key.key_type().unwrap() == ExtendedKeyType::Public);
571        assert!(key.depth() == 111);
572        assert!(key.parent_fingerprint() == [0_u8, 1_u8, 2_u8, 3_u8]);
573        assert!(key.index() == 44);
574        assert!(key.chain_code() == [5_u8; 32]);
575        assert!(
576            key.public_key().unwrap()[1..] == [6_u8; 32] && key.public_key().unwrap()[0] == 6_u8
577        );
578
579        // Errors
580        assert!(ExtendedKey::new_public_key(
581            Network::Testnet,
582            111,
583            &[0, 1, 2],
584            44,
585            &[5; 32],
586            &[6; 33],
587        )
588        .is_err());
589        assert!(ExtendedKey::new_public_key(
590            Network::Testnet,
591            111,
592            &[0, 1, 2, 3],
593            44,
594            &[5; 31],
595            &[6; 33],
596        )
597        .is_err());
598        assert!(ExtendedKey::new_public_key(
599            Network::Testnet,
600            111,
601            &[0, 1, 2, 3],
602            44,
603            &[5; 32],
604            &[6; 32],
605        )
606        .is_err());
607    }
608
609    #[test]
610    fn new_private_key() {
611        let key = ExtendedKey::new_private_key(
612            Network::Mainnet,
613            255,
614            &[4, 5, 6, 7],
615            HARDENED_KEY + 100,
616            &[7; 32],
617            &[8; 32],
618        )
619        .unwrap();
620        assert!(key.network().unwrap() == Network::Mainnet);
621        assert!(key.key_type().unwrap() == ExtendedKeyType::Private);
622        assert!(key.depth() == 255);
623        assert!(key.parent_fingerprint() == [4_u8, 5_u8, 6_u8, 7_u8]);
624        assert!(key.index() == HARDENED_KEY + 100);
625        assert!(key.chain_code() == [7_u8; 32]);
626        assert!(key.private_key().unwrap() == [8_u8; 32]);
627
628        // Errors
629        assert!(ExtendedKey::new_private_key(
630            Network::Mainnet,
631            255,
632            &[4, 5, 6],
633            HARDENED_KEY + 100,
634            &[7; 32],
635            &[8; 32],
636        )
637        .is_err());
638        assert!(ExtendedKey::new_private_key(
639            Network::Mainnet,
640            255,
641            &[4, 5, 6, 7],
642            HARDENED_KEY + 100,
643            &[7],
644            &[8; 32],
645        )
646        .is_err());
647        assert!(ExtendedKey::new_private_key(
648            Network::Mainnet,
649            255,
650            &[4, 5, 6, 7],
651            HARDENED_KEY + 100,
652            &[7; 32],
653            &[8; 33],
654        )
655        .is_err());
656    }
657
658    #[test]
659    fn invalid() {
660        let k = ExtendedKey([5; 78]);
661        assert!(k.network().is_err());
662        assert!(k.key_type().is_err());
663    }
664
665    #[test]
666    fn encode_decode() {
667        let k = master_private_key("0123456789abcdef");
668        assert!(k == ExtendedKey::decode(&k.encode()).unwrap());
669        let k = derive_extended_key(&k, "M/1/2/3/4/5").unwrap();
670        assert!(k == ExtendedKey::decode(&k.encode()).unwrap());
671    }
672
673    fn master_private_key(seed: &str) -> ExtendedKey {
674        let seed = hex::decode(seed).unwrap();
675        let key = "Bitcoin seed".to_string();
676        let key = hmac::Key::new(hmac::HMAC_SHA512, &key.as_bytes());
677        let hmac = hmac::sign(&key, &seed);
678        ExtendedKey::new_private_key(
679            Network::Mainnet,
680            0,
681            &[0; 4],
682            0,
683            &hmac.as_ref()[32..],
684            &hmac.as_ref()[0..32],
685        )
686        .unwrap()
687    }
688}