ZKChase is a battle royale game where players move on a grid to hunt and eliminate each other. Players are visible in open areas but can hide in bushes using zero-knowledge proofs to move secretly. The game leverages zero-knowledge circuits for privacy-preserving movement, with smart contracts orchestrating game logic, state, and verification.
- Grid Size: 18 columns × 14 rows (252 total cells)
- Position Encoding: Positions are compressed into a single
Fieldvalue:(x + y * 256) - Map Representation: The map is stored in two
U128values (map0,map1) that mark movement positions (bushes)
- Directions: Four possible moves:
- Up (y + 1)
- Down (y - 1)
- Left (x - 1)
- Right (x + 1)
- Public: Game map, previous position hash, new position hash
- Private: Actual positions, moves, salt values
- Verification: The Cairo (Starknet) contract can verify moves using hashes and proofs, without knowing the exact player positions
- Verify previous position: Check
hash(prev_pos, salt) == prev_pos_hash - Calculate new position: Apply move to get new (x, y)
- Validate move: Ensure new position is a bush (
map_bit() == 1) - Output new hash: Return
hash(new_pos, salt)for next round
Note: This circuit only handles hidden (bush-to-bush) movement. Open area moves are handled directly by the contract with full visibility.
hash(): Custom hash with salt for position privacymake_move(): Applies directional movementmap_bit(): Checks if position is valid on compressed mapcompress_position()/expand_position(): Convert between (x,y) and Field
The 252-cell map is compressed into two U128 values (map0, map1) where each bit represents a valid/invalid position.
- Open Areas: Full visibility - all players can see positions and moves
- Bushes: Hidden movement using ZK proofs
- Public: Map, position hashes, proof of valid move
- Private: Actual positions, moves, salt
- Result: Prove valid bush-to-bush movement without revealing location
- Dual System: Same game logic runs in both contract (open) and circuit (hidden)
Custom hash function that combines a value with a salt using multiple mathematical operations and pre-defined salt constants.
Algorithm:
- Multiplies input by first salt constant
- Applies series of exponentiations (cubic, 5th power, 7th power, etc.)
- Combines with additional salt values at each step
- Returns final hash value
Security Features:
- Uses 8 hardcoded salt constants for added security
- Multiple exponentiation rounds prevent reverse engineering
- Salt parameter adds randomness
Decompresses a position field into x,y coordinates.
- Converts field to 2-byte representation
- Returns (x, y) tuple
Compresses x,y coordinates into a single field value.
- Formula:
x + y * 256
Calculates new position based on previous position and move direction.
- Validates move is between 1-4
- Returns new (x, y) coordinates
- Asserts on invalid moves
Retrieves the bit value at position (x,y) from the compressed map representation.
Implementation Details:
- Calculates bit index:
y * COLS + x - Handles map split across two
U128values - Uses bit manipulation to extract specific position
- Returns 1 if position is valid (bush), 0 otherwise
The ZKChase smart contracts are organized around three core concepts:
Models define the core data structures representing the game’s state and entities.
- Location:
contracts/src/models - Purpose: Represent players, game state, and in-game objects.
- Examples:
Player: Player identity, position, status, etc.GameState: Current round, player list, eliminations.ChaseObject: In-game items, obstacles, or tokens.
Components are modular attributes or features that can be attached to models/entities.
- Location:
contracts/src/components - Purpose: Add properties like position, score, or ownership to entities.
- Examples:
PositionComponent: Stores positions.ScoreComponent: Tracks player scores.OwnershipComponent: Manages asset or player ownership.
Systems are contracts implementing the core game logic and rules.
- Location:
contracts/src/systems - Purpose: Execute movement, scoring, eliminations, and ZK verification.
- Examples:
MovementSystem: Handles player movement and updates.ScoringSystem: Updates scores, handles eliminations.ProofVerificationSystem: Verifies zero-knowledge proofs for bush movement.
- Models are the nouns (e.g., Player, Game).
- Components are the adjectives (e.g., position, score).
- Systems are the verbs (e.g., move, score, verify).
The contracts and circuits collectively enable a privacy-preserving, on-chain battle royale, with open and hidden movement seamlessly integrated.
For more details, see the contracts/src directory.