Wei Dai
February 16th, 2022

This post is an exposition on the landscape of privacy in the context of public blockchains (a.k.a. decentralized ledgers, crypto, and Web3). The first part touches on why privacy is a key hurdle to wide-scale adoption and what different aspects of privacy are. The second part surveys three different approaches to privacy: via zero-knowledge proofs, aiming for anonymity only, and via a new abstraction called MOCCAs.

Part I: Why and What is privacy for public blockchains?

Privacy—the final hurdle to wide-scale adoption

The modern financial system works well enough that we do not have to worry about the security or privacy of our day-to-day transactions. When you make a purchase at a grocery store, a rent payment via check, or take out a short-term loan at your bank, you don’t have to worry about your transactions being publicly scrutinized by non-relevant parties. In modern banking and credit card networks, transaction details (mostly) stay within relevant financial intermediaries and authorities. Users (ideally) don’t have to worry about their sensitive information being leaked to the public, and authorities can (mostly) track illicit activities.

Unfortunately, the same cannot be said for transactions conducted on popular blockchains today. Although blockchain technologies promise to decentralize and democratize the current financial ecosystem, most systems fail to meet even the most basic level of privacy that we have come to expect. Your pizza purchase could be permanently recorded, and all of your transactions could be easily and publicly accessed on Etherscan. There are privacy-focused projects out there, but they are currently underutilized due to the non-parity in terms of features and ease of use. This marks privacy as one of the key obstacles towards the large-scale adoption of blockchain technologies.

Privacy in the public blockchain setting is not an all-or-nothing feature. Rather, it is a complex and multidimensional question that requires care when navigating. Let us first dive into what types of privacy are relevant to blockchain applications.

Feature axes of privacy

Axis A: anonymity and confidentiality. Broadly speaking, there are two types of privacy for financial transactions: anonymity and confidentiality. When a non-profit organization receives an anonymous donation, they gain no information on the donor (anonymity) but know the donation amount received. When you are checking out at a drug store, your purchase is confidential–the person behind you does not know which drugs you might be prescribed and how much they cost, but they know that you are making a purchase.

Anonymity Can people know that I am the originator of a transaction?
Confidentiality Can people know the contents of my transaction?

Axis B: on-chain v.s. intermediated applications. One of the foundational theses of blockchains and cryptocurrencies is the ability to conduct financial transactions without trusted intermediaries. Following the footsteps of Bitcoin, almost all cryptocurrencies allow direct payments without intermediaries. Smart-contract platforms such as Ethereum go a step further and enable financial transactions beyond payments to be conducted without intermediaries, such as trading and lending. In this article, we use the term on-chain to describe functionalities and applications, such as payments, trading, lending, that a user could use directly as an operator of a consensus node. (A word of caution: users often do not run their own consensus nodes. For example, third-party RPC endpoint providers for Web3 wallets should be seen as intermediaries in practice.) Some examples of on-chain applications include payments on Bitcoin and Zcash, trades on Uniswap, and lending on Compound.

Unfortunately, intermediaries are still omnipresent in the ecosystem. Exchanges such as Coinbase are intermediaries of the services that they provide—users need to deposit assets to these exchanges to trade. Even some “decentralized” protocols rely on centrally-operated intermediaries. For example, dYdX and DiversiFi both have central exchange operators. This is unlike their on-chain counterparts such as Uniswap, where no interaction with servers outside the consensus network is needed. What dYdX and DiversiFi have over Coinbase is the elimination of trust required for the security of funds. Users instead need to trust cryptography and code, in particular STARKs, for the security of their funds. Payment channel networks (e.g. Lightning network) and roll-ups (e.g. Arbitrum, Optimism, Aztec, and Scroll) are two other categories of intermediated applications. Although most intermediaries are centralized at the moment, they could be engineered to be decentralized, which is especially desirable for roll-ups since they compete directly with side-chains. For example, zk-roll-ups could have a network of roll-up sequencers with some form of consensus mechanism, effectively making the roll-up a chain.

The above two categorizations of blockchain applications provide us with an additional axis to consider for privacy: on-chain privacy vs. privacy from intermediaries.

On-chain privacy Privacy from intermediaries
Is my information being permanently recorded on-chain? Is my information disclosed to an entity (think your bank, Coinbase, and swap aggregator such as 1inch) who I entrust to act on my behalf?

Putting the axes together. We obtain four notions of privacy for blockchain applications by combining the two privacy feature axes: between anonymity and confidentiality, as well as on-chain versus intermediated. Below is a table listing one privacy question in each category.

