mirror of
https://github.com/arnaucube/circom.git
synced 2026-02-07 11:16:42 +01:00
Compare commits
68 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bbe10438e0 | ||
|
|
c2cef8d80c | ||
|
|
2200408986 | ||
|
|
5f13d37fdc | ||
|
|
3b46b74d4a | ||
|
|
aa2d768465 | ||
|
|
f02ceb2508 | ||
|
|
d014d67032 | ||
|
|
2e1b35a94d | ||
|
|
7cef1be2c3 | ||
|
|
4b631994ca | ||
|
|
7239abcef1 | ||
|
|
633f755e34 | ||
|
|
923b19c414 | ||
|
|
90cc7d5072 | ||
|
|
145d5a21ad | ||
|
|
cbb0b229bc | ||
|
|
1d14e8c603 | ||
|
|
1e2fb12631 | ||
|
|
0e1a1bcc23 | ||
|
|
989987bfc2 | ||
|
|
5f3ef322a7 | ||
|
|
3c8e61b9a4 | ||
|
|
c39423e411 | ||
|
|
06b6c1a49e | ||
|
|
6b712f3587 | ||
|
|
26cad30222 | ||
|
|
f48de61ca9 | ||
|
|
89cea4755c | ||
|
|
9bf6ecc4f3 | ||
|
|
59d591c988 | ||
|
|
9fe8be9828 | ||
|
|
7e24d6f57d | ||
|
|
8655573b34 | ||
|
|
8fc6e3f1c6 | ||
|
|
c32d303d27 | ||
|
|
744d3b241c | ||
|
|
1a5f7d1a2b | ||
|
|
434e7ac498 | ||
|
|
99afb4312e | ||
|
|
67ec7c5d5b | ||
|
|
a76f3b5988 | ||
|
|
bc9d395e70 | ||
|
|
7fc457ac90 | ||
|
|
8c4980c3f9 | ||
|
|
767ca60008 | ||
|
|
f25842f67c | ||
|
|
92399017df | ||
|
|
1463685b11 | ||
|
|
a1ae6e4a44 | ||
|
|
c7c6b799ad | ||
|
|
b107a11432 | ||
|
|
96776d2374 | ||
|
|
ca7379995e | ||
|
|
f604c31e0d | ||
|
|
a9c0593ec0 | ||
|
|
80cce0ccbb | ||
|
|
fcef4f5f32 | ||
|
|
3ef303593b | ||
|
|
16cf75c94b | ||
|
|
d79d59416d | ||
|
|
eae13a94fa | ||
|
|
7e41508860 | ||
|
|
5d374237e1 | ||
|
|
a18b603b22 | ||
|
|
f261992689 | ||
|
|
45e359aa35 | ||
|
|
da6cff2335 |
63
TUTORIAL.md
63
TUTORIAL.md
@@ -1,6 +1,6 @@
|
|||||||
# circom and snarkjs tutorial
|
# circom and snarkjs tutorial
|
||||||
|
|
||||||
This tutorial will guide you in creating your first Zero Knowledge zkSnark circuit. It will take you through the various techniques to write circuits, and will show you how to create proofs and verify them off-chain and on-chain on Ethereum.
|
This tutorial will guide you in creating your first zero-knowledge SNARK circuit. It will take you through the various techniques to write circuits and show you how to create and verify proofs off-chain and on-chain on Ethereum.
|
||||||
|
|
||||||
## 1. Installing the tools
|
## 1. Installing the tools
|
||||||
|
|
||||||
@@ -8,7 +8,7 @@ This tutorial will guide you in creating your first Zero Knowledge zkSnark circu
|
|||||||
|
|
||||||
If you don't have it installed yet, you need to install `Node.js`.
|
If you don't have it installed yet, you need to install `Node.js`.
|
||||||
|
|
||||||
The last stable version of `Node.js` (or 8.12.0) works just fine, but if you install the latest current version `Node.js` (10.12.0) you will see a significant increase in performance. This is because last versions of node includes Big Integer Libraries nativelly. The `snarkjs` library makes use of this feature if available, and this improves the performance x10 (!).
|
You should install at least version 10 of node. It's important to note here that the latests versions of javascript, includes big integer support and web assembly compilers that make the code run fast.
|
||||||
|
|
||||||
### 1.2 Install **circom** and **snarkjs**
|
### 1.2 Install **circom** and **snarkjs**
|
||||||
|
|
||||||
@@ -16,14 +16,13 @@ Run:
|
|||||||
|
|
||||||
```sh
|
```sh
|
||||||
npm install -g circom
|
npm install -g circom
|
||||||
npm install -g circom_runtime
|
|
||||||
npm install -g snarkjs
|
npm install -g snarkjs
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## 2. Working with a circuit
|
## 2. Working with a circuit
|
||||||
|
|
||||||
Let's create a circuit that tries to prove that you are able to factor a number!
|
Let's create a circuit that will allow you to prove that you are able to factor a number!
|
||||||
|
|
||||||
### 2.1 Create a circuit in a new directory
|
### 2.1 Create a circuit in a new directory
|
||||||
|
|
||||||
@@ -66,9 +65,11 @@ We are now ready to compile the circuit. Run the following command:
|
|||||||
circom circuit.circom --r1cs --wasm --sym
|
circom circuit.circom --r1cs --wasm --sym
|
||||||
```
|
```
|
||||||
|
|
||||||
The -r optin will generate `circuit.r1cs` ( The r1cs constraint system of the circuit in binary format)
|
The `--r1cs` option will generate `circuit.r1cs` (the r1cs constraint system of the circuit in binary format).
|
||||||
The -w will generate `circuit.wasm` (The wasm code to generate the witness)
|
|
||||||
The -s will generate `circuit.sym` (This is the symbols file, required for debugging or if you want to print the constraint system in an annotated mode)
|
The `--wasm` option will generate `circuit.wasm` (the wasm code to generate the witness).
|
||||||
|
|
||||||
|
The `--sym` option will generate `circuit.sym` (a symbols file required for debugging or if you want to print the constraint system in an annotated mode).
|
||||||
|
|
||||||
|
|
||||||
## 3. Taking the compiled circuit to *snarkjs*
|
## 3. Taking the compiled circuit to *snarkjs*
|
||||||
@@ -104,21 +105,21 @@ Ok, let's run a setup for our circuit:
|
|||||||
snarkjs setup
|
snarkjs setup
|
||||||
```
|
```
|
||||||
|
|
||||||
> By default `snarkjs` will look for and use `circuit.r1cs`. You can always specify a different circuit file by adding `-r <circuit R1CS file name>`
|
> By default `snarkjs` will look for and use `circuit.r1cs`. You can always specify a different circuit file by adding `-r <circuit R1CS file name>`.
|
||||||
|
|
||||||
The output of the setup will in the form of 2 files: `proving_key.json` and `verification_key.json`
|
The output of the setup will be in the form of 2 files: `proving_key.json` and `verification_key.json`.
|
||||||
|
|
||||||
### 3.3. Calculating a witness
|
### 3.3. Calculating a witness
|
||||||
|
|
||||||
Before creating any proof, we need to calculate all the signals of the circuit that match (all) the constrains of the circuit.
|
Before creating any proof, we need to calculate all the signals of the circuit that match (all) the constraints of the circuit.
|
||||||
|
|
||||||
`circom` generates a wasm module that calculates those for you. You need to provide a file with the inputs and it will execute the circuit and calculate all the intermediate signals and the output. This set of signals is the *witness*.
|
`circom` generates a wasm module that calculates those for you. You need to provide a file with the inputs and it will execute the circuit and calculate all the intermediate signals and the output. This set of signals is the *witness*.
|
||||||
|
|
||||||
The zero knowledge proofs prove that you know a set of signals (witness) that match all the constraints, without revealing any of the signals except the public inputs plus the outputs.
|
The zero-knowledge proofs prove that you know a set of signals (witness) that match all the constraints without revealing any of the signals except the public inputs and the outputs.
|
||||||
|
|
||||||
For example, imagine you want to prove you are able to factor 33. It means that you know two numbers `a` and `b` and when you multiply them, it results in 33.
|
For example, imagine you want to prove you are able to factor the number 33. It means that you know two numbers `a` and `b` that when you multiply them, it results in 33.
|
||||||
|
|
||||||
> Of course you can always use one and the same number as `a` or `b`. We will deal with this problem later.
|
> Of course you can always use the number one and the same number as `a` or `b`. We will deal with this problem later.
|
||||||
|
|
||||||
So you want to prove that you know 3 and 11.
|
So you want to prove that you know 3 and 11.
|
||||||
|
|
||||||
@@ -131,13 +132,9 @@ Let's create a file named `input.json`
|
|||||||
Now let's calculate the witness:
|
Now let's calculate the witness:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
snarkjs --wasm circuit.wasm --input input.json --witness witness.json
|
snarkjs calculatewitness --wasm circuit.wasm --input input.json --witness witness.json
|
||||||
```
|
```
|
||||||
|
|
||||||
`calcwit` is part of the circom_runtime package and it's just a wrapper in JS to call the wasm module.
|
|
||||||
|
|
||||||
You can use `circom_runtime` from your own project to calulate the witness.
|
|
||||||
|
|
||||||
You may want to take a look at `witness.json` file with all the signals.
|
You may want to take a look at `witness.json` file with all the signals.
|
||||||
|
|
||||||
### Create the proof
|
### Create the proof
|
||||||
@@ -150,7 +147,7 @@ snarkjs proof
|
|||||||
|
|
||||||
This command will use the `proving_key.json` and the `witness.json` files by default to generate `proof.json` and `public.json`
|
This command will use the `proving_key.json` and the `witness.json` files by default to generate `proof.json` and `public.json`
|
||||||
|
|
||||||
The `proof.json` file will contain the actual proof. And the `public.json` file will contain just the values of the public inputs and the outputs.
|
The `proof.json` file will contain the actual proof and the `public.json` file will contain just the values of the public inputs and the outputs.
|
||||||
|
|
||||||
|
|
||||||
### Verifying the proof
|
### Verifying the proof
|
||||||
@@ -180,7 +177,7 @@ You can take the code in `verifier.sol` and cut and paste it in remix.
|
|||||||
|
|
||||||
This code contains two contracts: Pairings and Verifier. You only need to deploy the `Verifier` contract.
|
This code contains two contracts: Pairings and Verifier. You only need to deploy the `Verifier` contract.
|
||||||
|
|
||||||
> You may want to use a test net like Rinkeby, Kovan or Ropsten. You can also use the Javascript VM, but in some browsers, the verification takes long and it may hang the page.
|
> You may want to use a test net like Rinkeby, Kovan or Ropsten. You can also use the Javascript VM, but in some browsers the verification takes long and it may hang the page.
|
||||||
|
|
||||||
|
|
||||||
### Verifying the proof on-chain
|
### Verifying the proof on-chain
|
||||||
@@ -189,7 +186,7 @@ The verifier contract deployed in the last step has a `view` function called `ve
|
|||||||
|
|
||||||
This function will return true if the proof and the inputs are valid.
|
This function will return true if the proof and the inputs are valid.
|
||||||
|
|
||||||
To facilitate the call, you can use snarkjs to generate the parameters of the call by typing:
|
To facilitate the call, you can use `snarkjs` to generate the parameters of the call by typing:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
snarkjs generatecall
|
snarkjs generatecall
|
||||||
@@ -204,15 +201,15 @@ If you change any bit in the parameters, the result will be verifiably false.
|
|||||||
|
|
||||||
## Bonus track
|
## Bonus track
|
||||||
|
|
||||||
We can fix the circuit to not accept one as any of the values by adding some extra constraints.
|
We can fix the circuit to not accept the number 1 as any of the input values by adding some extra constraints.
|
||||||
|
|
||||||
Here the trick is that we use the property that 0 has no inverse. So `(a-1)` should not have an inverse.
|
Here, the trick is that we use the property that 0 has no inverse. So `(a-1)` should not have an inverse.
|
||||||
|
|
||||||
That means that `(a-1)*inv = 1` will be inpossible to match if `a` is 1.
|
That means that `(a-1)*inv = 1` will be inpossible to match if `a` is 1.
|
||||||
|
|
||||||
We just calculate inv by `1/(a-1)`
|
We just calculate inv by `1/(a-1)`.
|
||||||
|
|
||||||
So let's modify the circuit:
|
So, let's modify the circuit:
|
||||||
|
|
||||||
```
|
```
|
||||||
template Multiplier() {
|
template Multiplier() {
|
||||||
@@ -234,22 +231,22 @@ template Multiplier() {
|
|||||||
component main = Multiplier();
|
component main = Multiplier();
|
||||||
```
|
```
|
||||||
|
|
||||||
A nice thing of the circom language is that you can split a <== into two independent actions: <-- and ===
|
A nice thing of the circom language is that you can split a `<==` into two independent actions: `<--` and `===`.
|
||||||
|
|
||||||
The <-- and --> operators assign a value to a signal without creating any constraints.
|
The `<--` and `-->` operators assign a value to a signal without creating any constraints.
|
||||||
|
|
||||||
The === operator adds a constraint without assigning any value to any signal.
|
The `===` operator adds a constraint without assigning any value to a signal.
|
||||||
|
|
||||||
The circuit also has another problem: the operation works in Zr, so we need to guarantee the multiplication does not overflow. This can be done by converting the inputs to binary and checking the ranges, but we will reserve it for future tutorials.
|
The circuit also has another problem: the operation works in `Z_r`, so we need to guarantee the multiplication does not overflow. This can be done by converting the inputs to binary and checking the ranges, but we will reserve it for future tutorials.
|
||||||
|
|
||||||
## Where to go from here:
|
## Where to go from here
|
||||||
|
|
||||||
You may want to read the [README](https://github.com/iden3/circom) to learn more features about circom.
|
You may want to read the [README](https://github.com/iden3/circom) to learn more features about `circom`.
|
||||||
|
|
||||||
You can also check a library with many basic circuits lib binarizations, comparators, eddsa, hashes, merkle trees etc [here](https://github.com/iden3/circomlib) (Work in progress).
|
You can also check a library with many basic circuits lib binarizations, comparators, eddsa, hashes, merkle trees etc [here](https://github.com/iden3/circomlib) (Work in progress).
|
||||||
|
|
||||||
|
|
||||||
Or a exponentiation in the Baby Jub curve [here](https://github.com/iden3/circomlib) (Work in progress).
|
Or a exponentiation in the Baby Jubjub curve [here](https://github.com/iden3/circomlib) (Work in progress).
|
||||||
|
|
||||||
|
|
||||||
# Final note
|
# Final note
|
||||||
@@ -258,4 +255,4 @@ There is nothing worse for a dev than working with a buggy compiler. This is a
|
|||||||
|
|
||||||
And please contact us for any isue you have. In general, a github issue with a small piece of code with the bug is very useful to us.
|
And please contact us for any isue you have. In general, a github issue with a small piece of code with the bug is very useful to us.
|
||||||
|
|
||||||
Enjoy zero knowledge proving!
|
Enjoy zero-knowledge proving!
|
||||||
|
|||||||
125
cli.js
125
cli.js
@@ -23,7 +23,9 @@
|
|||||||
|
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const bigInt = require("big-integer");
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
|
const stringifyBigInts = require("ffjavascript").utils.stringifyBigInts;
|
||||||
|
const fastFile = require("fastfile");
|
||||||
|
|
||||||
const compiler = require("./src/compiler");
|
const compiler = require("./src/compiler");
|
||||||
|
|
||||||
@@ -60,78 +62,68 @@ const argv = require("yargs")
|
|||||||
.argv;
|
.argv;
|
||||||
|
|
||||||
|
|
||||||
let inputFile;
|
async function run() {
|
||||||
if (argv._.length == 0) {
|
let inputFile;
|
||||||
|
if (argv._.length == 0) {
|
||||||
inputFile = "circuit.circom";
|
inputFile = "circuit.circom";
|
||||||
} else if (argv._.length == 1) {
|
} else if (argv._.length == 1) {
|
||||||
inputFile = argv._[0];
|
inputFile = argv._[0];
|
||||||
} else {
|
} else {
|
||||||
console.log("Only one circuit at a time is permited");
|
console.log("Only one circuit at a time is permited");
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const fullFileName = path.resolve(process.cwd(), inputFile);
|
const fullFileName = path.resolve(process.cwd(), inputFile);
|
||||||
const fileName = path.basename(fullFileName, ".circom");
|
const fileName = path.basename(fullFileName, ".circom");
|
||||||
const cSourceName = typeof(argv.csource) === "string" ? argv.csource : fileName + ".cpp";
|
const cSourceName = typeof(argv.csource) === "string" ? argv.csource : fileName + ".cpp";
|
||||||
const wasmName = typeof(argv.wasm) === "string" ? argv.wasm : fileName + ".wasm";
|
const wasmName = typeof(argv.wasm) === "string" ? argv.wasm : fileName + ".wasm";
|
||||||
const watName = typeof(argv.wat) === "string" ? argv.wat : fileName + ".wat";
|
const watName = typeof(argv.wat) === "string" ? argv.wat : fileName + ".wat";
|
||||||
const r1csName = typeof(argv.r1cs) === "string" ? argv.r1cs : fileName + ".r1cs";
|
const r1csName = typeof(argv.r1cs) === "string" ? argv.r1cs : fileName + ".r1cs";
|
||||||
const symName = typeof(argv.sym) === "string" ? argv.sym : fileName + ".sym";
|
const symName = typeof(argv.sym) === "string" ? argv.sym : fileName + ".sym";
|
||||||
|
|
||||||
const options = {};
|
const options = {};
|
||||||
options.reduceConstraints = !argv.fast;
|
options.reduceConstraints = !argv.fast;
|
||||||
options.verbose = argv.verbose || false;
|
options.verbose = argv.verbose || false;
|
||||||
options.sanityCheck = argv.sanitycheck;
|
options.sanityCheck = argv.sanitycheck;
|
||||||
options.prime = argv.prime || bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
|
||||||
|
|
||||||
if (argv.csource) {
|
if (argv.csource) {
|
||||||
options.cSourceWriteStream = fs.createWriteStream(cSourceName);
|
options.cSourceFile = await fastFile.createOverride(cSourceName);
|
||||||
}
|
const noExt = cSourceName.substr(0, cSourceName.lastIndexOf(".")) || cSourceName;
|
||||||
if (argv.wasm) {
|
options.dataFile = await fastFile.createOverride(noExt+".dat");
|
||||||
options.wasmWriteStream = fs.createWriteStream(wasmName);
|
}
|
||||||
}
|
if (argv.wasm) {
|
||||||
if (argv.wat) {
|
options.wasmFile = await fastFile.createOverride(wasmName);
|
||||||
options.watWriteStream = fs.createWriteStream(watName);
|
}
|
||||||
}
|
if (argv.wat) {
|
||||||
if (argv.r1cs) {
|
options.watFile = await fastFile.createOverride(watName);
|
||||||
|
}
|
||||||
|
if (argv.r1cs) {
|
||||||
options.r1csFileName = r1csName;
|
options.r1csFileName = r1csName;
|
||||||
}
|
}
|
||||||
if (argv.sym) {
|
if (argv.sym) {
|
||||||
options.symWriteStream = fs.createWriteStream(symName);
|
options.symWriteStream = fs.createWriteStream(symName);
|
||||||
}
|
}
|
||||||
if (argv.newThreadTemplates) {
|
if (argv.newThreadTemplates) {
|
||||||
options.newThreadTemplates = new RegExp(argv.newThreadTemplates);
|
options.newThreadTemplates = new RegExp(argv.newThreadTemplates);
|
||||||
}
|
}
|
||||||
|
if (!argv.prime) {
|
||||||
|
options.prime = Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||||
|
} else if (["BLS12-381", "BLS12381"]. indexOf(argv.prime.toUpperCase()) >=0) {
|
||||||
|
options.prime = Scalar.fromString("73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001",16);
|
||||||
|
} else if (["BN-128", "BN128", "BN254", "BN-254"]. indexOf(argv.prime.toUpperCase()) >=0) {
|
||||||
|
options.prime = Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||||
|
} else {
|
||||||
|
options.prime = Scalar.fromString(argv.prime);
|
||||||
|
}
|
||||||
|
|
||||||
compiler(fullFileName, options).then( () => {
|
|
||||||
let cSourceDone = false;
|
await compiler(fullFileName, options);
|
||||||
let wasmDone = false;
|
|
||||||
|
if (options.cSourceFile) await options.cSourceFile.close();
|
||||||
|
if (options.dataFile) await options.dataFile.close();
|
||||||
|
if (options.wasmFile) await options.wasmFile.close();
|
||||||
|
if (options.watFile) await options.watFile.close();
|
||||||
let symDone = false;
|
let symDone = false;
|
||||||
let watDone = false;
|
|
||||||
if (options.cSourceWriteStream) {
|
|
||||||
options.cSourceWriteStream.on("finish", () => {
|
|
||||||
cSourceDone = true;
|
|
||||||
finishIfDone();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
cSourceDone = true;
|
|
||||||
}
|
|
||||||
if (options.wasmWriteStream) {
|
|
||||||
options.wasmWriteStream.on("finish", () => {
|
|
||||||
wasmDone = true;
|
|
||||||
finishIfDone();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
wasmDone = true;
|
|
||||||
}
|
|
||||||
if (options.watWriteStream) {
|
|
||||||
options.watWriteStream.on("finish", () => {
|
|
||||||
watDone = true;
|
|
||||||
finishIfDone();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
watDone = true;
|
|
||||||
}
|
|
||||||
if (options.symWriteStream) {
|
if (options.symWriteStream) {
|
||||||
options.symWriteStream.on("finish", () => {
|
options.symWriteStream.on("finish", () => {
|
||||||
symDone = true;
|
symDone = true;
|
||||||
@@ -141,12 +133,17 @@ compiler(fullFileName, options).then( () => {
|
|||||||
symDone = true;
|
symDone = true;
|
||||||
}
|
}
|
||||||
function finishIfDone() {
|
function finishIfDone() {
|
||||||
if ((cSourceDone)&&(symDone)&&(wasmDone)&&(watDone)) {
|
if (symDone) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
}, 300);
|
}, 300);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
run().then(()=> {
|
||||||
|
process.exit(0);
|
||||||
}, (err) => {
|
}, (err) => {
|
||||||
// console.log(err);
|
// console.log(err);
|
||||||
console.log(err.stack);
|
console.log(err.stack);
|
||||||
@@ -157,11 +154,9 @@ compiler(fullFileName, options).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);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
469
package-lock.json
generated
469
package-lock.json
generated
@@ -1,31 +1,31 @@
|
|||||||
{
|
{
|
||||||
"name": "circom",
|
"name": "circom",
|
||||||
"version": "0.5.1",
|
"version": "0.5.23",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/code-frame": {
|
"@babel/code-frame": {
|
||||||
"version": "7.8.3",
|
"version": "7.10.4",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
|
||||||
"integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
|
"integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/highlight": "^7.8.3"
|
"@babel/highlight": "^7.10.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@babel/helper-validator-identifier": {
|
"@babel/helper-validator-identifier": {
|
||||||
"version": "7.9.0",
|
"version": "7.10.4",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz",
|
||||||
"integrity": "sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw==",
|
"integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@babel/highlight": {
|
"@babel/highlight": {
|
||||||
"version": "7.9.0",
|
"version": "7.10.4",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
|
||||||
"integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==",
|
"integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/helper-validator-identifier": "^7.9.0",
|
"@babel/helper-validator-identifier": "^7.10.4",
|
||||||
"chalk": "^2.0.0",
|
"chalk": "^2.0.0",
|
||||||
"js-tokens": "^4.0.0"
|
"js-tokens": "^4.0.0"
|
||||||
}
|
}
|
||||||
@@ -48,9 +48,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"acorn": {
|
"acorn": {
|
||||||
"version": "7.1.1",
|
"version": "7.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz",
|
||||||
"integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==",
|
"integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"acorn-jsx": {
|
"acorn-jsx": {
|
||||||
@@ -60,9 +60,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"ajv": {
|
"ajv": {
|
||||||
"version": "6.12.0",
|
"version": "6.12.3",
|
||||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz",
|
||||||
"integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==",
|
"integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"fast-deep-equal": "^3.1.1",
|
"fast-deep-equal": "^3.1.1",
|
||||||
@@ -101,12 +101,11 @@
|
|||||||
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
|
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
|
||||||
},
|
},
|
||||||
"ansi-styles": {
|
"ansi-styles": {
|
||||||
"version": "4.2.1",
|
"version": "3.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||||
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
|
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/color-name": "^1.1.1",
|
"color-convert": "^1.9.0"
|
||||||
"color-convert": "^2.0.1"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"argparse": {
|
"argparse": {
|
||||||
@@ -129,6 +128,11 @@
|
|||||||
"integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
|
"integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"async": {
|
||||||
|
"version": "0.9.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
|
||||||
|
"integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0="
|
||||||
|
},
|
||||||
"balanced-match": {
|
"balanced-match": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||||
@@ -139,6 +143,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz",
|
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz",
|
||||||
"integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w=="
|
"integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w=="
|
||||||
},
|
},
|
||||||
|
"blakejs": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz",
|
||||||
|
"integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U="
|
||||||
|
},
|
||||||
"brace-expansion": {
|
"brace-expansion": {
|
||||||
"version": "1.1.11",
|
"version": "1.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
@@ -176,37 +185,10 @@
|
|||||||
"version": "2.4.2",
|
"version": "2.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"ansi-styles": "^3.2.1",
|
"ansi-styles": "^3.2.1",
|
||||||
"escape-string-regexp": "^1.0.5",
|
"escape-string-regexp": "^1.0.5",
|
||||||
"supports-color": "^5.3.0"
|
"supports-color": "^5.3.0"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"ansi-styles": {
|
|
||||||
"version": "3.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
|
||||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"color-convert": "^1.9.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"color-convert": {
|
|
||||||
"version": "1.9.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
|
||||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"color-name": "1.1.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"color-name": {
|
|
||||||
"version": "1.1.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
|
||||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
|
|
||||||
"dev": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"chardet": {
|
"chardet": {
|
||||||
@@ -221,11 +203,11 @@
|
|||||||
"integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII="
|
"integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII="
|
||||||
},
|
},
|
||||||
"circom_runtime": {
|
"circom_runtime": {
|
||||||
"version": "0.0.3",
|
"version": "0.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/circom_runtime/-/circom_runtime-0.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/circom_runtime/-/circom_runtime-0.1.5.tgz",
|
||||||
"integrity": "sha512-z4ypbs9cTQn7+2FHZNTnccMj6kQCcKT2agYqCrm2kdLBJh9LDoxU1JVu5mSnVuOtgc7BclQ7r0xclG0zP2rxhw==",
|
"integrity": "sha512-BT3d9VCrH/rBRbThDXG731JwezKyskxyE46nACO6Tt/jaorn27LDxFDORdAAjyD0RAoBt+6FpaTp3qlYSx7Pjg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"big-integer": "^1.6.48",
|
"ffjavascript": "0.2.10",
|
||||||
"fnv-plus": "^1.3.1"
|
"fnv-plus": "^1.3.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -248,9 +230,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cli-width": {
|
"cli-width": {
|
||||||
"version": "2.2.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz",
|
||||||
"integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
|
"integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"cliui": {
|
"cliui": {
|
||||||
@@ -264,17 +246,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"color-convert": {
|
"color-convert": {
|
||||||
"version": "2.0.1",
|
"version": "1.9.3",
|
||||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"color-name": "~1.1.4"
|
"color-name": "1.1.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"color-name": {
|
"color-name": {
|
||||||
"version": "1.1.4",
|
"version": "1.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
|
||||||
},
|
},
|
||||||
"colors": {
|
"colors": {
|
||||||
"version": "0.5.1",
|
"version": "0.5.1",
|
||||||
@@ -352,9 +334,12 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"ejs": {
|
"ejs": {
|
||||||
"version": "3.0.1",
|
"version": "3.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.5.tgz",
|
||||||
"integrity": "sha512-cuIMtJwxvzumSAkqaaoGY/L6Fc/t6YvoP9/VIaK0V/CyqKLEQ8sqODmYfy/cjXEdZ9+OOL8TecbJu+1RsofGDw=="
|
"integrity": "sha512-dldq3ZfFtgVTJMLjOe+/3sROTzALlL9E34V4/sDtUd/KlBSS0s6U1/+WPE1B4sj9CXHJpL1M6rhNJnc9Wbal9w==",
|
||||||
|
"requires": {
|
||||||
|
"jake": "^10.6.1"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"emoji-regex": {
|
"emoji-regex": {
|
||||||
"version": "8.0.0",
|
"version": "8.0.0",
|
||||||
@@ -364,8 +349,7 @@
|
|||||||
"escape-string-regexp": {
|
"escape-string-regexp": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||||
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
|
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"escodegen": {
|
"escodegen": {
|
||||||
"version": "1.3.3",
|
"version": "1.3.3",
|
||||||
@@ -462,9 +446,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"eslint-scope": {
|
"eslint-scope": {
|
||||||
"version": "5.0.0",
|
"version": "5.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz",
|
||||||
"integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==",
|
"integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"esrecurse": "^4.1.0",
|
"esrecurse": "^4.1.0",
|
||||||
@@ -481,9 +465,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"eslint-visitor-keys": {
|
"eslint-visitor-keys": {
|
||||||
"version": "1.1.0",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
|
||||||
"integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==",
|
"integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"espree": {
|
"espree": {
|
||||||
@@ -504,18 +488,18 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"esquery": {
|
"esquery": {
|
||||||
"version": "1.2.0",
|
"version": "1.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz",
|
||||||
"integrity": "sha512-weltsSqdeWIX9G2qQZz7KlTRJdkkOCTPgLYJUz1Hacf48R4YOwGPHO3+ORfWedqJKbq5WQmsgK90n+pFLIKt/Q==",
|
"integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"estraverse": "^5.0.0"
|
"estraverse": "^5.1.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"estraverse": {
|
"estraverse": {
|
||||||
"version": "5.0.0",
|
"version": "5.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
|
||||||
"integrity": "sha512-j3acdrMzqrxmJTNj5dbr1YbjacrYgAxVMeF0gK16E3j494mOe7xygM/ZLIguEQ0ETwAg2hlJCtHRGav+y0Ny5A==",
|
"integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -564,9 +548,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fast-deep-equal": {
|
"fast-deep-equal": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||||
"integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==",
|
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"fast-json-stable-stringify": {
|
"fast-json-stable-stringify": {
|
||||||
@@ -581,10 +565,15 @@
|
|||||||
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
|
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"fastfile": {
|
||||||
|
"version": "0.0.12",
|
||||||
|
"resolved": "https://registry.npmjs.org/fastfile/-/fastfile-0.0.12.tgz",
|
||||||
|
"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",
|
||||||
@@ -592,30 +581,33 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ffjavascript": {
|
"ffjavascript": {
|
||||||
"version": "0.0.3",
|
"version": "0.2.10",
|
||||||
"resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.10.tgz",
|
||||||
"integrity": "sha512-uXbiC7cNbFzNJCdkGlbQf2d7GciY1ICMcBeAA7+D8RHPr9Y5zYiDRWtU5etjAV8TplE7eZQ9Iqd9ieFi0ARJLA==",
|
"integrity": "sha512-GQI6gHYYG5/iD4Kt3VzezzK7fARJzP0zkc82V/+JAdjfeKBXhDSo5rpKFuK3cDcrdW0Fu2emuYNMEAuFqhEQvQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"big-integer": "^1.6.48"
|
"big-integer": "^1.6.48",
|
||||||
|
"wasmcurves": "0.0.5",
|
||||||
|
"worker-threads": "^1.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"wasmcurves": {
|
||||||
|
"version": "0.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/wasmcurves/-/wasmcurves-0.0.5.tgz",
|
||||||
|
"integrity": "sha512-BmI4GXLjLawGg2YkvHa8zRsnWec+d1uwoxE+Iov8cqOpDL7GA5XO2pk2yuDbXHMzwIug2exnKot3baRZ86R0pA==",
|
||||||
|
"requires": {
|
||||||
|
"big-integer": "^1.6.42",
|
||||||
|
"blakejs": "^1.1.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ffwasm": {
|
"ffwasm": {
|
||||||
"version": "0.0.5",
|
"version": "0.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/ffwasm/-/ffwasm-0.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/ffwasm/-/ffwasm-0.0.7.tgz",
|
||||||
"integrity": "sha512-biz1jK3TjxpwigoBLWzvBNtuQAC6WBVzlI1sw2BQp3RqTei66OhJ6E2G+zSk2SubUVWlrgTN+WfE+Fmn3qdtgg==",
|
"integrity": "sha512-17cTLzv7HHAKqZbX8MvHxjSrR0yDdn1sh4TVsTbAvO9e6klhFicnyoVXc/sCuViV/M8g65sCmVrAmoPCZp1YkQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"big-integer": "^1.6.48",
|
"big-integer": "^1.6.48",
|
||||||
"wasmbuilder": "0.0.8"
|
"wasmbuilder": "0.0.10"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"wasmbuilder": {
|
|
||||||
"version": "0.0.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/wasmbuilder/-/wasmbuilder-0.0.8.tgz",
|
|
||||||
"integrity": "sha512-d63cIsDmHnybA5hTlRRLadgys5r3Tl4W8SbcBRh13FauEPOo48dqjgzdL1xefpZkpKKybDRlFqgm+9cX04B3+w==",
|
|
||||||
"requires": {
|
|
||||||
"big-integer": "^1.6.43"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"figures": {
|
"figures": {
|
||||||
@@ -636,6 +628,14 @@
|
|||||||
"flat-cache": "^2.0.1"
|
"flat-cache": "^2.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"filelist": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-8zSK6Nu0DQIC08mUC46sWGXi+q3GGpKydAG36k+JDba6VRpkevvOWUW5a/PhShij4+vHT9M+ghgG7eM+a9JDUQ==",
|
||||||
|
"requires": {
|
||||||
|
"minimatch": "^3.0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"find-up": {
|
"find-up": {
|
||||||
"version": "4.1.0",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
|
||||||
@@ -668,9 +668,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flatted": {
|
"flatted": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
|
||||||
"integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==",
|
"integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"fnv-plus": {
|
"fnv-plus": {
|
||||||
@@ -733,8 +733,7 @@
|
|||||||
"has-flag": {
|
"has-flag": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||||
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
|
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"iconv-lite": {
|
"iconv-lite": {
|
||||||
"version": "0.4.24",
|
"version": "0.4.24",
|
||||||
@@ -782,36 +781,61 @@
|
|||||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||||
},
|
},
|
||||||
"inquirer": {
|
"inquirer": {
|
||||||
"version": "7.1.0",
|
"version": "7.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz",
|
||||||
"integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==",
|
"integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"ansi-escapes": "^4.2.1",
|
"ansi-escapes": "^4.2.1",
|
||||||
"chalk": "^3.0.0",
|
"chalk": "^4.1.0",
|
||||||
"cli-cursor": "^3.1.0",
|
"cli-cursor": "^3.1.0",
|
||||||
"cli-width": "^2.0.0",
|
"cli-width": "^3.0.0",
|
||||||
"external-editor": "^3.0.3",
|
"external-editor": "^3.0.3",
|
||||||
"figures": "^3.0.0",
|
"figures": "^3.0.0",
|
||||||
"lodash": "^4.17.15",
|
"lodash": "^4.17.19",
|
||||||
"mute-stream": "0.0.8",
|
"mute-stream": "0.0.8",
|
||||||
"run-async": "^2.4.0",
|
"run-async": "^2.4.0",
|
||||||
"rxjs": "^6.5.3",
|
"rxjs": "^6.6.0",
|
||||||
"string-width": "^4.1.0",
|
"string-width": "^4.1.0",
|
||||||
"strip-ansi": "^6.0.0",
|
"strip-ansi": "^6.0.0",
|
||||||
"through": "^2.3.6"
|
"through": "^2.3.6"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"ansi-styles": {
|
||||||
|
"version": "4.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
|
||||||
|
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/color-name": "^1.1.1",
|
||||||
|
"color-convert": "^2.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"chalk": {
|
"chalk": {
|
||||||
"version": "3.0.0",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
|
||||||
"integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
|
"integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"ansi-styles": "^4.1.0",
|
"ansi-styles": "^4.1.0",
|
||||||
"supports-color": "^7.1.0"
|
"supports-color": "^7.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"color-convert": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"color-name": "~1.1.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"color-name": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||||
|
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"has-flag": {
|
"has-flag": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||||
@@ -849,18 +873,23 @@
|
|||||||
"is-extglob": "^2.1.1"
|
"is-extglob": "^2.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"is-promise": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
|
|
||||||
"integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"isexe": {
|
"isexe": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||||
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
|
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"jake": {
|
||||||
|
"version": "10.8.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz",
|
||||||
|
"integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==",
|
||||||
|
"requires": {
|
||||||
|
"async": "0.9.x",
|
||||||
|
"chalk": "^2.4.2",
|
||||||
|
"filelist": "^1.0.1",
|
||||||
|
"minimatch": "^3.0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"jison": {
|
"jison": {
|
||||||
"version": "0.4.18",
|
"version": "0.4.18",
|
||||||
"resolved": "https://registry.npmjs.org/jison/-/jison-0.4.18.tgz",
|
"resolved": "https://registry.npmjs.org/jison/-/jison-0.4.18.tgz",
|
||||||
@@ -902,9 +931,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"js-yaml": {
|
"js-yaml": {
|
||||||
"version": "3.13.1",
|
"version": "3.14.0",
|
||||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz",
|
||||||
"integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
|
"integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"argparse": "^1.0.7",
|
"argparse": "^1.0.7",
|
||||||
@@ -958,9 +987,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"lodash": {
|
"lodash": {
|
||||||
"version": "4.17.15",
|
"version": "4.17.19",
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
|
||||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
|
"integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"mimic-fn": {
|
"mimic-fn": {
|
||||||
@@ -984,9 +1013,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"mkdirp": {
|
"mkdirp": {
|
||||||
"version": "0.5.4",
|
"version": "0.5.5",
|
||||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||||
"integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==",
|
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"minimist": "^1.2.5"
|
"minimist": "^1.2.5"
|
||||||
@@ -1035,9 +1064,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"onetime": {
|
"onetime": {
|
||||||
"version": "5.1.0",
|
"version": "5.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
|
||||||
"integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==",
|
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"mimic-fn": "^2.1.0"
|
"mimic-fn": "^2.1.0"
|
||||||
@@ -1064,9 +1093,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"p-limit": {
|
"p-limit": {
|
||||||
"version": "2.2.2",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
|
||||||
"integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==",
|
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"p-try": "^2.0.0"
|
"p-try": "^2.0.0"
|
||||||
}
|
}
|
||||||
@@ -1133,11 +1162,29 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"r1csfile": {
|
"r1csfile": {
|
||||||
"version": "0.0.2",
|
"version": "0.0.14",
|
||||||
"resolved": "https://registry.npmjs.org/r1csfile/-/r1csfile-0.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/r1csfile/-/r1csfile-0.0.14.tgz",
|
||||||
"integrity": "sha512-H1aR5NYRJ/RUrHWR/PNEivFEDkLV4R0+4SlKo2eq/fyiWxwgZNapOkjnJXsy5TZn40uFVrud0uOxGyVWgm9rDg==",
|
"integrity": "sha512-7m4eWpnbjkwGGUaRmIAJc4w+HvaeBPJXUKHIqLkHeD9Yyjem6/EHmlgDVl+4hWNWGZqdhXuMqWSH9+O6QOXBdw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"big-integer": "^1.6.48"
|
"fastfile": "0.0.7",
|
||||||
|
"ffjavascript": "0.2.4"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"fastfile": {
|
||||||
|
"version": "0.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/fastfile/-/fastfile-0.0.7.tgz",
|
||||||
|
"integrity": "sha512-Zk7sdqsV6DsN/rhjULDfCCowPiMDsziTMFicdkrKN80yybr/6YFf9H91ELXN85dVEf6EYkVR5EHkZNc0dMqZKA=="
|
||||||
|
},
|
||||||
|
"ffjavascript": {
|
||||||
|
"version": "0.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.4.tgz",
|
||||||
|
"integrity": "sha512-XFeWcjUDFPavN+DDOxhE8p5MOhZQJc9oO1Sj4ml1pyjqNhS1ujEamcjFyK0cctdnat61i7lvpTYzdtS3RYDC8w==",
|
||||||
|
"requires": {
|
||||||
|
"big-integer": "^1.6.48",
|
||||||
|
"wasmcurves": "0.0.4",
|
||||||
|
"worker-threads": "^1.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"regexpp": {
|
"regexpp": {
|
||||||
@@ -1181,18 +1228,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"run-async": {
|
"run-async": {
|
||||||
"version": "2.4.0",
|
"version": "2.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
|
||||||
"integrity": "sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg==",
|
"integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==",
|
||||||
"dev": true,
|
"dev": true
|
||||||
"requires": {
|
|
||||||
"is-promise": "^2.1.0"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"rxjs": {
|
"rxjs": {
|
||||||
"version": "6.5.4",
|
"version": "6.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.2.tgz",
|
||||||
"integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==",
|
"integrity": "sha512-BHdBMVoWC2sL26w//BCu3YzKT4s2jip/WhwsGEDmeKYBhKDZeYezVUnHatYB7L85v5xs0BAQmg6BEYJEKxBabg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"tslib": "^1.9.0"
|
"tslib": "^1.9.0"
|
||||||
@@ -1231,9 +1275,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"signal-exit": {
|
"signal-exit": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
|
||||||
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
|
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"slice-ansi": {
|
"slice-ansi": {
|
||||||
@@ -1247,30 +1291,6 @@
|
|||||||
"is-fullwidth-code-point": "^2.0.0"
|
"is-fullwidth-code-point": "^2.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ansi-styles": {
|
|
||||||
"version": "3.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
|
||||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"color-convert": "^1.9.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"color-convert": {
|
|
||||||
"version": "1.9.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
|
||||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"color-name": "1.1.3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"color-name": {
|
|
||||||
"version": "1.1.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
|
||||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"is-fullwidth-code-point": {
|
"is-fullwidth-code-point": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
|
||||||
@@ -1314,16 +1334,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"strip-json-comments": {
|
"strip-json-comments": {
|
||||||
"version": "3.0.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
|
||||||
"integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==",
|
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"supports-color": {
|
"supports-color": {
|
||||||
"version": "5.5.0",
|
"version": "5.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"has-flag": "^3.0.0"
|
"has-flag": "^3.0.0"
|
||||||
}
|
}
|
||||||
@@ -1401,17 +1420,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tmp-promise": {
|
"tmp-promise": {
|
||||||
"version": "2.0.2",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-2.1.1.tgz",
|
||||||
"integrity": "sha512-zl71nFWjPKW2KXs+73gEk8RmqvtAeXPxhWDkTUoa3MSMkjq3I+9OeknjF178MQoMYsdqL730hfzvNfEkePxq9Q==",
|
"integrity": "sha512-Z048AOz/w9b6lCbJUpevIJpRpUztENl8zdv1bmAKVHimfqRFl92ROkmT9rp7TVBnrEw2gtMTol/2Cp2S2kJa4Q==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"tmp": "0.1.0"
|
"tmp": "0.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tslib": {
|
"tslib": {
|
||||||
"version": "1.11.1",
|
"version": "1.13.0",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz",
|
||||||
"integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==",
|
"integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"type-check": {
|
"type-check": {
|
||||||
@@ -1450,19 +1469,28 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"v8-compile-cache": {
|
"v8-compile-cache": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz",
|
||||||
"integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==",
|
"integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"wasmbuilder": {
|
"wasmbuilder": {
|
||||||
"version": "0.0.9",
|
"version": "0.0.10",
|
||||||
"resolved": "https://registry.npmjs.org/wasmbuilder/-/wasmbuilder-0.0.9.tgz",
|
"resolved": "https://registry.npmjs.org/wasmbuilder/-/wasmbuilder-0.0.10.tgz",
|
||||||
"integrity": "sha512-QJ550VwQvN6P4oW0d+/tCfo3i+1GBuuFX906r8QpDRryYXmXvdRZWJM0qkHgOfhg8G47SfgJVYNl3fyLfkxaPw==",
|
"integrity": "sha512-zQSvZ7d74d9OvN+mCN6ucNne4QS5/cBBYTHldX0Oe+u9gStY21orapvuX1ajisA7RVIpuFhYg+ZgdySsPfeh0A==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"big-integer": "^1.6.48"
|
"big-integer": "^1.6.48"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"wasmcurves": {
|
||||||
|
"version": "0.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/wasmcurves/-/wasmcurves-0.0.4.tgz",
|
||||||
|
"integrity": "sha512-c/Tob+F/7jJhep1b2qtj54r4nkGaRifNbQ1OJx8cBBFH1RlHbWIbISHWONClOxiVwy/JZOpbN4SgvSX/4lF80A==",
|
||||||
|
"requires": {
|
||||||
|
"big-integer": "^1.6.42",
|
||||||
|
"blakejs": "^1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"which": {
|
"which": {
|
||||||
"version": "1.3.1",
|
"version": "1.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
||||||
@@ -1483,6 +1511,11 @@
|
|||||||
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
|
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"worker-threads": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/worker-threads/-/worker-threads-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-vK6Hhvph8oLxocEJIlc3YfGAZhm210uGzjZsXSu+JYLAQ/s/w4Tqgl60JrdH58hW8NSGP4m3bp8a92qPXgX05w=="
|
||||||
|
},
|
||||||
"wrap-ansi": {
|
"wrap-ansi": {
|
||||||
"version": "6.2.0",
|
"version": "6.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
|
||||||
@@ -1491,6 +1524,30 @@
|
|||||||
"ansi-styles": "^4.0.0",
|
"ansi-styles": "^4.0.0",
|
||||||
"string-width": "^4.1.0",
|
"string-width": "^4.1.0",
|
||||||
"strip-ansi": "^6.0.0"
|
"strip-ansi": "^6.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-styles": {
|
||||||
|
"version": "4.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
|
||||||
|
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
|
||||||
|
"requires": {
|
||||||
|
"@types/color-name": "^1.1.1",
|
||||||
|
"color-convert": "^2.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"color-convert": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||||
|
"requires": {
|
||||||
|
"color-name": "~1.1.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"color-name": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||||
|
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"wrappy": {
|
"wrappy": {
|
||||||
@@ -1513,9 +1570,9 @@
|
|||||||
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w=="
|
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w=="
|
||||||
},
|
},
|
||||||
"yargs": {
|
"yargs": {
|
||||||
"version": "15.3.1",
|
"version": "15.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
|
||||||
"integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==",
|
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"cliui": "^6.0.0",
|
"cliui": "^6.0.0",
|
||||||
"decamelize": "^1.2.0",
|
"decamelize": "^1.2.0",
|
||||||
@@ -1527,13 +1584,13 @@
|
|||||||
"string-width": "^4.2.0",
|
"string-width": "^4.2.0",
|
||||||
"which-module": "^2.0.0",
|
"which-module": "^2.0.0",
|
||||||
"y18n": "^4.0.0",
|
"y18n": "^4.0.0",
|
||||||
"yargs-parser": "^18.1.1"
|
"yargs-parser": "^18.1.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"yargs-parser": {
|
"yargs-parser": {
|
||||||
"version": "18.1.1",
|
"version": "18.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
|
||||||
"integrity": "sha512-KRHEsOM16IX7XuLnMOqImcPNbLVXMNHYAoFc3BKR8Ortl5gzDbtXvvEoGx9imk5E+X1VeNKNlcHr8B8vi+7ipA==",
|
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"camelcase": "^5.0.0",
|
"camelcase": "^5.0.0",
|
||||||
"decamelize": "^1.2.0"
|
"decamelize": "^1.2.0"
|
||||||
|
|||||||
16
package.json
16
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "circom",
|
"name": "circom",
|
||||||
"version": "0.5.1",
|
"version": "0.5.23",
|
||||||
"description": "Language to generate logic circuits",
|
"description": "Language to generate logic circuits",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"directories": {
|
"directories": {
|
||||||
@@ -29,16 +29,16 @@
|
|||||||
"url": "https://github.com/iden3/circom.git"
|
"url": "https://github.com/iden3/circom.git"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"big-integer": "^1.6.32",
|
|
||||||
"chai": "^4.2.0",
|
"chai": "^4.2.0",
|
||||||
"circom_runtime": "0.0.3",
|
"circom_runtime": "0.1.5",
|
||||||
"ffiasm": "0.0.2",
|
"fastfile": "0.0.12",
|
||||||
"ffjavascript": "0.0.3",
|
"ffiasm": "0.1.1",
|
||||||
"ffwasm": "0.0.5",
|
"ffjavascript": "0.2.10",
|
||||||
|
"ffwasm": "0.0.7",
|
||||||
"fnv-plus": "^1.3.1",
|
"fnv-plus": "^1.3.1",
|
||||||
"r1csfile": "0.0.2",
|
"r1csfile": "0.0.14",
|
||||||
"tmp-promise": "^2.0.2",
|
"tmp-promise": "^2.0.2",
|
||||||
"wasmbuilder": "0.0.9"
|
"wasmbuilder": "0.0.10"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint": "^6.8.0",
|
"eslint": "^6.8.0",
|
||||||
|
|||||||
114
parser/jaz.jison
114
parser/jaz.jison
@@ -132,10 +132,8 @@ include { return 'include'; }
|
|||||||
|
|
||||||
|
|
||||||
%{
|
%{
|
||||||
const bigInt = require('big-integer');
|
const Scalar = require('ffjavascript').Scalar;
|
||||||
const util = require('util');
|
const util = require('util');
|
||||||
const __P__ = new bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
|
||||||
const __MASK__ = new bigInt(2).pow(253).minus(1);
|
|
||||||
|
|
||||||
function setLines(dst, first, last) {
|
function setLines(dst, first, last) {
|
||||||
last = last || first;
|
last = last || first;
|
||||||
@@ -266,20 +264,12 @@ identifierList
|
|||||||
ifStatment
|
ifStatment
|
||||||
: 'if' '(' expression ')' statment 'else' statment
|
: 'if' '(' expression ')' statment 'else' statment
|
||||||
{
|
{
|
||||||
if ($3.type == "NUMBER") {
|
|
||||||
$$ = !$3.value.eq(0) ? $5 : $7;
|
|
||||||
} else {
|
|
||||||
$$ = { type: "IF", condition: $3, then: $5, else: $7 };
|
$$ = { type: "IF", condition: $3, then: $5, else: $7 };
|
||||||
}
|
|
||||||
setLines($$, @1, @7);
|
setLines($$, @1, @7);
|
||||||
}
|
}
|
||||||
| 'if' '(' expression ')' statment
|
| 'if' '(' expression ')' statment
|
||||||
{
|
{
|
||||||
if ($3.type == "NUMBER") {
|
|
||||||
$$ = !$3.value.eq(0) ? $5 : { type: "NUMBER", value: bigInt(0) };
|
|
||||||
} else {
|
|
||||||
$$ = { type: "IF", condition: $3, then: $5 };
|
$$ = { type: "IF", condition: $3, then: $5 };
|
||||||
}
|
|
||||||
setLines($$, @1, @5);
|
setLines($$, @1, @5);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@@ -451,11 +441,7 @@ e17
|
|||||||
}
|
}
|
||||||
| e17 '?' e17 ':' e17 %prec TERCOND
|
| e17 '?' e17 ':' e17 %prec TERCOND
|
||||||
{
|
{
|
||||||
if ($1.type == "NUMBER") {
|
|
||||||
$$ = !$1.value.eq(0) ? $3 : $5;
|
|
||||||
} else {
|
|
||||||
$$ = { type: "OP", op: "?", values: [$1, $3, $5] };
|
$$ = { type: "OP", op: "?", values: [$1, $3, $5] };
|
||||||
}
|
|
||||||
setLines($$, @1, @5);
|
setLines($$, @1, @5);
|
||||||
}
|
}
|
||||||
| e16 %prec EMPTY
|
| e16 %prec EMPTY
|
||||||
@@ -478,11 +464,7 @@ e16
|
|||||||
e15
|
e15
|
||||||
: e15 '||' e14
|
: e15 '||' e14
|
||||||
{
|
{
|
||||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
|
||||||
$$ = { type: "NUMBER", value: !$1.value.eq(0) || !$3.value.eq(0) ? bigInt(1) : bigInt(0) };
|
|
||||||
} else {
|
|
||||||
$$ = { type: "OP", op: "||", values: [$1, $3] };
|
$$ = { type: "OP", op: "||", values: [$1, $3] };
|
||||||
}
|
|
||||||
setLines($$, @1, @3);
|
setLines($$, @1, @3);
|
||||||
}
|
}
|
||||||
| e14 %prec EMPTY
|
| e14 %prec EMPTY
|
||||||
@@ -494,11 +476,7 @@ e15
|
|||||||
e14
|
e14
|
||||||
: e14 '&&' e13
|
: e14 '&&' e13
|
||||||
{
|
{
|
||||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
|
||||||
$$ = { type: "NUMBER", value: !$1.value.eq(0) && !$3.value.eq(0) ? bigInt(1) : bigInt(0) };
|
|
||||||
} else {
|
|
||||||
$$ = { type: "OP", op: "&&", values: [$1, $3] };
|
$$ = { type: "OP", op: "&&", values: [$1, $3] };
|
||||||
}
|
|
||||||
setLines($$, @1, @3);
|
setLines($$, @1, @3);
|
||||||
}
|
}
|
||||||
| e13 %prec EMPTY
|
| e13 %prec EMPTY
|
||||||
@@ -510,11 +488,7 @@ e14
|
|||||||
e13
|
e13
|
||||||
: e13 '|' e12
|
: e13 '|' e12
|
||||||
{
|
{
|
||||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
|
||||||
$$ = { type: "NUMBER", value: $1.value.or($3.value).and(__MASK__) };
|
|
||||||
} else {
|
|
||||||
$$ = { type: "OP", op: "|", values: [$1, $3] };
|
$$ = { type: "OP", op: "|", values: [$1, $3] };
|
||||||
}
|
|
||||||
setLines($$, @1, @3);
|
setLines($$, @1, @3);
|
||||||
}
|
}
|
||||||
| e12 %prec EMPTY
|
| e12 %prec EMPTY
|
||||||
@@ -527,11 +501,7 @@ e13
|
|||||||
e12
|
e12
|
||||||
: e12 '^' e11
|
: e12 '^' e11
|
||||||
{
|
{
|
||||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
|
||||||
$$ = { type: "NUMBER", value: $1.value.xor($3.value).and(__MASK__) };
|
|
||||||
} else {
|
|
||||||
$$ = { type: "OP", op: "^", values: [$1, $3] };
|
$$ = { type: "OP", op: "^", values: [$1, $3] };
|
||||||
}
|
|
||||||
setLines($$, @1, @3);
|
setLines($$, @1, @3);
|
||||||
}
|
}
|
||||||
| e11 %prec EMPTY
|
| e11 %prec EMPTY
|
||||||
@@ -543,11 +513,7 @@ e12
|
|||||||
e11
|
e11
|
||||||
: e11 '&' e10
|
: e11 '&' e10
|
||||||
{
|
{
|
||||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
|
||||||
$$ = { type: "NUMBER", value: $1.value.and($3.value).and(__MASK__) };
|
|
||||||
} else {
|
|
||||||
$$ = { type: "OP", op: "&", values: [$1, $3] };
|
$$ = { type: "OP", op: "&", values: [$1, $3] };
|
||||||
}
|
|
||||||
setLines($$, @1, @3);
|
setLines($$, @1, @3);
|
||||||
}
|
}
|
||||||
| e10 %prec EMPTY
|
| e10 %prec EMPTY
|
||||||
@@ -562,20 +528,12 @@ e11
|
|||||||
e10
|
e10
|
||||||
: e10 '==' e9
|
: e10 '==' e9
|
||||||
{
|
{
|
||||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
|
||||||
$$ = { type: "NUMBER", value: $1.value.equals($3.value) ? bigInt(1) : bigInt(0) };
|
|
||||||
} else {
|
|
||||||
$$ = { type: "OP", op: "==", values: [$1, $3] };
|
$$ = { type: "OP", op: "==", values: [$1, $3] };
|
||||||
}
|
|
||||||
setLines($$, @1, @3);
|
setLines($$, @1, @3);
|
||||||
}
|
}
|
||||||
| e10 '!=' e9
|
| e10 '!=' e9
|
||||||
{
|
{
|
||||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
|
||||||
$$ = { type: "NUMBER", value: $1.value.eq($3.value) ? bigInt(0) : bigInt(1) };
|
|
||||||
} else {
|
|
||||||
$$ = { type: "OP", op: "!=", values: [$1, $3] };
|
$$ = { type: "OP", op: "!=", values: [$1, $3] };
|
||||||
}
|
|
||||||
setLines($$, @1, @3);
|
setLines($$, @1, @3);
|
||||||
}
|
}
|
||||||
| e9 %prec EMPTY
|
| e9 %prec EMPTY
|
||||||
@@ -587,38 +545,22 @@ e10
|
|||||||
e9
|
e9
|
||||||
: e9 '<=' e7
|
: e9 '<=' e7
|
||||||
{
|
{
|
||||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
|
||||||
$$ = { type: "NUMBER", value: $1.value.lesserOrEquals($3.value) ? bigInt(1) : bigInt(0) };
|
|
||||||
} else {
|
|
||||||
$$ = { type: "OP", op: "<=", values: [$1, $3] };
|
$$ = { type: "OP", op: "<=", values: [$1, $3] };
|
||||||
}
|
|
||||||
setLines($$, @1, @3);
|
setLines($$, @1, @3);
|
||||||
}
|
}
|
||||||
| e9 '>=' e7
|
| e9 '>=' e7
|
||||||
{
|
{
|
||||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
|
||||||
$$ = { type: "NUMBER", value: $1.value.greaterOrEquals($3.value) ? bigInt(1) : bigInt(0) };
|
|
||||||
} else {
|
|
||||||
$$ = { type: "OP", op: ">=", values: [$1, $3] };
|
$$ = { type: "OP", op: ">=", values: [$1, $3] };
|
||||||
}
|
|
||||||
setLines($$, @1, @3);
|
setLines($$, @1, @3);
|
||||||
}
|
}
|
||||||
| e9 '<' e7
|
| e9 '<' e7
|
||||||
{
|
{
|
||||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
|
||||||
$$ = { type: "NUMBER", value: $1.value.lesser($3.value) ? bigInt(1) : bigInt(0) };
|
|
||||||
} else {
|
|
||||||
$$ = { type: "OP", op: "<", values: [$1, $3] };
|
$$ = { type: "OP", op: "<", values: [$1, $3] };
|
||||||
}
|
|
||||||
setLines($$, @1, @3);
|
setLines($$, @1, @3);
|
||||||
}
|
}
|
||||||
| e9 '>' e7
|
| e9 '>' e7
|
||||||
{
|
{
|
||||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
|
||||||
$$ = { type: "NUMBER", value: $1.value.greater($3.value) ? bigInt(1) : bigInt(0) };
|
|
||||||
} else {
|
|
||||||
$$ = { type: "OP", op: ">", values: [$1, $3] };
|
$$ = { type: "OP", op: ">", values: [$1, $3] };
|
||||||
}
|
|
||||||
setLines($$, @1, @3);
|
setLines($$, @1, @3);
|
||||||
}
|
}
|
||||||
| e7 %prec EMPTY
|
| e7 %prec EMPTY
|
||||||
@@ -630,22 +572,12 @@ e9
|
|||||||
e7
|
e7
|
||||||
: e7 '<<' e6
|
: e7 '<<' e6
|
||||||
{
|
{
|
||||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
|
||||||
let v = $3.value.greater(256) ? 256 : $3.value.value;
|
|
||||||
$$ = { type: "NUMBER", value: $1.value.shiftLeft(v).and(__MASK__) };
|
|
||||||
} else {
|
|
||||||
$$ = { type: "OP", op: "<<", values: [$1, $3] };
|
$$ = { type: "OP", op: "<<", values: [$1, $3] };
|
||||||
}
|
|
||||||
setLines($$, @1, @3);
|
setLines($$, @1, @3);
|
||||||
}
|
}
|
||||||
| e7 '>>' e6
|
| e7 '>>' e6
|
||||||
{
|
{
|
||||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
|
||||||
let v = $3.value.greater(256) ? 256 : $3.value.value;
|
|
||||||
$$ = {type: "NUMBER", value: $1.value.shiftRight(v).and(__MASK__) };
|
|
||||||
} else {
|
|
||||||
$$ = { type: "OP", op: ">>", values: [$1, $3] };
|
$$ = { type: "OP", op: ">>", values: [$1, $3] };
|
||||||
}
|
|
||||||
setLines($$, @1, @3);
|
setLines($$, @1, @3);
|
||||||
}
|
}
|
||||||
| e6 %prec EMPTY
|
| e6 %prec EMPTY
|
||||||
@@ -657,20 +589,12 @@ e7
|
|||||||
e6
|
e6
|
||||||
: e6 '+' e5
|
: e6 '+' e5
|
||||||
{
|
{
|
||||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
|
||||||
$$ = { type: "NUMBER", value: ($1.value.plus($3.value)).mod(__P__) };
|
|
||||||
} else {
|
|
||||||
$$ = { type: "OP", op: "+", values: [$1, $3] };
|
$$ = { type: "OP", op: "+", values: [$1, $3] };
|
||||||
}
|
|
||||||
setLines($$, @1, @3);
|
setLines($$, @1, @3);
|
||||||
}
|
}
|
||||||
| e6 '-' e5
|
| e6 '-' e5
|
||||||
{
|
{
|
||||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
|
||||||
$$ = { type: "NUMBER", value: ($1.value.plus(__P__).minus($3.value)).mod(__P__) };
|
|
||||||
} else {
|
|
||||||
$$ = { type: "OP", op: "-", values: [$1, $3] };
|
$$ = { type: "OP", op: "-", values: [$1, $3] };
|
||||||
}
|
|
||||||
setLines($$, @1, @3);
|
setLines($$, @1, @3);
|
||||||
}
|
}
|
||||||
| e5 %prec EMPTY
|
| e5 %prec EMPTY
|
||||||
@@ -683,38 +607,22 @@ e6
|
|||||||
e5
|
e5
|
||||||
: e5 '*' e4
|
: e5 '*' e4
|
||||||
{
|
{
|
||||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
|
||||||
$$ = { type: "NUMBER", value: ($1.value.times($3.value)).mod(__P__) };
|
|
||||||
} else {
|
|
||||||
$$ = { type: "OP", op: "*", values: [$1, $3] };
|
$$ = { type: "OP", op: "*", values: [$1, $3] };
|
||||||
}
|
|
||||||
setLines($$, @1, @3);
|
setLines($$, @1, @3);
|
||||||
}
|
}
|
||||||
| e5 '/' e4
|
| e5 '/' e4
|
||||||
{
|
{
|
||||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
|
||||||
$$ = { type: "NUMBER", value: ($1.value.times($3.value.modInv(__P__))).mod(__P__) };
|
|
||||||
} else {
|
|
||||||
$$ = { type: "OP", op: "/", values: [$1, $3] };
|
$$ = { type: "OP", op: "/", values: [$1, $3] };
|
||||||
}
|
|
||||||
setLines($$, @1, @3);
|
setLines($$, @1, @3);
|
||||||
}
|
}
|
||||||
| e5 '\\' e4
|
| e5 '\\' e4
|
||||||
{
|
{
|
||||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
|
||||||
$$ = { type: "NUMBER", value: ($1.value.divide($3.value)) };
|
|
||||||
} else {
|
|
||||||
$$ = { type: "OP", op: "\\", values: [$1, $3] };
|
$$ = { type: "OP", op: "\\", values: [$1, $3] };
|
||||||
}
|
|
||||||
setLines($$, @1, @3);
|
setLines($$, @1, @3);
|
||||||
}
|
}
|
||||||
| e5 '%' e4
|
| e5 '%' e4
|
||||||
{
|
{
|
||||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
|
||||||
$$ = { type: "NUMBER", value: $1.value.mod($3.value) };
|
|
||||||
} else {
|
|
||||||
$$ = { type: "OP", op: "%", values: [$1, $3] };
|
$$ = { type: "OP", op: "%", values: [$1, $3] };
|
||||||
}
|
|
||||||
setLines($$, @1, @3);
|
setLines($$, @1, @3);
|
||||||
}
|
}
|
||||||
| e4 %prec EMPTY
|
| e4 %prec EMPTY
|
||||||
@@ -726,11 +634,7 @@ e5
|
|||||||
e4
|
e4
|
||||||
: e4 '**' e3
|
: e4 '**' e3
|
||||||
{
|
{
|
||||||
if (($1.type == "NUMBER") && ($3.type == "NUMBER")) {
|
|
||||||
$$ = { type: "NUMBER", value: $1.value.modPow($3.value, __P__) };
|
|
||||||
} else {
|
|
||||||
$$ = { type: "OP", op: "**", values: [$1, $3] };
|
$$ = { type: "OP", op: "**", values: [$1, $3] };
|
||||||
}
|
|
||||||
setLines($$, @1, @3);
|
setLines($$, @1, @3);
|
||||||
}
|
}
|
||||||
| e3 %prec EMPTY
|
| e3 %prec EMPTY
|
||||||
@@ -758,29 +662,17 @@ e3
|
|||||||
}
|
}
|
||||||
| '-' e3 %prec UMINUS
|
| '-' e3 %prec UMINUS
|
||||||
{
|
{
|
||||||
if ($2.type == "NUMBER") {
|
|
||||||
$$ = { type: "NUMBER", value: __P__.minus($2.value).mod(__P__) };
|
|
||||||
} else {
|
|
||||||
$$ = { type: "OP", op: "UMINUS", values: [$2] };
|
$$ = { type: "OP", op: "UMINUS", values: [$2] };
|
||||||
}
|
|
||||||
setLines($$, @1, @2);
|
setLines($$, @1, @2);
|
||||||
}
|
}
|
||||||
| '!' e3
|
| '!' e3
|
||||||
{
|
{
|
||||||
if ($2.type == "NUMBER") {
|
|
||||||
$$ = { type: "NUMBER", value: $2.value.eq(0) ? bigInt(1) : bigInt(0) };
|
|
||||||
} else {
|
|
||||||
$$ = { type: "OP", op: "!", values: [$2] };
|
$$ = { type: "OP", op: "!", values: [$2] };
|
||||||
}
|
|
||||||
setLines($$, @1, @2);
|
setLines($$, @1, @2);
|
||||||
}
|
}
|
||||||
| '~' e3
|
| '~' e3
|
||||||
{
|
{
|
||||||
if ($2.type == "NUMBER") {
|
|
||||||
$$ = { type: "NUMBER", value: $2.value.xor(__MASK__) };
|
|
||||||
} else {
|
|
||||||
$$ = { type: "OP", op: "~", values: [$2] };
|
$$ = { type: "OP", op: "~", values: [$2] };
|
||||||
}
|
|
||||||
setLines($$, @1, @2);
|
setLines($$, @1, @2);
|
||||||
}
|
}
|
||||||
| e2 %prec EMPTY
|
| e2 %prec EMPTY
|
||||||
@@ -817,12 +709,12 @@ e0
|
|||||||
}
|
}
|
||||||
| DECNUMBER
|
| DECNUMBER
|
||||||
{
|
{
|
||||||
$$ = {type: "NUMBER", value: bigInt($1).mod(__P__) }
|
$$ = {type: "NUMBER", value: Scalar.fromString($1) }
|
||||||
setLines($$, @1);
|
setLines($$, @1);
|
||||||
}
|
}
|
||||||
| HEXNUMBER
|
| HEXNUMBER
|
||||||
{
|
{
|
||||||
$$ = {type: "NUMBER", value: bigInt($1.substr(2).toUpperCase(), 16).mod(__P__) }
|
$$ = {type: "NUMBER", value: Scalar.fromString($1.substr(2).toUpperCase(), 16) }
|
||||||
setLines($$, @1);
|
setLines($$, @1);
|
||||||
}
|
}
|
||||||
| '(' expression ')' %prec EMPTY
|
| '(' expression ')' %prec EMPTY
|
||||||
|
|||||||
116
parser/jaz.js
116
parser/jaz.js
@@ -146,21 +146,13 @@ case 20:
|
|||||||
break;
|
break;
|
||||||
case 21:
|
case 21:
|
||||||
|
|
||||||
if ($$[$0-4].type == "NUMBER") {
|
|
||||||
this.$ = !$$[$0-4].value.eq(0) ? $$[$0-2] : $$[$0];
|
|
||||||
} else {
|
|
||||||
this.$ = { type: "IF", condition: $$[$0-4], then: $$[$0-2], else: $$[$0] };
|
this.$ = { type: "IF", condition: $$[$0-4], then: $$[$0-2], else: $$[$0] };
|
||||||
}
|
|
||||||
setLines(this.$, _$[$0-6], _$[$0]);
|
setLines(this.$, _$[$0-6], _$[$0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 22:
|
case 22:
|
||||||
|
|
||||||
if ($$[$0-2].type == "NUMBER") {
|
|
||||||
this.$ = !$$[$0-2].value.eq(0) ? $$[$0] : { type: "NUMBER", value: bigInt(0) };
|
|
||||||
} else {
|
|
||||||
this.$ = { type: "IF", condition: $$[$0-2], then: $$[$0] };
|
this.$ = { type: "IF", condition: $$[$0-2], then: $$[$0] };
|
||||||
}
|
|
||||||
setLines(this.$, _$[$0-4], _$[$0]);
|
setLines(this.$, _$[$0-4], _$[$0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -321,11 +313,7 @@ case 50:
|
|||||||
break;
|
break;
|
||||||
case 51:
|
case 51:
|
||||||
|
|
||||||
if ($$[$0-4].type == "NUMBER") {
|
|
||||||
this.$ = !$$[$0-4].value.eq(0) ? $$[$0-2] : $$[$0];
|
|
||||||
} else {
|
|
||||||
this.$ = { type: "OP", op: "?", values: [$$[$0-4], $$[$0-2], $$[$0]] };
|
this.$ = { type: "OP", op: "?", values: [$$[$0-4], $$[$0-2], $$[$0]] };
|
||||||
}
|
|
||||||
setLines(this.$, _$[$0-4], _$[$0]);
|
setLines(this.$, _$[$0-4], _$[$0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -336,71 +324,43 @@ case 52: case 53: case 54: case 56: case 58: case 60:
|
|||||||
break;
|
break;
|
||||||
case 55:
|
case 55:
|
||||||
|
|
||||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
|
||||||
this.$ = { type: "NUMBER", value: !$$[$0-2].value.eq(0) || !$$[$0].value.eq(0) ? bigInt(1) : bigInt(0) };
|
|
||||||
} else {
|
|
||||||
this.$ = { type: "OP", op: "||", values: [$$[$0-2], $$[$0]] };
|
this.$ = { type: "OP", op: "||", values: [$$[$0-2], $$[$0]] };
|
||||||
}
|
|
||||||
setLines(this.$, _$[$0-2], _$[$0]);
|
setLines(this.$, _$[$0-2], _$[$0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 57:
|
case 57:
|
||||||
|
|
||||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
|
||||||
this.$ = { type: "NUMBER", value: !$$[$0-2].value.eq(0) && !$$[$0].value.eq(0) ? bigInt(1) : bigInt(0) };
|
|
||||||
} else {
|
|
||||||
this.$ = { type: "OP", op: "&&", values: [$$[$0-2], $$[$0]] };
|
this.$ = { type: "OP", op: "&&", values: [$$[$0-2], $$[$0]] };
|
||||||
}
|
|
||||||
setLines(this.$, _$[$0-2], _$[$0]);
|
setLines(this.$, _$[$0-2], _$[$0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 59:
|
case 59:
|
||||||
|
|
||||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
|
||||||
this.$ = { type: "NUMBER", value: $$[$0-2].value.or($$[$0].value).and(__MASK__) };
|
|
||||||
} else {
|
|
||||||
this.$ = { type: "OP", op: "|", values: [$$[$0-2], $$[$0]] };
|
this.$ = { type: "OP", op: "|", values: [$$[$0-2], $$[$0]] };
|
||||||
}
|
|
||||||
setLines(this.$, _$[$0-2], _$[$0]);
|
setLines(this.$, _$[$0-2], _$[$0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 61:
|
case 61:
|
||||||
|
|
||||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
|
||||||
this.$ = { type: "NUMBER", value: $$[$0-2].value.xor($$[$0].value).and(__MASK__) };
|
|
||||||
} else {
|
|
||||||
this.$ = { type: "OP", op: "^", values: [$$[$0-2], $$[$0]] };
|
this.$ = { type: "OP", op: "^", values: [$$[$0-2], $$[$0]] };
|
||||||
}
|
|
||||||
setLines(this.$, _$[$0-2], _$[$0]);
|
setLines(this.$, _$[$0-2], _$[$0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 63:
|
case 63:
|
||||||
|
|
||||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
|
||||||
this.$ = { type: "NUMBER", value: $$[$0-2].value.and($$[$0].value).and(__MASK__) };
|
|
||||||
} else {
|
|
||||||
this.$ = { type: "OP", op: "&", values: [$$[$0-2], $$[$0]] };
|
this.$ = { type: "OP", op: "&", values: [$$[$0-2], $$[$0]] };
|
||||||
}
|
|
||||||
setLines(this.$, _$[$0-2], _$[$0]);
|
setLines(this.$, _$[$0-2], _$[$0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 65:
|
case 65:
|
||||||
|
|
||||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
|
||||||
this.$ = { type: "NUMBER", value: $$[$0-2].value.equals($$[$0].value) ? bigInt(1) : bigInt(0) };
|
|
||||||
} else {
|
|
||||||
this.$ = { type: "OP", op: "==", values: [$$[$0-2], $$[$0]] };
|
this.$ = { type: "OP", op: "==", values: [$$[$0-2], $$[$0]] };
|
||||||
}
|
|
||||||
setLines(this.$, _$[$0-2], _$[$0]);
|
setLines(this.$, _$[$0-2], _$[$0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 66:
|
case 66:
|
||||||
|
|
||||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
|
||||||
this.$ = { type: "NUMBER", value: $$[$0-2].value.eq($$[$0].value) ? bigInt(0) : bigInt(1) };
|
|
||||||
} else {
|
|
||||||
this.$ = { type: "OP", op: "!=", values: [$$[$0-2], $$[$0]] };
|
this.$ = { type: "OP", op: "!=", values: [$$[$0-2], $$[$0]] };
|
||||||
}
|
|
||||||
setLines(this.$, _$[$0-2], _$[$0]);
|
setLines(this.$, _$[$0-2], _$[$0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -411,63 +371,37 @@ case 67: case 72:
|
|||||||
break;
|
break;
|
||||||
case 68:
|
case 68:
|
||||||
|
|
||||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
|
||||||
this.$ = { type: "NUMBER", value: $$[$0-2].value.lesserOrEquals($$[$0].value) ? bigInt(1) : bigInt(0) };
|
|
||||||
} else {
|
|
||||||
this.$ = { type: "OP", op: "<=", values: [$$[$0-2], $$[$0]] };
|
this.$ = { type: "OP", op: "<=", values: [$$[$0-2], $$[$0]] };
|
||||||
}
|
|
||||||
setLines(this.$, _$[$0-2], _$[$0]);
|
setLines(this.$, _$[$0-2], _$[$0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 69:
|
case 69:
|
||||||
|
|
||||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
|
||||||
this.$ = { type: "NUMBER", value: $$[$0-2].value.greaterOrEquals($$[$0].value) ? bigInt(1) : bigInt(0) };
|
|
||||||
} else {
|
|
||||||
this.$ = { type: "OP", op: ">=", values: [$$[$0-2], $$[$0]] };
|
this.$ = { type: "OP", op: ">=", values: [$$[$0-2], $$[$0]] };
|
||||||
}
|
|
||||||
setLines(this.$, _$[$0-2], _$[$0]);
|
setLines(this.$, _$[$0-2], _$[$0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 70:
|
case 70:
|
||||||
|
|
||||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
|
||||||
this.$ = { type: "NUMBER", value: $$[$0-2].value.lesser($$[$0].value) ? bigInt(1) : bigInt(0) };
|
|
||||||
} else {
|
|
||||||
this.$ = { type: "OP", op: "<", values: [$$[$0-2], $$[$0]] };
|
this.$ = { type: "OP", op: "<", values: [$$[$0-2], $$[$0]] };
|
||||||
}
|
|
||||||
setLines(this.$, _$[$0-2], _$[$0]);
|
setLines(this.$, _$[$0-2], _$[$0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 71:
|
case 71:
|
||||||
|
|
||||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
|
||||||
this.$ = { type: "NUMBER", value: $$[$0-2].value.greater($$[$0].value) ? bigInt(1) : bigInt(0) };
|
|
||||||
} else {
|
|
||||||
this.$ = { type: "OP", op: ">", values: [$$[$0-2], $$[$0]] };
|
this.$ = { type: "OP", op: ">", values: [$$[$0-2], $$[$0]] };
|
||||||
}
|
|
||||||
setLines(this.$, _$[$0-2], _$[$0]);
|
setLines(this.$, _$[$0-2], _$[$0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 73:
|
case 73:
|
||||||
|
|
||||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
|
||||||
let v = $$[$0].value.greater(256) ? 256 : $$[$0].value.value;
|
|
||||||
this.$ = { type: "NUMBER", value: $$[$0-2].value.shiftLeft(v).and(__MASK__) };
|
|
||||||
} else {
|
|
||||||
this.$ = { type: "OP", op: "<<", values: [$$[$0-2], $$[$0]] };
|
this.$ = { type: "OP", op: "<<", values: [$$[$0-2], $$[$0]] };
|
||||||
}
|
|
||||||
setLines(this.$, _$[$0-2], _$[$0]);
|
setLines(this.$, _$[$0-2], _$[$0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 74:
|
case 74:
|
||||||
|
|
||||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
|
||||||
let v = $$[$0].value.greater(256) ? 256 : $$[$0].value.value;
|
|
||||||
this.$ = {type: "NUMBER", value: $$[$0-2].value.shiftRight(v).and(__MASK__) };
|
|
||||||
} else {
|
|
||||||
this.$ = { type: "OP", op: ">>", values: [$$[$0-2], $$[$0]] };
|
this.$ = { type: "OP", op: ">>", values: [$$[$0-2], $$[$0]] };
|
||||||
}
|
|
||||||
setLines(this.$, _$[$0-2], _$[$0]);
|
setLines(this.$, _$[$0-2], _$[$0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -478,71 +412,43 @@ case 75:
|
|||||||
break;
|
break;
|
||||||
case 76:
|
case 76:
|
||||||
|
|
||||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
|
||||||
this.$ = { type: "NUMBER", value: ($$[$0-2].value.plus($$[$0].value)).mod(__P__) };
|
|
||||||
} else {
|
|
||||||
this.$ = { type: "OP", op: "+", values: [$$[$0-2], $$[$0]] };
|
this.$ = { type: "OP", op: "+", values: [$$[$0-2], $$[$0]] };
|
||||||
}
|
|
||||||
setLines(this.$, _$[$0-2], _$[$0]);
|
setLines(this.$, _$[$0-2], _$[$0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 77:
|
case 77:
|
||||||
|
|
||||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
|
||||||
this.$ = { type: "NUMBER", value: ($$[$0-2].value.plus(__P__).minus($$[$0].value)).mod(__P__) };
|
|
||||||
} else {
|
|
||||||
this.$ = { type: "OP", op: "-", values: [$$[$0-2], $$[$0]] };
|
this.$ = { type: "OP", op: "-", values: [$$[$0-2], $$[$0]] };
|
||||||
}
|
|
||||||
setLines(this.$, _$[$0-2], _$[$0]);
|
setLines(this.$, _$[$0-2], _$[$0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 79:
|
case 79:
|
||||||
|
|
||||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
|
||||||
this.$ = { type: "NUMBER", value: ($$[$0-2].value.times($$[$0].value)).mod(__P__) };
|
|
||||||
} else {
|
|
||||||
this.$ = { type: "OP", op: "*", values: [$$[$0-2], $$[$0]] };
|
this.$ = { type: "OP", op: "*", values: [$$[$0-2], $$[$0]] };
|
||||||
}
|
|
||||||
setLines(this.$, _$[$0-2], _$[$0]);
|
setLines(this.$, _$[$0-2], _$[$0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 80:
|
case 80:
|
||||||
|
|
||||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
|
||||||
this.$ = { type: "NUMBER", value: ($$[$0-2].value.times($$[$0].value.modInv(__P__))).mod(__P__) };
|
|
||||||
} else {
|
|
||||||
this.$ = { type: "OP", op: "/", values: [$$[$0-2], $$[$0]] };
|
this.$ = { type: "OP", op: "/", values: [$$[$0-2], $$[$0]] };
|
||||||
}
|
|
||||||
setLines(this.$, _$[$0-2], _$[$0]);
|
setLines(this.$, _$[$0-2], _$[$0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 81:
|
case 81:
|
||||||
|
|
||||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
|
||||||
this.$ = { type: "NUMBER", value: ($$[$0-2].value.divide($$[$0].value)) };
|
|
||||||
} else {
|
|
||||||
this.$ = { type: "OP", op: "\\", values: [$$[$0-2], $$[$0]] };
|
this.$ = { type: "OP", op: "\\", values: [$$[$0-2], $$[$0]] };
|
||||||
}
|
|
||||||
setLines(this.$, _$[$0-2], _$[$0]);
|
setLines(this.$, _$[$0-2], _$[$0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 82:
|
case 82:
|
||||||
|
|
||||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
|
||||||
this.$ = { type: "NUMBER", value: $$[$0-2].value.mod($$[$0].value) };
|
|
||||||
} else {
|
|
||||||
this.$ = { type: "OP", op: "%", values: [$$[$0-2], $$[$0]] };
|
this.$ = { type: "OP", op: "%", values: [$$[$0-2], $$[$0]] };
|
||||||
}
|
|
||||||
setLines(this.$, _$[$0-2], _$[$0]);
|
setLines(this.$, _$[$0-2], _$[$0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 84:
|
case 84:
|
||||||
|
|
||||||
if (($$[$0-2].type == "NUMBER") && ($$[$0].type == "NUMBER")) {
|
|
||||||
this.$ = { type: "NUMBER", value: $$[$0-2].value.modPow($$[$0].value, __P__) };
|
|
||||||
} else {
|
|
||||||
this.$ = { type: "OP", op: "**", values: [$$[$0-2], $$[$0]] };
|
this.$ = { type: "OP", op: "**", values: [$$[$0-2], $$[$0]] };
|
||||||
}
|
|
||||||
setLines(this.$, _$[$0-2], _$[$0]);
|
setLines(this.$, _$[$0-2], _$[$0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -566,31 +472,19 @@ case 88:
|
|||||||
break;
|
break;
|
||||||
case 89:
|
case 89:
|
||||||
|
|
||||||
if ($$[$0].type == "NUMBER") {
|
|
||||||
this.$ = { type: "NUMBER", value: __P__.minus($$[$0].value).mod(__P__) };
|
|
||||||
} else {
|
|
||||||
this.$ = { type: "OP", op: "UMINUS", values: [$$[$0]] };
|
this.$ = { type: "OP", op: "UMINUS", values: [$$[$0]] };
|
||||||
}
|
|
||||||
setLines(this.$, _$[$0-1], _$[$0]);
|
setLines(this.$, _$[$0-1], _$[$0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 90:
|
case 90:
|
||||||
|
|
||||||
if ($$[$0].type == "NUMBER") {
|
|
||||||
this.$ = { type: "NUMBER", value: $$[$0].value.eq(0) ? bigInt(1) : bigInt(0) };
|
|
||||||
} else {
|
|
||||||
this.$ = { type: "OP", op: "!", values: [$$[$0]] };
|
this.$ = { type: "OP", op: "!", values: [$$[$0]] };
|
||||||
}
|
|
||||||
setLines(this.$, _$[$0-1], _$[$0]);
|
setLines(this.$, _$[$0-1], _$[$0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 91:
|
case 91:
|
||||||
|
|
||||||
if ($$[$0].type == "NUMBER") {
|
|
||||||
this.$ = { type: "NUMBER", value: $$[$0].value.xor(__MASK__) };
|
|
||||||
} else {
|
|
||||||
this.$ = { type: "OP", op: "~", values: [$$[$0]] };
|
this.$ = { type: "OP", op: "~", values: [$$[$0]] };
|
||||||
}
|
|
||||||
setLines(this.$, _$[$0-1], _$[$0]);
|
setLines(this.$, _$[$0-1], _$[$0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -613,13 +507,13 @@ case 97: case 102: case 103:
|
|||||||
break;
|
break;
|
||||||
case 98:
|
case 98:
|
||||||
|
|
||||||
this.$ = {type: "NUMBER", value: bigInt($$[$0]).mod(__P__) }
|
this.$ = {type: "NUMBER", value: Scalar.fromString($$[$0]) }
|
||||||
setLines(this.$, _$[$0]);
|
setLines(this.$, _$[$0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 99:
|
case 99:
|
||||||
|
|
||||||
this.$ = {type: "NUMBER", value: bigInt($$[$0].substr(2).toUpperCase(), 16).mod(__P__) }
|
this.$ = {type: "NUMBER", value: Scalar.fromString($$[$0].substr(2).toUpperCase(), 16) }
|
||||||
setLines(this.$, _$[$0]);
|
setLines(this.$, _$[$0]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -866,10 +760,8 @@ parse: function parse(input) {
|
|||||||
return true;
|
return true;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
const bigInt = require('big-integer');
|
const Scalar = require('ffjavascript').Scalar;
|
||||||
const util = require('util');
|
const util = require('util');
|
||||||
const __P__ = new bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
|
||||||
const __MASK__ = new bigInt(2).pow(253).minus(1);
|
|
||||||
|
|
||||||
function setLines(dst, first, last) {
|
function setLines(dst, first, last) {
|
||||||
last = last || first;
|
last = last || first;
|
||||||
@@ -1365,7 +1257,7 @@ case 77: console.log("INVALID: " + yy_.yytext); return 'INVALID'
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
rules: [/^(?:\s+)/,/^(?:\/\*([^*]|[\r\n]|(\*+([^*\/]|[\r\n])))*\*+\/)/,/^(?:\/\/.*)/,/^(?:var\b)/,/^(?:signal\b)/,/^(?:private\b)/,/^(?:input\b)/,/^(?:output\b)/,/^(?:linearCombination\b)/,/^(?:component\b)/,/^(?:template\b)/,/^(?:function\b)/,/^(?:if\b)/,/^(?:else\b)/,/^(?:for\b)/,/^(?:while\b)/,/^(?:compute\b)/,/^(?:do\b)/,/^(?:return\b)/,/^(?:include\b)/,/^(?:0x[0-9A-Fa-f]*)/,/^(?:[0-9]+)/,/^(?:[a-zA-Z][a-zA-Z$_0-9]*)/,/^(?:"[^"]+")/,/^(?:==>)/,/^(?:<==)/,/^(?:-->)/,/^(?:<--)/,/^(?:===)/,/^(?:>>=)/,/^(?:<<=)/,/^(?:&&)/,/^(?:\|\|)/,/^(?:==)/,/^(?:<=)/,/^(?:>=)/,/^(?:!=)/,/^(?:>>)/,/^(?:<<)/,/^(?:\*\*)/,/^(?:\+\+)/,/^(?:--)/,/^(?:\+=)/,/^(?:-=)/,/^(?:\*=)/,/^(?:\/=)/,/^(?:%=)/,/^(?:\|=)/,/^(?:&=)/,/^(?:\^=)/,/^(?:=)/,/^(?:\+)/,/^(?:-)/,/^(?:\*)/,/^(?:\/)/,/^(?:\\)/,/^(?:%)/,/^(?:\^)/,/^(?:&)/,/^(?:\|)/,/^(?:!)/,/^(?:~)/,/^(?:<)/,/^(?:>)/,/^(?:!)/,/^(?:\?)/,/^(?::)/,/^(?:\()/,/^(?:\))/,/^(?:\[)/,/^(?:\])/,/^(?:\{)/,/^(?:\})/,/^(?:;)/,/^(?:,)/,/^(?:\.)/,/^(?:$)/,/^(?:.)/],
|
rules: [/^(?:\s+)/,/^(?:\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\/)/,/^(?:\/\/.*)/,/^(?:var\b)/,/^(?:signal\b)/,/^(?:private\b)/,/^(?:input\b)/,/^(?:output\b)/,/^(?:linearCombination\b)/,/^(?:component\b)/,/^(?:template\b)/,/^(?:function\b)/,/^(?:if\b)/,/^(?:else\b)/,/^(?:for\b)/,/^(?:while\b)/,/^(?:compute\b)/,/^(?:do\b)/,/^(?:return\b)/,/^(?:include\b)/,/^(?:0x[0-9A-Fa-f]*)/,/^(?:[0-9]+)/,/^(?:[a-zA-Z][a-zA-Z$_0-9]*)/,/^(?:"[^"]+")/,/^(?:==>)/,/^(?:<==)/,/^(?:-->)/,/^(?:<--)/,/^(?:===)/,/^(?:>>=)/,/^(?:<<=)/,/^(?:&&)/,/^(?:\|\|)/,/^(?:==)/,/^(?:<=)/,/^(?:>=)/,/^(?:!=)/,/^(?:>>)/,/^(?:<<)/,/^(?:\*\*)/,/^(?:\+\+)/,/^(?:--)/,/^(?:\+=)/,/^(?:-=)/,/^(?:\*=)/,/^(?:\/=)/,/^(?:%=)/,/^(?:\|=)/,/^(?:&=)/,/^(?:\^=)/,/^(?:=)/,/^(?:\+)/,/^(?:-)/,/^(?:\*)/,/^(?:\/)/,/^(?:\\)/,/^(?:%)/,/^(?:\^)/,/^(?:&)/,/^(?:\|)/,/^(?:!)/,/^(?:~)/,/^(?:<)/,/^(?:>)/,/^(?:!)/,/^(?:\?)/,/^(?::)/,/^(?:\()/,/^(?:\))/,/^(?:\[)/,/^(?:\])/,/^(?:\{)/,/^(?:\})/,/^(?:;)/,/^(?:,)/,/^(?:\.)/,/^(?:$)/,/^(?:.)/],
|
||||||
conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77],"inclusive":true}}
|
conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77],"inclusive":true}}
|
||||||
});
|
});
|
||||||
return lexer;
|
return lexer;
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
const streamFromMultiArray = require("../../src/streamfromarray_txt.js");
|
|
||||||
const bigInt = require("big-integer");
|
|
||||||
const utils = require("../../src/utils");
|
const utils = require("../../src/utils");
|
||||||
const assert = require("assert");
|
const assert = require("assert");
|
||||||
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
|
const F1Field = require("ffjavascript").F1Field;
|
||||||
|
const BigArray = require("../../src/bigarray");
|
||||||
|
|
||||||
function ref2src(c) {
|
function ref2src(c) {
|
||||||
if ((c[0] == "R")||(c[0] == "RI")) {
|
if ((c[0] == "R")||(c[0] == "RI")) {
|
||||||
@@ -94,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});
|
||||||
}
|
}
|
||||||
@@ -214,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)});`);
|
||||||
}
|
}
|
||||||
@@ -340,15 +347,23 @@ class FunctionBuilderC {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class BuilderC {
|
class BuilderC {
|
||||||
constructor() {
|
constructor(p, verbose) {
|
||||||
|
this.F = new F1Field(p);
|
||||||
|
|
||||||
this.hashMaps={};
|
this.hashMaps={};
|
||||||
this.componentEntriesTables={};
|
this.componentEntriesTables=new BigArray();
|
||||||
this.sizes ={};
|
this.sizes ={};
|
||||||
this.constants = [];
|
this.constants = [];
|
||||||
this.functions = [];
|
this.functions = [];
|
||||||
this.components = [];
|
this.components = new BigArray();
|
||||||
this.usedConstants = {};
|
this.usedConstants = {};
|
||||||
|
this.verbose = verbose;
|
||||||
|
|
||||||
|
|
||||||
|
this.sizePointers = {};
|
||||||
|
this.hashMapPointers = {};
|
||||||
|
this.functionIdx = {};
|
||||||
|
this.nCets = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
setHeader(header) {
|
setHeader(header) {
|
||||||
@@ -360,8 +375,11 @@ class BuilderC {
|
|||||||
this.hashMaps[name] = hm;
|
this.hashMaps[name] = hm;
|
||||||
}
|
}
|
||||||
|
|
||||||
addComponentEntriesTable(name, cet) {
|
addComponentEntriesTable(name, cet, idComponent) {
|
||||||
this.componentEntriesTables[name] = cet;
|
this.componentEntriesTables[idComponent] = {
|
||||||
|
name: name,
|
||||||
|
cet: cet
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
addSizes(name, accSizes) {
|
addSizes(name, accSizes) {
|
||||||
@@ -369,9 +387,9 @@ class BuilderC {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addConstant(c) {
|
addConstant(c) {
|
||||||
c = bigInt(c);
|
c = this.F.e(c);
|
||||||
const cS = c.toString();
|
const cS = c.toString();
|
||||||
if (this.usedConstants[cS]) return this.usedConstants[cS];
|
if (typeof this.usedConstants[cS] != "undefined") return this.usedConstants[cS];
|
||||||
this.constants.push(c);
|
this.constants.push(c);
|
||||||
this.usedConstants[cS] = this.constants.length - 1;
|
this.usedConstants[cS] = this.constants.length - 1;
|
||||||
return this.constants.length - 1;
|
return this.constants.length - 1;
|
||||||
@@ -407,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}`,
|
||||||
@@ -419,207 +437,285 @@ 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");
|
|
||||||
for (let cetName in this.componentEntriesTables) {
|
while (fdData.pos % 8) fdData.pos++;
|
||||||
const cet = this.componentEntriesTables[cetName];
|
this.pCets = fdData.pos;
|
||||||
|
for (let i=0; i< this.componentEntriesTables.length; i++) {
|
||||||
|
if ((this.verbose)&&(i%100000 ==0)) console.log(`_buildComponentEntriesTables ${i}/${this.componentEntriesTables.length}`);
|
||||||
|
const cet = this.componentEntriesTables[i].cet;
|
||||||
|
|
||||||
|
this.components[i].entryTablePointer = fdData.pos;
|
||||||
|
const buff = new Uint8Array(16*cet.length);
|
||||||
|
const buffV = new DataView(buff.buffer);
|
||||||
|
|
||||||
code.push(`Circom_ComponentEntry ${cetName}[${cet.length}] = {`);
|
|
||||||
for (let j=0; j<cet.length; j++) {
|
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;
|
||||||
const n64 = Math.floor((self.header.P.bitLength() - 1) / 64)+1;
|
|
||||||
const R = bigInt.one.shiftLeft(n64*64);
|
|
||||||
|
|
||||||
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);
|
||||||
|
const buffV = new DataView(buff.buffer);
|
||||||
|
|
||||||
|
|
||||||
|
while (fdData.pos % 8) fdData.pos++;
|
||||||
|
this.pConstants = fdData.pos;
|
||||||
|
|
||||||
|
let o = 0;
|
||||||
for (let i=0; i<self.constants.length; i++) {
|
for (let i=0; i<self.constants.length; i++) {
|
||||||
code.push((i>0 ? "," : " ") + "{" + number2Code(self.constants[i]) + "}");
|
Fr2Bytes(buffV, o, self.constants[i]);
|
||||||
|
o += frSize;
|
||||||
}
|
}
|
||||||
code.push("};");
|
await fdData.write(buff);
|
||||||
|
|
||||||
function number2Code(n) {
|
|
||||||
if (n.lt(bigInt("80000000", 16)) ) {
|
|
||||||
return addShortMontgomeryPositive(n);
|
|
||||||
}
|
|
||||||
if (n.geq(self.header.P.minus(bigInt("80000000", 16))) ) {
|
|
||||||
return addShortMontgomeryNegative(n);
|
|
||||||
}
|
|
||||||
return addLongMontgomery(n);
|
|
||||||
|
|
||||||
|
|
||||||
function addShortMontgomeryPositive(a) {
|
function Fr2Bytes(buffV, offset, n) {
|
||||||
return `${a.toString()}, 0x40000000, { ${getLongString(toMontgomery(a))} }`;
|
const minShort = self.F.neg(self.F.e("80000000"));
|
||||||
|
const maxShort = self.F.e("7FFFFFFF", 16);
|
||||||
|
|
||||||
|
if ( (self.F.geq(n, minShort))
|
||||||
|
&&(self.F.leq(n, maxShort)))
|
||||||
|
{
|
||||||
|
if (self.F.geq(n, self.F.zero)) {
|
||||||
|
return shortMontgomeryPositive(n);
|
||||||
|
} else {
|
||||||
|
return shortMontgomeryNegative(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return longMontgomery(n);
|
||||||
|
|
||||||
|
|
||||||
|
function shortMontgomeryPositive(a) {
|
||||||
|
buffV.setUint32(offset, Scalar.toNumber(a) , true );
|
||||||
|
buffV.setUint32(offset + 4, 0x40000000 , true );
|
||||||
|
long(buffV, offset + 8, toMontgomery(a));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function addShortMontgomeryNegative(a) {
|
function shortMontgomeryNegative(a) {
|
||||||
const b = a.minus(self.header.P);
|
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 r = bigInt(a);
|
|
||||||
let S = "";
|
let p = offset;
|
||||||
let i = 0;
|
const arr = Scalar.toArray(a, 0x100000000);
|
||||||
while (!r.isZero()) {
|
for (let i=0; i<self.F.n64*2; i++) {
|
||||||
if (S!= "") S = S+",";
|
const idx = arr.length-1-i;
|
||||||
S += "0x" + r.and(bigInt("FFFFFFFFFFFFFFFF", 16)).toString(16) + "LL";
|
|
||||||
i++;
|
if ( idx >=0) {
|
||||||
r = r.shiftRight(64);
|
buffV.setUint32(p, arr[idx], true);
|
||||||
|
} else {
|
||||||
|
buffV.setUint32(p, 0, true);
|
||||||
}
|
}
|
||||||
while (i<n64) {
|
p+= 4;
|
||||||
if (S!= "") S = S+",";
|
|
||||||
S += "0LL";
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
return S;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function toMontgomery(a) {
|
function toMontgomery(a) {
|
||||||
return a.times(R).mod(self.header.P);
|
return self.F.mul(a, self.F.R);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_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++) {
|
||||||
for (let i=0; i<this.components.length; i++) {
|
|
||||||
const c = this.components[i];
|
|
||||||
const sep = i>0 ? " ," : " ";
|
const sep = i>0 ? " ," : " ";
|
||||||
code.push(`${sep}{${c.hashMapName}, ${c.entryTableName}, ${c.functionName}, ${c.nInSignals}, ${c.newThread}}`);
|
code.push(`${sep}${this.functions[listedFunctions[i]].name}`);
|
||||||
}
|
}
|
||||||
code.push("};");
|
code.push("};");
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildMapIsInput(code) {
|
|
||||||
code.push("// mapIsInput");
|
async _buildComponents(fdData) {
|
||||||
code.push(`u32 _mapIsInput[${this.mapIsInput.length}] = {`);
|
|
||||||
let line = "";
|
const buff = new Uint8Array(32);
|
||||||
|
const buffV = new DataView(buff.buffer);
|
||||||
|
|
||||||
|
while (fdData.pos % 8) fdData.pos++;
|
||||||
|
this.pComponents = fdData.pos;
|
||||||
|
|
||||||
|
for (let i=0; i<this.components.length; i++) {
|
||||||
|
if ((this.verbose)&&(i%1000000 ==0)) console.log(`_buildComponents ${i}/${this.components.length}`);
|
||||||
|
const c = this.components[i];
|
||||||
|
|
||||||
|
utils.setUint64(buffV, 0, this.hashMapPointers[c.hashMapName], true);
|
||||||
|
utils.setUint64(buffV, 8, c.entryTablePointer, true);
|
||||||
|
utils.setUint64(buffV, 16, this.functionIdx[c.functionName], true);
|
||||||
|
buffV.setUint32(24, c.nInSignals, true);
|
||||||
|
buffV.setUint32(28, c.newThread ? 1 : 0, true);
|
||||||
|
|
||||||
|
await fdData.write(buff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async _buildMapIsInput(fdData) {
|
||||||
|
|
||||||
|
const buff = new Uint8Array(this.mapIsInput.length * 4);
|
||||||
|
const buffV = new DataView(buff.buffer);
|
||||||
|
|
||||||
|
while (fdData.pos % 8) fdData.pos++;
|
||||||
|
this.pMapIsInput = fdData.pos;
|
||||||
|
|
||||||
for (let i=0; i<this.mapIsInput.length; i++) {
|
for (let i=0; i<this.mapIsInput.length; i++) {
|
||||||
line += i>0 ? ", " : " ";
|
if ((this.verbose)&&(i%1000000 ==0)) console.log(`_buildMapIsInput ${i}/${this.mapIsInput.length}`);
|
||||||
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++) {
|
||||||
line += i>0 ? "," : " ";
|
if ((this.verbose)&&(i%1000000 ==0)) console.log(`_buildWit2Sig ${i}/${this.wit2sig.length}`);
|
||||||
line += this.wit2sig[i];
|
|
||||||
if (((i+1) % 64) == 0) {
|
buffV.setUint32(4*i, this.wit2sig[i], true);
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
build() {
|
async build(fdCode, fdData) {
|
||||||
const code=[];
|
const encoder = new TextEncoder("utf-8");
|
||||||
|
fdData.pos = 72;
|
||||||
|
while (fdData.pos % 8) fdData.pos++;
|
||||||
|
|
||||||
|
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);
|
||||||
return streamFromMultiArray(code);
|
await writeCode(code);
|
||||||
|
|
||||||
|
async function writeCode(c) {
|
||||||
|
if (c.push) {
|
||||||
|
for (let i=0; i<c.length; i++) {
|
||||||
|
await writeCode(c[i]);
|
||||||
|
}
|
||||||
|
} else if (typeof c === "string") {
|
||||||
|
await fdCode.write(encoder.encode(c + "\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,11 +8,14 @@ const compiler = require("../../src/compiler");
|
|||||||
const util = require("util");
|
const util = require("util");
|
||||||
const exec = util.promisify(require("child_process").exec);
|
const exec = util.promisify(require("child_process").exec);
|
||||||
|
|
||||||
const bigInt = require("big-integer");
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
const utils = require("../../src/utils");
|
const utils = require("../../src/utils");
|
||||||
const loadR1cs = require("r1csfile").load;
|
const loadR1cs = require("r1csfile").load;
|
||||||
const ZqField = require("ffjavascript").ZqField;
|
const ZqField = require("ffjavascript").ZqField;
|
||||||
const buildZqField = require("ffiasm").buildZqField;
|
const buildZqField = require("ffiasm").buildZqField;
|
||||||
|
const fastFile = require("fastfile");
|
||||||
|
|
||||||
|
const {stringifyBigInts, unstringifyBigInts } = require("ffjavascript").utils;
|
||||||
|
|
||||||
module.exports = c_tester;
|
module.exports = c_tester;
|
||||||
|
|
||||||
@@ -27,38 +30,45 @@ async function c_tester(circomFile, _options) {
|
|||||||
const baseName = path.basename(circomFile, ".circom");
|
const baseName = path.basename(circomFile, ".circom");
|
||||||
const options = Object.assign({}, _options);
|
const options = Object.assign({}, _options);
|
||||||
|
|
||||||
options.cSourceWriteStream = fs.createWriteStream(path.join(dir.path, baseName + ".cpp"));
|
options.cSourceFile = await fastFile.createOverride(path.join(dir.path, baseName + ".cpp"));
|
||||||
|
options.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");
|
||||||
|
|
||||||
options.p = options.p || bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
options.p = options.p || Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||||
await compiler(circomFile, options);
|
await compiler(circomFile, options);
|
||||||
|
|
||||||
|
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 = "";
|
||||||
|
|
||||||
if (process.platform === "darwin") {
|
if (process.platform === "darwin") {
|
||||||
await exec("nasm -fmacho64 --prefix _ " +
|
await exec("nasm -fmacho64 --prefix _ " +
|
||||||
` ${path.join(dir.path, "fr.asm")}`
|
` ${path.join(dir.path, "fr.asm")}`
|
||||||
);
|
);
|
||||||
} else if (process.platform === "linux") {
|
} else if (process.platform === "linux") {
|
||||||
|
pThread = "-pthread";
|
||||||
await exec("nasm -felf64 " +
|
await exec("nasm -felf64 " +
|
||||||
` ${path.join(dir.path, "fr.asm")}`
|
` ${path.join(dir.path, "fr.asm")}`
|
||||||
);
|
);
|
||||||
} else throw("Unsupported platform");
|
} else throw("Unsupported platform");
|
||||||
|
|
||||||
const cdir = path.join(__dirname, "..", "..", "node_modules", "circom_runtime", "c");
|
const cdir = path.join(path.dirname(require.resolve("circom_runtime")), "c");
|
||||||
|
|
||||||
await exec("g++" +
|
await exec("g++" + ` ${pThread}` +
|
||||||
` ${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)}` +
|
||||||
@@ -84,7 +94,7 @@ class CTester {
|
|||||||
async calculateWitness(input) {
|
async calculateWitness(input) {
|
||||||
await fs.promises.writeFile(
|
await fs.promises.writeFile(
|
||||||
path.join(this.dir.path, "in.json"),
|
path.join(this.dir.path, "in.json"),
|
||||||
JSON.stringify(utils.stringifyBigInts(input), null, 1)
|
JSON.stringify(stringifyBigInts(input), null, 1)
|
||||||
);
|
);
|
||||||
const r = await exec(`${path.join(this.dir.path, this.baseName)}` +
|
const r = await exec(`${path.join(this.dir.path, this.baseName)}` +
|
||||||
` ${path.join(this.dir.path, "in.json")}` +
|
` ${path.join(this.dir.path, "in.json")}` +
|
||||||
@@ -97,7 +107,7 @@ class CTester {
|
|||||||
path.join(this.dir.path, "out.json")
|
path.join(this.dir.path, "out.json")
|
||||||
);
|
);
|
||||||
|
|
||||||
const res = utils.unstringifyBigInts(JSON.parse(resStr));
|
const res = unstringifyBigInts(JSON.parse(resStr));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,7 +134,7 @@ class CTester {
|
|||||||
const self = this;
|
const self = this;
|
||||||
if (this.constraints) return;
|
if (this.constraints) return;
|
||||||
const r1cs = await loadR1cs(path.join(this.dir.path, this.baseName + ".r1cs"),true, false);
|
const r1cs = await loadR1cs(path.join(this.dir.path, this.baseName + ".r1cs"),true, false);
|
||||||
self.field = new ZqField(r1cs.prime);
|
self.F = new ZqField(r1cs.prime);
|
||||||
self.nVars = r1cs.nVars;
|
self.nVars = r1cs.nVars;
|
||||||
self.constraints = r1cs.constraints;
|
self.constraints = r1cs.constraints;
|
||||||
}
|
}
|
||||||
@@ -149,8 +159,8 @@ class CTester {
|
|||||||
if (typeof self.symbols[prefix] == "undefined") {
|
if (typeof self.symbols[prefix] == "undefined") {
|
||||||
assert(false, "Output variable not defined: "+ prefix);
|
assert(false, "Output variable not defined: "+ prefix);
|
||||||
}
|
}
|
||||||
const ba = bigInt(actualOut[self.symbols[prefix].varIdx]).toString();
|
const ba = actualOut[self.symbols[prefix].varIdx].toString();
|
||||||
const be = bigInt(eOut).toString();
|
const be = eOut.toString();
|
||||||
assert.strictEqual(ba, be, prefix);
|
assert.strictEqual(ba, be, prefix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -180,7 +190,7 @@ class CTester {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function checkConstraint(constraint) {
|
function checkConstraint(constraint) {
|
||||||
const F = self.field;
|
const F = self.F;
|
||||||
const a = evalLC(constraint[0]);
|
const a = evalLC(constraint[0]);
|
||||||
const b = evalLC(constraint[1]);
|
const b = evalLC(constraint[1]);
|
||||||
const c = evalLC(constraint[2]);
|
const c = evalLC(constraint[2]);
|
||||||
@@ -189,7 +199,7 @@ class CTester {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function evalLC(lc) {
|
function evalLC(lc) {
|
||||||
const F = self.field;
|
const F = self.F;
|
||||||
let v = F.zero;
|
let v = F.zero;
|
||||||
for (let w in lc) {
|
for (let w in lc) {
|
||||||
v = F.add(
|
v = F.add(
|
||||||
|
|||||||
@@ -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");
|
||||||
@@ -728,12 +757,9 @@ module.exports = function buildRuntime(module, builder) {
|
|||||||
|
|
||||||
c.setLocal(
|
c.setLocal(
|
||||||
"pSrc",
|
"pSrc",
|
||||||
c.i32_add(
|
c.call(
|
||||||
c.i32_const(builder.pSignals),
|
"getPWitness",
|
||||||
c.i32_mul(
|
|
||||||
c.getLocal("i"),
|
c.getLocal("i"),
|
||||||
c.i32_const(builder.sizeFr)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
|
||||||
@@ -745,7 +771,7 @@ module.exports = function buildRuntime(module, builder) {
|
|||||||
c.setLocal(
|
c.setLocal(
|
||||||
"pDst",
|
"pDst",
|
||||||
c.i32_add(
|
c.i32_add(
|
||||||
c.i32_const(builder.pSignals),
|
c.i32_const(builder.pOutput),
|
||||||
c.i32_mul(
|
c.i32_mul(
|
||||||
c.getLocal("i"),
|
c.getLocal("i"),
|
||||||
c.i32_const(builder.sizeFr-8)
|
c.i32_const(builder.sizeFr-8)
|
||||||
@@ -770,7 +796,7 @@ module.exports = function buildRuntime(module, builder) {
|
|||||||
c.br(0)
|
c.br(0)
|
||||||
)),
|
)),
|
||||||
|
|
||||||
c.i32_const(builder.pSignals)
|
c.i32_const(builder.pOutput)
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -804,6 +830,7 @@ module.exports = function buildRuntime(module, builder) {
|
|||||||
buildWasmFf(module, "Fr", builder.header.P);
|
buildWasmFf(module, "Fr", builder.header.P);
|
||||||
|
|
||||||
builder.pSignals=module.alloc(builder.header.NSignals*builder.sizeFr);
|
builder.pSignals=module.alloc(builder.header.NSignals*builder.sizeFr);
|
||||||
|
builder.pOutput=module.alloc(builder.header.NVars*(builder.sizeFr-8));
|
||||||
builder.pInputSignalsToTrigger=module.alloc(builder.header.NComponents*4);
|
builder.pInputSignalsToTrigger=module.alloc(builder.header.NComponents*4);
|
||||||
builder.pSignalsAssigned=module.alloc(builder.header.NSignals*4);
|
builder.pSignalsAssigned=module.alloc(builder.header.NSignals*4);
|
||||||
|
|
||||||
@@ -825,6 +852,7 @@ module.exports = function buildRuntime(module, builder) {
|
|||||||
buildComponentFinished();
|
buildComponentFinished();
|
||||||
|
|
||||||
buildCheckConstraint();
|
buildCheckConstraint();
|
||||||
|
buildCheckAssert();
|
||||||
|
|
||||||
buildGetNVars();
|
buildGetNVars();
|
||||||
buildGetFrLen();
|
buildGetFrLen();
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
const streamFromArrayTxt = require("../../src/streamfromarray_txt");
|
|
||||||
const streamFromArrayBin = require("../../src/streamfromarray_bin");
|
|
||||||
const bigInt = require("big-integer");
|
|
||||||
const assert = require("assert");
|
const assert = require("assert");
|
||||||
const ModuleBuilder = require("wasmbuilder").ModuleBuilder;
|
const ModuleBuilder = require("wasmbuilder").ModuleBuilder;
|
||||||
const ModuleBuilderWat = require("wasmbuilder").ModuleBuilderWat;
|
const ModuleBuilderWat = require("wasmbuilder").ModuleBuilderWat;
|
||||||
const buildRuntime = require("./build_runtime");
|
const buildRuntime = require("./build_runtime");
|
||||||
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
|
const F1Field = require("ffjavascript").F1Field;
|
||||||
|
|
||||||
|
|
||||||
const errs = require("./errs");
|
const errs = require("./errs");
|
||||||
@@ -99,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);
|
||||||
@@ -333,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(
|
||||||
@@ -689,7 +700,8 @@ class FunctionBuilderWasm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class BuilderWasm {
|
class BuilderWasm {
|
||||||
constructor() {
|
constructor(p) {
|
||||||
|
this.F = new F1Field(p);
|
||||||
this.hashMaps={};
|
this.hashMaps={};
|
||||||
this.componentEntriesTables={};
|
this.componentEntriesTables={};
|
||||||
this.sizes ={};
|
this.sizes ={};
|
||||||
@@ -701,8 +713,8 @@ class BuilderWasm {
|
|||||||
this.TYPE_SIGNAL = 1;
|
this.TYPE_SIGNAL = 1;
|
||||||
this.TYPE_COMPONENT = 2;
|
this.TYPE_COMPONENT = 2;
|
||||||
|
|
||||||
this.addConstant(bigInt(0)); // constants[0] = 0;
|
this.addConstant(Scalar.fromString("0")); // constants[0] = 0;
|
||||||
this.addConstant(bigInt(1)); // constants[1] = 1;
|
this.addConstant(Scalar.fromString("1")); // constants[1] = 1;
|
||||||
|
|
||||||
this.offsetComponentNInputSignals = 12;
|
this.offsetComponentNInputSignals = 12;
|
||||||
this.sizeofComponent = 20;
|
this.sizeofComponent = 20;
|
||||||
@@ -710,7 +722,8 @@ class BuilderWasm {
|
|||||||
|
|
||||||
setHeader(header) {
|
setHeader(header) {
|
||||||
this.header=header;
|
this.header=header;
|
||||||
this.n64 = Math.floor((this.header.P.bitLength() - 1) / 64)+1;
|
|
||||||
|
this.n64 = Math.floor((Scalar.bitLength(this.header.P) - 1) / 64)+1;
|
||||||
this.sizeFr = this.n64*8 + 8;
|
this.sizeFr = this.n64*8 + 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -728,9 +741,9 @@ class BuilderWasm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addConstant(c) {
|
addConstant(c) {
|
||||||
c = bigInt(c);
|
c = this.F.e(c);
|
||||||
const cS = c.toString();
|
const cS = c.toString();
|
||||||
if (this.usedConstants[cS]) return this.usedConstants[cS];
|
if (typeof this.usedConstants[cS] != "undefined") return this.usedConstants[cS];
|
||||||
this.constants.push(c);
|
this.constants.push(c);
|
||||||
this.usedConstants[cS] = this.constants.length - 1;
|
this.usedConstants[cS] = this.constants.length - 1;
|
||||||
return this.constants.length - 1;
|
return this.constants.length - 1;
|
||||||
@@ -842,7 +855,6 @@ class BuilderWasm {
|
|||||||
|
|
||||||
_buildConstants(module) {
|
_buildConstants(module) {
|
||||||
const self = this;
|
const self = this;
|
||||||
const R = bigInt.one.shiftLeft(this.n64*64);
|
|
||||||
|
|
||||||
const bytes = [];
|
const bytes = [];
|
||||||
for (let i=0; i<self.constants.length; i++) {
|
for (let i=0; i<self.constants.length; i++) {
|
||||||
@@ -852,19 +864,27 @@ class BuilderWasm {
|
|||||||
const fBytes = [].concat(...bytes);
|
const fBytes = [].concat(...bytes);
|
||||||
this.pConstants = module.alloc(fBytes);
|
this.pConstants = module.alloc(fBytes);
|
||||||
|
|
||||||
|
|
||||||
function Fr2Bytes(n) {
|
function Fr2Bytes(n) {
|
||||||
if (n.lt(bigInt("80000000", 16)) ) {
|
const minShort = self.F.neg(self.F.e("80000000"));
|
||||||
|
const maxShort = self.F.e("7FFFFFFF", 16);
|
||||||
|
|
||||||
|
if ( (self.F.geq(n, minShort))
|
||||||
|
&&(self.F.leq(n, maxShort)))
|
||||||
|
{
|
||||||
|
if (self.F.geq(n, self.F.zero)) {
|
||||||
return shortMontgomeryPositive(n);
|
return shortMontgomeryPositive(n);
|
||||||
}
|
} else {
|
||||||
if (n.geq(self.header.P.minus(bigInt("80000000", 16))) ) {
|
|
||||||
return shortMontgomeryNegative(n);
|
return shortMontgomeryNegative(n);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return longMontgomery(n);
|
return longMontgomery(n);
|
||||||
|
|
||||||
|
|
||||||
function shortMontgomeryPositive(a) {
|
function shortMontgomeryPositive(a) {
|
||||||
return [
|
return [
|
||||||
...intToBytes32(parseInt(a)),
|
...intToBytes32(Scalar.toNumber(a)),
|
||||||
...intToBytes32(0x40000000),
|
...intToBytes32(0x40000000),
|
||||||
...long(toMontgomery(a))
|
...long(toMontgomery(a))
|
||||||
];
|
];
|
||||||
@@ -872,9 +892,9 @@ class BuilderWasm {
|
|||||||
|
|
||||||
|
|
||||||
function shortMontgomeryNegative(a) {
|
function shortMontgomeryNegative(a) {
|
||||||
const b = a.minus(self.header.P);
|
const b = -Scalar.toNumber(self.F.neg(a));
|
||||||
return [
|
return [
|
||||||
...intToBytes32(parseInt(b)),
|
...intToBytes32(b),
|
||||||
...intToBytes32(0x40000000),
|
...intToBytes32(0x40000000),
|
||||||
...long(toMontgomery(a))
|
...long(toMontgomery(a))
|
||||||
];
|
];
|
||||||
@@ -889,27 +909,24 @@ class BuilderWasm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function long(a) {
|
function long(a) {
|
||||||
|
|
||||||
const bytes = [];
|
const bytes = [];
|
||||||
let r = bigInt(a);
|
const arr = Scalar.toArray(a, 0x100000000);
|
||||||
let S = "";
|
for (let i=0; i<self.F.n64*2; i++) {
|
||||||
let i = 0;
|
const idx = arr.length-1-i;
|
||||||
while (!r.isZero()) {
|
|
||||||
S = ("0000000000000000" + r.and(bigInt("FFFFFFFFFFFFFFFF", 16)).toString(16)).substr(-16);
|
if ( idx >=0) {
|
||||||
bytes.push(hexToBytesR(S));
|
bytes.push(...intToBytes32(arr[idx]));
|
||||||
i++;
|
} else {
|
||||||
r = r.shiftRight(64);
|
bytes.push(...intToBytes32(0));
|
||||||
}
|
}
|
||||||
while (i<self.n64) {
|
|
||||||
bytes.push(hexToBytesR("0000000000000000"));
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const fBytes = [].concat(...bytes);
|
return bytes;
|
||||||
return fBytes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function toMontgomery(a) {
|
function toMontgomery(a) {
|
||||||
return a.times(R).mod(self.header.P);
|
return self.F.mul(a, self.F.R);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -923,41 +940,41 @@ class BuilderWasm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_buildComponents(module) {
|
_buildComponents(module) {
|
||||||
const bytes = [];
|
const bytes = new Array(this.components.length*5*4);
|
||||||
|
bytes.length=0;
|
||||||
for (let i=0; i<this.components.length; i++) {
|
for (let i=0; i<this.components.length; i++) {
|
||||||
const c = this.components[i];
|
const c = this.components[i];
|
||||||
|
|
||||||
bytes.push(intToBytes32(this.hashMaps[c.hashMapName].pointer));
|
bytes.push(...intToBytes32(this.hashMaps[c.hashMapName].pointer));
|
||||||
bytes.push(intToBytes32(this.componentEntriesTables[c.entryTableName].pointer));
|
bytes.push(...intToBytes32(this.componentEntriesTables[c.entryTableName].pointer));
|
||||||
bytes.push(intToBytes32(i));
|
bytes.push(...intToBytes32(i));
|
||||||
bytes.push(intToBytes32(c.nInSignals));
|
bytes.push(...intToBytes32(c.nInSignals));
|
||||||
bytes.push(intToBytes32(c.newThread ? 1 : 0));
|
bytes.push(...intToBytes32(c.newThread ? 1 : 0));
|
||||||
|
|
||||||
module.addFunctionToTable(c.functionName);
|
module.addFunctionToTable(c.functionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
const fBytes = [].concat(...bytes);
|
this.pComponents = module.alloc(bytes);
|
||||||
this.pComponents = module.alloc(fBytes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildMapIsInput(module) {
|
_buildMapIsInput(module) {
|
||||||
const bytes = [];
|
const bytes = new Array(this.mapIsInput.length*4);
|
||||||
|
bytes.length=0;
|
||||||
for (let i=0; i<this.mapIsInput.length; i++) {
|
for (let i=0; i<this.mapIsInput.length; i++) {
|
||||||
bytes.push(intToBytes32(this.mapIsInput[i]));
|
bytes.push(...intToBytes32(this.mapIsInput[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
const fBytes = [].concat(...bytes);
|
this.pMapIsInput = module.alloc(bytes);
|
||||||
this.pMapIsInput = module.alloc(fBytes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildWit2Sig(module) {
|
_buildWit2Sig(module) {
|
||||||
const bytes = [];
|
const bytes = new Array(this.wit2sig.length*4);
|
||||||
|
bytes.length =0;
|
||||||
for (let i=0; i<this.wit2sig.length; i++) {
|
for (let i=0; i<this.wit2sig.length; i++) {
|
||||||
bytes.push(intToBytes32(this.wit2sig[i]));
|
bytes.push(...intToBytes32(this.wit2sig[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
const fBytes = [].concat(...bytes);
|
this.pWit2sig = module.alloc(bytes);
|
||||||
this.pWit2sig = module.alloc(fBytes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildCircuitVar(module) {
|
_buildCircuitVar(module) {
|
||||||
@@ -983,7 +1000,8 @@ class BuilderWasm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
build(outType) {
|
async build(fd, outType) {
|
||||||
|
const encoder = new TextEncoder("utf-8");
|
||||||
let module;
|
let module;
|
||||||
if (outType == "wasm") {
|
if (outType == "wasm") {
|
||||||
module=new ModuleBuilder();
|
module=new ModuleBuilder();
|
||||||
@@ -1010,12 +1028,25 @@ class BuilderWasm {
|
|||||||
|
|
||||||
module.setMemory(2000);
|
module.setMemory(2000);
|
||||||
if (outType == "wasm") {
|
if (outType == "wasm") {
|
||||||
return streamFromArrayBin(module.build());
|
const bytes = module.build();
|
||||||
|
const bytesArr = new Uint8Array(bytes);
|
||||||
|
await fd.write(bytesArr);
|
||||||
} else if (outType == "wat") {
|
} else if (outType == "wat") {
|
||||||
return streamFromArrayTxt(module.build());
|
const code = module.build();
|
||||||
|
await writeCode(code);
|
||||||
} else {
|
} else {
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function writeCode(c) {
|
||||||
|
if (c.push) {
|
||||||
|
for (let i=0; i<c.length; i++) {
|
||||||
|
await writeCode(c[i]);
|
||||||
|
}
|
||||||
|
} else if (typeof c === "string") {
|
||||||
|
await fd.write(encoder.encode(c + "\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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"},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ var tmp = require("tmp-promise");
|
|||||||
const path = require("path");
|
const path = require("path");
|
||||||
const compiler = require("../../src/compiler");
|
const compiler = require("../../src/compiler");
|
||||||
|
|
||||||
const bigInt = require("big-integer");
|
|
||||||
const utils = require("../../src/utils");
|
const utils = require("../../src/utils");
|
||||||
const loadR1cs = require("r1csfile").load;
|
const loadR1cs = require("r1csfile").load;
|
||||||
const ZqField = require("ffjavascript").ZqField;
|
const ZqField = require("ffjavascript").ZqField;
|
||||||
|
const fastFile = require("fastfile");
|
||||||
|
|
||||||
const WitnessCalculatorBuilder = require("circom_runtime").WitnessCalculatorBuilder;
|
const WitnessCalculatorBuilder = require("circom_runtime").WitnessCalculatorBuilder;
|
||||||
|
|
||||||
@@ -25,16 +25,14 @@ async function wasm_tester(circomFile, _options) {
|
|||||||
const baseName = path.basename(circomFile, ".circom");
|
const baseName = path.basename(circomFile, ".circom");
|
||||||
const options = Object.assign({}, _options);
|
const options = Object.assign({}, _options);
|
||||||
|
|
||||||
options.wasmWriteStream = fs.createWriteStream(path.join(dir.path, baseName + ".wasm"));
|
options.wasmFile = await fastFile.createOverride(path.join(dir.path, baseName + ".wasm"));
|
||||||
|
|
||||||
options.symWriteStream = fs.createWriteStream(path.join(dir.path, baseName + ".sym"));
|
options.symWriteStream = fs.createWriteStream(path.join(dir.path, baseName + ".sym"));
|
||||||
options.r1csFileName = path.join(dir.path, baseName + ".r1cs");
|
options.r1csFileName = path.join(dir.path, baseName + ".r1cs");
|
||||||
|
|
||||||
const promisesArr = [];
|
|
||||||
promisesArr.push(new Promise(fulfill => options.wasmWriteStream.on("finish", fulfill)));
|
|
||||||
|
|
||||||
await compiler(circomFile, options);
|
await compiler(circomFile, options);
|
||||||
|
|
||||||
await Promise.all(promisesArr);
|
await options.wasmFile.close();
|
||||||
|
|
||||||
const wasm = await fs.promises.readFile(path.join(dir.path, baseName + ".wasm"));
|
const wasm = await fs.promises.readFile(path.join(dir.path, baseName + ".wasm"));
|
||||||
|
|
||||||
@@ -82,7 +80,7 @@ class WasmTester {
|
|||||||
const self = this;
|
const self = this;
|
||||||
if (this.constraints) return;
|
if (this.constraints) return;
|
||||||
const r1cs = await loadR1cs(path.join(this.dir.path, this.baseName + ".r1cs"),true, false);
|
const r1cs = await loadR1cs(path.join(this.dir.path, this.baseName + ".r1cs"),true, false);
|
||||||
self.field = new ZqField(r1cs.prime);
|
self.F = new ZqField(r1cs.prime);
|
||||||
self.nVars = r1cs.nVars;
|
self.nVars = r1cs.nVars;
|
||||||
self.constraints = r1cs.constraints;
|
self.constraints = r1cs.constraints;
|
||||||
}
|
}
|
||||||
@@ -107,8 +105,8 @@ class WasmTester {
|
|||||||
if (typeof self.symbols[prefix] == "undefined") {
|
if (typeof self.symbols[prefix] == "undefined") {
|
||||||
assert(false, "Output variable not defined: "+ prefix);
|
assert(false, "Output variable not defined: "+ prefix);
|
||||||
}
|
}
|
||||||
const ba = bigInt(actualOut[self.symbols[prefix].varIdx]).toString();
|
const ba = actualOut[self.symbols[prefix].varIdx].toString();
|
||||||
const be = bigInt(eOut).toString();
|
const be = eOut.toString();
|
||||||
assert.strictEqual(ba, be, prefix);
|
assert.strictEqual(ba, be, prefix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -138,16 +136,16 @@ class WasmTester {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function checkConstraint(constraint) {
|
function checkConstraint(constraint) {
|
||||||
const F = self.field;
|
const F = self.F;
|
||||||
const a = evalLC(constraint[0]);
|
const a = evalLC(constraint[0]);
|
||||||
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) {
|
||||||
const F = self.field;
|
const F = self.F;
|
||||||
let v = F.zero;
|
let v = F.zero;
|
||||||
for (let w in lc) {
|
for (let w in lc) {
|
||||||
v = F.add(
|
v = F.add(
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
const SUBARRAY_SIZE = 0x10000;
|
const SUBARRAY_SIZE = 0x40000;
|
||||||
|
|
||||||
const BigArrayHandler = {
|
const BigArrayHandler = {
|
||||||
get: function(obj, prop) {
|
get: function(obj, prop) {
|
||||||
@@ -19,15 +19,17 @@ const BigArrayHandler = {
|
|||||||
class _BigArray {
|
class _BigArray {
|
||||||
constructor (initSize) {
|
constructor (initSize) {
|
||||||
this.length = initSize || 0;
|
this.length = initSize || 0;
|
||||||
this.arr = [];
|
this.arr = new Array(SUBARRAY_SIZE);
|
||||||
|
|
||||||
for (let i=0; i<initSize; i+=SUBARRAY_SIZE) {
|
for (let i=0; i<initSize; i+=SUBARRAY_SIZE) {
|
||||||
this.arr[i/SUBARRAY_SIZE] = new Array(Math.min(SUBARRAY_SIZE, initSize - i));
|
this.arr[i/SUBARRAY_SIZE] = new Array(Math.min(SUBARRAY_SIZE, initSize - i));
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
push (element) {
|
push () {
|
||||||
this.setElement (this.length, element);
|
for (let i=0; i<arguments.length; i++) {
|
||||||
|
this.setElement (this.length, arguments[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
getElement(idx) {
|
getElement(idx) {
|
||||||
idx = parseInt(idx);
|
idx = parseInt(idx);
|
||||||
@@ -39,13 +41,26 @@ class _BigArray {
|
|||||||
idx = parseInt(idx);
|
idx = parseInt(idx);
|
||||||
const idx1 = Math.floor(idx / SUBARRAY_SIZE);
|
const idx1 = Math.floor(idx / SUBARRAY_SIZE);
|
||||||
if (!this.arr[idx1]) {
|
if (!this.arr[idx1]) {
|
||||||
this.arr[idx1] = [];
|
this.arr[idx1] = new Array(SUBARRAY_SIZE);
|
||||||
}
|
}
|
||||||
const idx2 = idx % SUBARRAY_SIZE;
|
const idx2 = idx % SUBARRAY_SIZE;
|
||||||
this.arr[idx1][idx2] = value;
|
this.arr[idx1][idx2] = value;
|
||||||
if (idx >= this.length) this.length = idx+1;
|
if (idx >= this.length) this.length = idx+1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
getKeys() {
|
||||||
|
const newA = new BigArray();
|
||||||
|
for (let i=0; i<this.arr.length; i++) {
|
||||||
|
if (this.arr[i]) {
|
||||||
|
for (let j=0; j<this.arr[i].length; j++) {
|
||||||
|
if (typeof this.arr[i][j] !== "undefined") {
|
||||||
|
newA.push(i*SUBARRAY_SIZE+j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newA;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BigArray {
|
class BigArray {
|
||||||
|
|||||||
61
src/build.js
61
src/build.js
@@ -18,10 +18,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const assert = require("assert");
|
const assert = require("assert");
|
||||||
const bigInt = require("big-integer");
|
|
||||||
const utils = require("./utils");
|
const utils = require("./utils");
|
||||||
const gen = require("./gencode").gen;
|
const gen = require("./gencode").gen;
|
||||||
const createRefs = require("./gencode").createRefs;
|
const createRefs = require("./gencode").createRefs;
|
||||||
|
const BigArray = require("./bigarray");
|
||||||
|
|
||||||
module.exports = build;
|
module.exports = build;
|
||||||
|
|
||||||
@@ -35,31 +35,36 @@ function build(ctx) {
|
|||||||
ctx.definedSizes = {};
|
ctx.definedSizes = {};
|
||||||
ctx.addSizes = addSizes;
|
ctx.addSizes = addSizes;
|
||||||
ctx.addConstant = addConstant;
|
ctx.addConstant = addConstant;
|
||||||
ctx.addConstant(bigInt.zero);
|
ctx.addConstant(ctx.F.zero);
|
||||||
ctx.addConstant(bigInt.one);
|
ctx.addConstant(ctx.F.one);
|
||||||
|
|
||||||
|
if (ctx.verbose) console.log("buildHeader...");
|
||||||
buildHeader(ctx);
|
buildHeader(ctx);
|
||||||
|
if (ctx.verbose) console.log("buildEntryTables...");
|
||||||
buildEntryTables(ctx);
|
buildEntryTables(ctx);
|
||||||
ctx.globalNames = ctx.uniqueNames;
|
ctx.globalNames = ctx.uniqueNames;
|
||||||
|
|
||||||
|
if (ctx.verbose) console.log("buildCode...");
|
||||||
buildCode(ctx);
|
buildCode(ctx);
|
||||||
|
|
||||||
|
if (ctx.verbose) console.log("buildComponentsArray...");
|
||||||
buildComponentsArray(ctx);
|
buildComponentsArray(ctx);
|
||||||
|
|
||||||
|
if (ctx.verbose) console.log("buildMapIsInput...");
|
||||||
buildMapIsInput(ctx);
|
buildMapIsInput(ctx);
|
||||||
|
|
||||||
|
if (ctx.verbose) console.log("buildWit2Sig...");
|
||||||
buildWit2Sig(ctx);
|
buildWit2Sig(ctx);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildEntryTables(ctx) {
|
function buildEntryTables(ctx) {
|
||||||
|
|
||||||
const codes_hashMaps = [];
|
|
||||||
const codes_componentEntries = [];
|
|
||||||
const definedHashMaps = {};
|
const definedHashMaps = {};
|
||||||
for (let i=0; i<ctx.components.length; i++) {
|
for (let i=0; i<ctx.components.length; i++) {
|
||||||
|
if (ctx.verbose && (i%100000 ==0)) console.log(`buildEntryTables component: ${i}/${ctx.components.length}`);
|
||||||
const {htName, htMap} = addHashTable(i);
|
const {htName, htMap} = addHashTable(i);
|
||||||
|
|
||||||
let code = "";
|
|
||||||
const componentEntriesTableName = ctx.getUniqueName("_entryTable" + ctx.components[i].template);
|
const componentEntriesTableName = ctx.getUniqueName("_entryTable" + ctx.components[i].template);
|
||||||
|
|
||||||
const componentEntriesTable = [];
|
const componentEntriesTable = [];
|
||||||
@@ -73,34 +78,14 @@ function buildEntryTables(ctx) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.builder.addComponentEntriesTable(componentEntriesTableName, componentEntriesTable);
|
ctx.builder.addComponentEntriesTable(componentEntriesTableName, componentEntriesTable, i);
|
||||||
|
|
||||||
|
|
||||||
code += `Circom_ComponentEntry ${componentEntriesTableName}[${htMap.length}] = {\n`;
|
|
||||||
for (let j=0; j<htMap.length; j++) {
|
|
||||||
const entry = ctx.components[i].names.o[htMap[j]];
|
|
||||||
code += j>0 ? " ," : " ";
|
|
||||||
const sizeName = ctx.addSizes(entry.sizes);
|
|
||||||
|
|
||||||
const ty = entry.type == "S" ? "_typeSignal" : "_typeComponent";
|
|
||||||
code += `{${entry.offset},${sizeName}, ${ty}}\n`;
|
|
||||||
}
|
|
||||||
code += "};\n";
|
|
||||||
codes_componentEntries.push(code);
|
|
||||||
|
|
||||||
ctx.components[i].htName = htName;
|
ctx.components[i].htName = htName;
|
||||||
ctx.components[i].etName = componentEntriesTableName;
|
ctx.components[i].etName = componentEntriesTableName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return [
|
return;
|
||||||
"// HashMaps\n" ,
|
|
||||||
codes_hashMaps , "\n" ,
|
|
||||||
"\n" ,
|
|
||||||
"// Component Entries\n" ,
|
|
||||||
codes_componentEntries , "\n" ,
|
|
||||||
"\n"
|
|
||||||
];
|
|
||||||
|
|
||||||
function addHashTable(cIdx) {
|
function addHashTable(cIdx) {
|
||||||
const keys = Object.keys(ctx.components[cIdx].names.o);
|
const keys = Object.keys(ctx.components[cIdx].names.o);
|
||||||
@@ -132,6 +117,7 @@ function buildCode(ctx) {
|
|||||||
|
|
||||||
const fnComponents = [];
|
const fnComponents = [];
|
||||||
for (let i=0; i<ctx.components.length; i++) {
|
for (let i=0; i<ctx.components.length; i++) {
|
||||||
|
if (ctx.verbose && (i%100000 ==0)) console.log(`buildCode component: ${i}/${ctx.components.length}`);
|
||||||
const {h, instanceDef} = hashComponentCall(ctx, i);
|
const {h, instanceDef} = hashComponentCall(ctx, i);
|
||||||
const fName = ctx.components[i].template+"_"+h;
|
const fName = ctx.components[i].template+"_"+h;
|
||||||
if (!fDefined[fName]) {
|
if (!fDefined[fName]) {
|
||||||
@@ -181,6 +167,7 @@ function buildCode(ctx) {
|
|||||||
|
|
||||||
function buildComponentsArray(ctx) {
|
function buildComponentsArray(ctx) {
|
||||||
for (let i=0; i< ctx.components.length; i++) {
|
for (let i=0; i< ctx.components.length; i++) {
|
||||||
|
if (ctx.verbose && (i%1000000 ==0)) console.log(`buildComponentsArray component: ${i}/${ctx.components.length}`);
|
||||||
let newThread;
|
let newThread;
|
||||||
if (ctx.newThreadTemplates) {
|
if (ctx.newThreadTemplates) {
|
||||||
if (ctx.newThreadTemplates.test(ctx.components[i].template)) {
|
if (ctx.newThreadTemplates.test(ctx.components[i].template)) {
|
||||||
@@ -209,7 +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],
|
||||||
P: ctx.field.p
|
P: ctx.F.p
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,6 +205,7 @@ function buildMapIsInput(ctx) {
|
|||||||
let map = [];
|
let map = [];
|
||||||
let acc = 0;
|
let acc = 0;
|
||||||
for (i=0; i<ctx.signals.length; i++) {
|
for (i=0; i<ctx.signals.length; i++) {
|
||||||
|
if (ctx.verbose && (i%1000000 ==0)) console.log(`buildMapIsInput signal: ${i}/${ctx.signals.length}`);
|
||||||
if (ctx.signals[i].o & ctx.IN) {
|
if (ctx.signals[i].o & ctx.IN) {
|
||||||
acc = acc | (1 << (i%32) );
|
acc = acc | (1 << (i%32) );
|
||||||
}
|
}
|
||||||
@@ -242,8 +230,9 @@ function buildWit2Sig(ctx) {
|
|||||||
ctx.totals[ctx.stPUBINPUT] +
|
ctx.totals[ctx.stPUBINPUT] +
|
||||||
ctx.totals[ctx.stPRVINPUT] +
|
ctx.totals[ctx.stPRVINPUT] +
|
||||||
ctx.totals[ctx.stINTERNAL];
|
ctx.totals[ctx.stINTERNAL];
|
||||||
const arr = Array(NVars);
|
const arr = new BigArray(NVars);
|
||||||
for (let i=0; i<ctx.signals.length; i++) {
|
for (let i=0; i<ctx.signals.length; i++) {
|
||||||
|
if (ctx.verbose && (i%1000000 ==0)) console.log(`buildWit2Sig signal: ${i}/${ctx.signals.length}`);
|
||||||
const outIdx = ctx.signals[i].id;
|
const outIdx = ctx.signals[i].id;
|
||||||
if (ctx.signals[i].e>=0) continue; // If has an alias, continue..
|
if (ctx.signals[i].e>=0) continue; // If has an alias, continue..
|
||||||
assert(typeof outIdx != "undefined", `Signal ${i} does not have index`);
|
assert(typeof outIdx != "undefined", `Signal ${i} does not have index`);
|
||||||
@@ -391,7 +380,7 @@ function hashComponentCall(ctx, cIdx) {
|
|||||||
// TODO: At the moment generate a diferent function for each instance of the component
|
// TODO: At the moment generate a diferent function for each instance of the component
|
||||||
const constParams = [];
|
const constParams = [];
|
||||||
for (let p in ctx.components[cIdx].params) {
|
for (let p in ctx.components[cIdx].params) {
|
||||||
constParams.push(p + "=" + value2str(ctx.components[cIdx].params[p]));
|
constParams.push(p + "=" + value2str(ctx.F, ctx.components[cIdx].params[p]));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let n in ctx.components[cIdx].names.o) {
|
for (let n in ctx.components[cIdx].names.o) {
|
||||||
@@ -399,7 +388,7 @@ function hashComponentCall(ctx, cIdx) {
|
|||||||
if ((entry.type == "S")&&(ctx.signals[entry.offset].o & ctx.IN)) {
|
if ((entry.type == "S")&&(ctx.signals[entry.offset].o & ctx.IN)) {
|
||||||
travelSizes(n, entry.offset, entry.sizes, (prefix, offset) => {
|
travelSizes(n, entry.offset, entry.sizes, (prefix, offset) => {
|
||||||
if (utils.isDefined(ctx.signals[offset].v)) {
|
if (utils.isDefined(ctx.signals[offset].v)) {
|
||||||
constParams.push(prefix + "=" + bigInt(ctx.signals[offset].value));
|
constParams.push(prefix + "=" + ctx.F.e(ctx.signals[offset].v));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -433,7 +422,7 @@ function hashFunctionCall(ctx, name, paramValues) {
|
|||||||
const constParams = [];
|
const constParams = [];
|
||||||
for (let i=0; i<ctx.functions[name].params.length; i++) {
|
for (let i=0; i<ctx.functions[name].params.length; i++) {
|
||||||
if (!paramValues[i].used) {
|
if (!paramValues[i].used) {
|
||||||
constParams.push(ctx.functions[name].params[i] + utils.accSizes2Str(paramValues[i].sizes) + "=" + value2str(paramValues[i].value));
|
constParams.push(ctx.functions[name].params[i] + utils.accSizes2Str(paramValues[i].sizes) + "=" + value2str(ctx.F, paramValues[i].value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let instanceDef = name;
|
let instanceDef = name;
|
||||||
@@ -447,16 +436,16 @@ function hashFunctionCall(ctx, name, paramValues) {
|
|||||||
return {h, instanceDef};
|
return {h, instanceDef};
|
||||||
}
|
}
|
||||||
|
|
||||||
function value2str(v) {
|
function value2str(F, v) {
|
||||||
if (Array.isArray(v)) {
|
if (Array.isArray(v)) {
|
||||||
let S="[";
|
let S="[";
|
||||||
for (let i=0; i<v.length; i++) {
|
for (let i=0; i<v.length; i++) {
|
||||||
if (i>0) S+=",";
|
if (i>0) S+=",";
|
||||||
S+=value2str(v[i]);
|
S+=value2str(F, v[i]);
|
||||||
}
|
}
|
||||||
S+="]";
|
S+="]";
|
||||||
return S;
|
return S;
|
||||||
} else {
|
} else {
|
||||||
return bigInt(v).toString();
|
return F.toString(F.e(v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
348
src/compiler.js
348
src/compiler.js
@@ -17,39 +17,61 @@
|
|||||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const bigInt = require("big-integer");
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
const __P__ = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
|
||||||
const sONE = 0;
|
const sONE = 0;
|
||||||
const build = require("./build");
|
const build = require("./build");
|
||||||
const BuilderC = require("../ports/c/builder.js");
|
const BuilderC = require("../ports/c/builder.js");
|
||||||
const BuilderWasm = require("../ports/wasm/builder.js");
|
const BuilderWasm = require("../ports/wasm/builder.js");
|
||||||
const constructionPhase = require("./construction_phase");
|
const constructionPhase = require("./construction_phase");
|
||||||
const Ctx = require("./ctx");
|
const Ctx = require("./ctx");
|
||||||
const ZqField = require("ffjavascript").ZqField;
|
|
||||||
const utils = require("./utils");
|
const utils = require("./utils");
|
||||||
const buildR1cs = require("./r1csfile").buildR1cs;
|
const buildR1cs = require("./r1csfile").buildR1cs;
|
||||||
const BigArray = require("./bigarray");
|
const BigArray = require("./bigarray");
|
||||||
const buildSyms = require("./buildsyms");
|
const buildSyms = require("./buildsyms");
|
||||||
|
const {performance} = require("perf_hooks");
|
||||||
|
|
||||||
module.exports = compile;
|
module.exports = compile;
|
||||||
|
const measures = {};
|
||||||
|
|
||||||
|
function ms2String(v) {
|
||||||
|
v = Math.floor(v);
|
||||||
|
const ms = v % 1000;
|
||||||
|
v = Math.floor(v/1000);
|
||||||
|
const secs = v % 60;
|
||||||
|
v = Math.floor(v/60);
|
||||||
|
const mins = v % 60;
|
||||||
|
v = Math.floor(v/60);
|
||||||
|
const hours = v % 24;
|
||||||
|
const days = Math.floor(v/24);
|
||||||
|
let S = "";
|
||||||
|
if (days) S = S + days + "D ";
|
||||||
|
if ((S!="")||(hours)) S = S + hours.toString().padStart(2, "0") + ":";
|
||||||
|
if ((S!="")||(mins)) S = S + mins.toString().padStart(2, "0") + ":";
|
||||||
|
if ((S!="")||(secs)) S = S + secs.toString().padStart(2, "0");
|
||||||
|
S+=".";
|
||||||
|
S = S + ms.toString().padStart(3, "0");
|
||||||
|
return S;
|
||||||
|
}
|
||||||
|
|
||||||
async function compile(srcFile, options) {
|
async function compile(srcFile, options) {
|
||||||
options.p = options.p || __P__;
|
options.prime = options.prime || Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||||
if (!options) {
|
if (!options) {
|
||||||
options = {};
|
options = {};
|
||||||
}
|
}
|
||||||
if (typeof options.reduceConstraints === "undefined") {
|
if (typeof options.reduceConstraints === "undefined") {
|
||||||
options.reduceConstraints = true;
|
options.reduceConstraints = true;
|
||||||
}
|
}
|
||||||
const ctx = new Ctx();
|
const ctx = new Ctx(options.prime);
|
||||||
ctx.field = new ZqField(options.p);
|
|
||||||
ctx.verbose= options.verbose || false;
|
ctx.verbose= options.verbose || false;
|
||||||
ctx.mainComponent = options.mainComponent || "main";
|
ctx.mainComponent = options.mainComponent || "main";
|
||||||
ctx.newThreadTemplates = options.newThreadTemplates;
|
ctx.newThreadTemplates = options.newThreadTemplates;
|
||||||
|
|
||||||
|
measures.constructionPhase = -performance.now();
|
||||||
constructionPhase(ctx, srcFile);
|
constructionPhase(ctx, srcFile);
|
||||||
|
measures.constructionPhase += performance.now();
|
||||||
|
|
||||||
if (ctx.verbose) console.log("NConstraints Before: "+ctx.constraints.length);
|
if (ctx.verbose) console.log("NConstraints Before: "+ctx.constraints.length);
|
||||||
|
if (ctx.verbose) console.log("NSignals Before: "+ctx.signals.length);
|
||||||
|
|
||||||
if (ctx.error) {
|
if (ctx.error) {
|
||||||
throw(ctx.error);
|
throw(ctx.error);
|
||||||
@@ -60,70 +82,97 @@ async function compile(srcFile, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.verbose) console.log("Classify Signals");
|
if (ctx.verbose) console.log("Classify Signals");
|
||||||
|
measures.classifySignals = -performance.now();
|
||||||
classifySignals(ctx);
|
classifySignals(ctx);
|
||||||
|
measures.classifySignals += performance.now();
|
||||||
|
|
||||||
if (ctx.verbose) console.log("Reduce Constants");
|
if (ctx.verbose) console.log("Reduce Constants");
|
||||||
|
measures.reduceConstants = -performance.now();
|
||||||
reduceConstants(ctx);
|
reduceConstants(ctx);
|
||||||
|
measures.reduceConstants += performance.now();
|
||||||
|
|
||||||
if (options.reduceConstraints) {
|
if (options.reduceConstraints) {
|
||||||
|
|
||||||
if (ctx.verbose) console.log("Reduce Constraints");
|
if (ctx.verbose) console.log("Reduce Constraints");
|
||||||
// Repeat while reductions are performed
|
// Repeat while reductions are performed
|
||||||
|
/*
|
||||||
let oldNConstrains = -1;
|
let oldNConstrains = -1;
|
||||||
while (ctx.constraints.length != oldNConstrains) {
|
while (ctx.constraints.length != oldNConstrains) {
|
||||||
if (ctx.verbose) console.log("Reducing constraints: "+ctx.constraints.length);
|
if (ctx.verbose) console.log("Reducing constraints: "+ctx.constraints.length);
|
||||||
oldNConstrains = ctx.constraints.length;
|
oldNConstrains = ctx.constraints.length;
|
||||||
reduceConstrains(ctx);
|
reduceConstrains(ctx);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
measures.reduceConstraints = -performance.now();
|
||||||
|
await reduceConstrains(ctx);
|
||||||
|
measures.reduceConstraints += performance.now();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx.verbose) console.log("NConstraints After: "+ctx.constraints.length);
|
if (ctx.verbose) console.log("NConstraints After: "+ctx.constraints.length);
|
||||||
|
|
||||||
|
measures.generateWitnessNames = -performance.now();
|
||||||
generateWitnessNames(ctx);
|
generateWitnessNames(ctx);
|
||||||
|
measures.generateWitnessNames += performance.now();
|
||||||
|
|
||||||
if (ctx.error) {
|
if (ctx.error) {
|
||||||
throw(ctx.error);
|
throw(ctx.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.cSourceWriteStream) {
|
if (options.r1csFileName) {
|
||||||
ctx.builder = new BuilderC();
|
measures.generateR1cs = -performance.now();
|
||||||
|
await buildR1cs(ctx, options.r1csFileName);
|
||||||
|
measures.generateR1cs += performance.now();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx.error) throw(ctx.error);
|
||||||
|
|
||||||
|
delete ctx.constraints; // Liberate memory.
|
||||||
|
|
||||||
|
if (options.cSourceFile) {
|
||||||
|
if (ctx.verbose) console.log("Generating c...");
|
||||||
|
measures.generateC = -performance.now();
|
||||||
|
ctx.builder = new BuilderC(options.prime, ctx.verbose);
|
||||||
build(ctx);
|
build(ctx);
|
||||||
const rdStream = ctx.builder.build();
|
await ctx.builder.build(options.cSourceFile, options.dataFile);
|
||||||
rdStream.pipe(options.cSourceWriteStream);
|
measures.generateC += performance.now();
|
||||||
|
|
||||||
// await new Promise(fulfill => options.cSourceWriteStream.on("finish", fulfill));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((options.wasmWriteStream)||(options.watWriteStream)) {
|
if (ctx.error) throw(ctx.error);
|
||||||
ctx.builder = new BuilderWasm();
|
|
||||||
|
if ((options.wasmFile)||(options.watFile)) {
|
||||||
|
if (ctx.verbose) console.log("Generating wasm...");
|
||||||
|
measures.generateWasm = -performance.now();
|
||||||
|
ctx.builder = new BuilderWasm(options.prime);
|
||||||
build(ctx);
|
build(ctx);
|
||||||
if (options.wasmWriteStream) {
|
if (options.wasmFile) {
|
||||||
const rdStream = ctx.builder.build("wasm");
|
await ctx.builder.build(options.wasmFile, "wasm");
|
||||||
rdStream.pipe(options.wasmWriteStream);
|
|
||||||
}
|
}
|
||||||
if (options.watWriteStream) {
|
if (options.watFile) {
|
||||||
const rdStream = ctx.builder.build("wat");
|
await ctx.builder.build(options.watFile, "wat");
|
||||||
rdStream.pipe(options.watWriteStream);
|
|
||||||
}
|
}
|
||||||
|
measures.generateWasm += performance.now();
|
||||||
// await new Promise(fulfill => options.wasmWriteStream.on("finish", fulfill));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// const mainCode = gen(ctx,ast);
|
// const mainCode = gen(ctx,ast);
|
||||||
if (ctx.error) throw(ctx.error);
|
if (ctx.error) throw(ctx.error);
|
||||||
|
|
||||||
if (options.r1csFileName) {
|
|
||||||
await buildR1cs(ctx, options.r1csFileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options.symWriteStream) {
|
if (options.symWriteStream) {
|
||||||
|
measures.generateSyms = -performance.now();
|
||||||
const rdStream = buildSyms(ctx);
|
const rdStream = buildSyms(ctx);
|
||||||
rdStream.pipe(options.symWriteStream);
|
rdStream.pipe(options.symWriteStream);
|
||||||
|
measures.generateSyms += performance.now();
|
||||||
|
|
||||||
// await new Promise(fulfill => options.symWriteStream.on("finish", fulfill));
|
await new Promise(fulfill => options.symWriteStream.on("finish", fulfill));
|
||||||
}
|
}
|
||||||
|
|
||||||
// const def = buildCircuitDef(ctx, mainCode);
|
// const def = buildCircuitDef(ctx, mainCode);
|
||||||
|
|
||||||
|
if (ctx.verbose) {
|
||||||
|
for (let [mStr, mValue] of Object.entries(measures)) {
|
||||||
|
console.log(mStr + ": " + ms2String(mValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -149,6 +198,7 @@ function classifySignals(ctx) {
|
|||||||
|
|
||||||
// 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}`);
|
||||||
const signal = ctx.signals[s];
|
const signal = ctx.signals[s];
|
||||||
let tAll = ctx.stINTERNAL;
|
let tAll = ctx.stINTERNAL;
|
||||||
let lSignal = signal;
|
let lSignal = signal;
|
||||||
@@ -252,7 +302,239 @@ function reduceConstants(ctx) {
|
|||||||
ctx.constraints = newConstraints;
|
ctx.constraints = newConstraints;
|
||||||
}
|
}
|
||||||
|
|
||||||
function reduceConstrains(ctx) {
|
async function reduceConstrains(ctx) {
|
||||||
|
const sig2constraint = new BigArray();
|
||||||
|
let removedSignals = new BigArray();
|
||||||
|
let nRemoved;
|
||||||
|
let lIdx;
|
||||||
|
|
||||||
|
|
||||||
|
let possibleConstraints = new BigArray(ctx.constraints.length);
|
||||||
|
let nextPossibleConstraints;
|
||||||
|
for (let i=0; i<ctx.constraints.length; i++) {
|
||||||
|
if ((ctx.verbose)&&(i%100000 == 0)) console.log(`indexing constraints: ${i}/${ctx.constraints.length}`);
|
||||||
|
|
||||||
|
const insertedSig = { 0: true}; // Do not insert one.
|
||||||
|
const c = ctx.constraints[i];
|
||||||
|
for (let s in c.a.coefs) {
|
||||||
|
if (!insertedSig[s]) {
|
||||||
|
if (!sig2constraint[s]) sig2constraint[s] = [];
|
||||||
|
sig2constraint[s].push(i);
|
||||||
|
insertedSig[s] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let s in c.b.coefs) {
|
||||||
|
if (!insertedSig[s]) {
|
||||||
|
if (!sig2constraint[s]) sig2constraint[s] = [];
|
||||||
|
sig2constraint[s].push(i);
|
||||||
|
insertedSig[s] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let s in c.c.coefs) {
|
||||||
|
if (!insertedSig[s]) {
|
||||||
|
if (!sig2constraint[s]) sig2constraint[s] = [];
|
||||||
|
sig2constraint[s].push(i);
|
||||||
|
insertedSig[s] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
possibleConstraints[i] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (possibleConstraints.length >0) {
|
||||||
|
nextPossibleConstraints = new BigArray();
|
||||||
|
removedSignals = new BigArray();
|
||||||
|
nRemoved = 0;
|
||||||
|
lIdx = new BigArray();
|
||||||
|
for (let i=0;i<possibleConstraints.length;i++) {
|
||||||
|
if ((ctx.verbose)&&(i%10000 == 0)) {
|
||||||
|
await Promise.resolve();
|
||||||
|
console.log(`reducing constraints: ${i}/${possibleConstraints.length} reduced: ${nRemoved}`);
|
||||||
|
}
|
||||||
|
const c = ctx.constraints[possibleConstraints[i]];
|
||||||
|
if (!c) continue;
|
||||||
|
|
||||||
|
// Swap a and b if b has more variables.
|
||||||
|
if (Object.keys(c.b).length > Object.keys(c.a).length) {
|
||||||
|
const aux = c.a;
|
||||||
|
c.a=c.b;
|
||||||
|
c.b=aux;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mov to C if possible.
|
||||||
|
if (isConstant(c.a)) {
|
||||||
|
const ct = {t: "N", v: c.a.coefs[sONE]};
|
||||||
|
c.c = ctx.lc.add(ctx.lc.mul(c.b, ct), c.c);
|
||||||
|
c.a = { t: "LC", coefs: {} };
|
||||||
|
c.b = { t: "LC", coefs: {} };
|
||||||
|
}
|
||||||
|
if (isConstant(c.b)) {
|
||||||
|
const ct = {t: "N", v: c.b.coefs[sONE]};
|
||||||
|
c.c = ctx.lc.add(ctx.lc.mul(c.a, ct), c.c);
|
||||||
|
c.a = { t: "LC", coefs: {} };
|
||||||
|
c.b = { t: "LC", coefs: {} };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx.lc.isZero(c.a) || ctx.lc.isZero(c.b)) {
|
||||||
|
const freeC = substituteRemoved(c.c);
|
||||||
|
const isolatedSignal = getFirstInternalSignal(ctx, freeC);
|
||||||
|
if (isolatedSignal) {
|
||||||
|
// console.log(isolatedSignal);
|
||||||
|
// console.log(freeC);
|
||||||
|
removedSignals[isolatedSignal] = isolateSignal(freeC, isolatedSignal);
|
||||||
|
if (lIdx[isolatedSignal]) {
|
||||||
|
lIdx[isolatedSignal].forEach( (s) => {
|
||||||
|
removedSignals[s] = substitute(removedSignals[s], isolatedSignal, removedSignals[isolatedSignal]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
addTolIdx(removedSignals[isolatedSignal], isolatedSignal);
|
||||||
|
ctx.constraints[possibleConstraints[i]] = null;
|
||||||
|
nRemoved ++;
|
||||||
|
|
||||||
|
sig2constraint[isolatedSignal].forEach( (s) => {
|
||||||
|
nextPossibleConstraints[s] = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nextPossibleConstraints = nextPossibleConstraints.getKeys();
|
||||||
|
|
||||||
|
for (let i=0; i<nextPossibleConstraints.length;i++) {
|
||||||
|
if ((ctx.verbose)&&(i%10000 == 0)) {
|
||||||
|
await Promise.resolve();
|
||||||
|
console.log(`substituting constraints: ${i}/${nextPossibleConstraints.length}`);
|
||||||
|
}
|
||||||
|
const c = ctx.constraints[nextPossibleConstraints[i]];
|
||||||
|
if (c) {
|
||||||
|
const nc = {
|
||||||
|
a: substituteRemoved(c.a),
|
||||||
|
b: substituteRemoved(c.b),
|
||||||
|
c: substituteRemoved(c.c)
|
||||||
|
};
|
||||||
|
if (ctx.lc.isZero(nc)) {
|
||||||
|
delete ctx.constraints[nextPossibleConstraints[i]];
|
||||||
|
} else {
|
||||||
|
ctx.constraints[nextPossibleConstraints[i]] = nc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const removedSignalsList = removedSignals.getKeys;
|
||||||
|
|
||||||
|
for (let i=0; i<removedSignalsList.length; i++) {
|
||||||
|
if ((ctx.verbose )&&(i%100000 == 0)) console.log(`removing signals: ${i}/${removedSignalsList.length}`);
|
||||||
|
const s = removedSignalsList[i];
|
||||||
|
|
||||||
|
let lSignal = ctx.signals[s];
|
||||||
|
while (lSignal.e>=0) {
|
||||||
|
lSignal = ctx.signals[lSignal.e];
|
||||||
|
}
|
||||||
|
|
||||||
|
lSignal.c = ctx.stDISCARDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
possibleConstraints = nextPossibleConstraints;
|
||||||
|
}
|
||||||
|
|
||||||
|
let o=0;
|
||||||
|
for (let i=0; i<ctx.constraints.length;i++) {
|
||||||
|
if ((ctx.verbose)&&(i%100000 == 0)) console.log(`reordering constraints: ${i}/${ctx.constraints.length}`);
|
||||||
|
if (ctx.constraints[i]) {
|
||||||
|
if (!ctx.lc.isZero(ctx.constraints[i])) {
|
||||||
|
ctx.constraints[o] = ctx.constraints[i];
|
||||||
|
o++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.constraints.length = o;
|
||||||
|
|
||||||
|
function getFirstInternalSignal(ctx, l) {
|
||||||
|
for (let k in l.coefs) {
|
||||||
|
k = Number(k);
|
||||||
|
const signal = ctx.signals[k];
|
||||||
|
if ((signal.c == ctx.stINTERNAL)&&(!ctx.F.isZero(l.coefs[k])) &&(!removedSignals[k])) return k;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isolateSignal(lc, s) {
|
||||||
|
const eq = {
|
||||||
|
t: "LC",
|
||||||
|
coefs: {}
|
||||||
|
};
|
||||||
|
const invCoef = ctx.F.inv(lc.coefs[s]);
|
||||||
|
for (const k in lc.coefs) {
|
||||||
|
if (k != s) {
|
||||||
|
const v = ctx.F.mul( ctx.F.neg(lc.coefs[k]), invCoef);
|
||||||
|
if (!ctx.F.isZero(v)) {
|
||||||
|
eq.coefs[k] = v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return eq;
|
||||||
|
}
|
||||||
|
|
||||||
|
function substituteRemoved(lc) {
|
||||||
|
const newLc = ctx.lc._clone(lc);
|
||||||
|
for (let k in lc.coefs) {
|
||||||
|
if (removedSignals[k]) {
|
||||||
|
delete newLc.coefs[k];
|
||||||
|
for (let k2 in removedSignals[k].coefs) {
|
||||||
|
const newP = ctx.F.mul(removedSignals[k].coefs[k2], lc.coefs[k]);
|
||||||
|
if (!ctx.F.isZero(newP)) {
|
||||||
|
if (newLc.coefs[k2]) {
|
||||||
|
newLc.coefs[k2] = ctx.F.add(newLc.coefs[k2], newP);
|
||||||
|
if (ctx.F.isZero(newLc.coefs[k2])) delete newLc.coefs[k2];
|
||||||
|
} else {
|
||||||
|
newLc.coefs[k2] = newP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newLc;
|
||||||
|
}
|
||||||
|
|
||||||
|
function substitute(lc, s, eq) {
|
||||||
|
if (!lc.coefs[s]) return lc;
|
||||||
|
const newLc = ctx.lc._clone(lc);
|
||||||
|
delete newLc.coefs[s];
|
||||||
|
for (let k2 in eq.coefs) {
|
||||||
|
const newP = ctx.F.mul(eq.coefs[k2], lc.coefs[s]);
|
||||||
|
if (!ctx.F.isZero(newP)) {
|
||||||
|
if (newLc.coefs[k2]) {
|
||||||
|
newLc.coefs[k2] = ctx.F.add(newLc.coefs[k2], newP);
|
||||||
|
if (ctx.F.isZero(newLc.coefs[k2])) delete newLc.coefs[k2];
|
||||||
|
} else {
|
||||||
|
newLc.coefs[k2] = newP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newLc;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isConstant(l) {
|
||||||
|
for (let k in l.coefs) {
|
||||||
|
if ((k != sONE) && (!ctx.F.isZero(l.coefs[k]))) return false;
|
||||||
|
}
|
||||||
|
if (!l.coefs[sONE] || ctx.F.isZero(l.coefs[sONE])) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addTolIdx(lc, newS) {
|
||||||
|
for (let s in lc.coefs) {
|
||||||
|
if (!lIdx[s]) lIdx[s] = [];
|
||||||
|
lIdx[s].push(newS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function reduceConstrains_old(ctx) {
|
||||||
indexVariables();
|
indexVariables();
|
||||||
let possibleConstraints = ctx.constraints;
|
let possibleConstraints = ctx.constraints;
|
||||||
let ii=0;
|
let ii=0;
|
||||||
@@ -299,11 +581,11 @@ function reduceConstrains(ctx) {
|
|||||||
t: "LC",
|
t: "LC",
|
||||||
coefs: {}
|
coefs: {}
|
||||||
};
|
};
|
||||||
const invCoef = c.c.coefs[isolatedSignal].modInv(__P__);
|
const invCoef = ctx.F.inv(c.c.coefs[isolatedSignal]);
|
||||||
for (const s in c.c.coefs) {
|
for (const s in c.c.coefs) {
|
||||||
if (s != isolatedSignal) {
|
if (s != isolatedSignal) {
|
||||||
const v = __P__.minus(c.c.coefs[s]).times(invCoef).mod(__P__);
|
const v = ctx.F.mul( ctx.F.neg(c.c.coefs[s]), invCoef);
|
||||||
if (!v.isZero()) {
|
if (!ctx.F.isZero(v)) {
|
||||||
isolatedSignalEquivalence.coefs[s] = v;
|
isolatedSignalEquivalence.coefs[s] = v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -395,9 +677,9 @@ function reduceConstrains(ctx) {
|
|||||||
|
|
||||||
function isConstant(l) {
|
function isConstant(l) {
|
||||||
for (let k in l.coefs) {
|
for (let k in l.coefs) {
|
||||||
if ((k != sONE) && (!l.coefs[k].isZero())) return false;
|
if ((k != sONE) && (!ctx.F.isZero(l.coefs[k]))) return false;
|
||||||
}
|
}
|
||||||
if (!l.coefs[sONE] || l.coefs[sONE].isZero()) return false;
|
if (!l.coefs[sONE] || ctx.F.isZero(l.coefs[sONE])) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,10 +49,11 @@ const assert = require("assert");
|
|||||||
const iterateAST = require("./iterateast");
|
const iterateAST = require("./iterateast");
|
||||||
const utils = require("./utils");
|
const utils = require("./utils");
|
||||||
|
|
||||||
const bigInt = require("big-integer");
|
|
||||||
|
|
||||||
const LCAlgebra = require("./lcalgebra");
|
const LCAlgebra = require("./lcalgebra");
|
||||||
const parser = require("../parser/jaz.js").parser;
|
const parser = require("../parser/jaz.js").parser;
|
||||||
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
|
|
||||||
|
const {stringifyBigInts} = require("ffjavascript").utils;
|
||||||
|
|
||||||
/* TODO: Add lines information
|
/* TODO: Add lines information
|
||||||
|
|
||||||
@@ -79,7 +80,7 @@ function constructionPhase(ctx, srcFile) {
|
|||||||
|
|
||||||
assert(ctx.ast.type == "BLOCK");
|
assert(ctx.ast.type == "BLOCK");
|
||||||
|
|
||||||
ctx.lc = new LCAlgebra(ctx.field);
|
ctx.lc = new LCAlgebra(ctx.F);
|
||||||
ctx.filePath= fullFilePath;
|
ctx.filePath= fullFilePath;
|
||||||
ctx.fileName= fullFileName;
|
ctx.fileName= fullFileName;
|
||||||
ctx.includedFiles = {};
|
ctx.includedFiles = {};
|
||||||
@@ -218,7 +219,7 @@ function execNumber(ctx, ast) {
|
|||||||
s:[1,0],
|
s:[1,0],
|
||||||
v: [{
|
v: [{
|
||||||
t: "N",
|
t: "N",
|
||||||
v: bigInt(ast.value)
|
v: ctx.F.e(ast.value)
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -253,7 +254,7 @@ function execDeclareComponent(ctx, ast) {
|
|||||||
const size = val(ctx, sizeRef);
|
const size = val(ctx, sizeRef);
|
||||||
if (size.t != "N") return ctx.throwError( ast.name.selectors[i], "expected a number");
|
if (size.t != "N") return ctx.throwError( ast.name.selectors[i], "expected a number");
|
||||||
|
|
||||||
sizes.push( size.v.toJSNumber() );
|
sizes.push( Scalar.toNumber(size.v) );
|
||||||
}
|
}
|
||||||
|
|
||||||
let cIdx = ctx.addComponent(ast.name.name, sizes);
|
let cIdx = ctx.addComponent(ast.name.name, sizes);
|
||||||
@@ -277,7 +278,7 @@ function execDeclareSignal(ctx, ast) {
|
|||||||
if (ctx.error) return;
|
if (ctx.error) return;
|
||||||
if (size.s[0] != 1) return ctx.throwError(ast, "Size cannot be an array");
|
if (size.s[0] != 1) return ctx.throwError(ast, "Size cannot be an array");
|
||||||
if (size.v[0].t != "N") return ctx.throwError(ast, "Size must be declared in construction time");
|
if (size.v[0].t != "N") return ctx.throwError(ast, "Size must be declared in construction time");
|
||||||
sizes.push( size.v[0].v.toJSNumber() );
|
sizes.push( Scalar.toNumber(size.v[0].v) );
|
||||||
}
|
}
|
||||||
|
|
||||||
let sIdx = ctx.addSignal(ast.name.name, sizes);
|
let sIdx = ctx.addSignal(ast.name.name, sizes);
|
||||||
@@ -322,7 +323,7 @@ function execDeclareVariable(ctx, ast) {
|
|||||||
if (ctx.error) return;
|
if (ctx.error) return;
|
||||||
if (size.s[0] != 1) return ctx.throwError(ast, "Size cannot be an array");
|
if (size.s[0] != 1) return ctx.throwError(ast, "Size cannot be an array");
|
||||||
if (size.v[0].t != "N") return ctx.throwError(ast, "Size must be declared in construction time");
|
if (size.v[0].t != "N") return ctx.throwError(ast, "Size must be declared in construction time");
|
||||||
sizes.push( size.v[0].v.toJSNumber() );
|
sizes.push( Scalar.toNumber(size.v[0].v) );
|
||||||
}
|
}
|
||||||
|
|
||||||
const v = ctx.refs[ast.refId];
|
const v = ctx.refs[ast.refId];
|
||||||
@@ -353,13 +354,13 @@ function execAssignement(ctx, ast) {
|
|||||||
if (sel.s[0] != 1) return ctx.throwError(ast, "Selector cannot be an array");
|
if (sel.s[0] != 1) return ctx.throwError(ast, "Selector cannot be an array");
|
||||||
if (sel.v[0].t != "N") return {t: "NQ"};
|
if (sel.v[0].t != "N") return {t: "NQ"};
|
||||||
|
|
||||||
leftSels.push( sel.v[0].v.toJSNumber() );
|
leftSels.push( Scalar.toNumber(sel.v[0].v) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!left.s) return ctx.throwError(ast, "variable. not defined yet");
|
if ((!left)||(!left.s)) return ctx.throwError(ast, "variable. not defined yet");
|
||||||
|
|
||||||
if (left.t == "C") return execInstantiateComponet(ctx, left, ast.values[1], leftSels);
|
if (left.t == "C") return execInstantiateComponet(ctx, left, ast.values[1], leftSels);
|
||||||
if ((left.t == "S")&&( ["<--", "<==", "-->", "==>"].indexOf(ast.op) < 0)) return ctx.throwError(ast, "Cannot assign to a signal with `=` use <-- or <== ops");
|
if ((left.t == "S")&&( ["<--", "<==", "-->", "==>"].indexOf(ast.op) < 0)) return ctx.throwError(ast, "Cannot assign to a signal with `=` use <-- or <== ops");
|
||||||
@@ -380,7 +381,7 @@ function execAssignement(ctx, ast) {
|
|||||||
} else if (right.t == "S") {
|
} else if (right.t == "S") {
|
||||||
for (let i=0; i<right.s[0]; i++) {
|
for (let i=0; i<right.s[0]; i++) {
|
||||||
left.v[o+i]={t: "LC", coefs: {}};
|
left.v[o+i]={t: "LC", coefs: {}};
|
||||||
left.v[o+i].coefs[right.sIdx+i] = ctx.field.one;
|
left.v[o+i].coefs[right.sIdx+i] = ctx.F.one;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if ( left.t == "S") {
|
} else if ( left.t == "S") {
|
||||||
@@ -444,14 +445,14 @@ function execInstantiateComponet(ctx, vr, fn, sels) {
|
|||||||
const templateName = fn.name;
|
const templateName = fn.name;
|
||||||
|
|
||||||
const template = ctx.templates[templateName];
|
const template = ctx.templates[templateName];
|
||||||
if (!template) return ctx.throwError("Invalid Template");
|
if (!template) return ctx.throwError(fn, "Invalid Template");
|
||||||
|
|
||||||
const paramValues = [];
|
const paramValues = [];
|
||||||
for (let i=0; i< fn.params.length; i++) {
|
for (let i=0; i< fn.params.length; i++) {
|
||||||
const v = exec(ctx, fn.params[i]);
|
const v = exec(ctx, fn.params[i]);
|
||||||
if (ctx.error) return;
|
if (ctx.error) return;
|
||||||
for (let j=0; j<v.s[0]; j++) {
|
for (let j=0; j<v.s[0]; j++) {
|
||||||
if (v.v[j].t != "N") ctx.throwError("Parameters of a template must be constant");
|
if (v.v[j].t != "N") ctx.throwError(fn, "Parameters of a template must be constant");
|
||||||
}
|
}
|
||||||
paramValues.push(v);
|
paramValues.push(v);
|
||||||
}
|
}
|
||||||
@@ -561,19 +562,23 @@ function execFunctionCall(ctx, ast) {
|
|||||||
if (ev.v) {
|
if (ev.v) {
|
||||||
console.log(ev.v.toString());
|
console.log(ev.v.toString());
|
||||||
} else {
|
} else {
|
||||||
console.log(JSON.stringify(ev));
|
console.log(JSON.stringify(stringifyBigInts(ev)));
|
||||||
}
|
}
|
||||||
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 (ev.isZero()) 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];
|
||||||
|
|
||||||
if (!fnc) return ctx.throwError("Function not defined");
|
if (!fnc) return ctx.throwError(ast, "Function not defined");
|
||||||
|
|
||||||
const paramValues = [];
|
const paramValues = [];
|
||||||
for (let i=0; i< ast.params.length; i++) {
|
for (let i=0; i< ast.params.length; i++) {
|
||||||
@@ -624,6 +629,9 @@ function execReturn(ctx, ast) {
|
|||||||
function execVariable(ctx, ast) {
|
function execVariable(ctx, ast) {
|
||||||
|
|
||||||
const v = ctx.refs[ast.refId];
|
const v = ctx.refs[ast.refId];
|
||||||
|
if (!v) {
|
||||||
|
return ctx.throwError(ast, "Variable not defined: "+ast.name);
|
||||||
|
}
|
||||||
|
|
||||||
const sels = [];
|
const sels = [];
|
||||||
for (let i=0; i< ast.selectors.length; i++) {
|
for (let i=0; i< ast.selectors.length; i++) {
|
||||||
@@ -631,7 +639,7 @@ function execVariable(ctx, ast) {
|
|||||||
if (ctx.error) return;
|
if (ctx.error) return;
|
||||||
if (sel.s[0] != 1) return ctx.throwError(ast, "Variable selector cannot be an array");
|
if (sel.s[0] != 1) return ctx.throwError(ast, "Variable selector cannot be an array");
|
||||||
if (sel.v[0].t != "N") return NQVAL;
|
if (sel.v[0].t != "N") return NQVAL;
|
||||||
sels.push(sel.v[0].v.toJSNumber());
|
sels.push(Scalar.toNumber(sel.v[0].v));
|
||||||
}
|
}
|
||||||
|
|
||||||
let o = 0;
|
let o = 0;
|
||||||
@@ -679,7 +687,7 @@ function execPin(ctx, ast) {
|
|||||||
|
|
||||||
if (sel.s[0] != 1) return ctx.throwError(ast, "Component selector cannot be an array");
|
if (sel.s[0] != 1) return ctx.throwError(ast, "Component selector cannot be an array");
|
||||||
if (sel.v[0].t != "N") return NQVAL;
|
if (sel.v[0].t != "N") return NQVAL;
|
||||||
selsC.push(sel.v[0].v.toJSNumber());
|
selsC.push(Scalar.toNumber(sel.v[0].v));
|
||||||
}
|
}
|
||||||
|
|
||||||
const cIdx = ctx.getComponentIdx(ast.component.name, selsC);
|
const cIdx = ctx.getComponentIdx(ast.component.name, selsC);
|
||||||
@@ -691,7 +699,7 @@ function execPin(ctx, ast) {
|
|||||||
if (ctx.error) return;
|
if (ctx.error) return;
|
||||||
if (sel.s[0] != 1) return ctx.throwError(ast, "Signal selector cannot be an array");
|
if (sel.s[0] != 1) return ctx.throwError(ast, "Signal selector cannot be an array");
|
||||||
if (sel.v[0].t != "N") return NQVAL;
|
if (sel.v[0].t != "N") return NQVAL;
|
||||||
selsP.push(sel.v[0].v.toJSNumber());
|
selsP.push(Scalar.toNumber(sel.v[0].v));
|
||||||
}
|
}
|
||||||
const sIdx = ctx.components[cIdx].names.getSignalIdx(ast.pin.name, selsP);
|
const sIdx = ctx.components[cIdx].names.getSignalIdx(ast.pin.name, selsP);
|
||||||
|
|
||||||
@@ -738,7 +746,7 @@ function execLoop(ctx, ast) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((!v.v[0].v.isZero())&&(!ctx.returnValue)) {
|
while ((! ctx.F.isZero(v.v[0].v))&&(!ctx.returnValue)) {
|
||||||
exec(ctx, ast.body);
|
exec(ctx, ast.body);
|
||||||
if (ctx.error) return;
|
if (ctx.error) return;
|
||||||
|
|
||||||
@@ -781,7 +789,7 @@ function execIf(ctx, ast) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!v.v[0].v.isZero()) {
|
if (!ctx.F.isZero(v.v[0].v)) {
|
||||||
exec(ctx, ast.then);
|
exec(ctx, ast.then);
|
||||||
} else {
|
} else {
|
||||||
if (ast.else) {
|
if (ast.else) {
|
||||||
@@ -808,7 +816,7 @@ function execTerCon(ctx, ast) {
|
|||||||
return NQVAL;
|
return NQVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!v.v[0].v.isZero()) {
|
if (!ctx.F.isZero(v.v[0].v)) {
|
||||||
return exec(ctx, ast.values[1]);
|
return exec(ctx, ast.values[1]);
|
||||||
} else {
|
} else {
|
||||||
return exec(ctx, ast.values[2]);
|
return exec(ctx, ast.values[2]);
|
||||||
@@ -847,7 +855,7 @@ function execOpOp(ctx, ast, op, lr) {
|
|||||||
if (sel.s[0] != 1) return ctx.throwError(ast, "Selector cannot be an array");
|
if (sel.s[0] != 1) return ctx.throwError(ast, "Selector cannot be an array");
|
||||||
if (sel.v[0].t != "N") return {t: "NQ"};
|
if (sel.v[0].t != "N") return {t: "NQ"};
|
||||||
|
|
||||||
leftSels.push( sel.v[0].v.toJSNumber() );
|
leftSels.push( Scalar.toNumber(sel.v[0].v) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!left.s) return ctx.throwError(ast, "variable. not defined yet");
|
if (!left.s) return ctx.throwError(ast, "variable. not defined yet");
|
||||||
@@ -867,9 +875,11 @@ function execOpOp(ctx, ast, op, lr) {
|
|||||||
if (ctx.error) return;
|
if (ctx.error) return;
|
||||||
right = val(ctx, rightRef);
|
right = val(ctx, rightRef);
|
||||||
} else {
|
} else {
|
||||||
right = {t:"N", v: ctx.field.one};
|
right = {t:"N", v: ctx.F.one};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!right) return ctx.throwError(ast, "adding a no number");
|
||||||
|
|
||||||
const resAfter = ctx.lc[op](resBefore, right);
|
const resAfter = ctx.lc[op](resBefore, right);
|
||||||
left.v[o] = resAfter;
|
left.v[o] = resAfter;
|
||||||
|
|
||||||
@@ -902,7 +912,7 @@ function val(ctx, a, ast) {
|
|||||||
};
|
};
|
||||||
let sIdx = a.sIdx;
|
let sIdx = a.sIdx;
|
||||||
while (ctx.signals[sIdx].e >= 0) sIdx = ctx.signals[sIdx].e;
|
while (ctx.signals[sIdx].e >= 0) sIdx = ctx.signals[sIdx].e;
|
||||||
res.coefs[sIdx] = ctx.field.one;
|
res.coefs[sIdx] = ctx.F.one;
|
||||||
return res;
|
return res;
|
||||||
} else {
|
} else {
|
||||||
ctx.throwError(ast, "Invalid type: " + a.t);
|
ctx.throwError(ast, "Invalid type: " + a.t);
|
||||||
@@ -974,7 +984,7 @@ function execArray(ctx, ast) {
|
|||||||
} else if (e.t == "S") {
|
} else if (e.t == "S") {
|
||||||
for (let j=0; j<e.v.length;j++) {
|
for (let j=0; j<e.v.length;j++) {
|
||||||
const sv = {t: "LC", coefs: {}};
|
const sv = {t: "LC", coefs: {}};
|
||||||
sv.coefs[e.sIdx+j] = ctx.field.one;
|
sv.coefs[e.sIdx+j] = ctx.F.one;
|
||||||
res.v.push(sv);
|
res.v.push(sv);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
const bigInt = require("big-integer");
|
|
||||||
const BigArray = require("./bigarray.js");
|
const BigArray = require("./bigarray.js");
|
||||||
|
const F1Field = require("ffjavascript").F1Field;
|
||||||
|
|
||||||
class TableName {
|
class TableName {
|
||||||
constructor (ctx) {
|
constructor (ctx) {
|
||||||
@@ -86,7 +85,9 @@ class TableName {
|
|||||||
|
|
||||||
module.exports = class Ctx {
|
module.exports = class Ctx {
|
||||||
|
|
||||||
constructor() {
|
constructor(p) {
|
||||||
|
|
||||||
|
this.F = new F1Field(p);
|
||||||
|
|
||||||
this.stONE = 1;
|
this.stONE = 1;
|
||||||
this.stOUTPUT = 2;
|
this.stOUTPUT = 2;
|
||||||
@@ -121,7 +122,7 @@ module.exports = class Ctx {
|
|||||||
|
|
||||||
const oneIdx = this.addSignal("one");
|
const oneIdx = this.addSignal("one");
|
||||||
this.signals[oneIdx] = {
|
this.signals[oneIdx] = {
|
||||||
v: bigInt(1),
|
v: this.F.one,
|
||||||
o: this.ONE,
|
o: this.ONE,
|
||||||
e: -1,
|
e: -1,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
const bigInt = require("big-integer");
|
|
||||||
const utils = require("./utils");
|
const utils = require("./utils");
|
||||||
const assert = require("assert");
|
const assert = require("assert");
|
||||||
const iterateAST = require("./iterateast");
|
const iterateAST = require("./iterateast");
|
||||||
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
|
|
||||||
module.exports.gen = gen;
|
module.exports.gen = gen;
|
||||||
module.exports.newRef = newRef;
|
module.exports.newRef = newRef;
|
||||||
@@ -175,17 +175,17 @@ function gen(ctx, ast) {
|
|||||||
} else if (ast.op == ">>") {
|
} else if (ast.op == ">>") {
|
||||||
return genOp(ctx, ast, "shr", 2);
|
return genOp(ctx, ast, "shr", 2);
|
||||||
} else if (ast.op == "<") {
|
} else if (ast.op == "<") {
|
||||||
return genOp(ctx, ast, "lt", 2);
|
return genOp(ctx, ast, "lt", 2, true);
|
||||||
} else if (ast.op == ">") {
|
} else if (ast.op == ">") {
|
||||||
return genOp(ctx, ast, "gt", 2);
|
return genOp(ctx, ast, "gt", 2, true);
|
||||||
} else if (ast.op == "<=") {
|
} else if (ast.op == "<=") {
|
||||||
return genOp(ctx, ast, "leq", 2);
|
return genOp(ctx, ast, "leq", 2, true);
|
||||||
} else if (ast.op == ">=") {
|
} else if (ast.op == ">=") {
|
||||||
return genOp(ctx, ast, "geq", 2);
|
return genOp(ctx, ast, "geq", 2, true);
|
||||||
} else if (ast.op == "==") {
|
} else if (ast.op == "==") {
|
||||||
return genOp(ctx, ast, "eq", 2);
|
return genOp(ctx, ast, "eq", 2, true);
|
||||||
} else if (ast.op == "!=") {
|
} else if (ast.op == "!=") {
|
||||||
return genOp(ctx, ast, "neq", 2);
|
return genOp(ctx, ast, "neq", 2, true);
|
||||||
} else if (ast.op == "?") {
|
} else if (ast.op == "?") {
|
||||||
return genTerCon(ctx, ast);
|
return genTerCon(ctx, ast);
|
||||||
} else {
|
} else {
|
||||||
@@ -300,7 +300,7 @@ function genDeclareVariable(ctx, ast) {
|
|||||||
const size = ctx.refs[sizeRef];
|
const size = ctx.refs[sizeRef];
|
||||||
if (size.sizes[0] != 1) return ctx.throwError(ast, "A selector cannot be an array");
|
if (size.sizes[0] != 1) return ctx.throwError(ast, "A selector cannot be an array");
|
||||||
if (size.used) return ctx.throwError(ast, "Variable size variables not allowed");
|
if (size.used) return ctx.throwError(ast, "Variable size variables not allowed");
|
||||||
sizes.push(size.value[0]);
|
sizes.push(Scalar.toNumber(size.value[0]));
|
||||||
}
|
}
|
||||||
sizes = utils.accSizes(sizes);
|
sizes = utils.accSizes(sizes);
|
||||||
} else {
|
} else {
|
||||||
@@ -320,7 +320,7 @@ function genDeclareVariable(ctx, ast) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function genNumber(ctx, ast) {
|
function genNumber(ctx, ast) {
|
||||||
return newRef(ctx, "BIGINT", "_num", bigInt(ast.value));
|
return newRef(ctx, "BIGINT", "_num", ctx.F.e(ast.value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -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]);
|
||||||
@@ -950,7 +964,7 @@ function genLoop(ctx, ast) {
|
|||||||
ctx.codeBuilder.assign(loopCond.label, ["R", cond.label], ["V", 0]);
|
ctx.codeBuilder.assign(loopCond.label, ["R", cond.label], ["V", 0]);
|
||||||
} else {
|
} else {
|
||||||
if (!utils.isDefined(cond.value)) return ctx.throwError(ast, "condition value not assigned");
|
if (!utils.isDefined(cond.value)) return ctx.throwError(ast, "condition value not assigned");
|
||||||
if (cond.value[0].isZero()) end=true;
|
if (ctx.F.isZero(cond.value[0])) end=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -993,7 +1007,7 @@ function genLoop(ctx, ast) {
|
|||||||
} else {
|
} else {
|
||||||
oldCodeBuilder.concat(ctx.codeBuilder);
|
oldCodeBuilder.concat(ctx.codeBuilder);
|
||||||
ctx.codeBuilder = oldCodeBuilder;
|
ctx.codeBuilder = oldCodeBuilder;
|
||||||
if (cond2.value[0].isZero()) end=true;
|
if (ctx.F.isZero(cond2.value[0])) end=true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ctx.codeBuilder.assign(loopCond.label, ["R", cond2.label], ["V", 0]);
|
ctx.codeBuilder.assign(loopCond.label, ["R", cond2.label], ["V", 0]);
|
||||||
@@ -1042,7 +1056,7 @@ function genIf(ctx, ast) {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (!utils.isDefined(cond.value)) return ctx.throwError(ast, "condition value not assigned");
|
if (!utils.isDefined(cond.value)) return ctx.throwError(ast, "condition value not assigned");
|
||||||
if (!cond.value[0].isZero()) {
|
if (!ctx.F.isZero(cond.value[0])) {
|
||||||
gen(ctx, ast.then);
|
gen(ctx, ast.then);
|
||||||
} else {
|
} else {
|
||||||
if (ast.else) {
|
if (ast.else) {
|
||||||
@@ -1109,9 +1123,9 @@ function genOpOp(ctx, ast, op, lr) {
|
|||||||
const res = ctx.refs[resRef];
|
const res = ctx.refs[resRef];
|
||||||
if (veval.used) {
|
if (veval.used) {
|
||||||
instantiateRef(ctx, resRef);
|
instantiateRef(ctx, resRef);
|
||||||
ctx.codeBuilder.fieldOp(res.label, op, [["R", veval.label], ["C", ctx.addConstant(bigInt.one)]]);
|
ctx.codeBuilder.fieldOp(res.label, op, [["R", veval.label], ["C", ctx.addConstant(ctx.F.one)]]);
|
||||||
} else {
|
} else {
|
||||||
res.value = [ctx.field[op](veval.value[0], bigInt(1))];
|
res.value = [ctx.F[op](veval.value[0], ctx.F.one)];
|
||||||
}
|
}
|
||||||
genVarAssignment(ctx, ast, vRef, ast.values[0].selectors, resRef);
|
genVarAssignment(ctx, ast, vRef, ast.values[0].selectors, resRef);
|
||||||
if (lr == "RIGHT") {
|
if (lr == "RIGHT") {
|
||||||
@@ -1121,7 +1135,7 @@ function genOpOp(ctx, ast, op, lr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function genOp(ctx, ast, op, nOps) {
|
function genOp(ctx, ast, op, nOps, adjustBool) {
|
||||||
const vals = [];
|
const vals = [];
|
||||||
const valRefs = [];
|
const valRefs = [];
|
||||||
|
|
||||||
@@ -1157,9 +1171,10 @@ function genOp(ctx, ast, op, nOps) {
|
|||||||
} else {
|
} else {
|
||||||
const params = [];
|
const params = [];
|
||||||
for (let i=0; i<nOps; i++) {
|
for (let i=0; i<nOps; i++) {
|
||||||
params.push(vals[i].value[0]);
|
params.push(ctx.F.e(vals[i].value[0]));
|
||||||
}
|
}
|
||||||
rRef = newRef(ctx, "BIGINT", "_tmp", ctx.field[op](...params));
|
|
||||||
|
rRef = newRef(ctx, "BIGINT", "_tmp", adjustBool ? (ctx.F[op](...params)?ctx.F.one:ctx.F.zero) : ctx.F[op](...params));
|
||||||
}
|
}
|
||||||
return rRef;
|
return rRef;
|
||||||
}
|
}
|
||||||
@@ -1241,7 +1256,7 @@ function genTerCon(ctx, ast) {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (!utils.isDefined(cond.value)) return ctx.throwError(ast, "condition value not assigned");
|
if (!utils.isDefined(cond.value)) return ctx.throwError(ast, "condition value not assigned");
|
||||||
if (!cond.value[0].isZero()) {
|
if (!ctx.F.isZero(cond.value[0])) {
|
||||||
return gen(ctx, ast.values[1]);
|
return gen(ctx, ast.values[1]);
|
||||||
} else {
|
} else {
|
||||||
return gen(ctx, ast.values[2]);
|
return gen(ctx, ast.values[2]);
|
||||||
|
|||||||
@@ -76,21 +76,14 @@ QEX QEX NQ NQ NQ
|
|||||||
NQ NQ NQ NQ NQ
|
NQ NQ NQ NQ NQ
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const bigInt = require("big-integer");
|
|
||||||
const utils = require("./utils");
|
const utils = require("./utils");
|
||||||
const sONE = 0;
|
const sONE = 0;
|
||||||
|
|
||||||
class LCAlgebra {
|
class LCAlgebra {
|
||||||
constructor (aField) {
|
constructor (aField) {
|
||||||
const self = this;
|
const self = this;
|
||||||
this.field= aField;
|
this.F= aField;
|
||||||
[
|
[
|
||||||
["lt",2],
|
|
||||||
["leq",2],
|
|
||||||
["eq",2],
|
|
||||||
["neq",2],
|
|
||||||
["geq",2],
|
|
||||||
["gt",2],
|
|
||||||
["idiv",2],
|
["idiv",2],
|
||||||
["mod",2],
|
["mod",2],
|
||||||
["band",2],
|
["band",2],
|
||||||
@@ -102,12 +95,18 @@ class LCAlgebra {
|
|||||||
["lnot",2],
|
["lnot",2],
|
||||||
["shl",2],
|
["shl",2],
|
||||||
["shr",2],
|
["shr",2],
|
||||||
|
["lt",2, true],
|
||||||
|
["leq",2, true],
|
||||||
|
["eq",2, true],
|
||||||
|
["neq",2, true],
|
||||||
|
["geq",2, true],
|
||||||
|
["gt",2, true]
|
||||||
].forEach( (op) => {
|
].forEach( (op) => {
|
||||||
self._genNQOp(op[0], op[1]);
|
self._genNQOp(op[0], op[1], op[2]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_genNQOp(op, nOps) {
|
_genNQOp(op, nOps, adjustBool) {
|
||||||
const self=this;
|
const self=this;
|
||||||
self[op] = function() {
|
self[op] = function() {
|
||||||
const operands = [];
|
const operands = [];
|
||||||
@@ -118,18 +117,19 @@ class LCAlgebra {
|
|||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
t: "N",
|
t: "N",
|
||||||
v: self.field[op](...operands)
|
v: adjustBool ? ( self.F[op](...operands) ? self.F.one: self.F.zero) : self.F[op](...operands)
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
_signal2lc(a) {
|
_signal2lc(a) {
|
||||||
|
const self = this;
|
||||||
if (a.t == "S") {
|
if (a.t == "S") {
|
||||||
const lc = {
|
const lc = {
|
||||||
t: "LC",
|
t: "LC",
|
||||||
coefs: {}
|
coefs: {}
|
||||||
};
|
};
|
||||||
lc.coefs[a.sIdx] = bigInt(1);
|
lc.coefs[a.sIdx] = self.F.one;
|
||||||
return lc;
|
return lc;
|
||||||
} else {
|
} else {
|
||||||
return a;
|
return a;
|
||||||
@@ -200,17 +200,17 @@ class LCAlgebra {
|
|||||||
function add_N_N(a,b) {
|
function add_N_N(a,b) {
|
||||||
return {
|
return {
|
||||||
t: "N",
|
t: "N",
|
||||||
v: self.field.add(a.v, b.v)
|
v: self.F.add(a.v, b.v)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function add_LC_N(a,b) {
|
function add_LC_N(a,b) {
|
||||||
let res = self._clone(a);
|
let res = self._clone(a);
|
||||||
if (b.v.isZero()) return res;
|
if (self.F.isZero(b.v)) return res;
|
||||||
if (!utils.isDefined(res.coefs[sONE])) {
|
if (!utils.isDefined(res.coefs[sONE])) {
|
||||||
res.coefs[sONE]= b.v;
|
res.coefs[sONE]= b.v;
|
||||||
} else {
|
} else {
|
||||||
res.coefs[sONE]= self.field.add(res.coefs[sONE], b.v);
|
res.coefs[sONE]= self.F.add(res.coefs[sONE], b.v);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -221,7 +221,7 @@ class LCAlgebra {
|
|||||||
if (!utils.isDefined(res.coefs[k])) {
|
if (!utils.isDefined(res.coefs[k])) {
|
||||||
res.coefs[k]=b.coefs[k];
|
res.coefs[k]=b.coefs[k];
|
||||||
} else {
|
} else {
|
||||||
res.coefs[k]= self.field.add(res.coefs[k], b.coefs[k]);
|
res.coefs[k]= self.F.add(res.coefs[k], b.coefs[k]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
@@ -283,14 +283,14 @@ class LCAlgebra {
|
|||||||
function mul_N_N(a,b) {
|
function mul_N_N(a,b) {
|
||||||
return {
|
return {
|
||||||
t: "N",
|
t: "N",
|
||||||
v: self.field.mul(a.v, b.v)
|
v: self.F.mul(a.v, b.v)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function mul_LC_N(a,b) {
|
function mul_LC_N(a,b) {
|
||||||
let res = self._clone(a);
|
let res = self._clone(a);
|
||||||
for (let k in res.coefs) {
|
for (let k in res.coefs) {
|
||||||
res.coefs[k] = self.field.mul(res.coefs[k], b.v);
|
res.coefs[k] = self.F.mul(res.coefs[k], b.v);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -318,10 +318,10 @@ class LCAlgebra {
|
|||||||
const a = this._signal2lc(_a);
|
const a = this._signal2lc(_a);
|
||||||
let res = this._clone(a);
|
let res = this._clone(a);
|
||||||
if (res.t == "N") {
|
if (res.t == "N") {
|
||||||
res.v = this.field.neg(a.v);
|
res.v = this.F.neg(a.v);
|
||||||
} else if (res.t == "LC") {
|
} else if (res.t == "LC") {
|
||||||
for (let k in res.coefs) {
|
for (let k in res.coefs) {
|
||||||
res.coefs[k] = this.field.neg(res.coefs[k]);
|
res.coefs[k] = this.F.neg(res.coefs[k]);
|
||||||
}
|
}
|
||||||
} else if (res.t == "QEX") {
|
} else if (res.t == "QEX") {
|
||||||
res.a = this.neg(res.a);
|
res.a = this.neg(res.a);
|
||||||
@@ -338,10 +338,10 @@ class LCAlgebra {
|
|||||||
|
|
||||||
div(a, b) {
|
div(a, b) {
|
||||||
if (b.t == "N") {
|
if (b.t == "N") {
|
||||||
if (b.v.isZero()) throw new Error("Division by zero");
|
if (this.F.isZero(b.v)) throw new Error("Division by zero");
|
||||||
const inv = {
|
const inv = {
|
||||||
t: "N",
|
t: "N",
|
||||||
v: this.field.inv(b.v)
|
v: this.F.inv(b.v)
|
||||||
};
|
};
|
||||||
return this.mul(a, inv);
|
return this.mul(a, inv);
|
||||||
} else {
|
} else {
|
||||||
@@ -351,23 +351,23 @@ class LCAlgebra {
|
|||||||
|
|
||||||
pow(a, b) {
|
pow(a, b) {
|
||||||
if (b.t == "N") {
|
if (b.t == "N") {
|
||||||
if (b.v.isZero()) {
|
if (this.F.isZero(b.v)) {
|
||||||
if (this.isZero(a)) {
|
if (this.isZero(a)) {
|
||||||
throw new Error("Zero to the Zero");
|
throw new Error("Zero to the Zero");
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
t: "N",
|
t: "N",
|
||||||
v: this.field.one
|
v: this.F.one
|
||||||
};
|
};
|
||||||
} else if (b.v.eq(this.field.one)) {
|
} else if (this.F.eq(b.v, this.F.one)) {
|
||||||
return a;
|
return a;
|
||||||
} else if (b.v.eq(bigInt(2))) {
|
} else if (this.F.eq(b.v, this.F.two)) {
|
||||||
return this.mul(a,a);
|
return this.mul(a,a);
|
||||||
} else {
|
} else {
|
||||||
if (a.t=="N") {
|
if (a.t=="N") {
|
||||||
return {
|
return {
|
||||||
t: "N",
|
t: "N",
|
||||||
v: this.field.pow(a.v, b.v)
|
v: this.F.pow(a.v, b.v)
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return {t: "NQ"};
|
return {t: "NQ"};
|
||||||
@@ -381,18 +381,18 @@ class LCAlgebra {
|
|||||||
substitute(where, signal, equivalence) {
|
substitute(where, signal, equivalence) {
|
||||||
if (equivalence.t != "LC") throw new Error("Equivalence must be a Linear Combination");
|
if (equivalence.t != "LC") throw new Error("Equivalence must be a Linear Combination");
|
||||||
if (where.t == "LC") {
|
if (where.t == "LC") {
|
||||||
if (!utils.isDefined(where.coefs[signal]) || where.coefs[signal].isZero()) return where;
|
if (!utils.isDefined(where.coefs[signal]) || this.F.isZero(where.coefs[signal])) return where;
|
||||||
const res=this._clone(where);
|
const res=this._clone(where);
|
||||||
const coef = res.coefs[signal];
|
const coef = res.coefs[signal];
|
||||||
for (let k in equivalence.coefs) {
|
for (let k in equivalence.coefs) {
|
||||||
if (k != signal) {
|
if (k != signal) {
|
||||||
const v = this.field.mul( coef, equivalence.coefs[k] );
|
const v = this.F.mul( coef, equivalence.coefs[k] );
|
||||||
if (!utils.isDefined(res.coefs[k])) {
|
if (!utils.isDefined(res.coefs[k])) {
|
||||||
res.coefs[k]=v;
|
res.coefs[k]=v;
|
||||||
} else {
|
} else {
|
||||||
res.coefs[k]= this.field.add(res.coefs[k],v);
|
res.coefs[k]= this.F.add(res.coefs[k],v);
|
||||||
}
|
}
|
||||||
if (res.coefs[k].isZero()) delete res.coefs[k];
|
if (this.F.isZero(res.coefs[k])) delete res.coefs[k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete res.coefs[signal];
|
delete res.coefs[signal];
|
||||||
@@ -436,10 +436,10 @@ class LCAlgebra {
|
|||||||
|
|
||||||
isZero(a) {
|
isZero(a) {
|
||||||
if (a.t == "N") {
|
if (a.t == "N") {
|
||||||
return a.v.isZero();
|
return this.F.isZero(a.v);
|
||||||
} else if (a.t == "LC") {
|
} else if (a.t == "LC") {
|
||||||
for (let k in a.coefs) {
|
for (let k in a.coefs) {
|
||||||
if (!a.coefs[k].isZero()) return false;
|
if (!this.F.isZero(a.coefs[k])) return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else if (a.t == "QEX") {
|
} else if (a.t == "QEX") {
|
||||||
@@ -455,16 +455,16 @@ class LCAlgebra {
|
|||||||
} else if (a.t == "LC") {
|
} else if (a.t == "LC") {
|
||||||
let S="";
|
let S="";
|
||||||
for (let k in a.coefs) {
|
for (let k in a.coefs) {
|
||||||
if (!a.coefs[k].isZero()) {
|
if (!this.F.isZero(a.coefs[k])) {
|
||||||
let c;
|
let c;
|
||||||
if (a.coefs[k].greater(this.field.p.divide(2))) {
|
if (a.coefs[k].greater(this.F.p.divide(2))) {
|
||||||
S = S + "-";
|
S = S + "-";
|
||||||
c = this.field.p.minus(a.coefs[k]);
|
c = this.F.p.minus(a.coefs[k]);
|
||||||
} else {
|
} else {
|
||||||
if (S!="") S=S+" + ";
|
if (S!="") S=S+" + ";
|
||||||
c = a.coefs[k];
|
c = a.coefs[k];
|
||||||
}
|
}
|
||||||
if (!c.equals(bigInt.one)) {
|
if (!c.equals(this.F.one)) {
|
||||||
S = S + c.toString() + "*";
|
S = S + c.toString() + "*";
|
||||||
}
|
}
|
||||||
let sIdx = k;
|
let sIdx = k;
|
||||||
@@ -491,11 +491,11 @@ class LCAlgebra {
|
|||||||
} else if (n.t == "SIGNAL") {
|
} else if (n.t == "SIGNAL") {
|
||||||
return getSignalValue(ctx, n.sIdx);
|
return getSignalValue(ctx, n.sIdx);
|
||||||
} else if (n.t == "LC") {
|
} else if (n.t == "LC") {
|
||||||
let v= this.field.zero;
|
let v= this.F.zero;
|
||||||
for (let k in n.coefs) {
|
for (let k in n.coefs) {
|
||||||
const s = getSignalValue(ctx, k);
|
const s = getSignalValue(ctx, k);
|
||||||
if (s === null) return null;
|
if (s === null) return null;
|
||||||
v = this.field.add(v, this.field.mul( n.coefs[k], s));
|
v = this.F.add(v, this.F.mul( n.coefs[k], s));
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
} else if (n.type == "QEX") {
|
} else if (n.type == "QEX") {
|
||||||
@@ -506,7 +506,7 @@ class LCAlgebra {
|
|||||||
const c = this.evaluate(ctx, n.c);
|
const c = this.evaluate(ctx, n.c);
|
||||||
if (c === null) return null;
|
if (c === null) return null;
|
||||||
|
|
||||||
return this.field.add(this.field.mul(a,b), c);
|
return this.F.add(this.F.mul(a,b), c);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -529,24 +529,24 @@ class LCAlgebra {
|
|||||||
let s = k;
|
let s = k;
|
||||||
while (ctx.signals[s].e>=0) s= ctx.signals[s].e;
|
while (ctx.signals[s].e>=0) s= ctx.signals[s].e;
|
||||||
if (utils.isDefined(ctx.signals[s].v)&&(k != sONE)) {
|
if (utils.isDefined(ctx.signals[s].v)&&(k != sONE)) {
|
||||||
const v = this.field.mul(res.coefs[k], ctx.signals[s].v);
|
const v = this.F.mul(res.coefs[k], ctx.signals[s].v);
|
||||||
if (!utils.isDefined(res.coefs[sONE])) {
|
if (!utils.isDefined(res.coefs[sONE])) {
|
||||||
res.coefs[sONE]=v;
|
res.coefs[sONE]=v;
|
||||||
} else {
|
} else {
|
||||||
res.coefs[sONE]= this.field.add(res.coefs[sONE], v);
|
res.coefs[sONE]= this.F.add(res.coefs[sONE], v);
|
||||||
}
|
}
|
||||||
delete res.coefs[k];
|
delete res.coefs[k];
|
||||||
} else if (s != k) {
|
} else if (s != k) {
|
||||||
if (!utils.isDefined(res.coefs[s])) {
|
if (!utils.isDefined(res.coefs[s])) {
|
||||||
res.coefs[s]=res.coefs[k];
|
res.coefs[s]=res.coefs[k];
|
||||||
} else {
|
} else {
|
||||||
res.coefs[s]= this.field.add(res.coefs[s], res.coefs[k]);
|
res.coefs[s]= this.F.add(res.coefs[s], res.coefs[k]);
|
||||||
}
|
}
|
||||||
delete res.coefs[k];
|
delete res.coefs[k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let k in res.coefs) {
|
for (let k in res.coefs) {
|
||||||
if (res.coefs[k].isZero()) delete res.coefs[k];
|
if (this.F.isZero(res.coefs[k])) delete res.coefs[k];
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
} else if (a.t == "QEX") {
|
} else if (a.t == "QEX") {
|
||||||
|
|||||||
153
src/r1csfile.js
153
src/r1csfile.js
@@ -1,32 +1,37 @@
|
|||||||
|
|
||||||
const fs = require("fs");
|
const fastFile = require("fastfile");
|
||||||
const assert = require("assert");
|
const assert = require("assert");
|
||||||
const bigInt = require("big-integer");
|
const BigArray = require("./bigarray");
|
||||||
|
|
||||||
module.exports.buildR1cs = buildR1cs;
|
module.exports.buildR1cs = buildR1cs;
|
||||||
|
|
||||||
|
|
||||||
async function buildR1cs(ctx, fileName) {
|
async function buildR1cs(ctx, fileName) {
|
||||||
|
|
||||||
const fd = await fs.promises.open(fileName, "w");
|
const fd = await fastFile.createOverride(fileName);
|
||||||
|
|
||||||
|
|
||||||
await fd.write("r1cs"); // Magic "r1cs"
|
const buffBigInt = new Uint8Array(ctx.F.n8);
|
||||||
|
|
||||||
let p = 4;
|
const type = "r1cs";
|
||||||
await writeU32(1); // Version
|
const buff = new Uint8Array(4);
|
||||||
await writeU32(3); // Number of Sections
|
for (let i=0; i<4; i++) buff[i] = type.charCodeAt(i);
|
||||||
|
await fd.write(buff, 0); // Magic "r1cs"
|
||||||
|
|
||||||
|
await fd.writeULE32(1); // Version
|
||||||
|
await fd.writeULE32(3); // Number of Sections
|
||||||
|
|
||||||
// Write the header
|
// Write the header
|
||||||
///////////
|
///////////
|
||||||
await writeU32(1); // Header type
|
await fd.writeULE32(1); // Header type
|
||||||
const pHeaderSize = p;
|
const pHeaderSize = fd.pos;
|
||||||
await writeU64(0); // Temporally set to 0 length
|
await fd.writeULE64(0); // Temporally set to 0 length
|
||||||
|
|
||||||
|
|
||||||
const n8 = (Math.floor( (ctx.field.p.bitLength() - 1) / 64) +1)*8;
|
const n8 = (Math.floor( (ctx.F.bitLength - 1) / 64) +1)*8;
|
||||||
// Field Def
|
// Field Def
|
||||||
await writeU32(n8); // Temporally set to 0 length
|
await fd.writeULE32(n8); // Temporally set to 0 length
|
||||||
await writeBigInt(ctx.field.p);
|
await writeBigInt(ctx.F.p);
|
||||||
|
|
||||||
const NWires =
|
const NWires =
|
||||||
ctx.totals[ctx.stONE] +
|
ctx.totals[ctx.stONE] +
|
||||||
@@ -35,39 +40,38 @@ async function buildR1cs(ctx, fileName) {
|
|||||||
ctx.totals[ctx.stPRVINPUT] +
|
ctx.totals[ctx.stPRVINPUT] +
|
||||||
ctx.totals[ctx.stINTERNAL];
|
ctx.totals[ctx.stINTERNAL];
|
||||||
|
|
||||||
await writeU32(NWires);
|
await fd.writeULE32(NWires);
|
||||||
await writeU32(ctx.totals[ctx.stOUTPUT]);
|
await fd.writeULE32(ctx.totals[ctx.stOUTPUT]);
|
||||||
await writeU32(ctx.totals[ctx.stPUBINPUT]);
|
await fd.writeULE32(ctx.totals[ctx.stPUBINPUT]);
|
||||||
await writeU32(ctx.totals[ctx.stPRVINPUT]);
|
await fd.writeULE32(ctx.totals[ctx.stPRVINPUT]);
|
||||||
await writeU64(ctx.signals.length);
|
await fd.writeULE64(ctx.signals.length);
|
||||||
await writeU32(ctx.constraints.length);
|
await fd.writeULE32(ctx.constraints.length);
|
||||||
|
|
||||||
const headerSize = p - pHeaderSize - 8;
|
const headerSize = fd.pos - pHeaderSize - 8;
|
||||||
|
|
||||||
// Write constraints
|
// Write constraints
|
||||||
///////////
|
///////////
|
||||||
await writeU32(2); // Constraints type
|
await fd.writeULE32(2); // Constraints type
|
||||||
const pConstraintsSize = p;
|
const pConstraintsSize = fd.pos;
|
||||||
await writeU64(0); // Temporally set to 0 length
|
await fd.writeULE64(0); // Temporally set to 0 length
|
||||||
|
|
||||||
for (let i=0; i<ctx.constraints.length; i++) {
|
for (let i=0; i<ctx.constraints.length; i++) {
|
||||||
if ((ctx.verbose)&&(i%10000 == 0)) {
|
if ((ctx.verbose)&&(i%10000 == 0)) {
|
||||||
if (ctx.verbose) console.log("writing constraint: ", i);
|
if (ctx.verbose) console.log("writing constraint: ", i);
|
||||||
await fd.datasync();
|
|
||||||
}
|
}
|
||||||
await writeConstraint(ctx.constraints[i]);
|
await writeConstraint(ctx.constraints[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const constraintsSize = p - pConstraintsSize - 8;
|
const constraintsSize = fd.pos - pConstraintsSize - 8;
|
||||||
|
|
||||||
// Write map
|
// Write map
|
||||||
///////////
|
///////////
|
||||||
await writeU32(3); // wires2label type
|
await fd.writeULE32(3); // wires2label type
|
||||||
const pMapSize = p;
|
const pMapSize = fd.pos;
|
||||||
await writeU64(0); // Temporally set to 0 length
|
await fd.writeULE64(0); // Temporally set to 0 length
|
||||||
|
|
||||||
|
|
||||||
const arr = new Array(NWires);
|
const arr = new BigArray(NWires);
|
||||||
for (let i=0; i<ctx.signals.length; i++) {
|
for (let i=0; i<ctx.signals.length; i++) {
|
||||||
const outIdx = ctx.signals[i].id;
|
const outIdx = ctx.signals[i].id;
|
||||||
if (ctx.signals[i].e>=0) continue; // If has an alias, continue..
|
if (ctx.signals[i].e>=0) continue; // If has an alias, continue..
|
||||||
@@ -78,69 +82,64 @@ async function buildR1cs(ctx, fileName) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let i=0; i<arr.length; i++) {
|
for (let i=0; i<arr.length; i++) {
|
||||||
await writeU64(arr[i]);
|
await fd.writeULE64(arr[i]);
|
||||||
if ((ctx.verbose)&&(i%100000)) console.log("writing wire2label map: ", i);
|
if ((ctx.verbose)&&(i%100000 == 0)) console.log(`writing wire2label map: ${i}/${arr.length}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapSize = p - pMapSize - 8;
|
const mapSize = fd.pos - pMapSize - 8;
|
||||||
|
|
||||||
// Write sizes
|
// Write sizes
|
||||||
await writeU32(headerSize, pHeaderSize);
|
await fd.writeULE32(headerSize, pHeaderSize);
|
||||||
await writeU32(constraintsSize, pConstraintsSize);
|
await fd.writeULE32(constraintsSize, pConstraintsSize);
|
||||||
await writeU32(mapSize, pMapSize);
|
await fd.writeULE32(mapSize, pMapSize);
|
||||||
|
|
||||||
await fd.sync();
|
|
||||||
await fd.close();
|
await fd.close();
|
||||||
|
|
||||||
async function writeU32(v, pos) {
|
function writeConstraint(c) {
|
||||||
const b = Buffer.allocUnsafe(4);
|
const n8 = ctx.F.n8;
|
||||||
b.writeInt32LE(v);
|
const idxA = Object.keys(c.a.coefs);
|
||||||
|
const idxB = Object.keys(c.b.coefs);
|
||||||
await fd.write(b, 0, 4, pos);
|
const idxC = Object.keys(c.c.coefs);
|
||||||
|
const buff = new Uint8Array((idxA.length+idxB.length+idxC.length)*(n8+4) + 12);
|
||||||
if (typeof(pos) == "undefined") p += 4;
|
const buffV = new DataView(buff.buffer);
|
||||||
}
|
let o=0;
|
||||||
|
|
||||||
async function writeU64(v, pos) {
|
|
||||||
const b = Buffer.allocUnsafe(8);
|
|
||||||
b.writeBigUInt64LE(BigInt(v));
|
|
||||||
|
|
||||||
await fd.write(b, 0, 8, pos);
|
|
||||||
|
|
||||||
if (typeof(pos) == "undefined") p += 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function writeConstraint(c) {
|
|
||||||
await writeLC(c.a);
|
|
||||||
await writeLC(c.b);
|
|
||||||
await writeLC(ctx.lc.neg(c.c));
|
|
||||||
}
|
|
||||||
|
|
||||||
async function writeLC(lc) {
|
|
||||||
const idxs = Object.keys(lc.coefs);
|
|
||||||
await writeU32(idxs.length);
|
|
||||||
for (let s in lc.coefs) {
|
|
||||||
let lSignal = ctx.signals[s];
|
|
||||||
|
|
||||||
|
buffV.setUint32(o, idxA.length, true); o+=4;
|
||||||
|
for (let i=0; i<idxA.length; i++) {
|
||||||
|
const coef = idxA[i];
|
||||||
|
let lSignal = ctx.signals[coef];
|
||||||
while (lSignal.e >=0 ) lSignal = ctx.signals[lSignal.e];
|
while (lSignal.e >=0 ) lSignal = ctx.signals[lSignal.e];
|
||||||
|
buffV.setUint32(o, lSignal.id, true); o+=4;
|
||||||
await writeU32(lSignal.id);
|
ctx.F.toRprLE(buff, o, c.a.coefs[coef]); o+=n8;
|
||||||
await writeBigInt(lc.coefs[s]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buffV.setUint32(o, idxB.length, true); o+=4;
|
||||||
|
for (let i=0; i<idxB.length; i++) {
|
||||||
|
const coef = idxB[i];
|
||||||
|
let lSignal = ctx.signals[coef];
|
||||||
|
while (lSignal.e >=0 ) lSignal = ctx.signals[lSignal.e];
|
||||||
|
buffV.setUint32(o, lSignal.id, true); o+=4;
|
||||||
|
|
||||||
|
ctx.F.toRprLE(buff, o, c.b.coefs[coef]); o+=n8;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffV.setUint32(o, idxC.length, true); o+=4;
|
||||||
|
for (let i=0; i<idxC.length; i++) {
|
||||||
|
const coef = idxC[i];
|
||||||
|
let lSignal = ctx.signals[coef];
|
||||||
|
while (lSignal.e >=0 ) lSignal = ctx.signals[lSignal.e];
|
||||||
|
buffV.setUint32(o, lSignal.id, true); o+=4;
|
||||||
|
ctx.F.toRprLE(buff, o, ctx.F.neg(c.c.coefs[coef])); o+=n8;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fd.write(buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function writeBigInt(n, pos) {
|
async function writeBigInt(n, pos) {
|
||||||
const b = Buffer.allocUnsafe(n8);
|
|
||||||
|
|
||||||
const dwords = bigInt(n).toArray(0x100000000).value;
|
ctx.F.toRprLE(buffBigInt, 0, n);
|
||||||
|
|
||||||
for (let i=0; i<dwords.length; i++) {
|
await fd.write(buffBigInt, pos);
|
||||||
b.writeUInt32LE(dwords[dwords.length-1-i], i*4, 4 );
|
|
||||||
}
|
|
||||||
b.fill(0, dwords.length*4);
|
|
||||||
|
|
||||||
await fd.write(b, 0, fs, pos);
|
|
||||||
|
|
||||||
if (typeof(pos) == "undefined") p += n8;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
const Readable = require("stream").Readable;
|
const Readable = require("stream").Readable;
|
||||||
|
|
||||||
module.exports = function streamFromArrayTxt(ma) {
|
module.exports = function streamFromArrayTxt(ma) {
|
||||||
@@ -22,7 +21,7 @@ module.exports = function streamFromArrayTxt(ma) {
|
|||||||
|
|
||||||
|
|
||||||
function getFirstIdx(ma) {
|
function getFirstIdx(ma) {
|
||||||
if (!Array.isArray(ma)) return [];
|
if (typeof ma.push !== "function" ) return [];
|
||||||
return [0, ...getFirstIdx(ma[0])];
|
return [0, ...getFirstIdx(ma[0])];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
50
src/utils.js
50
src/utils.js
@@ -1,5 +1,4 @@
|
|||||||
const fnv = require("fnv-plus");
|
const fnv = require("fnv-plus");
|
||||||
const bigInt = require("big-integer");
|
|
||||||
|
|
||||||
module.exports.ident =ident;
|
module.exports.ident =ident;
|
||||||
|
|
||||||
@@ -8,11 +7,10 @@ module.exports.flatArray = flatArray;
|
|||||||
module.exports.csArr = csArr;
|
module.exports.csArr = csArr;
|
||||||
module.exports.accSizes = accSizes;
|
module.exports.accSizes = accSizes;
|
||||||
module.exports.fnvHash = fnvHash;
|
module.exports.fnvHash = fnvHash;
|
||||||
module.exports.stringifyBigInts = stringifyBigInts;
|
|
||||||
module.exports.unstringifyBigInts = unstringifyBigInts;
|
|
||||||
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") {
|
||||||
@@ -45,7 +43,7 @@ function flatArray(a) {
|
|||||||
fillArray(res, a[i]);
|
fillArray(res, a[i]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
res.push(bigInt(a));
|
res.push(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,42 +72,6 @@ function fnvHash(str) {
|
|||||||
return fnv.hash(str, 64).hex();
|
return fnv.hash(str, 64).hex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function stringifyBigInts(o) {
|
|
||||||
if ((typeof(o) == "bigint") || o.isZero !== undefined) {
|
|
||||||
return o.toString(10);
|
|
||||||
} else if (Array.isArray(o)) {
|
|
||||||
return o.map(stringifyBigInts);
|
|
||||||
} else if (typeof o == "object") {
|
|
||||||
const res = {};
|
|
||||||
for (let k in o) {
|
|
||||||
res[k] = stringifyBigInts(o[k]);
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
} else {
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function unstringifyBigInts(o) {
|
|
||||||
if ((typeof(o) == "string") && (/^[0-9]+$/.test(o) )) {
|
|
||||||
return bigInt(o);
|
|
||||||
} else if (Array.isArray(o)) {
|
|
||||||
return o.map(unstringifyBigInts);
|
|
||||||
} else if (typeof o == "object") {
|
|
||||||
const res = {};
|
|
||||||
for (let k in o) {
|
|
||||||
res[k] = unstringifyBigInts(o[k]);
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
} else {
|
|
||||||
return bigInt(o);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function sameSizes(s1, s2) {
|
function sameSizes(s1, s2) {
|
||||||
if (!Array.isArray(s1)) return false;
|
if (!Array.isArray(s1)) return false;
|
||||||
if (!Array.isArray(s2)) return false;
|
if (!Array.isArray(s2)) return false;
|
||||||
@@ -129,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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,19 @@
|
|||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
|
||||||
const bigInt = require("big-integer");
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
|
const F1Field = require("ffjavascript").F1Field;
|
||||||
const c_tester = require("../index.js").c_tester;
|
const c_tester = require("../index.js").c_tester;
|
||||||
const wasm_tester = require("../index.js").wasm_tester;
|
const wasm_tester = require("../index.js").wasm_tester;
|
||||||
|
|
||||||
const __P__ = new bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
const __P__ = Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||||
|
|
||||||
|
const Fr = new F1Field(__P__);
|
||||||
|
|
||||||
const basicCases = require("./basiccases.json");
|
const basicCases = require("./basiccases.json");
|
||||||
|
|
||||||
function normalize(o) {
|
function normalize(o) {
|
||||||
if ((typeof(o) == "bigint") || o.isZero !== undefined) {
|
if ((typeof(o) == "bigint") || o.isZero !== undefined) {
|
||||||
const res = bigInt(o);
|
return Fr.e(o);
|
||||||
return norm(res);
|
|
||||||
} else if (Array.isArray(o)) {
|
} else if (Array.isArray(o)) {
|
||||||
return o.map(normalize);
|
return o.map(normalize);
|
||||||
} else if (typeof o == "object") {
|
} else if (typeof o == "object") {
|
||||||
@@ -21,15 +23,9 @@ function normalize(o) {
|
|||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
} else {
|
} else {
|
||||||
const res = bigInt(o);
|
return Fr.e(o);
|
||||||
return norm(res);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function norm(n) {
|
|
||||||
let res = n.mod(__P__);
|
|
||||||
if (res.isNegative()) res = __P__.add(res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user