coins_bip32/lib.rs
1#![forbid(unsafe_code)]
2#![warn(
3 missing_docs,
4 missing_copy_implementations,
5 missing_debug_implementations,
6 unreachable_pub,
7 unused_crate_dependencies,
8 clippy::missing_const_for_fn,
9 unused_extern_crates
10)]
11
12//! This crate provides a basic implementation of BIP32, BIP49, and BIP84.
13//! It can be easily adapted to support other networks, using the
14//! paramaterizable encoder.
15//!
16//!
17//! Typically, users will want to use the `MainnetEncoder`, `DerivedXPub`, `DerivedXPriv` types,
18//! which are available at the crate root. If key derivations are unknown, use the `XPub` and
19//! `XPriv` objects instead. These may be deserialized using a network-specific `Encoder` from the
20//! `enc` module.
21//!
22//! Useful traits will need to be imported from the `enc` or `model` modules.
23//! We also provide a `prelude` module with everything you need to get started.
24//!
25//! # Warnings:
26//!
27//! - This crate is NOT designed to be used in adversarial environments.
28//! - This crate has NOT had a comprehensive security review.
29//!
30//! # Usage
31//! ```
32//! use coins_bip32::prelude::*;
33//!
34//! # fn main() -> Result<(), Bip32Error> {
35//! let digest = coins_core::Hash256::default();
36//!
37//! let xpriv_str = "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi".to_owned();
38//!
39//! let xpriv: XPriv = xpriv_str.parse().unwrap();
40//!
41//! let child_xpriv = xpriv.derive_child(33)?;
42//! let (sig, _recovery_id): (Signature, RecoveryId) = child_xpriv.sign_digest(digest.clone());
43//!
44//! // Signing key types are associated with verifying key types. You can always derive a pubkey
45//! let child_xpub = child_xpriv.verify_key();
46//! child_xpub.verify_digest(digest.clone(), &sig)?;
47//!
48//! MainnetEncoder::xpub_to_base58(&child_xpub)?;
49//! # Ok(())
50//! # }
51//! ```
52
53pub use k256::ecdsa;
54
55#[macro_use]
56pub(crate) mod macros;
57
58/// Network-differentiated encoders for extended keys.
59pub mod enc;
60
61/// `DerivationPath` type and tooling for parsing it from strings
62pub mod path;
63
64/// Low-level types
65pub mod primitives;
66
67/// Extended keys and related functionality
68pub mod xkeys;
69
70/// Provides keys that are coupled with their derivation path
71pub mod derived;
72
73#[doc(hidden)]
74#[cfg(any(feature = "mainnet", feature = "testnet"))]
75pub mod defaults;
76
77/// Quickstart types and traits
78pub mod prelude;
79
80use thiserror::Error;
81
82/// The hardened derivation flag. Keys at or above this index are hardened.
83pub const BIP32_HARDEN: u32 = 0x8000_0000;
84
85#[doc(hidden)]
86pub const CURVE_ORDER: [u8; 32] = [
87 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
88 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41,
89];
90
91/// Errors for this library
92#[derive(Debug, Error)]
93pub enum Bip32Error {
94 /// Error bubbled up from the backend
95 #[error("k256 error")]
96 BackendError(/*#[from]*/ ecdsa::Error),
97
98 /// Error bubbled up from the backend
99 #[error("elliptic curve error")]
100 EllipticCurveError(/*#[from]*/ k256::elliptic_curve::Error),
101
102 /// Error bubbled up froom std::io
103 #[error(transparent)]
104 IoError(#[from] std::io::Error),
105
106 /// Error bubbled up froom Ser
107 #[error(transparent)]
108 SerError(#[from] coins_core::ser::SerError),
109
110 /// Master key seed generation received <16 bytes
111 #[error("Master key seed generation received <16 bytes")]
112 SeedTooShort,
113
114 /// HMAC I_l was invalid during key generations.
115 #[error("HMAC left segment was 0 or greated than the curve order. How?")]
116 InvalidKey,
117
118 /// pted to derive the hardened child of an xpub
119 #[error("Attempted to derive the hardened child of an xpub")]
120 HardenedDerivationFailed,
121
122 /// Attempted to tweak an xpriv or xpub directly
123 #[error("Attempted to tweak an xpriv or xpub directly")]
124 BadTweak,
125
126 /// Unrecognized version when deserializing xpriv
127 #[error("Version bytes 0x{0:x?} don't match any network xpriv version bytes")]
128 BadXPrivVersionBytes([u8; 4]),
129
130 /// Unrecognized version when deserializing xpub
131 #[error("Version bytes 0x{0:x?} don't match any network xpub version bytes")]
132 BadXPubVersionBytes([u8; 4]),
133
134 /// Bad padding byte on serialized xprv
135 #[error("Expected 0 padding byte. Got {0}")]
136 BadPadding(u8),
137
138 /// Bad Checks on b58check
139 #[error("Checksum mismatch on b58 deserialization")]
140 BadB58Checksum,
141
142 /// Bubbled up error from bs58 library
143 #[error(transparent)]
144 B58Error(#[from] bs58::decode::Error),
145
146 /// Parsing an string derivation failed because an index string was malformatted
147 #[error("Malformatted index during derivation: {0}")]
148 MalformattedDerivation(String),
149
150 /// Attempted to deserialize a DER signature to a recoverable signature.
151 #[error("Attempted to deserialize a DER signature to a recoverable signature. Use deserialize_vrs instead")]
152 NoRecoveryId,
153
154 /// Attempted to deserialize a very long path
155 #[error("Invalid Bip32 Path.")]
156 InvalidBip32Path,
157}
158
159impl From<ecdsa::Error> for Bip32Error {
160 fn from(e: ecdsa::Error) -> Self {
161 Self::BackendError(e)
162 }
163}
164
165impl From<k256::elliptic_curve::Error> for Bip32Error {
166 fn from(e: k256::elliptic_curve::Error) -> Self {
167 Self::EllipticCurveError(e)
168 }
169}
170
171impl From<std::convert::Infallible> for Bip32Error {
172 fn from(_i: std::convert::Infallible) -> Self {
173 unimplemented!("unreachable, but required by type system")
174 }
175}