use super::Prefix;
use crate::error::Error;
use base64::decode_config;
use core::str::FromStr;
use ursa::{keys::*, signatures::prelude::*};
#[derive(Debug, PartialEq, Clone)]
pub enum SeedPrefix {
RandomSeed128(Vec<u8>),
RandomSeed256Ed25519(Vec<u8>),
RandomSeed256ECDSAsecp256k1(Vec<u8>),
RandomSeed448(Vec<u8>),
}
impl SeedPrefix {
pub fn derive_key_pair(&self) -> Result<(PublicKey, PrivateKey), Error> {
match self {
Self::RandomSeed256Ed25519(seed) => Ed25519Sha512::new()
.keypair(Some(KeyGenOption::UseSeed(seed.clone())))
.map_err(|e| Error::CryptoError(e)),
Self::RandomSeed256ECDSAsecp256k1(seed) => EcdsaSecp256k1Sha256::new()
.keypair(Some(KeyGenOption::UseSeed(seed.clone())))
.map_err(|e| Error::CryptoError(e)),
_ => Err(Error::ImproperPrefixType),
}
}
}
impl FromStr for SeedPrefix {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match &s[..1] {
"A" => Ok(Self::RandomSeed256Ed25519(decode_config(
&s[1..],
base64::URL_SAFE,
)?)),
"J" => Ok(Self::RandomSeed256ECDSAsecp256k1(decode_config(
&s[1..],
base64::URL_SAFE,
)?)),
"K" => Ok(Self::RandomSeed448(decode_config(
&s[1..],
base64::URL_SAFE,
)?)),
"0" => match &s[1..2] {
"A" => Ok(Self::RandomSeed128(decode_config(
&s[2..],
base64::URL_SAFE,
)?)),
_ => Err(Error::DeserializationError),
},
_ => Err(Error::DeserializationError),
}
}
}
impl Prefix for SeedPrefix {
fn derivative(&self) -> &[u8] {
match self {
Self::RandomSeed256Ed25519(seed) => &seed,
Self::RandomSeed256ECDSAsecp256k1(seed) => &seed,
Self::RandomSeed448(seed) => &seed,
Self::RandomSeed128(seed) => &seed,
}
}
fn derivation_code(&self) -> String {
match self {
Self::RandomSeed256Ed25519(_) => "A".to_string(),
Self::RandomSeed256ECDSAsecp256k1(_) => "J".to_string(),
Self::RandomSeed448(_) => "K".to_string(),
Self::RandomSeed128(_) => "0A".to_string(),
}
}
}