ZK Proofs Fundamentals
What is a Zero-Knowledge Proof
Prove statement is true WITHOUT revealing the secret/data used in the proof.
Example: "I know the solution to this sudoku" without showing the solution. On-chain: "I know a valid trade at this price" without revealing the actual price or identity.
SNARKs vs STARKs
| Property | SNARK | STARK |
|---|---|---|
| Proof size | Small (~200 bytes) | Large (~50KB) |
| Verification time | Fast | Slower |
| Trusted setup | Required | None |
| Quantum safe | No | Yes |
| Scalability | Limited | Better |
| Use cases | Private tx, privacy | Scaling, transparency |
SNARK: Groth16, Plonk (requires trusted setup ceremony — risky if not done correctly). STARK: DEEP-FRI (no trusted setup).
Circom (Circuit Language)
Describe computation in a circuit. Compiler generates constraints.
pragma circom 2.0.0;
// Sudoku solution verification circuit
template SudokuVerifier() {
signal input solution[81]; // Sudoku solution (9x9)
signal input puzzle[81]; // Puzzle clues
signal output valid; // 1 if valid, 0 otherwise
// Check rows
for (var i = 0; i < 9; i++) {
var seen[10] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
for (var j = 0; j < 9; j++) {
var idx = i * 9 + j;
var val = solution[idx];
// Check 1-9
(val - 1) * (val - 9) === 0;
// Check no duplicates (simplified)
seen[val]++;
}
}
// ... similar for columns and 3x3 boxes
// Check puzzle constraints (where puzzle has clues)
for (var i = 0; i < 81; i++) {
if (puzzle[i] != 0) {
solution[i] === puzzle[i];
}
}
valid <== 1; // All constraints satisfied
}
component main = SudokuVerifier();
Proving & Verification
Using snarkjs (JavaScript)
// 1. Compile circuit
const snarkjs = require("snarkjs");
const fs = require("fs");
const circuitCode = `pragma circom 2.0.0;
template Multiplier() { ... }`;
// Compile to R1CS
await snarkjs.wasm.wtnsCalculate(inputData, wasmFile, wtnsFile);
// 2. Perform trusted setup (generates proving/verification keys)
const zkey = await snarkjs.zkey.newZKey(r1cs, ptau, zkey_final);
// 3. Generate proof
const { proof, publicSignals } = await snarkjs.groth16.fullProve(
{ solution: solutionArray, puzzle: puzzleArray },
wasmFile,
zkeyFile
);
// 4. Verify proof (off-chain or on-chain)
const isValid = await snarkjs.groth16.verify(vkey, publicSignals, proof);
// Export for on-chain verification
const solidityProof = snarkjs.groth16.exportSolidityCallData(proof, publicSignals);
// solidityProof = ["0xa...", ["0xb...", "0xc..."], "0xd..."]
On-Chain Verification (Solidity)
contract SudokuVerifier {
// Generated by snarkjs
Pairing.VerifyingKey verifyingKey = ... ;
function verifyProof(
uint[2] memory a,
uint[2][2] memory b,
uint[2] memory c,
uint[1] memory input
) public view returns (bool) {
return verify(input, Proof(a, b, c));
}
}
// In your market contract
function submitProof(uint[2] memory a, uint[2][2] memory b, uint[2] memory c) external {
require(sudokuVerifier.verifyProof(a, b, c, [uint(1)]), "Invalid proof");
// Proof verified — process trade or claim prize
}
Use Cases for ZK in Prediction Markets
1. Private Order Submission
Problem: CLOB order book reveals all pending orders (MEV risk). Solution: Submit ZK proof that you know a valid limit order at price X, without revealing X or your identity until trade matches.
2. Privacy-Preserving Resolution
Problem: Oracle reveals outcome before users claim. Solution: Oracle signs commitment hash, reveals actual outcome later. Users prove their position with ZK.
3. Proof of Reserves
Problem: Did the prize pool operator actually lock all prize money? Solution: ZK proof that vault contains >= claimed funds without revealing exact amount.
4. Scalability
Generate ZK proof that 1000 transactions are all valid, submit one proof on-chain instead of 1000 txs.
Risks & Limitations
- Circuits are hard: Small bugs → invalid proofs accepted or valid ones rejected
- Trusted setup: If ceremony is compromised, fake proofs can be generated
- Proof generation is slow: Creating a proof can take seconds-to-minutes (on-chain may not work)
- Circuit audits are expensive: ZK adds another layer to audit
For Agent Sparta: ZK is cool but not necessary yet. Focus on simple, auditable contracts first. Consider ZK for next phase if privacy/MEV is a problem.