diff --git a/.gitignore b/.gitignore index cdc9d09..cc37631 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,4 @@ node_modules artifacts typechain-types circuit_cache - +.idea \ No newline at end of file diff --git a/zkdocs-backend/generator/ZkDocGenerator.ts b/zkdocs-backend/generator/ZkDocGenerator.ts index 9991673..f03e670 100644 --- a/zkdocs-backend/generator/ZkDocGenerator.ts +++ b/zkdocs-backend/generator/ZkDocGenerator.ts @@ -11,22 +11,22 @@ const exec = util.promisify(require('child_process').exec); /** * Util: wraps ZkDocSchema, helps generate the circuit and corresponding build files. - * __ ________ + * __ ________ * _______| | __\______ \ ____ ____ ______ * \___ / |/ / | | \ / _ \_/ ___\ / ___/ - * / /| < | ` ( <_> ) \___ \___ \ + * / /| < | ` ( <_> ) \___ \___ \ * /_____ \__|_ \/_______ /\____/ \___ >____ > - * \/ \/ \/ \/ \/ + * \/ \/ \/ \/ \/ */ export class ZkDocGenerator { public constructor( - public schema: ZkDocSchema, - public rootBuildPath: string, + public schema: ZkDocSchema, + public rootBuildPath: string, public potFilePath: string, public circuitName: string = "circuit", public importPathPrefix: string = "") { - if (!existsSync(rootBuildPath)){ + if (!existsSync(rootBuildPath)) { mkdirSync(rootBuildPath); } } @@ -38,17 +38,17 @@ export class ZkDocGenerator { public async buildCircuit() { // Write circuit - let circuitPath = `${this.rootBuildPath}/${this.circuitName}.circom`; - let constraintStr = this.generateConstraintString(); - let circuitString = CircuitTemplate( - this.schema.json.fields.length, - this.schema.json.constraints.filter(constraint => constraint.constant).length, + const circuitPath = path.join(this.rootBuildPath, `${ this.circuitName }.circom`); + const constraintStr = this.generateConstraintString(); + const circuitString = CircuitTemplate( + this.schema.json.fields.length, + this.schema.json.constraints.filter(constraint => constraint.constant).length, constraintStr, this.importPathPrefix); writeFileSync(circuitPath, circuitString); // Build circuit - let buildCmd = `circom ${circuitPath} --sym --wasm --r1cs -o ${this.rootBuildPath}`; + const buildCmd = `circom "${ circuitPath }" --sym --wasm --r1cs -o "${ this.rootBuildPath }"`; let { stdout, stderr } = await exec(buildCmd); if (stdout != "") { console.log("Circom build: \n", stdout); @@ -59,8 +59,10 @@ export class ZkDocGenerator { } public async genZkey() { - let genCmd = `snarkjs plonk setup ${this.rootBuildPath}/${this.circuitName}.r1cs ${this.potFilePath} ${this.rootBuildPath}/${this.circuitName}_final.zkey`; - let { stdout, stderr } = await exec(genCmd); + const circuitPath = path.join(this.rootBuildPath, `${ this.circuitName }.r1cs`); + const zkeyPath = path.join(this.rootBuildPath, `${ this.circuitName }_final.zkey`); + const genCmd = `snarkjs plonk setup "${ circuitPath }" "${ this.potFilePath }" "${ zkeyPath }"`; + const { stdout, stderr } = await exec(genCmd); if (stdout != "") { console.log("snarkjs gen zkey: \n", stdout); } @@ -73,7 +75,8 @@ export class ZkDocGenerator { if (destination === undefined) { destination = path.join(__dirname, "..", "contracts", "compiled") } - let cmd = `snarkjs zkey export solidityverifier ${this.rootBuildPath}/${this.circuitName}_final.zkey ${destination}/${fileName}.sol` + const zkeyPath = path.join(this.rootBuildPath, `${ this.circuitName }_final.zkey`); + const cmd = `snarkjs zkey export solidityverifier "${ zkeyPath }" "${ destination }/${ fileName }.sol"` let { stdout, stderr } = await exec(cmd); if (stdout != "") { console.log("snarkjs gen zkey: \n", stdout); @@ -84,11 +87,13 @@ export class ZkDocGenerator { } public async exportVkey() { - let cmd = `snarkjs zkey export verificationkey ${this.rootBuildPath}/${this.circuitName}_final.zkey ${this.rootBuildPath}/verification_key.json` - let { stdout, stderr } = await exec(cmd); + const zkeyPath = path.join(this.rootBuildPath, `${ this.circuitName }_final.zkey`); + const cmd = `snarkjs zkey export verificationkey "${ zkeyPath }" "${ this.rootBuildPath }/verification_key.json"` + const { stdout, stderr } = await exec(cmd); if (stdout != "") { console.log("snarkjs gen zkey: \n", stdout); } + if (stderr != "") { console.error("snarkjs gen zkey build failed: \n", stderr); } @@ -96,22 +101,23 @@ export class ZkDocGenerator { private generateConstraintString(): string { let constIndex = 0; - let constraints = this.schema.json.constraints.map((constraint, index) => { - let constraintVarName = `constraint${index}` - let constraintStr = `var ${constraintVarName} = `; + + return this.schema.json.constraints.map((constraint, index) => { + let constraintVarName = `constraint${ index }` + let constraintStr = `var ${ constraintVarName } = `; if (constraint.op == "ADD") { - constraintStr += `values[${this.lookupFieldIndex(constraint.fieldA)}] + values[${this.lookupFieldIndex(constraint.fieldB)}];\n` + constraintStr += `values[${ this.lookupFieldIndex(constraint.fieldA) }] + values[${ this.lookupFieldIndex(constraint.fieldB) }];\n` } else if (constraint.op == "SUB") { - constraintStr += `values[${this.lookupFieldIndex(constraint.fieldA)}] - values[${this.lookupFieldIndex(constraint.fieldB)}];\n` + constraintStr += `values[${ this.lookupFieldIndex(constraint.fieldA) }] - values[${ this.lookupFieldIndex(constraint.fieldB) }];\n` } else if (constraint.op == "NONE") { - constraintStr += `values[${this.lookupFieldIndex(constraint.fieldA)}];\n` + constraintStr += `values[${ this.lookupFieldIndex(constraint.fieldA) }];\n` } else { console.error("Cannot generate constraint from OP ", constraint); exit(-1); } - let componentName = `comp${index}` - constraintStr += `component ${componentName} = ` + let componentName = `comp${ index }` + constraintStr += `component ${ componentName } = ` if (constraint.constraint == "GT") { constraintStr += "GreaterEqThan(32);\n"; } else if (constraint.constraint == "LT") { @@ -121,31 +127,27 @@ export class ZkDocGenerator { exit(-1); } - constraintStr += `${componentName}.in[0] <== ${constraintVarName};\n` - constraintStr += `${componentName}.in[1] <== ` - + constraintStr += `${ componentName }.in[0] <== ${ constraintVarName };\n` + constraintStr += `${ componentName }.in[1] <== ` + if (constraint.constant) { - constraintStr += `consts[${constIndex}];\n`; + constraintStr += `consts[${ constIndex }];\n`; constIndex += 1; } else if (constraint.fieldCompare) { - constraintStr += `values[${this.lookupFieldIndex(constraint.fieldCompare!)}];\n` + constraintStr += `values[${ this.lookupFieldIndex(constraint.fieldCompare!) }];\n` } else { console.error("Constraint didn't have constant nor fieldCompare.") // Shouldn't happen } - constraintStr += `${componentName}.out === 1;\n\n`; + constraintStr += `${ componentName }.out === 1;\n\n`; return constraintStr; - }).reduce((full, next) => { - return full += next; - }) - - return constraints + }).reduce((full, next) => full + next); } private lookupFieldIndex(fieldName: string): number { let index = this.schema.json.fields.findIndex(field => field.field_name == fieldName); if (index == -1) { - console.error(`Failed to lookup field ${fieldName} in schema.`); + console.error(`Failed to lookup field ${ fieldName } in schema.`); exit(-1); } return index; diff --git a/zkdocs-backend/scripts/tasks.ts b/zkdocs-backend/scripts/tasks.ts index 51e68c6..2cf50fe 100644 --- a/zkdocs-backend/scripts/tasks.ts +++ b/zkdocs-backend/scripts/tasks.ts @@ -5,7 +5,7 @@ import { ZkDocGenerator } from "../generator/ZkDocGenerator"; import { keccakJson } from "zkdocs-lib"; const POT_PATH = path.join(__dirname, "..", "build", "pot16_final.ptau"); -const CACHE_DIR = path.join(__dirname, "..", "circuit_cache") +const CACHE_DIR = path.join(__dirname, "..", "circuit_cache"); export async function buildAndDeploySchema(args: any, hre: any) { await build(args.schema)