mirror of
https://github.com/arnaucube/circom.git
synced 2026-02-07 11:16:42 +01:00
Compare commits
38 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2200408986 | ||
|
|
5f13d37fdc | ||
|
|
3b46b74d4a | ||
|
|
aa2d768465 | ||
|
|
f02ceb2508 | ||
|
|
d014d67032 | ||
|
|
2e1b35a94d | ||
|
|
7cef1be2c3 | ||
|
|
4b631994ca | ||
|
|
7239abcef1 | ||
|
|
633f755e34 | ||
|
|
923b19c414 | ||
|
|
90cc7d5072 | ||
|
|
145d5a21ad | ||
|
|
cbb0b229bc | ||
|
|
1d14e8c603 | ||
|
|
1e2fb12631 | ||
|
|
0e1a1bcc23 | ||
|
|
989987bfc2 | ||
|
|
5f3ef322a7 | ||
|
|
3c8e61b9a4 | ||
|
|
c39423e411 | ||
|
|
06b6c1a49e | ||
|
|
6b712f3587 | ||
|
|
26cad30222 | ||
|
|
f48de61ca9 | ||
|
|
89cea4755c | ||
|
|
9bf6ecc4f3 | ||
|
|
59d591c988 | ||
|
|
9fe8be9828 | ||
|
|
7e24d6f57d | ||
|
|
8655573b34 | ||
|
|
8fc6e3f1c6 | ||
|
|
c32d303d27 | ||
|
|
744d3b241c | ||
|
|
1a5f7d1a2b | ||
|
|
434e7ac498 | ||
|
|
99afb4312e |
@@ -8,7 +8,7 @@ This tutorial will guide you in creating your first zero-knowledge SNARK circuit
|
||||
|
||||
If you don't have it installed yet, you need to install `Node.js`.
|
||||
|
||||
The last stable version of `Node.js` (or 8.12.0) works just fine, but if you install the latest current version `Node.js` (10.12.0) you will see a significant increase in performance. This is because last versions of node includes Big Integer Libraries nativelly. The `snarkjs` library makes use of this feature if available, and this improves the performance x10 (!).
|
||||
You should install at least version 10 of node. It's important to note here that the latests versions of javascript, includes big integer support and web assembly compilers that make the code run fast.
|
||||
|
||||
### 1.2 Install **circom** and **snarkjs**
|
||||
|
||||
|
||||
137
cli.js
137
cli.js
@@ -24,6 +24,8 @@
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const Scalar = require("ffjavascript").Scalar;
|
||||
const stringifyBigInts = require("ffjavascript").utils.stringifyBigInts;
|
||||
const fastFile = require("fastfile");
|
||||
|
||||
const compiler = require("./src/compiler");
|
||||
|
||||
@@ -60,78 +62,68 @@ const argv = require("yargs")
|
||||
.argv;
|
||||
|
||||
|
||||
let inputFile;
|
||||
if (argv._.length == 0) {
|
||||
inputFile = "circuit.circom";
|
||||
} else if (argv._.length == 1) {
|
||||
inputFile = argv._[0];
|
||||
} else {
|
||||
console.log("Only one circuit at a time is permited");
|
||||
process.exit(1);
|
||||
}
|
||||
async function run() {
|
||||
let inputFile;
|
||||
if (argv._.length == 0) {
|
||||
inputFile = "circuit.circom";
|
||||
} else if (argv._.length == 1) {
|
||||
inputFile = argv._[0];
|
||||
} else {
|
||||
console.log("Only one circuit at a time is permited");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const fullFileName = path.resolve(process.cwd(), inputFile);
|
||||
const fileName = path.basename(fullFileName, ".circom");
|
||||
const cSourceName = typeof(argv.csource) === "string" ? argv.csource : fileName + ".cpp";
|
||||
const wasmName = typeof(argv.wasm) === "string" ? argv.wasm : fileName + ".wasm";
|
||||
const watName = typeof(argv.wat) === "string" ? argv.wat : fileName + ".wat";
|
||||
const r1csName = typeof(argv.r1cs) === "string" ? argv.r1cs : fileName + ".r1cs";
|
||||
const symName = typeof(argv.sym) === "string" ? argv.sym : fileName + ".sym";
|
||||
const fullFileName = path.resolve(process.cwd(), inputFile);
|
||||
const fileName = path.basename(fullFileName, ".circom");
|
||||
const cSourceName = typeof(argv.csource) === "string" ? argv.csource : fileName + ".cpp";
|
||||
const wasmName = typeof(argv.wasm) === "string" ? argv.wasm : fileName + ".wasm";
|
||||
const watName = typeof(argv.wat) === "string" ? argv.wat : fileName + ".wat";
|
||||
const r1csName = typeof(argv.r1cs) === "string" ? argv.r1cs : fileName + ".r1cs";
|
||||
const symName = typeof(argv.sym) === "string" ? argv.sym : fileName + ".sym";
|
||||
|
||||
const options = {};
|
||||
options.reduceConstraints = !argv.fast;
|
||||
options.verbose = argv.verbose || false;
|
||||
options.sanityCheck = argv.sanitycheck;
|
||||
options.prime = argv.prime ? Scalar.fromString(argv.prime) : Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||
const options = {};
|
||||
options.reduceConstraints = !argv.fast;
|
||||
options.verbose = argv.verbose || false;
|
||||
options.sanityCheck = argv.sanitycheck;
|
||||
|
||||
if (argv.csource) {
|
||||
options.cSourceWriteStream = fs.createWriteStream(cSourceName);
|
||||
}
|
||||
if (argv.wasm) {
|
||||
options.wasmWriteStream = fs.createWriteStream(wasmName);
|
||||
}
|
||||
if (argv.wat) {
|
||||
options.watWriteStream = fs.createWriteStream(watName);
|
||||
}
|
||||
if (argv.r1cs) {
|
||||
options.r1csFileName = r1csName;
|
||||
}
|
||||
if (argv.sym) {
|
||||
options.symWriteStream = fs.createWriteStream(symName);
|
||||
}
|
||||
if (argv.newThreadTemplates) {
|
||||
options.newThreadTemplates = new RegExp(argv.newThreadTemplates);
|
||||
}
|
||||
if (argv.csource) {
|
||||
options.cSourceFile = await fastFile.createOverride(cSourceName);
|
||||
const noExt = cSourceName.substr(0, cSourceName.lastIndexOf(".")) || cSourceName;
|
||||
options.dataFile = await fastFile.createOverride(noExt+".dat");
|
||||
}
|
||||
if (argv.wasm) {
|
||||
options.wasmFile = await fastFile.createOverride(wasmName);
|
||||
}
|
||||
if (argv.wat) {
|
||||
options.watFile = await fastFile.createOverride(watName);
|
||||
}
|
||||
if (argv.r1cs) {
|
||||
options.r1csFileName = r1csName;
|
||||
}
|
||||
if (argv.sym) {
|
||||
options.symWriteStream = fs.createWriteStream(symName);
|
||||
}
|
||||
if (argv.newThreadTemplates) {
|
||||
options.newThreadTemplates = new RegExp(argv.newThreadTemplates);
|
||||
}
|
||||
if (!argv.prime) {
|
||||
options.prime = Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||
} else if (["BLS12-381", "BLS12381"]. indexOf(argv.prime.toUpperCase()) >=0) {
|
||||
options.prime = Scalar.fromString("73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001",16);
|
||||
} else if (["BN-128", "BN128", "BN254", "BN-254"]. indexOf(argv.prime.toUpperCase()) >=0) {
|
||||
options.prime = Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||
} else {
|
||||
options.prime = Scalar.fromString(argv.prime);
|
||||
}
|
||||
|
||||
compiler(fullFileName, options).then( () => {
|
||||
let cSourceDone = false;
|
||||
let wasmDone = false;
|
||||
|
||||
await compiler(fullFileName, options);
|
||||
|
||||
if (options.cSourceFile) await options.cSourceFile.close();
|
||||
if (options.dataFile) await options.dataFile.close();
|
||||
if (options.wasmFile) await options.wasmFile.close();
|
||||
if (options.watFile) await options.watFile.close();
|
||||
let symDone = false;
|
||||
let watDone = false;
|
||||
if (options.cSourceWriteStream) {
|
||||
options.cSourceWriteStream.on("finish", () => {
|
||||
cSourceDone = true;
|
||||
finishIfDone();
|
||||
});
|
||||
} else {
|
||||
cSourceDone = true;
|
||||
}
|
||||
if (options.wasmWriteStream) {
|
||||
options.wasmWriteStream.on("finish", () => {
|
||||
wasmDone = true;
|
||||
finishIfDone();
|
||||
});
|
||||
} else {
|
||||
wasmDone = true;
|
||||
}
|
||||
if (options.watWriteStream) {
|
||||
options.watWriteStream.on("finish", () => {
|
||||
watDone = true;
|
||||
finishIfDone();
|
||||
});
|
||||
} else {
|
||||
watDone = true;
|
||||
}
|
||||
if (options.symWriteStream) {
|
||||
options.symWriteStream.on("finish", () => {
|
||||
symDone = true;
|
||||
@@ -141,12 +133,17 @@ compiler(fullFileName, options).then( () => {
|
||||
symDone = true;
|
||||
}
|
||||
function finishIfDone() {
|
||||
if ((cSourceDone)&&(symDone)&&(wasmDone)&&(watDone)) {
|
||||
if (symDone) {
|
||||
setTimeout(() => {
|
||||
process.exit(0);
|
||||
}, 300);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
run().then(()=> {
|
||||
process.exit(0);
|
||||
}, (err) => {
|
||||
// console.log(err);
|
||||
console.log(err.stack);
|
||||
@@ -157,11 +154,9 @@ compiler(fullFileName, options).then( () => {
|
||||
if (argv.verbose) console.log(err.stack);
|
||||
}
|
||||
if (err.ast) {
|
||||
console.error(JSON.stringify(err.ast, null, 1));
|
||||
console.error(JSON.stringify(stringifyBigInts(err.ast), null, 1));
|
||||
}
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
441
package-lock.json
generated
441
package-lock.json
generated
@@ -1,31 +1,31 @@
|
||||
{
|
||||
"name": "circom",
|
||||
"version": "0.5.10",
|
||||
"version": "0.5.22",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": {
|
||||
"version": "7.8.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
|
||||
"integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
|
||||
"version": "7.10.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
|
||||
"integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/highlight": "^7.8.3"
|
||||
"@babel/highlight": "^7.10.4"
|
||||
}
|
||||
},
|
||||
"@babel/helper-validator-identifier": {
|
||||
"version": "7.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz",
|
||||
"integrity": "sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw==",
|
||||
"version": "7.10.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz",
|
||||
"integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==",
|
||||
"dev": true
|
||||
},
|
||||
"@babel/highlight": {
|
||||
"version": "7.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz",
|
||||
"integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==",
|
||||
"version": "7.10.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
|
||||
"integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/helper-validator-identifier": "^7.9.0",
|
||||
"@babel/helper-validator-identifier": "^7.10.4",
|
||||
"chalk": "^2.0.0",
|
||||
"js-tokens": "^4.0.0"
|
||||
}
|
||||
@@ -48,9 +48,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"acorn": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz",
|
||||
"integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==",
|
||||
"version": "7.4.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz",
|
||||
"integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==",
|
||||
"dev": true
|
||||
},
|
||||
"acorn-jsx": {
|
||||
@@ -60,9 +60,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"ajv": {
|
||||
"version": "6.12.0",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz",
|
||||
"integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==",
|
||||
"version": "6.12.3",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz",
|
||||
"integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fast-deep-equal": "^3.1.1",
|
||||
@@ -101,12 +101,11 @@
|
||||
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
|
||||
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"requires": {
|
||||
"@types/color-name": "^1.1.1",
|
||||
"color-convert": "^2.0.1"
|
||||
"color-convert": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"argparse": {
|
||||
@@ -129,6 +128,11 @@
|
||||
"integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
|
||||
"dev": true
|
||||
},
|
||||
"async": {
|
||||
"version": "0.9.2",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
|
||||
"integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0="
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
@@ -139,6 +143,11 @@
|
||||
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz",
|
||||
"integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w=="
|
||||
},
|
||||
"blakejs": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz",
|
||||
"integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U="
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
@@ -176,37 +185,10 @@
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"supports-color": "^5.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-convert": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"chardet": {
|
||||
@@ -221,11 +203,11 @@
|
||||
"integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII="
|
||||
},
|
||||
"circom_runtime": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/circom_runtime/-/circom_runtime-0.0.6.tgz",
|
||||
"integrity": "sha512-o0T5MuWzxnxinWG3+CygS/kZouoP+z5ZrufUwqKJy3gsVFJhkbqMpfKmcBGjhExB3uatA7cKyOiRAOLOz5+t5w==",
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/circom_runtime/-/circom_runtime-0.1.4.tgz",
|
||||
"integrity": "sha512-sQWeEBD3o2jIdrKPf3VDu7DNfP+NfscYO/pxi73FE0qQW8TXTfwno8Grdl++h6OKWbzvWJdG5jQvS+WGKjpMOg==",
|
||||
"requires": {
|
||||
"ffjavascript": "0.1.0",
|
||||
"ffjavascript": "0.2.10",
|
||||
"fnv-plus": "^1.3.1"
|
||||
}
|
||||
},
|
||||
@@ -248,9 +230,9 @@
|
||||
}
|
||||
},
|
||||
"cli-width": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
|
||||
"integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz",
|
||||
"integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==",
|
||||
"dev": true
|
||||
},
|
||||
"cliui": {
|
||||
@@ -264,17 +246,17 @@
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
|
||||
},
|
||||
"colors": {
|
||||
"version": "0.5.1",
|
||||
@@ -352,9 +334,12 @@
|
||||
"dev": true
|
||||
},
|
||||
"ejs": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.0.1.tgz",
|
||||
"integrity": "sha512-cuIMtJwxvzumSAkqaaoGY/L6Fc/t6YvoP9/VIaK0V/CyqKLEQ8sqODmYfy/cjXEdZ9+OOL8TecbJu+1RsofGDw=="
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.5.tgz",
|
||||
"integrity": "sha512-dldq3ZfFtgVTJMLjOe+/3sROTzALlL9E34V4/sDtUd/KlBSS0s6U1/+WPE1B4sj9CXHJpL1M6rhNJnc9Wbal9w==",
|
||||
"requires": {
|
||||
"jake": "^10.6.1"
|
||||
}
|
||||
},
|
||||
"emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
@@ -364,8 +349,7 @@
|
||||
"escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
|
||||
"dev": true
|
||||
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
|
||||
},
|
||||
"escodegen": {
|
||||
"version": "1.3.3",
|
||||
@@ -462,9 +446,9 @@
|
||||
}
|
||||
},
|
||||
"eslint-scope": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz",
|
||||
"integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==",
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz",
|
||||
"integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"esrecurse": "^4.1.0",
|
||||
@@ -481,9 +465,9 @@
|
||||
}
|
||||
},
|
||||
"eslint-visitor-keys": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz",
|
||||
"integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==",
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
|
||||
"integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
|
||||
"dev": true
|
||||
},
|
||||
"espree": {
|
||||
@@ -504,18 +488,18 @@
|
||||
"dev": true
|
||||
},
|
||||
"esquery": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.2.0.tgz",
|
||||
"integrity": "sha512-weltsSqdeWIX9G2qQZz7KlTRJdkkOCTPgLYJUz1Hacf48R4YOwGPHO3+ORfWedqJKbq5WQmsgK90n+pFLIKt/Q==",
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz",
|
||||
"integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"estraverse": "^5.0.0"
|
||||
"estraverse": "^5.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"estraverse": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.0.0.tgz",
|
||||
"integrity": "sha512-j3acdrMzqrxmJTNj5dbr1YbjacrYgAxVMeF0gK16E3j494mOe7xygM/ZLIguEQ0ETwAg2hlJCtHRGav+y0Ny5A==",
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
|
||||
"integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
@@ -564,9 +548,9 @@
|
||||
}
|
||||
},
|
||||
"fast-deep-equal": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
|
||||
"integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==",
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
||||
"dev": true
|
||||
},
|
||||
"fast-json-stable-stringify": {
|
||||
@@ -582,14 +566,14 @@
|
||||
"dev": true
|
||||
},
|
||||
"fastfile": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fastfile/-/fastfile-0.0.1.tgz",
|
||||
"integrity": "sha512-Fk8PWafGWGEUw7oPq/dJen92ASxknCEy4ZC8n4VEvSwCp/jcReyEmVoWsRIWTf+IvAp2MzvFi54vOPeK2LQZtQ=="
|
||||
"version": "0.0.12",
|
||||
"resolved": "https://registry.npmjs.org/fastfile/-/fastfile-0.0.12.tgz",
|
||||
"integrity": "sha512-0EZo2y5eW8X0oiDDRvcnufjVxlM96CQL5hvmRQtbRABWlCkH73IHwkzl0qOSdxtchaMr+0TSB7GVqaVEixRr1Q=="
|
||||
},
|
||||
"ffiasm": {
|
||||
"version": "0.0.2",
|
||||
"resolved": "https://registry.npmjs.org/ffiasm/-/ffiasm-0.0.2.tgz",
|
||||
"integrity": "sha512-o/CL7F4IodB7eRHCOQL1SrqN2DIPHrQbEwjPY7NIyeBRdnB3G0xo6b6Mj44SKiWFnvpQMb3n4N7acjD3vv4NVQ==",
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ffiasm/-/ffiasm-0.1.1.tgz",
|
||||
"integrity": "sha512-irMMHiR9JJ7BVBrAhtliUawxVdPYSdyl81taUYJ4C1mJ0iw2ueThE/qtr0J8B83tsIY8HJvh0lg5F+6ClK4xpA==",
|
||||
"requires": {
|
||||
"big-integer": "^1.6.48",
|
||||
"ejs": "^3.0.1",
|
||||
@@ -597,11 +581,24 @@
|
||||
}
|
||||
},
|
||||
"ffjavascript": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.1.0.tgz",
|
||||
"integrity": "sha512-dmKlUasSfvUcxBm8nCSKl2x7EFJsXA7OVP8XLFA03T2+6mAc3IiVLC2ambEVOcMOhyhl0vJfVZjM9f9d38D1rw==",
|
||||
"version": "0.2.10",
|
||||
"resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.10.tgz",
|
||||
"integrity": "sha512-GQI6gHYYG5/iD4Kt3VzezzK7fARJzP0zkc82V/+JAdjfeKBXhDSo5rpKFuK3cDcrdW0Fu2emuYNMEAuFqhEQvQ==",
|
||||
"requires": {
|
||||
"big-integer": "^1.6.48"
|
||||
"big-integer": "^1.6.48",
|
||||
"wasmcurves": "0.0.5",
|
||||
"worker-threads": "^1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"wasmcurves": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/wasmcurves/-/wasmcurves-0.0.5.tgz",
|
||||
"integrity": "sha512-BmI4GXLjLawGg2YkvHa8zRsnWec+d1uwoxE+Iov8cqOpDL7GA5XO2pk2yuDbXHMzwIug2exnKot3baRZ86R0pA==",
|
||||
"requires": {
|
||||
"big-integer": "^1.6.42",
|
||||
"blakejs": "^1.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ffwasm": {
|
||||
@@ -631,6 +628,14 @@
|
||||
"flat-cache": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"filelist": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.1.tgz",
|
||||
"integrity": "sha512-8zSK6Nu0DQIC08mUC46sWGXi+q3GGpKydAG36k+JDba6VRpkevvOWUW5a/PhShij4+vHT9M+ghgG7eM+a9JDUQ==",
|
||||
"requires": {
|
||||
"minimatch": "^3.0.4"
|
||||
}
|
||||
},
|
||||
"find-up": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
|
||||
@@ -663,9 +668,9 @@
|
||||
}
|
||||
},
|
||||
"flatted": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz",
|
||||
"integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==",
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
|
||||
"integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==",
|
||||
"dev": true
|
||||
},
|
||||
"fnv-plus": {
|
||||
@@ -728,8 +733,7 @@
|
||||
"has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
|
||||
"dev": true
|
||||
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
@@ -777,36 +781,61 @@
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"inquirer": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz",
|
||||
"integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==",
|
||||
"version": "7.3.3",
|
||||
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz",
|
||||
"integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-escapes": "^4.2.1",
|
||||
"chalk": "^3.0.0",
|
||||
"chalk": "^4.1.0",
|
||||
"cli-cursor": "^3.1.0",
|
||||
"cli-width": "^2.0.0",
|
||||
"cli-width": "^3.0.0",
|
||||
"external-editor": "^3.0.3",
|
||||
"figures": "^3.0.0",
|
||||
"lodash": "^4.17.15",
|
||||
"lodash": "^4.17.19",
|
||||
"mute-stream": "0.0.8",
|
||||
"run-async": "^2.4.0",
|
||||
"rxjs": "^6.5.3",
|
||||
"rxjs": "^6.6.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"through": "^2.3.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
|
||||
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/color-name": "^1.1.1",
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"chalk": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
|
||||
"integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
|
||||
"integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||
@@ -844,18 +873,23 @@
|
||||
"is-extglob": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"is-promise": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
|
||||
"integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
|
||||
"dev": true
|
||||
},
|
||||
"isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
|
||||
"dev": true
|
||||
},
|
||||
"jake": {
|
||||
"version": "10.8.2",
|
||||
"resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz",
|
||||
"integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==",
|
||||
"requires": {
|
||||
"async": "0.9.x",
|
||||
"chalk": "^2.4.2",
|
||||
"filelist": "^1.0.1",
|
||||
"minimatch": "^3.0.4"
|
||||
}
|
||||
},
|
||||
"jison": {
|
||||
"version": "0.4.18",
|
||||
"resolved": "https://registry.npmjs.org/jison/-/jison-0.4.18.tgz",
|
||||
@@ -897,9 +931,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"js-yaml": {
|
||||
"version": "3.13.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
|
||||
"integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
|
||||
"version": "3.14.0",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz",
|
||||
"integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"argparse": "^1.0.7",
|
||||
@@ -953,9 +987,9 @@
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.15",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
|
||||
"version": "4.17.19",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
|
||||
"integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
|
||||
"dev": true
|
||||
},
|
||||
"mimic-fn": {
|
||||
@@ -979,9 +1013,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz",
|
||||
"integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==",
|
||||
"version": "0.5.5",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "^1.2.5"
|
||||
@@ -1030,9 +1064,9 @@
|
||||
}
|
||||
},
|
||||
"onetime": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz",
|
||||
"integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==",
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
|
||||
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"mimic-fn": "^2.1.0"
|
||||
@@ -1059,9 +1093,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"p-limit": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz",
|
||||
"integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
|
||||
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
|
||||
"requires": {
|
||||
"p-try": "^2.0.0"
|
||||
}
|
||||
@@ -1128,12 +1162,29 @@
|
||||
"dev": true
|
||||
},
|
||||
"r1csfile": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/r1csfile/-/r1csfile-0.0.5.tgz",
|
||||
"integrity": "sha512-B+BdKPb/WUTp4N/3X4d1Spgx9Ojx5tFVejGZRJxpTtzq34mC8Vi/czWfiPj85V8kud31lCfYcZ16z7+czvM0Sw==",
|
||||
"version": "0.0.14",
|
||||
"resolved": "https://registry.npmjs.org/r1csfile/-/r1csfile-0.0.14.tgz",
|
||||
"integrity": "sha512-7m4eWpnbjkwGGUaRmIAJc4w+HvaeBPJXUKHIqLkHeD9Yyjem6/EHmlgDVl+4hWNWGZqdhXuMqWSH9+O6QOXBdw==",
|
||||
"requires": {
|
||||
"fastfile": "0.0.1",
|
||||
"ffjavascript": "0.1.0"
|
||||
"fastfile": "0.0.7",
|
||||
"ffjavascript": "0.2.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"fastfile": {
|
||||
"version": "0.0.7",
|
||||
"resolved": "https://registry.npmjs.org/fastfile/-/fastfile-0.0.7.tgz",
|
||||
"integrity": "sha512-Zk7sdqsV6DsN/rhjULDfCCowPiMDsziTMFicdkrKN80yybr/6YFf9H91ELXN85dVEf6EYkVR5EHkZNc0dMqZKA=="
|
||||
},
|
||||
"ffjavascript": {
|
||||
"version": "0.2.4",
|
||||
"resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.4.tgz",
|
||||
"integrity": "sha512-XFeWcjUDFPavN+DDOxhE8p5MOhZQJc9oO1Sj4ml1pyjqNhS1ujEamcjFyK0cctdnat61i7lvpTYzdtS3RYDC8w==",
|
||||
"requires": {
|
||||
"big-integer": "^1.6.48",
|
||||
"wasmcurves": "0.0.4",
|
||||
"worker-threads": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"regexpp": {
|
||||
@@ -1177,18 +1228,15 @@
|
||||
}
|
||||
},
|
||||
"run-async": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.0.tgz",
|
||||
"integrity": "sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-promise": "^2.1.0"
|
||||
}
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
|
||||
"integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==",
|
||||
"dev": true
|
||||
},
|
||||
"rxjs": {
|
||||
"version": "6.5.4",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz",
|
||||
"integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==",
|
||||
"version": "6.6.2",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.2.tgz",
|
||||
"integrity": "sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"tslib": "^1.9.0"
|
||||
@@ -1243,30 +1291,6 @@
|
||||
"is-fullwidth-code-point": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-convert": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
|
||||
"dev": true
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
|
||||
@@ -1310,16 +1334,15 @@
|
||||
}
|
||||
},
|
||||
"strip-json-comments": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz",
|
||||
"integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==",
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
|
||||
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
|
||||
"dev": true
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-flag": "^3.0.0"
|
||||
}
|
||||
@@ -1397,17 +1420,17 @@
|
||||
}
|
||||
},
|
||||
"tmp-promise": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-2.0.2.tgz",
|
||||
"integrity": "sha512-zl71nFWjPKW2KXs+73gEk8RmqvtAeXPxhWDkTUoa3MSMkjq3I+9OeknjF178MQoMYsdqL730hfzvNfEkePxq9Q==",
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-2.1.1.tgz",
|
||||
"integrity": "sha512-Z048AOz/w9b6lCbJUpevIJpRpUztENl8zdv1bmAKVHimfqRFl92ROkmT9rp7TVBnrEw2gtMTol/2Cp2S2kJa4Q==",
|
||||
"requires": {
|
||||
"tmp": "0.1.0"
|
||||
}
|
||||
},
|
||||
"tslib": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz",
|
||||
"integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==",
|
||||
"version": "1.13.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",
|
||||
"integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==",
|
||||
"dev": true
|
||||
},
|
||||
"type-check": {
|
||||
@@ -1446,9 +1469,9 @@
|
||||
}
|
||||
},
|
||||
"v8-compile-cache": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz",
|
||||
"integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==",
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz",
|
||||
"integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==",
|
||||
"dev": true
|
||||
},
|
||||
"wasmbuilder": {
|
||||
@@ -1459,6 +1482,15 @@
|
||||
"big-integer": "^1.6.48"
|
||||
}
|
||||
},
|
||||
"wasmcurves": {
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/wasmcurves/-/wasmcurves-0.0.4.tgz",
|
||||
"integrity": "sha512-c/Tob+F/7jJhep1b2qtj54r4nkGaRifNbQ1OJx8cBBFH1RlHbWIbISHWONClOxiVwy/JZOpbN4SgvSX/4lF80A==",
|
||||
"requires": {
|
||||
"big-integer": "^1.6.42",
|
||||
"blakejs": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"which": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
||||
@@ -1479,6 +1511,11 @@
|
||||
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
|
||||
"dev": true
|
||||
},
|
||||
"worker-threads": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/worker-threads/-/worker-threads-1.0.0.tgz",
|
||||
"integrity": "sha512-vK6Hhvph8oLxocEJIlc3YfGAZhm210uGzjZsXSu+JYLAQ/s/w4Tqgl60JrdH58hW8NSGP4m3bp8a92qPXgX05w=="
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
|
||||
@@ -1487,6 +1524,30 @@
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
|
||||
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
|
||||
"requires": {
|
||||
"@types/color-name": "^1.1.1",
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"wrappy": {
|
||||
@@ -1509,9 +1570,9 @@
|
||||
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w=="
|
||||
},
|
||||
"yargs": {
|
||||
"version": "15.3.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz",
|
||||
"integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==",
|
||||
"version": "15.4.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
|
||||
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
|
||||
"requires": {
|
||||
"cliui": "^6.0.0",
|
||||
"decamelize": "^1.2.0",
|
||||
@@ -1523,13 +1584,13 @@
|
||||
"string-width": "^4.2.0",
|
||||
"which-module": "^2.0.0",
|
||||
"y18n": "^4.0.0",
|
||||
"yargs-parser": "^18.1.1"
|
||||
"yargs-parser": "^18.1.2"
|
||||
}
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "18.1.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.2.tgz",
|
||||
"integrity": "sha512-hlIPNR3IzC1YuL1c2UwwDKpXlNFBqD1Fswwh1khz5+d8Cq/8yc/Mn0i+rQXduu8hcrFKvO7Eryk+09NecTQAAQ==",
|
||||
"version": "18.1.3",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
|
||||
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
|
||||
"requires": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
|
||||
12
package.json
12
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "circom",
|
||||
"version": "0.5.10",
|
||||
"version": "0.5.22",
|
||||
"description": "Language to generate logic circuits",
|
||||
"main": "index.js",
|
||||
"directories": {
|
||||
@@ -30,13 +30,13 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"chai": "^4.2.0",
|
||||
"circom_runtime": "0.0.6",
|
||||
"fastfile": "0.0.1",
|
||||
"ffiasm": "0.0.2",
|
||||
"ffjavascript": "0.1.0",
|
||||
"circom_runtime": "0.1.4",
|
||||
"fastfile": "0.0.12",
|
||||
"ffiasm": "0.1.1",
|
||||
"ffjavascript": "0.2.10",
|
||||
"ffwasm": "0.0.7",
|
||||
"fnv-plus": "^1.3.1",
|
||||
"r1csfile": "0.0.5",
|
||||
"r1csfile": "0.0.14",
|
||||
"tmp-promise": "^2.0.2",
|
||||
"wasmbuilder": "0.0.10"
|
||||
},
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
const streamFromMultiArray = require("../../src/streamfromarray_txt.js");
|
||||
const utils = require("../../src/utils");
|
||||
const assert = require("assert");
|
||||
const Scalar = require("ffjavascript").Scalar;
|
||||
const F1Field = require("ffjavascript").F1Field;
|
||||
const BigArray = require("../../src/bigarray");
|
||||
|
||||
function ref2src(c) {
|
||||
if ((c[0] == "R")||(c[0] == "RI")) {
|
||||
@@ -95,6 +95,10 @@ class CodeBuilderC {
|
||||
this.ops.push({op: "CHECKCONSTRAINT", a, b, strErr});
|
||||
}
|
||||
|
||||
checkAssert(a, strErr) {
|
||||
this.ops.push({op: "CHECKASSERT", a, strErr});
|
||||
}
|
||||
|
||||
log(val) {
|
||||
this.ops.push({op: "LOG", val});
|
||||
}
|
||||
@@ -215,6 +219,8 @@ class CodeBuilderC {
|
||||
code.push(`${o.fnName}(ctx, ${o.retLabel}, ${o.params.join(",")});`);
|
||||
} else if (o.op == "CHECKCONSTRAINT") {
|
||||
code.push(`ctx->checkConstraint(__cIdx, ${ref2src(o.a)}, ${ref2src(o.b)}, "${o.strErr}");`);
|
||||
} else if (o.op == "CHECKASSERT") {
|
||||
code.push(`ctx->checkAssert(__cIdx, ${ref2src(o.a)}, "${o.strErr}");`);
|
||||
} else if (o.op == "LOG") {
|
||||
code.push(`ctx->log(${ref2src(o.val)});`);
|
||||
}
|
||||
@@ -341,16 +347,23 @@ class FunctionBuilderC {
|
||||
}
|
||||
|
||||
class BuilderC {
|
||||
constructor(p) {
|
||||
constructor(p, verbose) {
|
||||
this.F = new F1Field(p);
|
||||
|
||||
this.hashMaps={};
|
||||
this.componentEntriesTables={};
|
||||
this.componentEntriesTables=new BigArray();
|
||||
this.sizes ={};
|
||||
this.constants = [];
|
||||
this.functions = [];
|
||||
this.components = [];
|
||||
this.components = new BigArray();
|
||||
this.usedConstants = {};
|
||||
this.verbose = verbose;
|
||||
|
||||
|
||||
this.sizePointers = {};
|
||||
this.hashMapPointers = {};
|
||||
this.functionIdx = {};
|
||||
this.nCets = 0;
|
||||
}
|
||||
|
||||
setHeader(header) {
|
||||
@@ -362,8 +375,11 @@ class BuilderC {
|
||||
this.hashMaps[name] = hm;
|
||||
}
|
||||
|
||||
addComponentEntriesTable(name, cet) {
|
||||
this.componentEntriesTables[name] = cet;
|
||||
addComponentEntriesTable(name, cet, idComponent) {
|
||||
this.componentEntriesTables[idComponent] = {
|
||||
name: name,
|
||||
cet: cet
|
||||
};
|
||||
}
|
||||
|
||||
addSizes(name, accSizes) {
|
||||
@@ -409,8 +425,8 @@ class BuilderC {
|
||||
|
||||
_buildHeader(code) {
|
||||
code.push(
|
||||
"#include \"circom.h\"",
|
||||
"#include \"calcwit.h\"",
|
||||
"#include \"circom.hpp\"",
|
||||
"#include \"calcwit.hpp\"",
|
||||
`#define NSignals ${this.header.NSignals}`,
|
||||
`#define NComponents ${this.header.NComponents}`,
|
||||
`#define NOutputs ${this.header.NOutputs}`,
|
||||
@@ -421,67 +437,91 @@ class BuilderC {
|
||||
);
|
||||
}
|
||||
|
||||
_buildHashMaps(code) {
|
||||
async _buildHashMaps(fdData) {
|
||||
|
||||
code.push("// Hash Maps ");
|
||||
while (fdData.pos % 8) fdData.pos++;
|
||||
this.pHashMaps = fdData.pos;
|
||||
|
||||
const buff = new Uint8Array(256*12);
|
||||
const buffV = new DataView(buff.buffer);
|
||||
for (let hmName in this.hashMaps ) {
|
||||
|
||||
while (fdData.pos % 8) fdData.pos++;
|
||||
this.hashMapPointers[hmName] = fdData.pos;
|
||||
const hm = this.hashMaps[hmName];
|
||||
|
||||
let c = `Circom_HashEntry ${hmName}[256] = {`;
|
||||
for (let i=0; i<256; i++) {
|
||||
c += i>0 ? "," : "";
|
||||
if (hm[i]) {
|
||||
c += `{0x${hm[i][0]}LL, ${hm[i][1]}} /* ${hm[i][2]} */`;
|
||||
} else {
|
||||
c += "{0,0}";
|
||||
}
|
||||
buffV.setUint32(i*12, hm[i] ? parseInt( hm[i][0].slice(8), 16 ) : 0, true);
|
||||
buffV.setUint32(i*12+4, hm[i] ? parseInt( hm[i][0].slice(0,8), 16 ) : 0, true);
|
||||
buffV.setUint32(i*12+8, hm[i] ? hm[i][1] : 0, true);
|
||||
}
|
||||
c += "};";
|
||||
code.push(c);
|
||||
|
||||
await fdData.write(buff);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_buildComponentEntriesTables(code) {
|
||||
code.push("// Component Entry tables");
|
||||
for (let cetName in this.componentEntriesTables) {
|
||||
const cet = this.componentEntriesTables[cetName];
|
||||
async _buildComponentEntriesTables(fdData) {
|
||||
|
||||
while (fdData.pos % 8) fdData.pos++;
|
||||
this.pCets = fdData.pos;
|
||||
for (let i=0; i< this.componentEntriesTables.length; i++) {
|
||||
if ((this.verbose)&&(i%100000 ==0)) console.log(`_buildComponentEntriesTables ${i}/${this.componentEntriesTables.length}`);
|
||||
const cet = this.componentEntriesTables[i].cet;
|
||||
|
||||
this.components[i].entryTablePointer = fdData.pos;
|
||||
const buff = new Uint8Array(16*cet.length);
|
||||
const buffV = new DataView(buff.buffer);
|
||||
|
||||
code.push(`Circom_ComponentEntry ${cetName}[${cet.length}] = {`);
|
||||
for (let j=0; j<cet.length; j++) {
|
||||
const ty = cet[j].type == "S" ? "_typeSignal" : "_typeComponent";
|
||||
code.push(` ${j>0?",":" "}{${cet[j].offset},${cet[j].sizeName}, ${ty}}`);
|
||||
utils.setUint64(buffV, 16*j+0, this.sizePointers[ cet[j].sizeName]);
|
||||
buffV.setUint32(16*j+8, cet[j].offset, true);
|
||||
buffV.setUint32(16*j+12, cet[j].type == "S" ? 0 : 1, true); // Size type 0-> Signal, 1->Component
|
||||
this.nCets ++;
|
||||
}
|
||||
code.push("};");
|
||||
|
||||
await fdData.write(buff);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
_buildSizes(code) {
|
||||
code.push("// Sizes");
|
||||
async _buildSizes(fdData) {
|
||||
for (let sName in this.sizes) {
|
||||
const accSizes = this.sizes[sName];
|
||||
|
||||
let c = `Circom_Size ${sName}[${accSizes.length}] = {`;
|
||||
while (fdData.pos % 8) fdData.pos++;
|
||||
this.sizePointers[sName] = fdData.pos;
|
||||
|
||||
const buff = new Uint8Array(4*accSizes.length);
|
||||
const buffV = new DataView(buff.buffer);
|
||||
for (let i=0; i<accSizes.length; i++) {
|
||||
if (i>0) c += ",";
|
||||
c += accSizes[i];
|
||||
buffV.setUint32(i*4, accSizes[i], true);
|
||||
}
|
||||
c += "};";
|
||||
code.push(c);
|
||||
await fdData.write(buff);
|
||||
}
|
||||
}
|
||||
|
||||
_buildConstants(code) {
|
||||
|
||||
async _buildConstants(fdData) {
|
||||
const self = this;
|
||||
|
||||
code.push("// Constants");
|
||||
code.push(`FrElement _constants[${self.constants.length}] = {`);
|
||||
for (let i=0; i<self.constants.length; i++) {
|
||||
code.push((i>0 ? "," : " ") + "{" + number2Code(self.constants[i]) + "}");
|
||||
}
|
||||
code.push("};");
|
||||
const frSize = (8 + self.F.n64*8);
|
||||
const buff = new Uint8Array(self.constants.length* frSize);
|
||||
const buffV = new DataView(buff.buffer);
|
||||
|
||||
function number2Code(n) {
|
||||
|
||||
while (fdData.pos % 8) fdData.pos++;
|
||||
this.pConstants = fdData.pos;
|
||||
|
||||
let o = 0;
|
||||
for (let i=0; i<self.constants.length; i++) {
|
||||
Fr2Bytes(buffV, o, self.constants[i]);
|
||||
o += frSize;
|
||||
}
|
||||
await fdData.write(buff);
|
||||
|
||||
|
||||
function Fr2Bytes(buffV, offset, n) {
|
||||
const minShort = self.F.neg(self.F.e("80000000"));
|
||||
const maxShort = self.F.e("7FFFFFFF", 16);
|
||||
|
||||
@@ -489,51 +529,49 @@ class BuilderC {
|
||||
&&(self.F.leq(n, maxShort)))
|
||||
{
|
||||
if (self.F.geq(n, self.F.zero)) {
|
||||
return addShortMontgomeryPositive(n);
|
||||
return shortMontgomeryPositive(n);
|
||||
} else {
|
||||
return addShortMontgomeryNegative(n);
|
||||
return shortMontgomeryNegative(n);
|
||||
}
|
||||
}
|
||||
|
||||
return addLongMontgomery(n);
|
||||
return longMontgomery(n);
|
||||
|
||||
|
||||
function addShortMontgomeryPositive(a) {
|
||||
return `${a.toString()}, 0x40000000, { ${getLongString(toMontgomery(a))} }`;
|
||||
function shortMontgomeryPositive(a) {
|
||||
buffV.setUint32(offset, Scalar.toNumber(a) , true );
|
||||
buffV.setUint32(offset + 4, 0x40000000 , true );
|
||||
long(buffV, offset + 8, toMontgomery(a));
|
||||
}
|
||||
|
||||
|
||||
function addShortMontgomeryNegative(a) {
|
||||
const b = a.minus(self.header.P);
|
||||
return `${b.toString()}, 0x40000000, { ${getLongString(toMontgomery(a))} }`;
|
||||
function shortMontgomeryNegative(a) {
|
||||
const b = -Scalar.toNumber(self.F.neg(a));
|
||||
buffV.setUint32(offset, b , true );
|
||||
buffV.setUint32(offset + 4, 0x40000000 , true );
|
||||
long(buffV, offset + 8, toMontgomery(a));
|
||||
}
|
||||
|
||||
function addLongMontgomery(a) {
|
||||
return `0, 0xC0000000, { ${getLongString(toMontgomery(a))} }`;
|
||||
function longMontgomery(a) {
|
||||
buffV.setUint32(offset, 0 , true );
|
||||
buffV.setUint32(offset + 4, 0xC0000000 , true );
|
||||
long(buffV, offset + 8, toMontgomery(a));
|
||||
}
|
||||
|
||||
function getLongString(a) {
|
||||
let S = "";
|
||||
function long(buffV, offset, a) {
|
||||
|
||||
let p = offset;
|
||||
const arr = Scalar.toArray(a, 0x100000000);
|
||||
for (let i=0; i<self.F.n64*2; i+=2) {
|
||||
const idx = arr.length-2-i;
|
||||
|
||||
if (i>0) S = S + ",";
|
||||
for (let i=0; i<self.F.n64*2; i++) {
|
||||
const idx = arr.length-1-i;
|
||||
|
||||
if ( idx >=0) {
|
||||
let msb = arr[idx].toString(16);
|
||||
while (msb.length<8) msb = "0" + msb;
|
||||
|
||||
let lsb = arr[idx+1].toString(16);
|
||||
while (lsb.length<8) lsb = "0" + lsb;
|
||||
|
||||
S += "0x" + msb + lsb + "LL";
|
||||
buffV.setUint32(p, arr[idx], true);
|
||||
} else {
|
||||
S += "0LL";
|
||||
buffV.setUint32(p, 0, true);
|
||||
}
|
||||
p+= 4;
|
||||
}
|
||||
|
||||
return S;
|
||||
}
|
||||
|
||||
function toMontgomery(a) {
|
||||
@@ -541,98 +579,143 @@ class BuilderC {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_buildFunctions(code) {
|
||||
const listedFunctions = [];
|
||||
for (let i=0; i<this.functions.length; i++) {
|
||||
const cfb = this.functions[i];
|
||||
cfb.build(code);
|
||||
if (this.functions[i].type == "COMPONENT") {
|
||||
this.functionIdx[this.functions[i].name] = listedFunctions.length;
|
||||
listedFunctions.push(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_buildComponents(code) {
|
||||
code.push("// Components");
|
||||
code.push(`Circom_Component _components[${this.components.length}] = {`);
|
||||
for (let i=0; i<this.components.length; i++) {
|
||||
const c = this.components[i];
|
||||
code.push("// Function Table");
|
||||
code.push(`Circom_ComponentFunction _functionTable[${listedFunctions.length}] = {`);
|
||||
for (let i=0; i<listedFunctions.length; i++) {
|
||||
const sep = i>0 ? " ," : " ";
|
||||
code.push(`${sep}{${c.hashMapName}, ${c.entryTableName}, ${c.functionName}, ${c.nInSignals}, ${c.newThread}}`);
|
||||
code.push(`${sep}${this.functions[listedFunctions[i]].name}`);
|
||||
}
|
||||
code.push("};");
|
||||
}
|
||||
|
||||
_buildMapIsInput(code) {
|
||||
code.push("// mapIsInput");
|
||||
code.push(`u32 _mapIsInput[${this.mapIsInput.length}] = {`);
|
||||
let line = "";
|
||||
|
||||
async _buildComponents(fdData) {
|
||||
|
||||
const buff = new Uint8Array(32);
|
||||
const buffV = new DataView(buff.buffer);
|
||||
|
||||
while (fdData.pos % 8) fdData.pos++;
|
||||
this.pComponents = fdData.pos;
|
||||
|
||||
for (let i=0; i<this.components.length; i++) {
|
||||
if ((this.verbose)&&(i%1000000 ==0)) console.log(`_buildComponents ${i}/${this.components.length}`);
|
||||
const c = this.components[i];
|
||||
|
||||
utils.setUint64(buffV, 0, this.hashMapPointers[c.hashMapName], true);
|
||||
utils.setUint64(buffV, 8, c.entryTablePointer, true);
|
||||
utils.setUint64(buffV, 16, this.functionIdx[c.functionName], true);
|
||||
buffV.setUint32(24, c.nInSignals, true);
|
||||
buffV.setUint32(28, c.newThread ? 1 : 0, true);
|
||||
|
||||
await fdData.write(buff);
|
||||
}
|
||||
}
|
||||
|
||||
async _buildMapIsInput(fdData) {
|
||||
|
||||
const buff = new Uint8Array(this.mapIsInput.length * 4);
|
||||
const buffV = new DataView(buff.buffer);
|
||||
|
||||
while (fdData.pos % 8) fdData.pos++;
|
||||
this.pMapIsInput = fdData.pos;
|
||||
|
||||
for (let i=0; i<this.mapIsInput.length; i++) {
|
||||
line += i>0 ? ", " : " ";
|
||||
line += toHex(this.mapIsInput[i]);
|
||||
if (((i+1) % 64)==0) {
|
||||
code.push(" "+line);
|
||||
line = "";
|
||||
}
|
||||
}
|
||||
if (line != "") code.push(" "+line);
|
||||
code.push("};");
|
||||
if ((this.verbose)&&(i%1000000 ==0)) console.log(`_buildMapIsInput ${i}/${this.mapIsInput.length}`);
|
||||
|
||||
function toHex(number) {
|
||||
if (number < 0) number = 0xFFFFFFFF + number + 1;
|
||||
let S=number.toString(16).toUpperCase();
|
||||
while (S.length<8) S = "0" + S;
|
||||
return "0x"+S;
|
||||
buffV.setUint32(4*i, this.mapIsInput[i], true);
|
||||
}
|
||||
|
||||
await fdData.write(buff);
|
||||
}
|
||||
|
||||
_buildWit2Sig(code) {
|
||||
code.push("// Witness to Signal Table");
|
||||
code.push(`int _wit2sig[${this.wit2sig.length}] = {`);
|
||||
let line = "";
|
||||
async _buildWit2Sig(fdData) {
|
||||
|
||||
const buff = new Uint8Array(this.wit2sig.length * 4);
|
||||
const buffV = new DataView(buff.buffer);
|
||||
|
||||
while (fdData.pos % 8) fdData.pos++;
|
||||
this.pWit2Sig = fdData.pos;
|
||||
|
||||
for (let i=0; i<this.wit2sig.length; i++) {
|
||||
line += i>0 ? "," : " ";
|
||||
line += this.wit2sig[i];
|
||||
if (((i+1) % 64) == 0) {
|
||||
code.push(" "+line);
|
||||
line = "";
|
||||
if ((this.verbose)&&(i%1000000 ==0)) console.log(`_buildWit2Sig ${i}/${this.wit2sig.length}`);
|
||||
|
||||
buffV.setUint32(4*i, this.wit2sig[i], true);
|
||||
}
|
||||
|
||||
await fdData.write(buff);
|
||||
}
|
||||
|
||||
async _buildCircuitVar(fdData) {
|
||||
|
||||
const pP = fdData.pos;
|
||||
|
||||
const strBuff = new TextEncoder("utf-8").encode(this.header.P.toString());
|
||||
await fdData.write(strBuff);
|
||||
|
||||
const buff = new Uint8Array(72);
|
||||
const buffV = new DataView(buff.buffer);
|
||||
|
||||
utils.setUint64(buffV, 0, this.pWit2Sig, true);
|
||||
utils.setUint64(buffV, 8, this.pComponents, true);
|
||||
utils.setUint64(buffV, 16, this.pMapIsInput, true);
|
||||
utils.setUint64(buffV, 24, this.pConstants, true);
|
||||
utils.setUint64(buffV, 32, pP, true);
|
||||
utils.setUint64(buffV, 40, this.pCets, true);
|
||||
|
||||
buffV.setUint32(48, this.header.NSignals, true);
|
||||
buffV.setUint32(52, this.header.NComponents, true);
|
||||
buffV.setUint32(56, this.header.NOutputs, true);
|
||||
buffV.setUint32(60, this.header.NInputs, true);
|
||||
buffV.setUint32(64, this.header.NVars, true);
|
||||
buffV.setUint32(68, this.nCets, true);
|
||||
|
||||
fdData.pos = 0;
|
||||
|
||||
await fdData.write(buff);
|
||||
}
|
||||
|
||||
|
||||
async build(fdCode, fdData) {
|
||||
const encoder = new TextEncoder("utf-8");
|
||||
fdData.pos = 72;
|
||||
while (fdData.pos % 8) fdData.pos++;
|
||||
|
||||
const code=new BigArray();
|
||||
this._buildHeader(code);
|
||||
await this._buildSizes(fdData);
|
||||
await this._buildConstants(fdData);
|
||||
await this._buildHashMaps(fdData);
|
||||
await this._buildComponentEntriesTables(fdData);
|
||||
this._buildFunctions(code);
|
||||
await this._buildComponents(fdData);
|
||||
await this._buildMapIsInput(fdData);
|
||||
await this._buildWit2Sig(fdData);
|
||||
await this._buildCircuitVar(fdData);
|
||||
await writeCode(code);
|
||||
|
||||
async function writeCode(c) {
|
||||
if (c.push) {
|
||||
for (let i=0; i<c.length; i++) {
|
||||
await writeCode(c[i]);
|
||||
}
|
||||
} else if (typeof c === "string") {
|
||||
await fdCode.write(encoder.encode(c + "\n"));
|
||||
}
|
||||
}
|
||||
if (line != "") code.push(" "+line);
|
||||
code.push("};");
|
||||
}
|
||||
|
||||
_buildCircuitVar(code) {
|
||||
|
||||
code.push(
|
||||
"// Circuit Variable",
|
||||
"Circom_Circuit _circuit = {" ,
|
||||
" NSignals,",
|
||||
" NComponents,",
|
||||
" NInputs,",
|
||||
" NOutputs,",
|
||||
" NVars,",
|
||||
" _wit2sig,",
|
||||
" _components,",
|
||||
" _mapIsInput,",
|
||||
" _constants,",
|
||||
" __P__",
|
||||
"};"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
build() {
|
||||
const code=[];
|
||||
this._buildHeader(code);
|
||||
this._buildSizes(code);
|
||||
this._buildConstants(code);
|
||||
this._buildHashMaps(code);
|
||||
this._buildComponentEntriesTables(code);
|
||||
this._buildFunctions(code);
|
||||
this._buildComponents(code);
|
||||
this._buildMapIsInput(code);
|
||||
this._buildWit2Sig(code);
|
||||
this._buildCircuitVar(code);
|
||||
return streamFromMultiArray(code);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ const utils = require("../../src/utils");
|
||||
const loadR1cs = require("r1csfile").load;
|
||||
const ZqField = require("ffjavascript").ZqField;
|
||||
const buildZqField = require("ffiasm").buildZqField;
|
||||
const fastFile = require("fastfile");
|
||||
|
||||
const {stringifyBigInts, unstringifyBigInts } = require("ffjavascript").utils;
|
||||
|
||||
@@ -29,20 +30,24 @@ async function c_tester(circomFile, _options) {
|
||||
const baseName = path.basename(circomFile, ".circom");
|
||||
const options = Object.assign({}, _options);
|
||||
|
||||
options.cSourceWriteStream = fs.createWriteStream(path.join(dir.path, baseName + ".cpp"));
|
||||
options.cSourceFile = await fastFile.createOverride(path.join(dir.path, baseName + ".cpp"));
|
||||
options.dataFile = await fastFile.createOverride(path.join(dir.path, baseName + ".dat"));
|
||||
options.symWriteStream = fs.createWriteStream(path.join(dir.path, baseName + ".sym"));
|
||||
options.r1csFileName = path.join(dir.path, baseName + ".r1cs");
|
||||
|
||||
options.p = options.p || Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||
await compiler(circomFile, options);
|
||||
|
||||
await options.cSourceFile.close();
|
||||
await options.dataFile.close();
|
||||
|
||||
const source = await buildZqField(options.p, "Fr");
|
||||
|
||||
// console.log(dir.path);
|
||||
|
||||
await fs.promises.writeFile(path.join(dir.path, "fr.asm"), source.asm, "utf8");
|
||||
await fs.promises.writeFile(path.join(dir.path, "fr.h"), source.h, "utf8");
|
||||
await fs.promises.writeFile(path.join(dir.path, "fr.c"), source.c, "utf8");
|
||||
await fs.promises.writeFile(path.join(dir.path, "fr.hpp"), source.hpp, "utf8");
|
||||
await fs.promises.writeFile(path.join(dir.path, "fr.cpp"), source.cpp, "utf8");
|
||||
|
||||
let pThread = "";
|
||||
|
||||
@@ -63,7 +68,7 @@ async function c_tester(circomFile, _options) {
|
||||
` ${path.join(cdir, "main.cpp")}` +
|
||||
` ${path.join(cdir, "calcwit.cpp")}` +
|
||||
` ${path.join(cdir, "utils.cpp")}` +
|
||||
` ${path.join(dir.path, "fr.c")}` +
|
||||
` ${path.join(dir.path, "fr.cpp")}` +
|
||||
` ${path.join(dir.path, "fr.o")}` +
|
||||
` ${path.join(dir.path, baseName + ".cpp")} ` +
|
||||
` -o ${path.join(dir.path, baseName)}` +
|
||||
|
||||
@@ -384,9 +384,9 @@ module.exports = function buildRuntime(module, builder) {
|
||||
"error",
|
||||
c.i32_const(errs.ACCESSING_NOT_ASSIGNED_SIGNAL.code),
|
||||
c.i32_const(errs.ACCESSING_NOT_ASSIGNED_SIGNAL.pointer),
|
||||
c.i32_const(0),
|
||||
c.i32_const(0),
|
||||
c.i32_const(0),
|
||||
c.getLocal("cIdx"),
|
||||
c.getLocal("component"),
|
||||
c.getLocal("signal"),
|
||||
c.i32_const(0)
|
||||
)
|
||||
)
|
||||
@@ -619,6 +619,35 @@ module.exports = function buildRuntime(module, builder) {
|
||||
));
|
||||
}
|
||||
|
||||
function buildCheckAssert() {
|
||||
const f = module.addFunction("checkAssert");
|
||||
f.addParam("cIdx", "i32");
|
||||
f.addParam("pA", "i32");
|
||||
f.addParam("pStr", "i32");
|
||||
|
||||
const c = f.getCodeBuilder();
|
||||
|
||||
f.addCode(ifSanityCheck(c,
|
||||
c.if (
|
||||
c.i32_eqz(
|
||||
c.call(
|
||||
"Fr_isTrue",
|
||||
c.getLocal("pA"),
|
||||
)
|
||||
),
|
||||
c.call(
|
||||
"error",
|
||||
c.i32_const(errs.ASSERT_DOES_NOT_MATCH.code),
|
||||
c.i32_const(errs.ASSERT_DOES_NOT_MATCH.pointer),
|
||||
c.getLocal("cIdx"),
|
||||
c.getLocal("pA"),
|
||||
c.getLocal("pStr"),
|
||||
c.i32_const(0)
|
||||
)
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
function buildGetNVars() {
|
||||
const f = module.addFunction("getNVars");
|
||||
f.setReturnType("i32");
|
||||
@@ -728,12 +757,9 @@ module.exports = function buildRuntime(module, builder) {
|
||||
|
||||
c.setLocal(
|
||||
"pSrc",
|
||||
c.i32_add(
|
||||
c.i32_const(builder.pSignals),
|
||||
c.i32_mul(
|
||||
c.getLocal("i"),
|
||||
c.i32_const(builder.sizeFr)
|
||||
)
|
||||
c.call(
|
||||
"getPWitness",
|
||||
c.getLocal("i"),
|
||||
)
|
||||
),
|
||||
|
||||
@@ -745,7 +771,7 @@ module.exports = function buildRuntime(module, builder) {
|
||||
c.setLocal(
|
||||
"pDst",
|
||||
c.i32_add(
|
||||
c.i32_const(builder.pSignals),
|
||||
c.i32_const(builder.pOutput),
|
||||
c.i32_mul(
|
||||
c.getLocal("i"),
|
||||
c.i32_const(builder.sizeFr-8)
|
||||
@@ -770,7 +796,7 @@ module.exports = function buildRuntime(module, builder) {
|
||||
c.br(0)
|
||||
)),
|
||||
|
||||
c.i32_const(builder.pSignals)
|
||||
c.i32_const(builder.pOutput)
|
||||
);
|
||||
|
||||
}
|
||||
@@ -804,6 +830,7 @@ module.exports = function buildRuntime(module, builder) {
|
||||
buildWasmFf(module, "Fr", builder.header.P);
|
||||
|
||||
builder.pSignals=module.alloc(builder.header.NSignals*builder.sizeFr);
|
||||
builder.pOutput=module.alloc(builder.header.NVars*(builder.sizeFr-8));
|
||||
builder.pInputSignalsToTrigger=module.alloc(builder.header.NComponents*4);
|
||||
builder.pSignalsAssigned=module.alloc(builder.header.NSignals*4);
|
||||
|
||||
@@ -825,6 +852,7 @@ module.exports = function buildRuntime(module, builder) {
|
||||
buildComponentFinished();
|
||||
|
||||
buildCheckConstraint();
|
||||
buildCheckAssert();
|
||||
|
||||
buildGetNVars();
|
||||
buildGetFrLen();
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
const streamFromArrayTxt = require("../../src/streamfromarray_txt");
|
||||
const streamFromArrayBin = require("../../src/streamfromarray_bin");
|
||||
const assert = require("assert");
|
||||
const ModuleBuilder = require("wasmbuilder").ModuleBuilder;
|
||||
const ModuleBuilderWat = require("wasmbuilder").ModuleBuilderWat;
|
||||
@@ -100,6 +98,9 @@ class CodeBuilderWasm {
|
||||
this.ops.push({op: "CHECKCONSTRAINT", a, b, strErr});
|
||||
}
|
||||
|
||||
checkAssert(a, strErr) {
|
||||
this.ops.push({op: "CHECKASSERT", a, strErr});
|
||||
}
|
||||
|
||||
concat(cb) {
|
||||
this.ops.push(...cb.ops);
|
||||
@@ -334,6 +335,15 @@ class CodeBuilderWasm {
|
||||
c.i32_const(this.fnBuilder.builder.module.allocString(o.strErr))
|
||||
)
|
||||
);
|
||||
} else if (o.op == "CHECKASSERT") {
|
||||
code.push(
|
||||
c.call(
|
||||
"checkAssert",
|
||||
c.getLocal("cIdx"),
|
||||
this.fnBuilder._deRefFr(c, o.a),
|
||||
c.i32_const(this.fnBuilder.builder.module.allocString(o.strErr))
|
||||
)
|
||||
);
|
||||
} else if (o.op == "LOG") {
|
||||
code.push(
|
||||
c.call(
|
||||
@@ -990,7 +1000,8 @@ class BuilderWasm {
|
||||
}
|
||||
|
||||
|
||||
build(outType) {
|
||||
async build(fd, outType) {
|
||||
const encoder = new TextEncoder("utf-8");
|
||||
let module;
|
||||
if (outType == "wasm") {
|
||||
module=new ModuleBuilder();
|
||||
@@ -1017,12 +1028,25 @@ class BuilderWasm {
|
||||
|
||||
module.setMemory(2000);
|
||||
if (outType == "wasm") {
|
||||
return streamFromArrayBin(module.build());
|
||||
const bytes = module.build();
|
||||
const bytesArr = new Uint8Array(bytes);
|
||||
await fd.write(bytesArr);
|
||||
} else if (outType == "wat") {
|
||||
return streamFromArrayTxt(module.build());
|
||||
const code = module.build();
|
||||
await writeCode(code);
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
async function writeCode(c) {
|
||||
if (c.push) {
|
||||
for (let i=0; i<c.length; i++) {
|
||||
await writeCode(c[i]);
|
||||
}
|
||||
} else if (typeof c === "string") {
|
||||
await fd.write(encoder.encode(c + "\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,4 +7,5 @@ module.exports = {
|
||||
SIGNAL_ASSIGNED_TWICE: {code: 6, str: "Signal assigned twice"},
|
||||
CONSTRAIN_DOES_NOT_MATCH: {code: 7, str: "Constraint doesn't match"},
|
||||
MAPISINPUT_DONT_MATCH: {code: 8, str: "MapIsInput don't match"},
|
||||
ASSERT_DOES_NOT_MATCH: {code: 9, str: "Assert not satisfied"},
|
||||
};
|
||||
|
||||
@@ -9,6 +9,7 @@ const compiler = require("../../src/compiler");
|
||||
const utils = require("../../src/utils");
|
||||
const loadR1cs = require("r1csfile").load;
|
||||
const ZqField = require("ffjavascript").ZqField;
|
||||
const fastFile = require("fastfile");
|
||||
|
||||
const WitnessCalculatorBuilder = require("circom_runtime").WitnessCalculatorBuilder;
|
||||
|
||||
@@ -24,16 +25,14 @@ async function wasm_tester(circomFile, _options) {
|
||||
const baseName = path.basename(circomFile, ".circom");
|
||||
const options = Object.assign({}, _options);
|
||||
|
||||
options.wasmWriteStream = fs.createWriteStream(path.join(dir.path, baseName + ".wasm"));
|
||||
options.wasmFile = await fastFile.createOverride(path.join(dir.path, baseName + ".wasm"));
|
||||
|
||||
options.symWriteStream = fs.createWriteStream(path.join(dir.path, baseName + ".sym"));
|
||||
options.r1csFileName = path.join(dir.path, baseName + ".r1cs");
|
||||
|
||||
const promisesArr = [];
|
||||
promisesArr.push(new Promise(fulfill => options.wasmWriteStream.on("finish", fulfill)));
|
||||
|
||||
await compiler(circomFile, options);
|
||||
|
||||
await Promise.all(promisesArr);
|
||||
await options.wasmFile.close();
|
||||
|
||||
const wasm = await fs.promises.readFile(path.join(dir.path, baseName + ".wasm"));
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const SUBARRAY_SIZE = 0x10000;
|
||||
const SUBARRAY_SIZE = 0x40000;
|
||||
|
||||
const BigArrayHandler = {
|
||||
get: function(obj, prop) {
|
||||
@@ -19,15 +19,17 @@ const BigArrayHandler = {
|
||||
class _BigArray {
|
||||
constructor (initSize) {
|
||||
this.length = initSize || 0;
|
||||
this.arr = [];
|
||||
this.arr = new Array(SUBARRAY_SIZE);
|
||||
|
||||
for (let i=0; i<initSize; i+=SUBARRAY_SIZE) {
|
||||
this.arr[i/SUBARRAY_SIZE] = new Array(Math.min(SUBARRAY_SIZE, initSize - i));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
push (element) {
|
||||
this.setElement (this.length, element);
|
||||
push () {
|
||||
for (let i=0; i<arguments.length; i++) {
|
||||
this.setElement (this.length, arguments[i]);
|
||||
}
|
||||
}
|
||||
getElement(idx) {
|
||||
idx = parseInt(idx);
|
||||
@@ -39,13 +41,26 @@ class _BigArray {
|
||||
idx = parseInt(idx);
|
||||
const idx1 = Math.floor(idx / SUBARRAY_SIZE);
|
||||
if (!this.arr[idx1]) {
|
||||
this.arr[idx1] = [];
|
||||
this.arr[idx1] = new Array(SUBARRAY_SIZE);
|
||||
}
|
||||
const idx2 = idx % SUBARRAY_SIZE;
|
||||
this.arr[idx1][idx2] = value;
|
||||
if (idx >= this.length) this.length = idx+1;
|
||||
return true;
|
||||
}
|
||||
getKeys() {
|
||||
const newA = new BigArray();
|
||||
for (let i=0; i<this.arr.length; i++) {
|
||||
if (this.arr[i]) {
|
||||
for (let j=0; j<this.arr[i].length; j++) {
|
||||
if (typeof this.arr[i][j] !== "undefined") {
|
||||
newA.push(i*SUBARRAY_SIZE+j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return newA;
|
||||
}
|
||||
}
|
||||
|
||||
class BigArray {
|
||||
|
||||
42
src/build.js
42
src/build.js
@@ -21,6 +21,7 @@ const assert = require("assert");
|
||||
const utils = require("./utils");
|
||||
const gen = require("./gencode").gen;
|
||||
const createRefs = require("./gencode").createRefs;
|
||||
const BigArray = require("./bigarray");
|
||||
|
||||
module.exports = build;
|
||||
|
||||
@@ -37,28 +38,33 @@ function build(ctx) {
|
||||
ctx.addConstant(ctx.F.zero);
|
||||
ctx.addConstant(ctx.F.one);
|
||||
|
||||
if (ctx.verbose) console.log("buildHeader...");
|
||||
buildHeader(ctx);
|
||||
if (ctx.verbose) console.log("buildEntryTables...");
|
||||
buildEntryTables(ctx);
|
||||
ctx.globalNames = ctx.uniqueNames;
|
||||
|
||||
if (ctx.verbose) console.log("buildCode...");
|
||||
buildCode(ctx);
|
||||
|
||||
if (ctx.verbose) console.log("buildComponentsArray...");
|
||||
buildComponentsArray(ctx);
|
||||
|
||||
if (ctx.verbose) console.log("buildMapIsInput...");
|
||||
buildMapIsInput(ctx);
|
||||
|
||||
if (ctx.verbose) console.log("buildWit2Sig...");
|
||||
buildWit2Sig(ctx);
|
||||
|
||||
}
|
||||
|
||||
function buildEntryTables(ctx) {
|
||||
|
||||
const codes_hashMaps = [];
|
||||
const codes_componentEntries = [];
|
||||
const definedHashMaps = {};
|
||||
for (let i=0; i<ctx.components.length; i++) {
|
||||
if (ctx.verbose && (i%100000 ==0)) console.log(`buildEntryTables component: ${i}/${ctx.components.length}`);
|
||||
const {htName, htMap} = addHashTable(i);
|
||||
|
||||
let code = "";
|
||||
const componentEntriesTableName = ctx.getUniqueName("_entryTable" + ctx.components[i].template);
|
||||
|
||||
const componentEntriesTable = [];
|
||||
@@ -72,34 +78,14 @@ function buildEntryTables(ctx) {
|
||||
});
|
||||
}
|
||||
|
||||
ctx.builder.addComponentEntriesTable(componentEntriesTableName, componentEntriesTable);
|
||||
|
||||
|
||||
code += `Circom_ComponentEntry ${componentEntriesTableName}[${htMap.length}] = {\n`;
|
||||
for (let j=0; j<htMap.length; j++) {
|
||||
const entry = ctx.components[i].names.o[htMap[j]];
|
||||
code += j>0 ? " ," : " ";
|
||||
const sizeName = ctx.addSizes(entry.sizes);
|
||||
|
||||
const ty = entry.type == "S" ? "_typeSignal" : "_typeComponent";
|
||||
code += `{${entry.offset},${sizeName}, ${ty}}\n`;
|
||||
}
|
||||
code += "};\n";
|
||||
codes_componentEntries.push(code);
|
||||
ctx.builder.addComponentEntriesTable(componentEntriesTableName, componentEntriesTable, i);
|
||||
|
||||
ctx.components[i].htName = htName;
|
||||
ctx.components[i].etName = componentEntriesTableName;
|
||||
}
|
||||
|
||||
|
||||
return [
|
||||
"// HashMaps\n" ,
|
||||
codes_hashMaps , "\n" ,
|
||||
"\n" ,
|
||||
"// Component Entries\n" ,
|
||||
codes_componentEntries , "\n" ,
|
||||
"\n"
|
||||
];
|
||||
return;
|
||||
|
||||
function addHashTable(cIdx) {
|
||||
const keys = Object.keys(ctx.components[cIdx].names.o);
|
||||
@@ -131,6 +117,7 @@ function buildCode(ctx) {
|
||||
|
||||
const fnComponents = [];
|
||||
for (let i=0; i<ctx.components.length; i++) {
|
||||
if (ctx.verbose && (i%100000 ==0)) console.log(`buildCode component: ${i}/${ctx.components.length}`);
|
||||
const {h, instanceDef} = hashComponentCall(ctx, i);
|
||||
const fName = ctx.components[i].template+"_"+h;
|
||||
if (!fDefined[fName]) {
|
||||
@@ -180,6 +167,7 @@ function buildCode(ctx) {
|
||||
|
||||
function buildComponentsArray(ctx) {
|
||||
for (let i=0; i< ctx.components.length; i++) {
|
||||
if (ctx.verbose && (i%1000000 ==0)) console.log(`buildComponentsArray component: ${i}/${ctx.components.length}`);
|
||||
let newThread;
|
||||
if (ctx.newThreadTemplates) {
|
||||
if (ctx.newThreadTemplates.test(ctx.components[i].template)) {
|
||||
@@ -217,6 +205,7 @@ function buildMapIsInput(ctx) {
|
||||
let map = [];
|
||||
let acc = 0;
|
||||
for (i=0; i<ctx.signals.length; i++) {
|
||||
if (ctx.verbose && (i%1000000 ==0)) console.log(`buildMapIsInput signal: ${i}/${ctx.signals.length}`);
|
||||
if (ctx.signals[i].o & ctx.IN) {
|
||||
acc = acc | (1 << (i%32) );
|
||||
}
|
||||
@@ -241,8 +230,9 @@ function buildWit2Sig(ctx) {
|
||||
ctx.totals[ctx.stPUBINPUT] +
|
||||
ctx.totals[ctx.stPRVINPUT] +
|
||||
ctx.totals[ctx.stINTERNAL];
|
||||
const arr = Array(NVars);
|
||||
const arr = new BigArray(NVars);
|
||||
for (let i=0; i<ctx.signals.length; i++) {
|
||||
if (ctx.verbose && (i%1000000 ==0)) console.log(`buildWit2Sig signal: ${i}/${ctx.signals.length}`);
|
||||
const outIdx = ctx.signals[i].id;
|
||||
if (ctx.signals[i].e>=0) continue; // If has an alias, continue..
|
||||
assert(typeof outIdx != "undefined", `Signal ${i} does not have index`);
|
||||
|
||||
339
src/compiler.js
339
src/compiler.js
@@ -28,25 +28,50 @@ const utils = require("./utils");
|
||||
const buildR1cs = require("./r1csfile").buildR1cs;
|
||||
const BigArray = require("./bigarray");
|
||||
const buildSyms = require("./buildsyms");
|
||||
const {performance} = require("perf_hooks");
|
||||
|
||||
module.exports = compile;
|
||||
const measures = {};
|
||||
|
||||
function ms2String(v) {
|
||||
v = Math.floor(v);
|
||||
const ms = v % 1000;
|
||||
v = Math.floor(v/1000);
|
||||
const secs = v % 60;
|
||||
v = Math.floor(v/60);
|
||||
const mins = v % 60;
|
||||
v = Math.floor(v/60);
|
||||
const hours = v % 24;
|
||||
const days = Math.floor(v/24);
|
||||
let S = "";
|
||||
if (days) S = S + days + "D ";
|
||||
if ((S!="")||(hours)) S = S + hours.toString().padStart(2, "0") + ":";
|
||||
if ((S!="")||(mins)) S = S + mins.toString().padStart(2, "0") + ":";
|
||||
if ((S!="")||(secs)) S = S + secs.toString().padStart(2, "0");
|
||||
S+=".";
|
||||
S = S + ms.toString().padStart(3, "0");
|
||||
return S;
|
||||
}
|
||||
|
||||
async function compile(srcFile, options) {
|
||||
options.p = options.p || Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||
options.prime = options.prime || Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||
if (!options) {
|
||||
options = {};
|
||||
}
|
||||
if (typeof options.reduceConstraints === "undefined") {
|
||||
options.reduceConstraints = true;
|
||||
}
|
||||
const ctx = new Ctx(options.p);
|
||||
const ctx = new Ctx(options.prime);
|
||||
ctx.verbose= options.verbose || false;
|
||||
ctx.mainComponent = options.mainComponent || "main";
|
||||
ctx.newThreadTemplates = options.newThreadTemplates;
|
||||
|
||||
measures.constructionPhase = -performance.now();
|
||||
constructionPhase(ctx, srcFile);
|
||||
measures.constructionPhase += performance.now();
|
||||
|
||||
if (ctx.verbose) console.log("NConstraints Before: "+ctx.constraints.length);
|
||||
if (ctx.verbose) console.log("NSignals Before: "+ctx.signals.length);
|
||||
|
||||
if (ctx.error) {
|
||||
throw(ctx.error);
|
||||
@@ -57,70 +82,97 @@ async function compile(srcFile, options) {
|
||||
}
|
||||
|
||||
if (ctx.verbose) console.log("Classify Signals");
|
||||
measures.classifySignals = -performance.now();
|
||||
classifySignals(ctx);
|
||||
measures.classifySignals += performance.now();
|
||||
|
||||
if (ctx.verbose) console.log("Reduce Constants");
|
||||
measures.reduceConstants = -performance.now();
|
||||
reduceConstants(ctx);
|
||||
measures.reduceConstants += performance.now();
|
||||
|
||||
if (options.reduceConstraints) {
|
||||
|
||||
if (ctx.verbose) console.log("Reduce Constraints");
|
||||
// Repeat while reductions are performed
|
||||
/*
|
||||
let oldNConstrains = -1;
|
||||
while (ctx.constraints.length != oldNConstrains) {
|
||||
if (ctx.verbose) console.log("Reducing constraints: "+ctx.constraints.length);
|
||||
oldNConstrains = ctx.constraints.length;
|
||||
reduceConstrains(ctx);
|
||||
}
|
||||
*/
|
||||
measures.reduceConstraints = -performance.now();
|
||||
await reduceConstrains(ctx);
|
||||
measures.reduceConstraints += performance.now();
|
||||
|
||||
}
|
||||
|
||||
if (ctx.verbose) console.log("NConstraints After: "+ctx.constraints.length);
|
||||
|
||||
measures.generateWitnessNames = -performance.now();
|
||||
generateWitnessNames(ctx);
|
||||
measures.generateWitnessNames += performance.now();
|
||||
|
||||
if (ctx.error) {
|
||||
throw(ctx.error);
|
||||
}
|
||||
|
||||
if (options.cSourceWriteStream) {
|
||||
ctx.builder = new BuilderC(options.p);
|
||||
build(ctx);
|
||||
const rdStream = ctx.builder.build();
|
||||
rdStream.pipe(options.cSourceWriteStream);
|
||||
|
||||
// await new Promise(fulfill => options.cSourceWriteStream.on("finish", fulfill));
|
||||
if (options.r1csFileName) {
|
||||
measures.generateR1cs = -performance.now();
|
||||
await buildR1cs(ctx, options.r1csFileName);
|
||||
measures.generateR1cs += performance.now();
|
||||
}
|
||||
|
||||
if ((options.wasmWriteStream)||(options.watWriteStream)) {
|
||||
ctx.builder = new BuilderWasm(options.p);
|
||||
build(ctx);
|
||||
if (options.wasmWriteStream) {
|
||||
const rdStream = ctx.builder.build("wasm");
|
||||
rdStream.pipe(options.wasmWriteStream);
|
||||
}
|
||||
if (options.watWriteStream) {
|
||||
const rdStream = ctx.builder.build("wat");
|
||||
rdStream.pipe(options.watWriteStream);
|
||||
}
|
||||
if (ctx.error) throw(ctx.error);
|
||||
|
||||
// await new Promise(fulfill => options.wasmWriteStream.on("finish", fulfill));
|
||||
delete ctx.constraints; // Liberate memory.
|
||||
|
||||
if (options.cSourceFile) {
|
||||
if (ctx.verbose) console.log("Generating c...");
|
||||
measures.generateC = -performance.now();
|
||||
ctx.builder = new BuilderC(options.prime, ctx.verbose);
|
||||
build(ctx);
|
||||
await ctx.builder.build(options.cSourceFile, options.dataFile);
|
||||
measures.generateC += performance.now();
|
||||
}
|
||||
|
||||
if (ctx.error) throw(ctx.error);
|
||||
|
||||
if ((options.wasmFile)||(options.watFile)) {
|
||||
if (ctx.verbose) console.log("Generating wasm...");
|
||||
measures.generateWasm = -performance.now();
|
||||
ctx.builder = new BuilderWasm(options.prime);
|
||||
build(ctx);
|
||||
if (options.wasmFile) {
|
||||
await ctx.builder.build(options.wasmFile, "wasm");
|
||||
}
|
||||
if (options.watFile) {
|
||||
await ctx.builder.build(options.watFile, "wat");
|
||||
}
|
||||
measures.generateWasm += performance.now();
|
||||
}
|
||||
|
||||
// const mainCode = gen(ctx,ast);
|
||||
if (ctx.error) throw(ctx.error);
|
||||
|
||||
if (options.r1csFileName) {
|
||||
await buildR1cs(ctx, options.r1csFileName);
|
||||
}
|
||||
|
||||
if (options.symWriteStream) {
|
||||
measures.generateSyms = -performance.now();
|
||||
const rdStream = buildSyms(ctx);
|
||||
rdStream.pipe(options.symWriteStream);
|
||||
measures.generateSyms += performance.now();
|
||||
|
||||
// await new Promise(fulfill => options.symWriteStream.on("finish", fulfill));
|
||||
await new Promise(fulfill => options.symWriteStream.on("finish", fulfill));
|
||||
}
|
||||
|
||||
// const def = buildCircuitDef(ctx, mainCode);
|
||||
|
||||
if (ctx.verbose) {
|
||||
for (let [mStr, mValue] of Object.entries(measures)) {
|
||||
console.log(mStr + ": " + ms2String(mValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -146,6 +198,7 @@ function classifySignals(ctx) {
|
||||
|
||||
// First classify the signals
|
||||
for (let s=0; s<ctx.signals.length; s++) {
|
||||
if ((ctx.verbose)&&(s%100000 == 0)) console.log(`classify signals: ${s}/${ctx.signals.length}`);
|
||||
const signal = ctx.signals[s];
|
||||
let tAll = ctx.stINTERNAL;
|
||||
let lSignal = signal;
|
||||
@@ -249,7 +302,239 @@ function reduceConstants(ctx) {
|
||||
ctx.constraints = newConstraints;
|
||||
}
|
||||
|
||||
function reduceConstrains(ctx) {
|
||||
async function reduceConstrains(ctx) {
|
||||
const sig2constraint = new BigArray();
|
||||
let removedSignals = new BigArray();
|
||||
let nRemoved;
|
||||
let lIdx;
|
||||
|
||||
|
||||
let possibleConstraints = new BigArray(ctx.constraints.length);
|
||||
let nextPossibleConstraints;
|
||||
for (let i=0; i<ctx.constraints.length; i++) {
|
||||
if ((ctx.verbose)&&(i%100000 == 0)) console.log(`indexing constraints: ${i}/${ctx.constraints.length}`);
|
||||
|
||||
const insertedSig = { 0: true}; // Do not insert one.
|
||||
const c = ctx.constraints[i];
|
||||
for (let s in c.a.coefs) {
|
||||
if (!insertedSig[s]) {
|
||||
if (!sig2constraint[s]) sig2constraint[s] = [];
|
||||
sig2constraint[s].push(i);
|
||||
insertedSig[s] = true;
|
||||
}
|
||||
}
|
||||
for (let s in c.b.coefs) {
|
||||
if (!insertedSig[s]) {
|
||||
if (!sig2constraint[s]) sig2constraint[s] = [];
|
||||
sig2constraint[s].push(i);
|
||||
insertedSig[s] = true;
|
||||
}
|
||||
}
|
||||
for (let s in c.c.coefs) {
|
||||
if (!insertedSig[s]) {
|
||||
if (!sig2constraint[s]) sig2constraint[s] = [];
|
||||
sig2constraint[s].push(i);
|
||||
insertedSig[s] = true;
|
||||
}
|
||||
}
|
||||
possibleConstraints[i] = i;
|
||||
}
|
||||
|
||||
while (possibleConstraints.length >0) {
|
||||
nextPossibleConstraints = new BigArray();
|
||||
removedSignals = new BigArray();
|
||||
nRemoved = 0;
|
||||
lIdx = new BigArray();
|
||||
for (let i=0;i<possibleConstraints.length;i++) {
|
||||
if ((ctx.verbose)&&(i%10000 == 0)) {
|
||||
await Promise.resolve();
|
||||
console.log(`reducing constraints: ${i}/${possibleConstraints.length} reduced: ${nRemoved}`);
|
||||
}
|
||||
const c = ctx.constraints[possibleConstraints[i]];
|
||||
if (!c) continue;
|
||||
|
||||
// Swap a and b if b has more variables.
|
||||
if (Object.keys(c.b).length > Object.keys(c.a).length) {
|
||||
const aux = c.a;
|
||||
c.a=c.b;
|
||||
c.b=aux;
|
||||
}
|
||||
|
||||
// Mov to C if possible.
|
||||
if (isConstant(c.a)) {
|
||||
const ct = {t: "N", v: c.a.coefs[sONE]};
|
||||
c.c = ctx.lc.add(ctx.lc.mul(c.b, ct), c.c);
|
||||
c.a = { t: "LC", coefs: {} };
|
||||
c.b = { t: "LC", coefs: {} };
|
||||
}
|
||||
if (isConstant(c.b)) {
|
||||
const ct = {t: "N", v: c.b.coefs[sONE]};
|
||||
c.c = ctx.lc.add(ctx.lc.mul(c.a, ct), c.c);
|
||||
c.a = { t: "LC", coefs: {} };
|
||||
c.b = { t: "LC", coefs: {} };
|
||||
}
|
||||
|
||||
if (ctx.lc.isZero(c.a) || ctx.lc.isZero(c.b)) {
|
||||
const freeC = substituteRemoved(c.c);
|
||||
const isolatedSignal = getFirstInternalSignal(ctx, freeC);
|
||||
if (isolatedSignal) {
|
||||
// console.log(isolatedSignal);
|
||||
// console.log(freeC);
|
||||
removedSignals[isolatedSignal] = isolateSignal(freeC, isolatedSignal);
|
||||
if (lIdx[isolatedSignal]) {
|
||||
lIdx[isolatedSignal].forEach( (s) => {
|
||||
removedSignals[s] = substitute(removedSignals[s], isolatedSignal, removedSignals[isolatedSignal]);
|
||||
});
|
||||
}
|
||||
|
||||
addTolIdx(removedSignals[isolatedSignal], isolatedSignal);
|
||||
ctx.constraints[possibleConstraints[i]] = null;
|
||||
nRemoved ++;
|
||||
|
||||
sig2constraint[isolatedSignal].forEach( (s) => {
|
||||
nextPossibleConstraints[s] = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nextPossibleConstraints = nextPossibleConstraints.getKeys();
|
||||
|
||||
for (let i=0; i<nextPossibleConstraints.length;i++) {
|
||||
if ((ctx.verbose)&&(i%10000 == 0)) {
|
||||
await Promise.resolve();
|
||||
console.log(`substituting constraints: ${i}/${nextPossibleConstraints.length}`);
|
||||
}
|
||||
const c = ctx.constraints[nextPossibleConstraints[i]];
|
||||
if (c) {
|
||||
const nc = {
|
||||
a: substituteRemoved(c.a),
|
||||
b: substituteRemoved(c.b),
|
||||
c: substituteRemoved(c.c)
|
||||
};
|
||||
if (ctx.lc.isZero(nc)) {
|
||||
delete ctx.constraints[nextPossibleConstraints[i]];
|
||||
} else {
|
||||
ctx.constraints[nextPossibleConstraints[i]] = nc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const removedSignalsList = removedSignals.getKeys;
|
||||
|
||||
for (let i=0; i<removedSignalsList.length; i++) {
|
||||
if ((ctx.verbose )&&(i%100000 == 0)) console.log(`removing signals: ${i}/${removedSignalsList.length}`);
|
||||
const s = removedSignalsList[i];
|
||||
|
||||
let lSignal = ctx.signals[s];
|
||||
while (lSignal.e>=0) {
|
||||
lSignal = ctx.signals[lSignal.e];
|
||||
}
|
||||
|
||||
lSignal.c = ctx.stDISCARDED;
|
||||
}
|
||||
|
||||
possibleConstraints = nextPossibleConstraints;
|
||||
}
|
||||
|
||||
let o=0;
|
||||
for (let i=0; i<ctx.constraints.length;i++) {
|
||||
if ((ctx.verbose)&&(i%100000 == 0)) console.log(`reordering constraints: ${i}/${ctx.constraints.length}`);
|
||||
if (ctx.constraints[i]) {
|
||||
if (!ctx.lc.isZero(ctx.constraints[i])) {
|
||||
ctx.constraints[o] = ctx.constraints[i];
|
||||
o++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ctx.constraints.length = o;
|
||||
|
||||
function getFirstInternalSignal(ctx, l) {
|
||||
for (let k in l.coefs) {
|
||||
k = Number(k);
|
||||
const signal = ctx.signals[k];
|
||||
if ((signal.c == ctx.stINTERNAL)&&(!ctx.F.isZero(l.coefs[k])) &&(!removedSignals[k])) return k;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function isolateSignal(lc, s) {
|
||||
const eq = {
|
||||
t: "LC",
|
||||
coefs: {}
|
||||
};
|
||||
const invCoef = ctx.F.inv(lc.coefs[s]);
|
||||
for (const k in lc.coefs) {
|
||||
if (k != s) {
|
||||
const v = ctx.F.mul( ctx.F.neg(lc.coefs[k]), invCoef);
|
||||
if (!ctx.F.isZero(v)) {
|
||||
eq.coefs[k] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
return eq;
|
||||
}
|
||||
|
||||
function substituteRemoved(lc) {
|
||||
const newLc = ctx.lc._clone(lc);
|
||||
for (let k in lc.coefs) {
|
||||
if (removedSignals[k]) {
|
||||
delete newLc.coefs[k];
|
||||
for (let k2 in removedSignals[k].coefs) {
|
||||
const newP = ctx.F.mul(removedSignals[k].coefs[k2], lc.coefs[k]);
|
||||
if (!ctx.F.isZero(newP)) {
|
||||
if (newLc.coefs[k2]) {
|
||||
newLc.coefs[k2] = ctx.F.add(newLc.coefs[k2], newP);
|
||||
if (ctx.F.isZero(newLc.coefs[k2])) delete newLc.coefs[k2];
|
||||
} else {
|
||||
newLc.coefs[k2] = newP;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return newLc;
|
||||
}
|
||||
|
||||
function substitute(lc, s, eq) {
|
||||
if (!lc.coefs[s]) return lc;
|
||||
const newLc = ctx.lc._clone(lc);
|
||||
delete newLc.coefs[s];
|
||||
for (let k2 in eq.coefs) {
|
||||
const newP = ctx.F.mul(eq.coefs[k2], lc.coefs[s]);
|
||||
if (!ctx.F.isZero(newP)) {
|
||||
if (newLc.coefs[k2]) {
|
||||
newLc.coefs[k2] = ctx.F.add(newLc.coefs[k2], newP);
|
||||
if (ctx.F.isZero(newLc.coefs[k2])) delete newLc.coefs[k2];
|
||||
} else {
|
||||
newLc.coefs[k2] = newP;
|
||||
}
|
||||
}
|
||||
}
|
||||
return newLc;
|
||||
}
|
||||
|
||||
function isConstant(l) {
|
||||
for (let k in l.coefs) {
|
||||
if ((k != sONE) && (!ctx.F.isZero(l.coefs[k]))) return false;
|
||||
}
|
||||
if (!l.coefs[sONE] || ctx.F.isZero(l.coefs[sONE])) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function addTolIdx(lc, newS) {
|
||||
for (let s in lc.coefs) {
|
||||
if (!lIdx[s]) lIdx[s] = [];
|
||||
lIdx[s].push(newS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
function reduceConstrains_old(ctx) {
|
||||
indexVariables();
|
||||
let possibleConstraints = ctx.constraints;
|
||||
let ii=0;
|
||||
|
||||
@@ -567,14 +567,18 @@ function execFunctionCall(ctx, ast) {
|
||||
return;
|
||||
}
|
||||
if (ast.name == "assert") {
|
||||
ast.fileName = ctx.fileName;
|
||||
ast.filePath = ctx.filePath;
|
||||
|
||||
const v = exec(ctx, ast.params[0]);
|
||||
const ev = val(ctx, v, ast);
|
||||
if (ctx.F.isZero(ev)) return ctx.throwError(ast, "Assertion failed");
|
||||
if ((typeof ev.v !== "undefined")&&(ctx.F.isZero(ev.v))) return ctx.throwError(ast, "Assertion failed");
|
||||
return;
|
||||
}
|
||||
|
||||
const fnc = ctx.functions[ast.name];
|
||||
|
||||
if (!fnc) return ctx.throwError("Function not defined");
|
||||
if (!fnc) return ctx.throwError(ast, "Function not defined");
|
||||
|
||||
const paramValues = [];
|
||||
for (let i=0; i< ast.params.length; i++) {
|
||||
|
||||
@@ -723,7 +723,15 @@ function genVarAssignment(ctx, ast, lRef, sels, rRef) {
|
||||
|
||||
if (instantiated) {
|
||||
if (offset.used) {
|
||||
ctx.codeBuilder.copyN(left.label, ["R", offset.label], ["R", right.label], right.sizes[0]);
|
||||
let ot;
|
||||
if (offset.type == "BIGINT") {
|
||||
ot = "R";
|
||||
} else if (offset.type == "INT") {
|
||||
ot= "RI";
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
ctx.codeBuilder.copyN(left.label, [ot, offset.label], ["R", right.label], right.sizes[0]);
|
||||
} else {
|
||||
ctx.codeBuilder.copyN(left.label, ["V", offset.value[0]], ["R", right.label], right.sizes[0]);
|
||||
}
|
||||
@@ -863,6 +871,12 @@ function genFunctionCall(ctx, ast) {
|
||||
ctx.codeBuilder.log(toRefA_Fr1(ctx, ast.params[0], vRef));
|
||||
return vRef;
|
||||
}
|
||||
if (ast.name == "assert") {
|
||||
const strErr = ast.fileName + ":" + ast.first_line + ":" + ast.first_column;
|
||||
const vRef = gen(ctx, ast.params[0]);
|
||||
ctx.codeBuilder.checkAssert(toRefA_Fr1(ctx, ast.params[0], vRef), strErr);
|
||||
return vRef;
|
||||
}
|
||||
const params = [];
|
||||
for (let i=0; i<ast.params.length; i++) {
|
||||
const pRef = gen(ctx, ast.params[i]);
|
||||
|
||||
@@ -123,6 +123,7 @@ class LCAlgebra {
|
||||
}
|
||||
|
||||
_signal2lc(a) {
|
||||
const self = this;
|
||||
if (a.t == "S") {
|
||||
const lc = {
|
||||
t: "LC",
|
||||
|
||||
149
src/r1csfile.js
149
src/r1csfile.js
@@ -1,30 +1,36 @@
|
||||
|
||||
const fastFile = require("fastfile");
|
||||
const assert = require("assert");
|
||||
const BigArray = require("./bigarray");
|
||||
|
||||
module.exports.buildR1cs = buildR1cs;
|
||||
|
||||
|
||||
async function buildR1cs(ctx, fileName) {
|
||||
|
||||
const fd = await fastFile.createOverride(fileName);
|
||||
|
||||
|
||||
await fd.write(Buffer.from("r1cs"), 0); // Magic "r1cs"
|
||||
const buffBigInt = new Uint8Array(ctx.F.n8);
|
||||
|
||||
let p = 4;
|
||||
await writeU32(1); // Version
|
||||
await writeU32(3); // Number of Sections
|
||||
const type = "r1cs";
|
||||
const buff = new Uint8Array(4);
|
||||
for (let i=0; i<4; i++) buff[i] = type.charCodeAt(i);
|
||||
await fd.write(buff, 0); // Magic "r1cs"
|
||||
|
||||
await fd.writeULE32(1); // Version
|
||||
await fd.writeULE32(3); // Number of Sections
|
||||
|
||||
// Write the header
|
||||
///////////
|
||||
await writeU32(1); // Header type
|
||||
const pHeaderSize = p;
|
||||
await writeU64(0); // Temporally set to 0 length
|
||||
await fd.writeULE32(1); // Header type
|
||||
const pHeaderSize = fd.pos;
|
||||
await fd.writeULE64(0); // Temporally set to 0 length
|
||||
|
||||
|
||||
const n8 = (Math.floor( (ctx.F.bitLength - 1) / 64) +1)*8;
|
||||
// Field Def
|
||||
await writeU32(n8); // Temporally set to 0 length
|
||||
await fd.writeULE32(n8); // Temporally set to 0 length
|
||||
await writeBigInt(ctx.F.p);
|
||||
|
||||
const NWires =
|
||||
@@ -34,20 +40,20 @@ async function buildR1cs(ctx, fileName) {
|
||||
ctx.totals[ctx.stPRVINPUT] +
|
||||
ctx.totals[ctx.stINTERNAL];
|
||||
|
||||
await writeU32(NWires);
|
||||
await writeU32(ctx.totals[ctx.stOUTPUT]);
|
||||
await writeU32(ctx.totals[ctx.stPUBINPUT]);
|
||||
await writeU32(ctx.totals[ctx.stPRVINPUT]);
|
||||
await writeU64(ctx.signals.length);
|
||||
await writeU32(ctx.constraints.length);
|
||||
await fd.writeULE32(NWires);
|
||||
await fd.writeULE32(ctx.totals[ctx.stOUTPUT]);
|
||||
await fd.writeULE32(ctx.totals[ctx.stPUBINPUT]);
|
||||
await fd.writeULE32(ctx.totals[ctx.stPRVINPUT]);
|
||||
await fd.writeULE64(ctx.signals.length);
|
||||
await fd.writeULE32(ctx.constraints.length);
|
||||
|
||||
const headerSize = p - pHeaderSize - 8;
|
||||
const headerSize = fd.pos - pHeaderSize - 8;
|
||||
|
||||
// Write constraints
|
||||
///////////
|
||||
await writeU32(2); // Constraints type
|
||||
const pConstraintsSize = p;
|
||||
await writeU64(0); // Temporally set to 0 length
|
||||
await fd.writeULE32(2); // Constraints type
|
||||
const pConstraintsSize = fd.pos;
|
||||
await fd.writeULE64(0); // Temporally set to 0 length
|
||||
|
||||
for (let i=0; i<ctx.constraints.length; i++) {
|
||||
if ((ctx.verbose)&&(i%10000 == 0)) {
|
||||
@@ -56,16 +62,16 @@ async function buildR1cs(ctx, fileName) {
|
||||
await writeConstraint(ctx.constraints[i]);
|
||||
}
|
||||
|
||||
const constraintsSize = p - pConstraintsSize - 8;
|
||||
const constraintsSize = fd.pos - pConstraintsSize - 8;
|
||||
|
||||
// Write map
|
||||
///////////
|
||||
await writeU32(3); // wires2label type
|
||||
const pMapSize = p;
|
||||
await writeU64(0); // Temporally set to 0 length
|
||||
await fd.writeULE32(3); // wires2label type
|
||||
const pMapSize = fd.pos;
|
||||
await fd.writeULE64(0); // Temporally set to 0 length
|
||||
|
||||
|
||||
const arr = new Array(NWires);
|
||||
const arr = new BigArray(NWires);
|
||||
for (let i=0; i<ctx.signals.length; i++) {
|
||||
const outIdx = ctx.signals[i].id;
|
||||
if (ctx.signals[i].e>=0) continue; // If has an alias, continue..
|
||||
@@ -76,75 +82,64 @@ async function buildR1cs(ctx, fileName) {
|
||||
}
|
||||
}
|
||||
for (let i=0; i<arr.length; i++) {
|
||||
await writeU64(arr[i]);
|
||||
if ((ctx.verbose)&&(i%100000)) console.log("writing wire2label map: ", i);
|
||||
await fd.writeULE64(arr[i]);
|
||||
if ((ctx.verbose)&&(i%100000 == 0)) console.log(`writing wire2label map: ${i}/${arr.length}`);
|
||||
}
|
||||
|
||||
const mapSize = p - pMapSize - 8;
|
||||
const mapSize = fd.pos - pMapSize - 8;
|
||||
|
||||
// Write sizes
|
||||
await writeU32(headerSize, pHeaderSize);
|
||||
await writeU32(constraintsSize, pConstraintsSize);
|
||||
await writeU32(mapSize, pMapSize);
|
||||
await fd.writeULE32(headerSize, pHeaderSize);
|
||||
await fd.writeULE32(constraintsSize, pConstraintsSize);
|
||||
await fd.writeULE32(mapSize, pMapSize);
|
||||
|
||||
await fd.close();
|
||||
|
||||
async function writeU32(v, pos) {
|
||||
let o = (typeof pos == "undefined") ? p : pos;
|
||||
|
||||
const b = Buffer.allocUnsafe(4);
|
||||
b.writeInt32LE(v);
|
||||
|
||||
await fd.write(b, o);
|
||||
|
||||
if (typeof(pos) == "undefined") p += 4;
|
||||
}
|
||||
|
||||
async function writeU64(v, pos) {
|
||||
let o = (typeof pos == "undefined") ? p : pos;
|
||||
|
||||
const b = Buffer.allocUnsafe(8);
|
||||
|
||||
const LSB = v & 0xFFFFFFFF;
|
||||
const MSB = Math.floor(v / 0x100000000);
|
||||
b.writeInt32LE(LSB, 0);
|
||||
b.writeInt32LE(MSB, 4);
|
||||
|
||||
await fd.write(b, o);
|
||||
|
||||
if (typeof(pos) == "undefined") p += 8;
|
||||
}
|
||||
|
||||
async function writeConstraint(c) {
|
||||
await writeLC(c.a);
|
||||
await writeLC(c.b);
|
||||
await writeLC(ctx.lc.neg(c.c));
|
||||
}
|
||||
|
||||
async function writeLC(lc) {
|
||||
const idxs = Object.keys(lc.coefs);
|
||||
await writeU32(idxs.length);
|
||||
for (let s in lc.coefs) {
|
||||
let lSignal = ctx.signals[s];
|
||||
function writeConstraint(c) {
|
||||
const n8 = ctx.F.n8;
|
||||
const idxA = Object.keys(c.a.coefs);
|
||||
const idxB = Object.keys(c.b.coefs);
|
||||
const idxC = Object.keys(c.c.coefs);
|
||||
const buff = new Uint8Array((idxA.length+idxB.length+idxC.length)*(n8+4) + 12);
|
||||
const buffV = new DataView(buff.buffer);
|
||||
let o=0;
|
||||
|
||||
buffV.setUint32(o, idxA.length, true); o+=4;
|
||||
for (let i=0; i<idxA.length; i++) {
|
||||
const coef = idxA[i];
|
||||
let lSignal = ctx.signals[coef];
|
||||
while (lSignal.e >=0 ) lSignal = ctx.signals[lSignal.e];
|
||||
|
||||
await writeU32(lSignal.id);
|
||||
await writeBigInt(lc.coefs[s]);
|
||||
buffV.setUint32(o, lSignal.id, true); o+=4;
|
||||
ctx.F.toRprLE(buff, o, c.a.coefs[coef]); o+=n8;
|
||||
}
|
||||
|
||||
buffV.setUint32(o, idxB.length, true); o+=4;
|
||||
for (let i=0; i<idxB.length; i++) {
|
||||
const coef = idxB[i];
|
||||
let lSignal = ctx.signals[coef];
|
||||
while (lSignal.e >=0 ) lSignal = ctx.signals[lSignal.e];
|
||||
buffV.setUint32(o, lSignal.id, true); o+=4;
|
||||
|
||||
ctx.F.toRprLE(buff, o, c.b.coefs[coef]); o+=n8;
|
||||
}
|
||||
|
||||
buffV.setUint32(o, idxC.length, true); o+=4;
|
||||
for (let i=0; i<idxC.length; i++) {
|
||||
const coef = idxC[i];
|
||||
let lSignal = ctx.signals[coef];
|
||||
while (lSignal.e >=0 ) lSignal = ctx.signals[lSignal.e];
|
||||
buffV.setUint32(o, lSignal.id, true); o+=4;
|
||||
ctx.F.toRprLE(buff, o, ctx.F.neg(c.c.coefs[coef])); o+=n8;
|
||||
}
|
||||
|
||||
return fd.write(buff);
|
||||
}
|
||||
|
||||
async function writeBigInt(n, pos) {
|
||||
|
||||
let o = (typeof pos == "undefined") ? p : pos;
|
||||
ctx.F.toRprLE(buffBigInt, 0, n);
|
||||
|
||||
const s = n.toString(16);
|
||||
const b = Buffer.from(s.padStart(n8*2, "0"), "hex");
|
||||
const buff = Buffer.allocUnsafe(b.length);
|
||||
for (let i=0; i<b.length; i++) buff[i] = b[b.length-1-i];
|
||||
await fd.write(buffBigInt, pos);
|
||||
|
||||
await fd.write(buff, o);
|
||||
|
||||
if (typeof(pos) == "undefined") p += n8;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
const Readable = require("stream").Readable;
|
||||
|
||||
module.exports = function streamFromArrayTxt(ma) {
|
||||
@@ -22,7 +21,7 @@ module.exports = function streamFromArrayTxt(ma) {
|
||||
|
||||
|
||||
function getFirstIdx(ma) {
|
||||
if (!Array.isArray(ma)) return [];
|
||||
if (typeof ma.push !== "function" ) return [];
|
||||
return [0, ...getFirstIdx(ma[0])];
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ module.exports.fnvHash = fnvHash;
|
||||
module.exports.sameSizes = sameSizes;
|
||||
module.exports.isDefined = isDefined;
|
||||
module.exports.accSizes2Str = accSizes2Str;
|
||||
module.exports.setUint64 = setUint64;
|
||||
|
||||
function ident(text) {
|
||||
if (typeof text === "string") {
|
||||
@@ -90,6 +91,14 @@ function accSizes2Str(sizes) {
|
||||
return `[${sizes[0]/sizes[1]}]`+accSizes2Str(sizes.slice(1));
|
||||
}
|
||||
|
||||
function setUint64(buffV, o, n) {
|
||||
const sLSB = n >>> 0;
|
||||
const sMSB = (n - sLSB) / 0x100000000;
|
||||
buffV.setUint32(o, sLSB , true);
|
||||
buffV.setUint32(o+4, sMSB , true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user