Zero-knowledge proofs (ZKPs) are a family of probabilistic protocols, first described by Goldwasser, Micali and Rackoff in 1985.
One particular family of ZKPs is described as zero-knowledge Succinct Non-interactive ARguments of Knowledge, a.k.a. zkSNARKs. zkSNARKs are the most widely used zero-knowledge protocols, with the anonymous cryptocurrency Zcash and the smart-contract platform Ethereum among the notable early adopters.(cite)
For more details on the background principles of ZPKs and zkSNARKs, please refer to the following materials.
- Vitalik Buterin’s introduction to SNARKs, part 1, 2, and 3
- What are zk-SNARKs?
- ZKP Science
In this lab, we will focus on the process of how a zk program was computed, proved, and verified, showcasing the active involvement of multiple parties, with the help of ZoKrates. Please read the deliverable before your hands-on.
For a better understanding, please view this figure first. (captured from here at 10:10) Blue texts are the commands used in ZoKrates CLI.
Follow the instructions in this link, and install ZoKrates in MacOS or Linux by using One-line installation
on the page. Then follow the instructions in 'Hello ZoKrates!' to execute the whole process. In each step, pay attention to which files are generated and match them to the above figure. After executing zokrates export-verifier
, you will find a verifier.sol
generated, deploy it to Remix IDE, and verify your proof in Remix.
Hints:
- Don't forget add ZoKrates to PATH as suggested
>>> export PATH=$PATH:/YOUR DIR/.zokrates/bin
- You can find the a, b, c, and input values required for verifier.verifyTx() in generated
proof.json
file, the format should be like these(for example):proof: [[a[0],a[1]], [[b[0][0],b[0][1]],[b[1][0],b[1][1]]], [c[0],c[1]]]
In this exercise, we simulate a scenario where you are a prover who tries to prove that your age is bigger than a given number(21, in this case). You will submit your proof to a smart contract deployed by a verifier, while your age is not included in the proof.
You should use a common .zok file to compile, and use a given setup(proving.key) to replace the command of zokrates setup
.
Using the given verifier.sol smart contract to Remix IDE and put your proof arguments to verifyTx
function.
Steps to finish the Exercise for your reference:
- Compile the .zok program:
>>> zokrates compile -i comp.zok
- Perform the setup phase using the given
proving.key
file - Execute the program with specified arguments, the format of arguments can be referred to the definition in
comp.zok
- Generate a proof of computation:
>>> zokrates generate-proof
- Note: Stop at this step and proceed with the provided Solidity file for further instructions.
Hint:
- You could use this command to download the files to avoid font/format issues, replace the link to adjust other files
>>> wget -O proving.key https://github.com/ZhouYuxuan97/zk-demo/blob/main/proving.key?raw=true
In this exercise, we simulate a scenario where Alice tries to prove she knows a hash preimage for a digest chosen by Bob. Samely, the preimage wouldn’t be revealed when Bob verifies the proof.
To start with, you can create a new file named generate-hash.zok
to learn about how to generate hash in .zok
:
import "hashes/sha256/512bitPacked" as sha256packed;
def main(private field a, private field b, private field c, private field d) -> field[2] {
field[2] h = sha256packed([a, b, c, d]);
return h;
}
The first line imports the sha256packed
function from the ZoKrates standard library.
sha256packed
is a SHA256 implementation that is optimized for the use in the ZoKrates DSL. Here is how it works: We want to pass 512 bits of input to SHA256. However, a field
value can only hold 254 bits due to the size of the underlying prime field we are using. As a consequence, we use four field elements, each one encoding 128 bits, to represent our input. The four elements are then concatenated in ZoKrates and passed to SHA256. Given that the resulting hash is 256 bit long, we split it in two and return each value as a 128 bit number.
Then compile generate-hash.zok and create a witness file, record the output.
Now, based on the code snippet in generate-hash.zok
and witness output, Bob needs to design a prove-preimage.zok
, compile it, make a setup and export verifier.sol
, and deploy verifier.sol
to Remix IDE. Alice is going to compile the prove-preimage.zok
as well, enter her preimage to generate witness, using Bob's proving.key
to construct the proof, then put the arguments in proof to verifier.verifyTx()
to show her knowledge of that hash preimage to Bob.
Help Bob to design prove-preimage.zok
and follow these steps to finish the demo.
Hints:
- You could use this command to generate witness of
generate-hash
>>> zokrates compute-witness -a 0 1 2 4 --verbose
- You should create separate folders for all exercises.
- Submission should be a pdf file.
- For all exercises, you should submit the screenshots of what files remain in your folder; the screenshots of the terminal showing what commands are executed and their outputs; the screenshots of your contract executing inputs and results in Remix IDE.
- For all exercises, copy your code in
.zok
files and proofs inproof.json
to the pdf submission. - For Exercise 3, create two folders called
Alice
andBob
individually, follow the instructions and understand the scenario(difference in roles' duties), and submit the screenshots of what files remain inAlice
andBob
folders.