pub use shared_memory_heap::sharedptr::SharedPtr; use crate::agent::Agent; use std::{ ops::Deref, path::Path, sync::{LazyLock, Mutex}, }; static ED25519AGENT: LazyLock>> = LazyLock::new(|| { let agent_path = std::env::var("ED25519_AGENT_PATH") .expect("ED25519_AGENT_PATH environment variable missing"); let keyfile_path = std::env::var("ED25519_KEYFILE").expect("Ed25519_KEYFILE environment variable missing"); let num_agents: usize = std::env::var("NUM_AGENTS") .expect("NUM_AGENTS environment variable missing") .parse() .expect("NUM_AGENTS should be an integer"); let mut agents = Vec::with_capacity(num_agents); for _ in 0..num_agents { let agent = unsafe { Agent::new(Path::new(&agent_path), Path::new(&keyfile_path)) .expect("Agent failed to start") }; agents.push(Mutex::new(agent)); } agents }); #[derive(Debug)] pub struct Ed25519PrivKey(SharedPtr); #[derive(Debug)] pub struct Ed25519PubKey(SharedPtr); #[derive(Debug)] pub struct Ed25519Signature(SharedPtr); impl From<&[u8; 32]> for Ed25519PubKey { fn from(value: &[u8; 32]) -> Self { let mut pk = SharedPtr::new(32).unwrap(); pk.copy_from_slice(value); Ed25519PubKey(pk) } } impl From<&[u8; 8]> for Ed25519PrivKey { fn from(value: &[u8; 8]) -> Self { let mut sk = SharedPtr::new(8).unwrap(); sk.copy_from_slice(value); Ed25519PrivKey(sk) } } impl Deref for Ed25519PrivKey { type Target = [u8; 8]; fn deref(&self) -> &Self::Target { self.0.deref().try_into().expect("this should never fail") } } impl Deref for Ed25519PubKey { type Target = [u8; 32]; fn deref(&self) -> &Self::Target { self.0.deref().try_into().expect("this should never fail") } } impl Deref for Ed25519Signature { type Target = [u8; 64]; fn deref(&self) -> &Self::Target { self.0.deref().try_into().expect("this should never fail") } } pub fn ed25519_keygen() -> (Ed25519PrivKey, Ed25519PubKey) { let sk = Ed25519PrivKey(SharedPtr::new(8).unwrap()); let pk = Ed25519PubKey(SharedPtr::new(32).unwrap()); let mut agent = None; while agent.is_none() { agent = ED25519AGENT .iter() .map(|agent| agent.try_lock()) .filter(|agent| agent.is_ok()) .next(); } let mut agent = agent.unwrap().unwrap(); unsafe { agent.perform_ipc_call(0, &[sk.0.get_offset(), pk.0.get_offset()]); } drop(agent); (sk, pk) } pub fn ed25519_sign(sk: &Ed25519PrivKey, msg: &SharedPtr) -> Ed25519Signature { let sig = Ed25519Signature(SharedPtr::new(64).unwrap()); let mut agent = None; while agent.is_none() { agent = ED25519AGENT .iter() .map(|agent| agent.try_lock()) .filter(|agent| agent.is_ok()) .next(); } let mut agent = agent.unwrap().unwrap(); unsafe { agent.perform_ipc_call( 1, &[ sk.0.get_offset(), msg.get_offset(), msg.get_size(), sig.0.get_offset(), ], ); } drop(agent); sig }