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"
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
1
.npmrc
Normal file
1
.npmrc
Normal file
@ -0,0 +1 @@
|
|||||||
|
@tornado:registry=https://git.tornado.is/api/packages/tornado-packages/npm/
|
@ -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.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
const bn128 = require("snarkjs").bn128;
|
const bn128 = require("@tornado/snarkjs").bn128;
|
||||||
const bigInt = require("snarkjs").bigInt;
|
const bigInt = require("@tornado/snarkjs").bigInt;
|
||||||
const createBlakeHash = require("blake-hash");
|
const createBlakeHash = require("blake-hash");
|
||||||
const babyJub = require("../src/babyjub");
|
const babyJub = require("../src/babyjub");
|
||||||
|
|
||||||
@ -8,17 +8,17 @@ function getPoint(S) {
|
|||||||
const h = createBlakeHash("blake256").update(S).digest();
|
const h = createBlakeHash("blake256").update(S).digest();
|
||||||
|
|
||||||
if (h.length != 32) {
|
if (h.length != 32) {
|
||||||
throw new Error("Invalid length")
|
throw new Error("Invalid length");
|
||||||
}
|
}
|
||||||
|
|
||||||
let sign = false;
|
let sign = false;
|
||||||
if (h[31] & 0x80) {
|
if (h[31] & 0x80) {
|
||||||
h[31] = h[31] & 0x7F;
|
h[31] = h[31] & 0x7f;
|
||||||
sign = true;
|
sign = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let y = bigInt(0);
|
let y = bigInt(0);
|
||||||
for (let i=0; i<32; i++) {
|
for (let i = 0; i < 32; i++) {
|
||||||
y = y.shl(8);
|
y = y.shl(8);
|
||||||
y = y.add(bigInt(h[i]));
|
y = y.add(bigInt(h[i]));
|
||||||
}
|
}
|
||||||
@ -28,9 +28,7 @@ function getPoint(S) {
|
|||||||
|
|
||||||
const y2 = F.square(y);
|
const y2 = F.square(y);
|
||||||
|
|
||||||
let x = F.sqrt(F.div(
|
let x = F.sqrt(F.div(F.sub(F.one, y2), F.sub(a, F.mul(d, y2))));
|
||||||
F.sub(F.one, y2),
|
|
||||||
F.sub(a, F.mul(d, y2))));
|
|
||||||
|
|
||||||
if (x == null) return null;
|
if (x == null) return null;
|
||||||
|
|
||||||
@ -43,41 +41,34 @@ function getPoint(S) {
|
|||||||
return p8;
|
return p8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function generatePoint(S) {
|
function generatePoint(S) {
|
||||||
let p= null;
|
let p = null;
|
||||||
let idx = 0;
|
let idx = 0;
|
||||||
while (p==null) {
|
while (p == null) {
|
||||||
let sidx = "" + idx;
|
let sidx = "" + idx;
|
||||||
while (sidx.length<16) sidx = "0"+sidx;
|
while (sidx.length < 16) sidx = "0" + sidx;
|
||||||
p = getPoint(S+"_"+sidx);
|
p = getPoint(S + "_" + sidx);
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
if (!babyJub.inCurve(p)){
|
if (!babyJub.inCurve(p)) {
|
||||||
throw new Error("Point not in curve");
|
throw new Error("Point not in curve");
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const g = [
|
const g = [
|
||||||
bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
||||||
bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")];
|
bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203"),
|
||||||
|
];
|
||||||
|
|
||||||
// Sanity check
|
// Sanity check
|
||||||
if (!babyJub.inCurve(g)) {
|
if (!babyJub.inCurve(g)) {
|
||||||
throw new Error("Generator not In curve -> Some thing goes wrong...");
|
throw new Error("Generator not In curve -> Some thing goes wrong...");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i=0; i<25; i++) {
|
for (let i = 0; i < 25; i++) {
|
||||||
let S = "" +i;
|
let S = "" + i;
|
||||||
while (S.length<16) S = "0"+S;
|
while (S.length < 16) S = "0" + S;
|
||||||
const P = generatePoint("Iden3_PedersenGenerator_"+S);
|
const P = generatePoint("Iden3_PedersenGenerator_" + S);
|
||||||
console.log(`[${P[0].toString()}, ${P[1].toString()}]`);
|
console.log(`[${P[0].toString()}, ${P[1].toString()}]`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -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)`
|
||||||
|
|
||||||
@ -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)`
|
||||||
|
|
||||||
@ -780,7 +780,7 @@ Implementation of Poseidon hash function (LINK)
|
|||||||
- BENCHMARKS
|
- BENCHMARKS
|
||||||
- EXAMPLE
|
- EXAMPLE
|
||||||
|
|
||||||
- `Ark(t, C)`
|
- `Ark(t, C, r)`
|
||||||
|
|
||||||
- DESCRIPTION
|
- DESCRIPTION
|
||||||
- SCHEMA
|
- SCHEMA
|
||||||
@ -798,7 +798,7 @@ Implementation of Poseidon hash function (LINK)
|
|||||||
- BENCHMARKS
|
- BENCHMARKS
|
||||||
- EXAMPLE
|
- EXAMPLE
|
||||||
|
|
||||||
- `Poseidon(nInputs, t, nRoundsF, nRoundsP)`
|
- `Poseidon(nInputs)`
|
||||||
|
|
||||||
- DESCRIPTION
|
- DESCRIPTION
|
||||||
- SCHEMA
|
- SCHEMA
|
||||||
|
@ -87,7 +87,7 @@ template BabyPbk() {
|
|||||||
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
|
||||||
|
@ -72,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;
|
||||||
|
@ -26,10 +26,12 @@ template Num2Bits(n) {
|
|||||||
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;
|
||||||
@ -54,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;
|
||||||
|
@ -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;
|
||||||
|
@ -122,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
|
||||||
];
|
];
|
||||||
|
@ -100,7 +100,7 @@ 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
|
||||||
];
|
];
|
||||||
|
@ -100,7 +100,7 @@ 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
|
||||||
];
|
];
|
||||||
|
@ -51,7 +51,7 @@ template EdDSAPoseidonVerifier() {
|
|||||||
|
|
||||||
// Calculate the h = H(R,A, msg)
|
// Calculate the h = H(R,A, msg)
|
||||||
|
|
||||||
component hash = Poseidon(5, 6, 8, 57);
|
component hash = Poseidon(5);
|
||||||
|
|
||||||
hash.inputs[0] <== R8x;
|
hash.inputs[0] <== R8x;
|
||||||
hash.inputs[1] <== R8y;
|
hash.inputs[1] <== R8y;
|
||||||
@ -99,7 +99,7 @@ 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
|
||||||
];
|
];
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -176,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];
|
||||||
@ -185,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++) {
|
||||||
|
@ -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,
|
||||||
|
@ -6,10 +6,12 @@ template MiMCSponge(nInputs, nRounds, nOutputs) {
|
|||||||
signal input k;
|
signal input k;
|
||||||
signal output outs[nOutputs];
|
signal output outs[nOutputs];
|
||||||
|
|
||||||
|
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) {
|
||||||
@ -23,7 +25,7 @@ template MiMCSponge(nInputs, nRounds, 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;
|
||||||
@ -40,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,
|
||||||
|
@ -128,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];
|
||||||
@ -153,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();
|
||||||
@ -176,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],
|
||||||
@ -187,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
include "./poseidon_constants.circom";
|
||||||
|
|
||||||
template Sigma() {
|
template Sigma() {
|
||||||
signal input in;
|
signal input in;
|
||||||
@ -12,163 +13,51 @@ template Sigma() {
|
|||||||
out <== in4*in;
|
out <== in4*in;
|
||||||
}
|
}
|
||||||
|
|
||||||
template Ark(t, C) {
|
template Ark(t, C, r) {
|
||||||
signal input in[t];
|
signal input in[t];
|
||||||
signal output out[t];
|
signal output out[t];
|
||||||
|
|
||||||
for (var i=0; i<t; i++) {
|
for (var i=0; i<t; i++) {
|
||||||
out[i] <== in[i] + C;
|
out[i] <== in[i] + C[i + r];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template Mix(t, M) {
|
template Mix(t, M) {
|
||||||
signal input in[t];
|
signal input in[t];
|
||||||
signal output out[t];
|
signal output out[t];
|
||||||
var lc;
|
|
||||||
|
|
||||||
|
var lc;
|
||||||
for (var i=0; i<t; i++) {
|
for (var i=0; i<t; i++) {
|
||||||
lc = 0;
|
lc = 0;
|
||||||
for (var j=0; j<t; j++) {
|
for (var j=0; j<t; j++) {
|
||||||
lc = lc + M[i][j]*in[j];
|
lc += M[j][i]*in[j];
|
||||||
}
|
}
|
||||||
out[i] <== lc;
|
out[i] <== lc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// var nRoundsF = 8;
|
template Poseidon(nInputs) {
|
||||||
// var nRoundsP = 57;
|
|
||||||
// var t = 6;
|
|
||||||
|
|
||||||
template Poseidon(nInputs, t, nRoundsF, nRoundsP) {
|
|
||||||
|
|
||||||
var C = [
|
|
||||||
14397397413755236225575615486459253198602422701513067526754101844196324375522,
|
|
||||||
10405129301473404666785234951972711717481302463898292859783056520670200613128,
|
|
||||||
5179144822360023508491245509308555580251733042407187134628755730783052214509,
|
|
||||||
9132640374240188374542843306219594180154739721841249568925550236430986592615,
|
|
||||||
20360807315276763881209958738450444293273549928693737723235350358403012458514,
|
|
||||||
17933600965499023212689924809448543050840131883187652471064418452962948061619,
|
|
||||||
3636213416533737411392076250708419981662897009810345015164671602334517041153,
|
|
||||||
2008540005368330234524962342006691994500273283000229509835662097352946198608,
|
|
||||||
16018407964853379535338740313053768402596521780991140819786560130595652651567,
|
|
||||||
20653139667070586705378398435856186172195806027708437373983929336015162186471,
|
|
||||||
17887713874711369695406927657694993484804203950786446055999405564652412116765,
|
|
||||||
4852706232225925756777361208698488277369799648067343227630786518486608711772,
|
|
||||||
8969172011633935669771678412400911310465619639756845342775631896478908389850,
|
|
||||||
20570199545627577691240476121888846460936245025392381957866134167601058684375,
|
|
||||||
16442329894745639881165035015179028112772410105963688121820543219662832524136,
|
|
||||||
20060625627350485876280451423010593928172611031611836167979515653463693899374,
|
|
||||||
16637282689940520290130302519163090147511023430395200895953984829546679599107,
|
|
||||||
15599196921909732993082127725908821049411366914683565306060493533569088698214,
|
|
||||||
16894591341213863947423904025624185991098788054337051624251730868231322135455,
|
|
||||||
1197934381747032348421303489683932612752526046745577259575778515005162320212,
|
|
||||||
6172482022646932735745595886795230725225293469762393889050804649558459236626,
|
|
||||||
21004037394166516054140386756510609698837211370585899203851827276330669555417,
|
|
||||||
15262034989144652068456967541137853724140836132717012646544737680069032573006,
|
|
||||||
15017690682054366744270630371095785995296470601172793770224691982518041139766,
|
|
||||||
15159744167842240513848638419303545693472533086570469712794583342699782519832,
|
|
||||||
11178069035565459212220861899558526502477231302924961773582350246646450941231,
|
|
||||||
21154888769130549957415912997229564077486639529994598560737238811887296922114,
|
|
||||||
20162517328110570500010831422938033120419484532231241180224283481905744633719,
|
|
||||||
2777362604871784250419758188173029886707024739806641263170345377816177052018,
|
|
||||||
15732290486829619144634131656503993123618032247178179298922551820261215487562,
|
|
||||||
6024433414579583476444635447152826813568595303270846875177844482142230009826,
|
|
||||||
17677827682004946431939402157761289497221048154630238117709539216286149983245,
|
|
||||||
10716307389353583413755237303156291454109852751296156900963208377067748518748,
|
|
||||||
14925386988604173087143546225719076187055229908444910452781922028996524347508,
|
|
||||||
8940878636401797005293482068100797531020505636124892198091491586778667442523,
|
|
||||||
18911747154199663060505302806894425160044925686870165583944475880789706164410,
|
|
||||||
8821532432394939099312235292271438180996556457308429936910969094255825456935,
|
|
||||||
20632576502437623790366878538516326728436616723089049415538037018093616927643,
|
|
||||||
71447649211767888770311304010816315780740050029903404046389165015534756512,
|
|
||||||
2781996465394730190470582631099299305677291329609718650018200531245670229393,
|
|
||||||
12441376330954323535872906380510501637773629931719508864016287320488688345525,
|
|
||||||
2558302139544901035700544058046419714227464650146159803703499681139469546006,
|
|
||||||
10087036781939179132584550273563255199577525914374285705149349445480649057058,
|
|
||||||
4267692623754666261749551533667592242661271409704769363166965280715887854739,
|
|
||||||
4945579503584457514844595640661884835097077318604083061152997449742124905548,
|
|
||||||
17742335354489274412669987990603079185096280484072783973732137326144230832311,
|
|
||||||
6266270088302506215402996795500854910256503071464802875821837403486057988208,
|
|
||||||
2716062168542520412498610856550519519760063668165561277991771577403400784706,
|
|
||||||
19118392018538203167410421493487769944462015419023083813301166096764262134232,
|
|
||||||
9386595745626044000666050847309903206827901310677406022353307960932745699524,
|
|
||||||
9121640807890366356465620448383131419933298563527245687958865317869840082266,
|
|
||||||
3078975275808111706229899605611544294904276390490742680006005661017864583210,
|
|
||||||
7157404299437167354719786626667769956233708887934477609633504801472827442743,
|
|
||||||
14056248655941725362944552761799461694550787028230120190862133165195793034373,
|
|
||||||
14124396743304355958915937804966111851843703158171757752158388556919187839849,
|
|
||||||
11851254356749068692552943732920045260402277343008629727465773766468466181076,
|
|
||||||
9799099446406796696742256539758943483211846559715874347178722060519817626047,
|
|
||||||
10156146186214948683880719664738535455146137901666656566575307300522957959544,
|
|
||||||
19908645952733301583346063785055921934459499091029406575311417879963332475861,
|
|
||||||
11766105336238068471342414351862472329437473380853789942065610694000443387471,
|
|
||||||
11002137593249972174092192767251572171769044073555430468487809799220351297047,
|
|
||||||
284136377911685911941431040940403846843630064858778505937392780738953624163,
|
|
||||||
19448733709802908339787967270452055364068697565906862913410983275341804035680,
|
|
||||||
14423660424692802524250720264041003098290275890428483723270346403986712981505,
|
|
||||||
10635360132728137321700090133109897687122647659471659996419791842933639708516
|
|
||||||
];
|
|
||||||
|
|
||||||
var M = [
|
|
||||||
[
|
|
||||||
19167410339349846567561662441069598364702008768579734801591448511131028229281,
|
|
||||||
14183033936038168803360723133013092560869148726790180682363054735190196956789,
|
|
||||||
9067734253445064890734144122526450279189023719890032859456830213166173619761,
|
|
||||||
16378664841697311562845443097199265623838619398287411428110917414833007677155,
|
|
||||||
12968540216479938138647596899147650021419273189336843725176422194136033835172,
|
|
||||||
3636162562566338420490575570584278737093584021456168183289112789616069756675
|
|
||||||
],[
|
|
||||||
17034139127218860091985397764514160131253018178110701196935786874261236172431,
|
|
||||||
2799255644797227968811798608332314218966179365168250111693473252876996230317,
|
|
||||||
2482058150180648511543788012634934806465808146786082148795902594096349483974,
|
|
||||||
16563522740626180338295201738437974404892092704059676533096069531044355099628,
|
|
||||||
10468644849657689537028565510142839489302836569811003546969773105463051947124,
|
|
||||||
3328913364598498171733622353010907641674136720305714432354138807013088636408
|
|
||||||
],[
|
|
||||||
18985203040268814769637347880759846911264240088034262814847924884273017355969,
|
|
||||||
8652975463545710606098548415650457376967119951977109072274595329619335974180,
|
|
||||||
970943815872417895015626519859542525373809485973005165410533315057253476903,
|
|
||||||
19406667490568134101658669326517700199745817783746545889094238643063688871948,
|
|
||||||
17049854690034965250221386317058877242629221002521630573756355118745574274967,
|
|
||||||
4964394613021008685803675656098849539153699842663541444414978877928878266244
|
|
||||||
],[
|
|
||||||
19025623051770008118343718096455821045904242602531062247152770448380880817517,
|
|
||||||
9077319817220936628089890431129759976815127354480867310384708941479362824016,
|
|
||||||
4770370314098695913091200576539533727214143013236894216582648993741910829490,
|
|
||||||
4298564056297802123194408918029088169104276109138370115401819933600955259473,
|
|
||||||
6905514380186323693285869145872115273350947784558995755916362330070690839131,
|
|
||||||
4783343257810358393326889022942241108539824540285247795235499223017138301952
|
|
||||||
],[
|
|
||||||
16205238342129310687768799056463408647672389183328001070715567975181364448609,
|
|
||||||
8303849270045876854140023508764676765932043944545416856530551331270859502246,
|
|
||||||
20218246699596954048529384569730026273241102596326201163062133863539137060414,
|
|
||||||
1712845821388089905746651754894206522004527237615042226559791118162382909269,
|
|
||||||
13001155522144542028910638547179410124467185319212645031214919884423841839406,
|
|
||||||
16037892369576300958623292723740289861626299352695838577330319504984091062115
|
|
||||||
],[
|
|
||||||
15162889384227198851506890526431746552868519326873025085114621698588781611738,
|
|
||||||
13272957914179340594010910867091459756043436017766464331915862093201960540910,
|
|
||||||
9416416589114508529880440146952102328470363729880726115521103179442988482948,
|
|
||||||
8035240799672199706102747147502951589635001418759394863664434079699838251138,
|
|
||||||
21642389080762222565487157652540372010968704000567605990102641816691459811717,
|
|
||||||
20261355950827657195644012399234591122288573679402601053407151083849785332516
|
|
||||||
]
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
signal input inputs[nInputs];
|
signal input inputs[nInputs];
|
||||||
signal output out;
|
signal output out;
|
||||||
|
|
||||||
component ark[nRoundsF + nRoundsP];
|
// Using recommended parameters from whitepaper https://eprint.iacr.org/2019/458.pdf (table 2, table 8)
|
||||||
component sigmaF[nRoundsF][t];
|
// 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
|
||||||
|
var t = nInputs + 1;
|
||||||
|
var nRoundsF = 8;
|
||||||
|
var nRoundsP = 35;
|
||||||
|
var C[t*(nRoundsF + nRoundsP)] = POSEIDON_C(t);
|
||||||
|
var M[t][t] = POSEIDON_M(t);
|
||||||
|
|
||||||
|
component ark[nRoundsF + nRoundsP - 1];
|
||||||
|
component sigmaF[nRoundsF - 1][t];
|
||||||
component sigmaP[nRoundsP];
|
component sigmaP[nRoundsP];
|
||||||
component mix[nRoundsF + nRoundsP];
|
component mix[nRoundsF + nRoundsP - 1];
|
||||||
|
|
||||||
var k;
|
var k;
|
||||||
|
|
||||||
for (var i=0; i<(nRoundsF + nRoundsP); i++) {
|
for (var i=0; i<nRoundsF + nRoundsP - 1; i++) {
|
||||||
ark[i] = Ark(t, C[i]);
|
ark[i] = Ark(t, C, t*i);
|
||||||
mix[i] = Mix(t, M);
|
|
||||||
|
|
||||||
for (var j=0; j<t; j++) {
|
for (var j=0; j<t; j++) {
|
||||||
if (i==0) {
|
if (i==0) {
|
||||||
if (j<nInputs) {
|
if (j<nInputs) {
|
||||||
@ -181,15 +70,17 @@ template Poseidon(nInputs, t, nRoundsF, nRoundsP) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((i<(nRoundsF/2)) || (i>= (nRoundsP + nRoundsF/2))) {
|
if (i < nRoundsF/2 || i >= nRoundsP + nRoundsF/2) {
|
||||||
k= i<nRoundsF/2 ? i : (i-nRoundsP);
|
k = i < nRoundsF/2 ? i : i - nRoundsP;
|
||||||
|
mix[i] = Mix(t, M);
|
||||||
for (var j=0; j<t; j++) {
|
for (var j=0; j<t; j++) {
|
||||||
sigmaF[k][j] = Sigma();
|
sigmaF[k][j] = Sigma();
|
||||||
sigmaF[k][j].in <== ark[i].out[j];
|
sigmaF[k][j].in <== ark[i].out[j];
|
||||||
mix[i].in[j] <== sigmaF[k][j].out;
|
mix[i].in[j] <== sigmaF[k][j].out;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
k= i-nRoundsF/2;
|
k = i - nRoundsF/2;
|
||||||
|
mix[i] = Mix(t, M);
|
||||||
sigmaP[k] = Sigma();
|
sigmaP[k] = Sigma();
|
||||||
sigmaP[k].in <== ark[i].out[0];
|
sigmaP[k].in <== ark[i].out[0];
|
||||||
mix[i].in[0] <== sigmaP[k].out;
|
mix[i].in[0] <== sigmaP[k].out;
|
||||||
@ -199,5 +90,8 @@ template Poseidon(nInputs, t, nRoundsF, nRoundsP) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out <== mix[nRoundsF + nRoundsP -1].out[0];
|
// last round is done only for the first word, so we do it manually to save constraints
|
||||||
|
component lastSigmaF = Sigma();
|
||||||
|
lastSigmaF.in <== mix[nRoundsF + nRoundsP - 2].out[0] + C[t*(nRoundsF + nRoundsP - 1)];
|
||||||
|
out <== lastSigmaF.out;
|
||||||
}
|
}
|
||||||
|
44
circuits/poseidon_constants.circom
Normal file
44
circuits/poseidon_constants.circom
Normal file
File diff suppressed because one or more lines are too long
@ -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];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ template SMTHash1() {
|
|||||||
signal input value;
|
signal input value;
|
||||||
signal output out;
|
signal output out;
|
||||||
|
|
||||||
component h = Poseidon(3, 6, 8, 57); // Constant
|
component h = Poseidon(3); // Constant
|
||||||
h.inputs[0] <== key;
|
h.inputs[0] <== key;
|
||||||
h.inputs[1] <== value;
|
h.inputs[1] <== value;
|
||||||
h.inputs[2] <== 1;
|
h.inputs[2] <== 1;
|
||||||
@ -48,7 +48,7 @@ template SMTHash2() {
|
|||||||
signal input R;
|
signal input R;
|
||||||
signal output out;
|
signal output out;
|
||||||
|
|
||||||
component h = Poseidon(2, 6, 8, 57); // Constant
|
component h = Poseidon(2); // Constant
|
||||||
h.inputs[0] <== L;
|
h.inputs[0] <== L;
|
||||||
h.inputs[1] <== R;
|
h.inputs[1] <== R;
|
||||||
|
|
||||||
|
@ -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");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
21296
package-lock.json
generated
21296
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
74
package.json
74
package.json
@ -1,39 +1,39 @@
|
|||||||
{
|
{
|
||||||
"name": "circomlib",
|
"name": "@tornado/circomlib",
|
||||||
"version": "0.0.20",
|
"version": "0.4.1",
|
||||||
"description": "Basic circuits library for Circom",
|
"description": "Basic circuits library for Circom",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"directories": {
|
"directories": {
|
||||||
"test": "test"
|
"test": "test"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "mocha --max-old-space-size=4000"
|
"test": "mocha --max-old-space-size=4000"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"pedersen",
|
"pedersen",
|
||||||
"hash",
|
"hash",
|
||||||
"ethereum",
|
"ethereum",
|
||||||
"circuit",
|
"circuit",
|
||||||
"circom",
|
"circom",
|
||||||
"zksnark"
|
"zksnark"
|
||||||
],
|
],
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/iden3/circomlib.git"
|
"url": "https://git.tornado.is/tornado-packages/circomlib.git"
|
||||||
},
|
},
|
||||||
"author": "0Kims",
|
"author": "0Kims",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"blake-hash": "^1.1.0",
|
"@tornado/snarkjs": "0.1.20",
|
||||||
"blake2b": "^2.1.3",
|
"blake-hash": "^1.1.0",
|
||||||
"snarkjs": "^0.1.20",
|
"blake2b": "^2.1.3",
|
||||||
"typedarray-to-buffer": "^3.1.5",
|
"circom": "0.5.33",
|
||||||
"web3": "^1.0.0-beta.55"
|
"ffjavascript": "0.1.0"
|
||||||
},
|
},
|
||||||
"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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
const bn128 = require("snarkjs").bn128;
|
const F1Field = require("ffjavascript").F1Field;
|
||||||
const bigInt = require("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,23 +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) {
|
function addPoint(a,b) {
|
||||||
const q = bn128.r;
|
|
||||||
|
|
||||||
const res = [];
|
const res = [];
|
||||||
|
|
||||||
@ -31,23 +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]).mul(b[1]).add(bigInt(b[0]).mul(a[1]))).mul(bigInt(bigInt("1").add(exports.D.mul(a[0]).mul(b[0]).mul(a[1]).mul(b[1]))).inverse(q))).affine(q);
|
|
||||||
res[1] = bigInt((bigInt(a[1]).mul(b[1]).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))).affine(q);
|
const beta = F.mul(a[0],b[1]);
|
||||||
|
const gamma = F.mul(a[1],b[0]);
|
||||||
|
const delta = F.mul(
|
||||||
|
F.sub(a[1], F.mul(exports.A, a[0])),
|
||||||
|
F.add(b[0], b[1])
|
||||||
|
);
|
||||||
|
const tau = F.mul(beta, gamma);
|
||||||
|
const dtau = F.mul(exports.D, tau);
|
||||||
|
|
||||||
|
res[0] = F.div(
|
||||||
|
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;
|
||||||
@ -56,16 +78,15 @@ 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(
|
if (!F.eq(
|
||||||
F.add(F.mul(exports.A, x2), y2),
|
F.add(F.mul(exports.A, x2), y2),
|
||||||
F.add(F.one, F.mul(F.mul(x2, y2), exports.D)))) return false;
|
F.add(F.one, F.mul(F.mul(x2, y2), exports.D)))) return false;
|
||||||
|
|
||||||
@ -73,16 +94,14 @@ function inCurve(P) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
@ -90,8 +109,8 @@ function unpackPoint(_buff) {
|
|||||||
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]);
|
||||||
|
|
||||||
@ -103,7 +122,7 @@ function unpackPoint(_buff) {
|
|||||||
|
|
||||||
if (sign) x = F.neg(x);
|
if (sign) x = F.neg(x);
|
||||||
|
|
||||||
P[0] = F.affine(x);
|
P[0] = x;
|
||||||
|
|
||||||
return P;
|
return P;
|
||||||
}
|
}
|
||||||
|
97
src/eddsa.js
97
src/eddsa.js
@ -1,11 +1,14 @@
|
|||||||
const createBlakeHash = require("blake-hash");
|
const createBlakeHash = require("blake-hash");
|
||||||
const bigInt = require("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;
|
||||||
@ -30,26 +33,27 @@ function pruneBuffer(_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").update(Buffer.concat([h1.slice(32,64), msg])).digest();
|
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msg])).digest();
|
||||||
let r = bigInt.leBuff2int(rBuff);
|
let r = utils.leBuff2int(rBuff);
|
||||||
r = r.mod(babyJub.subOrder);
|
const Fr = new F1Field(babyJub.subOrder);
|
||||||
|
r = Fr.e(r);
|
||||||
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
|
||||||
@ -59,16 +63,17 @@ function sign(prv, msg) {
|
|||||||
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").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
|
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
|
||||||
let r = bigInt.leBuff2int(rBuff);
|
let r = utils.leBuff2int(rBuff);
|
||||||
r = r.mod(babyJub.subOrder);
|
const Fr = new F1Field(babyJub.subOrder);
|
||||||
|
r = Fr.e(r);
|
||||||
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
|
||||||
@ -78,16 +83,17 @@ function signMiMC(prv, msg) {
|
|||||||
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").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
|
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
|
||||||
let r = bigInt.leBuff2int(rBuff);
|
let r = utils.leBuff2int(rBuff);
|
||||||
r = r.mod(babyJub.subOrder);
|
const Fr = new F1Field(babyJub.subOrder);
|
||||||
|
r = Fr.e(r);
|
||||||
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
|
||||||
@ -97,17 +103,17 @@ function signMiMCSponge(prv, msg) {
|
|||||||
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").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
|
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
|
||||||
let r = bigInt.leBuff2int(rBuff);
|
let r = utils.leBuff2int(rBuff);
|
||||||
r = r.mod(babyJub.subOrder);
|
const Fr = new F1Field(babyJub.subOrder);
|
||||||
|
r = Fr.e(r);
|
||||||
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
|
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
|
||||||
const hash = poseidon.createHash(6, 8, 57);
|
const hm = poseidon([R8[0], R8[1], A[0], A[1], msg]);
|
||||||
const hm = hash([R8[0], R8[1], A[0], A[1], msg]);
|
const S = Fr.add(r , Fr.mul(hm, s));
|
||||||
const S = r.add(hm.mul(s)).mod(babyJub.subOrder);
|
|
||||||
return {
|
return {
|
||||||
R8: R8,
|
R8: R8,
|
||||||
S: S
|
S: S
|
||||||
@ -128,14 +134,14 @@ function verify(msg, sig, A) {
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,11 +159,11 @@ function verifyMiMC(msg, sig, A) {
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,15 +179,14 @@ function verifyPoseidon(msg, sig, A) {
|
|||||||
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 hash = poseidon.createHash(6, 8, 57);
|
const hm = poseidon([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
|
||||||
const hm = hash([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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,24 +204,24 @@ function verifyMiMCSponge(msg, sig, A) {
|
|||||||
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))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,6 +154,17 @@ class Contract {
|
|||||||
}
|
}
|
||||||
|
|
||||||
push(data) {
|
push(data) {
|
||||||
|
if (typeof data === "number") {
|
||||||
|
let isNeg;
|
||||||
|
if (data<0) {
|
||||||
|
isNeg = true;
|
||||||
|
data = -data;
|
||||||
|
}
|
||||||
|
data = data.toString(16);
|
||||||
|
if (data.length % 2 == 1) data = "0" + data;
|
||||||
|
data = "0x" + data;
|
||||||
|
if (isNeg) data = "-"+data;
|
||||||
|
}
|
||||||
const d = Web3Utils.hexToBytes(Web3Utils.toHex(data));
|
const d = Web3Utils.hexToBytes(Web3Utils.toHex(data));
|
||||||
if (d.length == 0 || d.length > 32) {
|
if (d.length == 0 || d.length > 32) {
|
||||||
throw new Error("Assertion failed");
|
throw new Error("Assertion failed");
|
||||||
|
@ -3,24 +3,21 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
const Contract = require("./evmasm");
|
const Contract = require("./evmasm");
|
||||||
const G2 = require("snarkjs").bn128.G2;
|
const G2 = require("@tornado/snarkjs").bn128.G2;
|
||||||
const bigInt = require("snarkjs").bigInt;
|
|
||||||
|
|
||||||
|
|
||||||
function toHex256(a) {
|
function toHex256(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(P, w) {
|
function createCode(P, w) {
|
||||||
|
|
||||||
const C = new Contract();
|
const C = new Contract();
|
||||||
|
|
||||||
const NPOINTS = 1 << (w-1);
|
const NPOINTS = 1 << (w - 1);
|
||||||
|
|
||||||
const VAR_POS = C.allocMem(32);
|
const VAR_POS = C.allocMem(32);
|
||||||
const VAR_POINTS = C.allocMem( (NPOINTS)*4*32);
|
const VAR_POINTS = C.allocMem(NPOINTS * 4 * 32);
|
||||||
const savedP = C.allocMem(32);
|
const savedP = C.allocMem(32);
|
||||||
const savedZ3 = C.allocMem(32);
|
const savedZ3 = C.allocMem(32);
|
||||||
|
|
||||||
@ -38,7 +35,7 @@ function createCode(P, w) {
|
|||||||
|
|
||||||
storeVals();
|
storeVals();
|
||||||
|
|
||||||
C.push( Math.floor(255/w)*w ); // pos := 255
|
C.push(Math.floor(255 / w) * w); // pos := 255
|
||||||
C.push(VAR_POS);
|
C.push(VAR_POS);
|
||||||
C.mstore();
|
C.mstore();
|
||||||
|
|
||||||
@ -50,38 +47,38 @@ function createCode(P, w) {
|
|||||||
C.push(0);
|
C.push(0);
|
||||||
C.push(0);
|
C.push(0);
|
||||||
|
|
||||||
C.label("begin_loop"); // ACC_X ACC_Y ACC_Z q
|
C.label("begin_loop"); // ACC_X ACC_Y ACC_Z q
|
||||||
|
|
||||||
C.internalCall("double");
|
C.internalCall("double");
|
||||||
|
|
||||||
// g = (e>>pos)&MASK
|
// g = (e>>pos)&MASK
|
||||||
C.push(4);
|
C.push(4);
|
||||||
C.calldataload(); // e ACC_X ACC_Y ACC_Z q
|
C.calldataload(); // e ACC_X ACC_Y ACC_Z q
|
||||||
|
|
||||||
C.push(VAR_POS);
|
C.push(VAR_POS);
|
||||||
C.mload(); // pos e ACC_X ACC_Y ACC_Z q
|
C.mload(); // pos e ACC_X ACC_Y ACC_Z q
|
||||||
C.shr();
|
C.shr();
|
||||||
|
|
||||||
C.push(NPOINTS-1);
|
C.push(NPOINTS - 1);
|
||||||
C.and(); // g ACC_X ACC_Y ACC_Z q
|
C.and(); // g ACC_X ACC_Y ACC_Z q
|
||||||
|
|
||||||
C.internalCall("add"); // acc_x acc_y acc_z
|
C.internalCall("add"); // acc_x acc_y acc_z
|
||||||
|
|
||||||
C.push(VAR_POS);
|
C.push(VAR_POS);
|
||||||
C.mload(); // pos acc_x acc_y acc_z
|
C.mload(); // pos acc_x acc_y acc_z
|
||||||
C.dup(0); // pos pos acc_x acc_y acc_z
|
C.dup(0); // pos pos acc_x acc_y acc_z
|
||||||
C.push(0); // 0 pos pos acc_x acc_y acc_z
|
C.push(0); // 0 pos pos acc_x acc_y acc_z
|
||||||
C.eq(); // eq pos acc_x acc_y acc_z
|
C.eq(); // eq pos acc_x acc_y acc_z
|
||||||
C.jmpi("after_loop"); // pos acc_x acc_y acc_z
|
C.jmpi("after_loop"); // pos acc_x acc_y acc_z
|
||||||
C.push(w); // 5 pos acc_x acc_y acc_z
|
C.push(w); // 5 pos acc_x acc_y acc_z
|
||||||
C.sub(); // pos acc_x acc_y acc_z
|
C.sub(); // pos acc_x acc_y acc_z
|
||||||
C.push(VAR_POS);
|
C.push(VAR_POS);
|
||||||
C.mstore(); // acc_x acc_y acc_z
|
C.mstore(); // acc_x acc_y acc_z
|
||||||
C.jmp("begin_loop");
|
C.jmp("begin_loop");
|
||||||
C.label("after_loop"); // pos acc_x acc_y acc_z
|
C.label("after_loop"); // pos acc_x acc_y acc_z
|
||||||
C.pop(); // acc_x acc_y acc_z
|
C.pop(); // acc_x acc_y acc_z
|
||||||
|
|
||||||
C.internalCall("affine"); // acc_x acc_y
|
C.internalCall("affine"); // acc_x acc_y
|
||||||
|
|
||||||
C.push(0);
|
C.push(0);
|
||||||
C.mstore();
|
C.mstore();
|
||||||
@ -96,17 +93,16 @@ function createCode(P, w) {
|
|||||||
C.push("0x00");
|
C.push("0x00");
|
||||||
C.return();
|
C.return();
|
||||||
|
|
||||||
|
|
||||||
double();
|
double();
|
||||||
addPoint();
|
addPoint();
|
||||||
affine();
|
affine();
|
||||||
|
|
||||||
return C.createTxData();
|
return C.createTxData();
|
||||||
|
|
||||||
function add(a,b,q) {
|
function add(a, b, q) {
|
||||||
C.dup(q);
|
C.dup(q);
|
||||||
C.dup(a+1 + 1);
|
C.dup(a + 1 + 1);
|
||||||
C.dup(b+1 + 2);
|
C.dup(b + 1 + 2);
|
||||||
C.addmod();
|
C.addmod();
|
||||||
C.dup(q + 1);
|
C.dup(q + 1);
|
||||||
C.dup(a + 2);
|
C.dup(a + 2);
|
||||||
@ -114,73 +110,73 @@ function createCode(P, w) {
|
|||||||
C.addmod();
|
C.addmod();
|
||||||
}
|
}
|
||||||
|
|
||||||
function sub(a,b,q) {
|
function sub(a, b, q) {
|
||||||
C.dup(q); // q
|
C.dup(q); // q
|
||||||
C.dup(a+1 + 1); // ai q
|
C.dup(a + 1 + 1); // ai q
|
||||||
C.dub(q + 2); // q ai q
|
C.dub(q + 2); // q ai q
|
||||||
C.dup(b+1 + 3); // bi q ai q
|
C.dup(b + 1 + 3); // bi q ai q
|
||||||
C.sub(); // -bi ai q
|
C.sub(); // -bi ai q
|
||||||
C.addmod(); // ci
|
C.addmod(); // ci
|
||||||
C.dup(q + 1); // q ci
|
C.dup(q + 1); // q ci
|
||||||
C.dup(a + 2); // ar q ci
|
C.dup(a + 2); // ar q ci
|
||||||
C.dup(q + 3); // q ar q ci
|
C.dup(q + 3); // q ar q ci
|
||||||
C.dup(b + 4); // br q ar q ci
|
C.dup(b + 4); // br q ar q ci
|
||||||
C.sub(); // -br ar q ci
|
C.sub(); // -br ar q ci
|
||||||
C.addmod(); // cr ci
|
C.addmod(); // cr ci
|
||||||
}
|
}
|
||||||
|
|
||||||
function mul(a, b, q) {
|
function mul(a, b, q) {
|
||||||
C.dup(q); // q
|
C.dup(q); // q
|
||||||
C.dup(q + 1); // q q
|
C.dup(q + 1); // q q
|
||||||
C.dup(a + 2); // ar q q
|
C.dup(a + 2); // ar q q
|
||||||
C.dup(b+1 + 3); // bi ar q q
|
C.dup(b + 1 + 3); // bi ar q q
|
||||||
C.mulmod(); // ci1 q
|
C.mulmod(); // ci1 q
|
||||||
C.dup(q + 2); // q ci1 q
|
C.dup(q + 2); // q ci1 q
|
||||||
C.dup(a+1 + 3); // ai q ci1 q
|
C.dup(a + 1 + 3); // ai q ci1 q
|
||||||
C.dup(b + 4); // ar ai q ci1 q
|
C.dup(b + 4); // ar ai q ci1 q
|
||||||
C.mulmod(); // ci2 ci1 q
|
C.mulmod(); // ci2 ci1 q
|
||||||
C.addmod(); // ci
|
C.addmod(); // ci
|
||||||
C.dup(q + 1); // q ci
|
C.dup(q + 1); // q ci
|
||||||
C.dup(q + 2); // q q ci
|
C.dup(q + 2); // q q ci
|
||||||
C.dup(q + 3); // q q q ci
|
C.dup(q + 3); // q q q ci
|
||||||
C.dup(a+1 + 4); // ai q q ci
|
C.dup(a + 1 + 4); // ai q q ci
|
||||||
C.dup(b+1 + 5); // bi ai q q ci
|
C.dup(b + 1 + 5); // bi ai q q ci
|
||||||
C.mulmod(); // cr2 q q ci
|
C.mulmod(); // cr2 q q ci
|
||||||
C.sub(); // -cr2 q ci
|
C.sub(); // -cr2 q ci
|
||||||
C.dup(q + 3); // q -cr2 q ci
|
C.dup(q + 3); // q -cr2 q ci
|
||||||
C.dup(a + 4); // ar q -cr2 q ci
|
C.dup(a + 4); // ar q -cr2 q ci
|
||||||
C.dup(b + 5); // br ar q -cr2 q ci
|
C.dup(b + 5); // br ar q -cr2 q ci
|
||||||
C.mulmod(); // cr1 -cr2 q ci
|
C.mulmod(); // cr1 -cr2 q ci
|
||||||
C.addmod(); // cr ci
|
C.addmod(); // cr ci
|
||||||
}
|
}
|
||||||
|
|
||||||
function square(a, q) {
|
function square(a, q) {
|
||||||
C.dup(q); // q
|
C.dup(q); // q
|
||||||
C.dup(q + 1); // q q
|
C.dup(q + 1); // q q
|
||||||
C.dup(a + 2); // ar q q
|
C.dup(a + 2); // ar q q
|
||||||
C.dup(a+1 + 3); // ai ar q q
|
C.dup(a + 1 + 3); // ai ar q q
|
||||||
C.mulmod(); // arai q
|
C.mulmod(); // arai q
|
||||||
C.dup(0); // arai arai q
|
C.dup(0); // arai arai q
|
||||||
C.addmod(); // ci
|
C.addmod(); // ci
|
||||||
C.dup(q + 1); // q ci
|
C.dup(q + 1); // q ci
|
||||||
C.dup(q + 2); // q q ci
|
C.dup(q + 2); // q q ci
|
||||||
C.dup(q + 3); // q q q ci
|
C.dup(q + 3); // q q q ci
|
||||||
C.dup(a+1 + 4); // ai q q ci
|
C.dup(a + 1 + 4); // ai q q ci
|
||||||
C.dup(a+1 + 5); // ai ai q q ci
|
C.dup(a + 1 + 5); // ai ai q q ci
|
||||||
C.mulmod(); // cr2 q q ci
|
C.mulmod(); // cr2 q q ci
|
||||||
C.sub(); // -cr2 q ci
|
C.sub(); // -cr2 q ci
|
||||||
C.dup(q + 3); // q -cr2 q ci
|
C.dup(q + 3); // q -cr2 q ci
|
||||||
C.dup(a + 4); // ar q -cr2 q ci
|
C.dup(a + 4); // ar q -cr2 q ci
|
||||||
C.dup(a + 5); // br ar q -cr2 q ci
|
C.dup(a + 5); // br ar q -cr2 q ci
|
||||||
C.mulmod(); // cr1 -cr2 q ci
|
C.mulmod(); // cr1 -cr2 q ci
|
||||||
C.addmod(); // cr ci
|
C.addmod(); // cr ci
|
||||||
}
|
}
|
||||||
|
|
||||||
function add1(a, q) {
|
function add1(a, q) {
|
||||||
C.dup(a+1); // im
|
C.dup(a + 1); // im
|
||||||
C.dup(1 + q); // q
|
C.dup(1 + q); // q
|
||||||
C.dup(2 + a); // re q im
|
C.dup(2 + a); // re q im
|
||||||
C.push(1); // 1 re q im
|
C.push(1); // 1 re q im
|
||||||
C.addmod();
|
C.addmod();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,220 +184,212 @@ function createCode(P, w) {
|
|||||||
C.dup(a);
|
C.dup(a);
|
||||||
C.dup(b);
|
C.dup(b);
|
||||||
C.eq();
|
C.eq();
|
||||||
C.dup(a+1);
|
C.dup(a + 1);
|
||||||
C.dup(a+1);
|
C.dup(a + 1);
|
||||||
C.and();
|
C.and();
|
||||||
}
|
}
|
||||||
|
|
||||||
function rm(a) {
|
function rm(a) {
|
||||||
if (a>0) C.swap(a);
|
if (a > 0) C.swap(a);
|
||||||
C.pop();
|
C.pop();
|
||||||
if (a>0) C.swap(a);
|
if (a > 0) C.swap(a);
|
||||||
C.pop();
|
C.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
function double() {
|
function double() {
|
||||||
C.label("double"); // xR, xI, yR, yI, zR zI, q
|
C.label("double"); // xR, xI, yR, yI, zR zI, q
|
||||||
|
|
||||||
C.dup(4);
|
C.dup(4);
|
||||||
C.iszero();
|
C.iszero();
|
||||||
C.dup(6);
|
C.dup(6);
|
||||||
C.iszero();
|
C.iszero();
|
||||||
C.and();
|
C.and();
|
||||||
C.jumpi("enddouble"); // X Y Z q
|
C.jumpi("enddouble"); // X Y Z q
|
||||||
|
|
||||||
|
|
||||||
// Z3 = 2*Y*Z // Remove Z
|
// Z3 = 2*Y*Z // Remove Z
|
||||||
mul(2, 4, 6); // yz X Y Z q
|
mul(2, 4, 6); // yz X Y Z q
|
||||||
rm(6); // X Y yz q
|
rm(6); // X Y yz q
|
||||||
|
|
||||||
add(4, 4, 6); // 2yz X Y yz q
|
add(4, 4, 6); // 2yz X Y yz q
|
||||||
rm(6); // X Y Z3 q
|
rm(6); // X Y Z3 q
|
||||||
|
|
||||||
// A = X^2
|
// A = X^2
|
||||||
square(0,6); // A X Y Z3 q
|
square(0, 6); // A X Y Z3 q
|
||||||
|
|
||||||
// B = Y^2 // Remove Y
|
// B = Y^2 // Remove Y
|
||||||
square(4,8); // B A X Y Z3 q
|
square(4, 8); // B A X Y Z3 q
|
||||||
rm(6); // A X B Z3 q
|
rm(6); // A X B Z3 q
|
||||||
|
|
||||||
// C = B^2
|
// C = B^2
|
||||||
square(4,8); // C A X B Z3 q
|
square(4, 8); // C A X B Z3 q
|
||||||
|
|
||||||
// D = (X+B)^2-A-C // Remove X, Remove B
|
// D = (X+B)^2-A-C // Remove X, Remove B
|
||||||
add(4,6, 10); // X+B C A X B Z3 q
|
add(4, 6, 10); // X+B C A X B Z3 q
|
||||||
rm(6); // C A X+B B Z3 q
|
rm(6); // C A X+B B Z3 q
|
||||||
rm(6); // A X+B C Z3 q
|
rm(6); // A X+B C Z3 q
|
||||||
square(2,8); // (X+B)^2 A X+B C Z3 q
|
square(2, 8); // (X+B)^2 A X+B C Z3 q
|
||||||
rm(4); // A (X+B)^2 C Z3 q
|
rm(4); // A (X+B)^2 C Z3 q
|
||||||
sub(2, 0, 8); // (X+B)^2-A A (X+B)^2 C Z3 q
|
sub(2, 0, 8); // (X+B)^2-A A (X+B)^2 C Z3 q
|
||||||
rm(4); // A (X+B)^2-A C Z3 q
|
rm(4); // A (X+B)^2-A C Z3 q
|
||||||
sub(2, 4, 8); // (X+B)^2-A-C A (X+B)^2-A C Z3 q
|
sub(2, 4, 8); // (X+B)^2-A-C A (X+B)^2-A C Z3 q
|
||||||
rm(4); // A D C Z3 q
|
rm(4); // A D C Z3 q
|
||||||
|
|
||||||
// D = D+D
|
// D = D+D
|
||||||
add(2,2, 8); // D+D A D C Z3 q
|
add(2, 2, 8); // D+D A D C Z3 q
|
||||||
rm(4); // A D C Z3 q
|
rm(4); // A D C Z3 q
|
||||||
|
|
||||||
// E=A+A+A
|
// E=A+A+A
|
||||||
add(0, 0, 8); // 2A A D C Z3 q
|
add(0, 0, 8); // 2A A D C Z3 q
|
||||||
add(0, 2, 10); // 3A 2A A D C Z3 q
|
add(0, 2, 10); // 3A 2A A D C Z3 q
|
||||||
rm(4); // 2A 3A D C Z3 q
|
rm(4); // 2A 3A D C Z3 q
|
||||||
rm(0); // E D C Z3 q
|
rm(0); // E D C Z3 q
|
||||||
|
|
||||||
// F=E^2
|
// F=E^2
|
||||||
square(0, 8); // F E D C Z3 q
|
square(0, 8); // F E D C Z3 q
|
||||||
|
|
||||||
// X3= F - 2*D // Remove F
|
// X3= F - 2*D // Remove F
|
||||||
add(4, 4, 10); // 2D F E D C Z3 q
|
add(4, 4, 10); // 2D F E D C Z3 q
|
||||||
sub(2, 0, 12); // F-2D 2D F E D C Z3 q
|
sub(2, 0, 12); // F-2D 2D F E D C Z3 q
|
||||||
rm(4); // 2D X3 E D C Z3 q
|
rm(4); // 2D X3 E D C Z3 q
|
||||||
rm(0); // X3 E D C Z3 q
|
rm(0); // X3 E D C Z3 q
|
||||||
|
|
||||||
// Y3 = E * (D - X3) - 8 * C // Remove D C E
|
// Y3 = E * (D - X3) - 8 * C // Remove D C E
|
||||||
|
|
||||||
sub(4, 0, 10); // D-X3 X3 E D C Z3 q
|
sub(4, 0, 10); // D-X3 X3 E D C Z3 q
|
||||||
rm(6); // X3 E D-X3 C Z3 q
|
rm(6); // X3 E D-X3 C Z3 q
|
||||||
mul(2, 4, 10); // E*(D-X3) X3 E D-X3 C Z3 q
|
mul(2, 4, 10); // E*(D-X3) X3 E D-X3 C Z3 q
|
||||||
rm(6); // X3 E E*(D-X3) C Z3 q
|
rm(6); // X3 E E*(D-X3) C Z3 q
|
||||||
rm(2); // X3 E*(D-X3) C Z3 q
|
rm(2); // X3 E*(D-X3) C Z3 q
|
||||||
add(4, 4, 8); // 2C X3 E*(D-X3) C Z3 q
|
add(4, 4, 8); // 2C X3 E*(D-X3) C Z3 q
|
||||||
rm(6); // X3 E*(D-X3) 2C Z3 q
|
rm(6); // X3 E*(D-X3) 2C Z3 q
|
||||||
add(4, 4, 8); // 4C X3 E*(D-X3) 2C Z3 q
|
add(4, 4, 8); // 4C X3 E*(D-X3) 2C Z3 q
|
||||||
rm(6); // X3 E*(D-X3) 4C Z3 q
|
rm(6); // X3 E*(D-X3) 4C Z3 q
|
||||||
add(4, 4, 8); // 8C X3 E*(D-X3) 4C Z3 q
|
add(4, 4, 8); // 8C X3 E*(D-X3) 4C Z3 q
|
||||||
rm(6); // X3 E*(D-X3) 8C Z3 q
|
rm(6); // X3 E*(D-X3) 8C Z3 q
|
||||||
sub(2, 4, 8); // E*(D-X3)-8C X3 E*(D-X3) 8C Z3 q
|
sub(2, 4, 8); // E*(D-X3)-8C X3 E*(D-X3) 8C Z3 q
|
||||||
rm(6); // X3 E*(D-X3) Y3 Z3 q
|
rm(6); // X3 E*(D-X3) Y3 Z3 q
|
||||||
rm(2); // X3 Y3 Z3 q
|
rm(2); // X3 Y3 Z3 q
|
||||||
|
|
||||||
C.label("enddouble");
|
C.label("enddouble");
|
||||||
C.returnCall();
|
C.returnCall();
|
||||||
}
|
}
|
||||||
|
|
||||||
function addPoint() { // p, xR, xI, yR, yI, zR zI, q
|
function addPoint() {
|
||||||
|
// p, xR, xI, yR, yI, zR zI, q
|
||||||
|
|
||||||
|
C.dup(0); // p p X2 Y2 Z2 q
|
||||||
C.dup(0); // p p X2 Y2 Z2 q
|
|
||||||
|
|
||||||
C.push(savedP);
|
C.push(savedP);
|
||||||
C.mstore();
|
C.mstore();
|
||||||
|
|
||||||
C.iszero(); // X2 Y2 Z2 q
|
C.iszero(); // X2 Y2 Z2 q
|
||||||
C.jumpi("endpadd");
|
C.jumpi("endpadd");
|
||||||
|
|
||||||
|
|
||||||
C.dup(4);
|
C.dup(4);
|
||||||
C.iszero();
|
C.iszero();
|
||||||
C.dup(6);
|
C.dup(6);
|
||||||
C.iszero();
|
C.iszero();
|
||||||
C.and();
|
C.and();
|
||||||
C.jumpi("returnP"); // X2 Y2 Z2 q
|
C.jumpi("returnP"); // X2 Y2 Z2 q
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// lastZ3 = (Z2+1)^2 - Z2^2
|
// lastZ3 = (Z2+1)^2 - Z2^2
|
||||||
add1(4, 6); // Z2+1 X2 Y2 Z2 q
|
add1(4, 6); // Z2+1 X2 Y2 Z2 q
|
||||||
square(0, 8); // (Z2+1)^2 Z2+1 X2 Y2 Z2 q
|
square(0, 8); // (Z2+1)^2 Z2+1 X2 Y2 Z2 q
|
||||||
rm(2); // (Z2+1)^2 X2 Y2 Z2 q
|
rm(2); // (Z2+1)^2 X2 Y2 Z2 q
|
||||||
square(6, 8); // Z2^2 (Z2+1)^2 X2 Y2 Z2 q
|
square(6, 8); // Z2^2 (Z2+1)^2 X2 Y2 Z2 q
|
||||||
|
|
||||||
|
sub(2, 0, 10); // (Z2+1)^2-Z2^2 Z2^2 (Z2+1)^2 X2 Y2 Z2 q
|
||||||
|
|
||||||
sub(2, 0, 10); // (Z2+1)^2-Z2^2 Z2^2 (Z2+1)^2 X2 Y2 Z2 q
|
saveZ3(); // Z2^2 (Z2+1)^2 X2 Y2 Z2 q
|
||||||
|
rm(2); // Z2^2 X2 Y2 Z2 q
|
||||||
saveZ3(); // Z2^2 (Z2+1)^2 X2 Y2 Z2 q
|
|
||||||
rm(2); // Z2^2 X2 Y2 Z2 q
|
|
||||||
|
|
||||||
// U2 = X2
|
// U2 = X2
|
||||||
// S2 = Y2 // Z2^2 U2 S2 Z2 q
|
// S2 = Y2 // Z2^2 U2 S2 Z2 q
|
||||||
|
|
||||||
|
|
||||||
// U1 = X1 * Z2^2
|
// U1 = X1 * Z2^2
|
||||||
loadX(); // X1 Z2^2 U2 S2 Z2 q
|
loadX(); // X1 Z2^2 U2 S2 Z2 q
|
||||||
mul(0, 2, 10); // X1*Z2^2 X1 Z2^2 U2 S2 Z2 q
|
mul(0, 2, 10); // X1*Z2^2 X1 Z2^2 U2 S2 Z2 q
|
||||||
rm(2); // X1*Z2^2 Z2^2 U2 S2 Z2 q
|
rm(2); // X1*Z2^2 Z2^2 U2 S2 Z2 q
|
||||||
|
|
||||||
|
mul(2, 8, 10); // Z2^3 U1 Z2^2 U2 S2 Z2 q
|
||||||
mul(2, 8, 10); // Z2^3 U1 Z2^2 U2 S2 Z2 q
|
rm(4); // U1 Z2^3 U2 S2 Z2 q
|
||||||
rm(4); // U1 Z2^3 U2 S2 Z2 q
|
rm(8); // Z2^3 U2 S2 U1 q
|
||||||
rm(8); // Z2^3 U2 S2 U1 q
|
|
||||||
|
|
||||||
// S1 = Y1 * Z1^3
|
// S1 = Y1 * Z1^3
|
||||||
loadY(); // Y1 Z2^3 U2 S2 U1 q
|
loadY(); // Y1 Z2^3 U2 S2 U1 q
|
||||||
mul(0, 2, 10); // S1 Y1 Z2^3 U2 S2 U1 q
|
mul(0, 2, 10); // S1 Y1 Z2^3 U2 S2 U1 q
|
||||||
rm(4); // Y1 S1 U2 S2 U1 q
|
rm(4); // Y1 S1 U2 S2 U1 q
|
||||||
rm(0); // S1 U2 S2 U1 q
|
rm(0); // S1 U2 S2 U1 q
|
||||||
|
|
||||||
cmp(0, 4); // c1 S1 U2 S2 U1 q
|
cmp(0, 4); // c1 S1 U2 S2 U1 q
|
||||||
cmp(3, 7); // c2 c1 S1 U2 S2 U1 q
|
cmp(3, 7); // c2 c1 S1 U2 S2 U1 q
|
||||||
C.and(); // c2&c1 S1 U2 S2 U1 q
|
C.and(); // c2&c1 S1 U2 S2 U1 q
|
||||||
C.jumpi("double1"); // S1 U2 S2 U1 q
|
C.jumpi("double1"); // S1 U2 S2 U1 q
|
||||||
|
|
||||||
|
|
||||||
// Returns the double
|
// Returns the double
|
||||||
|
|
||||||
// H = U2-U1 // Remove U2
|
// H = U2-U1 // Remove U2
|
||||||
C.sub(4, 8, 10); // H S1 U2 S2 U1 q
|
C.sub(4, 8, 10); // H S1 U2 S2 U1 q
|
||||||
rm(4); // S1 H S2 U1 q
|
rm(4); // S1 H S2 U1 q
|
||||||
|
|
||||||
// // r = 2 * (S2-S1) // Remove S2
|
// // r = 2 * (S2-S1) // Remove S2
|
||||||
C.sub(4, 4, 8); // S1-S2 S1 H S2 U1 q
|
C.sub(4, 4, 8); // S1-S2 S1 H S2 U1 q
|
||||||
rm(6); // S1 H S1-S2 U1 q
|
rm(6); // S1 H S1-S2 U1 q
|
||||||
C.add(4, 4, 8); // 2*(S1-S2) S1 H S1-S2 U1 q
|
C.add(4, 4, 8); // 2*(S1-S2) S1 H S1-S2 U1 q
|
||||||
rm(6); // S1 H r U1 q
|
rm(6); // S1 H r U1 q
|
||||||
|
|
||||||
// I = (2 * H)^2
|
// I = (2 * H)^2
|
||||||
C.add(2, 2, 8); // 2*H S1 H r U1 q
|
C.add(2, 2, 8); // 2*H S1 H r U1 q
|
||||||
C.square(0, 10); // (2*H)^2 2*H S1 H r U1 q
|
C.square(0, 10); // (2*H)^2 2*H S1 H r U1 q
|
||||||
rm(2); // I S1 H r U1 q
|
rm(2); // I S1 H r U1 q
|
||||||
|
|
||||||
// V = U1 * I
|
// V = U1 * I
|
||||||
mul(8, 0, 10); // V I S1 H r U1 q
|
mul(8, 0, 10); // V I S1 H r U1 q
|
||||||
rm(10); // I S1 H r V q
|
rm(10); // I S1 H r V q
|
||||||
|
|
||||||
// J = H * I // Remove I
|
// J = H * I // Remove I
|
||||||
mul(4, 0, 10); // J I S1 H r V q
|
mul(4, 0, 10); // J I S1 H r V q
|
||||||
rm(2); // J S1 H r V q
|
rm(2); // J S1 H r V q
|
||||||
|
|
||||||
// X3 = r^2 - J - 2 * V
|
// X3 = r^2 - J - 2 * V
|
||||||
|
|
||||||
// S1J2 = (S1*J)*2 // Remove S1
|
// S1J2 = (S1*J)*2 // Remove S1
|
||||||
mul(2, 0, 10); // S1*J J S1 H r V q
|
mul(2, 0, 10); // S1*J J S1 H r V q
|
||||||
rm(4); // J S1*J H r V q
|
rm(4); // J S1*J H r V q
|
||||||
add(2,2, 10); // (S1*J)*2 J S1*J H r V q
|
add(2, 2, 10); // (S1*J)*2 J S1*J H r V q
|
||||||
rm(4); // J S1J2 H r V q
|
rm(4); // J S1J2 H r V q
|
||||||
|
|
||||||
// X3 = r^2 - J - 2 * V
|
// X3 = r^2 - J - 2 * V
|
||||||
square(6, 10); // r^2 J S1J2 H r V q
|
square(6, 10); // r^2 J S1J2 H r V q
|
||||||
sub(0, 2, 12); // r^2-J r^2 J S1J2 H r V q
|
sub(0, 2, 12); // r^2-J r^2 J S1J2 H r V q
|
||||||
rm(2); // r^2-J J S1J2 H r V q
|
rm(2); // r^2-J J S1J2 H r V q
|
||||||
rm(2); // r^2-J S1J2 H r V q
|
rm(2); // r^2-J S1J2 H r V q
|
||||||
add(8, 8, 10); // 2*V r^2-J S1J2 H r V q
|
add(8, 8, 10); // 2*V r^2-J S1J2 H r V q
|
||||||
sub(2, 0, 12); // r^2-J-2*V 2*V r^2-J S1J2 H r V q
|
sub(2, 0, 12); // r^2-J-2*V 2*V r^2-J S1J2 H r V q
|
||||||
rm(4); // 2*V X3 S1J2 H r V q
|
rm(4); // 2*V X3 S1J2 H r V q
|
||||||
rm(0); // X3 S1J2 H r V q
|
rm(0); // X3 S1J2 H r V q
|
||||||
|
|
||||||
// Y3 = r * (V-X3)-S1J2
|
// Y3 = r * (V-X3)-S1J2
|
||||||
|
|
||||||
sub(8, 0, 10); // V-X3 X3 S1J2 H r V q
|
sub(8, 0, 10); // V-X3 X3 S1J2 H r V q
|
||||||
rm(10); // X3 S1J2 H r V-X3 q
|
rm(10); // X3 S1J2 H r V-X3 q
|
||||||
mul(6, 8, 10); // r*(V-X3) X3 S1J2 H r V-X3 q
|
mul(6, 8, 10); // r*(V-X3) X3 S1J2 H r V-X3 q
|
||||||
rm(8); // X3 S1J2 H r*(V-X3) V-X3 q
|
rm(8); // X3 S1J2 H r*(V-X3) V-X3 q
|
||||||
rm(8); // S1J2 H r*(V-X3) X3 q
|
rm(8); // S1J2 H r*(V-X3) X3 q
|
||||||
sub(4, 0, 8); // Y3 S1J2 H r*(V-X3) X3 q
|
sub(4, 0, 8); // Y3 S1J2 H r*(V-X3) X3 q
|
||||||
rm(6); // S1J2 H Y3 X3 q
|
rm(6); // S1J2 H Y3 X3 q
|
||||||
rm(0); // H Y3 X3 q
|
rm(0); // H Y3 X3 q
|
||||||
|
|
||||||
// Z3 = lastZ * H
|
// Z3 = lastZ * H
|
||||||
loadZ3(); // lastZ3 H Y3 X3 q
|
loadZ3(); // lastZ3 H Y3 X3 q
|
||||||
mul(0, 2, 8); // Z3 lastZ3 H Y3 X3 q
|
mul(0, 2, 8); // Z3 lastZ3 H Y3 X3 q
|
||||||
rm(4); // lastZ3 Z3 Y3 X3 q
|
rm(4); // lastZ3 Z3 Y3 X3 q
|
||||||
rm(0); // Z3 Y3 X3 q
|
rm(0); // Z3 Y3 X3 q
|
||||||
|
|
||||||
C.swap(1);
|
C.swap(1);
|
||||||
C.swap(5);
|
C.swap(5);
|
||||||
C.swap(1);
|
C.swap(1);
|
||||||
C.swap(4); // X3 Y3 Z3 q
|
C.swap(4); // X3 Y3 Z3 q
|
||||||
|
|
||||||
// returns the point in memory
|
// returns the point in memory
|
||||||
C.label("returnP"); // X Y Z q
|
C.label("returnP"); // X Y Z q
|
||||||
@ -430,37 +418,37 @@ function createCode(P, w) {
|
|||||||
|
|
||||||
function loadX() {
|
function loadX() {
|
||||||
C.push(savedP);
|
C.push(savedP);
|
||||||
C.mload(); // p
|
C.mload(); // p
|
||||||
C.push(32);
|
C.push(32);
|
||||||
C.mul(); // P*32
|
C.mul(); // P*32
|
||||||
C.push(VAR_POINTS+32);
|
C.push(VAR_POINTS + 32);
|
||||||
C.add(); // P*32+32
|
C.add(); // P*32+32
|
||||||
C.dup(); // P*32+32 P*32+32
|
C.dup(); // P*32+32 P*32+32
|
||||||
C.mload(); // im P*32+32
|
C.mload(); // im P*32+32
|
||||||
C.swap(1); // P*32+32 im
|
C.swap(1); // P*32+32 im
|
||||||
C.push(0x20); // 32 P*32+32 im
|
C.push(0x20); // 32 P*32+32 im
|
||||||
C.sub(); // P*32 im
|
C.sub(); // P*32 im
|
||||||
C.mload(); // re im
|
C.mload(); // re im
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadY() {
|
function loadY() {
|
||||||
C.push(savedP);
|
C.push(savedP);
|
||||||
C.mload(); // p
|
C.mload(); // p
|
||||||
C.push(32);
|
C.push(32);
|
||||||
C.mul(); // P*32
|
C.mul(); // P*32
|
||||||
C.push(VAR_POINTS+32*3);
|
C.push(VAR_POINTS + 32 * 3);
|
||||||
C.add(); // P*32+32
|
C.add(); // P*32+32
|
||||||
C.dup(); // P*32+32 P*32+32
|
C.dup(); // P*32+32 P*32+32
|
||||||
C.mload(); // im P*32+32
|
C.mload(); // im P*32+32
|
||||||
C.swap(1); // P*32+32 im
|
C.swap(1); // P*32+32 im
|
||||||
C.push(0x20); // 32 P*32+32 im
|
C.push(0x20); // 32 P*32+32 im
|
||||||
C.sub(); // P*32 im
|
C.sub(); // P*32 im
|
||||||
C.mload(); // re im
|
C.mload(); // re im
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadZ3() {
|
function loadZ3() {
|
||||||
C.push(savedZ3+32);
|
C.push(savedZ3 + 32);
|
||||||
C.mload(); // p
|
C.mload(); // p
|
||||||
C.push(savedZ3);
|
C.push(savedZ3);
|
||||||
C.mload();
|
C.mload();
|
||||||
}
|
}
|
||||||
@ -468,18 +456,19 @@ function createCode(P, w) {
|
|||||||
function saveZ3() {
|
function saveZ3() {
|
||||||
C.push(savedZ3);
|
C.push(savedZ3);
|
||||||
C.mstore();
|
C.mstore();
|
||||||
C.push(savedZ3+32);
|
C.push(savedZ3 + 32);
|
||||||
C.mstore();
|
C.mstore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function affine() { // X Y Z q
|
function affine() {
|
||||||
|
// X Y Z q
|
||||||
// If Z2=0 return 0
|
// If Z2=0 return 0
|
||||||
C.label("affine");
|
C.label("affine");
|
||||||
C.dup(4);
|
C.dup(4);
|
||||||
C.dup(5 + 1);
|
C.dup(5 + 1);
|
||||||
C.or();
|
C.or();
|
||||||
C.jumpi("notZero"); // X Y Z q
|
C.jumpi("notZero"); // X Y Z q
|
||||||
rm(0);
|
rm(0);
|
||||||
rm(0);
|
rm(0);
|
||||||
C.push(0);
|
C.push(0);
|
||||||
@ -488,96 +477,95 @@ function createCode(P, w) {
|
|||||||
C.jmp("endAffine");
|
C.jmp("endAffine");
|
||||||
C.label("notZero");
|
C.label("notZero");
|
||||||
|
|
||||||
inverse2(4,6); // Z_inv X Y Z q
|
inverse2(4, 6); // Z_inv X Y Z q
|
||||||
square(2, 8); // Z2_inv Z_inv X Y Z q
|
square(2, 8); // Z2_inv Z_inv X Y Z q
|
||||||
mul(0, 2, 10); // Z3_inv Z2_inv Z_inv X Y Z q
|
mul(0, 2, 10); // Z3_inv Z2_inv Z_inv X Y Z q
|
||||||
rm(4); // Z2_inv Z3_inv X Y Z q
|
rm(4); // Z2_inv Z3_inv X Y Z q
|
||||||
C.push(1);
|
C.push(1);
|
||||||
C.push(0); // 1 Z2_inv Z3_inv X Y Z q
|
C.push(0); // 1 Z2_inv Z3_inv X Y Z q
|
||||||
rm(10); // Z2_inv Z3_inv X Y 1 q
|
rm(10); // Z2_inv Z3_inv X Y 1 q
|
||||||
mul(2, 6, 10); // YI Z2_inv Z3_inv X Y 1 q
|
mul(2, 6, 10); // YI Z2_inv Z3_inv X Y 1 q
|
||||||
rm(8); // Z2_inv Z3_inv X YI 1 q
|
rm(8); // Z2_inv Z3_inv X YI 1 q
|
||||||
mul(0, 4, 10); // XI Z2_inv Z3_inv X YI 1 q
|
mul(0, 4, 10); // XI Z2_inv Z3_inv X YI 1 q
|
||||||
rm(6); // Z2_inv Z3_inv XI YI 1 q
|
rm(6); // Z2_inv Z3_inv XI YI 1 q
|
||||||
rm(0); // Z3_inv XI YI 1 q
|
rm(0); // Z3_inv XI YI 1 q
|
||||||
rm(0); // XI YI 1 q
|
rm(0); // XI YI 1 q
|
||||||
C.label("endAffine");
|
C.label("endAffine");
|
||||||
C.returnCall();
|
C.returnCall();
|
||||||
}
|
}
|
||||||
|
|
||||||
function inverse2(a, q) {
|
function inverse2(a, q) {
|
||||||
C.dup(q); // q
|
C.dup(q); // q
|
||||||
C.dup(q + 1); // q q
|
C.dup(q + 1); // q q
|
||||||
C.push(2); // 2 q q
|
C.push(2); // 2 q q
|
||||||
C.sub(); // q-2 q
|
C.sub(); // q-2 q
|
||||||
C.dup(q + 2); // q q-2 q
|
C.dup(q + 2); // q q-2 q
|
||||||
C.dup(q + 3); // q q q-2 q
|
C.dup(q + 3); // q q q-2 q
|
||||||
C.dup(a + 4); // ar q q q-2 q
|
C.dup(a + 4); // ar q q q-2 q
|
||||||
C.dup(a + 5); // ar ar q q q-2 q
|
C.dup(a + 5); // ar ar q q q-2 q
|
||||||
C.mulmod(); // t0 q q-2 q
|
C.mulmod(); // t0 q q-2 q
|
||||||
|
|
||||||
C.dup(q + 4); // q t0 q q-2 q
|
C.dup(q + 4); // q t0 q q-2 q
|
||||||
C.dup(a+1 + 5); // ai q t0 q q-2 q
|
C.dup(a + 1 + 5); // ai q t0 q q-2 q
|
||||||
C.dup(a+1 + 6); // ai ai q t0 q q-2 q
|
C.dup(a + 1 + 6); // ai ai q t0 q q-2 q
|
||||||
C.mulmod(); // t1 t0 q q-2 q
|
C.mulmod(); // t1 t0 q q-2 q
|
||||||
|
|
||||||
C.addmod(); // t2 q-2 q
|
C.addmod(); // t2 q-2 q
|
||||||
C.expmod(); // t3
|
C.expmod(); // t3
|
||||||
|
|
||||||
C.dup(q + 1); // q t3
|
C.dup(q + 1); // q t3
|
||||||
C.dup(q + 2); // q q t3
|
C.dup(q + 2); // q q t3
|
||||||
C.dup(q + 3); // q q q t3
|
C.dup(q + 3); // q q q t3
|
||||||
C.dup(1); // t3 q q q t3
|
C.dup(1); // t3 q q q t3
|
||||||
C.sub(); // -t3 q q t3
|
C.sub(); // -t3 q q t3
|
||||||
C.dup(a+1 + 3); // ai -t3 q q t3
|
C.dup(a + 1 + 3); // ai -t3 q q t3
|
||||||
C.mulmod(); // ii q t3
|
C.mulmod(); // ii q t3
|
||||||
C.swap(2); // t3 q ii
|
C.swap(2); // t3 q ii
|
||||||
C.dup(a + 3); // ar t3 q ii
|
C.dup(a + 3); // ar t3 q ii
|
||||||
C.mulmod(); // ir ii
|
C.mulmod(); // ir ii
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
C.dup(1); // p MP[0][0] p
|
C.dup(1); // p MP[0][0] p
|
||||||
C.mstore(); // p
|
C.mstore(); // p
|
||||||
C.push(32); // 32 p
|
C.push(32); // 32 p
|
||||||
C.add(); // p+32
|
C.add(); // p+32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.abi = [
|
module.exports.abi = [
|
||||||
{
|
{
|
||||||
"constant": true,
|
constant: true,
|
||||||
"inputs": [
|
inputs: [
|
||||||
{
|
{
|
||||||
"name": "escalar",
|
name: "escalar",
|
||||||
"type": "uint256"
|
type: "uint256",
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
"name": "mulexp",
|
name: "mulexp",
|
||||||
"outputs": [
|
outputs: [
|
||||||
{
|
{
|
||||||
"name": "",
|
name: "",
|
||||||
"type": "uint256"
|
type: "uint256",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "",
|
name: "",
|
||||||
"type": "uint256"
|
type: "uint256",
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
"payable": false,
|
payable: false,
|
||||||
"stateMutability": "pure",
|
stateMutability: "pure",
|
||||||
"type": "function"
|
type: "function",
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
module.exports.createCode = createCode;
|
module.exports.createCode = createCode;
|
||||||
|
30
src/mimc7.js
30
src/mimc7.js
@ -1,7 +1,9 @@
|
|||||||
const bn128 = require("snarkjs").bn128;
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
const bigInt = require("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;
|
||||||
@ -9,8 +11,8 @@ 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -22,26 +24,26 @@ exports.getConstants = (seed, nRounds) => {
|
|||||||
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) => {
|
||||||
@ -57,8 +59,8 @@ exports.multiHash = (arr, key) => {
|
|||||||
r,
|
r,
|
||||||
arr[i]
|
arr[i]
|
||||||
),
|
),
|
||||||
exports.hash(bigInt(arr[i]), r)
|
exports.hash(F.e(arr[i]), r)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return F.affine(r);
|
return r;
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
const bn128 = require("snarkjs").bn128;
|
const Scalar = require("ffjavascript").Scalar
|
||||||
const bigInt = require("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;
|
||||||
@ -9,8 +9,8 @@ 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -22,41 +22,41 @@ exports.getConstants = (seed, nRounds) => {
|
|||||||
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;
|
||||||
@ -66,21 +66,21 @@ exports.multiHash = (arr, key, numOutputs) => {
|
|||||||
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));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
const bn128 = require("snarkjs").bn128;
|
|
||||||
const bigInt = require("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,13 +10,23 @@ const nWindowsPerSegment = 50;
|
|||||||
exports.hash = pedersenHash;
|
exports.hash = pedersenHash;
|
||||||
exports.getBasePoint = getBasePoint;
|
exports.getBasePoint = getBasePoint;
|
||||||
|
|
||||||
function pedersenHash(msg) {
|
function baseHash(type, S) {
|
||||||
|
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 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;
|
||||||
@ -25,32 +35,32 @@ function pedersenHash(msg) {
|
|||||||
} 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,13 +68,13 @@ 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++;
|
||||||
|
@ -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]}]`);
|
||||||
}
|
}
|
||||||
|
146
src/poseidon.js
146
src/poseidon.js
@ -1,116 +1,48 @@
|
|||||||
const bn128 = require("snarkjs").bn128;
|
|
||||||
const bigInt = require("snarkjs").bigInt;
|
|
||||||
const blake2b = require('blake2b');
|
|
||||||
const assert = require("assert");
|
const assert = require("assert");
|
||||||
const F = bn128.Fr;
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
|
const ZqField = require("ffjavascript").ZqField;
|
||||||
|
const { unstringifyBigInts } = require("ffjavascript").utils;
|
||||||
|
|
||||||
const SEED = "poseidon";
|
// Prime 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001
|
||||||
const NROUNDSF = 8;
|
const F = new ZqField(Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
|
||||||
const NROUNDSP = 57;
|
|
||||||
const T = 6;
|
|
||||||
|
|
||||||
function getPseudoRandom(seed, n) {
|
// Parameters are generated by a reference script https://extgit.iaik.tugraz.at/krypto/hadeshash/-/blob/master/code/generate_parameters_grain.sage
|
||||||
const res = [];
|
// Used like so: sage generate_parameters_grain.sage 1 0 254 2 8 56 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001
|
||||||
let input = Buffer.from(seed);
|
const { C, M } = unstringifyBigInts(require("./poseidon_constants.json"));
|
||||||
let h = blake2b(32).update(input).digest()
|
|
||||||
while (res.length<n) {
|
|
||||||
const n = F.affine(bigInt.leBuff2int(h));
|
|
||||||
res.push(n);
|
|
||||||
h = blake2b(32).update(h).digest()
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
// 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
|
||||||
|
// And rounded up to nearest integer that divides by t
|
||||||
|
const N_ROUNDS_F = 8;
|
||||||
|
const N_ROUNDS_P = 35;
|
||||||
|
|
||||||
function allDifferent(v) {
|
const pow5 = a => F.mul(a, F.square(F.square(a, a)));
|
||||||
for (let i=0; i<v.length; i++) {
|
|
||||||
if (v[i].isZero()) return false;
|
function poseidon(inputs) {
|
||||||
for (let j=i+1; j<v.length; j++) {
|
assert(inputs.length > 0);
|
||||||
if (v[i].equals(v[j])) return false;
|
assert(inputs.length < 5);
|
||||||
|
|
||||||
|
const t = inputs.length + 1;
|
||||||
|
const nRoundsF = N_ROUNDS_F;
|
||||||
|
const nRoundsP = N_ROUNDS_P;
|
||||||
|
|
||||||
|
let state = [...inputs.map(a => F.e(a)), F.zero];
|
||||||
|
for (let r = 0; r < nRoundsF + nRoundsP; r++) {
|
||||||
|
state = state.map((a, i) => F.add(a, BigInt(C[t - 2][r * t + i])));
|
||||||
|
if (r < nRoundsF / 2 || r >= nRoundsF / 2 + nRoundsP) {
|
||||||
|
state = state.map(a => pow5(a));
|
||||||
|
} else {
|
||||||
|
state[0] = pow5(state[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// no matrix multiplication in the last round
|
||||||
|
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)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return F.normalize(state[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.getMatrix = (t, seed, nRounds) => {
|
module.exports = poseidon;
|
||||||
if (typeof seed === "undefined") seed = SEED;
|
|
||||||
if (typeof nRounds === "undefined") nRounds = NROUNDSF + NROUNDSP;
|
|
||||||
if (typeof t === "undefined") t = T;
|
|
||||||
let nonce = "0000";
|
|
||||||
let cmatrix = getPseudoRandom(seed+"_matrix_"+nonce, t*2);
|
|
||||||
while (!allDifferent(cmatrix)) {
|
|
||||||
nonce = (Number(nonce)+1)+"";
|
|
||||||
while(nonce.length<4) nonce = "0"+nonce;
|
|
||||||
cmatrix = getPseudoRandom(seed+"_matrix_"+nonce, t*2);
|
|
||||||
}
|
|
||||||
|
|
||||||
const M = new Array(t);
|
|
||||||
for (let i=0; i<t; i++) {
|
|
||||||
M[i] = new Array(t);
|
|
||||||
for (let j=0; j<t; j++) {
|
|
||||||
M[i][j] = F.affine(F.inverse(F.sub(cmatrix[i], cmatrix[t+j])));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return M;
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.getConstants = (t, seed, nRounds) => {
|
|
||||||
if (typeof seed === "undefined") seed = SEED;
|
|
||||||
if (typeof nRounds === "undefined") nRounds = NROUNDSF + NROUNDSP;
|
|
||||||
if (typeof t === "undefined") t = T;
|
|
||||||
const cts = getPseudoRandom(seed+"_constants", nRounds);
|
|
||||||
return cts;
|
|
||||||
};
|
|
||||||
|
|
||||||
function ark(state, c) {
|
|
||||||
for (let j=0; j<state.length; j++ ) {
|
|
||||||
state[j] = F.add(state[j], c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function sigma(a) {
|
|
||||||
return F.mul(a, F.square(F.square(a,a)));
|
|
||||||
}
|
|
||||||
|
|
||||||
function mix(state, M) {
|
|
||||||
const newState = new Array(state.length);
|
|
||||||
for (let i=0; i<state.length; i++) {
|
|
||||||
newState[i] = F.zero;
|
|
||||||
for (let j=0; j<state.length; j++) {
|
|
||||||
newState[i] = F.add(newState[i], F.mul(M[i][j], state[j]) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (let i=0; i<state.length; i++) state[i] = newState[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.createHash = (t, nRoundsF, nRoundsP, seed) => {
|
|
||||||
|
|
||||||
if (typeof seed === "undefined") seed = SEED;
|
|
||||||
if (typeof nRoundsF === "undefined") nRoundsF = NROUNDSF;
|
|
||||||
if (typeof nRoundsP === "undefined") nRoundsP = NROUNDSP;
|
|
||||||
if (typeof t === "undefined") t = T;
|
|
||||||
|
|
||||||
assert(nRoundsF % 2 == 0);
|
|
||||||
const C = exports.getConstants(t, seed, nRoundsF + nRoundsP);
|
|
||||||
const M = exports.getMatrix(t, seed, nRoundsF + nRoundsP);
|
|
||||||
return function(inputs) {
|
|
||||||
let state = [];
|
|
||||||
assert(inputs.length <= t);
|
|
||||||
assert(inputs.length > 0);
|
|
||||||
for (let i=0; i<inputs.length; i++) state[i] = bigInt(inputs[i]);
|
|
||||||
for (let i=inputs.length; i<t; i++) state[i] = F.zero;
|
|
||||||
|
|
||||||
for (let i=0; i< nRoundsF + nRoundsP; i++) {
|
|
||||||
ark(state, C[i]);
|
|
||||||
if ((i<nRoundsF/2) || (i >= nRoundsF/2 + nRoundsP)) {
|
|
||||||
for (let j=0; j<t; j++) state[j] = sigma(state[j]);
|
|
||||||
} else {
|
|
||||||
state[0] = sigma(state[0]);
|
|
||||||
}
|
|
||||||
mix(state, M);
|
|
||||||
}
|
|
||||||
return F.affine(state[0]);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
706
src/poseidon_constants.json
Normal file
706
src/poseidon_constants.json
Normal file
@ -0,0 +1,706 @@
|
|||||||
|
{
|
||||||
|
"C": [
|
||||||
|
[
|
||||||
|
"0x1083c3a16f6c55c7956a5ce08fb39df23957cc6381c217985d9ba0ae29771100",
|
||||||
|
"0x1dd8990173e411a3a4dff6710e8c3df9ef8e07216efd610a63b3ce10ab57b8ae",
|
||||||
|
"0x1f3ff523faa41dab28fd27c47286a6b93fe44a9e993ea1ab3723d17aba78b3de",
|
||||||
|
"0x2662d2995574e11e58f4ce13e282b6b57c2d7df1681bfef79a0261dc300573fc",
|
||||||
|
"0x20b3c06fa2b82434f725af0c37efb847324312d182d127fdb2054cfa0da9a8be",
|
||||||
|
"0x18ff92e6daa7639fc832d97928e4098d84efa47d7ef5c1929e54232960ae32b1",
|
||||||
|
"0x2c175450b8686e4958e698cf1af0b54e0e912ea93f35be8e8e1c3daebbc034be",
|
||||||
|
"0x00596181885c32674b20103a1a153744c302cf1fa86ee39e14e2ff9a5f9efcba",
|
||||||
|
"0x0e21b4330dd8a9563e60ef4ffdbb26b85ae766e867633e58c20932365d273a53",
|
||||||
|
"0x16eb0a124adc927e3fdae149e1aef43d5ee08693f7dac9aa20b46bb31ae12d1f",
|
||||||
|
"0x0ba1d75274999eb448de5751b5bd165582205d564c636e8340d2a3fe09e4e01c",
|
||||||
|
"0x04d615bf7a10c566ae2b198a40bef494bc43e7bbd40baa908bf2ce989d39cb16",
|
||||||
|
"0x10f7d989ce23d2ec2dc7cb425b603ef0fb09efb7f620a25b4e0187fafaeb364e",
|
||||||
|
"0x091562ecab7c0dffec5f874d385c6a7f06e10c0ba2d43a6e4958a47b9d369438",
|
||||||
|
"0x214c48e2dd8005914ef1c20e4e2e73933abc7dde8bf2f87ffee4bacb52110931",
|
||||||
|
"0x29418d43249c5f094ff06f9bc1b80e21dffbaac1874539e42b40f8dc49facb42",
|
||||||
|
"0x017c1908a9f8359c1280d6ac4edfdcec6ae060d0d520bf64b183191397999203",
|
||||||
|
"0x1a01b85c3b8e81a862a90fd72d5989f75683d9573d4865d79228eb8c5a105e93",
|
||||||
|
"0x261b40b148e35d05c9a231b70f46bd67e973c7e3cb33648e1904cc257d52a4d5",
|
||||||
|
"0x036eb758e5135f0137fc7ef59c37454e2b86f0fd90932f0e382ae7c97e3b2e35",
|
||||||
|
"0x2de1f93fc74bfa9f08fae8bb730f8d266d3726892b97db237f703ed3a8817ac2",
|
||||||
|
"0x2be0f288c7cb40cf6b063559e689775aa6e0837ff4a3a5d3d62f9f14d688c925",
|
||||||
|
"0x202410f3233bc5ccf8621873ab2827da7a365ffbd5c55d62bed934a2bf441256",
|
||||||
|
"0x2f4aa966c6aaa0f96b1a2d8c7c6090ac81a390252e2c2eca95b2d9d4f6f60118",
|
||||||
|
"0x1c8b2beb3bbc01ec6a6f31261215c3d3aa4193322317b2a8f0816369fbd8db0d",
|
||||||
|
"0x09166d1877b85ed30781d55bd800917958abc8eb14be7acdf7c74dca69b9f293",
|
||||||
|
"0x054974baac27bad68c2928ad06d711cb424e77509102145b9e5a1b911dc2342c",
|
||||||
|
"0x08759d0b984c16c5ba432900cf2bd92c4919cdd7e99a10c29cd343f69b460f74",
|
||||||
|
"0x2a65153ca0dbc6487497126a6ec8a8d014bcb3d1818914865a504404a4ad03a0",
|
||||||
|
"0x2b1c5d81263028bcf7996584eede3c315789d1f3e205919585145e023cefd30e",
|
||||||
|
"0x1927d650073030417589aa9047f9b62ee876cca63cde015e24d0bf4894b2978f",
|
||||||
|
"0x2d76a732e12f3deafda7b22085efef22772cd3de8f7e001bc99088cb81c9b734",
|
||||||
|
"0x04063f088d29d7e91e72cdbc50afe1835c4b11ed14f769522c86760cbf526d50",
|
||||||
|
"0x03e3a3a1c937f3c05882148070e9dac6b5915751fbca27c212bf7582441819eb",
|
||||||
|
"0x0d416931f39d66d2c94f070c54cae280da1c12605fd2256a129696e98f11ccf6",
|
||||||
|
"0x2bc7ec8d56eaf3c8e0d7695f84cbf898f0155c3ebaf24583af09b0e7154bec1a",
|
||||||
|
"0x0367eff17e1bddbee7eed78ec874a9a01e6a9a38406108f487662dc60614010b",
|
||||||
|
"0x08dd17e110dc0768f10866e8ccf53efb5290468cd8afd07430def10ec9a586fd",
|
||||||
|
"0x218efb40100662ed34129a8246a90398a806f52f5f76e104299092860a7a8888",
|
||||||
|
"0x1ac99c81cc6f26be5143ea1daccd4eacaa31e3b223f0a6c4dec96633410f197d",
|
||||||
|
"0x12cd3c8d2ac7f084684109522fb7be0b7531e2acf8d9e7b686e177ea7a0f05d6",
|
||||||
|
"0x17e4773a46b9bb17843f36f6db850bace2c86aa3376abf06614f62bded94a7b1",
|
||||||
|
"0x29d767ca1255c6c1b1bce1d68ecfbd596aa77657dfbe4a604235e60449a9ff14",
|
||||||
|
"0x242b7392dec412813184d8dca1a25147c092f3d7dfd3c0c58174eb4268452cb8",
|
||||||
|
"0x0ea9a0a62f1db4cf40e5e2db0286e48312eee96e72305cf4f98c5f7d6c2df9e5",
|
||||||
|
"0x13b3fe8f9d94f4d1bcbbaa26018c2c54fcaf122015c5cb9bfbe7a6694ca718bc",
|
||||||
|
"0x2208e0ced2039b4140bd1fdc4cdff8568f92ea662ab6588a16c42fd95adc8f39",
|
||||||
|
"0x1e8616716cf3255c36bdb7b62fe0f9b41c3877aa2df998ab54e8974e017a3537",
|
||||||
|
"0x038c19e5b3c8c3a6e812190a39e6313b181dc71e065ada3b823547451b8288eb",
|
||||||
|
"0x2518ab4d82a14c358e67509c46fd78ef736049c9498592e9390fce0e8b42a314",
|
||||||
|
"0x2c2b623bc30fbc269b3ef27e6a7fd25c2968a321382218ab2548e18ff6ea4b3c",
|
||||||
|
"0x25fa075323cdc87b1db37b7d42fccf1fd9a7ad6a598085e68e57dd145032c15c",
|
||||||
|
"0x2f5f009c35bb13a3027067b3bf5881d8c533b67fcb390d162fc406c989575905",
|
||||||
|
"0x0b8e0cd5cab0e99ca405d6bd1597a9dee6cd3c0dd4e0f6929a1d4d88b42605a3",
|
||||||
|
"0x104069c2b60c8e4b01890e6992cc841e269636e3c5ab6905a8f4045711c19665",
|
||||||
|
"0x25d04aa8cab6c80cce8005e027f4bc3b82e91fe2f1ca6e2b652defed5b0af05c",
|
||||||
|
"0x2cc7d8d1f3deb41e50665cb11ad9e821464a382dd17d2e71fe9d1c52c167427d",
|
||||||
|
"0x1b176ebf76e8d0d4dd54afe65596621b9af71273e5006cc60cad9819e2a0b87c",
|
||||||
|
"0x128db0ff4dade1354d6ad7567e59b4aee9341ecf906f2988aaa53f6eff912aa1",
|
||||||
|
"0x19b85e448cd2bd1cd640922cc2c7ba93441f0bafdb8a38818a5d5a666c0eb921",
|
||||||
|
"0x0498634a814e0850c5063b301461fff914fb9debe1aa76673bc0dd089e8898a9",
|
||||||
|
"0x1e0081d167ae36dc04c5359042be8c26af96b4ecd92c398d36a12aa863f23bcc",
|
||||||
|
"0x26f2231aee75807dbbd2a46279b38e94514b1945517909b93e482feceaab0ac7",
|
||||||
|
"0x2b81566447dccb12959315088de6e42cabf4a0798110a8c2339e0c6fa35952f7",
|
||||||
|
"0x106920fdae1cfe63ce0199599d45c4343ae36a016cab57dee1a1bda89788a1d5",
|
||||||
|
"0x2d1b3979803f4f5ad56b9cfcb41d62c4a30b5f01251dbc845fc0004ffdf9aaee",
|
||||||
|
"0x0492886098bc8d5601930dd4bc7fabaded741f1acb5e6dceb523a7dfa70958eb",
|
||||||
|
"0x1b2f4d14a2c0d5908c6176e46d241af50de7927f0bc02d12ca61f4590c040823",
|
||||||
|
"0x1e792cdeb85952cdeddfc38534e2321f4a566798aa7b7caa7c655404f4aeec44",
|
||||||
|
"0x29d050fabbb2ec05984df81ed8be2838f94b6cf3819a68a42ffbb66dd4c90641",
|
||||||
|
"0x222805d8ae12b43cbe30e5be4dba67ff2353b06f4bde6af8a3e7f8860016a047",
|
||||||
|
"0x20eb248ee0196d8b59886a343afd2fa88960f208ebec71901da094128cbc4725",
|
||||||
|
"0x22058b95c5f9776d8d3dd8d0c7a922602606ac72d7ac0c3ce353ee0c798c54a1",
|
||||||
|
"0x22afd288266fa099adeaf954fe2a94b0c05445272ac8b50655677be97b130bee",
|
||||||
|
"0x25c343fe28997a29309a518d42c63b72c281bc44fcd4bc76d2cb1ad34a3fb59f",
|
||||||
|
"0x26c9e1c8f49e22d6ac88c7a362513a449e682ab324b5e792eced3c0cf5a41f4a",
|
||||||
|
"0x2b666c9f3ed397d5bb857215fce16a5de70d844ec6ad0b8e53a70287ee939668",
|
||||||
|
"0x0193818f6648e494b44941453f1163478525f5cbec6b7fbf7fbcd2f5f370052f",
|
||||||
|
"0x287663a600dd765c1439d38bb92544aeddcd9959c96868df261f70021f4643e1",
|
||||||
|
"0x044046628ffff9fb29c8c7d497ea02f9941fb149960b5f2ea48c800bcce85ac3",
|
||||||
|
"0x26677946fb04e67bf0603bccf418736f976fe326f2351e351a623a49f015950c",
|
||||||
|
"0x2a79f2df436cc4bf39b2ab08d989ea590d2d1fb85caac9bd8a526dd965b0ab6d",
|
||||||
|
"0x2177c32e659c0d78c6766c5633e9716e6a3e09b0f16e139985044f6d2d231bfd",
|
||||||
|
"0x2181f1fbf114eb1033d4727aa2b879e28d034d8197e460798b2d8be106695c25",
|
||||||
|
"0x1582e0e3ea89e6c7912c2b2ffd9b6de7f960a6a7ee9c27d2ec9d53aaed390656",
|
||||||
|
"0x2899f6acd826f205c140ac2599496b3a3448dd62e25b076be959cc24b12aa69a"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"0x211fa1419f2b7b630c9d42ac4dfff1d8201547e24651d10dd4b4988ac06216f6",
|
||||||
|
"0x18ac51e16e5865ee074806af313b040924f20a76c2a45a76b90aeb07ac438e03",
|
||||||
|
"0x2906c33d1c67bd9a2ba6ab37ef7aecf377eb3f324ce68be741441faa846133b6",
|
||||||
|
"0x0d6fdc1a5ff92bedc6919093d495de525266075a273eadea7287b1b4941cf427",
|
||||||
|
"0x2552b734c5a95e374c8286a1cf7c05975265132ec03487470a513366fb38c5fd",
|
||||||
|
"0x1a8e88f6d94394599224dba0906142559b388ba2cc168fe97b6af4a85aec2680",
|
||||||
|
"0x2573ce0ce1273b649d31dd96f1f03f2ec83cf4920b72db75e428707dc1e26db3",
|
||||||
|
"0x0ce0750d2b6bf2a1251c0c6b496f01f7217a58c4ae1e5bf17a1f884f9c430642",
|
||||||
|
"0x154735e5f8c0640c2c722fb3dac05c4d603c3e150dd2cd09475d5770159fdeef",
|
||||||
|
"0x1671d015b9090cd861a5a5ccbba2cbd7a51bf07febdefabeff7b69f4b219ff3f",
|
||||||
|
"0x2d2fbd76fcfbc5943b16d77456d974a7741165a49187f28efb5d64a7634a4260",
|
||||||
|
"0x040a119f75e867208bddfaeb55741ebf53a30c7a1affcb8b6cd267c66c054755",
|
||||||
|
"0x11a3eb9fe3312950bf5cafea6c2b97818825db4389b8ae9408f9c7cb4882665a",
|
||||||
|
"0x12c9a214894557df9260fee1fd68af4fe37e63234f4b1950fb6302ef5c7602e2",
|
||||||
|
"0x19fc5d4620dbaeaf5448897edf3bcbfeb3853a9126c7b3c3d5b77ebf5b7fbf21",
|
||||||
|
"0x257c925a34966aae22eb261d58f97b43f255ae75fd0864fc48e492de7e55becc",
|
||||||
|
"0x18115b83ed73527d8c1823f98ae53c499a375f99a82064b270a54d35ea9f0ba6",
|
||||||
|
"0x1002ae120de1a1f4ba32b976d7dd4f4579381ca75f00248c5afbdfd80fe521a3",
|
||||||
|
"0x24230056009f5af1b7f585fe11ab1af1f4e0529381455573c76094e9828c7cc1",
|
||||||
|
"0x2fefc9ed5c4feb1474dcdd8b11184afdfb5c4663cf077c81c8c2f118f101c583",
|
||||||
|
"0x121991b5b076111411145f18534359541107182407d3981d463a10a6c04f5f04",
|
||||||
|
"0x161a5dc3f5e215684236c228529d96b6cae2af12fce8c281ae7c5ae13251cf0d",
|
||||||
|
"0x1b7cde8e1bf7f5df08a8fc322f21af95a44f9d782a5d74de4b12b3cac52d3d18",
|
||||||
|
"0x1efcd1c5767a2ce97fa08064888beb441feb80d799f939d284790268313e0cb8",
|
||||||
|
"0x1516c91480500fb959576c060a50df5e5c13b86e39089be8fad5a3017c19fef1",
|
||||||
|
"0x1a5acefb238a038e8567c0f8a98840870c17b9e2841f6de8a75b4ec765fdc74e",
|
||||||
|
"0x26f743f547ba08bb0a3800e83d37a508063c10ab415fd1c6b71fc3e642e27804",
|
||||||
|
"0x0439c5460f9710db5ef74e5e4ecfbbab6c92d81e1bef048af2ba990af6a96412",
|
||||||
|
"0x0b1cdb26cef7f77835ba81f23832acbe2cc8ad11311982f0b39d89eaa4ff3d88",
|
||||||
|
"0x1a4cbeea3894f5692512f2e13ce9034239ef5c203682750d0ed7263c3dc4a05d",
|
||||||
|
"0x1be2d5efb6c55e9b31ade0b3ca179410702f09ab5c176fd719adb145642dd2fc",
|
||||||
|
"0x1771f3273703d9c276b6be221b24044ad33a4f04cfc871010b8d1d7b461a5034",
|
||||||
|
"0x21042bc294c0c181f4c512a6a7d94f3c2782bc28a774ce517efb5c567daa30ed",
|
||||||
|
"0x0d3ea1bd94a88d6d2a0aaece2f577ee98168284e59138411c47702aa6e9a9df7",
|
||||||
|
"0x1b2ec4de5e50bbf2c918dce28e1291e7620f28b0cdffec6db9a3afb857d48bec",
|
||||||
|
"0x052fe3c5b2091f4d9cd772fb788288430ab43c404a9f1afd28f9e8a9e2b539ba",
|
||||||
|
"0x1ad58f9fd03d9d21c74c08dce54dabdd724b25ce408fe990253740a1dac49186",
|
||||||
|
"0x11c044f3e07c21ff4a93fd1056d54567510c622ae24cc7c454af294b4d5a7371",
|
||||||
|
"0x14dc6b7bab9b24d83ab458d326ccb312335c3526cc9dee1802ccb7eb0cb8ee6b",
|
||||||
|
"0x137cf4c2a4afcc4bcb58a8eda56f5223750a12b2d4e41a66727d797138fbde86",
|
||||||
|
"0x07d9bc2c364231525ac35618fae08284af5127124da38777326b4ced6e87a0b8",
|
||||||
|
"0x0f7ead7cfeb697ad5d119032f9e8580cf8dc44c8268402d866ee3ec4f66e723b",
|
||||||
|
"0x0bb18ee7793d2bd5a3b32a6daf6bce111c1ba770a03c8cb19214cd9315e6b381",
|
||||||
|
"0x234650e3ac2fb30e34af2d36dc407c891d2093232f6e9d1a5c212bc998560d45",
|
||||||
|
"0x2eb1745785eb34354cbc25e4d7d20866e97bf688aba5aab3462aa9d53c753308",
|
||||||
|
"0x1695af57d2faab4077ac86998fa44f39c1b3a9a6e8e3da91293f254ce12fea86",
|
||||||
|
"0x1b9c5539bab55de67a1feff373539bf20d74b975f0271a77fa67c923529dafc7",
|
||||||
|
"0x1901b13ce9cbfd15e91fafb059ced8b7936dca44e3fb3a59b9858f80f7e79bb5",
|
||||||
|
"0x302d415567eda49ff0c3dc812dd4f2f90addb3161b7fc6f604b739a8988e9264",
|
||||||
|
"0x1ee445f02ed077fce7dcaae404c42c72ce5c73bb60c59ed03192398330f27e40",
|
||||||
|
"0x14577b4a2afc653d9193cf40100e439ed67b26be2a9c1dcc4c53f29fcce478ef",
|
||||||
|
"0x0f70ff1275eec4602dcbdd315329e51316e39bcf6ce618b8cf49b9d0b9cfaef8",
|
||||||
|
"0x2e26e4b699b1fabd0b7bb94ae902ce38f8e4be6b723b02918b59288fe36c6153",
|
||||||
|
"0x0596a8f8be07116754d6b2664f7759ca2a81dcc3f05f89977e04b0fa3e424aa1",
|
||||||
|
"0x050b34c574517ab6ac58b491774c7fa2572951c4c0c0cfdbd1ca46242da8b48d",
|
||||||
|
"0x17a32f1c2ed7875f416eb3c3bc5296085c0f95cf8fc91429a81010beff1aeda3",
|
||||||
|
"0x08c7b7dd56ffae4496dad107e585670dff7919514bf2dfa8572df8d019938cdc",
|
||||||
|
"0x1041cb8c6d4155e3f11ea4f4dcaac28874b20400d511c166108580f5b4e1ea5d",
|
||||||
|
"0x1b19cb3e41e9c29970a4123c4d0c834f19216a277a03caceb457463bf353ca1a",
|
||||||
|
"0x2e4680a4ac50cfc484bf0bc75f064e0cce85e5bf037908a1f4e54a66f1ae9a0c",
|
||||||
|
"0x114fc9070b4811217501ab969073e570d01ebf4b10b3ce9fa09007aed14d7b3b",
|
||||||
|
"0x12a97a6552f3cb4aed117f029d2fb8a26cc6142887d84579404893055fce6be0",
|
||||||
|
"0x1dda8d69266fd4f1ce596778727e55262f555f158ba453321bdb34e18d835dad",
|
||||||
|
"0x1aeeba0b8ee533f104ef753a049e0495ab8d2832d271580be677568dd54dbc8b",
|
||||||
|
"0x087d80c02cb866a6e48757dd0715ae16de850983a156e249e898c0a099feb2c2",
|
||||||
|
"0x210cd88db2e56f4197fd2e78fce4a33f955fadfb9db3f3442b864016e5ff30d6",
|
||||||
|
"0x132b7ca535bcb9e3c5b2c218a2a6ddf99900436d2d68bc7c5a155715db5bfc03",
|
||||||
|
"0x2c101ab309253551ba608b65def31b407a7d13b157818c1f1edfa96a8b3075bc",
|
||||||
|
"0x25a13366ee7d2cef6fc1365c349f2eab64dbb154f492885d950ab1494868125e",
|
||||||
|
"0x2f1a3b3695d525788fddb27219d3092eb8afbbec37d5e097bdfb1bcb1aa9bdf1",
|
||||||
|
"0x12eb5e560c681856fb6af9f6ea072fd7eb82aad57e88af7bfc7f0b075741efcd",
|
||||||
|
"0x11581e2e8eed45d13baa42e711b93639d3ae5247c69914272cc2ff6058d3acf3",
|
||||||
|
"0x0c0c34dae8f3bf7007564fabedd283cb025d64f4e8f88a47b4e37bd89b5c6fd1",
|
||||||
|
"0x05b47ec45a81568e0730df30770377053d5465341d3309a87fca8604fd1c35e4",
|
||||||
|
"0x09755b27f172ae86cffad94e78fab9d8b740d6891efe2cba55366e61c0c98206",
|
||||||
|
"0x0600a9f4ff5c9d8bccd4952029aae6f6e2004d7baaabd9040e3b4216e2cc4041",
|
||||||
|
"0x2864302ac98fdbe4a29cc57c83ee1b60e0a7ef59519bf20a556d7b77a0bdbf38",
|
||||||
|
"0x14a0943541647294c4d0442506d1896c909ac78166985ffc45a933b4c5a47f39",
|
||||||
|
"0x14f026e852ce5c5fd9a55741e4e33d0a6d8d45ea190894530871cf9803101b20",
|
||||||
|
"0x0b7ffc49fc5601a646564e4327ecf8061ff6f4982d5d6dd85699e6a589f59861",
|
||||||
|
"0x11ecc2afb666b89fa519954da8f1e775a16657786839dd15ce4e18b6114a17af",
|
||||||
|
"0x0266048d728717bb6736cec6bb53a48d53c34866376fdeb1368616540dd57b38",
|
||||||
|
"0x05d0653ece676b876c63c85abc06d14e4b4fd5bb959f24ff226aac3ef33c0604",
|
||||||
|
"0x04888bfa7c5cd40a493a9089b36341207c2302edfd283e723633e335ed4839d3",
|
||||||
|
"0x0c5df4b6cf3b9215e3d6342ffa2df33ede670db50dc2477a03d6d3063e64fdd1",
|
||||||
|
"0x2cdb43576702ed93262567dc50237ce620a628d4c3e4eba9eb863485db2a9a4f",
|
||||||
|
"0x1da473b175874ba5f44bb5ef6136b6a4e817140aa5d5fb30d7a7e4f05af44e5d",
|
||||||
|
"0x17c4bddb0c8bf05980c312557057790f8e9aa1345d0b2b24f652a72785199f16",
|
||||||
|
"0x156ff7be6a05828d933945b04155dd3cd1070d810843b334083850a8de293d73",
|
||||||
|
"0x0d37d0e3108d1f3f1b1677dd4174acc0afc962f54215fee14e32bceb8337aa2e",
|
||||||
|
"0x11ddb1a440a4d076942d52f68bf0ef70800aec60ef150216d242abdfa84b5c97",
|
||||||
|
"0x163bea67b48bc43fd3d96705cbef764c4db1b61041f02510abb546cb6dc4806a",
|
||||||
|
"0x22aa414c469933375bf3b583210ec1742b997ca4f121f62df210056624ecf304",
|
||||||
|
"0x2d7f90267ae5b326c3d007fac1f761190f1a2d2213c8a1915057705b888b3b42",
|
||||||
|
"0x103fba0819fa863fe82f18070149ed5b059825ca663e57ffc8e025f5f954ba9b",
|
||||||
|
"0x043ff968ce318a4219dc8b1b3e9b1d0b5770696dde2e8b6e4f5ede0cc630a4f9",
|
||||||
|
"0x0b3ac488943b0685151bda44aa6adb5b645fdf95d63c25bfa118729900b69551",
|
||||||
|
"0x1151bf21881610c2a1fccc5f25a8d24aadd5bab7620a456f542d2a27fb9d8333",
|
||||||
|
"0x0bfd02387911be559bbddb6072937662c15b2a5e2c190a5364f26ccf51d04def",
|
||||||
|
"0x1e23be22f022d1cd8a90938d552875a52efdccb8d51bfcd9993bae65f19f437a",
|
||||||
|
"0x2d64657d2392bab3d55a6f03f876da7325eaa8b26d4627623ee323280150d5c4",
|
||||||
|
"0x28398c2867f3e75c79a3d183ebc74757b0dbd5976375d5de3c4643d4696f9bba",
|
||||||
|
"0x2fe98cb56d56da5166550e3d62da69427818797fd678eb85548b3955bd9a8dde",
|
||||||
|
"0x15f2acb43b89e025ad031c3331b0cfe815ecdd34ce38c164d4ec65c1097fc152",
|
||||||
|
"0x1dc5214afb325fc97ec49b140c7362e48f916b5fefff40d1d4357a6e8a64afb1",
|
||||||
|
"0x0bf98e88782e75a8ce25deb8208bebd3dcde4a4d8c0d7c95b320f98ae37bde87",
|
||||||
|
"0x1c8e78dbdc499fe504d6637fb592695048f80d471e413f50cd13beb6008a8391",
|
||||||
|
"0x23445d2bc07a0705a84ad107f5ffef149f3deb0dc8993dff9ac7cb5d307cd0e0",
|
||||||
|
"0x165455fb86eb06686440c8c2289c446541e676341d95bf85105d08e994a2c9d0",
|
||||||
|
"0x177bd958941329e30138b30781b1686c1531212a075f0166494b226bd667fdda",
|
||||||
|
"0x1d9cac387b77178d0118f881ac7ca94f79cb8052a59235a42cf869b9290da2f8",
|
||||||
|
"0x294c0bc45d475a1175b9d7977763d26b155f39c6043ea67c7c528bd0ed4e7bb5",
|
||||||
|
"0x2338a930f2cae293c3dbd1386d74b5b7d88b8ad739bd54ae5d720fb697e0b5e5",
|
||||||
|
"0x1fb1f893d955103c39e9f5cba64bc7ff4a078f73f386d9c070179cc279881f51",
|
||||||
|
"0x04e7ce1c09295df1f4c16216867451d9424f33ade5e0274bda0cb417a729a7f6",
|
||||||
|
"0x12f5ceb80784cbc5631e1ca115f5b55dba3c4315cfbc4f3488eebc776194a3dc",
|
||||||
|
"0x0f6f9f33c1f40f141caea00e1b2acf51f41fe58ae14aa03ccd7d926bbe02148f",
|
||||||
|
"0x1be83122d94ce0deed510a78f30acd81764a4ea1b13acb7ad4ea3d481d4df954",
|
||||||
|
"0x0d80a6a155fb12ca328331a46dc758011bab2e4007a5e9a79b5d615131d3444a",
|
||||||
|
"0x194acfa387c01b063aa4a33551ed7cb9a5a217d4ffd0ed1639140db2b742470e",
|
||||||
|
"0x0b33f09047bc972a94494173ac41f3d7df5aa1fdd42d7217474d531e8ef6af68",
|
||||||
|
"0x0df147663bc28d9b200afd361dc6189a18b74ff6e4ec99c31d7f47db967a41e9",
|
||||||
|
"0x2a4338b94beca683c00f47c48bcafcbfe66babdaa51b27ffb32d17378aa78597",
|
||||||
|
"0x03afe0efd0394501f0fc763b3f1019182e62c0255e34d82a76719a5c6dcfcd06",
|
||||||
|
"0x1e1d4dcf35b59905dc2275f3a37f84b6dae9650988eea92180aee8f45fefba5b",
|
||||||
|
"0x2a4ae8053cb5aa44efa7af3f76957e572de37def354c04ae6eb0e17dc9f38012",
|
||||||
|
"0x26b6da57dd2d67f63611cf269d31b28080a92b00567894e3d56b6df783e02ec0",
|
||||||
|
"0x1d0b3ca820d67c20f0a83efd9a9c50a5ef2183813dc4d658329fe39435ce5710",
|
||||||
|
"0x1505b4c73b4b6b7d0d0e84d1cef6b86bc62c0d6eb3c745570ab1beb0669de635"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"0x0769209ddbe93ac17371b60ada48a8b0baf8c2df826d0c60791701122abb3647",
|
||||||
|
"0x08ef53e225e568f8c2957adf5e2418106f57809c8370793fb3ccac0eb9c4ef12",
|
||||||
|
"0x0f67730966f094a9ae0ece540cf1ed527cc31c5f161107ce2146ff11f6b6dcdf",
|
||||||
|
"0x2a2c892eca22e361229c79ac5dc2d9aab2ae508ed5f70b9832f0557ec40aabc3",
|
||||||
|
"0x039c7ef7c29f809073e30f2591c4ff9858f8d498e233f3883dacd7d6e7570be6",
|
||||||
|
"0x26ad7dce66a9a95a2b92d1633da3f33587a46117f4c26bc642c808b86b925a50",
|
||||||
|
"0x294402ea191b6b02d558c2f860e6e11898efc5cac4214d6eaf78bf046b424da7",
|
||||||
|
"0x200cc1d8d4d6f4a22934248446129b2082ebcac73dc9477599f5efcd8f092b7f",
|
||||||
|
"0x031b696ba36be3334afaa13168f5a212cb222a5a43dceb67ef2f90def1f2a3ac",
|
||||||
|
"0x22405ea030cbd6aea6efbc202372454f3cb7315bb24ec7d273569499cf602072",
|
||||||
|
"0x0e892bb94be4ddb0e13900727efbe6545a7cdaf7837d2e8aa91c085416f4a08b",
|
||||||
|
"0x2884ab441638fd7622aedc70b5a338450962e57e801975a887c28608a3f6f3d8",
|
||||||
|
"0x2ea66506abc2e2a5536857d8a372510a5dfd44005813a53d13a83eb3e30caff5",
|
||||||
|
"0x0fe3e93c274dfb0164a3479d77be40f51fbd808a27068da1e6d633566f5ad4b4",
|
||||||
|
"0x1b64728c657615de184eabf173ebd624e2eeba23e04c4a818be2e7ceef50d2b2",
|
||||||
|
"0x2c5d33d430dfddb329dab768eacff9d0be4dc9d638d171a835b72f2630fc07a3",
|
||||||
|
"0x00775ecd42283f8a4782a1a8e101c59df926ecaf123c83a569872cc8c1e3e955",
|
||||||
|
"0x2dd915162db8286e7863f207e5116c30539aa05753fa157dd2f3b07b6dfe11d0",
|
||||||
|
"0x1452f77a0c98817d3834aa29d6dceb1fd078b8873a02b33e650d3d9a463f4d7d",
|
||||||
|
"0x2bc056180a81b77fcbbf620aa8453ca644931dd432030390162525a596bc380b",
|
||||||
|
"0x0b3c1e2cb0607e12103406681be5635236551aa286f2261ec88f27a7ff16a7a9",
|
||||||
|
"0x1e7032ee33c3d1fa6d8d24f1307f53cb33461822f2717913ca654c0e3a13ab04",
|
||||||
|
"0x0bd2dd98fc4a8af526799f197c315857d71b0740f9a5274c4e3c4e269af0718c",
|
||||||
|
"0x142e9259f139ab5b18345dba3b11d4ea7ba6483cf28163b603674527073cdc2f",
|
||||||
|
"0x28bc36ae9e257061fcab76ad2114d96f29bdc78dc36bc65bc94328213e5ec615",
|
||||||
|
"0x274dedce47e3d3ad192b0d48e25c1e83c68d78318d2538d787b3a79b143cfaa5",
|
||||||
|
"0x172ee8a327ff74dd9910f098513499eace293d9276dd4ad9b01bed9a5fdd499b",
|
||||||
|
"0x27e7c5263cf192368bac114666c8adb002a01def45fbf084e3fb1781d37fa17a",
|
||||||
|
"0x2bda40b3cb61f7868ea66a588423000121bd08ac139e5bb92717fd427e15bbc6",
|
||||||
|
"0x26fac827cf9e87cd9f46a055ca32db3055c68f8e7097f1907b27e78197f6c4dd",
|
||||||
|
"0x271e74c38c0bc0b5f904e1459fafe0032ae2b3a27679fb8bdf8fcfd9294ff1f5",
|
||||||
|
"0x25da79c356d14b424f40e8052b8168c7dc4d938d181c2caaca27619f12d210ee",
|
||||||
|
"0x1e699abd2c6508eae9bd6a9a282e5513c003dd642dd262d2e17f79f09bdf6bd9",
|
||||||
|
"0x1ee81815c3be0406b2a9cff25d6f668d9ff89d3f795ca260c7187547cf09e79e",
|
||||||
|
"0x21c26c8c318b88a969c93cd35c7d227fcf0d69867238695726f90dffcf938279",
|
||||||
|
"0x14013837d5e3e65ea5155e016e3bddcd575fd584e4e61bbbf295f88fafd8fafa",
|
||||||
|
"0x154198f9c749177ed41262a5906028d7fe7ac4c6c808865a85816ef44824de23",
|
||||||
|
"0x1e59f9ee9c83ee78c55c6bec8201f28966beb0c5c11b54ffa01c6451f7a57210",
|
||||||
|
"0x2558c2e976422214f0dc5a2d2ff180de2628f1a18645da52f02b5e6f846f9504",
|
||||||
|
"0x0043de4604c7bd1ced85922717d06992924c23f4149f844be9bf6dd9c60f3388",
|
||||||
|
"0x282947ab201839e628460e16d3d31fad868bec724f263969b3d0c69e9e8bada6",
|
||||||
|
"0x0a1ada5b5b5018481015fbe3c43c38b44c7b67804f50bbe4952812372603c935",
|
||||||
|
"0x12d7c76e2833a9f8f57a17e7118ff6666581503026cc1c7a7655ccbb514e516e",
|
||||||
|
"0x24576880cf40f29a0fc19df8ed0239cfcc150e11b800aa880f6289bebd89a013",
|
||||||
|
"0x1c7590758c8996f2119af7cef10df7c1cf9d8c1dc388975e830b50680b09d7c4",
|
||||||
|
"0x2c9096f0f659ee66751cf179cdfe5af5470c6845335de41a3ade2111d9330152",
|
||||||
|
"0x0ce33a79644c079faa54139a5074943790985a7c6936aa2d3ea97fcadb8d64eb",
|
||||||
|
"0x0ffba00c11bbb7e6070153b817c9ab5acaeef3306cb05bb8feb5d54fe89ff8be",
|
||||||
|
"0x15a15cc692ed7bf420df399c9d14e5ff9758a6c7db3c5c097063217b4c6c4f1f",
|
||||||
|
"0x2214373b87f53cb1d4e91aa21d2e607e83c7ba2a61de8d32c54db7050e9fc17a",
|
||||||
|
"0x1f0ba195d267de887b51cbdc77e6c77a5c055a625e76c5a22ccbb8cc9bb15539",
|
||||||
|
"0x2f3b29c072d8cd7c1a673c6759fd58e34dbc2075dae7fd5ebde784113d61755a",
|
||||||
|
"0x23df997a7ef29ad9a5fc7cc21937c9977a73247434821ff60b31ef0170ed17a4",
|
||||||
|
"0x1928275de0e4fb64134721b14ab3d99f94b1c268368c1167b2b39ab30e308972",
|
||||||
|
"0x2bdfec339abdfc11fd5a9f48dceef79a463be5074df37bf00893c83f4b20cc0b",
|
||||||
|
"0x266134d4d26103883f7f429ed07fbed19bb0e17904cf03eda9da117f8c0f4e1a",
|
||||||
|
"0x0471a32e2cb225ba86c91cb136309cb462d49c9045a4d4d61e00de27e6ae3ea4",
|
||||||
|
"0x2c56d2388857121e91cea207347f0e5449b8f7d4bfcdd0c8d71872a5b223ba58",
|
||||||
|
"0x2acc967f4e0cda77f4f3578b2e463848895b31e7607dbe33e8a1f92a17ff1f2e",
|
||||||
|
"0x1a891c55471f9da7f6d6125219a3b47eef6560c0fd64dca3177e1efc9b681267",
|
||||||
|
"0x01f6674fb43a263d7e6bc9b5c02264b61fe779d65e28b68c2b4db7cb39cc94df",
|
||||||
|
"0x07bd8e87fd3c9d91bc1341cf7edde51781bc51834aa0e3b6a57a830a7e93b83b",
|
||||||
|
"0x17d9fa87ca04d5451aede41b787ed0313aeb5f1a5f4effb914820aeacf0af8cc",
|
||||||
|
"0x0793d4a71e22db2909586a0caeb15bb2edfa0eb1237ae62fa90033d45c9921b6",
|
||||||
|
"0x2e36dff4ef06152e28de7355e3c5e25f10c0da1dd9c639c7aea03e6d8c2e27a9",
|
||||||
|
"0x11ac31fa48899db062624788cfda7840b346854f90dd5a45be2496bf304e6131",
|
||||||
|
"0x2655ee18d2a0ff7ea24b51fc3d465eed4b5b579f0d7c8c1ee1c0e385f53ccfa8",
|
||||||
|
"0x01dfa376e1f3fa01a5efb6d4c79ec70fbc7a07a7ee7458f879da75e64d75ee5b",
|
||||||
|
"0x274eed37c69fb44ab5c9da14719d85bdde627967d14d460c7d44f7f32000d1e4",
|
||||||
|
"0x04fae3f7994206170e657f4064b91fd43f7f0a5542e333dbabaa60e2470fbc60",
|
||||||
|
"0x3045e0d8b192fd61f35a9b5369bbff3ae2cd4708ffe02e8f919230e428c5761a",
|
||||||
|
"0x14c7c2e746ce0b0f805ac85a3ac01207c9930368f4e8729c4248b433e845c794",
|
||||||
|
"0x095e5bc71d416d2301417d3693ed6cd5685af11569e2883f80756e683ca609fd",
|
||||||
|
"0x29c47dd05c547c0f3c194d5bb37ad7e1ba31a6ca4949da0224bc516986b61c78",
|
||||||
|
"0x221da684f92fd8f01d335437a5d5594849cdb4c0d3e350b2ab9a29e6e6ef93a4",
|
||||||
|
"0x20ec5172b4edcddeeb1a493cbe2e5561762f2c1d4b41b438bf04bfdfc0402f69",
|
||||||
|
"0x1b9bcb2aefaebc677c70fd0a4f38c87dc9a739d39bfef6b23b855b1a2e9724cd",
|
||||||
|
"0x098af3612282c3b93c2c3d782d4731b5cb5241cde22dc665230afd82ff5aa72b",
|
||||||
|
"0x056bf5e4248f55f2e4c5a800dc1086d82ca98cfd2c4be973e7d4685f612050e9",
|
||||||
|
"0x2eca3301b4fef07d2e51ae33d6e98033141a34ea1f9821529e73de6a8d67560e",
|
||||||
|
"0x0ee44ca475a08ce1d7579734cc1ac2ccab00dc92828df9a0a16b17bf0d040f40",
|
||||||
|
"0x061f484c4e6fbf65812ba4a08dd042b7be0148a35b79c0baab82dbd129e349f2",
|
||||||
|
"0x270a8d9040ee78734474a3f1c03258cdde4eb2774909520ac95056c48b471d86",
|
||||||
|
"0x24e8ea7fb0806e1f548e34b85f61fc93f6a33106e1c2837f26900261defeff5a",
|
||||||
|
"0x17e6f76d7f71216caa967230ba0d20b91991131c31fc03a77a0e4346fac0cc47",
|
||||||
|
"0x218e63ae07ab39824838ad7423b262f9231446669bd64596a21692938f5fdbd1",
|
||||||
|
"0x04cec38dafd7be3a0aad26b24b100e25977ad1d6ad471922e39211e54b5b9d78",
|
||||||
|
"0x14496b72f8518bbf22ae5764f4197df7eb2d4cce04eb2caedf606f1ea4183ab9",
|
||||||
|
"0x0b15601fc061a468459830764b59a565feeffd1bf6a536f420a7a3e0b7d6ef86",
|
||||||
|
"0x01955c37d5e6e42ab82c2a57ba398d10f90446acf0d1a98910db6fc7d56524dd",
|
||||||
|
"0x1bd6de8dc821a746020210e1e5f3dd6dbb41ceddbd73f7d73410181a8cc74d09",
|
||||||
|
"0x05280c6d461eb9d7967ac91f4af334607802b8db12e141b33a0e30217b693c44",
|
||||||
|
"0x159b199ca401c0c9b8248631bf39d7d35083b5c2bbbd0d871d3d0d4f3cecc368",
|
||||||
|
"0x248e2210ed2a826c83fbd6c235dcbbb3d24a7badce71702fcaf08f66b785777b",
|
||||||
|
"0x0c43b7f0265074447850c22cd3a81726f053f490b261dddc1712ca38a3ebd1b6",
|
||||||
|
"0x1ae8d611514f4d9e3750f4e66e8c2566e4842b6505e19c45f3eb051a7b6d8bb3",
|
||||||
|
"0x18eaf3e459dc8ba7d98d3cb2c274f8e902594d4bafebc0757dce1eed8332e8d8",
|
||||||
|
"0x0c7f13454b2f73791edea658be8d87c6dd72c3c7d26d91182d9c8cc87182edfa",
|
||||||
|
"0x16e398c145af7ac01167cf56440dc93eaa837cff3cc468de6029f5613270f964",
|
||||||
|
"0x0a7736c58b3771a259cc813f727d9c7fff087354542175eebf7d44e127c30aad",
|
||||||
|
"0x13684f6a837c01e824cbd026b6d8c4e61b98df6aeb62d1142df389894788b5ee",
|
||||||
|
"0x0c4b1c8e9801649077a17bb8eb2d995b3989780c3af7f651004fa2d3f1b8865f",
|
||||||
|
"0x173602d42c0a38489130960549542bef693e5681947c48657dfceb41b0a6606d",
|
||||||
|
"0x2389dddac6b2890c7e30504b0fc875ebf8629325206958b69c55c9cb6303edb4",
|
||||||
|
"0x06c9ca19714c42cc7189005cdb51ef7b2f07484cbe0c151d48c46d47b77a93f2",
|
||||||
|
"0x167b108ec7a36c0e1bcf9c69e8ecc5a189528813f1737e80209ac99c462159a1",
|
||||||
|
"0x1871a5f48a8e6bcf2319360dc7885cb1aabc505a3b53a44494e2fc400a62d370",
|
||||||
|
"0x2e59f862747c1ff8fb961836ce770a2aca5f3b4e0e83e338cd599f9c4e35c1c8",
|
||||||
|
"0x198c87cac3cc736412bf0d8d2f3a4672e3ecf503b4d7d2e40258e8e64e3eb72e",
|
||||||
|
"0x2b36f6f2c7130341b2c699532d06d98da2be8ad3b8556dc1bf35375f2dc2cc01",
|
||||||
|
"0x05ad47418ed404da00ae2493c6c532f783dfd5adc7c4a0f2fa1d60c0e7f4b82f",
|
||||||
|
"0x2c07656ed2a56f41ae7d387cc0213f440e102742360c44679a6aad8c8263315c",
|
||||||
|
"0x28fc3ed801e80b8f745f860d2f57447700d4470e31c1ecf0b1f19240085d3218",
|
||||||
|
"0x2315de5587a5ab1b774763401f71ac6e796055ad5633300abd2e63446bb87563",
|
||||||
|
"0x2f1f3fdf187e2a6e34a48ec9dc8838b188053dad8e6008c01f627388c8ebfd96",
|
||||||
|
"0x0c72edc09bff0911637af2314b12f04aa1ab2a8936a0d0932f129bf1e666e1fb",
|
||||||
|
"0x2061a56cde9b94de146617e1c2d7550a8f1272154eea488149faabcc614ecfb6",
|
||||||
|
"0x24efce7c9f9dc595ee0286527b581cdf659e5721bd7707e06580f5cf8b0cc513",
|
||||||
|
"0x2fbb45e2d316c9e9b974c081fda1418bf8de14ccae39daa6532e5e2473ad9b95",
|
||||||
|
"0x0db1fe4767ca51a7f940cc68ddd576211627ae28319f868ac47cf81163856da5",
|
||||||
|
"0x07d7947f75ca7eadc86debc9d876cb2421307bbb5518bf82c0e27b2206afdd83",
|
||||||
|
"0x301687b7aad786b2c3721f665fdf74b8170ab8650d287f842500224e93146169",
|
||||||
|
"0x0231c466db088e9f696b9aa566fdac7207155e19d5fdbed6524f2c1aec5020c7",
|
||||||
|
"0x29c11de1b503f5da4bd8b3c3db5fe7d37b3877ca51ad0dcad95152ba819fbfae",
|
||||||
|
"0x0101217cfe53dc6325a81eb7e920b198a1560cb9c7e5976443860a143f8445e2",
|
||||||
|
"0x29972ac040a02f55d8d0fd383d0ba147375dd71132b1a91f197292bbe424a41d",
|
||||||
|
"0x1a7bd39d6d6bec6cf5ddaeebd174bc8eb5b98d0cd36ecdd28e1319e745ba18c4",
|
||||||
|
"0x0c59b48dfe53bd9fea14943ccc317baab6476d230d29b69f1f6fdc8a7a4e0b80",
|
||||||
|
"0x16310faca95189f36bcf9855861205fe1af9940667db087684c76da61c759a11",
|
||||||
|
"0x2a3ca21c40d5bd4edacd339e5ac480354abfa781e43ab96e04c36fbfc9b96991",
|
||||||
|
"0x03856e1b9ea7eed963383320a289f8e4434ad11184075ec48441b07a6a996cf2",
|
||||||
|
"0x14bb06da170069f2075e2e98779980f8c25c9afa09b6d9200473b0b4be1dfd0e",
|
||||||
|
"0x021f6235693e64c3e04019d980f130a8e9e0463a06f20f7b48d70d4e2767df40",
|
||||||
|
"0x248a11d422e2ba3824f403b12bf91f7c3e1f4cd7df0c8d926f4db7ca088e88c4",
|
||||||
|
"0x27c83f0074d7f09f5c653402f14e6c237ffe6dc88517708d1a6f22f8fcc5eaa4",
|
||||||
|
"0x29d69c60e82302690ee548e134e3472c4fdfc0de1980b05a3b16f4bf90b75df3",
|
||||||
|
"0x16263dd56b3a5d8e1adf78537a59edebe9279a666be8376c0f857dbdf619b3b0",
|
||||||
|
"0x2faf509e27d009d539ded46f4205be2a4d07990c6c3adaec2774d29f211c333c",
|
||||||
|
"0x00636fcd12c4cea57010606a3032ec57759c1ef7857908bae6f478f2ce6b1116",
|
||||||
|
"0x1ae54440ec1448a756b6d17eca423496fc01981d625130f0a34b16406169c628",
|
||||||
|
"0x087f48ba394023dc06e837328fe9c5c360e8051f7331008f55e6efe703a6e670",
|
||||||
|
"0x259f66390c6850db70bd9baa0a9af2544f5038fef029dca5859c498359efcdde",
|
||||||
|
"0x1a320b174924a92e7e1799f926b1a4a8613469713df982d4feb17c469c6b3132",
|
||||||
|
"0x2cda975460540e7dab62116c6681d9687de10a80135949380a986da2d3b6a93b",
|
||||||
|
"0x2904eabcec7a95c537f59bf4ec25cb5f61050bc4b385af6a7ed8dc787844e00b",
|
||||||
|
"0x27ea9cb045a66580707da6934884df14aacf6f77e4196f940e022d3c02962f4b",
|
||||||
|
"0x2afd7329aa726b450e0687fa7661fcbccd1b4d00f5c63ff56cf71f6e0782b351",
|
||||||
|
"0x1f70cb2a4b5c22e7597556b55dc9ab3c289b63abb49109e64b3731c4cc899d02",
|
||||||
|
"0x09d2c500e798e9bd5c97a43a905fd18880ec3ab776c34ae975cd5820b5be6a71",
|
||||||
|
"0x187868870b76c4af4533bcfef9cfd3a26e89326389e87f79b23f986ef6546b36",
|
||||||
|
"0x20cf61235eb8a2faf09f62dee581d48e756b7f6f6b0e108abec7d1cb4c340523",
|
||||||
|
"0x06431aee16b0fbb9a402325fe3e1c78d03b49cf7211b78e122607f24906f74e1",
|
||||||
|
"0x0ea64a8557885b201149fed02d32539d2270ab155012f543419d66e584f70980",
|
||||||
|
"0x2f989e96ac7353934bd8333aaffd25900f6d4b78ed5b50d832e35915f20e3c9c",
|
||||||
|
"0x1f2357fea7a406b651ea80a7ae83f97248b2713a15b689d6b694f4a04464ac3e",
|
||||||
|
"0x091eadfd9e583cbf346d83b894982a75f827c89bbbfd6473dba601cedbb13dd5",
|
||||||
|
"0x0c14fd42428144b7b77b93340103fe047998e9c50993da3ddbe328b8bd804f9e",
|
||||||
|
"0x252da7206be17596eb2ef5bfa94f142b39eb9fdc7f7dc3bda16825e7ccfdd8c1",
|
||||||
|
"0x2ace67f28e90ecf05b00aca160ad0e5444d3397ef40640081864803a63747e1c",
|
||||||
|
"0x207aef533b735e20998f6b54574293f8b0e5479e32eff2dc6ea3fd10414db107",
|
||||||
|
"0x09b3080dbe8fa12b8eec5edc0d55d87fa3425ed591daaf8396f70421b1a0c35a",
|
||||||
|
"0x1003dc28c13b5737df9ce84ad23480f3393de6024b095ba842d9c8c3d7168a8e",
|
||||||
|
"0x23618fdc2960f9fa296e65a926573ae39e2c442f819c2ccd2387c1493a1ee57e",
|
||||||
|
"0x1b12fa3a918da62249968385c65552489c76f8a808f5b28e5a3b1a76a25a8ee6",
|
||||||
|
"0x087a632fe1f540ecf61722f036f3f6863ae9e5a093da6d4f57156e2e8c6f5f9d",
|
||||||
|
"0x2b460380d8151ee73eb997fcb89f9b0d63a210ea8cb9f23ae4e0c75346d89a0d",
|
||||||
|
"0x302e06a0b308b3004b980eece40bc80cdbfd863a284e643ccdb22c359af19241",
|
||||||
|
"0x13dc02643f54245a7ec529481d59e849f7e82e4328a4f1b0d916308aec44f20e",
|
||||||
|
"0x01f9ea46bd55b9f52acec310f44a71a389a5ecb20933baddbe29699a70adb6ba",
|
||||||
|
"0x15c2f7ff0464ec096a3c89e8a6563afc7d290bd50620c57fe0c3f8e2667ce224",
|
||||||
|
"0x2bb074ae7bd782f9a3aad78192c58d12535da87bb865936065a1c2d8bec0cb03",
|
||||||
|
"0x1afb2feafdd6b4b18bf120c1bd40a0661d675cb6cdea4ffb935550db66613f66"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"0x2f519d236ff3908aeed8bc12b6e3204820c18780cda2aa9bf32a675722a943e7",
|
||||||
|
"0x0d463eca09295bbf17ecbd6c0f1a2ae22e9e971abf332b50f6dc652948130ac9",
|
||||||
|
"0x04f7b92e174673f12ad94305e211dbc74505cea331c8270bbc0436cfd3f9203d",
|
||||||
|
"0x0b9ce1d7a1d5702d9cce533fed0eb4efa2d3d5adeb056a0bcfaa8df560e39d65",
|
||||||
|
"0x05fd9a940ebf8c4f6365146a71cc4d60792afcfe5edfb289ef3a5e0ee7171df5",
|
||||||
|
"0x0b5644601dcb7f359904a3be22a6726d88c91c83462e2a96eefcb2e0d3aac3b2",
|
||||||
|
"0x05270c934663d155aa71e7bb2c9bcc6d8dc181ae02c779a1bde958eda5b61398",
|
||||||
|
"0x1ca3acc7430ca47799891a4c459af74a965256eba9d6940381c1d0bf0a9739a5",
|
||||||
|
"0x03db72aade768b78c7a6a9ecda0f0f2c6733a0651cf2212e174ea97c01a59c70",
|
||||||
|
"0x1ad0aa205be150c5621b3fea98b78db2e4b20fecf80034c52e9ae558950dc780",
|
||||||
|
"0x041dddc69336c714ee7cb998b68d94c5232d4e8d1deeca05ce83b0ed0834cd3f",
|
||||||
|
"0x2b3e015174c3a6939f08df076b3ba73bbd4f2452100c1821492321175d162b1f",
|
||||||
|
"0x238e6389e5fb2584c06ed2f534d4d9e2d5d62bb99dfe8add413d809fbdc754d3",
|
||||||
|
"0x15f4f175fe2ef1101a4f0a34fb73acf4397c3379b1c2924dd94b1dd4d2c6b27a",
|
||||||
|
"0x04fa37d0ac02626ecd1f192e28acc2ad80f3de4354aa8ebe87471757dbabc9e7",
|
||||||
|
"0x24deab96a4e96719adf665e11c38a3334d9b47643171a7d814b9dc6fe7382d02",
|
||||||
|
"0x0a2c7eb8738a61719ce05c72547cfdce9f6ac8770cd64e6556a06c7ae86610c0",
|
||||||
|
"0x199482b63e5fdf185628c3046f0bf2f7be5d0f256ecd035bc212fc01eea8ffa6",
|
||||||
|
"0x296cfc7f739a3cf4e9b75994056e2568c6aa52b8333520627bd6b28cf484de9d",
|
||||||
|
"0x06fdb5a0e6f4e2c7e546bad6b1669db01d9d4e3bff4ee772507563da1ed92dca",
|
||||||
|
"0x1216f1b2f749f561078eeaf1fc60590a71e33157d0227ac8e796a4042e945ba8",
|
||||||
|
"0x193fa4aa12acc79be80e6a2424afeb3f4d249566e8a0908c908761758437929e",
|
||||||
|
"0x12ad33b11810144865ae5391c8f266adc3fa0adb622b90c2ada406253e09eb2b",
|
||||||
|
"0x1a90d5e1c0578c066529c54f8f37e23109de9159e298cb6c9102c6ccf581a07d",
|
||||||
|
"0x15af9b019146d04fd7db3dcc25ce29d163fb604f5ce11b8fd507089a8660095b",
|
||||||
|
"0x124aa9d20b2a15ec73fc6b6eb84b544edc13e9a72309ab080e362563881eb8ff",
|
||||||
|
"0x183cf3432c6354e3bef6170a32fd653b560748e59b65052512125db3b542ca7a",
|
||||||
|
"0x263159492b9a836f8d477e6ccf6f2dad9d4bc43eea7241f224314cd356fb07eb",
|
||||||
|
"0x2ef6717639f7e6a2a0c60da01ce73721b83f6f9fca63ad632a27c5e0d561dc26",
|
||||||
|
"0x1b85e4a891411168c803d411048f946a167f45edd0b98aea0e96fcf9796a5415",
|
||||||
|
"0x1712b6d3ab45b45a1a43bbb23ac830235f8fa4c6c057be35b84e77ef366fd89b",
|
||||||
|
"0x2e97c862eb257de5ef4f71b56bab12b449b3186cb3f4c44ff32c931bd9c3108a",
|
||||||
|
"0x0500ca19f7690358b983978382d969729008b41a902b03c8254e8a4b863ebe2d",
|
||||||
|
"0x25ecf7468c3d34ab9aced95fd7f966c7e7fe7ed74ac02c2f33cbf59d182c169a",
|
||||||
|
"0x061493f05adc4813cb62ea6269e2672c241b4ce0e3658542e4bedc660cb832c8",
|
||||||
|
"0x077d4ee2b3292e73eb891b51f63b0fc897ddf1095208c65a291f470391eccc8a",
|
||||||
|
"0x2a1ddaac93b561971f9174611a06273671f80dcf4eb355636577a623f2267239",
|
||||||
|
"0x28c9d37bc63119f5b846f969452d93c78743ed7c769590d1e2eaff2f7d51b636",
|
||||||
|
"0x1c12d6672a7c9c525e1ad06e91be238291b6a452298c3f0907b3bbeeee33a75b",
|
||||||
|
"0x295813176a99d708f66de0dd6a79790c1049113c1a9589f58e29aef2431dc3d0",
|
||||||
|
"0x11cf1b0b429cdde5235a2fa4044a75fa29d464d422bcec4cd5a77b2a70996952",
|
||||||
|
"0x26cd23abd3084eb97652a0bdfa0675107c27d021a797ffd85c3935035e82c708",
|
||||||
|
"0x0c98e951acef5ecdf322fd11adf84e1237fd7a2856f5d611185677e064e59a7c",
|
||||||
|
"0x0f65e0d787c7a80daffa6fcec8e4333baf1b7e536dc26da1617bf8d33fd571ea",
|
||||||
|
"0x0a6af46169c405b7aefa2369aea2437e83a5f936e21b2c5bdd40c4c229691035",
|
||||||
|
"0x2c5d17722f1e857bc53fb954a1c617be89f79f666e7d42e5cd289bd1f6c2c253",
|
||||||
|
"0x05ed375b0a7340fdd67b5a6e02e9d7f8cee95207cc1f021a98c9f026b6b8263a",
|
||||||
|
"0x05c43b6a0449ae8aba7f7ef495f81f9b1172e2e33d6b45641c85ac438f867072",
|
||||||
|
"0x0632e9aaccb645ff09e9a71c0bdc98bb8525d16dc0808089288084dc6a37239d",
|
||||||
|
"0x020115cdd5958aee185af3281eb02700cb22c680fea57e0e24ddcfea04e4ce44",
|
||||||
|
"0x130ed2b41ae4fa1bcb39907d9213b816fb5be6f78c8b33f81037c6c82351ad6e",
|
||||||
|
"0x198b2b80ff15fe2af3c414b89c4fab453017cadce1b42986a9064069b91e9d1a",
|
||||||
|
"0x26a02e2e22afd030083fac312c3ea5ef2b8261a789a3cdb14e0f59344710c7d6",
|
||||||
|
"0x1e972689e841a22940b918fb25a4fd47bc016bb627359e0f8efb982516900250",
|
||||||
|
"0x1719a91dcbaa2591741e3c6e8c813071dbb249caed013b1a49a09c6337588388",
|
||||||
|
"0x07ae0bd9a15c6093e83d203cee422cabaac2b1480b199a5a01f3b6bae8943c22",
|
||||||
|
"0x0335138c841a80c3374731753ec839f6240bd2a965d10971c20a5573c6700a61",
|
||||||
|
"0x0bccc625cafac996fc66d3d723e2efcbc7291c5c2ee94ec4308719f0f682bae9",
|
||||||
|
"0x1aca016e7c2b5f0fa4a3c8466822be48e461a2f96daa05a7e6bd65447ceedc20",
|
||||||
|
"0x228ca2efdfb5fc0371bef36dae53fb3e6743f7f5ac32773eb9daa1fff9ad5280",
|
||||||
|
"0x0abd2713ba22c5a0284319c09fdb52831253c15a3dd8bec25ef562dfd902ffb3",
|
||||||
|
"0x0c20a2af2b35bffc6c6b267df78c0ea1e9382f9508fa665f8fdc0836a4d5da0a",
|
||||||
|
"0x0da1ed20c40a98057ee6df9f8e55d6e0936ec8b1ded7ae68ee97c9329310c346",
|
||||||
|
"0x2b662b17eae86aef2137d9f669f08960d262f221708c49fe793884326c92aae8",
|
||||||
|
"0x00892d01420c44d4b5266e98d3963b613ee8b005a2b1c9cd20082a3d49f595ff",
|
||||||
|
"0x1e7068ac5f13d9a2e8b46d99b5d5f35f2d3de6de8bd81c8e78668ef467f05160",
|
||||||
|
"0x04c946cb36ed8b5935362ac33029dedd33cd3d62f638eb74f1834b1fb83060a2",
|
||||||
|
"0x0bfaea8cdbcbab42a9e8bf92141c329651a604055f555663fe983c1b0646d051",
|
||||||
|
"0x0ed5e5e518343fbbc0fb70386a6df1945679b165d1a65afc6c825315775694fb",
|
||||||
|
"0x266d7fa0ddc680255cb75a0cbaf4d586f8edee107e2d3d5ad5ce90b142b9812d",
|
||||||
|
"0x038632d442ca8a88fb33a37ffde668cc8c499b6eadc40af5b3f237f2ab62da06",
|
||||||
|
"0x18e36f3104718c8e25493c8d0410aec2779af54c23014de0feb6f96f34ee52bc",
|
||||||
|
"0x231745182598bb764367a8490e1d61c3d3db1699a7a54212144ffafddd37712e",
|
||||||
|
"0x298d6012d765ff5ca0e313106417ffe9a7f08185d7623b37abacf91ab0aebfb9",
|
||||||
|
"0x19f2674561197e8fe58d8547d3926ba2702999f9f5147fe77445ad75c336d683",
|
||||||
|
"0x2b15c22e56345b557175c1eca4279b909af4e965d941cc1b5352fe2d3229ab0a",
|
||||||
|
"0x289ad5b36e4dd22b2c92a95b1e3ef574601e8117ffd22ac0a0389b478f80572f",
|
||||||
|
"0x214626bdeae25c53e26eb6f7f65fa6bb4c83469735f03166061c245d00ca86d5",
|
||||||
|
"0x24f3525dabc6b7f53d021138eb9dc49133d046b851d4781ebbc94b05dec248d7",
|
||||||
|
"0x2791a40b5946f478a90d4e5efb36d8bba14f53e401f87056af2d55a6b7df5cf8",
|
||||||
|
"0x09318d2f819b522b0a847e5038118e65718f361f8947580cfa8b8b361ce5e8ee",
|
||||||
|
"0x219d8daacb4cef1375b06392f9220f1d204f0e88499c108c961de46fdb5d8fe5",
|
||||||
|
"0x268a3e49958e2d7a588b7276b41a2c7f18989d599e80dc85e39c7308d5e92f69",
|
||||||
|
"0x10d8226869f3e198f804bc9d51901e5bd24d824e03458fc549a6a16e5c62125d",
|
||||||
|
"0x0660a3ff70a9db2da72081518d7a9b473b054a2508b047a5c363f97931dfea83",
|
||||||
|
"0x031271a704e1a00bc2b860da159913bcaad3c8acf27c1fa3b28ce2c33841ffab",
|
||||||
|
"0x07eddfe02b81044a908a5f7d73f6f461aad59a29f1b55b41a2dfadb7968b4a07",
|
||||||
|
"0x1f93630d8bedc406368b348a7006ec4806b4dbadef3e7a022ac8e51f779f2828",
|
||||||
|
"0x085a2c147a95c4414b1b67df4fd75753f44d02cc54148ddbd6d771d3084f4cd9",
|
||||||
|
"0x02b256807b01a9aa040f02c771397590bad8d20df2520d6ff24401663a3d5f8d",
|
||||||
|
"0x1dc83ce1042b12070a2998b52f2d88a4fc2a7d324d6d00664a3bd617bbb4ae85",
|
||||||
|
"0x18233d96215c73f726760194809c1a4dd405a32ebe67620ae85f2f2b96862eaa",
|
||||||
|
"0x0c7add4ec9ce9e2fea0dbba3833f9e1260249cc855df6a2a1557740b9c477cd9",
|
||||||
|
"0x0eb7a2b2438ca0b3459f24bf4bfa719f08272a6f27c747cc151a482ad8fb3be0",
|
||||||
|
"0x0167e7ef87785ac6c577e395e475209462b7cfa832cebf6c2add446ecec58878",
|
||||||
|
"0x1e52ca68bd85803046e5036b236a6886aaf8fdfeb2bf41ab82c1e0eedf045a81",
|
||||||
|
"0x0875d6ad908a0e1b77b24422a99aba983c8eaee3a2ed63fe5d476d58890bf06b",
|
||||||
|
"0x1bd4fdd412c233e4ad6558382c336ce03b154baf81846aeb4977c1213c8d5618",
|
||||||
|
"0x13ad247e3e1eefb651b3ec25c7dc4aa9df5448c73adb7b683d96a6d66bfa3aa6",
|
||||||
|
"0x02bdda4b91162dfd2c210bae56f9252170f555fe3bb6b21a177cfd04eb660803",
|
||||||
|
"0x00e8b60d2341985c55753fb8e4ccbfa8b99692463b4e0a11a1b475b688480c4f",
|
||||||
|
"0x19cf84ff8a5184368bb6a6f20b3fe1380600b45758ad3cf7b88bfdee2ec61b49",
|
||||||
|
"0x25abb85753668de0457dfe38099de2bd1c47978b344ca58f7c2c0c02201997e5",
|
||||||
|
"0x24710d523c762410a2d4924464743478feb594b14f12851a541cd3d3ba75b247",
|
||||||
|
"0x29ffbe3a4a3087d01b5acb88009abde722a89296b420c9f52449128bc9fdc34c",
|
||||||
|
"0x0ec3577cf043961d009493d183d50720d25e49fbc8f9adf62ba72aecd781dc1a",
|
||||||
|
"0x26c113117e795ef7b8d7773f81912c80aabc19116464aa8fb12241ceb5dcc2ee",
|
||||||
|
"0x07d5f46533b2a2e88682c6fda0bc7cf8a0c70b160a83a967618c65b59c9001a1",
|
||||||
|
"0x23d54f9c4c3e67d924d26da36276acbfe02cb4f9ced76f4fe12e0a73ba803343",
|
||||||
|
"0x10cd6323749cc45b68d78b9d749dc4a3faf38bc329b4b29e4f80eb3dfe3e039f",
|
||||||
|
"0x29f2a6f05e471ef11fc76dfaf7732a9b03a69ebe58720dc54d95e8d66aac9601",
|
||||||
|
"0x188cf3ecdef093b77624ab20d47ae582fd0d9dae59987f7fd4c173900d50196e",
|
||||||
|
"0x27a03aefe417b4f88a4a811b2ef281b1b8eddd2ac9ea62560a86af54eb5f5f31",
|
||||||
|
"0x0990e3d736045f5fc126258b0bae3710d70a9a7fdd4a03834d6ba3e1c41645e1",
|
||||||
|
"0x01d0c03377b6c3e03a1cadb8f00aa6b3e856a5b12e9ffacd829a2e17eb1e57ff",
|
||||||
|
"0x0b3551f6faa579f6fec4b813a862f196a14f15357371499f98eeb9cfd9970acb",
|
||||||
|
"0x0f9444b6c7eafdb309da46679dcbab14a65268c58757e5ca9f76143205985949",
|
||||||
|
"0x14db8cfa9979850abc02c0b49b33e22dc4ba8d4557c37a4bbce9a2645a553934",
|
||||||
|
"0x08d995c609e1701dbc84e53f3bf3889beca275d0bf20de975ab7bd11f29168c1",
|
||||||
|
"0x22ee92f4ec09f2174537985f561d785c4942a28cefe4b1a6f2d736579b4306d5",
|
||||||
|
"0x0deac3e417c3e702add7e11e9a9076d2b12d6cd4c432b7bf199c492feaac78cf",
|
||||||
|
"0x215d0c99a7fb3227054ecbb04b39dd2e85a33be4b2a78455322b9a8209a7839a",
|
||||||
|
"0x144dfd27491018d95745bfa263ab11b6f6865c050700c8bc38ef6196973d4e82",
|
||||||
|
"0x2e4c9e84e7b07e659bfc709a3de211b454d028e4a74120b07f130f461210548b",
|
||||||
|
"0x260666b80f1d865b7ad6d98dca26cf2c1a5bcbd87d9d9d19673ca4db486652a3",
|
||||||
|
"0x21c2ef3ae808bc3b0c1ba5eb6fc594b6e383c1bcb05006b64fad6c3483aaa96f",
|
||||||
|
"0x1ea451ecce4adee6b1682153f4038d177e50944ae9cb55b4e0535c24f6911b55",
|
||||||
|
"0x0f8df7e95aeaaf0fd8f61c50a0b282c6df25fc884d707ab96936be3d87f75de2",
|
||||||
|
"0x2d9abc0ebc4284989c7cc7f6dac8b356c0ed4e6839d8a43d5783dd8dfb57acfb",
|
||||||
|
"0x1e851335f8cfaa72342db1d1cd9575d2190c671423fd5cde851051c0dd5746f7",
|
||||||
|
"0x189dd6ddeb39ca53540ecd57bfbdebc075f7abf25b1ce4f9ede0f093bee3e6cb",
|
||||||
|
"0x1e8e34d095df1eb92444afc3f89b848905b8c2ac63d3805af088e67ff695d5c8",
|
||||||
|
"0x187eb13c7f95499b8ebaa0c5100fbacb1184a61e62ca9be6601c3af34c0d0804",
|
||||||
|
"0x269000bab546cb9f4e54adc5adb3b08f6f45bb19114977cced6e5035b605e4cc",
|
||||||
|
"0x1a4273c2ff4b80a91443e25d1f0ad568ba4586cdb8bd9e412be1fa40ef2f10a2",
|
||||||
|
"0x0b2c26399060c182a27682869690bd61c9395795349b873b16ceceed98ccdb0f",
|
||||||
|
"0x187370c642e5fd783fba4b7cc7bf03341f6b8efd23fe8c82cf7b627f91bedeb2",
|
||||||
|
"0x1162e4855ebcea47475ef6016b2129f42c06dd2262eee9f43e5bdb024cb3e3ab",
|
||||||
|
"0x1cb4e22d4b8bfd114320b70e2edc8ec4d077820dc7caaaf3983e0791f77c5afd",
|
||||||
|
"0x0b9246a297596e5b285d111c1da4dec37a96a56fe1f3532d45b51cd06da11582",
|
||||||
|
"0x06b14752752ad07b43a8daa7963c3c0d9a522671c61f49e7aaa77373839a3ca3",
|
||||||
|
"0x21fb7f7798350e11d807e4bac95162f8cbba7f5528f030f22682de559952b444",
|
||||||
|
"0x26eaf07e3bb2ad298141174e39808d12d3e8359624d57dcd4bd40d517c889f41",
|
||||||
|
"0x1bc988e5a7e158d7367f959b6d877986fb0696e1e9c1f1a59462086d1b4a4a9d",
|
||||||
|
"0x1665b29cab9b55ffc5bf2376609265ed9a8f6b8b607636df26ce4f2bc3a6ae56",
|
||||||
|
"0x27b2623f1a2a2d769759232e2cff279d0916efd69efb8c8392a402192e4469a5",
|
||||||
|
"0x0b11a77df9412a21a871a117cb027da0f8af823131f60add22ed9c4a2928f332",
|
||||||
|
"0x1ce9f86e393b0e2d0ddf1270803c496284ded0b35f69972031a5ceaa360c5af4",
|
||||||
|
"0x2c97533771428606f2bb3d8cc740ee47c66018fe54fecc8b567483befaa3d898",
|
||||||
|
"0x1a257215c9ffb1465ec62562d98025bf33a23fcbb683f89d53a118d060c11cf8",
|
||||||
|
"0x25fd8cfe274fe98e6e3ae98aaaab03ade4d1c56cef810df237e42d324184d86d",
|
||||||
|
"0x286cea2aeabf040c9bf2160ce8ca90ac489f0098982d790fb42ab33345cfcfe7",
|
||||||
|
"0x124c35aa339e0ee2c2046b2f5f0367ce4eedfeb8e3c6c94b7f6460dee9e51099",
|
||||||
|
"0x1665dee3f142dbe8f44d85e4d93b39fbf1c86e7a797a8d55932d81a3efa516a4",
|
||||||
|
"0x12cc10508db3a8b2f2c53afe91252ddf4bbcf5e4e2738fa8e699edb9fa3df62c",
|
||||||
|
"0x1ef850e8b97b2c0560843986acfff158d75aa9210acc6420e9650b56dd9b3c4b",
|
||||||
|
"0x2afe8e7f5b4525a1c015f8ace5dd35e62cf89e2232b90eb3eb011d082a114a37",
|
||||||
|
"0x2e9c398649994f32c3cd610bc6546bc05aab563fbba41d3124e255ff45e1c940",
|
||||||
|
"0x03b21b85b77588506db2fc108bd0cf2c03f6c0653020f46d939d8194ea1e716b",
|
||||||
|
"0x2e43508dd63e40681c9122d482d7900ebad01b9392e6c1611019e43cbc5455b8",
|
||||||
|
"0x113febd0e87001dda480a8c347f8a368c00740a25ee2d8d36c0608500bec6f2f",
|
||||||
|
"0x23cfec0d834aadca55bfe515af80e59183c1b24ea600cf7cde863df02fc859fc",
|
||||||
|
"0x1cbb1f36a1e7bc45c29ed8922599374d57010887420c91ecfa8727ad51df9b21",
|
||||||
|
"0x1c2a24adf0e0c5254eb4c834e252a04758e84181cfd1a163dc7089337c4eba52",
|
||||||
|
"0x2b7a7d74ea33c98f3b45bae98a2498ad5d316a43cfd40e8be9e1c5fd901f5bd8",
|
||||||
|
"0x1edb94d38964f284b41136812bd52c7679b1e1a3ce3b3a1354b1417b9012ec4b",
|
||||||
|
"0x2c2bad47394f3068c8b996c4859a22dd65460292fef9c250a5a9da8e0628d534",
|
||||||
|
"0x0b140b193aab84f6235a88b862ce4275746d5cac940fc494aef23d2279e8a353",
|
||||||
|
"0x15673d3dd92656dd60513676f7814459619a09681ee4ab63dd8ff3407a547846",
|
||||||
|
"0x2180ff0b613f8cce937068fa4a77a0f97865c4aed76483cb1fe09227517ba888",
|
||||||
|
"0x1048b70290f52d668ee6b98950b3e904fee8c844428919300a8945c0fe3e7280",
|
||||||
|
"0x0326df120ad22e946c41f475b7702dae0dd42a4387a8702c8e954aca640b2c79",
|
||||||
|
"0x2fc77a73fdbaaa22e2fc521f72f9ce5cef4857f58001409898d52c5e5b1723db",
|
||||||
|
"0x14938b2b6259f02791cccd157d789c2de68cdad27dc55aa08b9b90ec13dbfd79",
|
||||||
|
"0x0493187bf26d38b13ca04c712b42778f8618e6f7d9f9dd52bd4da96e085c7a78",
|
||||||
|
"0x1d40769876c58db37289e371fef2ffa559c95630dee045cde6e18370d2ceb561",
|
||||||
|
"0x03e7e9b8084366995f7a2f5732349b1139726536b378d78772eabb302705d204",
|
||||||
|
"0x06147e6e152d7d58f4cf01e05ae0f024607b8b7c3770bd5b7f3a54e048c30a17",
|
||||||
|
"0x2e49300214c5a0a7a6ebbbc8c48cc323be26d42e98e5bbbb0e2a10ecf4fe40fe",
|
||||||
|
"0x051c8240e8907e776279e7c66cdbdf39c9516f39ae61883185fac1ef5c64bbba",
|
||||||
|
"0x2c737904e8f8e845bf132de2b3be5d638993a9987d0e8003022f08bf6633a5bd",
|
||||||
|
"0x07825bfc67f5658bb5a3b1a26c8ad00f657b54a4a1a679ee37df11bed2ba219d",
|
||||||
|
"0x1c0e4d8b013541963f8e04667f13e6a60fafebb9bceca823d4054a7a63f8b569",
|
||||||
|
"0x1083d7cd5a11e3d3dba85745de17ea4abec8a2790003f39f1b1262521380d4b6",
|
||||||
|
"0x0e14bed1525102ddc1d3c17478ab0c2d4cdbfa67f5ef1a568642984665b4dad2",
|
||||||
|
"0x1d0c3a89fcc0171b7977f8f20bad9cfae37507a2038d3165d764632461745760",
|
||||||
|
"0x03162758d9df43281331905c161ed977e240f4a0c9cdd3f3f18a3b0592c3e67e",
|
||||||
|
"0x0fe5ec0343e9832d8a4c7c1bee1d73decc0661a27c527bec309561fda95a529a",
|
||||||
|
"0x0ddd28a35af3aced48f61c6558c5c4a72690975c2fc948feec51e1a53a6be5e7",
|
||||||
|
"0x2318c886ea334e72e9833e3b0bc9868e51843b8b63e0fa3d814540ad7f5d0359",
|
||||||
|
"0x0d5786dec1685237e3d171eb298a36a475c83c0651a450227d261d78260bab70",
|
||||||
|
"0x152282540da509e8ab8abcf010d3bd8f29d1c2c60454ffda67ca732db024f3ec",
|
||||||
|
"0x1b7f4ec7b4c7a593efd5f53ef204e642bb16fb9298a6ffbd1767183170822ad2",
|
||||||
|
"0x19e02df6f343636868908d644e9a2f767bb9fa9c13756669cb1d805898d949c0",
|
||||||
|
"0x115d3fa50f1ea1f76b4641586e954be25d7428ad21f5fea76b5889a3f4923ab6",
|
||||||
|
"0x059db78b0146183e8e6e0829bad801fcb4a0c4e6a8872cb3a5a497118dd29f2c",
|
||||||
|
"0x0e6441f0174ebe123449b9072472442e03c2f72a29c474d514e4dbb72c23bce1",
|
||||||
|
"0x2c5302069d7b3b9638a3ea52e5530059155d706af30df469ab929fa1c954efa6",
|
||||||
|
"0x181a99f989f2f853ae7db14bef800710a05ddc26ed65cd5e1588150864565829",
|
||||||
|
"0x248a2275485f8946848f0d9433ee1cf6501bbfa8f9404341ef81a9c4b128db3a",
|
||||||
|
"0x081fa1eb11e0e5198e7135c533688ad0b4e438773b9d99a610ece3dd414845ad",
|
||||||
|
"0x17b1a8626b79093deb27cfa548da7bf8499e71928d9433a7243037d493c08b53",
|
||||||
|
"0x0af8f7fc8f0ba49245ae28cfbb7b86bdf3f38b4229981b42ad8ba4af993ae5d8",
|
||||||
|
"0x19da094b62046661682693af49d35d72a055555b0b2f1a717ef61a0fbdc90169",
|
||||||
|
"0x287b1755734c8e691d9651ff53f3bae296bc16d33713bf32457869e3650dbc9e",
|
||||||
|
"0x26501a99afdb95154415e3de32b0d4790ff228ee94577537608d30d85a3349d0",
|
||||||
|
"0x0c7ca2af6c86f460df0b20ccb30b2a3395f2dabaf7f970f1e1955a1166e0460b",
|
||||||
|
"0x141cffa13da7885f34ff295561b5d2da8c5b785932ebcd7039752c0dd1cc08a5",
|
||||||
|
"0x188f478690e359cc0b468d095b37f314c53a5873054cbdb5eb4cde9b97d8c837",
|
||||||
|
"0x2daafa58220bc8ab507118fb29b65e48e6d8d3ad20d6fa24d57b8a90e21530d6",
|
||||||
|
"0x1c8eaf137b6310715fc0881b8a080e9391a0217e8e3980ccc3fbc6423ae10f1b",
|
||||||
|
"0x018864151eb108a9115379b3d3ec902aa961f1b846490266855ab48077487948",
|
||||||
|
"0x16a426c1847543857385ef8ed03325a50d5cbeff1ac61ef3b710099ab8be88ae",
|
||||||
|
"0x13d7ed015205feee9d09307b193811ea89b22bf4ecb3e8dcb951ff1e86ea1dbb",
|
||||||
|
"0x2b35afa98d5c3da62ae05e0e3ec587eacbd195fa3405260ce2b910cb198acf5f"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"M": [
|
||||||
|
[
|
||||||
|
[
|
||||||
|
"0x028540ffcb050250186bb64a9b6e6d0eaf493d2c72701392fa8de7dbd371fad4",
|
||||||
|
"0x1afa3a02008d8eab18725ff780b7f310156ddef81579367ae944478644e6367e"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"0x00b0cad1d2259f1f6dd07b4e5674057f531b5ce316f741437137b7615caf9fb0",
|
||||||
|
"0x1378798a617a99c07cd850cb3daab0a1b20cb2fe9125133ae092132a071eeffe"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[
|
||||||
|
"0x142d76a5176d04542cc86c20ad276af0f1c4b85a08f5c7fb7076c37bee91b0b0",
|
||||||
|
"0x1f020db9ae14abc9448d91922ce7e8a4b751468b692082ac74d4db30f9a20cbd",
|
||||||
|
"0x02f57e7420298b689cc5932b434d659054d7e9e1a28ce342a357d28d3d0e7ce6"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"0x0cc8c6aa7aa0f7a0191f236aad3b994b4e6d2671ef5cddef7395a663f18a82b6",
|
||||||
|
"0x132d968e1372659c4b77528bec8b46830564bbb1ef44e828966a07578b52db1e",
|
||||||
|
"0x2e7a166a1b7e646c9f9e04f451e541b3eb516fbad05901b4f37e7dd402a501de"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"0x0411c26273e6ac2f2b7ef6da84499413605b6099bda4254a31ab3bac526a1581",
|
||||||
|
"0x1e9d5cd096fd315de38e6e2490b8e9c406f954ba63a8be9f11756780af6315f1",
|
||||||
|
"0x198dfceb06c35ab9162320e55b68a7d160ac9caf74ff1098d62b4cd86823e74c"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[
|
||||||
|
"0x055042fce3759fd347470105116d64130f5cb362e345d7651c377a63f1c73f81",
|
||||||
|
"0x2ce35792e15aa0836ab5089a71903eb626bfe7fd6a460cb2f9d93f338b1c93a8",
|
||||||
|
"0x123324a5430d1e324553566a662bab9bd5b78bc183829124d3407352f3399a44",
|
||||||
|
"0x014b3af716655fd79b921fb8aba95bf4033d91eefddba964c6813b194ec2e92b"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"0x00f7a1e3ee734053ac96e44087e97819d5289c2e002339ed649d14df4416c664",
|
||||||
|
"0x158586db6e410642a1e221f5d80a482cc6ba3cfbe51a38502987db8c42d53bea",
|
||||||
|
"0x1607fd8dcba9cecf99fa9f882b7bf67c9bdf121aef9843d5d47301d812d23406",
|
||||||
|
"0x02afb3d945a884974edcf2b2ea59422bfbfb98ba0ea6ae232a2fbf2a98fce73c"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"0x1303c19d840c01975ac5f417c7d797c84e32937e82c3267a8a5abf86c2adc2dc",
|
||||||
|
"0x0dfbb78b621ce3f17ea1fca649c7fdf8936872b335d86c5f3ac83072f2b0804e",
|
||||||
|
"0x0c6d9cca76d73644645d39f6da45e32a5784eb278da4ba346226e3503767c559",
|
||||||
|
"0x271868e3480e8509ee5b7d057e0e85677220d4751c1475c8a07c578584dba071"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"0x1ce85b8925fef3258cf52dd26ea5dbe2616118a051fad03b174c55e6bf25c193",
|
||||||
|
"0x10a902db55c0d71628c51efcb7f01c28e3e60833c254e68d38833c0b577e7bf8",
|
||||||
|
"0x24afc938e9d8abe5f4cc11f1388ab83460681a00dced6ccd170860e03508ca5c",
|
||||||
|
"0x297a43fb5e3fefcf3ccabaacf30e9171e4fb359ab66c6ebc8bd6654bd387ab1b"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[
|
||||||
|
"0x098df2176f14c72d9ef76d268c6526704b2dce0d2ab0bf0d0b6506c598a12e39",
|
||||||
|
"0x1ee4a90d3dc9864851e9cefb41c3e19218f7ec9b97283b8781d74a9260a9b182",
|
||||||
|
"0x090becc1ca85079c519e9519456d0613c4dea08dc17ce3d3ac24c51780bbe653",
|
||||||
|
"0x24510d25f0893ebc56cb6d302b08ebc1fe23a842483a1cf105efccdb8f6623be",
|
||||||
|
"0x1836f551337cc92e446cda258313ddb9a1291f822c2120d3765f5bb29bccd044"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"0x235a03a1f31060c62a1bb1b6cbce38317dcf3501e3f0b3d92b4b01a070ee58b2",
|
||||||
|
"0x1b0481c924c00fd4b7809ff4a9f9daa7f12efea4821078b869159d34e7c9caca",
|
||||||
|
"0x2f1ced49ea067ad0f3a22b51ad12da2d7b0280f3f50977f9b09d4bea92e6b34e",
|
||||||
|
"0x28f301e64ff54c671bb7a9fc672a420e3af0382c71af2aec84d1b26d19bd01ee",
|
||||||
|
"0x05c29dff5d6ae85f7bc09637a86134c63a8052d1905a8057449cc7d92658f24d"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"0x2885788b4255180581aac93d5313e7489efc386deceaf13050ebcb8cdddff5fa",
|
||||||
|
"0x2a7f03d4b0954a37f9a33ebd9117e2c4cfaa3978e5f221a30db56a7403572a3c",
|
||||||
|
"0x291093f3d5182756f267566140d2d8f5356be8408b40ead3748484267f1e90cb",
|
||||||
|
"0x29ecfb524f4135deb55d9d9eb02839dedda189c17726aeef96019b205c8aab53",
|
||||||
|
"0x1650d221980ec72736322d9fa404a0fe6bea3d8530b71c9522096e455be52379"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"0x10d08ba1c37b79a36c9d3c9a3d8fd2ff41f2445e7d71dd5ede6f45987e5e1044",
|
||||||
|
"0x1eaa7441754632ffae99c9e2f2264c1bc89551e7bbf2c889d92af30bef70e817",
|
||||||
|
"0x062101fedd4ecff781f529f57f45e8b479b03d86a11acf549c6555a1293c70b3",
|
||||||
|
"0x1c1ec7db63405475e844b5cb6215d9e2919e903a7387721db150c9977a1818b5",
|
||||||
|
"0x0b5ca51ebe8fd98da6e8f4a4465e19dd210bf59e0841f50fcf0f06e43d83ce1f"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"0x0143b223ed92a0b426f8f2886cda3d8fdb565eb6acb4841897489e14cbc943a8",
|
||||||
|
"0x017f82dcfdf078265df4cfa1d9d79aeec0fee433eebc489a875785b99dc8832a",
|
||||||
|
"0x0013ae98ed23af18461bcde9ff99728edeec173e63c5467a209c2a34b503dc72",
|
||||||
|
"0x0e120df26061ea797bba1f6153995de0090ddb744ad23bfcdf1ecc28a9b18338",
|
||||||
|
"0x0233c1411c8cb5ff0d33e20a65bfd9c0347deb9a12a50e55fb01a40248ccc366"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
@ -2,53 +2,52 @@
|
|||||||
// License: LGPL-3.0+
|
// License: LGPL-3.0+
|
||||||
//
|
//
|
||||||
|
|
||||||
const Poseidon = require("./poseidon.js");
|
|
||||||
|
|
||||||
const Contract = require("./evmasm");
|
const Contract = require("./evmasm");
|
||||||
|
const { unstringifyBigInts } = require("ffjavascript").utils;
|
||||||
|
const Web3Utils = require("web3-utils");
|
||||||
|
|
||||||
const SEED = "poseidon";
|
const { C:K, M } = unstringifyBigInts(require("./poseidon_constants.json"));
|
||||||
const NROUNDSF = 8;
|
|
||||||
const NROUNDSP = 57;
|
const N_ROUNDS_F = 8;
|
||||||
const T = 6;
|
const N_ROUNDS_P = 35;
|
||||||
|
|
||||||
function toHex256(a) {
|
function toHex256(a) {
|
||||||
|
if (typeof a === "string" && a.startsWith("0x")) {
|
||||||
|
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(t, nRoundsF, nRoundsP, seed) {
|
function createCode(nInputs) {
|
||||||
if (typeof seed === "undefined") seed = SEED;
|
|
||||||
if (typeof nRoundsF === "undefined") nRoundsF = NROUNDSF;
|
|
||||||
if (typeof nRoundsP === "undefined") nRoundsP = NROUNDSP;
|
|
||||||
if (typeof t === "undefined") t = T;
|
|
||||||
|
|
||||||
const K = Poseidon.getConstants(t, seed, nRoundsP + nRoundsF);
|
if (( nInputs<1) || (nInputs>4)) throw new Error("Invalid number of inputs. Must be 1<=nInputs<=8");
|
||||||
const M = Poseidon.getMatrix(t, seed, nRoundsP + nRoundsF);
|
const t = nInputs + 1;
|
||||||
|
const nRoundsF = N_ROUNDS_F;
|
||||||
|
const nRoundsP = N_ROUNDS_P;
|
||||||
|
|
||||||
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[i][j]));
|
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
|
||||||
C.push(toHex256(K[r])); // K, st, q
|
|
||||||
for (let i=0; i<t; i++) {
|
for (let i=0; i<t; i++) {
|
||||||
C.dup(1+t); // q, K, st, q
|
C.dup(t); // q, st, q
|
||||||
C.dup(1); // K, q, K, st, q
|
C.push(toHex256(K[t-2][r*t+i])); // K, q, st, q
|
||||||
C.dup(3+i); // st[i], K, q, K, st, q
|
C.dup(2+i); // st[i], K, q, st, q
|
||||||
C.addmod(); // newSt[i], K, st, q
|
C.addmod(); // newSt[i], st, q
|
||||||
C.swap(2 + i); // xx, K, st, q
|
C.swap(1 + i); // xx, st, q
|
||||||
C.pop();
|
C.pop();
|
||||||
}
|
}
|
||||||
C.pop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function sigma(p) {
|
function sigma(p) {
|
||||||
@ -104,8 +103,13 @@ function createCode(t, nRoundsF, nRoundsP, seed) {
|
|||||||
C.push(0);
|
C.push(0);
|
||||||
C.calldataload();
|
C.calldataload();
|
||||||
C.div();
|
C.div();
|
||||||
C.push("0xc4420fb4"); // poseidon(uint256[])
|
C.dup(0);
|
||||||
|
C.push(Web3Utils.keccak256(`poseidon(uint256[${nInputs}])`).slice(0, 10)); // poseidon(uint256[n])
|
||||||
C.eq();
|
C.eq();
|
||||||
|
C.swap(1);
|
||||||
|
C.push(Web3Utils.keccak256(`poseidon(bytes32[${nInputs}])`).slice(0, 10)); // poseidon(bytes32[n])
|
||||||
|
C.eq();
|
||||||
|
C.or();
|
||||||
C.jmpi("start");
|
C.jmpi("start");
|
||||||
C.invalid();
|
C.invalid();
|
||||||
|
|
||||||
@ -115,17 +119,16 @@ function createCode(t, nRoundsF, nRoundsP, seed) {
|
|||||||
|
|
||||||
C.push("0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001"); // q
|
C.push("0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001"); // q
|
||||||
|
|
||||||
// Load 6 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)] [Pointer (32)][Length (32)] [data1 (32)] ....
|
// [Selector (4)] [item1 (32)] [item2 (32)] ....
|
||||||
// We ignore the pointer and the length and just load 6 values to the state
|
// Stack positions 0-nInputs.
|
||||||
// (Stack positions 0-5) If the array is shorter, we just set zeros.
|
|
||||||
for (let i=0; i<t; i++) {
|
for (let i=0; i<t; i++) {
|
||||||
C.push(0x44+(0x20*(5-i)));
|
C.push(0x04+(0x20*(nInputs-i)));
|
||||||
C.calldataload();
|
C.calldataload();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i=0; i<nRoundsF+nRoundsP; 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++) {
|
||||||
@ -142,6 +145,13 @@ function createCode(t, nRoundsF, nRoundsP, seed) {
|
|||||||
C.label(strLabel);
|
C.label(strLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
C.push(toHex256(K[t-2][(nRoundsF+nRoundsP-1)*t])); // K, st, q
|
||||||
|
C.dup(t+1); // q, K, st, q
|
||||||
|
C.swap(2); // st[0], K, q, st\st[0]
|
||||||
|
C.addmod(); // st q
|
||||||
|
|
||||||
|
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");
|
||||||
@ -153,28 +163,54 @@ function createCode(t, nRoundsF, nRoundsP, seed) {
|
|||||||
return C.createTxData();
|
return C.createTxData();
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.abi = [
|
function generateABI(nInputs) {
|
||||||
{
|
return [
|
||||||
"constant": true,
|
{
|
||||||
"inputs": [
|
"constant": true,
|
||||||
{
|
"inputs": [
|
||||||
"name": "input",
|
{
|
||||||
"type": "uint256[]"
|
"internalType": `bytes32[${nInputs}]`,
|
||||||
}
|
"name": "input",
|
||||||
],
|
"type": `bytes32[${nInputs}]`
|
||||||
"name": "poseidon",
|
}
|
||||||
"outputs": [
|
],
|
||||||
{
|
"name": "poseidon",
|
||||||
"name": "",
|
"outputs": [
|
||||||
"type": "uint256"
|
{
|
||||||
}
|
"internalType": "bytes32",
|
||||||
],
|
"name": "",
|
||||||
"payable": false,
|
"type": "bytes32"
|
||||||
"stateMutability": "pure",
|
}
|
||||||
"type": "function"
|
],
|
||||||
}
|
"payable": false,
|
||||||
];
|
"stateMutability": "pure",
|
||||||
|
"type": "function"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"constant": true,
|
||||||
|
"inputs": [
|
||||||
|
{
|
||||||
|
"internalType": `uint256[${nInputs}]`,
|
||||||
|
"name": "input",
|
||||||
|
"type": `uint256[${nInputs}]`
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"name": "poseidon",
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"internalType": "uint256",
|
||||||
|
"name": "",
|
||||||
|
"type": "uint256"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"payable": false,
|
||||||
|
"stateMutability": "pure",
|
||||||
|
"type": "function"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.generateABI = generateABI;
|
||||||
module.exports.createCode = createCode;
|
module.exports.createCode = createCode;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
const Poseidon = require("./poseidon.js");
|
|
||||||
|
|
||||||
const C = Poseidon.getConstants();
|
|
||||||
|
|
||||||
let S = "[\n";
|
|
||||||
|
|
||||||
for (let i=0; i<C.length; i++) {
|
|
||||||
S = S + " " + C[i].toString();
|
|
||||||
if (i<C.length-1) S = S + ",";
|
|
||||||
S = S + "\n";
|
|
||||||
}
|
|
||||||
S=S+ "]\n";
|
|
||||||
|
|
||||||
console.log(S);
|
|
@ -1,5 +1,13 @@
|
|||||||
const poseidonGenContract = require("./poseidon_gencontract");
|
const poseidonGenContract = require("./poseidon_gencontract");
|
||||||
|
|
||||||
|
if (process.argv.length != 3) {
|
||||||
|
console.log("Usage: node poseidon_gencontract.js [numberOfInputs]");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
console.log(poseidonGenContract.createCode(6, 8, 57));
|
const nInputs = Number(process.argv[2]);
|
||||||
|
|
||||||
|
console.log(nInputs);
|
||||||
|
|
||||||
|
console.log(poseidonGenContract.createCode(nInputs));
|
||||||
|
|
||||||
|
60
src/smt.js
60
src/smt.js
@ -1,7 +1,6 @@
|
|||||||
const bigInt = require("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 {
|
||||||
|
|
||||||
@ -11,18 +10,7 @@ class SMT {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_splitBits(_key) {
|
_splitBits(_key) {
|
||||||
|
const res = Scalar.bits(_key);
|
||||||
let k = bigInt(_key);
|
|
||||||
const res = [];
|
|
||||||
|
|
||||||
while (!k.isZero()) {
|
|
||||||
if (k.isOdd()) {
|
|
||||||
res.push(true);
|
|
||||||
} else {
|
|
||||||
res.push(false);
|
|
||||||
}
|
|
||||||
k = k.shr(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (res.length<256) res.push(false);
|
while (res.length<256) res.push(false);
|
||||||
|
|
||||||
@ -30,8 +18,8 @@ class SMT {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
@ -70,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");
|
||||||
@ -99,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];
|
||||||
@ -108,16 +96,16 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,7 +114,7 @@ class SMT {
|
|||||||
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]) {
|
||||||
@ -135,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,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;
|
||||||
@ -183,7 +171,7 @@ 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);
|
||||||
@ -191,7 +179,7 @@ class SMT {
|
|||||||
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 = [];
|
||||||
@ -201,7 +189,7 @@ class SMT {
|
|||||||
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) {
|
||||||
@ -227,7 +215,7 @@ class SMT {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
@ -253,12 +241,12 @@ 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;
|
||||||
@ -266,8 +254,8 @@ class SMT {
|
|||||||
|
|
||||||
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: [],
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
const mimc7 = require("./mimc7");
|
const mimc7 = require("./mimc7");
|
||||||
const bigInt = require("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);
|
||||||
@ -8,3 +8,5 @@ exports.hash0 = function (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,12 +1,18 @@
|
|||||||
const Poseidon = require("./poseidon");
|
|
||||||
const bigInt = require("snarkjs").bigInt;
|
|
||||||
|
|
||||||
const hash = Poseidon.createHash(6, 8, 57);
|
const ZqField = require("ffjavascript").ZqField;
|
||||||
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
|
|
||||||
|
const poseidon = require("./poseidon");
|
||||||
|
|
||||||
|
const F = new ZqField(Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
|
||||||
|
|
||||||
|
|
||||||
exports.hash0 = function (left, right) {
|
exports.hash0 = function (left, right) {
|
||||||
return hash([left, right]);
|
return poseidon([left, right]);
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.hash1 = function(key, value) {
|
exports.hash1 = function(key, value) {
|
||||||
return hash([key, value, bigInt.one]);
|
return poseidon([key, value, F.one]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exports.F = F;
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
const bigInt = require("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]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("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)]);
|
||||||
@ -14,57 +18,56 @@ 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);
|
||||||
|
|
||||||
|
let cir;
|
||||||
before( async() => {
|
before( async() => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "aliascheck_test.circom"));
|
|
||||||
|
|
||||||
circuit = new snarkjs.Circuit(cirDef);
|
cir = await tester(path.join(__dirname, "circuits", "aliascheck_test.circom"));
|
||||||
|
|
||||||
console.log("NConstrains: " + circuit.nConstraints);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
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) );
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
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) );
|
||||||
|
104
test/babyjub.js
104
test/babyjub.js
@ -1,103 +1,90 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("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("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 = new snarkjs.Circuit(cirDefPbk);
|
|
||||||
console.log("NConstrains BabyPbk: " + circuitPbk.nConstraints);
|
|
||||||
|
|
||||||
|
circuitPbk = await tester(path.join(__dirname, "circuits", "babypbk_test.circom"));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should add point (0,1) and (0,1)", async () => {
|
it("Should add point (0,1) and (0,1)", async () => {
|
||||||
|
|
||||||
const input={
|
const input={
|
||||||
x1: snarkjs.bigInt(0),
|
x1: F.e(0),
|
||||||
y1: snarkjs.bigInt(1),
|
y1: F.e(1),
|
||||||
x2: snarkjs.bigInt(0),
|
x2: F.e(0),
|
||||||
y2: snarkjs.bigInt(1)
|
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={
|
const input={
|
||||||
x1: snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
x1: F.e("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
||||||
y1: snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
y1: F.e("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
||||||
x2: snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
x2: F.e("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
||||||
y2: snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475")
|
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={
|
const input={
|
||||||
x1: snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
x1: F.e("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
||||||
y1: snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
y1: F.e("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
|
||||||
x2: snarkjs.bigInt("16540640123574156134436876038791482806971768689494387082833631921987005038935"),
|
x2: F.e("16540640123574156134436876038791482806971768689494387082833631921987005038935"),
|
||||||
y2: snarkjs.bigInt("20819045374670962167435360035096875258406992893633759881276124905556507972311")
|
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) );
|
||||||
@ -108,18 +95,19 @@ describe("Baby Jub test", function () {
|
|||||||
|
|
||||||
const rawpvk = Buffer.from("0001020304050607080900010203040506070809000102030405060708090021", "hex");
|
const rawpvk = Buffer.from("0001020304050607080900010203040506070809000102030405060708090021", "hex");
|
||||||
const pvk = eddsa.pruneBuffer(createBlakeHash("blake512").update(rawpvk).digest().slice(0,32));
|
const pvk = eddsa.pruneBuffer(createBlakeHash("blake512").update(rawpvk).digest().slice(0,32));
|
||||||
const S = bigInt.leBuff2int(pvk).shr(3);
|
const S = Scalar.shr(utils.leBuff2int(pvk), 3);
|
||||||
|
|
||||||
const A = eddsa.prv2pub(rawpvk);
|
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,8 +1,6 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
|
||||||
const snarkjs = require("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;
|
||||||
|
|
||||||
@ -16,16 +14,16 @@ describe("Baby Jub js test", function () {
|
|||||||
it("Should add point (0,1) and (0,1)", () => {
|
it("Should add point (0,1) and (0,1)", () => {
|
||||||
|
|
||||||
const p1 = [
|
const p1 = [
|
||||||
snarkjs.bigInt(0),
|
babyjub.F.e(0),
|
||||||
snarkjs.bigInt(1)];
|
babyjub.F.e(1)];
|
||||||
const p2 = [
|
const p2 = [
|
||||||
snarkjs.bigInt(0),
|
babyjub.F.e(0),
|
||||||
snarkjs.bigInt(1)
|
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", () => {
|
||||||
@ -34,50 +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());
|
||||||
@ -88,65 +86,65 @@ 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(p, snarkjs.bigInt("14035240266687799601661095864649209771790948434046947201833777492504781204499"));
|
const r = babyjub.mulPointEscalar(p, Scalar.fromString("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(p, snarkjs.bigInt("20819045374670962167435360035096875258406992893633759881276124905556507972311"));
|
const r = babyjub.mulPointEscalar(p, Scalar.fromString("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");
|
||||||
const p2 = babyjub.unpackPoint(buf);
|
const p2 = babyjub.unpackPoint(buf);
|
||||||
assert.equal(p2[0].toString(), "17777552123799933955779906779655732241715742912184938656739573121738514868268");
|
assert.equal(p2[0].toString(), "17777552123799933955779906779655732241715742912184938656739573121738514868268");
|
||||||
assert.equal(p2[1].toString(), "2626589144620713026669568689430873010625803728049924121243784502389097019475");
|
assert.equal(p2[1].toString(), "2626589144620713026669568689430873010625803728049924121243784502389097019475");
|
||||||
@ -154,11 +152,11 @@ 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");
|
||||||
const p2 = babyjub.unpackPoint(buf);
|
const p2 = babyjub.unpackPoint(buf);
|
||||||
assert.equal(p2[0].toString(), "6890855772600357754907169075114257697580319025794532037257385534741338397365");
|
assert.equal(p2[0].toString(), "6890855772600357754907169075114257697580319025794532037257385534741338397365");
|
||||||
assert.equal(p2[1].toString(), "4338620300185947561074059802482547481416142213883829469920100239455078257889");
|
assert.equal(p2[1].toString(), "4338620300185947561074059802482547481416142213883829469920100239455078257889");
|
||||||
|
@ -1,55 +1,52 @@
|
|||||||
const chai = require("chai");
|
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("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,35 +1,37 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("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 circuit = await tester(path.join(__dirname, "circuits", "constants_test.circom"));
|
||||||
|
await circuit.loadConstraints();
|
||||||
|
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "constants_test.circom"));
|
assert.equal(circuit.nVars, 2);
|
||||||
assert.equal(cirDef.nVars, 2);
|
assert.equal(circuit.constraints.length, 1);
|
||||||
|
|
||||||
const circuit = new snarkjs.Circuit(cirDef);
|
const witness = await circuit.calculateWitness({ "in": Fr.e("d807aa98", 16)}, true);
|
||||||
|
|
||||||
const witness = circuit.calculateWitness({ "in": "0xd807aa98" });
|
assert(Fr.eq(witness[0],Fr.e(1)));
|
||||||
|
assert(Fr.eq(witness[1],Fr.e("d807aa98", 16)));
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
|
||||||
assert(witness[1].equals(snarkjs.bigInt("0xd807aa98")));
|
|
||||||
});
|
});
|
||||||
it("Should create a sum circuit", async () => {
|
it("Should create a sum circuit", async () => {
|
||||||
|
const circuit = await tester(path.join(__dirname, "circuits", "sum_test.circom"));
|
||||||
|
await circuit.loadConstraints();
|
||||||
|
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "sum_test.circom"));
|
assert.equal(circuit.constraints.length, 97); // 32 (in1) + 32(in2) + 32(out) + 1 (carry)
|
||||||
assert.equal(cirDef.nVars, 97); // 32 (in1) + 32(in2) + 32(out) + 1 (carry)
|
|
||||||
|
|
||||||
const circuit = new snarkjs.Circuit(cirDef);
|
const witness = await circuit.calculateWitness({ "a": "111", "b": "222" }, true);
|
||||||
|
|
||||||
const witness = circuit.calculateWitness({ "a": "111", "b": "222" });
|
assert(Fr.eq(witness[0],Fr.e(1)));
|
||||||
|
assert(Fr.eq(witness[1],Fr.e("333")));
|
||||||
assert(witness[0].equals(snarkjs.bigInt(1)));
|
|
||||||
assert(witness[1].equals(snarkjs.bigInt("333")));
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -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];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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/poseidon.circom"
|
include "../../circuits/poseidon.circom"
|
||||||
|
|
||||||
component main = Poseidon(2, 6, 8, 57);
|
component main = Poseidon(2);
|
3
test/circuits/poseidon6_test.circom
Normal file
3
test/circuits/poseidon6_test.circom
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
include "../../circuits/poseidon.circom"
|
||||||
|
|
||||||
|
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("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,16 +1,14 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("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)]);
|
||||||
}
|
}
|
||||||
@ -20,9 +18,9 @@ function buffer2bits(buff) {
|
|||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -36,11 +34,7 @@ describe("EdDSA test", function () {
|
|||||||
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 () => {
|
||||||
@ -66,9 +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,12 +1,11 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const snarkjs = require("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 () {
|
||||||
|
|
||||||
@ -14,7 +13,7 @@ describe("EdDSA js test", function () {
|
|||||||
|
|
||||||
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);
|
||||||
|
|
||||||
@ -49,7 +48,7 @@ describe("EdDSA js test", function () {
|
|||||||
|
|
||||||
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");
|
||||||
|
|
||||||
@ -68,12 +67,12 @@ describe("EdDSA js test", function () {
|
|||||||
assert.equal(signature.R8[1].toString(),
|
assert.equal(signature.R8[1].toString(),
|
||||||
"15383486972088797283337779941324724402501462225528836549661220478783371668959");
|
"15383486972088797283337779941324724402501462225528836549661220478783371668959");
|
||||||
assert.equal(signature.S.toString(),
|
assert.equal(signature.S.toString(),
|
||||||
"248298168863866362217836334079793350221620631973732197668910946177382043688");
|
"1398758333392199195742243841591064350253744445503462896781493968760929513778");
|
||||||
|
|
||||||
const pSignature = eddsa.packSignature(signature);
|
const pSignature = eddsa.packSignature(signature);
|
||||||
assert.equal(pSignature.toString("hex"), ""+
|
assert.equal(pSignature.toString("hex"), ""+
|
||||||
"dfedb4315d3f2eb4de2d3c510d7a987dcab67089c8ace06308827bf5bcbe02a2"+
|
"dfedb4315d3f2eb4de2d3c510d7a987dcab67089c8ace06308827bf5bcbe02a2"+
|
||||||
"28506bce274aa1b3f7e7c2fd7e4fe09bff8f9aa37a42def7994e98f322888c00");
|
"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("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,20 +29,22 @@ 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");
|
||||||
|
|
||||||
@ -57,14 +55,14 @@ describe("EdDSA MiMC test", function () {
|
|||||||
|
|
||||||
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) );
|
||||||
@ -73,7 +71,7 @@ describe("EdDSA MiMC test", function () {
|
|||||||
|
|
||||||
|
|
||||||
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");
|
||||||
|
|
||||||
@ -84,15 +82,16 @@ 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: 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,29 +1,25 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("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,20 +29,25 @@ 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");
|
||||||
|
|
||||||
@ -57,14 +58,14 @@ describe("EdDSA Poseidon test", function () {
|
|||||||
|
|
||||||
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) );
|
||||||
@ -73,7 +74,7 @@ describe("EdDSA Poseidon test", function () {
|
|||||||
|
|
||||||
|
|
||||||
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");
|
||||||
|
|
||||||
@ -84,15 +85,15 @@ describe("EdDSA Poseidon test", function () {
|
|||||||
|
|
||||||
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,172 +1,115 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("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"));
|
const circuit = await tester(path.join(__dirname, "circuits", "escalarmulw4table_test.circom"));
|
||||||
|
|
||||||
// console.log(JSON.stringify(cirDef, null, 1));
|
const w = await circuit.calculateWitness({in: 1});
|
||||||
|
|
||||||
// assert.equal(cirDef.nVars, 2);
|
await circuit.checkConstraints(w);
|
||||||
|
|
||||||
const circuit = new snarkjs.Circuit(cirDef);
|
let g = [
|
||||||
|
Fr.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
||||||
|
Fr.e("16950150798460657717958625567821834550301663161624707787222815936182638968203")
|
||||||
|
];
|
||||||
|
|
||||||
console.log("NConstrains: " + circuit.nConstraints);
|
let dbl= [Fr.e("0"), Fr.e("1")];
|
||||||
|
|
||||||
const w = circuit.calculateWitness({in: 1});
|
const expectedOut = [];
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
|
||||||
|
|
||||||
let g = [bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
|
||||||
bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")]
|
|
||||||
|
|
||||||
dbl= [bigInt("0"), snarkjs.bigInt("1")];
|
|
||||||
|
|
||||||
for (let i=0; i<16; i++) {
|
for (let i=0; i<16; i++) {
|
||||||
const xout1 = w[circuit.getSignalIdx(`main.out[${i}][0]`)];
|
|
||||||
const yout1 = w[circuit.getSignalIdx(`main.out[${i}][1]`)];
|
|
||||||
|
|
||||||
// console.log(xout1.toString());
|
expectedOut.push(dbl);
|
||||||
// console.log(yout1.toString());
|
dbl = babyJub.addPoint(dbl,g);
|
||||||
// console.log(dbl[0]);
|
|
||||||
// console.log(dbl[1]);
|
|
||||||
|
|
||||||
assert(xout1.equals(dbl[0]));
|
|
||||||
assert(yout1.equals(dbl[1]));
|
|
||||||
|
|
||||||
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"));
|
const circuit = await tester(path.join(__dirname, "circuits", "escalarmulw4table_test3.circom"));
|
||||||
|
|
||||||
// console.log(JSON.stringify(cirDef, null, 1));
|
const w = await circuit.calculateWitness({in: 1});
|
||||||
|
|
||||||
// assert.equal(cirDef.nVars, 2);
|
await circuit.checkConstraints(w);
|
||||||
|
|
||||||
const circuit = new snarkjs.Circuit(cirDef);
|
let g = [
|
||||||
|
Fr.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
||||||
console.log("NConstrains: " + circuit.nConstraints);
|
Fr.e("16950150798460657717958625567821834550301663161624707787222815936182638968203")
|
||||||
|
];
|
||||||
const w = circuit.calculateWitness({in: 1});
|
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
|
||||||
|
|
||||||
let g = [snarkjs.bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
|
||||||
snarkjs.bigInt("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")];
|
||||||
|
|
||||||
|
const expectedOut = [];
|
||||||
|
|
||||||
for (let i=0; i<16; i++) {
|
for (let i=0; i<16; i++) {
|
||||||
const xout1 = w[circuit.getSignalIdx(`main.out[${i}][0]`)];
|
expectedOut.push(dbl);
|
||||||
const yout1 = w[circuit.getSignalIdx(`main.out[${i}][1]`)];
|
|
||||||
|
|
||||||
|
dbl = babyJub.addPoint(dbl,g);
|
||||||
// console.log(xout1.toString());
|
|
||||||
// console.log(yout1.toString());
|
|
||||||
// console.log(dbl[0]);
|
|
||||||
// console.log(dbl[1]);
|
|
||||||
|
|
||||||
assert(xout1.equals(dbl[0]));
|
|
||||||
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);
|
let g = [
|
||||||
|
Fr.e("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
||||||
|
Fr.e("16950150798460657717958625567821834550301663161624707787222815936182638968203")
|
||||||
|
];
|
||||||
|
|
||||||
const w = circuit.calculateWitness({"in": 31});
|
let c = [Fr.e(0), Fr.e(1)];
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
|
||||||
|
|
||||||
let g = [snarkjs.bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
|
||||||
snarkjs.bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")]
|
|
||||||
|
|
||||||
let c = [0n, 1n];
|
|
||||||
|
|
||||||
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,7 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("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) {
|
||||||
@ -18,41 +14,33 @@ 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});
|
const w = await circuitEMulAny.calculateWitness({"e": 1, "p": g});
|
||||||
|
|
||||||
assert(circuitEMulAny.checkWitness(w));
|
await circuitEMulAny.checkConstraints(w);
|
||||||
|
|
||||||
const xout = w[circuitEMulAny.getSignalIdx("main.out[0]")];
|
await circuitEMulAny.assertOut(w, {out: g}, true);
|
||||||
const yout = w[circuitEMulAny.getSignalIdx("main.out[1]")];
|
|
||||||
|
|
||||||
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 r = Fr.e("2736030358979909402780800718157159386076813972158567259200215660948447373041");
|
||||||
const w = circuitEMulAny.calculateWitness({"e": r, "p": g});
|
const w = await circuitEMulAny.calculateWitness({"e": r, "p": g});
|
||||||
|
|
||||||
assert(circuitEMulAny.checkWitness(w));
|
await circuitEMulAny.checkConstraints(w);
|
||||||
|
|
||||||
const xout = w[circuitEMulAny.getSignalIdx("main.out[0]")];
|
await circuitEMulAny.assertOut(w, {out: [0,1]}, true);
|
||||||
const yout = w[circuitEMulAny.getSignalIdx("main.out[1]")];
|
|
||||||
|
|
||||||
assert(xout.equals(bigInt.zero));
|
|
||||||
assert(yout.equals(bigInt.one));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("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)]);
|
||||||
}
|
}
|
||||||
@ -19,93 +16,74 @@ 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});
|
const w = await circuit.calculateWitness({"e": 0});
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
await circuit.checkConstraints(w);
|
||||||
|
|
||||||
const xout = w[circuit.getSignalIdx("main.out[0]")];
|
await circuit.assertOut(w, {out: [0,1]}, true);
|
||||||
const yout = w[circuit.getSignalIdx("main.out[1]")];
|
|
||||||
|
|
||||||
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});
|
const w = await circuit.calculateWitness({"e": 1}, true);
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
await circuit.checkConstraints(w);
|
||||||
|
|
||||||
const xout = w[circuit.getSignalIdx("main.out[0]")];
|
await circuit.assertOut(w, {out: babyjub.Base8});
|
||||||
const yout = w[circuit.getSignalIdx("main.out[1]")];
|
|
||||||
|
|
||||||
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 });
|
const w = await circuit.calculateWitness({"e": babyjub.subOrder }, true);
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
await circuit.checkConstraints(w);
|
||||||
|
|
||||||
const xout = w[circuit.getSignalIdx("main.out[0]")];
|
await circuit.assertOut(w, {out: [0,1]});
|
||||||
const yout = w[circuit.getSignalIdx("main.out[1]")];
|
|
||||||
|
|
||||||
assert(xout.equals(bigInt.zero));
|
|
||||||
assert(yout.equals(bigInt.one));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
|
const snarkjs = require("@tornado/snarkjs");
|
||||||
const snarkjs = require("snarkjs");
|
|
||||||
|
|
||||||
const bigInt = snarkjs.bigInt;
|
const bigInt = snarkjs.bigInt;
|
||||||
|
|
||||||
module.exports = function hexBits(cir, witness, sig, nBits) {
|
module.exports = function hexBits(cir, witness, sig, nBits) {
|
||||||
let v = bigInt(0);
|
let v = bigInt(0);
|
||||||
for (let i=nBits-1; i>=0; i--) {
|
for (let i = nBits - 1; i >= 0; i--) {
|
||||||
v = v.shiftLeft(1);
|
v = v.shiftLeft(1);
|
||||||
const name = sig+"["+i+"]";
|
const name = sig + "[" + i + "]";
|
||||||
const idx = cir.getSignalIdx(name);
|
const idx = cir.getSignalIdx(name);
|
||||||
const vbit = bigInt(witness[idx].toString());
|
const vbit = bigInt(witness[idx].toString());
|
||||||
if (vbit.equals(bigInt(1))) {
|
if (vbit.equals(bigInt(1))) {
|
||||||
@ -15,7 +14,7 @@ module.exports = function hexBits(cir, witness, sig, nBits) {
|
|||||||
} else if (vbit.equals(bigInt(0))) {
|
} else if (vbit.equals(bigInt(0))) {
|
||||||
v;
|
v;
|
||||||
} else {
|
} else {
|
||||||
console.log("Not Binary: "+name);
|
console.log("Not Binary: " + name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return v.toString(16);
|
return v.toString(16);
|
||||||
|
@ -1,35 +1,25 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("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);
|
||||||
|
|
||||||
assert.equal(res.toString(), res2.toString());
|
await circuit.assertOut(w, {out: res2});
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
|
||||||
|
|
||||||
|
await circuit.checkConstraints(w);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
const chai = require("chai");
|
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("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,46 +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 xLout = w[circuit.getSignalIdx("main.xL_out")];
|
|
||||||
const xRout = w[circuit.getSignalIdx("main.xR_out")];
|
|
||||||
|
|
||||||
const out2 = mimcjs.hash(1,2,3);
|
const out2 = mimcjs.hash(1,2,3);
|
||||||
|
|
||||||
assert.equal(xLout.toString(), out2.xL.toString());
|
await circuit.assertOut(w, {xL_out: out2.xL, xR_out: out2.xR});
|
||||||
assert.equal(xRout.toString(), out2.xR.toString());
|
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
await circuit.checkConstraints(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 w = circuit.calculateWitness({ins: [1, 2], k: 0});
|
|
||||||
|
|
||||||
const o1 = w[circuit.getSignalIdx("main.outs[0]")];
|
|
||||||
const o2 = w[circuit.getSignalIdx("main.outs[1]")];
|
|
||||||
const o3 = w[circuit.getSignalIdx("main.outs[2]")];
|
|
||||||
|
|
||||||
const out2 = mimcjs.multiHash([1,2], 0, 3);
|
const out2 = mimcjs.multiHash([1,2], 0, 3);
|
||||||
|
|
||||||
assert.equal(o1.toString(), out2[0].toString());
|
await circuit.assertOut(w, {outs: out2});
|
||||||
assert.equal(o2.toString(), out2[1].toString());
|
|
||||||
assert.equal(o3.toString(), out2[2].toString());
|
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
|
||||||
|
|
||||||
|
await circuit.checkConstraints(w);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("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,85 +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,133 +1,98 @@
|
|||||||
const chai = require("chai");
|
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("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"));
|
const circuit = await tester(path.join(__dirname, "circuits", "mux4_1.circom"));
|
||||||
|
|
||||||
// console.log(JSON.stringify(cirDef, null, 1));
|
|
||||||
|
|
||||||
// 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 = await tester(path.join(__dirname, "circuits", "mux3_1.circom"));
|
||||||
|
|
||||||
const circuit = new snarkjs.Circuit(cirDef);
|
|
||||||
|
|
||||||
console.log("NConstrains Mux3: " + circuit.nConstraints);
|
|
||||||
|
|
||||||
const ct8 = [
|
const ct8 = [
|
||||||
bigInt("37"),
|
Fr.e("37"),
|
||||||
bigInt("47"),
|
Fr.e("47"),
|
||||||
bigInt("53"),
|
Fr.e("53"),
|
||||||
bigInt("71"),
|
Fr.e("71"),
|
||||||
bigInt("89"),
|
Fr.e("89"),
|
||||||
bigInt("107"),
|
Fr.e("107"),
|
||||||
bigInt("163"),
|
Fr.e("163"),
|
||||||
bigInt("191")
|
Fr.e("191")
|
||||||
];
|
];
|
||||||
|
|
||||||
for (let i=0; i<8; i++) {
|
for (let i=0; i<8; i++) {
|
||||||
const w = circuit.calculateWitness({ "selector": i });
|
const w = await circuit.calculateWitness({ "selector": i }, true);
|
||||||
|
|
||||||
assert(w[0].equals(bigInt(1)));
|
await circuit.checkConstraints(w);
|
||||||
|
|
||||||
// console.log(i + " -> " + w[circuit.getSignalIdx("main.out")].toString());
|
await circuit.assertOut(w, {out: ct8[i]});
|
||||||
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 = await tester(path.join(__dirname, "circuits", "mux2_1.circom"));
|
||||||
|
|
||||||
const circuit = new snarkjs.Circuit(cirDef);
|
const ct4 = [
|
||||||
|
Fr.e("37"),
|
||||||
console.log("NConstrains Mux2: " + circuit.nConstraints);
|
Fr.e("47"),
|
||||||
|
Fr.e("53"),
|
||||||
const ct8 = [
|
Fr.e("71"),
|
||||||
bigInt("37"),
|
|
||||||
bigInt("47"),
|
|
||||||
bigInt("53"),
|
|
||||||
bigInt("71"),
|
|
||||||
];
|
];
|
||||||
|
|
||||||
for (let i=0; i<4; i++) {
|
for (let i=0; i<4; 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: ct4[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 1", async () => {
|
it("Should create a constant multiplexer 1", async () => {
|
||||||
|
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "mux1_1.circom"));
|
const circuit = await tester(path.join(__dirname, "circuits", "mux1_1.circom"));
|
||||||
|
|
||||||
const circuit = new snarkjs.Circuit(cirDef);
|
const ct2 = [
|
||||||
|
Fr.e("37"),
|
||||||
console.log("NConstrains Mux1: " + circuit.nConstraints);
|
Fr.e("47"),
|
||||||
|
|
||||||
const ct8 = [
|
|
||||||
bigInt("37"),
|
|
||||||
bigInt("47"),
|
|
||||||
];
|
];
|
||||||
|
|
||||||
for (let i=0; i<2; i++) {
|
for (let i=0; i<2; 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: ct2[i]});
|
||||||
|
|
||||||
// console.log(i + " -> " + w[circuit.getSignalIdx("main.out")].toString());
|
|
||||||
assert(w[circuit.getSignalIdx("main.out")].equals(ct8[i]));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,100 +1,77 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("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"),bigInt("19824078218392094440610104313265183977899662750282163392862422243483260492317")],
|
[Fr.e("10457101036533406547632367118273992217979173478358440826365724437999023779287"),Fr.e("19824078218392094440610104313265183977899662750282163392862422243483260492317")],
|
||||||
[bigInt("2671756056509184035029146175565761955751135805354291559563293617232983272177"),bigInt("2663205510731142763556352975002641716101654201788071096152948830924149045094")],
|
[Fr.e("2671756056509184035029146175565761955751135805354291559563293617232983272177"),Fr.e("2663205510731142763556352975002641716101654201788071096152948830924149045094")],
|
||||||
[bigInt("5802099305472655231388284418920769829666717045250560929368476121199858275951"),bigInt("5980429700218124965372158798884772646841287887664001482443826541541529227896")],
|
[Fr.e("5802099305472655231388284418920769829666717045250560929368476121199858275951"),Fr.e("5980429700218124965372158798884772646841287887664001482443826541541529227896")],
|
||||||
[bigInt("7107336197374528537877327281242680114152313102022415488494307685842428166594"),bigInt("2857869773864086953506483169737724679646433914307247183624878062391496185654")],
|
[Fr.e("7107336197374528537877327281242680114152313102022415488494307685842428166594"),Fr.e("2857869773864086953506483169737724679646433914307247183624878062391496185654")],
|
||||||
[bigInt("20265828622013100949498132415626198973119240347465898028410217039057588424236"),bigInt("1160461593266035632937973507065134938065359936056410650153315956301179689506")]
|
[Fr.e("20265828622013100949498132415626198973119240347465898028410217039057588424236"),Fr.e("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;
|
let w;
|
||||||
|
|
||||||
w = circuit.calculateWitness({ in: ["0", "0"]});
|
w = await circuit.calculateWitness({ in: ["0", "0"]}, true);
|
||||||
|
|
||||||
xout = w[circuit.getSignalIdx("main.out[0]")];
|
await circuit.assertOut(w, {out: [0,1]});
|
||||||
yout = w[circuit.getSignalIdx("main.out[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]")];
|
|
||||||
yout = w[circuit.getSignalIdx("main.out[1]")];
|
|
||||||
|
|
||||||
|
|
||||||
const r = babyJub.addPoint(
|
const r = babyJub.addPoint(
|
||||||
babyJub.mulPointEscalar(PBASE[0], 3),
|
babyJub.mulPointEscalar(PBASE[0], 3),
|
||||||
babyJub.mulPointEscalar(PBASE[1], 7)
|
babyJub.mulPointEscalar(PBASE[1], 7)
|
||||||
);
|
);
|
||||||
|
|
||||||
assert(xout.equals(r[0]));
|
await circuit.assertOut(w, {out: r});
|
||||||
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(
|
const r2 = babyJub.addPoint(
|
||||||
babyJub.mulPointEscalar(PBASE[0], allOnes),
|
babyJub.mulPointEscalar(PBASE[0], allOnes),
|
||||||
babyJub.mulPointEscalar(PBASE[1], allOnes)
|
babyJub.mulPointEscalar(PBASE[1], allOnes)
|
||||||
);
|
);
|
||||||
|
|
||||||
assert(xout.equals(r2[0]));
|
await circuit.assertOut(w, {out: r2});
|
||||||
assert(yout.equals(r2[1]));
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
const chai = require("chai");
|
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("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");
|
||||||
@ -15,60 +11,39 @@ 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;
|
let w;
|
||||||
|
|
||||||
w = circuit.calculateWitness({ in: 0});
|
w = await circuit.calculateWitness({ in: 0}, true);
|
||||||
|
|
||||||
xout = w[circuit.getSignalIdx("main.out[0]")];
|
|
||||||
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;
|
let w;
|
||||||
|
|
||||||
const n = bigInt.one.shl(253).sub(bigInt.one);
|
const n = Fr.sub(Fr.shl(Fr.one, Fr.e(253)), Fr.one);
|
||||||
console.log(n.toString(16));
|
|
||||||
|
|
||||||
w = circuit.calculateWitness({ in: n});
|
w = await circuit.calculateWitness({ in: n}, true);
|
||||||
|
|
||||||
xout = w[circuit.getSignalIdx("main.out[0]")];
|
|
||||||
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,11 +1,5 @@
|
|||||||
const chai = require("chai");
|
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("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");
|
||||||
|
|
||||||
@ -14,20 +8,16 @@ 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,60 +1,57 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("snarkjs");
|
const tester = require("circom").tester;
|
||||||
const compiler = require("circom");
|
|
||||||
var blake2b = require('blake2b');
|
|
||||||
|
|
||||||
const poseidon = require("../src/poseidon.js");
|
const poseidon = require("../src/poseidon.js");
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
describe("Blake2b version test", function() {
|
|
||||||
it("Should give the expected output for blake2b version", async () => {
|
|
||||||
var output = new Uint8Array(32);
|
|
||||||
var input = Buffer.from('poseidon_constants');
|
|
||||||
h = blake2b(output.length).update(input).digest('hex')
|
|
||||||
assert.equal('e57ba154fb2c47811dc1a2369b27e25a44915b4e4ece4eb8ec74850cb78e01b1', h);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("Poseidon Circuit test", function () {
|
describe("Poseidon Circuit test", function () {
|
||||||
let circuit;
|
let circuit6;
|
||||||
|
let circuit3;
|
||||||
|
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
|
|
||||||
before( async () => {
|
before( async () => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "poseidon_test.circom"));
|
circuit6 = await tester(path.join(__dirname, "circuits", "poseidon6_test.circom"));
|
||||||
|
circuit3 = await tester(path.join(__dirname, "circuits", "poseidon3_test.circom"));
|
||||||
circuit = new snarkjs.Circuit(cirDef);
|
|
||||||
|
|
||||||
console.log("Poseidon constraints: " + circuit.nConstraints);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should check constrain of hash([1, 2])", async () => {
|
it("Should check constrain of hash([1, 2]) t=6", async () => {
|
||||||
const w = circuit.calculateWitness({inputs: [1, 2]});
|
const w = await circuit6.calculateWitness({inputs: [1, 2, 0,0,0]}, true);
|
||||||
|
|
||||||
const res = w[circuit.getSignalIdx("main.out")];
|
const res2 = poseidon([1,2,0,0,0]);
|
||||||
|
assert.equal("3975478831357328722254985704342968745327876719981393787143845259590563829094", res2.toString());
|
||||||
const hash = poseidon.createHash(6, 8, 57);
|
await circuit6.assertOut(w, {out : res2});
|
||||||
|
await circuit6.checkConstraints(w);
|
||||||
const res2 = hash([1,2]);
|
|
||||||
assert.equal('12242166908188651009877250812424843524687801523336557272219921456462821518061', res2.toString());
|
|
||||||
assert.equal(res.toString(), res2.toString());
|
|
||||||
assert(circuit.checkWitness(w));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should check constrain of hash([3, 4])", async () => {
|
it("Should check constrain of hash([3, 4]) t=6", async () => {
|
||||||
const w = circuit.calculateWitness({inputs: [3, 4]});
|
const w = await circuit6.calculateWitness({inputs: [3, 4,5,10,23]});
|
||||||
|
|
||||||
const res = w[circuit.getSignalIdx("main.out")];
|
const res2 = poseidon([3, 4,5,10,23]);
|
||||||
|
|
||||||
const hash = poseidon.createHash(6, 8, 57);
|
assert.equal("18540626624821144952552691894137986276337186174352554475896834101336254024067", res2.toString());
|
||||||
|
await circuit6.assertOut(w, {out : res2});
|
||||||
|
await circuit6.checkConstraints(w);
|
||||||
|
});
|
||||||
|
|
||||||
const res2 = hash([3, 4]);
|
|
||||||
assert.equal('17185195740979599334254027721507328033796809509313949281114643312710535000993', res2.toString());
|
|
||||||
|
|
||||||
assert.equal(res.toString(), res2.toString());
|
it("Should check constrain of hash([1, 2]) t=3", async () => {
|
||||||
|
const w = await circuit3.calculateWitness({inputs: [1, 2]});
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
const res2 = poseidon([1,2]);
|
||||||
|
assert.equal("17117985411748610629288516079940078114952304104811071254131751175361957805920", res2.toString());
|
||||||
|
await circuit3.assertOut(w, {out : res2});
|
||||||
|
await circuit3.checkConstraints(w);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should check constrain of hash([3, 4]) t=3", async () => {
|
||||||
|
const w = await circuit3.calculateWitness({inputs: [3, 4]});
|
||||||
|
|
||||||
|
const res2 = poseidon([3, 4]);
|
||||||
|
assert.equal("21867347236198497199818917118739170715216974132230970409806500217655788551452", res2.toString());
|
||||||
|
await circuit3.assertOut(w, {out : res2});
|
||||||
|
await circuit3.checkConstraints(w);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -2,19 +2,18 @@ const ganache = require("ganache-cli");
|
|||||||
const Web3 = require("web3");
|
const Web3 = require("web3");
|
||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const poseidonGenContract = require("../src/poseidon_gencontract.js");
|
const poseidonGenContract = require("../src/poseidon_gencontract.js");
|
||||||
const Poseidon = require("../src/poseidon.js");
|
const poseidon = require("../src/poseidon.js");
|
||||||
const bigInt = require("snarkjs").bigInt;
|
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
const log = (msg) => { if (process.env.MOCHA_VERBOSE) console.log(msg); };
|
const log = (msg) => { if (process.env.MOCHA_VERBOSE) console.log(msg); };
|
||||||
|
|
||||||
const SEED = "mimc";
|
describe("Poseidon Smart contract test", function () {
|
||||||
|
|
||||||
describe("Poseidon Smart contract test", () => {
|
|
||||||
let testrpc;
|
let testrpc;
|
||||||
let web3;
|
let web3;
|
||||||
let mimc;
|
let poseidon6;
|
||||||
|
let poseidon3;
|
||||||
let accounts;
|
let accounts;
|
||||||
|
this.timeout(100000);
|
||||||
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
web3 = new Web3(ganache.provider(), null, { transactionConfirmationBlocks: 1 });
|
web3 = new Web3(ganache.provider(), null, { transactionConfirmationBlocks: 1 });
|
||||||
@ -22,28 +21,45 @@ describe("Poseidon Smart contract test", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Should deploy the contract", async () => {
|
it("Should deploy the contract", async () => {
|
||||||
const C = new web3.eth.Contract(poseidonGenContract.abi);
|
const C6 = new web3.eth.Contract(poseidonGenContract.generateABI(5));
|
||||||
|
const C3 = new web3.eth.Contract(poseidonGenContract.generateABI(2));
|
||||||
|
|
||||||
mimc = await C.deploy({
|
poseidon6 = await C6.deploy({
|
||||||
data: poseidonGenContract.createCode()
|
data: poseidonGenContract.createCode(5)
|
||||||
}).send({
|
}).send({
|
||||||
gas: 2500000,
|
gas: 5000000,
|
||||||
|
from: accounts[0]
|
||||||
|
});
|
||||||
|
poseidon3 = await C3.deploy({
|
||||||
|
data: poseidonGenContract.createCode(2)
|
||||||
|
}).send({
|
||||||
|
gas: 5000000,
|
||||||
from: accounts[0]
|
from: accounts[0]
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Shold calculate the mimic correctly", async () => {
|
it("Should calculate the poseidon correctly t=6", async () => {
|
||||||
|
|
||||||
const res = await mimc.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 hash = Poseidon.createHash(6, 8, 57);
|
const res2 = poseidon([1,2, 0, 0, 0]);
|
||||||
|
|
||||||
const res2 = hash([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());
|
||||||
});
|
});
|
||||||
|
it("Should calculate the poseidon correctly t=3", async () => {
|
||||||
|
|
||||||
|
const res = await poseidon3.methods.poseidon([1,2]).call();
|
||||||
|
|
||||||
|
// console.log("Cir: " + bigInt(res.toString(16)).toString(16));
|
||||||
|
|
||||||
|
const res2 = poseidon([1,2]);
|
||||||
|
// console.log("Ref: " + bigInt(res2).toString(16));
|
||||||
|
|
||||||
|
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,14 +1,14 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("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");
|
||||||
|
|
||||||
|
|
||||||
@ -34,7 +34,8 @@ function bitArray2buffer(a) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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 () => {
|
||||||
@ -45,17 +46,13 @@ describe("SHA256 test", () => {
|
|||||||
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;
|
||||||
@ -70,21 +67,12 @@ describe("SHA256 test", () => {
|
|||||||
|
|
||||||
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;
|
||||||
@ -95,7 +83,7 @@ describe("SHA256 test", () => {
|
|||||||
.digest("hex");
|
.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");
|
||||||
@ -103,34 +91,25 @@ describe("SHA256 test", () => {
|
|||||||
assert.equal(hash, hash2);
|
assert.equal(hash, hash2);
|
||||||
|
|
||||||
}).timeout(1000000);
|
}).timeout(1000000);
|
||||||
|
it ("Should calculate a hash of 2 compressor", async () => {
|
||||||
|
const cir = await tester(path.join(__dirname, "circuits", "sha256_test448.circom"));
|
||||||
it("Should calculate a hash of 2 compressor", async () => {
|
|
||||||
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")
|
const hash = crypto.createHash("sha256")
|
||||||
.update(b)
|
.update(b)
|
||||||
.digest("hex");
|
.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("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)]);
|
||||||
@ -14,75 +10,71 @@ 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;
|
||||||
|
this.timeout(100000);
|
||||||
|
|
||||||
before( async() => {
|
before( async() => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "sign_test.circom"));
|
circuit = await tester(path.join(__dirname, "circuits", "sign_test.circom"));
|
||||||
|
|
||||||
circuit = new snarkjs.Circuit(cirDef);
|
|
||||||
|
|
||||||
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});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -1,29 +1,11 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const snarkjs = require("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 () => {
|
||||||
@ -31,22 +13,22 @@ describe("SMT Javascript test", function () {
|
|||||||
|
|
||||||
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();
|
||||||
@ -78,11 +60,11 @@ describe("SMT Javascript test", function () {
|
|||||||
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);
|
||||||
@ -94,19 +76,19 @@ describe("SMT Javascript test", function () {
|
|||||||
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]);
|
||||||
@ -115,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);
|
||||||
@ -145,7 +127,7 @@ describe("SMT Javascript test", function () {
|
|||||||
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++) {
|
||||||
@ -156,7 +138,7 @@ describe("SMT Javascript test", function () {
|
|||||||
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);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -176,7 +158,16 @@ describe("SMT Javascript test", function () {
|
|||||||
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,25 +1,23 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("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,
|
||||||
@ -28,19 +26,20 @@ async function testInsert(tree, key, value, circuit, log ) {
|
|||||||
isOld0: res.isOld0 ? 1 : 0,
|
isOld0: res.isOld0 ? 1 : 0,
|
||||||
newKey: key,
|
newKey: key,
|
||||||
newValue: value
|
newValue: value
|
||||||
}, log);
|
}, true);
|
||||||
|
|
||||||
|
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,
|
||||||
@ -49,20 +48,19 @@ async function testDelete(tree, key, circuit) {
|
|||||||
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,
|
||||||
@ -73,53 +71,47 @@ async function testUpdate(tree, key, newValue, circuit) {
|
|||||||
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);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
it("Should remove an element", async () => {
|
it("Should remove an element", async () => {
|
||||||
await testDelete(tree, 111, circuit);
|
await testDelete(tree, 111, circuit);
|
||||||
await testDelete(tree, 333, circuit);
|
await testDelete(tree, 333, circuit);
|
||||||
});
|
});
|
||||||
|
|
||||||
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();
|
||||||
@ -178,8 +170,8 @@ 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,
|
||||||
@ -190,12 +182,12 @@ describe("SMT test", function () {
|
|||||||
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();
|
||||||
@ -213,5 +205,4 @@ describe("SMT test", function () {
|
|||||||
await testUpdate(tree1, 9, 999, circuit);
|
await testUpdate(tree1, 9, 999, circuit);
|
||||||
await testUpdate(tree1, 32, 323232, circuit);
|
await testUpdate(tree1, 32, 323232, circuit);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("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)]);
|
||||||
}
|
}
|
||||||
@ -19,9 +17,9 @@ async function testInclusion(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: 0,
|
fnc: 0,
|
||||||
root: tree.root,
|
root: tree.root,
|
||||||
@ -31,9 +29,10 @@ async function testInclusion(tree, key, circuit) {
|
|||||||
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) {
|
||||||
@ -41,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,
|
||||||
@ -55,21 +54,18 @@ async function testExclusion(tree, key, circuit) {
|
|||||||
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);
|
||||||
@ -97,7 +93,7 @@ describe("SMT test", function () {
|
|||||||
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,
|
||||||
@ -108,18 +104,20 @@ describe("SMT test", function () {
|
|||||||
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);
|
||||||
|
@ -1,98 +0,0 @@
|
|||||||
const path = require("path");
|
|
||||||
const snarkjs = require("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