A constant-time comparison prevents execution time from revealing where two values first differ. A short-circuit comparison can let an attacker guess a secret byte by byte by measuring server response times. section 10.4.1
The early-exit failure
A comparison that stops at the first mismatch runs longer when more leading bytes match. The glibc memcmp implementation loops until a differing byte appears, so its runtime reflects the number of successfully matched bytes. An attacker can use repeated measurements to refine guesses. section 10.4.1
The defensive pattern checks equal lengths, scans every byte, accumulates x[i] ^ y[i] with bitwise OR, and tests whether the accumulated value is zero. Runtime then depends on slice length rather than contents. The OR accumulator preserves any discovered difference; addition or XOR could incorrectly cancel differences or introduce overflow concerns. section 10.4.1 section 10.7
Listing 10.2 Constant-time comparisons in the crypto/subtle Go package
func ConstantTimeCompare(x, y []byte) int {
if len(x) != len(y) {
return 0
}
var v byte
for i := 0; i < len(x); i++ {
v |= x[i] ^ y[i]
}
return ConstantTimeByteEq(v, 0)
}
// ...
func ConstantTimeByteEq(x, y uint8) int {
return int((uint32(x^y) - 1) >> 31)
}
The Go crypto/subtle implementation makes the constant-time structure concrete: length handling precedes a full XOR-and-OR scan, followed by an equality test. section 10.4.1
Apply these defensive rules:
- Do not use ordinary bytes.Compare or memcmp for secrets when content-dependent timing matters. section 10.4.1
- Use an implementation that scans all equal-length inputs and treats length handling explicitly. section 10.4.1

