Zero Knowledge Proofs workshop @ Decentralize Now!
In a circuit we generate a proof of this relation:
inputs(public and private) => circuit => output
We have inputs, a defined circuit, and an output.
The proof is something that proves this relation, without revealing the private input.
Some examples of circuits:
- Merkle trees
- UXTO's (for scalable coins)
- for alternative to layer 2 scalability (vitalik)
The thing about zero knowledge proofs is that they're similar to how public-private cryptography works.
When you generate a public-private keypair, its security comes from the intractibility/unreverseability of a certain operaion. Basically:
pubkey, privkey = generate_keys() sig = sign(data, privkey) assert(checksig(data, pubkey), true) # However, you cannot derive privkey from the checksig alone
For the circuit to be built, we need to use some random values. The process of generating these is very important, because much like pubprivkey tech, you need this random data to be completely secret. However, unlike pubprivkey tech, the circuit itself will be public.
Why then do we need this random data? It's called trusted setup. The randomness is required to make the computation in the circuit intractable. If we multiply some number by an incredibly large random number, we are able to prove certain things about it, but if the random number is known or it is very simple (like 100000000000) - then generating proofs for the circuit becomes extremely easy and thus, useless.
So instead, we must go through something called trusted setup, or a ceremony, where we generate the parameters for randomness. The key here is that - each party contributes randomness, and as long as one party destroys their randomness- we are okay (assuming it was really random data).
You can read further about this here and multi-party computation here. Also why they call it toxic waste.
What is the ZKSNARK framework?
We create circuits which represent a particular algorithm. We decide which inputs we want to be "zero knowledge", or private. We perform the trusted setup to generate the random parameters of the circuit to make it intractable to generate invalid proofs.
A proof is something which verifies an output that was produced from applying the circuit logic to some input (not revealed). To do this, we ourselves run the circuit with our private input, thus producing something called the witness. The witness is the set of all signals that satisfy all constraints contained within the circuit - the constraints are simply the algorithm - if it's SHA256, it's outputs of each round of shift operations and so on...
Follow the tutorial here to:
- write a ZKSNARK circuit
- compile and run the trusted setup
- generate and deploy a Solidity verifier for this circuit
- generate a proof to be sent to the contract