JOVANA
Explore Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

Privacy vs compliance: the unsolved tension

A public ledger and personal privacy pull in opposite directions, and anti-money-laundering law pulls harder still. Meet the genuinely unsolved problem — and the cleverest middle paths we have: viewing keys, selective disclosure, and zero-knowledge proof of innocence.

Two sides of the same coin

The banknote in your pocket might once have paid for groceries, then changed hands in a drug deal, then bought a coffee — and the barista still takes it without a second thought. Cash forgets. That forgetting is fungibility: every unit is worth exactly every other unit, and nobody audits its past. A public blockchain remembers everything. Every coin drags a permanent, auditable history behind it, and firms run taint analysis and chain analysis across it. Back in 2019 users discovered that some exchanges flagged or even froze Bitcoin that had passed through a CoinJoin, treating it as "tainted." The moment coins can be graded clean or dirty, they stop being interchangeable — and a blacklisted coin is worth less than a fresh one.

But the very property that protects an ordinary user — unlinkability between sender and receiver — is the same property a money launderer wants. That is the whole tension of this guide. There is no privacy feature that helps only the innocent. Shielded transactions, coin mixing, and tumblers are dual-use by construction. So the hard question is not "should ordinary people have privacy" (almost everyone agrees they should) but "can we build privacy that law enforcement can live with" — and after more than a decade we still have no clean answer.

What the law actually asks for

To understand the conflict you have to take the regulator's logic seriously. The global anti-money-laundering (AML) regime rests on knowing who is transacting. Banks must perform KYC (Know Your Customer), monitor for suspicious activity, and file reports. When crypto exchanges became the on/off-ramps into the traditional financial system, regulators extended the same duties to them as "Virtual Asset Service Providers" (VASPs).

The sharpest demand is the FATF Travel Rule (Recommendation 16). The Financial Action Task Force — the inter-governmental body that sets AML standards for roughly 200 jurisdictions — requires that when a VASP sends a virtual-asset transfer above a threshold (commonly USD/EUR 1,000), it must collect and transmit the originator's and beneficiary's identifying information to the receiving VASP, exactly as a bank wire carries sender/recipient data. On a transparent chain this is merely awkward; on a privacy chain it can be impossible without extra machinery bolted on.

  1. Money laundering and terrorist financing are real harms the financial system is legally obligated to fight.
  2. The standard tool is identity: tie every transfer to a known person who can be investigated.
  3. Crypto on/off-ramps touch the regulated system, so they inherit the AML/KYC and Travel-Rule duties.
  4. Strong privacy tools (mixers, shielded pools, privacy coins) deliberately sever the identity link the whole regime depends on.
  5. Therefore regulators treat anonymity-enhancing technology as a red flag — and sometimes as something to ban outright.

Tornado Cash: the case that set everything on fire

On 8 August 2022 the US Treasury's Office of Foreign Assets Control (OFAC) did something unprecedented: it sanctioned not a person or a company but software. It added Tornado Cash — a set of immutable Ethereum mixer smart contracts — to the SDN sanctions list, making it illegal for US persons to interact with those addresses. OFAC cited more than $7 billion laundered through the protocol since 2019, including over $455 million stolen by North Korea's Lazarus Group in the Ronin bridge hack and washed through the pool.

That raised a question nobody had a clean answer to: can you sanction a smart contract? A bank can comply with a sanction; an autonomous, ownerless contract cannot be told to stop. Donors to a public-goods fund, Ukrainians moving money out of a war zone, and people who simply wanted financial privacy were now potentially transacting with a sanctioned entity. The reaction split the industry down the middle.

  1. Aug 2022 — OFAC sanctions the Tornado Cash contracts; Circle freezes USDC sitting in them; GitHub removes repositories and developer accounts.
  2. 2022–2024 — Dutch developer Alexey Pertsev is arrested in the Netherlands and, in May 2024, convicted of money laundering and sentenced to 5 years 4 months — for writing and deploying code.
  3. 2024–2025 — US co-developer Roman Storm is tried in New York; in 2025 a jury convicts him on one count of running an unlicensed money-transmitting business but deadlocks on the money-laundering and sanctions counts.
  4. Nov 2024 — in Van Loon v. Treasury the US Fifth Circuit rules OFAC overstepped: immutable smart contracts are not "property" a foreign national can own, so they could not lawfully be designated.
  5. Mar 2025 — OFAC formally removes Tornado Cash from the sanctions list — even as the criminal cases against its developers grind on.

Middle path 1: viewing keys and selective disclosure

If the conflict is framed as "all-public versus all-private," maybe the escape is controlled disclosure: keep transactions private by default, but let the owner reveal exactly what they choose, to exactly whom they choose. Zcash builds this in. Spending authority and viewing authority are different keys: your spending key can move funds, while a viewing key can only read them.

