Skip to main content

What are ZK-SNARKs?

Zero-Knowledge Succinct Non-Interactive Argument of Knowledge

ZK-SNARKs are cryptographic proofs that let you prove you know something without revealing what that thing is.

The Problem

On public blockchains like Stellar, every transaction is visible to everyone:

  • Your exact balance
  • Who you transact with
  • How much you send

This lack of privacy is a barrier for businesses and individuals who value confidentiality.

The Solution

ZK-SNARKs enable private compliance:

┌─────────────────┐      ┌──────────────┐      ┌────────────────┐
│ Private Data │ ───> │ ZK Circuit │ ───> │ Public Proof │
│ age: 25 │ │ (Groth16) │ │ │
│ balance: $150 │ │ │ │ kycValid = 1 │
│ country: AR │ │ BN254 curve │ │ (800 bytes) │
└─────────────────┘ └──────────────┘ └────────────────┘


┌────────────────────────────┐
│ Stellar Soroban Contract │
│ Verifies: true/false │
└────────────────────────────┘

Real-World Example

Alice wants to prove she's over 18 to access a DeFi protocol:

Without ZK:

  • Alice submits: "I'm 25 years old"
  • Everyone sees her exact age

With ZK:

  • Alice generates proof: age ≥ 18
  • Proof is verified on-chain
  • Nobody learns she's 25, only that she's 18+

How It Works

1. Circuit Design

Define what you want to prove in code:

template AgeVerification() {
signal input age; // Private
signal input minAge; // Public
signal output valid; // Public

// Constraint: age must be >= minAge
component gte = GreaterEqThan(8);
gte.in[0] <== age;
gte.in[1] <== minAge;

valid <== gte.out;
}

2. Trusted Setup

Generate cryptographic keys:

  • Proving key: Used to create proofs (private data → proof)
  • Verification key: Used to verify proofs (embedded in smart contract)

3. Proof Generation

User creates a proof off-chain:

const proof = await groth16.fullProve(
{ age: 25, minAge: 18 },
"circuit.wasm",
"circuit_final.zkey"
);

4. On-Chain Verification

Smart contract verifies the proof:

pub fn verify(env: Env, proof: Bytes, public_inputs: Bytes) -> bool {
groth16::verify(&proof, &public_inputs)
}

Why Groth16?

OpenZKTool uses Groth16 ZK-SNARKs because:

FeatureBenefit
Small proofs~800 bytes (low tx costs)
Fast verificationUnder 50ms off-chain, ~200k gas on-chain
Battle-testedUsed by Zcash since 2018
ECC-friendlyWorks with BN254 curve

Trade-offs

✅ Advantages

  • Privacy-preserving
  • Compact proofs
  • Fast verification
  • Composable (can verify multiple proofs)

⚠️ Considerations

  • Requires trusted setup ceremony
  • Circuit design needs expertise
  • Proof generation is compute-intensive (~1s)

Use Cases on Stellar

  • KYC/AML: Prove identity without revealing PII
  • Age verification: Prove age > 18 without exact birthdate
  • Solvency: Prove sufficient balance without amount
  • Geographic compliance: Verify country without location
  • Private DeFi: Trade without revealing balances

Next Steps