iop_keyvault/
lib.rs

1#![warn(missing_docs)]
2
3//! # Keyvault
4//!
5//! Keyvault is a general purpose hierarchical deterministic (HD) generator for asymmetric keys.
6//! It is based on the same concepts as a Bitcoin HD-wallet and is built on the same specifications like
7//! [HD wallets of Bip32](https://en.bitcoin.it/wiki/BIP_0032),
8//! [Mnemonic word lists of Bip39](https://en.bitcoin.it/wiki/BIP_0039) and
9//! [Purpose fields of Bip43](https://en.bitcoin.it/wiki/BIP_0043).
10//!
11//! Though keyvault is capable of generating wallet addresses as defined in
12//! [Multi-Account cryptocurrency wallets of Bip44](https://en.bitcoin.it/wiki/BIP_0044),
13//! it is not only an address generator for multiple cryptocurrencies.
14//! Keyvault can also derive all the keys you might need in other software stacks
15//! and aims to be your all-in-one Swiss Army knife identity manager.
16//!
17//! Keyvault can
18//!
19//! - use the same seed to derive keys with multiple cipher suites, currently `ed25519` and `secp256k1`
20//! - use any purpose field and account hierarchy, not only Bip43 and Bip44
21//! - handle several purposes (i.e. attached subhierarchies) at the same time
22//! - be used from other platforms via its C and WebAssembly bindings
23//!
24//! Keyvault was originally created as part of the
25//! [Mercury communication protocol](https://github.com/Internet-of-People/mercury-rust)
26//! but being a general-purpose tool it was reused in other components as well,
27//! hence was separated into [its own repository](https://github.com/Internet-of-People/keyvault-rust) then finally merged into this monorepository.
28//!
29//! For more information on this crate and potential usage, see the [IOP developer site].
30//!
31//! [IOP developer site]: https://developer.iop.technology/glossary?id=multicipher
32
33mod bip32;
34mod bip39;
35mod bip43;
36mod bip44;
37mod bip44path;
38mod cc;
39pub mod ed25519;
40pub mod encrypt;
41pub mod multicipher;
42mod network;
43mod networks;
44pub mod secp256k1;
45mod seed;
46#[cfg(test)]
47mod test_crypto;
48#[cfg(test)]
49mod tests;
50
51pub use ::bip39::ErrorKind as Bip39ErrorKind;
52pub use ::bip39::Language as Bip39Language;
53pub use anyhow::Result;
54pub use digest::Mac;
55
56pub use crate::bip39::*;
57pub use bip32::*;
58pub use bip43::*;
59pub use bip44::*;
60pub use bip44path::*;
61pub use network::*;
62pub use networks::Networks;
63pub use seed::*;
64
65use std::cmp::Ordering;
66use std::fmt;
67use std::hash::{Hash, Hasher};
68use std::str::FromStr;
69
70use anyhow::{anyhow, bail, ensure};
71use digest::KeyInit;
72use serde::{Deserialize, Deserializer, Serialize, Serializer};
73
74/// A public key (also called shared key or pk in some literature) is that part of an asymmetric keypair
75/// which can be used to verify the authenticity of the sender of a message or to encrypt a message that
76/// can only be decrypted by a single recipient. In both cases this other party owns the [`PrivateKey`]
77/// part of the keypair and never shares it with anyone else.
78///
79/// [`PrivateKey`]: trait.PrivateKey.html
80pub trait PublicKey<C: AsymmetricCrypto + ?Sized>: Clone {
81    /// Calculates the ID (also called fingerprint or address in some literature) of the public key. In
82    /// some algorithms the public key is only revealed in point-to-point communications and a keypair is
83    /// identified only by the digest of the public key in all other channels.
84    fn key_id(&self) -> C::KeyId;
85
86    /// We do not have multiple versions of KeyIds for the same multicipher public key, so for now this comparison is trivial. But when we
87    /// introduce newer versions, we need to take the version of the `key_id` argument into account and calculate that possibly older version
88    /// from `self`.
89    // When implementing, consider timing attack for validation with key_id() generation
90    fn validate_id(&self, id: &C::KeyId) -> bool;
91
92    /// This method can be used to verify if a given signature for a message was made using the private
93    /// key that belongs to this public key. See also [`PrivateKey::sign`]
94    ///
95    /// [`PrivateKey::sign`]: trait.PrivateKey.html#tymethod.sign
96    fn verify<D: AsRef<[u8]>>(&self, data: D, sig: &C::Signature) -> bool;
97}
98
99/// A private key (also called secret key or sk in some literature) is the part of an asymmetric keypair
100/// which is never shared with anyone. It is used to sign a message sent to any recipient or to decrypt a
101/// message that was sent encrypted from any recipients.
102pub trait PrivateKey<C: AsymmetricCrypto + ?Sized>: Clone {
103    /// Calculates the [`PublicKey`] that belongs to this private key. These two keys together form an
104    /// asymmetric keypair, where the private key cannot be calculated from the public key with a reasonable
105    /// effort, but the public key can be calculated from the private key cheaply.
106    ///
107    /// [`PublicKey`]: trait.PublicKey.html
108    fn public_key(&self) -> C::PublicKey;
109
110    /// Calculates the signature of a message that can be then verified using [`PublicKey::verify`]
111    ///
112    /// [`PublicKey::verify`]: trait.PublicKey.html#tymethod.verify
113    fn sign<D: AsRef<[u8]>>(&self, data: D) -> C::Signature;
114}
115
116/// An implementation of this trait defines a family of types that fit together perfectly to form a
117/// cryptography using asymmetric keypairs.
118pub trait AsymmetricCrypto {
119    /// The ID (also called fingerprint or address in some literature) of the public key. See
120    /// [`PublicKey::key_id`] for more details.
121    ///
122    /// [`PublicKey::key_id`]: trait.PublicKey.html#tymethod.key_id
123    type KeyId: std::hash::Hash + Eq + Clone;
124
125    /// See [`PublicKey`] for more details.
126    ///
127    /// [`PublicKey`]: trait.PublicKey.html
128    type PublicKey: PublicKey<Self>;
129
130    /// See [`PrivateKey`] for more details.
131    ///
132    /// [`PrivateKey`]: trait.PrivateKey.html
133    type PrivateKey: PrivateKey<Self>;
134
135    /// The signature of a given message with a given private key. Its size and representation is up
136    /// to the implementation.
137    type Signature: Clone;
138}
139
140/// The hashing algorithm used for deriving child keys in SLIP-0010
141pub type HmacSha512 = hmac::Hmac<sha2::Sha512>;
142
143/// Extended private key not only contains a private key, but also a chain code that is some additional entropy that
144/// is used to derive child keys. Some cryptographic suites implement both normal (public) and hardened (private)
145/// derivation, some, like Ed25519 is missing normal derivation and just err when called.
146///
147/// An extended private key can be neutered to an extended public key, which contains the same chain code, but its
148/// public key part does not reveal any information about the private key.
149pub trait ExtendedPrivateKey<C: KeyDerivationCrypto + ?Sized>: Clone {
150    /// Normal derivation allows the neutered extended public key to calculate child extended public keys without
151    /// revealing any private keys.
152    fn derive_normal_child(&self, idx: i32) -> Result<C::ExtendedPrivateKey>;
153    /// Hardened derivation makes it impossible to the neutered extended public key to calculate children. It uses
154    /// a different derivation algorithm.
155    fn derive_hardened_child(&self, idx: i32) -> Result<C::ExtendedPrivateKey>;
156    /// Neutering an extended private key gives an extended public key that contains the private key neutered, plus
157    /// the chain code. It is useless to reveal the chain code when hardened derivation is used.
158    fn neuter(&self) -> C::ExtendedPublicKey;
159    /// Throws away the chain code and gives back only the private key from the extended private key.
160    fn private_key(&self) -> C::PrivateKey;
161}
162
163/// Extended public key is a neutered extended private key that contains the public key that belongs to the private key in that,
164/// but it also contains the chain code so it can be used in normal (public) derivation. Some cryptographic suites do not have
165/// normal derivation and those are free to implement extended public keys containing only the public key.
166pub trait ExtendedPublicKey<C: KeyDerivationCrypto + ?Sized>: Clone {
167    /// Derive child extended public keys. Useful for auditing hierarchical deterministic wallets, or generating a new address
168    /// for each on-chain transaction knowing the owner of the corresponding extended private key can spend the received coins.
169    fn derive_normal_child(&self, idx: i32) -> Result<C::ExtendedPublicKey>;
170    /// Throws away the chain code and gives back only the public key from the extended public key.
171    fn public_key(&self) -> C::PublicKey;
172}
173
174/// An implementation of this trait defines a family of types that fit together to extend [`AsymmetricCrypto`]
175/// with the ability to have a hierarchical deterministic wallet, so a tree of private and public keys all
176/// derived from a single master secret.
177///
178/// [`AsymmetricCrypto`]: trait.AsymmetricCrypto.html
179pub trait KeyDerivationCrypto: AsymmetricCrypto {
180    /// See [`ExtendedPrivateKey`] for more details.
181    ///
182    /// [`ExtendedPrivateKey`]: trait.ExtendedPrivateKey.html
183    type ExtendedPrivateKey: ExtendedPrivateKey<Self>;
184    /// See [`ExtendedPublicKey`] for more details.
185    ///
186    /// [`ExtendedPublicKey`]: trait.ExtendedPublicKey.html
187    type ExtendedPublicKey: ExtendedPublicKey<Self>;
188
189    /// Does not seem to completely belong here, but calculates the master extended private key - the root of a hierarchical
190    /// deterministic wallet - from a given seed. All other keys are derived from this one extended private key.
191    fn master(seed: &Seed) -> Self::ExtendedPrivateKey;
192}
193
194/// Unicode code point for planet mercury
195pub const BIP43_PURPOSE_MERCURY: i32 = 0x263F;