Prove that a chess position has a checkmate without revealing what the checkmate move is, demonstrating zero-knowledge proofs for game logic.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/risc0/risc0/llms.txt
Use this file to discover all available pages before exploring further.
What You’ll Learn
- Using external Rust crates in the zkVM
- Implementing game logic with zero-knowledge
- Working with chess notation (FEN and SAN)
- Privacy-preserving competitive gaming
Overview
This example uses the shakmaty crate to:- Parse chess positions in FEN format
- Validate moves in SAN format
- Check for checkmate conditions
- Prove a mate-in-one exists without revealing it
The prover knows the winning move, but only the initial board position is revealed in the journal.
How It Works
use chess_core::Inputs;
use risc0_zkvm::guest::env;
use shakmaty::{
CastlingMode, Chess, FromSetup, Move, Position, Setup,
fen::Fen, san::San,
};
fn main() {
let inputs: Inputs = env::read();
let mv: String = inputs.mv;
let initial_state: String = inputs.board;
// Commit only the initial board state
env::commit(&initial_state);
// Parse the position
let setup = Setup::from(
Fen::from_ascii(initial_state.as_bytes()).unwrap()
);
let pos = Chess::from_setup(setup, CastlingMode::Standard).unwrap();
// Parse and apply the move
let mv: Move = mv.parse::<San>()
.unwrap()
.to_move(&pos)
.unwrap();
let pos = pos.play(&mv).unwrap();
// Verify it's checkmate
assert!(pos.is_checkmate());
}
use chess_core::Inputs;
use chess_methods::{CHECKMATE_ELF, CHECKMATE_ID};
use clap::Parser;
use risc0_zkvm::{ExecutorEnv, default_prover};
#[derive(Parser)]
struct Cli {
#[arg(id = "MOVE", default_value = "Qxf7")]
mv: String,
#[arg(default_value = "r1bqkb1r/pppp1ppp/2n2n2/4p2Q/2B1P3/8/PPPP1PPP/RNB1K1NR w KQkq - 4 4")]
board: String,
}
fn main() {
let args = Cli::parse();
let inputs = Inputs {
board: args.board,
mv: args.mv,
};
// Generate proof
let env = ExecutorEnv::builder()
.write(&inputs)
.unwrap()
.build()
.unwrap();
let receipt = default_prover()
.prove(env, CHECKMATE_ELF)
.unwrap()
.receipt;
// Verify receipt
receipt.verify(CHECKMATE_ID).unwrap();
let committed_state: String = receipt.journal.decode().unwrap();
assert_eq!(inputs.board, committed_state);
println!("There is a checkmate in this position:");
// Display the board...
}
Running the Example
There is a checkmate for White in this position:
r . b q k b . r
p p p p . p p p
. . n . . n . .
. . . . p . . Q
. . B . P . . .
. . . . . . . .
P P P P . P P P
R N B . K . N R
What Gets Proven?
The receipt proves:- Checkmate Exists: There is a legal move that results in checkmate
- From This Position: The checkmate is from the committed board state
- Move is Secret: The winning move is never revealed
Zero-Knowledge Property
Anyone with the receipt can verify:- The board position has a mate-in-one
- The prover knows the move
- What the checkmate move is
- Any details about the move
Chess Notation
FEN (Forsyth-Edwards Notation)
Describes a chess position:- Piece placement: Board from rank 8 to 1
- Active color:
w(white) orb(black) - Castling rights:
KQkq(both sides can castle) - En passant: Target square if available
- Halfmove clock: Moves since last capture/pawn move
- Fullmove number: Current move number
SAN (Standard Algebraic Notation)
Describes a move:Use Cases
Puzzle Contests
Offer rewards for finding checkmates without revealing solutions:- First solver proven fairly
- Solution stays secret for other solvers
- Trustless reward distribution
Tournament Integrity
Prove game outcomes without revealing moves:Training Systems
Verify students found tactics without revealing solutions:Onchain Chess
Integrate with blockchain games:Using the Shakmaty Crate
The shakmaty crate provides comprehensive chess logic:Position Parsing
Move Parsing
Position Updates
Checking Game State
Legal Move Generation
Extending the Example
Mate-in-N
Extend to prove mate-in-N moves:Game Recording
Prove entire game validity:Opening Verification
Prove game followed specific opening:Performance
| Metric | Value |
|---|---|
| Cycles (mate-in-1) | ~5M |
| Proving time | ~5-10 seconds |
| Receipt size | ~128 KB |
| Memory usage | ~2 GB |
- Move sequence length
- Position complexity
- Number of legal moves evaluated
Rust Crates in zkVM
This example demonstrates using pure-Rust crates: Works in zkVM:- Pure Rust implementation
- No system calls
- Supports
no_std(with features) - Deterministic behavior
- Pure Rust chess logic
- No external dependencies on system libraries
- Well-structured and efficient
Video Tutorial
For a detailed walkthrough, see this excerpt from our workshop at ZK HACK III.Bonsai Integration
Use as a Bonsai application for onchain chess:Next Steps
- Implement mate-in-N verification
- Integrate with ECDSA signatures for player authentication
- Build an onchain chess game
- Explore Bonsai applications