This commit is contained in:
Jordi Baylina 2018-08-09 08:16:34 +02:00
commit 3f2f303b94
No known key found for this signature in database
GPG Key ID: 7480C80C1BE43112
15 changed files with 1471 additions and 0 deletions

33
.eslintrc.js Normal file

@ -0,0 +1,33 @@
module.exports = {
"plugins": [
"mocha"
],
"env": {
"es6": true,
"node": true,
"mocha": true
},
"parserOptions": {
"ecmaVersion": 2017
},
"extends": "eslint:recommended",
"rules": {
"indent": [
"error",
4
],
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"double"
],
"semi": [
"error",
"always"
],
"mocha/no-exclusive-tests": "error"
}
};

63
.gitignore vendored Normal file

@ -0,0 +1,63 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Typescript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
# next.js build output
.next
tmp

107
README Normal file

@ -0,0 +1,107 @@
# javascript implementation of zkSnark
This is a javascript implementation of zkSnarks.
This library allows to do the trusted setup, generate proofs and verify the proofs.
This library uses the compiled circuits generated by the jaz compiler.
## Install
```
npm install zkSnark
```
## Usage
### import
```
const zkSnark = require("zksnark");
```
### Load a circuit.
```
// "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.
```
// `signalId` can always be a number or an alias string
circuit.m; // number of constrains
circuit.n; // number of signals
circuit.p; // number of public signals (nPublicInputs + nOutputs)
// The array of signals is always sorted in this order:
// [ outputs, publicInputs, privedInputs, internalSignals, constants]
// returns a,b and c coeficients of the `signalId` on a given `constrain`
circuit.a(constrain, signalId)
circuit.b(constrain, signalId)
circuit.c(constrain, signalId)
circuit.nOutputs // number of public outputs
circuit.nPublicInputs // number of public inputs
circuit.nPrivateInputs // number of private inputs
circuit.nInputs // number of inputs ( nPublicInputs + nPrivateInputs)
circuit.outputIdx(i) // returns the index of the i'th output
circuit.inputIdx(i) // returns the index of the i'th input
circuit.inputPublicIdx(i) // returns the index of the i'th public input
circuit.inputPrivateIdx(i) // returns the index of the i'th private input
// returns signal Idx given a signalId
// if the idx >= n , it is a constant
// if the idx == -1, the signal does not exist
circuit.signalId2idx(signalId);
// returns an array aliases names for a given signalId
circuit.signalNames(signalId)
// input is a key value object where keys are the signal names
// of all the inputs (public and private)
// returns an array of values that represent the witness
circuit.generateWitness(input)
```
### Trusted setup
```
const setup = zkSnark.setup(circuit);
fs.writeFileSink("myCircuit.vk_proof", JSON.stringify(setup.vk_proof), "utf8");
fs.writeFileSink("myCircuit.vk_verifier", JSON.stringify(setup.vk_verifier), "utf8");
setup.toxic // Must be discarded.
```
### Generate proof
```
const circuitDef = JSON.parse(fs.readFileSync("myCircuit.cir", "utf8"));
const circuit = new zkSnark.Circuit(circuitDef);
const input = {
"main.pubIn1": "123",
"main.out1": "456"
}
const witness = circuit.generateWitness(input);
const vk_proof = JSON.parse(fs.readFileSync("myCircuit.vk_proof", "utf8"));
const {proof, publicSignals} = zkSnark.genProof(vk_proof, witness);
```
### Verifier
```
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");
}
```

4
index.js Normal file

@ -0,0 +1,4 @@
exports.Circuit = require "./src/circuit.js";
exports.setup = require "./src/setup.js";
exports.genProof = require "./src/prover.js";
exports.isValid = require "./src/verifier.js";

1066
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

26
package.json Normal file

@ -0,0 +1,26 @@
{
"name": "zksnark",
"version": "0.0.1",
"description": "zkSnark implementation in javascript",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"zksnark",
"zcash",
"ethereum",
"zero",
"knowlage",
"cryptography",
"circuit"
],
"author": "Jordi Baylina",
"license": "GPL-3.0",
"dependencies": {
"eslint": "^5.3.0"
},
"devDependencies": {
"eslint-plugin-mocha": "^5.1.0"
}
}

6
src/circuit.js Normal file

@ -0,0 +1,6 @@
module.exports = class Circuit {
constructor(circuitDef) {
}
};

29
src/g1curve.js Normal file

@ -0,0 +1,29 @@
const bigInt = require("big-integer");
const ZnField = require("./znfield.js");
module.eports = class G1Curve {
constructor() {
this.F = new ZnField(bigInt("21888242871839275222246405745257275088696311157297823662689037894645226208583"));
this.g = [
];
}
add(p1, p2) {
// TODO
throw new Error("Not Implementted");
}
double(p1) {
// TODO
throw new Error("Not Implementted");
}
mulEscalar(p1, e) {
// TODO
throw new Error("Not Implementted");
}
};

28
src/g2curve.js Normal file

@ -0,0 +1,28 @@
const bigInt = require("big-integer");
const ZnField = require("./znfield.js");
module.eports = class G2Curve {
constructor() {
this.F = new ZnField(bigInt("21888242871839275222246405745257275088696311157297823662689037894645226208583"));
this.g = [
];
}
add(p1, p2) {
// TODO
throw new Error("Not Implementted");
}
double(p1) {
// TODO
throw new Error("Not Implementted");
}
mulEscalar(p1, e) {
// TODO
throw new Error("Not Implementted");
}
};

10
src/pairing.js Normal file

@ -0,0 +1,10 @@
/*
This module calculate the pairing of p1 and p2 where p1 in G1 and p2 in G2
*/
const bigInt = require("big-integer");
module.exports = function pairing(p1, p2) {
// TODO
throw new Error("Not Implementted");
};

46
src/polinomial.js Normal file

@ -0,0 +1,46 @@
/*
This library do operations on polinomials where their coefficients are in field F
The polynomial P(x) = p0 + p1 * x + p2 * x^2 + p3 * x^3, ...
is represented by the array [ p0, p1, p2, p3, ... ]
*/
class PolField {
constructor (F) {
this.F = F;
}
_reduce(a) {
let i = a.length-1;
while ((i>=0) && (this.F.isZero(a[i])) ) i--;
return (i < a.length-1) ? a.slice(0, i+1) : a;
}
add(a, b) {
const maxGrade = Math.max(a.length, b.length);
const res = new Array(maxGrade);
for (let i=0; i<maxGrade; i++) {
res[i] = this.F.add(a[i], b[i]);
}
return this._reduce(res);
}
sub(a, b) {
throw new Error("Not Implementted");
}
mul(a, b) {
throw new Error("Not Implementted");
}
div(a, b) {
throw new Error("Not Implementted");
}
lagrange(points) {
throw new Error("Not Implementted");
}
}
module.exports = PolField;

5
src/prover.js Normal file

@ -0,0 +1,5 @@
module.exports = function genProof(vk_proof, witness) {
}

5
src/setup.js Normal file

@ -0,0 +1,5 @@
module.exports = function setup(circuit) {
}

4
src/verifier.js Normal file

@ -0,0 +1,4 @@
module.exports = function isValid(vk_verifier, proof, publicSignals) {
}

39
src/znfield.js Normal file

@ -0,0 +1,39 @@
class ZnField {
constructor(n) {
this.n = n;
}
add(a, b) {
const maxGrade = Math.max(a.length, b.length);
const res = new Array(maxGrade);
for (let i=0; i<maxGrade; i++) {
res[i] = this.F.add(a[i], b[i]);
}
return this._reduce(res);
}
sub(a, b) {
// TODO
throw new Error("Not Implementted");
}
mul(a, b) {
// TODO
throw new Error("Not Implementted");
}
inverse(a, b) {
// TODO
throw new Error("Not Implementted");
}
div(a, b) {
// TODO
throw new Error("Not Implementted");
}
}
module.exports = ZnField;