Compare commits
56 Commits
master
...
tornado-tr
Author | SHA1 | Date | |
---|---|---|---|
7b7a057160 | |||
ea3dc38335 | |||
fdcb762030 | |||
e9256fbf85 | |||
d20d53411d | |||
|
f4e209728e | ||
|
c90b18e93b | ||
|
5935ac69df | ||
|
45f190b445 | ||
|
8423282b8c | ||
|
1e04fc0325 | ||
|
1f9d0bd37f | ||
|
411a7d7576 | ||
|
6bcbf3370e | ||
|
9d876a1b32 | ||
|
d422471b5b | ||
|
01da5f90db | ||
fabc586fea | |||
|
7e93b3fcf8 | ||
|
3f4734d4dd | ||
|
1cd3d203c5 | ||
|
01e3f0d680 | ||
|
86c6a2a6f5 | ||
|
5269afee0a | ||
|
48c721c8af | ||
|
0efecf16fa | ||
|
7705fe8339 | ||
|
401c9e0728 | ||
|
d5ed1c3ce4 | ||
|
6a1efe4820 | ||
|
b2ac4daaa7 | ||
|
6df6e9cb1c | ||
|
9c68d4a363 | ||
|
57be559c44 | ||
|
7bf8325662 | ||
|
899d15f0c2 | ||
|
0bf26ea5ec | ||
|
e240605642 | ||
|
273ab79665 | ||
|
a851d08a46 | ||
|
19bbada388 | ||
|
cf6d1f0bb1 | ||
|
2f28fc7002 | ||
|
4f11565ca4 | ||
|
756f1f51e5 | ||
|
bc0fb60f89 | ||
|
7a6b0eda6e | ||
|
e32460efe1 | ||
|
a8107abbe9 | ||
|
4117ebc64a | ||
|
b4cd3889b6 | ||
|
30c6cf55b9 | ||
|
d5bca9feb6 | ||
|
bdfb0fb928 | ||
|
8bd0fac913 | ||
|
9941aac2f2 |
@ -1,7 +1,4 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
"plugins": [
|
|
||||||
"mocha"
|
|
||||||
],
|
|
||||||
"env": {
|
"env": {
|
||||||
"es6": true,
|
"es6": true,
|
||||||
"node": true,
|
"node": true,
|
||||||
@ -27,7 +24,6 @@ module.exports = {
|
|||||||
"semi": [
|
"semi": [
|
||||||
"error",
|
"error",
|
||||||
"always"
|
"always"
|
||||||
],
|
]
|
||||||
"mocha/no-exclusive-tests": "error"
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
- This repository contains a library of circuit templates.
|
- This repository contains a library of circuit templates.
|
||||||
- All files are copyrighted under 2018 0KIMS association and part of the free software [circom](https://github.com/iden3/circom) (Zero Knowledge Circuit Compiler).
|
- All files are copyrighted under 2018 0KIMS association and part of the free software [circom](https://github.com/iden3/circom) (Zero Knowledge Circuit Compiler).
|
||||||
|
- You can read more about the circom language in [the circom documentation webpage](https://docs.circom.io/).
|
||||||
|
|
||||||
## Organisation
|
## Organisation
|
||||||
|
|
||||||
@ -14,4 +15,4 @@ This respository contains 5 folders:
|
|||||||
- `src`: it contains similar implementation of circuits in JavaScript.
|
- `src`: it contains similar implementation of circuits in JavaScript.
|
||||||
- `test`: tests.
|
- `test`: tests.
|
||||||
|
|
||||||
A description of the specific circuit templates for the `circuit` folder will be soon updated.
|
A description of the specific circuit templates for the `circuit` folder will be soon updated.
|
||||||
|
@ -49,7 +49,7 @@ Folder containing the circuit implementation of Sparse Merkle Trees.
|
|||||||
- OUTPUT
|
- OUTPUT
|
||||||
- BENCHMARKS
|
- BENCHMARKS
|
||||||
- EXAMPLE
|
- EXAMPLE
|
||||||
|
|
||||||
### babyjub
|
### babyjub
|
||||||
|
|
||||||
Arithmetic on [Baby Jubjub elliptic curve](https://github.com/barryWhiteHat/baby_jubjub) in twisted Edwards form. (TODO: Expose here the characteristics of the curve?)
|
Arithmetic on [Baby Jubjub elliptic curve](https://github.com/barryWhiteHat/baby_jubjub) in twisted Edwards form. (TODO: Expose here the characteristics of the curve?)
|
||||||
@ -58,22 +58,22 @@ Arithmetic on [Baby Jubjub elliptic curve](https://github.com/barryWhiteHat/baby
|
|||||||
- `BabyAdd()`
|
- `BabyAdd()`
|
||||||
|
|
||||||
- DESCRIPTION
|
- DESCRIPTION
|
||||||
|
|
||||||
It adds two points on the Baby Jubjub curve. More specifically, given two points P1 = (`x1`, `y1`) and P2 = (`x2`, `y2`) it returns a point P3 = (`xout`, `yout`) such that
|
It adds two points on the Baby Jubjub curve. More specifically, given two points P1 = (`x1`, `y1`) and P2 = (`x2`, `y2`) it returns a point P3 = (`xout`, `yout`) such that
|
||||||
|
|
||||||
(`xout`, `yout`) = (`x1`,`y1`) + (`x2`,`y2`)
|
(`xout`, `yout`) = (`x1`,`y1`) + (`x2`,`y2`)
|
||||||
= ((`x1y2`+`y1x2`)/(1+`dx1x2y1y2`)),(`y1y2`-`ax1x2`)/(1-`dx1x2y1y2`))
|
= ((`x1y2`+`y1x2`)/(1+`dx1x2y1y2`)),(`y1y2`-`ax1x2`)/(1-`dx1x2y1y2`))
|
||||||
|
|
||||||
- SCHEMA
|
- SCHEMA
|
||||||
```
|
```
|
||||||
var a var d
|
var a var d
|
||||||
| |
|
| |
|
||||||
| |
|
| |
|
||||||
______v_________v_______
|
______v_________v_______
|
||||||
input x1 ----> | |
|
input x1 ----> | |
|
||||||
input y1 ----> | BabyAdd() | ----> output xout
|
input y1 ----> | BabyAdd() | ----> output xout
|
||||||
input x2 ----> | | ----> output yout
|
input x2 ----> | | ----> output yout
|
||||||
input y2 ----> |________________________|
|
input y2 ----> |________________________|
|
||||||
```
|
```
|
||||||
|
|
||||||
- INPUTS
|
- INPUTS
|
||||||
@ -84,16 +84,16 @@ Arithmetic on [Baby Jubjub elliptic curve](https://github.com/barryWhiteHat/baby
|
|||||||
| `y1` | Bigint | Field element of Fp | Second coordinate of a point (x1, y1) on E. |
|
| `y1` | Bigint | Field element of Fp | Second coordinate of a point (x1, y1) on E. |
|
||||||
| `x2` | Bigint | Field element of Fp | First coordinate of a point (x2, y2) on E. |
|
| `x2` | Bigint | Field element of Fp | First coordinate of a point (x2, y2) on E. |
|
||||||
| `y2` | Bigint | Field element of Fp | Second coordinate of a point (x2, y2) on E. |
|
| `y2` | Bigint | Field element of Fp | Second coordinate of a point (x2, y2) on E. |
|
||||||
|
|
||||||
Requirement: at least `x1`!=`x2` or `y1`!=`y2`.
|
Requirement: at least `x1`!=`x2` or `y1`!=`y2`.
|
||||||
|
|
||||||
- OUTPUT
|
- OUTPUT
|
||||||
|
|
||||||
| Input | Representation | Description | |
|
| Input | Representation | Description | |
|
||||||
| ------------- | ------------- | ------------- | ------------- |
|
| ------------- | ------------- | ------------- | ------------- |
|
||||||
| `xout` | Bigint | Field element of Fp | First coordinate of the addition point (xout, yout) = (x1, y1) + (x2, y2). |
|
| `xout` | Bigint | Field element of Fp | First coordinate of the addition point (xout, yout) = (x1, y1) + (x2, y2). |
|
||||||
| `yout` | Bigint | Field element of Fp | Second coordinate of the addition point (xout, yout) = (x1, y1) + (x2, y2). |
|
| `yout` | Bigint | Field element of Fp | Second coordinate of the addition point (xout, yout) = (x1, y1) + (x2, y2). |
|
||||||
|
|
||||||
- BENCHMARKS (constraints)
|
- BENCHMARKS (constraints)
|
||||||
|
|
||||||
- EXAMPLE
|
- EXAMPLE
|
||||||
@ -108,7 +108,7 @@ Arithmetic on [Baby Jubjub elliptic curve](https://github.com/barryWhiteHat/baby
|
|||||||
|
|
||||||
- `BabyCheck()`
|
- `BabyCheck()`
|
||||||
|
|
||||||
- DESCRIPTION : checks if a given point is in the curve.
|
- DESCRIPTION : checks if a given point is in the curve.
|
||||||
- SCHEMA
|
- SCHEMA
|
||||||
- INPUT
|
- INPUT
|
||||||
- OUTPUT
|
- OUTPUT
|
||||||
@ -127,7 +127,7 @@ Arithmetic on [Baby Jubjub elliptic curve](https://github.com/barryWhiteHat/baby
|
|||||||
|
|
||||||
### binsub
|
### binsub
|
||||||
|
|
||||||
- `BinSub(n)`
|
- `BinSub(n)`
|
||||||
|
|
||||||
- DESCRIPTION: binary substraction.
|
- DESCRIPTION: binary substraction.
|
||||||
- SCHEMA
|
- SCHEMA
|
||||||
@ -140,7 +140,7 @@ Arithmetic on [Baby Jubjub elliptic curve](https://github.com/barryWhiteHat/baby
|
|||||||
|
|
||||||
- `nbits(a)`
|
- `nbits(a)`
|
||||||
|
|
||||||
- DESCRIPTION : binary sum.
|
- DESCRIPTION : binary sum.
|
||||||
- SCHEMA
|
- SCHEMA
|
||||||
- INPUT
|
- INPUT
|
||||||
- OUTPUT
|
- OUTPUT
|
||||||
@ -149,7 +149,7 @@ Arithmetic on [Baby Jubjub elliptic curve](https://github.com/barryWhiteHat/baby
|
|||||||
|
|
||||||
- `BinSum(n, ops)`
|
- `BinSum(n, ops)`
|
||||||
|
|
||||||
- DESCRIPTION
|
- DESCRIPTION
|
||||||
- SCHEMA
|
- SCHEMA
|
||||||
- INPUT
|
- INPUT
|
||||||
- OUTPUT
|
- OUTPUT
|
||||||
@ -169,7 +169,7 @@ Arithmetic on [Baby Jubjub elliptic curve](https://github.com/barryWhiteHat/baby
|
|||||||
|
|
||||||
- `Num2Bits_strict()`
|
- `Num2Bits_strict()`
|
||||||
|
|
||||||
- DESCRIPTION
|
- DESCRIPTION
|
||||||
- SCHEMA
|
- SCHEMA
|
||||||
- INPUT
|
- INPUT
|
||||||
- OUTPUT
|
- OUTPUT
|
||||||
@ -259,7 +259,7 @@ Arithmetic on [Baby Jubjub elliptic curve](https://github.com/barryWhiteHat/baby
|
|||||||
- BENCHMARKS
|
- BENCHMARKS
|
||||||
- EXAMPLE
|
- EXAMPLE
|
||||||
|
|
||||||
### compconstant
|
### compconstant
|
||||||
|
|
||||||
- `CompConstant(ct)`
|
- `CompConstant(ct)`
|
||||||
|
|
||||||
@ -512,7 +512,7 @@ Implementation of MiMC-7 hash in Fp being... (link to description of the hash)
|
|||||||
|
|
||||||
### mimcsponge
|
### mimcsponge
|
||||||
|
|
||||||
- `MiMCSponge(nInputs, nOutputs)`
|
- `MiMCSponge(nInputs, nRounds, nOutputs)`
|
||||||
|
|
||||||
- DESCRIPTION
|
- DESCRIPTION
|
||||||
- SCHEMA
|
- SCHEMA
|
||||||
@ -688,7 +688,7 @@ Implementation of MiMC-7 hash in Fp being... (link to description of the hash)
|
|||||||
|
|
||||||
### pedersen_old
|
### pedersen_old
|
||||||
|
|
||||||
Old version of the Pedersen hash (do not use any
|
Old version of the Pedersen hash (do not use any
|
||||||
more?).
|
more?).
|
||||||
|
|
||||||
### pedersen
|
### pedersen
|
||||||
@ -720,7 +720,7 @@ more?).
|
|||||||
- BENCHMARKS
|
- BENCHMARKS
|
||||||
- EXAMPLE
|
- EXAMPLE
|
||||||
|
|
||||||
### pointbits
|
### pointbits
|
||||||
|
|
||||||
- `sqrt(n)`
|
- `sqrt(n)`
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ include "compconstant.circom";
|
|||||||
|
|
||||||
|
|
||||||
template AliasCheck() {
|
template AliasCheck() {
|
||||||
|
|
||||||
signal input in[254];
|
signal input in[254];
|
||||||
|
|
||||||
component compConstant = CompConstant(-1);
|
component compConstant = CompConstant(-1);
|
||||||
@ -29,15 +30,3 @@ template AliasCheck() {
|
|||||||
|
|
||||||
compConstant.out === 0;
|
compConstant.out === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template AliasCheckBabyJub() {
|
|
||||||
signal input in[251];
|
|
||||||
signal input enabled;
|
|
||||||
|
|
||||||
component compConstant = CompConstant(2736030358979909402780800718157159386076813972158567259200215660948447373040);
|
|
||||||
|
|
||||||
for (var i=0; i<251; i++) in[i] ==> compConstant.in[i];
|
|
||||||
for (var i=0; i<3; i++) 0 ==> compConstant.in[251+i];
|
|
||||||
|
|
||||||
compConstant.out*enabled === 0;
|
|
||||||
}
|
|
||||||
|
@ -81,13 +81,13 @@ template BabyCheck() {
|
|||||||
a*x2 + y2 === 1 + d*x2*y2;
|
a*x2 + y2 === 1 + d*x2*y2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extracts the public key from private key, as mentioned in https://tools.ietf.org/html/rfc8032
|
// Extracts the public key from private key
|
||||||
template BabyPbk() {
|
template BabyPbk() {
|
||||||
signal private input in;
|
signal private input in;
|
||||||
signal output Ax;
|
signal output Ax;
|
||||||
signal output Ay;
|
signal output Ay;
|
||||||
|
|
||||||
var BASE8 = [
|
var BASE8[2] = [
|
||||||
5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||||
16950150798460657717958625567821834550301663161624707787222815936182638968203
|
16950150798460657717958625567821834550301663161624707787222815936182638968203
|
||||||
];
|
];
|
||||||
|
@ -48,12 +48,14 @@ template BinSub(n) {
|
|||||||
var lin = 2**n;
|
var lin = 2**n;
|
||||||
var lout = 0;
|
var lout = 0;
|
||||||
|
|
||||||
for (var i=0; i<n; i++) {
|
var i;
|
||||||
|
|
||||||
|
for (i=0; i<n; i++) {
|
||||||
lin = lin + in[0][i]*(2**i);
|
lin = lin + in[0][i]*(2**i);
|
||||||
lin = lin - in[1][i]*(2**i);
|
lin = lin - in[1][i]*(2**i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i=0; i<n; i++) {
|
for (i=0; i<n; i++) {
|
||||||
out[i] <-- (lin >> i) & 1;
|
out[i] <-- (lin >> i) & 1;
|
||||||
|
|
||||||
// Ensure out is binary
|
// Ensure out is binary
|
||||||
|
@ -50,7 +50,6 @@ To waranty binary outputs:
|
|||||||
This function calculates the number of extra bits in the output to do the full sum.
|
This function calculates the number of extra bits in the output to do the full sum.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* a must be < Nq/2, where Nq is the number of elements in the scalar field */
|
|
||||||
function nbits(a) {
|
function nbits(a) {
|
||||||
var n = 1;
|
var n = 1;
|
||||||
var r = 0;
|
var r = 0;
|
||||||
@ -62,7 +61,6 @@ function nbits(a) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* n must be such that (2**(n+1) -2) < Nq/ops, where Nq is the number of bits in the scalar field */
|
|
||||||
template BinSum(n, ops) {
|
template BinSum(n, ops) {
|
||||||
var nout = nbits((2**n -1)*ops);
|
var nout = nbits((2**n -1)*ops);
|
||||||
signal input in[ops][n];
|
signal input in[ops][n];
|
||||||
@ -74,19 +72,26 @@ template BinSum(n, ops) {
|
|||||||
var k;
|
var k;
|
||||||
var j;
|
var j;
|
||||||
|
|
||||||
|
var e2;
|
||||||
|
|
||||||
|
e2 = 1;
|
||||||
for (k=0; k<n; k++) {
|
for (k=0; k<n; k++) {
|
||||||
for (j=0; j<ops; j++) {
|
for (j=0; j<ops; j++) {
|
||||||
lin += in[j][k] * 2**k;
|
lin += in[j][k] * e2;
|
||||||
}
|
}
|
||||||
|
e2 = e2 + e2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
e2 = 1;
|
||||||
for (k=0; k<nout; k++) {
|
for (k=0; k<nout; k++) {
|
||||||
out[k] <-- (lin >> k) & 1;
|
out[k] <-- (lin >> k) & 1;
|
||||||
|
|
||||||
// Ensure out is binary
|
// Ensure out is binary
|
||||||
out[k] * (out[k] - 1) === 0;
|
out[k] * (out[k] - 1) === 0;
|
||||||
|
|
||||||
lout += out[k] * 2**k;
|
lout += out[k] * e2;
|
||||||
|
|
||||||
|
e2 = e2+e2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the sum;
|
// Ensure the sum;
|
||||||
|
@ -21,16 +21,17 @@ include "comparators.circom";
|
|||||||
include "aliascheck.circom";
|
include "aliascheck.circom";
|
||||||
|
|
||||||
|
|
||||||
/* This doesn't check aliasing, so for n > 253 there are multiple bit strings for each number */
|
|
||||||
template Num2Bits(n) {
|
template Num2Bits(n) {
|
||||||
signal input in;
|
signal input in;
|
||||||
signal output out[n];
|
signal output out[n];
|
||||||
var lc1=0;
|
var lc1=0;
|
||||||
|
|
||||||
|
var e2=1;
|
||||||
for (var i = 0; i<n; i++) {
|
for (var i = 0; i<n; i++) {
|
||||||
out[i] <-- (in >> i) & 1;
|
out[i] <-- (in >> i) & 1;
|
||||||
out[i] * (out[i] -1 ) === 0;
|
out[i] * (out[i] -1 ) === 0;
|
||||||
lc1 += out[i] * 2**i;
|
lc1 += out[i] * e2;
|
||||||
|
e2 = e2+e2;
|
||||||
}
|
}
|
||||||
|
|
||||||
lc1 === in;
|
lc1 === in;
|
||||||
@ -55,8 +56,10 @@ template Bits2Num(n) {
|
|||||||
signal output out;
|
signal output out;
|
||||||
var lc1=0;
|
var lc1=0;
|
||||||
|
|
||||||
|
var e2 = 1;
|
||||||
for (var i = 0; i<n; i++) {
|
for (var i = 0; i<n; i++) {
|
||||||
lc1 += in[i] * 2**i;
|
lc1 += in[i] * e2;
|
||||||
|
e2 = e2 + e2;
|
||||||
}
|
}
|
||||||
|
|
||||||
lc1 ==> out;
|
lc1 ==> out;
|
||||||
@ -77,7 +80,6 @@ template Bits2Num_strict() {
|
|||||||
b2n.out ==> out;
|
b2n.out ==> out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* n must not exceed 253 */
|
|
||||||
template Num2BitsNeg(n) {
|
template Num2BitsNeg(n) {
|
||||||
signal input in;
|
signal input in;
|
||||||
signal output out[n];
|
signal output out[n];
|
||||||
|
@ -86,10 +86,11 @@ template LessThan(n) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
template LessThan(n) {
|
template LessThan(n) {
|
||||||
|
assert(n <= 252);
|
||||||
signal input in[2];
|
signal input in[2];
|
||||||
signal output out;
|
signal output out;
|
||||||
|
|
||||||
component n2b = Num2Bits(n*2+1);
|
component n2b = Num2Bits(n+1);
|
||||||
|
|
||||||
n2b.in <== in[0]+ (1<<n) - in[1];
|
n2b.in <== in[0]+ (1<<n) - in[1];
|
||||||
|
|
||||||
|
@ -46,12 +46,11 @@ template CompConstant(ct) {
|
|||||||
slsb = in[i*2];
|
slsb = in[i*2];
|
||||||
smsb = in[i*2+1];
|
smsb = in[i*2+1];
|
||||||
|
|
||||||
|
if ((cmsb==0)&&(clsb==0)) {
|
||||||
if ((cmsb==0)&(clsb==0)) {
|
|
||||||
parts[i] <== -b*smsb*slsb + b*smsb + b*slsb;
|
parts[i] <== -b*smsb*slsb + b*smsb + b*slsb;
|
||||||
} else if ((cmsb==0)&(clsb==1)) {
|
} else if ((cmsb==0)&&(clsb==1)) {
|
||||||
parts[i] <== a*smsb*slsb - a*slsb + b*smsb - a*smsb + a;
|
parts[i] <== a*smsb*slsb - a*slsb + b*smsb - a*smsb + a;
|
||||||
} else if ((cmsb==1)&(clsb==0)) {
|
} else if ((cmsb==1)&&(clsb==0)) {
|
||||||
parts[i] <== b*smsb*slsb - a*smsb + a;
|
parts[i] <== b*smsb*slsb - a*smsb + a;
|
||||||
} else {
|
} else {
|
||||||
parts[i] <== -a*smsb*slsb + a;
|
parts[i] <== -a*smsb*slsb + a;
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
include "aliascheck.circom";
|
include "compconstant.circom";
|
||||||
include "pointbits.circom";
|
include "pointbits.circom";
|
||||||
include "pedersen.circom";
|
include "pedersen.circom";
|
||||||
include "escalarmulany.circom";
|
include "escalarmulany.circom";
|
||||||
@ -40,15 +40,12 @@ template EdDSAVerifier(n) {
|
|||||||
|
|
||||||
// Ensure S<Subgroup Order
|
// Ensure S<Subgroup Order
|
||||||
|
|
||||||
component aliasCheck = AliasCheckBabyJub();
|
component compConstant = CompConstant(2736030358979909402780800718157159386076813972158567259200215660948447373040);
|
||||||
aliasCheck.enabled <== 1;
|
|
||||||
|
|
||||||
for (i=0; i<251; i++) {
|
for (i=0; i<254; i++) {
|
||||||
S[i] ==> aliasCheck.in[i];
|
S[i] ==> compConstant.in[i];
|
||||||
}
|
}
|
||||||
S[251] === 0;
|
compConstant.out === 0;
|
||||||
S[252] === 0;
|
|
||||||
S[253] === 0;
|
|
||||||
S[254] === 0;
|
S[254] === 0;
|
||||||
S[255] === 0;
|
S[255] === 0;
|
||||||
|
|
||||||
@ -125,7 +122,7 @@ template EdDSAVerifier(n) {
|
|||||||
|
|
||||||
// Calculate left side of equation left = S*B8
|
// Calculate left side of equation left = S*B8
|
||||||
|
|
||||||
var BASE8 = [
|
var BASE8[2] = [
|
||||||
5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||||
16950150798460657717958625567821834550301663161624707787222815936182638968203
|
16950150798460657717958625567821834550301663161624707787222815936182638968203
|
||||||
];
|
];
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
include "aliascheck.circom";
|
include "compconstant.circom";
|
||||||
include "pointbits.circom";
|
include "pointbits.circom";
|
||||||
include "mimc.circom";
|
include "mimc.circom";
|
||||||
include "bitify.circom";
|
include "bitify.circom";
|
||||||
@ -39,15 +39,16 @@ template EdDSAMiMCVerifier() {
|
|||||||
|
|
||||||
// Ensure S<Subgroup Order
|
// Ensure S<Subgroup Order
|
||||||
|
|
||||||
component snum2bits = Num2Bits(251);
|
component snum2bits = Num2Bits(253);
|
||||||
snum2bits.in <== S;
|
snum2bits.in <== S;
|
||||||
|
|
||||||
component aliasCheck = AliasCheckBabyJub();
|
component compConstant = CompConstant(2736030358979909402780800718157159386076813972158567259200215660948447373040);
|
||||||
aliasCheck.enabled <== 1;
|
|
||||||
|
|
||||||
for (i=0; i<251; i++) {
|
for (i=0; i<253; i++) {
|
||||||
snum2bits.out[i] ==> aliasCheck.in[i];
|
snum2bits.out[i] ==> compConstant.in[i];
|
||||||
}
|
}
|
||||||
|
compConstant.in[253] <== 0;
|
||||||
|
compConstant.out === 0;
|
||||||
|
|
||||||
// Calculate the h = H(R,A, msg)
|
// Calculate the h = H(R,A, msg)
|
||||||
|
|
||||||
@ -99,12 +100,12 @@ template EdDSAMiMCVerifier() {
|
|||||||
|
|
||||||
// Calculate left side of equation left = S*B8
|
// Calculate left side of equation left = S*B8
|
||||||
|
|
||||||
var BASE8 = [
|
var BASE8[2] = [
|
||||||
5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||||
16950150798460657717958625567821834550301663161624707787222815936182638968203
|
16950150798460657717958625567821834550301663161624707787222815936182638968203
|
||||||
];
|
];
|
||||||
component mulFix = EscalarMulFix(251, BASE8);
|
component mulFix = EscalarMulFix(253, BASE8);
|
||||||
for (i=0; i<251; i++) {
|
for (i=0; i<253; i++) {
|
||||||
mulFix.e[i] <== snum2bits.out[i];
|
mulFix.e[i] <== snum2bits.out[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
include "aliascheck.circom";
|
include "compconstant.circom";
|
||||||
include "pointbits.circom";
|
include "pointbits.circom";
|
||||||
include "mimcsponge.circom";
|
include "mimcsponge.circom";
|
||||||
include "bitify.circom";
|
include "bitify.circom";
|
||||||
@ -39,19 +39,20 @@ template EdDSAMiMCSpongeVerifier() {
|
|||||||
|
|
||||||
// Ensure S<Subgroup Order
|
// Ensure S<Subgroup Order
|
||||||
|
|
||||||
component snum2bits = Num2Bits(251);
|
component snum2bits = Num2Bits(253);
|
||||||
snum2bits.in <== S;
|
snum2bits.in <== S;
|
||||||
|
|
||||||
component aliasCheck = AliasCheckBabyJub();
|
component compConstant = CompConstant(2736030358979909402780800718157159386076813972158567259200215660948447373040);
|
||||||
aliasCheck.enabled <== 1;
|
|
||||||
|
|
||||||
for (i=0; i<251; i++) {
|
for (i=0; i<253; i++) {
|
||||||
snum2bits.out[i] ==> aliasCheck.in[i];
|
snum2bits.out[i] ==> compConstant.in[i];
|
||||||
}
|
}
|
||||||
|
compConstant.in[253] <== 0;
|
||||||
|
compConstant.out === 0;
|
||||||
|
|
||||||
// Calculate the h = H(R,A, msg)
|
// Calculate the h = H(R,A, msg)
|
||||||
|
|
||||||
component hash = MiMCSponge(5, 1);
|
component hash = MiMCSponge(5, 220, 1);
|
||||||
hash.ins[0] <== R8x;
|
hash.ins[0] <== R8x;
|
||||||
hash.ins[1] <== R8y;
|
hash.ins[1] <== R8y;
|
||||||
hash.ins[2] <== Ax;
|
hash.ins[2] <== Ax;
|
||||||
@ -99,12 +100,12 @@ template EdDSAMiMCSpongeVerifier() {
|
|||||||
|
|
||||||
// Calculate left side of equation left = S*B8
|
// Calculate left side of equation left = S*B8
|
||||||
|
|
||||||
var BASE8 = [
|
var BASE8[2] = [
|
||||||
5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||||
16950150798460657717958625567821834550301663161624707787222815936182638968203
|
16950150798460657717958625567821834550301663161624707787222815936182638968203
|
||||||
];
|
];
|
||||||
component mulFix = EscalarMulFix(251, BASE8);
|
component mulFix = EscalarMulFix(253, BASE8);
|
||||||
for (i=0; i<251; i++) {
|
for (i=0; i<253; i++) {
|
||||||
mulFix.e[i] <== snum2bits.out[i];
|
mulFix.e[i] <== snum2bits.out[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,15 +38,16 @@ template EdDSAPoseidonVerifier() {
|
|||||||
|
|
||||||
// Ensure S<Subgroup Order
|
// Ensure S<Subgroup Order
|
||||||
|
|
||||||
component snum2bits = Num2Bits(251);
|
component snum2bits = Num2Bits(253);
|
||||||
snum2bits.in <== S;
|
snum2bits.in <== S;
|
||||||
|
|
||||||
component aliasCheck = AliasCheckBabyJub();
|
component compConstant = CompConstant(2736030358979909402780800718157159386076813972158567259200215660948447373040);
|
||||||
aliasCheck.enabled <== enabled;
|
|
||||||
|
|
||||||
for (i=0; i<251; i++) {
|
for (i=0; i<253; i++) {
|
||||||
snum2bits.out[i] ==> aliasCheck.in[i];
|
snum2bits.out[i] ==> compConstant.in[i];
|
||||||
}
|
}
|
||||||
|
compConstant.in[253] <== 0;
|
||||||
|
compConstant.out*enabled === 0;
|
||||||
|
|
||||||
// Calculate the h = H(R,A, msg)
|
// Calculate the h = H(R,A, msg)
|
||||||
|
|
||||||
@ -98,12 +99,12 @@ template EdDSAPoseidonVerifier() {
|
|||||||
|
|
||||||
// Calculate left side of equation left = S*B8
|
// Calculate left side of equation left = S*B8
|
||||||
|
|
||||||
var BASE8 = [
|
var BASE8[2] = [
|
||||||
5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||||
16950150798460657717958625567821834550301663161624707787222815936182638968203
|
16950150798460657717958625567821834550301663161624707787222815936182638968203
|
||||||
];
|
];
|
||||||
component mulFix = EscalarMulFix(251, BASE8);
|
component mulFix = EscalarMulFix(253, BASE8);
|
||||||
for (i=0; i<251; i++) {
|
for (i=0; i<253; i++) {
|
||||||
mulFix.e[i] <== snum2bits.out[i];
|
mulFix.e[i] <== snum2bits.out[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ template EscalarMulWindow(base, k) {
|
|||||||
signal input sel[4];
|
signal input sel[4];
|
||||||
signal output out[2];
|
signal output out[2];
|
||||||
|
|
||||||
var table;
|
var table[16][2];
|
||||||
component mux;
|
component mux;
|
||||||
component adder;
|
component adder;
|
||||||
|
|
||||||
|
@ -44,7 +44,6 @@ include "babyjub.circom";
|
|||||||
A good way to see it is that the accumulator input of the adder >= 2^247*B and the other input
|
A good way to see it is that the accumulator input of the adder >= 2^247*B and the other input
|
||||||
is the output of the windows that it's going to be <= 2^246*B
|
is the output of the windows that it's going to be <= 2^246*B
|
||||||
*/
|
*/
|
||||||
/* base must not be the neutral element nor points of small order */
|
|
||||||
template WindowMulFix() {
|
template WindowMulFix() {
|
||||||
signal input in[3];
|
signal input in[3];
|
||||||
signal input base[2];
|
signal input base[2];
|
||||||
@ -134,12 +133,11 @@ template WindowMulFix() {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
This component does a multiplication of a escalar times a fix base
|
This component does a multiplication of a escalar times a fix base
|
||||||
nWindows must not exceed 82
|
|
||||||
Signals:
|
Signals:
|
||||||
e: The scalar in bits
|
e: The scalar in bits
|
||||||
base: the base point in edwards format
|
base: the base point in edwards format
|
||||||
out: The result
|
out: The result
|
||||||
dbl: Point in Montgomery to be linked to the next segment.
|
dbl: Point in Edwards to be linked to the next segment.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template SegmentMulFix(nWindows) {
|
template SegmentMulFix(nWindows) {
|
||||||
@ -178,6 +176,9 @@ template SegmentMulFix(nWindows) {
|
|||||||
cadders[i].in1[0] <== cadders[i-1].out[0];
|
cadders[i].in1[0] <== cadders[i-1].out[0];
|
||||||
cadders[i].in1[1] <== cadders[i-1].out[1];
|
cadders[i].in1[1] <== cadders[i-1].out[1];
|
||||||
}
|
}
|
||||||
|
for (j=0; j<3; j++) {
|
||||||
|
windows[i].in[j] <== e[3*i+j];
|
||||||
|
}
|
||||||
if (i<nWindows-1) {
|
if (i<nWindows-1) {
|
||||||
cadders[i].in2[0] <== windows[i].out8[0];
|
cadders[i].in2[0] <== windows[i].out8[0];
|
||||||
cadders[i].in2[1] <== windows[i].out8[1];
|
cadders[i].in2[1] <== windows[i].out8[1];
|
||||||
@ -187,9 +188,6 @@ template SegmentMulFix(nWindows) {
|
|||||||
cadders[i].in2[0] <== dblLast.out[0];
|
cadders[i].in2[0] <== dblLast.out[0];
|
||||||
cadders[i].in2[1] <== dblLast.out[1];
|
cadders[i].in2[1] <== dblLast.out[1];
|
||||||
}
|
}
|
||||||
for (j=0; j<3; j++) {
|
|
||||||
windows[i].in[j] <== e[3*i+j];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i<nWindows; i++) {
|
for (i=0; i<nWindows; i++) {
|
||||||
@ -238,7 +236,7 @@ template EscalarMulFix(n, BASE) {
|
|||||||
signal output out[2]; // Point (Twisted format)
|
signal output out[2]; // Point (Twisted format)
|
||||||
|
|
||||||
var nsegments = (n-1)\246 +1; // 249 probably would work. But I'm not sure and for security I keep 246
|
var nsegments = (n-1)\246 +1; // 249 probably would work. But I'm not sure and for security I keep 246
|
||||||
var nlastsegment = n - (nsegments-1)*246;
|
var nlastsegment = n - (nsegments-1)*249;
|
||||||
|
|
||||||
component segments[nsegments];
|
component segments[nsegments];
|
||||||
|
|
||||||
@ -252,13 +250,13 @@ template EscalarMulFix(n, BASE) {
|
|||||||
|
|
||||||
for (s=0; s<nsegments; s++) {
|
for (s=0; s<nsegments; s++) {
|
||||||
|
|
||||||
nseg = (s < nsegments-1) ? 246 : nlastsegment;
|
nseg = (s < nsegments-1) ? 249 : nlastsegment;
|
||||||
nWindows = ((nseg - 1)\3)+1;
|
nWindows = ((nseg - 1)\3)+1;
|
||||||
|
|
||||||
segments[s] = SegmentMulFix(nWindows);
|
segments[s] = SegmentMulFix(nWindows);
|
||||||
|
|
||||||
for (i=0; i<nseg; i++) {
|
for (i=0; i<nseg; i++) {
|
||||||
segments[s].e[i] <== e[s*246+i];
|
segments[s].e[i] <== e[s*249+i];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = nseg; i<nWindows*3; i++) {
|
for (i = nseg; i<nWindows*3; i++) {
|
||||||
|
@ -33,7 +33,7 @@ function EscalarMulW4Table(base, k) {
|
|||||||
var i;
|
var i;
|
||||||
var p[2];
|
var p[2];
|
||||||
|
|
||||||
var dbl = base;
|
var dbl[2] = base;
|
||||||
|
|
||||||
for (i=0; i<k*4; i++) {
|
for (i=0; i<k*4; i++) {
|
||||||
dbl = pointAdd(dbl[0], dbl[1], dbl[0], dbl[1]);
|
dbl = pointAdd(dbl[0], dbl[1], dbl[0], dbl[1]);
|
||||||
|
@ -67,6 +67,7 @@ template NOR() {
|
|||||||
template MultiAND(n) {
|
template MultiAND(n) {
|
||||||
signal input in[n];
|
signal input in[n];
|
||||||
signal output out;
|
signal output out;
|
||||||
|
var i;
|
||||||
if (n==1) {
|
if (n==1) {
|
||||||
out <== in[0];
|
out <== in[0];
|
||||||
} else if (n==2) {
|
} else if (n==2) {
|
||||||
@ -81,8 +82,8 @@ template MultiAND(n) {
|
|||||||
var n2 = n-n\2;
|
var n2 = n-n\2;
|
||||||
ands[0] = MultiAND(n1);
|
ands[0] = MultiAND(n1);
|
||||||
ands[1] = MultiAND(n2);
|
ands[1] = MultiAND(n2);
|
||||||
for (var i=0; i<n1; i++) ands[0].in[i] <== in[i];
|
for (i=0; i<n1; i++) ands[0].in[i] <== in[i];
|
||||||
for (var i=0; i<n2; i++) ands[1].in[i] <== in[n1+i];
|
for (i=0; i<n2; i++) ands[1].in[i] <== in[n1+i];
|
||||||
and2.a <== ands[0].out;
|
and2.a <== ands[0].out;
|
||||||
and2.b <== ands[1].out;
|
and2.b <== ands[1].out;
|
||||||
out <== and2.out;
|
out <== and2.out;
|
||||||
|
@ -22,7 +22,7 @@ template MiMC7(nrounds) {
|
|||||||
signal input k;
|
signal input k;
|
||||||
signal output out;
|
signal output out;
|
||||||
|
|
||||||
var c = [
|
var c[91] = [
|
||||||
0,
|
0,
|
||||||
20888961410941983456478427210666206549300505294776164667214940546594746570981,
|
20888961410941983456478427210666206549300505294776164667214940546594746570981,
|
||||||
15265126113435022738560151911929040668591755459209400716467504685752745317193,
|
15265126113435022738560151911929040668591755459209400716467504685752745317193,
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
// implements MiMC-2n/n as hash using a sponge construction.
|
// implements MiMC-2n/n as hash using a sponge construction.
|
||||||
// log_5(21888242871839275222246405745257275088548364400416034343698204186575808495617) ~= 110
|
// log_5(21888242871839275222246405745257275088548364400416034343698204186575808495617) ~= 110
|
||||||
// => nRounds should be 220
|
// => nRounds should be 220
|
||||||
template MiMCSponge(nInputs, nOutputs) {
|
template MiMCSponge(nInputs, nRounds, nOutputs) {
|
||||||
signal input ins[nInputs];
|
signal input ins[nInputs];
|
||||||
signal input k;
|
signal input k;
|
||||||
signal output outs[nOutputs];
|
signal output outs[nOutputs];
|
||||||
|
|
||||||
var nRounds = 220;
|
var i;
|
||||||
|
|
||||||
// S = R||C
|
// S = R||C
|
||||||
component S[nInputs + nOutputs - 1];
|
component S[nInputs + nOutputs - 1];
|
||||||
|
|
||||||
for (var i = 0; i < nInputs; i++) {
|
for (i = 0; i < nInputs; i++) {
|
||||||
S[i] = MiMCFeistel(nRounds);
|
S[i] = MiMCFeistel(nRounds);
|
||||||
S[i].k <== k;
|
S[i].k <== k;
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
@ -25,7 +25,7 @@ template MiMCSponge(nInputs, nOutputs) {
|
|||||||
|
|
||||||
outs[0] <== S[nInputs - 1].xL_out;
|
outs[0] <== S[nInputs - 1].xL_out;
|
||||||
|
|
||||||
for (var i = 0; i < nOutputs - 1; i++) {
|
for (i = 0; i < nOutputs - 1; i++) {
|
||||||
S[nInputs + i] = MiMCFeistel(nRounds);
|
S[nInputs + i] = MiMCFeistel(nRounds);
|
||||||
S[nInputs + i].k <== k;
|
S[nInputs + i].k <== k;
|
||||||
S[nInputs + i].xL_in <== S[nInputs + i - 1].xL_out;
|
S[nInputs + i].xL_in <== S[nInputs + i - 1].xL_out;
|
||||||
@ -42,7 +42,7 @@ template MiMCFeistel(nrounds) {
|
|||||||
signal output xR_out;
|
signal output xR_out;
|
||||||
|
|
||||||
// doesn't contain the first and last round constants, which are always zero
|
// doesn't contain the first and last round constants, which are always zero
|
||||||
var c_partial = [
|
var c_partial[218] = [
|
||||||
7120861356467848435263064379192047478074060781135320967663101236819528304084,
|
7120861356467848435263064379192047478074060781135320967663101236819528304084,
|
||||||
5024705281721889198577876690145313457398658950011302225525409148828000436681,
|
5024705281721889198577876690145313457398658950011302225525409148828000436681,
|
||||||
17980351014018068290387269214713820287804403312720763401943303895585469787384,
|
17980351014018068290387269214713820287804403312720763401943303895585469787384,
|
||||||
|
@ -85,7 +85,6 @@ template Montgomery2Edwards() {
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* in1 must be != in2 */
|
|
||||||
template MontgomeryAdd() {
|
template MontgomeryAdd() {
|
||||||
signal input in1[2];
|
signal input in1[2];
|
||||||
signal input in2[2];
|
signal input in2[2];
|
||||||
|
@ -108,7 +108,6 @@ template Window4() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* nWindows must not exceed 50 */
|
|
||||||
template Segment(nWindows) {
|
template Segment(nWindows) {
|
||||||
signal input in[nWindows*4];
|
signal input in[nWindows*4];
|
||||||
signal input base[2];
|
signal input base[2];
|
||||||
@ -129,6 +128,9 @@ template Segment(nWindows) {
|
|||||||
component adders[nWindows-1];
|
component adders[nWindows-1];
|
||||||
for (i=0; i<nWindows; i++) {
|
for (i=0; i<nWindows; i++) {
|
||||||
windows[i] = Window4();
|
windows[i] = Window4();
|
||||||
|
for (j=0; j<4; j++) {
|
||||||
|
windows[i].in[j] <== in[4*i+j];
|
||||||
|
}
|
||||||
if (i==0) {
|
if (i==0) {
|
||||||
windows[i].base[0] <== e2m.out[0];
|
windows[i].base[0] <== e2m.out[0];
|
||||||
windows[i].base[1] <== e2m.out[1];
|
windows[i].base[1] <== e2m.out[1];
|
||||||
@ -154,9 +156,6 @@ template Segment(nWindows) {
|
|||||||
adders[i-1].in2[0] <== windows[i].out[0];
|
adders[i-1].in2[0] <== windows[i].out[0];
|
||||||
adders[i-1].in2[1] <== windows[i].out[1];
|
adders[i-1].in2[1] <== windows[i].out[1];
|
||||||
}
|
}
|
||||||
for (j=0; j<4; j++) {
|
|
||||||
windows[i].in[j] <== in[4*i+j];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
component m2e = Montgomery2Edwards();
|
component m2e = Montgomery2Edwards();
|
||||||
@ -177,7 +176,7 @@ template Pedersen(n) {
|
|||||||
signal input in[n];
|
signal input in[n];
|
||||||
signal output out[2];
|
signal output out[2];
|
||||||
|
|
||||||
var BASE = [
|
var BASE[10][2] = [
|
||||||
[10457101036533406547632367118273992217979173478358440826365724437999023779287,19824078218392094440610104313265183977899662750282163392862422243483260492317],
|
[10457101036533406547632367118273992217979173478358440826365724437999023779287,19824078218392094440610104313265183977899662750282163392862422243483260492317],
|
||||||
[2671756056509184035029146175565761955751135805354291559563293617232983272177,2663205510731142763556352975002641716101654201788071096152948830924149045094],
|
[2671756056509184035029146175565761955751135805354291559563293617232983272177,2663205510731142763556352975002641716101654201788071096152948830924149045094],
|
||||||
[5802099305472655231388284418920769829666717045250560929368476121199858275951,5980429700218124965372158798884772646841287887664001482443826541541529227896],
|
[5802099305472655231388284418920769829666717045250560929368476121199858275951,5980429700218124965372158798884772646841287887664001482443826541541529227896],
|
||||||
@ -188,7 +187,8 @@ template Pedersen(n) {
|
|||||||
[6814338563135591367010655964669793483652536871717891893032616415581401894627,13660303521961041205824633772157003587453809761793065294055279768121314853695],
|
[6814338563135591367010655964669793483652536871717891893032616415581401894627,13660303521961041205824633772157003587453809761793065294055279768121314853695],
|
||||||
[3571615583211663069428808372184817973703476260057504149923239576077102575715,11981351099832644138306422070127357074117642951423551606012551622164230222506],
|
[3571615583211663069428808372184817973703476260057504149923239576077102575715,11981351099832644138306422070127357074117642951423551606012551622164230222506],
|
||||||
[18597552580465440374022635246985743886550544261632147935254624835147509493269,6753322320275422086923032033899357299485124665258735666995435957890214041481]
|
[18597552580465440374022635246985743886550544261632147935254624835147509493269,6753322320275422086923032033899357299485124665258735666995435957890214041481]
|
||||||
]
|
|
||||||
|
];
|
||||||
|
|
||||||
var nSegments = ((n-1)\200)+1;
|
var nSegments = ((n-1)\200)+1;
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ template Pedersen(n) {
|
|||||||
|
|
||||||
component escalarMuls[nexps];
|
component escalarMuls[nexps];
|
||||||
|
|
||||||
var PBASE = [
|
var PBASE[10][2] = [
|
||||||
[10457101036533406547632367118273992217979173478358440826365724437999023779287,19824078218392094440610104313265183977899662750282163392862422243483260492317],
|
[10457101036533406547632367118273992217979173478358440826365724437999023779287,19824078218392094440610104313265183977899662750282163392862422243483260492317],
|
||||||
[2671756056509184035029146175565761955751135805354291559563293617232983272177,2663205510731142763556352975002641716101654201788071096152948830924149045094],
|
[2671756056509184035029146175565761955751135805354291559563293617232983272177,2663205510731142763556352975002641716101654201788071096152948830924149045094],
|
||||||
[5802099305472655231388284418920769829666717045250560929368476121199858275951,5980429700218124965372158798884772646841287887664001482443826541541529227896],
|
[5802099305472655231388284418920769829666717045250560929368476121199858275951,5980429700218124965372158798884772646841287887664001482443826541541529227896],
|
||||||
@ -39,6 +39,7 @@ template Pedersen(n) {
|
|||||||
[6814338563135591367010655964669793483652536871717891893032616415581401894627,13660303521961041205824633772157003587453809761793065294055279768121314853695],
|
[6814338563135591367010655964669793483652536871717891893032616415581401894627,13660303521961041205824633772157003587453809761793065294055279768121314853695],
|
||||||
[3571615583211663069428808372184817973703476260057504149923239576077102575715,11981351099832644138306422070127357074117642951423551606012551622164230222506],
|
[3571615583211663069428808372184817973703476260057504149923239576077102575715,11981351099832644138306422070127357074117642951423551606012551622164230222506],
|
||||||
[18597552580465440374022635246985743886550544261632147935254624835147509493269,6753322320275422086923032033899357299485124665258735666995435957890214041481]
|
[18597552580465440374022635246985743886550544261632147935254624835147509493269,6753322320275422086923032033899357299485124665258735666995435957890214041481]
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
var i;
|
var i;
|
||||||
|
@ -61,7 +61,7 @@ function sqrt(n) {
|
|||||||
r = r*b;
|
r = r*b;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r > ((-1) >> 1)) {
|
if (r < 0 ) {
|
||||||
r = -r;
|
r = -r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,9 +40,9 @@ template Poseidon(nInputs) {
|
|||||||
signal input inputs[nInputs];
|
signal input inputs[nInputs];
|
||||||
signal output out;
|
signal output out;
|
||||||
|
|
||||||
// Using recommended parameters from whitepaper https://eprint.iacr.org/2019/458.pdf (table 2, table 8)
|
// Using recommended parameters from whitepaper https://eprint.iacr.org/2019/458.pdf (table 2, table 8)
|
||||||
// Generated by https://extgit.iaik.tugraz.at/krypto/hadeshash/-/blob/master/code/calc_round_numbers.py
|
// Generated by https://extgit.iaik.tugraz.at/krypto/hadeshash/-/blob/master/code/calc_round_numbers.py
|
||||||
// And rounded up to nearest integer that divides by t
|
// And rounded up to nearest integer that divides by t
|
||||||
var t = nInputs + 1;
|
var t = nInputs + 1;
|
||||||
var nRoundsF = 8;
|
var nRoundsF = 8;
|
||||||
var nRoundsP = 35;
|
var nRoundsP = 35;
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
template H(x) {
|
template H(x) {
|
||||||
signal output out[32];
|
signal output out[32];
|
||||||
var c = [0x6a09e667,
|
var c[8] = [0x6a09e667,
|
||||||
0xbb67ae85,
|
0xbb67ae85,
|
||||||
0x3c6ef372,
|
0x3c6ef372,
|
||||||
0xa54ff53a,
|
0xa54ff53a,
|
||||||
@ -35,7 +35,7 @@ template H(x) {
|
|||||||
|
|
||||||
template K(x) {
|
template K(x) {
|
||||||
signal output out[32];
|
signal output out[32];
|
||||||
var c = [
|
var c[64] = [
|
||||||
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||||
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||||
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||||
|
@ -22,6 +22,8 @@ include "t1.circom";
|
|||||||
include "t2.circom";
|
include "t2.circom";
|
||||||
include "../binsum.circom";
|
include "../binsum.circom";
|
||||||
include "sigmaplus.circom";
|
include "sigmaplus.circom";
|
||||||
|
include "sha256compression_function.circom";
|
||||||
|
|
||||||
|
|
||||||
template Sha256compression() {
|
template Sha256compression() {
|
||||||
signal input hin[256];
|
signal input hin[256];
|
||||||
@ -37,7 +39,11 @@ template Sha256compression() {
|
|||||||
signal h[65][32];
|
signal h[65][32];
|
||||||
signal w[64][32];
|
signal w[64][32];
|
||||||
|
|
||||||
|
|
||||||
|
var outCalc[256] = sha256compression(hin, inp);
|
||||||
|
|
||||||
var i;
|
var i;
|
||||||
|
for (i=0; i<256; i++) out[i] <-- outCalc[i];
|
||||||
|
|
||||||
component sigmaPlus[48];
|
component sigmaPlus[48];
|
||||||
for (i=0; i<48; i++) sigmaPlus[i] = SigmaPlus();
|
for (i=0; i<48; i++) sigmaPlus[i] = SigmaPlus();
|
||||||
@ -74,6 +80,9 @@ template Sha256compression() {
|
|||||||
sigmaPlus[t-16].in7[k] <== w[t-7][k];
|
sigmaPlus[t-16].in7[k] <== w[t-7][k];
|
||||||
sigmaPlus[t-16].in15[k] <== w[t-15][k];
|
sigmaPlus[t-16].in15[k] <== w[t-15][k];
|
||||||
sigmaPlus[t-16].in16[k] <== w[t-16][k];
|
sigmaPlus[t-16].in16[k] <== w[t-16][k];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (k=0; k<32; k++) {
|
||||||
w[t][k] <== sigmaPlus[t-16].out[k];
|
w[t][k] <== sigmaPlus[t-16].out[k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -144,13 +153,13 @@ template Sha256compression() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (k=0; k<32; k++) {
|
for (k=0; k<32; k++) {
|
||||||
out[31-k] <== fsum[0].out[k];
|
out[31-k] === fsum[0].out[k];
|
||||||
out[32+31-k] <== fsum[1].out[k];
|
out[32+31-k] === fsum[1].out[k];
|
||||||
out[64+31-k] <== fsum[2].out[k];
|
out[64+31-k] === fsum[2].out[k];
|
||||||
out[96+31-k] <== fsum[3].out[k];
|
out[96+31-k] === fsum[3].out[k];
|
||||||
out[128+31-k] <== fsum[4].out[k];
|
out[128+31-k] === fsum[4].out[k];
|
||||||
out[160+31-k] <== fsum[5].out[k];
|
out[160+31-k] === fsum[5].out[k];
|
||||||
out[192+31-k] <== fsum[6].out[k];
|
out[192+31-k] === fsum[6].out[k];
|
||||||
out[224+31-k] <== fsum[7].out[k];
|
out[224+31-k] === fsum[7].out[k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
112
circuits/sha256/sha256compression_function.circom
Normal file
112
circuits/sha256/sha256compression_function.circom
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
// signal input hin[256];
|
||||||
|
// signal input inp[512];
|
||||||
|
// signal output out[256];
|
||||||
|
|
||||||
|
|
||||||
|
function rrot(x, n) {
|
||||||
|
return ((x >> n) | (x << (32-n))) & 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
function bsigma0(x) {
|
||||||
|
return rrot(x,2) ^ rrot(x,13) ^ rrot(x,22);
|
||||||
|
}
|
||||||
|
|
||||||
|
function bsigma1(x) {
|
||||||
|
return rrot(x,6) ^ rrot(x,11) ^ rrot(x,25);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ssigma0(x) {
|
||||||
|
return rrot(x,7) ^ rrot(x,18) ^ (x >> 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ssigma1(x) {
|
||||||
|
return rrot(x,17) ^ rrot(x,19) ^ (x >> 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Maj(x, y, z) {
|
||||||
|
return (x&y) ^ (x&z) ^ (y&z);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Ch(x, y, z) {
|
||||||
|
return (x & y) ^ ((0xFFFFFFFF ^x) & z);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sha256K(i) {
|
||||||
|
var k[64] = [
|
||||||
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
||||||
|
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
||||||
|
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
||||||
|
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
|
||||||
|
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
|
||||||
|
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
||||||
|
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
||||||
|
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
||||||
|
];
|
||||||
|
return k[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
function sha256compression(hin, inp) {
|
||||||
|
var H[8];
|
||||||
|
var a;
|
||||||
|
var b;
|
||||||
|
var c;
|
||||||
|
var d;
|
||||||
|
var e;
|
||||||
|
var f;
|
||||||
|
var g;
|
||||||
|
var h;
|
||||||
|
var out[256];
|
||||||
|
for (var i=0; i<8; i++) {
|
||||||
|
H[i] = 0;
|
||||||
|
for (var j=0; j<32; j++) {
|
||||||
|
H[i] += hin[i*32+j] << j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a=H[0];
|
||||||
|
b=H[1];
|
||||||
|
c=H[2];
|
||||||
|
d=H[3];
|
||||||
|
e=H[4];
|
||||||
|
f=H[5];
|
||||||
|
g=H[6];
|
||||||
|
h=H[7];
|
||||||
|
var w[64];
|
||||||
|
var T1;
|
||||||
|
var T2;
|
||||||
|
for (var i=0; i<64; i++) {
|
||||||
|
if (i<16) {
|
||||||
|
w[i]=0;
|
||||||
|
for (var j=0; j<32; j++) {
|
||||||
|
w[i] += inp[i*32+31-j]<<j;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
w[i] = (ssigma1(w[i-2]) + w[i-7] + ssigma0(w[i-15]) + w[i-16]) & 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
T1 = (h + bsigma1(e) + Ch(e,f,g) + sha256K(i) + w[i]) & 0xFFFFFFFF;
|
||||||
|
T2 = (bsigma0(a) + Maj(a,b,c)) & 0xFFFFFFFF;
|
||||||
|
|
||||||
|
h=g;
|
||||||
|
g=f;
|
||||||
|
f=e;
|
||||||
|
e=(d+T1) & 0xFFFFFFFF;
|
||||||
|
d=c;
|
||||||
|
c=b;
|
||||||
|
b=a;
|
||||||
|
a=(T1+T2) & 0xFFFFFFFF;
|
||||||
|
|
||||||
|
}
|
||||||
|
H[0] = H[0] + a;
|
||||||
|
H[1] = H[1] + b;
|
||||||
|
H[2] = H[2] + c;
|
||||||
|
H[3] = H[3] + d;
|
||||||
|
H[4] = H[4] + e;
|
||||||
|
H[5] = H[5] + f;
|
||||||
|
H[6] = H[6] + g;
|
||||||
|
H[7] = H[7] + h;
|
||||||
|
for (var i=0; i<8; i++) {
|
||||||
|
for (var j=0; j<32; j++) {
|
||||||
|
out[i*32+31-j] = (H[i] >> j) & 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
@ -24,22 +24,26 @@ include "shift.circom";
|
|||||||
template SmallSigma(ra, rb, rc) {
|
template SmallSigma(ra, rb, rc) {
|
||||||
signal input in[32];
|
signal input in[32];
|
||||||
signal output out[32];
|
signal output out[32];
|
||||||
|
var k;
|
||||||
component xor3 = Xor3(32);
|
|
||||||
|
|
||||||
component rota = RotR(32, ra);
|
component rota = RotR(32, ra);
|
||||||
component rotb = RotR(32, rb);
|
component rotb = RotR(32, rb);
|
||||||
component shrc = ShR(32, rc);
|
component shrc = ShR(32, rc);
|
||||||
|
|
||||||
for (var k=0; k<32; k++) {
|
for (k=0; k<32; k++) {
|
||||||
rota.in[k] <== in[k];
|
rota.in[k] <== in[k];
|
||||||
rotb.in[k] <== in[k];
|
rotb.in[k] <== in[k];
|
||||||
shrc.in[k] <== in[k];
|
shrc.in[k] <== in[k];
|
||||||
|
}
|
||||||
|
|
||||||
|
component xor3 = Xor3(32);
|
||||||
|
for (k=0; k<32; k++) {
|
||||||
xor3.a[k] <== rota.out[k];
|
xor3.a[k] <== rota.out[k];
|
||||||
xor3.b[k] <== rotb.out[k];
|
xor3.b[k] <== rotb.out[k];
|
||||||
xor3.c[k] <== shrc.out[k];
|
xor3.c[k] <== shrc.out[k];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (k=0; k<32; k++) {
|
||||||
out[k] <== xor3.out[k];
|
out[k] <== xor3.out[k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -47,22 +51,26 @@ template SmallSigma(ra, rb, rc) {
|
|||||||
template BigSigma(ra, rb, rc) {
|
template BigSigma(ra, rb, rc) {
|
||||||
signal input in[32];
|
signal input in[32];
|
||||||
signal output out[32];
|
signal output out[32];
|
||||||
|
var k;
|
||||||
component xor3 = Xor3(32);
|
|
||||||
|
|
||||||
component rota = RotR(32, ra);
|
component rota = RotR(32, ra);
|
||||||
component rotb = RotR(32, rb);
|
component rotb = RotR(32, rb);
|
||||||
component rotc = RotR(32, rc);
|
component rotc = RotR(32, rc);
|
||||||
|
for (k=0; k<32; k++) {
|
||||||
for (var k=0; k<32; k++) {
|
|
||||||
rota.in[k] <== in[k];
|
rota.in[k] <== in[k];
|
||||||
rotb.in[k] <== in[k];
|
rotb.in[k] <== in[k];
|
||||||
rotc.in[k] <== in[k];
|
rotc.in[k] <== in[k];
|
||||||
|
}
|
||||||
|
|
||||||
|
component xor3 = Xor3(32);
|
||||||
|
|
||||||
|
for (k=0; k<32; k++) {
|
||||||
xor3.a[k] <== rota.out[k];
|
xor3.a[k] <== rota.out[k];
|
||||||
xor3.b[k] <== rotb.out[k];
|
xor3.b[k] <== rotb.out[k];
|
||||||
xor3.c[k] <== rotc.out[k];
|
xor3.c[k] <== rotc.out[k];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (k=0; k<32; k++) {
|
||||||
out[k] <== xor3.out[k];
|
out[k] <== xor3.out[k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,20 +26,24 @@ template SigmaPlus() {
|
|||||||
signal input in15[32];
|
signal input in15[32];
|
||||||
signal input in16[32];
|
signal input in16[32];
|
||||||
signal output out[32];
|
signal output out[32];
|
||||||
|
var k;
|
||||||
|
|
||||||
component sum = BinSum(32, 4);
|
|
||||||
component sigma1 = SmallSigma(17,19,10);
|
component sigma1 = SmallSigma(17,19,10);
|
||||||
component sigma0 = SmallSigma(7, 18, 3);
|
component sigma0 = SmallSigma(7, 18, 3);
|
||||||
|
for (k=0; k<32; k++) {
|
||||||
for (var k=0; k<32; k++) {
|
|
||||||
sigma1.in[k] <== in2[k];
|
sigma1.in[k] <== in2[k];
|
||||||
sigma0.in[k] <== in15[k];
|
sigma0.in[k] <== in15[k];
|
||||||
|
}
|
||||||
|
|
||||||
|
component sum = BinSum(32, 4);
|
||||||
|
for (k=0; k<32; k++) {
|
||||||
sum.in[0][k] <== sigma1.out[k];
|
sum.in[0][k] <== sigma1.out[k];
|
||||||
sum.in[1][k] <== in7[k];
|
sum.in[1][k] <== in7[k];
|
||||||
sum.in[2][k] <== sigma0.out[k];
|
sum.in[2][k] <== sigma0.out[k];
|
||||||
sum.in[3][k] <== in16[k];
|
sum.in[3][k] <== in16[k];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (k=0; k<32; k++) {
|
||||||
out[k] <== sum.out[k];
|
out[k] <== sum.out[k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,23 +30,28 @@ template T1() {
|
|||||||
signal input w[32];
|
signal input w[32];
|
||||||
signal output out[32];
|
signal output out[32];
|
||||||
|
|
||||||
component sum = BinSum(32, 5);
|
var ki;
|
||||||
component ch = Ch(32);
|
|
||||||
|
|
||||||
|
component ch = Ch(32);
|
||||||
component bigsigma1 = BigSigma(6, 11, 25);
|
component bigsigma1 = BigSigma(6, 11, 25);
|
||||||
|
|
||||||
for (var ki=0; ki<32; ki++) {
|
for (ki=0; ki<32; ki++) {
|
||||||
bigsigma1.in[ki] <== e[ki];
|
bigsigma1.in[ki] <== e[ki];
|
||||||
ch.a[ki] <== e[ki];
|
ch.a[ki] <== e[ki];
|
||||||
ch.b[ki] <== f[ki];
|
ch.b[ki] <== f[ki];
|
||||||
ch.c[ki] <== g[ki]
|
ch.c[ki] <== g[ki];
|
||||||
|
}
|
||||||
|
|
||||||
|
component sum = BinSum(32, 5);
|
||||||
|
for (ki=0; ki<32; ki++) {
|
||||||
sum.in[0][ki] <== h[ki];
|
sum.in[0][ki] <== h[ki];
|
||||||
sum.in[1][ki] <== bigsigma1.out[ki];
|
sum.in[1][ki] <== bigsigma1.out[ki];
|
||||||
sum.in[2][ki] <== ch.out[ki];
|
sum.in[2][ki] <== ch.out[ki];
|
||||||
sum.in[3][ki] <== k[ki];
|
sum.in[3][ki] <== k[ki];
|
||||||
sum.in[4][ki] <== w[ki];
|
sum.in[4][ki] <== w[ki];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ki=0; ki<32; ki++) {
|
||||||
out[ki] <== sum.out[ki];
|
out[ki] <== sum.out[ki];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,22 +26,25 @@ template T2() {
|
|||||||
signal input b[32];
|
signal input b[32];
|
||||||
signal input c[32];
|
signal input c[32];
|
||||||
signal output out[32];
|
signal output out[32];
|
||||||
|
var k;
|
||||||
component sum = BinSum(32, 2);
|
|
||||||
|
|
||||||
component bigsigma0 = BigSigma(2, 13, 22);
|
component bigsigma0 = BigSigma(2, 13, 22);
|
||||||
component maj = Maj(32);
|
component maj = Maj(32);
|
||||||
|
for (k=0; k<32; k++) {
|
||||||
for (var k=0; k<32; k++) {
|
|
||||||
|
|
||||||
bigsigma0.in[k] <== a[k];
|
bigsigma0.in[k] <== a[k];
|
||||||
maj.a[k] <== a[k];
|
maj.a[k] <== a[k];
|
||||||
maj.b[k] <== b[k];
|
maj.b[k] <== b[k];
|
||||||
maj.c[k] <== c[k];
|
maj.c[k] <== c[k];
|
||||||
|
}
|
||||||
|
|
||||||
|
component sum = BinSum(32, 2);
|
||||||
|
|
||||||
|
for (k=0; k<32; k++) {
|
||||||
sum.in[0][k] <== bigsigma0.out[k];
|
sum.in[0][k] <== bigsigma0.out[k];
|
||||||
sum.in[1][k] <== maj.out[k];
|
sum.in[1][k] <== maj.out[k];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (k=0; k<32; k++) {
|
||||||
out[k] <== sum.out[k];
|
out[k] <== sum.out[k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,9 +79,11 @@ template SMTLevIns(nLevels) {
|
|||||||
signal output levIns[nLevels];
|
signal output levIns[nLevels];
|
||||||
signal done[nLevels-1]; // Indicates if the insLevel has aready been detected.
|
signal done[nLevels-1]; // Indicates if the insLevel has aready been detected.
|
||||||
|
|
||||||
|
var i;
|
||||||
|
|
||||||
component isZero[nLevels];
|
component isZero[nLevels];
|
||||||
|
|
||||||
for (var i=0; i<nLevels; i++) {
|
for (i=0; i<nLevels; i++) {
|
||||||
isZero[i] = IsZero();
|
isZero[i] = IsZero();
|
||||||
isZero[i].in <== siblings[i];
|
isZero[i].in <== siblings[i];
|
||||||
}
|
}
|
||||||
@ -91,7 +93,7 @@ template SMTLevIns(nLevels) {
|
|||||||
|
|
||||||
levIns[nLevels-1] <== (1-isZero[nLevels-2].out);
|
levIns[nLevels-1] <== (1-isZero[nLevels-2].out);
|
||||||
done[nLevels-2] <== levIns[nLevels-1];
|
done[nLevels-2] <== levIns[nLevels-1];
|
||||||
for (var i=nLevels-2; i>0; i--) {
|
for (i=nLevels-2; i>0; i--) {
|
||||||
levIns[i] <== (1-done[i])*(1-isZero[i-1].out)
|
levIns[i] <== (1-done[i])*(1-isZero[i-1].out)
|
||||||
done[i-1] <== levIns[i] + done[i];
|
done[i-1] <== levIns[i] + done[i];
|
||||||
}
|
}
|
||||||
|
@ -150,6 +150,8 @@ template SMTProcessor(nLevels) {
|
|||||||
|
|
||||||
signal enabled;
|
signal enabled;
|
||||||
|
|
||||||
|
var i;
|
||||||
|
|
||||||
enabled <== fnc[0] + fnc[1] - fnc[0]*fnc[1]
|
enabled <== fnc[0] + fnc[1] - fnc[0]*fnc[1]
|
||||||
|
|
||||||
component hash1Old = SMTHash1();
|
component hash1Old = SMTHash1();
|
||||||
@ -167,18 +169,18 @@ template SMTProcessor(nLevels) {
|
|||||||
n2bNew.in <== newKey;
|
n2bNew.in <== newKey;
|
||||||
|
|
||||||
component smtLevIns = SMTLevIns(nLevels);
|
component smtLevIns = SMTLevIns(nLevels);
|
||||||
for (var i=0; i<nLevels; i++) smtLevIns.siblings[i] <== siblings[i];
|
for (i=0; i<nLevels; i++) smtLevIns.siblings[i] <== siblings[i];
|
||||||
smtLevIns.enabled <== enabled;
|
smtLevIns.enabled <== enabled;
|
||||||
|
|
||||||
component xors[nLevels];
|
component xors[nLevels];
|
||||||
for (var i=0; i<nLevels; i++) {
|
for (i=0; i<nLevels; i++) {
|
||||||
xors[i] = XOR();
|
xors[i] = XOR();
|
||||||
xors[i].a <== n2bOld.out[i];
|
xors[i].a <== n2bOld.out[i];
|
||||||
xors[i].b <== n2bNew.out[i];
|
xors[i].b <== n2bNew.out[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
component sm[nLevels];
|
component sm[nLevels];
|
||||||
for (var i=0; i<nLevels; i++) {
|
for (i=0; i<nLevels; i++) {
|
||||||
sm[i] = SMTProcessorSM();
|
sm[i] = SMTProcessorSM();
|
||||||
if (i==0) {
|
if (i==0) {
|
||||||
sm[i].prev_top <== enabled;
|
sm[i].prev_top <== enabled;
|
||||||
@ -204,7 +206,7 @@ template SMTProcessor(nLevels) {
|
|||||||
sm[nLevels-1].st_na + sm[nLevels-1].st_new1 + sm[nLevels-1].st_old0 +sm[nLevels-1].st_upd === 1;
|
sm[nLevels-1].st_na + sm[nLevels-1].st_new1 + sm[nLevels-1].st_old0 +sm[nLevels-1].st_upd === 1;
|
||||||
|
|
||||||
component levels[nLevels];
|
component levels[nLevels];
|
||||||
for (var i=nLevels-1; i != -1; i--) {
|
for (i=nLevels-1; i != -1; i--) {
|
||||||
levels[i] = SMTProcessorLevel();
|
levels[i] = SMTProcessorLevel();
|
||||||
|
|
||||||
levels[i].st_top <== sm[i].st_top;
|
levels[i].st_top <== sm[i].st_top;
|
||||||
|
@ -48,6 +48,8 @@ template SMTVerifier(nLevels) {
|
|||||||
signal input value;
|
signal input value;
|
||||||
signal input fnc;
|
signal input fnc;
|
||||||
|
|
||||||
|
var i;
|
||||||
|
|
||||||
component hash1Old = SMTHash1();
|
component hash1Old = SMTHash1();
|
||||||
hash1Old.key <== oldKey;
|
hash1Old.key <== oldKey;
|
||||||
hash1Old.value <== oldValue;
|
hash1Old.value <== oldValue;
|
||||||
@ -63,11 +65,11 @@ template SMTVerifier(nLevels) {
|
|||||||
n2bNew.in <== key;
|
n2bNew.in <== key;
|
||||||
|
|
||||||
component smtLevIns = SMTLevIns(nLevels);
|
component smtLevIns = SMTLevIns(nLevels);
|
||||||
for (var i=0; i<nLevels; i++) smtLevIns.siblings[i] <== siblings[i];
|
for (i=0; i<nLevels; i++) smtLevIns.siblings[i] <== siblings[i];
|
||||||
smtLevIns.enabled <== enabled;
|
smtLevIns.enabled <== enabled;
|
||||||
|
|
||||||
component sm[nLevels];
|
component sm[nLevels];
|
||||||
for (var i=0; i<nLevels; i++) {
|
for (i=0; i<nLevels; i++) {
|
||||||
sm[i] = SMTVerifierSM();
|
sm[i] = SMTVerifierSM();
|
||||||
if (i==0) {
|
if (i==0) {
|
||||||
sm[i].prev_top <== enabled;
|
sm[i].prev_top <== enabled;
|
||||||
@ -89,7 +91,7 @@ template SMTVerifier(nLevels) {
|
|||||||
sm[nLevels-1].st_na + sm[nLevels-1].st_iold + sm[nLevels-1].st_inew + sm[nLevels-1].st_i0 === 1;
|
sm[nLevels-1].st_na + sm[nLevels-1].st_iold + sm[nLevels-1].st_inew + sm[nLevels-1].st_i0 === 1;
|
||||||
|
|
||||||
component levels[nLevels];
|
component levels[nLevels];
|
||||||
for (var i=nLevels-1; i != -1; i--) {
|
for (i=nLevels-1; i != -1; i--) {
|
||||||
levels[i] = SMTVerifierLevel();
|
levels[i] = SMTVerifierLevel();
|
||||||
|
|
||||||
levels[i].st_top <== sm[i].st_top;
|
levels[i].st_top <== sm[i].st_top;
|
||||||
|
3
index.js
3
index.js
@ -7,3 +7,6 @@ exports.pedersenHash = require("./src/pedersenHash");
|
|||||||
exports.SMT = require("./src/smt").SMT;
|
exports.SMT = require("./src/smt").SMT;
|
||||||
exports.SMTMemDB = require("./src/smt_memdb");
|
exports.SMTMemDB = require("./src/smt_memdb");
|
||||||
exports.poseidon = require("./src/poseidon");
|
exports.poseidon = require("./src/poseidon");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
19882
package-lock.json
generated
19882
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
16
package.json
16
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@tornado/circomlib",
|
"name": "@tornado/circomlib",
|
||||||
"version": "0.0.21",
|
"version": "0.4.1",
|
||||||
"description": "Basic circuits library for Circom",
|
"description": "Basic circuits library for Circom",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"directories": {
|
"directories": {
|
||||||
@ -24,16 +24,16 @@
|
|||||||
"author": "0Kims",
|
"author": "0Kims",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@tornado/snarkjs": "0.1.20",
|
||||||
"blake-hash": "^1.1.0",
|
"blake-hash": "^1.1.0",
|
||||||
"blake2b": "^2.1.3",
|
"blake2b": "^2.1.3",
|
||||||
"@tornado/snarkjs": "0.1.20",
|
"circom": "0.5.33",
|
||||||
"typedarray-to-buffer": "^3.1.5",
|
"ffjavascript": "0.1.0"
|
||||||
"web3": "^1.2.11"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"circom": "0.0.35",
|
"eslint": "^6.8.0",
|
||||||
"eslint-plugin-mocha": "^5.2.0",
|
"ganache-cli": "^6.12.1",
|
||||||
"ganache-cli": "^6.4.4",
|
"mocha": "^7.1.1",
|
||||||
"mocha": "^5.2.0"
|
"web3": "^1.3.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
100
src/babyjub.js
100
src/babyjub.js
@ -1,5 +1,6 @@
|
|||||||
const bn128 = require("@tornado/snarkjs").bn128;
|
const F1Field = require("ffjavascript").F1Field;
|
||||||
const bigInt = require("@tornado/snarkjs").bigInt;
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
|
const utils = require("ffjavascript").utils;
|
||||||
|
|
||||||
exports.addPoint = addPoint;
|
exports.addPoint = addPoint;
|
||||||
exports.mulPointEscalar = mulPointEscalar;
|
exports.mulPointEscalar = mulPointEscalar;
|
||||||
@ -7,22 +8,27 @@ exports.inCurve = inCurve;
|
|||||||
exports.inSubgroup = inSubgroup;
|
exports.inSubgroup = inSubgroup;
|
||||||
exports.packPoint = packPoint;
|
exports.packPoint = packPoint;
|
||||||
exports.unpackPoint = unpackPoint;
|
exports.unpackPoint = unpackPoint;
|
||||||
|
|
||||||
|
|
||||||
|
exports.p = Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||||
|
const F = new F1Field(exports.p);
|
||||||
|
exports.F = F;
|
||||||
|
|
||||||
exports.Generator = [
|
exports.Generator = [
|
||||||
bigInt("995203441582195749578291179787384436505546430278305826713579947235728471134"),
|
F.e("995203441582195749578291179787384436505546430278305826713579947235728471134"),
|
||||||
bigInt("5472060717959818805561601436314318772137091100104008585924551046643952123905"),
|
F.e("5472060717959818805561601436314318772137091100104008585924551046643952123905")
|
||||||
];
|
];
|
||||||
exports.Base8 = [
|
exports.Base8 = [
|
||||||
bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
F.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
||||||
bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203"),
|
F.e("16950150798460657717958625567821834550301663161624707787222815936182638968203")
|
||||||
];
|
];
|
||||||
exports.order = bigInt("21888242871839275222246405745257275088614511777268538073601725287587578984328");
|
exports.order = Scalar.fromString("21888242871839275222246405745257275088614511777268538073601725287587578984328");
|
||||||
exports.subOrder = exports.order.shr(3);
|
exports.subOrder = Scalar.shiftRight(exports.order, 3);
|
||||||
exports.p = bn128.r;
|
exports.A = F.e("168700");
|
||||||
exports.A = bigInt("168700");
|
exports.D = F.e("168696");
|
||||||
exports.D = bigInt("168696");
|
|
||||||
|
|
||||||
function addPoint(a, b) {
|
|
||||||
const q = bn128.r;
|
function addPoint(a,b) {
|
||||||
|
|
||||||
const res = [];
|
const res = [];
|
||||||
|
|
||||||
@ -30,33 +36,40 @@ function addPoint(a, b) {
|
|||||||
res[0] = bigInt((a[0]*b[1] + b[0]*a[1]) * bigInt(bigInt("1") + d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q);
|
res[0] = bigInt((a[0]*b[1] + b[0]*a[1]) * bigInt(bigInt("1") + d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q);
|
||||||
res[1] = bigInt((a[1]*b[1] - cta*a[0]*b[0]) * bigInt(bigInt("1") - d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q);
|
res[1] = bigInt((a[1]*b[1] - cta*a[0]*b[0]) * bigInt(bigInt("1") - d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q);
|
||||||
*/
|
*/
|
||||||
res[0] = bigInt(
|
|
||||||
bigInt(a[0])
|
const beta = F.mul(a[0],b[1]);
|
||||||
.mul(b[1])
|
const gamma = F.mul(a[1],b[0]);
|
||||||
.add(bigInt(b[0]).mul(a[1]))
|
const delta = F.mul(
|
||||||
.mul(bigInt(bigInt("1").add(exports.D.mul(a[0]).mul(b[0]).mul(a[1]).mul(b[1]))).inverse(q))
|
F.sub(a[1], F.mul(exports.A, a[0])),
|
||||||
).affine(q);
|
F.add(b[0], b[1])
|
||||||
res[1] = bigInt(
|
);
|
||||||
bigInt(a[1])
|
const tau = F.mul(beta, gamma);
|
||||||
.mul(b[1])
|
const dtau = F.mul(exports.D, tau);
|
||||||
.sub(exports.A.mul(a[0]).mul(b[0]))
|
|
||||||
.mul(bigInt(bigInt("1").sub(exports.D.mul(a[0]).mul(b[0]).mul(a[1]).mul(b[1]))).inverse(q))
|
res[0] = F.div(
|
||||||
).affine(q);
|
F.add(beta, gamma),
|
||||||
|
F.add(F.one, dtau)
|
||||||
|
);
|
||||||
|
|
||||||
|
res[1] = F.div(
|
||||||
|
F.add(delta, F.sub(F.mul(exports.A,beta), gamma)),
|
||||||
|
F.sub(F.one, dtau)
|
||||||
|
);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function mulPointEscalar(base, e) {
|
function mulPointEscalar(base, e) {
|
||||||
let res = [bigInt("0"), bigInt("1")];
|
let res = [F.e("0"),F.e("1")];
|
||||||
let rem = bigInt(e);
|
let rem = e;
|
||||||
let exp = base;
|
let exp = base;
|
||||||
|
|
||||||
while (!rem.isZero()) {
|
while (! Scalar.isZero(rem)) {
|
||||||
if (rem.isOdd()) {
|
if (Scalar.isOdd(rem)) {
|
||||||
res = addPoint(res, exp);
|
res = addPoint(res, exp);
|
||||||
}
|
}
|
||||||
exp = addPoint(exp, exp);
|
exp = addPoint(exp, exp);
|
||||||
rem = rem.shr(1);
|
rem = Scalar.shiftRight(rem, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
@ -64,51 +77,52 @@ function mulPointEscalar(base, e) {
|
|||||||
|
|
||||||
function inSubgroup(P) {
|
function inSubgroup(P) {
|
||||||
if (!inCurve(P)) return false;
|
if (!inCurve(P)) return false;
|
||||||
const res = mulPointEscalar(P, exports.subOrder);
|
const res= mulPointEscalar(P, exports.subOrder);
|
||||||
return res[0].equals(bigInt(0)) && res[1].equals(bigInt(1));
|
return (F.isZero(res[0]) && F.eq(res[1], F.one));
|
||||||
}
|
}
|
||||||
|
|
||||||
function inCurve(P) {
|
function inCurve(P) {
|
||||||
const F = bn128.Fr;
|
|
||||||
|
|
||||||
const x2 = F.square(P[0]);
|
const x2 = F.square(P[0]);
|
||||||
const y2 = F.square(P[1]);
|
const y2 = F.square(P[1]);
|
||||||
|
|
||||||
if (!F.equals(F.add(F.mul(exports.A, x2), y2), F.add(F.one, F.mul(F.mul(x2, y2), exports.D)))) return false;
|
if (!F.eq(
|
||||||
|
F.add(F.mul(exports.A, x2), y2),
|
||||||
|
F.add(F.one, F.mul(F.mul(x2, y2), exports.D)))) return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function packPoint(P) {
|
function packPoint(P) {
|
||||||
const buff = bigInt.leInt2Buff(P[1], 32);
|
const buff = utils.leInt2Buff(P[1], 32);
|
||||||
if (P[0].greater(exports.p.shr(1))) {
|
if (F.lt(P[0], F.zero)) {
|
||||||
buff[31] = buff[31] | 0x80;
|
buff[31] = buff[31] | 0x80;
|
||||||
}
|
}
|
||||||
return buff;
|
return buff;
|
||||||
}
|
}
|
||||||
|
|
||||||
function unpackPoint(_buff) {
|
function unpackPoint(_buff) {
|
||||||
const F = bn128.Fr;
|
|
||||||
|
|
||||||
const buff = Buffer.from(_buff);
|
const buff = Buffer.from(_buff);
|
||||||
let sign = false;
|
let sign = false;
|
||||||
const P = new Array(2);
|
const P = new Array(2);
|
||||||
if (buff[31] & 0x80) {
|
if (buff[31] & 0x80) {
|
||||||
sign = true;
|
sign = true;
|
||||||
buff[31] = buff[31] & 0x7f;
|
buff[31] = buff[31] & 0x7F;
|
||||||
}
|
}
|
||||||
P[1] = bigInt.leBuff2int(buff);
|
P[1] = utils.leBuff2int(buff);
|
||||||
if (P[1].greaterOrEquals(exports.p)) return null;
|
if (Scalar.gt(P[1], exports.p)) return null;
|
||||||
|
|
||||||
const y2 = F.square(P[1]);
|
const y2 = F.square(P[1]);
|
||||||
|
|
||||||
let x = F.sqrt(F.div(F.sub(F.one, y2), F.sub(exports.A, F.mul(exports.D, y2))));
|
let x = F.sqrt(F.div(
|
||||||
|
F.sub(F.one, y2),
|
||||||
|
F.sub(exports.A, F.mul(exports.D, y2))));
|
||||||
|
|
||||||
if (x == null) return null;
|
if (x == null) return null;
|
||||||
|
|
||||||
if (sign) x = F.neg(x);
|
if (sign) x = F.neg(x);
|
||||||
|
|
||||||
P[0] = F.affine(x);
|
P[0] = x;
|
||||||
|
|
||||||
return P;
|
return P;
|
||||||
}
|
}
|
||||||
|
161
src/eddsa.js
161
src/eddsa.js
@ -1,12 +1,15 @@
|
|||||||
const createBlakeHash = require("blake-hash");
|
const createBlakeHash = require("blake-hash");
|
||||||
const bigInt = require("@tornado/snarkjs").bigInt;
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
|
const F1Field = require("ffjavascript").F1Field;
|
||||||
const babyJub = require("./babyjub");
|
const babyJub = require("./babyjub");
|
||||||
|
const utils = require("ffjavascript").utils;
|
||||||
const pedersenHash = require("./pedersenHash").hash;
|
const pedersenHash = require("./pedersenHash").hash;
|
||||||
const mimc7 = require("./mimc7");
|
const mimc7 = require("./mimc7");
|
||||||
const poseidon = require("./poseidon.js");
|
const poseidon = require("./poseidon.js");
|
||||||
const mimcsponge = require("./mimcsponge");
|
const mimcsponge = require("./mimcsponge");
|
||||||
|
|
||||||
exports.prv2pub = prv2pub;
|
|
||||||
|
exports.prv2pub= prv2pub;
|
||||||
exports.sign = sign;
|
exports.sign = sign;
|
||||||
exports.signMiMC = signMiMC;
|
exports.signMiMC = signMiMC;
|
||||||
exports.signPoseidon = signPoseidon;
|
exports.signPoseidon = signPoseidon;
|
||||||
@ -19,104 +22,101 @@ exports.packSignature = packSignature;
|
|||||||
exports.unpackSignature = unpackSignature;
|
exports.unpackSignature = unpackSignature;
|
||||||
exports.pruneBuffer = pruneBuffer;
|
exports.pruneBuffer = pruneBuffer;
|
||||||
|
|
||||||
|
|
||||||
function pruneBuffer(_buff) {
|
function pruneBuffer(_buff) {
|
||||||
const buff = Buffer.from(_buff);
|
const buff = Buffer.from(_buff);
|
||||||
buff[0] = buff[0] & 0xf8;
|
buff[0] = buff[0] & 0xF8;
|
||||||
buff[31] = buff[31] & 0x7f;
|
buff[31] = buff[31] & 0x7F;
|
||||||
buff[31] = buff[31] | 0x40;
|
buff[31] = buff[31] | 0x40;
|
||||||
return buff;
|
return buff;
|
||||||
}
|
}
|
||||||
|
|
||||||
function prv2pub(prv) {
|
function prv2pub(prv) {
|
||||||
const sBuff = pruneBuffer(createBlakeHash("blake512").update(prv).digest().slice(0, 32));
|
const sBuff = pruneBuffer(createBlakeHash("blake512").update(prv).digest().slice(0,32));
|
||||||
let s = bigInt.leBuff2int(sBuff);
|
let s = utils.leBuff2int(sBuff);
|
||||||
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
|
const A = babyJub.mulPointEscalar(babyJub.Base8, Scalar.shr(s,3));
|
||||||
return A;
|
return A;
|
||||||
}
|
}
|
||||||
|
|
||||||
function sign(prv, msg) {
|
function sign(prv, msg) {
|
||||||
const h1 = createBlakeHash("blake512").update(prv).digest();
|
const h1 = createBlakeHash("blake512").update(prv).digest();
|
||||||
const sBuff = pruneBuffer(h1.slice(0, 32));
|
const sBuff = pruneBuffer(h1.slice(0,32));
|
||||||
const s = bigInt.leBuff2int(sBuff);
|
const s = utils.leBuff2int(sBuff);
|
||||||
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
|
const A = babyJub.mulPointEscalar(babyJub.Base8, Scalar.shr(s, 3));
|
||||||
|
|
||||||
const rBuff = createBlakeHash("blake512")
|
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msg])).digest();
|
||||||
.update(Buffer.concat([h1.slice(32, 64), msg]))
|
let r = utils.leBuff2int(rBuff);
|
||||||
.digest();
|
const Fr = new F1Field(babyJub.subOrder);
|
||||||
let r = bigInt.leBuff2int(rBuff);
|
r = Fr.e(r);
|
||||||
r = r.mod(babyJub.subOrder);
|
|
||||||
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
|
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
|
||||||
const R8p = babyJub.packPoint(R8);
|
const R8p = babyJub.packPoint(R8);
|
||||||
const Ap = babyJub.packPoint(A);
|
const Ap = babyJub.packPoint(A);
|
||||||
const hmBuff = pedersenHash(Buffer.concat([R8p, Ap, msg]));
|
const hmBuff = pedersenHash(Buffer.concat([R8p, Ap, msg]));
|
||||||
const hm = bigInt.leBuff2int(hmBuff);
|
const hm = utils.leBuff2int(hmBuff);
|
||||||
const S = r.add(hm.mul(s)).mod(babyJub.subOrder);
|
const S = Fr.add(r , Fr.mul(hm, s));
|
||||||
return {
|
return {
|
||||||
R8: R8,
|
R8: R8,
|
||||||
S: S,
|
S: S
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function signMiMC(prv, msg) {
|
function signMiMC(prv, msg) {
|
||||||
const h1 = createBlakeHash("blake512").update(prv).digest();
|
const h1 = createBlakeHash("blake512").update(prv).digest();
|
||||||
const sBuff = pruneBuffer(h1.slice(0, 32));
|
const sBuff = pruneBuffer(h1.slice(0,32));
|
||||||
const s = bigInt.leBuff2int(sBuff);
|
const s = utils.leBuff2int(sBuff);
|
||||||
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
|
const A = babyJub.mulPointEscalar(babyJub.Base8, Scalar.shr(s, 3));
|
||||||
|
|
||||||
const msgBuff = bigInt.leInt2Buff(msg, 32);
|
const msgBuff = utils.leInt2Buff(msg, 32);
|
||||||
const rBuff = createBlakeHash("blake512")
|
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
|
||||||
.update(Buffer.concat([h1.slice(32, 64), msgBuff]))
|
let r = utils.leBuff2int(rBuff);
|
||||||
.digest();
|
const Fr = new F1Field(babyJub.subOrder);
|
||||||
let r = bigInt.leBuff2int(rBuff);
|
r = Fr.e(r);
|
||||||
r = r.mod(babyJub.subOrder);
|
|
||||||
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
|
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
|
||||||
const hm = mimc7.multiHash([R8[0], R8[1], A[0], A[1], msg]);
|
const hm = mimc7.multiHash([R8[0], R8[1], A[0], A[1], msg]);
|
||||||
const S = r.add(hm.mul(s)).mod(babyJub.subOrder);
|
const S = Fr.add(r , Fr.mul(hm, s));
|
||||||
return {
|
return {
|
||||||
R8: R8,
|
R8: R8,
|
||||||
S: S,
|
S: S
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function signMiMCSponge(prv, msg) {
|
function signMiMCSponge(prv, msg) {
|
||||||
const h1 = createBlakeHash("blake512").update(prv).digest();
|
const h1 = createBlakeHash("blake512").update(prv).digest();
|
||||||
const sBuff = pruneBuffer(h1.slice(0, 32));
|
const sBuff = pruneBuffer(h1.slice(0,32));
|
||||||
const s = bigInt.leBuff2int(sBuff);
|
const s = utils.leBuff2int(sBuff);
|
||||||
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
|
const A = babyJub.mulPointEscalar(babyJub.Base8, Scalar.shr(s, 3));
|
||||||
|
|
||||||
const msgBuff = bigInt.leInt2Buff(msg, 32);
|
const msgBuff = utils.leInt2Buff(msg, 32);
|
||||||
const rBuff = createBlakeHash("blake512")
|
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
|
||||||
.update(Buffer.concat([h1.slice(32, 64), msgBuff]))
|
let r = utils.leBuff2int(rBuff);
|
||||||
.digest();
|
const Fr = new F1Field(babyJub.subOrder);
|
||||||
let r = bigInt.leBuff2int(rBuff);
|
r = Fr.e(r);
|
||||||
r = r.mod(babyJub.subOrder);
|
|
||||||
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
|
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
|
||||||
const hm = mimcsponge.multiHash([R8[0], R8[1], A[0], A[1], msg]);
|
const hm = mimcsponge.multiHash([R8[0], R8[1], A[0], A[1], msg]);
|
||||||
const S = r.add(hm.mul(s)).mod(babyJub.subOrder);
|
const S = Fr.add(r , Fr.mul(hm, s));
|
||||||
return {
|
return {
|
||||||
R8: R8,
|
R8: R8,
|
||||||
S: S,
|
S: S
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function signPoseidon(prv, msg) {
|
function signPoseidon(prv, msg) {
|
||||||
const h1 = createBlakeHash("blake512").update(prv).digest();
|
const h1 = createBlakeHash("blake512").update(prv).digest();
|
||||||
const sBuff = pruneBuffer(h1.slice(0, 32));
|
const sBuff = pruneBuffer(h1.slice(0,32));
|
||||||
const s = bigInt.leBuff2int(sBuff);
|
const s = utils.leBuff2int(sBuff);
|
||||||
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
|
const A = babyJub.mulPointEscalar(babyJub.Base8, Scalar.shr(s, 3));
|
||||||
|
|
||||||
const msgBuff = bigInt.leInt2Buff(msg, 32);
|
const msgBuff = utils.leInt2Buff(msg, 32);
|
||||||
const rBuff = createBlakeHash("blake512")
|
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
|
||||||
.update(Buffer.concat([h1.slice(32, 64), msgBuff]))
|
let r = utils.leBuff2int(rBuff);
|
||||||
.digest();
|
const Fr = new F1Field(babyJub.subOrder);
|
||||||
let r = bigInt.leBuff2int(rBuff);
|
r = Fr.e(r);
|
||||||
r = r.mod(babyJub.subOrder);
|
|
||||||
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
|
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
|
||||||
const hm = poseidon([R8[0], R8[1], A[0], A[1], msg]);
|
const hm = poseidon([R8[0], R8[1], A[0], A[1], msg]);
|
||||||
const S = r.add(hm.mul(s)).mod(babyJub.subOrder);
|
const S = Fr.add(r , Fr.mul(hm, s));
|
||||||
return {
|
return {
|
||||||
R8: R8,
|
R8: R8,
|
||||||
S: S,
|
S: S
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,24 +124,24 @@ function verify(msg, sig, A) {
|
|||||||
// Check parameters
|
// Check parameters
|
||||||
if (typeof sig != "object") return false;
|
if (typeof sig != "object") return false;
|
||||||
if (!Array.isArray(sig.R8)) return false;
|
if (!Array.isArray(sig.R8)) return false;
|
||||||
if (sig.R8.length != 2) return false;
|
if (sig.R8.length!= 2) return false;
|
||||||
if (!babyJub.inCurve(sig.R8)) return false;
|
if (!babyJub.inCurve(sig.R8)) return false;
|
||||||
if (!Array.isArray(A)) return false;
|
if (!Array.isArray(A)) return false;
|
||||||
if (A.length != 2) return false;
|
if (A.length!= 2) return false;
|
||||||
if (!babyJub.inCurve(A)) return false;
|
if (!babyJub.inCurve(A)) return false;
|
||||||
if (sig.S >= babyJub.subOrder) return false;
|
if (sig.S>= babyJub.subOrder) return false;
|
||||||
|
|
||||||
const R8p = babyJub.packPoint(sig.R8);
|
const R8p = babyJub.packPoint(sig.R8);
|
||||||
const Ap = babyJub.packPoint(A);
|
const Ap = babyJub.packPoint(A);
|
||||||
const hmBuff = pedersenHash(Buffer.concat([R8p, Ap, msg]));
|
const hmBuff = pedersenHash(Buffer.concat([R8p, Ap, msg]));
|
||||||
const hm = bigInt.leBuff2int(hmBuff);
|
const hm = utils.leBuff2int(hmBuff);
|
||||||
|
|
||||||
const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
|
const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
|
||||||
let Pright = babyJub.mulPointEscalar(A, hm.mul(bigInt("8")));
|
let Pright = babyJub.mulPointEscalar(A, Scalar.mul(hm,8));
|
||||||
Pright = babyJub.addPoint(sig.R8, Pright);
|
Pright = babyJub.addPoint(sig.R8, Pright);
|
||||||
|
|
||||||
if (!Pleft[0].equals(Pright[0])) return false;
|
if (!babyJub.F.eq(Pleft[0],Pright[0])) return false;
|
||||||
if (!Pleft[1].equals(Pright[1])) return false;
|
if (!babyJub.F.eq(Pleft[1],Pright[1])) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,43 +149,44 @@ function verifyMiMC(msg, sig, A) {
|
|||||||
// Check parameters
|
// Check parameters
|
||||||
if (typeof sig != "object") return false;
|
if (typeof sig != "object") return false;
|
||||||
if (!Array.isArray(sig.R8)) return false;
|
if (!Array.isArray(sig.R8)) return false;
|
||||||
if (sig.R8.length != 2) return false;
|
if (sig.R8.length!= 2) return false;
|
||||||
if (!babyJub.inCurve(sig.R8)) return false;
|
if (!babyJub.inCurve(sig.R8)) return false;
|
||||||
if (!Array.isArray(A)) return false;
|
if (!Array.isArray(A)) return false;
|
||||||
if (A.length != 2) return false;
|
if (A.length!= 2) return false;
|
||||||
if (!babyJub.inCurve(A)) return false;
|
if (!babyJub.inCurve(A)) return false;
|
||||||
if (sig.S >= babyJub.subOrder) return false;
|
if (sig.S>= babyJub.subOrder) return false;
|
||||||
|
|
||||||
const hm = mimc7.multiHash([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
|
const hm = mimc7.multiHash([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
|
||||||
|
|
||||||
const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
|
const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
|
||||||
let Pright = babyJub.mulPointEscalar(A, hm.mul(bigInt("8")));
|
let Pright = babyJub.mulPointEscalar(A, Scalar.mul(hm, 8));
|
||||||
Pright = babyJub.addPoint(sig.R8, Pright);
|
Pright = babyJub.addPoint(sig.R8, Pright);
|
||||||
|
|
||||||
if (!Pleft[0].equals(Pright[0])) return false;
|
if (!babyJub.F.eq(Pleft[0],Pright[0])) return false;
|
||||||
if (!Pleft[1].equals(Pright[1])) return false;
|
if (!babyJub.F.eq(Pleft[1],Pright[1])) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function verifyPoseidon(msg, sig, A) {
|
function verifyPoseidon(msg, sig, A) {
|
||||||
// Check parameters
|
// Check parameters
|
||||||
if (typeof sig != "object") return false;
|
if (typeof sig != "object") return false;
|
||||||
if (!Array.isArray(sig.R8)) return false;
|
if (!Array.isArray(sig.R8)) return false;
|
||||||
if (sig.R8.length != 2) return false;
|
if (sig.R8.length!= 2) return false;
|
||||||
if (!babyJub.inCurve(sig.R8)) return false;
|
if (!babyJub.inCurve(sig.R8)) return false;
|
||||||
if (!Array.isArray(A)) return false;
|
if (!Array.isArray(A)) return false;
|
||||||
if (A.length != 2) return false;
|
if (A.length!= 2) return false;
|
||||||
if (!babyJub.inCurve(A)) return false;
|
if (!babyJub.inCurve(A)) return false;
|
||||||
if (sig.S >= babyJub.subOrder) return false;
|
if (sig.S>= babyJub.subOrder) return false;
|
||||||
|
|
||||||
const hm = poseidon([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
|
const hm = poseidon([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
|
||||||
|
|
||||||
const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
|
const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
|
||||||
let Pright = babyJub.mulPointEscalar(A, hm.mul(bigInt("8")));
|
let Pright = babyJub.mulPointEscalar(A, Scalar.mul(hm, 8));
|
||||||
Pright = babyJub.addPoint(sig.R8, Pright);
|
Pright = babyJub.addPoint(sig.R8, Pright);
|
||||||
|
|
||||||
if (!Pleft[0].equals(Pright[0])) return false;
|
if (!babyJub.F.eq(Pleft[0],Pright[0])) return false;
|
||||||
if (!Pleft[1].equals(Pright[1])) return false;
|
if (!babyJub.F.eq(Pleft[1],Pright[1])) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,33 +194,35 @@ function verifyMiMCSponge(msg, sig, A) {
|
|||||||
// Check parameters
|
// Check parameters
|
||||||
if (typeof sig != "object") return false;
|
if (typeof sig != "object") return false;
|
||||||
if (!Array.isArray(sig.R8)) return false;
|
if (!Array.isArray(sig.R8)) return false;
|
||||||
if (sig.R8.length != 2) return false;
|
if (sig.R8.length!= 2) return false;
|
||||||
if (!babyJub.inCurve(sig.R8)) return false;
|
if (!babyJub.inCurve(sig.R8)) return false;
|
||||||
if (!Array.isArray(A)) return false;
|
if (!Array.isArray(A)) return false;
|
||||||
if (A.length != 2) return false;
|
if (A.length!= 2) return false;
|
||||||
if (!babyJub.inCurve(A)) return false;
|
if (!babyJub.inCurve(A)) return false;
|
||||||
if (sig.S >= babyJub.subOrder) return false;
|
if (sig.S>= babyJub.subOrder) return false;
|
||||||
|
|
||||||
const hm = mimcsponge.multiHash([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
|
const hm = mimcsponge.multiHash([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
|
||||||
|
|
||||||
const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
|
const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
|
||||||
let Pright = babyJub.mulPointEscalar(A, hm.mul(bigInt("8")));
|
let Pright = babyJub.mulPointEscalar(A, hm.times(bigInt("8")));
|
||||||
Pright = babyJub.addPoint(sig.R8, Pright);
|
Pright = babyJub.addPoint(sig.R8, Pright);
|
||||||
|
|
||||||
if (!Pleft[0].equals(Pright[0])) return false;
|
if (!babyJub.F.eq(Pleft[0],Pright[0])) return false;
|
||||||
if (!Pleft[1].equals(Pright[1])) return false;
|
if (!babyJub.F.eq(Pleft[1],Pright[1])) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function packSignature(sig) {
|
function packSignature(sig) {
|
||||||
const R8p = babyJub.packPoint(sig.R8);
|
const R8p = babyJub.packPoint(sig.R8);
|
||||||
const Sp = bigInt.leInt2Buff(sig.S, 32);
|
const Sp = utils.leInt2Buff(sig.S, 32);
|
||||||
return Buffer.concat([R8p, Sp]);
|
return Buffer.concat([R8p, Sp]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function unpackSignature(sigBuff) {
|
function unpackSignature(sigBuff) {
|
||||||
return {
|
return {
|
||||||
R8: babyJub.unpackPoint(sigBuff.slice(0, 32)),
|
R8: babyJub.unpackPoint(sigBuff.slice(0,32)),
|
||||||
S: bigInt.leBuff2int(sigBuff.slice(32, 64)),
|
S: utils.leBuff2int(sigBuff.slice(32,64))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
const Contract = require("./evmasm");
|
const Contract = require("./evmasm");
|
||||||
const G2 = require("@tornado/snarkjs").bn128.G2;
|
const G2 = require("@tornado/snarkjs").bn128.G2;
|
||||||
const bigInt = require("@tornado/snarkjs").bigInt;
|
|
||||||
|
|
||||||
function toHex256(a) {
|
function toHex256(a) {
|
||||||
let S = a.toString(16);
|
let S = a.toString(16);
|
||||||
@ -529,7 +528,7 @@ function createCode(P, w) {
|
|||||||
function storeVals() {
|
function storeVals() {
|
||||||
C.push(VAR_POINTS); // p
|
C.push(VAR_POINTS); // p
|
||||||
for (let i = 0; i < NPOINTS; i++) {
|
for (let i = 0; i < NPOINTS; i++) {
|
||||||
const MP = G2.affine(G2.mulScalar(P, bigInt(i)));
|
const MP = G2.affine(G2.mulScalar(P, i));
|
||||||
for (let j = 0; j < 2; j++) {
|
for (let j = 0; j < 2; j++) {
|
||||||
for (let k = 0; k < 2; k++) {
|
for (let k = 0; k < 2; k++) {
|
||||||
C.push(toHex256(MP[j][k])); // MP[0][0] p
|
C.push(toHex256(MP[j][k])); // MP[0][0] p
|
||||||
|
50
src/mimc7.js
50
src/mimc7.js
@ -1,16 +1,18 @@
|
|||||||
const bn128 = require("@tornado/snarkjs").bn128;
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
const bigInt = require("@tornado/snarkjs").bigInt;
|
const ZqField = require("ffjavascript").ZqField;
|
||||||
|
|
||||||
const Web3Utils = require("web3-utils");
|
const Web3Utils = require("web3-utils");
|
||||||
const F = bn128.Fr;
|
const F = new ZqField(Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
|
||||||
|
exports.F = F;
|
||||||
|
|
||||||
const SEED = "mimc";
|
const SEED = "mimc";
|
||||||
const NROUNDS = 91;
|
const NROUNDS = 91;
|
||||||
|
|
||||||
exports.getIV = (seed) => {
|
exports.getIV = (seed) => {
|
||||||
if (typeof seed === "undefined") seed = SEED;
|
if (typeof seed === "undefined") seed = SEED;
|
||||||
const c = Web3Utils.keccak256(seed + "_iv");
|
const c = Web3Utils.keccak256(seed+"_iv");
|
||||||
const cn = bigInt(Web3Utils.toBN(c).toString());
|
const cn = Scalar.FromString(Web3Utils.toBN(c).toString());
|
||||||
const iv = cn.mod(F.q);
|
const iv = cn.mod(F.p);
|
||||||
return iv;
|
return iv;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -19,40 +21,46 @@ exports.getConstants = (seed, nRounds) => {
|
|||||||
if (typeof nRounds === "undefined") nRounds = NROUNDS;
|
if (typeof nRounds === "undefined") nRounds = NROUNDS;
|
||||||
const cts = new Array(nRounds);
|
const cts = new Array(nRounds);
|
||||||
let c = Web3Utils.keccak256(SEED);
|
let c = Web3Utils.keccak256(SEED);
|
||||||
for (let i = 1; i < nRounds; i++) {
|
for (let i=1; i<nRounds; i++) {
|
||||||
c = Web3Utils.keccak256(c);
|
c = Web3Utils.keccak256(c);
|
||||||
|
|
||||||
const n1 = Web3Utils.toBN(c).mod(Web3Utils.toBN(F.q.toString()));
|
const n1 = Web3Utils.toBN(c).mod(Web3Utils.toBN(F.p.toString()));
|
||||||
const c2 = Web3Utils.padLeft(Web3Utils.toHex(n1), 64);
|
const c2 = Web3Utils.padLeft(Web3Utils.toHex(n1), 64);
|
||||||
cts[i] = bigInt(Web3Utils.toBN(c2).toString());
|
cts[i] = Scalar.fromString(Web3Utils.toBN(c2).toString());
|
||||||
}
|
}
|
||||||
cts[0] = bigInt(0);
|
cts[0] = F.e(0);
|
||||||
return cts;
|
return cts;
|
||||||
};
|
};
|
||||||
|
|
||||||
const cts = exports.getConstants(SEED, 91);
|
const cts = exports.getConstants(SEED, 91);
|
||||||
|
|
||||||
exports.hash = (_x_in, _k) => {
|
exports.hash = (_x_in, _k) =>{
|
||||||
const x_in = bigInt(_x_in);
|
const x_in = F.e(_x_in);
|
||||||
const k = bigInt(_k);
|
const k = F.e(_k);
|
||||||
let r;
|
let r;
|
||||||
for (let i = 0; i < NROUNDS; i++) {
|
for (let i=0; i<NROUNDS; i++) {
|
||||||
const c = cts[i];
|
const c = cts[i];
|
||||||
const t = i == 0 ? F.add(x_in, k) : F.add(F.add(r, k), c);
|
const t = (i==0) ? F.add(x_in, k) : F.add(F.add(r, k), c);
|
||||||
r = F.exp(t, 7);
|
r = F.pow(t, 7);
|
||||||
}
|
}
|
||||||
return F.affine(F.add(r, k));
|
return F.add(r, k);
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.multiHash = (arr, key) => {
|
exports.multiHash = (arr, key) => {
|
||||||
let r;
|
let r;
|
||||||
if (typeof key === "undefined") {
|
if (typeof(key) === "undefined") {
|
||||||
r = F.zero;
|
r = F.zero;
|
||||||
} else {
|
} else {
|
||||||
r = key;
|
r = key;
|
||||||
}
|
}
|
||||||
for (let i = 0; i < arr.length; i++) {
|
for (let i=0; i<arr.length; i++) {
|
||||||
r = F.add(F.add(r, arr[i]), exports.hash(bigInt(arr[i]), r));
|
r = F.add(
|
||||||
|
F.add(
|
||||||
|
r,
|
||||||
|
arr[i]
|
||||||
|
),
|
||||||
|
exports.hash(F.e(arr[i]), r)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return F.affine(r);
|
return r;
|
||||||
};
|
};
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
const bn128 = require("@tornado/snarkjs").bn128;
|
const Scalar = require("ffjavascript").Scalar
|
||||||
const bigInt = require("@tornado/snarkjs").bigInt;
|
|
||||||
const Web3Utils = require("web3-utils");
|
const Web3Utils = require("web3-utils");
|
||||||
const F = bn128.Fr;
|
const ZqField = require("ffjavascript").ZqField;
|
||||||
|
const F = new ZqField(Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
|
||||||
|
|
||||||
const SEED = "mimcsponge";
|
const SEED = "mimcsponge";
|
||||||
const NROUNDS = 220;
|
const NROUNDS = 220;
|
||||||
|
|
||||||
exports.getIV = (seed) => {
|
exports.getIV = (seed) => {
|
||||||
if (typeof seed === "undefined") seed = SEED;
|
if (typeof seed === "undefined") seed = SEED;
|
||||||
const c = Web3Utils.keccak256(seed + "_iv");
|
const c = Web3Utils.keccak256(seed+"_iv");
|
||||||
const cn = bigInt(Web3Utils.toBN(c).toString());
|
const cn = Scalar.fromString(Web3Utils.toBN(c).toString());
|
||||||
const iv = cn.mod(F.q);
|
const iv = cn.mod(F.p);
|
||||||
return iv;
|
return iv;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -19,68 +19,68 @@ exports.getConstants = (seed, nRounds) => {
|
|||||||
if (typeof nRounds === "undefined") nRounds = NROUNDS;
|
if (typeof nRounds === "undefined") nRounds = NROUNDS;
|
||||||
const cts = new Array(nRounds);
|
const cts = new Array(nRounds);
|
||||||
let c = Web3Utils.keccak256(SEED);
|
let c = Web3Utils.keccak256(SEED);
|
||||||
for (let i = 1; i < nRounds; i++) {
|
for (let i=1; i<nRounds; i++) {
|
||||||
c = Web3Utils.keccak256(c);
|
c = Web3Utils.keccak256(c);
|
||||||
|
|
||||||
const n1 = Web3Utils.toBN(c).mod(Web3Utils.toBN(F.q.toString()));
|
const n1 = Web3Utils.toBN(c).mod(Web3Utils.toBN(F.p.toString()));
|
||||||
const c2 = Web3Utils.padLeft(Web3Utils.toHex(n1), 64);
|
const c2 = Web3Utils.padLeft(Web3Utils.toHex(n1), 64);
|
||||||
cts[i] = bigInt(Web3Utils.toBN(c2).toString());
|
cts[i] = F.e(Web3Utils.toBN(c2).toString());
|
||||||
}
|
}
|
||||||
cts[0] = bigInt(0);
|
cts[0] = F.e(0);
|
||||||
cts[cts.length - 1] = bigInt(0);
|
cts[cts.length - 1] = F.e(0);
|
||||||
return cts;
|
return cts;
|
||||||
};
|
};
|
||||||
|
|
||||||
const cts = exports.getConstants(SEED, NROUNDS);
|
const cts = exports.getConstants(SEED, NROUNDS);
|
||||||
|
|
||||||
exports.hash = (_xL_in, _xR_in, _k) => {
|
exports.hash = (_xL_in, _xR_in, _k) =>{
|
||||||
let xL = bigInt(_xL_in);
|
let xL = F.e(_xL_in);
|
||||||
let xR = bigInt(_xR_in);
|
let xR = F.e(_xR_in);
|
||||||
const k = bigInt(_k);
|
const k = F.e(_k);
|
||||||
for (let i = 0; i < NROUNDS; i++) {
|
for (let i=0; i<NROUNDS; i++) {
|
||||||
const c = cts[i];
|
const c = cts[i];
|
||||||
const t = i == 0 ? F.add(xL, k) : F.add(F.add(xL, k), c);
|
const t = (i==0) ? F.add(xL, k) : F.add(F.add(xL, k), c);
|
||||||
const xR_tmp = bigInt(xR);
|
const xR_tmp = F.e(xR);
|
||||||
if (i < NROUNDS - 1) {
|
if (i < (NROUNDS - 1)) {
|
||||||
xR = xL;
|
xR = xL;
|
||||||
xL = F.add(xR_tmp, F.exp(t, 5));
|
xL = F.add(xR_tmp, F.pow(t, 5));
|
||||||
} else {
|
} else {
|
||||||
xR = F.add(xR_tmp, F.exp(t, 5));
|
xR = F.add(xR_tmp, F.pow(t, 5));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
xL: F.affine(xL),
|
xL: F.normalize(xL),
|
||||||
xR: F.affine(xR),
|
xR: F.normalize(xR),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.multiHash = (arr, key, numOutputs) => {
|
exports.multiHash = (arr, key, numOutputs) => {
|
||||||
if (typeof numOutputs === "undefined") {
|
if (typeof(numOutputs) === "undefined") {
|
||||||
numOutputs = 1;
|
numOutputs = 1;
|
||||||
}
|
}
|
||||||
if (typeof key === "undefined") {
|
if (typeof(key) === "undefined") {
|
||||||
key = F.zero;
|
key = F.zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
let R = F.zero;
|
let R = F.zero;
|
||||||
let C = F.zero;
|
let C = F.zero;
|
||||||
|
|
||||||
for (let i = 0; i < arr.length; i++) {
|
for (let i=0; i<arr.length; i++) {
|
||||||
R = F.add(R, bigInt(arr[i]));
|
R = F.add(R, F.e(arr[i]));
|
||||||
const S = exports.hash(R, C, key);
|
const S = exports.hash(R, C, key);
|
||||||
R = S.xL;
|
R = S.xL;
|
||||||
C = S.xR;
|
C = S.xR;
|
||||||
}
|
}
|
||||||
let outputs = [R];
|
let outputs = [R];
|
||||||
for (let i = 1; i < numOutputs; i++) {
|
for (let i=1; i < numOutputs; i++) {
|
||||||
const S = exports.hash(R, C, key);
|
const S = exports.hash(R, C, key);
|
||||||
R = S.xL;
|
R = S.xL;
|
||||||
C = S.xR;
|
C = S.xR;
|
||||||
outputs.push(R);
|
outputs.push(R);
|
||||||
}
|
}
|
||||||
if (numOutputs == 1) {
|
if (numOutputs == 1) {
|
||||||
return F.affine(outputs[0]);
|
return F.normalize(outputs[0]);
|
||||||
} else {
|
} else {
|
||||||
return outputs.map((x) => F.affine(x));
|
return outputs.map(x => F.normalize(x));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -20,29 +20,34 @@ function createCode(seed, n) {
|
|||||||
C.push("0x00");
|
C.push("0x00");
|
||||||
C.mload();
|
C.mload();
|
||||||
C.div();
|
C.div();
|
||||||
C.push("0xf47d33b5"); // MiMCSponge(uint256,uint256)
|
C.push("0x3f1a1187"); // MiMCSponge(uint256,uint256,uint256)
|
||||||
C.eq();
|
C.eq();
|
||||||
C.jmpi("start");
|
C.jmpi("start");
|
||||||
C.invalid();
|
C.invalid();
|
||||||
|
|
||||||
C.label("start");
|
C.label("start");
|
||||||
C.push("0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001"); // q
|
C.push("0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001"); // q
|
||||||
|
C.push("0x44");
|
||||||
|
C.mload(); // k q
|
||||||
C.push("0x04");
|
C.push("0x04");
|
||||||
C.mload(); // xL q
|
C.mload(); // xL k q
|
||||||
C.dup(1); // q xL q
|
C.dup(2); // q xL k q
|
||||||
C.push("0x24");
|
C.push("0x24");
|
||||||
C.mload(); // xR q xL q
|
C.mload(); // xR q xL k q
|
||||||
C.dup(1); // q xR q xL q
|
C.dup(1); // q xR q xL k q
|
||||||
C.dup(3); // xL q xR q xL q
|
C.dup(0); // q q xR q xL k q
|
||||||
C.dup(1); // q xL q xR q xL q
|
C.dup(4); // xL q q xR q xL k q
|
||||||
C.dup(0); // q q xL q xR q xL q
|
C.dup(6); // k xL q q xR q xL k q
|
||||||
C.dup(2); // xL q q xL q xR q xL q
|
C.addmod(); // t=k+xL q xR q xL k q
|
||||||
C.dup(0); // xL xL q q xL q xR q xL q
|
C.dup(1); // q t q xR q xL k q
|
||||||
C.mulmod(); // b=xL^2 q xL q xR q xL q
|
C.dup(0); // q q t q xR q xL k q
|
||||||
C.dup(0); // b b q xL q xR q xL q
|
C.dup(2); // t q q t q xR q xL k q
|
||||||
C.mulmod(); // c=xL^4 xL q xR q xL q
|
C.dup(0); // t t q q t q xR q xL k q
|
||||||
C.mulmod(); // d=xL^5 xR q xL q
|
C.mulmod(); // b=t^2 q t q xR q xL k q
|
||||||
C.addmod(); // e=xL^5+xR xL q (for next round: xL xR q)
|
C.dup(0); // b b q t q xR q xL k q
|
||||||
|
C.mulmod(); // c=t^4 t q xR q xL k q
|
||||||
|
C.mulmod(); // d=t^5 xR q xL k q
|
||||||
|
C.addmod(); // e=t^5+xR xL k q (for next round: xL xR k q)
|
||||||
|
|
||||||
for (let i=0; i<n-1; i++) {
|
for (let i=0; i<n-1; i++) {
|
||||||
if (i < n-2) {
|
if (i < n-2) {
|
||||||
@ -50,24 +55,27 @@ function createCode(seed, n) {
|
|||||||
} else {
|
} else {
|
||||||
ci = "0x00";
|
ci = "0x00";
|
||||||
}
|
}
|
||||||
C.swap(1); // xR xL q
|
C.swap(1); // xR xL k q
|
||||||
C.dup(2); // q xR xL q
|
C.dup(3); // q xR xL k q
|
||||||
C.dup(2); // xL q xR xL q
|
C.dup(3); // k q xR xL k q
|
||||||
C.push(ci); // ci xL q xR xL q
|
C.dup(1); // q k q xR xL k q
|
||||||
C.addmod(); // a=ci+xL xR xL q
|
C.dup(4); // xL q k q xR xL k q
|
||||||
C.dup(3); // q a xR xL q
|
C.push(ci); // ci xL q k q xR xL k q
|
||||||
C.swap(1); // a q xR xL q
|
C.addmod(); // a=ci+xL k q xR xL k q
|
||||||
C.dup(1); // q a q xR xL q
|
C.addmod(); // t=a+k xR xL k q
|
||||||
C.dup(0); // q q a q xR xL q
|
C.dup(4); // q t xR xL k q
|
||||||
C.dup(2); // a q q a q xR xL q
|
C.swap(1); // t q xR xL k q
|
||||||
C.dup(0); // a a q q a q xR xL q
|
C.dup(1); // q t q xR xL k q
|
||||||
C.mulmod(); // b=a^2 q a q xR xL q
|
C.dup(0); // q q t q xR xL k q
|
||||||
C.dup(0); // b b q a q xR xL q
|
C.dup(2); // t q q t q xR xL k q
|
||||||
C.mulmod(); // c=a^4 a q xR xL q
|
C.dup(0); // t t q q t q xR xL k q
|
||||||
C.mulmod(); // d=a^5 xR xL q
|
C.mulmod(); // b=t^2 q t q xR xL k q
|
||||||
C.dup(3); // q d xR xL q
|
C.dup(0); // b b q t q xR xL k q
|
||||||
C.swap(2); // xR d q xL q
|
C.mulmod(); // c=t^4 t q xR xL k q
|
||||||
C.addmod(); // e=a^5+xR xL q (for next round: xL xR q)
|
C.mulmod(); // d=t^5 xR xL k q
|
||||||
|
C.dup(4); // q d xR xL k q
|
||||||
|
C.swap(2); // xR d q xL k q
|
||||||
|
C.addmod(); // e=t^5+xR xL k q (for next round: xL xR k q)
|
||||||
}
|
}
|
||||||
|
|
||||||
C.push("0x20");
|
C.push("0x20");
|
||||||
@ -92,6 +100,10 @@ module.exports.abi = [
|
|||||||
{
|
{
|
||||||
"name": "xR_in",
|
"name": "xR_in",
|
||||||
"type": "uint256"
|
"type": "uint256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "k",
|
||||||
|
"type": "uint256"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"name": "MiMCSponge",
|
"name": "MiMCSponge",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
const bn128 = require("@tornado/snarkjs").bn128;
|
|
||||||
const bigInt = require("@tornado/snarkjs").bigInt;
|
|
||||||
const babyJub = require("./babyjub");
|
const babyJub = require("./babyjub");
|
||||||
const createBlakeHash = require("blake-hash");
|
const createBlakeHash = require("blake-hash");
|
||||||
|
const blake2b = require("blake2b");
|
||||||
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
|
|
||||||
const GENPOINT_PREFIX = "PedersenGenerator";
|
const GENPOINT_PREFIX = "PedersenGenerator";
|
||||||
const windowSize = 4;
|
const windowSize = 4;
|
||||||
@ -10,47 +10,57 @@ const nWindowsPerSegment = 50;
|
|||||||
exports.hash = pedersenHash;
|
exports.hash = pedersenHash;
|
||||||
exports.getBasePoint = getBasePoint;
|
exports.getBasePoint = getBasePoint;
|
||||||
|
|
||||||
function pedersenHash(msg) {
|
function baseHash(type, S) {
|
||||||
const bitsPerSegment = windowSize * nWindowsPerSegment;
|
if (type == "blake") {
|
||||||
|
return createBlakeHash("blake256").update(S).digest();
|
||||||
|
} else if (type == "blake2b") {
|
||||||
|
return Buffer.from(blake2b(32).update(Buffer.from(S)).digest());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function pedersenHash(msg, options) {
|
||||||
|
options = options || {};
|
||||||
|
options.baseHash = options.baseHash || "blake";
|
||||||
|
const bitsPerSegment = windowSize*nWindowsPerSegment;
|
||||||
const bits = buffer2bits(msg);
|
const bits = buffer2bits(msg);
|
||||||
|
|
||||||
const nSegments = Math.floor((bits.length - 1) / (windowSize * nWindowsPerSegment)) + 1;
|
const nSegments = Math.floor((bits.length - 1)/(windowSize*nWindowsPerSegment)) +1;
|
||||||
|
|
||||||
let accP = [bigInt.zero, bigInt.one];
|
let accP = [babyJub.F.zero,babyJub.F.one];
|
||||||
|
|
||||||
for (let s = 0; s < nSegments; s++) {
|
for (let s=0; s<nSegments; s++) {
|
||||||
let nWindows;
|
let nWindows;
|
||||||
if (s == nSegments - 1) {
|
if (s == nSegments-1) {
|
||||||
nWindows = Math.floor((bits.length - (nSegments - 1) * bitsPerSegment - 1) / windowSize) + 1;
|
nWindows = Math.floor(((bits.length - (nSegments - 1)*bitsPerSegment) - 1) / windowSize) +1;
|
||||||
} else {
|
} else {
|
||||||
nWindows = nWindowsPerSegment;
|
nWindows = nWindowsPerSegment;
|
||||||
}
|
}
|
||||||
let escalar = bigInt.zero;
|
let escalar = Scalar.e(0);
|
||||||
let exp = bigInt.one;
|
let exp = Scalar.e(1);
|
||||||
for (let w = 0; w < nWindows; w++) {
|
for (let w=0; w<nWindows; w++) {
|
||||||
let o = s * bitsPerSegment + w * windowSize;
|
let o = s*bitsPerSegment + w*windowSize;
|
||||||
let acc = bigInt.one;
|
let acc = Scalar.e(1);
|
||||||
for (let b = 0; b < windowSize - 1 && o < bits.length; b++) {
|
for (let b=0; ((b<windowSize-1)&&(o<bits.length)) ; b++) {
|
||||||
if (bits[o]) {
|
if (bits[o]) {
|
||||||
acc = acc.add(bigInt.one.shl(b));
|
acc = Scalar.add(acc, Scalar.shl(Scalar.e(1), b) );
|
||||||
}
|
}
|
||||||
o++;
|
o++;
|
||||||
}
|
}
|
||||||
if (o < bits.length) {
|
if (o<bits.length) {
|
||||||
if (bits[o]) {
|
if (bits[o]) {
|
||||||
acc = acc.neg();
|
acc = Scalar.neg(acc);
|
||||||
}
|
}
|
||||||
o++;
|
o++;
|
||||||
}
|
}
|
||||||
escalar = escalar.add(acc.mul(exp));
|
escalar = Scalar.add(escalar, Scalar.mul(acc, exp));
|
||||||
exp = exp.shl(windowSize + 1);
|
exp = Scalar.shl(exp, windowSize+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (escalar.lesser(bigInt.zero)) {
|
if (Scalar.lt(escalar, 0)) {
|
||||||
escalar = babyJub.subOrder.add(escalar);
|
escalar = Scalar.add( escalar, babyJub.subOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
accP = babyJub.addPoint(accP, babyJub.mulPointEscalar(getBasePoint(s), escalar));
|
accP = babyJub.addPoint(accP, babyJub.mulPointEscalar(getBasePoint(options.baseHash, s), escalar));
|
||||||
}
|
}
|
||||||
|
|
||||||
return babyJub.packPoint(accP);
|
return babyJub.packPoint(accP);
|
||||||
@ -58,14 +68,14 @@ function pedersenHash(msg) {
|
|||||||
|
|
||||||
let bases = [];
|
let bases = [];
|
||||||
|
|
||||||
function getBasePoint(pointIdx) {
|
function getBasePoint(baseHashType, pointIdx) {
|
||||||
if (pointIdx < bases.length) return bases[pointIdx];
|
if (pointIdx<bases.length) return bases[pointIdx];
|
||||||
let p = null;
|
let p= null;
|
||||||
let tryIdx = 0;
|
let tryIdx = 0;
|
||||||
while (p == null) {
|
while (p==null) {
|
||||||
const S = GENPOINT_PREFIX + "_" + padLeftZeros(pointIdx, 32) + "_" + padLeftZeros(tryIdx, 32);
|
const S = GENPOINT_PREFIX + "_" + padLeftZeros(pointIdx, 32) + "_" + padLeftZeros(tryIdx, 32);
|
||||||
const h = createBlakeHash("blake256").update(S).digest();
|
const h = baseHash(baseHashType, S);
|
||||||
h[31] = h[31] & 0xbf; // Set 255th bit to 0 (256th is the signal and 254th is the last possible bit to 1)
|
h[31] = h[31] & 0xBF; // Set 255th bit to 0 (256th is the signal and 254th is the last possible bit to 1)
|
||||||
p = babyJub.unpackPoint(h);
|
p = babyJub.unpackPoint(h);
|
||||||
tryIdx++;
|
tryIdx++;
|
||||||
}
|
}
|
||||||
@ -82,7 +92,7 @@ function getBasePoint(pointIdx) {
|
|||||||
|
|
||||||
function padLeftZeros(idx, n) {
|
function padLeftZeros(idx, n) {
|
||||||
let sidx = "" + idx;
|
let sidx = "" + idx;
|
||||||
while (sidx.length < n) sidx = "0" + sidx;
|
while (sidx.length<n) sidx = "0"+sidx;
|
||||||
return sidx;
|
return sidx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,17 +101,21 @@ Input a buffer
|
|||||||
Returns an array of booleans. 0 is LSB of first byte and so on.
|
Returns an array of booleans. 0 is LSB of first byte and so on.
|
||||||
*/
|
*/
|
||||||
function buffer2bits(buff) {
|
function buffer2bits(buff) {
|
||||||
const res = new Array(buff.length * 8);
|
const res = new Array(buff.length*8);
|
||||||
for (let i = 0; i < buff.length; i++) {
|
for (let i=0; i<buff.length; i++) {
|
||||||
const b = buff[i];
|
const b = buff[i];
|
||||||
res[i * 8] = b & 0x01;
|
res[i*8] = b & 0x01;
|
||||||
res[i * 8 + 1] = b & 0x02;
|
res[i*8+1] = b & 0x02;
|
||||||
res[i * 8 + 2] = b & 0x04;
|
res[i*8+2] = b & 0x04;
|
||||||
res[i * 8 + 3] = b & 0x08;
|
res[i*8+3] = b & 0x08;
|
||||||
res[i * 8 + 4] = b & 0x10;
|
res[i*8+4] = b & 0x10;
|
||||||
res[i * 8 + 5] = b & 0x20;
|
res[i*8+5] = b & 0x20;
|
||||||
res[i * 8 + 6] = b & 0x40;
|
res[i*8+6] = b & 0x40;
|
||||||
res[i * 8 + 7] = b & 0x80;
|
res[i*8+7] = b & 0x80;
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,7 +7,15 @@ if (typeof process.argv[2] != "undefined") {
|
|||||||
nBases = 5;
|
nBases = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let baseHash;
|
||||||
|
if (typeof process.argv[3] != "undefined") {
|
||||||
|
baseHash = process.argv[3];
|
||||||
|
} else {
|
||||||
|
baseHash = "blake";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
for (let i=0; i < nBases; i++) {
|
for (let i=0; i < nBases; i++) {
|
||||||
const p = pedersenHash.getBasePoint(i);
|
const p = pedersenHash.getBasePoint(baseHash, i);
|
||||||
console.log(`[${p[0]},${p[1]}]`);
|
console.log(`[${p[0]},${p[1]}]`);
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
const assert = require("assert");
|
const assert = require("assert");
|
||||||
const bn128 = require("@tornado/snarkjs").bn128;
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
const bigInt = require("@tornado/snarkjs").bigInt;
|
const ZqField = require("ffjavascript").ZqField;
|
||||||
const F = bn128.Fr;
|
const { unstringifyBigInts } = require("ffjavascript").utils;
|
||||||
const { unstringifyBigInts } = require("@tornado/snarkjs");
|
|
||||||
|
|
||||||
// Prime 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001
|
// Prime 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001
|
||||||
// const F = new ZqField(Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
|
const F = new ZqField(Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
|
||||||
|
|
||||||
// Parameters are generated by a reference script https://extgit.iaik.tugraz.at/krypto/hadeshash/-/blob/master/code/generate_parameters_grain.sage
|
// Parameters are generated by a reference script https://extgit.iaik.tugraz.at/krypto/hadeshash/-/blob/master/code/generate_parameters_grain.sage
|
||||||
// Used like so: sage generate_parameters_grain.sage 1 0 254 2 8 56 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001
|
// Used like so: sage generate_parameters_grain.sage 1 0 254 2 8 56 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001
|
||||||
@ -17,7 +16,7 @@ const { C, M } = unstringifyBigInts(require("./poseidon_constants.json"));
|
|||||||
const N_ROUNDS_F = 8;
|
const N_ROUNDS_F = 8;
|
||||||
const N_ROUNDS_P = 35;
|
const N_ROUNDS_P = 35;
|
||||||
|
|
||||||
const pow5 = (a) => F.mul(a, F.square(F.square(a, a)));
|
const pow5 = a => F.mul(a, F.square(F.square(a, a)));
|
||||||
|
|
||||||
function poseidon(inputs) {
|
function poseidon(inputs) {
|
||||||
assert(inputs.length > 0);
|
assert(inputs.length > 0);
|
||||||
@ -27,22 +26,23 @@ function poseidon(inputs) {
|
|||||||
const nRoundsF = N_ROUNDS_F;
|
const nRoundsF = N_ROUNDS_F;
|
||||||
const nRoundsP = N_ROUNDS_P;
|
const nRoundsP = N_ROUNDS_P;
|
||||||
|
|
||||||
let state = [...inputs.map((a) => bigInt(a)), F.zero];
|
let state = [...inputs.map(a => F.e(a)), F.zero];
|
||||||
for (let r = 0; r < nRoundsF + nRoundsP; r++) {
|
for (let r = 0; r < nRoundsF + nRoundsP; r++) {
|
||||||
state = state.map((a, i) => F.add(a, bigInt(C[t - 2][r * t + i])));
|
state = state.map((a, i) => F.add(a, BigInt(C[t - 2][r * t + i])));
|
||||||
|
|
||||||
if (r < nRoundsF / 2 || r >= nRoundsF / 2 + nRoundsP) {
|
if (r < nRoundsF / 2 || r >= nRoundsF / 2 + nRoundsP) {
|
||||||
state = state.map((a) => pow5(a));
|
state = state.map(a => pow5(a));
|
||||||
} else {
|
} else {
|
||||||
state[0] = pow5(state[0]);
|
state[0] = pow5(state[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// no matrix multiplication in the last round
|
// no matrix multiplication in the last round
|
||||||
if (r < nRoundsF + nRoundsP - 1) {
|
if (r < nRoundsF + nRoundsP - 1) {
|
||||||
state = state.map((_, i) => state.reduce((acc, a, j) => F.add(acc, F.mul(bigInt(M[t - 2][j][i]), a)), F.zero));
|
state = state.map((_, i) =>
|
||||||
|
state.reduce((acc, a, j) => F.add(acc, F.mul(BigInt(M[t - 2][j][i]), a)), F.zero)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return F.affine(state[0]);
|
return F.normalize(state[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = poseidon;
|
module.exports = poseidon;
|
||||||
|
@ -3,10 +3,10 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
const Contract = require("./evmasm");
|
const Contract = require("./evmasm");
|
||||||
const { unstringifyBigInts } = require("@tornado/snarkjs");
|
const { unstringifyBigInts } = require("ffjavascript").utils;
|
||||||
const Web3Utils = require("web3-utils");
|
const Web3Utils = require("web3-utils");
|
||||||
|
|
||||||
const { C: K, M } = unstringifyBigInts(require("./poseidon_constants.json"));
|
const { C:K, M } = unstringifyBigInts(require("./poseidon_constants.json"));
|
||||||
|
|
||||||
const N_ROUNDS_F = 8;
|
const N_ROUNDS_F = 8;
|
||||||
const N_ROUNDS_P = 35;
|
const N_ROUNDS_P = 35;
|
||||||
@ -16,12 +16,13 @@ function toHex256(a) {
|
|||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
let S = a.toString(16);
|
let S = a.toString(16);
|
||||||
while (S.length < 64) S = "0" + S;
|
while (S.length < 64) S="0"+S;
|
||||||
return "0x" + S;
|
return "0x" + S;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createCode(nInputs) {
|
function createCode(nInputs) {
|
||||||
if (nInputs < 1 || nInputs > 4) throw new Error("Invalid number of inputs. Must be 1<=nInputs<=8");
|
|
||||||
|
if (( nInputs<1) || (nInputs>4)) throw new Error("Invalid number of inputs. Must be 1<=nInputs<=8");
|
||||||
const t = nInputs + 1;
|
const t = nInputs + 1;
|
||||||
const nRoundsF = N_ROUNDS_F;
|
const nRoundsF = N_ROUNDS_F;
|
||||||
const nRoundsP = N_ROUNDS_P;
|
const nRoundsP = N_ROUNDS_P;
|
||||||
@ -29,21 +30,20 @@ function createCode(nInputs) {
|
|||||||
const C = new Contract();
|
const C = new Contract();
|
||||||
|
|
||||||
function saveM() {
|
function saveM() {
|
||||||
for (let i = 0; i < t; i++) {
|
for (let i=0; i<t; i++) {
|
||||||
for (let j = 0; j < t; j++) {
|
for (let j=0; j<t; j++) {
|
||||||
C.push(toHex256(M[t - 2][j][i]));
|
C.push(toHex256(M[t-2][j][i]));
|
||||||
C.push((1 + i * t + j) * 32);
|
C.push((1+i*t+j)*32);
|
||||||
C.mstore();
|
C.mstore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function ark(r) {
|
function ark(r) { // st, q
|
||||||
// st, q
|
for (let i=0; i<t; i++) {
|
||||||
for (let i = 0; i < t; i++) {
|
|
||||||
C.dup(t); // q, st, q
|
C.dup(t); // q, st, q
|
||||||
C.push(toHex256(K[t - 2][r * t + i])); // K, q, st, q
|
C.push(toHex256(K[t-2][r*t+i])); // K, q, st, q
|
||||||
C.dup(2 + i); // st[i], K, q, st, q
|
C.dup(2+i); // st[i], K, q, st, q
|
||||||
C.addmod(); // newSt[i], st, q
|
C.addmod(); // newSt[i], st, q
|
||||||
C.swap(1 + i); // xx, st, q
|
C.swap(1 + i); // xx, st, q
|
||||||
C.pop();
|
C.pop();
|
||||||
@ -52,44 +52,44 @@ function createCode(nInputs) {
|
|||||||
|
|
||||||
function sigma(p) {
|
function sigma(p) {
|
||||||
// sq, q
|
// sq, q
|
||||||
C.dup(t); // q, st, q
|
C.dup(t); // q, st, q
|
||||||
C.dup(1 + p); // st[p] , q , st, q
|
C.dup(1+p); // st[p] , q , st, q
|
||||||
C.dup(1); // q, st[p] , q , st, q
|
C.dup(1); // q, st[p] , q , st, q
|
||||||
C.dup(0); // q, q, st[p] , q , st, q
|
C.dup(0); // q, q, st[p] , q , st, q
|
||||||
C.dup(2); // st[p] , q, q, st[p] , q , st, q
|
C.dup(2); // st[p] , q, q, st[p] , q , st, q
|
||||||
C.dup(0); // st[p] , st[p] , q, q, st[p] , q , st, q
|
C.dup(0); // st[p] , st[p] , q, q, st[p] , q , st, q
|
||||||
C.mulmod(); // st2[p], q, st[p] , q , st, q
|
C.mulmod(); // st2[p], q, st[p] , q , st, q
|
||||||
C.dup(0); // st2[p], st2[p], q, st[p] , q , st, q
|
C.dup(0); // st2[p], st2[p], q, st[p] , q , st, q
|
||||||
C.mulmod(); // st4[p], st[p] , q , st, q
|
C.mulmod(); // st4[p], st[p] , q , st, q
|
||||||
C.mulmod(); // st5[p], st, q
|
C.mulmod(); // st5[p], st, q
|
||||||
C.swap(1 + p);
|
C.swap(1+p);
|
||||||
C.pop(); // newst, q
|
C.pop(); // newst, q
|
||||||
}
|
}
|
||||||
|
|
||||||
function mix() {
|
function mix() {
|
||||||
C.label("mix");
|
C.label("mix");
|
||||||
for (let i = 0; i < t; i++) {
|
for (let i=0; i<t; i++) {
|
||||||
for (let j = 0; j < t; j++) {
|
for (let j=0; j<t; j++) {
|
||||||
if (j == 0) {
|
if (j==0) {
|
||||||
C.dup(i + t); // q, newSt, oldSt, q
|
C.dup(i+t); // q, newSt, oldSt, q
|
||||||
C.push((1 + i * t + j) * 32);
|
C.push((1+i*t+j)*32);
|
||||||
C.mload(); // M, q, newSt, oldSt, q
|
C.mload(); // M, q, newSt, oldSt, q
|
||||||
C.dup(2 + i + j); // oldSt[j], M, q, newSt, oldSt, q
|
C.dup(2+i+j); // oldSt[j], M, q, newSt, oldSt, q
|
||||||
C.mulmod(); // acc, newSt, oldSt, q
|
C.mulmod(); // acc, newSt, oldSt, q
|
||||||
} else {
|
} else {
|
||||||
C.dup(1 + i + t); // q, acc, newSt, oldSt, q
|
C.dup(1+i+t); // q, acc, newSt, oldSt, q
|
||||||
C.push((1 + i * t + j) * 32);
|
C.push((1+i*t+j)*32);
|
||||||
C.mload(); // M, q, acc, newSt, oldSt, q
|
C.mload(); // M, q, acc, newSt, oldSt, q
|
||||||
C.dup(3 + i + j); // oldSt[j], M, q, acc, newSt, oldSt, q
|
C.dup(3+i+j); // oldSt[j], M, q, acc, newSt, oldSt, q
|
||||||
C.mulmod(); // aux, acc, newSt, oldSt, q
|
C.mulmod(); // aux, acc, newSt, oldSt, q
|
||||||
C.dup(2 + i + t); // q, aux, acc, newSt, oldSt, q
|
C.dup(2+i+t); // q, aux, acc, newSt, oldSt, q
|
||||||
C.swap(2); // acc, aux, q, newSt, oldSt, q
|
C.swap(2); // acc, aux, q, newSt, oldSt, q
|
||||||
C.addmod(); // acc, newSt, oldSt, q
|
C.addmod(); // acc, newSt, oldSt, q
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (let i = 0; i < t; i++) {
|
for (let i=0; i<t; i++) {
|
||||||
C.swap(t - i + (t - i - 1));
|
C.swap((t -i) + (t -i-1));
|
||||||
C.pop();
|
C.pop();
|
||||||
}
|
}
|
||||||
C.push(0);
|
C.push(0);
|
||||||
@ -97,6 +97,7 @@ function createCode(nInputs) {
|
|||||||
C.jmp();
|
C.jmp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Check selector
|
// Check selector
|
||||||
C.push("0x0100000000000000000000000000000000000000000000000000000000");
|
C.push("0x0100000000000000000000000000000000000000000000000000000000");
|
||||||
C.push(0);
|
C.push(0);
|
||||||
@ -116,27 +117,27 @@ function createCode(nInputs) {
|
|||||||
|
|
||||||
saveM();
|
saveM();
|
||||||
|
|
||||||
C.push("0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001"); // q
|
C.push("0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001"); // q
|
||||||
|
|
||||||
// Load t values from the call data.
|
// Load t values from the call data.
|
||||||
// The function has a single array param param
|
// The function has a single array param param
|
||||||
// [Selector (4)] [item1 (32)] [item2 (32)] ....
|
// [Selector (4)] [item1 (32)] [item2 (32)] ....
|
||||||
// Stack positions 0-nInputs.
|
// Stack positions 0-nInputs.
|
||||||
for (let i = 0; i < t; i++) {
|
for (let i=0; i<t; i++) {
|
||||||
C.push(0x04 + 0x20 * (nInputs - i));
|
C.push(0x04+(0x20*(nInputs-i)));
|
||||||
C.calldataload();
|
C.calldataload();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < nRoundsF + nRoundsP - 1; i++) {
|
for (let i=0; i<nRoundsF+nRoundsP-1; i++) {
|
||||||
ark(i);
|
ark(i);
|
||||||
if (i < nRoundsF / 2 || i >= nRoundsP + nRoundsF / 2) {
|
if ((i<nRoundsF/2) || (i>=nRoundsP+nRoundsF/2)) {
|
||||||
for (let j = 0; j < t; j++) {
|
for (let j=0; j<t; j++) {
|
||||||
sigma(j);
|
sigma(j);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sigma(0);
|
sigma(0);
|
||||||
}
|
}
|
||||||
const strLabel = "aferMix" + i;
|
const strLabel = "aferMix"+i;
|
||||||
C._pushLabel(strLabel);
|
C._pushLabel(strLabel);
|
||||||
C.push(0);
|
C.push(0);
|
||||||
C.mstore();
|
C.mstore();
|
||||||
@ -144,15 +145,15 @@ function createCode(nInputs) {
|
|||||||
C.label(strLabel);
|
C.label(strLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
C.push(toHex256(K[t - 2][(nRoundsF + nRoundsP - 1) * t])); // K, st, q
|
C.push(toHex256(K[t-2][(nRoundsF+nRoundsP-1)*t])); // K, st, q
|
||||||
C.dup(t + 1); // q, K, st, q
|
C.dup(t+1); // q, K, st, q
|
||||||
C.swap(2); // st[0], K, q, st\st[0]
|
C.swap(2); // st[0], K, q, st\st[0]
|
||||||
C.addmod(); // st q
|
C.addmod(); // st q
|
||||||
|
|
||||||
sigma(0);
|
sigma(0);
|
||||||
|
|
||||||
C.push("0x00");
|
C.push("0x00");
|
||||||
C.mstore(); // Save it to pos 0;
|
C.mstore(); // Save it to pos 0;
|
||||||
C.push("0x20");
|
C.push("0x20");
|
||||||
C.push("0x00");
|
C.push("0x00");
|
||||||
C.return();
|
C.return();
|
||||||
@ -165,49 +166,51 @@ function createCode(nInputs) {
|
|||||||
function generateABI(nInputs) {
|
function generateABI(nInputs) {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
constant: true,
|
"constant": true,
|
||||||
inputs: [
|
"inputs": [
|
||||||
{
|
{
|
||||||
internalType: `bytes32[${nInputs}]`,
|
"internalType": `bytes32[${nInputs}]`,
|
||||||
name: "input",
|
"name": "input",
|
||||||
type: `bytes32[${nInputs}]`,
|
"type": `bytes32[${nInputs}]`
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
name: "poseidon",
|
"name": "poseidon",
|
||||||
outputs: [
|
"outputs": [
|
||||||
{
|
{
|
||||||
internalType: "bytes32",
|
"internalType": "bytes32",
|
||||||
name: "",
|
"name": "",
|
||||||
type: "bytes32",
|
"type": "bytes32"
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
payable: false,
|
"payable": false,
|
||||||
stateMutability: "pure",
|
"stateMutability": "pure",
|
||||||
type: "function",
|
"type": "function"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
constant: true,
|
"constant": true,
|
||||||
inputs: [
|
"inputs": [
|
||||||
{
|
{
|
||||||
internalType: `uint256[${nInputs}]`,
|
"internalType": `uint256[${nInputs}]`,
|
||||||
name: "input",
|
"name": "input",
|
||||||
type: `uint256[${nInputs}]`,
|
"type": `uint256[${nInputs}]`
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
name: "poseidon",
|
"name": "poseidon",
|
||||||
outputs: [
|
"outputs": [
|
||||||
{
|
{
|
||||||
internalType: "uint256",
|
"internalType": "uint256",
|
||||||
name: "",
|
"name": "",
|
||||||
type: "uint256",
|
"type": "uint256"
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
payable: false,
|
"payable": false,
|
||||||
stateMutability: "pure",
|
"stateMutability": "pure",
|
||||||
type: "function",
|
"type": "function"
|
||||||
},
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.generateABI = generateABI;
|
module.exports.generateABI = generateABI;
|
||||||
module.exports.createCode = createCode;
|
module.exports.createCode = createCode;
|
||||||
|
|
||||||
|
|
||||||
|
101
src/smt.js
101
src/smt.js
@ -1,35 +1,26 @@
|
|||||||
const bigInt = require("@tornado/snarkjs").bigInt;
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
|
|
||||||
const SMTMemDB = require("./smt_memdb");
|
const SMTMemDB = require("./smt_memdb");
|
||||||
const { hash0, hash1 } = require("./smt_hashes_poseidon");
|
const {hash0, hash1, F} = require("./smt_hashes_poseidon");
|
||||||
|
|
||||||
class SMT {
|
class SMT {
|
||||||
|
|
||||||
constructor(db, root) {
|
constructor(db, root) {
|
||||||
this.db = db;
|
this.db = db;
|
||||||
this.root = root;
|
this.root = root;
|
||||||
}
|
}
|
||||||
|
|
||||||
_splitBits(_key) {
|
_splitBits(_key) {
|
||||||
let k = bigInt(_key);
|
const res = Scalar.bits(_key);
|
||||||
const res = [];
|
|
||||||
|
|
||||||
while (!k.isZero()) {
|
while (res.length<256) res.push(false);
|
||||||
if (k.isOdd()) {
|
|
||||||
res.push(true);
|
|
||||||
} else {
|
|
||||||
res.push(false);
|
|
||||||
}
|
|
||||||
k = k.shr(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (res.length < 256) res.push(false);
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
async update(_key, _newValue) {
|
async update(_key, _newValue) {
|
||||||
const key = bigInt(_key);
|
const key = Scalar.e(_key);
|
||||||
const newValue = bigInt(_newValue);
|
const newValue = F.e(_newValue);
|
||||||
|
|
||||||
|
|
||||||
const resFind = await this.find(key);
|
const resFind = await this.find(key);
|
||||||
const res = {};
|
const res = {};
|
||||||
@ -45,11 +36,11 @@ class SMT {
|
|||||||
|
|
||||||
let rtOld = hash1(key, resFind.foundValue);
|
let rtOld = hash1(key, resFind.foundValue);
|
||||||
let rtNew = hash1(key, newValue);
|
let rtNew = hash1(key, newValue);
|
||||||
ins.push([rtNew, [1, key, newValue]]);
|
ins.push([rtNew, [1, key, newValue ]]);
|
||||||
dels.push(rtOld);
|
dels.push(rtOld);
|
||||||
|
|
||||||
const keyBits = this._splitBits(key);
|
const keyBits = this._splitBits(key);
|
||||||
for (let level = resFind.siblings.length - 1; level >= 0; level--) {
|
for (let level = resFind.siblings.length-1; level >=0; level--) {
|
||||||
let oldNode, newNode;
|
let oldNode, newNode;
|
||||||
const sibling = resFind.siblings[level];
|
const sibling = resFind.siblings[level];
|
||||||
if (keyBits[level]) {
|
if (keyBits[level]) {
|
||||||
@ -67,16 +58,16 @@ class SMT {
|
|||||||
|
|
||||||
res.newRoot = rtNew;
|
res.newRoot = rtNew;
|
||||||
|
|
||||||
|
await this.db.multiDel(dels);
|
||||||
await this.db.multiIns(ins);
|
await this.db.multiIns(ins);
|
||||||
await this.db.setRoot(rtNew);
|
await this.db.setRoot(rtNew);
|
||||||
this.root = rtNew;
|
this.root = rtNew;
|
||||||
await this.db.multiDel(dels);
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
async delete(_key) {
|
async delete(_key) {
|
||||||
const key = bigInt(_key);
|
const key = Scalar.e(_key);
|
||||||
|
|
||||||
const resFind = await this.find(key);
|
const resFind = await this.find(key);
|
||||||
if (!resFind.found) throw new Error("Key does not exists");
|
if (!resFind.found) throw new Error("Key does not exists");
|
||||||
@ -84,7 +75,7 @@ class SMT {
|
|||||||
const res = {
|
const res = {
|
||||||
siblings: [],
|
siblings: [],
|
||||||
delKey: key,
|
delKey: key,
|
||||||
delValue: resFind.foundValue,
|
delValue: resFind.foundValue
|
||||||
};
|
};
|
||||||
|
|
||||||
const dels = [];
|
const dels = [];
|
||||||
@ -96,7 +87,7 @@ class SMT {
|
|||||||
let mixed;
|
let mixed;
|
||||||
if (resFind.siblings.length > 0) {
|
if (resFind.siblings.length > 0) {
|
||||||
const record = await this.db.get(resFind.siblings[resFind.siblings.length - 1]);
|
const record = await this.db.get(resFind.siblings[resFind.siblings.length - 1]);
|
||||||
if (record.length == 3 && record[0].equals(bigInt.one)) {
|
if ((record.length == 3)&&(F.eq(record[0], F.one))) {
|
||||||
mixed = false;
|
mixed = false;
|
||||||
res.oldKey = record[1];
|
res.oldKey = record[1];
|
||||||
res.oldValue = record[2];
|
res.oldValue = record[2];
|
||||||
@ -105,25 +96,25 @@ class SMT {
|
|||||||
} else if (record.length == 2) {
|
} else if (record.length == 2) {
|
||||||
mixed = true;
|
mixed = true;
|
||||||
res.oldKey = key;
|
res.oldKey = key;
|
||||||
res.oldValue = bigInt(0);
|
res.oldValue = F.zero;
|
||||||
res.isOld0 = true;
|
res.isOld0 = true;
|
||||||
rtNew = bigInt.zero;
|
rtNew = F.zero;
|
||||||
} else {
|
} else {
|
||||||
throw new Error("Invalid node. Database corrupted");
|
throw new Error("Invalid node. Database corrupted");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rtNew = bigInt.zero;
|
rtNew = F.zero;
|
||||||
res.oldKey = key;
|
res.oldKey = key;
|
||||||
res.oldValue = bigInt(0);
|
res.oldValue = F.zero;
|
||||||
res.isOld0 = true;
|
res.isOld0 = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const keyBits = this._splitBits(key);
|
const keyBits = this._splitBits(key);
|
||||||
|
|
||||||
for (let level = resFind.siblings.length - 1; level >= 0; level--) {
|
for (let level = resFind.siblings.length-1; level >=0; level--) {
|
||||||
let newSibling = resFind.siblings[level];
|
let newSibling = resFind.siblings[level];
|
||||||
if (level == resFind.siblings.length - 1 && !res.isOld0) {
|
if ((level == resFind.siblings.length-1)&&(!res.isOld0)) {
|
||||||
newSibling = bigInt.zero;
|
newSibling = F.zero;
|
||||||
}
|
}
|
||||||
const oldSibling = resFind.siblings[level];
|
const oldSibling = resFind.siblings[level];
|
||||||
if (keyBits[level]) {
|
if (keyBits[level]) {
|
||||||
@ -132,7 +123,7 @@ class SMT {
|
|||||||
rtOld = hash0(rtOld, oldSibling);
|
rtOld = hash0(rtOld, oldSibling);
|
||||||
}
|
}
|
||||||
dels.push(rtOld);
|
dels.push(rtOld);
|
||||||
if (!newSibling.isZero()) {
|
if (!F.isZero(newSibling)) {
|
||||||
mixed = true;
|
mixed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,8 +152,8 @@ class SMT {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async insert(_key, _value) {
|
async insert(_key, _value) {
|
||||||
const key = bigInt(_key);
|
const key = Scalar.e(_key);
|
||||||
const value = bigInt(_value);
|
const value = F.e(_value);
|
||||||
let addedOne = false;
|
let addedOne = false;
|
||||||
const res = {};
|
const res = {};
|
||||||
res.oldRoot = this.root;
|
res.oldRoot = this.root;
|
||||||
@ -179,26 +170,26 @@ class SMT {
|
|||||||
|
|
||||||
if (!resFind.isOld0) {
|
if (!resFind.isOld0) {
|
||||||
const oldKeyits = this._splitBits(resFind.notFoundKey);
|
const oldKeyits = this._splitBits(resFind.notFoundKey);
|
||||||
for (let i = res.siblings.length; oldKeyits[i] == newKeyBits[i]; i++) {
|
for (let i= res.siblings.length; oldKeyits[i] == newKeyBits[i]; i++) {
|
||||||
res.siblings.push(bigInt.zero);
|
res.siblings.push(F.zero);
|
||||||
}
|
}
|
||||||
rtOld = hash1(resFind.notFoundKey, resFind.notFoundValue);
|
rtOld = hash1(resFind.notFoundKey, resFind.notFoundValue);
|
||||||
res.siblings.push(rtOld);
|
res.siblings.push(rtOld);
|
||||||
addedOne = true;
|
addedOne = true;
|
||||||
mixed = false;
|
mixed = false;
|
||||||
} else if (res.siblings.length > 0) {
|
} else if (res.siblings.length >0) {
|
||||||
mixed = true;
|
mixed = true;
|
||||||
rtOld = bigInt.zero;
|
rtOld = F.zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
const inserts = [];
|
const inserts = [];
|
||||||
const dels = [];
|
const dels = [];
|
||||||
|
|
||||||
let rt = hash1(key, value);
|
let rt = hash1(key, value);
|
||||||
inserts.push([rt, [1, key, value]]);
|
inserts.push([rt,[1, key, value]] );
|
||||||
|
|
||||||
for (let i = res.siblings.length - 1; i >= 0; i--) {
|
for (let i=res.siblings.length-1; i>=0; i--) {
|
||||||
if (i < res.siblings.length - 1 && !res.siblings[i].isZero()) {
|
if ((i<res.siblings.length-1)&&(!F.isZero(res.siblings[i]))) {
|
||||||
mixed = true;
|
mixed = true;
|
||||||
}
|
}
|
||||||
if (mixed) {
|
if (mixed) {
|
||||||
@ -211,19 +202,20 @@ class SMT {
|
|||||||
dels.push(rtOld);
|
dels.push(rtOld);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
let newRt;
|
let newRt;
|
||||||
if (newKeyBits[i]) {
|
if (newKeyBits[i]) {
|
||||||
newRt = hash0(res.siblings[i], rt);
|
newRt = hash0(res.siblings[i], rt);
|
||||||
inserts.push([newRt, [res.siblings[i], rt]]);
|
inserts.push([newRt,[res.siblings[i], rt]] );
|
||||||
} else {
|
} else {
|
||||||
newRt = hash0(rt, res.siblings[i]);
|
newRt = hash0(rt, res.siblings[i]);
|
||||||
inserts.push([newRt, [rt, res.siblings[i]]]);
|
inserts.push([newRt,[rt, res.siblings[i]]] );
|
||||||
}
|
}
|
||||||
rt = newRt;
|
rt = newRt;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addedOne) res.siblings.pop();
|
if (addedOne) res.siblings.pop();
|
||||||
while (res.siblings.length > 0 && res.siblings[res.siblings.length - 1].isZero()) {
|
while ((res.siblings.length>0) && (F.isZero(res.siblings[res.siblings.length-1]))) {
|
||||||
res.siblings.pop();
|
res.siblings.pop();
|
||||||
}
|
}
|
||||||
res.oldKey = resFind.notFoundKey;
|
res.oldKey = resFind.notFoundKey;
|
||||||
@ -231,6 +223,7 @@ class SMT {
|
|||||||
res.newRoot = rt;
|
res.newRoot = rt;
|
||||||
res.isOld0 = resFind.isOld0;
|
res.isOld0 = resFind.isOld0;
|
||||||
|
|
||||||
|
|
||||||
await this.db.multiIns(inserts);
|
await this.db.multiIns(inserts);
|
||||||
await this.db.setRoot(rt);
|
await this.db.setRoot(rt);
|
||||||
this.root = rt;
|
this.root = rt;
|
||||||
@ -248,26 +241,26 @@ class SMT {
|
|||||||
if (typeof root === "undefined") root = this.root;
|
if (typeof root === "undefined") root = this.root;
|
||||||
|
|
||||||
let res;
|
let res;
|
||||||
if (root.isZero()) {
|
if (F.isZero(root)) {
|
||||||
res = {
|
res = {
|
||||||
found: false,
|
found: false,
|
||||||
siblings: [],
|
siblings: [],
|
||||||
notFoundKey: key,
|
notFoundKey: key,
|
||||||
notFoundValue: bigInt.zero,
|
notFoundValue: F.zero,
|
||||||
isOld0: true,
|
isOld0: true
|
||||||
};
|
};
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
const record = await this.db.get(root);
|
const record = await this.db.get(root);
|
||||||
|
|
||||||
if (record.length == 3 && record[0].equals(bigInt.one)) {
|
if ((record.length==3)&&(F.eq(record[0],F.one))) {
|
||||||
if (record[1].equals(key)) {
|
if (F.eq(record[1],key)) {
|
||||||
res = {
|
res = {
|
||||||
found: true,
|
found: true,
|
||||||
siblings: [],
|
siblings: [],
|
||||||
foundValue: record[2],
|
foundValue: record[2],
|
||||||
isOld0: false,
|
isOld0: false
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
res = {
|
res = {
|
||||||
@ -275,15 +268,15 @@ class SMT {
|
|||||||
siblings: [],
|
siblings: [],
|
||||||
notFoundKey: record[1],
|
notFoundKey: record[1],
|
||||||
notFoundValue: record[2],
|
notFoundValue: record[2],
|
||||||
isOld0: false,
|
isOld0: false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (keyBits[level] == 0) {
|
if (keyBits[level] == 0) {
|
||||||
res = await this._find(key, keyBits, record[0], level + 1);
|
res = await this._find(key, keyBits, record[0], level+1);
|
||||||
res.siblings.unshift(record[1]);
|
res.siblings.unshift(record[1]);
|
||||||
} else {
|
} else {
|
||||||
res = await this._find(key, keyBits, record[1], level + 1);
|
res = await this._find(key, keyBits, record[1], level+1);
|
||||||
res.siblings.unshift(record[0]);
|
res.siblings.unshift(record[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -291,7 +284,9 @@ class SMT {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadFromFile(fileName) {}
|
async function loadFromFile(fileName) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
async function newMemEmptyTrie() {
|
async function newMemEmptyTrie() {
|
||||||
const db = new SMTMemDB();
|
const db = new SMTMemDB();
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
const mimc7 = require("./mimc7");
|
const mimc7 = require("./mimc7");
|
||||||
const bigInt = require("@tornado/snarkjs").bigInt;
|
const bigInt = require("big-integer");
|
||||||
|
|
||||||
exports.hash0 = function (left, right) {
|
exports.hash0 = function (left, right) {
|
||||||
return mimc7.multiHash(left, right);
|
return mimc7.multiHash(left, right);
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.hash1 = function (key, value) {
|
exports.hash1 = function(key, value) {
|
||||||
return mimc7.multiHash([key, value], bigInt.one);
|
return mimc7.multiHash([key, value], bigInt.one);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exports.F = mimc7.F;
|
||||||
|
@ -1,10 +1,18 @@
|
|||||||
|
|
||||||
|
const ZqField = require("ffjavascript").ZqField;
|
||||||
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
|
|
||||||
const poseidon = require("./poseidon");
|
const poseidon = require("./poseidon");
|
||||||
const bigInt = require("@tornado/snarkjs").bigInt;
|
|
||||||
|
const F = new ZqField(Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
|
||||||
|
|
||||||
|
|
||||||
exports.hash0 = function (left, right) {
|
exports.hash0 = function (left, right) {
|
||||||
return poseidon([left, right]);
|
return poseidon([left, right]);
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.hash1 = function (key, value) {
|
exports.hash1 = function(key, value) {
|
||||||
return poseidon([key, value, bigInt.one]);
|
return poseidon([key, value, F.one]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exports.F = F;
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
const bigInt = require("@tornado/snarkjs").bigInt;
|
|
||||||
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
|
const ZqField = require("ffjavascript").ZqField;
|
||||||
|
|
||||||
|
// Prime 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001
|
||||||
|
const F = new ZqField(Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
|
||||||
|
|
||||||
class SMTMemDb {
|
class SMTMemDb {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.nodes = {};
|
this.nodes = {};
|
||||||
this.root = bigInt(0);
|
this.root = F.zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getRoot() {
|
async getRoot() {
|
||||||
@ -12,13 +17,13 @@ class SMTMemDb {
|
|||||||
|
|
||||||
_key2str(k) {
|
_key2str(k) {
|
||||||
// const keyS = bigInt(key).leInt2Buff(32).toString("hex");
|
// const keyS = bigInt(key).leInt2Buff(32).toString("hex");
|
||||||
const keyS = bigInt(k).toString();
|
const keyS = k.toString();
|
||||||
return keyS;
|
return keyS;
|
||||||
}
|
}
|
||||||
|
|
||||||
_normalize(n) {
|
_normalize(n) {
|
||||||
for (let i = 0; i < n.length; i++) {
|
for (let i=0; i<n.length; i++) {
|
||||||
n[i] = bigInt(n[i]);
|
n[i] = F.e(n[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,7 +34,7 @@ class SMTMemDb {
|
|||||||
|
|
||||||
async multiGet(keys) {
|
async multiGet(keys) {
|
||||||
const promises = [];
|
const promises = [];
|
||||||
for (let i = 0; i < keys.length; i++) {
|
for (let i=0; i<keys.length; i++) {
|
||||||
promises.push(this.get(keys[i]));
|
promises.push(this.get(keys[i]));
|
||||||
}
|
}
|
||||||
return await Promise.all(promises);
|
return await Promise.all(promises);
|
||||||
@ -40,7 +45,7 @@ class SMTMemDb {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async multiIns(inserts) {
|
async multiIns(inserts) {
|
||||||
for (let i = 0; i < inserts.length; i++) {
|
for (let i=0; i<inserts.length; i++) {
|
||||||
const keyS = this._key2str(inserts[i][0]);
|
const keyS = this._key2str(inserts[i][0]);
|
||||||
this._normalize(inserts[i][1]);
|
this._normalize(inserts[i][1]);
|
||||||
this.nodes[keyS] = inserts[i][1];
|
this.nodes[keyS] = inserts[i][1];
|
||||||
@ -48,7 +53,7 @@ class SMTMemDb {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async multiDel(dels) {
|
async multiDel(dels) {
|
||||||
for (let i = 0; i < dels.length; i++) {
|
for (let i=0; i<dels.length; i++) {
|
||||||
const keyS = this._key2str(dels[i]);
|
const keyS = this._key2str(dels[i]);
|
||||||
delete this.nodes[keyS];
|
delete this.nodes[keyS];
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("@tornado/snarkjs");
|
|
||||||
const compiler = require("circom");
|
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
const bigInt = snarkjs.bigInt;
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
|
const F1Field = require("ffjavascript").F1Field;
|
||||||
|
const utils = require("ffjavascript").utils;
|
||||||
|
const q = Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||||
|
const F = new F1Field(q);
|
||||||
|
|
||||||
|
const tester = require("circom").tester;
|
||||||
|
|
||||||
function print(circuit, w, s) {
|
function print(circuit, w, s) {
|
||||||
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
||||||
@ -13,62 +17,61 @@ function print(circuit, w, s) {
|
|||||||
|
|
||||||
function getBits(v, n) {
|
function getBits(v, n) {
|
||||||
const res = [];
|
const res = [];
|
||||||
for (let i = 0; i < n; i++) {
|
for (let i=0; i<n; i++) {
|
||||||
if (v.shr(i).isOdd()) {
|
if (Scalar.isOdd(Scalar.shr(v,i))) {
|
||||||
res.push(bigInt.one);
|
res.push(F.one);
|
||||||
} else {
|
} else {
|
||||||
res.push(bigInt.zero);
|
res.push(F.zero);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
|
||||||
|
|
||||||
describe("Aliascheck test", () => {
|
describe("Aliascheck test", function () {
|
||||||
let circuit;
|
this.timeout(100000);
|
||||||
before(async () => {
|
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "aliascheck_test.circom"));
|
|
||||||
|
|
||||||
circuit = new snarkjs.Circuit(cirDef);
|
let cir;
|
||||||
|
before( async() => {
|
||||||
|
|
||||||
console.log("NConstrains: " + circuit.nConstraints);
|
cir = await tester(path.join(__dirname, "circuits", "aliascheck_test.circom"));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Satisfy the aliastest 0", async () => {
|
it("Satisfy the aliastest 0", async () => {
|
||||||
const inp = getBits(bigInt.zero, 254);
|
const inp = getBits(0, 254);
|
||||||
circuit.calculateWitness({ in: inp });
|
await cir.calculateWitness({in: inp}, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Satisfy the aliastest 3", async () => {
|
it("Satisfy the aliastest 3", async () => {
|
||||||
const inp = getBits(bigInt(3), 254);
|
const inp = getBits(3, 254);
|
||||||
circuit.calculateWitness({ in: inp });
|
await cir.calculateWitness({in: inp}, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Satisfy the aliastest q-1", async () => {
|
it("Satisfy the aliastest q-1", async () => {
|
||||||
const inp = getBits(q.sub(bigInt.one), 254);
|
const inp = getBits(F.minusone, 254);
|
||||||
circuit.calculateWitness({ in: inp });
|
// console.log(JSON.stringify(utils.stringifyBigInts(inp)));
|
||||||
|
await cir.calculateWitness({in: inp}, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Nhot not satisfy an input of q", async () => {
|
it("Should not satisfy an input of q", async () => {
|
||||||
const inp = getBits(q, 254);
|
const inp = getBits(q, 254);
|
||||||
try {
|
try {
|
||||||
circuit.calculateWitness({ in: inp });
|
await cir.calculateWitness({in: inp}, true);
|
||||||
assert(false);
|
assert(false);
|
||||||
} catch (err) {
|
} catch(err) {
|
||||||
assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message));
|
assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message) );
|
||||||
assert(err.message.indexOf("1 != 0") >= 0);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Nhot not satisfy all ones", async () => {
|
it("Should not satisfy all ones", async () => {
|
||||||
const inp = getBits(bigInt(1).shl(254).sub(bigInt(1)), 254);
|
|
||||||
|
const inp = getBits(Scalar.sub(Scalar.shl(1, 254) , 1) , 254);
|
||||||
try {
|
try {
|
||||||
circuit.calculateWitness({ in: inp });
|
await cir.calculateWitness({in: inp}, true);
|
||||||
assert(false);
|
assert(false);
|
||||||
} catch (err) {
|
} catch(err) {
|
||||||
assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message));
|
assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message) );
|
||||||
assert(err.message.indexOf("1 != 0") >= 0);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -1,74 +0,0 @@
|
|||||||
const chai = require("chai");
|
|
||||||
const path = require("path");
|
|
||||||
const snarkjs = require("@tornado/snarkjs");
|
|
||||||
const compiler = require("circom");
|
|
||||||
|
|
||||||
const assert = chai.assert;
|
|
||||||
|
|
||||||
const bigInt = snarkjs.bigInt;
|
|
||||||
|
|
||||||
function print(circuit, w, s) {
|
|
||||||
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getBits(v, n) {
|
|
||||||
const res = [];
|
|
||||||
for (let i = 0; i < n; i++) {
|
|
||||||
if (v.shr(i).isOdd()) {
|
|
||||||
res.push(bigInt.one);
|
|
||||||
} else {
|
|
||||||
res.push(bigInt.zero);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
const r = bigInt("2736030358979909402780800718157159386076813972158567259200215660948447373041");
|
|
||||||
|
|
||||||
describe("Aliascheck test", () => {
|
|
||||||
let circuit;
|
|
||||||
before(async () => {
|
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "aliascheckbabyjub_test.circom"));
|
|
||||||
|
|
||||||
circuit = new snarkjs.Circuit(cirDef);
|
|
||||||
|
|
||||||
console.log("NConstrains: " + circuit.nConstraints);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Satisfy the aliastest 0", async () => {
|
|
||||||
const inp = getBits(bigInt.zero, 251);
|
|
||||||
circuit.calculateWitness({ in: inp });
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Satisfy the aliastest 3", async () => {
|
|
||||||
const inp = getBits(bigInt(3), 251);
|
|
||||||
circuit.calculateWitness({ in: inp });
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Satisfy the aliastest r-1", async () => {
|
|
||||||
const inp = getBits(r.sub(bigInt.one), 251);
|
|
||||||
circuit.calculateWitness({ in: inp });
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Nhot not satisfy an input of r", async () => {
|
|
||||||
const inp = getBits(r, 251);
|
|
||||||
try {
|
|
||||||
circuit.calculateWitness({ in: inp });
|
|
||||||
assert(false);
|
|
||||||
} catch (err) {
|
|
||||||
assert(err.message.indexOf("Constraint doesn't match") >= 0);
|
|
||||||
assert(err.message.indexOf("1 != 0") >= 0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Nhot not satisfy all ones", async () => {
|
|
||||||
const inp = getBits(bigInt(1).shl(251).sub(bigInt(1)), 251);
|
|
||||||
try {
|
|
||||||
circuit.calculateWitness({ in: inp });
|
|
||||||
assert(false);
|
|
||||||
} catch (err) {
|
|
||||||
assert(err.message.indexOf("Constraint doesn't match") >= 0);
|
|
||||||
assert(err.message.indexOf("1 != 0") >= 0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
125
test/babyjub.js
125
test/babyjub.js
@ -1,120 +1,113 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("@tornado/snarkjs");
|
|
||||||
const compiler = require("circom");
|
|
||||||
|
|
||||||
const createBlakeHash = require("blake-hash");
|
const createBlakeHash = require("blake-hash");
|
||||||
const eddsa = require("../src/eddsa.js");
|
const eddsa = require("../src/eddsa.js");
|
||||||
|
const F = require("../src/babyjub.js").F;
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
const bigInt = require("@tornado/snarkjs").bigInt;
|
const tester = require("circom").tester;
|
||||||
|
const utils = require("ffjavascript").utils;
|
||||||
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
|
|
||||||
describe("Baby Jub test", function () {
|
describe("Baby Jub test", function () {
|
||||||
let circuitAdd;
|
let circuitAdd;
|
||||||
let circuitTest;
|
let circuitTest;
|
||||||
|
let circuitPbk;
|
||||||
|
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
|
|
||||||
before(async () => {
|
before( async() => {
|
||||||
const cirDefAdd = await compiler(path.join(__dirname, "circuits", "babyadd_tester.circom"));
|
circuitAdd = await tester(path.join(__dirname, "circuits", "babyadd_tester.circom"));
|
||||||
circuitAdd = new snarkjs.Circuit(cirDefAdd);
|
|
||||||
console.log("NConstrains BabyAdd: " + circuitAdd.nConstraints);
|
|
||||||
|
|
||||||
const cirDefTest = await compiler(path.join(__dirname, "circuits", "babycheck_test.circom"));
|
circuitTest = await tester(path.join(__dirname, "circuits", "babycheck_test.circom"));
|
||||||
circuitTest = new snarkjs.Circuit(cirDefTest);
|
|
||||||
console.log("NConstrains BabyTest: " + circuitTest.nConstraints);
|
|
||||||
|
|
||||||
const cirDefPbk = await compiler(path.join(__dirname, "circuits", "babypbk_test.circom"));
|
circuitPbk = await tester(path.join(__dirname, "circuits", "babypbk_test.circom"));
|
||||||
circuitPbk = new snarkjs.Circuit(cirDefPbk);
|
|
||||||
console.log("NConstrains BabyPbk: " + circuitPbk.nConstraints);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should add point (0,1) and (0,1)", async () => {
|
it("Should add point (0,1) and (0,1)", async () => {
|
||||||
const input = {
|
|
||||||
x1: snarkjs.bigInt(0),
|
const input={
|
||||||
y1: snarkjs.bigInt(1),
|
x1: F.e(0),
|
||||||
x2: snarkjs.bigInt(0),
|
y1: F.e(1),
|
||||||
y2: snarkjs.bigInt(1),
|
x2: F.e(0),
|
||||||
|
y2: F.e(1)
|
||||||
};
|
};
|
||||||
|
|
||||||
const w = circuitAdd.calculateWitness(input);
|
const w = await circuitAdd.calculateWitness(input, true);
|
||||||
|
|
||||||
const xout = w[circuitAdd.getSignalIdx("main.xout")];
|
await circuitAdd.assertOut(w, {xout: F.e(0), yout: F.e(1)});
|
||||||
const yout = w[circuitAdd.getSignalIdx("main.yout")];
|
|
||||||
|
|
||||||
assert(xout.equals(0));
|
|
||||||
assert(yout.equals(1));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should add 2 same numbers", async () => {
|
it("Should add 2 same numbers", async () => {
|
||||||
const input = {
|
|
||||||
x1: snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
const input={
|
||||||
y1: snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
x1: F.e("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
||||||
x2: snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
y1: F.e("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
||||||
y2: snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
x2: F.e("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
||||||
|
y2: F.e("2626589144620713026669568689430873010625803728049924121243784502389097019475")
|
||||||
};
|
};
|
||||||
|
|
||||||
const w = circuitAdd.calculateWitness(input);
|
const w = await circuitAdd.calculateWitness(input, true);
|
||||||
|
|
||||||
const xout = w[circuitAdd.getSignalIdx("main.xout")];
|
await circuitAdd.assertOut(w, {
|
||||||
const yout = w[circuitAdd.getSignalIdx("main.yout")];
|
xout: F.e("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
|
||||||
|
yout: F.e("4338620300185947561074059802482547481416142213883829469920100239455078257889")
|
||||||
|
});
|
||||||
|
|
||||||
assert(xout.equals(snarkjs.bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365")));
|
|
||||||
assert(yout.equals(snarkjs.bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889")));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should add 2 different numbers", async () => {
|
it("Should add 2 different numbers", async () => {
|
||||||
const input = {
|
|
||||||
x1: snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
const input={
|
||||||
y1: snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
x1: F.e("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
||||||
x2: snarkjs.bigInt("16540640123574156134436876038791482806971768689494387082833631921987005038935"),
|
y1: F.e("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
||||||
y2: snarkjs.bigInt("20819045374670962167435360035096875258406992893633759881276124905556507972311"),
|
x2: F.e("16540640123574156134436876038791482806971768689494387082833631921987005038935"),
|
||||||
|
y2: F.e("20819045374670962167435360035096875258406992893633759881276124905556507972311")
|
||||||
};
|
};
|
||||||
|
|
||||||
const w = circuitAdd.calculateWitness(input);
|
const w = await circuitAdd.calculateWitness(input, true);
|
||||||
|
|
||||||
const xout = w[circuitAdd.getSignalIdx("main.xout")];
|
await circuitAdd.assertOut(w, {
|
||||||
const yout = w[circuitAdd.getSignalIdx("main.yout")];
|
xout: F.e("7916061937171219682591368294088513039687205273691143098332585753343424131937"),
|
||||||
|
yout: F.e("14035240266687799601661095864649209771790948434046947201833777492504781204499")
|
||||||
|
});
|
||||||
|
|
||||||
/*
|
|
||||||
console.log(xout.toString());
|
|
||||||
console.log(yout.toString());
|
|
||||||
*/
|
|
||||||
|
|
||||||
assert(xout.equals(snarkjs.bigInt("7916061937171219682591368294088513039687205273691143098332585753343424131937")));
|
|
||||||
assert(yout.equals(snarkjs.bigInt("14035240266687799601661095864649209771790948434046947201833777492504781204499")));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should check 0 is a valid poiny", async () => {
|
it("Should check (0,1) is a valid point", async() => {
|
||||||
const w = circuitTest.calculateWitness({ x: 0, y: 1 });
|
const w = await circuitTest.calculateWitness({x: 0, y:1}, true);
|
||||||
assert(circuitTest.checkWitness(w));
|
|
||||||
|
await circuitTest.checkConstraints(w);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should check 0 is an invalid poiny", async () => {
|
it("Should check (1,0) is an invalid point", async() => {
|
||||||
try {
|
try {
|
||||||
circuitTest.calculateWitness({ x: 1, y: 0 });
|
await circuitTest.calculateWitness({x: 1, y: 0}, true);
|
||||||
assert(false, "Should be a valid point");
|
assert(false, "Should be a valid point");
|
||||||
} catch (err) {
|
} catch(err) {
|
||||||
assert(/Constraint\sdoesn't\smatch(.*)168700\s!=\s1/.test(err.message));
|
assert(/Constraint\sdoesn't\smatch(.*)168700\s!=\s1/.test(err.message) );
|
||||||
assert(err.message.indexOf("168700 != 1") >= 0);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should extract the public key from the private one", async () => {
|
it("Should extract the public key from the private one", async () => {
|
||||||
const rawpvk = Buffer.from("0001020304050607080900010203040506070809000102030405060708090021", "hex");
|
|
||||||
const pvk = eddsa.pruneBuffer(createBlakeHash("blake512").update(rawpvk).digest().slice(0, 32));
|
|
||||||
const S = bigInt.leBuff2int(pvk).shr(3);
|
|
||||||
|
|
||||||
const A = eddsa.prv2pub(rawpvk);
|
const rawpvk = Buffer.from("0001020304050607080900010203040506070809000102030405060708090021", "hex");
|
||||||
|
const pvk = eddsa.pruneBuffer(createBlakeHash("blake512").update(rawpvk).digest().slice(0,32));
|
||||||
|
const S = Scalar.shr(utils.leBuff2int(pvk), 3);
|
||||||
|
|
||||||
|
const A = eddsa.prv2pub(rawpvk);
|
||||||
|
|
||||||
const input = {
|
const input = {
|
||||||
in: S,
|
in : S
|
||||||
Ax: A[0],
|
|
||||||
Ay: A[1],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const w = circuitPbk.calculateWitness(input);
|
const w = await circuitPbk.calculateWitness(input, true);
|
||||||
assert(circuitPbk.checkWitness(w));
|
|
||||||
|
await circuitPbk.assertOut(w, {Ax : A[0], Ay: A[1]});
|
||||||
|
|
||||||
|
await circuitPbk.checkConstraints(w);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -1,23 +1,29 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
|
||||||
const snarkjs = require("@tornado/snarkjs");
|
|
||||||
const compiler = require("circom");
|
|
||||||
const babyjub = require("../src/babyjub.js");
|
const babyjub = require("../src/babyjub.js");
|
||||||
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
// const bigInt = require("big-integer");
|
// const bigInt = require("big-integer");
|
||||||
|
|
||||||
|
|
||||||
describe("Baby Jub js test", function () {
|
describe("Baby Jub js test", function () {
|
||||||
|
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
|
|
||||||
it("Should add point (0,1) and (0,1)", () => {
|
it("Should add point (0,1) and (0,1)", () => {
|
||||||
const p1 = [snarkjs.bigInt(0), snarkjs.bigInt(1)];
|
|
||||||
const p2 = [snarkjs.bigInt(0), snarkjs.bigInt(1)];
|
const p1 = [
|
||||||
|
babyjub.F.e(0),
|
||||||
|
babyjub.F.e(1)];
|
||||||
|
const p2 = [
|
||||||
|
babyjub.F.e(0),
|
||||||
|
babyjub.F.e(1)
|
||||||
|
];
|
||||||
|
|
||||||
const out = babyjub.addPoint(p1, p2);
|
const out = babyjub.addPoint(p1, p2);
|
||||||
assert(out[0].equals(0));
|
assert(babyjub.F.eq(out[0], babyjub.F.zero));
|
||||||
assert(out[1].equals(1));
|
assert(babyjub.F.eq(out[1], babyjub.F.one));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should base be 8*generator", () => {
|
it("Should base be 8*generator", () => {
|
||||||
@ -26,48 +32,50 @@ describe("Baby Jub js test", function () {
|
|||||||
res = babyjub.addPoint(res, res);
|
res = babyjub.addPoint(res, res);
|
||||||
res = babyjub.addPoint(res, res);
|
res = babyjub.addPoint(res, res);
|
||||||
|
|
||||||
assert(res[0].equals(babyjub.Base8[0]));
|
assert(babyjub.F.eq(res[0], babyjub.Base8[0]));
|
||||||
assert(res[1].equals(babyjub.Base8[1]));
|
assert(babyjub.F.eq(res[1], babyjub.Base8[1]));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should add 2 same numbers", () => {
|
it("Should add 2 same numbers", () => {
|
||||||
|
|
||||||
const p1 = [
|
const p1 = [
|
||||||
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
babyjub.F.e("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
||||||
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
babyjub.F.e("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
||||||
];
|
];
|
||||||
const p2 = [
|
const p2 = [
|
||||||
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
babyjub.F.e("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
||||||
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
babyjub.F.e("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
||||||
];
|
];
|
||||||
|
|
||||||
const out = babyjub.addPoint(p1, p2);
|
const out = babyjub.addPoint(p1, p2);
|
||||||
assert(out[0].equals(snarkjs.bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365")));
|
assert(babyjub.F.eq(out[0], babyjub.F.e("6890855772600357754907169075114257697580319025794532037257385534741338397365")));
|
||||||
assert(out[1].equals(snarkjs.bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889")));
|
assert(babyjub.F.eq(out[1], babyjub.F.e("4338620300185947561074059802482547481416142213883829469920100239455078257889")));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should add 2 different numbers", () => {
|
it("Should add 2 different numbers", () => {
|
||||||
|
|
||||||
const p1 = [
|
const p1 = [
|
||||||
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
babyjub.F.e("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
||||||
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
babyjub.F.e("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
||||||
];
|
];
|
||||||
const p2 = [
|
const p2 = [
|
||||||
snarkjs.bigInt("16540640123574156134436876038791482806971768689494387082833631921987005038935"),
|
babyjub.F.e("16540640123574156134436876038791482806971768689494387082833631921987005038935"),
|
||||||
snarkjs.bigInt("20819045374670962167435360035096875258406992893633759881276124905556507972311"),
|
babyjub.F.e("20819045374670962167435360035096875258406992893633759881276124905556507972311"),
|
||||||
];
|
];
|
||||||
|
|
||||||
const out = babyjub.addPoint(p1, p2);
|
const out = babyjub.addPoint(p1, p2);
|
||||||
|
assert(babyjub.F.eq(out[0], babyjub.F.e("7916061937171219682591368294088513039687205273691143098332585753343424131937")));
|
||||||
|
assert(babyjub.F.eq(out[1], babyjub.F.e("14035240266687799601661095864649209771790948434046947201833777492504781204499")));
|
||||||
|
|
||||||
assert(out[0].equals(snarkjs.bigInt("7916061937171219682591368294088513039687205273691143098332585753343424131937")));
|
|
||||||
assert(out[1].equals(snarkjs.bigInt("14035240266687799601661095864649209771790948434046947201833777492504781204499")));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should mulPointEscalar 0", () => {
|
it("should mulPointEscalar 0", () => {
|
||||||
const p = [
|
const p = [
|
||||||
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
babyjub.F.e("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
||||||
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
babyjub.F.e("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
||||||
];
|
];
|
||||||
|
|
||||||
const r = babyjub.mulPointEscalar(p, snarkjs.bigInt("3"));
|
const r = babyjub.mulPointEscalar(p, 3);
|
||||||
let r2 = babyjub.addPoint(p, p);
|
let r2 = babyjub.addPoint(p, p);
|
||||||
r2 = babyjub.addPoint(r2, p);
|
r2 = babyjub.addPoint(r2, p);
|
||||||
assert.equal(r2[0].toString(), r[0].toString());
|
assert.equal(r2[0].toString(), r[0].toString());
|
||||||
@ -78,68 +86,62 @@ describe("Baby Jub js test", function () {
|
|||||||
|
|
||||||
it("should mulPointEscalar 1", () => {
|
it("should mulPointEscalar 1", () => {
|
||||||
const p = [
|
const p = [
|
||||||
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
babyjub.F.e("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
||||||
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
babyjub.F.e("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
||||||
];
|
];
|
||||||
|
|
||||||
const r = babyjub.mulPointEscalar(
|
const r = babyjub.mulPointEscalar(p, Scalar.fromString("14035240266687799601661095864649209771790948434046947201833777492504781204499"));
|
||||||
p,
|
|
||||||
snarkjs.bigInt("14035240266687799601661095864649209771790948434046947201833777492504781204499")
|
|
||||||
);
|
|
||||||
assert.equal(r[0].toString(), "17070357974431721403481313912716834497662307308519659060910483826664480189605");
|
assert.equal(r[0].toString(), "17070357974431721403481313912716834497662307308519659060910483826664480189605");
|
||||||
assert.equal(r[1].toString(), "4014745322800118607127020275658861516666525056516280575712425373174125159339");
|
assert.equal(r[1].toString(), "4014745322800118607127020275658861516666525056516280575712425373174125159339");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should mulPointEscalar 2", () => {
|
it("should mulPointEscalar 2", () => {
|
||||||
const p = [
|
const p = [
|
||||||
snarkjs.bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
|
babyjub.F.e("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
|
||||||
snarkjs.bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889"),
|
babyjub.F.e("4338620300185947561074059802482547481416142213883829469920100239455078257889"),
|
||||||
];
|
];
|
||||||
|
|
||||||
const r = babyjub.mulPointEscalar(
|
const r = babyjub.mulPointEscalar(p, Scalar.fromString("20819045374670962167435360035096875258406992893633759881276124905556507972311"));
|
||||||
p,
|
|
||||||
snarkjs.bigInt("20819045374670962167435360035096875258406992893633759881276124905556507972311")
|
|
||||||
);
|
|
||||||
assert.equal(r[0].toString(), "13563888653650925984868671744672725781658357821216877865297235725727006259983");
|
assert.equal(r[0].toString(), "13563888653650925984868671744672725781658357821216877865297235725727006259983");
|
||||||
assert.equal(r[1].toString(), "8442587202676550862664528699803615547505326611544120184665036919364004251662");
|
assert.equal(r[1].toString(), "8442587202676550862664528699803615547505326611544120184665036919364004251662");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should inCurve 1", () => {
|
it("should inCurve 1", () => {
|
||||||
const p = [
|
const p = [
|
||||||
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
babyjub.F.e("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
||||||
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
babyjub.F.e("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
||||||
];
|
];
|
||||||
assert(babyjub.inCurve(p));
|
assert(babyjub.inCurve(p));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should inCurve 2", () => {
|
it("should inCurve 2", () => {
|
||||||
const p = [
|
const p = [
|
||||||
snarkjs.bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
|
babyjub.F.e("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
|
||||||
snarkjs.bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889"),
|
babyjub.F.e("4338620300185947561074059802482547481416142213883829469920100239455078257889"),
|
||||||
];
|
];
|
||||||
assert(babyjub.inCurve(p));
|
assert(babyjub.inCurve(p));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should inSubgroup 1", () => {
|
it("should inSubgroup 1", () => {
|
||||||
const p = [
|
const p = [
|
||||||
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
babyjub.F.e("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
||||||
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
babyjub.F.e("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
||||||
];
|
];
|
||||||
assert(babyjub.inSubgroup(p));
|
assert(babyjub.inSubgroup(p));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should inSubgroup 2", () => {
|
it("should inSubgroup 2", () => {
|
||||||
const p = [
|
const p = [
|
||||||
snarkjs.bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
|
babyjub.F.e("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
|
||||||
snarkjs.bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889"),
|
babyjub.F.e("4338620300185947561074059802482547481416142213883829469920100239455078257889"),
|
||||||
];
|
];
|
||||||
assert(babyjub.inSubgroup(p));
|
assert(babyjub.inSubgroup(p));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should packPoint - unpackPoint 1", () => {
|
it("should packPoint - unpackPoint 1", () => {
|
||||||
const p = [
|
const p = [
|
||||||
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
babyjub.F.e("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
||||||
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
babyjub.F.e("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
||||||
];
|
];
|
||||||
const buf = babyjub.packPoint(p);
|
const buf = babyjub.packPoint(p);
|
||||||
assert.equal(buf.toString("hex"), "53b81ed5bffe9545b54016234682e7b2f699bd42a5e9eae27ff4051bc698ce85");
|
assert.equal(buf.toString("hex"), "53b81ed5bffe9545b54016234682e7b2f699bd42a5e9eae27ff4051bc698ce85");
|
||||||
@ -150,8 +152,8 @@ describe("Baby Jub js test", function () {
|
|||||||
|
|
||||||
it("should packPoint - unpackPoint 2", () => {
|
it("should packPoint - unpackPoint 2", () => {
|
||||||
const p = [
|
const p = [
|
||||||
snarkjs.bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
|
babyjub.F.e("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
|
||||||
snarkjs.bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889"),
|
babyjub.F.e("4338620300185947561074059802482547481416142213883829469920100239455078257889"),
|
||||||
];
|
];
|
||||||
const buf = babyjub.packPoint(p);
|
const buf = babyjub.packPoint(p);
|
||||||
assert.equal(buf.toString("hex"), "e114eb17eddf794f063a68fecac515e3620e131976108555735c8b0773929709");
|
assert.equal(buf.toString("hex"), "e114eb17eddf794f063a68fecac515e3620e131976108555735c8b0773929709");
|
||||||
|
@ -1,54 +1,53 @@
|
|||||||
const chai = require("chai");
|
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("@tornado/snarkjs");
|
|
||||||
const compiler = require("circom");
|
|
||||||
|
|
||||||
const assert = chai.assert;
|
const Fr = require("ffjavascript").bn128.Fr;
|
||||||
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
const bigInt = snarkjs.bigInt;
|
const tester = require("circom").tester;
|
||||||
|
|
||||||
function print(circuit, w, s) {
|
function print(circuit, w, s) {
|
||||||
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkSub(_a, _b, circuit) {
|
async function checkSub(_a,_b, circuit) {
|
||||||
let a = bigInt(_a);
|
let a=Scalar.e(_a);
|
||||||
let b = bigInt(_b);
|
let b=Scalar.e(_b);
|
||||||
if (a.lesser(bigInt.zero)) a = a.add(bigInt.one.shl(16));
|
if (Scalar.lt(a, 0)) a = Scalar.add(a, Scalar.shl(1, 16));
|
||||||
if (b.lesser(bigInt.zero)) b = b.add(bigInt.one.shl(16));
|
if (Scalar.lt(b, 0)) b = Scalar.add(b, Scalar.shl(1, 16));
|
||||||
const w = circuit.calculateWitness({ a: a, b: b });
|
const w = await circuit.calculateWitness({a: a, b: b}, true);
|
||||||
|
|
||||||
let res = a.sub(b);
|
let res = Scalar.sub(a, b);
|
||||||
if (res.lesser(bigInt.zero)) res = res.add(bigInt.one.shl(16));
|
if (Scalar.lt(res, 0)) res = Scalar.add(res, Scalar.shl(1, 16));
|
||||||
assert(w[circuit.getSignalIdx("main.out")].equals(bigInt(res)));
|
|
||||||
|
await circuit.assertOut(w, {out: res});
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("BinSub test", () => {
|
describe("BinSub test", function () {
|
||||||
|
|
||||||
|
this.timeout(100000);
|
||||||
|
|
||||||
let circuit;
|
let circuit;
|
||||||
before(async () => {
|
before( async() => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "binsub_test.circom"));
|
circuit = await tester(path.join(__dirname, "circuits", "binsub_test.circom"));
|
||||||
|
|
||||||
circuit = new snarkjs.Circuit(cirDef);
|
|
||||||
|
|
||||||
console.log("NConstrains BinSub: " + circuit.nConstraints);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should check variuos ege cases", async () => {
|
it("Should check variuos ege cases", async () => {
|
||||||
checkSub(0, 0, circuit);
|
await checkSub(0,0, circuit);
|
||||||
checkSub(1, 0, circuit);
|
await checkSub(1,0, circuit);
|
||||||
checkSub(-1, 0, circuit);
|
await checkSub(-1,0, circuit);
|
||||||
checkSub(2, 1, circuit);
|
await checkSub(2,1, circuit);
|
||||||
checkSub(2, 2, circuit);
|
await checkSub(2,2, circuit);
|
||||||
checkSub(2, 3, circuit);
|
await checkSub(2,3, circuit);
|
||||||
checkSub(2, -1, circuit);
|
await checkSub(2,-1, circuit);
|
||||||
checkSub(2, -2, circuit);
|
await checkSub(2,-2, circuit);
|
||||||
checkSub(2, -3, circuit);
|
await checkSub(2,-3, circuit);
|
||||||
checkSub(-2, -3, circuit);
|
await checkSub(-2,-3, circuit);
|
||||||
checkSub(-2, -2, circuit);
|
await checkSub(-2,-2, circuit);
|
||||||
checkSub(-2, -1, circuit);
|
await checkSub(-2,-1, circuit);
|
||||||
checkSub(-2, 0, circuit);
|
await checkSub(-2,0, circuit);
|
||||||
checkSub(-2, 1, circuit);
|
await checkSub(-2,1, circuit);
|
||||||
checkSub(-2, 2, circuit);
|
await checkSub(-2,2, circuit);
|
||||||
checkSub(-2, 3, circuit);
|
await checkSub(-2,3, circuit);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -1,33 +1,37 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("@tornado/snarkjs");
|
|
||||||
const crypto = require("crypto");
|
|
||||||
|
|
||||||
const compiler = require("circom");
|
const tester = require("circom").tester;
|
||||||
|
|
||||||
|
const Fr = require("ffjavascript").bn128.Fr;
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
describe("Sum test", () => {
|
describe("Binary sum test", function () {
|
||||||
|
|
||||||
|
this.timeout(100000000);
|
||||||
|
|
||||||
it("Should create a constant circuit", async () => {
|
it("Should create a constant circuit", async () => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "constants_test.circom"));
|
const circuit = await tester(path.join(__dirname, "circuits", "constants_test.circom"));
|
||||||
assert.equal(cirDef.nVars, 2);
|
await circuit.loadConstraints();
|
||||||
|
|
||||||
const circuit = new snarkjs.Circuit(cirDef);
|
assert.equal(circuit.nVars, 2);
|
||||||
|
assert.equal(circuit.constraints.length, 1);
|
||||||
|
|
||||||
const witness = circuit.calculateWitness({ in: "0xd807aa98" });
|
const witness = await circuit.calculateWitness({ "in": Fr.e("d807aa98", 16)}, true);
|
||||||
|
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0],Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt("0xd807aa98")));
|
assert(Fr.eq(witness[1],Fr.e("d807aa98", 16)));
|
||||||
});
|
});
|
||||||
it("Should create a sum circuit", async () => {
|
it("Should create a sum circuit", async () => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "sum_test.circom"));
|
const circuit = await tester(path.join(__dirname, "circuits", "sum_test.circom"));
|
||||||
assert.equal(cirDef.nVars, 97); // 32 (in1) + 32(in2) + 32(out) + 1 (carry)
|
await circuit.loadConstraints();
|
||||||
|
|
||||||
const circuit = new snarkjs.Circuit(cirDef);
|
assert.equal(circuit.constraints.length, 97); // 32 (in1) + 32(in2) + 32(out) + 1 (carry)
|
||||||
|
|
||||||
const witness = circuit.calculateWitness({ a: "111", b: "222" });
|
const witness = await circuit.calculateWitness({ "a": "111", "b": "222" }, true);
|
||||||
|
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0],Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt("333")));
|
assert(Fr.eq(witness[1],Fr.e("333")));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
include "../../circuits/aliascheck.circom";
|
|
||||||
|
|
||||||
component main = AliasCheckBabyJub()
|
|
@ -6,6 +6,8 @@ template A() {
|
|||||||
signal input b;
|
signal input b;
|
||||||
signal output out;
|
signal output out;
|
||||||
|
|
||||||
|
var i;
|
||||||
|
|
||||||
component n2ba = Num2Bits(16);
|
component n2ba = Num2Bits(16);
|
||||||
component n2bb = Num2Bits(16);
|
component n2bb = Num2Bits(16);
|
||||||
component sub = BinSub(16);
|
component sub = BinSub(16);
|
||||||
@ -14,9 +16,12 @@ template A() {
|
|||||||
n2ba.in <== a;
|
n2ba.in <== a;
|
||||||
n2bb.in <== b;
|
n2bb.in <== b;
|
||||||
|
|
||||||
for (var i=0; i<16; i++) {
|
for (i=0; i<16; i++) {
|
||||||
sub.in[0][i] <== n2ba.out[i];
|
sub.in[0][i] <== n2ba.out[i];
|
||||||
sub.in[1][i] <== n2bb.out[i];
|
sub.in[1][i] <== n2bb.out[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i<16; i++) {
|
||||||
b2n.in[i] <== sub.out[i];
|
b2n.in[i] <== sub.out[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
include "../../circuits/eddsamimcsponge.circom";
|
|
||||||
|
|
||||||
component main = EdDSAMiMCSpongeVerifier();
|
|
@ -6,7 +6,7 @@ template Main() {
|
|||||||
signal input in;
|
signal input in;
|
||||||
signal output out[2];
|
signal output out[2];
|
||||||
|
|
||||||
var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||||
16950150798460657717958625567821834550301663161624707787222815936182638968203];
|
16950150798460657717958625567821834550301663161624707787222815936182638968203];
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,8 +7,8 @@ template Main() {
|
|||||||
|
|
||||||
var i;
|
var i;
|
||||||
|
|
||||||
var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||||
16950150798460657717958625567821834550301663161624707787222815936182638968203];
|
16950150798460657717958625567821834550301663161624707787222815936182638968203];
|
||||||
|
|
||||||
component escalarMul = EscalarMul(256, base);
|
component escalarMul = EscalarMul(256, base);
|
||||||
|
|
||||||
|
@ -6,8 +6,8 @@ template Main() {
|
|||||||
signal input e;
|
signal input e;
|
||||||
signal output out[2];
|
signal output out[2];
|
||||||
|
|
||||||
var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||||
16950150798460657717958625567821834550301663161624707787222815936182638968203]
|
16950150798460657717958625567821834550301663161624707787222815936182638968203]
|
||||||
|
|
||||||
|
|
||||||
component n2b = Num2Bits(253);
|
component n2b = Num2Bits(253);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
include "../../circuits/escalarmulw4table.circom";
|
include "../../circuits/escalarmulw4table.circom";
|
||||||
|
|
||||||
var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||||
16950150798460657717958625567821834550301663161624707787222815936182638968203]
|
16950150798460657717958625567821834550301663161624707787222815936182638968203]
|
||||||
|
|
||||||
component main = EscalarMulW4Table(base, 0);
|
component main = EscalarMulW4Table(base, 0);
|
||||||
|
@ -4,10 +4,10 @@ include "../../circuits/escalarmulw4table.circom";
|
|||||||
template Main() {
|
template Main() {
|
||||||
signal input in;
|
signal input in;
|
||||||
signal output out[16][2];
|
signal output out[16][2];
|
||||||
var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||||
16950150798460657717958625567821834550301663161624707787222815936182638968203];
|
16950150798460657717958625567821834550301663161624707787222815936182638968203];
|
||||||
|
|
||||||
var escalarMul = EscalarMulW4Table(base, 0);
|
var escalarMul[16][2] = EscalarMulW4Table(base, 0);
|
||||||
for (var i=0; i<16; i++) {
|
for (var i=0; i<16; i++) {
|
||||||
out[i][0] <== escalarMul[i][0]*in;
|
out[i][0] <== escalarMul[i][0]*in;
|
||||||
out[i][1] <== escalarMul[i][1]*in;
|
out[i][1] <== escalarMul[i][1]*in;
|
||||||
|
@ -4,10 +4,10 @@ include "../../circuits/escalarmulw4table.circom";
|
|||||||
template Main() {
|
template Main() {
|
||||||
signal input in;
|
signal input in;
|
||||||
signal output out[16][2];
|
signal output out[16][2];
|
||||||
var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||||
16950150798460657717958625567821834550301663161624707787222815936182638968203];
|
16950150798460657717958625567821834550301663161624707787222815936182638968203];
|
||||||
|
|
||||||
var escalarMul = EscalarMulW4Table(base, 3);
|
var escalarMul[16][2] = EscalarMulW4Table(base, 3);
|
||||||
for (var i=0; i<16; i++) {
|
for (var i=0; i<16; i++) {
|
||||||
out[i][0] <== escalarMul[i][0]*in;
|
out[i][0] <== escalarMul[i][0]*in;
|
||||||
out[i][1] <== escalarMul[i][1]*in;
|
out[i][1] <== escalarMul[i][1]*in;
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
include "../../circuits/mimcsponge.circom"
|
include "../../circuits/mimcsponge.circom"
|
||||||
|
|
||||||
component main = MiMCSponge(2, 3);
|
component main = MiMCSponge(2, 220, 3);
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
include "../../circuits/poseidon.circom"
|
include "../../circuits/poseidon.circom"
|
||||||
|
|
||||||
component main = Poseidon(4);
|
component main = Poseidon(5);
|
@ -6,6 +6,8 @@ template A() {
|
|||||||
signal input b;
|
signal input b;
|
||||||
signal output out;
|
signal output out;
|
||||||
|
|
||||||
|
var i;
|
||||||
|
|
||||||
component n2ba = Num2Bits(32);
|
component n2ba = Num2Bits(32);
|
||||||
component n2bb = Num2Bits(32);
|
component n2bb = Num2Bits(32);
|
||||||
component sum = BinSum(32,2);
|
component sum = BinSum(32,2);
|
||||||
@ -14,9 +16,12 @@ template A() {
|
|||||||
n2ba.in <== a;
|
n2ba.in <== a;
|
||||||
n2bb.in <== b;
|
n2bb.in <== b;
|
||||||
|
|
||||||
for (var i=0; i<32; i++) {
|
for (i=0; i<32; i++) {
|
||||||
sum.in[0][i] <== n2ba.out[i];
|
sum.in[0][i] <== n2ba.out[i];
|
||||||
sum.in[1][i] <== n2bb.out[i];
|
sum.in[1][i] <== n2bb.out[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i=0; i<32; i++) {
|
||||||
b2n.in[i] <== sum.out[i];
|
b2n.in[i] <== sum.out[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,193 +1,185 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("@tornado/snarkjs");
|
|
||||||
const crypto = require("crypto");
|
|
||||||
|
|
||||||
const compiler = require("circom");
|
const tester = require("circom").tester;
|
||||||
|
|
||||||
|
const Fr = require("ffjavascript").bn128.Fr;
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
describe("Sum test", () => {
|
describe("Comparators test", function () {
|
||||||
it("Should create a iszero circuit", async () => {
|
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "iszero.circom"));
|
|
||||||
|
|
||||||
const circuit = new snarkjs.Circuit(cirDef);
|
this.timeout(100000);
|
||||||
|
|
||||||
|
it("Should create a iszero circuit", async() => {
|
||||||
|
const circuit = await tester(path.join(__dirname, "circuits", "iszero.circom"));
|
||||||
|
|
||||||
let witness;
|
let witness;
|
||||||
witness = circuit.calculateWitness({ in: 111 });
|
witness = await circuit.calculateWitness({ "in": 111}, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(0)));
|
assert(Fr.eq(witness[1], Fr.e(0)));
|
||||||
|
|
||||||
witness = circuit.calculateWitness({ in: 0 });
|
witness = await circuit.calculateWitness({ "in": 0 }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[1], Fr.e(1)));
|
||||||
});
|
});
|
||||||
it("Should create a isequal circuit", async () => {
|
it("Should create a isequal circuit", async() => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "isequal.circom"));
|
const circuit = await tester(path.join(__dirname, "circuits", "isequal.circom"));
|
||||||
|
|
||||||
const circuit = new snarkjs.Circuit(cirDef);
|
|
||||||
|
|
||||||
let witness;
|
let witness;
|
||||||
witness = circuit.calculateWitness({ "in[0]": "111", "in[1]": "222" });
|
witness = await circuit.calculateWitness({ "in": [111,222] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(0)));
|
assert(Fr.eq(witness[1], Fr.e(0)));
|
||||||
|
|
||||||
witness = circuit.calculateWitness({ "in[0]": "444", "in[1]": "444" });
|
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
witness = await circuit.calculateWitness({ "in": [444,444] }, true);
|
||||||
assert(witness[1].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
|
assert(Fr.eq(witness[1], Fr.e(1)));
|
||||||
});
|
});
|
||||||
it("Should create a comparison lessthan", async () => {
|
it("Should create a comparison lessthan", async() => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "lessthan.circom"));
|
const circuit = await tester(path.join(__dirname, "circuits", "lessthan.circom"));
|
||||||
|
|
||||||
const circuit = new snarkjs.Circuit(cirDef);
|
|
||||||
|
|
||||||
let witness;
|
let witness;
|
||||||
witness = circuit.calculateWitness({ "in[0]": "333", "in[1]": "444" });
|
witness = await circuit.calculateWitness({ "in": [333,444] }), true;
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[1], Fr.e(1)));
|
||||||
|
|
||||||
witness = circuit.calculateWitness({ "in[0]": "1", "in[1]": "1" });
|
witness = await circuit.calculateWitness({ "in":[1,1] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(0)));
|
assert(Fr.eq(witness[1], Fr.e(0)));
|
||||||
|
|
||||||
witness = circuit.calculateWitness({ "in[0]": "661", "in[1]": "660" });
|
witness = await circuit.calculateWitness({ "in": [661, 660] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(0)));
|
assert(Fr.eq(witness[1], Fr.e(0)));
|
||||||
|
|
||||||
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "1" });
|
witness = await circuit.calculateWitness({ "in": [0, 1] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[1], Fr.e(1)));
|
||||||
|
|
||||||
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "444" });
|
witness = await circuit.calculateWitness({ "in": [0, 444] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[1], Fr.e(1)));
|
||||||
|
|
||||||
witness = circuit.calculateWitness({ "in[0]": "1", "in[1]": "0" });
|
witness = await circuit.calculateWitness({ "in": [1, 0] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(0)));
|
assert(Fr.eq(witness[1], Fr.e(0)));
|
||||||
|
|
||||||
witness = circuit.calculateWitness({ "in[0]": "555", "in[1]": "0" });
|
witness = await circuit.calculateWitness({ "in": [555, 0] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(0)));
|
assert(Fr.eq(witness[1], Fr.e(0)));
|
||||||
|
|
||||||
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "0" });
|
witness = await circuit.calculateWitness({ "in": [0, 0] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(0)));
|
assert(Fr.eq(witness[1], Fr.e(0)));
|
||||||
});
|
});
|
||||||
it("Should create a comparison lesseqthan", async () => {
|
it("Should create a comparison lesseqthan", async() => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "lesseqthan.circom"));
|
|
||||||
|
|
||||||
const circuit = new snarkjs.Circuit(cirDef);
|
const circuit = await tester(path.join(__dirname, "circuits", "lesseqthan.circom"));
|
||||||
|
|
||||||
let witness;
|
let witness;
|
||||||
witness = circuit.calculateWitness({ "in[0]": "333", "in[1]": "444" });
|
witness = await circuit.calculateWitness({ "in": [333,444] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[1], Fr.e(1)));
|
||||||
|
|
||||||
witness = circuit.calculateWitness({ "in[0]": "1", "in[1]": "1" });
|
witness = await circuit.calculateWitness({ "in":[1,1] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[1], Fr.e(1)));
|
||||||
|
|
||||||
witness = circuit.calculateWitness({ "in[0]": "661", "in[1]": "660" });
|
witness = await circuit.calculateWitness({ "in": [661, 660] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(0)));
|
assert(Fr.eq(witness[1], Fr.e(0)));
|
||||||
|
|
||||||
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "1" });
|
witness = await circuit.calculateWitness({ "in": [0, 1] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[1], Fr.e(1)));
|
||||||
|
|
||||||
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "444" });
|
witness = await circuit.calculateWitness({ "in": [0, 444] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[1], Fr.e(1)));
|
||||||
|
|
||||||
witness = circuit.calculateWitness({ "in[0]": "1", "in[1]": "0" });
|
witness = await circuit.calculateWitness({ "in": [1, 0] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(0)));
|
assert(Fr.eq(witness[1], Fr.e(0)));
|
||||||
|
|
||||||
witness = circuit.calculateWitness({ "in[0]": "555", "in[1]": "0" });
|
witness = await circuit.calculateWitness({ "in": [555, 0] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(0)));
|
assert(Fr.eq(witness[1], Fr.e(0)));
|
||||||
|
|
||||||
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "0" });
|
witness = await circuit.calculateWitness({ "in": [0, 0] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[1], Fr.e(1)));
|
||||||
});
|
});
|
||||||
it("Should create a comparison greaterthan", async () => {
|
it("Should create a comparison greaterthan", async() => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "greaterthan.circom"));
|
|
||||||
|
|
||||||
const circuit = new snarkjs.Circuit(cirDef);
|
const circuit = await tester(path.join(__dirname, "circuits", "greaterthan.circom"));
|
||||||
|
|
||||||
let witness;
|
let witness;
|
||||||
witness = circuit.calculateWitness({ "in[0]": "333", "in[1]": "444" });
|
witness = await circuit.calculateWitness({ "in": [333,444] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(0)));
|
assert(Fr.eq(witness[1], Fr.e(0)));
|
||||||
|
|
||||||
witness = circuit.calculateWitness({ "in[0]": "1", "in[1]": "1" });
|
witness = await circuit.calculateWitness({ "in":[1,1] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(0)));
|
assert(Fr.eq(witness[1], Fr.e(0)));
|
||||||
|
|
||||||
witness = circuit.calculateWitness({ "in[0]": "661", "in[1]": "660" });
|
witness = await circuit.calculateWitness({ "in": [661, 660] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[1], Fr.e(1)));
|
||||||
|
|
||||||
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "1" });
|
witness = await circuit.calculateWitness({ "in": [0, 1] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(0)));
|
assert(Fr.eq(witness[1], Fr.e(0)));
|
||||||
|
|
||||||
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "444" });
|
witness = await circuit.calculateWitness({ "in": [0, 444] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(0)));
|
assert(Fr.eq(witness[1], Fr.e(0)));
|
||||||
|
|
||||||
witness = circuit.calculateWitness({ "in[0]": "1", "in[1]": "0" });
|
witness = await circuit.calculateWitness({ "in": [1, 0] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[1], Fr.e(1)));
|
||||||
|
|
||||||
witness = circuit.calculateWitness({ "in[0]": "555", "in[1]": "0" });
|
witness = await circuit.calculateWitness({ "in": [555, 0] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[1], Fr.e(1)));
|
||||||
|
|
||||||
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "0" });
|
witness = await circuit.calculateWitness({ "in": [0, 0] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(0)));
|
assert(Fr.eq(witness[1], Fr.e(0)));
|
||||||
});
|
});
|
||||||
it("Should create a comparison greatereqthan", async () => {
|
it("Should create a comparison greatereqthan", async() => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "greatereqthan.circom"));
|
const circuit = await tester(path.join(__dirname, "circuits", "greatereqthan.circom"));
|
||||||
|
|
||||||
const circuit = new snarkjs.Circuit(cirDef);
|
|
||||||
|
|
||||||
console.log("NConstraints BalancesUpdater: " + circuit.nConstraints);
|
|
||||||
|
|
||||||
let witness;
|
let witness;
|
||||||
witness = circuit.calculateWitness({ "in[0]": "333", "in[1]": "444" });
|
witness = await circuit.calculateWitness({ "in": [333,444] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(0)));
|
assert(Fr.eq(witness[1], Fr.e(0)));
|
||||||
|
|
||||||
witness = circuit.calculateWitness({ "in[0]": "1", "in[1]": "1" });
|
witness = await circuit.calculateWitness({ "in":[1,1] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[1], Fr.e(1)));
|
||||||
|
|
||||||
witness = circuit.calculateWitness({ "in[0]": "661", "in[1]": "660" });
|
witness = await circuit.calculateWitness({ "in": [661, 660] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[1], Fr.e(1)));
|
||||||
|
|
||||||
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "1" });
|
witness = await circuit.calculateWitness({ "in": [0, 1] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(0)));
|
assert(Fr.eq(witness[1], Fr.e(0)));
|
||||||
|
|
||||||
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "444" });
|
witness = await circuit.calculateWitness({ "in": [0, 444] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(0)));
|
assert(Fr.eq(witness[1], Fr.e(0)));
|
||||||
|
|
||||||
witness = circuit.calculateWitness({ "in[0]": "1", "in[1]": "0" });
|
witness = await circuit.calculateWitness({ "in": [1, 0] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[1], Fr.e(1)));
|
||||||
|
|
||||||
witness = circuit.calculateWitness({ "in[0]": "555", "in[1]": "0" });
|
witness = await circuit.calculateWitness({ "in": [555, 0] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[1], Fr.e(1)));
|
||||||
|
|
||||||
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "0" });
|
witness = await circuit.calculateWitness({ "in": [0, 0] }, true);
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[0], Fr.e(1)));
|
||||||
assert(witness[1].equals(snarkjs.bigInt(1)));
|
assert(Fr.eq(witness[1], Fr.e(1)));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,51 +1,46 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("@tornado/snarkjs");
|
|
||||||
const compiler = require("circom");
|
const tester = require("circom").tester;
|
||||||
// const crypto = require("crypto");
|
const Fr = require("ffjavascript").bn128.Fr;
|
||||||
|
|
||||||
const eddsa = require("../src/eddsa.js");
|
const eddsa = require("../src/eddsa.js");
|
||||||
const babyJub = require("../src/babyjub.js");
|
const babyJub = require("../src/babyjub.js");
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
const bigInt = snarkjs.bigInt;
|
|
||||||
|
|
||||||
function print(circuit, w, s) {
|
function print(circuit, w, s) {
|
||||||
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function buffer2bits(buff) {
|
function buffer2bits(buff) {
|
||||||
const res = [];
|
const res = [];
|
||||||
for (let i = 0; i < buff.length; i++) {
|
for (let i=0; i<buff.length; i++) {
|
||||||
for (let j = 0; j < 8; j++) {
|
for (let j=0; j<8; j++) {
|
||||||
if ((buff[i] >> j) & 1) {
|
if ((buff[i]>>j)&1) {
|
||||||
res.push(bigInt.one);
|
res.push(Fr.one);
|
||||||
} else {
|
} else {
|
||||||
res.push(bigInt.zero);
|
res.push(Fr.zero);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
describe("EdDSA test", function () {
|
describe("EdDSA test", function () {
|
||||||
let circuit;
|
let circuit;
|
||||||
|
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
|
|
||||||
before(async () => {
|
before( async () => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "eddsa_test.circom"));
|
circuit = await tester(path.join(__dirname, "circuits", "eddsa_test.circom"));
|
||||||
|
|
||||||
circuit = new snarkjs.Circuit(cirDef);
|
|
||||||
|
|
||||||
console.log("NConstrains EdDSA: " + circuit.nConstraints);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Sign a single 10 bytes from 0 to 9", async () => {
|
it("Sign a single 10 bytes from 0 to 9", async () => {
|
||||||
const msg = Buffer.from("00010203040506070809", "hex");
|
const msg = Buffer.from("00010203040506070809", "hex");
|
||||||
|
|
||||||
// const prvKey = crypto.randomBytes(32);
|
// const prvKey = crypto.randomBytes(32);
|
||||||
|
|
||||||
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
||||||
|
|
||||||
@ -65,8 +60,8 @@ describe("EdDSA test", function () {
|
|||||||
const sBits = buffer2bits(pSignature.slice(32, 64));
|
const sBits = buffer2bits(pSignature.slice(32, 64));
|
||||||
const aBits = buffer2bits(pPubKey);
|
const aBits = buffer2bits(pPubKey);
|
||||||
|
|
||||||
const w = circuit.calculateWitness({ A: aBits, R8: r8Bits, S: sBits, msg: msgBits });
|
const w = await circuit.calculateWitness({A: aBits, R8: r8Bits, S: sBits, msg: msgBits}, true);
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
await circuit.checkConstraints(w);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const snarkjs = require("@tornado/snarkjs");
|
|
||||||
|
|
||||||
const eddsa = require("../src/eddsa.js");
|
const eddsa = require("../src/eddsa.js");
|
||||||
const babyJub = require("../src/babyjub.js");
|
const babyJub = require("../src/babyjub.js");
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
const bigInt = snarkjs.bigInt;
|
const utils = require("ffjavascript").utils;
|
||||||
|
|
||||||
describe("EdDSA js test", function () {
|
describe("EdDSA js test", function () {
|
||||||
|
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
|
|
||||||
it("Sign (using Mimc7) a single 10 bytes from 0 to 9", () => {
|
it("Sign (using Mimc7) a single 10 bytes from 0 to 9", () => {
|
||||||
const msgBuf = Buffer.from("00010203040506070809", "hex");
|
const msgBuf = Buffer.from("00010203040506070809", "hex");
|
||||||
const msg = bigInt.leBuff2int(msgBuf);
|
const msg = utils.leBuff2int(msgBuf);
|
||||||
|
|
||||||
// const prvKey = crypto.randomBytes(32);
|
// const prvKey = crypto.randomBytes(32);
|
||||||
|
|
||||||
@ -21,55 +21,61 @@ describe("EdDSA js test", function () {
|
|||||||
|
|
||||||
const pubKey = eddsa.prv2pub(prvKey);
|
const pubKey = eddsa.prv2pub(prvKey);
|
||||||
|
|
||||||
assert.equal(pubKey[0].toString(), "13277427435165878497778222415993513565335242147425444199013288855685581939618");
|
assert.equal(pubKey[0].toString(),
|
||||||
assert.equal(pubKey[1].toString(), "13622229784656158136036771217484571176836296686641868549125388198837476602820");
|
"13277427435165878497778222415993513565335242147425444199013288855685581939618");
|
||||||
|
assert.equal(pubKey[1].toString(),
|
||||||
|
"13622229784656158136036771217484571176836296686641868549125388198837476602820");
|
||||||
|
|
||||||
const pPubKey = babyJub.packPoint(pubKey);
|
const pPubKey = babyJub.packPoint(pubKey);
|
||||||
|
|
||||||
const signature = eddsa.signMiMC(prvKey, msg);
|
const signature = eddsa.signMiMC(prvKey, msg);
|
||||||
assert.equal(signature.R8[0].toString(), "11384336176656855268977457483345535180380036354188103142384839473266348197733");
|
assert.equal(signature.R8[0].toString(),
|
||||||
assert.equal(signature.R8[1].toString(), "15383486972088797283337779941324724402501462225528836549661220478783371668959");
|
"11384336176656855268977457483345535180380036354188103142384839473266348197733");
|
||||||
assert.equal(signature.S.toString(), "2523202440825208709475937830811065542425109372212752003460238913256192595070");
|
assert.equal(signature.R8[1].toString(),
|
||||||
|
"15383486972088797283337779941324724402501462225528836549661220478783371668959");
|
||||||
|
assert.equal(signature.S.toString(),
|
||||||
|
"2523202440825208709475937830811065542425109372212752003460238913256192595070");
|
||||||
|
|
||||||
const pSignature = eddsa.packSignature(signature);
|
const pSignature = eddsa.packSignature(signature);
|
||||||
assert.equal(
|
assert.equal(pSignature.toString("hex"), ""+
|
||||||
pSignature.toString("hex"),
|
"dfedb4315d3f2eb4de2d3c510d7a987dcab67089c8ace06308827bf5bcbe02a2"+
|
||||||
"" +
|
"7ed40dab29bf993c928e789d007387998901a24913d44fddb64b1f21fc149405");
|
||||||
"dfedb4315d3f2eb4de2d3c510d7a987dcab67089c8ace06308827bf5bcbe02a2" +
|
|
||||||
"7ed40dab29bf993c928e789d007387998901a24913d44fddb64b1f21fc149405"
|
|
||||||
);
|
|
||||||
|
|
||||||
const uSignature = eddsa.unpackSignature(pSignature);
|
const uSignature = eddsa.unpackSignature(pSignature);
|
||||||
assert(eddsa.verifyMiMC(msg, uSignature, pubKey));
|
assert(eddsa.verifyMiMC(msg, uSignature, pubKey));
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Sign (using Poseidon) a single 10 bytes from 0 to 9", () => {
|
it("Sign (using Poseidon) a single 10 bytes from 0 to 9", () => {
|
||||||
const msgBuf = Buffer.from("00010203040506070809", "hex");
|
const msgBuf = Buffer.from("00010203040506070809", "hex");
|
||||||
const msg = bigInt.leBuff2int(msgBuf);
|
const msg = utils.leBuff2int(msgBuf);
|
||||||
|
|
||||||
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
||||||
|
|
||||||
const pubKey = eddsa.prv2pub(prvKey);
|
const pubKey = eddsa.prv2pub(prvKey);
|
||||||
|
|
||||||
assert.equal(pubKey[0].toString(), "13277427435165878497778222415993513565335242147425444199013288855685581939618");
|
assert.equal(pubKey[0].toString(),
|
||||||
assert.equal(pubKey[1].toString(), "13622229784656158136036771217484571176836296686641868549125388198837476602820");
|
"13277427435165878497778222415993513565335242147425444199013288855685581939618");
|
||||||
|
assert.equal(pubKey[1].toString(),
|
||||||
|
"13622229784656158136036771217484571176836296686641868549125388198837476602820");
|
||||||
|
|
||||||
const pPubKey = babyJub.packPoint(pubKey);
|
const pPubKey = babyJub.packPoint(pubKey);
|
||||||
|
|
||||||
const signature = eddsa.signPoseidon(prvKey, msg);
|
const signature = eddsa.signPoseidon(prvKey, msg);
|
||||||
assert.equal(signature.R8[0].toString(), "11384336176656855268977457483345535180380036354188103142384839473266348197733");
|
assert.equal(signature.R8[0].toString(),
|
||||||
assert.equal(signature.R8[1].toString(), "15383486972088797283337779941324724402501462225528836549661220478783371668959");
|
"11384336176656855268977457483345535180380036354188103142384839473266348197733");
|
||||||
assert.equal(signature.S.toString(), "1398758333392199195742243841591064350253744445503462896781493968760929513778");
|
assert.equal(signature.R8[1].toString(),
|
||||||
|
"15383486972088797283337779941324724402501462225528836549661220478783371668959");
|
||||||
|
assert.equal(signature.S.toString(),
|
||||||
|
"1398758333392199195742243841591064350253744445503462896781493968760929513778");
|
||||||
|
|
||||||
const pSignature = eddsa.packSignature(signature);
|
const pSignature = eddsa.packSignature(signature);
|
||||||
assert.equal(
|
assert.equal(pSignature.toString("hex"), ""+
|
||||||
pSignature.toString("hex"),
|
"dfedb4315d3f2eb4de2d3c510d7a987dcab67089c8ace06308827bf5bcbe02a2"+
|
||||||
"" +
|
"32f16b0f2f4c4e1169aa59685637e1429b6581a9531d058d65f4ab224eab1703");
|
||||||
"dfedb4315d3f2eb4de2d3c510d7a987dcab67089c8ace06308827bf5bcbe02a2" +
|
|
||||||
"32f16b0f2f4c4e1169aa59685637e1429b6581a9531d058d65f4ab224eab1703"
|
|
||||||
);
|
|
||||||
|
|
||||||
const uSignature = eddsa.unpackSignature(pSignature);
|
const uSignature = eddsa.unpackSignature(pSignature);
|
||||||
assert(eddsa.verifyPoseidon(msg, uSignature, pubKey));
|
assert(eddsa.verifyPoseidon(msg, uSignature, pubKey));
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,29 +1,25 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("@tornado/snarkjs");
|
const tester = require("circom").tester;
|
||||||
const compiler = require("circom");
|
|
||||||
|
const Fr = require("ffjavascript").bn128.Fr;
|
||||||
|
|
||||||
const eddsa = require("../src/eddsa.js");
|
const eddsa = require("../src/eddsa.js");
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
const bigInt = snarkjs.bigInt;
|
|
||||||
|
|
||||||
describe("EdDSA MiMC test", function () {
|
describe("EdDSA MiMC test", function () {
|
||||||
let circuit;
|
let circuit;
|
||||||
|
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
|
|
||||||
before(async () => {
|
before( async () => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "eddsamimc_test.circom"));
|
|
||||||
|
|
||||||
circuit = new snarkjs.Circuit(cirDef);
|
circuit = await tester(path.join(__dirname, "circuits", "eddsamimc_test.circom"));
|
||||||
|
|
||||||
console.log("NConstrains EdDSA MiMC: " + circuit.nConstraints);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Sign a single number", async () => {
|
it("Sign a single number", async () => {
|
||||||
const msg = bigInt(1234);
|
const msg = Fr.e(1234);
|
||||||
|
|
||||||
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
||||||
|
|
||||||
@ -33,66 +29,69 @@ describe("EdDSA MiMC test", function () {
|
|||||||
|
|
||||||
assert(eddsa.verifyMiMC(msg, signature, pubKey));
|
assert(eddsa.verifyMiMC(msg, signature, pubKey));
|
||||||
|
|
||||||
const w = circuit.calculateWitness({
|
const w = await circuit.calculateWitness({
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
Ax: pubKey[0],
|
Ax: pubKey[0],
|
||||||
Ay: pubKey[1],
|
Ay: pubKey[1],
|
||||||
R8x: signature.R8[0],
|
R8x: signature.R8[0],
|
||||||
R8y: signature.R8[1],
|
R8y: signature.R8[1],
|
||||||
S: signature.S,
|
S: signature.S,
|
||||||
M: msg,
|
M: msg}, true);
|
||||||
});
|
|
||||||
|
|
||||||
|
await circuit.checkConstraints(w);
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Detect Invalid signature", async () => {
|
it("Detect Invalid signature", async () => {
|
||||||
const msg = bigInt(1234);
|
const msg = Fr.e(1234);
|
||||||
|
|
||||||
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
||||||
|
|
||||||
const pubKey = eddsa.prv2pub(prvKey);
|
const pubKey = eddsa.prv2pub(prvKey);
|
||||||
|
|
||||||
|
|
||||||
const signature = eddsa.signMiMC(prvKey, msg);
|
const signature = eddsa.signMiMC(prvKey, msg);
|
||||||
|
|
||||||
assert(eddsa.verifyMiMC(msg, signature, pubKey));
|
assert(eddsa.verifyMiMC(msg, signature, pubKey));
|
||||||
try {
|
try {
|
||||||
const w = circuit.calculateWitness({
|
const w = await circuit.calculateWitness({
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
Ax: pubKey[0],
|
Ax: pubKey[0],
|
||||||
Ay: pubKey[1],
|
Ay: pubKey[1],
|
||||||
R8x: signature.R8[0].add(bigInt(1)),
|
R8x: Fr.add(signature.R8[0], Fr.e(1)),
|
||||||
R8y: signature.R8[1],
|
R8y: signature.R8[1],
|
||||||
S: signature.S,
|
S: signature.S,
|
||||||
M: msg,
|
M: msg}, true);
|
||||||
});
|
|
||||||
assert(false);
|
assert(false);
|
||||||
} catch (err) {
|
} catch(err) {
|
||||||
assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message));
|
assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message) );
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it("Test a dissabled circuit with a bad signature", async () => {
|
it("Test a dissabled circuit with a bad signature", async () => {
|
||||||
const msg = bigInt(1234);
|
const msg = Fr.e(1234);
|
||||||
|
|
||||||
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
||||||
|
|
||||||
const pubKey = eddsa.prv2pub(prvKey);
|
const pubKey = eddsa.prv2pub(prvKey);
|
||||||
|
|
||||||
|
|
||||||
const signature = eddsa.signMiMC(prvKey, msg);
|
const signature = eddsa.signMiMC(prvKey, msg);
|
||||||
|
|
||||||
assert(eddsa.verifyMiMC(msg, signature, pubKey));
|
assert(eddsa.verifyMiMC(msg, signature, pubKey));
|
||||||
|
|
||||||
const w = circuit.calculateWitness({
|
const w = await circuit.calculateWitness({
|
||||||
enabled: 0,
|
enabled: 0,
|
||||||
Ax: pubKey[0],
|
Ax: pubKey[0],
|
||||||
Ay: pubKey[1],
|
Ay: pubKey[1],
|
||||||
R8x: signature.R8[0].add(bigInt(1)),
|
R8x: Fr.add(signature.R8[0], Fr.e(1)),
|
||||||
R8y: signature.R8[1],
|
R8y: signature.R8[1],
|
||||||
S: signature.S,
|
S: signature.S,
|
||||||
M: msg,
|
M: msg}, true);
|
||||||
});
|
|
||||||
|
await circuit.checkConstraints(w);
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,99 +0,0 @@
|
|||||||
const chai = require("chai");
|
|
||||||
const path = require("path");
|
|
||||||
const snarkjs = require("@tornado/snarkjs");
|
|
||||||
const compiler = require("circom");
|
|
||||||
|
|
||||||
const eddsa = require("../src/eddsa.js");
|
|
||||||
|
|
||||||
const assert = chai.assert;
|
|
||||||
|
|
||||||
const bigInt = snarkjs.bigInt;
|
|
||||||
|
|
||||||
describe("EdDSA MiMCSponge test", function () {
|
|
||||||
let circuit;
|
|
||||||
|
|
||||||
this.timeout(100000);
|
|
||||||
|
|
||||||
before(async () => {
|
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "eddsamimcsponge_test.circom"));
|
|
||||||
|
|
||||||
circuit = new snarkjs.Circuit(cirDef);
|
|
||||||
|
|
||||||
console.log("NConstrains EdDSA MiMCSponge: " + circuit.nConstraints);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Sign a single number", async () => {
|
|
||||||
const msg = bigInt(1234);
|
|
||||||
|
|
||||||
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
|
||||||
|
|
||||||
const pubKey = eddsa.prv2pub(prvKey);
|
|
||||||
|
|
||||||
const signature = eddsa.signMiMCSponge(prvKey, msg);
|
|
||||||
|
|
||||||
assert(eddsa.verifyMiMCSponge(msg, signature, pubKey));
|
|
||||||
|
|
||||||
const w = circuit.calculateWitness({
|
|
||||||
enabled: 1,
|
|
||||||
Ax: pubKey[0],
|
|
||||||
Ay: pubKey[1],
|
|
||||||
R8x: signature.R8[0],
|
|
||||||
R8y: signature.R8[1],
|
|
||||||
S: signature.S,
|
|
||||||
M: msg,
|
|
||||||
});
|
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Detect Invalid signature", async () => {
|
|
||||||
const msg = bigInt(1234);
|
|
||||||
|
|
||||||
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
|
||||||
|
|
||||||
const pubKey = eddsa.prv2pub(prvKey);
|
|
||||||
|
|
||||||
const signature = eddsa.signMiMCSponge(prvKey, msg);
|
|
||||||
|
|
||||||
assert(eddsa.verifyMiMCSponge(msg, signature, pubKey));
|
|
||||||
try {
|
|
||||||
const w = circuit.calculateWitness({
|
|
||||||
enabled: 1,
|
|
||||||
Ax: pubKey[0],
|
|
||||||
Ay: pubKey[1],
|
|
||||||
R8x: signature.R8[0].add(bigInt(1)),
|
|
||||||
R8y: signature.R8[1],
|
|
||||||
S: signature.S,
|
|
||||||
M: msg,
|
|
||||||
});
|
|
||||||
assert(false);
|
|
||||||
} catch (err) {
|
|
||||||
assert(err.message.indexOf("Constraint doesn't match") >= 0);
|
|
||||||
assert(err.message.indexOf("1 != 0") >= 0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Test a dissabled circuit with a bad signature", async () => {
|
|
||||||
const msg = bigInt(1234);
|
|
||||||
|
|
||||||
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
|
||||||
|
|
||||||
const pubKey = eddsa.prv2pub(prvKey);
|
|
||||||
|
|
||||||
const signature = eddsa.signMiMCSponge(prvKey, msg);
|
|
||||||
|
|
||||||
assert(eddsa.verifyMiMCSponge(msg, signature, pubKey));
|
|
||||||
|
|
||||||
const w = circuit.calculateWitness({
|
|
||||||
enabled: 0,
|
|
||||||
Ax: pubKey[0],
|
|
||||||
Ay: pubKey[1],
|
|
||||||
R8x: signature.R8[0].add(bigInt(1)),
|
|
||||||
R8y: signature.R8[1],
|
|
||||||
S: signature.S,
|
|
||||||
M: msg,
|
|
||||||
});
|
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,29 +1,25 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("@tornado/snarkjs");
|
const tester = require("circom").tester;
|
||||||
const compiler = require("circom");
|
const Fr = require("ffjavascript").bn128.Fr;
|
||||||
|
|
||||||
const eddsa = require("../src/eddsa.js");
|
const eddsa = require("../src/eddsa.js");
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
const bigInt = snarkjs.bigInt;
|
|
||||||
|
|
||||||
describe("EdDSA Poseidon test", function () {
|
describe("EdDSA Poseidon test", function () {
|
||||||
let circuit;
|
let circuit;
|
||||||
|
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
|
|
||||||
before(async () => {
|
before( async () => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "eddsaposeidon_test.circom"));
|
|
||||||
|
|
||||||
circuit = new snarkjs.Circuit(cirDef);
|
circuit = await tester(path.join(__dirname, "circuits", "eddsaposeidon_test.circom"));
|
||||||
|
|
||||||
console.log("NConstrains EdDSA Poseidon: " + circuit.nConstraints);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Sign a single number", async () => {
|
it("Sign a single number", async () => {
|
||||||
const msg = bigInt(1234);
|
const msg = Fr.e(1234);
|
||||||
|
|
||||||
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
||||||
|
|
||||||
@ -33,66 +29,71 @@ describe("EdDSA Poseidon test", function () {
|
|||||||
|
|
||||||
assert(eddsa.verifyPoseidon(msg, signature, pubKey));
|
assert(eddsa.verifyPoseidon(msg, signature, pubKey));
|
||||||
|
|
||||||
const w = circuit.calculateWitness({
|
const input = {
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
Ax: pubKey[0],
|
Ax: pubKey[0],
|
||||||
Ay: pubKey[1],
|
Ay: pubKey[1],
|
||||||
R8x: signature.R8[0],
|
R8x: signature.R8[0],
|
||||||
R8y: signature.R8[1],
|
R8y: signature.R8[1],
|
||||||
S: signature.S,
|
S: signature.S,
|
||||||
M: msg,
|
M: msg
|
||||||
});
|
};
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
// console.log(JSON.stringify(utils.stringifyBigInts(input)));
|
||||||
|
|
||||||
|
const w = await circuit.calculateWitness(input, true);
|
||||||
|
|
||||||
|
await circuit.checkConstraints(w);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Detect Invalid signature", async () => {
|
it("Detect Invalid signature", async () => {
|
||||||
const msg = bigInt(1234);
|
const msg = Fr.e(1234);
|
||||||
|
|
||||||
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
||||||
|
|
||||||
const pubKey = eddsa.prv2pub(prvKey);
|
const pubKey = eddsa.prv2pub(prvKey);
|
||||||
|
|
||||||
|
|
||||||
const signature = eddsa.signPoseidon(prvKey, msg);
|
const signature = eddsa.signPoseidon(prvKey, msg);
|
||||||
|
|
||||||
assert(eddsa.verifyPoseidon(msg, signature, pubKey));
|
assert(eddsa.verifyPoseidon(msg, signature, pubKey));
|
||||||
try {
|
try {
|
||||||
circuit.calculateWitness({
|
await circuit.calculateWitness({
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
Ax: pubKey[0],
|
Ax: pubKey[0],
|
||||||
Ay: pubKey[1],
|
Ay: pubKey[1],
|
||||||
R8x: signature.R8[0].add(bigInt(1)),
|
R8x: Fr.add(signature.R8[0], Fr.e(1)),
|
||||||
R8y: signature.R8[1],
|
R8y: signature.R8[1],
|
||||||
S: signature.S,
|
S: signature.S,
|
||||||
M: msg,
|
M: msg}, true);
|
||||||
});
|
|
||||||
assert(false);
|
assert(false);
|
||||||
} catch (err) {
|
} catch(err) {
|
||||||
assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message));
|
assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message) );
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it("Test a dissabled circuit with a bad signature", async () => {
|
it("Test a dissabled circuit with a bad signature", async () => {
|
||||||
const msg = bigInt(1234);
|
const msg = Fr.e(1234);
|
||||||
|
|
||||||
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
||||||
|
|
||||||
const pubKey = eddsa.prv2pub(prvKey);
|
const pubKey = eddsa.prv2pub(prvKey);
|
||||||
|
|
||||||
|
|
||||||
const signature = eddsa.signPoseidon(prvKey, msg);
|
const signature = eddsa.signPoseidon(prvKey, msg);
|
||||||
|
|
||||||
assert(eddsa.verifyPoseidon(msg, signature, pubKey));
|
assert(eddsa.verifyPoseidon(msg, signature, pubKey));
|
||||||
|
|
||||||
const w = circuit.calculateWitness({
|
const w = await circuit.calculateWitness({
|
||||||
enabled: 0,
|
enabled: 0,
|
||||||
Ax: pubKey[0],
|
Ax: pubKey[0],
|
||||||
Ay: pubKey[1],
|
Ay: pubKey[1],
|
||||||
R8x: signature.R8[0].add(bigInt(1)),
|
R8x: Fr.add(signature.R8[0], Fr.e(1)),
|
||||||
R8y: signature.R8[1],
|
R8y: signature.R8[1],
|
||||||
S: signature.S,
|
S: signature.S,
|
||||||
M: msg,
|
M: msg}, true);
|
||||||
});
|
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
await circuit.checkConstraints(w);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,170 +1,115 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("@tornado/snarkjs");
|
const tester = require("circom").tester;
|
||||||
const compiler = require("circom");
|
const babyJub = require("../src/babyjub.js");
|
||||||
|
const Fr = require("ffjavascript").bn128.Fr;
|
||||||
|
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
const bigInt = snarkjs.bigInt;
|
|
||||||
|
|
||||||
const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
|
||||||
function addPoint(a, b) {
|
|
||||||
const cta = bigInt("168700");
|
|
||||||
const d = bigInt("168696");
|
|
||||||
|
|
||||||
const res = [];
|
|
||||||
res[0] = bigInt((a[0] * b[1] + b[0] * a[1]) * bigInt(bigInt.one + d * a[0] * b[0] * a[1] * b[1]).inverse(q)).affine(q);
|
|
||||||
res[1] = bigInt((a[1] * b[1] - cta * a[0] * b[0]) * bigInt(bigInt.one - d * a[0] * b[0] * a[1] * b[1]).inverse(q)).affine(q);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
function print(circuit, w, s) {
|
function print(circuit, w, s) {
|
||||||
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("Exponentioation test", () => {
|
describe("Exponentioation test", function () {
|
||||||
|
|
||||||
|
this.timeout(100000);
|
||||||
|
|
||||||
it("Should generate the Exponentiation table in k=0", async () => {
|
it("Should generate the Exponentiation table in k=0", async () => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "escalarmulw4table_test.circom"));
|
|
||||||
|
|
||||||
// console.log(JSON.stringify(cirDef, null, 1));
|
const circuit = await tester(path.join(__dirname, "circuits", "escalarmulw4table_test.circom"));
|
||||||
|
|
||||||
// assert.equal(cirDef.nVars, 2);
|
const w = await circuit.calculateWitness({in: 1});
|
||||||
|
|
||||||
const circuit = new snarkjs.Circuit(cirDef);
|
await circuit.checkConstraints(w);
|
||||||
|
|
||||||
console.log("NConstrains: " + circuit.nConstraints);
|
|
||||||
|
|
||||||
const w = circuit.calculateWitness({ in: 1 });
|
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
|
||||||
|
|
||||||
let g = [
|
let g = [
|
||||||
bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
Fr.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
||||||
bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203"),
|
Fr.e("16950150798460657717958625567821834550301663161624707787222815936182638968203")
|
||||||
];
|
];
|
||||||
|
|
||||||
dbl = [bigInt("0"), snarkjs.bigInt("1")];
|
let dbl= [Fr.e("0"), Fr.e("1")];
|
||||||
|
|
||||||
for (let i = 0; i < 16; i++) {
|
const expectedOut = [];
|
||||||
const xout1 = w[circuit.getSignalIdx(`main.out[${i}][0]`)];
|
|
||||||
const yout1 = w[circuit.getSignalIdx(`main.out[${i}][1]`)];
|
|
||||||
|
|
||||||
// console.log(xout1.toString());
|
for (let i=0; i<16; i++) {
|
||||||
// console.log(yout1.toString());
|
|
||||||
// console.log(dbl[0]);
|
|
||||||
// console.log(dbl[1]);
|
|
||||||
|
|
||||||
assert(xout1.equals(dbl[0]));
|
expectedOut.push(dbl);
|
||||||
assert(yout1.equals(dbl[1]));
|
dbl = babyJub.addPoint(dbl,g);
|
||||||
|
|
||||||
dbl = addPoint([xout1, yout1], g);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await circuit.assertOut(w, {out: expectedOut});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should generate the Exponentiation table in k=3", async () => {
|
it("Should generate the Exponentiation table in k=3", async () => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "escalarmulw4table_test3.circom"));
|
|
||||||
|
|
||||||
// console.log(JSON.stringify(cirDef, null, 1));
|
const circuit = await tester(path.join(__dirname, "circuits", "escalarmulw4table_test3.circom"));
|
||||||
|
|
||||||
// assert.equal(cirDef.nVars, 2);
|
const w = await circuit.calculateWitness({in: 1});
|
||||||
|
|
||||||
const circuit = new snarkjs.Circuit(cirDef);
|
await circuit.checkConstraints(w);
|
||||||
|
|
||||||
console.log("NConstrains: " + circuit.nConstraints);
|
|
||||||
|
|
||||||
const w = circuit.calculateWitness({ in: 1 });
|
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
|
||||||
|
|
||||||
let g = [
|
let g = [
|
||||||
snarkjs.bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
Fr.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
||||||
snarkjs.bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203"),
|
Fr.e("16950150798460657717958625567821834550301663161624707787222815936182638968203")
|
||||||
];
|
];
|
||||||
|
|
||||||
for (let i = 0; i < 12; i++) {
|
for (let i=0; i<12;i++) {
|
||||||
g = addPoint(g, g);
|
g = babyJub.addPoint(g,g);
|
||||||
}
|
}
|
||||||
|
|
||||||
dbl = [snarkjs.bigInt("0"), snarkjs.bigInt("1")];
|
let dbl= [Fr.e("0"), Fr.e("1")];
|
||||||
|
|
||||||
for (let i = 0; i < 16; i++) {
|
const expectedOut = [];
|
||||||
const xout1 = w[circuit.getSignalIdx(`main.out[${i}][0]`)];
|
|
||||||
const yout1 = w[circuit.getSignalIdx(`main.out[${i}][1]`)];
|
|
||||||
|
|
||||||
// console.log(xout1.toString());
|
for (let i=0; i<16; i++) {
|
||||||
// console.log(yout1.toString());
|
expectedOut.push(dbl);
|
||||||
// console.log(dbl[0]);
|
|
||||||
// console.log(dbl[1]);
|
|
||||||
|
|
||||||
assert(xout1.equals(dbl[0]));
|
dbl = babyJub.addPoint(dbl,g);
|
||||||
assert(yout1.equals(dbl[1]));
|
|
||||||
|
|
||||||
dbl = addPoint([xout1, yout1], g);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await circuit.assertOut(w, {out: expectedOut});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should exponentiate g^31", async () => {
|
it("Should exponentiate g^31", async () => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "escalarmul_test.circom"), { reduceConstraints: true });
|
|
||||||
|
|
||||||
// console.log(JSON.stringify(cirDef, null, 1));
|
const circuit = await tester(path.join(__dirname, "circuits", "escalarmul_test.circom"));
|
||||||
|
|
||||||
// assert.equal(cirDef.nVars, 2);
|
const w = await circuit.calculateWitness({"in": 31});
|
||||||
|
|
||||||
const circuit = new snarkjs.Circuit(cirDef);
|
await circuit.checkConstraints(w);
|
||||||
|
|
||||||
console.log("NConstrains: " + circuit.nConstraints);
|
|
||||||
|
|
||||||
const w = circuit.calculateWitness({ in: 31 });
|
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
|
||||||
|
|
||||||
let g = [
|
let g = [
|
||||||
snarkjs.bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
Fr.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
||||||
snarkjs.bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203"),
|
Fr.e("16950150798460657717958625567821834550301663161624707787222815936182638968203")
|
||||||
];
|
];
|
||||||
|
|
||||||
let c = [0n, 1n];
|
let c = [Fr.e(0), Fr.e(1)];
|
||||||
|
|
||||||
for (let i = 0; i < 31; i++) {
|
for (let i=0; i<31;i++) {
|
||||||
c = addPoint(c, g);
|
c = babyJub.addPoint(c,g);
|
||||||
}
|
}
|
||||||
|
|
||||||
const xout = w[circuit.getSignalIdx(`main.out[0]`)];
|
await circuit.assertOut(w, {out: c});
|
||||||
const yout = w[circuit.getSignalIdx(`main.out[1]`)];
|
|
||||||
|
|
||||||
/*
|
const w2 = await circuit.calculateWitness({"in": Fr.add(Fr.shl(Fr.e(1), Fr.e(252)),Fr.one)});
|
||||||
console.log(xout.toString());
|
|
||||||
console.log(yout.toString());
|
|
||||||
*/
|
|
||||||
assert(xout.equals(c[0]));
|
|
||||||
assert(yout.equals(c[1]));
|
|
||||||
|
|
||||||
console.log("-------");
|
|
||||||
const w2 = circuit.calculateWitness({ in: (1n << 252n) + 1n });
|
|
||||||
|
|
||||||
const xout2 = w2[circuit.getSignalIdx(`main.out[0]`)];
|
|
||||||
const yout2 = w2[circuit.getSignalIdx(`main.out[1]`)];
|
|
||||||
|
|
||||||
c = [g[0], g[1]];
|
c = [g[0], g[1]];
|
||||||
for (let i = 0; i < 252; i++) {
|
for (let i=0; i<252;i++) {
|
||||||
c = addPoint(c, c);
|
c = babyJub.addPoint(c,c);
|
||||||
}
|
}
|
||||||
c = addPoint(c, g);
|
c = babyJub.addPoint(c,g);
|
||||||
|
|
||||||
// console.log(xout2.toString());
|
await circuit.assertOut(w2, {out: c});
|
||||||
// console.log(yout2.toString());
|
|
||||||
// console.log(c[0].toString());
|
|
||||||
// console.log(c[1].toString());
|
|
||||||
|
|
||||||
assert(xout2.equals(c[0]));
|
|
||||||
assert(yout2.equals(c[1]));
|
|
||||||
}).timeout(10000000);
|
}).timeout(10000000);
|
||||||
|
|
||||||
it("Number of constrains for 256 bits", async () => {
|
it("Number of constrains for 256 bits", async () => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "escalarmul_test_min.circom"));
|
|
||||||
|
|
||||||
const circuit = new snarkjs.Circuit(cirDef);
|
const circuit = await tester(path.join(__dirname, "circuits", "escalarmul_test_min.circom"));
|
||||||
|
|
||||||
console.log("NConstrains: " + circuit.nConstraints);
|
|
||||||
}).timeout(10000000);
|
}).timeout(10000000);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("@tornado/snarkjs");
|
const tester = require("circom").tester;
|
||||||
const compiler = require("circom");
|
const Fr = require("ffjavascript").bn128.Fr;
|
||||||
|
|
||||||
const assert = chai.assert;
|
|
||||||
|
|
||||||
const bigInt = snarkjs.bigInt;
|
|
||||||
|
|
||||||
function print(circuit, w, s) {
|
function print(circuit, w, s) {
|
||||||
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
||||||
@ -17,38 +14,34 @@ describe("Escalarmul test", function () {
|
|||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
|
|
||||||
let g = [
|
let g = [
|
||||||
snarkjs.bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
Fr.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
||||||
snarkjs.bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203"),
|
Fr.e("16950150798460657717958625567821834550301663161624707787222815936182638968203")
|
||||||
];
|
];
|
||||||
|
|
||||||
before(async () => {
|
before( async() => {
|
||||||
const cirDefEMulAny = await compiler(path.join(__dirname, "circuits", "escalarmulany_test.circom"));
|
circuitEMulAny = await tester(path.join(__dirname, "circuits", "escalarmulany_test.circom"));
|
||||||
circuitEMulAny = new snarkjs.Circuit(cirDefEMulAny);
|
|
||||||
console.log("NConstrains Escalarmul any: " + circuitEMulAny.nConstraints);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should generate Same escalar mul", async () => {
|
it("Should generate Same escalar mul", async () => {
|
||||||
const w = circuitEMulAny.calculateWitness({ e: 1, p: g });
|
|
||||||
|
|
||||||
assert(circuitEMulAny.checkWitness(w));
|
const w = await circuitEMulAny.calculateWitness({"e": 1, "p": g});
|
||||||
|
|
||||||
const xout = w[circuitEMulAny.getSignalIdx("main.out[0]")];
|
await circuitEMulAny.checkConstraints(w);
|
||||||
const yout = w[circuitEMulAny.getSignalIdx("main.out[1]")];
|
|
||||||
|
await circuitEMulAny.assertOut(w, {out: g}, true);
|
||||||
|
|
||||||
assert(xout.equals(g[0]));
|
|
||||||
assert(yout.equals(g[1]));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("If multiply by order should return 0", async () => {
|
it("If multiply by order should return 0", async () => {
|
||||||
const r = bigInt("2736030358979909402780800718157159386076813972158567259200215660948447373041");
|
|
||||||
const w = circuitEMulAny.calculateWitness({ e: r, p: g });
|
|
||||||
|
|
||||||
assert(circuitEMulAny.checkWitness(w));
|
const r = Fr.e("2736030358979909402780800718157159386076813972158567259200215660948447373041");
|
||||||
|
const w = await circuitEMulAny.calculateWitness({"e": r, "p": g});
|
||||||
|
|
||||||
const xout = w[circuitEMulAny.getSignalIdx("main.out[0]")];
|
await circuitEMulAny.checkConstraints(w);
|
||||||
const yout = w[circuitEMulAny.getSignalIdx("main.out[1]")];
|
|
||||||
|
await circuitEMulAny.assertOut(w, {out: [0,1]}, true);
|
||||||
|
|
||||||
assert(xout.equals(bigInt.zero));
|
|
||||||
assert(yout.equals(bigInt.one));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("@tornado/snarkjs");
|
const tester = require("circom").tester;
|
||||||
const compiler = require("circom");
|
|
||||||
const babyjub = require("../src/babyjub");
|
const babyjub = require("../src/babyjub");
|
||||||
|
const Fr = require("ffjavascript").bn128.Fr;
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
const bigInt = snarkjs.bigInt;
|
|
||||||
|
|
||||||
function print(circuit, w, s) {
|
function print(circuit, w, s) {
|
||||||
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
||||||
}
|
}
|
||||||
@ -17,88 +15,76 @@ describe("Escalarmul test", function () {
|
|||||||
|
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
|
|
||||||
before(async () => {
|
before( async() => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "escalarmulfix_test.circom"));
|
circuit = await tester(path.join(__dirname, "circuits", "escalarmulfix_test.circom"));
|
||||||
circuit = new snarkjs.Circuit(cirDef);
|
|
||||||
console.log("NConstrains Escalarmul fix: " + circuit.nConstraints);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should generate Same escalar mul", async () => {
|
it("Should generate Same escalar mul", async () => {
|
||||||
const w = circuit.calculateWitness({ e: 0 });
|
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
const w = await circuit.calculateWitness({"e": 0});
|
||||||
|
|
||||||
const xout = w[circuit.getSignalIdx("main.out[0]")];
|
await circuit.checkConstraints(w);
|
||||||
const yout = w[circuit.getSignalIdx("main.out[1]")];
|
|
||||||
|
await circuit.assertOut(w, {out: [0,1]}, true);
|
||||||
|
|
||||||
assert(xout.equals(0));
|
|
||||||
assert(yout.equals(1));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should generate Same escalar mul", async () => {
|
it("Should generate Same escalar mul", async () => {
|
||||||
const w = circuit.calculateWitness({ e: 1 });
|
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
const w = await circuit.calculateWitness({"e": 1}, true);
|
||||||
|
|
||||||
const xout = w[circuit.getSignalIdx("main.out[0]")];
|
await circuit.checkConstraints(w);
|
||||||
const yout = w[circuit.getSignalIdx("main.out[1]")];
|
|
||||||
|
await circuit.assertOut(w, {out: babyjub.Base8});
|
||||||
|
|
||||||
assert(xout.equals(babyjub.Base8[0]));
|
|
||||||
assert(yout.equals(babyjub.Base8[1]));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should generate scalar mul of a specific constant", async () => {
|
it("Should generate scalar mul of a specific constant", async () => {
|
||||||
const s = bigInt("2351960337287830298912035165133676222414898052661454064215017316447594616519");
|
|
||||||
|
const s = Fr.e("2351960337287830298912035165133676222414898052661454064215017316447594616519");
|
||||||
const base8 = [
|
const base8 = [
|
||||||
bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
Fr.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
||||||
bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203"),
|
Fr.e("16950150798460657717958625567821834550301663161624707787222815936182638968203")
|
||||||
];
|
];
|
||||||
|
|
||||||
const w = circuit.calculateWitness({ e: s });
|
const w = await circuit.calculateWitness({"e": s}, true);
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
await circuit.checkConstraints(w);
|
||||||
|
|
||||||
const xout = w[circuit.getSignalIdx("main.out[0]")];
|
|
||||||
const yout = w[circuit.getSignalIdx("main.out[1]")];
|
|
||||||
|
|
||||||
const expectedRes = babyjub.mulPointEscalar(base8, s);
|
const expectedRes = babyjub.mulPointEscalar(base8, s);
|
||||||
|
|
||||||
assert(xout.equals(expectedRes[0]));
|
await circuit.assertOut(w, {out: expectedRes});
|
||||||
assert(yout.equals(expectedRes[1]));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should generate scalar mul of the firsts 50 elements", async () => {
|
it("Should generate scalar mul of the firsts 50 elements", async () => {
|
||||||
|
|
||||||
const base8 = [
|
const base8 = [
|
||||||
bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
Fr.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
||||||
bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203"),
|
Fr.e("16950150798460657717958625567821834550301663161624707787222815936182638968203")
|
||||||
];
|
];
|
||||||
|
|
||||||
for (let i = 0; i < 50; i++) {
|
for (let i=0; i<50; i++) {
|
||||||
const s = bigInt(i);
|
const s = Fr.e(i);
|
||||||
|
|
||||||
const w = circuit.calculateWitness({ e: s });
|
const w = await circuit.calculateWitness({"e": s}, true);
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
await circuit.checkConstraints(w);
|
||||||
|
|
||||||
const xout = w[circuit.getSignalIdx("main.out[0]")];
|
|
||||||
const yout = w[circuit.getSignalIdx("main.out[1]")];
|
|
||||||
|
|
||||||
const expectedRes = babyjub.mulPointEscalar(base8, s);
|
const expectedRes = babyjub.mulPointEscalar(base8, s);
|
||||||
|
|
||||||
assert(xout.equals(expectedRes[0]));
|
await circuit.assertOut(w, {out: expectedRes});
|
||||||
assert(yout.equals(expectedRes[1]));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it("If multiply by order should return 0", async () => {
|
it("If multiply by order should return 0", async () => {
|
||||||
const w = circuit.calculateWitness({ e: babyjub.subOrder });
|
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
const w = await circuit.calculateWitness({"e": babyjub.subOrder }, true);
|
||||||
|
|
||||||
const xout = w[circuit.getSignalIdx("main.out[0]")];
|
await circuit.checkConstraints(w);
|
||||||
const yout = w[circuit.getSignalIdx("main.out[1]")];
|
|
||||||
|
|
||||||
assert(xout.equals(bigInt.zero));
|
await circuit.assertOut(w, {out: [0,1]});
|
||||||
assert(yout.equals(bigInt.one));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,34 +1,25 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("@tornado/snarkjs");
|
const tester = require("circom").tester;
|
||||||
const compiler = require("circom");
|
|
||||||
|
|
||||||
const mimcjs = require("../src/mimc7.js");
|
const mimcjs = require("../src/mimc7.js");
|
||||||
|
|
||||||
const assert = chai.assert;
|
|
||||||
|
|
||||||
describe("MiMC Circuit test", function () {
|
describe("MiMC Circuit test", function () {
|
||||||
let circuit;
|
let circuit;
|
||||||
|
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
|
|
||||||
before(async () => {
|
before( async () => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "mimc_test.circom"));
|
circuit = await tester(path.join(__dirname, "circuits", "mimc_test.circom"));
|
||||||
|
|
||||||
circuit = new snarkjs.Circuit(cirDef);
|
|
||||||
|
|
||||||
console.log("MiMC constraints: " + circuit.nConstraints);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should check constrain", async () => {
|
it("Should check constrain", async () => {
|
||||||
const w = circuit.calculateWitness({ x_in: 1, k: 2 });
|
const w = await circuit.calculateWitness({x_in: 1, k: 2}, true);
|
||||||
|
|
||||||
const res = w[circuit.getSignalIdx("main.out")];
|
const res2 = mimcjs.hash(1,2,91);
|
||||||
|
|
||||||
const res2 = mimcjs.hash(1, 2, 91);
|
await circuit.assertOut(w, {out: res2});
|
||||||
|
|
||||||
assert.equal(res.toString(), res2.toString());
|
await circuit.checkConstraints(w);
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
const chai = require("chai");
|
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("@tornado/snarkjs");
|
const tester = require("circom").tester;
|
||||||
const compiler = require("circom");
|
|
||||||
|
|
||||||
const mimcjs = require("../src/mimcsponge.js");
|
const mimcjs = require("../src/mimcsponge.js");
|
||||||
|
|
||||||
const assert = chai.assert;
|
|
||||||
|
|
||||||
describe("MiMC Sponge Circuit test", function () {
|
describe("MiMC Sponge Circuit test", function () {
|
||||||
let circuit;
|
let circuit;
|
||||||
@ -13,44 +10,28 @@ describe("MiMC Sponge Circuit test", function () {
|
|||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
|
|
||||||
it("Should check permutation", async () => {
|
it("Should check permutation", async () => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "mimc_sponge_test.circom"));
|
|
||||||
|
|
||||||
circuit = new snarkjs.Circuit(cirDef);
|
circuit = await tester(path.join(__dirname, "circuits", "mimc_sponge_test.circom"));
|
||||||
|
|
||||||
console.log("MiMC Feistel constraints: " + circuit.nConstraints);
|
const w = await circuit.calculateWitness({xL_in: 1, xR_in: 2, k: 3});
|
||||||
|
|
||||||
const w = circuit.calculateWitness({ xL_in: 1, xR_in: 2, k: 3 });
|
const out2 = mimcjs.hash(1,2,3);
|
||||||
|
|
||||||
const xLout = w[circuit.getSignalIdx("main.xL_out")];
|
await circuit.assertOut(w, {xL_out: out2.xL, xR_out: out2.xR});
|
||||||
const xRout = w[circuit.getSignalIdx("main.xR_out")];
|
|
||||||
|
|
||||||
const out2 = mimcjs.hash(1, 2, 3);
|
await circuit.checkConstraints(w);
|
||||||
|
|
||||||
assert.equal(xLout.toString(), out2.xL.toString());
|
|
||||||
assert.equal(xRout.toString(), out2.xR.toString());
|
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should check hash", async () => {
|
it("Should check hash", async () => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "mimc_sponge_hash_test.circom"));
|
circuit = await tester(path.join(__dirname, "circuits", "mimc_sponge_hash_test.circom"));
|
||||||
|
|
||||||
circuit = new snarkjs.Circuit(cirDef);
|
const w = await circuit.calculateWitness({ins: [1, 2], k: 0});
|
||||||
|
|
||||||
console.log("MiMC Sponge constraints: " + circuit.nConstraints);
|
const out2 = mimcjs.multiHash([1,2], 0, 3);
|
||||||
|
|
||||||
const w = circuit.calculateWitness({ ins: [1, 2], k: 0 });
|
await circuit.assertOut(w, {outs: out2});
|
||||||
|
|
||||||
const o1 = w[circuit.getSignalIdx("main.outs[0]")];
|
await circuit.checkConstraints(w);
|
||||||
const o2 = w[circuit.getSignalIdx("main.outs[1]")];
|
|
||||||
const o3 = w[circuit.getSignalIdx("main.outs[2]")];
|
|
||||||
|
|
||||||
const out2 = mimcjs.multiHash([1, 2], 0, 3);
|
|
||||||
|
|
||||||
assert.equal(o1.toString(), out2[0].toString());
|
|
||||||
assert.equal(o2.toString(), out2[1].toString());
|
|
||||||
assert.equal(o3.toString(), out2[2].toString());
|
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -33,8 +33,8 @@ describe("MiMC Sponge Smart contract test", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Shold calculate the mimc correctly", async () => {
|
it("Shold calculate the mimc correctly", async () => {
|
||||||
const res = await mimc.methods.MiMCSponge(1,2).call();
|
const res = await mimc.methods.MiMCSponge(1,2,3).call();
|
||||||
const res2 = await mimcjs.hash(1,2, 0);
|
const res2 = await mimcjs.hash(1,2,3);
|
||||||
|
|
||||||
assert.equal(res.xL.toString(), res2.xL.toString());
|
assert.equal(res.xL.toString(), res2.xL.toString());
|
||||||
assert.equal(res.xR.toString(), res2.xR.toString());
|
assert.equal(res.xR.toString(), res2.xR.toString());
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("@tornado/snarkjs");
|
const tester = require("circom").tester;
|
||||||
const compiler = require("circom");
|
|
||||||
const babyJub = require("../src/babyjub.js");
|
const babyJub = require("../src/babyjub.js");
|
||||||
|
const Fr = require("ffjavascript").bn128.Fr;
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
const bigInt = snarkjs.bigInt;
|
|
||||||
|
|
||||||
describe("Montgomery test", function () {
|
describe("Montgomery test", function () {
|
||||||
let circuitE2M;
|
let circuitE2M;
|
||||||
let circuitM2E;
|
let circuitM2E;
|
||||||
@ -15,86 +13,80 @@ describe("Montgomery test", function () {
|
|||||||
let circuitMDouble;
|
let circuitMDouble;
|
||||||
|
|
||||||
let g = [
|
let g = [
|
||||||
snarkjs.bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
Fr.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
||||||
snarkjs.bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203"),
|
Fr.e("16950150798460657717958625567821834550301663161624707787222815936182638968203")
|
||||||
];
|
];
|
||||||
|
|
||||||
let mg, mg2, g2, g3, mg3;
|
let mg, mg2, g2, g3, mg3;
|
||||||
|
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
before(async () => {
|
before( async() => {
|
||||||
const cirDefE2M = await compiler(path.join(__dirname, "circuits", "edwards2montgomery.circom"));
|
circuitE2M = await tester(path.join(__dirname, "circuits", "edwards2montgomery.circom"));
|
||||||
circuitE2M = new snarkjs.Circuit(cirDefE2M);
|
await circuitE2M.loadSymbols();
|
||||||
console.log("NConstrains Edwards -> Montgomery: " + circuitE2M.nConstraints);
|
circuitM2E = await tester(path.join(__dirname, "circuits", "montgomery2edwards.circom"));
|
||||||
|
await circuitM2E.loadSymbols();
|
||||||
const cirDefM2E = await compiler(path.join(__dirname, "circuits", "montgomery2edwards.circom"));
|
circuitMAdd = await tester(path.join(__dirname, "circuits", "montgomeryadd.circom"));
|
||||||
circuitM2E = new snarkjs.Circuit(cirDefM2E);
|
await circuitMAdd.loadSymbols();
|
||||||
console.log("NConstrains Montgomery -> Edwards: " + circuitM2E.nConstraints);
|
circuitMDouble = await tester(path.join(__dirname, "circuits", "montgomerydouble.circom"));
|
||||||
|
await circuitMDouble.loadSymbols();
|
||||||
const cirDefMAdd = await compiler(path.join(__dirname, "circuits", "montgomeryadd.circom"));
|
|
||||||
circuitMAdd = new snarkjs.Circuit(cirDefMAdd);
|
|
||||||
console.log("NConstrains Montgomery Add: " + circuitMAdd.nConstraints);
|
|
||||||
|
|
||||||
const cirDefMDouble = await compiler(path.join(__dirname, "circuits", "montgomerydouble.circom"));
|
|
||||||
circuitMDouble = new snarkjs.Circuit(cirDefMDouble);
|
|
||||||
console.log("NConstrains Montgomery Double: " + circuitMDouble.nConstraints);
|
|
||||||
});
|
});
|
||||||
it("Convert Edwards to Montgomery and back again", async () => {
|
it("Convert Edwards to Montgomery and back again", async () => {
|
||||||
let w, xout, yout;
|
let w, xout, yout;
|
||||||
|
|
||||||
w = circuitE2M.calculateWitness({ in: g });
|
w = await circuitE2M.calculateWitness({ in: g}, true);
|
||||||
|
|
||||||
xout = w[circuitE2M.getSignalIdx("main.out[0]")];
|
xout = w[circuitE2M.symbols["main.out[0]"].varIdx];
|
||||||
yout = w[circuitE2M.getSignalIdx("main.out[1]")];
|
yout = w[circuitE2M.symbols["main.out[1]"].varIdx];
|
||||||
|
|
||||||
mg = [xout, yout];
|
mg = [xout, yout];
|
||||||
|
|
||||||
w = circuitM2E.calculateWitness({ in: [xout, yout] });
|
w = await circuitM2E.calculateWitness({ in: [xout, yout]}, true);
|
||||||
|
|
||||||
xout = w[circuitM2E.getSignalIdx("main.out[0]")];
|
xout = w[circuitM2E.symbols["main.out[0]"].varIdx];
|
||||||
yout = w[circuitM2E.getSignalIdx("main.out[1]")];
|
yout = w[circuitM2E.symbols["main.out[1]"].varIdx];
|
||||||
|
|
||||||
assert(xout.equals(g[0]));
|
assert(Fr.eq(xout, g[0]));
|
||||||
assert(yout.equals(g[1]));
|
assert(Fr.eq(yout, g[1]));
|
||||||
});
|
});
|
||||||
it("Should double a point", async () => {
|
it("Should double a point", async () => {
|
||||||
let w, xout, yout;
|
let w, xout, yout;
|
||||||
|
|
||||||
g2 = babyJub.addPoint(g, g);
|
g2 = babyJub.addPoint(g,g);
|
||||||
|
|
||||||
w = circuitMDouble.calculateWitness({ in: mg });
|
w = await circuitMDouble.calculateWitness({ in: mg}, true);
|
||||||
|
|
||||||
xout = w[circuitE2M.getSignalIdx("main.out[0]")];
|
xout = w[circuitE2M.symbols["main.out[0]"].varIdx];
|
||||||
yout = w[circuitE2M.getSignalIdx("main.out[1]")];
|
yout = w[circuitE2M.symbols["main.out[1]"].varIdx];
|
||||||
|
|
||||||
mg2 = [xout, yout];
|
mg2 = [xout, yout];
|
||||||
|
|
||||||
w = circuitM2E.calculateWitness({ in: mg2 });
|
w = await circuitM2E.calculateWitness({ in: mg2}, true);
|
||||||
|
|
||||||
xout = w[circuitM2E.getSignalIdx("main.out[0]")];
|
xout = w[circuitM2E.symbols["main.out[0]"].varIdx];
|
||||||
yout = w[circuitM2E.getSignalIdx("main.out[1]")];
|
yout = w[circuitM2E.symbols["main.out[1]"].varIdx];
|
||||||
|
|
||||||
assert(xout.equals(g2[0]));
|
|
||||||
assert(yout.equals(g2[1]));
|
assert(Fr.eq(xout, g2[0]));
|
||||||
|
assert(Fr.eq(yout, g2[1]));
|
||||||
});
|
});
|
||||||
it("Should add a point", async () => {
|
it("Should add a point", async () => {
|
||||||
let w, xout, yout;
|
let w, xout, yout;
|
||||||
|
|
||||||
g3 = babyJub.addPoint(g, g2);
|
g3 = babyJub.addPoint(g,g2);
|
||||||
|
|
||||||
w = circuitMAdd.calculateWitness({ in1: mg, in2: mg2 });
|
w = await circuitMAdd.calculateWitness({ in1: mg, in2: mg2}, true);
|
||||||
|
|
||||||
xout = w[circuitMAdd.getSignalIdx("main.out[0]")];
|
xout = w[circuitMAdd.symbols["main.out[0]"].varIdx];
|
||||||
yout = w[circuitMAdd.getSignalIdx("main.out[1]")];
|
yout = w[circuitMAdd.symbols["main.out[1]"].varIdx];
|
||||||
|
|
||||||
mg3 = [xout, yout];
|
mg3 = [xout, yout];
|
||||||
|
|
||||||
w = circuitM2E.calculateWitness({ in: mg3 });
|
w = await circuitM2E.calculateWitness({ in: mg3}, true);
|
||||||
|
|
||||||
xout = w[circuitM2E.getSignalIdx("main.out[0]")];
|
xout = w[circuitM2E.symbols["main.out[0]"].varIdx];
|
||||||
yout = w[circuitM2E.getSignalIdx("main.out[1]")];
|
yout = w[circuitM2E.symbols["main.out[1]"].varIdx];
|
||||||
|
|
||||||
assert(xout.equals(g3[0]));
|
assert(Fr.eq(xout, g3[0]));
|
||||||
assert(yout.equals(g3[1]));
|
assert(Fr.eq(yout, g3[1]));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,111 +1,98 @@
|
|||||||
const chai = require("chai");
|
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("@tornado/snarkjs");
|
const tester = require("circom").tester;
|
||||||
const compiler = require("circom");
|
const Fr = require("ffjavascript").bn128.Fr;
|
||||||
|
|
||||||
const assert = chai.assert;
|
describe("Mux4 test", function() {
|
||||||
|
this.timeout(100000);
|
||||||
const bigInt = snarkjs.bigInt;
|
|
||||||
|
|
||||||
describe("Mux4 test", () => {
|
|
||||||
it("Should create a constant multiplexer 4", async () => {
|
it("Should create a constant multiplexer 4", async () => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "mux4_1.circom"));
|
|
||||||
|
|
||||||
// console.log(JSON.stringify(cirDef, null, 1));
|
const circuit = await tester(path.join(__dirname, "circuits", "mux4_1.circom"));
|
||||||
|
|
||||||
// assert.equal(cirDef.nVars, 2);
|
|
||||||
|
|
||||||
const circuit = new snarkjs.Circuit(cirDef);
|
|
||||||
|
|
||||||
console.log("NConstrains Mux4: " + circuit.nConstraints);
|
|
||||||
|
|
||||||
const ct16 = [
|
const ct16 = [
|
||||||
bigInt("123"),
|
Fr.e("123"),
|
||||||
bigInt("456"),
|
Fr.e("456"),
|
||||||
bigInt("789"),
|
Fr.e("789"),
|
||||||
bigInt("012"),
|
Fr.e("012"),
|
||||||
bigInt("111"),
|
Fr.e("111"),
|
||||||
bigInt("222"),
|
Fr.e("222"),
|
||||||
bigInt("333"),
|
Fr.e("333"),
|
||||||
bigInt("4546"),
|
Fr.e("4546"),
|
||||||
bigInt("134523"),
|
Fr.e("134523"),
|
||||||
bigInt("44356"),
|
Fr.e("44356"),
|
||||||
bigInt("15623"),
|
Fr.e("15623"),
|
||||||
bigInt("4566"),
|
Fr.e("4566"),
|
||||||
bigInt("1223"),
|
Fr.e("1223"),
|
||||||
bigInt("4546"),
|
Fr.e("4546"),
|
||||||
bigInt("4256"),
|
Fr.e("4256"),
|
||||||
bigInt("4456"),
|
Fr.e("4456")
|
||||||
];
|
];
|
||||||
|
|
||||||
for (let i = 0; i < 16; i++) {
|
for (let i=0; i<16; i++) {
|
||||||
const w = circuit.calculateWitness({ selector: i });
|
const w = await circuit.calculateWitness({ "selector": i }, true);
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
await circuit.checkConstraints(w);
|
||||||
|
|
||||||
assert(w[0].equals(bigInt(1)));
|
await circuit.assertOut(w, {out: ct16[i]});
|
||||||
|
|
||||||
// console.log(i + " -> " + w[circuit.getSignalIdx("main.out")].toString());
|
|
||||||
assert(w[circuit.getSignalIdx("main.out")].equals(ct16[i]));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should create a constant multiplexer 3", async () => {
|
it("Should create a constant multiplexer 3", async () => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "mux3_1.circom"));
|
|
||||||
|
|
||||||
const circuit = new snarkjs.Circuit(cirDef);
|
const circuit = await tester(path.join(__dirname, "circuits", "mux3_1.circom"));
|
||||||
|
|
||||||
console.log("NConstrains Mux3: " + circuit.nConstraints);
|
const ct8 = [
|
||||||
|
Fr.e("37"),
|
||||||
|
Fr.e("47"),
|
||||||
|
Fr.e("53"),
|
||||||
|
Fr.e("71"),
|
||||||
|
Fr.e("89"),
|
||||||
|
Fr.e("107"),
|
||||||
|
Fr.e("163"),
|
||||||
|
Fr.e("191")
|
||||||
|
];
|
||||||
|
|
||||||
const ct8 = [bigInt("37"), bigInt("47"), bigInt("53"), bigInt("71"), bigInt("89"), bigInt("107"), bigInt("163"), bigInt("191")];
|
for (let i=0; i<8; i++) {
|
||||||
|
const w = await circuit.calculateWitness({ "selector": i }, true);
|
||||||
|
|
||||||
for (let i = 0; i < 8; i++) {
|
await circuit.checkConstraints(w);
|
||||||
const w = circuit.calculateWitness({ selector: i });
|
|
||||||
|
|
||||||
assert(w[0].equals(bigInt(1)));
|
await circuit.assertOut(w, {out: ct8[i]});
|
||||||
|
|
||||||
// console.log(i + " -> " + w[circuit.getSignalIdx("main.out")].toString());
|
|
||||||
assert(w[circuit.getSignalIdx("main.out")].equals(ct8[i]));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
it("Should create a constant multiplexer 2", async () => {
|
it("Should create a constant multiplexer 2", async () => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "mux2_1.circom"));
|
|
||||||
|
|
||||||
const circuit = new snarkjs.Circuit(cirDef);
|
const circuit = await tester(path.join(__dirname, "circuits", "mux2_1.circom"));
|
||||||
|
|
||||||
console.log("NConstrains Mux2: " + circuit.nConstraints);
|
const ct4 = [
|
||||||
|
Fr.e("37"),
|
||||||
|
Fr.e("47"),
|
||||||
|
Fr.e("53"),
|
||||||
|
Fr.e("71"),
|
||||||
|
];
|
||||||
|
|
||||||
const ct8 = [bigInt("37"), bigInt("47"), bigInt("53"), bigInt("71")];
|
for (let i=0; i<4; i++) {
|
||||||
|
const w = await circuit.calculateWitness({ "selector": i }, true);
|
||||||
|
|
||||||
for (let i = 0; i < 4; i++) {
|
await circuit.checkConstraints(w);
|
||||||
const w = circuit.calculateWitness({ selector: i });
|
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
await circuit.assertOut(w, {out: ct4[i]});
|
||||||
|
|
||||||
assert(w[0].equals(bigInt(1)));
|
|
||||||
|
|
||||||
// console.log(i + " -> " + w[circuit.getSignalIdx("main.out")].toString());
|
|
||||||
assert(w[circuit.getSignalIdx("main.out")].equals(ct8[i]));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
it("Should create a constant multiplexer 1", async () => {
|
it("Should create a constant multiplexer 1", async () => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "mux1_1.circom"));
|
|
||||||
|
|
||||||
const circuit = new snarkjs.Circuit(cirDef);
|
const circuit = await tester(path.join(__dirname, "circuits", "mux1_1.circom"));
|
||||||
|
|
||||||
console.log("NConstrains Mux1: " + circuit.nConstraints);
|
const ct2 = [
|
||||||
|
Fr.e("37"),
|
||||||
|
Fr.e("47"),
|
||||||
|
];
|
||||||
|
|
||||||
const ct8 = [bigInt("37"), bigInt("47")];
|
for (let i=0; i<2; i++) {
|
||||||
|
const w = await circuit.calculateWitness({ "selector": i }, true);
|
||||||
|
|
||||||
for (let i = 0; i < 2; i++) {
|
await circuit.checkConstraints(w);
|
||||||
const w = circuit.calculateWitness({ selector: i });
|
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
await circuit.assertOut(w, {out: ct2[i]});
|
||||||
|
|
||||||
assert(w[0].equals(bigInt(1)));
|
|
||||||
|
|
||||||
// console.log(i + " -> " + w[circuit.getSignalIdx("main.out")].toString());
|
|
||||||
assert(w[circuit.getSignalIdx("main.out")].equals(ct8[i]));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
101
test/pedersen.js
101
test/pedersen.js
@ -1,104 +1,77 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("@tornado/snarkjs");
|
|
||||||
const compiler = require("circom");
|
|
||||||
|
|
||||||
const assert = chai.assert;
|
const Fr = require("ffjavascript").bn128.Fr;
|
||||||
|
const tester = require("circom").tester;
|
||||||
const bigInt = snarkjs.bigInt;
|
|
||||||
|
|
||||||
const babyJub = require("../src/babyjub.js");
|
const babyJub = require("../src/babyjub.js");
|
||||||
|
|
||||||
const PBASE = [
|
const PBASE =
|
||||||
[
|
[
|
||||||
bigInt("10457101036533406547632367118273992217979173478358440826365724437999023779287"),
|
[Fr.e("10457101036533406547632367118273992217979173478358440826365724437999023779287"),Fr.e("19824078218392094440610104313265183977899662750282163392862422243483260492317")],
|
||||||
bigInt("19824078218392094440610104313265183977899662750282163392862422243483260492317"),
|
[Fr.e("2671756056509184035029146175565761955751135805354291559563293617232983272177"),Fr.e("2663205510731142763556352975002641716101654201788071096152948830924149045094")],
|
||||||
],
|
[Fr.e("5802099305472655231388284418920769829666717045250560929368476121199858275951"),Fr.e("5980429700218124965372158798884772646841287887664001482443826541541529227896")],
|
||||||
[
|
[Fr.e("7107336197374528537877327281242680114152313102022415488494307685842428166594"),Fr.e("2857869773864086953506483169737724679646433914307247183624878062391496185654")],
|
||||||
bigInt("2671756056509184035029146175565761955751135805354291559563293617232983272177"),
|
[Fr.e("20265828622013100949498132415626198973119240347465898028410217039057588424236"),Fr.e("1160461593266035632937973507065134938065359936056410650153315956301179689506")]
|
||||||
bigInt("2663205510731142763556352975002641716101654201788071096152948830924149045094"),
|
];
|
||||||
],
|
|
||||||
[
|
|
||||||
bigInt("5802099305472655231388284418920769829666717045250560929368476121199858275951"),
|
|
||||||
bigInt("5980429700218124965372158798884772646841287887664001482443826541541529227896"),
|
|
||||||
],
|
|
||||||
[
|
|
||||||
bigInt("7107336197374528537877327281242680114152313102022415488494307685842428166594"),
|
|
||||||
bigInt("2857869773864086953506483169737724679646433914307247183624878062391496185654"),
|
|
||||||
],
|
|
||||||
[
|
|
||||||
bigInt("20265828622013100949498132415626198973119240347465898028410217039057588424236"),
|
|
||||||
bigInt("1160461593266035632937973507065134938065359936056410650153315956301179689506"),
|
|
||||||
],
|
|
||||||
];
|
|
||||||
|
|
||||||
describe("Double Pedersen test", function () {
|
describe("Double Pedersen test", function() {
|
||||||
let circuit;
|
let circuit;
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
before(async () => {
|
before( async() => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "pedersen_test.circom"));
|
|
||||||
|
|
||||||
circuit = new snarkjs.Circuit(cirDef);
|
circuit = await tester(path.join(__dirname, "circuits", "pedersen_test.circom"));
|
||||||
|
|
||||||
console.log("NConstrains: " + circuit.nConstraints);
|
|
||||||
});
|
});
|
||||||
it("Should pedersen at zero", async () => {
|
it("Should pedersen at zero", async () => {
|
||||||
let w, xout, yout;
|
|
||||||
|
|
||||||
w = circuit.calculateWitness({ in: ["0", "0"] });
|
let w;
|
||||||
|
|
||||||
xout = w[circuit.getSignalIdx("main.out[0]")];
|
w = await circuit.calculateWitness({ in: ["0", "0"]}, true);
|
||||||
yout = w[circuit.getSignalIdx("main.out[1]")];
|
|
||||||
|
await circuit.assertOut(w, {out: [0,1]});
|
||||||
|
|
||||||
assert(xout.equals("0"));
|
|
||||||
assert(yout.equals("1"));
|
|
||||||
});
|
});
|
||||||
it("Should pedersen at one first generator", async () => {
|
it("Should pedersen at one first generator", async () => {
|
||||||
let w, xout, yout;
|
let w;
|
||||||
|
|
||||||
w = circuit.calculateWitness({ in: ["1", "0"] });
|
w = await circuit.calculateWitness({ in: ["1", "0"]}, true);
|
||||||
|
|
||||||
xout = bigInt(w[circuit.getSignalIdx("main.out[0]")]);
|
await circuit.assertOut(w, {out: PBASE[0]});
|
||||||
yout = bigInt(w[circuit.getSignalIdx("main.out[1]")]);
|
|
||||||
|
|
||||||
assert(xout.equals(PBASE[0][0]));
|
|
||||||
assert(yout.equals(PBASE[0][1]));
|
|
||||||
});
|
});
|
||||||
it("Should pedersen at one second generator", async () => {
|
it("Should pedersen at one second generator", async () => {
|
||||||
let w, xout, yout;
|
let w;
|
||||||
|
|
||||||
w = circuit.calculateWitness({ in: ["0", "1"] });
|
w = await circuit.calculateWitness({ in: ["0", "1"]}, true);
|
||||||
|
|
||||||
xout = w[circuit.getSignalIdx("main.out[0]")];
|
await circuit.assertOut(w, {out: PBASE[1]});
|
||||||
yout = w[circuit.getSignalIdx("main.out[1]")];
|
|
||||||
|
|
||||||
assert(xout.equals(PBASE[1][0]));
|
|
||||||
assert(yout.equals(PBASE[1][1]));
|
|
||||||
});
|
});
|
||||||
it("Should pedersen at mixed generators", async () => {
|
it("Should pedersen at mixed generators", async () => {
|
||||||
let w, xout, yout;
|
let w;
|
||||||
w = circuit.calculateWitness({ in: ["3", "7"] });
|
w = await circuit.calculateWitness({ in: ["3", "7"]}, true);
|
||||||
|
|
||||||
xout = w[circuit.getSignalIdx("main.out[0]")];
|
const r = babyJub.addPoint(
|
||||||
yout = w[circuit.getSignalIdx("main.out[1]")];
|
babyJub.mulPointEscalar(PBASE[0], 3),
|
||||||
|
babyJub.mulPointEscalar(PBASE[1], 7)
|
||||||
|
);
|
||||||
|
|
||||||
const r = babyJub.addPoint(babyJub.mulPointEscalar(PBASE[0], 3), babyJub.mulPointEscalar(PBASE[1], 7));
|
await circuit.assertOut(w, {out: r});
|
||||||
|
|
||||||
assert(xout.equals(r[0]));
|
|
||||||
assert(yout.equals(r[1]));
|
|
||||||
});
|
});
|
||||||
it("Should pedersen all ones", async () => {
|
it("Should pedersen all ones", async () => {
|
||||||
let w, xout, yout;
|
let w;
|
||||||
|
|
||||||
const allOnes = bigInt("1").shl(250).sub(bigInt("1"));
|
const allOnes = Fr.sub(Fr.shl(Fr.e("1"), Fr.e(250)), Fr.e("1"));
|
||||||
w = circuit.calculateWitness({ in: [allOnes, allOnes] });
|
w = await circuit.calculateWitness({ in: [allOnes, allOnes]}, true);
|
||||||
|
|
||||||
xout = w[circuit.getSignalIdx("main.out[0]")];
|
|
||||||
yout = w[circuit.getSignalIdx("main.out[1]")];
|
|
||||||
|
|
||||||
const r2 = babyJub.addPoint(babyJub.mulPointEscalar(PBASE[0], allOnes), babyJub.mulPointEscalar(PBASE[1], allOnes));
|
const r2 = babyJub.addPoint(
|
||||||
|
babyJub.mulPointEscalar(PBASE[0], allOnes),
|
||||||
|
babyJub.mulPointEscalar(PBASE[1], allOnes)
|
||||||
|
);
|
||||||
|
|
||||||
assert(xout.equals(r2[0]));
|
await circuit.assertOut(w, {out: r2});
|
||||||
assert(yout.equals(r2[1]));
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,70 +1,49 @@
|
|||||||
const chai = require("chai");
|
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("@tornado/snarkjs");
|
|
||||||
const compiler = require("circom");
|
|
||||||
|
|
||||||
const assert = chai.assert;
|
const Fr = require("ffjavascript").bn128.Fr;
|
||||||
|
const tester = require("circom").tester;
|
||||||
const bigInt = snarkjs.bigInt;
|
|
||||||
|
|
||||||
const babyJub = require("../src/babyjub.js");
|
const babyJub = require("../src/babyjub.js");
|
||||||
const pedersen = require("../src/pedersenHash.js");
|
const pedersen = require("../src/pedersenHash.js");
|
||||||
|
|
||||||
describe("Pedersen test", function () {
|
|
||||||
|
describe("Pedersen test", function() {
|
||||||
let circuit;
|
let circuit;
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
before(async () => {
|
before( async() => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "pedersen2_test.circom"));
|
|
||||||
|
|
||||||
circuit = new snarkjs.Circuit(cirDef);
|
circuit = await tester(path.join(__dirname, "circuits", "pedersen2_test.circom"));
|
||||||
|
|
||||||
console.log("NConstrains Pedersen2: " + circuit.nConstraints);
|
|
||||||
});
|
});
|
||||||
it("Should pedersen at zero", async () => {
|
it("Should pedersen at zero", async () => {
|
||||||
let w, xout, yout;
|
|
||||||
|
|
||||||
w = circuit.calculateWitness({ in: 0 });
|
let w;
|
||||||
|
|
||||||
xout = w[circuit.getSignalIdx("main.out[0]")];
|
w = await circuit.calculateWitness({ in: 0}, true);
|
||||||
yout = w[circuit.getSignalIdx("main.out[1]")];
|
|
||||||
|
|
||||||
const b = Buffer.alloc(32);
|
const b = Buffer.alloc(32);
|
||||||
|
|
||||||
const h = pedersen.hash(b);
|
const h = pedersen.hash(b);
|
||||||
const hP = babyJub.unpackPoint(h);
|
const hP = babyJub.unpackPoint(h);
|
||||||
|
|
||||||
/*
|
await circuit.assertOut(w, {out: hP});
|
||||||
console.log(`[${xout.toString()}, ${yout.toString()}]`);
|
|
||||||
console.log(`[${hP[0].toString()}, ${hP[1].toString()}]`);
|
|
||||||
*/
|
|
||||||
|
|
||||||
assert(xout.equals(hP[0]));
|
|
||||||
assert(yout.equals(hP[1]));
|
|
||||||
});
|
});
|
||||||
it("Should pedersen with 253 ones", async () => {
|
it("Should pedersen with 253 ones", async () => {
|
||||||
let w, xout, yout;
|
|
||||||
|
|
||||||
const n = bigInt.one.shl(253).sub(bigInt.one);
|
let w;
|
||||||
console.log(n.toString(16));
|
|
||||||
|
|
||||||
w = circuit.calculateWitness({ in: n });
|
const n = Fr.sub(Fr.shl(Fr.one, Fr.e(253)), Fr.one);
|
||||||
|
|
||||||
xout = w[circuit.getSignalIdx("main.out[0]")];
|
w = await circuit.calculateWitness({ in: n}, true);
|
||||||
yout = w[circuit.getSignalIdx("main.out[1]")];
|
|
||||||
|
|
||||||
const b = Buffer.alloc(32);
|
const b = Buffer.alloc(32);
|
||||||
for (let i = 0; i < 31; i++) b[i] = 0xff;
|
for (let i=0; i<31; i++) b[i] = 0xFF;
|
||||||
b[31] = 0x1f;
|
b[31] = 0x1F;
|
||||||
|
|
||||||
const h = pedersen.hash(b);
|
const h = pedersen.hash(b);
|
||||||
const hP = babyJub.unpackPoint(h);
|
const hP = babyJub.unpackPoint(h);
|
||||||
|
|
||||||
/*
|
await circuit.assertOut(w, {out: hP});
|
||||||
console.log(`[${xout.toString()}, ${yout.toString()}]`);
|
|
||||||
console.log(`[${hP[0].toString()}, ${hP[1].toString()}]`);
|
|
||||||
*/
|
|
||||||
|
|
||||||
assert(xout.equals(hP[0]));
|
|
||||||
assert(yout.equals(hP[1]));
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,32 +1,23 @@
|
|||||||
const chai = require("chai");
|
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("@tornado/snarkjs");
|
const tester = require("circom").tester;
|
||||||
const compiler = require("circom");
|
|
||||||
|
|
||||||
const assert = chai.assert;
|
|
||||||
|
|
||||||
const bigInt = snarkjs.bigInt;
|
|
||||||
|
|
||||||
const babyJub = require("../src/babyjub.js");
|
const babyJub = require("../src/babyjub.js");
|
||||||
|
|
||||||
describe("Point 2 bits test", function () {
|
|
||||||
|
describe("Point 2 bits test", function() {
|
||||||
let circuit;
|
let circuit;
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
before(async () => {
|
before( async() => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "pointbits_loopback.circom"));
|
circuit = await tester(path.join(__dirname, "circuits", "pointbits_loopback.circom"));
|
||||||
|
|
||||||
circuit = new snarkjs.Circuit(cirDef);
|
|
||||||
|
|
||||||
console.log("NConstrains Point2Bits loopback: " + circuit.nConstraints);
|
|
||||||
});
|
});
|
||||||
it("Should do the both convertions for 8Base", async () => {
|
it("Should do the both convertions for 8Base", async () => {
|
||||||
const w = circuit.calculateWitness({ in: babyJub.Base8 });
|
const w = await circuit.calculateWitness({ in: babyJub.Base8}, true);
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
await circuit.checkConstraints(w);
|
||||||
});
|
});
|
||||||
it("Should do the both convertions for Zero point", async () => {
|
it("Should do the both convertions for Zero point", async () => {
|
||||||
const w = circuit.calculateWitness({ in: [0, 1] });
|
const w = await circuit.calculateWitness({ in: [0, 1]}, true);
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
await circuit.checkConstraints(w);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,59 +1,57 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("@tornado/snarkjs");
|
const tester = require("circom").tester;
|
||||||
const compiler = require("circom");
|
|
||||||
|
|
||||||
const poseidon = require("../src/poseidon.js");
|
const poseidon = require("../src/poseidon.js");
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
describe("Poseidon Circuit test", function () {
|
describe("Poseidon Circuit test", function () {
|
||||||
let circuit2;
|
let circuit6;
|
||||||
let circuit4;
|
let circuit3;
|
||||||
|
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
|
|
||||||
before(async () => {
|
before( async () => {
|
||||||
const cirDef2 = await compiler(path.join(__dirname, "circuits", "poseidon2_test.circom"));
|
circuit6 = await tester(path.join(__dirname, "circuits", "poseidon6_test.circom"));
|
||||||
const cirDef4 = await compiler(path.join(__dirname, "circuits", "poseidon4_test.circom"));
|
circuit3 = await tester(path.join(__dirname, "circuits", "poseidon3_test.circom"));
|
||||||
|
|
||||||
circuit2 = new snarkjs.Circuit(cirDef2);
|
|
||||||
circuit4 = new snarkjs.Circuit(cirDef4);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should check constrain of hash([1, 2])", async () => {
|
it("Should check constrain of hash([1, 2]) t=6", async () => {
|
||||||
const hash = poseidon([1, 2]);
|
const w = await circuit6.calculateWitness({inputs: [1, 2, 0,0,0]}, true);
|
||||||
assert.equal("0x11ad302b36a2d7e09653c8e90618f00c06cd0a7348e52cdf2ccced3c3abec679", "0x" + hash.toString(16));
|
|
||||||
const w = await circuit2.calculateWitness({ inputs: [1, 2] }, true);
|
const res2 = poseidon([1,2,0,0,0]);
|
||||||
const res = w[circuit2.getSignalIdx("main.out")];
|
assert.equal("3975478831357328722254985704342968745327876719981393787143845259590563829094", res2.toString());
|
||||||
assert.equal(res.toString(), hash.toString());
|
await circuit6.assertOut(w, {out : res2});
|
||||||
await circuit2.checkWitness(w);
|
await circuit6.checkConstraints(w);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should check constrain of hash([3, 4])", async () => {
|
it("Should check constrain of hash([3, 4]) t=6", async () => {
|
||||||
const hash = poseidon([3, 4]);
|
const w = await circuit6.calculateWitness({inputs: [3, 4,5,10,23]});
|
||||||
assert.equal("0x23939f0972e764d6e252060279aabaca8ec650ab30b17d2c13551bec2a66bcef", "0x" + hash.toString(16));
|
|
||||||
const w = await circuit2.calculateWitness({ inputs: [3, 4] });
|
const res2 = poseidon([3, 4,5,10,23]);
|
||||||
const res = w[circuit2.getSignalIdx("main.out")];
|
|
||||||
assert.equal(res.toString(), hash.toString());
|
assert.equal("18540626624821144952552691894137986276337186174352554475896834101336254024067", res2.toString());
|
||||||
await circuit2.checkWitness(w);
|
await circuit6.assertOut(w, {out : res2});
|
||||||
|
await circuit6.checkConstraints(w);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should check constrain of hash([1, 2, 3, 4])", async () => {
|
|
||||||
const hash = poseidon([1, 2, 3, 4]);
|
it("Should check constrain of hash([1, 2]) t=3", async () => {
|
||||||
assert.equal("0x2e4fb80ce74868b0d33f4acb22071d8d8f8da7d30ebf972e6e4f72a64bb0633f", "0x" + hash.toString(16));
|
const w = await circuit3.calculateWitness({inputs: [1, 2]});
|
||||||
const w = await circuit4.calculateWitness({ inputs: [1, 2, 3, 4] });
|
|
||||||
const res = w[circuit4.getSignalIdx("main.out")];
|
const res2 = poseidon([1,2]);
|
||||||
assert.equal(res.toString(), hash.toString());
|
assert.equal("17117985411748610629288516079940078114952304104811071254131751175361957805920", res2.toString());
|
||||||
await circuit4.checkWitness(w);
|
await circuit3.assertOut(w, {out : res2});
|
||||||
|
await circuit3.checkConstraints(w);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should check constrain of hash([5, 6, 7, 8])", async () => {
|
it("Should check constrain of hash([3, 4]) t=3", async () => {
|
||||||
const hash = poseidon([5, 6, 7, 8]);
|
const w = await circuit3.calculateWitness({inputs: [3, 4]});
|
||||||
assert.equal("0x2a3fc67aa97766917ee06e927f35fd70f4655ad6c1f2e7bcd5c5c85aa3a8a974", "0x" + hash.toString(16));
|
|
||||||
const w = await circuit4.calculateWitness({ inputs: [5, 6, 7, 8] });
|
const res2 = poseidon([3, 4]);
|
||||||
const res = w[circuit4.getSignalIdx("main.out")];
|
assert.equal("21867347236198497199818917118739170715216974132230970409806500217655788551452", res2.toString());
|
||||||
assert.equal(res.toString(), hash.toString());
|
await circuit3.assertOut(w, {out : res2});
|
||||||
await circuit4.checkWitness(w);
|
await circuit3.checkConstraints(w);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -10,12 +10,10 @@ const log = (msg) => { if (process.env.MOCHA_VERBOSE) console.log(msg); };
|
|||||||
describe("Poseidon Smart contract test", function () {
|
describe("Poseidon Smart contract test", function () {
|
||||||
let testrpc;
|
let testrpc;
|
||||||
let web3;
|
let web3;
|
||||||
let poseidon2;
|
let poseidon6;
|
||||||
let poseidon4;
|
let poseidon3;
|
||||||
let accounts;
|
let accounts;
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
let C2;
|
|
||||||
let C4;
|
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
web3 = new Web3(ganache.provider(), null, { transactionConfirmationBlocks: 1 });
|
web3 = new Web3(ganache.provider(), null, { transactionConfirmationBlocks: 1 });
|
||||||
@ -23,41 +21,41 @@ describe("Poseidon Smart contract test", function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Should deploy the contract", async () => {
|
it("Should deploy the contract", async () => {
|
||||||
|
const C6 = new web3.eth.Contract(poseidonGenContract.generateABI(5));
|
||||||
C2 = new web3.eth.Contract(poseidonGenContract.generateABI(2));
|
const C3 = new web3.eth.Contract(poseidonGenContract.generateABI(2));
|
||||||
poseidon2 = await C2.deploy({
|
|
||||||
|
poseidon6 = await C6.deploy({
|
||||||
|
data: poseidonGenContract.createCode(5)
|
||||||
|
}).send({
|
||||||
|
gas: 5000000,
|
||||||
|
from: accounts[0]
|
||||||
|
});
|
||||||
|
poseidon3 = await C3.deploy({
|
||||||
data: poseidonGenContract.createCode(2)
|
data: poseidonGenContract.createCode(2)
|
||||||
}).send({
|
}).send({
|
||||||
gas: 5000000,
|
gas: 5000000,
|
||||||
from: accounts[0]
|
from: accounts[0]
|
||||||
});
|
});
|
||||||
|
|
||||||
C4 = new web3.eth.Contract(poseidonGenContract.generateABI(4));
|
|
||||||
poseidon4 = await C4.deploy({
|
|
||||||
data: poseidonGenContract.createCode(4)
|
|
||||||
}).send({
|
|
||||||
gas: 5000000,
|
|
||||||
from: accounts[0]
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should calculate the poseidon correctly for 2 inputs", async () => {
|
it("Should calculate the poseidon correctly t=6", async () => {
|
||||||
const res = await poseidon2.methods.poseidon([1, 2]).call();
|
|
||||||
|
const res = await poseidon6.methods.poseidon([1,2, 0, 0, 0]).call();
|
||||||
|
|
||||||
// console.log("Cir: " + bigInt(res.toString(16)).toString(16));
|
// console.log("Cir: " + bigInt(res.toString(16)).toString(16));
|
||||||
|
|
||||||
const res2 = poseidon([1, 2]);
|
const res2 = poseidon([1,2, 0, 0, 0]);
|
||||||
// console.log("Ref: " + bigInt(res2).toString(16));
|
// console.log("Ref: " + bigInt(res2).toString(16));
|
||||||
|
|
||||||
assert.equal(res.toString(), res2.toString());
|
assert.equal(res.toString(), res2.toString());
|
||||||
});
|
});
|
||||||
it("Should calculate the poseidon correctly for 4 inputs", async () => {
|
it("Should calculate the poseidon correctly t=3", async () => {
|
||||||
|
|
||||||
const res = await poseidon4.methods.poseidon([1, 2, 3, 4]).call();
|
const res = await poseidon3.methods.poseidon([1,2]).call();
|
||||||
|
|
||||||
// console.log("Cir: " + bigInt(res.toString(16)).toString(16));
|
// console.log("Cir: " + bigInt(res.toString(16)).toString(16));
|
||||||
|
|
||||||
const res2 = poseidon([1, 2, 3, 4]);
|
const res2 = poseidon([1,2]);
|
||||||
// console.log("Ref: " + bigInt(res2).toString(16));
|
// console.log("Ref: " + bigInt(res2).toString(16));
|
||||||
|
|
||||||
assert.equal(res.toString(), res2.toString());
|
assert.equal(res.toString(), res2.toString());
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
|
|
||||||
include "../circuits/smt/smtverifier.circom";
|
|
||||||
template SMT(nLevels) {
|
|
||||||
signal input root;
|
|
||||||
signal input mtp[nLevels];
|
|
||||||
signal input hi;
|
|
||||||
signal input hv;
|
|
||||||
|
|
||||||
component smtClaimExists = SMTVerifier(nLevels);
|
|
||||||
smtClaimExists.enabled <== 1;
|
|
||||||
smtClaimExists.fnc <== 0;
|
|
||||||
smtClaimExists.root <== root;
|
|
||||||
for (var i=0; i<nLevels; i++) {
|
|
||||||
smtClaimExists.siblings[i] <== mtp[i];
|
|
||||||
}
|
|
||||||
smtClaimExists.oldKey <== 0;
|
|
||||||
smtClaimExists.oldValue <== 0;
|
|
||||||
smtClaimExists.isOld0 <== 0;
|
|
||||||
|
|
||||||
smtClaimExists.key <== hi;
|
|
||||||
smtClaimExists.value <== hv;
|
|
||||||
}
|
|
||||||
component main = SMT(4);
|
|
@ -1,122 +1,115 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("@tornado/snarkjs");
|
|
||||||
const crypto = require("crypto");
|
const crypto = require("crypto");
|
||||||
|
const Fr = require("ffjavascript").bn128.Fr;
|
||||||
const compiler = require("circom");
|
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
const sha256 = require("./helpers/sha256");
|
const sha256 = require("./helpers/sha256");
|
||||||
|
|
||||||
|
const tester = require("circom").tester;
|
||||||
|
|
||||||
// const printSignal = require("./helpers/printsignal");
|
// const printSignal = require("./helpers/printsignal");
|
||||||
|
|
||||||
|
|
||||||
function buffer2bitArray(b) {
|
function buffer2bitArray(b) {
|
||||||
const res = [];
|
const res = [];
|
||||||
for (let i = 0; i < b.length; i++) {
|
for (let i=0; i<b.length; i++) {
|
||||||
for (let j = 0; j < 8; j++) {
|
for (let j=0; j<8; j++) {
|
||||||
res.push((b[i] >> (7 - j)) & 1);
|
res.push((b[i] >> (7-j) &1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function bitArray2buffer(a) {
|
function bitArray2buffer(a) {
|
||||||
const len = Math.floor((a.length - 1) / 8) + 1;
|
const len = Math.floor((a.length -1 )/8)+1;
|
||||||
const b = new Buffer.alloc(len);
|
const b = new Buffer.alloc(len);
|
||||||
|
|
||||||
for (let i = 0; i < a.length; i++) {
|
for (let i=0; i<a.length; i++) {
|
||||||
const p = Math.floor(i / 8);
|
const p = Math.floor(i/8);
|
||||||
b[p] = b[p] | (Number(a[i]) << (7 - (i % 8)));
|
b[p] = b[p] | (Number(a[i]) << ( 7 - (i%8) ));
|
||||||
}
|
}
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("SHA256 test", () => {
|
|
||||||
|
describe("SHA256 test", function () {
|
||||||
|
this.timeout(100000);
|
||||||
|
|
||||||
|
|
||||||
it("Should work bits to array and array to bits", async () => {
|
it("Should work bits to array and array to bits", async () => {
|
||||||
const b = new Buffer.alloc(64);
|
const b = new Buffer.alloc(64);
|
||||||
for (let i = 0; i < 64; i++) {
|
for (let i=0; i<64; i++) {
|
||||||
b[i] = i + 1;
|
b[i] = i+1;
|
||||||
}
|
}
|
||||||
const a = buffer2bitArray(b);
|
const a = buffer2bitArray(b);
|
||||||
const b2 = bitArray2buffer(a);
|
const b2 = bitArray2buffer(a);
|
||||||
|
|
||||||
assert.equal(b.toString("hex"), b2.toString("hex"));
|
assert.equal(b.toString("hex"), b2.toString("hex"), true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should calculate a hash of 1 compressor", async () => {
|
it("Should calculate a hash of 1 compressor", async () => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "sha256_2_test.circom"));
|
const cir = await tester(path.join(__dirname, "circuits", "sha256_2_test.circom"));
|
||||||
const circuit = new snarkjs.Circuit(cirDef);
|
|
||||||
|
|
||||||
console.log("Vars: " + circuit.nVars);
|
const witness = await cir.calculateWitness({ "a": "1", "b": "2" }, true);
|
||||||
console.log("Constraints: " + circuit.nConstraints);
|
|
||||||
|
|
||||||
const witness = circuit.calculateWitness({ a: "1", b: "2" });
|
|
||||||
|
|
||||||
const b = new Buffer.alloc(54);
|
const b = new Buffer.alloc(54);
|
||||||
b[26] = 1;
|
b[26] = 1;
|
||||||
b[53] = 2;
|
b[53] = 2;
|
||||||
|
|
||||||
const hash = crypto.createHash("sha256").update(b).digest("hex");
|
const hash = crypto.createHash("sha256")
|
||||||
|
.update(b)
|
||||||
|
.digest("hex");
|
||||||
const r = "0x" + hash.slice(10);
|
const r = "0x" + hash.slice(10);
|
||||||
|
|
||||||
const hash2 = sha256.hash(b.toString("hex"), { msgFormat: "hex-bytes" });
|
const hash2 = sha256.hash(b.toString("hex"), {msgFormat: "hex-bytes"});
|
||||||
|
|
||||||
assert.equal(hash, hash2);
|
assert.equal(hash, hash2);
|
||||||
|
|
||||||
assert(witness[1].equals(snarkjs.bigInt(r)));
|
assert(Fr.eq(witness[1], Fr.e(r)));
|
||||||
}).timeout(1000000);
|
}).timeout(1000000);
|
||||||
|
|
||||||
it("Should calculate a hash of 2 compressor", async () => {
|
it("Should calculate a hash of 2 compressor", async () => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "sha256_test512.circom"), { reduceConstraints: false });
|
const cir = await tester(path.join(__dirname, "circuits", "sha256_test512.circom"));
|
||||||
const circuit = new snarkjs.Circuit(cirDef);
|
|
||||||
|
|
||||||
console.log("Vars: " + circuit.nVars);
|
|
||||||
console.log("Constraints: " + circuit.nConstraints);
|
|
||||||
|
|
||||||
/*
|
|
||||||
const testStr = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
|
|
||||||
|
|
||||||
const b = Buffer.from(testStr, 'utf8');
|
|
||||||
*/
|
|
||||||
const b = new Buffer.alloc(64);
|
const b = new Buffer.alloc(64);
|
||||||
for (let i = 0; i < 64; i++) {
|
for (let i=0; i<64; i++) {
|
||||||
b[i] = i + 1;
|
b[i] = i+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const hash = crypto.createHash("sha256").update(b).digest("hex");
|
const hash = crypto.createHash("sha256")
|
||||||
|
.update(b)
|
||||||
|
.digest("hex");
|
||||||
|
|
||||||
const arrIn = buffer2bitArray(b);
|
const arrIn = buffer2bitArray(b);
|
||||||
const witness = circuit.calculateWitness({ in: arrIn } /*, {logOutput: true} */);
|
const witness = await cir.calculateWitness({ "in": arrIn }, true);
|
||||||
|
|
||||||
const arrOut = witness.slice(1, 257);
|
const arrOut = witness.slice(1, 257);
|
||||||
const hash2 = bitArray2buffer(arrOut).toString("hex");
|
const hash2 = bitArray2buffer(arrOut).toString("hex");
|
||||||
|
|
||||||
assert.equal(hash, hash2);
|
assert.equal(hash, hash2);
|
||||||
|
|
||||||
}).timeout(1000000);
|
}).timeout(1000000);
|
||||||
|
it ("Should calculate a hash of 2 compressor", async () => {
|
||||||
it("Should calculate a hash of 2 compressor", async () => {
|
const cir = await tester(path.join(__dirname, "circuits", "sha256_test448.circom"));
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "sha256_test448.circom"), { reduceConstraints: false });
|
|
||||||
const circuit = new snarkjs.Circuit(cirDef);
|
|
||||||
|
|
||||||
console.log("Vars: " + circuit.nVars);
|
|
||||||
console.log("Constraints: " + circuit.nConstraints);
|
|
||||||
|
|
||||||
const testStr = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
|
const testStr = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
|
||||||
|
|
||||||
const b = Buffer.from(testStr, "utf8");
|
const b = Buffer.from(testStr, "utf8");
|
||||||
for (let i = 0; i < 64; i++) {
|
|
||||||
b[i] = i + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const hash = crypto.createHash("sha256").update(b).digest("hex");
|
const hash = crypto.createHash("sha256")
|
||||||
|
.update(b)
|
||||||
|
.digest("hex");
|
||||||
|
|
||||||
const arrIn = buffer2bitArray(b);
|
const arrIn = buffer2bitArray(b);
|
||||||
const witness = circuit.calculateWitness({ in: arrIn } /*, {logOutput: true} */);
|
|
||||||
|
const witness = await cir.calculateWitness({ "in": arrIn }, true);
|
||||||
|
|
||||||
const arrOut = witness.slice(1, 257);
|
const arrOut = witness.slice(1, 257);
|
||||||
const hash2 = bitArray2buffer(arrOut).toString("hex");
|
const hash2 = bitArray2buffer(arrOut).toString("hex");
|
||||||
|
|
||||||
assert.equal(hash, hash2);
|
assert.equal(hash, hash2);
|
||||||
}).timeout(1000000);
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
70
test/sign.js
70
test/sign.js
@ -1,11 +1,7 @@
|
|||||||
const chai = require("chai");
|
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("@tornado/snarkjs");
|
const Fr = require("ffjavascript").bn128.Fr;
|
||||||
const compiler = require("circom");
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
|
const tester = require("circom").tester;
|
||||||
const assert = chai.assert;
|
|
||||||
|
|
||||||
const bigInt = snarkjs.bigInt;
|
|
||||||
|
|
||||||
function print(circuit, w, s) {
|
function print(circuit, w, s) {
|
||||||
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
||||||
@ -13,74 +9,72 @@ function print(circuit, w, s) {
|
|||||||
|
|
||||||
function getBits(v, n) {
|
function getBits(v, n) {
|
||||||
const res = [];
|
const res = [];
|
||||||
for (let i = 0; i < n; i++) {
|
for (let i=0; i<n; i++) {
|
||||||
if (v.shr(i).isOdd()) {
|
if (Scalar.isOdd(Scalar.shr(v, i))) {
|
||||||
res.push(bigInt.one);
|
res.push(Fr.one);
|
||||||
} else {
|
} else {
|
||||||
res.push(bigInt.zero);
|
res.push(Fr.zero);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
const q = Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||||
|
|
||||||
describe("Sign test", () => {
|
describe("Sign test", function() {
|
||||||
let circuit;
|
let circuit;
|
||||||
before(async () => {
|
this.timeout(100000);
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "sign_test.circom"));
|
|
||||||
|
|
||||||
circuit = new snarkjs.Circuit(cirDef);
|
before( async() => {
|
||||||
|
circuit = await tester(path.join(__dirname, "circuits", "sign_test.circom"));
|
||||||
console.log("NConstrains: " + circuit.nConstraints);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Sign of 0", async () => {
|
it("Sign of 0", async () => {
|
||||||
const inp = getBits(bigInt.zero, 254);
|
const inp = getBits(Scalar.e(0), 254);
|
||||||
const w = circuit.calculateWitness({ in: inp });
|
const w = await circuit.calculateWitness({in: inp}, true);
|
||||||
|
|
||||||
assert(w[circuit.getSignalIdx("main.sign")].equals(bigInt(0)));
|
await circuit.assertOut(w, {sign: 0});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Sign of 3", async () => {
|
it("Sign of 3", async () => {
|
||||||
const inp = getBits(bigInt(3), 254);
|
const inp = getBits(Scalar.e(3), 254);
|
||||||
const w = circuit.calculateWitness({ in: inp });
|
const w = await circuit.calculateWitness({in: inp}, true);
|
||||||
|
|
||||||
assert(w[circuit.getSignalIdx("main.sign")].equals(bigInt(0)));
|
await circuit.assertOut(w, {sign: 0});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Sign of q/2", async () => {
|
it("Sign of q/2", async () => {
|
||||||
const inp = getBits(q.shr(bigInt.one), 254);
|
const inp = getBits(Scalar.shr(q, 1), 254);
|
||||||
const w = circuit.calculateWitness({ in: inp });
|
const w = await circuit.calculateWitness({in: inp}, true);
|
||||||
|
|
||||||
assert(w[circuit.getSignalIdx("main.sign")].equals(bigInt(0)));
|
await circuit.assertOut(w, {sign: 0});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Sign of q/2+1", async () => {
|
it("Sign of q/2+1", async () => {
|
||||||
const inp = getBits(q.shr(bigInt.one).add(bigInt.one), 254);
|
const inp = getBits(Scalar.add(Scalar.shr(q, 1), 1) , 254);
|
||||||
const w = circuit.calculateWitness({ in: inp });
|
const w = await circuit.calculateWitness({in: inp}, true);
|
||||||
|
|
||||||
assert(w[circuit.getSignalIdx("main.sign")].equals(bigInt(1)));
|
await circuit.assertOut(w, {sign: 1});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Sign of q-1", async () => {
|
it("Sign of q-1", async () => {
|
||||||
const inp = getBits(q.sub(bigInt.one), 254);
|
const inp = getBits(Scalar.sub(q, 1), 254);
|
||||||
const w = circuit.calculateWitness({ in: inp });
|
const w = await circuit.calculateWitness({in: inp}, true);
|
||||||
|
|
||||||
assert(w[circuit.getSignalIdx("main.sign")].equals(bigInt(1)));
|
await circuit.assertOut(w, {sign: 1});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Sign of q", async () => {
|
it("Sign of q", async () => {
|
||||||
const inp = getBits(q, 254);
|
const inp = getBits(q, 254);
|
||||||
const w = circuit.calculateWitness({ in: inp });
|
const w = await circuit.calculateWitness({in: inp}, true);
|
||||||
|
|
||||||
assert(w[circuit.getSignalIdx("main.sign")].equals(bigInt(1)));
|
await circuit.assertOut(w, {sign: 1});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Sign of all ones", async () => {
|
it("Sign of all ones", async () => {
|
||||||
const inp = getBits(bigInt(1).shl(254).sub(bigInt(1)), 254);
|
const inp = getBits(Scalar.sub(Scalar.shl(1,254),1), 254);
|
||||||
const w = circuit.calculateWitness({ in: inp });
|
const w = await circuit.calculateWitness({in: inp}, true);
|
||||||
|
|
||||||
assert(w[circuit.getSignalIdx("main.sign")].equals(bigInt(1)));
|
await circuit.assertOut(w, {sign: 1});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
152
test/smtjs.js
152
test/smtjs.js
@ -1,50 +1,34 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const snarkjs = require("@tornado/snarkjs");
|
|
||||||
|
const Fr = require("ffjavascript").bn128.Fr;
|
||||||
|
|
||||||
const smt = require("../src/smt.js");
|
const smt = require("../src/smt.js");
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
const bigInt = snarkjs.bigInt;
|
|
||||||
|
|
||||||
function stringifyBigInts(o) {
|
|
||||||
if (typeof o == "bigint" || o instanceof bigInt) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
describe("SMT Javascript test", function () {
|
describe("SMT Javascript test", function () {
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
before(async () => {});
|
before( async () => {
|
||||||
|
});
|
||||||
|
|
||||||
it("Should insert 2 elements and empty them", async () => {
|
it("Should insert 2 elements and empty them", async () => {
|
||||||
const tree = await smt.newMemEmptyTrie();
|
const tree = await smt.newMemEmptyTrie();
|
||||||
const key1 = bigInt(111);
|
const key1 = Fr.e(111);
|
||||||
const value1 = bigInt(222);
|
const value1 = Fr.e(222);
|
||||||
const key2 = bigInt(333);
|
const key2 = Fr.e(333);
|
||||||
const value2 = bigInt(444);
|
const value2 = Fr.e(444);
|
||||||
|
|
||||||
await tree.insert(key1, value1);
|
await tree.insert(key1,value1);
|
||||||
await tree.insert(key2, value2);
|
await tree.insert(key2,value2);
|
||||||
await tree.delete(key2);
|
await tree.delete(key2);
|
||||||
await tree.delete(key1);
|
await tree.delete(key1);
|
||||||
|
|
||||||
assert(tree.root.isZero());
|
assert(Fr.isZero(tree.root));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should insert 3 elements in dferent order and should be the same", async () => {
|
it("Should insert 3 elements in dferent order and should be the same", async () => {
|
||||||
const keys = [bigInt(8), bigInt(9), bigInt(32)];
|
const keys = [Fr.e(8), Fr.e(9), Fr.e(32)];
|
||||||
const values = [bigInt(88), bigInt(99), bigInt(3232)];
|
const values = [Fr.e(88), Fr.e(99), Fr.e(3232)];
|
||||||
const tree1 = await smt.newMemEmptyTrie();
|
const tree1 = await smt.newMemEmptyTrie();
|
||||||
const tree2 = await smt.newMemEmptyTrie();
|
const tree2 = await smt.newMemEmptyTrie();
|
||||||
const tree3 = await smt.newMemEmptyTrie();
|
const tree3 = await smt.newMemEmptyTrie();
|
||||||
@ -52,59 +36,59 @@ describe("SMT Javascript test", function () {
|
|||||||
const tree5 = await smt.newMemEmptyTrie();
|
const tree5 = await smt.newMemEmptyTrie();
|
||||||
const tree6 = await smt.newMemEmptyTrie();
|
const tree6 = await smt.newMemEmptyTrie();
|
||||||
|
|
||||||
await tree1.insert(keys[0], values[0]);
|
await tree1.insert(keys[0],values[0]);
|
||||||
await tree1.insert(keys[1], values[1]);
|
await tree1.insert(keys[1],values[1]);
|
||||||
await tree1.insert(keys[2], values[2]);
|
await tree1.insert(keys[2],values[2]);
|
||||||
|
|
||||||
await tree2.insert(keys[0], values[0]);
|
await tree2.insert(keys[0],values[0]);
|
||||||
await tree2.insert(keys[2], values[2]);
|
await tree2.insert(keys[2],values[2]);
|
||||||
await tree2.insert(keys[1], values[1]);
|
await tree2.insert(keys[1],values[1]);
|
||||||
|
|
||||||
await tree3.insert(keys[1], values[1]);
|
await tree3.insert(keys[1],values[1]);
|
||||||
await tree3.insert(keys[0], values[0]);
|
await tree3.insert(keys[0],values[0]);
|
||||||
await tree3.insert(keys[2], values[2]);
|
await tree3.insert(keys[2],values[2]);
|
||||||
|
|
||||||
await tree4.insert(keys[1], values[1]);
|
await tree4.insert(keys[1],values[1]);
|
||||||
await tree4.insert(keys[2], values[2]);
|
await tree4.insert(keys[2],values[2]);
|
||||||
await tree4.insert(keys[0], values[0]);
|
await tree4.insert(keys[0],values[0]);
|
||||||
|
|
||||||
await tree5.insert(keys[2], values[2]);
|
await tree5.insert(keys[2],values[2]);
|
||||||
await tree5.insert(keys[0], values[0]);
|
await tree5.insert(keys[0],values[0]);
|
||||||
await tree5.insert(keys[1], values[1]);
|
await tree5.insert(keys[1],values[1]);
|
||||||
|
|
||||||
await tree6.insert(keys[2], values[2]);
|
await tree6.insert(keys[2],values[2]);
|
||||||
await tree6.insert(keys[1], values[1]);
|
await tree6.insert(keys[1],values[1]);
|
||||||
await tree6.insert(keys[0], values[0]);
|
await tree6.insert(keys[0],values[0]);
|
||||||
|
|
||||||
assert(tree1.root.equals(tree2.root));
|
assert(Fr.eq(tree1.root, tree2.root));
|
||||||
assert(tree2.root.equals(tree3.root));
|
assert(Fr.eq(tree2.root, tree3.root));
|
||||||
assert(tree3.root.equals(tree4.root));
|
assert(Fr.eq(tree3.root, tree4.root));
|
||||||
assert(tree4.root.equals(tree5.root));
|
assert(Fr.eq(tree4.root, tree5.root));
|
||||||
assert(tree5.root.equals(tree6.root));
|
assert(Fr.eq(tree5.root, tree6.root));
|
||||||
|
|
||||||
assert.equal(Object.keys(tree1.db.nodes).length, Object.keys(tree2.db.nodes).length);
|
assert.equal(Object.keys(tree1.db.nodes).length, Object.keys(tree2.db.nodes).length);
|
||||||
assert.equal(Object.keys(tree2.db.nodes).length, Object.keys(tree3.db.nodes).length);
|
assert.equal(Object.keys(tree2.db.nodes).length, Object.keys(tree3.db.nodes).length);
|
||||||
assert.equal(Object.keys(tree3.db.nodes).length, Object.keys(tree4.db.nodes).length);
|
assert.equal(Object.keys(tree3.db.nodes).length, Object.keys(tree4.db.nodes).length);
|
||||||
assert.equal(Object.keys(tree4.db.nodes).length, Object.keys(tree5.db.nodes).length);
|
assert.equal(Object.keys(tree4.db.nodes).length, Object.keys(tree5.db.nodes).length);
|
||||||
assert.equal(Object.keys(tree5.db.nodes).length, Object.keys(tree6.db.nodes).length);
|
assert.equal(Object.keys(tree5.db.nodes).length, Object.keys(tree6.db.nodes).length);
|
||||||
|
|
||||||
await tree1.delete(keys[0]);
|
await tree1.delete(keys[0]);
|
||||||
await tree1.delete(keys[1]);
|
await tree1.delete(keys[1]);
|
||||||
await tree2.delete(keys[1]);
|
await tree2.delete(keys[1]);
|
||||||
await tree2.delete(keys[0]);
|
await tree2.delete(keys[0]);
|
||||||
assert(tree1.root.equals(tree2.root));
|
assert(Fr.eq(tree1.root, tree2.root));
|
||||||
|
|
||||||
await tree3.delete(keys[0]);
|
await tree3.delete(keys[0]);
|
||||||
await tree3.delete(keys[2]);
|
await tree3.delete(keys[2]);
|
||||||
await tree4.delete(keys[2]);
|
await tree4.delete(keys[2]);
|
||||||
await tree4.delete(keys[0]);
|
await tree4.delete(keys[0]);
|
||||||
assert(tree3.root.equals(tree4.root));
|
assert(Fr.eq(tree3.root, tree4.root));
|
||||||
|
|
||||||
await tree5.delete(keys[1]);
|
await tree5.delete(keys[1]);
|
||||||
await tree5.delete(keys[2]);
|
await tree5.delete(keys[2]);
|
||||||
await tree6.delete(keys[2]);
|
await tree6.delete(keys[2]);
|
||||||
await tree6.delete(keys[1]);
|
await tree6.delete(keys[1]);
|
||||||
assert(tree5.root.equals(tree6.root));
|
assert(Fr.eq(tree5.root, tree6.root));
|
||||||
|
|
||||||
await tree1.delete(keys[2]);
|
await tree1.delete(keys[2]);
|
||||||
await tree2.delete(keys[2]);
|
await tree2.delete(keys[2]);
|
||||||
@ -113,12 +97,12 @@ describe("SMT Javascript test", function () {
|
|||||||
await tree5.delete(keys[0]);
|
await tree5.delete(keys[0]);
|
||||||
await tree6.delete(keys[0]);
|
await tree6.delete(keys[0]);
|
||||||
|
|
||||||
assert(tree1.root.isZero());
|
assert(Fr.isZero(tree1.root));
|
||||||
assert(tree2.root.isZero());
|
assert(Fr.isZero(tree2.root));
|
||||||
assert(tree3.root.isZero());
|
assert(Fr.isZero(tree3.root));
|
||||||
assert(tree4.root.isZero());
|
assert(Fr.isZero(tree4.root));
|
||||||
assert(tree5.root.isZero());
|
assert(Fr.isZero(tree5.root));
|
||||||
assert(tree6.root.isZero());
|
assert(Fr.isZero(tree6.root));
|
||||||
|
|
||||||
assert.equal(Object.keys(tree1.db.nodes).length, 0);
|
assert.equal(Object.keys(tree1.db.nodes).length, 0);
|
||||||
assert.equal(Object.keys(tree2.db.nodes).length, 0);
|
assert.equal(Object.keys(tree2.db.nodes).length, 0);
|
||||||
@ -132,7 +116,7 @@ describe("SMT Javascript test", function () {
|
|||||||
function perm(a) {
|
function perm(a) {
|
||||||
const arr = a.slice();
|
const arr = a.slice();
|
||||||
const rArr = [];
|
const rArr = [];
|
||||||
for (let i = 0; i < arr.length; i++) {
|
for (let i=0; i<arr.length; i++) {
|
||||||
let rIdx = Math.floor(Math.random() * (arr.length - i));
|
let rIdx = Math.floor(Math.random() * (arr.length - i));
|
||||||
rArr.push(arr[rIdx]);
|
rArr.push(arr[rIdx]);
|
||||||
arr[rIdx] = arr[arr.length - i - 1];
|
arr[rIdx] = arr[arr.length - i - 1];
|
||||||
@ -142,19 +126,19 @@ describe("SMT Javascript test", function () {
|
|||||||
const tree = await smt.newMemEmptyTrie();
|
const tree = await smt.newMemEmptyTrie();
|
||||||
const arr = [];
|
const arr = [];
|
||||||
const N = 100;
|
const N = 100;
|
||||||
for (let i = 0; i < N; i++) {
|
for (let i=0; i<N; i++) {
|
||||||
arr.push(bigInt(i));
|
arr.push(Fr.e(i));
|
||||||
}
|
}
|
||||||
const insArr = perm(arr);
|
const insArr = perm(arr);
|
||||||
for (let i = 0; i < N; i++) {
|
for (let i=0; i<N; i++) {
|
||||||
await tree.insert(insArr[i], i);
|
await tree.insert(insArr[i], i);
|
||||||
}
|
}
|
||||||
const delArr = perm(insArr);
|
const delArr = perm(insArr);
|
||||||
for (let i = 0; i < N; i++) {
|
for (let i=0; i<N; i++) {
|
||||||
await tree.delete(delArr[i]);
|
await tree.delete(delArr[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(tree.root.isZero());
|
assert(Fr.isZero(tree.root));
|
||||||
assert.equal(Object.keys(tree.db.nodes).length, 0);
|
assert.equal(Object.keys(tree.db.nodes).length, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -162,18 +146,28 @@ describe("SMT Javascript test", function () {
|
|||||||
const tree1 = await smt.newMemEmptyTrie();
|
const tree1 = await smt.newMemEmptyTrie();
|
||||||
const tree2 = await smt.newMemEmptyTrie();
|
const tree2 = await smt.newMemEmptyTrie();
|
||||||
|
|
||||||
await tree1.insert(8, 88);
|
await tree1.insert(8,88);
|
||||||
await tree1.insert(9, 99);
|
await tree1.insert(9,99,);
|
||||||
await tree1.insert(32, 3232);
|
await tree1.insert(32,3232);
|
||||||
|
|
||||||
await tree2.insert(8, 888);
|
await tree2.insert(8,888);
|
||||||
await tree2.insert(9, 999);
|
await tree2.insert(9,999);
|
||||||
await tree2.insert(32, 323232);
|
await tree2.insert(32,323232);
|
||||||
|
|
||||||
await tree1.update(8, 888);
|
await tree1.update(8, 888);
|
||||||
await tree1.update(9, 999);
|
await tree1.update(9, 999);
|
||||||
await tree1.update(32, 323232);
|
await tree1.update(32, 323232);
|
||||||
|
|
||||||
assert(tree1.root.equals(tree2.root));
|
assert(Fr.eq(tree1.root, tree2.root));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should test update with same key-value", async () => {
|
||||||
|
const tree1 = await smt.newMemEmptyTrie();
|
||||||
|
|
||||||
|
await tree1.insert(8,88);
|
||||||
|
await tree1.update(8,88);
|
||||||
|
|
||||||
|
const res = await tree1.db.get(tree1.root);
|
||||||
|
assert.notEqual(res, undefined);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,112 +1,105 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("@tornado/snarkjs");
|
const tester = require("circom").tester;
|
||||||
const compiler = require("circom");
|
const Fr = require("ffjavascript").bn128.Fr;
|
||||||
|
|
||||||
const smt = require("../src/smt.js");
|
const smt = require("../src/smt.js");
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
const bigInt = snarkjs.bigInt;
|
|
||||||
|
|
||||||
function print(circuit, w, s) {
|
function print(circuit, w, s) {
|
||||||
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function testInsert(tree, key, value, circuit, log) {
|
async function testInsert(tree, key, value, circuit ) {
|
||||||
const res = await tree.insert(key, value);
|
|
||||||
|
const res = await tree.insert(key,value);
|
||||||
let siblings = res.siblings;
|
let siblings = res.siblings;
|
||||||
while (siblings.length < 10) siblings.push(bigInt(0));
|
while (siblings.length<10) siblings.push(Fr.e(0));
|
||||||
|
|
||||||
const w = circuit.calculateWitness(
|
const w = await circuit.calculateWitness({
|
||||||
{
|
fnc: [1,0],
|
||||||
fnc: [1, 0],
|
oldRoot: res.oldRoot,
|
||||||
oldRoot: res.oldRoot,
|
siblings: siblings,
|
||||||
siblings: siblings,
|
oldKey: res.isOld0 ? 0 : res.oldKey,
|
||||||
oldKey: res.isOld0 ? 0 : res.oldKey,
|
oldValue: res.isOld0 ? 0 : res.oldValue,
|
||||||
oldValue: res.isOld0 ? 0 : res.oldValue,
|
isOld0: res.isOld0 ? 1 : 0,
|
||||||
isOld0: res.isOld0 ? 1 : 0,
|
newKey: key,
|
||||||
newKey: key,
|
newValue: value
|
||||||
newValue: value,
|
}, true);
|
||||||
},
|
|
||||||
log
|
await circuit.checkConstraints(w);
|
||||||
);
|
|
||||||
|
await circuit.assertOut(w, {newRoot: res.newRoot});
|
||||||
|
|
||||||
const root1 = w[circuit.getSignalIdx("main.newRoot")];
|
|
||||||
assert(circuit.checkWitness(w));
|
|
||||||
assert(root1.equals(res.newRoot));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function testDelete(tree, key, circuit) {
|
async function testDelete(tree, key, circuit) {
|
||||||
const res = await tree.delete(key);
|
const res = await tree.delete(key);
|
||||||
let siblings = res.siblings;
|
let siblings = res.siblings;
|
||||||
while (siblings.length < 10) siblings.push(bigInt(0));
|
while (siblings.length<10) siblings.push(Fr.e(0));
|
||||||
|
|
||||||
const w = circuit.calculateWitness({
|
const w = await circuit.calculateWitness({
|
||||||
fnc: [1, 1],
|
fnc: [1,1],
|
||||||
oldRoot: res.oldRoot,
|
oldRoot: res.oldRoot,
|
||||||
siblings: siblings,
|
siblings: siblings,
|
||||||
oldKey: res.isOld0 ? 0 : res.oldKey,
|
oldKey: res.isOld0 ? 0 : res.oldKey,
|
||||||
oldValue: res.isOld0 ? 0 : res.oldValue,
|
oldValue: res.isOld0 ? 0 : res.oldValue,
|
||||||
isOld0: res.isOld0 ? 1 : 0,
|
isOld0: res.isOld0 ? 1 : 0,
|
||||||
newKey: res.delKey,
|
newKey: res.delKey,
|
||||||
newValue: res.delValue,
|
newValue: res.delValue
|
||||||
});
|
}, true);
|
||||||
|
|
||||||
const root1 = w[circuit.getSignalIdx("main.newRoot")];
|
await circuit.checkConstraints(w);
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
await circuit.assertOut(w, {newRoot: res.newRoot});
|
||||||
assert(root1.equals(res.newRoot));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function testUpdate(tree, key, newValue, circuit) {
|
async function testUpdate(tree, key, newValue, circuit) {
|
||||||
const res = await tree.update(key, newValue);
|
const res = await tree.update(key, newValue);
|
||||||
let siblings = res.siblings;
|
let siblings = res.siblings;
|
||||||
while (siblings.length < 10) siblings.push(bigInt(0));
|
while (siblings.length<10) siblings.push(Fr.e(0));
|
||||||
|
|
||||||
const w = circuit.calculateWitness({
|
const w = await circuit.calculateWitness({
|
||||||
fnc: [0, 1],
|
fnc: [0,1],
|
||||||
oldRoot: res.oldRoot,
|
oldRoot: res.oldRoot,
|
||||||
siblings: siblings,
|
siblings: siblings,
|
||||||
oldKey: res.oldKey,
|
oldKey: res.oldKey,
|
||||||
oldValue: res.oldValue,
|
oldValue: res.oldValue,
|
||||||
isOld0: 0,
|
isOld0: 0,
|
||||||
newKey: res.newKey,
|
newKey: res.newKey,
|
||||||
newValue: res.newValue,
|
newValue: res.newValue
|
||||||
});
|
});
|
||||||
|
|
||||||
const root1 = w[circuit.getSignalIdx("main.newRoot")];
|
await circuit.checkConstraints(w);
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
await circuit.assertOut(w, {newRoot: res.newRoot});
|
||||||
assert(root1.equals(res.newRoot));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("SMT test", function () {
|
|
||||||
|
describe("SMT Processor test", function () {
|
||||||
let circuit;
|
let circuit;
|
||||||
let tree;
|
let tree;
|
||||||
|
|
||||||
this.timeout(10000000);
|
this.timeout(10000000);
|
||||||
|
|
||||||
before(async () => {
|
before( async () => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "smtprocessor10_test.circom"));
|
circuit = await tester(path.join(__dirname, "circuits", "smtprocessor10_test.circom"));
|
||||||
|
await circuit.loadSymbols();
|
||||||
circuit = new snarkjs.Circuit(cirDef);
|
|
||||||
|
|
||||||
console.log("NConstrains SMTProcessor: " + circuit.nConstraints);
|
|
||||||
|
|
||||||
tree = await smt.newMemEmptyTrie();
|
tree = await smt.newMemEmptyTrie();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should verify an insert to an empty tree", async () => {
|
it("Should verify an insert to an empty tree", async () => {
|
||||||
const key = bigInt(111);
|
const key = Fr.e(111);
|
||||||
const value = bigInt(222);
|
const value = Fr.e(222);
|
||||||
|
|
||||||
await testInsert(tree, key, value, circuit);
|
await testInsert(tree, key, value, circuit);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("It should add another element", async () => {
|
it("It should add another element", async () => {
|
||||||
const key = bigInt(333);
|
const key = Fr.e(333);
|
||||||
const value = bigInt(444);
|
const value = Fr.e(444);
|
||||||
|
|
||||||
await testInsert(tree, key, value, circuit);
|
await testInsert(tree, key, value, circuit);
|
||||||
});
|
});
|
||||||
@ -117,8 +110,8 @@ describe("SMT test", function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Should test convination of adding and removing 3 elements", async () => {
|
it("Should test convination of adding and removing 3 elements", async () => {
|
||||||
const keys = [bigInt(8), bigInt(9), bigInt(32)];
|
const keys = [Fr.e(8), Fr.e(9), Fr.e(32)];
|
||||||
const values = [bigInt(88), bigInt(99), bigInt(3232)];
|
const values = [Fr.e(88), Fr.e(99), Fr.e(3232)];
|
||||||
const tree1 = await smt.newMemEmptyTrie();
|
const tree1 = await smt.newMemEmptyTrie();
|
||||||
const tree2 = await smt.newMemEmptyTrie();
|
const tree2 = await smt.newMemEmptyTrie();
|
||||||
const tree3 = await smt.newMemEmptyTrie();
|
const tree3 = await smt.newMemEmptyTrie();
|
||||||
@ -126,29 +119,30 @@ describe("SMT test", function () {
|
|||||||
const tree5 = await smt.newMemEmptyTrie();
|
const tree5 = await smt.newMemEmptyTrie();
|
||||||
const tree6 = await smt.newMemEmptyTrie();
|
const tree6 = await smt.newMemEmptyTrie();
|
||||||
|
|
||||||
await testInsert(tree1, keys[0], values[0], circuit);
|
await testInsert(tree1,keys[0],values[0], circuit);
|
||||||
await testInsert(tree1, keys[1], values[1], circuit);
|
await testInsert(tree1,keys[1],values[1], circuit);
|
||||||
await testInsert(tree1, keys[2], values[2], circuit);
|
await testInsert(tree1,keys[2],values[2], circuit);
|
||||||
|
|
||||||
await testInsert(tree2, keys[0], values[0], circuit);
|
await testInsert(tree2,keys[0],values[0], circuit);
|
||||||
await testInsert(tree2, keys[2], values[2], circuit);
|
await testInsert(tree2,keys[2],values[2], circuit);
|
||||||
await testInsert(tree2, keys[1], values[1], circuit);
|
await testInsert(tree2,keys[1],values[1], circuit);
|
||||||
|
|
||||||
await testInsert(tree3, keys[1], values[1], circuit);
|
await testInsert(tree3,keys[1],values[1], circuit);
|
||||||
await testInsert(tree3, keys[0], values[0], circuit);
|
await testInsert(tree3,keys[0],values[0], circuit);
|
||||||
await testInsert(tree3, keys[2], values[2], circuit);
|
await testInsert(tree3,keys[2],values[2], circuit);
|
||||||
|
|
||||||
await testInsert(tree4, keys[1], values[1], circuit);
|
await testInsert(tree4,keys[1],values[1], circuit);
|
||||||
await testInsert(tree4, keys[2], values[2], circuit);
|
await testInsert(tree4,keys[2],values[2], circuit);
|
||||||
await testInsert(tree4, keys[0], values[0], circuit);
|
await testInsert(tree4,keys[0],values[0], circuit);
|
||||||
|
|
||||||
await testInsert(tree5, keys[2], values[2], circuit);
|
await testInsert(tree5,keys[2],values[2], circuit);
|
||||||
await testInsert(tree5, keys[0], values[0], circuit);
|
await testInsert(tree5,keys[0],values[0], circuit);
|
||||||
await testInsert(tree5, keys[1], values[1], circuit);
|
await testInsert(tree5,keys[1],values[1], circuit);
|
||||||
|
|
||||||
|
await testInsert(tree6,keys[2],values[2], circuit);
|
||||||
|
await testInsert(tree6,keys[1],values[1], circuit);
|
||||||
|
await testInsert(tree6,keys[0],values[0], circuit);
|
||||||
|
|
||||||
await testInsert(tree6, keys[2], values[2], circuit);
|
|
||||||
await testInsert(tree6, keys[1], values[1], circuit);
|
|
||||||
await testInsert(tree6, keys[0], values[0], circuit);
|
|
||||||
|
|
||||||
await testDelete(tree1, keys[0], circuit);
|
await testDelete(tree1, keys[0], circuit);
|
||||||
await testDelete(tree1, keys[1], circuit);
|
await testDelete(tree1, keys[1], circuit);
|
||||||
@ -160,6 +154,7 @@ describe("SMT test", function () {
|
|||||||
await testDelete(tree4, keys[2], circuit);
|
await testDelete(tree4, keys[2], circuit);
|
||||||
await testDelete(tree4, keys[0], circuit);
|
await testDelete(tree4, keys[0], circuit);
|
||||||
|
|
||||||
|
|
||||||
await testDelete(tree5, keys[1], circuit);
|
await testDelete(tree5, keys[1], circuit);
|
||||||
await testDelete(tree5, keys[2], circuit);
|
await testDelete(tree5, keys[2], circuit);
|
||||||
await testDelete(tree6, keys[2], circuit);
|
await testDelete(tree6, keys[2], circuit);
|
||||||
@ -175,35 +170,36 @@ describe("SMT test", function () {
|
|||||||
|
|
||||||
it("Should match a NOp with random vals", async () => {
|
it("Should match a NOp with random vals", async () => {
|
||||||
let siblings = [];
|
let siblings = [];
|
||||||
while (siblings.length < 10) siblings.push(bigInt(88));
|
while (siblings.length<10) siblings.push(Fr.e(88));
|
||||||
const w = circuit.calculateWitness({
|
const w = await circuit.calculateWitness({
|
||||||
fnc: [0, 0],
|
fnc: [0,0],
|
||||||
oldRoot: 11,
|
oldRoot: 11,
|
||||||
siblings: siblings,
|
siblings: siblings,
|
||||||
oldKey: 33,
|
oldKey: 33,
|
||||||
oldValue: 44,
|
oldValue: 44,
|
||||||
isOld0: 55,
|
isOld0: 55,
|
||||||
newKey: 66,
|
newKey: 66,
|
||||||
newValue: 77,
|
newValue: 77
|
||||||
});
|
});
|
||||||
|
|
||||||
const root1 = w[circuit.getSignalIdx("main.oldRoot")];
|
const root1 = w[circuit.symbols["main.oldRoot"].varIdx];
|
||||||
const root2 = w[circuit.getSignalIdx("main.newRoot")];
|
const root2 = w[circuit.symbols["main.newRoot"].varIdx];
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
await circuit.checkConstraints(w);
|
||||||
assert(root1.equals(root2));
|
|
||||||
|
assert(Fr.eq(root1, root2));
|
||||||
});
|
});
|
||||||
it("Should update an element", async () => {
|
it("Should update an element", async () => {
|
||||||
const tree1 = await smt.newMemEmptyTrie();
|
const tree1 = await smt.newMemEmptyTrie();
|
||||||
const tree2 = await smt.newMemEmptyTrie();
|
const tree2 = await smt.newMemEmptyTrie();
|
||||||
|
|
||||||
await testInsert(tree1, 8, 88, circuit);
|
await testInsert(tree1,8,88, circuit);
|
||||||
await testInsert(tree1, 9, 99, circuit);
|
await testInsert(tree1,9,99, circuit);
|
||||||
await testInsert(tree1, 32, 3232, circuit);
|
await testInsert(tree1,32,3232, circuit);
|
||||||
|
|
||||||
await testInsert(tree2, 8, 888, circuit);
|
await testInsert(tree2,8,888, circuit);
|
||||||
await testInsert(tree2, 9, 999, circuit);
|
await testInsert(tree2,9,999, circuit);
|
||||||
await testInsert(tree2, 32, 323232, circuit);
|
await testInsert(tree2,32,323232, circuit);
|
||||||
|
|
||||||
await testUpdate(tree1, 8, 888, circuit);
|
await testUpdate(tree1, 8, 888, circuit);
|
||||||
await testUpdate(tree1, 9, 999, circuit);
|
await testUpdate(tree1, 9, 999, circuit);
|
||||||
|
@ -1,26 +1,25 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("@tornado/snarkjs");
|
const Fr = require("ffjavascript").bn128.Fr;
|
||||||
const compiler = require("circom");
|
const tester = require("circom").tester;
|
||||||
|
|
||||||
const smt = require("../src/smt.js");
|
const smt = require("../src/smt.js");
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
const bigInt = snarkjs.bigInt;
|
|
||||||
|
|
||||||
function print(circuit, w, s) {
|
function print(circuit, w, s) {
|
||||||
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function testInclusion(tree, key, circuit) {
|
async function testInclusion(tree, key, circuit) {
|
||||||
|
|
||||||
const res = await tree.find(key);
|
const res = await tree.find(key);
|
||||||
|
|
||||||
assert(res.found);
|
assert(res.found);
|
||||||
let siblings = res.siblings;
|
let siblings = res.siblings;
|
||||||
while (siblings.length < 10) siblings.push(bigInt(0));
|
while (siblings.length<10) siblings.push(Fr.e(0));
|
||||||
|
|
||||||
const w = circuit.calculateWitness({
|
const w = await circuit.calculateWitness({
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
fnc: 0,
|
fnc: 0,
|
||||||
root: tree.root,
|
root: tree.root,
|
||||||
@ -29,10 +28,11 @@ async function testInclusion(tree, key, circuit) {
|
|||||||
oldValue: 0,
|
oldValue: 0,
|
||||||
isOld0: 0,
|
isOld0: 0,
|
||||||
key: key,
|
key: key,
|
||||||
value: res.foundValue,
|
value: res.foundValue
|
||||||
});
|
}, true);
|
||||||
|
|
||||||
|
await circuit.checkConstraints(w);
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function testExclusion(tree, key, circuit) {
|
async function testExclusion(tree, key, circuit) {
|
||||||
@ -40,9 +40,9 @@ async function testExclusion(tree, key, circuit) {
|
|||||||
|
|
||||||
assert(!res.found);
|
assert(!res.found);
|
||||||
let siblings = res.siblings;
|
let siblings = res.siblings;
|
||||||
while (siblings.length < 10) siblings.push(bigInt(0));
|
while (siblings.length<10) siblings.push(Fr.e(0));
|
||||||
|
|
||||||
const w = circuit.calculateWitness({
|
const w = await circuit.calculateWitness({
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
fnc: 1,
|
fnc: 1,
|
||||||
root: tree.root,
|
root: tree.root,
|
||||||
@ -51,29 +51,26 @@ async function testExclusion(tree, key, circuit) {
|
|||||||
oldValue: res.isOld0 ? 0 : res.notFoundValue,
|
oldValue: res.isOld0 ? 0 : res.notFoundValue,
|
||||||
isOld0: res.isOld0 ? 1 : 0,
|
isOld0: res.isOld0 ? 1 : 0,
|
||||||
key: key,
|
key: key,
|
||||||
value: 0,
|
value: 0
|
||||||
});
|
});
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
await circuit.checkConstraints(w);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("SMT test", function () {
|
describe("SMT Verifier test", function () {
|
||||||
let circuit;
|
let circuit;
|
||||||
let tree;
|
let tree;
|
||||||
|
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
|
|
||||||
before(async () => {
|
before( async () => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "smtverifier10_test.circom"));
|
circuit = await tester(path.join(__dirname, "circuits", "smtverifier10_test.circom"));
|
||||||
|
|
||||||
circuit = new snarkjs.Circuit(cirDef);
|
|
||||||
|
|
||||||
console.log("NConstrains SMTVerifier: " + circuit.nConstraints);
|
|
||||||
|
|
||||||
tree = await smt.newMemEmptyTrie();
|
tree = await smt.newMemEmptyTrie();
|
||||||
await tree.insert(7, 77);
|
await tree.insert(7,77);
|
||||||
await tree.insert(8, 88);
|
await tree.insert(8,88);
|
||||||
await tree.insert(32, 3232);
|
await tree.insert(32,3232);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Check inclussion in a tree of 3", async () => {
|
it("Check inclussion in a tree of 3", async () => {
|
||||||
@ -94,9 +91,9 @@ describe("SMT test", function () {
|
|||||||
|
|
||||||
it("Check not enabled accepts any thing", async () => {
|
it("Check not enabled accepts any thing", async () => {
|
||||||
let siblings = [];
|
let siblings = [];
|
||||||
for (let i = 0; i < 10; i++) siblings.push(i);
|
for (let i=0; i<10; i++) siblings.push(i);
|
||||||
|
|
||||||
const w = circuit.calculateWitness({
|
const w = await circuit.calculateWitness({
|
||||||
enabled: 0,
|
enabled: 0,
|
||||||
fnc: 0,
|
fnc: 0,
|
||||||
root: 1,
|
root: 1,
|
||||||
@ -105,31 +102,35 @@ describe("SMT test", function () {
|
|||||||
oldValue: 33,
|
oldValue: 33,
|
||||||
isOld0: 0,
|
isOld0: 0,
|
||||||
key: 44,
|
key: 44,
|
||||||
value: 0,
|
value: 0
|
||||||
});
|
});
|
||||||
assert(circuit.checkWitness(w));
|
|
||||||
|
|
||||||
|
await circuit.checkConstraints(w);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Check inclussion Adria case", async () => {
|
it("Check inclussion Adria case", async () => {
|
||||||
const e1_hi = bigInt("17124152697573569611556136390143205198134245887034837071647643529178599000839");
|
const e1_hi= Fr.e("17124152697573569611556136390143205198134245887034837071647643529178599000839");
|
||||||
const e1_hv = bigInt("19650379996168153643111744440707177573540245771926102415571667548153444658179");
|
const e1_hv= Fr.e("19650379996168153643111744440707177573540245771926102415571667548153444658179");
|
||||||
|
|
||||||
const e2ok_hi = bigInt("16498254692537945203721083102154618658340563351558973077349594629411025251262");
|
const e2ok_hi= Fr.e("16498254692537945203721083102154618658340563351558973077349594629411025251262");
|
||||||
const e2ok_hv = bigInt("19650379996168153643111744440707177573540245771926102415571667548153444658179");
|
const e2ok_hv= Fr.e("19650379996168153643111744440707177573540245771926102415571667548153444658179");
|
||||||
|
|
||||||
const e2fail_hi = bigInt("17195092312975762537892237130737365903429674363577646686847513978084990105579");
|
const e2fail_hi= Fr.e("17195092312975762537892237130737365903429674363577646686847513978084990105579");
|
||||||
const e2fail_hv = bigInt("19650379996168153643111744440707177573540245771926102415571667548153444658179");
|
const e2fail_hv= Fr.e("19650379996168153643111744440707177573540245771926102415571667548153444658179");
|
||||||
|
|
||||||
const tree1 = await smt.newMemEmptyTrie();
|
const tree1 = await smt.newMemEmptyTrie();
|
||||||
await tree1.insert(e1_hi, e1_hv);
|
await tree1.insert(e1_hi,e1_hv);
|
||||||
await tree1.insert(e2ok_hi, e2ok_hv);
|
await tree1.insert(e2ok_hi,e2ok_hv);
|
||||||
|
|
||||||
await testInclusion(tree1, e2ok_hi, circuit);
|
await testInclusion(tree1, e2ok_hi, circuit);
|
||||||
|
|
||||||
const tree2 = await smt.newMemEmptyTrie();
|
const tree2 = await smt.newMemEmptyTrie();
|
||||||
await tree2.insert(e1_hi, e1_hv);
|
await tree2.insert(e1_hi,e1_hv);
|
||||||
await tree2.insert(e2fail_hi, e2fail_hv);
|
await tree2.insert(e2fail_hi,e2fail_hv);
|
||||||
|
|
||||||
await testInclusion(tree2, e2fail_hi, circuit);
|
await testInclusion(tree2, e2fail_hi, circuit);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -1,93 +0,0 @@
|
|||||||
const path = require("path");
|
|
||||||
const snarkjs = require("@tornado/snarkjs");
|
|
||||||
const compiler = require("circom");
|
|
||||||
const fs = require("fs");
|
|
||||||
|
|
||||||
const bigInt = snarkjs.bigInt;
|
|
||||||
const smt = require("../src/smt.js");
|
|
||||||
|
|
||||||
const circuitSource = `
|
|
||||||
include "../circuits/smt/smtverifier.circom";
|
|
||||||
template SMT(nLevels) {
|
|
||||||
signal input root;
|
|
||||||
signal input mtp[nLevels];
|
|
||||||
signal input hi;
|
|
||||||
signal input hv;
|
|
||||||
|
|
||||||
component smtClaimExists = SMTVerifier(nLevels);
|
|
||||||
smtClaimExists.enabled <== 1;
|
|
||||||
smtClaimExists.fnc <== 0;
|
|
||||||
smtClaimExists.root <== root;
|
|
||||||
for (var i=0; i<nLevels; i++) {
|
|
||||||
smtClaimExists.siblings[i] <== mtp[i];
|
|
||||||
}
|
|
||||||
smtClaimExists.oldKey <== 0;
|
|
||||||
smtClaimExists.oldValue <== 0;
|
|
||||||
smtClaimExists.isOld0 <== 0;
|
|
||||||
|
|
||||||
smtClaimExists.key <== hi;
|
|
||||||
smtClaimExists.value <== hv;
|
|
||||||
}
|
|
||||||
component main = SMT(4);
|
|
||||||
`;
|
|
||||||
|
|
||||||
describe("smt3test", function () {
|
|
||||||
this.timeout(200000);
|
|
||||||
|
|
||||||
let circuitFileName;
|
|
||||||
|
|
||||||
before(async () => {
|
|
||||||
circuitFileName = path.join(__dirname, ".", "rawsmt3.circom");
|
|
||||||
fs.writeFileSync(circuitFileName, circuitSource);
|
|
||||||
});
|
|
||||||
|
|
||||||
const levels = 4;
|
|
||||||
async function testsmt3(e1, e2) {
|
|
||||||
let tree = await smt.newMemEmptyTrie();
|
|
||||||
|
|
||||||
// insert e1, e2
|
|
||||||
await tree.insert(e1.hi, e1.hv);
|
|
||||||
await tree.insert(e2.hi, e2.hv);
|
|
||||||
|
|
||||||
// generate proof for e1
|
|
||||||
const findInfo = await tree.find(e1.hi);
|
|
||||||
const siblings = findInfo.siblings;
|
|
||||||
while (siblings.length < levels) siblings.push(bigInt(0));
|
|
||||||
|
|
||||||
const input = {
|
|
||||||
root: tree.root,
|
|
||||||
mtp: siblings,
|
|
||||||
hi: e1.hi,
|
|
||||||
hv: e1.hv,
|
|
||||||
};
|
|
||||||
|
|
||||||
const compiledCircuit = await compiler(circuitFileName, { reduceConstraints: false });
|
|
||||||
|
|
||||||
const circuit = new snarkjs.Circuit(compiledCircuit);
|
|
||||||
const witness = circuit.calculateWitness(input);
|
|
||||||
circuit.checkWitness(witness);
|
|
||||||
}
|
|
||||||
|
|
||||||
it("TestSmts", async () => {
|
|
||||||
const e1 = {
|
|
||||||
hi: bigInt("17124152697573569611556136390143205198134245887034837071647643529178599000839"),
|
|
||||||
hv: bigInt("19650379996168153643111744440707177573540245771926102415571667548153444658179"),
|
|
||||||
};
|
|
||||||
|
|
||||||
const e2ok = {
|
|
||||||
hi: bigInt("16498254692537945203721083102154618658340563351558973077349594629411025251262"),
|
|
||||||
hv: bigInt("19650379996168153643111744440707177573540245771926102415571667548153444658179"),
|
|
||||||
};
|
|
||||||
|
|
||||||
const e2fail = {
|
|
||||||
hi: bigInt("17195092312975762537892237130737365903429674363577646686847513978084990105579"),
|
|
||||||
hv: bigInt("19650379996168153643111744440707177573540245771926102415571667548153444658179"),
|
|
||||||
};
|
|
||||||
|
|
||||||
console.log("test e1, e2ok");
|
|
||||||
await testsmt3(e1, e2ok);
|
|
||||||
|
|
||||||
console.log("test e1, e2fail");
|
|
||||||
await testsmt3(e1, e2fail);
|
|
||||||
});
|
|
||||||
});
|
|
Loading…
Reference in New Issue
Block a user