privacy math
How much privacy a shielded protocol actually delivers depends on three independent quantities: the cryptographic strength of the proof system, the size of the active anonymity set, and the entropy of withdraw timing. KIRITE's v1 launch positions on the first; the other two scale with usage.
cryptographic strength (fixed)
The Groth16 membership proof reduces deposit↔withdraw unlinkability to standard BN254 hardness assumptions: q-PKE, q-PDH, and the SXDH family. The best known classical attack on these requires ~2128 operations, comparable to AES-256. A successful break would let an attacker forge proofs and drain the pool, not just deanonymize.
Poseidon over BN254 is the Merkle hash. Its security relies on ~2128 collision resistance for the Circom-default parameter set, the standard configuration for this curve.
anonymity set (variable)
Practical unlinkability is bounded by the active anonymity set. Let n be the number of unspent leaves in the same pool denomination at the time of withdraw. The probability of a chain-only adversary correctly linking one withdraw back to its deposit is at most 1/n.
v2 caps each pool at 32,768 leaves (Merkle height 15). The anonymity set only counts active leaves: deposits whose nullifier has not yet been consumed.
timing correlation (variable)
v1 does not enforce on-chain timelock. The miniapp recommends a 10+ minute delay between deposit and withdraw. Aggressive timing analysis on a sparsely-trafficked pool can still partially deanonymize: if only one deposit lands at 14:32 and only one withdraw lands at 14:45, the correlation is obvious regardless of how strong the proof is.
This is the failure mode that traffic volume fixes, not cryptography.
realistic privacy bounds
| scenario | active leaves | upper bound on linkability |
|---|---|---|
| cold-start (first depositor) | 1 | 100% (effectively transparent) |
| 10 unspent leaves in pool | 10 | 10% per attempt |
| 100 unspent leaves | 100 | 1% per attempt |
| 1,000 unspent leaves | 1,000 | 0.1% per attempt |
| v2 pool full (height 15) | 32,768 | ~0.003% per attempt |
These are upper bounds. Real-world adversaries combine timing, amount-on-the-margin, and stealth recipient-clustering to narrow further. KIRITE's recipient-hash binding closes the relayer-redirect angle; everything else is a function of how many strangers share the pool with you.
Privacy in KIRITE v1 is real but bounded by traffic. If you are the only depositor in a pool, you have stealth-recipient privacy but not unlinkability. Before sending material amounts privately, watch the pool counters and wait for others to deposit too.
further reading
- Threat model — adversary types and defenses.
- Shield pool — the on-chain Merkle / nullifier mechanism.