Transactions in well-known cryptocurrencies such as Bitcoin and Ethereum are publicly recorded and permanently stored in the blockchain. While blockchain’s decentralization provides transparency, it can also compromise privacy. In a centralized model, privacy is easily achieved as long as the central party is trusted. In traditional banking services, a customer’s transaction is kept confidential unless there is a legal reason to disclose it. However, achieving both decentralization and privacy can be challenging because transactions must be visible to everyone for proper verification of transaction history.
One way to hide transaction history in coins is by using a mixing service. The mixing service receives coins from multiple users and combines them to obscure the destination of each transaction. Nevertheless, there are drawbacks: maintaining privacy can be challenging when there are few users. Additionally, the mixing service has access to all information and may potentially steal coins if it behaves maliciously.
Zerocash↗, proposed by Ben-Sasson et al., is a decentralized anonymous payment scheme and is considered one of the privacy coins. It allows a user to send coins without revealing the destination or amount in a decentralized manner using zero-knowledge proofs.
In this post, we will discuss the structure of Zerocash and its real-world applications, specifically Zcash↗.
Backgrounds
In this section, we will introduce basic cryptographic protocols which are building blocks of Zerocash.
Commitment Scheme
A commitment scheme is a cryptographic protocol that enables a party to commit to a message or value without revealing the value itself, and later reveal it in a verifiable manner. This is useful in scenarios where a party needs to prove that they made a commitment to a particular message at an earlier time without revealing the message until a later time.
Commitment schemes can be constructed using a cryptographic hash function. To commit a message , it is enough to reveal , where is a randomness, is a cryptographic hash function, and denotes a concatenation operation. Due to preimage resistance property, it is impossible to recover from . We will denote a commitment for a message with a given randomness as .
Pseudorandom Function
A pseudorandom function (PRF) is a function that takes input and outputs a string that looks random. The PRF is initialized with a seed, which is generally public. It is deterministic, so if the seed and are the same, the output is always the same. Additionally, if is unknown, the output is unpredictable.
The PRF can also be constructed from a cryptographic hash function. For instance, is unpredictable.
Zero-Knowledge Proof and zk-SNARK
A zero-knowledge proof is a cryptographic technique that allows a prover to convince a verifier of the truth of a statement to a verifier without revealing any additional information beyond the truth of the statement. This technique enables the prover to exhibit knowledge of a confidential value to the verifier without disclosing that value or any related details. Zero-knowledge proofs must satisfy three properties:
- Completeness. If the statement is true, then an honest prover should be able to convince the verifier of its truth.
- Soundness. If the statement is false, then no cheating prover should be able to convince the verifier of its truth.
- Zero-knowledgeness. The proof should not reveal any additional information beyond the truth of the statement.
Intuitively, the prover can convince their knowledge of such that without revealing itself to the verifier.
zk-SNARK is a type of zero-knowledge–proof protocol that has one additional feature called succintness (i.e., proof size and verifier time are sublinear). Zerocash uses zk-SNARK for zero-knowledge proofs. Even without knowledge of how zk-SNARK works, one can understand the structure of Zerocash based on the aforementioned properties. Therefore, we will omit further details. Check Intro to Zero-Knowledge: A Guided Tour of the ZK Landscape, Part 1↗ in our blog if interested.
UTXO: Transactions in Bitcoin
To gain a better understanding of the Zerocash protocol, it is important to first examine how transactions work in Bitcoin. In Bitcoin, the amount of assets each user holds is managed in unspent transaction output (UTXO) model. In a typical banking system, each user has a balance and the amount of the balance increases or decreases depending on deposits/withdrawals. This model is called the account model. However, in the UTXO model, individual units of coins named as UTXOs are transferred between users.
Assume that Alice and Bob earn 6.25 BTC from mining, respectively. Then each mining result is recorded in transaction. In other words, Alice and Bob each have 6.25 BTC UTXO. UTXO lists for each user are shown below:
- Alice : 6.25 BTC,
- Bob : 6.25 BTC.
They wish to send 1 BTC to Charles. Then, Alice’s transaction input is the 6.25 BTC UTXO she mined, and outputs are 1 BTC UTXO for Charles and 5.25 BTC UTXO for Alice. She retrieves a change by sending the remaining coin to herself. Now, 6.25 BTC transaction output is spent and a new 5.25 BTC UTXO is created. Sames goes for Bob. UTXO lists for each user are shown below:
- Alice : 5.25 BTC,
- Bob : 5.25 BTC,
- Charles : 1 BTC, 1 BTC.
Finally, Charles wants to send 1.5 BTC to Daniel. Then Charles’s new transaction inputs are two 1 BTC UTXO, and the outputs are that 1.5 BTC UTXO belong to Daniel and 0.5 BTC UTXO belong to Charles. UTXO lists for each user are shown below:
- Alice : 5.25 BTC,
- Bob : 5.25 BTC,
- Charles : 0.5 BTC,
- Daniel : 1.5 BTC.
Graphical overview of transactions example. |
A transaction is considered valid if 1) UTXO inputs have not been used before, 2) the sum of inputs and outputs are equal (transaction fee is ignored for simplicity), and 3) the transaction is generated by senders. The first two conditions can be easily verified. To verify the third condition, a digital signature for the transaction is embedded in the transaction. If the UTXO inputs belong to more than one owner, then multi-signature↗ is embedded.
Zerocash Protocol
A transaction in the Zerocash protocol is based on a transaction in Bitcoin. To clarify, since the Zerocash protocol also uses the UTXO model, we only need to fulfill the three aforementioned conditions. However, it may be impossible to satisfy all of these conditions when the destination and even the amount are hidden. For instance, it may seem strange to verify a sum of inputs and a sum of outputs are equal without revealing the amounts. Nevertheless, this is made possible through the use of zero-knowledge proofs.
It has been mentioned that a prover can convince a verifier of their knowledge of such that without revealing itself to the verifier using zero-knowledge proof. Therefore, once we represent all conditions of a transaction in equations, the sender can prove the validity of their transaction, revealing sensitive information. We will discuss how to set the conditions into equations. The simplification below will give us a bigger picture of the protocol, and then we’ll break it down to understand the details of a Zerocash transaction.
Protocol (Simplified)
This is the simplified version of the Zerocash protocol introduced in the Zerocash paper. In this protocol, the value of the coin is fixed. If Alice wants to mint a new coin , Alice does the following:
- Alice samples a random serial number and a trapdoor , computes a coin commitment . Now a new coin is defined.
- A corresponding mint transaction containing is sent to the ledger. Note that neither nor will be sent.
If an Alice wants to spend , Alice does the following:
- Alice posts transaction containing the coin’s serial number and a zk-SNARK proof of her knowledge of such that appears in the list of coin commitments. The transaction is valid if does not appear in past spending transactions.
Maintaining the list of coin commitments in a Merkle tree↗ enables efficient membership checks while ensuring anonymity through the zero-knowledgeness of zk-SNARK. Users can prove their knowledge of without revealing which coin corresponds to in the list of coin commitments.
Protocol (Exact)
While the simplified version helps to understand the basic concepts of Zerocash, it has several limitations. Firstly, assuming that one coin corresponds to one dollar, if a user wants to transfer 100 dollars, they must post 100 transactions, which is inefficient and leaks the amount. Secondly, transferring a coin is not naturally defined. In this procedure, Alice can prove that coin was minted by herself. However, if Alice wishes to transfer a to Bob, the only possible way is to inform Bob of and . In this scenario, Alice may spend before Bob, and even if she does not, if Bob spends , Alice will become aware of it by examining the in the transaction.
The exact protocol includes several methods to prevent these flaws. Let’s check out the protocol.
In the full protocol, each user generates addresses. As usual, address is a key pair where is a public key and is a private key. The key pair is generated by randomly sampling first and setting . A user can generate any number of address key pairs.
Minting
To mint a new coin with value , Alice follows these steps:
- Alice samples and then the coin’s serial number .
- Alice computes for a random , then computes for a random .
- A coin and a mint transaction are generated.
Compared to the simplified protocol, the transaction includes the user’s public address. Additionally, the commitment process has become more complex. This nested structure allows anyone to verify that is a commitment for a coin value by checking that without zk-SNARK proofs, while the owner and serial number remain hidden.
Pouring
Coins are spent using the pour operation, which works similarly to the UTXO model. The operation takes a set of input coins to be consumed and pours their value into a set of fresh output coins.
The procedure for Alice, with address key pair , consumes her coin
and produces two new coins:
and
The procedure is as follows.
- Alice samples for .
- Alice computes for a random for .
- Alice computes for a random for .
- Now two new coins and are produced. Alice produces a zk-SNARK proof of her knowledge of and such that
- The coins are well-formed: , , , , , and .
- The address secret key matches the public key: .
- The serial number is computed correctly:
- The coin commitment appears in the list of coin commitments.
- The vaules add up: .
- A resulting pour transaction is appended to the ledger. The transaction is valid if has not appeared in past pour transactions.
The below illustration introduces a structure of the coin commitment.
Illustration of the structure of a coin commitment. refers receiver’s public key in public-key cryptosystem mentioned in point 1. Images from Zerocash paper. |
The statements that zk-SNARK proves are quite complicated. It is recommended to check each statement carefully. To help the reader understand, here are some points:
- If Alice wants to send to Bob, she must first need to know Bob’s address public key and set as Bob’s address public key. Moreover, she also needs to provide . These can be transferred over a private channel or by preparing a public-key cryptosystem beforehand and adding ciphertext with Bob’s public key in transaction.
- Suppose are provided using public-key cryptosystem. Then in order to receive a coin, Bob should verify the entire pour transactions so that is decrypted with Bob’s own private key.
- If Alice does not know , then Alice cannot generate valid to spend . In particular, it contradicts with the second statement, the address secret key matches the public key.
- Assume that belongs to Bob. When Bob spends , Alice cannot find it, because is revealed in the transaction, but Alice does not know it.
Now that we understand the protocol, let’s check out a real-life implementation of Zerocash: Zcash.
Zcash: An Implementation of Zerocash
Zcash↗ is an implementation of Zerocash. Zerocash was announced in 2014, and Zcash was launched in 2016. Since then, it has undergone continuous development. In essence, Zcash follows the approach introduced in Zerocash but with several changes made over the past decade. It has evolved from a simple proof-of-concept implementation to a vast ecosystem with a market capitalization of approximately 400 million dollars.
Zcash offers two types of address: z-addresses and t-addresses. Transactions between t-addresses are transparent, similar to Bitcoin transactions. Transactions between z-addresses are shielded, simliar to Zerocash transactions. It is also possible to send coins from a t-address to a z-address or from a z-address to t-address. In both cases, only the value is revealed on the t-address side.
Zcash has three shielded protocols named Sprout, Sapling, and Orchard. Sprout was the original protocol implemented in the launch of Zcash. Sapling, introduced in 2018, addressed the limitations of the Sprout protocol and offers faster transaction generation and verification. Orchard, the latest protocol upgrade activated in 2022, further enhances privacy and scalability. Orchard utilizes a new zk-SNARK called Halo2↗, which eliminates the need for a trusted setup. This is an improvement over BCTV14↗ in Sprout and Groth16↗ in Sapling. Currently, Sapling is the most widely used shielded protocol.
The amount of ZEC stored in each of Zcash’s three shielded pools since 2016. Images from ELECTRIC COIN CO.↗ |
For more information on the protocol’s structure, please refer to the Zcash Protocol Specification↗.
Attacks on Zcash
There are cases where cryptographic vulnerabilities in the Zcash protocol have been discovered and the protocol has been modified. We will discuss Faerie Gold attack and Internal hash collision attack, which are also mentioned in the protocol specification. Note that these vulnerabilities are already addressed by developers.
Faerie Gold Attack
In the Zerocash protocol, the coin serial number is determined by with arbitrary chosen . If Alice needs send two coins and to Bob but wants to do something maliciously, then she may choose the same for and . Then serial numbers and are collided. Although both coins are valid, Bob can only use one of them because the serial number in the transaction is checked to see if it has appeared before.
To address this issue, Zcash ensures the uniqueness of by changing the specification. Instead of randomly choosing , it is derived from a PRF. The inputs of the PRF are a hash digest , which differ in each transaction, and the output order index . If and are generated in different transactions, values will differ, and if they are generated in the same transaction, the output order index will differ. Therefore will never collide.
Internal Hash Collision Attack
Recall the minting process with a new coin with value in Zerocash:
- Alice samples and then the coin’s serial number .
- Alice computes for a random , then computes for a random .
- A coin and a mint transaction are generated.
In the original Zcash design, commitment is derived as follows:
Since is only 128-bits, an attacker can find and pairs that have the same with computations. Two coins derived from and looks different, as their serial numbers and are different. Therefore an attacker can double-spend them by generating two different zk-SNARK proofs using and .
To mitigate this, commitment is changed into . With this fix, Zcash commits and all at once, whereas Zerocash uses a nested commitment scheme where and are committed first, then . The reason for the nested commitment scheme in Zerocash is to allow mint transactions to be publically verified without requiring zk-SNARK proofs. However, in Zcash, mint and pour transactions are combined and each transfer always uses a zk-SNARK proof. Therefore Zcash does not require the nesting.
Conclusion
This post discusses Zerocash and its use in Zcash, a cryptocurrency. Zerocash is a protocol that enhances privacy and anonymity in cryptocurrencies, addressing security and privacy concerns. It uses advanced cryptographic techniques, such as zk-SNARKs, to prove transaction validity while anonymizing the sender, receiver, and transaction amount. This feature enables users to preserve the transparency and integrity of the blockchain while concealing the content of their transactions. Moreover, from a researcher’s perspective, it is interesting to investigate the protocol further to identify potential vulnerabilities, such as the Faerie Gold attack.
About Us
Zellic specializes in securing emerging technologies. Our security researchers have uncovered vulnerabilities in the most valuable targets, from Fortune 500s to DeFi giants.
Developers, founders, and investors trust our security assessments to ship quickly, confidently, and without critical vulnerabilities. With our background in real-world offensive security research, we find what others miss.
Contact us↗ for an audit that’s better than the rest. Real audits, not rubber stamps.