Zero-Knowledge Proofs
What Is a Zero-Knowledge Proof?
A zero-knowledge proof (ZK proof) lets you prove a statement is true without revealing why it is true. The classic analogy: you can prove you are over 21 years old without showing your driver's license. The verifier learns the fact (you meet the age threshold) but learns nothing else — not your name, not your birthdate, not your address.
More precisely, a ZK proof satisfies three properties:
| Property | Meaning |
|---|---|
| Completeness | If the statement is true, an honest prover can always convince the verifier. |
| Soundness | If the statement is false, no cheating prover can convince the verifier (except with negligible probability). |
| Zero-knowledge | The verifier learns nothing beyond the truth of the statement itself. |
In the context of blockchain, ZK proofs allow on-chain smart contracts to verify that a computation was performed correctly without having access to the underlying data. The proof is a small, constant-size object that can be checked cheaply on-chain, while the private data never leaves the prover's device.
How Specter Uses Zero-Knowledge Proofs
Specter is a data privacy protocol. Its core primitive — the Ghost Protocol — allows users to commit any data to a Merkle tree as a Poseidon hash, then prove ownership of that data later without revealing what the data was, when it was committed, or who committed it.
The ZK proof is what makes this possible. When you want to reveal or access committed data, you generate a proof off-chain that demonstrates:
- You know the preimage — you possess the secret values that hash to a specific commitment in the tree.
- The commitment exists — the commitment is a leaf in the Merkle tree at a known root.
- You are authorized — the proof binds to session-specific or recipient-specific values that prevent front-running and replay.
The on-chain verifier checks the proof in constant time. If it passes, the protocol executes the reveal or access operation. At no point does the chain learn which commitment you are proving against, what the original data was, or any link between the commit and reveal transactions.
Two Circuits, Two Purposes
Specter uses two distinct ZK circuits, each designed for a different access pattern:
Redemption Circuit (Token Reveals)
The Redemption Circuit is the specialized circuit for the GHOST token use case. It proves that the prover committed a specific amount of tokens to the tree and is entitled to withdraw some or all of them. This circuit handles amount conservation, partial withdrawals with change commitments, nullifier derivation (to prevent double-spending), and policy enforcement.
| Property | Value |
|---|---|
| Public inputs | 8 (root, nullifier, withdrawAmount, recipient, changeCommitment, tokenId, policyId, policyParamsHash) |
| Private inputs | 7 (secret, nullifierSecret, amount, blinding, pathElements[20], pathIndices[20], newBlinding) |
| Source | redemption.circom (174 LOC) |
| Use case | One-time token reveals and private transfers |
Access Proof Circuit (Persistent Data Access)
The Access Proof Circuit is the core data access circuit — the circuit that makes Specter a data protocol, not just a token mixer. It proves that the prover knows a commitment preimage and that the commitment exists in the tree, without computing a nullifier. Because no nullifier is spent, the same proof can be generated repeatedly. This enables persistent, reusable access to sealed data.
| Property | Value |
|---|---|
| Public inputs | 4 (root, dataHash, sessionNonce, accessTag) |
| Private inputs | 5 (secret, nullifierSecret, blinding, pathElements[20], pathIndices[20]) |
| Source | accessProof.circom (93 LOC) |
| Use case | Persistent credential access, Phantom Identity, sealed data verification |
Why Groth16?
Specter uses Groth16, a pairing-based zero-knowledge proof system, for all on-chain verification. The choice is deliberate:
| Property | Groth16 | PLONK | STARKs |
|---|---|---|---|
| Proof size | ~128 bytes (constant) | ~400-500 bytes | ~50-200 KB |
| Verification time | ~3 pairings (constant) | ~20 group operations | Logarithmic in circuit size |
| On-chain gas cost | ~200K gas | ~300-500K gas | ~1-2M gas |
| Trusted setup | Required (circuit-specific) | Universal (updatable) | None |
| Tooling maturity | Excellent (circom, snarkjs) | Good | Growing |
Groth16 has the smallest proof size and the fastest verification time of any deployed ZK proof system. For a protocol that verifies proofs on every reveal and access operation, these properties directly translate to lower gas costs and better user experience.
The trade-off is a trusted setup: Groth16 requires a one-time ceremony to generate proving and verification keys for each circuit. If the ceremony is compromised, an attacker could forge proofs. Specter mitigates this through a planned multi-party computation ceremony (see Trusted Setup) and defense-in-depth via a quantum commitment layer.
For single-application circuits like Specter's redemption and access proof circuits, the trusted setup is a practical and acceptable trade-off. The circuits are fixed at deployment time, so the setup ceremony only needs to happen once per circuit version.