Constant-Time Comparison
Constant-time comparison checks equality of secrets by touching every byte with identical operations, removing the early-exit timing signal that leaks prefix matches.
Definition
A constant-time comparison accumulates a difference across all bytes of both inputs and returns equality only if the accumulated value is zero. It performs no data-dependent branches or memory accesses, so runtime is independent of where the inputs differ. It is the required primitive for comparing tokens, MACs, digests, and any secret material.
Context and scope
Implemented as library functions — timingSafeEqual, constant_time_eq, hmac.compare_digest — and applied at every secret equality check in login, token validation, and webhook signature verification.
Common misconceptions
- It makes comparison unmeasurably slow — it costs one pass over fixed-length inputs, negligible against network latency
- Double-hashing then using == is equivalent — the final digest comparison still needs constant time; hashing does not remove the leak
- It protects against all side channels — it removes timing from comparison; power analysis and cache attacks are separate disciplines
Anti-patterns
- Comparing webhook signatures or API tokens with === or memcmp directly
- Short-circuiting on length mismatch before comparison and leaking length via timing anyway
- Wrapping comparisons in variable-time glue code — logging, early returns — that reintroduces the signal
Related concepts
Related examples
Authoritative source
What it is
Naive equality stops at the first differing byte, so time reveals how many leading bytes matched. Constant-time comparison reads every byte of both inputs, XORs into an accumulator, and reports whether the accumulator is zero. Identical work, identical duration, no signal.
How it works
The canonical form loops over the full length computing bitwise differences and OR-ing them, then converts the accumulator to a boolean without branching. Library versions additionally require equal-length inputs or handle length explicitly, because leaking length via an early return is its own vulnerability.
When to use it
Every comparison where either operand is secret or derived from a secret: session token lookup results, HMAC checks, password-reset tokens, webhook signatures, and encrypted-cookie integrity tags. Audit every equality check on secrets, not only the login path.
Pitfalls
Comparing digests still needs constant time; hashing a secret does not launder the requirement. Call sites often wrap the comparison in logging or exception paths whose presence differs per outcome — audit the whole function, not one line. Verify with timing distributions under load in CI for the most sensitive endpoints.