mirror of
https://github.com/arnaucube/circom.git
synced 2026-02-07 03:06:42 +01:00
Compare commits
20 Commits
v0.5.26
...
fix/c_test
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a320978214 | ||
|
|
0d5077106a | ||
|
|
b68c9fa5d2 | ||
|
|
94cb37bd9e | ||
|
|
9f15dd2e29 | ||
|
|
334697dd0c | ||
|
|
6c48e9ba01 | ||
|
|
42162b10c1 | ||
|
|
a84873161f | ||
|
|
9bf1354bf1 | ||
|
|
ed4c4b4de0 | ||
|
|
a1f3f714ea | ||
|
|
dafc9db614 | ||
|
|
6e4a192c6a | ||
|
|
e1286c29c7 | ||
|
|
a002bcbc25 | ||
|
|
f9f1d0c13e | ||
|
|
fc01aad8b6 | ||
|
|
3d5aa14cdc | ||
|
|
5dc54bb7d2 |
@@ -1,12 +1,15 @@
|
|||||||
# Circom
|
# Circom
|
||||||
|
|
||||||
Circom is a language designed to write arithmetic circuits that can be used in zero knowledge proofs.
|
Circom is a language designed to write arithmetic circuits that can be used in zero-knowledge proofs.
|
||||||
|
|
||||||
In particular, it is designed to work in [zksnarks JavaScript library](https://github.com/iden3/zksnark).
|
In particular, it is designed to work in [zksnarks JavaScript library](https://github.com/iden3/zksnark).
|
||||||
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
### Circom Docs
|
||||||
|
|
||||||
|
You can read the details of circom in [the documentation webpage](https://docs.circom.io/).
|
||||||
|
|
||||||
### Tutorial
|
### Tutorial
|
||||||
|
|
||||||
A good starting point [is this tutorial](https://github.com/iden3/circom/blob/master/TUTORIAL.md)
|
A good starting point [is this tutorial](https://github.com/iden3/circom/blob/master/TUTORIAL.md)
|
||||||
|
|||||||
79
package-lock.json
generated
79
package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "circom",
|
"name": "circom",
|
||||||
"version": "0.5.26",
|
"version": "0.5.34",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -30,6 +30,11 @@
|
|||||||
"js-tokens": "^4.0.0"
|
"js-tokens": "^4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@iden3/bigarray": {
|
||||||
|
"version": "0.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@iden3/bigarray/-/bigarray-0.0.2.tgz",
|
||||||
|
"integrity": "sha512-Xzdyxqm1bOFF6pdIsiHLLl3HkSLjbhqJHVyqaTxXt3RqXBEnmsUmEW47H7VOi/ak7TdkRpNkxjyK5Zbkm+y52g=="
|
||||||
|
},
|
||||||
"@types/color-name": {
|
"@types/color-name": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
|
||||||
@@ -203,12 +208,24 @@
|
|||||||
"integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII="
|
"integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII="
|
||||||
},
|
},
|
||||||
"circom_runtime": {
|
"circom_runtime": {
|
||||||
"version": "0.1.5",
|
"version": "0.1.9",
|
||||||
"resolved": "https://registry.npmjs.org/circom_runtime/-/circom_runtime-0.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/circom_runtime/-/circom_runtime-0.1.9.tgz",
|
||||||
"integrity": "sha512-BT3d9VCrH/rBRbThDXG731JwezKyskxyE46nACO6Tt/jaorn27LDxFDORdAAjyD0RAoBt+6FpaTp3qlYSx7Pjg==",
|
"integrity": "sha512-eh34quaGpeEWXthnhmC9zpoBL/5zJ0mGDbPT/plb/xVmFaKxJDcLuCr2sma5s3il8AYlEIb/nbqytojyI3TWDQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"ffjavascript": "0.2.10",
|
"ffjavascript": "0.2.10",
|
||||||
"fnv-plus": "^1.3.1"
|
"fnv-plus": "^1.3.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ffjavascript": {
|
||||||
|
"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",
|
||||||
|
"wasmcurves": "0.0.5",
|
||||||
|
"worker-threads": "^1.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cjson": {
|
"cjson": {
|
||||||
@@ -566,9 +583,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"fastfile": {
|
"fastfile": {
|
||||||
"version": "0.0.16",
|
"version": "0.0.18",
|
||||||
"resolved": "https://registry.npmjs.org/fastfile/-/fastfile-0.0.16.tgz",
|
"resolved": "https://registry.npmjs.org/fastfile/-/fastfile-0.0.18.tgz",
|
||||||
"integrity": "sha512-2sX5M4JQWAVmS2GojuRPA759aTOs5PyUEpZHjaecNtWBU9CfRFlTf2aBqFG2PJJnrcrawBBAQ1s0QSO+qQ4Zmg=="
|
"integrity": "sha512-q03PTKc+wptis4WmuFOwPNQx2p5myFUrl/dMgRlW9mymc1Egyc14JPHgiGnWK+sJ0+dBl2Vwtfh5GfSQltYOpw=="
|
||||||
},
|
},
|
||||||
"ffiasm": {
|
"ffiasm": {
|
||||||
"version": "0.1.1",
|
"version": "0.1.1",
|
||||||
@@ -581,19 +598,19 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ffjavascript": {
|
"ffjavascript": {
|
||||||
"version": "0.2.10",
|
"version": "0.2.22",
|
||||||
"resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.10.tgz",
|
"resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.22.tgz",
|
||||||
"integrity": "sha512-GQI6gHYYG5/iD4Kt3VzezzK7fARJzP0zkc82V/+JAdjfeKBXhDSo5rpKFuK3cDcrdW0Fu2emuYNMEAuFqhEQvQ==",
|
"integrity": "sha512-EsVqap2Txm17bKW0z/jXCX3M7rQ++nQUAJY8alWDpyhjRj90xjl6GLeVSKZQ8rOFDQ/SFFXcEB8w9X8Boxid+w==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"big-integer": "^1.6.48",
|
"big-integer": "^1.6.48",
|
||||||
"wasmcurves": "0.0.5",
|
"wasmcurves": "0.0.12",
|
||||||
"worker-threads": "^1.0.0"
|
"worker-threads": "^1.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"wasmcurves": {
|
"wasmcurves": {
|
||||||
"version": "0.0.5",
|
"version": "0.0.12",
|
||||||
"resolved": "https://registry.npmjs.org/wasmcurves/-/wasmcurves-0.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/wasmcurves/-/wasmcurves-0.0.12.tgz",
|
||||||
"integrity": "sha512-BmI4GXLjLawGg2YkvHa8zRsnWec+d1uwoxE+Iov8cqOpDL7GA5XO2pk2yuDbXHMzwIug2exnKot3baRZ86R0pA==",
|
"integrity": "sha512-1Jl9mkatyHSNj80ILjf85SZUNuZQBCkTjJlhzqHnZQXUmIimCIWkugaVaYNjozLs1Gun4h/keZe1MBeBN0sRpg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"big-integer": "^1.6.42",
|
"big-integer": "^1.6.42",
|
||||||
"blakejs": "^1.1.0"
|
"blakejs": "^1.1.0"
|
||||||
@@ -1162,29 +1179,13 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"r1csfile": {
|
"r1csfile": {
|
||||||
"version": "0.0.14",
|
"version": "0.0.16",
|
||||||
"resolved": "https://registry.npmjs.org/r1csfile/-/r1csfile-0.0.14.tgz",
|
"resolved": "https://registry.npmjs.org/r1csfile/-/r1csfile-0.0.16.tgz",
|
||||||
"integrity": "sha512-7m4eWpnbjkwGGUaRmIAJc4w+HvaeBPJXUKHIqLkHeD9Yyjem6/EHmlgDVl+4hWNWGZqdhXuMqWSH9+O6QOXBdw==",
|
"integrity": "sha512-A2jRVWzGgmXeG2lVAc0H4suJmzt50it5UvBnycJgBCpMXM3tH/M6RguP7nvs6suY/yYnkN6jX6iTScSiDUF3FA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"fastfile": "0.0.7",
|
"@iden3/bigarray": "0.0.2",
|
||||||
"ffjavascript": "0.2.4"
|
"fastfile": "0.0.18",
|
||||||
},
|
"ffjavascript": "0.2.22"
|
||||||
"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": {
|
"regexpp": {
|
||||||
@@ -1483,9 +1484,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"wasmcurves": {
|
"wasmcurves": {
|
||||||
"version": "0.0.4",
|
"version": "0.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/wasmcurves/-/wasmcurves-0.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/wasmcurves/-/wasmcurves-0.0.5.tgz",
|
||||||
"integrity": "sha512-c/Tob+F/7jJhep1b2qtj54r4nkGaRifNbQ1OJx8cBBFH1RlHbWIbISHWONClOxiVwy/JZOpbN4SgvSX/4lF80A==",
|
"integrity": "sha512-BmI4GXLjLawGg2YkvHa8zRsnWec+d1uwoxE+Iov8cqOpDL7GA5XO2pk2yuDbXHMzwIug2exnKot3baRZ86R0pA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"big-integer": "^1.6.42",
|
"big-integer": "^1.6.42",
|
||||||
"blakejs": "^1.1.0"
|
"blakejs": "^1.1.0"
|
||||||
|
|||||||
10
package.json
10
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "circom",
|
"name": "circom",
|
||||||
"version": "0.5.26",
|
"version": "0.5.34",
|
||||||
"description": "Language to generate logic circuits",
|
"description": "Language to generate logic circuits",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"directories": {
|
"directories": {
|
||||||
@@ -30,13 +30,13 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chai": "^4.2.0",
|
"chai": "^4.2.0",
|
||||||
"circom_runtime": "0.1.5",
|
"circom_runtime": "0.1.9",
|
||||||
"fastfile": "0.0.16",
|
"fastfile": "0.0.18",
|
||||||
"ffiasm": "0.1.1",
|
"ffiasm": "0.1.1",
|
||||||
"ffjavascript": "0.2.10",
|
"ffjavascript": "0.2.22",
|
||||||
"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.16",
|
||||||
"tmp-promise": "^2.0.2",
|
"tmp-promise": "^2.0.2",
|
||||||
"wasmbuilder": "0.0.10"
|
"wasmbuilder": "0.0.10"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -59,8 +59,9 @@ class CodeBuilderC {
|
|||||||
this.ops.push({op: "SETSIGNAL", component, signal, value});
|
this.ops.push({op: "SETSIGNAL", component, signal, value});
|
||||||
}
|
}
|
||||||
|
|
||||||
getSignal(dLabel, component, signal) {
|
getSignal(dLabel, component, signal, n) {
|
||||||
this.ops.push({op: "GETSIGNAL", dLabel, component, signal});
|
if (typeof(n) == "undefined") n=1;
|
||||||
|
this.ops.push({op: "GETSIGNAL", dLabel, component, signal, n});
|
||||||
}
|
}
|
||||||
|
|
||||||
copyN(dLabel, offset, src, n) {
|
copyN(dLabel, offset, src, n) {
|
||||||
@@ -181,7 +182,7 @@ class CodeBuilderC {
|
|||||||
} else if (o.op == "SETSIGNAL") {
|
} else if (o.op == "SETSIGNAL") {
|
||||||
code.push(`ctx->setSignal(__cIdx, ${ref2src(o.component)}, ${ref2src(o.signal)}, ${ref2src(o.value)});`);
|
code.push(`ctx->setSignal(__cIdx, ${ref2src(o.component)}, ${ref2src(o.signal)}, ${ref2src(o.value)});`);
|
||||||
} else if (o.op == "GETSIGNAL") {
|
} else if (o.op == "GETSIGNAL") {
|
||||||
code.push(`ctx->getSignal(__cIdx, ${ref2src(o.component)}, ${ref2src(o.signal)}, ${o.dLabel});`);
|
code.push(`ctx->multiGetSignal(__cIdx, ${ref2src(o.component)}, ${ref2src(o.signal)}, ${o.dLabel}, ${o.n});`);
|
||||||
} else if (o.op == "COPYN") {
|
} else if (o.op == "COPYN") {
|
||||||
const oS = ref2src(o.offset);
|
const oS = ref2src(o.offset);
|
||||||
const dLabel = (oS != "0") ? (o.dLabel + "+" + oS) : o.dLabel;
|
const dLabel = (oS != "0") ? (o.dLabel + "+" + oS) : o.dLabel;
|
||||||
@@ -432,6 +433,7 @@ class BuilderC {
|
|||||||
`#define NOutputs ${this.header.NOutputs}`,
|
`#define NOutputs ${this.header.NOutputs}`,
|
||||||
`#define NInputs ${this.header.NInputs}`,
|
`#define NInputs ${this.header.NInputs}`,
|
||||||
`#define NVars ${this.header.NVars}`,
|
`#define NVars ${this.header.NVars}`,
|
||||||
|
`#define NPublic ${this.header.NPublic}`,
|
||||||
`#define __P__ "${this.header.P.toString()}"`,
|
`#define __P__ "${this.header.P.toString()}"`,
|
||||||
""
|
""
|
||||||
);
|
);
|
||||||
@@ -661,19 +663,14 @@ class BuilderC {
|
|||||||
|
|
||||||
async _buildCircuitVar(fdData) {
|
async _buildCircuitVar(fdData) {
|
||||||
|
|
||||||
const pP = fdData.pos;
|
const buff = new Uint8Array(76);
|
||||||
|
|
||||||
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);
|
const buffV = new DataView(buff.buffer);
|
||||||
|
|
||||||
utils.setUint64(buffV, 0, this.pWit2Sig, true);
|
utils.setUint64(buffV, 0, this.pWit2Sig, true);
|
||||||
utils.setUint64(buffV, 8, this.pComponents, true);
|
utils.setUint64(buffV, 8, this.pComponents, true);
|
||||||
utils.setUint64(buffV, 16, this.pMapIsInput, true);
|
utils.setUint64(buffV, 16, this.pMapIsInput, true);
|
||||||
utils.setUint64(buffV, 24, this.pConstants, true);
|
utils.setUint64(buffV, 24, this.pConstants, true);
|
||||||
utils.setUint64(buffV, 32, pP, true);
|
utils.setUint64(buffV, 32, this.pPriemStr, true);
|
||||||
utils.setUint64(buffV, 40, this.pCets, true);
|
utils.setUint64(buffV, 40, this.pCets, true);
|
||||||
|
|
||||||
buffV.setUint32(48, this.header.NSignals, true);
|
buffV.setUint32(48, this.header.NSignals, true);
|
||||||
@@ -682,20 +679,32 @@ class BuilderC {
|
|||||||
buffV.setUint32(60, this.header.NInputs, true);
|
buffV.setUint32(60, this.header.NInputs, true);
|
||||||
buffV.setUint32(64, this.header.NVars, true);
|
buffV.setUint32(64, this.header.NVars, true);
|
||||||
buffV.setUint32(68, this.nCets, true);
|
buffV.setUint32(68, this.nCets, true);
|
||||||
|
buffV.setUint32(72, this.header.NPublic, true);
|
||||||
|
|
||||||
fdData.pos = 0;
|
fdData.pos = 0;
|
||||||
|
|
||||||
await fdData.write(buff);
|
await fdData.write(buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _buildPrimeStr(fdData) {
|
||||||
|
this.pPriemStr = fdData.pos;
|
||||||
|
const strBuff = new TextEncoder("utf-8").encode(this.header.P.toString());
|
||||||
|
await fdData.write(strBuff);
|
||||||
|
|
||||||
|
const zB = new Uint8Array(1);
|
||||||
|
zB[0] =0;
|
||||||
|
await fdData.write(zB);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
async build(fdCode, fdData) {
|
async build(fdCode, fdData) {
|
||||||
const encoder = new TextEncoder("utf-8");
|
const encoder = new TextEncoder("utf-8");
|
||||||
fdData.pos = 72;
|
fdData.pos = 76;
|
||||||
while (fdData.pos % 8) fdData.pos++;
|
while (fdData.pos % 8) fdData.pos++;
|
||||||
|
|
||||||
const code=new BigArray();
|
const code=new BigArray();
|
||||||
this._buildHeader(code);
|
this._buildHeader(code);
|
||||||
|
await this._buildPrimeStr(fdData);
|
||||||
await this._buildSizes(fdData);
|
await this._buildSizes(fdData);
|
||||||
await this._buildConstants(fdData);
|
await this._buildConstants(fdData);
|
||||||
await this._buildHashMaps(fdData);
|
await this._buildHashMaps(fdData);
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ class CTester {
|
|||||||
const b = evalLC(constraint[1]);
|
const b = evalLC(constraint[1]);
|
||||||
const c = evalLC(constraint[2]);
|
const c = evalLC(constraint[2]);
|
||||||
|
|
||||||
assert (F.sub(F.mul(a,b), c).isZero(), "Constraint doesn't match");
|
assert (F.isZero(F.sub(F.mul(a,b), c)), "Constraint doesn't match");
|
||||||
}
|
}
|
||||||
|
|
||||||
function evalLC(lc) {
|
function evalLC(lc) {
|
||||||
|
|||||||
@@ -412,6 +412,42 @@ module.exports = function buildRuntime(module, builder) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildMultiGetSignal() {
|
||||||
|
const f = module.addFunction("multiGetSignal");
|
||||||
|
f.addParam("cIdx", "i32");
|
||||||
|
f.addParam("pR", "i32");
|
||||||
|
f.addParam("component", "i32");
|
||||||
|
f.addParam("signal", "i32");
|
||||||
|
f.addParam("n", "i32");
|
||||||
|
f.addLocal("i", "i32");
|
||||||
|
|
||||||
|
const c = f.getCodeBuilder();
|
||||||
|
|
||||||
|
f.addCode(
|
||||||
|
c.setLocal("i", c.i32_const(0)),
|
||||||
|
c.block(c.loop(
|
||||||
|
c.br_if(1, c.i32_eq(c.getLocal("i"), c.getLocal("n"))),
|
||||||
|
c.call(
|
||||||
|
"getSignal",
|
||||||
|
c.getLocal("cIdx"),
|
||||||
|
c.i32_add(
|
||||||
|
c.getLocal("pR"),
|
||||||
|
c.i32_mul(
|
||||||
|
c.getLocal("i"),
|
||||||
|
c.i32_const(builder.sizeFr)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
c.getLocal("component"),
|
||||||
|
c.i32_add(
|
||||||
|
c.getLocal("signal"),
|
||||||
|
c.getLocal("i")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
c.setLocal("i", c.i32_add(c.getLocal("i"), c.i32_const(1))),
|
||||||
|
c.br(0)
|
||||||
|
))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function buildSetSignal() {
|
function buildSetSignal() {
|
||||||
const f = module.addFunction("setSignal");
|
const f = module.addFunction("setSignal");
|
||||||
@@ -473,7 +509,7 @@ module.exports = function buildRuntime(module, builder) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
f.addCode(
|
f.addCode(
|
||||||
c.if( // If ( mapIsInput[s >> 5] & 1 << (s & 0x1f) )
|
c.if( // If ( mapIsInput[s >> 5] & (1 << (s & 0x1f)) )
|
||||||
c.i32_and(
|
c.i32_and(
|
||||||
c.i32_load(
|
c.i32_load(
|
||||||
c.i32_add(
|
c.i32_add(
|
||||||
@@ -657,6 +693,15 @@ module.exports = function buildRuntime(module, builder) {
|
|||||||
f.addCode(c.i32_const(builder.header.NVars));
|
f.addCode(c.i32_const(builder.header.NVars));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildGetNPublic() {
|
||||||
|
const f = module.addFunction("getNPublic");
|
||||||
|
f.setReturnType("i32");
|
||||||
|
|
||||||
|
const c = f.getCodeBuilder();
|
||||||
|
|
||||||
|
f.addCode(c.i32_const(builder.header.NPublic));
|
||||||
|
}
|
||||||
|
|
||||||
function buildGetFrLen() {
|
function buildGetFrLen() {
|
||||||
const f = module.addFunction("getFrLen");
|
const f = module.addFunction("getFrLen");
|
||||||
f.setReturnType("i32");
|
f.setReturnType("i32");
|
||||||
@@ -847,6 +892,7 @@ module.exports = function buildRuntime(module, builder) {
|
|||||||
|
|
||||||
buildGetSignal();
|
buildGetSignal();
|
||||||
buildSetSignal();
|
buildSetSignal();
|
||||||
|
buildMultiGetSignal();
|
||||||
|
|
||||||
buildComponentStarted();
|
buildComponentStarted();
|
||||||
buildComponentFinished();
|
buildComponentFinished();
|
||||||
@@ -855,6 +901,7 @@ module.exports = function buildRuntime(module, builder) {
|
|||||||
buildCheckAssert();
|
buildCheckAssert();
|
||||||
|
|
||||||
buildGetNVars();
|
buildGetNVars();
|
||||||
|
buildGetNPublic();
|
||||||
buildGetFrLen();
|
buildGetFrLen();
|
||||||
buildGetPWitness();
|
buildGetPWitness();
|
||||||
buildGetPRawPrime();
|
buildGetPRawPrime();
|
||||||
@@ -864,9 +911,11 @@ module.exports = function buildRuntime(module, builder) {
|
|||||||
|
|
||||||
module.exportFunction("init");
|
module.exportFunction("init");
|
||||||
module.exportFunction("getNVars");
|
module.exportFunction("getNVars");
|
||||||
|
module.exportFunction("getNPublic");
|
||||||
module.exportFunction("getFrLen");
|
module.exportFunction("getFrLen");
|
||||||
module.exportFunction("getSignalOffset32");
|
module.exportFunction("getSignalOffset32");
|
||||||
module.exportFunction("setSignal");
|
module.exportFunction("setSignal");
|
||||||
|
module.exportFunction("multiGetSignal");
|
||||||
module.exportFunction("getPWitness");
|
module.exportFunction("getPWitness");
|
||||||
module.exportFunction("Fr_toInt");
|
module.exportFunction("Fr_toInt");
|
||||||
module.exportFunction("getPRawPrime");
|
module.exportFunction("getPRawPrime");
|
||||||
|
|||||||
@@ -62,8 +62,9 @@ class CodeBuilderWasm {
|
|||||||
this.ops.push({op: "SETSIGNAL", component, signal, value});
|
this.ops.push({op: "SETSIGNAL", component, signal, value});
|
||||||
}
|
}
|
||||||
|
|
||||||
getSignal(dLabel, component, signal) {
|
getSignal(dLabel, component, signal, n) {
|
||||||
this.ops.push({op: "GETSIGNAL", dLabel, component, signal});
|
if (typeof n == "undefined") n=1;
|
||||||
|
this.ops.push({op: "GETSIGNAL", dLabel, component, signal, n});
|
||||||
}
|
}
|
||||||
|
|
||||||
copyN(dLabel, offset, src, n) {
|
copyN(dLabel, offset, src, n) {
|
||||||
@@ -251,11 +252,12 @@ class CodeBuilderWasm {
|
|||||||
} else if (o.op == "GETSIGNAL") {
|
} else if (o.op == "GETSIGNAL") {
|
||||||
code.push(
|
code.push(
|
||||||
c.call(
|
c.call(
|
||||||
"getSignal",
|
"multiGetSignal",
|
||||||
c.getLocal("cIdx"),
|
c.getLocal("cIdx"),
|
||||||
this.fnBuilder._getPtr(c, o.dLabel),
|
this.fnBuilder._getPtr(c, o.dLabel),
|
||||||
this.fnBuilder._deRefInt(c, o.component),
|
this.fnBuilder._deRefInt(c, o.component),
|
||||||
this.fnBuilder._deRefInt(c, o.signal)
|
this.fnBuilder._deRefInt(c, o.signal),
|
||||||
|
c.i32_const(o.n)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
} else if (o.op == "COPYN") {
|
} else if (o.op == "COPYN") {
|
||||||
@@ -779,20 +781,21 @@ class BuilderWasm {
|
|||||||
|
|
||||||
_buildHeader(module) {
|
_buildHeader(module) {
|
||||||
|
|
||||||
this.pCircuit = module.alloc(48);
|
this.pCircuit = module.alloc(52);
|
||||||
|
|
||||||
this.pNSignals = this.pCircuit;
|
this.pNSignals = this.pCircuit;
|
||||||
this.pNComponents = this.pCircuit + 4;
|
this.pNComponents = this.pCircuit + 4;
|
||||||
this.pNInputs = this.pCircuit + 8;
|
this.pNInputs = this.pCircuit + 8;
|
||||||
this.pNOutputs = this.pCircuit + 12;
|
this.pNOutputs = this.pCircuit + 12;
|
||||||
this.pNVars = this.pCircuit + 16;
|
this.pNVars = this.pCircuit + 16;
|
||||||
this.ppWit2sig = this.pCircuit + 20;
|
this.pNPublic = this.pCircuit + 20;
|
||||||
this.ppComponents = this.pCircuit + 24;
|
this.ppWit2sig = this.pCircuit + 24;
|
||||||
this.ppMapIsInput = this.pCircuit + 28;
|
this.ppComponents = this.pCircuit + 28;
|
||||||
this.ppConstants = this.pCircuit + 32;
|
this.ppMapIsInput = this.pCircuit + 32;
|
||||||
this.ppSignals = this.pCircuit + 36;
|
this.ppConstants = this.pCircuit + 36;
|
||||||
this.ppInputSignalsToTrigger = this.pCircuit + 40;
|
this.ppSignals = this.pCircuit + 40;
|
||||||
this.ppSignalsAssigned = this.pCircuit + 44;
|
this.ppInputSignalsToTrigger = this.pCircuit + 44;
|
||||||
|
this.ppSignalsAssigned = this.pCircuit + 48;
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildSizes(module) {
|
_buildSizes(module) {
|
||||||
@@ -983,6 +986,7 @@ class BuilderWasm {
|
|||||||
module.addData(this.pNInputs, intToBytes32(this.header.NInputs));
|
module.addData(this.pNInputs, intToBytes32(this.header.NInputs));
|
||||||
module.addData(this.pNOutputs, intToBytes32(this.header.NOutputs));
|
module.addData(this.pNOutputs, intToBytes32(this.header.NOutputs));
|
||||||
module.addData(this.pNVars, intToBytes32(this.header.NVars));
|
module.addData(this.pNVars, intToBytes32(this.header.NVars));
|
||||||
|
module.addData(this.pNPublic, intToBytes32(this.header.NPublic));
|
||||||
module.addData(this.ppWit2sig, intToBytes32(this.pWit2sig));
|
module.addData(this.ppWit2sig, intToBytes32(this.pWit2sig));
|
||||||
module.addData(this.ppComponents, intToBytes32(this.pComponents));
|
module.addData(this.ppComponents, intToBytes32(this.pComponents));
|
||||||
module.addData(this.ppMapIsInput, intToBytes32(this.pMapIsInput));
|
module.addData(this.ppMapIsInput, intToBytes32(this.pMapIsInput));
|
||||||
|
|||||||
@@ -196,6 +196,7 @@ function buildHeader(ctx) {
|
|||||||
NInputs: ctx.components[ ctx.getComponentIdx("main") ].nInSignals,
|
NInputs: ctx.components[ ctx.getComponentIdx("main") ].nInSignals,
|
||||||
NOutputs: ctx.totals[ ctx.stOUTPUT ],
|
NOutputs: ctx.totals[ ctx.stOUTPUT ],
|
||||||
NVars: ctx.totals[ctx.stONE] + ctx.totals[ctx.stOUTPUT] + ctx.totals[ctx.stPUBINPUT] + ctx.totals[ctx.stPRVINPUT] + ctx.totals[ctx.stINTERNAL],
|
NVars: ctx.totals[ctx.stONE] + ctx.totals[ctx.stOUTPUT] + ctx.totals[ctx.stPUBINPUT] + ctx.totals[ctx.stPRVINPUT] + ctx.totals[ctx.stINTERNAL],
|
||||||
|
NPublic: ctx.totals[ctx.stOUTPUT] + ctx.totals[ctx.stPUBINPUT],
|
||||||
P: ctx.F.p
|
P: ctx.F.p
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,10 +81,6 @@ async function compile(srcFile, options) {
|
|||||||
throw new Error("A main component must be defined");
|
throw new Error("A main component must be defined");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.verbose) console.log("Classify Signals");
|
|
||||||
measures.classifySignals = -performance.now();
|
|
||||||
classifySignals(ctx);
|
|
||||||
measures.classifySignals += performance.now();
|
|
||||||
|
|
||||||
if (ctx.verbose) console.log("Reduce Constants");
|
if (ctx.verbose) console.log("Reduce Constants");
|
||||||
measures.reduceConstants = -performance.now();
|
measures.reduceConstants = -performance.now();
|
||||||
@@ -108,9 +104,13 @@ async function compile(srcFile, options) {
|
|||||||
measures.reduceConstraints += performance.now();
|
measures.reduceConstraints += performance.now();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.verbose) console.log("NConstraints After: "+ctx.constraints.length);
|
if (ctx.verbose) console.log("NConstraints After: "+ctx.constraints.length);
|
||||||
|
|
||||||
|
if (ctx.verbose) console.log("Classify Signals");
|
||||||
|
measures.classifySignals = -performance.now();
|
||||||
|
classifySignals(ctx);
|
||||||
|
measures.classifySignals += performance.now();
|
||||||
|
|
||||||
measures.generateWitnessNames = -performance.now();
|
measures.generateWitnessNames = -performance.now();
|
||||||
generateWitnessNames(ctx);
|
generateWitnessNames(ctx);
|
||||||
measures.generateWitnessNames += performance.now();
|
measures.generateWitnessNames += performance.now();
|
||||||
@@ -183,28 +183,36 @@ function classifySignals(ctx) {
|
|||||||
|
|
||||||
function priorize(t1, t2) {
|
function priorize(t1, t2) {
|
||||||
if ((t1 == ERROR) || (t2==ERROR)) return ERROR;
|
if ((t1 == ERROR) || (t2==ERROR)) return ERROR;
|
||||||
if (t1 == ctx.stINTERNAL) {
|
|
||||||
return t2;
|
|
||||||
} else if (t2==ctx.stINTERNAL) {
|
|
||||||
return t1;
|
|
||||||
}
|
|
||||||
if ((t1 == ctx.stONE) || (t2 == ctx.stONE)) return ctx.stONE;
|
if ((t1 == ctx.stONE) || (t2 == ctx.stONE)) return ctx.stONE;
|
||||||
if ((t1 == ctx.stOUTPUT) || (t2 == ctx.stOUTPUT)) return ctx.stOUTPUT;
|
if ((t1 == ctx.stOUTPUT) || (t2 == ctx.stOUTPUT)) return ctx.stOUTPUT;
|
||||||
|
if ((t1 == ctx.stPUBINPUT) || (t2 == ctx.stPUBINPUT)) return ctx.stPUBINPUT;
|
||||||
|
if ((t1 == ctx.stPRVINPUT) || (t2 == ctx.stPRVINPUT)) return ctx.stPRVINPUT;
|
||||||
|
if ((t1 == ctx.stINTERNAL) || (t2 == ctx.stINTERNAL)) return ctx.stINTERNAL;
|
||||||
if ((t1 == ctx.stCONSTANT) || (t2 == ctx.stCONSTANT)) return ctx.stCONSTANT;
|
if ((t1 == ctx.stCONSTANT) || (t2 == ctx.stCONSTANT)) return ctx.stCONSTANT;
|
||||||
if ((t1 == ctx.stDISCARDED) || (t2 == ctx.stDISCARDED)) return ctx.stDISCARDED;
|
if ((t1 == ctx.stDISCARDED) || (t2 == ctx.stDISCARDED)) return ctx.stDISCARDED;
|
||||||
if (t1!=t2) return ERROR;
|
if (t1!=t2) return ERROR;
|
||||||
return t1;
|
return t1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (let i=0; i<ctx.constraints.length; i++) {
|
||||||
|
if ((ctx.verbose)&&(i%100000 == 0)) console.log(`marking as internal: ${i}/${ctx.constraints.length}`);
|
||||||
|
|
||||||
|
const c = ctx.constraints[i];
|
||||||
|
for (let s in c.a.coefs) ctx.signals[s].c = ctx.stINTERNAL;
|
||||||
|
for (let s in c.b.coefs) ctx.signals[s].c = ctx.stINTERNAL;
|
||||||
|
for (let s in c.c.coefs) ctx.signals[s].c = ctx.stINTERNAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// First classify the signals
|
// First classify the signals
|
||||||
for (let s=0; s<ctx.signals.length; s++) {
|
for (let s=0; s<ctx.signals.length; s++) {
|
||||||
if ((ctx.verbose)&&(s%100000 == 0)) console.log(`classify signals: ${s}/${ctx.signals.length}`);
|
if ((ctx.verbose)&&(s%100000 == 0)) console.log(`classify signals: ${s}/${ctx.signals.length}`);
|
||||||
const signal = ctx.signals[s];
|
const signal = ctx.signals[s];
|
||||||
let tAll = ctx.stINTERNAL;
|
let tAll = ctx.stDISCARDED;
|
||||||
let lSignal = signal;
|
let lSignal = signal;
|
||||||
let end = false;
|
let end = false;
|
||||||
while (!end) {
|
while (!end) {
|
||||||
let t = lSignal.c || ctx.stINTERNAL;
|
let t = lSignal.c || ctx.stDISCARDED;
|
||||||
if (s == 0) {
|
if (s == 0) {
|
||||||
t = ctx.stONE;
|
t = ctx.stONE;
|
||||||
} else if (lSignal.o & ctx.MAIN) {
|
} else if (lSignal.o & ctx.MAIN) {
|
||||||
@@ -340,23 +348,31 @@ async function reduceConstrains(ctx) {
|
|||||||
possibleConstraints[i] = ctx.constraints.length - i -1;
|
possibleConstraints[i] = ctx.constraints.length - i -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let totalRemoved = 0;
|
||||||
while (possibleConstraints.length >0) {
|
while (possibleConstraints.length >0) {
|
||||||
if (possibleConstraints.length>1<<20) {
|
if (possibleConstraints.length>1<<20) {
|
||||||
nextPossibleConstraints = new BigArray();
|
nextPossibleConstraints = new BigArray();
|
||||||
} else {
|
} else {
|
||||||
nextPossibleConstraints = {};
|
nextPossibleConstraints = {};
|
||||||
}
|
}
|
||||||
removedSignals = new BigArray();
|
removedSignals = {};
|
||||||
nRemoved = 0;
|
nRemoved = 0;
|
||||||
lIdx = new BigArray();
|
lIdx = {};
|
||||||
for (let i=0;i<possibleConstraints.length;i++) {
|
for (let i=0;i<possibleConstraints.length;i++) {
|
||||||
if ((ctx.verbose)&&(i%10000 == 0)) {
|
if ((ctx.verbose)&&(i%10000 == 0)) {
|
||||||
await Promise.resolve();
|
await Promise.resolve();
|
||||||
console.log(`reducing constraints: ${i}/${possibleConstraints.length} reduced: ${nRemoved}`);
|
console.log(`reducing constraints: ${i}/${possibleConstraints.length} reduced: ${nRemoved}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const c = ctx.constraints[possibleConstraints[i]];
|
const c = ctx.constraints[possibleConstraints[i]];
|
||||||
if (!c) continue;
|
if (!c) continue;
|
||||||
|
|
||||||
|
// Limit of number of lelements removed per step
|
||||||
|
if (nRemoved>5000000) {
|
||||||
|
nextPossibleConstraints[possibleConstraints[i]] = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Swap a and b if b has more variables.
|
// Swap a and b if b has more variables.
|
||||||
if (Object.keys(c.b).length > Object.keys(c.a).length) {
|
if (Object.keys(c.b).length > Object.keys(c.a).length) {
|
||||||
const aux = c.a;
|
const aux = c.a;
|
||||||
@@ -402,7 +418,7 @@ async function reduceConstrains(ctx) {
|
|||||||
|
|
||||||
const cts = Object.keys(sig2constraint[isolatedSignal]);
|
const cts = Object.keys(sig2constraint[isolatedSignal]);
|
||||||
for (let k=0; k<cts.length; k++) {
|
for (let k=0; k<cts.length; k++) {
|
||||||
nextPossibleConstraints[cts[k]] = true;
|
if (ctx.constraints[cts[k]]) nextPossibleConstraints[cts[k]] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -434,7 +450,7 @@ async function reduceConstrains(ctx) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const removedSignalsList = removedSignals.getKeys();
|
const removedSignalsList = Object.keys(removedSignals);
|
||||||
|
|
||||||
for (let i=0; i<removedSignalsList.length; i++) {
|
for (let i=0; i<removedSignalsList.length; i++) {
|
||||||
if ((ctx.verbose )&&(i%100000 == 0)) console.log(`removing signals: ${i}/${removedSignalsList.length}`);
|
if ((ctx.verbose )&&(i%100000 == 0)) console.log(`removing signals: ${i}/${removedSignalsList.length}`);
|
||||||
@@ -445,7 +461,7 @@ async function reduceConstrains(ctx) {
|
|||||||
lSignal = ctx.signals[lSignal.e];
|
lSignal = ctx.signals[lSignal.e];
|
||||||
}
|
}
|
||||||
|
|
||||||
lSignal.c = ctx.stDISCARDED;
|
sig2constraint[s] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -456,6 +472,9 @@ async function reduceConstrains(ctx) {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
possibleConstraints = nextPossibleConstraints;
|
possibleConstraints = nextPossibleConstraints;
|
||||||
|
|
||||||
|
totalRemoved += nRemoved;
|
||||||
|
if (ctx.verbose) console.log(`Removed: ${totalRemoved} TotalConstraints: ${ctx.constraints.length}` );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -476,7 +495,12 @@ async function reduceConstrains(ctx) {
|
|||||||
for (let k in l.coefs) {
|
for (let k in l.coefs) {
|
||||||
k = Number(k);
|
k = Number(k);
|
||||||
const signal = ctx.signals[k];
|
const signal = ctx.signals[k];
|
||||||
if ((signal.c == ctx.stINTERNAL)&&(!ctx.F.isZero(l.coefs[k])) &&(!removedSignals[k])) return k;
|
if ( ( ((signal.o & ctx.MAIN) == 0)
|
||||||
|
||( ((signal.o & ctx.IN) == 0)
|
||||||
|
&&((signal.o & ctx.OUT) == 0)))
|
||||||
|
&&((signal.o & ctx.ONE) ==0)
|
||||||
|
&&(!ctx.F.isZero(l.coefs[k]))
|
||||||
|
&&(!removedSignals[k])) return k;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -428,10 +428,17 @@ function execAssignement(ctx, ast) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Skip if an out is assigned directly to an input.
|
// Skip if an out is assigned directly to an input.
|
||||||
if ((!isIn)||(!isOut)) {
|
if (!(isIn&&isOut)) {
|
||||||
sDest.e = sIdx;
|
if (isIn) {
|
||||||
} else {
|
sDest.e = sIdx;
|
||||||
if (utils.isDefined(sSrc.v)) sDest.v = sSrc.v;
|
} else if (isOut) {
|
||||||
|
sSrc.e = dIdx;
|
||||||
|
} else {
|
||||||
|
sDest.e = sIdx;
|
||||||
|
}
|
||||||
|
if (!isOut) {
|
||||||
|
if (utils.isDefined(sSrc.v)) sDest.v = sSrc.v;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -701,6 +708,9 @@ function execPin(ctx, ast) {
|
|||||||
if (sel.v[0].t != "N") return NQVAL;
|
if (sel.v[0].t != "N") return NQVAL;
|
||||||
selsP.push(Scalar.toNumber(sel.v[0].v));
|
selsP.push(Scalar.toNumber(sel.v[0].v));
|
||||||
}
|
}
|
||||||
|
if (!ctx.components[cIdx]) {
|
||||||
|
return ctx.throwError(ast, "Component not defined yet");
|
||||||
|
}
|
||||||
const sIdx = ctx.components[cIdx].names.getSignalIdx(ast.pin.name, selsP);
|
const sIdx = ctx.components[cIdx].names.getSignalIdx(ast.pin.name, selsP);
|
||||||
|
|
||||||
if (sIdx<0) return ctx.throwError(ast, "Signal not defined:" + buildFullName() );
|
if (sIdx<0) return ctx.throwError(ast, "Signal not defined:" + buildFullName() );
|
||||||
@@ -878,7 +888,8 @@ function execOpOp(ctx, ast, op, lr) {
|
|||||||
right = {t:"N", v: ctx.F.one};
|
right = {t:"N", v: ctx.F.one};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!right) return ctx.throwError(ast, "adding a no number");
|
if (!right) return ctx.throwError(ast, "right operand is not initialized");
|
||||||
|
if (!resBefore) return ctx.throwError(ast, "left operand is not initialized");
|
||||||
|
|
||||||
const resAfter = ctx.lc[op](resBefore, right);
|
const resAfter = ctx.lc[op](resBefore, right);
|
||||||
left.v[o] = resAfter;
|
left.v[o] = resAfter;
|
||||||
|
|||||||
@@ -284,6 +284,32 @@ function genDeclareComponent(ctx, ast) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function genDeclareSignal(ctx, ast) {
|
function genDeclareSignal(ctx, ast) {
|
||||||
|
|
||||||
|
const v = ctx.refs[ast.refId];
|
||||||
|
|
||||||
|
let sizes;
|
||||||
|
if (ast.name.selectors.length>0) {
|
||||||
|
sizes=[];
|
||||||
|
for (let i=0; i< ast.name.selectors.length; i++) {
|
||||||
|
const sizeRef = gen(ctx, ast.name.selectors[i]);
|
||||||
|
const size = ctx.refs[sizeRef];
|
||||||
|
if (size.sizes[0] != 1) return ctx.throwError(ast, "A selector cannot be an array");
|
||||||
|
if (size.used) return ctx.throwError(ast, "Signal size variables not allowed");
|
||||||
|
sizes.push(Scalar.toNumber(size.value[0]));
|
||||||
|
}
|
||||||
|
sizes = utils.accSizes(sizes);
|
||||||
|
} else {
|
||||||
|
sizes = [1,0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((!v.sizes)&&(sizes)) {
|
||||||
|
v.sizes = sizes;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v.sizes) {
|
||||||
|
if (!utils.sameSizes(v.sizes, sizes)) return ctx.throwError(ast, "Redefined a signal with different sized");
|
||||||
|
}
|
||||||
|
|
||||||
return ast.refId;
|
return ast.refId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -414,12 +440,13 @@ function genVariable(ctx, ast) {
|
|||||||
vOffset = genGetSignalOffset(ctx, -1, ast.name);
|
vOffset = genGetSignalOffset(ctx, -1, ast.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
const resRef = newRef(ctx, "BIGINT", "_sigValue");
|
const sizes = v.sizes.slice(l);
|
||||||
|
|
||||||
|
const resRef = newRef(ctx, "BIGINT", "_sigValue", null, sizes);
|
||||||
const res = ctx.refs[resRef];
|
const res = ctx.refs[resRef];
|
||||||
instantiateRef(ctx, resRef);
|
instantiateRef(ctx, resRef);
|
||||||
ctx.codeBuilder.getSignal(res.label, ["CC"], toRefA_Int1(ctx, ast, vOffset));
|
ctx.codeBuilder.getSignal(res.label, ["CC"], toRefA_Int1(ctx, ast, vOffset), sizes[0]);
|
||||||
return resRef;
|
return resRef;
|
||||||
|
|
||||||
} else if (v.type == "BIGINT") {
|
} else if (v.type == "BIGINT") {
|
||||||
const refOffset = genGetOffset(ctx, 0, v.sizes, ast.selectors );
|
const refOffset = genGetOffset(ctx, 0, v.sizes, ast.selectors );
|
||||||
const offset = ctx.refs[refOffset];
|
const offset = ctx.refs[refOffset];
|
||||||
@@ -486,13 +513,18 @@ function genPin(ctx, ast) {
|
|||||||
vsIdx = genGetSignalOffset(ctx, vcIdx, ast.pin.name);
|
vsIdx = genGetSignalOffset(ctx, vcIdx, ast.pin.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
const resRef = newRef(ctx, "BIGINT", "_sigValue");
|
const l = ast.selectors ? ast.selectors.length : 0;
|
||||||
|
|
||||||
|
const sizes = [1,0]; // TODO, Treat array
|
||||||
|
|
||||||
|
const resRef = newRef(ctx, "BIGINT", "_sigValue", null, sizes);
|
||||||
const res = ctx.refs[resRef];
|
const res = ctx.refs[resRef];
|
||||||
instantiateRef(ctx, resRef);
|
instantiateRef(ctx, resRef);
|
||||||
ctx.codeBuilder.getSignal(
|
ctx.codeBuilder.getSignal(
|
||||||
res.label,
|
res.label,
|
||||||
toRefA_Int1(ctx, ast.component, vcIdx),
|
toRefA_Int1(ctx, ast.component, vcIdx),
|
||||||
toRefA_Int1(ctx, ast.pin, vsIdx)
|
toRefA_Int1(ctx, ast.pin, vsIdx),
|
||||||
|
sizes[0]
|
||||||
);
|
);
|
||||||
return resRef;
|
return resRef;
|
||||||
}
|
}
|
||||||
@@ -951,7 +983,7 @@ function genLoop(ctx, ast) {
|
|||||||
if (ctx.error) return;
|
if (ctx.error) return;
|
||||||
|
|
||||||
const cond = ctx.refs[condRef];
|
const cond = ctx.refs[condRef];
|
||||||
if (!utils.sameSizes(cond.sizes, [1,0])) return ctx.throwError(ast.condition, "Operation cannot be done on an array");
|
if (!utils.sameSizes(cond.sizes, [1,0])) return ctx.throwError(ast.condition, "genLoop: Operation cannot be done on an array");
|
||||||
|
|
||||||
if (cond.used) {
|
if (cond.used) {
|
||||||
inLoop = true;
|
inLoop = true;
|
||||||
@@ -1028,7 +1060,7 @@ function genIf(ctx, ast) {
|
|||||||
const condRef = gen(ctx, ast.condition);
|
const condRef = gen(ctx, ast.condition);
|
||||||
if (ctx.error) return;
|
if (ctx.error) return;
|
||||||
const cond = ctx.refs[condRef];
|
const cond = ctx.refs[condRef];
|
||||||
if (!utils.sameSizes(cond.sizes, [1,0])) return ctx.throwError(ast.condition, "Operation cannot be done on an array");
|
if (!utils.sameSizes(cond.sizes, [1,0])) return ctx.throwError(ast.condition, "genIf: Operation cannot be done on an array");
|
||||||
|
|
||||||
if (cond.used) {
|
if (cond.used) {
|
||||||
let thenCode, elseCode;
|
let thenCode, elseCode;
|
||||||
@@ -1148,7 +1180,12 @@ function genOp(ctx, ast, op, nOps, adjustBool) {
|
|||||||
valRefs.push(ref);
|
valRefs.push(ref);
|
||||||
vals.push(v);
|
vals.push(v);
|
||||||
|
|
||||||
if (!utils.sameSizes(v.sizes, [1,0])) return ctx.throwError(ast, "Operation cannot be done on an array");
|
if (!utils.sameSizes(v.sizes, [1,0])) {
|
||||||
|
console.log("xx");
|
||||||
|
console.log(i);
|
||||||
|
console.log(v);
|
||||||
|
return ctx.throwError(ast, "genOp2: Operation cannot be done on an array");
|
||||||
|
}
|
||||||
if ( (!v.used)
|
if ( (!v.used)
|
||||||
&&( (!utils.isDefined(v.value))
|
&&( (!utils.isDefined(v.value))
|
||||||
||(!utils.isDefined(v.value[0]))))
|
||(!utils.isDefined(v.value[0]))))
|
||||||
@@ -1184,7 +1221,7 @@ function genTerCon(ctx, ast) {
|
|||||||
const condRef = gen(ctx, ast.values[0]);
|
const condRef = gen(ctx, ast.values[0]);
|
||||||
if (ctx.error) return;
|
if (ctx.error) return;
|
||||||
const cond = ctx.refs[condRef];
|
const cond = ctx.refs[condRef];
|
||||||
if (!utils.sameSizes(cond.sizes, [1,0])) return ctx.throwError(ast.condition, "Operation cannot be done on an array");
|
if (!utils.sameSizes(cond.sizes, [1,0])) return ctx.throwError(ast.condition, "genTer: Operation cannot be done on an array");
|
||||||
|
|
||||||
if (cond.used) {
|
if (cond.used) {
|
||||||
let thenCode, elseCode;
|
let thenCode, elseCode;
|
||||||
|
|||||||
@@ -8,8 +8,7 @@ module.exports.buildR1cs = buildR1cs;
|
|||||||
|
|
||||||
async function buildR1cs(ctx, fileName) {
|
async function buildR1cs(ctx, fileName) {
|
||||||
|
|
||||||
const fd = await fastFile.createOverride(fileName);
|
const fd = await fastFile.createOverride(fileName, 1<<24, 1<<22);
|
||||||
|
|
||||||
|
|
||||||
const buffBigInt = new Uint8Array(ctx.F.n8);
|
const buffBigInt = new Uint8Array(ctx.F.n8);
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ async function doTest(tester, circuit, testVectors) {
|
|||||||
describe("basic cases", function () {
|
describe("basic cases", function () {
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
|
|
||||||
for (let i=0; i<basicCases.length; i++) {
|
for (let i=0; i< basicCases.length; i++) {
|
||||||
it("c/c++ " + basicCases[i].name, async () => {
|
it("c/c++ " + basicCases[i].name, async () => {
|
||||||
await doTest(c_tester, basicCases[i].circuit, basicCases[i].tv);
|
await doTest(c_tester, basicCases[i].circuit, basicCases[i].tv);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -14,6 +14,17 @@
|
|||||||
}]
|
}]
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "fnarray",
|
||||||
|
"circuit": "fnarray.circom",
|
||||||
|
"tv": [
|
||||||
|
[{
|
||||||
|
"in": [1, 8, 25]
|
||||||
|
}, {
|
||||||
|
"out": [2, 16, 50]
|
||||||
|
}]
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "add",
|
"name": "add",
|
||||||
"circuit": "add.circom",
|
"circuit": "add.circom",
|
||||||
|
|||||||
21
test/circuits/fnarray.circom
Normal file
21
test/circuits/fnarray.circom
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function calc(h) {
|
||||||
|
var res[3];
|
||||||
|
for (var i=0; i<3; i++) res[i] = h[i]*2;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
template Test() {
|
||||||
|
signal input in[3];
|
||||||
|
signal output out[3];
|
||||||
|
|
||||||
|
var cout[3] = calc(in);
|
||||||
|
for (var i=0; i<3; i++) out[i] <-- cout[i];
|
||||||
|
|
||||||
|
for (var i=0; i<3; i++) out[i] === in[i]*2;
|
||||||
|
}
|
||||||
|
|
||||||
|
component main = Test();
|
||||||
Reference in New Issue
Block a user