use nettle_sys::{nettle_ecdsa_sign, nettle_ecdsa_verify};
use std::mem::zeroed;
use crate::{dsa, Point, Random, Scalar};
pub fn sign<R: Random>(
private: &Scalar,
digest: &[u8],
random: &mut R,
) -> dsa::Signature {
unsafe {
let mut ret = zeroed();
nettle_ecdsa_sign(
&private.scalar,
random.context(),
Some(R::random_impl),
digest.len(),
digest.as_ptr(),
&mut ret as *mut _,
);
dsa::Signature { signature: ret }
}
}
pub fn verify(
public: &Point,
digest: &[u8],
signature: &dsa::Signature,
) -> bool {
unsafe {
nettle_ecdsa_verify(
&public.point,
digest.len(),
digest.as_ptr(),
&signature.signature as *const _,
) == 1
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::ecdsa::generate_keypair;
use crate::{Secp192r1, Yarrow};
#[test]
fn sign_verify() {
let mut rand = Yarrow::default();
let (public, private) =
generate_keypair::<Secp192r1, _>(&mut rand).unwrap();
for _ in 0..3 {
let mut msg = [0u8; 160];
rand.random(&mut msg);
let sig = sign(&private, &msg, &mut rand);
assert!(verify(&public, &msg, &sig));
}
for _ in 0..3 {
let mut msg = [0u8; 160];
rand.random(&mut msg);
let sig = sign(&private, &msg, &mut rand);
rand.random(&mut msg);
assert!(!verify(&public, &msg, &sig));
}
}
}