Privacy on Stellar
The privacy challenge on public distributed ledgers
The Problem
Stellar, like all public blockchains, provides transparency by default:
Every transaction reveals:
├── Sender address
├── Receiver address
├── Asset type
├── Amount
├── Timestamp
└── Memo (optional)
Why This Matters
For Businesses:
- Competitors can track your cash flow
- Suppliers see your profit margins
- Trade strategies are public
- Client relationships are exposed
For Individuals:
- Net worth is visible
- Spending patterns are public
- Financial privacy is impossible
- Targeted attacks (phishing, extortion)
For Institutions:
- Regulatory compliance conflicts with privacy
- Can't protect customer PII
- Settlement patterns are visible
- Whale watching affects markets
Current Solutions Are Insufficient
1. Private Networks (Permissioned)
❌ Sacrifices decentralization ❌ Requires trusted parties ❌ Limited interoperability
2. Mixing Services
❌ Regulatory risk ❌ Custody concerns ❌ Still linkable
3. Separate Privacy Coins
❌ Fragmented liquidity ❌ Exchange delistings ❌ Not composable with Stellar ecosystem
OpenZKTool's Approach
Privacy without sacrificing compliance or composability
Core Principle: Selective Disclosure
Instead of hiding everything, prove only what's necessary:
┌──────────────────────────────────────────────────────┐
│ Transaction Requirements │
├──────────────────────────────────────────────────────┤
│ ✓ User is over 18 (don't reveal age) │
│ ✓ Balance > $500 (don't reveal exact amount) │
│ ✓ From allowed country (don't reveal which one) │
└──────────────────────────────────────────────────────┘
│
▼
┌────────────────────┐
│ ZK Proof (800B) │
│ kycValid = true │
└────────────────────┘
│
▼
┌─────────────────────────────┐
│ Stellar Soroban Contract │
│ if (verify(proof)) { │
│ allow_transaction() │
│ } │
└─────────────────────────────┘
How It Works on Stellar
Architecture Overview
┌─────────────────────────────────────────────────────────┐
│ User's Device │
├─────────────────────────────────────────────────────────┤
│ 1. Private data (age, balance, country) │
│ 2. Generate ZK proof (~1s) │
│ ↓ │
│ [ Proof: 800 bytes ] │
└────────────┬────────────────────────────────────────────┘
│
│ Submit to Stellar
▼
┌─────────────────────────────────────────────────────────┐
│ Stellar Network (Public) │
├─────────────────────────────────────────────────────────┤
│ Soroban Smart Contract (20KB WASM) │
│ ┌──────────────────────────────────┐ │
│ │ Groth16 Verifier │ │
│ │ - BN254 curve operations │ │
│ │ - Pairing verification │ │
│ │ - Returns: true/false │ │
│ └────────────────────────── ────────┘ │
│ │
│ Observable on-chain: │
│ ✓ Proof bytes (800) │
│ ✓ Verification result (true/false) │
│ ✗ Private data (never revealed) │
└─────────────────────────────────────────────────────────┘
Privacy Guarantees
| Data | Privacy Level |
|---|---|
| Age, Balance, Country | Never on-chain |
| KYC valid/invalid | Public (boolean) |
| Proof data | Public (but meaningless without private inputs) |
| Transaction allowed | Public (result of verification) |
Use Cases
1. Private DeFi on Stellar
// Prove you have collateral without revealing amount
const proof = await generateProof({
balance: 10000, // Private
minCollateral: 5000 // Public
});
await stellarContract.openCDPPosition(proof);
// ✓ Position opened
// ✗ Nobody knows you have 10,000 (just that you have ≥5,000)
2. Compliant Privacy
// Prove KYC compliance without revealing identity
const proof = await generateProof({
age: 30, // Private
country: 'US', // Private
kycLevel: 2, // Private
minAge: 18, // Public
allowedCountries: ['US', 'CA', 'UK'], // Public
requiredKYC: 1 // Public
});
await stellarDEX.trade(proof, tradeParams);
// ✓ Trade executed
// ✗ Exchange doesn't learn your age, country, or KYC details
3. Institutional Settlement
// Prove solvency without revealing holdings
const proof = await generateProof({
totalAssets: 1000000000, // Private
totalLiabilities: 800000000, // Private
minSolvencyRatio: 1.1 // Public (110%)
});
await sorobanAudit.submitSolvencyProof(proof);
// ✓ Solvency verified
// ✗ Exact assets/liabilities remain private
Why Stellar?
OpenZKTool is built specifically for Stellar because:
Technical Advantages
- WASM runtime: Efficient ZK verification (vs EVM opcodes)
- Low fees: 10-100x cheaper than Ethereum mainnet
- Fast finality: ~5 seconds vs 12-15 minutes
- Soroban flexibility: Full Rust implementation possible
Ecosystem Fit
- RWA tokenization: Privacy needed for institutional assets
- DeFi growth: DEXs, lending, stablecoins need privacy
- Compliance focus: Stellar's regulated approach aligns with ZK
- Multi-asset native: Built-in support for private multi-asset proofs
Comparison
| Solution | Privacy | Decentralization | Stellar Native | Compliance |
|---|---|---|---|---|
| Transparent (default) | ❌ None | ✅ Full | ✅ Yes | ✅ Easy |
| Permissioned Networks | ✅ Full | ❌ Centralized | ❌ No | ✅ Easy |
| Mixing Services | ⚠️ Partial | ⚠️ Trusted | ⚠️ External | ❌ Risky |
| OpenZKTool | ✅ Selective | ✅ Full | ✅ Yes | ✅ Enabled |
Security Considerations
Trusted Setup
- Groth16 requires one-time ceremony
- Safe if ≥1 participant is honest
- Can use multi-party computation (MPC)
- Ceremony can involve 100s-1000s of participants
Circuit Auditing
- Circuits must be carefully designed
- Formal verification recommended
- Public review before production
- Test coverage critical
Privacy Limitations
- Proof linkability (same user = same nullifier)
- Timing analysis (when proofs are submitted)
- Amount correlation (if amounts are public)
Roadmap
Current (Phase 0):
- ✅ Groth16 verifier on Soroban testnet
- ✅ KYC/compliance circuit templates
- ✅ TypeScript proof generation
Next (Phase 1):
- SDK release (@openzktool/sdk)
- 6+ production circuit templates
- Browser-based proof generation
Future:
- Mainnet deployment
- Recursive proofs (proof of proofs)
- Integration with Stellar DEXs/protocols
Next Steps
- Architecture - Deep dive into technical implementation
- Quick Start - Generate your first ZK proof
- Stellar Integration - Deploy to Soroban