Sign it twice, and the whole private key falls out

A server holds ONE Lamport one-time keypair and reuses it on every /sign call. It will happily sign almost anything you ask — except the one exact message that matters, which it refuses outright. Ask it to sign that message's bitwise complement too, and you never need the refused message signed at all: you can forge it yourself, offline, from the two signatures it did give you.

The message the server refuses to sign directly (this is the one that matters):

Every hash below is a real SHA-256 (byte-identical to Python's hashlib.sha256), every preimage is 32 genuinely random bytes, and the two verifiers below run the exact sign / verify logic in vulnerable_app.py and fixed_app.py. Nothing here is scripted to a preset outcome — click through and the verdicts are computed live.

Verifier A — vulnerable_app.py :8100 (key reused, no enforcement)

Verifier B — fixed_app.py :8101 (one-time enforced)

What you know, bit by bit (32 positions, Verifier A's keypair). Cells with a dashed orange underline are where the target message needs bit=1 — exactly the positions Verifier B's forgery above gets wrong. Click any cell for the real SHA-256 check there.

Click a bit position after step ① to see the real SHA-256 check.