by Mikerah and John Adler
|Mar 28||Public post|
In this edition of the Blockchain Research Newsletter, we will be summarizing and comparing two papers on blockchain privacy solutions, Zexe (Zero Knowledge Execution) and Zether. Both of these papers attempt to tackle different areas of privacy in blockchains that support smart contracts. Zexe builds on top of Zerocash and proposes a new blockchain architecture for supporting privacy-preserving smart contracts. On the other hand, Zether is a solution that can be deployed on account-based smart contract platforms like Ethereum.
Currently, most blockchains lack privacy. In popular blockchains like Bitcoin and Ethereum, anyone with access to the blockchain can see who sends and receives coins and the amounts sent. This allows blockchains to be transparent and anyone can verify the details of any transaction as necessary. However, by studying and tracking long-term usage, a malicious party can link addresses to particular transactions and build profiles of addresses. If this adversary has real world information (e.g., Twitter handles, KYC info), this could potentially link real world identities to pseudonymous addresses. This problem worsens in blockchains supporting stateful smart contracts like Ethereum. Now, we have to deal with data privacy, i.e., hiding an application’s data layer to third parties on the blockchain, and function privacy, i.e., which state transitions functions have been executed.
Zexe is a new blockchain design that can be thought of as an extension to the Zerocash protocol, used in cryptocurrencies like ZCash. It enables both data privacy and function privacy in addition to succinctness. In other words, not only can transactions be generated offline and efficiently verified on-chain, the time needed to verify the transaction is independent of the time needed to do the offline computation to which the prover attests to. It achieves this by introducing a new cryptographic primitive called a Decentralized Private Computation (DPC).
Before we deep dive into Zexe, we will go over the Zerocash protocol upon which Zexe is based on. Then, we will go over the DPC scheme that makes up the core of the Zexe protocol.
Overview of Zerocash Protocol
The Zerocash protocol builds upon the Bitcoin protocol. In addition to Bitcoin, Zerocash adds an additional cryptocurrency, called Zerocoin, which is anonymous. Users can transact using both Bitcoin and Zerocoin or can just transact using Zerocoin. Users can also convert between both currencies. As in Bitcoin, transactions are mined into blocks and appended to a decentralized ledger. Now, Zerocash introduces two types of transactions, mint transactions and pour transactions.
Mint transactions convert a specified amount of bitcoin to zerocoins, using cryptographic commitments, to a new zerocoin address. Cryptographic commitments allow one to commit to a value that is hidden to others with the ability to reveal this value in the future. However, this isn’t sufficient to provide privacy. Here enters pour transactions. Pour transactions provide privacy by using zero-knowledge proofs. Zero-knowledge proofs allows a prover to prove to a verifier a statement such as `f(x) = y` without revealing `x`. In this case, in order to spend zerocoins privately, a user conducts a pour transaction in which various pieces of information are proved in zero-knowledge. Additionally, pour transactions provide functionality in order to convert back to non-anonymous bitcoins.
Overview of Zexe
Zexe, much like the Zerocash protocol, uses a UTXO-style data model. Transactions on the Zexe system consume and produce records, which are analogous to UTXOs. Each record can have birth and death predicates, which allows us to create records that follow rules independent of the usual ones for UTXOs (i.e., sum of outputs must be no greater than sum of inputs for the native coin, inputs all have valid digital signatures).
The birth and death predicates for records can specify interesting rules, which can be used, for example, to create a fixed-supply token. The predicates of a record define the rules under which it is consumed, including requiring recursively that outputs of a transaction that consume this record have the same predicates governing them. In the case of a fixed-supply token, this can take the form of all records that descend from a genesis record (that mints the tokens originally) must satisfy a condition such as: “for a transaction, the sum of the outputs must be no greater than the sum of the inputs for this token.” The token type of these records can be determined by simply tracing each output to its input(s) to find the appropriate unique genesis record.
Transactions in Zexe can consume any number of input records and produce any number of output records, so long as the predicates of each record are satisfied (and the base rules of the protocol are followed, of course). This allows records to potentially interact with each other, should they be designed that way.
Zexe is ledger-agnostic. So long as the underlying implementation of the ledger provides a total ordering of valid transactions, any ledger technology can be used, including a simple blockchain, or a construction like a blockDAG (see: Avalanche).
A DPC scheme consists of the 3 data structures (records, transactions, and a ledger) described above and a set of algorithms. The algorithms consist of a trusted setup that produces public parameters, a key pair generation algorithm for generating addresses, an execution algorithm to consume and create new records and a verification algorithm for verifying the validity of transactions. DPC schemes provide several security guarantees such as execution privacy and correctness.
Delegated DPC schemes allow for light-client support in ZEXE. A special delegation scheme, that is outside the scope of this post, can be used to allow a provider to generate the necessary proofs (which are quite expensive to generate using zero-knowledge protocols!) without compromising the privacy of the sender.
Zether leverages homomorphic encryption to achieve private general computations with an accounts data model, like Zexe’s UTXO data model. Homomorphic encryption allows arithmetic operations to be performed on encrypted data, with the encrypted output of an operation on plaintext data being the same as the output of the operation on the same data but encrypted.
Participation in Zether happens entirely within a separate system that uses ZTH tokens, with a 1:1 peg to ETH. Each user (identified by a public key) within the Zether system has an encrypted ZTH balance.
Joining To join the system, a user deposits Ether to a contract, indicating the public key that will own these funds within the Zether system. This amount is added to the encrypted ZTH balance of that public key, which can be done since ZTH balances are homomorphically encrypted using public keys.
Transacting To make a transaction, e.g., sending funds to another user, the sender simply posts a zero-knowledge proof on-chain that attests to the following conditions:
The amount to send is encrypted properly with both the sender’s and recipient's public keys, and
The amount sent does not make the sender’s balance negative.
These proofs are all posted on-chain, so everyone will know the sender and receiver of transactions, but not the amount sent. Since you can send zero or dust amounts, this potentially allows for a large amount of mixing to be done. The protocol can be extended to use a construction similar to ring signatures to hide the receiver among an anonymity set, but won’t be discussed here.
The final consideration for transactions is front-running. It would be absurdly difficult to verify each proof and update the Zether system’s state for each transfer, so ideally we want to batch transactions. With batching, however, what if a user sends two proofs on-chain that spend the same coin? Each individually is valid, but together constitute a double-spend. The solution is to force a state update for a public key for all outstanding incoming transactions whenever that public key wants to send funds.
Leaving To leave the system, the state of a public key merely needs to be updated as above, then a proof of the encrypted ZTH amount sent on-chain to unlock the same amount of ETH.
Zether and Zexe aim to tackle privacy in blockchain networks in very different ways. As such, they are designed according to different goals. Zether provides a construction of confidential transactions for an account-based blockchain systems. As such, Zether is a layer 2 privacy solution for account-based blockchain systems, whereas Zexe provides a privacy-preserving scripting language on top of a UTXO-based blockchain system. As such, Zexe is a layer 1 privacy solution for UTXO-based blockchain systems. We would also like to note that neither of these solutions tackle privacy at the networking level and are thus susceptible to the usual networking eavesdropping attacks that current blockchains deal with. Since both of these solutions provide privacy at different layers, they both come with different security guarantees. As Zether can be deployed on account-based blockchain systems, it provides for statefulness, while Zexe, which depends on a UTXO-based scripting language like Bitcoin Script, does not.
In summary, Zexe proposes a new UTXO-based blockchain protocol that not only provides functional privacy but also data privacy. Zether is a layer 2 privacy solution that allows one to spend ETH without revealing the amounts spent and provides extensions in order to hide both the sender and receiver. If you want to read both papers in-depth, you can read the Zexe paper and Zether paper.