Table demonstrating example questions for each privacy category.
On-chain From intermediaries
Anonymity Are my trades on Uniswap linkable to other activities that I do on-chain, such as NFT trading? Can exchange operators (Coinbase, dYdX, etc.) block trades based on who is trading?
Confidentiality Is my total on-chain trading amount public information? Can exchange operators (Coinbase, dYdX, etc.) see and record the trade details?

Of course, for any of the above questions, the answer is that your information is being permanently recorded on-chain and transmitted to intermediaries. With this understanding, we are now able to dive into what privacy is possible with on-chain and intermediated blockchain applications.

Disclaimer 1: Although most applications claim to be decentralized, development of and access to the on-chain smart contracts are often very centralized. For example, one coding bug can often lead to multi-million dollar exploits, and DEX trades often go through a shrinking number of mining pools that exploit users’ transactions for their own profit (which is called MEV, or Miner Extracted Value). We will not further elaborate on these issues here, as our focus is on the issue of privacy.

Disclaimer 2: One important dimension to privacy that we will not touch on deeper is the interplay between privacy, regulation, and compliance. Financial intermediaries in many circumstances have legal obligations to not only know their customers (KYC) but also record and report certain financial transactions. Anti money laundering (AML) is one of the main objectives of this. For example, transparency of cryptocurrencies has recently helped the Department of Justice in recovering $3.6B worth of funds stolen from the 2016 Bitfinex hack. We will not touch on the issue of regulation and compliance to instead focus solely on the issue of privacy from a technical and theoretical level in this article.

Part II: How to build privacy-preserving blockchain applications

Let us first take a look at payments, as they are mostly solved and do not require intermediaries. Zcash and Monero are two large-cap coins that provide both anonymity and confidentiality. They rely on zero-knowledge proofs and ring signatures respectively to provide different levels of anonymity and confidentiality. We also have other methods of building private payments that are more efficient but require interaction like Mimblewimble, or without an ever-expanding UTXO set such as Quisquis and Anonymous Zether.

Beyond payments, however, the landscape is way less clear. For example, one of the most successful applications beyond payments is in the area of Decentralized Finance (DeFi). We still don’t know or have widely established privacy techniques for DeFi applications.

To reason about this holistically, we need to first have a good theoretical model of talking about on-chain applications. General on-chain applications can be modeled as iterative computation, specified by a transition function f, which computes (st′, output) ← f(st, input) for each starting state st and input.

Users can construct transactions as inputs before submitting them to consensus nodes for processing. To preserve users’ privacy during this process, we need to carry out the computation without revealing users’ identities and inputs. There are three approaches: (1) push the computation off-chain, (2) keep computation transparent but hide identities of originators, and (3) do homomorphic computation over encrypted inputs with transparent outputs.

Privacy for off-chain computation via ZKPs

Zero-knowledge proofs (ZKPs) were a crucial development in the field of theoretical computer science and cryptography in the late 1980s (Chapter 1 of these lecture notes gives a good survey). The particular form of zero-knowledge proof (ZKP) used in the blockchain setting is typically academically referred to as a NIZK, or Non-Interactive Zero-Knowledge. When proofs are succinct, they are usually called SNARGs (or SNARKs), or Succinct Non-interactive Argument (of Knowledge). Additional features of interest are transparency (STARKs) and universality, which allow the proof system to be used for multiple circuits without a trusted setup or with one universal trusted setup.

The core application of ZKPs to public blockchains is the ability to perform verifiable, off-chain computation. Typically, the prover is an end-user (in case of ZK application platforms) or an intermediary (ZK roll-ups), while the verifier is the chain, i.e. the validator set. A straightforward way to use ZKPs for general computation is to prove the correctness of state transitions directly. To elaborate, the user proves off-chain that for a particular on-chain state st, the user has an input that results in a new state st with some output when applied to staring state st. The consensus nodes then verify the validity of proposed state transitions before overwriting the old state. This is the approach taken by ZK application platforms such as Mina Snapps and Aleo, both inspired by the academic work of Zexe.

The crucial difference between the transparent on-chain applications and the above architecture is that, naively, an update (st′, output, π) is only valid against the application state st used to generate the update by the user. This leads to “race conditions” if multiple users interact with the same application without coordination. To elaborate, suppose there are two valid transactions constructed against the same on-chain state st0, updating it to st1 and st2, respectively. When the first transaction gets recorded on-chain, the on-chain state is updated to st1. As a result, the second transaction is then being validated using the new state st1, not st0, likely rendering it invalid.

