diff --git a/README.md b/README.md index c136cb1..1bc22f1 100644 --- a/README.md +++ b/README.md @@ -196,7 +196,7 @@ Input Signals: │ b │ '2' │ └───────────┴────────┘ -No ouput signal found: +No output signal found: Constraint no 1: passed diff --git a/package-lock.json b/package-lock.json index e52c4e1..5012f68 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4044,63 +4044,6 @@ "node": ">=10.13.0" } }, - "node_modules/eslint/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/espree": { "version": "9.3.3", "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.3.tgz", @@ -5827,33 +5770,6 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-changed-files/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-changed-files/node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/jest-circus": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-28.1.3.tgz", @@ -5884,33 +5800,6 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-circus/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-circus/node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/jest-cli": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-28.1.3.tgz", @@ -6263,33 +6152,6 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-runner/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-runner/node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/jest-runtime": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-28.1.3.tgz", @@ -6636,6 +6498,21 @@ "lie": "3.1.1" } }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", @@ -10256,6 +10133,36 @@ "node": ">=8" } }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/p-map": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", @@ -12428,6 +12335,18 @@ "engines": { "node": ">=6" } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } }, "dependencies": { @@ -15360,39 +15279,6 @@ "requires": { "is-glob": "^4.0.3" } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true } } }, @@ -16793,23 +16679,6 @@ "requires": { "execa": "^5.0.0", "p-limit": "^3.1.0" - }, - "dependencies": { - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true - } } }, "jest-circus": { @@ -16837,23 +16706,6 @@ "pretty-format": "^28.1.3", "slash": "^3.0.0", "stack-utils": "^2.0.3" - }, - "dependencies": { - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true - } } }, "jest-cli": { @@ -17119,23 +16971,6 @@ "jest-worker": "^28.1.3", "p-limit": "^3.1.0", "source-map-support": "0.5.13" - }, - "dependencies": { - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true - } } }, "jest-runtime": { @@ -17421,6 +17256,15 @@ "lie": "3.1.1" } }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", @@ -20096,6 +19940,24 @@ "integrity": "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==", "dev": true }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, "p-map": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", @@ -21728,6 +21590,12 @@ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true } } } diff --git a/src/commands/actions/debug.ts b/src/commands/actions/debug.ts index 5e647fb..bd6380d 100644 --- a/src/commands/actions/debug.ts +++ b/src/commands/actions/debug.ts @@ -12,6 +12,8 @@ import { load } from "r1csfile"; // @ts-ignore import { utils } from "ffjavascript"; +const fs = require("fs/promises"); + enum Protocol { GROTH16 = "groth16", PLONK = "plonk", @@ -169,13 +171,11 @@ export const debug = async (options: any) => { if (await fileExists(inputFilePath)) { try { - const inputFileData = await wasmFs.readFileSync( - inputFilePath, - "utf8" + + const input = utils.unstringifyBigInts( + JSON.parse(await fs.readFile(inputFilePath, "utf8")) ); - const input = utils.unstringifyBigInts(JSON.parse(inputFileData)); - const wtnsFile = await WrappedSnarkJs.util.generateWtns( wtnsFilePath, wasmFilePath, @@ -186,7 +186,7 @@ export const debug = async (options: any) => { const symFile = await wasmFs.readFileSync(symFilePath); - await logSignals(r1cs, wtnsFile, symFile); + await logSignals(r1cs, wtnsFile, symFile, input); const checker = new Checker(r1csFilePath, symFilePath); @@ -194,7 +194,7 @@ export const debug = async (options: any) => { wtnsFilePath.replace(".wtns", ".json") ); spinner.succeed( - chalk.greenBright(`${circuitName} succesfully debugged.`) + chalk.greenBright(`${circuitName} successfully debugged.`) ); } catch (error) { if (error instanceof Error) { diff --git a/utils/checker.ts b/utils/checker.ts index 615cd9d..7d21173 100644 --- a/utils/checker.ts +++ b/utils/checker.ts @@ -15,7 +15,7 @@ const groupOrderPrime = BigInt(groupOrderPrimeStr); export class Checker { r1csFilepath; symFilepath; - r1cs: { constraints: any; prime: any } | undefined; + r1cs: { constraints: any; prime: any; nConstraints: number } | any; symbols: {} | undefined; signals: {} | undefined; constructor(r1csFilepath: string, symFilepath: string) { @@ -31,18 +31,26 @@ export class Checker { async checkConstraintsAndOutput(witnessFilePath: string) { // 0. load r1cs and witness - if (!this.r1cs) { - await this.load(); - } - let witness; - if (witnessFilePath.endsWith("json")) { - witness = JSON.parse(nodefs.readFileSync(witnessFilePath).toString()); + try { + if (!this.r1cs) { + await this.load(); + } + let witness; + if (witnessFilePath.endsWith("json")) { + witness = JSON.parse(nodefs.readFileSync(witnessFilePath).toString()); + } + // 1. check constraints + const F = new ZqField(this.r1cs?.prime); + const constraints = this.r1cs?.constraints; + if (this.r1cs.nConstraints !== 0) { + await checkConstraints(F, constraints, witness, this.signals); + } else { + log("No quadratic constraint signal found:\n", "info"); + } + return true; + } catch (err) { + console.log({ err }); } - // 1. check constraints - const F = new ZqField(this.r1cs?.prime); - const constraints = this.r1cs?.constraints; - await checkConstraints(F, constraints, witness, this.signals); - return true; } } diff --git a/utils/logger.ts b/utils/logger.ts index 40fae42..8d689cc 100644 --- a/utils/logger.ts +++ b/utils/logger.ts @@ -1,6 +1,9 @@ const chalk = require("chalk"); -// @ts-ignore -import { readBinFile, readSection } from "@iden3/binfileutils"; +import { + readBinFile, + readSection, + // @ts-ignore +} from "@iden3/binfileutils"; import { readWtnsHeader } from "./witness"; // @ts-ignore import { Scalar } from "ffjavascript"; @@ -48,7 +51,12 @@ export const circomLog = (message = "") => { ); }; -export const logSignals = async (r1cs: any, wtnsFile: any, symFile: any) => { +export const logSignals = async ( + r1cs: any, + wtnsFile: any, + symFile: any, + inputSignals: any +) => { if (r1cs) { const { fd: fdWtns, sections: sectionsWtns } = await readBinFile( wtnsFile, @@ -58,7 +66,7 @@ export const logSignals = async (r1cs: any, wtnsFile: any, symFile: any) => { 1 << 23 ); - const wtns = await readWtnsHeader(fdWtns, sectionsWtns); + const { n8 } = await readWtnsHeader(fdWtns, sectionsWtns); const buffWitness = await readSection(fdWtns, sectionsWtns, 2); let outputPrefixes: any = {}; @@ -73,23 +81,17 @@ export const logSignals = async (r1cs: any, wtnsFile: any, symFile: any) => { outputPrefixes[wireNo] = line.split(",")[3].replace("main.", "") + " = "; } else { - inputPrefixes[wireNo] = - line.split(",")[3].replace("main.", "") + " = "; + inputPrefixes[line.split(",")[3].replace("main.", "")] = 0; } lastPos = i; } } - - let outputSignals: any = {}; - if (r1cs.nOutputs > 0) { - for (const wire in outputPrefixes) { - - // @ts-ignore - const b = buffWitness.slice(wire * wtns.n8, wire * wtns.n8 + wtns.n8); - - const outputPrefix = outputPrefixes[wire] || ""; - + let outputSignals: any = {}; + let outputIndex = 1; + for (; outputIndex <= r1cs.nOutputs; outputIndex++) { + const b = buffWitness.slice(outputIndex * n8, outputIndex * n8 + n8); + const outputPrefix = outputPrefixes[outputIndex] || ""; try { outputSignals[outputPrefix.replace("=", "").trim()] = Scalar.fromRprLE(b).toString(); @@ -97,46 +99,42 @@ export const logSignals = async (r1cs: any, wtnsFile: any, symFile: any) => { outputSignals[outputPrefix.replace("=", "").trim()] = "0"; } } - } - - let inputSignals: any = {}; - - console.log({ inputPrefixes }); - - for (const wire in inputPrefixes) { - // @ts-ignore - const b = buffWitness.slice(wire * wtns.n8, wire * wtns.n8 + wtns.n8); - console.log({ b }); + if (Object.keys(outputSignals).length !== 0) { + console.log(chalk.cyan(`\nOutput Signals:\n`)); - const inputPrefix = inputPrefixes[wire] || ""; - - console.log({ inputPrefix }, b); - - try { - inputSignals[inputPrefix.replace("=", "").trim()] = - Scalar.fromRprLE(b).toString(); - } catch (err) { - inputSignals[inputPrefix.replace("=", "").trim()] = "0"; + console.table(outputSignals); + } else { + console.log(chalk.yellow(`No output signal found:\n`)); } } - if (Object.keys(inputSignals).length !== 0) { - console.log(chalk.cyan(`Input Signals:\n`)); - - console.table(inputSignals); - } else { - console.log(chalk.yellow(`No input signal found\n`)); + const sortedKeys = Object.keys(inputPrefixes).sort(); + const sortedSignals = Object.keys(inputSignals).sort(); + + let iterator = 0; + for (const key of sortedSignals) { + if (Object.prototype.hasOwnProperty.call(inputSignals, key)) { + const element = inputSignals[key]; + if (typeof element === "object") { + const flatArray = element.flat(); + for (const signal of flatArray) { + inputPrefixes[sortedKeys[iterator]] = signal; + iterator++; + } + } else { + inputPrefixes[sortedKeys[iterator]] = element; + iterator++; + } + } } - if (Object.keys(outputSignals).length !== 0) { - console.log(chalk.cyan(`\nOutput Signals:\n`)); - - console.table(outputSignals); + if (Object.keys(inputSignals).length !== 0) { + console.log(chalk.cyan(`\nInput Signals:\n`)); + console.table(inputPrefixes); } else { - console.log(chalk.yellow(`No ouput signal found:\n`)); + console.log(chalk.yellow(`No input signal found:\n`)); } - await fdWtns.close(); } }; diff --git a/utils/snarkjs.ts b/utils/snarkjs.ts index 40ff8b3..4544561 100644 --- a/utils/snarkjs.ts +++ b/utils/snarkjs.ts @@ -1,7 +1,7 @@ // @ts-ignore import bfj from "bfj"; // @ts-ignore -import { utils, Scalar } from "ffjavascript"; +import { utils } from "ffjavascript"; import fs from "fs"; import path from "path"; import shelljs from "shelljs"; @@ -11,15 +11,13 @@ import { log } from "./logger"; import { wtnsBuilder } from "./witness"; // @ts-ignore import * as fastFile from "fastfile"; -const { zKey, plonk, wtns } = require("snarkjs"); -const { stringifyBigInts, unstringifyBigInts } = utils; -import { - createBinFile, - endWriteSection, - startWriteSection, - writeBigInt, - // @ts-ignore -} from "@iden3/binfileutils"; +const { zKey, plonk } = require("snarkjs"); +const { stringifyBigInts } = utils; +// @ts-ignore + +const DEFAULT_NODE_ARGS = "--max-old-space-size=8192 --stack-size=65500"; +const NODE_ARGS = process.env.NODE_ARGS || DEFAULT_NODE_ARGS; +const NODE_CMD = `node ${NODE_ARGS}`; export const WrappedSnarkJs = { groth16: { @@ -151,43 +149,47 @@ export const WrappedSnarkJs = { }, generateWtns: async (wtnsPath: string, wasmPath: string, input: any) => { try { - const _input = unstringifyBigInts(input); - const fdWasm = await fastFile.readExisting(wasmPath); const wasm = await fdWasm.read(fdWasm.totalSize); await fdWasm.close(); - const wc = await wtnsBuilder(wasm, { - log() {}, + const logs = []; + + const witness = await wtnsBuilder(wasm, { + log(message: bigint, label?: string) { + if (label) { + logs.push(label + ": " + message.toString()); + } else { + logs.push(message.toString()); + } + }, }); - let w; - if (wc.circom_version() == 1) { - w = await wc.calculateBinWitness(_input, true); - const fdWtns = await createBinFile(wtnsPath, "wtns", 2, 2); + const witnessBinFile = await witness.calculateWTNSBin(input, true); - await writeBin(fdWtns, w, wc.prime); + const fsWtns = await fastFile.createOverride(wtnsPath); - await fdWtns.close(); - } else { - const fdWtns = await fastFile.createOverride(wtnsPath); + await fsWtns.write(witnessBinFile); + await fsWtns.close(); - w = await wc.calculateWTNSBin(_input, true); + const snarkjsPath = path.join( + require.resolve("snarkjs"), + "..", + "cli.cjs" + ); - await fdWtns.write(w); - await fdWtns.close(); - } + const command = `${NODE_CMD} ${snarkjsPath} wej ${wtnsPath} ${wtnsPath.replace( + ".wtns", + ".json" + )}`; - const wtnsData = await wtns.exportJson(wtnsPath); - await bfj.write( - wtnsPath.replace(".wtns", ".json"), - stringifyBigInts(wtnsData), - { space: 1 } - ); - if (wtnsData) { + shelljs.exec(command); + + if (witnessBinFile) { log(`✓ Successfully generated the witness file`, "success"); } - return w; + + return witnessBinFile; } catch (error) { log(`${error}`, "error"); throw error; @@ -196,18 +198,16 @@ export const WrappedSnarkJs = { }, }; -async function writeBin(fd: any, witnessBin: any, prime: any) { - await startWriteSection(fd, 1); - const n8 = (Math.floor((Scalar.bitLength(prime) - 1) / 64) + 1) * 8; - await fd.writeULE32(n8); - await writeBigInt(fd, prime, n8); - if (witnessBin.byteLength % n8 != 0) { - throw new Error("Invalid witness length"); - } - await fd.writeULE32(witnessBin.byteLength / n8); - await endWriteSection(fd); - - await startWriteSection(fd, 2); - await fd.write(witnessBin); - await endWriteSection(fd); +function defaultWitnessOption() { + let logFn = console.log; + let calculateWitnessOptions = { + sanityCheck: true, + logTrigger: logFn, + logOutput: logFn, + logStartComponent: logFn, + logFinishComponent: logFn, + logSetSignal: logFn, + logGetSignal: logFn, + }; + return calculateWitnessOptions; } diff --git a/utils/witness.ts b/utils/witness.ts index e3f7818..8165ce9 100644 --- a/utils/witness.ts +++ b/utils/witness.ts @@ -136,9 +136,11 @@ class WitnessCalculator { const arr = new Uint32Array(this.n32); for (let i = 0; i < this.n32; i++) { arr[this.n32 - 1 - i] = this.instance.exports.readSharedRWMemory(i); + } this.prime = fromArray32(arr); + this.witnessSize = this.instance.exports.getWitnessSize(); this.sanityCheck = sanityCheck; @@ -153,6 +155,7 @@ class WitnessCalculator { //input is assumed to be a map from signals to arrays of bigints this.instance.exports.init(this.sanityCheck || sanityCheck ? 1 : 0); const keys = Object.keys(input); + var input_counter = 0; keys.forEach((k) => { const h = fnvHash(k); @@ -160,6 +163,7 @@ class WitnessCalculator { const hLSB = parseInt(h.slice(8, 16), 16); const fArr = flatArray(input[k]); let signalSize = this.instance.exports.getInputSignalSize(hMSB, hLSB); + if (signalSize < 0) { throw new Error(`Signal ${k} not found\n`); } @@ -205,9 +209,11 @@ class WitnessCalculator { for (let i = 0; i < this.witnessSize; i++) { this.instance.exports.getWitness(i); const arr = new Uint32Array(this.n32); + for (let j = 0; j < this.n32; j++) { arr[this.n32 - 1 - j] = this.instance.exports.readSharedRWMemory(j); } + // @ts-ignore w.push(fromArray32(arr)); // @ts-ignore @@ -221,7 +227,6 @@ class WitnessCalculator { const buff32 = new Uint32Array(this.witnessSize * this.n32); const buff = new Uint8Array(buff32.buffer); await this._doCalculateWitness(input, sanityCheck); - for (let i = 0; i < this.witnessSize; i++) { this.instance.exports.getWitness(i); const pos = i * this.n32; @@ -236,6 +241,7 @@ class WitnessCalculator { async calculateWTNSBin(input: any, sanityCheck: any) { const buff32 = new Uint32Array(this.witnessSize * this.n32 + this.n32 + 11); const buff = new Uint8Array(buff32.buffer); + await this._doCalculateWitness(input, sanityCheck); //"wtns"