A timing attack infers secret information from differences in computation time. An implementation can therefore leak data even when its outputs appear correct: how long an operation takes becomes an observable side channel. section 10.4
A classic failure is an ordinary comparison that stops at the first unequal byte. Matching prefixes take longer, allowing repeated measurements to reveal information about the secret. Constant-time comparison instead accumulates XOR differences across every byte and tests the final accumulator. section 10.4.1
Comparison and control-flow leaks
A constant-time comparison can return zero immediately when lengths differ, then OR each x[i] ^ y[i] into an accumulator before testing whether it is zero. The same caution applies to square-and-multiply algorithms, branching, and indexing based on secrets. Modern speculative execution can make secret-dependent control flow observable without an oscilloscope. section 10.4.1 section 10.5
Reduce timing leakage with direct engineering rules:
- Use specialized constant-time comparison functions such as OpenSSL CRYPTO_memcmp, Python hmac.compare_digest, Node.js crypto.timingSafeEqual, Java MessageDigest.isEqual, or Rust's subtle crate. section 10.4.1
- Avoid branching and iterating on sensitive values; prefer constant-time implementations for cryptographic code. section 10.5 section 10.9
Figure 10.4 Looking at runner C’s finish time of 2 seconds, we can roughly guess that they fell around the second hurdle.
Use the hurdle-race analogy to see how a finish time can reveal where an unseen delay occurred. section 10.4.1
