Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Privacy Pools

Understanding the core cryptographic primitives behind Shinobi Cash.

Key Terms

TermMeaning
CommitmentA hash representing your deposit, added to the Merkle tree
NullifierA unique value revealed during withdrawal to prevent double-spend
Merkle TreeData structure that allows proving membership without revealing position
ZK ProofCryptographic proof that verifies claims without revealing inputs

Overview

Privacy Pools enable private transactions by breaking the on-chain link between deposits and withdrawals. Users deposit funds into a shared pool and later withdraw using zero-knowledge proofs that verify ownership without revealing which deposit is theirs.

Concrete Example

Alice deposits 1 ETH:
  → Commitment C₁ added to Merkle tree
  → Alice stores secret S₁ locally
 
Later, Alice withdraws 0.3 ETH:
  → Generates ZK proof: "I know secret for some commitment in the tree"
  → Reveals nullifier N₁ (derived from S₁)
  → Receives 0.3 ETH to recipient address
  → Change note: 0.7 ETH commitment C₂ created
 
On-chain, observers see:
  → Deposit: someone added C₁
  → Withdrawal: someone spent N₁, created C₂
  → No link between C₁ and N₁ visible

Key Concepts

Commitments

When you deposit, a commitment is created and added to a Merkle tree:

commitment = hash(nullifier, secret, amount, ...)

This commitment is public, but the underlying values (nullifier, secret) are known only to you.

Nullifiers

When you withdraw, you reveal a nullifier derived from your deposit:

nullifier = hash(secret, depositIndex)

The nullifier proves you own a valid deposit without revealing which one. Once revealed, the nullifier is marked as "spent" to prevent double-spending.

Zero-Knowledge Proofs

Withdrawals require a Groth16 SNARK proof that verifies:

  1. You know the secret for a valid commitment in the tree
  2. The nullifier is correctly derived from that commitment
  3. The commitment is in a compliant Association Set (ASP membership)

The proof reveals nothing about which deposit you're spending.

Merkle Trees

Shinobi Cash uses two Merkle trees:

State Tree

Contains all deposit commitments. The root changes with each deposit.

ASP Tree

Contains commitments approved by Association Set Providers. Only deposits in the ASP tree can be withdrawn (ensuring compliance).

Proof Signals

Standard Withdrawal (8 signals)

[0] newCommitmentHash      // Change note commitment
[1] existingNullifierHash  // Spent deposit nullifier
[2] withdrawnValue         // Amount withdrawn
[3] stateRoot              // Merkle root of deposits
[4] stateTreeDepth         // Depth of state tree
[5] ASPRoot                // Merkle root of ASP set
[6] ASPTreeDepth           // Depth of ASP tree
[7] context                // Binding context (prevents replay)

Cross-Chain Withdrawal (9 signals)

Adds one additional signal:

[2] refundCommitmentHash   // Fallback if intent fails

This enables recovery if the cross-chain settlement fails.

Privacy Guarantees

What's HiddenWhat's Revealed
Which deposit you're spendingThat you have a valid deposit
Your deposit historyThe nullifier (once spent)
Connection to your identityThe withdrawal amount
The recipient address

Learn More