use nettle_sys::{nettle_dsa_sign, nettle_dsa_verify};
use std::mem::zeroed;
use crate::{Error, random::Random, Result};
use super::{Params, PrivateKey, PublicKey, Signature};
pub fn sign<R: Random>(
params: &Params,
private: &PrivateKey,
digest: &[u8],
random: &mut R,
) -> Result<Signature> {
unsafe {
let mut ret = zeroed();
let mut private = private.private[0];
let res = nettle_dsa_sign(
¶ms.params,
&mut private,
random.context(),
Some(R::random_impl),
digest.len(),
digest.as_ptr(),
&mut ret as *mut _,
);
if res == 1 {
Ok(Signature { signature: ret })
} else {
Err(Error::SigningFailed)
}
}
}
pub fn verify(
params: &Params,
public: &PublicKey,
digest: &[u8],
signature: &Signature,
) -> bool {
unsafe {
let mut public = public.public[0];
nettle_dsa_verify(
¶ms.params,
&mut public,
digest.len(),
digest.as_ptr(),
&signature.signature,
) == 1
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::dsa::generate_keypair;
use crate::random::Yarrow;
#[test]
fn sign_verify() {
let mut rand = Yarrow::default();
let params = Params::generate(&mut rand, 1024, 160).unwrap();
let (mut public, mut private) = generate_keypair(¶ms, &mut rand);
for _ in 0..3 {
let mut msg = [0u8; 160];
rand.random(&mut msg);
let sig = sign(¶ms, &mut private, &msg, &mut rand).unwrap();
assert!(verify(¶ms, &mut public, &msg, &sig));
}
for _ in 0..3 {
let mut msg = [0u8; 160];
rand.random(&mut msg);
let sig = sign(¶ms, &mut private, &msg, &mut rand).unwrap();
rand.random(&mut msg);
assert!(!verify(¶ms, &mut public, &msg, &sig));
}
}
}