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

38
.vscode/launch.json vendored
View File

@ -65,6 +65,42 @@
"test/plonk_circuit/proof.json",
"-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"
}
]
}

View File

@ -276,11 +276,29 @@ cat circuit.r1cs.json
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
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` 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
#### Plonk
```sh
snarkjs plonk prove circuit_final.zkey witness.wtns proof.json public.json
```
#### Groth16
```sh
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:
> ```sh
@ -393,11 +420,18 @@ We create the proof. `groth16 prove` generates the files `proof.json` and `publi
### 25. Verify the proof
#### Plonk
```sh
snarkjs plonk verify verification_key.json public.json proof.json
```
#### Groth16
```sh
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.

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
View File

@ -1,20 +1,20 @@
/*
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
the Free Software Foundation, either version 3 of the License, or
(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
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 jaz. If not, see <https://www.gnu.org/licenses/>.
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
*/
/* eslint-disable no-console */
@ -167,13 +167,6 @@ const commands = [
alias: ["wej"],
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>",
description: "creates a zkey file with a new contribution",
@ -243,11 +236,18 @@ const commands = [
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.",
alias: ["zkesc", "generatecall -pub|public -p|proof"],
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]",
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) {
let S = fileName;
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");
let templateName;
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 templates = {};
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");
@ -610,33 +600,15 @@ async function zkeyExportSolidityCalldata(params, options) {
const pub = unstringifyBigInts(JSON.parse(fs.readFileSync(publicName, "utf8")));
const proof = unstringifyBigInts(JSON.parse(fs.readFileSync(proofName, "utf8")));
let inputs = "";
for (let i=0; i<pub.length; i++) {
if (inputs != "") inputs = inputs + ",";
inputs = inputs + p256(pub[i]);
}
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}]`;
let res;
if (proof.protocol == "groth16") {
res = await groth16.exportSolidityCallData(proof, pub);
} else if (proof.protocol == "plonk") {
res = await plonk.exportSolidityCallData(proof, pub);
} else {
throw new Error("InvalidProof");
throw new Error("Invalid Protocol");
}
console.log(S);
console.log(res);
return 0;
}

View File

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

View File

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

340
package-lock.json generated
View File

