diff --git a/Cargo.lock b/Cargo.lock index aae8e12..e04d43a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -413,6 +413,7 @@ dependencies = [ "hex-literal", "hmac", "k256", + "keyfork-mnemonic-util", "ripemd", "serde", "sha2", @@ -735,18 +736,18 @@ checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" [[package]] name = "serde" -version = "1.0.186" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f5db24220c009de9bd45e69fb2938f4b6d2df856aa9304ce377b3180f83b7c1" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.186" +version = "1.0.188" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ad697f7e0b65af4983a4ce8f56ed5b357e8d3c36651bf6a7e13639c17b8e670" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" dependencies = [ "proc-macro2", "quote", diff --git a/keyfork-derive-util/Cargo.toml b/keyfork-derive-util/Cargo.toml index d400a95..28b8b60 100644 --- a/keyfork-derive-util/Cargo.toml +++ b/keyfork-derive-util/Cargo.toml @@ -26,6 +26,7 @@ thiserror = "1.0.47" # Optional, not personally audited k256 = { version = "0.13.1", default-features = false, features = ["std", "arithmetic"], optional = true } ed25519-dalek = { version = "2.0.0", optional = true } +keyfork-mnemonic-util = { version = "0.1.0", path = "../keyfork-mnemonic-util" } [dev-dependencies] hex-literal = "0.4.1" diff --git a/keyfork-derive-util/src/lib.rs b/keyfork-derive-util/src/lib.rs index e6fa6cf..cbbfce4 100644 --- a/keyfork-derive-util/src/lib.rs +++ b/keyfork-derive-util/src/lib.rs @@ -7,6 +7,7 @@ pub mod index; pub mod path; pub mod private_key; pub mod public_key; +pub mod request; #[cfg(test)] mod tests; diff --git a/keyfork-derive-util/src/request.rs b/keyfork-derive-util/src/request.rs new file mode 100644 index 0000000..7c95f19 --- /dev/null +++ b/keyfork-derive-util/src/request.rs @@ -0,0 +1,73 @@ +use crate::{extended_key::private_key::Error as XPrvError, DerivationPath, ExtendedPrivateKey}; +use keyfork_mnemonic_util::Mnemonic; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, thiserror::Error)] +pub enum DerivationError { + #[error("algorithm not supported")] + Algorithm, + + #[error("{0}")] + ExtendedPrivateKey(#[from] XPrvError), +} + +pub type Result = std::result::Result; + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub enum DerivationAlgorithm { + Ed25519, + Secp256k1, +} + +impl DerivationAlgorithm { + pub fn derive(&self, seed: Vec, path: &DerivationPath) -> Result { + match self { + #[cfg(feature = "ed25519")] + Self::Ed25519 => { + let key = ExtendedPrivateKey::::new(seed)?; + let derived_key = key.derive_path(path)?; + Ok(DerivationResponse { + algorithm: self.clone(), + data: derived_key.private_key.to_bytes().to_vec(), + }) + } + #[cfg(feature = "secp256k1")] + Self::Secp256k1 => { + let key = ExtendedPrivateKey::::new(seed)?; + let derived_key = key.derive_path(path)?; + Ok(DerivationResponse { + algorithm: self.clone(), + data: derived_key.private_key.to_bytes().to_vec(), + }) + } + #[allow(unreachable_patterns)] + _ => Err(DerivationError::Algorithm), + } + } +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct DerivationRequest { + algorithm: DerivationAlgorithm, + path: DerivationPath, +} + +impl DerivationRequest { + pub fn new(algorithm: DerivationAlgorithm, path: DerivationPath) -> Self { + Self { algorithm, path } + } + + pub fn derive_with_mnemonic(&self, mnemonic: &Mnemonic) -> Result { + self.derive_with_master_seed(mnemonic.seed()) + } + + pub fn derive_with_master_seed(&self, seed: Vec) -> Result { + self.algorithm.derive(seed, &self.path) + } +} + +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct DerivationResponse { + algorithm: DerivationAlgorithm, + data: Vec, +} diff --git a/keyforkd/src/service.rs b/keyforkd/src/service.rs index f576a74..5e2db9a 100644 --- a/keyforkd/src/service.rs +++ b/keyforkd/src/service.rs @@ -1,8 +1,7 @@ use std::{future::Future, pin::Pin, sync::Arc, task::Poll}; -use keyfork_derive_util::DerivationPath; +use keyfork_derive_util::request::{DerivationError, DerivationRequest, DerivationResponse}; use keyfork_mnemonic_util::Mnemonic; -use thiserror::Error; use tower::Service; #[derive(Clone, Debug)] @@ -10,10 +9,6 @@ pub struct Keyforkd { mnemonic: Arc, } -// Currently, this can't be instantiated, therefore it is a never-type -#[derive(Debug, Error)] -pub enum DerivationError {} - impl Keyforkd { pub fn new(mnemonic: Mnemonic) -> Self { Self { @@ -22,8 +17,8 @@ impl Keyforkd { } } -impl Service for Keyforkd { - type Response = Vec; +impl Service for Keyforkd { + type Response = DerivationResponse; type Error = DerivationError; @@ -37,8 +32,8 @@ impl Service for Keyforkd { } #[cfg_attr(feature = "tracing", tracing::instrument(skip(self)))] - fn call(&mut self, req: DerivationPath) -> Self::Future { - dbg!(&req, &self.mnemonic); - Box::pin(async { Ok(vec![]) }) + fn call(&mut self, req: DerivationRequest) -> Self::Future { + let app = self.clone(); + Box::pin(async { req.derive_with_mnemonic(&app.mnemonic) }) } }