Let the game state at turn $t$ be $$ S_t = (B_t, p_t) $$ where $B_t \in {\varnothing, A, B}^{9}$ is board occupancy and $p_t \in {A,B}$ is next player.
Transition $T$ for a submitted commitment is valid iff:
Then the server records the commitment and advances turn: $$ p_{t+1} = \text{other}(p_t) $$ with terminal checks deferred until reveal settlement.
A client message body is canonical encoding $$ m = \text{enc}(sender, game_id, turn, nonce, payload) $$ and MAC tag $$ au = \text{KMAC}{k{sender}}(m) $$ (implementation uses keyed BLAKE3 for integrity tagging). Verification accepts iff recomputed tag equals $\tau$ and nonce has not appeared for that sender in this game.
For each opponent move proposal commitment $C_t$, the responder runs SMP equality checks between its hidden occupied set and the proposed hidden cell secret.
Output is a boolean verdict: $$ v_t \in {\text{accept}, \text{reject}} $$ relayed as opaque peer packets through the server.
On settlement request (typically local win claim), each player reveals openings for its committed moves.
Each revealed move $(turn, commitment, receipt)$ must satisfy verifier relation: $$ ext{VerifyOpening}(game_id, player_id, turn, commitment, receipt) = 1 $$
If all openings verify, the server reconstructs final board and resolves winner/draw, then reveals board to both players (current product policy).