74 lines
2.3 KiB
Rust
74 lines
2.3 KiB
Rust
|
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<T, E = DerivationError> = std::result::Result<T, E>;
|
||
|
|
||
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||
|
pub enum DerivationAlgorithm {
|
||
|
Ed25519,
|
||
|
Secp256k1,
|
||
|
}
|
||
|
|
||
|
impl DerivationAlgorithm {
|
||
|
pub fn derive(&self, seed: Vec<u8>, path: &DerivationPath) -> Result<DerivationResponse> {
|
||
|
match self {
|
||
|
#[cfg(feature = "ed25519")]
|
||
|
Self::Ed25519 => {
|
||
|
let key = ExtendedPrivateKey::<k256::SecretKey>::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::<ed25519_dalek::SigningKey>::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<DerivationResponse> {
|
||
|
self.derive_with_master_seed(mnemonic.seed())
|
||
|
}
|
||
|
|
||
|
pub fn derive_with_master_seed(&self, seed: Vec<u8>) -> Result<DerivationResponse> {
|
||
|
self.algorithm.derive(seed, &self.path)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||
|
pub struct DerivationResponse {
|
||
|
algorithm: DerivationAlgorithm,
|
||
|
data: Vec<u8>,
|
||
|
}
|