Members of the Ethereum R&D team and Zcash Company are collaborating on a research project addressing the combination of programmability and privacy in blockchains. This joint publication is published simultaneously in the zcash blogand is co-authored by Ariel Gabizon (Zcash) and Christian Reitwiessner (Ethereum).
Ethereum’s flexible smart contract interface allows for a wide variety of applications, many of which have probably not yet been conceived. The possibilities grow considerably by adding the privacy capability. Imagine, for example, an election or auction conducted on the blockchain via a smart contract so that any observer on the blockchain can verify the results, but individual votes or bids are not revealed. Another possible scenario may involve targeted disclosure where users would have the ability to prove that they are in a certain city without revealing their exact location. The key to adding such capabilities to Ethereum is Zero-Knowledge Non-Interactive Succinct Arguments (zk-SNARK), precisely the underlying cryptographic engine of Zcash.
One of the goals of the company Zcash, whose code name Alchemy Project, is to allow a direct decentralized exchange between Ethereum and Zcash. Connecting these two blockchains and technologies, one focused on programmability and the other on privacy, is a natural way to facilitate the development of applications that require both.
As part of the Zcash/Ethereum technical collaboration, Zcash’s Ariel Gabizon visited Christian Reitwiessner from the Ethereum hub in Berlin a few weeks ago. The highlight of the tour is a proof-of-concept implementation of a zk-SNARK verifier written in Solidity, based on pre-compiled Ethereum contracts implemented for the Ethereum C++ client. This work complements baby zoe , where a zk-SNARK precompiled contract was written for Parity (the Ethereum Rust client). The updates we’ve made involved adding small cryptographic primitives (multiplication, addition, and elliptic curve matching) and implementing the rest in Solidity, all of which allow for greater flexibility and allow a variety of zk-SNARK constructs to be used without the need for a hard fork. . . Details will be shared as they become available later. We tested the new code by successfully verifying a real privacy-preserving Zcash transaction on a testnet of the Ethereum blockchain.
The verification took only 42 milliseconds, which shows that such precompiled contracts can be added and the gas costs to use them can be made quite affordable.
What can be done with such a system?
The Zcash system can be reused on Ethereum to create custom protected tokens. Such tokens already allow for many applications such as voting (see below) or simple blind auctions where participants bid without knowing the amounts bid by others.
If you want to try to build the proof of concept, you can use the following commands. If you need help, see https://gitter.im/ethereum/privacy-tech
git clone https://github.com/scipr-lab/libsnark.git cd libsnark
sudo PREFIX=/usr/local make NO_PROCPS=1 NO_GTEST=1 NO_DOCS=1 \ CURVE=ALT_BN128 \
FEATUREFLAGS="-DBINARY_OUTPUT=1 -DMONTGOMERY_OUTPUT=1 \ -DNO_PT_COMPRESSION=1" \
lib install
cd ..
git clone --recursive -b snark https://github.com/ethereum/cpp-ethereum.git
cd cpp-ethereum
./scripts/install_deps.sh && cmake . -DEVMJIT=0 -DETHASHCL=0 && make eth
cd ..
git clone --recursive -b snarks https://github.com/ethereum/solidity.git
cd solidity
./scripts/install_deps.sh && cmake . && make soltest
cd ..
./cpp-ethereum/eth/eth --test -d /tmp/test
# And on a second terminal:
./solidity/test/soltest -t "*/snark" -- --ipcpath /tmp/test/geth.ipc --show-messages
We also discussed various aspects of zk-SNARK’s integration into the Ethereum blockchain, which we now expand on.
Deciding which precompiled contracts to define
Remember that a SNARK is a short proof of ownership, and what is needed to add privacy features to the Ethereum blockchain are clients that have the ability to verify that proof.
In all recent constructions, the verification procedure consisted solely of operations on elliptic curves. Specifically, the checker requires scalar addition and multiplication on a group of elliptic curves, and would also require a heavier operation called bilinear matching.
as mentioned here, implementing these operations directly in the EVM is too expensive. Therefore, we would like to implement precompiled contracts that perform these operations. Now, the question being debated is: what level of generality should these precompiled contracts aim for?
The security level of the SNARK corresponds to the parameters of the curve. Roughly, the higher the order of the curve, and the larger something called the degree of embedment, and the safer the SNARK based on this curve. On the other hand, the higher these quantities are, the more expensive are naturally the operations on the corresponding curve. Therefore, a contract designer using SNARK can choose these parameters according to their own desired efficiency/security tradeoff. This tradeoff is one of the reasons to implement a precompiled contract with a high level of generality, where the contract designer can choose from a large family of curves. In fact, we start by aiming for a high level of generality, where the curve description is provided as part of the contract entry. In such a case, a smart contract could perform sums on any group of elliptic curves.
One complication with this approach is assigning the cost of gas to the operation. You need to assess, simply from the description of the curve, and without access to a specific implementation, how costly a group operation on that curve would be in the worst case. A somewhat less general approach is to allow all curves in a given family. We note that when working with the Barreto-Naehrig (BN) family of curves, one can roughly assess how costly the matching operation will be, given the curve parameters, since all those curves support a specific type of optimal Ate matching. . Here is a Sketch of how such a precompile would work and how the cost of gas would be calculated.
We learned a lot from this discussion, but ultimately decided to “keep it simple” for this proof of concept: we chose to implement contracts for the specific curve that Zcash currently uses. We did this by using wrappers of the corresponding functions in the libsnark library, which is also used by Zcash.
Note that we could have simply used a wrapper for the entire SNARK verification function currently used by Zcash, as was done in the Baby ZoE project mentioned above. However, the advantage of explicitly defining elliptic curve operations is to allow the use of a wide variety of SNARK constructs which, again, all have a checker that works using some combination of the three elliptic curve operations mentioned above.
Zcash configuration reuse for new anonymous tokens and other applications
As you may have heard, using SNARK requires a complex setup phase in which the so-called public system parameters are built. The fact that these public parameters need to be safely generated every time we want to use a SNARK for a particular circuit significantly hinders the usability of SNARKs. Simplifying this setup phase is an important goal we’ve thought about, but so far we haven’t had any success.
The good news is that someone who wants to issue a token that supports privacy-preserving transactions can simply reuse the public parameters that Zcash has already safely generated. It can be reused because the circuitry used to verify privacy-preserving transactions is not inherently tied to a currency or blockchain. Rather, one of its explicit inputs is the root of a Merkle tree containing all valid notes of the currency. Thus, this input can be changed according to the currency with which you want to work. Also, if it is easy to start a new anonymous token. You can already perform many tasks that do not look like tabs at first glance. For example, suppose we want to perform an anonymous election to choose a preferred option out of two. We can issue an anonymous custom token for voting and send a coin to each voting party. Since there is no “mining”, it will not be possible to generate tokens in any other way. Now each party sends its currency to one of two addresses based on its vote. The address with the highest final balance corresponds to the result of the election.
Other apps
Below is a non-token based system that is fairly simple to build and allows for “selective disclosure”. You can, for example, post an encrypted message at regular intervals, containing your physical location on the blockchain (perhaps with other people’s signatures to prevent spoofing). If you use a different key for each message, you can reveal your location only at a certain time by posting the key. However, with zk-SNARK you can also prove that you were in a certain area without revealing exactly where you were. Inside the zk-SNARK, you figure out your location and check that it is within the area. Due to the zero-knowledge property, everyone can verify that verification, but no one will be able to retrieve your actual location.
work ahead
Achieving the mentioned functionalities (creating anonymous tokens and verifying Zcash transactions on the Ethereum blockchain) will require implementing other elements used by Zcash in Solidity.
For the first functionality, we need to have an implementation of tasks performed by nodes in the Zcash network, such as updating the note commit tree.
For the second functionality, we need an implementation of the equihash proof-of-work algorithm used by Zcash in Solidity. Otherwise, the transactions can be verified as valid themselves, but we don’t know if the transaction was actually integrated into the Zcash blockchain.
Fortunately, such an implementation was written; however, it is necessary to improve its efficiency to be able to use it in practical applications.
Recognition: Thanks to Sean Bowe for technical support. We also thank Sean and Vitalik Buterin for helpful comments and Ming Chan for editing.