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}