Compare commits
No commits in common. "0375ce7bdf04bd7a71d2e5d89994ac824aa6a4b4" and "5096df993ea814b92437ab482ae36b645e2cc968" have entirely different histories.
0375ce7bdf
...
5096df993e
|
@ -1,51 +0,0 @@
|
||||||
# Keyfork Derive: BIP-0032 Key Derivation
|
|
||||||
|
|
||||||
Keyfork offers a [BIP-0032] based hierarchial key derivation system enabling
|
|
||||||
the ability to create keys based on a [BIP-0032] seed, a value between 128 to
|
|
||||||
512 bits. The keys can be made using any algorithm supported by Keyfork Derive.
|
|
||||||
Newtypes can be added to wrap around foreign key types that aren't supported by
|
|
||||||
Keyfork.
|
|
||||||
|
|
||||||
Keys derived with the same parameters, from the same seed, will _always_ return
|
|
||||||
the same value. This makes Keyfork a reliable backend for generating encryption
|
|
||||||
or signature keys, as every key can be recovered using the previously used
|
|
||||||
derivation algorithm. However, this may be seen as a concern, as all an
|
|
||||||
attacker may need to recreate all previously-used seeds would be the original
|
|
||||||
derivation seed. For this reason, it is recommended to use the Keyfork server
|
|
||||||
for derivation from the root seed. The Keyfork server will ensure the root seed
|
|
||||||
and any highest-level keys (such as BIP-44, BIP-85, etc.) keys are not leaked.
|
|
||||||
|
|
||||||
The primary use case of Keyfork Derive will be the creation of Derivation
|
|
||||||
Requests, to be used by Keyforkd Client. In the included example, derivation is
|
|
||||||
performed directly on a master seed. This is how Keyforkd works internally.
|
|
||||||
|
|
||||||
## Example
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use std::str::FromStr;
|
|
||||||
use keyfork_mnemonic_util::Mnemonic;
|
|
||||||
use keyfork_derive_util::{*, request::*};
|
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
let mnemonic = Mnemonic::from_str(
|
|
||||||
"enter settle kiwi high shift absorb protect sword talent museum lazy okay"
|
|
||||||
)?;
|
|
||||||
let path = DerivationPath::from_str("m/44'/0'/0'/0/0")?;
|
|
||||||
|
|
||||||
let request = DerivationRequest::new(
|
|
||||||
DerivationAlgorithm::Secp256k1,
|
|
||||||
&path
|
|
||||||
);
|
|
||||||
|
|
||||||
let key1 = request.derive_with_mnemonic(&mnemonic)?;
|
|
||||||
|
|
||||||
let seed = mnemonic.seed(None)?;
|
|
||||||
let key2 = request.derive_with_master_seed(seed)?;
|
|
||||||
|
|
||||||
assert_eq!(key1, key2);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
[BIP-0032]: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
|
|
|
@ -1,49 +1,4 @@
|
||||||
//! # Extended Key Derivation
|
|
||||||
//!
|
|
||||||
//! Oftentimes, a client will want to create multiple keys. Some examples may include deriving
|
|
||||||
//! non-hardened public keys to see how many wallets have been used, deriving multiple OpenPGP
|
|
||||||
//! keys, or generally avoiding key reuse. While Keyforkd locks the root mnemonic and the
|
|
||||||
//! first-level derivation, any second-level derivations acquired from Keyforkd (for example,
|
|
||||||
//! `"m/44'/0'"`) can be used to derive further keys by converting the key to an Extended Public
|
|
||||||
//! Key or Extended Private Key and calling [`ExtendedPublicKey::derive_child`] or
|
|
||||||
//! [`ExtendedPrivateKey::derive_child`].
|
|
||||||
//!
|
|
||||||
//! # Examples
|
|
||||||
//! ```rust
|
|
||||||
//! use std::str::FromStr;
|
|
||||||
//! use keyfork_mnemonic_util::Mnemonic;
|
|
||||||
//! use keyfork_derive_util::{*, request::*};
|
|
||||||
//! use k256::SecretKey;
|
|
||||||
//!
|
|
||||||
//! # fn check_wallet<T: PublicKey>(_: ExtendedPublicKey<T>) -> Result<(), Box<dyn std::error::Error>> { Ok(()) }
|
|
||||||
//! fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
//! # let mnemonic = Mnemonic::from_str(
|
|
||||||
//! # "enter settle kiwi high shift absorb protect sword talent museum lazy okay"
|
|
||||||
//! # )?;
|
|
||||||
//! let path = DerivationPath::from_str("m/44'/0'/0'/0")?;
|
|
||||||
//! let request = DerivationRequest::new(
|
|
||||||
//! DerivationAlgorithm::Secp256k1, // The algorithm of k256::SecretKey
|
|
||||||
//! &path,
|
|
||||||
//! );
|
|
||||||
//!
|
|
||||||
//! let response = // perform a Keyforkd Client request...
|
|
||||||
//! # request.derive_with_mnemonic(&mnemonic)?;
|
|
||||||
//! let key: ExtendedPrivateKey<SecretKey> = response.try_into()?;
|
|
||||||
//! let pubkey = key.extended_public_key();
|
|
||||||
//! drop(key);
|
|
||||||
//!
|
|
||||||
//! for account in (0..20).map(|i| DerivationIndex::new(i, false).unwrap()) {
|
|
||||||
//! let derived_key = pubkey.derive_child(&account)?;
|
|
||||||
//! check_wallet(derived_key);
|
|
||||||
//! }
|
|
||||||
//!
|
|
||||||
//! Ok(())
|
|
||||||
//! }
|
|
||||||
//! ```
|
|
||||||
|
|
||||||
///
|
///
|
||||||
pub mod private_key;
|
pub mod private_key;
|
||||||
///
|
///
|
||||||
pub mod public_key;
|
pub mod public_key;
|
||||||
|
|
||||||
pub use {private_key::ExtendedPrivateKey, public_key::ExtendedPublicKey};
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#![allow(clippy::module_name_repetitions, clippy::must_use_candidate)]
|
#![allow(clippy::module_name_repetitions, clippy::must_use_candidate)]
|
||||||
|
|
||||||
#![doc = include_str!("../README.md")]
|
//! BIP-0032 derivation utilities.
|
||||||
|
|
||||||
|
///
|
||||||
pub mod extended_key;
|
pub mod extended_key;
|
||||||
|
|
||||||
///
|
///
|
||||||
pub mod index;
|
pub mod index;
|
||||||
///
|
///
|
||||||
|
|
|
@ -1,23 +1,6 @@
|
||||||
// Because all algorithms make use of wildcard matching
|
// Because all algorithms make use of wildcard matching
|
||||||
#![allow(clippy::match_wildcard_for_single_variants)]
|
#![allow(clippy::match_wildcard_for_single_variants)]
|
||||||
|
|
||||||
//! # Derivation Requests
|
|
||||||
//!
|
|
||||||
//! Derivation requests can be sent to Keyforkd using Keyforkd Client to request derivation from a
|
|
||||||
//! mnemonic or seed that has been loaded into Keyforkd.
|
|
||||||
//!
|
|
||||||
//! # Examples
|
|
||||||
//! ```rust
|
|
||||||
//! use std::str::FromStr;
|
|
||||||
//! use keyfork_derive_util::{DerivationPath, request::{DerivationRequest, DerivationAlgorithm}};
|
|
||||||
//!
|
|
||||||
//! let path = DerivationPath::from_str("m/44'/0'/0'/0/0").unwrap();
|
|
||||||
//! let request = DerivationRequest::new(
|
|
||||||
//! DerivationAlgorithm::Secp256k1,
|
|
||||||
//! &path
|
|
||||||
//! );
|
|
||||||
//! ```
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
extended_key::private_key::Error as XPrvError,
|
extended_key::private_key::Error as XPrvError,
|
||||||
private_key::{PrivateKey, TestPrivateKey},
|
private_key::{PrivateKey, TestPrivateKey},
|
||||||
|
@ -48,7 +31,7 @@ pub type Result<T, E = DerivationError> = std::result::Result<T, E>;
|
||||||
|
|
||||||
/// The algorithm to derive a key for. The choice of algorithm will result in a different resulting
|
/// The algorithm to derive a key for. The choice of algorithm will result in a different resulting
|
||||||
/// derivation.
|
/// derivation.
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub enum DerivationAlgorithm {
|
pub enum DerivationAlgorithm {
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
|
@ -111,7 +94,7 @@ impl std::str::FromStr for DerivationAlgorithm {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A derivation request.
|
/// A derivation request.
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
pub struct DerivationRequest {
|
pub struct DerivationRequest {
|
||||||
algorithm: DerivationAlgorithm,
|
algorithm: DerivationAlgorithm,
|
||||||
path: DerivationPath,
|
path: DerivationPath,
|
||||||
|
@ -228,7 +211,7 @@ impl DerivationRequest {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A response to a [`DerivationRequest`]
|
/// A response to a [`DerivationRequest`]
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
pub struct DerivationResponse {
|
pub struct DerivationResponse {
|
||||||
/// The algorithm used to derive the data.
|
/// The algorithm used to derive the data.
|
||||||
pub algorithm: DerivationAlgorithm,
|
pub algorithm: DerivationAlgorithm,
|
||||||
|
|
Loading…
Reference in New Issue