Can Zero-Knowledge Proofs achieve Layer 2 privacy?
Matter Labs announced the launching of the first EVM-compatible ZK Rollup on public testnet. This is a significant step towards scalability on Ethereum because it unlocks the possibility to build DeFi (Autonomous Agents) on ZK powered rollups.
This article is the follow up of "DeFi on Bitcoin and private ZK Proofs", where we'll explore the missing link between zero-knowledge proofs (ZKP) and Layer 2 scalability, and then we'll try to understand what else we need to achieve privacy.
Most ZKP articles start with the typical example of Alice holding some valuable secret information and proving to Bob that she knows the secret without revealing the actual data. Then, technical articles discuss polynomials, elliptic curve pairings, finite fields, trusted setups, etc. This article will stay on a higher level and focus on how ZKP can be applied to Layer 2 networks.
How do you go from Alice's secret to blockchain scalability?
It is very rare to find an answer to this question, which is, after all, very relevant, and the main reason why so much effort was invested in ZKP research.
Note: I suggest that the reader familiar with ZKP take a moment to think about this, and then compare notes at the end of the section.
To answer the question, we'll analyse a typical Layer 2 network design that batches transactions and uses ZKP to reduce the computation performed on the main chain.
The Layer 2 nodes receive signed transactions from users, process them in a batch and calculate the state after the batch. Instead of just publishing the result, these nodes will calculate a ZKP that proves they indeed possess a set of signed user transactions that advance the state to the new valid value.
The ZKP can only be generated if the prover has used transactions authorised by end-users as an input to the calculation. The prover can keep the transactions themselves secret.
To put it differently, the proving Layer 2 node (Alice from the example) has received a set of valid (signed) transactions that update some balances. She then computes a proof that she indeed "knows" these transactions. This ZKP convinces any verifier (like Bob) that the resulting state is correct without the need to see the transactions. If Alice didn't use those valid transactions as inputs, she wouldn't have been able to create the proof.
The proof is submitted to the main chain together with the state changes. The smart contract then verifies it (without seeing the transactions) and records the advance in the state. Verification of the proof is thus equivalent to executing the actual transactions and calculating the resulting output state.
This approach achieves scalability if the proof is "succinct", making it cheaper to check the proof generated for a batch of transactions than to execute each transaction.
The solution described above can achieve some privacy since user transactions are not published to the public Layer 1 chain. Still, the transactions themselves are not private during processing by the Layer 2 nodes, and the state is public and visible by everyone.
Can we achieve better privacy?
In the previous article, we tried to build a DeFi application (or Autonomous Agent) on a "verify-only" network, and it turned out we couldn't make it scalable.
We will now attempt to build a fully privacy-preserving Layer 2 that supports DeFi.
Reminder: Most commonly referred to as a "smart contract", an "Autonomous Agent" (AA) is a program that runs on a decentralised platform that can accumulate and control any on-ledger value and, most importantly, has the power to dispense this value based only on coded predictable logic.
Note: For the rest of this exercise, we will assume a viable ZK VM implementation that can generate proofs for any program is available. Without it, it's impossible to execute the code of the AA.
On a high level, the problem we want to solve is to keep the user transactions and the resulting state private. This means it has to be visible only to the users themselves and to no one else.
It turns out that this task is very similar to building an AA on a verify-only network. Please spend a few minutes quickly reading our attempt at doing that.
Now let's apply the same principle using the available ZK VM.
The setup is that we have the code for an AA (let's say a DEX) running on the ZK VM, and there is a Layer 2 network of nodes.
The linear approach
The most straightforward way to achieve privacy is for every user to execute the AA code and build a zero-knowledge proof on their own computer or phone. The proof is as good as the actual transaction, which can remain private to the user.
Readers of the previous article will remember that we described this exact mechanism and showed that it couldn't scale because users must coordinate.
In our case, to build a ZKP, a user must know the exact state of the AA as it was after the previous user.
Besides the non-scalable coordination problem, there is more complexity in sharing the state after each computation because that also needs to remain private.
It is safe to conclude that the linear approach is a dead-end.
The batch approach
We described this approach in the first part of the article when designing for scalability. We concluded that it couldn't achieve satisfactory privacy because Layer 2 node operators have access to user transactions because they need to process them.
We can improve it by introducing application-specific operators to avoid everyone seeing all transactions.
That is clearly better since the number of parties that see the transactions is lower but still very far from ideal.
On top of that, for data-availability reasons, the account balances have to be published for everyone to see.
The batch approach is also a dead-end unless we find a way to prevent the Layer 2 nodes from reading user transactions.
One way to achieve privacy is through encryption. End users could submit encrypted transactions, and the nodes should only be able to calculate the ZKP on these transactions and nothing else.
If such a technical solution existed, along with a viable ZK VM, it would solve both privacy and scalability.
This would work as follows: users create encrypted transactions to interact with the AA. They send these transactions to Layer 2 nodes who batch them, process them in the encrypted form, and finally generate the new state and the ZKP. Once submitted to the Layer 1, the rollup smart contract will verify the proof and update the state without the need to see the transactions.
The reader might notice that this is still not enough to achieve complete privacy since the state (balances of the accounts) is visible to everyone, as it is published to the Layer 1, even though the nodes cannot decrypt the transactions.
The state must also be encrypted when submitted to the Layer 1 network to solve this. It should be processed together with the encrypted transactions but not visible otherwise.
The good news is that hardware-based confidential computing can help with all these problems, and this is the direction that the project I'm working on, Obscuro, is heading towards. You can read the whitepaper here.
Besides processing encrypted transactions, there are other significant challenges to overcome to build a decentralised solution that achieves privacy and safety. Of course, the most important challenge is that no viable ZK VM is available yet. Obscuro will rely on crypto-economic incentives to achieve the safety guarantee in the first version, similar to Optimistic rollups like Optimism and Arbitrum.
This article started by clarifying how zero-knowledge proofs can be used to achieve Layer 2 scalability. Then we used the techniques from "DeFi on Bitcoin" to discover the missing link needed to achieve privacy on Layer 2s.
The answer to the question from the title is that ZKP Layer 2 solutions can achieve privacy only when combined with a solution like Obscuro.