The Tornado.Cash Revolution: Taking Back Control of Your Financial Privacy
Tags: security, blockchain, computerscience
Published: 2023-05-05 19:23:02

A lot of buzz is happening around Tornado.Cash after the smart contract of the crypto mixer is blacklisted by the US Authorities.
In this article let's make a technical breakdown of the working of Tornado.Cash.

Tornado.Cash according to the whitepaper:

> Tornado.Cash implements an Ethereum zero-knowledge privacy solution: a smart contract that accepts
transactions in Ether (in future also in ERC-20 tokens) so that the amount can be later withdrawn with no reference to the original transaction.

Before understanding what Tornado.Cash is let's first understand what a crypto mixer is.

> A crypto mixer is a tool used to make cryptocurrency transactions more anonymous by "mixing" them with other users' cryptocurrency.

Mixing in the context of cryptocurrency refers to the process of combining multiple cryptocurrency transactions into one, in order to obscure the original source and destination of the cryptocurrency.

![mixer image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gvxkycdozlljt00x9qq8.png)

If you look at the diagram, there are different ethereum addresses that are transferring exactly 1 ETH to the smart contract address of the Tornado.Cash and withdrawer can withdraw the 1 ETH deposited to a new ethereym address so that link between depositer and withdrawer is masked. Since all ethereum deposits are of the same amount, the privacy is even more improved.

This is a very high level overview

Now let's get into **Technical details**.
This involves 3 steps
**1.** Deposit Ether(or other ERC-20 token)
**2.** Mixing and Smart Contract Functionality.
**3.** Withdraw

**DEPOSIT**
while depositing the ether to the smart contract, the depositer should generate a secret(r) and a nullifier(k) both re 256 bits long and a commitment(c) is generated by hashing both nullfier and the secret using pedersen hashing algorithm.

`c = pedersen(r||k)`

Now we have the commitment and 1 ETH and the depositer is ready to send the data and ether to the Tornado.Cash smart contract.
_It is advised to use TOR for enhaced privacy._
Deposit is succesfully completed.

**Smart Contract Functionality**
Smart contract implements a data structure called merkle tree.
If your not familiar with merkle trees then [study here](https://blog.codeminer42.com/zero-knowledge-proofs-and-merkle-trees-an-overview-before-diving-into-it/).
The height of merkle tree in the smart contract is 20,for now lets keep the height of the tree as 4 so there would be 8 leaves.
and each level of the tree has a level defualt, which are random BigNumbers.

```
uint256[10] levelDefaults = [
        23183772226880328093887215408966704399401918833188238128725944610428185466379,
        24000819369602093814416139508614852491908395579435466932859056804037806454973,
        90767735163385213280029221395007952082767922246267858237072012090673396196740,
        36838446922933702266161394000006956756061899673576454513992013853093276527813
        
    ];
```


![merkle tree](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s47bii2fr0lb6chh7dly.png)


Each leaf of the merkle tree would store a single commitment hash which depositer send and a corresponding merkle root is calculated.

The merkle root is calculated using the commitment and the corresponding level defaults by feeding it into _MIMC hashing algorithm._

The green coloured nodes are the sister nodes(R) which are emitted by the smart contract after successful deposit to reconstruct the merkle root during the withdraw process.

Once the deposit function is successful the merkle root for the given commitment is marked TRUE.

**WITHDRAW**

Withdraw can be done by the depositer itself or any other person who has valid proof to prove that there is some ether on the contract associated with that proof.

To withdraw the Ether the withdrawer should send the required proof.

withdrawer needs to first calculate the nullifierHash, which is the pedersen hash of the nullifier(k).

`nullifierHash = pedersen(k)`

Now the withdrawer has to create a zero-knowlege proof, proving to the smart contract that he owns a certain commitment in the merkle tree without revealing the which commitment it is.
If you are not familiar with zero-knowledge proof check out my profile.

> D = (dp, dv) be the ZK-SNARK proving-verifying key pair created using some trusted setup procedure.

`ZKProof = groth16(k,s,R,Ri*,A)`

> K = nullifier
> s = secret
> R = sister nodes
> Ri* = merkle root
> A = new withdrwal Address

the withdrawer needs to send the ZKProof, and some public variables( nullifierHash, Ri*, A) to the smart contract for verification. 

If the verification is successful the nullifierHash is added to the smart contract mapping and marked true which means the nullifierHash for the corresponding commitment is already spent which prevents double spending.

After successful verification the 1 ETH is transferred to new withdrawl address and some gas fees(f) is deducted.


This is basic understanding of the TornadoCash.