2018-10-21 19:24:49 +03:00
/ *
Copyright 2018 0 KIMS 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
} ,
2020-06-18 20:14:06 +03:00
{
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-18 20:14:06 +03:00
} ,
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" ;
2020-09-20 06:51:26 +03:00
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
2021-05-31 21:41:10 +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 = { } ;
2021-05-31 21:41:10 +03:00
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 ] ;
2020-06-18 20:14:06 +03:00
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 {
2020-06-18 20:14:06 +03:00
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 ] ;
}
2020-06-18 20:14:06 +03:00
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
}
2020-06-18 20:14:06 +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-06-18 20:14:06 +03:00
}
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 ;
2020-06-18 20:14:06 +03:00
let responseName ;
2020-06-30 22:39:25 +03:00
const curve = await curves . getCurveFromName ( params [ 0 ] ) ;
2020-06-18 20:14:06 +03:00
2020-07-14 12:55:12 +03:00
challengeName = params [ 1 ] ;
2020-06-18 20:14:06 +03:00
if ( params . length < 3 ) {
2020-07-14 12:55:12 +03:00
responseName = changeExt ( challengeName , "response" ) ;
2020-06-18 20:14:06 +03:00
} 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 ) ;
2020-06-18 20:14:06 +03:00
}
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 ;
}
}