Skip to content

sreeduggirala/burner

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

4 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Burner

Burner is a Solana-native mixer that breaks on-chain transaction linkability for SPL token transfers.

⚠️ EDUCATIONAL RESEARCH PROJECT β€” NOT PRODUCTION READY ⚠️ Do NOT use with real funds. Not audited. Experimental design.

This project took inspiration from Privacy Cash

Overview

Burner is a privacy protocol that allows users to deposit tokens (SOL or SPL tokens) into a shielded pool and withdraw them later without revealing which deposit was theirs. It offers transaction privacy similar to Tornado Cash, but built natively on Solana.

How It Works

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  User deposits 10 SOL                           β”‚
β”‚  β†’ Receives secret commitment                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                  β”‚
                  β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Shielded Pool (Merkle Tree)                    β”‚
β”‚  β€’ Contains all user commitments                β”‚
β”‚  β€’ No link between deposits and withdrawals     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                  β”‚
                  β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  User proves ownership with ZK proof            β”‚
β”‚  β†’ Withdraws to new address                     β”‚
β”‚  β†’ Privacy preserved!                           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key Features:

  • Zero-knowledge proofs using Noir circuits and Groth16
  • Support for SOL and SPL tokens (USDC, USDT, ORE, ZEC, stORE)
  • Sparse Merkle tree supporting ~67M transactions (height 26)
  • Configurable deposit/withdrawal fees
  • On-chain proof verification using BN254 pairing
  • Nullifier tracking to prevent double-spending

Architecture

Noir Circuits (/circuits)

Zero-knowledge circuits written in Noir that prove transaction validity without revealing inputs:

  • JoinSplit Transaction (main.nr) - Proves:

    • Input UTXOs exist in merkle tree
    • Balance conservation: sum(inputs) + public_amount == sum(outputs)
    • Unique nullifiers generated
    • Outputs are correctly formed
  • Merkle Proof (merkle_proof.nr) - Verifies UTXO membership in tree

  • Keypair (keypair.nr) - Key derivation and signature generation

  • Utils (utils.nr) - Helper functions (conditional swaps, assertions)

Circuit Constants:

LEVELS: u32 = 26    // Merkle tree depth (67M capacity)
N_INS: u32 = 2      // Number of inputs
N_OUTS: u32 = 2     // Number of outputs

Anchor Program (/anchor)

Solana smart contract that verifies proofs and manages the shielded pool:

  • Groth16 Verification (groth16.rs) - Verifies zero-knowledge proofs using BN254 pairing
  • Merkle Tree (merkle_tree.rs) - Manages commitment tree and root history (100 roots)
  • Main Program (lib.rs) - Transaction processing, nullifier tracking, token transfers

Key Instructions:

  • initialize() - Create main SOL merkle tree
  • initialize_tree_account_for_spl_token() - Create SPL token trees
  • transact() - Process SOL deposits/withdrawals with ZK proofs
  • transact_spl() - Process SPL token deposits/withdrawals
  • update_deposit_limit() - Configure max deposit amounts
  • update_global_config() - Set deposit/withdrawal fees

Integration Flow

  1. Client Side (TypeScript/JavaScript):

    • Generates JoinSplit transaction using Noir circuit
    • Creates Groth16 proof with snarkjs
    • Encrypts transaction details
  2. Proof Submission:

    • Submits transact() instruction with:
      • Proof components (proof_a, proof_b, proof_c)
      • Public inputs (root, nullifiers, commitments)
      • External data (amounts, fees, recipients)
  3. On-Chain Verification (Anchor Program):

    // Verify ZK proof
    verify_proof(proof, VERIFYING_KEY)?
    
    // Verify merkle root in history
    MerkleTree::is_known_root(&tree, proof.root)?
    
    // Prevent double-spending
    check_nullifiers_unspent(proof.input_nullifiers)?
    
    // Execute token transfers
    process_transaction(proof.public_amount)?
    
    // Update tree with new commitments
    tree.insert(proof.output_commitments)?
  4. Privacy Guarantee:

    • Proof reveals ONLY: "I have valid inputs and they balance"
    • Proof hides: Which specific inputs, who owns them, amounts
    • Merkle tree breaks link between deposits and withdrawals