It is worth noting that one could get around this race condition either by segmenting the application state into independent parts or eliminating shared on-chain states completely. This makes these ZK-application platforms a great fit for select applications that do not require shared states between users (e.g. ZKPass), but not so much for the majority of on-chain applications that require these shared states, especially on-chain DeFi protocols like constant-function market makers (CFMMs). For these applications, using ZKPs for the whole application state transition is a bit of a “one step forward and one step back” solution due to the problem of race conditions. There is a work-around however, which is to add an intermediary or exchange operator, making the application state private to the operator instead of shared between all users. Unfortunately, there is no known way of hiding trade information from these intermediaries without adopting other solutions discussed later in this article. To summarize, exchanges on ZK applications platforms such as Aleo and Mina achieve the following privacy properties.

Table detailing the privacy features of exchanges that can be built on ZK-application platforms such as Mina and Aleo.
On-chain From intermediaries
Anonymity Yes Possibly
Confidentiality Yes No

Anonymity for transparent on-chain computation

Adding confidentiality to on-chain applications is hard. What if we don’t attempt to provide confidentiality but only aim to provide anonymity? This is already possible using existing tools: using tumblers and mixers such as CoinJoin and Tornado Cash, one can fund new pseudo-anonymous addresses to gain anonymity. Unfortunately, the opt-in nature of these tools means that they are utilized more so by malicious users than legitimate ones. For example, CoinJoin was used by the Colonial Pipeline ransomware and Tornado Cash is often used to fund anonymous addresses to mount DeFi hacks.

There are two projects that try to build anonymity by default onto transparent smart-contract platforms. The first is Aztec Connect, which is an up-and-coming “zkzk-rollup” for Ethereum that offers trade anonymity when trading with a supported layer-one application. The roll-up contract acts on behalf of layer-two users (whose identities are hidden both on-chain and to the roll-up provider) to interact with layer-one DeFi protocols, providing anonymity to these layer-two users.

The second is the academic work of FLAX. Which proposes a redesign of an Ethereum-like smart-contract platform to support built-in anonymity for end-users. At the core, FLAX proposes an anonymous version of the ERC20 token standard that allows anonymous and atomic delegation of token use. Interestingly, there is no new cryptography required to realize these “anonymous ERC20s”. One could use the same techniques from any of the previously mentioned private payment schemes, such as Zcash, Monero, or Zether inside the token contract.

Below is a table outlining the privacy features of the solutions discussed above. We omit the intermediary column here since there are no intermediaries involved–except for Aztec Connect–which potentially provides anonymity from the intermediaries (roll-up providers), depending on the level of decentralization and the exact behavior of these providers.

Table detailing the privacy features of tumblers, mixers, Aztec Connect and FLAX.
On-chain
Anonymity Yes (opt-in in case of tumblers and mixers, default in case of Aztec Connect and FLAX)
Confidentiality No

Privacy for on-chain computation via MOCCAs

What if we can encrypt the on-chain application state and user input but still be able to do computation on them, and even derive public unencrypted output information? Let us call such an ideal functionality a Magical On-chain Confidential Computing Apparatus (MOCCA).

Intuitively, MOCCAs offer the best-possible privacy for the state transition function f. They can be computed on-chain given necessary encrypted input, and the computation should yield both an encrypted and updated state as well as some transparent output value. Specifically, program states and inputs are encrypted to the chain such that the only operation consensus can carry out is computing the state transitions, meaning only application-intended information is ever decrypted and made transparent. Assume for a moment that we have such a magic box, then it is easy to replicate the functionality of on-chain applications while offering privacy. As application designers can design their applications to release only the relevant information as transparent output, such as spot prices or reserve amounts.

There are two approaches to building MOCCAs, via trusted hardware and via cryptography. In either case, we could hope to achieve privacy-preserving decentralized applications without intermediaries with the following properties.

Table detailing the privacy features of applications from MOCCAs.
On-chain
Anonymity Yes
Confidentiality Yes (exact privacy depends on application design)

MOCCAs from Trusted Hardware. The first solution is to utilize trusted execution environments, specifically Intel SGX. This was first described in the academic work of Ekiden and is the approach taken by Oasis and Secret Network. There are already applications running on these platforms such as Secret Swap. However, Intel SGX is known to be buggy.

MOCCAs from Cryptography. Can we build Turing-complete MOCCAs using only cryptography? It turns out the answer is yes, and cryptographers have already discovered all the individual pieces of the puzzle.

