snarkjs/cli.js

1092 lines
33 KiB
JavaScript
Raw Normal View History

2018-10-21 19:24:49 +03:00
/*
Copyright 2018 0KIMS association.
2021-05-31 14:21:07 +03:00
This file is part of snarkJS.
2018-10-21 19:24:49 +03:00
2021-05-31 14:21:07 +03:00
snarkJS is a free software: you can redistribute it and/or modify it
2018-10-21 19:24:49 +03:00
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.
2021-05-31 14:21:07 +03:00
snarkJS is distributed in the hope that it will be useful, but WITHOUT
2018-10-21 19:24:49 +03:00
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
2021-05-31 14:21:07 +03:00
along with snarkJS. If not, see <https://www.gnu.org/licenses/>.
2018-10-21 19:24:49 +03:00
*/
/* eslint-disable no-console */
2020-07-11 11:31:52 +03:00
import fs from "fs";
2018-10-21 19:24:49 +03:00
2020-10-08 12:43:05 +03:00
import {readR1cs} from "r1csfile";
2020-03-26 22:16:29 +03:00
2020-07-11 11:31:52 +03:00
import loadSyms from "./src/loadsyms.js";
import * as r1cs from "./src/r1cs.js";
2020-05-09 16:05:45 +03:00
2020-07-11 11:31:52 +03:00
import clProcessor from "./src/clprocessor.js";
2020-05-09 16:05:45 +03:00
2020-09-02 13:06:20 +03:00
import * as powersOfTau from "./src/powersoftau.js";
2020-05-09 16:05:45 +03:00
2020-07-11 11:31:52 +03:00
import { utils } from "ffjavascript";
const {stringifyBigInts, unstringifyBigInts} = utils;
2020-06-08 12:03:36 +03:00
2020-07-11 11:31:52 +03:00
import * as zkey from "./src/zkey.js";
import * as groth16 from "./src/groth16.js";
2021-05-18 23:26:22 +03:00
import * as plonk from "./src/plonk.js";
2020-07-11 11:31:52 +03:00
import * as wtns from "./src/wtns.js";
import * as curves from "./src/curves.js";
import path from "path";
2020-06-08 12:03:36 +03:00
2020-07-11 11:31:52 +03:00
import Logger from "logplease";
const logger = Logger.create("snarkJS", {showTimestamp:false});
Logger.setLogLevel("INFO");
2020-05-31 01:46:49 +03:00
2020-08-29 15:12:24 +03:00
const __dirname = path.dirname(new URL(import.meta.url).pathname);
2020-05-09 16:05:45 +03:00
const commands = [
2020-07-11 11:31:52 +03:00
{
cmd: "powersoftau new <curve> <power> [powersoftau_0000.ptau]",
description: "Starts a powers of tau ceremony",
alias: ["ptn"],
options: "-verbose|v",
2020-09-02 13:06:20 +03:00
action: powersOfTauNew
2020-07-11 11:31:52 +03:00
},
{
cmd: "powersoftau contribute <powersoftau.ptau> <new_powersoftau.ptau>",
description: "creates a ptau file with a new contribution",
alias: ["ptc"],
options: "-verbose|v -name|n -entropy|e",
2020-09-02 13:06:20 +03:00
action: powersOfTauContribute
2020-07-11 11:31:52 +03:00
},
{
2020-07-14 12:55:12 +03:00
cmd: "powersoftau export challenge <powersoftau_0000.ptau> [challenge]",
description: "Creates a challenge",
2020-07-11 11:31:52 +03:00
alias: ["ptec"],
options: "-verbose|v",
2020-09-02 13:06:20 +03:00
action: powersOfTauExportChallenge
2020-07-11 11:31:52 +03:00
},
{
2020-07-14 12:55:12 +03:00
cmd: "powersoftau challenge contribute <curve> <challenge> [response]",
description: "Contribute to a challenge",
2020-07-11 11:31:52 +03:00
alias: ["ptcc"],
options: "-verbose|v -entropy|e",
2020-09-02 13:06:20 +03:00
action: powersOfTauChallengeContribute
2020-07-11 11:31:52 +03:00
},
{
cmd: "powersoftau import response <powersoftau_old.ptau> <response> <<powersoftau_new.ptau>",
description: "import a response to a ptau file",
alias: ["ptir"],
options: "-verbose|v -nopoints -nocheck -name|n",
2020-09-02 13:06:20 +03:00
action: powersOfTauImport
2020-07-11 11:31:52 +03:00
},
{
cmd: "powersoftau beacon <old_powersoftau.ptau> <new_powersoftau.ptau> <beaconHash(Hex)> <numIterationsExp>",
description: "adds a beacon",
alias: ["ptb"],
options: "-verbose|v -name|n",
2020-09-02 13:06:20 +03:00
action: powersOfTauBeacon
2020-07-11 11:31:52 +03:00
},
{
cmd: "powersoftau prepare phase2 <powersoftau.ptau> <new_powersoftau.ptau>",
description: "Prepares phase 2. ",
longDescription: " This process calculates the evaluation of the Lagrange polinomials at tau for alpha*tau and beta tau",
alias: ["pt2"],
options: "-verbose|v",
2020-09-02 13:06:20 +03:00
action: powersOfTauPreparePhase2
},
{
cmd: "powersoftau convert <old_powersoftau.ptau> <new_powersoftau.ptau>",
description: "Convert ptau",
longDescription: " This process calculates the evaluation of the Lagrange polinomials at tau for alpha*tau and beta tau",
alias: ["ptcv"],
options: "-verbose|v",
action: powersOfTauConvert
},
{
cmd: "powersoftau truncate <powersoftau.ptau>",
description: "Generate diferent powers of tau with smoller sizes ",
longDescription: " This process generates smaller ptau files from a bigger power ptau",
alias: ["ptt"],
options: "-verbose|v",
action: powersOfTauTruncate
2020-07-11 11:31:52 +03:00
},
2020-07-13 08:21:03 +03:00
{
cmd: "powersoftau verify <powersoftau.ptau>",
description: "verifies a powers of tau file",
alias: ["ptv"],
options: "-verbose|v",
2020-09-02 13:06:20 +03:00
action: powersOfTauVerify
2020-07-13 08:21:03 +03:00
},
2020-07-11 11:31:52 +03:00
{
cmd: "powersoftau export json <powersoftau_0000.ptau> <powersoftau_0000.json>",
description: "Exports a power of tau file to a JSON",
alias: ["ptej"],
options: "-verbose|v",
2020-09-02 13:06:20 +03:00
action: powersOfTauExportJson
2020-07-11 11:31:52 +03:00
},
2020-05-09 16:05:45 +03:00
{
cmd: "r1cs info [circuit.r1cs]",
description: "Print statistiscs of a circuit",
alias: ["ri", "info -r|r1cs:circuit.r1cs"],
action: r1csInfo
},
{
cmd: "r1cs print [circuit.r1cs] [circuit.sym]",
description: "Print the constraints of a circuit",
alias: ["rp", "print -r|r1cs:circuit.r1cs -s|sym"],
action: r1csPrint
},
{
2020-06-30 16:45:21 +03:00
cmd: "r1cs export json [circuit.r1cs] [circuit.json]",
description: "Export r1cs to JSON file",
alias: ["rej"],
action: r1csExportJSON
},
{
cmd: "wtns calculate [circuit.wasm] [input.json] [witness.wtns]",
2020-05-09 16:05:45 +03:00
description: "Caclculate specific witness of a circuit given an input",
alias: ["wc", "calculatewitness -ws|wasm:circuit.wasm -i|input:input.json -wt|witness:witness.wtns"],
2020-06-30 16:45:21 +03:00
action: wtnsCalculate
2020-05-09 16:05:45 +03:00
},
{
2020-06-30 16:45:21 +03:00
cmd: "wtns debug [circuit.wasm] [input.json] [witness.wtns] [circuit.sym]",
2020-05-09 16:05:45 +03:00
description: "Calculate the witness with debug info.",
longDescription: "Calculate the witness with debug info. \nOptions:\n-g or --g : Log signal gets\n-s or --s : Log signal sets\n-t or --trigger : Log triggers ",
options: "-get|g -set|s -trigger|t",
alias: ["wd"],
2020-06-30 16:45:21 +03:00
action: wtnsDebug
},
{
cmd: "wtns export json [witness.wtns] [witnes.json]",
description: "Calculate the witness with debug info.",
longDescription: "Calculate the witness with debug info. \nOptions:\n-g or --g : Log signal gets\n-s or --s : Log signal sets\n-t or --trigger : Log triggers ",
2020-07-11 11:31:52 +03:00
options: "-verbose|v",
2020-06-30 16:45:21 +03:00
alias: ["wej"],
action: wtnsExportJson
2020-05-09 16:05:45 +03:00
},
2020-07-13 08:21:03 +03:00
{
cmd: "zkey contribute <circuit_old.zkey> <circuit_new.zkey>",
description: "creates a zkey file with a new contribution",
alias: ["zkc"],
options: "-verbose|v -entropy|e -name|n",
action: zkeyContribute
},
2020-06-14 18:37:22 +03:00
{
2020-12-18 17:38:31 +03:00
cmd: "zkey export bellman <circuit_xxxx.zkey> [circuit.mpcparams]",
2020-06-14 18:37:22 +03:00
description: "Export a zKey to a MPCParameters file compatible with kobi/phase2 (Bellman)",
alias: ["zkeb"],
options: "-verbose|v",
action: zkeyExportBellman
},
2020-07-13 08:21:03 +03:00
{
cmd: "zkey bellman contribute <curve> <circuit.mpcparams> <circuit_response.mpcparams>",
2020-07-22 11:39:18 +03:00
description: "contributes to a challenge file in bellman format",
2020-07-13 08:21:03 +03:00
alias: ["zkbc"],
options: "-verbose|v -entropy|e",
action: zkeyBellmanContribute
},
2020-06-14 18:37:22 +03:00
{
cmd: "zkey import bellman <circuit_old.zkey> <circuit.mpcparams> <circuit_new.zkey>",
description: "Export a zKey to a MPCParameters file compatible with kobi/phase2 (Bellman) ",
alias: ["zkib"],
2020-07-11 11:31:52 +03:00
options: "-verbose|v -name|n",
2020-06-14 18:37:22 +03:00
action: zkeyImportBellman
},
{
cmd: "zkey beacon <circuit_old.zkey> <circuit_new.zkey> <beaconHash(Hex)> <numIterationsExp>",
description: "adds a beacon",
alias: ["zkb"],
options: "-verbose|v -name|n",
action: zkeyBeacon
},
{
2020-12-18 17:38:31 +03:00
cmd: "zkey verify r1cs [circuit.r1cs] [powersoftau.ptau] [circuit_final.zkey]",
2020-07-13 08:21:03 +03:00
description: "Verify zkey file contributions and verify that matches with the original circuit.r1cs and ptau",
2020-12-18 17:38:31 +03:00
alias: ["zkv", "zkvr", "zkey verify"],
2020-07-13 08:21:03 +03:00
options: "-verbose|v",
2020-12-18 17:38:31 +03:00
action: zkeyVerifyFromR1cs
},
2020-06-14 18:37:22 +03:00
{
2020-12-18 17:38:31 +03:00
cmd: "zkey verify init [circuit_0000.zkey] [powersoftau.ptau] [circuit_final.zkey]",
description: "Verify zkey file contributions and verify that matches with the original circuit.r1cs and ptau",
alias: ["zkvi"],
options: "-verbose|v",
action: zkeyVerifyFromInit
},
{
cmd: "zkey export verificationkey [circuit_final.zkey] [verification_key.json]",
2020-06-14 18:37:22 +03:00
description: "Exports a verification key",
alias: ["zkev"],
action: zkeyExportVKey
},
{
2020-12-18 17:38:31 +03:00
cmd: "zkey export json [circuit_final.zkey] [circuit_final.zkey.json]",
2020-06-14 18:37:22 +03:00
description: "Exports a circuit key to a JSON file",
alias: ["zkej"],
2020-05-31 01:46:49 +03:00
options: "-verbose|v",
2020-06-14 18:37:22 +03:00
action: zkeyExportJson
2020-05-31 01:46:49 +03:00
},
2020-07-13 08:21:03 +03:00
{
2020-12-18 17:38:31 +03:00
cmd: "zkey export solidityverifier [circuit_final.zkey] [verifier.sol]",
2020-07-13 08:21:03 +03:00
description: "Creates a verifier in solidity",
alias: ["zkesv", "generateverifier -vk|verificationkey -v|verifier"],
action: zkeyExportSolidityVerifier
},
{
2021-05-31 14:21:07 +03:00
cmd: "zkey export soliditycalldata [public.json] [proof.json]",
2020-07-13 08:21:03 +03:00
description: "Generates call parameters ready to be called.",
alias: ["zkesc", "generatecall -pub|public -p|proof"],
action: zkeyExportSolidityCalldata
},
2021-05-31 14:21:07 +03:00
{
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
},
2020-07-13 08:21:03 +03:00
{
2020-12-18 17:38:31 +03:00
cmd: "groth16 prove [circuit_final.zkey] [witness.wtns] [proof.json] [public.json]",
2020-07-13 08:21:03 +03:00
description: "Generates a zk Proof from witness",
alias: ["g16p", "zpw", "zksnark proof", "proof -pk|provingkey -wt|witness -p|proof -pub|public"],
options: "-verbose|v -protocol",
action: groth16Prove
},
{
2020-12-18 17:38:31 +03:00
cmd: "groth16 fullprove [input.json] [circuit_final.wasm] [circuit_final.zkey] [proof.json] [public.json]",
2020-07-13 08:21:03 +03:00
description: "Generates a zk Proof from input",
alias: ["g16f", "g16i"],
options: "-verbose|v -protocol",
action: groth16FullProve
},
{
cmd: "groth16 verify [verification_key.json] [public.json] [proof.json]",
description: "Verify a zk Proof",
alias: ["g16v", "verify -vk|verificationkey -pub|public -p|proof"],
action: groth16Verify
},
2021-05-18 23:26:22 +03:00
{
cmd: "plonk setup [circuit.r1cs] [powersoftau.ptau] [circuit.zkey]",
description: "Creates an initial PLONK pkey ",
alias: ["pks"],
options: "-verbose|v",
action: plonkSetup
},
{
cmd: "plonk prove [circuit.zkey] [witness.wtns] [proof.json] [public.json]",
description: "Generates a PLONK Proof from witness",
alias: ["pkp"],
options: "-verbose|v -protocol",
action: plonkProve
},
{
cmd: "plonk fullprove [input.json] [circuit.wasm] [circuit.zkey] [proof.json] [public.json]",
description: "Generates a PLONK Proof from input",
alias: ["pkf"],
options: "-verbose|v -protocol",
action: plonkFullProve
},
{
cmd: "plonk verify [verification_key.json] [public.json] [proof.json]",
description: "Verify a PLONK Proof",
alias: ["pkv"],
options: "-verbose|v",
action: plonkVerify
}
2020-05-09 16:05:45 +03:00
];
clProcessor(commands).then( (res) => {
process.exit(res);
}, (err) => {
2020-07-11 11:31:52 +03:00
logger.error(err);
2020-05-09 16:05:45 +03:00
process.exit(1);
});
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
/*
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
TODO COMMANDS
=============
2019-06-16 01:12:50 +03:00
2020-05-09 16:05:45 +03:00
{
2020-07-13 08:21:03 +03:00
cmd: "zksnark setup [circuit.r1cs] [circuit.zkey] [verification_key.json]",
description: "Run a simple setup for a circuit generating the proving key.",
alias: ["zs", "setup -r1cs|r -provingkey|pk -verificationkey|vk"],
options: "-verbose|v -protocol",
action: zksnarkSetup
2020-05-09 16:05:45 +03:00
},
{
cmd: "witness verify <circuit.r1cs> <witness.wtns>",
description: "Verify a witness agains a r1cs",
alias: ["wv"],
action: witnessVerify
},
2020-07-13 08:21:03 +03:00
{
cmd: "powersOfTau export response"
}
2020-05-09 16:05:45 +03:00
*/
2019-06-16 01:12:50 +03:00
2020-05-09 16:05:45 +03:00
function changeExt(fileName, newExt) {
let S = fileName;
while ((S.length>0) && (S[S.length-1] != ".")) S = S.slice(0, S.length-1);
if (S.length>0) {
return S + newExt;
} else {
return fileName+"."+newExt;
}
}
2019-06-16 01:12:50 +03:00
2020-05-09 16:05:45 +03:00
// r1cs export circomJSON [circuit.r1cs] [circuit.json]
async function r1csInfo(params, options) {
const r1csName = params[0] || "circuit.r1cs";
2019-06-16 01:12:50 +03:00
2020-07-11 11:31:52 +03:00
if (options.verbose) Logger.setLogLevel("DEBUG");
await r1cs.info(r1csName, logger);
2020-03-26 22:16:29 +03:00
2020-04-18 21:21:16 +03:00
2020-05-09 16:05:45 +03:00
return 0;
}
2020-04-18 21:21:16 +03:00
2020-05-09 16:05:45 +03:00
// r1cs print [circuit.r1cs] [circuit.sym]
async function r1csPrint(params, options) {
const r1csName = params[0] || "circuit.r1cs";
2020-06-30 16:45:21 +03:00
const symName = params[1] || changeExt(r1csName, "sym");
2020-07-11 11:31:52 +03:00
if (options.verbose) Logger.setLogLevel("DEBUG");
2020-10-09 07:19:20 +03:00
const cir = await readR1cs(r1csName, true, true, false);
2019-06-16 01:12:50 +03:00
2020-05-09 16:05:45 +03:00
const sym = await loadSyms(symName);
2018-10-21 19:24:49 +03:00
2020-07-11 11:31:52 +03:00
await r1cs.print(cir, sym, logger);
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
return 0;
}
2018-10-21 19:24:49 +03:00
2020-06-30 16:45:21 +03:00
// r1cs export json [circuit.r1cs] [circuit.json]
async function r1csExportJSON(params, options) {
const r1csName = params[0] || "circuit.r1cs";
const jsonName = params[1] || changeExt(r1csName, "json");
2020-07-11 11:31:52 +03:00
if (options.verbose) Logger.setLogLevel("DEBUG");
const r1csObj = await r1cs.exportJson(r1csName, logger);
2020-10-08 17:06:48 +03:00
const S = JSON.stringify(r1csObj, null, 1);
2020-07-11 11:31:52 +03:00
await fs.promises.writeFile(jsonName, S);
2020-06-30 16:45:21 +03:00
return 0;
}
// wtns calculate <circuit.wasm> <input.json> <witness.wtns>
async function wtnsCalculate(params, options) {
2020-05-09 16:05:45 +03:00
const wasmName = params[0] || "circuit.wasm";
const inputName = params[1] || "input.json";
const witnessName = params[2] || "witness.wtns";
2018-10-21 19:24:49 +03:00
2020-07-11 11:31:52 +03:00
if (options.verbose) Logger.setLogLevel("DEBUG");
2018-10-21 19:24:49 +03:00
2020-07-11 11:31:52 +03:00
const input = unstringifyBigInts(JSON.parse(await fs.promises.readFile(inputName, "utf8")));
2018-10-21 19:24:49 +03:00
2020-07-11 11:31:52 +03:00
await wtns.calculate(input, wasmName, witnessName, {});
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
return 0;
}
2018-10-21 19:24:49 +03:00
2020-06-30 16:45:21 +03:00
// wtns debug <circuit.wasm> <input.json> <witness.wtns> <circuit.sym>
2020-05-09 16:05:45 +03:00
// -get|g -set|s -trigger|t
2020-06-30 16:45:21 +03:00
async function wtnsDebug(params, options) {
2020-05-09 16:05:45 +03:00
const wasmName = params[0] || "circuit.wasm";
const inputName = params[1] || "input.json";
const witnessName = params[2] || "witness.wtns";
const symName = params[3] || changeExt(wasmName, "sym");
2020-07-11 11:31:52 +03:00
if (options.verbose) Logger.setLogLevel("DEBUG");
2018-10-21 19:24:49 +03:00
2020-07-11 11:31:52 +03:00
const input = unstringifyBigInts(JSON.parse(await fs.promises.readFile(inputName, "utf8")));
2018-10-21 19:24:49 +03:00
2020-07-11 11:31:52 +03:00
await wtns.debug(input, wasmName, witnessName, symName, options, logger);
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
return 0;
}
2020-04-18 21:21:16 +03:00
2020-06-30 16:45:21 +03:00
// wtns export json [witness.wtns] [witness.json]
// -get|g -set|s -trigger|t
async function wtnsExportJson(params, options) {
const wtnsName = params[0] || "witness.wtns";
const jsonName = params[1] || "witness.json";
2020-07-11 11:31:52 +03:00
if (options.verbose) Logger.setLogLevel("DEBUG");
const w = await wtns.exportJson(wtnsName);
2020-06-30 16:45:21 +03:00
await fs.promises.writeFile(jsonName, JSON.stringify(stringifyBigInts(w), null, 1));
return 0;
}
2020-07-11 11:31:52 +03:00
/*
2020-05-09 16:05:45 +03:00
// zksnark setup [circuit.r1cs] [circuit.zkey] [verification_key.json]
async function zksnarkSetup(params, options) {
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
const r1csName = params[0] || "circuit.r1cs";
const zkeyName = params[1] || changeExt(r1csName, "zkey");
const verificationKeyName = params[2] || "verification_key.json";
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
const protocol = options.protocol || "groth16";
2018-10-21 19:24:49 +03:00
2020-10-08 12:43:05 +03:00
const cir = await readR1cs(r1csName, true);
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
if (!zkSnark[protocol]) throw new Error("Invalid protocol");
const setup = zkSnark[protocol].setup(cir, options.verbose);
2018-10-21 19:24:49 +03:00
2020-06-14 18:37:22 +03:00
await zkey.utils.write(zkeyName, setup.vk_proof);
2020-05-09 16:05:45 +03:00
// await fs.promises.writeFile(provingKeyName, JSON.stringify(stringifyBigInts(setup.vk_proof), null, 1), "utf-8");
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
await fs.promises.writeFile(verificationKeyName, JSON.stringify(stringifyBigInts(setup.vk_verifier), null, 1), "utf-8");
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
return 0;
}
2020-07-11 11:31:52 +03:00
*/
2018-10-21 19:24:49 +03:00
2020-07-11 11:31:52 +03:00
// groth16 prove [circuit.zkey] [witness.wtns] [proof.json] [public.json]
2020-07-13 08:21:03 +03:00
async function groth16Prove(params, options) {
2018-10-21 19:24:49 +03:00
2020-12-18 17:38:31 +03:00
const zkeyName = params[0] || "circuit_final.zkey";
2020-05-09 16:05:45 +03:00
const witnessName = params[1] || "witness.wtns";
const proofName = params[2] || "proof.json";
const publicName = params[3] || "public.json";
2018-10-21 19:24:49 +03:00
2020-07-11 11:31:52 +03:00
if (options.verbose) Logger.setLogLevel("DEBUG");
2018-11-10 16:43:37 +03:00
2020-07-11 11:31:52 +03:00
const {proof, publicSignals} = await groth16.prove(zkeyName, witnessName, logger);
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
await fs.promises.writeFile(proofName, JSON.stringify(stringifyBigInts(proof), null, 1), "utf-8");
await fs.promises.writeFile(publicName, JSON.stringify(stringifyBigInts(publicSignals), null, 1), "utf-8");
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
return 0;
}
2020-06-08 12:03:36 +03:00
2020-07-11 11:31:52 +03:00
// groth16 fullprove [input.json] [circuit.wasm] [circuit.zkey] [proof.json] [public.json]
2020-07-13 08:21:03 +03:00
async function groth16FullProve(params, options) {
2020-06-08 12:03:36 +03:00
2020-07-11 11:31:52 +03:00
const inputName = params[0] || "input.json";
const wasmName = params[1] || "circuit.wasm";
2020-12-18 17:38:31 +03:00
const zkeyName = params[2] || "circuit_final.zkey";
2020-07-11 11:31:52 +03:00
const proofName = params[3] || "proof.json";
const publicName = params[4] || "public.json";
2020-06-08 12:03:36 +03:00
2020-07-11 11:31:52 +03:00
if (options.verbose) Logger.setLogLevel("DEBUG");
2020-06-08 12:03:36 +03:00
2020-07-11 11:31:52 +03:00
const input = unstringifyBigInts(JSON.parse(await fs.promises.readFile(inputName, "utf8")));
2020-06-08 12:03:36 +03:00
2020-07-11 11:31:52 +03:00
const {proof, publicSignals} = await groth16.fullProve(input, wasmName, zkeyName, logger);
2020-06-08 12:03:36 +03:00
await fs.promises.writeFile(proofName, JSON.stringify(stringifyBigInts(proof), null, 1), "utf-8");
await fs.promises.writeFile(publicName, JSON.stringify(stringifyBigInts(publicSignals), null, 1), "utf-8");
return 0;
}
2018-10-21 19:24:49 +03:00
2020-07-11 11:31:52 +03:00
// groth16 verify [verification_key.json] [public.json] [proof.json]
2020-07-13 08:21:03 +03:00
async function groth16Verify(params, options) {
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
const verificationKeyName = params[0] || "verification_key.json";
2020-07-11 11:31:52 +03:00
const publicName = params[1] || "public.json";
const proofName = params[2] || "proof.json";
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
const verificationKey = unstringifyBigInts(JSON.parse(fs.readFileSync(verificationKeyName, "utf8")));
const pub = unstringifyBigInts(JSON.parse(fs.readFileSync(publicName, "utf8")));
const proof = unstringifyBigInts(JSON.parse(fs.readFileSync(proofName, "utf8")));
2018-10-21 19:24:49 +03:00
2020-07-11 11:31:52 +03:00
if (options.verbose) Logger.setLogLevel("DEBUG");
2018-10-21 19:24:49 +03:00
2020-07-13 08:21:03 +03:00
const isValid = await groth16.verify(verificationKey, pub, proof, logger);
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
if (isValid) {
return 0;
} else {
return 1;
}
}
2018-11-10 16:43:37 +03:00
2020-12-18 17:38:31 +03:00
// zkey export vkey [circuit_final.zkey] [verification_key.json]",
2020-07-11 11:31:52 +03:00
async function zkeyExportVKey(params, options) {
2020-12-18 17:38:31 +03:00
const zkeyName = params[0] || "circuit_final.zkey";
const verificationKeyName = params[1] || "verification_key.json";
2020-06-08 12:03:36 +03:00
2020-07-11 11:31:52 +03:00
if (options.verbose) Logger.setLogLevel("DEBUG");
const vKey = await zkey.exportVerificationKey(zkeyName);
const S = JSON.stringify(utils.stringifyBigInts(vKey), null, 1);
await fs.promises.writeFile(verificationKeyName, S);
2020-06-08 12:03:36 +03:00
}
2020-12-18 17:38:31 +03:00
// zkey export json [circuit_final.zkey] [circuit.zkey.json]",
2020-06-14 18:37:22 +03:00
async function zkeyExportJson(params, options) {
2020-12-18 17:38:31 +03:00
const zkeyName = params[0] || "circuit_final.zkey";
const zkeyJsonName = params[1] || "circuit_final.zkey.json";
2020-06-14 18:37:22 +03:00
2020-07-11 11:31:52 +03:00
if (options.verbose) Logger.setLogLevel("DEBUG");
const zKey = await zkey.exportJson(zkeyName, logger);
const S = JSON.stringify(utils.stringifyBigInts(zKey), null, 1);
await fs.promises.writeFile(zkeyJsonName, S);
2020-06-14 18:37:22 +03:00
}
2018-10-21 19:24:49 +03:00
async function fileExists(file) {
return fs.promises.access(file, fs.constants.F_OK)
.then(() => true)
.catch(() => false);
}
2020-12-18 17:38:31 +03:00
// solidity genverifier [circuit_final.zkey] [verifier.sol]
2020-07-11 11:31:52 +03:00
async function zkeyExportSolidityVerifier(params, options) {
let zkeyName;
2020-05-09 16:05:45 +03:00
let verifierName;
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
if (params.length < 1) {
2020-12-18 17:38:31 +03:00
zkeyName = "circuit_final.zkey";
2020-05-09 16:05:45 +03:00
} else {
2020-07-11 11:31:52 +03:00
zkeyName = params[0];
2020-05-09 16:05:45 +03:00
}
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
if (params.length < 2) {
verifierName = "verifier.sol";
} else {
verifierName = params[1];
}
2018-10-21 19:24:49 +03:00
2020-07-11 11:31:52 +03:00
if (options.verbose) Logger.setLogLevel("DEBUG");
2020-05-09 16:05:45 +03:00
2021-05-31 14:21:07 +03:00
const templates = {};
if (await fileExists(path.join(__dirname, "templates"))) {
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");
} else {
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");
}
2021-05-31 14:21:07 +03:00
const verifierCode = await zkey.exportSolidityVerifier(zkeyName, templates, logger);
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
fs.writeFileSync(verifierName, verifierCode, "utf-8");
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
return 0;
}
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
// solidity gencall <public.json> <proof.json>
2020-07-11 11:31:52 +03:00
async function zkeyExportSolidityCalldata(params, options) {
2020-05-09 16:05:45 +03:00
let publicName;
let proofName;
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
if (params.length < 1) {
publicName = "public.json";
} else {
publicName = params[0];
}
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
if (params.length < 2) {
proofName = "proof.json";
} else {
proofName = params[1];
}
2018-10-22 09:34:49 +03:00
2020-07-11 11:31:52 +03:00
if (options.verbose) Logger.setLogLevel("DEBUG");
2018-10-22 09:34:49 +03:00
2020-07-11 11:31:52 +03:00
const pub = unstringifyBigInts(JSON.parse(fs.readFileSync(publicName, "utf8")));
2020-05-09 16:05:45 +03:00
const proof = unstringifyBigInts(JSON.parse(fs.readFileSync(proofName, "utf8")));
2018-10-22 09:34:49 +03:00
2021-05-31 14:21:07 +03:00
let res;
if (proof.protocol == "groth16") {
res = await groth16.exportSolidityCallData(proof, pub);
} else if (proof.protocol == "plonk") {
res = await plonk.exportSolidityCallData(proof, pub);
2020-05-09 16:05:45 +03:00
} else {
2021-05-31 14:21:07 +03:00
throw new Error("Invalid Protocol");
2020-05-09 16:05:45 +03:00
}
2021-05-31 14:21:07 +03:00
console.log(res);
2018-10-22 09:34:49 +03:00
2020-05-09 16:05:45 +03:00
return 0;
}
2018-10-22 09:34:49 +03:00
2020-06-30 16:45:21 +03:00
// powersoftau new <curve> <power> [powersoftau_0000.ptau]",
2020-09-02 13:06:20 +03:00
async function powersOfTauNew(params, options) {
2020-06-30 16:45:21 +03:00
let curveName;
2020-05-09 16:05:45 +03:00
let power;
2020-05-31 01:46:49 +03:00
let ptauName;
2018-10-22 09:34:49 +03:00
2020-06-30 16:45:21 +03:00
curveName = params[0];
power = parseInt(params[1]);
2020-05-27 08:03:44 +03:00
if ((power<1) || (power>28)) {
throw new Error("Power must be between 1 and 28");
2020-05-09 16:05:45 +03:00
}
2018-10-22 09:34:49 +03:00
2020-06-30 16:45:21 +03:00
if (params.length < 3) {
2020-09-02 13:06:20 +03:00
ptauName = "powersOfTau" + power + "_0000.ptau";
2020-05-09 16:05:45 +03:00
} else {
2020-06-30 16:45:21 +03:00
ptauName = params[2];
2020-05-09 16:05:45 +03:00
}
2018-10-22 09:34:49 +03:00
2020-06-30 16:45:21 +03:00
const curve = await curves.getCurveFromName(curveName);
2020-07-11 11:31:52 +03:00
if (options.verbose) Logger.setLogLevel("DEBUG");
2020-09-02 13:06:20 +03:00
return await powersOfTau.newAccumulator(curve, power, ptauName, logger);
2020-05-09 16:05:45 +03:00
}
2020-03-26 22:16:29 +03:00
2020-09-02 13:06:20 +03:00
async function powersOfTauExportChallenge(params, options) {
2020-05-31 01:46:49 +03:00
let ptauName;
2020-07-14 12:55:12 +03:00
let challengeName;
2020-03-26 22:16:29 +03:00
2020-05-31 01:46:49 +03:00
ptauName = params[0];
2020-03-26 22:16:29 +03:00
2020-05-09 16:05:45 +03:00
if (params.length < 2) {
2020-07-14 12:55:12 +03:00
challengeName = "challenge";
2020-05-09 16:05:45 +03:00
} else {
2020-07-14 12:55:12 +03:00
challengeName = params[1];
2020-05-09 16:05:45 +03:00
}
2019-06-16 01:12:50 +03:00
2020-07-11 11:31:52 +03:00
if (options.verbose) Logger.setLogLevel("DEBUG");
2020-09-02 13:06:20 +03:00
return await powersOfTau.exportChallenge(ptauName, challengeName, logger);
2020-05-09 16:05:45 +03:00
}
2018-10-21 19:24:49 +03:00
2020-07-14 12:55:12 +03:00
// powersoftau challenge contribute <curve> <challenge> [response]
2020-09-02 13:06:20 +03:00
async function powersOfTauChallengeContribute(params, options) {
2020-07-14 12:55:12 +03:00
let challengeName;
2020-05-09 16:05:45 +03:00
let responseName;
2018-10-21 19:24:49 +03:00
2020-06-30 16:45:21 +03:00
const curve = await curves.getCurveFromName(params[0]);
2018-10-21 19:24:49 +03:00
2020-07-14 12:55:12 +03:00
challengeName = params[1];
if (params.length < 3) {
2020-07-14 12:55:12 +03:00
responseName = changeExt(challengeName, "response");
2020-05-09 16:05:45 +03:00
} else {
responseName = params[2];
2018-10-21 19:24:49 +03:00
}
2020-05-09 16:05:45 +03:00
2020-07-11 11:31:52 +03:00
if (options.verbose) Logger.setLogLevel("DEBUG");
2020-09-02 13:06:20 +03:00
return await powersOfTau.challengeContribute(curve, challengeName, responseName, options.entropy, logger);
2018-10-21 19:24:49 +03:00
}
2020-09-02 13:06:20 +03:00
async function powersOfTauImport(params, options) {
2020-05-11 21:23:04 +03:00
let oldPtauName;
let response;
let newPtauName;
let importPoints = true;
let doCheck = true;
oldPtauName = params[0];
response = params[1];
newPtauName = params[2];
if (options.nopoints) importPoints = false;
if (options.nocheck) doCheck = false;
2020-07-11 11:31:52 +03:00
if (options.verbose) Logger.setLogLevel("DEBUG");
2020-09-02 13:06:20 +03:00
const res = await powersOfTau.importResponse(oldPtauName, response, newPtauName, options.name, importPoints, logger);
2020-05-11 21:23:04 +03:00
if (res) return res;
if (!doCheck) return;
// TODO Verify
}
2020-09-02 13:06:20 +03:00
async function powersOfTauVerify(params, options) {
2020-05-11 21:23:04 +03:00
let ptauName;
ptauName = params[0];
2020-07-11 11:31:52 +03:00
if (options.verbose) Logger.setLogLevel("DEBUG");
2020-09-02 13:06:20 +03:00
const res = await powersOfTau.verify(ptauName, logger);
2020-06-14 18:37:22 +03:00
if (res === true) {
2020-05-26 19:45:49 +03:00
return 0;
2020-05-11 21:23:04 +03:00
} else {
2020-05-26 19:45:49 +03:00
return 1;
2020-05-11 21:23:04 +03:00
}
}
2020-09-02 13:06:20 +03:00
async function powersOfTauBeacon(params, options) {
2020-05-15 22:30:37 +03:00
let oldPtauName;
let newPtauName;
let beaconHashStr;
let numIterationsExp;
oldPtauName = params[0];
newPtauName = params[1];
beaconHashStr = params[2];
numIterationsExp = params[3];
2020-07-11 11:31:52 +03:00
if (options.verbose) Logger.setLogLevel("DEBUG");
2020-09-02 13:06:20 +03:00
return await powersOfTau.beacon(oldPtauName, newPtauName, options.name ,beaconHashStr, numIterationsExp, logger);
2020-05-15 22:30:37 +03:00
}
2020-09-02 13:06:20 +03:00
async function powersOfTauContribute(params, options) {
2020-05-15 22:30:37 +03:00
let oldPtauName;
let newPtauName;
oldPtauName = params[0];
newPtauName = params[1];
2020-07-11 11:31:52 +03:00
if (options.verbose) Logger.setLogLevel("DEBUG");
2020-09-02 13:06:20 +03:00
return await powersOfTau.contribute(oldPtauName, newPtauName, options.name , options.entropy, logger);
2020-05-15 22:30:37 +03:00
}
2020-09-02 13:06:20 +03:00
async function powersOfTauPreparePhase2(params, options) {
2020-05-26 19:45:49 +03:00
let oldPtauName;
let newPtauName;
2020-05-11 21:23:04 +03:00
2020-05-26 19:45:49 +03:00
oldPtauName = params[0];
newPtauName = params[1];
2018-10-21 19:24:49 +03:00
2020-07-11 11:31:52 +03:00
if (options.verbose) Logger.setLogLevel("DEBUG");
2020-09-02 13:06:20 +03:00
return await powersOfTau.preparePhase2(oldPtauName, newPtauName, logger);
}
async function powersOfTauConvert(params, options) {
let oldPtauName;
let newPtauName;
oldPtauName = params[0];
newPtauName = params[1];
if (options.verbose) Logger.setLogLevel("DEBUG");
return await powersOfTau.convert(oldPtauName, newPtauName, logger);
}
async function powersOfTauTruncate(params, options) {
let ptauName;
ptauName = params[0];
let template = ptauName;
while ((template.length>0) && (template[template.length-1] != ".")) template = template.slice(0, template.length-1);
template = template.slice(0, template.length-1);
template = template+"_";
if (options.verbose) Logger.setLogLevel("DEBUG");
return await powersOfTau.truncate(ptauName, template, logger);
2019-06-16 01:12:50 +03:00
}
2018-10-21 19:24:49 +03:00
2020-06-14 18:37:22 +03:00
// powersoftau export json <powersoftau_0000.ptau> <powersoftau_0000.json>",
2020-09-02 13:06:20 +03:00
async function powersOfTauExportJson(params, options) {
2020-06-14 18:37:22 +03:00
let ptauName;
let jsonName;
ptauName = params[0];
jsonName = params[1];
2020-07-11 11:31:52 +03:00
if (options.verbose) Logger.setLogLevel("DEBUG");
2020-09-02 13:06:20 +03:00
const pTau = await powersOfTau.exportJson(ptauName, logger);
2020-07-11 11:31:52 +03:00
const S = JSON.stringify(stringifyBigInts(pTau), null, 1);
await fs.promises.writeFile(jsonName, S);
2020-06-14 18:37:22 +03:00
}
2020-05-31 01:46:49 +03:00
2020-12-18 17:38:31 +03:00
// phase2 new <circuit.r1cs> <powersoftau.ptau> <circuit_0000.zkey>
2020-06-14 18:37:22 +03:00
async function zkeyNew(params, options) {
2020-05-31 01:46:49 +03:00
let r1csName;
let ptauName;
let zkeyName;
if (params.length < 1) {
r1csName = "circuit.r1cs";
} else {
r1csName = params[0];
}
if (params.length < 2) {
ptauName = "powersoftau.ptau";
} else {
ptauName = params[1];
}
if (params.length < 3) {
2020-12-18 17:38:31 +03:00
zkeyName = "circuit_0000.zkey";
2020-05-31 01:46:49 +03:00
} else {
zkeyName = params[2];
}
2020-07-11 11:31:52 +03:00
if (options.verbose) Logger.setLogLevel("DEBUG");
return zkey.newZKey(r1csName, ptauName, zkeyName, logger);
2020-05-31 01:46:49 +03:00
}
2020-06-14 18:37:22 +03:00
2020-12-18 17:38:31 +03:00
// zkey export bellman [circuit_0000.zkey] [circuit.mpcparams]
2020-06-14 18:37:22 +03:00
async function zkeyExportBellman(params, options) {
let zkeyName;
let mpcparamsName;
2020-12-18 17:38:31 +03:00
zkeyName = params[0];
2020-06-14 18:37:22 +03:00
if (params.length < 2) {
mpcparamsName = "circuit.mpcparams";
} else {
mpcparamsName = params[1];
}
2020-07-11 11:31:52 +03:00
if (options.verbose) Logger.setLogLevel("DEBUG");
return zkey.exportBellman(zkeyName, mpcparamsName, logger);
2020-06-14 18:37:22 +03:00
}
// zkey import bellman <circuit_old.zkey> <circuit.mpcparams> <circuit_new.zkey>
async function zkeyImportBellman(params, options) {
let zkeyNameOld;
let mpcParamsName;
let zkeyNameNew;
zkeyNameOld = params[0];
mpcParamsName = params[1];
zkeyNameNew = params[2];
2020-07-11 11:31:52 +03:00
if (options.verbose) Logger.setLogLevel("DEBUG");
return zkey.importBellman(zkeyNameOld, mpcParamsName, zkeyNameNew, options.name, logger);
2020-06-14 18:37:22 +03:00
}
2020-12-18 17:38:31 +03:00
// phase2 verify r1cs [circuit.r1cs] [powersoftau.ptau] [circuit_final.zkey]
async function zkeyVerifyFromR1cs(params, options) {
2020-06-14 18:37:22 +03:00
let r1csName;
let ptauName;
let zkeyName;
if (params.length < 1) {
r1csName = "circuit.r1cs";
} else {
r1csName = params[0];
}
if (params.length < 2) {
ptauName = "powersoftau.ptau";
} else {
ptauName = params[1];
}
if (params.length < 3) {
2020-12-18 17:38:31 +03:00
zkeyName = "circuit_final.zkey";
2020-06-14 18:37:22 +03:00
} else {
zkeyName = params[2];
}
2020-07-11 11:31:52 +03:00
if (options.verbose) Logger.setLogLevel("DEBUG");
2020-12-18 17:38:31 +03:00
const res = await zkey.verifyFromR1cs(r1csName, ptauName, zkeyName, logger);
2020-06-14 18:37:22 +03:00
if (res === true) {
return 0;
} else {
return 1;
}
}
2020-12-18 17:38:31 +03:00
// phase2 verify [circuit_0000] [powersoftau.ptau] [circuit_final.zkey]
async function zkeyVerifyFromInit(params, options) {
let initZKeyName;
let ptauName;
let zkeyName;
if (params.length < 1) {
initZKeyName = "circuit_0000.zkey";
} else {
initZKeyName = params[0];
}
if (params.length < 2) {
ptauName = "powersoftau.ptau";
} else {
ptauName = params[1];
}
if (params.length < 3) {
zkeyName = "circuit_final.zkey";
} else {
zkeyName = params[2];
}
if (options.verbose) Logger.setLogLevel("DEBUG");
2020-12-20 12:25:38 +03:00
const res = await zkey.verifyFromInit(initZKeyName, ptauName, zkeyName, logger);
2020-12-18 17:38:31 +03:00
if (res === true) {
return 0;
} else {
return 1;
}
}
2020-06-14 18:37:22 +03:00
2020-06-16 17:45:32 +03:00
// zkey contribute <circuit_old.zkey> <circuit_new.zkey>
2020-06-14 18:37:22 +03:00
async function zkeyContribute(params, options) {
let zkeyOldName;
let zkeyNewName;
zkeyOldName = params[0];
zkeyNewName = params[1];
2020-07-11 11:31:52 +03:00
if (options.verbose) Logger.setLogLevel("DEBUG");
2020-06-14 18:37:22 +03:00
2020-07-11 11:31:52 +03:00
return zkey.contribute(zkeyOldName, zkeyNewName, options.name, options.entropy, logger);
2020-06-14 18:37:22 +03:00
}
// zkey beacon <circuit_old.zkey> <circuit_new.zkey> <beaconHash(Hex)> <numIterationsExp>
async function zkeyBeacon(params, options) {
let zkeyOldName;
let zkeyNewName;
let beaconHashStr;
let numIterationsExp;
zkeyOldName = params[0];
zkeyNewName = params[1];
beaconHashStr = params[2];
numIterationsExp = params[3];
2020-07-11 11:31:52 +03:00
if (options.verbose) Logger.setLogLevel("DEBUG");
return await zkey.beacon(zkeyOldName, zkeyNewName, options.name ,beaconHashStr, numIterationsExp, logger);
}
2020-07-14 12:55:12 +03:00
// zkey challenge contribute <curve> <challenge> [response]",
2020-07-11 11:31:52 +03:00
async function zkeyBellmanContribute(params, options) {
2020-07-14 12:55:12 +03:00
let challengeName;
let responseName;
2020-06-30 22:39:25 +03:00
const curve = await curves.getCurveFromName(params[0]);
2020-07-14 12:55:12 +03:00
challengeName = params[1];
if (params.length < 3) {
2020-07-14 12:55:12 +03:00
responseName = changeExt(challengeName, "response");
} else {
responseName = params[2];
}
2020-07-11 11:31:52 +03:00
if (options.verbose) Logger.setLogLevel("DEBUG");
2020-07-14 12:55:12 +03:00
return zkey.bellmanContribute(curve, challengeName, responseName, options.entropy, logger);
}
2021-05-18 23:26:22 +03:00
// plonk setup <circuit.r1cs> <powersoftau.ptau> <circuit.zkey>
async function plonkSetup(params, options) {
let r1csName;
let ptauName;
let zkeyName;
if (params.length < 1) {
r1csName = "circuit.r1cs";
} else {
r1csName = params[0];
}
if (params.length < 2) {
ptauName = "powersoftau.ptau";
} else {
ptauName = params[1];
}
if (params.length < 3) {
zkeyName = "circuit.zkey";
} else {
zkeyName = params[2];
}
if (options.verbose) Logger.setLogLevel("DEBUG");
return plonk.setup(r1csName, ptauName, zkeyName, logger);
}
// plonk prove [circuit.zkey] [witness.wtns] [proof.json] [public.json]
async function plonkProve(params, options) {
const zkeyName = params[0] || "circuit.zkey";
const witnessName = params[1] || "witness.wtns";
const proofName = params[2] || "proof.json";
const publicName = params[3] || "public.json";
if (options.verbose) Logger.setLogLevel("DEBUG");
const {proof, publicSignals} = await plonk.prove(zkeyName, witnessName, logger);
await fs.promises.writeFile(proofName, JSON.stringify(stringifyBigInts(proof), null, 1), "utf-8");
await fs.promises.writeFile(publicName, JSON.stringify(stringifyBigInts(publicSignals), null, 1), "utf-8");
return 0;
}
// plonk fullprove [input.json] [circuit.wasm] [circuit.zkey] [proof.json] [public.json]
async function plonkFullProve(params, options) {
const inputName = params[0] || "input.json";
const wasmName = params[1] || "circuit.wasm";
const zkeyName = params[2] || "circuit.zkey";
const proofName = params[3] || "proof.json";
const publicName = params[4] || "public.json";
if (options.verbose) Logger.setLogLevel("DEBUG");
const input = unstringifyBigInts(JSON.parse(await fs.promises.readFile(inputName, "utf8")));
const {proof, publicSignals} = await plonk.fullProve(input, wasmName, zkeyName, logger);
await fs.promises.writeFile(proofName, JSON.stringify(stringifyBigInts(proof), null, 1), "utf-8");
await fs.promises.writeFile(publicName, JSON.stringify(stringifyBigInts(publicSignals), null, 1), "utf-8");
return 0;
}
// plonk verify [verification_key.json] [public.json] [proof.json]
async function plonkVerify(params, options) {
const verificationKeyName = params[0] || "verification_key.json";
const publicName = params[1] || "public.json";
const proofName = params[2] || "proof.json";
const verificationKey = unstringifyBigInts(JSON.parse(fs.readFileSync(verificationKeyName, "utf8")));
const pub = unstringifyBigInts(JSON.parse(fs.readFileSync(publicName, "utf8")));
const proof = unstringifyBigInts(JSON.parse(fs.readFileSync(proofName, "utf8")));
if (options.verbose) Logger.setLogLevel("DEBUG");
const isValid = await plonk.verify(verificationKey, pub, proof, logger);
if (isValid) {
return 0;
} else {
return 1;
}
}