use ed25519_dalek::{Signer, Verifier}; use serde::{Deserialize, Serialize}; /// Public key wrapper #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub struct PublicKey(pub [u8; 32]); /// Secret key wrapper #[derive(Debug, Clone, Serialize, Deserialize)] pub struct SecretKey(pub [u8; 32]); /// Key pair for signing #[derive(Debug, Clone)] pub struct KeyPair { pub public: PublicKey, pub secret: SecretKey, signing_key: ed25519_dalek::SigningKey, } impl KeyPair { /// Generate new random keypair pub fn generate() -> Self { use rand::RngCore; let mut rng = rand::thread_rng(); let mut secret_bytes = [0u8; 32]; rng.fill_bytes(&mut secret_bytes); let signing_key = ed25519_dalek::SigningKey::from_bytes(&secret_bytes); let verifying_key = signing_key.verifying_key(); Self { public: PublicKey(verifying_key.to_bytes()), secret: SecretKey(signing_key.to_bytes()), signing_key, } } /// Sign a message pub fn sign(&self, message: &[u8]) -> [u8; 64] { self.signing_key.sign(message).to_bytes() } /// Verify a signature pub fn verify(public_key: &PublicKey, message: &[u8], signature: &[u8; 64]) -> bool { let verifying_key = match ed25519_dalek::VerifyingKey::from_bytes(&public_key.0) { Ok(key) => key, Err(_) => return false, }; let sig = ed25519_dalek::Signature::from_bytes(signature); verifying_key.verify(message, &sig).is_ok() } } #[cfg(test)] mod tests { use super::*; #[test] fn test_keypair_generation() { let keypair = KeyPair::generate(); assert_ne!(keypair.public.0, [0u8; 32]); assert_ne!(keypair.secret.0, [0u8; 32]); } #[test] fn test_sign_verify() { let keypair = KeyPair::generate(); let message = b"Hello, OnionCoin!"; let signature = keypair.sign(message); assert!(KeyPair::verify(&keypair.public, message, &signature)); } #[test] fn test_verify_invalid_signature() { let keypair = KeyPair::generate(); let message = b"Hello, OnionCoin!"; let wrong_sig = [0u8; 64]; assert!(!KeyPair::verify(&keypair.public, message, &wrong_sig)); } }