Zero-Knowledge Naval Warfare on Stellar
A zero-knowledge battleship game built on Stellar for the Stellar Hacks: ZK Gaming hackathon. Two players connect via Freighter wallets, commit hidden board states using Pedersen hash commitments, and prove shot results with ZK proofs โ all on-chain, all without revealing ship positions.
- Connect Wallet โ Both players connect Freighter wallets on Stellar testnet
- Create / Join โ Player 1 creates a game and shares the game code; Player 2 joins with the code
- Place Ships โ Each player places 5 ships on a private 10ร10 grid
- Commit Board โ A ZK proof validates placement and commits a Pedersen hash on-chain
- Battle โ Players take turns firing shots; the defender generates a ZK proof for every hit/miss report, stored on-chain and verified by the opponent in real time
- Sonar Ping โ After 3 turns, unlock a one-time sonar ability โ the opponent proves ship count in a 3ร3 area via ZK without revealing positions
- Win โ First to sink all 17 ship cells claims victory on-chain
The game uses Noir zero-knowledge circuits for privacy and Soroban smart contracts on Stellar for trustless game state management.
Browser A (Player 1) Browser B (Player 2)
โโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ
โ React Frontend โ โ React Frontend โ
โ + Noir WASM โโโโ verify โโโถโ + Noir WASM โ
โ + Freighter โ โ + Freighter โ
โโโโโโโโโโฌโโโโโโโโโโ โโโโโโโโโโฌโโโโโโโโโโ
โ โ
โ Stellar Testnet (Soroban) โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโค Battleship Contract โโโโโ
โ Game state + ZK proofs โ
โโโโโโโโโโโโฌโโโโโโโโโโโโโโโโ
โ
โโโโโโโโโโโโดโโโโโโโโโโโโโโโโ
โ Game Hub Contract โ
โ (Hackathon registry) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Built with Noir 0.34.0, based on BattleZips-Noir patterns.
Board Circuit (circuits/board/)
- Validates ship placement: all 5 ships within 10ร10 grid, no overlaps
- Ships: Carrier (5), Battleship (4), Cruiser (3), Submarine (3), Destroyer (2) = 17 cells
- Computes and outputs Pedersen hash commitment of ship positions
- Private input:
ships[15](x, y, orientation for each ship) - Public output: board hash (Field)
Shot Circuit (circuits/shot/)
- Proves whether a shot at (x, y) is a hit or miss
- Verifies the prover's ships match their committed board hash
- Private input:
ships[15] - Public inputs:
board_hash,hit(0 or 1),shot_x,shot_y
Sonar Circuit (circuits/sonar/)
- Proves the count of ship cells in a 3ร3 area around a center point
- Verifies the prover's ships match their committed board hash
- Demonstrates ZK's power beyond simple boolean proofs โ partial information disclosure
- Private input:
ships[15] - Public inputs:
board_hash,center_x,center_y,count
The Soroban contract (contracts/battleship/) manages the full game lifecycle:
| Function | Description |
|---|---|
new_game(player1) |
Create a game session, returns game ID |
join_game(game_id, player2) |
Join an existing game with a game code |
commit_board(game_id, player, board_hash) |
Submit Pedersen hash commitment |
take_shot(game_id, player, x, y) |
Fire a shot (must be your turn) |
report_result(game_id, player, hit, proof) |
Report hit/miss with ZK proof stored on-chain |
use_sonar(game_id, player, center_x, center_y) |
Sonar ping instead of firing (once per game, after 3 turns) |
report_sonar(game_id, player, count, proof) |
Report sonar count with ZK proof stored on-chain |
claim_victory(game_id, player) |
Claim win after 17 hits |
get_game(game_id) |
Read current game state (view-only) |
Integrates with the Stellar Game Hub contract (CB4VZAT2U3UC6XFK3N23SKRF2NDCMP3QHJYMCHHFMZO7MRQO6DQ2EMYG) via start_game() and end_game() calls.
- Freighter wallet integration for 2-player on-chain gameplay
- Create/join game flow with shareable base-32 game codes
- Ship placement with click-to-place and R to rotate
- In-browser ZK proof generation via
@noir-lang/noir_js+@noir-lang/backend_barretenberg - On-chain battle: every shot, report, and sonar is a Stellar transaction
- Auto-reporting: opponent actions detected via polling, ZK proofs generated and reported automatically
- Cross-verification: opponent's browser fetches and verifies ZK proofs from on-chain state in real time
- Proof & transaction log with StellarExpert explorer links
- Dark theme with Tailwind CSS
Dark Fleet uses on-chain proof storage + client-side cross-verification to ensure fair play:
- Proof submission โ When a player reports a shot result (hit/miss) or sonar count, their browser generates a ZK proof and submits it alongside the report to the Soroban contract. The proof is stored as
Bytesin the contract's game state. - Cross-verification โ The opponent's browser fetches the proof from the contract state and verifies it client-side using the Barretenberg WASM verifier. If the proof is invalid, a cheating alert is displayed.
- Public auditability โ All proofs are stored on-chain and can be fetched and verified by anyone via
get_game(game_id).
P1 fires โ P2 generates ZK proof โ report_result(hit, proof) on-chain
โ
P1 fetches proof from contract
P1 verifies proof in-browser
โ
โ
Valid / โ Invalid
Future work: On-chain proof verification (contract auto-rejects invalid proofs) via a Soroban UltraHonk verifier.
- Contract Address:
CAMPSSS224MFUVQY6X6LA2QIQEM7AFDKHXG4Q5IVWAJQHLQOX3WQL3EX - Live App: darkfleet.ayazabbas.com
- Noir 0.34.0 (
nargo) - Rust with
wasm32v1-nonetarget - Node.js 18+
- Stellar CLI (optional, for deployment)
cd circuits/board && nargo test
cd ../shot && nargo test
cd ../sonar && nargo testcd contracts/battleship
cargo build --target wasm32v1-none --release
cargo testcd frontend
npm install
npm run devOpen http://localhost:5173 to play.
dark-fleet/
โโโ circuits/
โ โโโ board/ # Board validation ZK circuit
โ โ โโโ src/main.nr # Ship placement + Pedersen hash
โ โโโ shot/ # Shot verification ZK circuit
โ โ โโโ src/main.nr # Hit/miss proof
โ โโโ sonar/ # Sonar ping ZK circuit
โ โโโ src/main.nr # 3ร3 area ship count proof
โโโ contracts/
โ โโโ battleship/ # Soroban smart contract
โ โโโ src/lib.rs # Game state management
โโโ frontend/ # React web application
โ โโโ src/
โ โ โโโ App.tsx # Main game flow (create/join/battle)
โ โ โโโ components/
โ โ โ โโโ Board.tsx # 10ร10 grid component
โ โ โ โโโ ShipPlacement.tsx # Ship placement UI
โ โ โ โโโ OnlineBattle.tsx # On-chain 2-player battle
โ โ โ โโโ GamePlay.tsx # Hotseat battle (legacy)
โ โ โโโ lib/
โ โ โ โโโ game.ts # Game logic & types
โ โ โ โโโ gameCode.ts # Base-32 game code encoding
โ โ โ โโโ noir.ts # ZK proof generation & verification
โ โ โ โโโ stellar.ts # Stellar wallet & contract calls
โ โ โโโ pages/
โ โ โโโ Docs.tsx # Documentation page
โ โโโ public/circuits/ # Compiled circuit artifacts
โโโ .github/workflows/
โ โโโ release.yml # SEP-0055 attestation workflow
โโโ README.md
Board Circuit: 6 tests passed
- Valid horizontal/vertical/mixed placements
- Out-of-bounds detection
- Ship collision detection
Shot Circuit: 7 tests passed
- Hit detection (origin, middle of ship, vertical ships)
- Miss detection
- False hit/miss claim rejection
- Wrong hash rejection
Sonar Circuit: 7 tests passed
- Empty area scan (count 0)
- Dense area scan (count 9)
- Corner/edge clamping
- Partial count with mixed layout
- Wrong count rejection
- Wrong hash rejection
Smart Contract: 10 tests passed
- Game creation and joining
- Board commitment
- Shot and result reporting (with proof storage)
- Full game to victory
- Turn enforcement
- Premature victory rejection
- Sonar availability after 3 turns
- Sonar full flow (use + report with proof)
- Sonar too early rejection
- Sonar double use rejection
| Component | Technology |
|---|---|
| ZK Circuits | Noir 0.34.0 (Pedersen hash, BN254) |
| Smart Contract | Soroban SDK 25.1.1 (Rust) |
| Frontend | React 19, TypeScript, Vite, Tailwind CSS |
| Proof Engine | noir_js + backend_barretenberg (in-browser WASM) |
| Blockchain | Stellar Soroban (Testnet) |
| Wallet | Freighter (@stellar/freighter-api) |
- Pedersen hash for board commitments โ native to Noir circuits, efficient and ZK-friendly
- Board hash as circuit output โ the board circuit computes and returns the hash, eliminating external hash computation
- On-chain proof storage + client-side cross-verification โ ZK proofs stored on-chain with every report, verified by the opponent's browser in real time; on-chain UltraHonk verification is the natural next step
- 2-player on-chain multiplayer โ each player connects via Freighter in separate browser windows; game state synced via Soroban contract polling
- Sonar ping (unique ZK mechanic) โ most ZK battleship implementations only prove binary hit/miss; our sonar circuit proves a count of ship cells in a region, demonstrating ZK's ability to disclose partial information without revealing exact positions
- Base-32 game codes โ short, shareable codes (e.g.
19VG) for game joining instead of raw numeric IDs
- On-chain proof verification via UltraHonk Soroban Verifier
- WebSocket real-time sync (replace polling)
- Ship sinking detection and animation
- Game replay from on-chain events
- Mainnet deployment
Built for Stellar Hacks: ZK Gaming โ February 2026
