use blst::min_pk::SecretKey as BlstSecretKey;
use sha2::{Digest, Sha256};
pub type VaultSecretKey = bls::SecretKey;
#[derive(Debug, thiserror::Error)]
pub enum VaultKeyError {
#[error("Failed to sign message: {0}")]
FailedToSignMessage(#[from] ant_evm::cryptography::SignError),
#[error("Failed to generate vault secret key: {0}")]
FailedToGenerateVaultSecretKey(String),
#[error("Failed to convert blst secret key to blsttc secret key: {0}")]
BlsConversionError(#[from] bls::Error),
#[error("Failed to generate blst secret key")]
KeyGenerationError,
}
const VAULT_SECRET_KEY_SEED: &[u8] = b"Massive Array of Internet Disks Secure Access For Everyone";
pub fn vault_derive_key(evm_sk_hex: &str) -> Result<VaultSecretKey, VaultKeyError> {
let signature = ant_evm::cryptography::sign_message(evm_sk_hex, VAULT_SECRET_KEY_SEED)
.map_err(VaultKeyError::FailedToSignMessage)?;
let blst_key = derive_secret_key_from_seed(&signature)?;
let vault_sk = blst_to_blsttc(&blst_key)?;
Ok(vault_sk)
}
#[deprecated(since = "0.6.0", note = "Use `vault_derive_key` instead")]
pub fn derive_vault_key(evm_sk_hex: &str) -> Result<VaultSecretKey, VaultKeyError> {
vault_derive_key(evm_sk_hex)
}
pub fn vault_key_from_signature_hex(signature_hex: &str) -> Result<VaultSecretKey, VaultKeyError> {
let signature_bytes = hex::decode(signature_hex)
.map_err(|e| VaultKeyError::FailedToGenerateVaultSecretKey(e.to_string()))?;
let blst_key = derive_secret_key_from_seed(&signature_bytes)?;
let vault_sk = blst_to_blsttc(&blst_key)?;
Ok(vault_sk)
}
pub(crate) fn blst_to_blsttc(sk: &BlstSecretKey) -> Result<bls::SecretKey, VaultKeyError> {
let sk_bytes = sk.to_bytes();
let sk = bls::SecretKey::from_bytes(sk_bytes).map_err(VaultKeyError::BlsConversionError)?;
Ok(sk)
}
pub(crate) fn derive_secret_key_from_seed(seed: &[u8]) -> Result<BlstSecretKey, VaultKeyError> {
let mut hasher = Sha256::new();
hasher.update(seed);
let hashed_seed = hasher.finalize();
let sk =
BlstSecretKey::key_gen(&hashed_seed, &[]).map_err(|_| VaultKeyError::KeyGenerationError)?;
Ok(sk)
}