use ed25519_dalek::{
pkcs8::DecodePublicKey, Signature, Signer, SigningKey, Verifier, VerifyingKey,
};
use std::error::Error;
pub fn sign_ed25519(signing_key: &SigningKey, msg: &[u8]) -> Vec<u8> {
let signature = signing_key.sign(msg);
signature.to_bytes().to_vec()
}
pub fn read_ed25519_verifying_key(
key_data: &[u8],
) -> Result<VerifyingKey, Box<dyn Error + Send + Sync + 'static>> {
let key = VerifyingKey::try_from(key_data).or_else(|e| {
VerifyingKey::from_public_key_der(key_data).map_err(|_| e)
})?;
Ok(key)
}
pub fn verify_ed25519(
verifying_key: &VerifyingKey,
msg: &[u8],
signature_data: &[u8],
) -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
let signature = Signature::from_slice(signature_data)?;
verifying_key.verify(msg, &signature)?;
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use crate::util;
use ed25519_dalek::pkcs8::DecodePrivateKey;
const PRIVKEY_PEM: &str = "-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIAgXiPH5szmdVoCcjN7r/swuGVTkWOMQLeFmoCJAcDmJ
-----END PRIVATE KEY-----";
#[test]
fn read_ed25519_verifying_key_spki() {
let privkey = SigningKey::from_pkcs8_pem(PRIVKEY_PEM).unwrap();
let pubkey_der64 = "MCowBQYDK2VwAyEA1QHCX4X6j/obHOeL7puSIFsr8Kd7XQcupCD5S2rvYdU=";
let pubkey_bytes = util::decode_base64(pubkey_der64).unwrap();
let pubkey = read_ed25519_verifying_key(&pubkey_bytes).unwrap();
assert_eq!(pubkey, privkey.verifying_key());
}
#[test]
fn read_ed25519_verifying_key_raw() {
let privkey = SigningKey::from_pkcs8_pem(PRIVKEY_PEM).unwrap();
let pubkey_der64 = "1QHCX4X6j/obHOeL7puSIFsr8Kd7XQcupCD5S2rvYdU=";
let pubkey_bytes = util::decode_base64(pubkey_der64).unwrap();
let pubkey = read_ed25519_verifying_key(&pubkey_bytes).unwrap();
assert_eq!(pubkey, privkey.verifying_key());
}
}