2023-09-07 20:20:32 +00:00
|
|
|
use crate::{
|
|
|
|
extended_key::private_key::Error as XPrvError, DerivationPath, ExtendedPrivateKey, PrivateKey,
|
|
|
|
};
|
2023-09-07 15:06:34 +00:00
|
|
|
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 => {
|
2023-09-07 18:24:07 +00:00
|
|
|
let key = ExtendedPrivateKey::<ed25519_dalek::SigningKey>::new(seed)?;
|
2023-09-07 15:06:34 +00:00
|
|
|
let derived_key = key.derive_path(path)?;
|
|
|
|
Ok(DerivationResponse {
|
|
|
|
algorithm: self.clone(),
|
2023-09-07 18:24:07 +00:00
|
|
|
data: PrivateKey::to_bytes(&derived_key.private_key).to_vec(),
|
2023-09-07 15:06:34 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
#[cfg(feature = "secp256k1")]
|
|
|
|
Self::Secp256k1 => {
|
2023-09-07 18:24:07 +00:00
|
|
|
let key = ExtendedPrivateKey::<k256::SecretKey>::new(seed)?;
|
2023-09-07 15:06:34 +00:00
|
|
|
let derived_key = key.derive_path(path)?;
|
|
|
|
Ok(DerivationResponse {
|
|
|
|
algorithm: self.clone(),
|
2023-09-07 18:24:07 +00:00
|
|
|
data: PrivateKey::to_bytes(&derived_key.private_key).to_vec(),
|
2023-09-07 15:06:34 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
#[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 {
|
2023-09-07 18:24:07 +00:00
|
|
|
pub algorithm: DerivationAlgorithm,
|
|
|
|
pub data: Vec<u8>,
|
2023-09-07 15:06:34 +00:00
|
|
|
}
|