kibitz

module
v0.16.0 Latest Latest
Warning

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

Go to latest
Published: Jul 25, 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
compress-assets command
Command compress-assets precompresses the built web client into .br (brotli) and .gz (gzip) siblings, so the relay can serve the smallest encoding each client accepts.
Command compress-assets precompresses the built web client into .br (brotli) and .gz (gzip) siblings, so the relay can serve the smallest encoding each client accepts.
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
bot
Package bot is the solo "Play the computer" opponent.
Package bot is the solo "Play the computer" opponent.
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.
pushfwd
Package pushfwd is a keyless Web Push forwarder.
Package pushfwd is a keyless Web Push forwarder.
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