pub use subtle;
pub use zeroize;
use subtle::ConstantTimeEq;
pub fn ct_eq(a: &[u8], b: &[u8]) -> bool {
a.ct_eq(b).into()
}
pub fn verify_tag(computed: &[u8], received: &[u8]) -> Result<(), crate::Error> {
if ct_eq(computed, received) {
Ok(())
} else {
Err(crate::Error::VerificationFailed)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn ct_eq_matches_and_length_mismatch() {
assert!(ct_eq(b"", b""));
assert!(ct_eq(b"abcdef", b"abcdef"));
assert!(!ct_eq(b"abcdef", b"abcdeg"));
for i in 0..6 {
let mut b = *b"abcdef";
b[i] ^= 1;
assert!(!ct_eq(b"abcdef", &b), "bit flip at byte {i} must differ");
}
assert!(!ct_eq(b"", b"a"));
assert!(!ct_eq(b"ab", b"abc"));
}
#[test]
fn verify_tag_maps_to_verification_failed() {
assert_eq!(verify_tag(b"tag-value-16byt", b"tag-value-16byt"), Ok(()));
assert_eq!(
verify_tag(b"tag-value-16byt", b"tag-value-16byz"),
Err(crate::Error::VerificationFailed)
);
assert_eq!(
verify_tag(b"short", b"shorter"),
Err(crate::Error::VerificationFailed)
);
}
}