getting started

Privacy Model

How Mini Veil achieves unlinkable private transfers

Privacy Guarantees#

Mini Veil provides unlinkability between deposit and withdrawal transactions. An observer cannot determine which withdrawal corresponds to which deposit, even with full visibility of the Solana ledger.

| Property | Guarantee | Mechanism | |---|---|---| | Sender privacy | Withdrawal cannot be linked to a specific deposit | ZK proof hides which leaf is spent | | Recipient privacy | Recipient address is hidden from observers | One-time stealth addresses | | Amount privacy | Withdrawn amount equals deposited amount | Circuit constrains denomination | | Double-spend protection | Each note spent exactly once | Nullifier PDA checked on-chain | | Censorship resistance | Anyone can deposit and withdraw | Permissionless pool |

Threat Model#

Mini Veil protects against:

  • Chain analysis. An observer monitoring the ledger cannot link a shield transaction to its corresponding unshield. The ZK proof reveals only the Merkle root, nullifier hash, recipient, and denomination — not which leaf was spent.
  • Linkage via amount. All withdrawals within a denomination pool are for the same amount. An observer cannot differentiate transactions by value.
  • Timing analysis. Shield and unshield events occur asynchronously. Multiple deposits accumulate before the Merkle root is updated, creating a larger anonymity set.

Privacy Boundary

Mini Veil does not protect against:

  • IP address leakage during transaction submission
  • Wallet-level privacy (the sender's wallet IP may be visible to RPC nodes)
  • Sybil attacks on the anonymity set
  • Compromised proving key or toxic waste from trusted setup

Anonymity Set#

The anonymity set is the set of all unspent deposits in a given denomination pool. When a user withdraws, the ZK proof demonstrates membership in this set without revealing which element.

The effective anonymity set size at any time is:

anonymity_set = total_shielded - spent_nullifiers

Where total_shielded is stored on-chain in MixerState and spent_nullifiers can be estimated by counting nullifier PDA accounts.

Selective Disclosure#

Mini Veil supports selective disclosure of viewing capabilities. The key hierarchy allows a user to:

  • Share a viewing key. Allows scanning for incoming stealth payments without spending capability
  • Share a spending key. Allows spending from the anonymity pool
  • Derive independently. Spending and viewing keys are independently derived from the master seed

On-chain Footprint#

Each privacy-preserving operation leaves a minimal on-chain footprint:

| Operation | On-chain data | |---|---| | Shield | Commitment (32 bytes), amount (8 bytes), denomination (8 bytes) — in event logs | | Unshield | Proof (256 bytes), public inputs (128 bytes), nullifier PDA creation | | Announce | Ephemeral key (32 bytes), view tag (2 bytes), encrypted key (80 bytes) | | Claim | Standard SOL transfer |

The nullifier PDA (41 bytes) is the only persistent state created by a withdrawal, marking the note as spent.