Compare commits

..

12 Commits

Author SHA1 Message Date
Jordi Baylina
7239abcef1 0.5.18 2020-08-12 02:26:33 +02:00
Jordi Baylina
633f755e34 Fix testers with fastfile 2020-08-12 02:26:15 +02:00
Jordi Baylina
923b19c414 Fix: Error description function not found 2020-08-12 01:36:01 +02:00
Jordi Baylina
90cc7d5072 Remove streams c and wasm gen 2020-08-07 17:10:30 +02:00
Jordi Baylina
145d5a21ad BigArray in wit2sig 2020-08-06 22:59:19 +02:00
Jordi Baylina
cbb0b229bc Big array in r1cs labels 2020-08-05 14:32:05 +02:00
Jordi Baylina
1d14e8c603 BigArray require 2020-07-30 05:06:58 +02:00
Jordi Baylina
1e2fb12631 BigArray in code 2020-07-30 05:04:15 +02:00
Jordi Baylina
0e1a1bcc23 BigArray in CBuild 2020-07-29 19:40:24 +02:00
Jordi Baylina
989987bfc2 deps 2020-07-29 09:16:43 +02:00
Jordi Baylina
5f3ef322a7 Simplify buildC 2020-07-28 12:50:23 +02:00
Jordi Baylina
3c8e61b9a4 log buildC 2020-07-27 05:00:47 +02:00
13 changed files with 215 additions and 207 deletions

50
cli.js
View File

