keyfork-derive-path-data: initial commit
This commit is contained in:
parent
0f31cd2424
commit
fa5d5ede1d
|
@ -893,6 +893,13 @@ dependencies = [
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "keyfork-derive-path-data"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"keyfork-derive-util",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "keyfork-derive-util"
|
name = "keyfork-derive-util"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -954,6 +961,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"hex-literal",
|
"hex-literal",
|
||||||
|
"keyfork-derive-path-data",
|
||||||
"keyfork-derive-util",
|
"keyfork-derive-util",
|
||||||
"keyfork-frame",
|
"keyfork-frame",
|
||||||
"keyfork-mnemonic-util",
|
"keyfork-mnemonic-util",
|
||||||
|
|
|
@ -3,9 +3,10 @@
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
members = [
|
members = [
|
||||||
"keyfork",
|
"keyfork",
|
||||||
"keyfork-derive-util",
|
|
||||||
"keyfork-derive-key",
|
"keyfork-derive-key",
|
||||||
"keyfork-derive-openpgp",
|
"keyfork-derive-openpgp",
|
||||||
|
"keyfork-derive-path-data",
|
||||||
|
"keyfork-derive-util",
|
||||||
"keyfork-frame",
|
"keyfork-frame",
|
||||||
"keyfork-mnemonic-util",
|
"keyfork-mnemonic-util",
|
||||||
"keyfork-plumbing",
|
"keyfork-plumbing",
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
[package]
|
||||||
|
name = "keyfork-derive-path-data"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
keyfork-derive-util = { version = "0.1.0", path = "../keyfork-derive-util", default-features = false }
|
|
@ -0,0 +1,26 @@
|
||||||
|
use keyfork_derive_util::{DerivationPath, DerivationIndex};
|
||||||
|
|
||||||
|
pub static OPENPGP: DerivationIndex = DerivationIndex::new_unchecked(7366512, true);
|
||||||
|
|
||||||
|
pub enum Target {
|
||||||
|
OpenPGP(DerivationIndex),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for Target {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::OpenPGP(account) => {
|
||||||
|
write!(f, "OpenPGP key (account {account})")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determine the closest [`Target`] for the given path. This method is intended to be used by
|
||||||
|
/// `keyforkd` to provide an optional textual prompt to what a client is attempting to derive.
|
||||||
|
pub fn guess_target(path: &DerivationPath) -> Option<Target> {
|
||||||
|
Some(match Vec::from_iter(path.iter())[..] {
|
||||||
|
[t, index] if t == &OPENPGP => Target::OpenPGP(index.clone()),
|
||||||
|
_ => return None,
|
||||||
|
})
|
||||||
|
}
|
|
@ -25,11 +25,16 @@ impl DerivationIndex {
|
||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
/// Returns an error if the index is larger than the hardened flag.
|
/// Returns an error if the index is larger than the hardened flag.
|
||||||
pub fn new(index: u32, hardened: bool) -> Result<Self> {
|
pub const fn new(index: u32, hardened: bool) -> Result<Self> {
|
||||||
if index & (0b1 << 31) > 0 {
|
if index & (0b1 << 31) > 0 {
|
||||||
return Err(Error::IndexTooLarge(index));
|
return Err(Error::IndexTooLarge(index));
|
||||||
}
|
}
|
||||||
Ok(Self(index | (u32::from(hardened) << 31)))
|
Ok(Self(index | ((hardened as u32) << 31)))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub const fn new_unchecked(index: u32, hardened: bool) -> Self {
|
||||||
|
Self(index | ((hardened as u32) << 31))
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -39,6 +44,10 @@ impl DerivationIndex {
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
pub fn inner(&self) -> u32 {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn to_bytes(&self) -> [u8; 4] {
|
pub(crate) fn to_bytes(&self) -> [u8; 4] {
|
||||||
self.0.to_be_bytes()
|
self.0.to_be_bytes()
|
||||||
}
|
}
|
||||||
|
|
|
@ -207,7 +207,7 @@ impl Mnemonic {
|
||||||
bits[index * 11 + bit] = (word & (1 << (10 - bit))) > 0;
|
bits[index * 11 + bit] = (word & (1 << (10 - bit))) > 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove checksum bits
|
// remove checksum bits
|
||||||
bits.truncate(bits.len() - bits.len() % 32);
|
bits.truncate(bits.len() - bits.len() % 32);
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ tower = { version = "0.4.13", features = ["tokio", "util"] }
|
||||||
# Personally audited
|
# Personally audited
|
||||||
thiserror = "1.0.47"
|
thiserror = "1.0.47"
|
||||||
serde = { version = "1.0.186", features = ["derive"] }
|
serde = { version = "1.0.186", features = ["derive"] }
|
||||||
|
keyfork-derive-path-data = { version = "0.1.0", path = "../keyfork-derive-path-data" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
hex-literal = "0.4.1"
|
hex-literal = "0.4.1"
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
use std::{future::Future, pin::Pin, sync::Arc, task::Poll};
|
use std::{future::Future, pin::Pin, sync::Arc, task::Poll};
|
||||||
|
|
||||||
use keyfork_derive_util::request::{DerivationError, DerivationRequest, DerivationResponse};
|
use keyfork_derive_util::request::{DerivationError, DerivationRequest, DerivationResponse};
|
||||||
|
use keyfork_derive_path_data::guess_target;
|
||||||
use tower::Service;
|
use tower::Service;
|
||||||
|
use tracing::info;
|
||||||
|
|
||||||
// NOTE: All values implemented in Keyforkd must implement Clone with low overhead, either by
|
// NOTE: All values implemented in Keyforkd must implement Clone with low overhead, either by
|
||||||
// using an Arc or by having a small signature. This is because Service<T> takes &mut self.
|
// using an Arc or by having a small signature. This is because Service<T> takes &mut self.
|
||||||
|
@ -50,6 +52,14 @@ impl Service<DerivationRequest> for Keyforkd {
|
||||||
if len < 2 {
|
if len < 2 {
|
||||||
return Err(KeyforkdRequestError::InvalidDerivationLength(len));
|
return Err(KeyforkdRequestError::InvalidDerivationLength(len));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "tracing")]
|
||||||
|
if let Some(target) = guess_target(req.path()) {
|
||||||
|
info!("Deriving path: {target}");
|
||||||
|
} else {
|
||||||
|
info!("Deriving path: {}", req.path());
|
||||||
|
}
|
||||||
|
|
||||||
req.derive_with_master_seed((*seed).clone())
|
req.derive_with_master_seed((*seed).clone())
|
||||||
.map_err(KeyforkdRequestError::from)
|
.map_err(KeyforkdRequestError::from)
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue