mirror of
https://github.com/arnaucube/circom.git
synced 2026-02-07 11:16:42 +01:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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)
|
||||||
|
|||||||
73
package-lock.json
generated
73
package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "circom",
|
"name": "circom",
|
||||||
"version": "0.5.26",
|
"version": "0.5.30",
|
||||||
"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",
|
||||||
@@ -209,6 +214,18 @@
|
|||||||
"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"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "circom",
|
"name": "circom",
|
||||||
"version": "0.5.26",
|
"version": "0.5.30",
|
||||||
"description": "Language to generate logic circuits",
|
"description": "Language to generate logic circuits",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"directories": {
|
"directories": {
|
||||||
@@ -31,12 +31,12 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chai": "^4.2.0",
|
"chai": "^4.2.0",
|
||||||
"circom_runtime": "0.1.5",
|
"circom_runtime": "0.1.5",
|
||||||
"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"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -661,11 +661,6 @@ class BuilderC {
|
|||||||
|
|
||||||
async _buildCircuitVar(fdData) {
|
async _buildCircuitVar(fdData) {
|
||||||
|
|
||||||
const pP = fdData.pos;
|
|
||||||
|
|
||||||
const strBuff = new TextEncoder("utf-8").encode(this.header.P.toString());
|
|
||||||
await fdData.write(strBuff);
|
|
||||||
|
|
||||||
const buff = new Uint8Array(72);
|
const buff = new Uint8Array(72);
|
||||||
const buffV = new DataView(buff.buffer);
|
const buffV = new DataView(buff.buffer);
|
||||||
|
|
||||||
@@ -673,7 +668,7 @@ class BuilderC {
|
|||||||
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);
|
||||||
@@ -688,6 +683,16 @@ class BuilderC {
|
|||||||
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");
|
||||||
@@ -696,6 +701,7 @@ class BuilderC {
|
|||||||
|
|
||||||
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);
|
||||||
|
|||||||
@@ -473,7 +473,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(
|
||||||
|
|||||||
@@ -340,23 +340,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 +410,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 +442,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,6 +453,7 @@ async function reduceConstrains(ctx) {
|
|||||||
lSignal = ctx.signals[lSignal.e];
|
lSignal = ctx.signals[lSignal.e];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sig2constraint[s] = null;
|
||||||
lSignal.c = ctx.stDISCARDED;
|
lSignal.c = ctx.stDISCARDED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -456,6 +465,9 @@ async function reduceConstrains(ctx) {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
possibleConstraints = nextPossibleConstraints;
|
possibleConstraints = nextPossibleConstraints;
|
||||||
|
|
||||||
|
totalRemoved += nRemoved;
|
||||||
|
if (ctx.verbose) console.log(`Removed: ${totalRemoved} TotalConstraints: ${ctx.constraints.length}` );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -701,6 +701,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() );
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user