kibitz

module
v0.7.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 24, 2026 License: MIT

README

kibitz

Pull up a chair.

kibitz is croc-style pairing for long-lived, end-to-end-encrypted sessions — chat and turn-based games (chess first, backgammon next) instead of file transfer.

  • Pair like croc: the host gets a code phrase like lion-42-maple, plus a share link and QR code. Friends join by clicking or typing.
  • The relay can't read anything: the phrase seeds a PAKE key exchange; the relay only forwards opaque encrypted frames. Self-host it or use a hosted one — either way it's blind.
  • One binary: the relay embeds the whole web client. kibitz --listen :8080, open a browser, play.
  • Spectators welcome: sessions hold two players and any number of kibitzers, all in the same encrypted chat.

Status

v0.3 — six games. Chess, backgammon (provably fair commit-reveal dice), checkers, reversi, Connect Four, and Battleship where cheating is cryptographically impossible: each player commits to every cell of their board before the first shot, every reveal is verified by every participant (spectators included), and both full boards are opened and legality-checked at game end — all without any server ever seeing a thing, because the relay only ever forwards ciphertext. Games start on demand from the picker and run side by side in one session; rematches swap colors.

How it works

The relay forwards frames it can never read. The code phrase seeds a PAKE handshake (as in croc); the host wraps a session group key to each joiner; all chat and moves are XChaCha20-Poly1305 envelopes. Games are both-sides-validate: every client runs the same rules engine and checks a position hash on every move — there's no server to cheat past, because the server is blind. Details: docs/THREAT-MODEL.md.

Hosted instance

A public relay runs at https://kibitz-play.fly.dev — open it, start a table, share the phrase. (Remember: the relay is blind either way; you never have to trust it.)

Self-hosting

Grab a release binary (or go install github.com/richardwooding/kibitz/cmd/kibitz@latest) and:

kibitz --listen :8080

Or run the container image:

docker run -p 8080:8080 ghcr.io/richardwooding/kibitz

Put TLS in front with your reverse proxy of choice. That's it — the web UI, relay, and everything else is in the one binary. Useful flags: --max-sessions (default 1000), --version.

Development

make serve    # build the WASM client and run the relay on :8080
make test     # go test -race ./...

License

MIT

Directories

Path Synopsis
cmd
kibitz command
Command kibitz is the relay server.
Command kibitz is the relay server.
kibitz-wasm command
Native stub so `go build ./...` and `go vet ./...` succeed on the host — the real entrypoint is main.go, built only under GOOS=js GOARCH=wasm.
Native stub so `go build ./...` and `go vet ./...` succeed on the host — the real entrypoint is main.go, built only under GOOS=js GOARCH=wasm.
internal
crypto
Package crypto is kibitz's security boundary.
Package crypto is kibitz's security boundary.
phrase
Package phrase generates croc-style code phrases and derives session IDs from them.
Package phrase generates croc-style code phrases and derives session IDs from them.
relay
Package relay implements the kibitz relay server: a blind frame forwarder.
Package relay implements the kibitz relay server: a blind frame forwarder.
service
Package service defines the layered-service abstraction and the mux that routes decrypted envelopes to services.
Package service defines the layered-service abstraction and the mux that routes decrypted envelopes to services.
service/backgammon
The backgammon service: engine + fair dice + turn protocol.
The backgammon service: engine + fair dice + turn protocol.
service/battleship
The battleship service — kibitz's flagship: hidden ship placement with NO trusted server anywhere.
The battleship service — kibitz's flagship: hidden ship placement with NO trusted server anywhere.
service/chat
Package chat is the simplest layered service: broadcast text messages with a bounded history that late joiners receive via the ctl snapshot.
Package chat is the simplest layered service: broadcast text messages with a bounded history that late joiners receive via the ctl snapshot.
service/checkers
The checkers service: game.Table lifecycle, on-demand Start, forced-move validation by membership, applyAndHash convention (hash after advance, identical on send and receive paths).
The checkers service: game.Table lifecycle, on-demand Start, forced-move validation by membership, applyAndHash convention (hash after advance, identical on send and receive paths).
service/chess
Package chess is the first game service, wrapping corentings/chess for rules.
Package chess is the first game service, wrapping corentings/chess for rules.
service/connect4
Connect Four rules — pure logic, no protocol.
Connect Four rules — pure logic, no protocol.
service/game
Package game holds the seat/lifecycle logic every two-player game service shares: who sits where, who may start a game, rematch seat-swapping, and forfeit-on-leave.
Package game holds the seat/lifecycle logic every two-player game service shares: who sits where, who may start a game, rematch seat-swapping, and forfeit-on-leave.
service/reversi
The reversi service: game.Table lifecycle, on-demand Start, computed passes (never sent), applyAndHash convention.
The reversi service: game.Table lifecycle, on-demand Start, computed passes (never sent), applyAndHash convention.
session
Package session is the client-side engine: it dials the relay, runs the create/join handshake, performs the PAKE + group-key exchange, and moves encrypted service envelopes.
Package session is the client-side engine: it dials the relay, runs the create/join handshake, performs the PAKE + group-key exchange, and moves encrypted service envelopes.
shipcommit
Package shipcommit implements the Battleship hiding scheme: each player commits to all 100 cells of their board before the first shot, then reveals exactly the cells that get shot.
Package shipcommit implements the Battleship hiding scheme: each player commits to all 100 cells of their board before the first shot, then reveals exactly the cells that get shot.
solo
Package solo provides a relay-free, in-memory transport for the local "try a game" hot-seat: two session ends (a host and one player) wired to each other with no WebSocket, PAKE, or crypto.
Package solo provides a relay-free, in-memory transport for the local "try a game" hot-seat: two session ends (a host and one player) wired to each other with no WebSocket, PAKE, or crypto.
wire
The inner payload layer: what clients put inside Direct/Broadcast Payload fields.
The inner payload layer: what clients put inside Direct/Broadcast Payload fields.
Package web embeds the built browser client.
Package web embeds the built browser client.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL