use crate::{signature, vrf, PublicKey};
use curve25519_dalek::edwards::{CompressedEdwardsY, EdwardsPoint};
use curve25519_dalek::ristretto::RistrettoPoint;
use std::mem::transmute;
pub fn is_valid_staking_key(public_key: &PublicKey) -> bool {
match public_key {
PublicKey::ED25519(key) => convert_public_key(key).is_some(),
PublicKey::SECP256K1(_) => false,
}
}
pub fn convert_public_key(key: &signature::ED25519PublicKey) -> Option<vrf::PublicKey> {
let ep: EdwardsPoint = CompressedEdwardsY::from_slice(&key.0).ok()?.decompress()?;
if !ep.is_torsion_free() {
return None;
}
let rp: RistrettoPoint = unsafe { transmute(ep) };
Some(vrf::PublicKey(rp.compress().to_bytes(), rp))
}
pub fn convert_secret_key(key: &signature::ED25519SecretKey) -> vrf::SecretKey {
let b = <&[u8; 32]>::try_from(&key.0[..32]).unwrap();
let s = ed25519_dalek::hazmat::ExpandedSecretKey::from(b).scalar;
vrf::SecretKey::from_scalar(s)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_conversion() {
for _ in 0..10 {
let kk = signature::SecretKey::from_random(signature::KeyType::ED25519);
let pk = match kk.public_key() {
signature::PublicKey::ED25519(k) => k,
_ => unreachable!(),
};
let sk = match kk {
signature::SecretKey::ED25519(k) => k,
_ => unreachable!(),
};
assert_eq!(
convert_secret_key(&sk).public_key().clone(),
convert_public_key(&pk).unwrap()
);
}
}
}