@ -11,8 +11,9 @@
"@iden3/binfileutils": "0.0.8",
"blake2b-wasm": "https://github.com/jbaylina/blake2b-wasm.git",
"circom_runtime": "0.1.13",
"ejs": "^3.1.6",
"fastfile": "0.0.19",
"ffjavascript": "0.2.35",
"ffjavascript": "0.2.36",
"js-sha3": "^0.8.0",
"logplease": "^1.2.15",
"r1csfile": "0.0.32",
@ -103,15 +104,6 @@
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"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": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
@ -380,11 +372,15 @@
"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": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
"dev": true
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
},
"node_modules/big-integer": {
"version": "1.6.48",
@ -418,7 +414,6 @@
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -542,6 +537,16 @@
"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": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
@ -642,8 +647,7 @@
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
"node_modules/cross-spawn": {
"version": "6.0.5",
@ -754,6 +758,20 @@
"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": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
@ -823,6 +841,14 @@
"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": {
"version": "6.8.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz",
@ -958,15 +984,6 @@
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"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": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
@ -1131,9 +1148,9 @@
"integrity": "sha512-tz9nWR5KYb6eR2odFQ7oxqEkx8F3YQZ6NBJoJR92YEG3DqYOqyxMck8PKvTVNKx3uwvOqGnLXNScnqpdHRdHGQ=="
},
"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==",
"version": "0.2.36",
"resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.36.tgz",
"integrity": "sha512-OPgov0qQiV7wffycylpmEq6rm4Pu68LIMFbB1jrM5bCr1yXqgIMQ6IparbgRuFG5aj3NPmsorrGh7pQJnQlIIw==",
"dependencies": {
"big-integer": "^1.6.48",
"wasmcurves": "0.0.14",
@ -1152,15 +1169,6 @@
"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": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz",
@ -1173,6 +1181,14 @@
"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": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
@ -1657,6 +1673,79 @@
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
"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": {
"version": "26.6.2",
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz",
@ -1721,9 +1810,9 @@
}
},
"node_modules/lodash": {
"version": "4.17.20",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true
},
"node_modules/logplease": {
@ -1759,7 +1848,6 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"dependencies": {
"brace-expansion": "^1.1.7"
},
@ -1925,15 +2013,6 @@
"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": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
@ -2394,6 +2473,16 @@
"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": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@ -3339,12 +3428,6 @@
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"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": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
@ -3576,11 +3659,15 @@
"integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
"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": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
"dev": true
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
},
"big-integer": {
"version": "1.6.48",
@ -3609,7 +3696,6 @@
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -3707,6 +3793,18 @@
"requires": {
"ffjavascript": "0.2.35",
"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": {
@ -3793,8 +3891,7 @@
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
"cross-spawn": {
"version": "6.0.5",
@ -3880,6 +3977,14 @@
"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": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
@ -3939,6 +4044,11 @@
"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
"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": {
"version": "6.8.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz",
@ -4025,12 +4135,6 @@
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"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": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
@ -4186,9 +4290,9 @@
"integrity": "sha512-tz9nWR5KYb6eR2odFQ7oxqEkx8F3YQZ6NBJoJR92YEG3DqYOqyxMck8PKvTVNKx3uwvOqGnLXNScnqpdHRdHGQ=="
},
"ffjavascript": {
"version": "0.2.35",
"resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.35.tgz",
"integrity": "sha512-xnC51tWbi0ah4SH+02jEfJyO+P+NiZWnxQrLDLtBYY1Dv3QM5ydxzd+gxnLEfWdT8i1bMM5pIh5P25l6fNCaVQ==",
"version": "0.2.36",
"resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.36.tgz",
"integrity": "sha512-OPgov0qQiV7wffycylpmEq6rm4Pu68LIMFbB1jrM5bCr1yXqgIMQ6IparbgRuFG5aj3NPmsorrGh7pQJnQlIIw==",
"requires": {
"big-integer": "^1.6.48",
"wasmcurves": "0.0.14",
@ -4202,14 +4306,6 @@
"dev": true,
"requires": {
"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": {
@ -4221,6 +4317,14 @@
"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": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
@ -4596,6 +4700,63 @@
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
"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": {
"version": "26.6.2",
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz",
@ -4651,9 +4812,9 @@
}
},
"lodash": {
"version": "4.17.20",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
"dev": true
},
"logplease": {
@ -4686,7 +4847,6 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@ -4821,12 +4981,6 @@
"integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
"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": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
@ -5184,6 +5338,18 @@
"@iden3/binfileutils": "0.0.8",
"fastfile": "0.0.19",
"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": {

View File

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

View File

@ -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 BigArrayHandler = {

View File

@ -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";
const version = pkg.version;

View File

@ -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 prove} from "./groth16_prove.js";
export {default as verify} from "./groth16_verify.js";
export {default as exportSolidityCallData} from "./groth16_exportsoliditycalldata.js";

View File

@ -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;
}

View File

@ -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 wtns_calculate from "./wtns_calculate.js";

View File

@ -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 zkeyUtils from "./zkey_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.protocol = "groth16";
proof.curve = curve.name;
await fdZKey.close();
await fdWtns.close();

View File

@ -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";

View File

@ -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";
export default async function loadSymbols(symFileName) {

View File

@ -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 */
import Blake2b from "blake2b-wasm";
import readline from "readline";

View File

@ -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";

View File

@ -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 fullProve} from "./plonk_fullprove.js";
export {default as prove} from "./plonk_prove.js";
export {default as verify} from "./plonk_verify.js";
export {default as exportSolidityCallData} from "./plonk_exportsoliditycalldata.js";

View File

@ -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;
}

View File

@ -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 wtns_calculate from "./wtns_calculate.js";

View File

@ -98,6 +98,7 @@ export default async function plonk16Prove(zkeyFileName, witnessFileName, logger
///////////////////////
proof.protocol = "plonk";
proof.curve = curve.name;
await fdZKey.close();
await fdWtns.close();
@ -130,6 +131,8 @@ export default async function plonk16Prove(zkeyFileName, witnessFileName, logger
proof.Wxi = G1.toObject(proof.Wxi);
proof.Wxiw = G1.toObject(proof.Wxiw);
delete proof.eval_t;
proof = stringifyBigInts(proof);
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--;
return deg;
}
*/
function printPol(P) {
const n=(P.byteLength/n8r);
@ -323,6 +325,7 @@ export default async function plonk16Prove(zkeyFileName, witnessFileName, logger
}
console.log("]");
}
*/
const QM4 = new BigBuffer(zkey.domainSize*4*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])),
];
/*
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 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]);
}
printPol(T);
let t = await Fr.ifft(T);
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);
printPol(tz);
for (let i=0; i<zkey.domainSize*4; i++) {
const a = tz.slice(i*n8r, (i+1)*n8r);
if (i > (zkey.domainSize*3 +5) ) {
@ -698,15 +685,14 @@ export default async function plonk16Prove(zkeyFileName, witnessFileName, logger
}
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, n8r, proof.eval_b);
Fr.toRprBE(transcript5, n8r*2, proof.eval_c);
Fr.toRprBE(transcript5, n8r*3, proof.eval_s1);
Fr.toRprBE(transcript5, n8r*4, proof.eval_s2);
Fr.toRprBE(transcript5, n8r*5, proof.eval_zw);
Fr.toRprBE(transcript5, n8r*6, proof.eval_t);
Fr.toRprBE(transcript5, n8r*7, proof.eval_r);
Fr.toRprBE(transcript5, n8r*6, proof.eval_r);
ch.v = [];
ch.v[1] = hashToFr(transcript5);
if (logger) logger.debug("v: " + Fr.toString(ch.v[1]));

View File

@ -61,7 +61,7 @@ export default async function plonkSetup(r1csName, ptauName, zkeyName, logger) {
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) {

View File

@ -44,18 +44,19 @@ export default async function plonkVerify(vk_verifier, publicSignals, proof, log
}
const challanges = calculateChallanges(curve, proof);
if (logger) {
logger.debug("beta: " + Fr.toString(challanges.beta));
logger.debug("gamma: " + Fr.toString(challanges.gamma));
logger.debug("alpha: " + Fr.toString(challanges.alpha));
logger.debug("xi: " + Fr.toString(challanges.xi));
logger.debug("v: " + Fr.toString(challanges.v));
logger.debug("u: " + Fr.toString(challanges.u));
logger.debug("beta: " + Fr.toString(challanges.beta, 16));
logger.debug("gamma: " + Fr.toString(challanges.gamma, 16));
logger.debug("alpha: " + Fr.toString(challanges.alpha, 16));
logger.debug("xi: " + Fr.toString(challanges.xi, 16));
logger.debug("v1: " + Fr.toString(challanges.v[1], 16));
logger.debug("v6: " + Fr.toString(challanges.v[6], 16));
logger.debug("u: " + Fr.toString(challanges.u, 16));
}
const L = calculateLagrangeEvaluations(curve, challanges, vk_verifier);
if (logger) {
logger.debug("Lagrange Evaluations: ");
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);
if (logger) {
logger.debug("Pl: " + Fr.toString(pl));
logger.debug("Pl: " + Fr.toString(pl, 16));
}
const t = calculateT(curve, proof, challanges, pl, L[1]);
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]);
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);
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);
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);
@ -121,7 +122,6 @@ function fromObjectProof(curve, proof) {
res.eval_zw = Fr.fromObject(proof.eval_zw);
res.eval_s1 = Fr.fromObject(proof.eval_s1);
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.Wxi = G1.fromObject(proof.Wxi);
res.Wxiw = G1.fromObject(proof.Wxiw);
@ -181,7 +181,6 @@ function calculateChallanges(curve, proof) {
const transcript3 = new Uint8Array(G1.F.n8*2);
G1.toRprUncompressed(transcript3, 0, proof.Z);
res.alpha = hashToFr(curve, transcript3);
console.log("Alpha: ", res.alpha);
const transcript4 = new Uint8Array(G1.F.n8*2*3);
G1.toRprUncompressed(transcript4, 0, proof.T1);
@ -189,15 +188,14 @@ function calculateChallanges(curve, proof) {
G1.toRprUncompressed(transcript4, G1.F.n8*4, proof.T3);
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, n8r, proof.eval_b);
Fr.toRprBE(transcript5, n8r*2, proof.eval_c);
Fr.toRprBE(transcript5, n8r*3, proof.eval_s1);
Fr.toRprBE(transcript5, n8r*4, proof.eval_s2);
Fr.toRprBE(transcript5, n8r*5, proof.eval_zw);
Fr.toRprBE(transcript5, n8r*6, proof.eval_t);
Fr.toRprBE(transcript5, n8r*7, proof.eval_r);
Fr.toRprBE(transcript5, n8r*6, proof.eval_r);
res.v = [];
res.v[1] = hashToFr(curve, transcript5);
@ -277,14 +275,6 @@ function calculateT(curve, proof, challanges, pl, l1) {
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;
}

View File

@ -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 exportChallenge} from "./powersoftau_export_challenge.js";

View File

@ -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 * as utils from "./powersoftau_utils.js";
import * as misc from "./misc.js";
import * as binFileUtils from "@iden3/binfileutils";
export default async function beacon(oldPtauFilename, newPTauFilename, name, beaconHashStr,numIterationsExp, logger) {
const beaconHash = misc.hex2ByteArray(beaconHashStr);
if ( (beaconHash.byteLength == 0)

View File

@ -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
// Hash of the last contribution 64 Bytes
// 2^N*2-1 TauG1 Points (compressed)

View File

@ -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
// Hash of the last contribution 64 Bytes
// 2^N*2-1 TauG1 Points (uncompressed)

View File

@ -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 utils from "./powersoftau_utils.js";
import * as fastFile from "fastfile";

View File

@ -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 binFileUtils from "@iden3/binfileutils";

View File

@ -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 Blake2b from "blake2b-wasm";
import * as utils from "./powersoftau_utils.js";

View File

@ -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)
n8

View File

@ -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 utils from "./powersoftau_utils.js";
import {BigBuffer} from "ffjavascript";

View File

@ -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 utils from "./powersoftau_utils.js";

View File

@ -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 Blake2b from "blake2b-wasm";
import * as keyPair from "./keypair.js";

View File

@ -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 * as utils from "./powersoftau_utils.js";
import * as keyPair from "./keypair.js";

View File

@ -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 info} from "./r1cs_info.js";
export {default as exportJson} from "./r1cs_export_json.js";

View File

@ -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";
export function stringifyBigInts(Fr, o) {

View File

@ -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 { readR1cs } from "r1csfile";

View File

@ -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) {
for (let i=0; i<r1cs.constraints.length; i++) {

View File

@ -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 prove} from "./groth16_prove.js";
export {default as validate} from "./groth16_verify.js";

View File

@ -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");
let NodeWorker;
if (!inBrowser) {

View File

@ -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 debug} from "./wtns_debug.js";
export {default as exportJson} from "./wtns_export_json.js";

View File

@ -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 { WitnessCalculatorBuilder } from "circom_runtime";
import * as wtnsUtils from "./wtns_utils.js";

View File

@ -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 { WitnessCalculatorBuilder } from "circom_runtime";
import * as wtnsUtils from "./wtns_utils.js";

View File

@ -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";
export default async function wtnsExportJson(wtnsFileName) {

View File

@ -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 * as binFileUtils from "@iden3/binfileutils";

View File

@ -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 exportBellman} from "./zkey_export_bellman.js";
export {default as importBellman} from "./zkey_import_bellman.js";

View File

@ -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 zkeyUtils from "./zkey_utils.js";
import { getCurveFromQ as getCurve } from "./curves.js";

View File

@ -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
// Hash of the last contribution 64 Bytes
// 2^N*2-1 TauG1 Points (compressed)

View File

@ -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 zkeyUtils from "./zkey_utils.js";

View File

@ -1,4 +1,5 @@
import * as fastFile from "fastfile";
import ejs from "ejs";
import exportVerificationKey from "./zkey_export_verificationkey.js";
// 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 fd = await fastFile.readExisting(templateName);
const buff = await fd.read(fd.totalSize);
let template = new TextDecoder("utf-8").decode(buff);
let template = templates[verificationKey.protocol];
const vkalpha1_str = `${verificationKey.vk_alpha_1[0].toString()},`+
`${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;
return ejs.render(template , verificationKey);
}

View File

@ -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 zkeyUtils from "./zkey_utils.js";
import { getCurveFromQ as getCurve } from "./curves.js";
import { utils } from "ffjavascript";
const {stringifyBigInts} = utils;
export default async function zkeyExportVerificationKey(zkeyName, /* logger */ ) {
const {fd, sections} = await binFileUtils.readBinFile(zkeyName, "zkey", 2);

View File

@ -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 binFileUtils from "@iden3/binfileutils";
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) {
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 sG1 = curve.G1.F.n8*2;

View File

@ -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 * as utils from "./powersoftau_utils.js";

View File

@ -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
// ======

View File

@ -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 zkeyUtils from "./zkey_utils.js";
import { getCurveFromQ as getCurve } from "./curves.js";
@ -17,7 +36,7 @@ export default async function phase2verifyFromInit(initFileName, pTauFileName, z
await Blake2b.ready();
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") {
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 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))
||(!Scalar.eq(zkeyInit.r, zkey.r))

View File

@ -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 phase2verifyFromInit from "./zkey_verify_frominit.js";

View File

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

View File

@ -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)
}
}
}

View File

@ -18,9 +18,11 @@ describe("Full process", function () {
const zkey_1 = {type: "mem"};
const zkey_2 = {type: "mem"};
const zkey_final = {type: "mem"};
const zkey_plonk = {type: "mem"};
const bellman_1 = {type: "mem"};
const bellman_2 = {type: "mem"};
let vKey;
let vKeyPlonk;
const wtns = {type: "mem"};
let proof;
let publicSignals;
@ -36,7 +38,7 @@ describe("Full process", function () {
});
it ("powersoftau new", async () => {
await snarkjs.powersOfTau.newAccumulator(curve, 10, ptau_0);
await snarkjs.powersOfTau.newAccumulator(curve, 11, ptau_0);
});
it ("powersoftau contribute ", async () => {
@ -68,7 +70,7 @@ describe("Full process", function () {
assert(res);
});
it ("zkey new", async () => {
it ("groth16 setup", async () => {
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;
});
it ("groth16 verify", async () => {
const res = await snarkjs.groth16.verify(vKey, publicSignals, proof);
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);
});
});

View File

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

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

View File

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

View File

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

View File

@ -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)
}
}
}