Introduction to CRISP
CRISP (Coercion-Resistant Impartial Selection Protocol) is a secure protocol for digital decision-making, leveraging fully homomorphic encryption (FHE) and distributed threshold cryptography (DTC) to enable verifiable secret ballots. Built with Enclave, CRISP safeguards democratic systems and decision-making applications against coercion, manipulation, and other vulnerabilities.
This project serves as a comprehensive example of an E3 Program, demonstrating secure and impartial decision-making processes with a modern Hardhat-based architecture. It showcases a complete full-stack implementation including frontend, backend, smart contracts, and zkVM components.
Why CRISP?
Open ballots are known to produce suboptimal outcomes, exposing participants to bribery and coercion. CRISP mitigates these risks through:
- Secret ballots: Votes remain encrypted throughout the process
- Receipt-free voting: No proof of vote can be generated for coercion
- Verifiable results: Zero-knowledge proofs ensure computation integrity
- Distributed trust: No single point of failure or control
Project Structure
CRISP follows a modern Hardhat-based structure with clear separation of concerns:
CRISP/
|── client/ # React frontend application
|── server/ # Rust coordination server
|── program/ # RISC Zero computation program
|── wasm-crypto/ # WebAssembly crypto utilities
├── contracts/ # Smart contracts (Solidity)
├── circuits/ # Noir circuits for ZK proofs
├── scripts/ # Development and utility scripts
├── enclave.config.yaml # Ciphernode configuration
Client Application (/client
)
The client is a React application built with TypeScript that provides a voting interface:
- Wallet connection with MetaMask and other wallets
- Vote encryption using WebAssembly-based FHE encryption before submission
- Noir Zero-knowledge proof generation for vote validation
- Real-time updates on voting status and results
Coordination Server (/server
)
The server is a Rust-based coordination service that manages the E3 lifecycle:
- Listens to blockchain events and coordinates protocol progression
- Collects encrypted votes from the Smart Contract
- Triggers FHE computations after the voting round is closed.
- Publishes results back to the blockchain
- RESTful API for client interactions
ZK Program (/program
)
The core computation logic written in Rust for zkVM:
- Performs computations on encrypted votes
- Counts votes without decrypting individual ballots
- Creates proofs of correct computation
WebAssembly Crypto (/wasm-crypto
)
High-performance cryptographic operations compiled to WebAssembly:
- Client-side fully homomorphic encryption
- ZK Circuit input generation for Noir proofs
- Optimized for browser execution
Smart Contracts (/contracts
)
Solidity contracts implementing the E3 program interface:
CRISPProgram.sol
Main E3 program contract implementing the IE3Program
interface:
validate()
: Validates voting parameters and setupverify()
: Verifies zkVM proofs of computation
CRISPInputValidator.sol
Handles vote validation and zero-knowledge proof verification:
- Validates encrypted vote format
- Verifies voter eligibility proofs
- Ensures vote uniqueness
CRISPVerifier.sol
Noir verifier for proof of correct encryption:
- Verifies if the vote was encrypted correctly
- Verifies if the vote is valid
CRISPPolicy.sol
Manages voting policies and governance:
- Defines voting rules and constraints
- Manages voter registration
CRISPChecker.sol
Additional verification and checking logic:
- Vote format validation
- Eligibility checking
- Result verification
Next Steps
To get started with CRISP:
- Setup: Install dependencies and configure your environment
- Running E3: Deploy and run the complete CRISP protocol
- Study the code: Examine the implementation for your own E3 programs
CRISP demonstrates the full potential of E3 programs for privacy-preserving applications, providing a complete reference implementation for developers building with Enclave.