The shielded pool.
A zero-knowledge pool for BNB, built like Tornado Nova. You can shield, unshield and send privately on Move BNB. Harvests, holder rewards and donations can also be paid straight into it.
Field BN254 scalar field
Hash Poseidon
Note commitment = Poseidon(amount, pubKey, blinding)
Keypair pubKey = Poseidon(privKey); privKey = keccak(signature of "zkBNB shielded key v1") mod p
Nullifier Poseidon(commitment, leafIndex, Poseidon(privKey, commitment, leafIndex))
Tree depth 20, incremental, 100-root history
Join-split 2 inputs → 2 outputs, Groth16 on BN254, Powers of Tau 16
Address zkbnb1 + pubKey (32 bytes) + x25519 encryption key (32 bytes), hextransact(proof, extData) handles three cases: extAmount > 0 is a deposit (you send exactly that much BNB), extAmount < 0 is a withdrawal to recipient, and 0 is a private transfer. An optional fee is paid to relayer. Encrypted outputs are emitted with each new commitment, so a recipient finds their notes by trying to decrypt them. depositFor(pubKey, blinding) lets zkBNB contracts pay into the pool without a proof; the commitment is computed on-chain.
What is private
- Which note pays for which withdrawal or transfer (the spending graph inside the pool).
- The recipient of a private transfer, and the amount of each note created by a proof.
What is not private
- Every shield: the sending wallet and the amount.
- Every unshield: the recipient address and the amount. Unshield to a fresh address. Unshielding to the wallet you shielded from links the two.
- Every contract payout into the pool (harvest, claim, donation settlement): the amount, the destination pubKey and the blinding are in the
DepositForevent. The harvester's or claimer's wallet signed that transaction. - Timing. A shield followed shortly by an unshield of the same amount is easy to match. Your privacy depends on how much activity the pool has.
- Whoever sends the
transacttransaction pays gas and is visible as the sender. There is no relayer network yet.
Keys
Your shielded key is derived from a wallet signature and kept in memory only. Anyone who can sign with your wallet can derive your shielded key. Proofs are generated in your browser in a Web Worker; the proving key is about 15 to 20 MB and is downloaded once.
You can only lose shielded notes by losing the wallet you derived the key from. Notes are found again by scanning the pool's events; the copy cached in your browser is a convenience.
Limits
- Deposits through
transactare capped (100 BNB by default). Contract payouts throughdepositForare never capped, so they can never be blocked. - The withdrawal and relayer-fee limits are constants, so the admin cannot freeze withdrawals.
- The tree holds about a million notes. When it is full, the pool still pays out withdrawals: it can never lock funds.