secureEquals
Constant-time string comparison for secrets/tokens. Avoids leaking how many leading bytes matched via timing. Null inputs never match (including null vs null) to prevent fail-open behaviour when a secret is absent. Both sides are hashed before comparison so input length is not observable.