Merge pull request #51 from sachayves/readme-copy

Readme edits
This commit is contained in:
Jordi Baylina 2020-07-14 07:12:38 +02:00 committed by GitHub
commit ded45aac6f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

320
README.md

@ -1,119 +1,177 @@
# snarkjs: JavaScript implementation of zkSNARKs.
# snarkjs
This is a JavaScript and Pure Web Assembly implementation of zkSNARK schemes. It uses the Groth16 Protocol (3 point only and 3 pairings)
This is a **JavaScript and Pure Web Assembly implementation of zkSNARK schemes.** It uses the Groth16 Protocol (3 point only and 3 pairings).
This library includes all the tools for the Trusted setup multiparty ceremony.
This includes the universal ceremony "powers of tau".
And the per circuit phase 2 ceremony.
This library includes all the tools required to perform trusted setup multi-party ceremonies: including the universal [*powers of tau*](https://medium.com/coinmonks/announcing-the-perpetual-powers-of-tau-ceremony-to-benefit-all-zk-snark-projects-c3da86af8377) ceremony, and the second phase circuit specific ceremonies.
The formats used in this library for the multipary computation are compatible with the ones used in other (implementations in rust)[].
> Any zk-snark project can pick a round from the common phase 1 to start their circuit-specific phase 2 ceremony.
This library uses the compiled circuits generated by the circom compiler.
The formats used in this library for the multi-party computation are compatible with the ones used in [Semaphore's Perpetual Powers of Tau](https://github.com/weijiekoh/perpetualpowersoftau) and [other implementations](https://github.com/kobigurk/phase2-bn254).
The library works in nodejs and browser.
This library uses the compiled circuits generated by the [circom](https://github.com/iden3/circom) compiler.
It's a ESM module, so it can be directly imported from bigger projects using rollup or webpack.
It works in [`node.js`](#using-node) as well as directly in the [browser](#in-the-browser).
The low level criptography is done directly in wasm. And it uses working threads to parallelize the computations. The result is a high performance library with benchmarks comparable with implementations running in the host.
It's an [ES module](https://hacks.mozilla.org/2018/03/es-modules-a-cartoon-deep-dive/), so it can be directly imported into bigger projects using [Rollup](https://rollupjs.org/guide/en/) or [Webpack](https://webpack.js.org/).
## Usage / Tutorial.
The low-level cryptography is performed directly in `wasm`, and uses worker threads to parallelize the computations. The result is a high performance library with benchmarks comparable to host implementations.
## Preliminaries
### Install node v14
First off, make sure you have a recent version of `Node.js` installed. While any version after `v12` should work fine, we recommend you install `v14` or later.
If youre not sure which version of Node you have installed, you can run:
```sh
node -v
```
To download the latest version of Node, see [here](https://nodejs.org/en/download/).
### Install snarkjs and circom
To install `circom` and `snarkjs`, run:
```sh
npm install -g circom@latest
npm install -g snarkjs@latest
```
### Help
If you're seeing an error, try prefixing both commands with `sudo`.
### Understand the `help` command
To see a list of all `snarkjs` commands, as well as descriptions about their inputs and outputs, run:
```sh
snarkjs --help
```
In commands that takes long time, you can add the -v or --verbose option to see the progress.
The help for specific command:
You can also us the `--help` option with specific commands:
Example
```sh
snarkjs groth16 prove --help
```
Most of the commands have a shor alias.
Most of the commands have an alternative shorter alias (which you can discover using `--help`).
For example, the previos command can also be invoked as:
For example, the previous command can also be invoked with:
```sh
snarkjs g16p --help
```
For this tutorial, create a new direcory and change the path
### Debugging tip
If you a feel a command is taking longer than it should, re-run it with a `-v` or `--verbose` option to see more details about how it's progressing and where it's getting blocked.
## Guide
> If this is your first time using circom and snarkjs, we recommend going through [this tutorial](https://blog.iden3.io/first-zk-proof.html) first.
### 0. Create and move into a new directory
```sh
mkdir snarkjs_example
cd snarkjs_example
```
### Start a new ceremony.
### 1. Start a new powers of tau ceremony
```sh
snarkjs powersoftau new bn128 12 pot12_0000.ptau
snarkjs powersoftau new bn128 12 pot12_0000.ptau -v
```
You can also use bls12-381 as the curve.
The `new` command is used to start a powers of tau ceremony.
The secons parameter is the power of two of the maximum number of contraints that can accept this ceremony.
The first parameter after `new` refers to the type of curve you wish to use. At the moment, we support both `bn128` and `bls12-381`.
In this case 12 means that the maximum constraints will be 2**12 = 4096
The second parameter, in this case `12`, is the power of two of the maximum number of contraints that the ceremony can accept: in this case, the number of constraints is `2 ^ 12 = 4096`. The maximum value supported here is `28`, which means you can use `snarkjs` to securely generate zk-snark parameters for circuits with up to `2 ^ 28` (≈268 million) constraints.
### Contribute in the ceremony
> Note that the creator of the ceremony is also the first contributor.
### 2. Contribute to the ceremony
```sh
snarkjs powersoftau contribute pot12_0000.ptau pot12_0001.ptau --name="Example Name" -v
snarkjs powersoftau contribute pot12_0000.ptau pot12_0001.ptau --name="First contribution" -v
```
The name is a random name and it's include for reference. It's printed in the verification.
The `contribute` command creates a ptau file with a new contribution.
### Do a second contribution
You'll be prompted to enter a random text as an extra source of entropy.
`contribute` takes as input the transcript of the protocol so far, in this case `pot12_0000.ptau`, and outputs a new transcript, in this case `pot12_0001.ptau`, which includes the computation carried out by the new contributor (`ptau` files contain a history of all the challenges and responses that have taken place so far).
`name` can be anything you want, and is just included for reference (it will be printed when you verify the file (step 5).
### 3. Provide a second contribution
```sh
snarkjs powersoftau contribute pot12_0001.ptau pot12_0002.ptau --name="Second contribution Name" -v -e="some random text"
snarkjs powersoftau contribute pot12_0001.ptau pot12_0002.ptau --name="Second contribution" -v -e="some random text"
```
the -e parameter allows the comman to be non interactive and use this text as an extra source of entropy for the random generation.
### Verify the file
```sh
snarkjs powersoftau verify pot12_0002.ptau
```
This command checks all the contributions of the Multiparty Computation (MPC) and list the hashes of the
intermediary results.
### Contribute using ther party software.
By allowing you to write the random text as part of the command, the `-e` parameter allows `contribute` to be non-interactive.
### 4. Provide a third contribution using third party software
```sh
snarkjs powersoftau export challange pot12_0002.ptau challange_0003
snarkjs powersoftau challange contribute bn128 challange_0003 response_0003
snarkjs powersoftau challange contribute bn128 challange_0003 response_0003 -e="some random text"
snarkjs powersoftau import response pot12_0002.ptau response_0003 pot12_0003.ptau -n="Third contribution name"
```
The commands above use [this software](https://github.com/kobigurk/phase2-bn254) to help generate a challenge, response, and a new `ptau` file.
### Add a beacon
### 5. Verify the protocol so far
```sh
snarkjs powersoftau verify pot12_0003.ptau
```
The `verify` command verifies a `ptau` (powers of tau) file. Which means it checks all the contributions to the multi-party computation (MPC) up to that point. It also prints the hashes of all the intermediary results to the console.
If everything checks out, you should see the following at the top of the output:
```sh
[INFO] snarkJS: Powers Of tau file OK!
```
In sum, whenever a new zk-snark project needs to perform a trusted setup, you can just pick the latest `ptau` file, and run the `verify` command to verify the entire chain of challenges and responses so far.
### 6. Apply a random beacon
```sh
snarkjs powersoftau beacon pot12_0003.ptau pot12_beacon.ptau 0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f 10 -n="Final Beacon"
```
### Prepare phase2
The `beacon` command creates a `ptau` file with a contribution applied in the form of a random beacon.
The next step is to apply a random beacon to it (we need to apply a random beacon in order to finalise phase 1 of the trusted setup).
> To paraphrase Sean Bowe and Ariel Gabizon, a random beacon is a source of public randomness that is not available before a fixed time. The beacon itself can be a delayed hash function (e.g. 2^40 iterations of SHA256) evaluated on some high entropy and publicly available data. Possible sources of data include: the closing value of the stock market on a certain date in the future, the output of a selected set of national lotteries, or the value of a block at a particular height in one or more blockchains. E.g. the hash of the 11 millionth Ethereum block (which as of this writing is some 3 months in the future). See [here](https://eprint.iacr.org/2017/1050.pdf) for more on the importance of a random beacon.
In the above case, the beacon is essentially a delayed hash function evaluated on `0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f` (in practice, this will be some form of high entropy and publicly available data). The `10` just means perform `2 ^ 10` iterations of this hash function.
> Note that [security holds](https://eprint.iacr.org/2017/1050) even if an adversary has limited influence on the beacon.
### 7. Prepare phase 2
```sh
snarkjs powersoftau prepare phase2 pot12_beacon.ptau pot12_final.ptau -v
```
### Verify the last file
We're now ready to prepare phase 2 of the setup (the circuit-specific phase).
Under the hood, the `prepare phase2` command calculates the evaluation of the Lagrange polynomials at tau for `alpha*tau` and `beta*tau`. It takes the beacon `ptau` file we generated in the previous step, and outputs a final `ptau` file which will be used to generate the circuit proving and verification keys.
### 8. Verify the final `ptau`
```sh
snarkjs powersoftau verify pot12_final.ptau
```
### Create a circuit
The `verify` command verifies a powers of tau file.
Before we go ahead and create the circuit, we perform a final check and verify the final protocol transcript.
### 9. Create the circuit
```sh
cat <<EOT > circuit.circom
template Multiplier(n) {
@ -135,86 +193,145 @@ component main = Multiplier(1000);
EOT
```
This is an example circom fille that allows to test the system with different number of contraints.
We create a circom file that allows us to easily test the system with a different number of contraints.
In this case 1000, but it can be changed to any nomber of constraints.
In this case, we've chosen `1000`, but we can change this to anything we want (as long as it's below the number we defined in step 1).
### compile the circuit
### 10. Compile the circuit
```sh
circom circuit.circom -r -w -s -v
circom circuit.circom --r1cs --wasm --sym -v
```
-r to generate the .r1cs file
-w to generate the .wasm file that computes the witness from an input.
-s to generate the .sym file that contains the human readable names of all signals. (Important to debug the circuit)
-v Verbose. To see the progress of the compilation.
The `circom` command takes one input (the circuit to compile, in our case `circuit.circom`) and three options:
### info of a circuit
- `r1cs`: generates `circuit.r1cs` (the r1cs constraint system of the circuit in binary format).
- `wasm`: generates `circuit.wasm` (the wasm code to generate the witness more on that later).
- `sym`: generates `circuit.sym` (a symbols file required for debugging and printing the constraint system in an annotated mode).
### 11. View information about the circuit
```sh
snarkjs r1cs info circuit.r1cs
```
### Print the constraints
The `info` command is used to print circuit stats.
You should see the following output:
```
[INFO] snarkJS: Curve: bn-128
[INFO] snarkJS: # of Wires: 1003
[INFO] snarkJS: # of Constraints: 1000
[INFO] snarkJS: # of Private Inputs: 2
[INFO] snarkJS: # of Public Inputs: 0
[INFO] snarkJS: # of Outputs: 1
```
This information fits with our mental map of the circuit we created: we had two private inputs `a` and `b`, one output `c`, and a thousand constraints of the form `a * b = c.`
### 12. Print the constraints
```sh
snarkjs r1cs print circuit.r1cs
```
### export r1cs to json
To double check, we print the constraints of the circuit.
You should see a thousand constraints of the form:
```
[ -main.int[i] ] * [ main.int[i] ] - [ main.b -main.int[i+1] ] = 0
```
### 13. Export r1cs to json
```sh
snarkjs r1cs export json circuit.r1cs circuit.r1cs.json
cat circuit.r1cs.json
```
We export r1cs to `json` format to make it human readable.
### Generate the reference zKey without contributions from the circuit.
### 14. Generate the reference `zkey` without phase2 contributions
```sh
snarkjs zkey new circuit.r1cs pot12_final.ptau circuit_0000.zkey
```
circuit_0000.zkey does not include any contribution yet, so it cannot be used in a final circuit.
The `zkey new` command creates an initial `zkey` file with zero contributions.
### Contribute in the phase2 ceremony
The `zkey` is a zero-knowledge key that includes both the pairing and verification keys as well as phase2 contributions.
Importantly, one can verify whether a `zkey` belongs to a specific circuit or not.
Note that `circuit_0000.zkey` (the output of the `zkey` command above) does not include any contributions yet, so it cannot be used in a final circuit.
*The following steps (15-20) are similar to the equivalent phase1 steps, except we use `zkey` instead of `powersoftau` as the main command, and we generate `zkey` rather that `ptau` files.*
### 15. Contribute to the phase2 ceremony
```sh
snarkjs zkey contribute circuit_0000.zkey circuit_0001.zkey --name="1st Contributor Name" -v
```
### Do a second phase2 contribution
The `zkey contribute` command creates a `zkey` file with a new contribution.
As in phase 1, you'll be prompted to enter a random text as an extra source of entropy.
### 16. Provide a second phase2 contribution
```sh
snarkjs zkey contribute circuit_0001.zkey circuit_0002.zkey --name="Second contribution Name" -v -e="Another random entropy"
```
We provide a second contribution.
### Verify the zkey file
```sh
snarkjs zkey verify circuit.r1cs pot12_final.ptau circuit_0002.zkey
```
### Contribute using third party software.
### 17. Provide a third contribution using third party software
```sh
snarkjs zkey export bellman circuit_0002.zkey challange_phase2_0003
snarkjs zkey bellman contribute bn128 challange_phase2_0003 response_phase2_0003
snarkjs zkey bellman contribute bn128 challange_phase2_0003 response_phase2_0003 -e="some random text"
snarkjs zkey import bellman circuit_0002.zkey response_phase2_0003 circuit_0003.zkey -n="Third contribution name"
```
And a third using [third-party software](https://github.com/kobigurk/phase2-bn254).
### Add a beacon
### 18. Verify the latest `zkey`
```sh
snarkjs zkey verify circuit.r1cs pot12_final.ptau circuit_0003.zkey
```
The `zkey verify` command verifies a `zkey` file. It also prints the hashes of all the intermediary results to the console.
We verify the `zkey` file we created in the previous step. Which means we check all the contributions to the second phase of the multi-party computation (MPC) up to that point.
If everything checks out, you should see the following:
```
[INFO] snarkJS: ZKey Ok!
```
### 19. Apply a random beacon
```sh
snarkjs zkey beacon circuit_0003.zkey circuit_final.zkey 0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f 10 -n="Final Beacon phase2"
```
### Verify the final file
The `zkey beacon` command creates a `zkey` file with a contribution applied in the form of a random beacon.
We us it to apply a random beacon to the latest `zkey` after all the final contribution has been made (this is necessary in order to generate a final `zkey` file and finalise phase 2 of the trusted setup).
### 20. Verify the final `zkey`
```sh
snarkjs zkey verify circuit.r1cs pot12_final.ptau circuit_final.zkey
```
### Export the verification key
Before we go ahead and export the verification key as a `json`, we perform a final check and verify the final protocol transcript (`zkey`).
### 21. Export the verification key
```sh
snarkjs zkey export verificationkey circuit_final.zkey verification_key.json
```
We export the verification key from `circuit_final.zkey` into `verification_key.json`.
### Calculat witess
### 22. Calculate the witness
```sh
cat <<EOT > input.json
{"a": 3, "b": 11}
@ -222,54 +339,63 @@ EOT
snarkjs wtns calculate circuit.wasm input.json witness.wtns
```
Calculate the witness (given the inputs `a = 3` and `b = 11`).
### Debug witness calculation
In general, when you are developing a new circuit you will want to check for some errors in the witness calculation process.
You can do it by doing
### 23. Debug the final witness calculation
```sh
snarkjs wtns debug circuit.wasm input.json witness.wtns circuit.sym --trigger --get --set
```
This will log every time a new component is started/ended ( --trigger ) when a signal is set (--set) and when it's get (--get)
And check for any errors in the witness calculation process (this is best practice).
### Proof calculation
The above command will log every time a new component starts/ends (`--trigger`), when a signal is set (`--set`) and when it's read (`--get`).
### 24. Create the proof
```sh
snarkjs groth16 prove circuit_final.zkey witness.wtns proof.json public.json
```
It is possible also to do the calculate witness and the prove calculation in the same command:
We create the proof. `groth16 prove` generates the files `proof.json` and `public.json`: `proof.json` contains the actual proof, whereas `public.json` contains the values of the public inputs and output.
Note that it's also possible to create the proof and calculate the witness in the same command by running:
```sh
snarkjs groth16 fullprove input.json circuit.wasm circuit_final.zkey proof.json public.json
```
### Verify
### 25. Verify the proof
```sh
snarkjs groth16 verify verification_key.json public.json proof.json
```
### Export Solidity Verifier
We use the `groth16 verify` command to verify the proof, passing in the `verification_key` we exported earlier.
If all is well, you should see that `OK` has been outputted to your console. This signifies the proof is valid.
### 26. Turn the verifier into a smart contract
```sh
snarkjs zkey export solidityverifier circuit_final.zkey verifier.sol
```
You can deploy th "Verifier" smartcontract using remix for example.
In order to simulate a verification call, you can do:
Finally, we export the verifier as a Solidity smart-contract so that we can publish it on-chain using [remix](https://remix.ethereum.org/) for example. For the details on how to do this, see section 4 of [this tutorial](https://blog.iden3.io/first-zk-proof.html).
### 27. Simulate a verification call
```sh
snarkjs zkey export soliditycalldata public.json proof.json
```
And cut and paste the resolt directlly in the "verifyProof" field in the deployed smart contract.
We use `soliditycalldata` to simulate a verification call, and cut and paste the result directly in the verifyProof field in the deployed smart contract.
This call will return true if the proof and the public data is valid.
This call will return true if both the proof and public data are valid.
And voila! That's all there is to it :)
## Use in node
## Using Node
```sh
npm init
@ -303,9 +429,9 @@ run().then(() => {
});
```
## Use in the web
## In the browser
load snarkjs.min.js and start using it normally.
Load `snarkjs.min.js` and start using it as usual.
```
cp node_modules/snarkjs/build/snarkjs.min.js .
@ -364,6 +490,18 @@ async function calculateProof() {
</html>
```
## Further resources
- [Announcing the Perpetual Powers of Tau Ceremony to benefit all zk-SNARK projects](https://medium.com/coinmonks/announcing-the-perpetual-powers-of-tau-ceremony-to-benefit-all-zk-snark-projects-c3da86af8377)
- [Scalable Multi-party Computation for zk-SNARK Parameters in
the Random Beacon Model](https://eprint.iacr.org/2017/1050.pdf)
- [phase2-bn254](https://github.com/kobigurk/phase2-bn254)
- [Perpetual Powers of Tau](https://github.com/weijiekoh/perpetualpowersoftau)
- [Powers of Tau](https://github.com/ebfull/powersoftau)
- [Trusted setup ceremonies explored](https://www.zeroknowledge.fm/133)
## Final note
We hope you enjoyed this quick walk-through. Please address any questions you may have to our [telegram group](https://t.me/iden3io) (its also a great way to join the community and stay up-to-date with the latest circom and snarkjs developments) 💙
## License