2018-10-21 19:24:49 +03:00
#!/usr/bin/env node
/ *
Copyright 2018 0 KIMS association .
This file is part of jaz ( Zero Knowledge Circuit Compiler ) .
jaz 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
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/>.
* /
/* eslint-disable no-console */
const fs = require ( "fs" ) ;
const path = require ( "path" ) ;
const zkSnark = require ( "./index.js" ) ;
2020-04-18 21:21:16 +03:00
const { stringifyBigInts , unstringifyBigInts } = require ( "ffjavascript" ) . utils ;
2018-10-21 19:24:49 +03:00
2020-03-26 22:16:29 +03:00
const loadR1cs = require ( "r1csfile" ) . load ;
const WitnessCalculatorBuilder = require ( "circom_runtime" ) . WitnessCalculatorBuilder ;
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
const zkeyFile = require ( "./src/zkeyfile" ) ;
const wtnsFile = require ( "./src/wtnsfile" ) ;
2018-10-21 19:24:49 +03:00
2020-03-26 22:16:29 +03:00
const loadSyms = require ( "./src/loadsyms" ) ;
const printR1cs = require ( "./src/printr1cs" ) ;
2020-05-09 16:05:45 +03:00
const clProcessor = require ( "./src/clprocessor" ) ;
const powersOfTaw = require ( "./src/powersoftaw" ) ;
const bn128 = require ( "ffjavascript" ) . bn128 ;
const commands = [
{
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
} ,
{
cmd : "witness calculate [circuit.wasm] [input.json] [witness.wtns]" ,
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" ] ,
action : witnessCalculate
} ,
{
cmd : "witness debug [circuit.wasm] [input.json] [witness.wtns] [circuit.sym]" ,
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" ] ,
action : witnessDebug
} ,
{
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
} ,
{
cmd : "zksnark prove [circuit.zkey] [witness.wtns] [proof.json] [public.json]" ,
description : "Generates a zk Proof" ,
alias : [ "zp" , "zksnark proof" , "proof -pk|provingkey -wt|witness -p|proof -pub|public" ] ,
options : "-verbose|v -protocol" ,
action : zksnarkProve
} ,
{
cmd : "zksnark verify [verification_key.json] [public.json] [proof.json]" ,
description : "Verify a zk Proof" ,
alias : [ "zv" , "verify -vk|verificationkey -pub|public -p|proof" ] ,
action : zksnarkVerify
} ,
{
cmd : "solidity genverifier <verificationKey.json> <verifier.sol>" ,
description : "Creates a verifier in solidity" ,
alias : [ "ks" , "generateverifier -vk|verificationkey -v|verifier" ] ,
action : solidityGenVerifier
} ,
{
cmd : "solidity gencall <public.json> <proof.json>" ,
description : "Generates call parameters ready to be called." ,
alias : [ "pc" , "generatecall -pub|public -p|proof" ] ,
action : solidityGenCall
} ,
{
cmd : "powersoftaw new <power> [powersoftaw_0000.ptaw]" ,
description : "Starts a powers of taw ceremony" ,
alias : [ "ptn" ] ,
options : "-verbose|v" ,
action : powersOfTawNew
} ,
{
cmd : "powersoftaw export challange <powersoftaw_0000.ptaw> [challange]" ,
description : "Creates a challange" ,
alias : [ "pte" ] ,
options : "-verbose|v" ,
action : powersOfTawExportChallange
} ,
{
cmd : "powersoftaw contribute <challange> [response]" ,
description : "Contribute to a challange" ,
alias : [ "ptc" ] ,
options : "-verbose|v -entropy|e" ,
action : powersOfTawContribute
} ,
] ;
clProcessor ( commands ) . then ( ( res ) => {
process . exit ( res ) ;
} , ( err ) => {
console . log ( err . stack ) ;
console . log ( "ERROR: " + err ) ;
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
{
cmd : "r1cs export circomJSON [circuit.r1cs] [circuit.json]" ,
description : "Exports a R1CS to JSON file." ,
alias : [ "rj" ] ,
action : r1csExportCircomJSON
} ,
{
cmd : "witness export json <witness.wtns> <witness.json>" ,
description : "Export witness file to json" ,
alias : [ "wj" ] ,
action : witnessExportJson
} ,
{
cmd : "zkey export vkey <circuit.zkey> <verification_key.json>" ,
description : "Exports a verification key to JSON" ,
alias : [ "kv" ] ,
action : zKeySolidity
} ,
{
cmd : "witness verify <circuit.r1cs> <witness.wtns>" ,
description : "Verify a witness agains a r1cs" ,
alias : [ "wv" ] ,
action : witnessVerify
} ,
ptau new Starts a ceremony with a new challange for the powes of Tau ceremony
ptau contribute Contribute in the ceremony of powers of tau
ptau beacon Apply a beacon random to the ceremony
ptau verify Verify the powers of tau ceremony
ptau preparePhase2 Prepare Powers of Taus for a phase 2
phase2 new Starts a second phase ceremony for a given circuit with a first challange and a reference Hash .
phase2 constribute Contribute in the seconf phase ceremony
phase2 beacon Contribute in the seconf phase ceremony with a Powers of Tau
phase2 verify Verify the Powers of tau
zksnark setup s Run a simple setup for a circuit generating the proving key .
zksnark prove p Generates a zk Proof
zksnark verify v Verify a zk Proof
zkey export pkJSON pkjson Exports a proving key to JSON
zkey export vkJSON vkjson Exports a verification key to JSON
zkey export vkSolidity vksol Creates a verifier in solidity
proof callParameters cp Generates call parameters ready to be called .
* /
2019-06-16 01:12:50 +03:00
2020-05-09 16:05:45 +03:00
function p256 ( n ) {
let nstr = n . toString ( 16 ) ;
while ( nstr . length < 64 ) nstr = "0" + nstr ;
nstr = ` "0x ${ nstr } " ` ;
return nstr ;
}
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-05-09 16:05:45 +03:00
const cir = await loadR1cs ( r1csName ) ;
2020-03-26 22:16:29 +03:00
2020-05-09 16:05:45 +03:00
console . log ( ` # Wires: ${ cir . nVars } ` ) ;
console . log ( ` # Constraints: ${ cir . nConstraints } ` ) ;
console . log ( ` # Private Inputs: ${ cir . nPrvInputs } ` ) ;
console . log ( ` # Public Inputs: ${ cir . nPubInputs } ` ) ;
console . log ( ` # Outputs: ${ cir . nOutputs } ` ) ;
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" ;
const symName = params [ 2 ] || changeExt ( r1csName , "sym" ) ;
const cir = await loadR1cs ( r1csName , true , true ) ;
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-05-09 16:05:45 +03:00
printR1cs ( cir , sym ) ;
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
// witness calculate <circuit.wasm> <input.json> <witness.wtns>
async function witnessCalculate ( params , options ) {
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-05-09 16:05:45 +03:00
const wasm = await fs . promises . readFile ( wasmName ) ;
const input = unstringifyBigInts ( JSON . parse ( await fs . promises . readFile ( inputName , "utf8" ) ) ) ;
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
const wc = await WitnessCalculatorBuilder ( wasm , options ) ;
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
const w = await wc . calculateBinWitness ( input ) ;
await wtnsFile . writeBin ( witnessName , w , wc . prime ) ;
/ *
const w = await wc . calculateWitness ( input ) ;
await wtnsFile . write ( witnessName , w , wc . prime ) ;
* /
// fs.promises.writeFile(witnessName, JSON.stringify(stringifyBigInts(w), null, 1));
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
// witness debug <circuit.wasm> <input.json> <witness.wtns> <circuit.sym>
// -get|g -set|s -trigger|t
async function witnessDebug ( params , options ) {
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" ) ;
const wasm = await fs . promises . readFile ( wasmName ) ;
const input = unstringifyBigInts ( JSON . parse ( await fs . promises . readFile ( inputName , "utf8" ) ) ) ;
let wcOps = {
sanityCheck : true
} ;
let sym = await loadSyms ( symName ) ;
if ( options . set ) {
if ( ! sym ) sym = await loadSyms ( symName ) ;
wcOps . logSetSignal = function ( labelIdx , value ) {
console . log ( "SET " + sym . labelIdx2Name [ labelIdx ] + " <-- " + value . toString ( ) ) ;
} ;
}
if ( options . get ) {
if ( ! sym ) sym = await loadSyms ( symName ) ;
wcOps . logGetSignal = function ( varIdx , value ) {
console . log ( "GET " + sym . labelIdx2Name [ varIdx ] + " --> " + value . toString ( ) ) ;
} ;
}
if ( options . trigger ) {
if ( ! sym ) sym = await loadSyms ( symName ) ;
wcOps . logStartComponent = function ( cIdx ) {
console . log ( "START: " + sym . componentIdx2Name [ cIdx ] ) ;
} ;
wcOps . logFinishComponent = function ( cIdx ) {
console . log ( "FINISH: " + sym . componentIdx2Name [ cIdx ] ) ;
} ;
}
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
const wc = await WitnessCalculatorBuilder ( wasm , wcOps ) ;
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
const w = await wc . calculateWitness ( input ) ;
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
await wtnsFile . write ( witnessName , w ) ;
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
// await fs.promises.writeFile(witnessName, JSON.stringify(stringifyBigInts(w), null, 1));
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-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-05-09 16:05:45 +03:00
const cir = await loadR1cs ( 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-05-09 16:05:45 +03:00
await zkeyFile . write ( zkeyName , setup . vk _proof ) ;
// 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 ;
}
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
// zksnark prove [circuit.zkey] [witness.wtns] [proof.json] [public.json]
async function zksnarkProve ( params , options ) {
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
const zkeyName = params [ 0 ] || "circuit.zkey" ;
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-05-09 16:05:45 +03:00
const witness = await wtnsFile . read ( witnessName ) ;
// const witness = unstringifyBigInts(JSON.parse(fs.readFileSync(witnessName, "utf8")));
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
const provingKey = await zkeyFile . read ( zkeyName ) ;
// const provingKey = unstringifyBigInts(JSON.parse(fs.readFileSync(provingKeyName, "utf8")));
2018-11-10 16:43:37 +03:00
2020-05-09 16:05:45 +03:00
const protocol = provingKey . protocol ;
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 { proof , publicSignals } = zkSnark [ protocol ] . genProof ( provingKey , witness , options . verbose ) ;
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 ;
}
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
// zksnark verify [verification_key.json] [public.json] [proof.json]
async function zksnarkVerify ( 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" ;
const publicName = params [ 0 ] || "public.json" ;
const proofName = params [ 0 ] || "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-05-09 16:05:45 +03:00
const protocol = verificationKey . protocol ;
if ( ! zkSnark [ protocol ] ) throw new Error ( "Invalid protocol" ) ;
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
const isValid = zkSnark [ protocol ] . isValid ( verificationKey , proof , pub ) ;
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
if ( isValid ) {
console . log ( "OK" ) ;
return 0 ;
} else {
console . log ( "INVALID" ) ;
return 1 ;
}
}
2018-11-10 16:43:37 +03:00
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
// solidity genverifier <verificationKey.json> <verifier.sol>
async function solidityGenVerifier ( params , options ) {
let verificationKeyName ;
let verifierName ;
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
if ( params . length < 1 ) {
verificationKeyName = "verification_key.json" ;
} else {
verificationKeyName = params [ 0 ] ;
}
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-05-09 16:05:45 +03:00
const verificationKey = unstringifyBigInts ( JSON . parse ( fs . readFileSync ( verificationKeyName , "utf8" ) ) ) ;
let verifierCode ;
if ( verificationKey . protocol == "original" ) {
verifierCode = generateVerifier _original ( verificationKey ) ;
} else if ( verificationKey . protocol == "groth16" ) {
verifierCode = generateVerifier _groth16 ( verificationKey ) ;
} else if ( verificationKey . protocol == "kimleeoh" ) {
verifierCode = generateVerifier _kimleeoh ( verificationKey ) ;
} else {
throw new Error ( "InvalidProof" ) ;
}
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>
async function solidityGenCall ( params , options ) {
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-05-09 16:05:45 +03:00
const public = unstringifyBigInts ( JSON . parse ( fs . readFileSync ( publicName , "utf8" ) ) ) ;
const proof = unstringifyBigInts ( JSON . parse ( fs . readFileSync ( proofName , "utf8" ) ) ) ;
2018-10-22 09:34:49 +03:00
2020-05-09 16:05:45 +03:00
let inputs = "" ;
for ( let i = 0 ; i < public . length ; i ++ ) {
if ( inputs != "" ) inputs = inputs + "," ;
inputs = inputs + p256 ( public [ i ] ) ;
}
2018-10-22 09:34:49 +03:00
2020-05-09 16:05:45 +03:00
let S ;
if ( ( typeof proof . protocol === "undefined" ) || ( proof . protocol == "original" ) ) {
S = ` [ ${ p256 ( proof . pi _a [ 0 ] ) } , ${ p256 ( proof . pi _a [ 1 ] ) } ], ` +
` [ ${ p256 ( proof . pi _ap [ 0 ] ) } , ${ p256 ( proof . pi _ap [ 1 ] ) } ], ` +
` [[ ${ p256 ( proof . pi _b [ 0 ] [ 1 ] ) } , ${ p256 ( proof . pi _b [ 0 ] [ 0 ] ) } ],[ ${ p256 ( proof . pi _b [ 1 ] [ 1 ] ) } , ${ p256 ( proof . pi _b [ 1 ] [ 0 ] ) } ]], ` +
` [ ${ p256 ( proof . pi _bp [ 0 ] ) } , ${ p256 ( proof . pi _bp [ 1 ] ) } ], ` +
` [ ${ p256 ( proof . pi _c [ 0 ] ) } , ${ p256 ( proof . pi _c [ 1 ] ) } ], ` +
` [ ${ p256 ( proof . pi _cp [ 0 ] ) } , ${ p256 ( proof . pi _cp [ 1 ] ) } ], ` +
` [ ${ p256 ( proof . pi _h [ 0 ] ) } , ${ p256 ( proof . pi _h [ 1 ] ) } ], ` +
` [ ${ p256 ( proof . pi _kp [ 0 ] ) } , ${ p256 ( proof . pi _kp [ 1 ] ) } ], ` +
` [ ${ inputs } ] ` ;
} else if ( ( proof . protocol == "groth16" ) || ( proof . protocol == "kimleeoh" ) ) {
S = ` [ ${ p256 ( proof . pi _a [ 0 ] ) } , ${ p256 ( proof . pi _a [ 1 ] ) } ], ` +
` [[ ${ p256 ( proof . pi _b [ 0 ] [ 1 ] ) } , ${ p256 ( proof . pi _b [ 0 ] [ 0 ] ) } ],[ ${ p256 ( proof . pi _b [ 1 ] [ 1 ] ) } , ${ p256 ( proof . pi _b [ 1 ] [ 0 ] ) } ]], ` +
` [ ${ p256 ( proof . pi _c [ 0 ] ) } , ${ p256 ( proof . pi _c [ 1 ] ) } ], ` +
` [ ${ inputs } ] ` ;
} else {
throw new Error ( "InvalidProof" ) ;
}
2018-10-22 09:34:49 +03:00
2020-05-09 16:05:45 +03:00
console . log ( S ) ;
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-05-09 16:05:45 +03:00
async function powersOfTawNew ( params , options ) {
let power ;
let ptawName ;
2018-10-22 09:34:49 +03:00
2020-05-09 16:05:45 +03:00
power = parseInt ( params [ 0 ] ) ;
if ( ( power < 1 ) || ( power > 27 ) ) {
throw new Error ( "Power must be between 1 and 27" ) ;
}
2018-10-22 09:34:49 +03:00
2020-05-09 16:05:45 +03:00
if ( params . length < 2 ) {
ptawName = "powersOfTaw" + power + "_0000.ptaw" ;
} else {
ptawName = params [ 1 ] ;
}
2018-10-22 09:34:49 +03:00
2020-05-09 16:05:45 +03:00
return await powersOfTaw . newAccumulator ( bn128 , power , ptawName , options . verbose ) ;
}
2020-03-26 22:16:29 +03:00
2020-05-09 16:05:45 +03:00
async function powersOfTawExportChallange ( params , options ) {
let ptawName ;
let challangeName ;
2020-03-26 22:16:29 +03:00
2020-05-09 16:05:45 +03:00
ptawName = params [ 0 ] ;
2020-03-26 22:16:29 +03:00
2020-05-09 16:05:45 +03:00
if ( params . length < 2 ) {
challangeName = "challange" ;
} else {
challangeName = params [ 1 ] ;
}
2019-06-16 01:12:50 +03:00
2020-05-09 16:05:45 +03:00
return await powersOfTaw . exportChallange ( ptawName , challangeName , options . verbose ) ;
}
2018-10-21 19:24:49 +03:00
2020-03-26 22:16:29 +03:00
2020-05-09 16:05:45 +03:00
async function powersOfTawContribute ( params , options ) {
let challangeName ;
let responseName ;
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
challangeName = params [ 0 ] ;
2018-10-21 19:24:49 +03:00
2020-05-09 16:05:45 +03:00
if ( params . length < 2 ) {
responseName = changeExt ( challangeName , "response" ) ;
} else {
responseName = params [ 1 ] ;
2018-10-21 19:24:49 +03:00
}
2020-05-09 16:05:45 +03:00
return await powersOfTaw . contribute ( bn128 , challangeName , responseName , options . entropy , options . verbose ) ;
2018-10-21 19:24:49 +03:00
}
2018-11-10 16:43:37 +03:00
function generateVerifier _original ( verificationKey ) {
let template = fs . readFileSync ( path . join ( _ _dirname , "templates" , "verifier_original.sol" ) , "utf-8" ) ;
const vka _str = ` [ ${ verificationKey . vk _a [ 0 ] [ 1 ] . toString ( ) } , ` +
` ${ verificationKey . vk _a [ 0 ] [ 0 ] . toString ( ) } ], ` +
` [ ${ verificationKey . vk _a [ 1 ] [ 1 ] . toString ( ) } , ` +
` ${ verificationKey . vk _a [ 1 ] [ 0 ] . toString ( ) } ] ` ;
template = template . replace ( "<%vk_a%>" , vka _str ) ;
const vkb _str = ` ${ verificationKey . vk _b [ 0 ] . toString ( ) } , ` +
` ${ verificationKey . vk _b [ 1 ] . toString ( ) } ` ;
template = template . replace ( "<%vk_b%>" , vkb _str ) ;
const vkc _str = ` [ ${ verificationKey . vk _c [ 0 ] [ 1 ] . toString ( ) } , ` +
` ${ verificationKey . vk _c [ 0 ] [ 0 ] . toString ( ) } ], ` +
` [ ${ verificationKey . vk _c [ 1 ] [ 1 ] . toString ( ) } , ` +
` ${ verificationKey . vk _c [ 1 ] [ 0 ] . toString ( ) } ] ` ;
template = template . replace ( "<%vk_c%>" , vkc _str ) ;
const vkg _str = ` [ ${ verificationKey . vk _g [ 0 ] [ 1 ] . toString ( ) } , ` +
2019-06-16 01:12:50 +03:00
` ${ verificationKey . vk _g [ 0 ] [ 0 ] . toString ( ) } ], ` +
2018-11-10 16:43:37 +03:00
` [ ${ verificationKey . vk _g [ 1 ] [ 1 ] . toString ( ) } , ` +
` ${ verificationKey . vk _g [ 1 ] [ 0 ] . toString ( ) } ] ` ;
template = template . replace ( "<%vk_g%>" , vkg _str ) ;
const vkgb1 _str = ` ${ verificationKey . vk _gb _1 [ 0 ] . toString ( ) } , ` +
` ${ verificationKey . vk _gb _1 [ 1 ] . toString ( ) } ` ;
template = template . replace ( "<%vk_gb1%>" , vkgb1 _str ) ;
const vkgb2 _str = ` [ ${ verificationKey . vk _gb _2 [ 0 ] [ 1 ] . toString ( ) } , ` +
` ${ verificationKey . vk _gb _2 [ 0 ] [ 0 ] . toString ( ) } ], ` +
` [ ${ verificationKey . vk _gb _2 [ 1 ] [ 1 ] . toString ( ) } , ` +
` ${ verificationKey . vk _gb _2 [ 1 ] [ 0 ] . toString ( ) } ] ` ;
template = template . replace ( "<%vk_gb2%>" , vkgb2 _str ) ;
const vkz _str = ` [ ${ verificationKey . vk _z [ 0 ] [ 1 ] . toString ( ) } , ` +
` ${ verificationKey . vk _z [ 0 ] [ 0 ] . toString ( ) } ], ` +
` [ ${ verificationKey . vk _z [ 1 ] [ 1 ] . toString ( ) } , ` +
` ${ verificationKey . vk _z [ 1 ] [ 0 ] . toString ( ) } ] ` ;
template = template . replace ( "<%vk_z%>" , vkz _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 ;
}
2020-05-09 16:05:45 +03:00
function generateVerifier _groth16 ( verificationKey ) {
let template = fs . readFileSync ( path . join ( _ _dirname , "templates" , "verifier_groth16.sol" ) , "utf-8" ) ;
2018-11-10 16:43:37 +03:00
const vkalfa1 _str = ` ${ verificationKey . vk _alfa _1 [ 0 ] . toString ( ) } , ` +
` ${ verificationKey . vk _alfa _1 [ 1 ] . toString ( ) } ` ;
template = template . replace ( "<%vk_alfa1%>" , vkalfa1 _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 ;
}
2018-10-21 19:24:49 +03:00
2019-06-16 01:12:50 +03:00
function generateVerifier _kimleeoh ( verificationKey ) {
2020-05-09 16:05:45 +03:00
assert ( false ) ; // Not implemented yet because it requires G2 exponentiation onchain.
let template = fs . readFileSync ( path . join ( _ _dirname , "templates" , "verifier_groth16.sol" ) , "utf-8" ) ;
2019-06-16 01:12:50 +03:00
const vkalfa1 _str = ` ${ verificationKey . vk _alfa _1 [ 0 ] . toString ( ) } , ` +
` ${ verificationKey . vk _alfa _1 [ 1 ] . toString ( ) } ` ;
template = template . replace ( "<%vk_alfa1%>" , vkalfa1 _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 ) ;
2018-10-21 19:24:49 +03:00
2019-06-16 01:12:50 +03:00
return template ;
}
2018-10-21 19:24:49 +03:00