A privacy-preserving mixing pool implementation using Noir zero-knowledge proofs. This project allows users to deposit and withdraw funds while maintaining transaction privacy through cryptographic commitments and Merkle tree proofs.
Privacy Pool operates on the principle of commitment schemes and zero-knowledge proofs to break the link between deposits and withdrawals:
-
Deposit: When users deposit funds, they generate a secret commitment that represents their deposit without revealing the amount or their identity.
-
Merkle Tree: All commitments are stored in a binary Merkle tree, creating a cryptographic structure that allows proving membership without revealing which specific commitment belongs to whom.
-
Withdrawal: To withdraw funds, users generate a zero-knowledge proof that demonstrates:
- They know the secret to a valid commitment in the tree
- They haven't already spent this commitment (nullifier mechanism)
- The withdrawal amount is valid
-
Privacy: Since the proof doesn't reveal which commitment is being spent, withdrawals are unlinkable to deposits, providing transaction privacy.
-
Clone the repository:
git clone <repository-url> cd privacy_pool
-
Install dependencies:
# Install root dependencies bun install # Install web-app dependencies cd web-app bun install
-
Start the development server:
# From the web-app directory bun run dev
-
Open your browser: Navigate to
http://localhost:5173
to access the Privacy Pool interface.
From the root directory, you can use the following commands:
# Initialize the system
bun run init
# Make a deposit
bun run deposit
# Make a withdrawal
bun run withdraw
# Generate a proof
bun run gen-proof
# Get latest note information
bun run get-latest-note
The Noir circuit that handles the zero-knowledge proof generation and verification:
- Hash Function: Uses SHA-256 compression for creating commitments
- Merkle Proof Verification: Validates that a commitment exists in the tree
- Nullifier System: Prevents double-spending of commitments
Command-line tools for interacting with the privacy pool:
init.ts
: Initializes the privacy pool system and storagedeposit.ts
: Handles deposit operations and commitment generationwithdraw.ts
: Processes withdrawal requests with proof generationgen_proof.ts
: Generates zero-knowledge proofs for withdrawalsget_latest_note.ts
: Retrieves the user's current note informationgen_input.ts
: Generates input data for proof generation
constants.ts
: System configuration (tree depth, zero values, etc.)storage.ts
: Persistent storage management for notes and tree stateindex.ts
: Utility functions and common operationstypes.ts
: TypeScript type definitions for notes and commitments
A React-based user interface for interacting with the privacy pool:
BankingInterface.tsx
: Main interface for deposits, withdrawals, and balance managementui/
: Reusable UI components (buttons, cards, inputs, etc.)pages/
: Application pages and routing
storage.ts
: Browser-side storage managementtypes.ts
: Frontend type definitionsutils.ts
: Utility functions including proof generationconstants.ts
: Frontend configuration constants
Nargo.toml
: Noir project configuration and dependenciespackage.json
: Node.js dependencies and scriptsProver.toml
: Proof generation parameters and test data
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Web App UI │ │ CLI Scripts │ │ Noir Circuit │
│ │ │ │ │ │
│ • Deposits │ │ • init.ts │ │ • Commitment │
│ • Withdrawals │ │ • deposit.ts │ │ • Merkle Proof │
│ • Balance │ │ • withdraw.ts │ │ • Nullifiers │
│ • History │ │ • gen_proof.ts │ │ • ZK Proofs │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
└───────────────────────┼───────────────────────┘
│
┌─────────────────┐
│ Local Storage │
│ │
│ • Notes │
│ • Tree State │
│ • Balances │
│ • Commitments │
└─────────────────┘
- Privacy-Preserving: Transactions are unlinkable through zero-knowledge proofs
- Commitment Scheme: Deposits are represented as cryptographic commitments
- Merkle Tree: Efficient membership proofs for large commitment sets
- Nullifier System: Prevents double-spending of commitments
- Dual Interface: Both CLI and web-based interfaces available
- Partial Withdrawals: Support for withdrawing portions of deposited amounts
- Real-time UI: Live updates for balances and transaction history
- Noir: Zero-knowledge proof system for privacy-preserving computations
- TypeScript: Type-safe development environment
- React: Frontend user interface framework
- Bun: Fast JavaScript runtime and package manager
- Tailwind CSS: Utility-first CSS framework
- Poseidon: Cryptographic hash function optimized for ZK circuits
- BB.js: Aztec's proving system for generating proofs
- Commitment Uniqueness: Each deposit generates a unique commitment
- Nullifier Protection: Prevents double-spending through nullifier tracking
- Merkle Tree Integrity: Ensures only valid commitments can be withdrawn
- Zero-Knowledge: Proofs reveal no information about the prover's identity
- Storage Validation: Automatic validation of stored data consistency
This is a demonstration project (v0.1) showcasing privacy pool concepts using Noir. The system maintains separate account and pool balances with a retro terminal-style interface for an engaging user experience.
This code is experimental and unaudited. It is intended for educational and research purposes only. Do not use this code in production environments or with real funds. The implementation may contain bugs, security vulnerabilities, or other issues that could result in loss of funds or privacy breaches.
This project builds upon the excellent work of several teams and projects:
- 0xbow.io - For inspiration on the random withdraw logic design
- Privacy Scaling Explorations (PSE) - For the invaluable ZK-Kit libraries:
- zk-kit.noir - Reusable Noir circuits including binary Merkle tree implementations
- zk-kit - Comprehensive zero-knowledge libraries and utilities
- Noir Team - For creating the amazing Noir language that makes zero-knowledge circuit development accessible and powerful
Privacy Pool - Secure, Private, Decentralized