use crate::{DidError, DidResult};
use ed25519_dalek::{Signature, Signer, SigningKey, Verifier, VerifyingKey};
pub struct Ed25519Signer {
signing_key: SigningKey,
}
impl Ed25519Signer {
pub fn from_bytes(secret_key: &[u8]) -> DidResult<Self> {
if secret_key.len() != 32 {
return Err(DidError::InvalidKey(
"Ed25519 secret key must be 32 bytes".to_string(),
));
}
let mut bytes = [0u8; 32];
bytes.copy_from_slice(secret_key);
let signing_key = SigningKey::from_bytes(&bytes);
Ok(Self { signing_key })
}
pub fn generate() -> Self {
use scirs2_core::random::{Random, RngExt};
let seed = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap_or_default()
.as_nanos() as u64;
let mut rng = Random::seed(seed);
let bytes: [u8; 32] = rng.random();
let signing_key = SigningKey::from_bytes(&bytes);
Self { signing_key }
}
pub fn secret_key_bytes(&self) -> [u8; 32] {
self.signing_key.to_bytes()
}
pub fn public_key_bytes(&self) -> [u8; 32] {
self.signing_key.verifying_key().to_bytes()
}
pub fn verifying_key(&self) -> VerifyingKey {
self.signing_key.verifying_key()
}
pub fn sign(&self, message: &[u8]) -> Vec<u8> {
let signature = self.signing_key.sign(message);
signature.to_bytes().to_vec()
}
}
pub struct Ed25519Verifier {
verifying_key: VerifyingKey,
}
impl Ed25519Verifier {
pub fn from_bytes(public_key: &[u8]) -> DidResult<Self> {
if public_key.len() != 32 {
return Err(DidError::InvalidKey(
"Ed25519 public key must be 32 bytes".to_string(),
));
}
let mut bytes = [0u8; 32];
bytes.copy_from_slice(public_key);
let verifying_key =
VerifyingKey::from_bytes(&bytes).map_err(|e| DidError::InvalidKey(e.to_string()))?;
Ok(Self { verifying_key })
}
pub fn verify(&self, message: &[u8], signature: &[u8]) -> DidResult<bool> {
if signature.len() != 64 {
return Err(DidError::InvalidProof(
"Ed25519 signature must be 64 bytes".to_string(),
));
}
let mut sig_bytes = [0u8; 64];
sig_bytes.copy_from_slice(signature);
let signature = Signature::from_bytes(&sig_bytes);
match self.verifying_key.verify(message, &signature) {
Ok(()) => Ok(true),
Err(_) => Ok(false),
}
}
}
pub fn sign_ed25519(secret_key: &[u8], message: &[u8]) -> DidResult<Vec<u8>> {
let signer = Ed25519Signer::from_bytes(secret_key)?;
Ok(signer.sign(message))
}
pub fn verify_ed25519(public_key: &[u8], message: &[u8], signature: &[u8]) -> DidResult<bool> {
let verifier = Ed25519Verifier::from_bytes(public_key)?;
verifier.verify(message, signature)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_sign_verify() {
let signer = Ed25519Signer::generate();
let message = b"Hello, World!";
let signature = signer.sign(message);
assert_eq!(signature.len(), 64);
let verifier = Ed25519Verifier::from_bytes(&signer.public_key_bytes()).unwrap();
let valid = verifier.verify(message, &signature).unwrap();
assert!(valid);
let invalid = verifier.verify(b"Wrong message", &signature).unwrap();
assert!(!invalid);
}
#[test]
fn test_from_bytes() {
let secret = [42u8; 32];
let signer = Ed25519Signer::from_bytes(&secret).unwrap();
let public_key = signer.public_key_bytes();
assert_eq!(public_key.len(), 32);
}
#[test]
fn test_invalid_key_length() {
let short_key = [0u8; 16];
assert!(Ed25519Signer::from_bytes(&short_key).is_err());
assert!(Ed25519Verifier::from_bytes(&short_key).is_err());
}
}