use super::{assert_ct_eq, assert_ct_ne};
use crate::{
csprng::{Csprng, Random},
mac::Mac,
};
#[macro_export]
macro_rules! for_each_mac_test {
($callback:ident) => {
$crate::__apply! {
$callback,
test_default,
test_update,
test_verify,
test_different_keys,
test_different_data,
}
};
}
#[macro_export]
macro_rules! test_mac {
($name:ident, $mac:ty $(, MacTest::$vectors:ident)?) => {
mod $name {
#[allow(unused_imports)]
use super::*;
$crate::test_mac!($mac $(, MacTest::$vectors)?);
}
};
($mac:ty $(, MacTest::$vectors:ident)?) => {
macro_rules! __mac_test {
($test:ident) => {
#[test]
fn $test() {
$crate::test_util::mac::$test::<$mac, _>(&mut $crate::default::Rng)
}
};
}
$crate::for_each_mac_test!(__mac_test);
$(
#[test]
fn vectors() {
$crate::test_util::vectors::test_mac::<$mac>(
$crate::test_util::vectors::MacTest::$vectors,
);
}
)?
};
}
pub use test_mac;
const DATA: &[u8] = b"hello, world!";
pub fn test_default<T: Mac, R: Csprng>(rng: &R) {
let key = Random::random(rng);
let tag1 = T::mac(&key, DATA);
let tag2 = T::mac(&key, DATA);
assert_ct_eq!(tag1, tag2, "tags should be the same");
}
pub fn test_update<T: Mac, R: Csprng>(rng: &R) {
let key = Random::random(rng);
let tag1 = T::mac(&key, DATA);
let tag2 = {
let mut h = T::new(&key);
for c in DATA {
h.update(&[*c]);
}
h.tag()
};
assert_ct_eq!(tag1, tag2, "tags should be the same");
}
pub fn test_verify<T: Mac, R: Csprng>(rng: &R) {
let key = Random::random(rng);
let tag1 = T::mac(&key, DATA);
let mut h = T::new(&key);
for c in DATA {
h.update(&[*c]);
}
h.verify(&tag1).expect("tags should be the same");
}
pub fn test_different_keys<T: Mac, R: Csprng>(rng: &R) {
let key1 = Random::random(rng);
let key2 = Random::random(rng);
assert_ct_ne!(key1, key2, "keys should differ");
let tag1 = T::mac(&key1, DATA);
let tag2 = T::mac(&key2, DATA);
assert_ct_ne!(tag1, tag2, "tags should differ");
}
pub fn test_different_data<T: Mac, R: Csprng>(rng: &R) {
let key = Random::random(rng);
let tag1 = T::mac(&key, b"hello");
let tag2 = T::mac(&key, b"world");
assert_ct_ne!(tag1, tag2, "tags should differ");
}