Project Structure

burner/
β”œβ”€β”€ circuits/               # Noir zero-knowledge circuits
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ main.nr        # JoinSplit transaction circuit
β”‚   β”‚   β”œβ”€β”€ merkle_proof.nr
β”‚   β”‚   β”œβ”€β”€ keypair.nr
β”‚   β”‚   └── utils.nr
β”‚   β”œβ”€β”€ Nargo.toml         # Noir project config
β”‚   └── README.md          # Circuit documentation
β”‚
β”œβ”€β”€ anchor/                # Solana Anchor program
β”‚   β”œβ”€β”€ programs/zkcash/
β”‚   β”‚   └── src/
β”‚   β”‚       β”œβ”€β”€ lib.rs     # Main program (~950 lines)
β”‚   β”‚       β”œβ”€β”€ groth16.rs # Proof verification
β”‚   β”‚       β”œβ”€β”€ merkle_tree.rs
β”‚   β”‚       └── utils.rs
β”‚   β”œβ”€β”€ tests/             # Anchor tests
β”‚   └── package.json
β”‚
β”œβ”€β”€ scripts/               # Deployment and utility scripts
β”‚   β”œβ”€β”€ initialize_devnet.ts
β”‚   └── package.json
β”‚
β”œβ”€β”€ artifacts/circuits/    # Compiled circuit artifacts
β”‚   β”œβ”€β”€ transaction2.r1cs
β”‚   β”œβ”€β”€ transaction2.zkey  # Proving key (16.4 MB)
β”‚   β”œβ”€β”€ transaction2.wasm
β”‚   └── verifyingkey2.json # Hardcoded in Anchor program
β”‚
└── README.md             # This file

Getting Started

Prerequisites

  • Rust (latest stable)
  • Solana CLI (v1.18+)
  • Anchor (v0.31.0)
  • Node.js (v18+)
  • Noir/Nargo (v0.36.0+)

Installation

  1. Clone the repository:

    git clone <repository-url>
    cd burner
  2. Install Noir:

    curl -L https://raw.githubusercontent.com/noir-lang/noirup/main/install | bash
    noirup
  3. Install Anchor dependencies:

    cd anchor
    npm install
  4. Install script dependencies:

    cd scripts
    npm install

Build

  1. Compile Noir circuits:

    cd circuits
    nargo check      # Verify syntax
    nargo test       # Run tests
    nargo compile    # Compile to ACIR
  2. Build Anchor program:

    cd anchor
    anchor build

Testing

Run circuit tests:

cd circuits
nargo test

Run Anchor tests:

cd anchor

# Test SOL transactions
npm run test:sol

# Test SPL transactions
npm run test:spl

# Test with mint authority checks
npm run test:mint-checked

Deployment

  1. Configure Solana CLI:

    solana config set --url devnet
    solana-keygen new  # Create keypair if needed
    solana airdrop 2   # Get devnet SOL
  2. Deploy program:

    cd anchor
    anchor deploy --provider.cluster devnet
  3. Initialize program:

    cd scripts
    npx ts-node initialize_devnet.ts

Security

Cryptographic Primitives

  • Hash Function: Poseidon (BN254-optimized)
  • Proof System: Groth16
  • Curve: BN254 (alt_bn128)
  • Tree Structure: Sparse Merkle Tree (height 26)

Security Properties

  1. Transaction Privacy:

    • ZK proofs hide input/output relationships
    • Encrypted transaction details
    • No on-chain metadata linking deposits to withdrawals
  2. Double-Spend Prevention:

    • Nullifiers mark UTXOs as spent
    • Nullifier uniqueness enforced on-chain
    • Historical root tracking prevents replay attacks
  3. Balance Integrity:

    • Amount invariant: sum(inputs) + public_amount == sum(outputs)
    • Range checks on all amounts (248-bit limit)
    • Fee validation and extraction
  4. Access Control:

    • Ownership proven via ZK signatures
    • Private keys never revealed
    • Public key derived using Poseidon

