mirror of
https://github.com/arnaucube/circom.git
synced 2026-02-07 03:06:42 +01:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2200408986 | ||
|
|
5f13d37fdc | ||
|
|
3b46b74d4a | ||
|
|
aa2d768465 | ||
|
|
f02ceb2508 | ||
|
|
d014d67032 | ||
|
|
2e1b35a94d | ||
|
|
7cef1be2c3 | ||
|
|
4b631994ca |
6
cli.js
6
cli.js
@@ -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 stringifyBigInts = require("ffjavascript").utils.stringifyBigInts;
|
||||||
const fastFile = require("fastfile");
|
const fastFile = require("fastfile");
|
||||||
|
|
||||||
const compiler = require("./src/compiler");
|
const compiler = require("./src/compiler");
|
||||||
@@ -87,6 +88,8 @@ async function run() {
|
|||||||
|
|
||||||
if (argv.csource) {
|
if (argv.csource) {
|
||||||
options.cSourceFile = await fastFile.createOverride(cSourceName);
|
options.cSourceFile = await fastFile.createOverride(cSourceName);
|
||||||
|
const noExt = cSourceName.substr(0, cSourceName.lastIndexOf(".")) || cSourceName;
|
||||||
|
options.dataFile = await fastFile.createOverride(noExt+".dat");
|
||||||
}
|
}
|
||||||
if (argv.wasm) {
|
if (argv.wasm) {
|
||||||
options.wasmFile = await fastFile.createOverride(wasmName);
|
options.wasmFile = await fastFile.createOverride(wasmName);
|
||||||
@@ -117,6 +120,7 @@ async function run() {
|
|||||||
await compiler(fullFileName, options);
|
await compiler(fullFileName, options);
|
||||||
|
|
||||||
if (options.cSourceFile) await options.cSourceFile.close();
|
if (options.cSourceFile) await options.cSourceFile.close();
|
||||||
|
if (options.dataFile) await options.dataFile.close();
|
||||||
if (options.wasmFile) await options.wasmFile.close();
|
if (options.wasmFile) await options.wasmFile.close();
|
||||||
if (options.watFile) await options.watFile.close();
|
if (options.watFile) await options.watFile.close();
|
||||||
let symDone = false;
|
let symDone = false;
|
||||||
@@ -150,7 +154,7 @@ run().then(()=> {
|
|||||||
if (argv.verbose) console.log(err.stack);
|
if (argv.verbose) console.log(err.stack);
|
||||||
}
|
}
|
||||||
if (err.ast) {
|
if (err.ast) {
|
||||||
console.error(JSON.stringify(err.ast, null, 1));
|
console.error(JSON.stringify(stringifyBigInts(err.ast), null, 1));
|
||||||
}
|
}
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
});
|
});
|
||||||
|
|||||||
61
package-lock.json
generated
61
package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "circom",
|
"name": "circom",
|
||||||
"version": "0.5.18",
|
"version": "0.5.22",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -203,22 +203,12 @@
|
|||||||
"integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII="
|
"integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII="
|
||||||
},
|
},
|
||||||
"circom_runtime": {
|
"circom_runtime": {
|
||||||
"version": "0.0.6",
|
"version": "0.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/circom_runtime/-/circom_runtime-0.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/circom_runtime/-/circom_runtime-0.1.4.tgz",
|
||||||
"integrity": "sha512-o0T5MuWzxnxinWG3+CygS/kZouoP+z5ZrufUwqKJy3gsVFJhkbqMpfKmcBGjhExB3uatA7cKyOiRAOLOz5+t5w==",
|
"integrity": "sha512-sQWeEBD3o2jIdrKPf3VDu7DNfP+NfscYO/pxi73FE0qQW8TXTfwno8Grdl++h6OKWbzvWJdG5jQvS+WGKjpMOg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"ffjavascript": "0.1.0",
|
"ffjavascript": "0.2.10",
|
||||||
"fnv-plus": "^1.3.1"
|
"fnv-plus": "^1.3.1"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"ffjavascript": {
|
|
||||||
"version": "0.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.1.0.tgz",
|
|
||||||
"integrity": "sha512-dmKlUasSfvUcxBm8nCSKl2x7EFJsXA7OVP8XLFA03T2+6mAc3IiVLC2ambEVOcMOhyhl0vJfVZjM9f9d38D1rw==",
|
|
||||||
"requires": {
|
|
||||||
"big-integer": "^1.6.48"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cjson": {
|
"cjson": {
|
||||||
@@ -344,9 +334,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"ejs": {
|
"ejs": {
|
||||||
"version": "3.1.3",
|
"version": "3.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.5.tgz",
|
||||||
"integrity": "sha512-wmtrUGyfSC23GC/B1SMv2ogAUgbQEtDmTIhfqielrG5ExIM9TP4UoYdi90jLF1aTcsWCJNEO0UrgKzP0y3nTSg==",
|
"integrity": "sha512-dldq3ZfFtgVTJMLjOe+/3sROTzALlL9E34V4/sDtUd/KlBSS0s6U1/+WPE1B4sj9CXHJpL1M6rhNJnc9Wbal9w==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"jake": "^10.6.1"
|
"jake": "^10.6.1"
|
||||||
}
|
}
|
||||||
@@ -581,9 +571,9 @@
|
|||||||
"integrity": "sha512-0EZo2y5eW8X0oiDDRvcnufjVxlM96CQL5hvmRQtbRABWlCkH73IHwkzl0qOSdxtchaMr+0TSB7GVqaVEixRr1Q=="
|
"integrity": "sha512-0EZo2y5eW8X0oiDDRvcnufjVxlM96CQL5hvmRQtbRABWlCkH73IHwkzl0qOSdxtchaMr+0TSB7GVqaVEixRr1Q=="
|
||||||
},
|
},
|
||||||
"ffiasm": {
|
"ffiasm": {
|
||||||
"version": "0.0.2",
|
"version": "0.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/ffiasm/-/ffiasm-0.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/ffiasm/-/ffiasm-0.1.1.tgz",
|
||||||
"integrity": "sha512-o/CL7F4IodB7eRHCOQL1SrqN2DIPHrQbEwjPY7NIyeBRdnB3G0xo6b6Mj44SKiWFnvpQMb3n4N7acjD3vv4NVQ==",
|
"integrity": "sha512-irMMHiR9JJ7BVBrAhtliUawxVdPYSdyl81taUYJ4C1mJ0iw2ueThE/qtr0J8B83tsIY8HJvh0lg5F+6ClK4xpA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"big-integer": "^1.6.48",
|
"big-integer": "^1.6.48",
|
||||||
"ejs": "^3.0.1",
|
"ejs": "^3.0.1",
|
||||||
@@ -591,13 +581,24 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ffjavascript": {
|
"ffjavascript": {
|
||||||
"version": "0.2.4",
|
"version": "0.2.10",
|
||||||
"resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.10.tgz",
|
||||||
"integrity": "sha512-XFeWcjUDFPavN+DDOxhE8p5MOhZQJc9oO1Sj4ml1pyjqNhS1ujEamcjFyK0cctdnat61i7lvpTYzdtS3RYDC8w==",
|
"integrity": "sha512-GQI6gHYYG5/iD4Kt3VzezzK7fARJzP0zkc82V/+JAdjfeKBXhDSo5rpKFuK3cDcrdW0Fu2emuYNMEAuFqhEQvQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"big-integer": "^1.6.48",
|
"big-integer": "^1.6.48",
|
||||||
"wasmcurves": "0.0.4",
|
"wasmcurves": "0.0.5",
|
||||||
"worker-threads": "^1.0.0"
|
"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": {
|
"ffwasm": {
|
||||||
@@ -1173,6 +1174,16 @@
|
|||||||
"version": "0.0.7",
|
"version": "0.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/fastfile/-/fastfile-0.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/fastfile/-/fastfile-0.0.7.tgz",
|
||||||
"integrity": "sha512-Zk7sdqsV6DsN/rhjULDfCCowPiMDsziTMFicdkrKN80yybr/6YFf9H91ELXN85dVEf6EYkVR5EHkZNc0dMqZKA=="
|
"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"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "circom",
|
"name": "circom",
|
||||||
"version": "0.5.18",
|
"version": "0.5.22",
|
||||||
"description": "Language to generate logic circuits",
|
"description": "Language to generate logic circuits",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"directories": {
|
"directories": {
|
||||||
@@ -30,10 +30,10 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chai": "^4.2.0",
|
"chai": "^4.2.0",
|
||||||
"circom_runtime": "0.0.6",
|
"circom_runtime": "0.1.4",
|
||||||
"fastfile": "0.0.12",
|
"fastfile": "0.0.12",
|
||||||
"ffiasm": "0.0.2",
|
"ffiasm": "0.1.1",
|
||||||
"ffjavascript": "0.2.4",
|
"ffjavascript": "0.2.10",
|
||||||
"ffwasm": "0.0.7",
|
"ffwasm": "0.0.7",
|
||||||
"fnv-plus": "^1.3.1",
|
"fnv-plus": "^1.3.1",
|
||||||
"r1csfile": "0.0.14",
|
"r1csfile": "0.0.14",
|
||||||
|
|||||||
@@ -95,6 +95,10 @@ class CodeBuilderC {
|
|||||||
this.ops.push({op: "CHECKCONSTRAINT", a, b, strErr});
|
this.ops.push({op: "CHECKCONSTRAINT", a, b, strErr});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkAssert(a, strErr) {
|
||||||
|
this.ops.push({op: "CHECKASSERT", a, strErr});
|
||||||
|
}
|
||||||
|
|
||||||
log(val) {
|
log(val) {
|
||||||
this.ops.push({op: "LOG", val});
|
this.ops.push({op: "LOG", val});
|
||||||
}
|
}
|
||||||
@@ -215,6 +219,8 @@ class CodeBuilderC {
|
|||||||
code.push(`${o.fnName}(ctx, ${o.retLabel}, ${o.params.join(",")});`);
|
code.push(`${o.fnName}(ctx, ${o.retLabel}, ${o.params.join(",")});`);
|
||||||
} else if (o.op == "CHECKCONSTRAINT") {
|
} else if (o.op == "CHECKCONSTRAINT") {
|
||||||
code.push(`ctx->checkConstraint(__cIdx, ${ref2src(o.a)}, ${ref2src(o.b)}, "${o.strErr}");`);
|
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") {
|
} else if (o.op == "LOG") {
|
||||||
code.push(`ctx->log(${ref2src(o.val)});`);
|
code.push(`ctx->log(${ref2src(o.val)});`);
|
||||||
}
|
}
|
||||||
@@ -352,6 +358,12 @@ class BuilderC {
|
|||||||
this.components = new BigArray();
|
this.components = new BigArray();
|
||||||
this.usedConstants = {};
|
this.usedConstants = {};
|
||||||
this.verbose = verbose;
|
this.verbose = verbose;
|
||||||
|
|
||||||
|
|
||||||
|
this.sizePointers = {};
|
||||||
|
this.hashMapPointers = {};
|
||||||
|
this.functionIdx = {};
|
||||||
|
this.nCets = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
setHeader(header) {
|
setHeader(header) {
|
||||||
@@ -363,11 +375,11 @@ class BuilderC {
|
|||||||
this.hashMaps[name] = hm;
|
this.hashMaps[name] = hm;
|
||||||
}
|
}
|
||||||
|
|
||||||
addComponentEntriesTable(name, cet) {
|
addComponentEntriesTable(name, cet, idComponent) {
|
||||||
this.componentEntriesTables.push({
|
this.componentEntriesTables[idComponent] = {
|
||||||
name: name,
|
name: name,
|
||||||
cet: cet
|
cet: cet
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
addSizes(name, accSizes) {
|
addSizes(name, accSizes) {
|
||||||
@@ -413,8 +425,8 @@ class BuilderC {
|
|||||||
|
|
||||||
_buildHeader(code) {
|
_buildHeader(code) {
|
||||||
code.push(
|
code.push(
|
||||||
"#include \"circom.h\"",
|
"#include \"circom.hpp\"",
|
||||||
"#include \"calcwit.h\"",
|
"#include \"calcwit.hpp\"",
|
||||||
`#define NSignals ${this.header.NSignals}`,
|
`#define NSignals ${this.header.NSignals}`,
|
||||||
`#define NComponents ${this.header.NComponents}`,
|
`#define NComponents ${this.header.NComponents}`,
|
||||||
`#define NOutputs ${this.header.NOutputs}`,
|
`#define NOutputs ${this.header.NOutputs}`,
|
||||||
@@ -425,70 +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 ) {
|
for (let hmName in this.hashMaps ) {
|
||||||
|
|
||||||
|
while (fdData.pos % 8) fdData.pos++;
|
||||||
|
this.hashMapPointers[hmName] = fdData.pos;
|
||||||
const hm = this.hashMaps[hmName];
|
const hm = this.hashMaps[hmName];
|
||||||
|
|
||||||
let c = `Circom_HashEntry ${hmName}[256] = {`;
|
|
||||||
for (let i=0; i<256; i++) {
|
for (let i=0; i<256; i++) {
|
||||||
c += i>0 ? "," : "";
|
buffV.setUint32(i*12, hm[i] ? parseInt( hm[i][0].slice(8), 16 ) : 0, true);
|
||||||
if (hm[i]) {
|
buffV.setUint32(i*12+4, hm[i] ? parseInt( hm[i][0].slice(0,8), 16 ) : 0, true);
|
||||||
c += `{0x${hm[i][0]}LL, ${hm[i][1]}} /* ${hm[i][2]} */`;
|
buffV.setUint32(i*12+8, hm[i] ? hm[i][1] : 0, true);
|
||||||
} else {
|
|
||||||
c += "{0,0}";
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
c += "};";
|
await fdData.write(buff);
|
||||||
code.push(c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildComponentEntriesTables(code) {
|
async _buildComponentEntriesTables(fdData) {
|
||||||
code.push("// Component Entry tables");
|
|
||||||
|
while (fdData.pos % 8) fdData.pos++;
|
||||||
|
this.pCets = fdData.pos;
|
||||||
for (let i=0; i< this.componentEntriesTables.length; i++) {
|
for (let i=0; i< this.componentEntriesTables.length; i++) {
|
||||||
if ((this.verbose)&&(i%100000 ==0)) console.log(`_buildComponentEntriesTables ${i}/${this.componentEntriesTables.length}`);
|
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;
|
const cet = this.componentEntriesTables[i].cet;
|
||||||
|
|
||||||
code.push(`Circom_ComponentEntry ${cetName}[${cet.length}] = {`);
|
this.components[i].entryTablePointer = fdData.pos;
|
||||||
|
const buff = new Uint8Array(16*cet.length);
|
||||||
|
const buffV = new DataView(buff.buffer);
|
||||||
|
|
||||||
for (let j=0; j<cet.length; j++) {
|
for (let j=0; j<cet.length; j++) {
|
||||||
const ty = cet[j].type == "S" ? "_typeSignal" : "_typeComponent";
|
utils.setUint64(buffV, 16*j+0, this.sizePointers[ cet[j].sizeName]);
|
||||||
code.push(` ${j>0?",":" "}{${cet[j].offset},${cet[j].sizeName}, ${ty}}`);
|
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) {
|
async _buildSizes(fdData) {
|
||||||
code.push("// Sizes");
|
|
||||||
for (let sName in this.sizes) {
|
for (let sName in this.sizes) {
|
||||||
const accSizes = this.sizes[sName];
|
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++) {
|
for (let i=0; i<accSizes.length; i++) {
|
||||||
if (i>0) c += ",";
|
buffV.setUint32(i*4, accSizes[i], true);
|
||||||
c += accSizes[i];
|
|
||||||
}
|
}
|
||||||
c += "};";
|
await fdData.write(buff);
|
||||||
code.push(c);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildConstants(code) {
|
|
||||||
|
async _buildConstants(fdData) {
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
||||||
code.push("// Constants");
|
const frSize = (8 + self.F.n64*8);
|
||||||
code.push(`FrElement _constants[${self.constants.length}] = {`);
|
const buff = new Uint8Array(self.constants.length* frSize);
|
||||||
for (let i=0; i<self.constants.length; i++) {
|
const buffV = new DataView(buff.buffer);
|
||||||
if ((this.verbose)&&(i%1000000 ==0)) console.log(`_buildConstants ${i}/${this.constants.length}`);
|
|
||||||
code.push((i>0 ? "," : " ") + "{" + number2Code(self.constants[i]) + "}");
|
|
||||||
}
|
|
||||||
code.push("};");
|
|
||||||
|
|
||||||
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 minShort = self.F.neg(self.F.e("80000000"));
|
||||||
const maxShort = self.F.e("7FFFFFFF", 16);
|
const maxShort = self.F.e("7FFFFFFF", 16);
|
||||||
|
|
||||||
@@ -496,51 +529,49 @@ class BuilderC {
|
|||||||
&&(self.F.leq(n, maxShort)))
|
&&(self.F.leq(n, maxShort)))
|
||||||
{
|
{
|
||||||
if (self.F.geq(n, self.F.zero)) {
|
if (self.F.geq(n, self.F.zero)) {
|
||||||
return addShortMontgomeryPositive(n);
|
return shortMontgomeryPositive(n);
|
||||||
} else {
|
} else {
|
||||||
return addShortMontgomeryNegative(n);
|
return shortMontgomeryNegative(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return addLongMontgomery(n);
|
return longMontgomery(n);
|
||||||
|
|
||||||
|
|
||||||
function addShortMontgomeryPositive(a) {
|
function shortMontgomeryPositive(a) {
|
||||||
return `${a.toString()}, 0x40000000, { ${getLongString(toMontgomery(a))} }`;
|
buffV.setUint32(offset, Scalar.toNumber(a) , true );
|
||||||
|
buffV.setUint32(offset + 4, 0x40000000 , true );
|
||||||
|
long(buffV, offset + 8, toMontgomery(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function addShortMontgomeryNegative(a) {
|
function shortMontgomeryNegative(a) {
|
||||||
const b = -Scalar.toNumber(self.F.neg(a));
|
const b = -Scalar.toNumber(self.F.neg(a));
|
||||||
return `${b.toString()}, 0x40000000, { ${getLongString(toMontgomery(a))} }`;
|
buffV.setUint32(offset, b , true );
|
||||||
|
buffV.setUint32(offset + 4, 0x40000000 , true );
|
||||||
|
long(buffV, offset + 8, toMontgomery(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
function addLongMontgomery(a) {
|
function longMontgomery(a) {
|
||||||
return `0, 0xC0000000, { ${getLongString(toMontgomery(a))} }`;
|
buffV.setUint32(offset, 0 , true );
|
||||||
|
buffV.setUint32(offset + 4, 0xC0000000 , true );
|
||||||
|
long(buffV, offset + 8, toMontgomery(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLongString(a) {
|
function long(buffV, offset, a) {
|
||||||
let S = "";
|
|
||||||
|
let p = offset;
|
||||||
const arr = Scalar.toArray(a, 0x100000000);
|
const arr = Scalar.toArray(a, 0x100000000);
|
||||||
for (let i=0; i<self.F.n64*2; i+=2) {
|
for (let i=0; i<self.F.n64*2; i++) {
|
||||||
const idx = arr.length-2-i;
|
const idx = arr.length-1-i;
|
||||||
|
|
||||||
if (i>0) S = S + ",";
|
|
||||||
|
|
||||||
if ( idx >=0) {
|
if ( idx >=0) {
|
||||||
let msb = arr[idx].toString(16);
|
buffV.setUint32(p, arr[idx], true);
|
||||||
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";
|
|
||||||
} else {
|
} else {
|
||||||
S += "0LL";
|
buffV.setUint32(p, 0, true);
|
||||||
}
|
}
|
||||||
|
p+= 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
return S;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function toMontgomery(a) {
|
function toMontgomery(a) {
|
||||||
@@ -548,101 +579,132 @@ class BuilderC {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildFunctions(code) {
|
_buildFunctions(code) {
|
||||||
|
const listedFunctions = [];
|
||||||
for (let i=0; i<this.functions.length; i++) {
|
for (let i=0; i<this.functions.length; i++) {
|
||||||
const cfb = this.functions[i];
|
const cfb = this.functions[i];
|
||||||
cfb.build(code);
|
cfb.build(code);
|
||||||
|
if (this.functions[i].type == "COMPONENT") {
|
||||||
|
this.functionIdx[this.functions[i].name] = listedFunctions.length;
|
||||||
|
listedFunctions.push(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildComponents(code) {
|
code.push("// Function Table");
|
||||||
code.push("// Components");
|
code.push(`Circom_ComponentFunction _functionTable[${listedFunctions.length}] = {`);
|
||||||
code.push(`Circom_Component _components[${this.components.length}] = {`);
|
for (let i=0; i<listedFunctions.length; i++) {
|
||||||
|
const sep = i>0 ? " ," : " ";
|
||||||
|
code.push(`${sep}${this.functions[listedFunctions[i]].name}`);
|
||||||
|
}
|
||||||
|
code.push("};");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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++) {
|
for (let i=0; i<this.components.length; i++) {
|
||||||
if ((this.verbose)&&(i%1000000 ==0)) console.log(`_buildComponents ${i}/${this.components.length}`);
|
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 ? " ," : " ";
|
|
||||||
code.push(`${sep}{${c.hashMapName}, ${c.entryTableName}, ${c.functionName}, ${c.nInSignals}, ${c.newThread}}`);
|
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);
|
||||||
}
|
}
|
||||||
code.push("};");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildMapIsInput(code) {
|
async _buildMapIsInput(fdData) {
|
||||||
code.push("// mapIsInput");
|
|
||||||
code.push(`u32 _mapIsInput[${this.mapIsInput.length}] = {`);
|
const buff = new Uint8Array(this.mapIsInput.length * 4);
|
||||||
let line = "";
|
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++) {
|
for (let i=0; i<this.mapIsInput.length; i++) {
|
||||||
if ((this.verbose)&&(i%1000000 ==0)) console.log(`_buildMapIsInput ${i}/${this.mapIsInput.length}`);
|
if ((this.verbose)&&(i%1000000 ==0)) console.log(`_buildMapIsInput ${i}/${this.mapIsInput.length}`);
|
||||||
line += i>0 ? ", " : " ";
|
|
||||||
line += toHex(this.mapIsInput[i]);
|
|
||||||
if (((i+1) % 64)==0) {
|
|
||||||
code.push(" "+line);
|
|
||||||
line = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (line != "") code.push(" "+line);
|
|
||||||
code.push("};");
|
|
||||||
|
|
||||||
function toHex(number) {
|
buffV.setUint32(4*i, this.mapIsInput[i], true);
|
||||||
if (number < 0) number = 0xFFFFFFFF + number + 1;
|
|
||||||
let S=number.toString(16).toUpperCase();
|
|
||||||
while (S.length<8) S = "0" + S;
|
|
||||||
return "0x"+S;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildWit2Sig(code) {
|
await fdData.write(buff);
|
||||||
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++) {
|
for (let i=0; i<this.wit2sig.length; i++) {
|
||||||
if ((this.verbose)&&(i%1000000 ==0)) console.log(`_buildWit2Sig ${i}/${this.wit2sig.length}`);
|
if ((this.verbose)&&(i%1000000 ==0)) console.log(`_buildWit2Sig ${i}/${this.wit2sig.length}`);
|
||||||
line += i>0 ? "," : " ";
|
|
||||||
line += this.wit2sig[i];
|
buffV.setUint32(4*i, this.wit2sig[i], true);
|
||||||
if (((i+1) % 64) == 0) {
|
|
||||||
code.push(" "+line);
|
|
||||||
line = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (line != "") code.push(" "+line);
|
|
||||||
code.push("};");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildCircuitVar(code) {
|
await fdData.write(buff);
|
||||||
|
}
|
||||||
|
|
||||||
code.push(
|
async _buildCircuitVar(fdData) {
|
||||||
"// Circuit Variable",
|
|
||||||
"Circom_Circuit _circuit = {" ,
|
const pP = fdData.pos;
|
||||||
" NSignals,",
|
|
||||||
" NComponents,",
|
const strBuff = new TextEncoder("utf-8").encode(this.header.P.toString());
|
||||||
" NInputs,",
|
await fdData.write(strBuff);
|
||||||
" NOutputs,",
|
|
||||||
" NVars,",
|
const buff = new Uint8Array(72);
|
||||||
" _wit2sig,",
|
const buffV = new DataView(buff.buffer);
|
||||||
" _components,",
|
|
||||||
" _mapIsInput,",
|
utils.setUint64(buffV, 0, this.pWit2Sig, true);
|
||||||
" _constants,",
|
utils.setUint64(buffV, 8, this.pComponents, true);
|
||||||
" __P__",
|
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(fd) {
|
async build(fdCode, fdData) {
|
||||||
const encoder = new TextEncoder("utf-8");
|
const encoder = new TextEncoder("utf-8");
|
||||||
|
fdData.pos = 72;
|
||||||
|
while (fdData.pos % 8) fdData.pos++;
|
||||||
|
|
||||||
const code=new BigArray();
|
const code=new BigArray();
|
||||||
this._buildHeader(code);
|
this._buildHeader(code);
|
||||||
this._buildSizes(code);
|
await this._buildSizes(fdData);
|
||||||
this._buildConstants(code);
|
await this._buildConstants(fdData);
|
||||||
this._buildHashMaps(code);
|
await this._buildHashMaps(fdData);
|
||||||
this._buildComponentEntriesTables(code);
|
await this._buildComponentEntriesTables(fdData);
|
||||||
this._buildFunctions(code);
|
this._buildFunctions(code);
|
||||||
this._buildComponents(code);
|
await this._buildComponents(fdData);
|
||||||
this._buildMapIsInput(code);
|
await this._buildMapIsInput(fdData);
|
||||||
this._buildWit2Sig(code);
|
await this._buildWit2Sig(fdData);
|
||||||
this._buildCircuitVar(code);
|
await this._buildCircuitVar(fdData);
|
||||||
await writeCode(code);
|
await writeCode(code);
|
||||||
|
|
||||||
async function writeCode(c) {
|
async function writeCode(c) {
|
||||||
@@ -651,7 +713,7 @@ class BuilderC {
|
|||||||
await writeCode(c[i]);
|
await writeCode(c[i]);
|
||||||
}
|
}
|
||||||
} else if (typeof c === "string") {
|
} else if (typeof c === "string") {
|
||||||
await fd.write(encoder.encode(c + "\n"));
|
await fdCode.write(encoder.encode(c + "\n"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ async function c_tester(circomFile, _options) {
|
|||||||
const options = Object.assign({}, _options);
|
const options = Object.assign({}, _options);
|
||||||
|
|
||||||
options.cSourceFile = await fastFile.createOverride(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.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");
|
||||||
|
|
||||||
@@ -38,14 +39,15 @@ async function c_tester(circomFile, _options) {
|
|||||||
await compiler(circomFile, options);
|
await compiler(circomFile, options);
|
||||||
|
|
||||||
await options.cSourceFile.close();
|
await options.cSourceFile.close();
|
||||||
|
await options.dataFile.close();
|
||||||
|
|
||||||
const source = await buildZqField(options.p, "Fr");
|
const source = await buildZqField(options.p, "Fr");
|
||||||
|
|
||||||
// console.log(dir.path);
|
// 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.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.hpp"), source.hpp, "utf8");
|
||||||
await fs.promises.writeFile(path.join(dir.path, "fr.c"), source.c, "utf8");
|
await fs.promises.writeFile(path.join(dir.path, "fr.cpp"), source.cpp, "utf8");
|
||||||
|
|
||||||
let pThread = "";
|
let pThread = "";
|
||||||
|
|
||||||
@@ -66,7 +68,7 @@ async function c_tester(circomFile, _options) {
|
|||||||
` ${path.join(cdir, "main.cpp")}` +
|
` ${path.join(cdir, "main.cpp")}` +
|
||||||
` ${path.join(cdir, "calcwit.cpp")}` +
|
` ${path.join(cdir, "calcwit.cpp")}` +
|
||||||
` ${path.join(cdir, "utils.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, "fr.o")}` +
|
||||||
` ${path.join(dir.path, baseName + ".cpp")} ` +
|
` ${path.join(dir.path, baseName + ".cpp")} ` +
|
||||||
` -o ${path.join(dir.path, baseName)}` +
|
` -o ${path.join(dir.path, baseName)}` +
|
||||||
|
|||||||
@@ -384,9 +384,9 @@ module.exports = function buildRuntime(module, builder) {
|
|||||||
"error",
|
"error",
|
||||||
c.i32_const(errs.ACCESSING_NOT_ASSIGNED_SIGNAL.code),
|
c.i32_const(errs.ACCESSING_NOT_ASSIGNED_SIGNAL.code),
|
||||||
c.i32_const(errs.ACCESSING_NOT_ASSIGNED_SIGNAL.pointer),
|
c.i32_const(errs.ACCESSING_NOT_ASSIGNED_SIGNAL.pointer),
|
||||||
c.i32_const(0),
|
c.getLocal("cIdx"),
|
||||||
c.i32_const(0),
|
c.getLocal("component"),
|
||||||
c.i32_const(0),
|
c.getLocal("signal"),
|
||||||
c.i32_const(0)
|
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() {
|
function buildGetNVars() {
|
||||||
const f = module.addFunction("getNVars");
|
const f = module.addFunction("getNVars");
|
||||||
f.setReturnType("i32");
|
f.setReturnType("i32");
|
||||||
@@ -823,6 +852,7 @@ module.exports = function buildRuntime(module, builder) {
|
|||||||
buildComponentFinished();
|
buildComponentFinished();
|
||||||
|
|
||||||
buildCheckConstraint();
|
buildCheckConstraint();
|
||||||
|
buildCheckAssert();
|
||||||
|
|
||||||
buildGetNVars();
|
buildGetNVars();
|
||||||
buildGetFrLen();
|
buildGetFrLen();
|
||||||
|
|||||||
@@ -98,6 +98,9 @@ class CodeBuilderWasm {
|
|||||||
this.ops.push({op: "CHECKCONSTRAINT", a, b, strErr});
|
this.ops.push({op: "CHECKCONSTRAINT", a, b, strErr});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkAssert(a, strErr) {
|
||||||
|
this.ops.push({op: "CHECKASSERT", a, strErr});
|
||||||
|
}
|
||||||
|
|
||||||
concat(cb) {
|
concat(cb) {
|
||||||
this.ops.push(...cb.ops);
|
this.ops.push(...cb.ops);
|
||||||
@@ -332,6 +335,15 @@ class CodeBuilderWasm {
|
|||||||
c.i32_const(this.fnBuilder.builder.module.allocString(o.strErr))
|
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") {
|
} else if (o.op == "LOG") {
|
||||||
code.push(
|
code.push(
|
||||||
c.call(
|
c.call(
|
||||||
|
|||||||
@@ -7,4 +7,5 @@ module.exports = {
|
|||||||
SIGNAL_ASSIGNED_TWICE: {code: 6, str: "Signal assigned twice"},
|
SIGNAL_ASSIGNED_TWICE: {code: 6, str: "Signal assigned twice"},
|
||||||
CONSTRAIN_DOES_NOT_MATCH: {code: 7, str: "Constraint doesn't match"},
|
CONSTRAIN_DOES_NOT_MATCH: {code: 7, str: "Constraint doesn't match"},
|
||||||
MAPISINPUT_DONT_MATCH: {code: 8, str: "MapIsInput don't match"},
|
MAPISINPUT_DONT_MATCH: {code: 8, str: "MapIsInput don't match"},
|
||||||
|
ASSERT_DOES_NOT_MATCH: {code: 9, str: "Assert not satisfied"},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ function buildEntryTables(ctx) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.builder.addComponentEntriesTable(componentEntriesTableName, componentEntriesTable);
|
ctx.builder.addComponentEntriesTable(componentEntriesTableName, componentEntriesTable, i);
|
||||||
|
|
||||||
ctx.components[i].htName = htName;
|
ctx.components[i].htName = htName;
|
||||||
ctx.components[i].etName = componentEntriesTableName;
|
ctx.components[i].etName = componentEntriesTableName;
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ async function compile(srcFile, options) {
|
|||||||
measures.generateC = -performance.now();
|
measures.generateC = -performance.now();
|
||||||
ctx.builder = new BuilderC(options.prime, ctx.verbose);
|
ctx.builder = new BuilderC(options.prime, ctx.verbose);
|
||||||
build(ctx);
|
build(ctx);
|
||||||
await ctx.builder.build(options.cSourceFile);
|
await ctx.builder.build(options.cSourceFile, options.dataFile);
|
||||||
measures.generateC += performance.now();
|
measures.generateC += performance.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -567,9 +567,13 @@ function execFunctionCall(ctx, ast) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ast.name == "assert") {
|
if (ast.name == "assert") {
|
||||||
|
ast.fileName = ctx.fileName;
|
||||||
|
ast.filePath = ctx.filePath;
|
||||||
|
|
||||||
const v = exec(ctx, ast.params[0]);
|
const v = exec(ctx, ast.params[0]);
|
||||||
const ev = val(ctx, v, ast);
|
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];
|
const fnc = ctx.functions[ast.name];
|
||||||
|
|||||||
@@ -723,7 +723,15 @@ function genVarAssignment(ctx, ast, lRef, sels, rRef) {
|
|||||||
|
|
||||||
if (instantiated) {
|
if (instantiated) {
|
||||||
if (offset.used) {
|
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 {
|
} else {
|
||||||
ctx.codeBuilder.copyN(left.label, ["V", offset.value[0]], ["R", right.label], right.sizes[0]);
|
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));
|
ctx.codeBuilder.log(toRefA_Fr1(ctx, ast.params[0], vRef));
|
||||||
return 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 = [];
|
const params = [];
|
||||||
for (let i=0; i<ast.params.length; i++) {
|
for (let i=0; i<ast.params.length; i++) {
|
||||||
const pRef = gen(ctx, ast.params[i]);
|
const pRef = gen(ctx, ast.params[i]);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ module.exports.fnvHash = fnvHash;
|
|||||||
module.exports.sameSizes = sameSizes;
|
module.exports.sameSizes = sameSizes;
|
||||||
module.exports.isDefined = isDefined;
|
module.exports.isDefined = isDefined;
|
||||||
module.exports.accSizes2Str = accSizes2Str;
|
module.exports.accSizes2Str = accSizes2Str;
|
||||||
|
module.exports.setUint64 = setUint64;
|
||||||
|
|
||||||
function ident(text) {
|
function ident(text) {
|
||||||
if (typeof text === "string") {
|
if (typeof text === "string") {
|
||||||
@@ -90,6 +91,14 @@ function accSizes2Str(sizes) {
|
|||||||
return `[${sizes[0]/sizes[1]}]`+accSizes2Str(sizes.slice(1));
|
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