2018-10-21 20:41:44 +03:00
# snarkjs: JavaScript implementation of zkSNARKs.
2018-08-09 09:16:34 +03:00
2018-11-10 16:43:37 +03:00
This is a JavaScript implementation of zkSNARK schemes. It allows the original 8points protocol
and the Groth Protocol (3 point only and 3 pairings)
2018-08-09 09:16:34 +03:00
2018-09-10 12:53:09 +03:00
This library allows to do the trusted setup, generate proofs and verify the proofs.
2018-08-09 09:16:34 +03:00
This library uses the compiled circuits generated by the jaz compiler.
2019-04-12 15:20:43 +03:00
### Tutorial.
A good starting point [is this tutorial ](https://github.com/iden3/circom/blob/master/TUTORIAL.md )
Also this [video ](https://www.youtube.com/watch?v=-9TJa1hVsKA ) is a good starting point.
2018-09-10 12:53:09 +03:00
## Install.
2018-08-09 09:16:34 +03:00
2018-09-14 15:27:36 +03:00
```sh
2018-10-21 20:41:44 +03:00
npm install snarkjs
2018-08-09 09:16:34 +03:00
```
2018-10-21 20:41:44 +03:00
## Usage from command line.
```sh
snarkjs --help
```
Will show all the info in how to use the cli.
2018-12-29 10:26:45 +03:00
## Usage from javascript
2018-10-21 20:41:44 +03:00
2018-08-09 09:16:34 +03:00
2018-09-10 12:53:09 +03:00
### Import.
2018-08-09 09:16:34 +03:00
2018-09-14 15:27:36 +03:00
```js
2018-10-21 20:41:44 +03:00
const zkSnark = require("snarkjs");
2018-08-09 09:16:34 +03:00
```
### Load a circuit.
2018-09-14 15:27:36 +03:00
```js
2018-08-09 09:16:34 +03:00
// "myCircuit.cir" is the output of the jaz compiler
const circuitDef = JSON.parse(fs.readFileSync("myCircuit.cir", "utf8"));
const circuit = new zkSnark.Circuit(circuitDef);
```
### Inspect the circuit.
2018-09-14 15:27:36 +03:00
```js
2018-08-09 09:16:34 +03:00
// `signalId` can always be a number or an alias string
2018-09-09 15:04:22 +03:00
circuit.nConstraints; // number of constraints
2018-08-09 16:31:16 +03:00
circuit.nSignals; // number of signals
circuit.nPublic; // number of public signals (nOutputs + nPublicInputs)
2018-08-09 09:16:34 +03:00
// The array of signals is always sorted in this order:
2018-09-09 15:04:22 +03:00
// [ 1, outputs, publicInputs, privateInputs, internalSignals, constants]
2018-08-09 09:16:34 +03:00
2018-09-09 15:04:22 +03:00
// returns a,b and c coeficients of the `signalId` on a given `constraint`
circuit.a(constraint, signalId)
circuit.b(constraint, signalId)
circuit.c(constraint, signalId)
2018-08-09 09:16:34 +03:00
circuit.nOutputs // number of public outputs
2018-08-25 01:16:12 +03:00
circuit.pubInputs // number of public inputs
circuit.nPrvInputs // number of private inputs
2018-08-09 09:16:34 +03:00
circuit.nInputs // number of inputs ( nPublicInputs + nPrivateInputs)
2018-08-25 01:16:12 +03:00
circuit.nVars // number of variables ( not including constants (one is a variable) )
circuit.nSignals // number of signals ( including constants )
2018-08-09 09:16:34 +03:00
circuit.outputIdx(i) // returns the index of the i'th output
circuit.inputIdx(i) // returns the index of the i'th input
2018-08-25 01:16:12 +03:00
circuit.pubInputIdx(i) // returns the index of the i'th public input
circuit.prvInputIdx(i) // returns the index of the i'th private input
circuit.varIdx(i) // returns the index of the i'th variable
circuit.constantIdx(i) // returns the index of the i'th constant
circuit.signalIdx(i) // returns the index of the i'th signal
2018-08-09 09:16:34 +03:00
// returns signal Idx given a signalId
// if the idx >= n , it is a constant
// if the idx == -1, the signal does not exist
2018-09-14 08:08:56 +03:00
circuit.getSignalIdx(name);
2018-08-09 09:16:34 +03:00
2018-09-14 08:08:56 +03:00
// returns an array aliases names of the i'th signal
circuit.signalNames(i)
2018-08-09 09:16:34 +03:00
// input is a key value object where keys are the signal names
// of all the inputs (public and private)
2018-09-10 12:53:09 +03:00
// returns an array of values representing the witness
2018-09-05 06:24:24 +03:00
circuit.calculateWitness(input)
2018-08-09 09:16:34 +03:00
```
2018-09-10 12:53:09 +03:00
### Trusted setup.
2018-08-09 09:16:34 +03:00
2018-09-14 15:27:36 +03:00
```js
2018-08-09 09:16:34 +03:00
const setup = zkSnark.setup(circuit);
2018-09-16 00:14:36 +03:00
fs.writeFileSync("myCircuit.vk_proof", JSON.stringify(setup.vk_proof), "utf8");
fs.writeFileSync("myCircuit.vk_verifier", JSON.stringify(setup.vk_verifier), "utf8");
2018-08-09 09:16:34 +03:00
setup.toxic // Must be discarded.
```
2018-09-10 12:53:09 +03:00
### Generate proof.
2018-08-09 09:16:34 +03:00
2018-09-14 15:27:36 +03:00
```js
2018-08-09 09:16:34 +03:00
const circuitDef = JSON.parse(fs.readFileSync("myCircuit.cir", "utf8"));
const circuit = new zkSnark.Circuit(circuitDef);
const input = {
"main.pubIn1": "123",
"main.out1": "456"
}
2018-09-05 06:24:24 +03:00
const witness = circuit.calculateWitness(input);
2018-08-09 09:16:34 +03:00
const vk_proof = JSON.parse(fs.readFileSync("myCircuit.vk_proof", "utf8"));
const {proof, publicSignals} = zkSnark.genProof(vk_proof, witness);
```
2018-09-10 12:53:09 +03:00
### Verifier.
2018-08-09 09:16:34 +03:00
2018-09-14 15:27:36 +03:00
```js
2018-08-09 09:16:34 +03:00
const vk_verifier = JSON.parse(fs.readFileSync("myCircuit.vk_verifier", "utf8"));
if (zkSnark.isValid(vk_verifier, proof, publicSignals)) {
console.log("The proof is valid");
} else {
console.log("The proof is not valid");
}
```
2018-10-21 20:41:44 +03:00
## License
snarkjs is part of the iden3 project copyright 2018 0KIMS association and published with GPL-3 license. Please check the COPYING file for more details.