Overview
The ZK Verifier contract (identipay::zk_verifier) implements zero-knowledge proof verification using Groth16 over BN254. It enables privacy-preserving eligibility checks such as age verification without revealing personal information.
Per the whitepaper section 4.6, proofs are bound to the intent hash to prevent replay attacks. The verifier learns only the predicate truth (e.g., “age >= 21”) without seeing the underlying attributes (actual birthdate, name, etc.).
Source Code
Location:contracts/sources/zk_verifier.move:8
Data Structures
VerificationKey
Stores a prepared verification key for a specific ZK circuit.Sui object identifier
Human-readable circuit identifier (e.g., “age_check”, “identity_registration”, “pool_spend”)
Pre-processed verifying key for efficient verification
Public Functions
create_verification_key
Create and share a new verification key for a ZK circuit. Called once during deployment to register each circuit. Function Signature:Human-readable identifier for the circuit
Serialized Groth16 verification key from the circuit’s trusted setup
zk_verifier.move:36-51
Example:
verify_proof
Verify a Groth16 proof against the stored verification key. Returnstrue if valid, false otherwise.
Function Signature:
Reference to the verification key object
Serialized Groth16 proof
Serialized public inputs to the circuit
Returns
true if proof is valid, false otherwiseEEmptyProof(1): Proof bytes are emptyEEmptyPublicInputs(2): Public inputs are empty
public(package) — only callable by other modules in the identipay package.
Location: zk_verifier.move:56-69
assert_proof_valid
Verify a proof and abort if invalid. Convenience wrapper for use in settlement. Function Signature:EProofVerificationFailed(0): Proof is invalid- Plus errors from
verify_proof
zk_verifier.move:73-80
Accessors
circuit_name
zk_verifier.move:84
ZK Circuits
identiPay uses several ZK circuits for different purposes:Age Check Circuit
Verifies that a user’s age meets a threshold without revealing their birthdate. Private Inputs:birthdate: User’s birthdate (YYYYMMDD as integer)credential_fields: Other ID fields for commitment verificationcredential_signature: Government signature on credential
min_age: Minimum age requirement (e.g., 21)current_date: Current date (YYYYMMDD)identity_commitment: Poseidon hash of credential fieldsintent_hash: Intent hash to bind proof to transaction
Identity Registration Circuit
Proves ownership of a valid government credential for meta-address registration. Private Inputs:credential_fields: ID fields (name, DOB, ID number, etc.)credential_signature: Government signature
identity_commitment: Poseidon(credential_fields)
Pool Spend Circuit
Proves ownership of a note in the shielded pool without revealing which note. Private Inputs:amount: Note amountowner_key: Owner’s private keysalt: Random salt from note creationmerkle_path: Merkle authentication path
merkle_root: Current pool Merkle rootnullifier: Unique nullifier to prevent double-spendrecipient: Withdrawal recipient addresswithdraw_amount: Amount being withdrawnchange_commitment: Commitment to change note (if partial withdrawal)
Usage Example
Groth16 Background
Groth16 is a zero-knowledge SNARK proof system with:- Small proofs: 3 elliptic curve points (~192 bytes)
- Fast verification: Single pairing check (~10ms)
- Trusted setup: Requires one-time setup ceremony
- BN254 curve: 128-bit security level
Proof Structure
A Groth16 proof consists of 3 points on the BN254 elliptic curve:e() is the optimal ate pairing on BN254.
Sui Native Integration
Sui Move provides native Groth16 verification:Security Considerations
Circuit Bugs: Bugs in the circuit logic can allow invalid proofs to verify. Thoroughly audit circuits before deployment.
Gas Costs: Groth16 verification on Sui costs ~50,000 gas units per proof. This is efficient compared to other proof systems.
Privacy Guarantees
Zero Knowledge
Zero Knowledge
Proofs reveal only the truth of the statement (e.g., “age >= 21”), not the underlying data (birthdate).
Unlinkability
Unlinkability
Different proofs from the same credential are unlinkable (assuming proper randomization in proof generation).
Soundness
Soundness
Computationally infeasible to create a valid proof for a false statement (assuming trusted setup is secure).
Succinctness
Succinctness
Proofs are constant size (~192 bytes) regardless of computation complexity.
Circuit Development Workflow
Trusted Setup
Run Powers of Tau ceremony + circuit-specific setup to generate proving/verification keys.
Related Modules
Settlement
Uses ZK proofs for age-gated transactions
Meta-Address Registry
Uses ZK proofs for identity registration
Shielded Pool
Uses ZK proofs for private withdrawals
