Signed tokens
Sign an encoded payload and verify its tag with constant-time comparison.
Build it in your language
The tester treats your program as a black box: any language works. These are just the most convenient ones for this project.
Signed Token Verification (Constant-Time Verification)
A ubiquitous application of HMAC is signed authentication tokens (like JWTs). Verifying tokens requires checking signatures without leaking timing side-channels.
Mental Model: Verification Pipeline
- Read
keyandpayload. - Compute expected tag:
expectedTag = HMAC-SHA-256(key, payload). - Compare against
tagHex. Return booleanvalid.
Your Goal in this Stage
Read a JSON object from stdin with op: "verify", key, payload, and tagHex. Output verification status valid.
Input Format
{
"op": "verify",
"key": "secret",
"payload": "user=7",
"tagHex": "f1e5fc74182d5d7550bd0bf416add2187cfeb4e5071b221f3ebd018c5a67ea47"
}
Output Format
{
"valid": true
}
Step-by-Step Implementation Guide
- Compute expected HMAC: Run HMAC-SHA-256 over
payloadwithkey. - Compare tags: Validate equality against
tagHex. - Emit output: Print JSON object.
Acceptance Criteria
- ✅ Validates authentic signed tokens with
valid: true. - ✅ Rejects tampered payloads or invalid tags with
valid: false.
Tag comparison
key and payload are UTF-8 text; tagHex represents tag bytes. Compare decoded bytes, not strings with different letter casing. For equal-length tags, examine every byte while accumulating differences rather than returning at the first mismatch. A SHA-256 tag has 32 bytes. A library constant-time comparison primitive is allowed; delegating SHA-256 or HMAC is not. Automated tests check functionality; constant-time behavior also needs source/compiler review.
Output and errors
Multiline examples are formatted for readability. Emit compact JSON without optional spaces, with properties in the order shown by the output examples, and a final newline. Keep logs off stdout. Tests compare exact text.
Invalid inputs use stderr containing error, empty stdout, and exit 1. Valid inputs exit 0. Serialize integer results as JSON integers.