use ed25519_dalek;
use sha2::Digest;
use signature;
use std::convert::TryFrom;
pub const CONTEXT: &'static [u8] = env!("CARGO_PKG_HOMEPAGE").as_bytes();
pub fn verify(
key: &ed25519_dalek::PublicKey,
msg: &[u8],
sig: &[u8],
) -> Result<(), signature::Error> {
let sig = ed25519_dalek::Signature::try_from(sig)?;
if CONTEXT.len() == 0 {
return Err(signature::Error::new());
}
let mut prehashed = ed25519_dalek::Sha512::new();
prehashed.update(msg);
key.verify_prehashed(prehashed, Some(CONTEXT), &sig)
}
pub fn sign(key: &ed25519_dalek::Keypair, msg: &[u8]) -> Vec<u8> {
let mut prehashed = ed25519_dalek::Sha512::new();
prehashed.update(msg);
key.sign_prehashed(prehashed, Some(CONTEXT))
.unwrap()
.to_bytes()
.into()
}
#[cfg(test)]
mod tests {
use super::{sign, verify};
use ed25519_dalek::Keypair;
use rand07::rngs::OsRng;
#[test]
fn test_sign_verify() {
let mut csprng = OsRng {};
let keypair: Keypair = Keypair::generate(&mut csprng);
let foo = "foo".as_bytes();
let bar = "bar".as_bytes();
let sig_foo = sign(&keypair, foo);
let sig_bar = sign(&keypair, bar);
assert!(matches!(verify(&keypair.public, foo, &sig_foo), Ok(())));
assert!(matches!(verify(&keypair.public, foo, &sig_bar), Err(_)));
assert!(matches!(verify(&keypair.public, bar, &sig_bar), Ok(())));
assert!(matches!(verify(&keypair.public, bar, &sig_foo), Err(_)));
}
#[test]
fn test_export_public() {
let mut csprng = OsRng {};
let keypair: Keypair = Keypair::generate(&mut csprng);
let export = Vec::from(keypair.public.to_bytes());
let public = ed25519_dalek::PublicKey::from_bytes(&export).unwrap();
let foo = "foo".as_bytes();
let bar = "bar".as_bytes();
let sig_foo = sign(&keypair, foo);
let sig_bar = sign(&keypair, bar);
assert!(matches!(verify(&public, foo, &sig_foo), Ok(())));
assert!(matches!(verify(&public, foo, &sig_bar), Err(_)));
assert!(matches!(verify(&public, bar, &sig_bar), Ok(())));
assert!(matches!(verify(&public, bar, &sig_foo), Err(_)));
}
}