Zokrates is a toolbox for zkSNARKs on Ethereum.
This is a proof-of-concept implementation. It has not been tested for production.
Ethereum runs computations on all nodes of the network, resulting in high expenses, restrains in complexity, and low privacy. SNARKs have been enabling to only verify computations on-chain for a fraction of the cost of running them, but are hard to grasp and work with.
Zokrates bridges this gap. It helps one create off-chain programs and link them to the Ethereum blockchain, expanding the possibilities for the Dapp.
To start off, the ZoKrates framework needs to be installed. ZoKrates runs best inside a Docker container. The repository accompanies a Docker configuration which will install every single required dependency. If it is not already installed, one can download Docker here. Next, clone or download ZoKrates from the Github repository. Inside the ZoKrates folder run the following commands to start the docker container.
|docker build -t zokrates_tutorial
docker run -v $PWD/code:/home/zokrates/ZoKrates/target/debug/code -ti zokrates_tutorial /bin/bash
Inside the docker container, there is a folder containing the ZoKrates executable. Likewise, in the second command above, a folder called code which is synced with the code/ folder created inside the ZoKrates folder on the host machine (not the docker container) is seen.
One should be able to create and edit files in that folder using any editor on the host machine and changes will be reflected inside the docker container (from where the ZoKrates commands will be executed).
First, create the textfile add.code and implement your program:
|def main(field a, field b, field c) -> (field):
return a + b + c
The keyword field declares the type of the parameters utilized as components of the underlying finite field.
After that, run the various phases of the protocol:
|./zokrates compile -i ‘add.code’
./zokrates compute-witness -a 1 2 3
ZoKrates’ syntax might be a bit confusing at first sight. There are two basic types of statements: assignments (lines 10–15) and assertions (lines 6–7).
Conditional if statements must be written into a single line (like ternaries in different languages) and return distinctive values for then and else case.
Also, there is as of now no support for statically sized arrays.
Zokrates provides a command line interface. An overview of the available subcommands can be seen by running the command shown below-
Before running the computation with actual data, the compilation of the code has to be done.
|./zokrates compile -i /path/to/add.code|
Compiles a .code file into ZoKrates internal representation of arithmetic circuits.
Creates a compiled .code file at ./out.code.
As a rule of thumb, a single machine with 32GB memory and a modern processor can demonstrate a computation of up to around 10 million constraints in ~30 minutes.
With further optimization, programs written with ZoKrates are likely to be slightly more expensive than manually written arithmetic circuits (just like manual assembly is usually more efficient than compiled code). This is the reason some expensive functions (for example, hash functions) might be handwritten and incorporated in ZoKrates through so-called ‘gadgets’.
RUNNING THE CODE
Now that compilation of the program is done, the next step is to execute it. That is, for the underlying constraint system, computing a satisfying variable assignment (called witness), given a set of public and private inputs. To do this, the public and private input to be tested are passed into the compute-witness command-
|./zokrates compute-witness -a 1 2 3|
A witness for the compiled program found at ./out.code and arguments to the program is computed. A witness is a valid assignment of the variables, which incorporate the results of the computation.
A witness file at ./witness is created.
SETTING UP VERIFIER
To prove the execution of the program, a smart contract which can verify proofs needs to be created.
Creates a trusted setup for the compiled program found at ./out.code.
Generates a proving key and a verifying key at ./proving.key and ./verifying.key. These keys are gotten from a source of randomness, commonly referred to as “toxic waste”. Anybody having access to the source of randomness can create fake proofs that will be acknowledged by a verifier following the protocol.
Utilizing the verifying key at ./verifying.key creates a Solidity contract which contains the generated verification key and a public function to verify a solution for the compiled program at ./out.code.
Creates a verifier contract at ./verifier.sol.
This smart contract is tied to the code that was previously compiled. Any changes to the underlying code will require to rerun the setup and export a new verifier. The verifier contract should be deployed on the Ethereum chain.
A simple way of doing this is using a wallet (e.g. MetaMask) with some free test ether on the Ropsten network, and also the Remix web editor. Paste the content of verifier.sol into the Remix editor. On the right side, choose the “Run” tab, select the Verifier contract (instead of Pairing) and click “Create”. Sign the transaction with MetaMask and wait for it to go through.
Now that the verifier contract is deployed, anyone could run the code that was compiled locally on their machine and prove that they did it without revealing the private inputs.
Note: During setup, some parameters that are commonly referred to as toxic waste are generated. If these parameters are not removed (which ZoKrates does by default) a person gaining access to them could create arbitrary proofs without actually running the code, thereby breaking the security of snarks. Thus, it’s essential that the party setting up the verifier has no motivation in cheating or that the setup occurs through a secure multi-party computation, for example, as in the case of the Zcash ceremony.
GENERATING AND VERIFYING THE PROOF
Utilizing the proving key at ./proving.key generates a proof for computation of the compiled program ./out.code resulting in ./witness.
Passed to the verifier contract, this proof can be checked, for instance, utilizing web3.
To verify the computation using the smart contract deployed in the step above, the last part of the output of the generate-proof command should be copied to the remix editor (while converting it into proper JSON). ZoKrates is working on printing JSON directly in the proof-generation step to make this step less tedious.
Run normal tests with
and also run long and expensive tests with
|cargo test — –ignored|