Skip to main content

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

DataPrivacy Level
Age, Balance, CountryNever on-chain
KYC valid/invalidPublic (boolean)
Proof dataPublic (but meaningless without private inputs)
Transaction allowedPublic (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

SolutionPrivacyDecentralizationStellar NativeCompliance
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