1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#![no_std]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![doc = include_str!("../README.md")]
#![forbid(unsafe_code)]
#![warn(
    clippy::unwrap_used,
    missing_docs,
    rust_2018_idioms,
    unused_qualifications
)]

//! ## Backends
//! This crate provides a generic implementation of BIP32 which can be used
//! with any backing provider which implements the [`PrivateKey`] and
//! [`PublicKey`] traits. The following providers are built into this crate,
//! under the following crate features:
//!
//! - `secp256k1` (enabled by default): support for the pure Rust [`k256`]
//!   crate, with [`XPrv`] and [`XPub`] type aliases.
//! - `secp256k1-ffi`: support for Bitcoin Core's [libsecp256k1 C library],
//!   as wrapped by the [`secp256k1` Rust crate].
//!
//! ## Limitations and further work
//! - Only 24-word BIP39 mnemonics are supported
//! - BIP43, BIP44, BIP49, BIP84 not yet properly supported
//!
//! # Usage
//! The following is an end-to-end example of how to generate a random BIP39
//! mnemonic and use it to derive child keys according to a provided BIP32
//! derivation path.
//!
//! ## Accessing `OsRng`
//! The following example uses `OsRng` for cryptographically secure random
//! number generation. To use it, you need to include `rand_core` with the
//! `std` feature by adding the following to `Cargo.toml`:
//!
//! ```toml
//! rand_core = { version = "0.6", features = ["std"] }
//! ```
//!
//! (on embedded platforms, you will need to supply our own RNG)
//!
//! ## Rust code example
//! ```
//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
//! # #[cfg(all(feature = "bip39", feature = "secp256k1"))]
//! # {
//! use bip32::{Mnemonic, Prefix, XPrv};
//! use rand_core::OsRng;
//!
//! // Generate random Mnemonic using the default language (English)
//! let mnemonic = Mnemonic::random(&mut OsRng, Default::default());
//!
//! // Derive a BIP39 seed value using the given password
//! let seed = mnemonic.to_seed("password");
//!
//! // Derive the root `XPrv` from the `seed` value
//! let root_xprv = XPrv::new(&seed)?;
//! assert_eq!(root_xprv, XPrv::derive_from_path(&seed, &"m".parse()?)?);
//!
//! // Derive a child `XPrv` using the provided BIP32 derivation path
//! let child_path = "m/0/2147483647'/1/2147483646'";
//! let child_xprv = XPrv::derive_from_path(&seed, &child_path.parse()?)?;
//!
//! // Get the `XPub` associated with `child_xprv`.
//! let child_xpub = child_xprv.public_key();
//!
//! // Serialize `child_xprv` as a string with the `xprv` prefix.
//! let child_xprv_str = child_xprv.to_string(Prefix::XPRV);
//! assert!(child_xprv_str.starts_with("xprv"));
//!
//! // Serialize `child_xpub` as a string with the `xpub` prefix.
//! let child_xpub_str = child_xpub.to_string(Prefix::XPUB);
//! assert!(child_xpub_str.starts_with("xpub"));
//!
//! // Get the ECDSA/secp256k1 signing and verification keys for the xprv and xpub
//! let signing_key = child_xprv.private_key();
//! let verification_key = child_xpub.public_key();
//!
//! // Sign and verify an example message using the derived keys.
//! use bip32::secp256k1::ecdsa::{
//!     signature::{Signer, Verifier},
//!     Signature
//! };
//!
//! let example_msg = b"Hello, world!";
//! let signature: Signature = signing_key.sign(example_msg);
//! assert!(verification_key.verify(example_msg, &signature).is_ok());
//! # }
//! # Ok(())
//! # }
//! ```
//!
//! [bip32]: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
//! [libsecp256k1 C library]: https://github.com/bitcoin-core/secp256k1
//! [`secp256k1` Rust crate]: https://github.com/rust-bitcoin/rust-secp256k1/

#[cfg(feature = "alloc")]
extern crate alloc;

#[cfg(feature = "std")]
extern crate std;

mod child_number;
mod error;
mod extended_key;
mod prefix;
mod private_key;
mod public_key;

#[cfg(feature = "alloc")]
mod derivation_path;

#[cfg(feature = "mnemonic")]
mod mnemonic;

pub use crate::{
    child_number::ChildNumber,
    error::{Error, Result},
    extended_key::{
        attrs::ExtendedKeyAttrs, private_key::ExtendedPrivateKey, public_key::ExtendedPublicKey,
        ExtendedKey,
    },
    prefix::Prefix,
    private_key::{PrivateKey, PrivateKeyBytes},
    public_key::{PublicKey, PublicKeyBytes},
};

#[cfg(feature = "alloc")]
pub use crate::derivation_path::DerivationPath;

#[cfg(feature = "bip39")]
pub use crate::mnemonic::{Language, Phrase as Mnemonic, Seed};

#[cfg(feature = "secp256k1")]
pub use {
    crate::extended_key::{private_key::XPrv, public_key::XPub},
    k256 as secp256k1,
};

/// Chain code: extension for both private and public keys which provides an
/// additional 256-bits of entropy.
pub type ChainCode = [u8; KEY_SIZE];

/// Derivation depth.
pub type Depth = u8;

/// BIP32 key fingerprints.
pub type KeyFingerprint = [u8; 4];

/// BIP32 "versions": integer representation of the key prefix.
pub type Version = u32;

/// HMAC with SHA-512
type HmacSha512 = hmac::Hmac<sha2::Sha512>;

/// Size of input key material and derived keys.
pub const KEY_SIZE: usize = 32;