utility_crypto/
key_conversion.rs1use crate::{signature, vrf, PublicKey};
2use curve25519_dalek::edwards::{CompressedEdwardsY, EdwardsPoint};
3use curve25519_dalek::ristretto::RistrettoPoint;
4use std::mem::transmute;
5
6pub fn is_valid_staking_key(public_key: &PublicKey) -> bool {
7 match public_key {
9 PublicKey::ED25519(key) => convert_public_key(key).is_some(),
10 _ => false,
11 }
12}
13
14pub fn convert_public_key(key: &signature::ED25519PublicKey) -> Option<vrf::PublicKey> {
15 let ep: EdwardsPoint = CompressedEdwardsY::from_slice(&key.0).ok()?.decompress()?;
16 if !ep.is_torsion_free() {
18 return None;
19 }
20 let rp: RistrettoPoint = unsafe { transmute(ep) };
22 Some(vrf::PublicKey(rp.compress().to_bytes(), rp))
23}
24
25pub fn convert_secret_key(key: &signature::ED25519SecretKey) -> vrf::SecretKey {
26 let b = <&[u8; 32]>::try_from(&key.0[..32]).unwrap();
27 let s = ed25519_dalek::hazmat::ExpandedSecretKey::from(b).scalar;
28 vrf::SecretKey::from_scalar(s)
29}
30
31#[cfg(test)]
32mod tests {
33 use super::*;
34
35 #[test]
36 fn test_conversion() {
37 for _ in 0..10 {
38 let kk = signature::SecretKey::from_random(signature::KeyType::ED25519);
39 let pk = match kk.public_key() {
40 signature::PublicKey::ED25519(k) => k,
41 _ => unreachable!(),
42 };
43 let sk = match kk {
44 signature::SecretKey::ED25519(k) => k,
45 _ => unreachable!(),
46 };
47 assert_eq!(
48 convert_secret_key(&sk).public_key().clone(),
49 convert_public_key(&pk).unwrap()
50 );
51 }
52 }
53}