Security Notes

  • Output amounts are range-checked to 248 bits
  • Duplicate nullifiers are rejected
  • Merkle proofs only verified for non-zero amounts
  • Circuit constants (LEVELS, N_INS, N_OUTS) must be < 16 to prevent overflow
  • 100 historical roots maintained for proof flexibility

UTXO Structure

Each UTXO (Unspent Transaction Output) contains:

{
  amount: Field,         // Token amount
  pubkey: Field,         // Owner's public key
  blinding: Field,       // Random blinding factor
  mint_address: Field    // SOL or SPL token mint
}

Commitment Calculation:

commitment = Poseidon(amount, pubkey, blinding, mint_address)

Nullifier Calculation:

signature = Poseidon(privKey, commitment, merklePath)
nullifier = Poseidon(commitment, merklePath, signature)

Supported Tokens

  • SOL (native Solana)
  • USDC (USD Coin)
  • USDT (Tether)
  • ORE (Ore token)
  • ZEC (Zcash wrapped)
  • stORE (Staked ORE)

Each token type has its own merkle tree for isolation and scalability.

Fee Structure

Configurable fees (in basis points, 1 bp = 0.01%):

  • Deposit Fee: Charged on deposits
  • Withdrawal Fee: Charged on withdrawals
  • Fee Recipient: Configurable admin account

Fees are extracted during transaction processing and transferred to the fee recipient.

Compatibility

Noir Circuits

  • Noir version: β‰₯0.36.0
  • Poseidon library: v0.1.1 (noir-lang/poseidon)
  • Field: BN254 curve

Anchor Program

  • Anchor: 0.31.0
  • Solana: Compatible with 1.18+
  • Dependencies:
    • light-poseidon: 0.4.0
    • ark-bn254: 0.5.0
    • solana-bn254: 2.2.2

Migrated from Circom

This project was migrated from Circom to Noir for better developer experience while maintaining full compatibility:

  • Same Poseidon hash function (BN254)
  • Identical UTXO structure and commitment scheme
  • Preserved all security checks and constraints
  • Compatible proof outputs

See circuits/README.md for detailed migration notes.

Development

Code Style

cd anchor
npm run lint        # Check formatting
npm run lint:fix    # Auto-format

Testing Strategy

  1. Unit Tests - Test individual components (circuits, merkle tree, utils)
  2. Integration Tests - Test full transaction flows
  3. Feature Flags - Test different network configurations:
    • localnet - Local development
    • localnet-mint-checked - With mint authority checks
    • devnet - Devnet deployment

License

Burner is licensed under the Business Source License 1.1 (BSL), with automatic transition to GPL v2.0 or later on 12/27/2027.

What You Can Do

  • View and audit source code
  • Modify for research or non-commercial purposes
  • Use internally within your organization
  • Build on top without offering competing product

What You Cannot Do

  • Offer as hosted/paid service competing with Burner
  • Embed into competing commercial product
  • Monetize fork that overlaps with Burner's offerings

After 2 years from release, the code becomes GPL v2.0 or later permanently.

See LICENSE.md for full details.

Contributing

Contributions are welcome! Please ensure:

  1. All tests pass (nargo test and anchor test)
  2. Code is formatted (npm run lint:fix)
  3. Security properties are preserved
  4. Changes are documented

Acknowledgments

  • Inspired by Tornado Cash and other privacy protocols
  • Uses Noir language by Aztec Labs
  • Built with Anchor framework for Solana
  • Groth16 implementation based on arkworks

Resources

Disclaimer

This software is provided "AS IS" without warranties. Use at your own risk. See LICENSE.md for full disclaimer.

About

Crypto mixer on Solana

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors