The 2021 DeFi incidents that motivated this article raised questions about financial privacy and the limits of tracing public-chain activity. This article looks at the underlying zero-knowledge concepts and their limitations.

Flash loans and creating imbalances certainly deserve their own blog post. But this week we will take a closer look at tornado.cash.

So what is it?

Comic in which “explain it like I’m five” is taken literally, prompting concern about the questioner’s missing parents.

ELI5: Tornado.cash

A room full of money

Money Room

Imagine we have a room with a single door and a guard in front of the room. Anyone is allowed to walk up to the guard and give him a 100$ note. The guard takes the note and puts it inside the locked room. Then he asks the person giving the money to think of a very large number. Instead of giving him the number directly, the person computes the hash of the number, writes it down and hands it to the guard. The paper with the hash is thrown into a big bowl.

No imagine over time hundreds or thousands of people do the same. The room will then have thousands of 100$ notes and the guard will have a bowl with thousands of papers containing the hashes.

If someone wants his 100$ back, he can walk up to the guard. The easy solution would just be showing the random number from before to the guard. The guard can compute the hash and check all papers for any such hash. If he finds one, he will destroy that paper and give you 100$ back.

But if we do it like this, what if the guard is malicious? He could secretly track which exact 100$ belongs to which random number. Then we would receive exactly the same 100$ note as we put in the room. A pretty pointless transaction, achieving nothing.

An experiment with balls

Now what if we could prove to the guard that we know a secret number that hashes to a commitment inside the bowl without revealing the actual number? Well we can do that with a Zero-knowledge Proof. Zero-knowledge Proofs are complicated, but an easy way to conceptualize them is the following example (thank you to Lucas for giving me this example at ETH.Berlin):

Imagine you are blind and I give you two balls that feel exactly the same way and are the same weight. Now I tell you those two balls have different colors. There's no one else nearby. How can you find out if I'm telling the truth?

You can put one ball in each hand, show them to me. Now you put them behind your back and you either swap the balls between both hands, or you don't. Then you show them to me and ask me: 'Did I swap the balls, yes or no?'. Now if both balls are the same color, I could try to guess it. I'll have a 50% chance of guessing correctly. That's why you do this 15 times in a row. If I answered correctly every time, an always-guessing prover passes with probability 1/2^15, about 0.003%, assuming independent fair hidden swaps. This is a false-acceptance probability, not a 99.997% posterior certainty without further assumptions. If not, I must have randomly guessed correctly 15 times, pretty unlikely.

I have now proven to you that the balls are of different color without ever revealing the actual colors, hence the name 'zero knowledge' proof. You have no idea if the balls are green, black, orange or something else.

Getting your money back

The guard needs two separate checks: a proof that the person knows a valid secret associated with some commitment in the bowl, and a public nullifier tied to that secret. The proof establishes the relationship without identifying the commitment. Recording the nullifier prevents the same deposit from being spent again, even if someone presents different proof bytes.

The nullifier is not a signature or a unique encoding of the proof. And hiding the commitment-to-withdrawal link in this model does not hide all surrounding timing, network or transaction metadata.

From Zero-knowledge to zk-SNARKs

Non-interactive zero-knowledge systems let the prover send a proof that the verifier can check without a live challenge-response conversation. A zk-SNARK is a succinct non-interactive argument of knowledge, with security and setup assumptions that depend on the construction. It is not generally a matter of performing a fixed number of hashes or pre-answering a list of questions.

At a high level, a computation can be expressed as arithmetic constraints. The prover uses a private witness that satisfies those constraints, while the verifier checks a compact proof against the public inputs. Polynomial relations and commitments are tools used in many constructions; “finding a lowest-degree polynomial” is not the general rule. The details are subtle, and Vitalik’s polynomial introduction is still a useful next read.

To understand this properly, read the post. I'll link it once again: https://vitalik.ca/general/2021/01/26/snarks.html.

From theory into practice: tornado.cash

tornado.cash

The original Classic interface exposed separate fixed-denomination pools for several assets. The screenshot and asset list are historical. A deposit commitment represented an eligible note; the count of commitments is not a count of distinct people, and one person can control several notes.

Zero knowledge can hide which eligible commitment a valid proof refers to. It does not by itself prevent inferences from timing, amounts, network information or other transaction relationships. A large displayed set is therefore not a quantified anonymity guarantee.

The Classic design used commitments, a Merkle tree and a proof verifier, with a public nullifier to reject repeat spends. Those are separate components with separate assumptions.

Governance for tornado.cash

Plans to add governance to the protocol are in the planning. This will include its own TORN token which will used as treasury (55%), paid out to the team and investors (30%), airdropped to early users of the service (5%) as well as used for a new concept of anonymity mining (10%).

Since the service is only secure when a lot of people are using it, the idea is to incentive people further to leave funds in the contracts and pay them TORN for it. That proposal’s privacy goals do not establish complete anonymity for surrounding user activity.

Deanonymzing tornado.cash

People have already started to try and de-anonymize users. This is possible by three metrics:

  1. time of the day of sending the deposit/withdrawal
  2. gas price distribution
  3. transaction graph analysis

Timing, fee choices and transaction relationships can reveal correlations. Their strength depends on the data and assumptions, so neither “extremely easy to identify” nor guaranteed prevention is justified here. The old random-time, random-fee and fresh-address recipe did not establish anonymity and has been removed.

The future of tornado.cash

It's not clear at this point where the future is headed for tornado.cash. The TORN token that launched a few days ago already increased significantly, but what the treasury funds will be used for is not clear at this point. Some people have raised concerns regarding the necessity for a service like tornado.cash to require a token.

What do you think of tornado.cash? Let me know in the comments.