@@ -24,6 +24,7 @@
const fs = require("fs"); const fs = require("fs");
const path = require("path"); const path = require("path");
const Scalar = require("ffjavascript").Scalar; const Scalar = require("ffjavascript").Scalar;
const fastFile = require("fastfile");
const compiler = require("./src/compiler"); const compiler = require("./src/compiler");
@@ -60,6 +61,7 @@ const argv = require("yargs")
.argv; .argv;
async function run() {
let inputFile; let inputFile;
if (argv._.length == 0) { if (argv._.length == 0) {
inputFile = "circuit.circom"; inputFile = "circuit.circom";
@@ -84,13 +86,13 @@ options.verbose = argv.verbose || false;
options.sanityCheck = argv.sanitycheck; options.sanityCheck = argv.sanitycheck;
if (argv.csource) { if (argv.csource) {
options.cSourceWriteStream = fs.createWriteStream(cSourceName); options.cSourceFile = await fastFile.createOverride(cSourceName);
} }
if (argv.wasm) { if (argv.wasm) {
options.wasmWriteStream = fs.createWriteStream(wasmName); options.wasmFile = await fastFile.createOverride(wasmName);
} }
if (argv.wat) { if (argv.wat) {
options.watWriteStream = fs.createWriteStream(watName); options.watFile = await fastFile.createOverride(watName);
} }
if (argv.r1cs) { if (argv.r1cs) {
options.r1csFileName = r1csName; options.r1csFileName = r1csName;
@@ -112,35 +114,12 @@ if (!argv.prime) {
} }
compiler(fullFileName, options).then( () => { await compiler(fullFileName, options);
let cSourceDone = false;
let wasmDone = false; if (options.cSourceFile) await options.cSourceFile.close();
if (options.wasmFile) await options.wasmFile.close();
if (options.watFile) await options.watFile.close();
let symDone = false; 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) { if (options.symWriteStream) {
options.symWriteStream.on("finish", () => { options.symWriteStream.on("finish", () => {
symDone = true; symDone = true;
@@ -150,12 +129,17 @@ compiler(fullFileName, options).then( () => {
symDone = true; symDone = true;
} }
function finishIfDone() { function finishIfDone() {
if ((cSourceDone)&&(symDone)&&(wasmDone)&&(watDone)) { if (symDone) {
setTimeout(() => { setTimeout(() => {
process.exit(0); process.exit(0);
}, 300); }, 300);
} }
} }
}
run().then(()=> {
process.exit(0);
}, (err) => { }, (err) => {
// console.log(err); // console.log(err);
console.log(err.stack); console.log(err.stack);
@@ -172,5 +156,3 @@ compiler(fullFileName, options).then( () => {
}); });

84
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{ {
"name": "circom", "name": "circom",
"version": "0.5.17", "version": "0.5.18",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@@ -48,9 +48,9 @@
"dev": true "dev": true
}, },
"acorn": { "acorn": {
"version": "7.3.1", "version": "7.4.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz",
"integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==", "integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==",
"dev": true "dev": true
}, },
"acorn-jsx": { "acorn-jsx": {
@@ -60,9 +60,9 @@
"dev": true "dev": true
}, },
"ajv": { "ajv": {
"version": "6.12.2", "version": "6.12.3",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz",
"integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==",
"dev": true, "dev": true,
"requires": { "requires": {
"fast-deep-equal": "^3.1.1", "fast-deep-equal": "^3.1.1",
@@ -240,9 +240,9 @@
} }
}, },
"cli-width": { "cli-width": {
"version": "2.2.1", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz",
"integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==",
"dev": true "dev": true
}, },
"cliui": { "cliui": {
@@ -507,9 +507,9 @@
}, },
"dependencies": { "dependencies": {
"estraverse": { "estraverse": {
"version": "5.1.0", "version": "5.2.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
"integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==", "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
"dev": true "dev": true
} }
} }
@@ -576,9 +576,9 @@
"dev": true "dev": true
}, },
"fastfile": { "fastfile": {
"version": "0.0.9", "version": "0.0.12",
"resolved": "https://registry.npmjs.org/fastfile/-/fastfile-0.0.9.tgz", "resolved": "https://registry.npmjs.org/fastfile/-/fastfile-0.0.12.tgz",
"integrity": "sha512-njh6lH2SJiS0u0JofJQf2YfEOSgGfbYPtmFnpEXXy6OilWoX1wGw3klaSKIwhq8+E5MqYpqJXMiaqmptaU2wig==" "integrity": "sha512-0EZo2y5eW8X0oiDDRvcnufjVxlM96CQL5hvmRQtbRABWlCkH73IHwkzl0qOSdxtchaMr+0TSB7GVqaVEixRr1Q=="
}, },
"ffiasm": { "ffiasm": {
"version": "0.0.2", "version": "0.0.2",
@@ -780,21 +780,21 @@
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
}, },
"inquirer": { "inquirer": {
"version": "7.2.0", "version": "7.3.3",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.2.0.tgz", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz",
"integrity": "sha512-E0c4rPwr9ByePfNlTIB8z51kK1s2n6jrHuJeEHENl/sbq2G/S1auvibgEwNR4uSyiU+PiYHqSwsgGiXjG8p5ZQ==", "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==",
"dev": true, "dev": true,
"requires": { "requires": {
"ansi-escapes": "^4.2.1", "ansi-escapes": "^4.2.1",
"chalk": "^3.0.0", "chalk": "^4.1.0",
"cli-cursor": "^3.1.0", "cli-cursor": "^3.1.0",
"cli-width": "^2.0.0", "cli-width": "^3.0.0",
"external-editor": "^3.0.3", "external-editor": "^3.0.3",
"figures": "^3.0.0", "figures": "^3.0.0",
"lodash": "^4.17.15", "lodash": "^4.17.19",
"mute-stream": "0.0.8", "mute-stream": "0.0.8",
"run-async": "^2.4.0", "run-async": "^2.4.0",
"rxjs": "^6.5.3", "rxjs": "^6.6.0",
"string-width": "^4.1.0", "string-width": "^4.1.0",
"strip-ansi": "^6.0.0", "strip-ansi": "^6.0.0",
"through": "^2.3.6" "through": "^2.3.6"
@@ -811,9 +811,9 @@
} }
}, },
"chalk": { "chalk": {
"version": "3.0.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
"integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
"dev": true, "dev": true,
"requires": { "requires": {
"ansi-styles": "^4.1.0", "ansi-styles": "^4.1.0",
@@ -986,9 +986,9 @@
} }
}, },
"lodash": { "lodash": {
"version": "4.17.15", "version": "4.17.19",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
"dev": true "dev": true
}, },
"mimic-fn": { "mimic-fn": {
@@ -1063,9 +1063,9 @@
} }
}, },
"onetime": { "onetime": {
"version": "5.1.0", "version": "5.1.2",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
"integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
"dev": true, "dev": true,
"requires": { "requires": {
"mimic-fn": "^2.1.0" "mimic-fn": "^2.1.0"
@@ -1223,9 +1223,9 @@
"dev": true "dev": true
}, },
"rxjs": { "rxjs": {
"version": "6.6.0", "version": "6.6.2",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.0.tgz", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.2.tgz",
"integrity": "sha512-3HMA8z/Oz61DUHe+SdOiQyzIf4tOx5oQHmMir7IZEu6TMqCLHT4LRcmNaUS0NwOz8VLvmmBduMsoaUvMaIiqzg==", "integrity": "sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg==",
"dev": true, "dev": true,
"requires": { "requires": {
"tslib": "^1.9.0" "tslib": "^1.9.0"
@@ -1323,9 +1323,9 @@
} }
}, },
"strip-json-comments": { "strip-json-comments": {
"version": "3.1.0", "version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.0.tgz", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
"integrity": "sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w==", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
"dev": true "dev": true
}, },
"supports-color": { "supports-color": {
@@ -1559,9 +1559,9 @@
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w=="
}, },
"yargs": { "yargs": {
"version": "15.3.1", "version": "15.4.1",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
"integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
"requires": { "requires": {
"cliui": "^6.0.0", "cliui": "^6.0.0",
"decamelize": "^1.2.0", "decamelize": "^1.2.0",
@@ -1573,7 +1573,7 @@
"string-width": "^4.2.0", "string-width": "^4.2.0",
"which-module": "^2.0.0", "which-module": "^2.0.0",
"y18n": "^4.0.0", "y18n": "^4.0.0",
"yargs-parser": "^18.1.1" "yargs-parser": "^18.1.2"
} }
}, },
"yargs-parser": { "yargs-parser": {

View File

@@ -1,6 +1,6 @@
{ {
"name": "circom", "name": "circom",
"version": "0.5.17", "version": "0.5.18",
"description": "Language to generate logic circuits", "description": "Language to generate logic circuits",
"main": "index.js", "main": "index.js",
"directories": { "directories": {
@@ -31,7 +31,7 @@
"dependencies": { "dependencies": {
"chai": "^4.2.0", "chai": "^4.2.0",
"circom_runtime": "0.0.6", "circom_runtime": "0.0.6",
"fastfile": "0.0.9", "fastfile": "0.0.12",
"ffiasm": "0.0.2", "ffiasm": "0.0.2",
"ffjavascript": "0.2.4", "ffjavascript": "0.2.4",
"ffwasm": "0.0.7", "ffwasm": "0.0.7",

View File

@@ -1,8 +1,8 @@
const streamFromMultiArray = require("../../src/streamfromarray_txt.js");
const utils = require("../../src/utils"); const utils = require("../../src/utils");
const assert = require("assert"); const assert = require("assert");
const Scalar = require("ffjavascript").Scalar; const Scalar = require("ffjavascript").Scalar;
const F1Field = require("ffjavascript").F1Field; const F1Field = require("ffjavascript").F1Field;
const BigArray = require("../../src/bigarray");
function ref2src(c) { function ref2src(c) {
if ((c[0] == "R")||(c[0] == "RI")) { if ((c[0] == "R")||(c[0] == "RI")) {
@@ -341,16 +341,17 @@ class FunctionBuilderC {
} }
class BuilderC { class BuilderC {
constructor(p) { constructor(p, verbose) {
this.F = new F1Field(p); this.F = new F1Field(p);
this.hashMaps={}; this.hashMaps={};
this.componentEntriesTables={}; this.componentEntriesTables=new BigArray();
this.sizes ={}; this.sizes ={};
this.constants = []; this.constants = [];
this.functions = []; this.functions = [];
this.components = []; this.components = new BigArray();
this.usedConstants = {}; this.usedConstants = {};
this.verbose = verbose;
} }
setHeader(header) { setHeader(header) {
@@ -363,7 +364,10 @@ class BuilderC {
} }
addComponentEntriesTable(name, cet) { addComponentEntriesTable(name, cet) {
this.componentEntriesTables[name] = cet; this.componentEntriesTables.push({
name: name,
cet: cet
});
} }
addSizes(name, accSizes) { addSizes(name, accSizes) {
@@ -444,8 +448,10 @@ class BuilderC {
_buildComponentEntriesTables(code) { _buildComponentEntriesTables(code) {
code.push("// Component Entry tables"); code.push("// Component Entry tables");
for (let cetName in this.componentEntriesTables) { for (let i=0; i< this.componentEntriesTables.length; i++) {
const cet = this.componentEntriesTables[cetName]; if ((this.verbose)&&(i%100000 ==0)) console.log(`_buildComponentEntriesTables ${i}/${this.componentEntriesTables.length}`);
const cetName = this.componentEntriesTables[i].name;
const cet = this.componentEntriesTables[i].cet;
code.push(`Circom_ComponentEntry ${cetName}[${cet.length}] = {`); code.push(`Circom_ComponentEntry ${cetName}[${cet.length}] = {`);
for (let j=0; j<cet.length; j++) { for (let j=0; j<cet.length; j++) {
@@ -477,6 +483,7 @@ class BuilderC {
code.push("// Constants"); code.push("// Constants");
code.push(`FrElement _constants[${self.constants.length}] = {`); code.push(`FrElement _constants[${self.constants.length}] = {`);
for (let i=0; i<self.constants.length; i++) { for (let i=0; i<self.constants.length; i++) {
if ((this.verbose)&&(i%1000000 ==0)) console.log(`_buildConstants ${i}/${this.constants.length}`);
code.push((i>0 ? "," : " ") + "{" + number2Code(self.constants[i]) + "}"); code.push((i>0 ? "," : " ") + "{" + number2Code(self.constants[i]) + "}");
} }
code.push("};"); code.push("};");
@@ -554,6 +561,7 @@ class BuilderC {
code.push("// Components"); code.push("// Components");
code.push(`Circom_Component _components[${this.components.length}] = {`); code.push(`Circom_Component _components[${this.components.length}] = {`);
for (let i=0; i<this.components.length; i++) { 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]; const c = this.components[i];
const sep = i>0 ? " ," : " "; const sep = i>0 ? " ," : " ";
code.push(`${sep}{${c.hashMapName}, ${c.entryTableName}, ${c.functionName}, ${c.nInSignals}, ${c.newThread}}`); code.push(`${sep}{${c.hashMapName}, ${c.entryTableName}, ${c.functionName}, ${c.nInSignals}, ${c.newThread}}`);
@@ -566,6 +574,7 @@ class BuilderC {
code.push(`u32 _mapIsInput[${this.mapIsInput.length}] = {`); code.push(`u32 _mapIsInput[${this.mapIsInput.length}] = {`);
let line = ""; let line = "";
for (let i=0; i<this.mapIsInput.length; i++) { for (let i=0; i<this.mapIsInput.length; i++) {
if ((this.verbose)&&(i%1000000 ==0)) console.log(`_buildMapIsInput ${i}/${this.mapIsInput.length}`);
line += i>0 ? ", " : " "; line += i>0 ? ", " : " ";
line += toHex(this.mapIsInput[i]); line += toHex(this.mapIsInput[i]);
if (((i+1) % 64)==0) { if (((i+1) % 64)==0) {
@@ -589,6 +598,7 @@ class BuilderC {
code.push(`int _wit2sig[${this.wit2sig.length}] = {`); code.push(`int _wit2sig[${this.wit2sig.length}] = {`);
let line = ""; let line = "";
for (let i=0; i<this.wit2sig.length; i++) { for (let i=0; i<this.wit2sig.length; i++) {
if ((this.verbose)&&(i%1000000 ==0)) console.log(`_buildWit2Sig ${i}/${this.wit2sig.length}`);
line += i>0 ? "," : " "; line += i>0 ? "," : " ";
line += this.wit2sig[i]; line += this.wit2sig[i];
if (((i+1) % 64) == 0) { if (((i+1) % 64) == 0) {
@@ -620,8 +630,9 @@ class BuilderC {
} }
build() { async build(fd) {
const code=[]; const encoder = new TextEncoder("utf-8");
const code=new BigArray();
this._buildHeader(code); this._buildHeader(code);
this._buildSizes(code); this._buildSizes(code);
this._buildConstants(code); this._buildConstants(code);
@@ -632,7 +643,17 @@ class BuilderC {
this._buildMapIsInput(code); this._buildMapIsInput(code);
this._buildWit2Sig(code); this._buildWit2Sig(code);
this._buildCircuitVar(code); this._buildCircuitVar(code);
return streamFromMultiArray(code); 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 fd.write(encoder.encode(c + "\n"));
}
}
} }
} }

View File

@@ -13,6 +13,7 @@ const utils = require("../../src/utils");
const loadR1cs = require("r1csfile").load; const loadR1cs = require("r1csfile").load;
const ZqField = require("ffjavascript").ZqField; const ZqField = require("ffjavascript").ZqField;
const buildZqField = require("ffiasm").buildZqField; const buildZqField = require("ffiasm").buildZqField;
const fastFile = require("fastfile");
const {stringifyBigInts, unstringifyBigInts } = require("ffjavascript").utils; const {stringifyBigInts, unstringifyBigInts } = require("ffjavascript").utils;
@@ -29,13 +30,15 @@ async function c_tester(circomFile, _options) {
const baseName = path.basename(circomFile, ".circom"); const baseName = path.basename(circomFile, ".circom");
const options = Object.assign({}, _options); 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.symWriteStream = fs.createWriteStream(path.join(dir.path, baseName + ".sym")); options.symWriteStream = fs.createWriteStream(path.join(dir.path, baseName + ".sym"));
options.r1csFileName = path.join(dir.path, baseName + ".r1cs"); options.r1csFileName = path.join(dir.path, baseName + ".r1cs");
options.p = options.p || Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"); options.p = options.p || Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617");
await compiler(circomFile, options); await compiler(circomFile, options);
await options.cSourceFile.close();
const source = await buildZqField(options.p, "Fr"); const source = await buildZqField(options.p, "Fr");
// console.log(dir.path); // console.log(dir.path);

View File

@@ -1,5 +1,3 @@
const streamFromArrayTxt = require("../../src/streamfromarray_txt");
const streamFromArrayBin = require("../../src/streamfromarray_bin");
const assert = require("assert"); const assert = require("assert");
const ModuleBuilder = require("wasmbuilder").ModuleBuilder; const ModuleBuilder = require("wasmbuilder").ModuleBuilder;
const ModuleBuilderWat = require("wasmbuilder").ModuleBuilderWat; const ModuleBuilderWat = require("wasmbuilder").ModuleBuilderWat;
@@ -990,7 +988,8 @@ class BuilderWasm {
} }
build(outType) { async build(fd, outType) {
const encoder = new TextEncoder("utf-8");
let module; let module;
if (outType == "wasm") { if (outType == "wasm") {
module=new ModuleBuilder(); module=new ModuleBuilder();
@@ -1017,12 +1016,25 @@ class BuilderWasm {
module.setMemory(2000); module.setMemory(2000);
if (outType == "wasm") { if (outType == "wasm") {
return streamFromArrayBin(module.build()); const bytes = module.build();
const bytesArr = new Uint8Array(bytes);
await fd.write(bytesArr);
} else if (outType == "wat") { } else if (outType == "wat") {
return streamFromArrayTxt(module.build()); const code = module.build();
await writeCode(code);
} else { } else {
assert(false); 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"));
}
}
} }
} }

View File

@@ -9,6 +9,7 @@ const compiler = require("../../src/compiler");
const utils = require("../../src/utils"); const utils = require("../../src/utils");
const loadR1cs = require("r1csfile").load; const loadR1cs = require("r1csfile").load;
const ZqField = require("ffjavascript").ZqField; const ZqField = require("ffjavascript").ZqField;
const fastFile = require("fastfile");
const WitnessCalculatorBuilder = require("circom_runtime").WitnessCalculatorBuilder; const WitnessCalculatorBuilder = require("circom_runtime").WitnessCalculatorBuilder;
@@ -24,16 +25,14 @@ async function wasm_tester(circomFile, _options) {
const baseName = path.basename(circomFile, ".circom"); const baseName = path.basename(circomFile, ".circom");
const options = Object.assign({}, _options); 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.symWriteStream = fs.createWriteStream(path.join(dir.path, baseName + ".sym"));
options.r1csFileName = path.join(dir.path, baseName + ".r1cs"); 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 compiler(circomFile, options);
await Promise.all(promisesArr); await options.wasmFile.close();
const wasm = await fs.promises.readFile(path.join(dir.path, baseName + ".wasm")); const wasm = await fs.promises.readFile(path.join(dir.path, baseName + ".wasm"));

View File

@@ -26,8 +26,10 @@ class _BigArray {
} }
return this; return this;
} }
push (element) { push () {
this.setElement (this.length, element); for (let i=0; i<arguments.length; i++) {
this.setElement (this.length, arguments[i]);
}
} }
getElement(idx) { getElement(idx) {
idx = parseInt(idx); idx = parseInt(idx);

View File

@@ -21,6 +21,7 @@ const assert = require("assert");
const utils = require("./utils"); const utils = require("./utils");
const gen = require("./gencode").gen; const gen = require("./gencode").gen;
const createRefs = require("./gencode").createRefs; const createRefs = require("./gencode").createRefs;
const BigArray = require("./bigarray");
module.exports = build; module.exports = build;
@@ -37,28 +38,33 @@ function build(ctx) {
ctx.addConstant(ctx.F.zero); ctx.addConstant(ctx.F.zero);
ctx.addConstant(ctx.F.one); ctx.addConstant(ctx.F.one);
if (ctx.verbose) console.log("buildHeader...");
buildHeader(ctx); buildHeader(ctx);
if (ctx.verbose) console.log("buildEntryTables...");
buildEntryTables(ctx); buildEntryTables(ctx);
ctx.globalNames = ctx.uniqueNames; ctx.globalNames = ctx.uniqueNames;
if (ctx.verbose) console.log("buildCode...");
buildCode(ctx); buildCode(ctx);
if (ctx.verbose) console.log("buildComponentsArray...");
buildComponentsArray(ctx); buildComponentsArray(ctx);
if (ctx.verbose) console.log("buildMapIsInput...");
buildMapIsInput(ctx); buildMapIsInput(ctx);
if (ctx.verbose) console.log("buildWit2Sig...");
buildWit2Sig(ctx); buildWit2Sig(ctx);
} }
function buildEntryTables(ctx) { function buildEntryTables(ctx) {
const codes_hashMaps = [];
const codes_componentEntries = [];
const definedHashMaps = {}; const definedHashMaps = {};
for (let i=0; i<ctx.components.length; i++) { 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); const {htName, htMap} = addHashTable(i);
let code = "";
const componentEntriesTableName = ctx.getUniqueName("_entryTable" + ctx.components[i].template); const componentEntriesTableName = ctx.getUniqueName("_entryTable" + ctx.components[i].template);
const componentEntriesTable = []; const componentEntriesTable = [];
@@ -74,32 +80,12 @@ function buildEntryTables(ctx) {
ctx.builder.addComponentEntriesTable(componentEntriesTableName, componentEntriesTable); 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.components[i].htName = htName; ctx.components[i].htName = htName;
ctx.components[i].etName = componentEntriesTableName; ctx.components[i].etName = componentEntriesTableName;
} }
return [ return;
"// HashMaps\n" ,
codes_hashMaps , "\n" ,
"\n" ,
"// Component Entries\n" ,
codes_componentEntries , "\n" ,
"\n"
];
function addHashTable(cIdx) { function addHashTable(cIdx) {
const keys = Object.keys(ctx.components[cIdx].names.o); const keys = Object.keys(ctx.components[cIdx].names.o);
@@ -131,6 +117,7 @@ function buildCode(ctx) {
const fnComponents = []; const fnComponents = [];
for (let i=0; i<ctx.components.length; i++) { 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 {h, instanceDef} = hashComponentCall(ctx, i);
const fName = ctx.components[i].template+"_"+h; const fName = ctx.components[i].template+"_"+h;
if (!fDefined[fName]) { if (!fDefined[fName]) {
@@ -180,6 +167,7 @@ function buildCode(ctx) {
function buildComponentsArray(ctx) { function buildComponentsArray(ctx) {
for (let i=0; i< ctx.components.length; i++) { 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; let newThread;
if (ctx.newThreadTemplates) { if (ctx.newThreadTemplates) {
if (ctx.newThreadTemplates.test(ctx.components[i].template)) { if (ctx.newThreadTemplates.test(ctx.components[i].template)) {
@@ -217,6 +205,7 @@ function buildMapIsInput(ctx) {
let map = []; let map = [];
let acc = 0; let acc = 0;
for (i=0; i<ctx.signals.length; i++) { 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) { if (ctx.signals[i].o & ctx.IN) {
acc = acc | (1 << (i%32) ); acc = acc | (1 << (i%32) );
} }
@@ -241,8 +230,9 @@ function buildWit2Sig(ctx) {
ctx.totals[ctx.stPUBINPUT] + ctx.totals[ctx.stPUBINPUT] +
ctx.totals[ctx.stPRVINPUT] + ctx.totals[ctx.stPRVINPUT] +
ctx.totals[ctx.stINTERNAL]; ctx.totals[ctx.stINTERNAL];
const arr = Array(NVars); const arr = new BigArray(NVars);
for (let i=0; i<ctx.signals.length; i++) { 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; const outIdx = ctx.signals[i].id;
if (ctx.signals[i].e>=0) continue; // If has an alias, continue.. if (ctx.signals[i].e>=0) continue; // If has an alias, continue..
assert(typeof outIdx != "undefined", `Signal ${i} does not have index`); assert(typeof outIdx != "undefined", `Signal ${i} does not have index`);

View File

@@ -119,45 +119,44 @@ async function compile(srcFile, options) {
throw(ctx.error); throw(ctx.error);
} }
if (options.cSourceWriteStream) {
if (ctx.verbose) console.log("Generating c...");
measures.generateC = -performance.now();
ctx.builder = new BuilderC(options.prime);
build(ctx);
const rdStream = ctx.builder.build();
rdStream.pipe(options.cSourceWriteStream);
measures.generateC += performance.now();
// await new Promise(fulfill => options.cSourceWriteStream.on("finish", fulfill));
}
if ((options.wasmWriteStream)||(options.watWriteStream)) {
if (ctx.verbose) console.log("Generating wasm...");
measures.generateWasm = -performance.now();
ctx.builder = new BuilderWasm(options.prime);
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);
}
measures.generateWasm += performance.now();
// await new Promise(fulfill => options.wasmWriteStream.on("finish", fulfill));
}
// const mainCode = gen(ctx,ast);
if (ctx.error) throw(ctx.error);
if (options.r1csFileName) { if (options.r1csFileName) {
measures.generateR1cs = -performance.now(); measures.generateR1cs = -performance.now();
await buildR1cs(ctx, options.r1csFileName); await buildR1cs(ctx, options.r1csFileName);
measures.generateR1cs += performance.now(); measures.generateR1cs += performance.now();
} }
if (ctx.error) throw(ctx.error);
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);
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.symWriteStream) { if (options.symWriteStream) {
measures.generateSyms = -performance.now(); measures.generateSyms = -performance.now();
const rdStream = buildSyms(ctx); const rdStream = buildSyms(ctx);

View File

@@ -574,7 +574,7 @@ function execFunctionCall(ctx, ast) {
const fnc = ctx.functions[ast.name]; 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 = []; const paramValues = [];
for (let i=0; i< ast.params.length; i++) { for (let i=0; i< ast.params.length; i++) {

View File

@@ -1,6 +1,7 @@
const fastFile = require("fastfile"); const fastFile = require("fastfile");
const assert = require("assert"); const assert = require("assert");
const BigArray = require("./bigarray");
module.exports.buildR1cs = buildR1cs; module.exports.buildR1cs = buildR1cs;
@@ -70,7 +71,7 @@ async function buildR1cs(ctx, fileName) {
await fd.writeULE64(0); // Temporally set to 0 length 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++) { for (let i=0; i<ctx.signals.length; i++) {
const outIdx = ctx.signals[i].id; const outIdx = ctx.signals[i].id;
if (ctx.signals[i].e>=0) continue; // If has an alias, continue.. if (ctx.signals[i].e>=0) continue; // If has an alias, continue..

View File

@@ -1,4 +1,3 @@
const Readable = require("stream").Readable; const Readable = require("stream").Readable;
module.exports = function streamFromArrayTxt(ma) { module.exports = function streamFromArrayTxt(ma) {
@@ -22,7 +21,7 @@ module.exports = function streamFromArrayTxt(ma) {
function getFirstIdx(ma) { function getFirstIdx(ma) {
if (!Array.isArray(ma)) return []; if (typeof ma.push !== "function" ) return [];
return [0, ...getFirstIdx(ma[0])]; return [0, ...getFirstIdx(ma[0])];
} }