# Zcash: a viewing key reveals, it does not spend
# spending key         -> can SPEND and SEE your shielded notes (keep secret!)
# full viewing key     -> can SEE incoming + outgoing, CANNOT spend
# incoming viewing key -> can only SEE notes sent TO you

# Give an auditor read-only access to ONE shielded address:
$ zcash-cli z_exportviewingkey "zs1...myaddr"     # -> "zxviews1...key"

# The auditor imports it (the trailing 'no' = do NOT treat as spendable):
$ zcash-cli z_importviewingkey "zxviews1...key" no
$ zcash-cli z_listreceivedbyaddress "zs1...myaddr"
#   -> amounts, memos, timestamps ... but NO ability to move a single coin
A Zcash viewing key lets an auditor read your shielded history with zero power to spend it.

This is selective disclosure: you can hand a tax authority or auditor an incoming viewing key for one account and one year — proving your income and balances — without surrendering spend authority and without making the data public to the whole world. More advanced versions wrap a zero-knowledge proof around it, so you reveal only a predicate ("this account paid more than $10,000 of tax in 2024") rather than the full transaction graph.

Middle path 2: proof of innocence and privacy pools

The most promising idea turns the usual goal inside out. A mixer normally proves nothing about where your coins came from. What if instead you could prove, in zero knowledge, that your coins came from a clean source — without revealing which deposit is yours? That is proof of innocence, formalized in the 2023 paper Blockchain Privacy and Regulatory Compliance: Towards a Practical Equilibrium by Buterin, Illum, Nadler, Schär, and Soleimani, and shipped as Privacy Pools.

The mechanism is an association set. A standard mixer proves your withdrawal note is in the Merkle tree of all deposits. A privacy pool additionally lets you prove membership in a subset you choose — an association set that, say, excludes every deposit known to be stolen funds. You reveal which set you are associated with, but not which leaf you are. Honest users gather into association sets that exclude the Lazarus Group's deposits; a launderer simply cannot build that proof, because their coins are in no clean set. The community self-separates, with no central gatekeeper deciding for everyone.

// Privacy Pool withdrawal -- the zero-knowledge statement (Circom-style sketch)
//
// PUBLIC inputs (everyone sees these on-chain):
//   depositsRoot     -- Merkle root of ALL deposits in the pool
//   associationRoot  -- Merkle root of a chosen SUBSET (your association set)
//   nullifierHash    -- = Hash(nullifier), revealed to block double-spends
//   recipient        -- where the withdrawn funds are sent
//
// PRIVATE inputs (only the prover knows these):
//   secret, nullifier  -- your note's secrets
//   pathFull[]         -- Merkle path proving membership in depositsRoot
//   pathAssoc[]        -- Merkle path proving membership in associationRoot

commitment := Hash(nullifier, secret)
assert MerkleVerify(commitment, pathFull,  depositsRoot)     // I really deposited
assert MerkleVerify(commitment, pathAssoc, associationRoot)  // ...into a CLEAN set
assert nullifierHash == Hash(nullifier)                      // can't withdraw twice
// 'recipient' is constrained into the proof so a front-runner can't re-target it
A Privacy Pools withdrawal proves your note is in the pool AND in a chosen 'clean' association set — without revealing which note is yours.

Crucially the nullifier still prevents double-withdrawal, and the proof is non-interactive, so anyone can verify it on-chain. The honest user gets privacy within the clean set; the regulator gets cryptographic assurance the funds are not from a blacklisted source. Neither side has to trust the other — only the math.

Why this stays unsolved

Step back and the tension turns out to be structural, not a bug waiting to be patched. Every proposed equilibrium trades along the same axes, and improving one almost always worsens another:

  1. Privacy vs traceability — perfect privacy protects the activist and the launderer with the same key; perfect traceability protects the investigator and the surveillance state with the same key.
  2. Fungibility vs blacklisting — to keep coins interchangeable you must stop grading them; to enforce sanctions you must grade them.
  3. Trustlessness vs enforceability — ownerless code can't answer a subpoena, and code that can answer one has an owner who can be coerced or corrupted.
  4. Who decides "legitimate"? — selective disclosure and association sets only move the conflict from cryptography to whoever defines the predicate or the set.

The honest conclusion: this is a genuinely open problem, not a solved one merely waiting for adoption. The technology has advanced faster than the law or the social consensus around it. Zero-knowledge gives us new dials — prove a property without the data, prove innocence without identity, disclose selectively rather than totally — and over the binary of "fully public or fully dark" these are real progress. But they relocate the value judgments; they do not eliminate them. Someone still has to decide what counts as clean, who may demand a disclosure, and how much privacy a free society owes its citizens by default.