Plonk finished

This commit is contained in:
Jordi Baylina 2021-05-31 13:21:07 +02:00
parent 1e89672bec
commit 577b3f3580
No known key found for this signature in database
GPG Key ID: 7480C80C1BE43112
74 changed files with 17783 additions and 745 deletions

36
.vscode/launch.json vendored

@ -65,6 +65,42 @@
"test/plonk_circuit/proof.json", "test/plonk_circuit/proof.json",
"-v" "-v"
] ]
},
{
"type": "pwa-node",
"request": "launch",
"name": "export solidity calldata",
"skipFiles": [
"<node_internals>/**"
],
"program": "cli.js",
"args": [
"zkesc",
"test/plonk_circuit/public.json",
"test/plonk_circuit/proof.json",
]
},
{
"type": "pwa-node",
"request": "launch",
"name": "export solidity verifier",
"skipFiles": [
"<node_internals>/**"
],
"program": "cli.js",
"args": [
"zkesv",
"test/plonk_circuit/circuit.zkey",
"test/plonk_circuit/verifier.sol",
]
},
{
"type": "node",
"request": "launch",
"name": "Mocha all tests",
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
"cwd": "${workspaceRoot}",
"internalConsoleOptions": "openOnSessionStart"
} }
] ]
} }

@ -276,11 +276,29 @@ cat circuit.r1cs.json
We export `r1cs` to `json` format to make it human readable. We export `r1cs` to `json` format to make it human readable.
### 14. Generate the reference `zkey` without phase 2 contributions
### 14. Setup
Currently, snarkjs supports 2 proving systems: groth16 and plonk.
Groth16 requires a trusted ceremony for each circuit. Plonk does not require it, it's enought with the powers of tau ceremony which is universal.
#### Plonk
```sh ```sh
snarkjs zkey new circuit.r1cs pot12_final.ptau circuit_0000.zkey snarkjs plonk setup circuit.r1cs pot12_final.ptau circuit_0000.zkey
``` ```
You can jump directly to Section 21 as plonk does not require a specific trusted ceremony.
### Groth16
```sh
snarkjs groth16 setup circuit.r1cs pot12_final.ptau circuit_0000.zkey
```
This generates the reference `zkey` without phase 2 contributions
IMPORTANT: Do not use this zkey in production, as it's not safe. It requires at least a contribution,
The `zkey new` command creates an initial `zkey` file with zero contributions. The `zkey new` command creates an initial `zkey` file with zero contributions.
The `zkey` is a zero-knowledge key that includes both the proving and verification keys as well as phase 2 contributions. The `zkey` is a zero-knowledge key that includes both the proving and verification keys as well as phase 2 contributions.
@ -380,11 +398,20 @@ The `wtns debug` command logs every time a new component starts/ends (`--trigger
### 24. Create the proof ### 24. Create the proof
#### Plonk
```sh
snarkjs plonk prove circuit_final.zkey witness.wtns proof.json public.json
```
#### Groth16
```sh ```sh
snarkjs groth16 prove circuit_final.zkey witness.wtns proof.json public.json snarkjs groth16 prove circuit_final.zkey witness.wtns proof.json public.json
``` ```
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. We create the proof. this command 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: > Note that it's also possible to create the proof and calculate the witness in the same command by running:
> ```sh > ```sh
@ -393,11 +420,18 @@ We create the proof. `groth16 prove` generates the files `proof.json` and `publi
### 25. Verify the proof ### 25. Verify the proof
#### Plonk
```sh
snarkjs plonk verify verification_key.json public.json proof.json
```
#### Groth16
```sh ```sh
snarkjs groth16 verify verification_key.json public.json proof.json snarkjs groth16 verify verification_key.json public.json proof.json
``` ```
We use the `groth16 verify` command to verify the proof, passing in the `verification_key` we exported earlier. We use the this 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. If all is well, you should see that `OK` has been outputted to your console. This signifies the proof is valid.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

11
build/snarkjs.min.js vendored

File diff suppressed because one or more lines are too long

76
cli.js

@ -1,20 +1,20 @@
/* /*
Copyright 2018 0KIMS association. Copyright 2018 0KIMS association.
This file is part of jaz (Zero Knowledge Circuit Compiler). This file is part of snarkJS.
jaz is a free software: you can redistribute it and/or modify it snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
jaz is distributed in the hope that it will be useful, but WITHOUT snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details. License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with jaz. If not, see <https://www.gnu.org/licenses/>. along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/ */
/* eslint-disable no-console */ /* eslint-disable no-console */
@ -167,13 +167,6 @@ const commands = [
alias: ["wej"], alias: ["wej"],
action: wtnsExportJson action: wtnsExportJson
}, },
{
cmd: "zkey new [circuit.r1cs] [powersoftau.ptau] [circuit_0000.zkey]",
description: "Creates an initial pkey file with zero contributions ",
alias: ["zkn"],
options: "-verbose|v",
action: zkeyNew
},
{ {
cmd: "zkey contribute <circuit_old.zkey> <circuit_new.zkey>", cmd: "zkey contribute <circuit_old.zkey> <circuit_new.zkey>",
description: "creates a zkey file with a new contribution", description: "creates a zkey file with a new contribution",
@ -243,11 +236,18 @@ const commands = [
action: zkeyExportSolidityVerifier action: zkeyExportSolidityVerifier
}, },
{ {
cmd: "zkey export soliditycalldata <public.json> <proof.json>", cmd: "zkey export soliditycalldata [public.json] [proof.json]",
description: "Generates call parameters ready to be called.", description: "Generates call parameters ready to be called.",
alias: ["zkesc", "generatecall -pub|public -p|proof"], alias: ["zkesc", "generatecall -pub|public -p|proof"],
action: zkeyExportSolidityCalldata action: zkeyExportSolidityCalldata
}, },
{
cmd: "groth16 setup [circuit.r1cs] [powersoftau.ptau] [circuit_0000.zkey]",
description: "Creates an initial groth16 pkey file with zero contributions",
alias: ["g16s", "zkn", "zkey new"],
options: "-verbose|v",
action: zkeyNew
},
{ {
cmd: "groth16 prove [circuit_final.zkey] [witness.wtns] [proof.json] [public.json]", cmd: "groth16 prove [circuit_final.zkey] [witness.wtns] [proof.json] [public.json]",
description: "Generates a zk Proof from witness", description: "Generates a zk Proof from witness",
@ -331,13 +331,6 @@ TODO COMMANDS
*/ */
function p256(n) {
let nstr = n.toString(16);
while (nstr.length < 64) nstr = "0"+nstr;
nstr = `"0x${nstr}"`;
return nstr;
}
function changeExt(fileName, newExt) { function changeExt(fileName, newExt) {
let S = fileName; let S = fileName;
while ((S.length>0) && (S[S.length-1] != ".")) S = S.slice(0, S.length-1); while ((S.length>0) && (S[S.length-1] != ".")) S = S.slice(0, S.length-1);
@ -572,15 +565,12 @@ async function zkeyExportSolidityVerifier(params, options) {
if (options.verbose) Logger.setLogLevel("DEBUG"); if (options.verbose) Logger.setLogLevel("DEBUG");
let templateName; const templates = {};
try {
templateName = path.join( __dirname, "templates", "verifier_groth16.sol");
await fs.promises.stat(templateName);
} catch (err) {
templateName = path.join( __dirname, "..", "templates", "verifier_groth16.sol");
}
const verifierCode = await zkey.exportSolidityVerifier(zkeyName, templateName, logger); templates.groth16 = await fs.promises.readFile(path.join(__dirname, "templates", "verifier_groth16.sol.ejs"), "utf8");
templates.plonk = await fs.promises.readFile(path.join(__dirname, "templates", "verifier_plonk.sol.ejs"), "utf8");
const verifierCode = await zkey.exportSolidityVerifier(zkeyName, templates, logger);
fs.writeFileSync(verifierName, verifierCode, "utf-8"); fs.writeFileSync(verifierName, verifierCode, "utf-8");
@ -610,33 +600,15 @@ async function zkeyExportSolidityCalldata(params, options) {
const pub = unstringifyBigInts(JSON.parse(fs.readFileSync(publicName, "utf8"))); const pub = unstringifyBigInts(JSON.parse(fs.readFileSync(publicName, "utf8")));
const proof = unstringifyBigInts(JSON.parse(fs.readFileSync(proofName, "utf8"))); const proof = unstringifyBigInts(JSON.parse(fs.readFileSync(proofName, "utf8")));
let inputs = ""; let res;
for (let i=0; i<pub.length; i++) { if (proof.protocol == "groth16") {
if (inputs != "") inputs = inputs + ","; res = await groth16.exportSolidityCallData(proof, pub);
inputs = inputs + p256(pub[i]); } else if (proof.protocol == "plonk") {
} res = await plonk.exportSolidityCallData(proof, pub);
let S;
if ((typeof proof.protocol === "undefined") || (proof.protocol == "original")) {
S=`[${p256(proof.pi_a[0])}, ${p256(proof.pi_a[1])}],` +
`[${p256(proof.pi_ap[0])}, ${p256(proof.pi_ap[1])}],` +
`[[${p256(proof.pi_b[0][1])}, ${p256(proof.pi_b[0][0])}],[${p256(proof.pi_b[1][1])}, ${p256(proof.pi_b[1][0])}]],` +
`[${p256(proof.pi_bp[0])}, ${p256(proof.pi_bp[1])}],` +
`[${p256(proof.pi_c[0])}, ${p256(proof.pi_c[1])}],` +
`[${p256(proof.pi_cp[0])}, ${p256(proof.pi_cp[1])}],` +
`[${p256(proof.pi_h[0])}, ${p256(proof.pi_h[1])}],` +
`[${p256(proof.pi_kp[0])}, ${p256(proof.pi_kp[1])}],` +
`[${inputs}]`;
} else if ((proof.protocol == "groth16")||(proof.protocol == "kimleeoh")) {
S=`[${p256(proof.pi_a[0])}, ${p256(proof.pi_a[1])}],` +
`[[${p256(proof.pi_b[0][1])}, ${p256(proof.pi_b[0][0])}],[${p256(proof.pi_b[1][1])}, ${p256(proof.pi_b[1][0])}]],` +
`[${p256(proof.pi_c[0])}, ${p256(proof.pi_c[1])}],` +
`[${inputs}]`;
} else { } else {
throw new Error("InvalidProof"); throw new Error("Invalid Protocol");
} }
console.log(res);
console.log(S);
return 0; return 0;
} }

@ -24,6 +24,7 @@ export default {
os: empty, os: empty,
crypto: empty, crypto: empty,
readline: empty, readline: empty,
ejs: empty,
// Stub out a "global" module that we can inject later // Stub out a "global" module that we can inject later
global: empty, global: empty,
}), }),

@ -5,3 +5,4 @@ export * as powersOfTau from "./src/powersoftau.js";
export * as r1cs from "./src/r1cs.js"; export * as r1cs from "./src/r1cs.js";
export * as wtns from "./src/wtns.js"; export * as wtns from "./src/wtns.js";
export * as zKey from "./src/zkey.js"; export * as zKey from "./src/zkey.js";
export * as plonk from "./src/plonk.js";

340
package-lock.json generated

@ -11,8 +11,9 @@
"@iden3/binfileutils": "0.0.8", "@iden3/binfileutils": "0.0.8",
"blake2b-wasm": "https://github.com/jbaylina/blake2b-wasm.git", "blake2b-wasm": "https://github.com/jbaylina/blake2b-wasm.git",
"circom_runtime": "0.1.13", "circom_runtime": "0.1.13",
"ejs": "^3.1.6",
"fastfile": "0.0.19", "fastfile": "0.0.19",
"ffjavascript": "0.2.35", "ffjavascript": "0.2.36",
"js-sha3": "^0.8.0", "js-sha3": "^0.8.0",
"logplease": "^1.2.15", "logplease": "^1.2.15",
"r1csfile": "0.0.32", "r1csfile": "0.0.32",
@ -103,15 +104,6 @@
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true "dev": true
}, },
"node_modules/@babel/highlight/node_modules/escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true,
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/@babel/highlight/node_modules/has-flag": { "node_modules/@babel/highlight/node_modules/has-flag": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
@ -380,11 +372,15 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/async": {
"version": "0.9.2",
"resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
"integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0="
},
"node_modules/balanced-match": { "node_modules/balanced-match": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
"dev": true
}, },
"node_modules/big-integer": { "node_modules/big-integer": {
"version": "1.6.48", "version": "1.6.48",
@ -418,7 +414,6 @@
"version": "1.1.11", "version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"dependencies": { "dependencies": {
"balanced-match": "^1.0.0", "balanced-match": "^1.0.0",
"concat-map": "0.0.1" "concat-map": "0.0.1"
@ -542,6 +537,16 @@
"calcwit": "calcwit.js" "calcwit": "calcwit.js"
} }
}, },
"node_modules/circom_runtime/node_modules/ffjavascript": {
"version": "0.2.35",
"resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.35.tgz",
"integrity": "sha512-xnC51tWbi0ah4SH+02jEfJyO+P+NiZWnxQrLDLtBYY1Dv3QM5ydxzd+gxnLEfWdT8i1bMM5pIh5P25l6fNCaVQ==",
"dependencies": {
"big-integer": "^1.6.48",
"wasmcurves": "0.0.14",
"web-worker": "^1.0.0"
}
},
"node_modules/cli-cursor": { "node_modules/cli-cursor": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
@ -642,8 +647,7 @@
"node_modules/concat-map": { "node_modules/concat-map": {
"version": "0.0.1", "version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
"dev": true
}, },
"node_modules/cross-spawn": { "node_modules/cross-spawn": {
"version": "6.0.5", "version": "6.0.5",
@ -754,6 +758,20 @@
"node": ">=6.0.0" "node": ">=6.0.0"
} }
}, },
"node_modules/ejs": {
"version": "3.1.6",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz",
"integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==",
"dependencies": {
"jake": "^10.6.1"
},
"bin": {
"ejs": "bin/cli.js"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/emoji-regex": { "node_modules/emoji-regex": {
"version": "7.0.3", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
@ -823,6 +841,14 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/eslint": { "node_modules/eslint": {
"version": "6.8.0", "version": "6.8.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz",
@ -958,15 +984,6 @@
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true "dev": true
}, },
"node_modules/eslint/node_modules/escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true,
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/eslint/node_modules/has-flag": { "node_modules/eslint/node_modules/has-flag": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
@ -1131,9 +1148,9 @@
"integrity": "sha512-tz9nWR5KYb6eR2odFQ7oxqEkx8F3YQZ6NBJoJR92YEG3DqYOqyxMck8PKvTVNKx3uwvOqGnLXNScnqpdHRdHGQ==" "integrity": "sha512-tz9nWR5KYb6eR2odFQ7oxqEkx8F3YQZ6NBJoJR92YEG3DqYOqyxMck8PKvTVNKx3uwvOqGnLXNScnqpdHRdHGQ=="
}, },
"node_modules/ffjavascript": { "node_modules/ffjavascript": {
"version": "0.2.35", "version": "0.2.36",
"resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.35.tgz", "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.36.tgz",
"integrity": "sha512-xnC51tWbi0ah4SH+02jEfJyO+P+NiZWnxQrLDLtBYY1Dv3QM5ydxzd+gxnLEfWdT8i1bMM5pIh5P25l6fNCaVQ==", "integrity": "sha512-OPgov0qQiV7wffycylpmEq6rm4Pu68LIMFbB1jrM5bCr1yXqgIMQ6IparbgRuFG5aj3NPmsorrGh7pQJnQlIIw==",
"dependencies": { "dependencies": {
"big-integer": "^1.6.48", "big-integer": "^1.6.48",
"wasmcurves": "0.0.14", "wasmcurves": "0.0.14",
@ -1152,15 +1169,6 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/figures/node_modules/escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true,
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/file-entry-cache": { "node_modules/file-entry-cache": {
"version": "5.0.1", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz",
@ -1173,6 +1181,14 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/filelist": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz",
"integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==",
"dependencies": {
"minimatch": "^3.0.4"
}
},
"node_modules/fill-range": { "node_modules/fill-range": {
"version": "7.0.1", "version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
@ -1657,6 +1673,79 @@
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
"dev": true "dev": true
}, },
"node_modules/jake": {
"version": "10.8.2",
"resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz",
"integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==",
"dependencies": {
"async": "0.9.x",
"chalk": "^2.4.2",
"filelist": "^1.0.1",
"minimatch": "^3.0.4"
},
"bin": {
"jake": "bin/cli.js"
},
"engines": {
"node": "*"
}
},
"node_modules/jake/node_modules/ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dependencies": {
"color-convert": "^1.9.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/jake/node_modules/chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"dependencies": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/jake/node_modules/color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dependencies": {
"color-name": "1.1.3"
}
},
"node_modules/jake/node_modules/color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
"node_modules/jake/node_modules/has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"engines": {
"node": ">=4"
}
},
"node_modules/jake/node_modules/supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dependencies": {
"has-flag": "^3.0.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/jest-worker": { "node_modules/jest-worker": {
"version": "26.6.2", "version": "26.6.2",
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz",
@ -1721,9 +1810,9 @@
} }
}, },
"node_modules/lodash": { "node_modules/lodash": {
"version": "4.17.20", "version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true "dev": true
}, },
"node_modules/logplease": { "node_modules/logplease": {
@ -1759,7 +1848,6 @@
"version": "3.0.4", "version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"dependencies": { "dependencies": {
"brace-expansion": "^1.1.7" "brace-expansion": "^1.1.7"
}, },
@ -1925,15 +2013,6 @@
"node": ">=0.3.1" "node": ">=0.3.1"
} }
}, },
"node_modules/mocha/node_modules/escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true,
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/mocha/node_modules/find-up": { "node_modules/mocha/node_modules/find-up": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
@ -2394,6 +2473,16 @@
"ffjavascript": "0.2.35" "ffjavascript": "0.2.35"
} }
}, },
"node_modules/r1csfile/node_modules/ffjavascript": {
"version": "0.2.35",
"resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.35.tgz",
"integrity": "sha512-xnC51tWbi0ah4SH+02jEfJyO+P+NiZWnxQrLDLtBYY1Dv3QM5ydxzd+gxnLEfWdT8i1bMM5pIh5P25l6fNCaVQ==",
"dependencies": {
"big-integer": "^1.6.48",
"wasmcurves": "0.0.14",
"web-worker": "^1.0.0"
}
},
"node_modules/randombytes": { "node_modules/randombytes": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@ -3339,12 +3428,6 @@
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true "dev": true
}, },
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true
},
"has-flag": { "has-flag": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
@ -3576,11 +3659,15 @@
"integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
"dev": true "dev": true
}, },
"async": {
"version": "0.9.2",
"resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
"integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0="
},
"balanced-match": { "balanced-match": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
"dev": true
}, },
"big-integer": { "big-integer": {
"version": "1.6.48", "version": "1.6.48",
@ -3609,7 +3696,6 @@
"version": "1.1.11", "version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"requires": { "requires": {
"balanced-match": "^1.0.0", "balanced-match": "^1.0.0",
"concat-map": "0.0.1" "concat-map": "0.0.1"
@ -3707,6 +3793,18 @@
"requires": { "requires": {
"ffjavascript": "0.2.35", "ffjavascript": "0.2.35",
"fnv-plus": "^1.3.1" "fnv-plus": "^1.3.1"
},
"dependencies": {
"ffjavascript": {
"version": "0.2.35",
"resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.35.tgz",
"integrity": "sha512-xnC51tWbi0ah4SH+02jEfJyO+P+NiZWnxQrLDLtBYY1Dv3QM5ydxzd+gxnLEfWdT8i1bMM5pIh5P25l6fNCaVQ==",
"requires": {
"big-integer": "^1.6.48",
"wasmcurves": "0.0.14",
"web-worker": "^1.0.0"
}
}
} }
}, },
"cli-cursor": { "cli-cursor": {
@ -3793,8 +3891,7 @@
"concat-map": { "concat-map": {
"version": "0.0.1", "version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
"dev": true
}, },
"cross-spawn": { "cross-spawn": {
"version": "6.0.5", "version": "6.0.5",
@ -3880,6 +3977,14 @@
"esutils": "^2.0.2" "esutils": "^2.0.2"
} }
}, },
"ejs": {
"version": "3.1.6",
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz",
"integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==",
"requires": {
"jake": "^10.6.1"
}
},
"emoji-regex": { "emoji-regex": {
"version": "7.0.3", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
@ -3939,6 +4044,11 @@
"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
"dev": true "dev": true
}, },
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
},
"eslint": { "eslint": {
"version": "6.8.0", "version": "6.8.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz",
@ -4025,12 +4135,6 @@
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true "dev": true
}, },
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true
},
"has-flag": { "has-flag": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
@ -4186,9 +4290,9 @@
"integrity": "sha512-tz9nWR5KYb6eR2odFQ7oxqEkx8F3YQZ6NBJoJR92YEG3DqYOqyxMck8PKvTVNKx3uwvOqGnLXNScnqpdHRdHGQ==" "integrity": "sha512-tz9nWR5KYb6eR2odFQ7oxqEkx8F3YQZ6NBJoJR92YEG3DqYOqyxMck8PKvTVNKx3uwvOqGnLXNScnqpdHRdHGQ=="
}, },
"ffjavascript": { "ffjavascript": {
"version": "0.2.35", "version": "0.2.36",
"resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.35.tgz", "resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.36.tgz",
"integrity": "sha512-xnC51tWbi0ah4SH+02jEfJyO+P+NiZWnxQrLDLtBYY1Dv3QM5ydxzd+gxnLEfWdT8i1bMM5pIh5P25l6fNCaVQ==", "integrity": "sha512-OPgov0qQiV7wffycylpmEq6rm4Pu68LIMFbB1jrM5bCr1yXqgIMQ6IparbgRuFG5aj3NPmsorrGh7pQJnQlIIw==",
"requires": { "requires": {
"big-integer": "^1.6.48", "big-integer": "^1.6.48",
"wasmcurves": "0.0.14", "wasmcurves": "0.0.14",
@ -4202,14 +4306,6 @@
"dev": true, "dev": true,
"requires": { "requires": {
"escape-string-regexp": "^1.0.5" "escape-string-regexp": "^1.0.5"
},
"dependencies": {
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true
}
} }
}, },
"file-entry-cache": { "file-entry-cache": {
@ -4221,6 +4317,14 @@
"flat-cache": "^2.0.1" "flat-cache": "^2.0.1"
} }
}, },
"filelist": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz",
"integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==",
"requires": {
"minimatch": "^3.0.4"
}
},
"fill-range": { "fill-range": {
"version": "7.0.1", "version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
@ -4596,6 +4700,63 @@
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
"dev": true "dev": true
}, },
"jake": {
"version": "10.8.2",
"resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz",
"integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==",
"requires": {
"async": "0.9.x",
"chalk": "^2.4.2",
"filelist": "^1.0.1",
"minimatch": "^3.0.4"
},
"dependencies": {
"ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"requires": {
"color-convert": "^1.9.0"
}
},
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
}
},
"color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"requires": {
"color-name": "1.1.3"
}
},
"color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"requires": {
"has-flag": "^3.0.0"
}
}
}
},
"jest-worker": { "jest-worker": {
"version": "26.6.2", "version": "26.6.2",
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz",
@ -4651,9 +4812,9 @@
} }
}, },
"lodash": { "lodash": {
"version": "4.17.20", "version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true "dev": true
}, },
"logplease": { "logplease": {
@ -4686,7 +4847,6 @@
"version": "3.0.4", "version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"requires": { "requires": {
"brace-expansion": "^1.1.7" "brace-expansion": "^1.1.7"
} }
@ -4821,12 +4981,6 @@
"integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
"dev": true "dev": true
}, },
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true
},
"find-up": { "find-up": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
@ -5184,6 +5338,18 @@
"@iden3/binfileutils": "0.0.8", "@iden3/binfileutils": "0.0.8",
"fastfile": "0.0.19", "fastfile": "0.0.19",
"ffjavascript": "0.2.35" "ffjavascript": "0.2.35"
},
"dependencies": {
"ffjavascript": {
"version": "0.2.35",
"resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.35.tgz",
"integrity": "sha512-xnC51tWbi0ah4SH+02jEfJyO+P+NiZWnxQrLDLtBYY1Dv3QM5ydxzd+gxnLEfWdT8i1bMM5pIh5P25l6fNCaVQ==",
"requires": {
"big-integer": "^1.6.48",
"wasmcurves": "0.0.14",
"web-worker": "^1.0.0"
}
}
} }
}, },
"randombytes": { "randombytes": {

@ -41,8 +41,9 @@
"@iden3/binfileutils": "0.0.8", "@iden3/binfileutils": "0.0.8",
"blake2b-wasm": "https://github.com/jbaylina/blake2b-wasm.git", "blake2b-wasm": "https://github.com/jbaylina/blake2b-wasm.git",
"circom_runtime": "0.1.13", "circom_runtime": "0.1.13",
"ejs": "^3.1.6",
"fastfile": "0.0.19", "fastfile": "0.0.19",
"ffjavascript": "0.2.35", "ffjavascript": "0.2.36",
"js-sha3": "^0.8.0", "js-sha3": "^0.8.0",
"logplease": "^1.2.15", "logplease": "^1.2.15",
"r1csfile": "0.0.32", "r1csfile": "0.0.32",

@ -1,3 +1,22 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
const SUBARRAY_SIZE = 0x40000; const SUBARRAY_SIZE = 0x40000;
const BigArrayHandler = { const BigArrayHandler = {

@ -1,3 +1,22 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
/* /*
import pkg from "../package.json"; import pkg from "../package.json";
const version = pkg.version; const version = pkg.version;

@ -1,3 +1,23 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
export {default as fullProve} from "./groth16_fullprove.js"; export {default as fullProve} from "./groth16_fullprove.js";
export {default as prove} from "./groth16_prove.js"; export {default as prove} from "./groth16_prove.js";
export {default as verify} from "./groth16_verify.js"; export {default as verify} from "./groth16_verify.js";
export {default as exportSolidityCallData} from "./groth16_exportsoliditycalldata.js";

@ -0,0 +1,42 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
function p256(n) {
let nstr = n.toString(16);
while (nstr.length < 64) nstr = "0"+nstr;
nstr = `"0x${nstr}"`;
return nstr;
}
export default async function groth16ExportSolidityCallData(proof, pub) {
let inputs = "";
for (let i=0; i<pub.length; i++) {
if (inputs != "") inputs = inputs + ",";
inputs = inputs + p256(pub[i]);
}
let S;
S=`[${p256(proof.pi_a[0])}, ${p256(proof.pi_a[1])}],` +
`[[${p256(proof.pi_b[0][1])}, ${p256(proof.pi_b[0][0])}],[${p256(proof.pi_b[1][1])}, ${p256(proof.pi_b[1][0])}]],` +
`[${p256(proof.pi_c[0])}, ${p256(proof.pi_c[1])}],` +
`[${inputs}]`;
return S;
}

@ -1,3 +1,22 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
import groth16_prove from "./groth16_prove.js"; import groth16_prove from "./groth16_prove.js";
import wtns_calculate from "./wtns_calculate.js"; import wtns_calculate from "./wtns_calculate.js";

@ -1,3 +1,22 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
import * as binFileUtils from "@iden3/binfileutils"; import * as binFileUtils from "@iden3/binfileutils";
import * as zkeyUtils from "./zkey_utils.js"; import * as zkeyUtils from "./zkey_utils.js";
import * as wtnsUtils from "./wtns_utils.js"; import * as wtnsUtils from "./wtns_utils.js";
@ -113,6 +132,7 @@ export default async function groth16Prove(zkeyFileName, witnessFileName, logger
proof.pi_c = G1.toObject(G1.toAffine(proof.pi_c)); proof.pi_c = G1.toObject(G1.toAffine(proof.pi_c));
proof.protocol = "groth16"; proof.protocol = "groth16";
proof.curve = curve.name;
await fdZKey.close(); await fdZKey.close();
await fdWtns.close(); await fdWtns.close();

@ -1,3 +1,21 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
import blake2b from "blake2b-wasm"; import blake2b from "blake2b-wasm";

@ -1,3 +1,22 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
import * as fastFile from "fastfile"; import * as fastFile from "fastfile";
export default async function loadSymbols(symFileName) { export default async function loadSymbols(symFileName) {

@ -1,3 +1,22 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
/* global window */ /* global window */
import Blake2b from "blake2b-wasm"; import Blake2b from "blake2b-wasm";
import readline from "readline"; import readline from "readline";

@ -1,3 +1,21 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
import * as binFileUtils from "@iden3/binfileutils"; import * as binFileUtils from "@iden3/binfileutils";

@ -1,4 +1,24 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
export {default as setup} from "./plonk_setup.js"; export {default as setup} from "./plonk_setup.js";
export {default as fullProve} from "./plonk_fullprove.js"; export {default as fullProve} from "./plonk_fullprove.js";
export {default as prove} from "./plonk_prove.js"; export {default as prove} from "./plonk_prove.js";
export {default as verify} from "./plonk_verify.js"; export {default as verify} from "./plonk_verify.js";
export {default as exportSolidityCallData} from "./plonk_exportsoliditycalldata.js";

@ -0,0 +1,68 @@
/*
Copyright 2021 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
import { getCurveFromName } from "./curves.js";
function i2hex(i) {
return ("0" + i.toString(16)).slice(-2);
}
function p256(n) {
let nstr = n.toString(16);
while (nstr.length < 64) nstr = "0"+nstr;
nstr = `"0x${nstr}"`;
return nstr;
}
export default async function plonkExportSolidityCallData(proof, pub) {
const curve = await getCurveFromName(proof.curve);
const G1 = curve.G1;
const Fr = curve.Fr;
let inputs = "";
for (let i=0; i<pub.length; i++) {
if (inputs != "") inputs = inputs + ",";
inputs = inputs + p256(pub[i]);
}
const proofBuff = new Uint8Array(G1.F.n8*2*9 + Fr.n8*7);
G1.toRprUncompressed(proofBuff, 0, G1.e(proof.A));
G1.toRprUncompressed(proofBuff, G1.F.n8*2, G1.e(proof.B));
G1.toRprUncompressed(proofBuff, G1.F.n8*4, G1.e(proof.C));
G1.toRprUncompressed(proofBuff, G1.F.n8*6, G1.e(proof.Z));
G1.toRprUncompressed(proofBuff, G1.F.n8*8, G1.e(proof.T1));
G1.toRprUncompressed(proofBuff, G1.F.n8*10, G1.e(proof.T2));
G1.toRprUncompressed(proofBuff, G1.F.n8*12, G1.e(proof.T3));
G1.toRprUncompressed(proofBuff, G1.F.n8*14, G1.e(proof.Wxi));
G1.toRprUncompressed(proofBuff, G1.F.n8*16, G1.e(proof.Wxiw));
Fr.toRprBE(proofBuff, G1.F.n8*18 , Fr.e(proof.eval_a));
Fr.toRprBE(proofBuff, G1.F.n8*18 + Fr.n8, Fr.e(proof.eval_b));
Fr.toRprBE(proofBuff, G1.F.n8*18 + Fr.n8*2, Fr.e(proof.eval_c));
Fr.toRprBE(proofBuff, G1.F.n8*18 + Fr.n8*3, Fr.e(proof.eval_s1));
Fr.toRprBE(proofBuff, G1.F.n8*18 + Fr.n8*4, Fr.e(proof.eval_s2));
Fr.toRprBE(proofBuff, G1.F.n8*18 + Fr.n8*5, Fr.e(proof.eval_zw));
Fr.toRprBE(proofBuff, G1.F.n8*18 + Fr.n8*6, Fr.e(proof.eval_r));
const proofHex = Array.from(proofBuff).map(i2hex).join("");
const S="0x"+proofHex+",["+inputs+"]";
return S;
}

@ -1,3 +1,22 @@
/*
Copyright 2021 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
import plonk_prove from "./plonk_prove.js"; import plonk_prove from "./plonk_prove.js";
import wtns_calculate from "./wtns_calculate.js"; import wtns_calculate from "./wtns_calculate.js";

@ -98,6 +98,7 @@ export default async function plonk16Prove(zkeyFileName, witnessFileName, logger
/////////////////////// ///////////////////////
proof.protocol = "plonk"; proof.protocol = "plonk";
proof.curve = curve.name;
await fdZKey.close(); await fdZKey.close();
await fdWtns.close(); await fdWtns.close();
@ -130,6 +131,8 @@ export default async function plonk16Prove(zkeyFileName, witnessFileName, logger
proof.Wxi = G1.toObject(proof.Wxi); proof.Wxi = G1.toObject(proof.Wxi);
proof.Wxiw = G1.toObject(proof.Wxiw); proof.Wxiw = G1.toObject(proof.Wxiw);
delete proof.eval_t;
proof = stringifyBigInts(proof); proof = stringifyBigInts(proof);
publicSignals = stringifyBigInts(publicSignals); publicSignals = stringifyBigInts(publicSignals);
@ -313,7 +316,6 @@ export default async function plonk16Prove(zkeyFileName, witnessFileName, logger
while ((deg>0)&&(Fr.isZero(p.slice(deg*n8r, deg*n8r+n8r)))) deg--; while ((deg>0)&&(Fr.isZero(p.slice(deg*n8r, deg*n8r+n8r)))) deg--;
return deg; return deg;
} }
*/
function printPol(P) { function printPol(P) {
const n=(P.byteLength/n8r); const n=(P.byteLength/n8r);
@ -323,6 +325,7 @@ export default async function plonk16Prove(zkeyFileName, witnessFileName, logger
} }
console.log("]"); console.log("]");
} }
*/
const QM4 = new BigBuffer(zkey.domainSize*4*n8r); const QM4 = new BigBuffer(zkey.domainSize*4*n8r);
await fdZKey.readToBuffer(QM4, 0 , zkey.domainSize*n8r*4, sectionsZKey[7][0].p + zkey.domainSize*n8r); await fdZKey.readToBuffer(QM4, 0 , zkey.domainSize*n8r*4, sectionsZKey[7][0].p + zkey.domainSize*n8r);
@ -370,19 +373,6 @@ export default async function plonk16Prove(zkeyFileName, witnessFileName, logger
Fr.sub(Fr.e(2), Fr.mul(Fr.e(2), Fr.w[2])), Fr.sub(Fr.e(2), Fr.mul(Fr.e(2), Fr.w[2])),
]; ];
/*
const Zw = new BigBuffer(zkey.domainSize*4*n8r);
for (let i=0; i<zkey.domainSize*4; i++) {
Zw.set(
Z4.slice(((i+zkey.domainSize*4+4)%(zkey.domainSize*4)) *n8r, ((i+zkey.domainSize*4+4)%(zkey.domainSize*4)) *n8r +n8r),
i*n8r
);
}
const degZw = await checkDegree(Zw);
printPol(Zw);
console.log("degZw: " + degZw);
*/
const T = new BigBuffer(zkey.domainSize*4*n8r); const T = new BigBuffer(zkey.domainSize*4*n8r);
const Tz = new BigBuffer(zkey.domainSize*4*n8r); const Tz = new BigBuffer(zkey.domainSize*4*n8r);
@ -487,8 +477,6 @@ export default async function plonk16Prove(zkeyFileName, witnessFileName, logger
w = Fr.mul(w, Fr.w[zkey.power+2]); w = Fr.mul(w, Fr.w[zkey.power+2]);
} }
printPol(T);
let t = await Fr.ifft(T); let t = await Fr.ifft(T);
for (let i=0; i<zkey.domainSize; i++) { for (let i=0; i<zkey.domainSize; i++) {
@ -509,7 +497,6 @@ export default async function plonk16Prove(zkeyFileName, witnessFileName, logger
} }
const tz = await Fr.ifft(Tz); const tz = await Fr.ifft(Tz);
printPol(tz);
for (let i=0; i<zkey.domainSize*4; i++) { for (let i=0; i<zkey.domainSize*4; i++) {
const a = tz.slice(i*n8r, (i+1)*n8r); const a = tz.slice(i*n8r, (i+1)*n8r);
if (i > (zkey.domainSize*3 +5) ) { if (i > (zkey.domainSize*3 +5) ) {
@ -698,15 +685,14 @@ export default async function plonk16Prove(zkeyFileName, witnessFileName, logger
} }
async function round5() { async function round5() {
const transcript5 = new Uint8Array(n8r*8); const transcript5 = new Uint8Array(n8r*7);
Fr.toRprBE(transcript5, 0, proof.eval_a); Fr.toRprBE(transcript5, 0, proof.eval_a);
Fr.toRprBE(transcript5, n8r, proof.eval_b); Fr.toRprBE(transcript5, n8r, proof.eval_b);
Fr.toRprBE(transcript5, n8r*2, proof.eval_c); Fr.toRprBE(transcript5, n8r*2, proof.eval_c);
Fr.toRprBE(transcript5, n8r*3, proof.eval_s1); Fr.toRprBE(transcript5, n8r*3, proof.eval_s1);
Fr.toRprBE(transcript5, n8r*4, proof.eval_s2); Fr.toRprBE(transcript5, n8r*4, proof.eval_s2);
Fr.toRprBE(transcript5, n8r*5, proof.eval_zw); Fr.toRprBE(transcript5, n8r*5, proof.eval_zw);
Fr.toRprBE(transcript5, n8r*6, proof.eval_t); Fr.toRprBE(transcript5, n8r*6, proof.eval_r);
Fr.toRprBE(transcript5, n8r*7, proof.eval_r);
ch.v = []; ch.v = [];
ch.v[1] = hashToFr(transcript5); ch.v[1] = hashToFr(transcript5);
if (logger) logger.debug("v: " + Fr.toString(ch.v[1])); if (logger) logger.debug("v: " + Fr.toString(ch.v[1]));

@ -61,7 +61,7 @@ export default async function plonkSetup(r1csName, ptauName, zkeyName, logger) {
await processConstraints(); await processConstraints();
const fdZKey = await createBinFile(zkeyName, "zkey", 1, 15, 1<<22, 1<<24); const fdZKey = await createBinFile(zkeyName, "zkey", 1, 14, 1<<22, 1<<24);
if (r1cs.prime != curve.r) { if (r1cs.prime != curve.r) {

@ -44,18 +44,19 @@ export default async function plonkVerify(vk_verifier, publicSignals, proof, log
} }
const challanges = calculateChallanges(curve, proof); const challanges = calculateChallanges(curve, proof);
if (logger) { if (logger) {
logger.debug("beta: " + Fr.toString(challanges.beta)); logger.debug("beta: " + Fr.toString(challanges.beta, 16));
logger.debug("gamma: " + Fr.toString(challanges.gamma)); logger.debug("gamma: " + Fr.toString(challanges.gamma, 16));
logger.debug("alpha: " + Fr.toString(challanges.alpha)); logger.debug("alpha: " + Fr.toString(challanges.alpha, 16));
logger.debug("xi: " + Fr.toString(challanges.xi)); logger.debug("xi: " + Fr.toString(challanges.xi, 16));
logger.debug("v: " + Fr.toString(challanges.v)); logger.debug("v1: " + Fr.toString(challanges.v[1], 16));
logger.debug("u: " + Fr.toString(challanges.u)); logger.debug("v6: " + Fr.toString(challanges.v[6], 16));
logger.debug("u: " + Fr.toString(challanges.u, 16));
} }
const L = calculateLagrangeEvaluations(curve, challanges, vk_verifier); const L = calculateLagrangeEvaluations(curve, challanges, vk_verifier);
if (logger) { if (logger) {
logger.debug("Lagrange Evaluations: "); logger.debug("Lagrange Evaluations: ");
for (let i=1; i<L.length; i++) { for (let i=1; i<L.length; i++) {
logger.debug(`L${i}(xi)=` + Fr.toString(L[i])); logger.debug(`L${i}(xi)=` + Fr.toString(L[i], 16));
} }
} }
@ -66,27 +67,27 @@ export default async function plonkVerify(vk_verifier, publicSignals, proof, log
const pl = calculatePl(curve, publicSignals, L); const pl = calculatePl(curve, publicSignals, L);
if (logger) { if (logger) {
logger.debug("Pl: " + Fr.toString(pl)); logger.debug("Pl: " + Fr.toString(pl, 16));
} }
const t = calculateT(curve, proof, challanges, pl, L[1]); const t = calculateT(curve, proof, challanges, pl, L[1]);
if (logger) { if (logger) {
logger.debug("t: " + Fr.toString(t)); logger.debug("t: " + Fr.toString(t, 16));
} }
const D = calculateD(curve, proof, challanges, vk_verifier, L[1]); const D = calculateD(curve, proof, challanges, vk_verifier, L[1]);
if (logger) { if (logger) {
logger.debug("D: " + G1.toString(D)); logger.debug("D: " + G1.toString(G1.toAffine(D), 16));
} }
const F = calculateF(curve, proof, challanges, vk_verifier, D); const F = calculateF(curve, proof, challanges, vk_verifier, D);
if (logger) { if (logger) {
logger.debug("F: " + G1.toString(F)); logger.debug("F: " + G1.toString(G1.toAffine(F), 16));
} }
const E = calculateE(curve, proof, challanges, vk_verifier, t); const E = calculateE(curve, proof, challanges, vk_verifier, t);
if (logger) { if (logger) {
logger.debug("E: " + G1.toString(E)); logger.debug("E: " + G1.toString(G1.toAffine(E), 16));
} }
const res = await isValidPairing(curve, proof, challanges, vk_verifier, E, F); const res = await isValidPairing(curve, proof, challanges, vk_verifier, E, F);
@ -121,7 +122,6 @@ function fromObjectProof(curve, proof) {
res.eval_zw = Fr.fromObject(proof.eval_zw); res.eval_zw = Fr.fromObject(proof.eval_zw);
res.eval_s1 = Fr.fromObject(proof.eval_s1); res.eval_s1 = Fr.fromObject(proof.eval_s1);
res.eval_s2 = Fr.fromObject(proof.eval_s2); res.eval_s2 = Fr.fromObject(proof.eval_s2);
res.eval_t = Fr.fromObject(proof.eval_t);
res.eval_r = Fr.fromObject(proof.eval_r); res.eval_r = Fr.fromObject(proof.eval_r);
res.Wxi = G1.fromObject(proof.Wxi); res.Wxi = G1.fromObject(proof.Wxi);
res.Wxiw = G1.fromObject(proof.Wxiw); res.Wxiw = G1.fromObject(proof.Wxiw);
@ -181,7 +181,6 @@ function calculateChallanges(curve, proof) {
const transcript3 = new Uint8Array(G1.F.n8*2); const transcript3 = new Uint8Array(G1.F.n8*2);
G1.toRprUncompressed(transcript3, 0, proof.Z); G1.toRprUncompressed(transcript3, 0, proof.Z);
res.alpha = hashToFr(curve, transcript3); res.alpha = hashToFr(curve, transcript3);
console.log("Alpha: ", res.alpha);
const transcript4 = new Uint8Array(G1.F.n8*2*3); const transcript4 = new Uint8Array(G1.F.n8*2*3);
G1.toRprUncompressed(transcript4, 0, proof.T1); G1.toRprUncompressed(transcript4, 0, proof.T1);
@ -189,15 +188,14 @@ function calculateChallanges(curve, proof) {
G1.toRprUncompressed(transcript4, G1.F.n8*4, proof.T3); G1.toRprUncompressed(transcript4, G1.F.n8*4, proof.T3);
res.xi = hashToFr(curve, transcript4); res.xi = hashToFr(curve, transcript4);
const transcript5 = new Uint8Array(n8r*8); const transcript5 = new Uint8Array(n8r*7);
Fr.toRprBE(transcript5, 0, proof.eval_a); Fr.toRprBE(transcript5, 0, proof.eval_a);
Fr.toRprBE(transcript5, n8r, proof.eval_b); Fr.toRprBE(transcript5, n8r, proof.eval_b);
Fr.toRprBE(transcript5, n8r*2, proof.eval_c); Fr.toRprBE(transcript5, n8r*2, proof.eval_c);
Fr.toRprBE(transcript5, n8r*3, proof.eval_s1); Fr.toRprBE(transcript5, n8r*3, proof.eval_s1);
Fr.toRprBE(transcript5, n8r*4, proof.eval_s2); Fr.toRprBE(transcript5, n8r*4, proof.eval_s2);
Fr.toRprBE(transcript5, n8r*5, proof.eval_zw); Fr.toRprBE(transcript5, n8r*5, proof.eval_zw);
Fr.toRprBE(transcript5, n8r*6, proof.eval_t); Fr.toRprBE(transcript5, n8r*6, proof.eval_r);
Fr.toRprBE(transcript5, n8r*7, proof.eval_r);
res.v = []; res.v = [];
res.v[1] = hashToFr(curve, transcript5); res.v[1] = hashToFr(curve, transcript5);
@ -277,14 +275,6 @@ function calculateT(curve, proof, challanges, pl, l1) {
const t = Fr.div(num, challanges.zh); const t = Fr.div(num, challanges.zh);
if (!Fr.eq(t, proof.eval_t)) {
console.log("t DOES NOT MATCH");
} else {
console.log("t OK");
}
console.log(Fr.toString(proof.eval_t));
console.log(Fr.toString(t));
return t; return t;
} }

@ -1,3 +1,21 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
export {default as newAccumulator} from "./powersoftau_new.js"; export {default as newAccumulator} from "./powersoftau_new.js";
export {default as exportChallenge} from "./powersoftau_export_challenge.js"; export {default as exportChallenge} from "./powersoftau_export_challenge.js";

@ -1,10 +1,27 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
import Blake2b from "blake2b-wasm"; import Blake2b from "blake2b-wasm";
import * as utils from "./powersoftau_utils.js"; import * as utils from "./powersoftau_utils.js";
import * as misc from "./misc.js"; import * as misc from "./misc.js";
import * as binFileUtils from "@iden3/binfileutils"; import * as binFileUtils from "@iden3/binfileutils";
export default async function beacon(oldPtauFilename, newPTauFilename, name, beaconHashStr,numIterationsExp, logger) { export default async function beacon(oldPtauFilename, newPTauFilename, name, beaconHashStr,numIterationsExp, logger) {
const beaconHash = misc.hex2ByteArray(beaconHashStr); const beaconHash = misc.hex2ByteArray(beaconHashStr);
if ( (beaconHash.byteLength == 0) if ( (beaconHash.byteLength == 0)

@ -1,3 +1,22 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
// Format of the output // Format of the output
// Hash of the last contribution 64 Bytes // Hash of the last contribution 64 Bytes
// 2^N*2-1 TauG1 Points (compressed) // 2^N*2-1 TauG1 Points (compressed)

@ -1,3 +1,22 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
// Format of the output // Format of the output
// Hash of the last contribution 64 Bytes // Hash of the last contribution 64 Bytes
// 2^N*2-1 TauG1 Points (uncompressed) // 2^N*2-1 TauG1 Points (uncompressed)

@ -1,3 +1,22 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
import * as binFileUtils from "@iden3/binfileutils"; import * as binFileUtils from "@iden3/binfileutils";
import * as utils from "./powersoftau_utils.js"; import * as utils from "./powersoftau_utils.js";
import * as fastFile from "fastfile"; import * as fastFile from "fastfile";

@ -1,3 +1,22 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
import * as utils from "./powersoftau_utils.js"; import * as utils from "./powersoftau_utils.js";
import * as binFileUtils from "@iden3/binfileutils"; import * as binFileUtils from "@iden3/binfileutils";

@ -1,3 +1,22 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
import * as fastFile from "fastfile"; import * as fastFile from "fastfile";
import Blake2b from "blake2b-wasm"; import Blake2b from "blake2b-wasm";
import * as utils from "./powersoftau_utils.js"; import * as utils from "./powersoftau_utils.js";

@ -1,3 +1,22 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
/* /*
Header(1) Header(1)
n8 n8

@ -1,3 +1,22 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
import * as binFileUtils from "@iden3/binfileutils"; import * as binFileUtils from "@iden3/binfileutils";
import * as utils from "./powersoftau_utils.js"; import * as utils from "./powersoftau_utils.js";
import {BigBuffer} from "ffjavascript"; import {BigBuffer} from "ffjavascript";

@ -1,3 +1,21 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
import * as binFileUtils from "@iden3/binfileutils"; import * as binFileUtils from "@iden3/binfileutils";
import * as utils from "./powersoftau_utils.js"; import * as utils from "./powersoftau_utils.js";

@ -1,3 +1,22 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
import { Scalar } from "ffjavascript"; import { Scalar } from "ffjavascript";
import Blake2b from "blake2b-wasm"; import Blake2b from "blake2b-wasm";
import * as keyPair from "./keypair.js"; import * as keyPair from "./keypair.js";

@ -1,3 +1,22 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
import Blake2b from "blake2b-wasm"; import Blake2b from "blake2b-wasm";
import * as utils from "./powersoftau_utils.js"; import * as utils from "./powersoftau_utils.js";
import * as keyPair from "./keypair.js"; import * as keyPair from "./keypair.js";

@ -1,3 +1,22 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
export {default as print} from "./r1cs_print.js"; export {default as print} from "./r1cs_print.js";
export {default as info} from "./r1cs_info.js"; export {default as info} from "./r1cs_info.js";
export {default as exportJson} from "./r1cs_export_json.js"; export {default as exportJson} from "./r1cs_export_json.js";

@ -1,3 +1,22 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
import {readR1cs} from "r1csfile"; import {readR1cs} from "r1csfile";
export function stringifyBigInts(Fr, o) { export function stringifyBigInts(Fr, o) {

@ -1,3 +1,22 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
import { Scalar } from "ffjavascript"; import { Scalar } from "ffjavascript";
import { readR1cs } from "r1csfile"; import { readR1cs } from "r1csfile";

@ -1,3 +1,21 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
export default function r1csPrint(r1cs, syms, logger) { export default function r1csPrint(r1cs, syms, logger) {
for (let i=0; i<r1cs.constraints.length; i++) { for (let i=0; i<r1cs.constraints.length; i++) {

@ -1,3 +1,22 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
export {default as genGroth16Verifier} from "./solidity_gengroth16verifier.js"; export {default as genGroth16Verifier} from "./solidity_gengroth16verifier.js";
export {default as prove} from "./groth16_prove.js"; export {default as prove} from "./groth16_prove.js";
export {default as validate} from "./groth16_verify.js"; export {default as validate} from "./groth16_verify.js";

@ -1,3 +1,22 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
const inBrowser = (typeof window !== "undefined"); const inBrowser = (typeof window !== "undefined");
let NodeWorker; let NodeWorker;
if (!inBrowser) { if (!inBrowser) {

@ -1,3 +1,22 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
export {default as calculate} from "./wtns_calculate.js"; export {default as calculate} from "./wtns_calculate.js";
export {default as debug} from "./wtns_debug.js"; export {default as debug} from "./wtns_debug.js";
export {default as exportJson} from "./wtns_export_json.js"; export {default as exportJson} from "./wtns_export_json.js";

@ -1,3 +1,22 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
import * as fastFile from "fastfile"; import * as fastFile from "fastfile";
import { WitnessCalculatorBuilder } from "circom_runtime"; import { WitnessCalculatorBuilder } from "circom_runtime";
import * as wtnsUtils from "./wtns_utils.js"; import * as wtnsUtils from "./wtns_utils.js";

@ -1,3 +1,22 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
import * as fastFile from "fastfile"; import * as fastFile from "fastfile";
import { WitnessCalculatorBuilder } from "circom_runtime"; import { WitnessCalculatorBuilder } from "circom_runtime";
import * as wtnsUtils from "./wtns_utils.js"; import * as wtnsUtils from "./wtns_utils.js";

@ -1,3 +1,22 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
import {read} from "./wtns_utils.js"; import {read} from "./wtns_utils.js";
export default async function wtnsExportJson(wtnsFileName) { export default async function wtnsExportJson(wtnsFileName) {

@ -1,3 +1,22 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
import { Scalar } from "ffjavascript"; import { Scalar } from "ffjavascript";
import * as binFileUtils from "@iden3/binfileutils"; import * as binFileUtils from "@iden3/binfileutils";

@ -1,3 +1,22 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
export {default as newZKey} from "./zkey_new.js"; export {default as newZKey} from "./zkey_new.js";
export {default as exportBellman} from "./zkey_export_bellman.js"; export {default as exportBellman} from "./zkey_export_bellman.js";
export {default as importBellman} from "./zkey_import_bellman.js"; export {default as importBellman} from "./zkey_import_bellman.js";

@ -1,3 +1,22 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
import * as binFileUtils from "@iden3/binfileutils"; import * as binFileUtils from "@iden3/binfileutils";
import * as zkeyUtils from "./zkey_utils.js"; import * as zkeyUtils from "./zkey_utils.js";
import { getCurveFromQ as getCurve } from "./curves.js"; import { getCurveFromQ as getCurve } from "./curves.js";

@ -1,3 +1,22 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
// Format of the output // Format of the output
// Hash of the last contribution 64 Bytes // Hash of the last contribution 64 Bytes
// 2^N*2-1 TauG1 Points (compressed) // 2^N*2-1 TauG1 Points (compressed)

@ -1,3 +1,21 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
import * as binFileUtils from "@iden3/binfileutils"; import * as binFileUtils from "@iden3/binfileutils";
import * as zkeyUtils from "./zkey_utils.js"; import * as zkeyUtils from "./zkey_utils.js";

@ -1,4 +1,5 @@
import * as fastFile from "fastfile"; import * as fastFile from "fastfile";
import ejs from "ejs";
import exportVerificationKey from "./zkey_export_verificationkey.js"; import exportVerificationKey from "./zkey_export_verificationkey.js";
// Not ready yet // Not ready yet
@ -6,47 +7,11 @@ import exportVerificationKey from "./zkey_export_verificationkey.js";
export default async function exportSolidityVerifier(zKeyName, templateName, logger) { export default async function exportSolidityVerifier(zKeyName, templates, logger) {
const verificationKey = await exportVerificationKey(zKeyName, logger); const verificationKey = await exportVerificationKey(zKeyName, logger);
const fd = await fastFile.readExisting(templateName); let template = templates[verificationKey.protocol];
const buff = await fd.read(fd.totalSize);
let template = new TextDecoder("utf-8").decode(buff);
const vkalpha1_str = `${verificationKey.vk_alpha_1[0].toString()},`+ return ejs.render(template , verificationKey);
`${verificationKey.vk_alpha_1[1].toString()}`;
template = template.replace("<%vk_alpha1%>", vkalpha1_str);
const vkbeta2_str = `[${verificationKey.vk_beta_2[0][1].toString()},`+
`${verificationKey.vk_beta_2[0][0].toString()}], `+
`[${verificationKey.vk_beta_2[1][1].toString()},` +
`${verificationKey.vk_beta_2[1][0].toString()}]`;
template = template.replace("<%vk_beta2%>", vkbeta2_str);
const vkgamma2_str = `[${verificationKey.vk_gamma_2[0][1].toString()},`+
`${verificationKey.vk_gamma_2[0][0].toString()}], `+
`[${verificationKey.vk_gamma_2[1][1].toString()},` +
`${verificationKey.vk_gamma_2[1][0].toString()}]`;
template = template.replace("<%vk_gamma2%>", vkgamma2_str);
const vkdelta2_str = `[${verificationKey.vk_delta_2[0][1].toString()},`+
`${verificationKey.vk_delta_2[0][0].toString()}], `+
`[${verificationKey.vk_delta_2[1][1].toString()},` +
`${verificationKey.vk_delta_2[1][0].toString()}]`;
template = template.replace("<%vk_delta2%>", vkdelta2_str);
// The points
template = template.replace("<%vk_input_length%>", (verificationKey.IC.length-1).toString());
template = template.replace("<%vk_ic_length%>", verificationKey.IC.length.toString());
let vi = "";
for (let i=0; i<verificationKey.IC.length; i++) {
if (vi != "") vi = vi + " ";
vi = vi + `vk.IC[${i}] = Pairing.G1Point(${verificationKey.IC[i][0].toString()},`+
`${verificationKey.IC[i][1].toString()});\n`;
}
template = template.replace("<%vk_ic_pts%>", vi);
return template;
} }

@ -1,10 +1,28 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
import * as binFileUtils from "@iden3/binfileutils"; import * as binFileUtils from "@iden3/binfileutils";
import * as zkeyUtils from "./zkey_utils.js"; import * as zkeyUtils from "./zkey_utils.js";
import { getCurveFromQ as getCurve } from "./curves.js"; import { getCurveFromQ as getCurve } from "./curves.js";
import { utils } from "ffjavascript"; import { utils } from "ffjavascript";
const {stringifyBigInts} = utils; const {stringifyBigInts} = utils;
export default async function zkeyExportVerificationKey(zkeyName, /* logger */ ) { export default async function zkeyExportVerificationKey(zkeyName, /* logger */ ) {
const {fd, sections} = await binFileUtils.readBinFile(zkeyName, "zkey", 2); const {fd, sections} = await binFileUtils.readBinFile(zkeyName, "zkey", 2);

@ -1,3 +1,22 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
import * as zkeyUtils from "./zkey_utils.js"; import * as zkeyUtils from "./zkey_utils.js";
import * as binFileUtils from "@iden3/binfileutils"; import * as binFileUtils from "@iden3/binfileutils";
import * as fastFile from "fastfile"; import * as fastFile from "fastfile";
@ -7,7 +26,10 @@ import * as misc from "./misc.js";
export default async function phase2importMPCParams(zkeyNameOld, mpcparamsName, zkeyNameNew, name, logger) { export default async function phase2importMPCParams(zkeyNameOld, mpcparamsName, zkeyNameNew, name, logger) {
const {fd: fdZKeyOld, sections: sectionsZKeyOld} = await binFileUtils.readBinFile(zkeyNameOld, "zkey", 2); const {fd: fdZKeyOld, sections: sectionsZKeyOld} = await binFileUtils.readBinFile(zkeyNameOld, "zkey", 2);
const zkeyHeader = await zkeyUtils.readHeader(fdZKeyOld, sectionsZKeyOld, "groth16"); const zkeyHeader = await zkeyUtils.readHeader(fdZKeyOld, sectionsZKeyOld, false);
if (zkeyHeader.protocol != "groth16") {
throw new Error("zkey file is not groth16");
}
const curve = await getCurve(zkeyHeader.q); const curve = await getCurve(zkeyHeader.q);
const sG1 = curve.G1.F.n8*2; const sG1 = curve.G1.F.n8*2;

@ -1,3 +1,21 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
import {readR1csHeader} from "r1csfile"; import {readR1csHeader} from "r1csfile";
import * as utils from "./powersoftau_utils.js"; import * as utils from "./powersoftau_utils.js";

@ -1,3 +1,21 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
// Format // Format
// ====== // ======

@ -1,3 +1,22 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
import * as binFileUtils from "@iden3/binfileutils"; import * as binFileUtils from "@iden3/binfileutils";
import * as zkeyUtils from "./zkey_utils.js"; import * as zkeyUtils from "./zkey_utils.js";
import { getCurveFromQ as getCurve } from "./curves.js"; import { getCurveFromQ as getCurve } from "./curves.js";
@ -17,7 +36,7 @@ export default async function phase2verifyFromInit(initFileName, pTauFileName, z
await Blake2b.ready(); await Blake2b.ready();
const {fd, sections} = await binFileUtils.readBinFile(zkeyFileName, "zkey", 2); const {fd, sections} = await binFileUtils.readBinFile(zkeyFileName, "zkey", 2);
const zkey = await zkeyUtils.readHeader(fd, sections); const zkey = await zkeyUtils.readHeader(fd, sections, false);
if (zkey.protocol != "groth16") { if (zkey.protocol != "groth16") {
throw new Error("zkey file is not groth16"); throw new Error("zkey file is not groth16");
} }
@ -83,7 +102,11 @@ export default async function phase2verifyFromInit(initFileName, pTauFileName, z
const {fd: fdInit, sections: sectionsInit} = await binFileUtils.readBinFile(initFileName, "zkey", 2); const {fd: fdInit, sections: sectionsInit} = await binFileUtils.readBinFile(initFileName, "zkey", 2);
const zkeyInit = await zkeyUtils.readHeader(fdInit, sectionsInit, "groth16"); const zkeyInit = await zkeyUtils.readHeader(fdInit, sectionsInit, false);
if (zkeyInit.protocol != "groth16") {
throw new Error("zkeyinit file is not groth16");
}
if ( (!Scalar.eq(zkeyInit.q, zkey.q)) if ( (!Scalar.eq(zkeyInit.q, zkey.q))
||(!Scalar.eq(zkeyInit.r, zkey.r)) ||(!Scalar.eq(zkeyInit.r, zkey.r))

@ -1,3 +1,22 @@
/*
Copyright 2018 0KIMS association.
This file is part of snarkJS.
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
import newZKey from "./zkey_new.js"; import newZKey from "./zkey_new.js";
import phase2verifyFromInit from "./zkey_verify_frominit.js"; import phase2verifyFromInit from "./zkey_verify_frominit.js";

@ -176,12 +176,36 @@ contract Verifier {
Pairing.G1Point C; Pairing.G1Point C;
} }
function verifyingKey() internal pure returns (VerifyingKey memory vk) { function verifyingKey() internal pure returns (VerifyingKey memory vk) {
vk.alfa1 = Pairing.G1Point(<%vk_alpha1%>); vk.alfa1 = Pairing.G1Point(
vk.beta2 = Pairing.G2Point(<%vk_beta2%>); <%=vk_alpha_1[0]%>,
vk.gamma2 = Pairing.G2Point(<%vk_gamma2%>); <%=vk_alpha_1[1]%>
vk.delta2 = Pairing.G2Point(<%vk_delta2%>); );
vk.IC = new Pairing.G1Point[](<%vk_ic_length%>);
<%vk_ic_pts%> vk.beta2 = Pairing.G2Point(
[<%=vk_beta_2[0][1]%>,
<%=vk_beta_2[0][0]%>],
[<%=vk_beta_2[1][1]%>,
<%=vk_beta_2[1][0]%>]
);
vk.gamma2 = Pairing.G2Point(
[<%=vk_gamma_2[0][1]%>,
<%=vk_gamma_2[0][0]%>],
[<%=vk_gamma_2[1][1]%>,
<%=vk_gamma_2[1][0]%>]
);
vk.delta2 = Pairing.G2Point(
[<%=vk_delta_2[0][1]%>,
<%=vk_delta_2[0][0]%>],
[<%=vk_delta_2[1][1]%>,
<%=vk_delta_2[1][0]%>]
);
vk.IC = new Pairing.G1Point[](<%=IC.length%>);
<% for (let i=0; i<IC.length; i++) { %>
vk.IC[<%=i%>] = Pairing.G1Point(
<%=IC[i][0]%>,
<%=IC[i][1]%>
);
<% } %>
} }
function verify(uint[] memory input, Proof memory proof) internal view returns (uint) { function verify(uint[] memory input, Proof memory proof) internal view returns (uint) {
uint256 snark_scalar_field = 21888242871839275222246405745257275088548364400416034343698204186575808495617; uint256 snark_scalar_field = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
@ -207,7 +231,7 @@ contract Verifier {
uint[2] memory a, uint[2] memory a,
uint[2][2] memory b, uint[2][2] memory b,
uint[2] memory c, uint[2] memory c,
uint[<%vk_input_length%>] memory input uint[<%=IC.length-1%>] memory input
) public view returns (bool r) { ) public view returns (bool r) {
Proof memory proof; Proof memory proof;
proof.A = Pairing.G1Point(a[0], a[1]); proof.A = Pairing.G1Point(a[0], a[1]);

@ -0,0 +1,632 @@
// SPDX-License-Identifier: GPL-3.0
/*
Copyright 2021 0KIMS association.
This file is generated with [snarkJS](https://github.com/iden3/snarkjs).
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
pragma solidity >=0.7.0 <0.9.0;
contract PlonkVerifier {
uint16 constant n = <%=2**power%>;
uint16 constant nPublic = <%=nPublic%>;
uint16 constant nLagrange = <%=Math.max(nPublic, 1)%>;
uint256 constant Qmx = <%=Qm[0]%>;
uint256 constant Qmy = <%=Qm[1]%>;
uint256 constant Qlx = <%=Ql[0]%>;
uint256 constant Qly = <%=Ql[1]%>;
uint256 constant Qrx = <%=Qr[0]%>;
uint256 constant Qry = <%=Qr[1]%>;
uint256 constant Qox = <%=Qo[0]%>;
uint256 constant Qoy = <%=Qo[1]%>;
uint256 constant Qcx = <%=Qc[0]%>;
uint256 constant Qcy = <%=Qc[1]%>;
uint256 constant S1x = <%=S1[0]%>;
uint256 constant S1y = <%=S1[1]%>;
uint256 constant S2x = <%=S2[0]%>;
uint256 constant S2y = <%=S2[1]%>;
uint256 constant S3x = <%=S3[0]%>;
uint256 constant S3y = <%=S3[1]%>;
uint256 constant k1 = 2;
uint256 constant k2 = 3;
uint256 constant X2x1 = <%=X_2[0][0]%>;
uint256 constant X2x2 = <%=X_2[0][1]%>;
uint256 constant X2y1 = <%=X_2[1][0]%>;
uint256 constant X2y2 = <%=X_2[1][1]%>;
uint256 constant q = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
uint256 constant qf = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
uint256 constant w1 = 19540430494807482326159819597004422086093766032135589407132600596362845576832;
uint256 constant G1x = 1;
uint256 constant G1y = 2;
uint256 constant G2x1 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;
uint256 constant G2x2 = 11559732032986387107991004021392285783925812861821192530917403151452391805634;
uint256 constant G2y1 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;
uint256 constant G2y2 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;
uint16 constant pA = 32;
uint16 constant pB = 96;
uint16 constant pC = 160;
uint16 constant pZ = 224;
uint16 constant pT1 = 288;
uint16 constant pT2 = 352;
uint16 constant pT3 = 416;
uint16 constant pWxi = 480;
uint16 constant pWxiw = 544;
uint16 constant pEval_a = 608;
uint16 constant pEval_b = 640;
uint16 constant pEval_c = 672;
uint16 constant pEval_s1 = 704;
uint16 constant pEval_s2 = 736;
uint16 constant pEval_zw = 768;
uint16 constant pEval_r = 800;
uint16 constant pAlpha = 0;
uint16 constant pBeta = 32;
uint16 constant pGamma = 64;
uint16 constant pXi = 96;
uint16 constant pXin = 128;
uint16 constant pBetaXi = 160;
uint16 constant pV1 = 192;
uint16 constant pV2 = 224;
uint16 constant pV3 = 256;
uint16 constant pV4 = 288;
uint16 constant pV5 = 320;
uint16 constant pV6 = 352;
uint16 constant pU = 384;
uint16 constant pPl = 416;
uint16 constant pEval_t = 448;
uint16 constant pA1 = 480;
uint16 constant pB1 = 544;
uint16 constant pZh = 608;
uint16 constant pZhInv = 640;
<% for (let i=1; i<=Math.max(nPublic, 1); i++) { %>
uint16 constant pEval_l<%=i%> = <%=640+i*32%>;
<% } %>
uint16 constant lastMem = <%=672+32*Math.max(nPublic,1)%>;
function verifyProof(bytes memory proof, uint[] memory pubSignals) public view returns (bool) {
assembly {
/////////
// Computes the inverse using the extended euclidean algorithm
/////////
function inverse(a, q) -> inv {
let t := 0
let newt := 1
let r := q
let newr := a
let quotient
let aux
for { } newr { } {
quotient := sdiv(r, newr)
aux := sub(t, mul(quotient, newt))
t:= newt
newt:= aux
aux := sub(r,mul(quotient, newr))
r := newr
newr := aux
}
if gt(r, 1) { revert(0,0) }
if slt(t, 0) { t:= add(t, q) }
inv := t
}
///////
// Computes the inverse of an array of values
// See https://vitalik.ca/general/2018/07/21/starks_part_3.html in section where explain fields operations
//////
function inverseArray(pVals, n) {
let pAux := mload(0x40) // Point to the next free position
let pIn := pVals
let lastPIn := add(pVals, mul(n, 32)) // Read n elemnts
let acc := mload(pIn) // Read the first element
pIn := add(pIn, 32) // Point to the second element
let inv
for { } lt(pIn, lastPIn) {
pAux := add(pAux, 32)
pIn := add(pIn, 32)
}
{
mstore(pAux, acc)
acc := mulmod(acc, mload(pIn), q)
}
acc := inverse(acc, q)
// At this point pAux pint to the next free position we substract 1 to point to the last used
pAux := sub(pAux, 32)
// pIn points to the n+1 element, we substract to point to n
pIn := sub(pIn, 32)
lastPIn := pVals // We don't process the first element
for { } gt(pIn, lastPIn) {
pAux := sub(pAux, 32)
pIn := sub(pIn, 32)
}
{
inv := mulmod(acc, mload(pAux), q)
acc := mulmod(acc, mload(pIn), q)
mstore(pIn, inv)
}
// pIn points to first element, we just set it.
mstore(pIn, acc)
}
function checkField(v) {
if iszero(lt(v, q)) {
mstore(0, 0)
return(0,0x20)
}
}
function checkInput(pProof) {
if iszero(eq(mload(pProof), 800 )) {
mstore(0, 0)
return(0,0x20)
}
checkField(mload(add(pProof, pEval_a)))
checkField(mload(add(pProof, pEval_b)))
checkField(mload(add(pProof, pEval_c)))
checkField(mload(add(pProof, pEval_s1)))
checkField(mload(add(pProof, pEval_s2)))
checkField(mload(add(pProof, pEval_zw)))
checkField(mload(add(pProof, pEval_r)))
// Points are checked in the point operations precompiled smart contracts
}
function calculateChallanges(pProof, pMem) {
let a
let b
b := mod(keccak256(add(pProof, pA), 192), q)
mstore( add(pMem, pBeta), b)
mstore( add(pMem, pGamma), mod(keccak256(add(pMem, pBeta), 32), q))
mstore( add(pMem, pAlpha), mod(keccak256(add(pProof, pZ), 64), q))
a := mod(keccak256(add(pProof, pT1), 192), q)
mstore( add(pMem, pXi), a)
mstore( add(pMem, pBetaXi), mulmod(b, a, q))
<%for (let i=0; i<power;i++) {%>
a:= mulmod(a, a, q)
<%}%>
mstore( add(pMem, pXin), a)
a:= mod(add(sub(a, 1),q), q)
mstore( add(pMem, pZh), a)
mstore( add(pMem, pZhInv), a) // We will invert later together with lagrange pols
let v1 := mod(keccak256(add(pProof, pEval_a), 224), q)
mstore( add(pMem, pV1), v1)
a := mulmod(v1, v1, q)
mstore( add(pMem, pV2), a)
a := mulmod(a, v1, q)
mstore( add(pMem, pV3), a)
a := mulmod(a, v1, q)
mstore( add(pMem, pV4), a)
a := mulmod(a, v1, q)
mstore( add(pMem, pV5), a)
a := mulmod(a, v1, q)
mstore( add(pMem, pV6), a)
mstore( add(pMem, pU), mod(keccak256(add(pProof, pWxi), 128), q))
}
function calculateLagrange(pMem) {
let w := 1
<% for (let i=1; i<=Math.max(nPublic, 1); i++) { %>
mstore(
add(pMem, pEval_l<%=i%>),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
<% if (i<Math.max(nPublic, 1)) { %>
w := mulmod(w, w1, q)
<% } %>
<% } %>
inverseArray(add(pMem, pZhInv), <%=Math.max(nPublic, 1)+1%> )
let zh := mload(add(pMem, pZh))
w := 1
<% for (let i=1; i<=Math.max(nPublic, 1); i++) { %>
<% if (i==1) { %>
mstore(
add(pMem, pEval_l1 ),
mulmod(
mload(add(pMem, pEval_l1 )),
zh,
q
)
)
<% } else { %>
mstore(
add(pMem, pEval_l<%=i%>),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l<%=i%>)),
zh,
q
),
q
)
)
<% } %>
<% if (i<Math.max(nPublic, 1)) { %>
w := mulmod(w, w1, q)
<% } %>
<% } %>
}
function calculatePl(pMem, pPub) {
let pl := 0
<% for (let i=0; i<nPublic; i++) { %>
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l<%=i+1%>)),
mload(add(pPub, <%=32+i*32%>)),
q
)
),
q
),
q
)
<% } %>
mstore(add(pMem, pPl), pl)
}
function calculateT(pProof, pMem) {
let t
let t1
let t2
t := addmod(
mload(add(pProof, pEval_r)),
mload(add(pMem, pPl)),
q
)
t1 := mulmod(
mload(add(pProof, pEval_s1)),
mload(add(pMem, pBeta)),
q
)
t1 := addmod(
t1,
mload(add(pProof, pEval_a)),
q
)
t1 := addmod(
t1,
mload(add(pMem, pGamma)),
q
)
t2 := mulmod(
mload(add(pProof, pEval_s2)),
mload(add(pMem, pBeta)),
q
)
t2 := addmod(
t2,
mload(add(pProof, pEval_b)),
q
)
t2 := addmod(
t2,
mload(add(pMem, pGamma)),
q
)
t1 := mulmod(t1, t2, q)
t2 := addmod(
mload(add(pProof, pEval_c)),
mload(add(pMem, pGamma)),
q
)
t1 := mulmod(t1, t2, q)
t1 := mulmod(t1, mload(add(pProof, pEval_zw)), q)
t1 := mulmod(t1, mload(add(pMem, pAlpha)), q)
t2 := mulmod(
mload(add(pMem, pEval_l1)),
mload(add(pMem, pAlpha)),
q
)
t2 := mulmod(
t2,
mload(add(pMem, pAlpha)),
q
)
t1 := addmod(t1, t2, q)
t := mod(sub(add(t, q), t1), q)
t := mulmod(t, mload(add(pMem, pZhInv)), q)
mstore( add(pMem, pEval_t) , t)
}
function g1_set(pR, pP) {
mstore(pR, mload(pP))
mstore(add(pR, 32), mload(add(pP,32)))
}
function g1_acc(pR, pP) {
let mIn := mload(0x40)
mstore(mIn, mload(pR))
mstore(add(mIn,32), mload(add(pR, 32)))
mstore(add(mIn,64), mload(pP))
mstore(add(mIn,96), mload(add(pP, 32)))
let success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
}
function g1_mulAcc(pR, pP, s) {
let success
let mIn := mload(0x40)
mstore(mIn, mload(pP))
mstore(add(mIn,32), mload(add(pP, 32)))
mstore(add(mIn,64), s)
success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
mstore(add(mIn,64), mload(pR))
mstore(add(mIn,96), mload(add(pR, 32)))
success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
}
function g1_mulAccC(pR, x, y, s) {
let success
let mIn := mload(0x40)
mstore(mIn, x)
mstore(add(mIn,32), y)
mstore(add(mIn,64), s)
success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
mstore(add(mIn,64), mload(pR))
mstore(add(mIn,96), mload(add(pR, 32)))
success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
}
function g1_mulSetC(pR, x, y, s) {
let success
let mIn := mload(0x40)
mstore(mIn, x)
mstore(add(mIn,32), y)
mstore(add(mIn,64), s)
success := staticcall(sub(gas(), 2000), 7, mIn, 96, pR, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
}
function calculateA1(pProof, pMem) {
let p := add(pMem, pA1)
g1_set(p, add(pProof, pWxi))
g1_mulAcc(p, add(pProof, pWxiw), mload(add(pMem, pU)))
}
function calculateB1(pProof, pMem) {
let s
let s1
let p := add(pMem, pB1)
// Calculate D
s := mulmod( mload(add(pProof, pEval_a)), mload(add(pMem, pV1)), q)
g1_mulSetC(p, Qlx, Qly, s)
s := mulmod( s, mload(add(pProof, pEval_b)), q)
g1_mulAccC(p, Qmx, Qmy, s)
s := mulmod( mload(add(pProof, pEval_b)), mload(add(pMem, pV1)), q)
g1_mulAccC(p, Qrx, Qry, s)
s := mulmod( mload(add(pProof, pEval_c)), mload(add(pMem, pV1)), q)
g1_mulAccC(p, Qox, Qoy, s)
s :=mload(add(pMem, pV1))
g1_mulAccC(p, Qcx, Qcy, s)
s := addmod(mload(add(pProof, pEval_a)), mload(add(pMem, pBetaXi)), q)
s := addmod(s, mload(add(pMem, pGamma)), q)
s1 := mulmod(k1, mload(add(pMem, pBetaXi)), q)
s1 := addmod(s1, mload(add(pProof, pEval_b)), q)
s1 := addmod(s1, mload(add(pMem, pGamma)), q)
s := mulmod(s, s1, q)
s1 := mulmod(k2, mload(add(pMem, pBetaXi)), q)
s1 := addmod(s1, mload(add(pProof, pEval_c)), q)
s1 := addmod(s1, mload(add(pMem, pGamma)), q)
s := mulmod(s, s1, q)
s := mulmod(s, mload(add(pMem, pAlpha)), q)
s := mulmod(s, mload(add(pMem, pV1)), q)
s1 := mulmod(mload(add(pMem, pEval_l1)), mload(add(pMem, pAlpha)), q)
s1 := mulmod(s1, mload(add(pMem, pAlpha)), q)
s1 := mulmod(s1, mload(add(pMem, pV1)), q)
s := addmod(s, s1, q)
s := addmod(s, mload(add(pMem, pU)), q)
g1_mulAcc(p, add(pProof, pZ), s)
s := mulmod(mload(add(pMem, pBeta)), mload(add(pProof, pEval_s1)), q)
s := addmod(s, mload(add(pProof, pEval_a)), q)
s := addmod(s, mload(add(pMem, pGamma)), q)
s1 := mulmod(mload(add(pMem, pBeta)), mload(add(pProof, pEval_s2)), q)
s1 := addmod(s1, mload(add(pProof, pEval_b)), q)
s1 := addmod(s1, mload(add(pMem, pGamma)), q)
s := mulmod(s, s1, q)
s := mulmod(s, mload(add(pMem, pAlpha)), q)
s := mulmod(s, mload(add(pMem, pV1)), q)
s := mulmod(s, mload(add(pMem, pBeta)), q)
s := mulmod(s, mload(add(pProof, pEval_zw)), q)
s := mod(sub(q, s), q)
g1_mulAccC(p, S3x, S3y, s)
// calculate F
g1_acc(p , add(pProof, pT1))
s := mload(add(pMem, pXin))
g1_mulAcc(p, add(pProof, pT2), s)
s := mulmod(s, s, q)
g1_mulAcc(p, add(pProof, pT3), s)
g1_mulAcc(p, add(pProof, pA), mload(add(pMem, pV2)))
g1_mulAcc(p, add(pProof, pB), mload(add(pMem, pV3)))
g1_mulAcc(p, add(pProof, pC), mload(add(pMem, pV4)))
g1_mulAccC(p, S1x, S1y, mload(add(pMem, pV5)))
g1_mulAccC(p, S2x, S2y, mload(add(pMem, pV6)))
// calculate E
s := mload(add(pMem, pEval_t))
s := addmod(s, mulmod(mload(add(pProof, pEval_r)), mload(add(pMem, pV1)), q), q)
s := addmod(s, mulmod(mload(add(pProof, pEval_a)), mload(add(pMem, pV2)), q), q)
s := addmod(s, mulmod(mload(add(pProof, pEval_b)), mload(add(pMem, pV3)), q), q)
s := addmod(s, mulmod(mload(add(pProof, pEval_c)), mload(add(pMem, pV4)), q), q)
s := addmod(s, mulmod(mload(add(pProof, pEval_s1)), mload(add(pMem, pV5)), q), q)
s := addmod(s, mulmod(mload(add(pProof, pEval_s2)), mload(add(pMem, pV6)), q), q)
s := addmod(s, mulmod(mload(add(pProof, pEval_zw)), mload(add(pMem, pU)), q), q)
s := mod(sub(q, s), q)
g1_mulAccC(p, G1x, G1y, s)
// Last part of B
s := mload(add(pMem, pXi))
g1_mulAcc(p, add(pProof, pWxi), s)
s := mulmod(mload(add(pMem, pU)), mload(add(pMem, pXi)), q)
s := mulmod(s, w1, q)
g1_mulAcc(p, add(pProof, pWxiw), s)
}
function checkPairing(pMem) -> isOk {
let mIn := mload(0x40)
mstore(mIn, mload(add(pMem, pA1)))
mstore(add(mIn,32), mload(add(add(pMem, pA1), 32)))
mstore(add(mIn,64), X2x2)
mstore(add(mIn,96), X2x1)
mstore(add(mIn,128), X2y2)
mstore(add(mIn,160), X2y1)
mstore(add(mIn,192), mload(add(pMem, pB1)))
let s := mload(add(add(pMem, pB1), 32))
s := mod(sub(qf, s), qf)
mstore(add(mIn,224), s)
mstore(add(mIn,256), G2x2)
mstore(add(mIn,288), G2x1)
mstore(add(mIn,320), G2y2)
mstore(add(mIn,352), G2y1)
let success := staticcall(sub(gas(), 2000), 8, mIn, 384, mIn, 0x20)
isOk := and(success, mload(mIn))
}
let pMem := mload(0x40)
mstore(0x40, add(pMem, lastMem))
checkInput(proof)
calculateChallanges(proof, pMem)
calculateLagrange(pMem)
calculatePl(pMem, pubSignals)
calculateT(proof, pMem)
calculateA1(proof, pMem)
calculateB1(proof, pMem)
let isValid := checkPairing(pMem)
mstore(0x40, sub(pMem, lastMem))
mstore(0, isValid)
return(0,0x20)
}
}
}

@ -18,9 +18,11 @@ describe("Full process", function () {
const zkey_1 = {type: "mem"}; const zkey_1 = {type: "mem"};
const zkey_2 = {type: "mem"}; const zkey_2 = {type: "mem"};
const zkey_final = {type: "mem"}; const zkey_final = {type: "mem"};
const zkey_plonk = {type: "mem"};
const bellman_1 = {type: "mem"}; const bellman_1 = {type: "mem"};
const bellman_2 = {type: "mem"}; const bellman_2 = {type: "mem"};
let vKey; let vKey;
let vKeyPlonk;
const wtns = {type: "mem"}; const wtns = {type: "mem"};
let proof; let proof;
let publicSignals; let publicSignals;
@ -36,7 +38,7 @@ describe("Full process", function () {
}); });
it ("powersoftau new", async () => { it ("powersoftau new", async () => {
await snarkjs.powersOfTau.newAccumulator(curve, 10, ptau_0); await snarkjs.powersOfTau.newAccumulator(curve, 11, ptau_0);
}); });
it ("powersoftau contribute ", async () => { it ("powersoftau contribute ", async () => {
@ -68,7 +70,7 @@ describe("Full process", function () {
assert(res); assert(res);
}); });
it ("zkey new", async () => { it ("groth16 setup", async () => {
await snarkjs.zKey.newZKey(path.join("test", "circuit", "circuit.r1cs"), ptau_final, zkey_0); await snarkjs.zKey.newZKey(path.join("test", "circuit", "circuit.r1cs"), ptau_final, zkey_0);
}); });
@ -116,9 +118,31 @@ describe("Full process", function () {
publicSignals = res.publicSignals; publicSignals = res.publicSignals;
}); });
it ("groth16 verify", async () => { it ("groth16 verify", async () => {
const res = await snarkjs.groth16.verify(vKey, publicSignals, proof); const res = await snarkjs.groth16.verify(vKey, publicSignals, proof);
assert(res == true); assert(res == true);
}); });
it ("plonk setup", async () => {
await snarkjs.plonk.setup(path.join("test", "circuit", "circuit.r1cs"), ptau_final, zkey_plonk);
});
it ("zkey export verificationkey", async () => {
vKey = await snarkjs.zKey.exportVerificationKey(zkey_plonk);
});
it ("plonk proof", async () => {
const res = await snarkjs.plonk.prove(zkey_plonk, wtns);
proof = res.proof;
publicSignals = res.publicSignals;
});
it ("plonk verify", async () => {
const res = await snarkjs.plonk.verify(vKey, publicSignals, proof);
assert(res == true);
});
}); });

@ -1,5 +1,5 @@
template TestPlonk() { template TestPlonk() {
signal private input a; signal input a;
signal private input b; signal private input b;
signal output c; signal output c;

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -1,56 +1,56 @@
{ {
"A": [ "A": [
"8839447420316742728199672120007516770398996562499593209826233055164831459834", "11939839401037308014501661426368356653724850605345253332929657172853812043781",
"16189635412848654749378322490220441430077839960004046391626438625637726226000", "16803150087255544989431958662488492904420336924238680701501581437584428607157",
"1" "1"
], ],
"B": [ "B": [
"17465184056494179801925813691588125272949911271611543454528130157857909913246", "12217796857989229870486480566571024020165537615492120027996617913635583550919",
"869328347486379578626658936503731002520626692524913211521742050768236719305", "15953050028732489401139070996642159829273127420498389055201687358737110395633",
"1" "1"
], ],
"C": [ "C": [
"19519544555708553879767666138947412440629548042175907283737565586445507479903", "2906696582521990272421790638819759482269959041206664482786284127016128717160",
"17669026430269534969805497624294901955270334914625983358714826411609764475804", "13202026981472500389768834017524824796942889042108968745956553624097139985303",
"1" "1"
], ],
"Z": [ "Z": [
"3346839295724370624732530222814040339873780027932771271059227118623825895313", "12963117237509670288018978167117384995558675963765854814463910896579884709481",
"10771064980375572846317420996468711290464809627547728487032820584132296464087", "4622289012016200197589549612287854254636168290945719641009001753279825228149",
"1" "1"
], ],
"T1": [ "T1": [
"6168675305758589840782279635487697914964888136358086288899584897562377682341", "18104357506804140563327524454292715928794326274573109553633239600891197573562",
"1310251258624946189756801650980878849173726360620822836933820834682621444297", "538095434184877169430117038240223945215803059446062355137183333593880141605",
"1" "1"
], ],
"T2": [ "T2": [
"16452753478240443931891239628843197353427455171472174094729996434600044435135", "11026905931134233808041270707862602948406795505689051352903565023828166906250",
"8929495594150478290096744687495763476858314760863627578988262303134274489344", "18119786770119651916429915278124137884233023858386753737488502838895847215949",
"1" "1"
], ],
"T3": [ "T3": [
"19819502442073307622314428521645368167900579868696060575639423061202619148825", "17566889279472128646779664131922958011041076031971155851685601770551415716030",
"1296256729870262422650485730805825715543370241968740278951378382748106685", "9098203299195991935285362173962848018633069009185836024035896571651321000209",
"1" "1"
], ],
"eval_a": "17308412617343213496686623338374754645623487581648979513260734198232305768219", "eval_a": "18055865061248928277436374209575542340767389401367587042080949450055475826552",
"eval_b": "18345454810685357058582137490005137834611428833597017516916268835300742089352", "eval_b": "21850645998014953033835315242107188012141028920551179313126430204177981301827",
"eval_c": "16074233345199063790683870465201170590190471729874269213657192492651425327675", "eval_c": "5824117629917668551774989696896451058359923623432918656361263478103100196767",
"eval_s1": "14015572845284403142110641193521146039944984657769005309306690365631231445048", "eval_s1": "65743854351722680405937613500622654105481480423395233482389298676037124381",
"eval_s2": "7691129033989434863426855513508666093916526662958551024915431222123575206817", "eval_s2": "403993049457837292639608362612899661597754187086038035508895737334683813284",
"eval_t": "5852485600510874249119136745640279381547655754620311863376257247975117708663", "eval_zw": "14169472644142979719809496569719127849776868311673021350864638375395829014729",
"eval_zw": "13923465555995912889009033724768828925333434248874337536329403180953424994345", "eval_r": "9395413794097544253619189223051084436435081924218993403215287776407899118006",
"eval_r": "1366062923125011032494175183956831254719864451259174775709441138581956258656",
"Wxi": [ "Wxi": [
"338371644772673995306261030076125401282839784249944929895162794096576157571", "3539391490802181190120434708628288229123728841695494613225112420761229267477",
"17341033938816793745315773504010937698365013917156300011885252183580989524581", "19988904286663115119238205828592812126968004685055289879546007973679529590700",
"1" "1"
], ],
"Wxiw": [ "Wxiw": [
"17454198881576966899691410005788764637613831450763965078826728621580498180724", "19317464275069150558817973507256614963505445298046435829549010698677013964612",
"5460326051028606573687415138444061925446401900718369209656673120203041901304", "16876609931905898917226763969880049506487107879332614688130170393689647229232",
"1" "1"
], ],
"protocol": "plonk" "protocol": "plonk",
"curve": "bn128"
} }

@ -1,3 +1,4 @@
[ [
"7776" "7776",
"1"
] ]

@ -1,48 +1,48 @@
{ {
"protocol": "plonk", "protocol": "plonk",
"curve": "bn128", "curve": "bn128",
"nPublic": 1, "nPublic": 2,
"power": 3, "power": 3,
"k1": "2", "k1": "2",
"k2": "3", "k2": "3",
"Qm": [ "Qm": [
"17168609912386190999462867062592844491706144727020886602745470454037632312807", "4574976860925876233715815557145957880705707179788243092345689458042383890488",
"4824893185019084254715538827477609000309081525483856078561591934996168045584", "4280641572679440220740870768701934042005081764212788702122100316880968332003",
"1" "1"
], ],
"Ql": [ "Ql": [
"15450133393628414971876261621748138496338605666826023846615859108791492332989", "965658296392348546197801330054212493203716810675203464920320569299615906620",
"1184681025187442459325266097207314011772232923873671071468501257625715473389", "2656007013467620250344837426700774817845582578535592475523934494973414078961",
"1" "1"
], ],
"Qr": [ "Qr": [
"16752106819266013412663211551583756351765466845186589867767132691506607495492", "9466120146806803512081752933000124200435544680867502413168004293837549973279",
"14299683507274194476312714964546495843580088611903841363880636607454602216010", "21718061423910769411439185483074527939398926867139106591112998426662463026765",
"1" "1"
], ],
"Qo": [ "Qo": [
"7984966467262973095497162697022203877199031573073309221047701766279201883804", "14232475876760437187555678371073865360567175818750566973123447255794615727867",
"18404871471444263234086942561943030263846986803222776461621204864269731897231", "12884948380030714721172201264029036846611910042838904312559968631894569296588",
"1" "1"
], ],
"Qc": [ "Qc": [
"16135959299033384762614902229352182078283157726424477475533552688440953520084", "14611255151810715369553599153356422265550902840832241273629187752840438096443",
"349204288781237561964913896195664733659754516098184691353357621586316325634", "9099095607583972457036848580058361056377035074964862926640921566382822995435",
"1" "1"
], ],
"S1": [ "S1": [
"1910989172493900079102803565308322125332203370089591628568145817380913373724", "14533465958261944855196820716374074689704505288368818447966063234824080424576",
"9337220904228568088603689620174503369357413191014667225917702935803917493067", "12453353674569653145950160230568106433424266373528956571501497772329286407421",
"1" "1"
], ],
"S2": [ "S2": [
"371255004847147127096466409492899314753458794130581205813923179247808061393", "19581287390493194877650947725652399954855738146667446650367315521331119724530",
"2961742946983985442978214878084168395967577369032613662121930483289108288759", "13292535777423157488265774466403939589622049710743071078999542362804505686482",
"1" "1"
], ],
"S3": [ "S3": [
"12610570891683582603162481901590486845060916419456929897556794111704166680394", "7628615832235497959754170049702774596960536866278288444040861507702299255530",
"886409796777648048370939111979503186274941933388434245426850564817301004445", "6061093738111279431632848690609155827426019335581022466737969401920480256170",
"1" "1"
], ],
"X_2": [ "X_2": [

@ -0,0 +1,675 @@
// SPDX-License-Identifier: GPL-3.0
/*
Copyright 2021 0KIMS association.
This file is generated with [snarkJS](https://github.com/iden3/snarkjs).
snarkJS is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
snarkJS is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
pragma solidity >=0.7.0 <0.9.0;
contract PlonkVerifier {
uint16 constant n = 8;
uint16 constant nPublic = 2;
uint16 constant nLagrange = 2;
uint256 constant Qmx = 4574976860925876233715815557145957880705707179788243092345689458042383890488;
uint256 constant Qmy = 4280641572679440220740870768701934042005081764212788702122100316880968332003;
uint256 constant Qlx = 965658296392348546197801330054212493203716810675203464920320569299615906620;
uint256 constant Qly = 2656007013467620250344837426700774817845582578535592475523934494973414078961;
uint256 constant Qrx = 9466120146806803512081752933000124200435544680867502413168004293837549973279;
uint256 constant Qry = 21718061423910769411439185483074527939398926867139106591112998426662463026765;
uint256 constant Qox = 14232475876760437187555678371073865360567175818750566973123447255794615727867;
uint256 constant Qoy = 12884948380030714721172201264029036846611910042838904312559968631894569296588;
uint256 constant Qcx = 14611255151810715369553599153356422265550902840832241273629187752840438096443;
uint256 constant Qcy = 9099095607583972457036848580058361056377035074964862926640921566382822995435;
uint256 constant S1x = 14533465958261944855196820716374074689704505288368818447966063234824080424576;
uint256 constant S1y = 12453353674569653145950160230568106433424266373528956571501497772329286407421;
uint256 constant S2x = 19581287390493194877650947725652399954855738146667446650367315521331119724530;
uint256 constant S2y = 13292535777423157488265774466403939589622049710743071078999542362804505686482;
uint256 constant S3x = 7628615832235497959754170049702774596960536866278288444040861507702299255530;
uint256 constant S3y = 6061093738111279431632848690609155827426019335581022466737969401920480256170;
uint256 constant k1 = 2;
uint256 constant k2 = 3;
uint256 constant X2x1 = 18029695676650738226693292988307914797657423701064905010927197838374790804409;
uint256 constant X2x2 = 14583779054894525174450323658765874724019480979794335525732096752006891875705;
uint256 constant X2y1 = 2140229616977736810657479771656733941598412651537078903776637920509952744750;
uint256 constant X2y2 = 11474861747383700316476719153975578001603231366361248090558603872215261634898;
uint256 constant q = 21888242871839275222246405745257275088548364400416034343698204186575808495617;
uint256 constant qf = 21888242871839275222246405745257275088696311157297823662689037894645226208583;
uint256 constant w1 = 19540430494807482326159819597004422086093766032135589407132600596362845576832;
uint256 constant G1x = 1;
uint256 constant G1y = 2;
uint256 constant G2x1 = 10857046999023057135944570762232829481370756359578518086990519993285655852781;
uint256 constant G2x2 = 11559732032986387107991004021392285783925812861821192530917403151452391805634;
uint256 constant G2y1 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;
uint256 constant G2y2 = 4082367875863433681332203403145435568316851327593401208105741076214120093531;
uint16 constant pA = 32;
uint16 constant pB = 96;
uint16 constant pC = 160;
uint16 constant pZ = 224;
uint16 constant pT1 = 288;
uint16 constant pT2 = 352;
uint16 constant pT3 = 416;
uint16 constant pWxi = 480;
uint16 constant pWxiw = 544;
uint16 constant pEval_a = 608;
uint16 constant pEval_b = 640;
uint16 constant pEval_c = 672;
uint16 constant pEval_s1 = 704;
uint16 constant pEval_s2 = 736;
uint16 constant pEval_zw = 768;
uint16 constant pEval_r = 800;
uint16 constant pAlpha = 0;
uint16 constant pBeta = 32;
uint16 constant pGamma = 64;
uint16 constant pXi = 96;
uint16 constant pXin = 128;
uint16 constant pBetaXi = 160;
uint16 constant pV1 = 192;
uint16 constant pV2 = 224;
uint16 constant pV3 = 256;
uint16 constant pV4 = 288;
uint16 constant pV5 = 320;
uint16 constant pV6 = 352;
uint16 constant pU = 384;
uint16 constant pPl = 416;
uint16 constant pEval_t = 448;
uint16 constant pA1 = 480;
uint16 constant pB1 = 544;
uint16 constant pZh = 608;
uint16 constant pZhInv = 640;
uint16 constant pEval_l1 = 672;
uint16 constant pEval_l2 = 704;
uint16 constant lastMem = 736;
function verifyProof(bytes memory proof, uint[] memory pubSignals) public view returns (bool) {
assembly {
/////////
// Computes the inverse using the extended euclidean algorithm
/////////
function inverse(a, q) -> inv {
let t := 0
let newt := 1
let r := q
let newr := a
let quotient
let aux
for { } newr { } {
quotient := sdiv(r, newr)
aux := sub(t, mul(quotient, newt))
t:= newt
newt:= aux
aux := sub(r,mul(quotient, newr))
r := newr
newr := aux
}
if gt(r, 1) { revert(0,0) }
if slt(t, 0) { t:= add(t, q) }
inv := t
}
///////
// Computes the inverse of an array of values
// See https://vitalik.ca/general/2018/07/21/starks_part_3.html in section where explain fields operations
//////
function inverseArray(pVals, n) {
let pAux := mload(0x40) // Point to the next free position
let pIn := pVals
let lastPIn := add(pVals, mul(n, 32)) // Read n elemnts
let acc := mload(pIn) // Read the first element
pIn := add(pIn, 32) // Point to the second element
let inv
for { } lt(pIn, lastPIn) {
pAux := add(pAux, 32)
pIn := add(pIn, 32)
}
{
mstore(pAux, acc)
acc := mulmod(acc, mload(pIn), q)
}
acc := inverse(acc, q)
// At this point pAux pint to the next free position we substract 1 to point to the last used
pAux := sub(pAux, 32)
// pIn points to the n+1 element, we substract to point to n
pIn := sub(pIn, 32)
lastPIn := pVals // We don't process the first element
for { } gt(pIn, lastPIn) {
pAux := sub(pAux, 32)
pIn := sub(pIn, 32)
}
{
inv := mulmod(acc, mload(pAux), q)
acc := mulmod(acc, mload(pIn), q)
mstore(pIn, inv)
}
// pIn points to first element, we just set it.
mstore(pIn, acc)
}
function checkField(v) {
if iszero(lt(v, q)) {
mstore(0, 0)
return(0,0x20)
}
}
function checkInput(pProof) {
if iszero(eq(mload(pProof), 800 )) {
mstore(0, 0)
return(0,0x20)
}
checkField(mload(add(pProof, pEval_a)))
checkField(mload(add(pProof, pEval_b)))
checkField(mload(add(pProof, pEval_c)))
checkField(mload(add(pProof, pEval_s1)))
checkField(mload(add(pProof, pEval_s2)))
checkField(mload(add(pProof, pEval_zw)))
checkField(mload(add(pProof, pEval_r)))
// Points are checked in the point operations precompiled smart contracts
}
function calculateChallanges(pProof, pMem) {
let a
let b
b := mod(keccak256(add(pProof, pA), 192), q)
mstore( add(pMem, pBeta), b)
mstore( add(pMem, pGamma), mod(keccak256(add(pMem, pBeta), 32), q))
mstore( add(pMem, pAlpha), mod(keccak256(add(pProof, pZ), 64), q))
a := mod(keccak256(add(pProof, pT1), 192), q)
mstore( add(pMem, pXi), a)
mstore( add(pMem, pBetaXi), mulmod(b, a, q))
a:= mulmod(a, a, q)
a:= mulmod(a, a, q)
a:= mulmod(a, a, q)
mstore( add(pMem, pXin), a)
a:= mod(add(sub(a, 1),q), q)
mstore( add(pMem, pZh), a)
mstore( add(pMem, pZhInv), a) // We will invert later together with lagrange pols
let v1 := mod(keccak256(add(pProof, pEval_a), 224), q)
mstore( add(pMem, pV1), v1)
a := mulmod(v1, v1, q)
mstore( add(pMem, pV2), a)
a := mulmod(a, v1, q)
mstore( add(pMem, pV3), a)
a := mulmod(a, v1, q)
mstore( add(pMem, pV4), a)
a := mulmod(a, v1, q)
mstore( add(pMem, pV5), a)
a := mulmod(a, v1, q)
mstore( add(pMem, pV6), a)
mstore( add(pMem, pU), mod(keccak256(add(pProof, pWxi), 128), q))
}
function calculateLagrange(pMem) {
let w := 1
mstore(
add(pMem, pEval_l1),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l2),
mulmod(
n,
mod(
add(
sub(
mload(add(pMem, pXi)),
w
),
q
),
q
),
q
)
)
inverseArray(add(pMem, pZhInv), 3 )
let zh := mload(add(pMem, pZh))
w := 1
mstore(
add(pMem, pEval_l1 ),
mulmod(
mload(add(pMem, pEval_l1 )),
zh,
q
)
)
w := mulmod(w, w1, q)
mstore(
add(pMem, pEval_l2),
mulmod(
w,
mulmod(
mload(add(pMem, pEval_l2)),
zh,
q
),
q
)
)
}
function calculatePl(pMem, pPub) {
let pl := 0
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l1)),
mload(add(pPub, 32)),
q
)
),
q
),
q
)
pl := mod(
add(
sub(
pl,
mulmod(
mload(add(pMem, pEval_l2)),
mload(add(pPub, 64)),
q
)
),
q
),
q
)
mstore(add(pMem, pPl), pl)
}
function calculateT(pProof, pMem) {
let t
let t1
let t2
t := addmod(
mload(add(pProof, pEval_r)),
mload(add(pMem, pPl)),
q
)
t1 := mulmod(
mload(add(pProof, pEval_s1)),
mload(add(pMem, pBeta)),
q
)
t1 := addmod(
t1,
mload(add(pProof, pEval_a)),
q
)
t1 := addmod(
t1,
mload(add(pMem, pGamma)),
q
)
t2 := mulmod(
mload(add(pProof, pEval_s2)),
mload(add(pMem, pBeta)),
q
)
t2 := addmod(
t2,
mload(add(pProof, pEval_b)),
q
)
t2 := addmod(
t2,
mload(add(pMem, pGamma)),
q
)
t1 := mulmod(t1, t2, q)
t2 := addmod(
mload(add(pProof, pEval_c)),
mload(add(pMem, pGamma)),
q
)
t1 := mulmod(t1, t2, q)
t1 := mulmod(t1, mload(add(pProof, pEval_zw)), q)
t1 := mulmod(t1, mload(add(pMem, pAlpha)), q)
t2 := mulmod(
mload(add(pMem, pEval_l1)),
mload(add(pMem, pAlpha)),
q
)
t2 := mulmod(
t2,
mload(add(pMem, pAlpha)),
q
)
t1 := addmod(t1, t2, q)
t := mod(sub(add(t, q), t1), q)
t := mulmod(t, mload(add(pMem, pZhInv)), q)
mstore( add(pMem, pEval_t) , t)
}
function g1_set(pR, pP) {
mstore(pR, mload(pP))
mstore(add(pR, 32), mload(add(pP,32)))
}
function g1_acc(pR, pP) {
let mIn := mload(0x40)
mstore(mIn, mload(pR))
mstore(add(mIn,32), mload(add(pR, 32)))
mstore(add(mIn,64), mload(pP))
mstore(add(mIn,96), mload(add(pP, 32)))
let success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
}
function g1_mulAcc(pR, pP, s) {
let success
let mIn := mload(0x40)
mstore(mIn, mload(pP))
mstore(add(mIn,32), mload(add(pP, 32)))
mstore(add(mIn,64), s)
success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
mstore(add(mIn,64), mload(pR))
mstore(add(mIn,96), mload(add(pR, 32)))
success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
}
function g1_mulAccC(pR, x, y, s) {
let success
let mIn := mload(0x40)
mstore(mIn, x)
mstore(add(mIn,32), y)
mstore(add(mIn,64), s)
success := staticcall(sub(gas(), 2000), 7, mIn, 96, mIn, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
mstore(add(mIn,64), mload(pR))
mstore(add(mIn,96), mload(add(pR, 32)))
success := staticcall(sub(gas(), 2000), 6, mIn, 128, pR, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
}
function g1_mulSetC(pR, x, y, s) {
let success
let mIn := mload(0x40)
mstore(mIn, x)
mstore(add(mIn,32), y)
mstore(add(mIn,64), s)
success := staticcall(sub(gas(), 2000), 7, mIn, 96, pR, 64)
if iszero(success) {
mstore(0, 0)
return(0,0x20)
}
}
function calculateA1(pProof, pMem) {
let p := add(pMem, pA1)
g1_set(p, add(pProof, pWxi))
g1_mulAcc(p, add(pProof, pWxiw), mload(add(pMem, pU)))
}
function calculateB1(pProof, pMem) {
let s
let s1
let p := add(pMem, pB1)
// Calculate D
s := mulmod( mload(add(pProof, pEval_a)), mload(add(pMem, pV1)), q)
g1_mulSetC(p, Qlx, Qly, s)
s := mulmod( s, mload(add(pProof, pEval_b)), q)
g1_mulAccC(p, Qmx, Qmy, s)
s := mulmod( mload(add(pProof, pEval_b)), mload(add(pMem, pV1)), q)
g1_mulAccC(p, Qrx, Qry, s)
s := mulmod( mload(add(pProof, pEval_c)), mload(add(pMem, pV1)), q)
g1_mulAccC(p, Qox, Qoy, s)
s :=mload(add(pMem, pV1))
g1_mulAccC(p, Qcx, Qcy, s)
s := addmod(mload(add(pProof, pEval_a)), mload(add(pMem, pBetaXi)), q)
s := addmod(s, mload(add(pMem, pGamma)), q)
s1 := mulmod(k1, mload(add(pMem, pBetaXi)), q)
s1 := addmod(s1, mload(add(pProof, pEval_b)), q)
s1 := addmod(s1, mload(add(pMem, pGamma)), q)
s := mulmod(s, s1, q)
s1 := mulmod(k2, mload(add(pMem, pBetaXi)), q)
s1 := addmod(s1, mload(add(pProof, pEval_c)), q)
s1 := addmod(s1, mload(add(pMem, pGamma)), q)
s := mulmod(s, s1, q)
s := mulmod(s, mload(add(pMem, pAlpha)), q)
s := mulmod(s, mload(add(pMem, pV1)), q)
s1 := mulmod(mload(add(pMem, pEval_l1)), mload(add(pMem, pAlpha)), q)
s1 := mulmod(s1, mload(add(pMem, pAlpha)), q)
s1 := mulmod(s1, mload(add(pMem, pV1)), q)
s := addmod(s, s1, q)
s := addmod(s, mload(add(pMem, pU)), q)
g1_mulAcc(p, add(pProof, pZ), s)
s := mulmod(mload(add(pMem, pBeta)), mload(add(pProof, pEval_s1)), q)
s := addmod(s, mload(add(pProof, pEval_a)), q)
s := addmod(s, mload(add(pMem, pGamma)), q)
s1 := mulmod(mload(add(pMem, pBeta)), mload(add(pProof, pEval_s2)), q)
s1 := addmod(s1, mload(add(pProof, pEval_b)), q)
s1 := addmod(s1, mload(add(pMem, pGamma)), q)
s := mulmod(s, s1, q)
s := mulmod(s, mload(add(pMem, pAlpha)), q)
s := mulmod(s, mload(add(pMem, pV1)), q)
s := mulmod(s, mload(add(pMem, pBeta)), q)
s := mulmod(s, mload(add(pProof, pEval_zw)), q)
s := mod(sub(q, s), q)
g1_mulAccC(p, S3x, S3y, s)
// calculate F
g1_acc(p , add(pProof, pT1))
s := mload(add(pMem, pXin))
g1_mulAcc(p, add(pProof, pT2), s)
s := mulmod(s, s, q)
g1_mulAcc(p, add(pProof, pT3), s)
g1_mulAcc(p, add(pProof, pA), mload(add(pMem, pV2)))
g1_mulAcc(p, add(pProof, pB), mload(add(pMem, pV3)))
g1_mulAcc(p, add(pProof, pC), mload(add(pMem, pV4)))
g1_mulAccC(p, S1x, S1y, mload(add(pMem, pV5)))
g1_mulAccC(p, S2x, S2y, mload(add(pMem, pV6)))
// calculate E
s := mload(add(pMem, pEval_t))
s := addmod(s, mulmod(mload(add(pProof, pEval_r)), mload(add(pMem, pV1)), q), q)
s := addmod(s, mulmod(mload(add(pProof, pEval_a)), mload(add(pMem, pV2)), q), q)
s := addmod(s, mulmod(mload(add(pProof, pEval_b)), mload(add(pMem, pV3)), q), q)
s := addmod(s, mulmod(mload(add(pProof, pEval_c)), mload(add(pMem, pV4)), q), q)
s := addmod(s, mulmod(mload(add(pProof, pEval_s1)), mload(add(pMem, pV5)), q), q)
s := addmod(s, mulmod(mload(add(pProof, pEval_s2)), mload(add(pMem, pV6)), q), q)
s := addmod(s, mulmod(mload(add(pProof, pEval_zw)), mload(add(pMem, pU)), q), q)
s := mod(sub(q, s), q)
g1_mulAccC(p, G1x, G1y, s)
// Last part of B
s := mload(add(pMem, pXi))
g1_mulAcc(p, add(pProof, pWxi), s)
s := mulmod(mload(add(pMem, pU)), mload(add(pMem, pXi)), q)
s := mulmod(s, w1, q)
g1_mulAcc(p, add(pProof, pWxiw), s)
}
function checkPairing(pMem) -> isOk {
let mIn := mload(0x40)
mstore(mIn, mload(add(pMem, pA1)))
mstore(add(mIn,32), mload(add(add(pMem, pA1), 32)))
mstore(add(mIn,64), X2x2)
mstore(add(mIn,96), X2x1)
mstore(add(mIn,128), X2y2)
mstore(add(mIn,160), X2y1)
mstore(add(mIn,192), mload(add(pMem, pB1)))
let s := mload(add(add(pMem, pB1), 32))
s := mod(sub(qf, s), qf)
mstore(add(mIn,224), s)
mstore(add(mIn,256), G2x2)
mstore(add(mIn,288), G2x1)
mstore(add(mIn,320), G2y2)
mstore(add(mIn,352), G2y1)
let success := staticcall(sub(gas(), 2000), 8, mIn, 384, mIn, 0x20)
isOk := and(success, mload(mIn))
}
let pMem := mload(0x40)
mstore(0x40, add(pMem, lastMem))
checkInput(proof)
calculateChallanges(proof, pMem)
calculateLagrange(pMem)
calculatePl(pMem, pubSignals)
calculateT(proof, pMem)
calculateA1(proof, pMem)
calculateB1(proof, pMem)
let isValid := checkPairing(pMem)
mstore(0x40, sub(pMem, lastMem))
mstore(0, isValid)
return(0,0x20)
}
}
}