ZK Identity System
The ZK Identity System provides a privacy-preserving way to attest to an identity (e.g., verifying you are a Github user) without revealing the specific identity or linking multiple actions to the same user. It uses Zero-Knowledge Proofs (ZK-SNARKs) to guarantee:- Privacy: No one knows which user performed an action.
- Uniqueness: A user cannot double-spend an action in the same context (via Nullifiers).
- Soundness: Mathematical proof of validity.
Core Concepts
Commitment
Poseidon(provider_id, secret)
A cryptographic commitment to an identity, stored on-chain in a Merkle Tree. It hides the userβs ID and secret.Nullifier
Poseidon(provider_id, context)
A unique hash generated for a specific action (context). Prevents double-spending while maintaining anonymity.Merkle Tree
A valid commitment must exist in the global Merkle Tree. The ZK proof verifies inclusion in this tree.
ZK Proof
A Groth16 proof that asserts: βI know a secret corresponding to a commitment in the Merkle Tree, and here is my unique nullifier for this context.β
Architecture Overview
The system operates in a Two-Phase Flow:Phase 1: Link Identity (One-time)
Submit to Chain
User submits the commitment to the blockchain via an
identity_commitment transaction.Phase 2: Prove Ownership (Repeatable)
When a user wants to perform an action (e.g., vote, claim airdrop) anonymously:Calculate Nullifier
User calculates a nullifier based on the action context:
Hash(provider_id, context).Privacy Model
| Component | Visibility | Description |
|---|---|---|
| Provider ID | π Private | Hidden inside commitment and ZK proof |
| User Secret | π Private | Known only to user, never transmitted |
| Commitment | π Public | Visible on-chain, but opaque |
| Nullifier | π Public | Visible on-chain, used for uniqueness check |
| Context | π Public | The specific action being performed |
Security Guarantees
- Anonymity Set: All users across all providers in the Merkle Tree.
- Unlinkability: No link between the commitment (Phase 1) and the attestation (Phase 2).
- Double-Spend Protection: The nullifier guarantees a user can only act once per context.