Constant-Time Byte Comparison

Compare secrets without early exit so timing does not leak the matching prefix, and keep the result observable with black_box.

RustSecurity Boundaries

Code

snippet
use std::hint::black_box;

fn constant_time_eq(left: &[u8], right: &[u8]) -> bool {
    if left.len() != right.len() {
        return false;
    }
    let mut difference = 0u8;
    for (a, b) in left.iter().zip(right.iter()) {
        difference |= a ^ b;
    }
    black_box(difference) == 0
}

fn compare_tokens(expected: &str, provided: &str) -> bool {
    constant_time_eq(expected.as_bytes(), provided.as_bytes())
}

fn main() {
    println!("equal: {}", compare_tokens("token-abc", "token-abc"));
    println!("different: {}", compare_tokens("token-abc", "token-abd"));
    println!("length mismatch: {}", compare_tokens("token-abc", "token"));
    println!("empty: {}", compare_tokens("", ""));
}