/** * Compare fixed-format cryptographic values without data-dependent early exit. * * Length remains observable, so callers should validate public wire formats * first. Peach's keys and tokens have fixed lengths at every authenticated * comparison site. */ export function constantTimeEqualBytes( left: Uint8Array, right: Uint8Array, ): boolean { let difference = left.length ^ right.length; const length = Math.max(left.length, right.length); for (let index = 0; index < length; index += 1) { difference |= (left[index] ?? 0) ^ (right[index] ?? 0); } return difference === 0; } export function constantTimeEqualHex(left: string, right: string): boolean { return constantTimeEqualBytes( new TextEncoder().encode(left.toLowerCase()), new TextEncoder().encode(right.toLowerCase()), ); }