Pawnshake v0.1.0 · draft

Security

Threat model

Who might cheat, what they can touch, what a chain can prove about it, and the single act that is ever punished.

Who we defend against

The opponent

Runs a modified client. Can sign anything with its own key, delay, reorder or drop its messages, and lie about its own clock.

The network

Can delay, drop, duplicate or replay messages. Cannot forge a signature, and cannot fake pings on a direct link: every frame there is sealed.

The server

Could try to drop or reorder receipts, or fudge times. Its receipts form a hash chain, and it never carries the moves between players.

Out of scope: a player using an engine (that is fair-play detection, a different problem), and two accounts of one person farming rating against each other (that is collusion, the same online or off).

The one punishable act

Every cheating strategy that involves telling different parties different stories needs two signed records for one sequence number, because every record pins down its predecessor and what it had seen. So these all reduce to a fork:

  • one move to the opponent, another to the server,
  • two different moves to the opponent (to fork the board),
  • a report that differs from what the opponent holds or the anchors saw,
  • pre-anchoring several candidate moves.

A heartbeat is a signed statement of the same kind ("at my time t, my newest record was seq n"), so a record that contradicts it is a fork too. That is what stops a player who stayed silent past its flag from reporting a move dated in time.

The opponent holds the copy you sent it. The server holds the copy you anchored. Same seq, different headers.
genesishashe4seq 1ACKseq 2Qh5seq 3 · to BlackACKseq 1e5seq 2Nf3seq 3 · anchoredWhiteBlackgenesishashe4seq 1ACKseq 2Qh5seq 3 · to BlackACKseq 1e5seq 2Nf3seq 3 · anchoredWhiteBlack

Void, not punished

Everything else that is wrong only makes that one record void. It changes nothing and the game goes on after it:

  • a bad signature (forged or corrupted),
  • an illegal or out-of-range move code, or a wrong legal count,
  • a command at a point where it is not allowed (accepting a draw nobody offered, a move out of turn),
  • a record that claims to have seen something the opponent never signed.

This keeps bugs and bad links from turning into losses. Only the act an honest client cannot commit is punished.

What a chain can prove

Peer clocks
(offline, hybrid)
Anchored clocks
(online)
every move, and that it was legalyesyes
mate, stalemate, threefold, fifty moves, insufficient materialyesyes
resignation, draw agreement, abort, takebackyesyes
a player forking the chainyesyes
a record existed at time Tonly if anchoredyes
a flagyes, from both devices' timestampsyes
how long a player really thoughtwithin J per move; more is caught livebounded by the lag quota
a link outagepaused up to a budget, then canceledthe disconnected clock runs
who went awayoffline: nobody can tell. Hybrid: only when checkpoints prove it (the player was there, held the record and did not answer), else as offlinethe server sees it

Cryptographic choices

  • Ed25519 (RFC 8032) for everything signed: records, genesis, certificates, receipts, verdicts, heartbeats, link hellos. 64-byte signatures, 128-bit security, deterministic nonces.
  • ZIP-215 verification rules. Ed25519 libraries disagree on edge cases (non-canonical points, small-order components). Here that could split a game: a fork one device can prove and the other cannot. ZIP-215 fixes exactly which signatures are valid; every Pawnshake library uses it and passes its 196 test cases.
  • Sealed direct links. X25519 for a fresh key per session, HKDF-SHA256 bound to the genesis and both hellos, ChaCha20-Poly1305 on every frame. Pings are unsigned, so this is what keeps a stranger on the radio path from faking them. See Links.
  • Domain separation. Every signed message starts with its own magic tag, so a signature for one kind of message never verifies as another.
  • Identity by header hash. Signature bytes are malleable for a dishonest signer, so records are identified by the hash of their header. A re-signed duplicate is not a fork.
  • Keys stay put. Device keys are created on the device and never exported. Secure enclaves only sign P-256, and would not stop a modified client anyway, since that client holds its own key.

Every trick we know of, with a picture, is in the attack gallery.