The first piece of the puzzle is threshold key generation and resharing. We know how to generate and manage Shamir secret-shares in a dynamic consensus set as nodes join and leave, even for large consensus sets. These allow any number “t” out of “n” consensus nodes to act as if they are together the secret-key holder of a public-key encryption scheme or signature scheme. These advances were put forth for the prevention of front-running (e.g. Ferveo) and construction of succinct light clients (e.g. chain-key cryptography), respectively.

Additive MOCCAs and exchanges. The second piece of the puzzle is threshold homomorphic encryption. Well-known and deployed public-key encryption schemes such as ElGamal and Paillier are both additively homomorphic and support Shamir secret shares as keys. Using them, we can build MOCCAs that support addition.

It turns out, we can already build on-chain exchanges (in particular, constant-function market makers, or CFMMs) using MOCCAs that only support addition. This is the genius observation of Penumbra, which utilizes additive homomorphic properties of ElGamal encryption to aggregate trades and threshold decryption to reveal the net trade amounts of a batch. This provides confidentiality of trades in the form of differential privacy.

Turing-complete MOCCAs from Threshold FHE. To realize MOCCAs for more general computation, we of course need fully homomorphic encryption (FHE). Since the first constructions of FHE by Genry’s construction in 2009, the efficiency of FHE schemes has steadily improved both theoretically and practically over the past decade and is likely to continue to improve (e.g. by tapping into hardware acceleration). However, FHE by itself is not the entire solution, as holding the decryption key still empowers any single party to all the information ever posted to chain under the corresponding encryption key. This is where previous efforts on deploying FHE in the blockchain setting such as NuCypher and smartFHE fall short of providing privacy-preserving on-chain applications.

Fortunately, we know of ways of constructing FHE schemes with threshold decryption where the decryption keys are Shamir secret-shares. Specifically, each consensus node can carry out computation on encrypted program state and input independently to derive encrypted new program state and encrypted output. Crucially, to release the transparent output, consensus nodes can threshold decrypt the encrypted output with one round of communication. The threshold property here guarantees that, as long as under threshold number of validators are malicious (in any epoch), only the intended information (i.e. transparent outputs) are ever released, and inputs and program states are never decrypted.

Combining the above, we can build a MOCCA for general Turing-complete state transition functions relying purely on cryptography, modulo numerous technical details of course. (This exact usage of threshold FHE in the blockchain setting has not been stated elsewhere to my knowledge. I would appreciate pointers to prior works that I have missed.)

Summary

Privacy is one of the final roadblocks towards the wide-scale adoption of public blockchains. Privacy can be divided into two feature axes: anonymity vs confidentiality and on-chain privacy vs privacy from intermediaries. There are three categories of approaches to achieve privacy.

First, using zero-knowledge (ZK) proofs (in particular STARKs or universal SNARKs), we can achieve both on-chain anonymity and on-chain confidentiality by moving computation off-chain to intermediaries, thereby sacrificing privacy from intermediaries (e.g. Mina Snapps and Aleo).

Second, without relying on intermediaries, we can add anonymity (without confidentiality) to existing on-chain application ecosystems without major changes to application design (e.g. CoinJoin, Tornado Cash, Aztec Connect, and FLAX).

Finally, this article proposes an abstraction called a MOCCA, or Magical On-Chain Confidential Computing Apparatus, which can compute on encrypted data and release transparent outputs. MOCCAs can be used to build generic on-chain anonymous and confidential applications without intermediaries. MOCCAs can be built from trusted execution environments (Oasis and Secret Network) or relying on “threshold cryptography for blockchains”. Specifically, threshold additively homomorphic encryption (ElGamal) can be used to build additive MOCCAs to realize anonymous and confidential (differentially private) on-chain exchanges (Penumbra); threshold fully homomorphic encryption (FHE) can be used to build general-purpose MOCCAs to realize any privacy-preserving on-chain application (proposed in this post).

The ZK approach is currently receiving the most amount of attention in the industry. However, I argue that more attention should go towards approaches two and three. Adding easy-to-use anonymity to the current smart-contract architecture serves as a good mid-point between privacy and functionality (someone should build FLAX!). Moreover, we should foster long-term research and development efforts on threshold FHE to support general privacy-preserving applications. These approaches are not exclusive either, we can have application platforms that support all three types of computation: transparent on-chain, private off-chain (ZKPs), and “opaque” on-chain (MOCCAs). Please reach out to me if you are interested in any of the above.

Acknowledgments

Many thanks to Alex Evans and Guillermo Angeris for their helpful editorial comments. Credits to Adrian Brink for coining the term “opaque” to describe on-chain computation on encrypted data.