pub fn constant_time_eq(a: impl AsRef<[u8]>, b: impl AsRef<[u8]>) -> bool {
let a = a.as_ref();
let b = b.as_ref();
if a.len() != b.len() {
return false;
}
let mut diff = 0u8;
for (x, y) in a.iter().zip(b.iter()) {
diff |= x ^ y;
}
diff == 0
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn equal_values_match_and_others_do_not() {
assert!(constant_time_eq("token-abc", "token-abc"));
assert!(constant_time_eq(b"\x00\x01\x02".as_slice(), b"\x00\x01\x02".as_slice()));
assert!(!constant_time_eq("token-abc", "token-abd"));
assert!(!constant_time_eq("token", "token-abc"));
assert!(!constant_time_eq("", "x"));
assert!(constant_time_eq("", ""));
}
}