Skip to main content

haste_server/auth_n/
constant_time.rs

1//! Comparisons of secrets whose running time does not depend on where the
2//! values first differ.
3//!
4//! `==` on strings stops at the first mismatching byte, so how long a
5//! comparison takes tells a caller how many leading bytes they got right.
6//! Client secrets and CSRF tokens are compared here instead.
7
8use subtle::ConstantTimeEq;
9
10/// Whether `a` and `b` are the same string, in time that depends only on
11/// their lengths.
12pub fn str_eq(a: &str, b: &str) -> bool {
13    a.as_bytes().ct_eq(b.as_bytes()).into()
14}
15
16/// Whether an optional secret matches: both absent, or both present and
17/// equal under [`str_eq`].
18pub fn optional_str_eq(a: Option<&str>, b: Option<&str>) -> bool {
19    match (a, b) {
20        (None, None) => true,
21        (Some(a), Some(b)) => str_eq(a, b),
22        _ => false,
23    }
24}