Compare commits
No commits in common. "master" and "v0.0.3" have entirely different histories.
1
.npmrc
1
.npmrc
@ -1 +0,0 @@
|
||||
@tornado:registry=https://git.tornado.ws/api/packages/tornado-packages/npm/
|
||||
17
README.md
17
README.md
@ -1,17 +1,4 @@
|
||||
# CircomLib
|
||||
# cirpedersen
|
||||
|
||||
## Description
|
||||
Pedersen Hash and Exponentiation circuits using Baby Jub Curve in circom language
|
||||
|
||||
- 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).
|
||||
|
||||
## Organisation
|
||||
|
||||
This respository contains 5 folders:
|
||||
- `circuits`: it contains the implementation of different cryptographic primitives in circom language.
|
||||
- `calcpedersenbases`: set of functions in JavaScript used to find a set of points in [Baby Jubjub](https://github.com/barryWhiteHat/baby_jubjub) elliptic curve that serve as basis for the [Pedersen Hash](https://github.com/zcash/zcash/issues/2234).
|
||||
- `doc`: it contains some circuit schemes in ASCII (must be opened with Monodraw, an ASCII art editor for Mac).
|
||||
- `src`: it contains similar implementation of circuits in JavaScript.
|
||||
- `test`: tests.
|
||||
|
||||
A description of the specific circuit templates for the `circuit` folder will be soon updated.
|
||||
@ -1,24 +1,23 @@
|
||||
const bn128 = require("@tornado/snarkjs").bn128;
|
||||
const bigInt = require("@tornado/snarkjs").bigInt;
|
||||
const bn128 = require("snarkjs").bn128;
|
||||
const bigInt = require("snarkjs").bigInt;
|
||||
const createBlakeHash = require("blake-hash");
|
||||
const assert = require("assert");
|
||||
const babyJub = require("../src/babyjub");
|
||||
|
||||
function getPoint(S) {
|
||||
const F = bn128.Fr;
|
||||
const h = createBlakeHash("blake256").update(S).digest();
|
||||
|
||||
if (h.length != 32) {
|
||||
throw new Error("Invalid length");
|
||||
}
|
||||
assert(h.length == 32);
|
||||
|
||||
let sign = false;
|
||||
if (h[31] & 0x80) {
|
||||
h[31] = h[31] & 0x7f;
|
||||
h[31] = h[31] & 0x7F;
|
||||
sign = true;
|
||||
}
|
||||
|
||||
let y = bigInt(0);
|
||||
for (let i = 0; i < 32; i++) {
|
||||
for (let i=0; i<32; i++) {
|
||||
y = y.shl(8);
|
||||
y = y.add(bigInt(h[i]));
|
||||
}
|
||||
@ -28,7 +27,9 @@ function getPoint(S) {
|
||||
|
||||
const y2 = F.square(y);
|
||||
|
||||
let x = F.sqrt(F.div(F.sub(F.one, y2), F.sub(a, F.mul(d, y2))));
|
||||
let x = F.sqrt(F.div(
|
||||
F.sub(F.one, y2),
|
||||
F.sub(a, F.mul(d, y2))));
|
||||
|
||||
if (x == null) return null;
|
||||
|
||||
@ -41,34 +42,39 @@ function getPoint(S) {
|
||||
return p8;
|
||||
}
|
||||
|
||||
|
||||
function generatePoint(S) {
|
||||
let p = null;
|
||||
let p= null;
|
||||
let idx = 0;
|
||||
while (p == null) {
|
||||
while (p==null) {
|
||||
let sidx = "" + idx;
|
||||
while (sidx.length < 16) sidx = "0" + sidx;
|
||||
p = getPoint(S + "_" + sidx);
|
||||
while (sidx.length<16) sidx = "0"+sidx;
|
||||
p = getPoint(S+"_"+sidx);
|
||||
idx++;
|
||||
}
|
||||
if (!babyJub.inCurve(p)) {
|
||||
throw new Error("Point not in curve");
|
||||
}
|
||||
assert(babyJub.inCurve(p), "Point not in curve");
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const g = [
|
||||
bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
||||
bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203"),
|
||||
];
|
||||
bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
||||
bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475")];
|
||||
|
||||
// Sanity check
|
||||
if (!babyJub.inCurve(g)) {
|
||||
throw new Error("Generator not In curve -> Some thing goes wrong...");
|
||||
}
|
||||
|
||||
for (let i = 0; i < 25; i++) {
|
||||
let S = "" + i;
|
||||
while (S.length < 16) S = "0" + S;
|
||||
const P = generatePoint("Iden3_PedersenGenerator_" + S);
|
||||
for (let i=0; i<25; i++) {
|
||||
let S = "" +i;
|
||||
while (S.length<16) S = "0"+S;
|
||||
const P = generatePoint("Iden3_PedersenGenerator_"+S);
|
||||
console.log(`[${P[0].toString()}, ${P[1].toString()}]`);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
122243
circuit.json
Normal file
122243
circuit.json
Normal file
File diff suppressed because one or more lines are too long
14
circuit/aliascheck.circom
Normal file
14
circuit/aliascheck.circom
Normal file
@ -0,0 +1,14 @@
|
||||
|
||||
include "compconstant.circom";
|
||||
|
||||
|
||||
template AliasCheck() {
|
||||
|
||||
signal input in[254];
|
||||
|
||||
component compConstant = CompConstant(-1);
|
||||
|
||||
for (var i=0; i<254; i++) in[i] ==> compConstant.in[i];
|
||||
|
||||
compConstant.out === 0;
|
||||
}
|
||||
64
circuit/babyjub.circom
Normal file
64
circuit/babyjub.circom
Normal file
@ -0,0 +1,64 @@
|
||||
|
||||
|
||||
template BabyAdd() {
|
||||
signal input x1;
|
||||
signal input y1;
|
||||
signal input x2;
|
||||
signal input y2;
|
||||
signal output xout;
|
||||
signal output yout;
|
||||
|
||||
signal beta;
|
||||
signal gamma;
|
||||
signal delta;
|
||||
signal epsilon;
|
||||
signal tau;
|
||||
|
||||
var a = 168700;
|
||||
var d = 168696;
|
||||
|
||||
beta <== x1*y2;
|
||||
gamma <== y1*x2;
|
||||
delta <== y1*y2;
|
||||
epsilon <== x1*x2;
|
||||
tau <== delta * epsilon;
|
||||
|
||||
xout <-- (beta + gamma) / (1+ d*tau);
|
||||
(1+ d*tau) * xout === (beta + gamma);
|
||||
|
||||
yout <-- (delta - a * epsilon) / (1-d*tau);
|
||||
(1-d*tau)*yout === (delta - a * epsilon);
|
||||
}
|
||||
|
||||
template BabyDbl() {
|
||||
signal input x;
|
||||
signal input y;
|
||||
signal output xout;
|
||||
signal output yout;
|
||||
|
||||
component adder = BabyAdd();
|
||||
adder.x1 <== x;
|
||||
adder.y1 <== y;
|
||||
adder.x2 <== x;
|
||||
adder.y2 <== y;
|
||||
|
||||
adder.xout ==> xout;
|
||||
adder.yout ==> yout;
|
||||
}
|
||||
|
||||
|
||||
template BabyCheck() {
|
||||
signal input x;
|
||||
signal input y;
|
||||
|
||||
signal x2;
|
||||
signal y2;
|
||||
|
||||
var a = 168700;
|
||||
var d = 168696;
|
||||
|
||||
x2 <== x*x;
|
||||
y2 <== y*y;
|
||||
|
||||
a*x2 + y2 === 1 + d*x2*y2;
|
||||
}
|
||||
@ -1,23 +1,5 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
include "bitify.circom";
|
||||
include "../node_modules/circom/circuits/bitify.circom";
|
||||
|
||||
// Returns 1 if in (in binary) > ct
|
||||
|
||||
@ -1,28 +1,14 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
include "aliascheck.circom";
|
||||
include "compconstant.circom";
|
||||
include "pointbits.circom";
|
||||
include "pedersen.circom";
|
||||
include "pedersen2.circom";
|
||||
include "escalarmulany.circom";
|
||||
include "escalarmulfix.circom";
|
||||
|
||||
/*
|
||||
include "../node_modules/circom/circuits/bitify.circom";
|
||||
include "babyjub.circom";
|
||||
*/
|
||||
|
||||
template EdDSAVerifier(n) {
|
||||
signal input msg[n];
|
||||
|
||||
@ -40,15 +26,12 @@ template EdDSAVerifier(n) {
|
||||
|
||||
// Ensure S<Subgroup Order
|
||||
|
||||
component aliasCheck = AliasCheckBabyJub();
|
||||
aliasCheck.enabled <== 1;
|
||||
component compConstant = CompConstant(2736030358979909402780800718157159386076813972158567259200215660948447373040);
|
||||
|
||||
for (i=0; i<251; i++) {
|
||||
S[i] ==> aliasCheck.in[i];
|
||||
for (i=0; i<254; i++) {
|
||||
S[i] ==> compConstant.in[i];
|
||||
}
|
||||
S[251] === 0;
|
||||
S[252] === 0;
|
||||
S[253] === 0;
|
||||
compConstant.out === 0;
|
||||
S[254] === 0;
|
||||
S[255] === 0;
|
||||
|
||||
@ -126,8 +109,8 @@ template EdDSAVerifier(n) {
|
||||
// Calculate left side of equation left = S*B8
|
||||
|
||||
var BASE8 = [
|
||||
5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||
16950150798460657717958625567821834550301663161624707787222815936182638968203
|
||||
17777552123799933955779906779655732241715742912184938656739573121738514868268,
|
||||
2626589144620713026669568689430873010625803728049924121243784502389097019475
|
||||
];
|
||||
component mulFix = EscalarMulFix(256, BASE8);
|
||||
for (i=0; i<256; i++) {
|
||||
@ -1,22 +1,3 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
┏━━━━━━━━━━━┓
|
||||
@ -71,7 +52,7 @@ template EscalarMulWindow(base, k) {
|
||||
signal input sel[4];
|
||||
signal output out[2];
|
||||
|
||||
var table;
|
||||
component table;
|
||||
component mux;
|
||||
component adder;
|
||||
|
||||
@ -86,8 +67,8 @@ template EscalarMulWindow(base, k) {
|
||||
}
|
||||
|
||||
for (i=0; i<16; i++) {
|
||||
mux.c[0][i] <== table[i][0];
|
||||
mux.c[1][i] <== table[i][1];
|
||||
table.out[i][0] ==> mux.c[0][i];
|
||||
table.out[i][1] ==> mux.c[1][i];
|
||||
}
|
||||
|
||||
in[0] ==> adder.x1;
|
||||
@ -1,25 +1,6 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
include "montgomery.circom";
|
||||
include "babyjub.circom";
|
||||
include "comparators.circom";
|
||||
|
||||
template Multiplexor2() {
|
||||
signal input sel;
|
||||
@ -139,8 +120,6 @@ template EscalarMulAny(n) {
|
||||
component doublers[nsegments-1];
|
||||
component m2e[nsegments-1];
|
||||
component adders[nsegments-1];
|
||||
component zeropoint = IsZero();
|
||||
zeropoint.in <== p[0];
|
||||
|
||||
var s;
|
||||
var i;
|
||||
@ -157,9 +136,8 @@ template EscalarMulAny(n) {
|
||||
}
|
||||
|
||||
if (s==0) {
|
||||
// force G8 point if input point is zero
|
||||
segments[s].p[0] <== p[0] + (5299619240641551281634865583518297030282874472190772894086521144482721001553 - p[0])*zeropoint.out;
|
||||
segments[s].p[1] <== p[1] + (16950150798460657717958625567821834550301663161624707787222815936182638968203 - p[1])*zeropoint.out;
|
||||
p[0] ==> segments[s].p[0];
|
||||
p[1] ==> segments[s].p[1];
|
||||
} else {
|
||||
doublers[s-1] = MontgomeryDouble();
|
||||
m2e[s-1] = Montgomery2Edwards();
|
||||
@ -187,10 +165,10 @@ template EscalarMulAny(n) {
|
||||
}
|
||||
|
||||
if (nsegments == 1) {
|
||||
segments[0].out[0]*(1-zeropoint.out) ==> out[0];
|
||||
segments[0].out[1]+(1-segments[0].out[1])*zeropoint.out ==> out[1];
|
||||
segments[0].out[0] ==> out[0];
|
||||
segments[0].out[1] ==> out[1];
|
||||
} else {
|
||||
adders[nsegments-2].xout*(1-zeropoint.out) ==> out[0];
|
||||
adders[nsegments-2].yout+(1-adders[nsegments-2].yout)*zeropoint.out ==> out[1];
|
||||
adders[nsegments-2].xout ==> out[0];
|
||||
adders[nsegments-2].yout ==> out[1];
|
||||
}
|
||||
}
|
||||
@ -1,22 +1,3 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
include "mux3.circom";
|
||||
include "montgomery.circom";
|
||||
include "babyjub.circom";
|
||||
@ -28,23 +9,6 @@ include "babyjub.circom";
|
||||
|
||||
The result should be compensated.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
The scalar is s = a0 + a1*2^3 + a2*2^6 + ...... + a81*2^243
|
||||
First We calculate Q = B + 2^3*B + 2^6*B + ......... + 2^246*B
|
||||
|
||||
Then we calculate S1 = 2*2^246*B + (1 + a0)*B + (2^3 + a1)*B + .....+ (2^243 + a81)*B
|
||||
|
||||
And Finaly we compute the result: RES = SQ - Q
|
||||
|
||||
As you can see the input of the adders cannot be equal nor zero, except for the last
|
||||
substraction that it's done in montgomery.
|
||||
|
||||
A good way to see it is that the accumulator input of the adder >= 2^247*B and the other input
|
||||
is the output of the windows that it's going to be <= 2^246*B
|
||||
*/
|
||||
/* base must not be the neutral element nor points of small order */
|
||||
template WindowMulFix() {
|
||||
signal input in[3];
|
||||
signal input base[2];
|
||||
@ -134,12 +98,11 @@ template WindowMulFix() {
|
||||
|
||||
/*
|
||||
This component does a multiplication of a escalar times a fix base
|
||||
nWindows must not exceed 82
|
||||
Signals:
|
||||
e: The scalar in bits
|
||||
base: the base point in edwards format
|
||||
out: The result
|
||||
dbl: Point in Montgomery to be linked to the next segment.
|
||||
dbl: Point in Edwards to be linked to the next segment.
|
||||
*/
|
||||
|
||||
template SegmentMulFix(nWindows) {
|
||||
@ -158,60 +121,54 @@ template SegmentMulFix(nWindows) {
|
||||
e2m.in[1] <== base[1];
|
||||
|
||||
component windows[nWindows];
|
||||
component adders[nWindows];
|
||||
component cadders[nWindows];
|
||||
|
||||
// In the last step we add an extra doubler so that numbers do not match.
|
||||
component dblLast = MontgomeryDouble();
|
||||
|
||||
component adders[nWindows-1];
|
||||
component cadders[nWindows-1];
|
||||
for (i=0; i<nWindows; i++) {
|
||||
windows[i] = WindowMulFix();
|
||||
cadders[i] = MontgomeryAdd();
|
||||
if (i==0) {
|
||||
windows[i].base[0] <== e2m.out[0];
|
||||
windows[i].base[1] <== e2m.out[1];
|
||||
cadders[i].in1[0] <== e2m.out[0];
|
||||
cadders[i].in1[1] <== e2m.out[1];
|
||||
} else {
|
||||
windows[i].base[0] <== windows[i-1].out8[0];
|
||||
windows[i].base[1] <== windows[i-1].out8[1];
|
||||
cadders[i].in1[0] <== cadders[i-1].out[0];
|
||||
cadders[i].in1[1] <== cadders[i-1].out[1];
|
||||
}
|
||||
if (i<nWindows-1) {
|
||||
cadders[i].in2[0] <== windows[i].out8[0];
|
||||
cadders[i].in2[1] <== windows[i].out8[1];
|
||||
} else {
|
||||
dblLast.in[0] <== windows[i].out8[0];
|
||||
dblLast.in[1] <== windows[i].out8[1];
|
||||
cadders[i].in2[0] <== dblLast.out[0];
|
||||
cadders[i].in2[1] <== dblLast.out[1];
|
||||
|
||||
adders[i-1] = MontgomeryAdd();
|
||||
cadders[i-1] = MontgomeryAdd();
|
||||
if (i==1) {
|
||||
adders[i-1].in1[0] <== windows[0].out[0];
|
||||
adders[i-1].in1[1] <== windows[0].out[1];
|
||||
cadders[i-1].in1[0] <== e2m.out[0];
|
||||
cadders[i-1].in1[1] <== e2m.out[1];
|
||||
} else {
|
||||
adders[i-1].in1[0] <== adders[i-2].out[0];
|
||||
adders[i-1].in1[1] <== adders[i-2].out[1];
|
||||
cadders[i-1].in1[0] <== cadders[i-2].out[0];
|
||||
cadders[i-1].in1[1] <== cadders[i-2].out[1];
|
||||
}
|
||||
adders[i-1].in2[0] <== windows[i].out[0];
|
||||
adders[i-1].in2[1] <== windows[i].out[1];
|
||||
cadders[i-1].in2[0] <== windows[i-1].out8[0];
|
||||
cadders[i-1].in2[1] <== windows[i-1].out8[1];
|
||||
}
|
||||
for (j=0; j<3; j++) {
|
||||
windows[i].in[j] <== e[3*i+j];
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<nWindows; i++) {
|
||||
adders[i] = MontgomeryAdd();
|
||||
if (i==0) {
|
||||
adders[i].in1[0] <== dblLast.out[0];
|
||||
adders[i].in1[1] <== dblLast.out[1];
|
||||
} else {
|
||||
adders[i].in1[0] <== adders[i-1].out[0];
|
||||
adders[i].in1[1] <== adders[i-1].out[1];
|
||||
}
|
||||
adders[i].in2[0] <== windows[i].out[0];
|
||||
adders[i].in2[1] <== windows[i].out[1];
|
||||
}
|
||||
|
||||
component m2e = Montgomery2Edwards();
|
||||
component cm2e = Montgomery2Edwards();
|
||||
|
||||
m2e.in[0] <== adders[nWindows-1].out[0];
|
||||
m2e.in[1] <== adders[nWindows-1].out[1];
|
||||
cm2e.in[0] <== cadders[nWindows-1].out[0];
|
||||
cm2e.in[1] <== cadders[nWindows-1].out[1];
|
||||
if (nWindows > 1) {
|
||||
m2e.in[0] <== adders[nWindows-2].out[0];
|
||||
m2e.in[1] <== adders[nWindows-2].out[1];
|
||||
cm2e.in[0] <== cadders[nWindows-2].out[0];
|
||||
cm2e.in[1] <== cadders[nWindows-2].out[1];
|
||||
} else {
|
||||
m2e.in[0] <== windows[0].out[0];
|
||||
m2e.in[1] <== windows[0].out[1];
|
||||
cm2e.in[0] <== e2m.out[0];
|
||||
cm2e.in[1] <== e2m.out[1];
|
||||
}
|
||||
|
||||
component cAdd = BabyAdd();
|
||||
cAdd.x1 <== m2e.out[0];
|
||||
@ -219,6 +176,7 @@ template SegmentMulFix(nWindows) {
|
||||
cAdd.x2 <== -cm2e.out[0];
|
||||
cAdd.y2 <== cm2e.out[1];
|
||||
|
||||
|
||||
cAdd.xout ==> out[0];
|
||||
cAdd.yout ==> out[1];
|
||||
|
||||
@ -237,8 +195,8 @@ template EscalarMulFix(n, BASE) {
|
||||
signal input e[n]; // Input in binary format
|
||||
signal output out[2]; // Point (Twisted format)
|
||||
|
||||
var nsegments = (n-1)\246 +1; // 249 probably would work. But I'm not sure and for security I keep 246
|
||||
var nlastsegment = n - (nsegments-1)*246;
|
||||
var nsegments = (n-1)\249 +1;
|
||||
var nlastsegment = n - (nsegments-1)*249;
|
||||
|
||||
component segments[nsegments];
|
||||
|
||||
@ -248,17 +206,17 @@ template EscalarMulFix(n, BASE) {
|
||||
var s;
|
||||
var i;
|
||||
var nseg;
|
||||
var nWindows;
|
||||
var nWindows
|
||||
|
||||
for (s=0; s<nsegments; s++) {
|
||||
|
||||
nseg = (s < nsegments-1) ? 246 : nlastsegment;
|
||||
nseg = (s < nsegments-1) ? 249 : nlastsegment;
|
||||
nWindows = ((nseg - 1)\3)+1;
|
||||
|
||||
segments[s] = SegmentMulFix(nWindows);
|
||||
|
||||
for (i=0; i<nseg; i++) {
|
||||
segments[s].e[i] <== e[s*246+i];
|
||||
segments[s].e[i] <== e[s*249+i];
|
||||
}
|
||||
|
||||
for (i = nseg; i<nWindows*3; i++) {
|
||||
30
circuit/escalarmulw4table.circom
Normal file
30
circuit/escalarmulw4table.circom
Normal file
@ -0,0 +1,30 @@
|
||||
function pointAdd(x1,y1,x2,y2) {
|
||||
var a = 168700;
|
||||
var d = 168696;
|
||||
|
||||
var res[2];
|
||||
res[0] = (x1*y2 + y1*x2) / (1 + d*x1*x2*y1*y2);
|
||||
res[1] = (y1*y2 - a*x1*x2) / (1 - d*x1*x2*y1*y2);
|
||||
return res;
|
||||
}
|
||||
|
||||
template EscalarMulW4Table(base, k) {
|
||||
signal output out[16][2];
|
||||
|
||||
var i;
|
||||
var p[2];
|
||||
|
||||
var dbl = base;
|
||||
|
||||
for (i=0; i<k*4; i++) {
|
||||
dbl = pointAdd(dbl[0], dbl[1], dbl[0], dbl[1]);
|
||||
}
|
||||
|
||||
out[0][0] <== 0;
|
||||
out[0][1] <== 1;
|
||||
for (i=1; i<16; i++) {
|
||||
p = pointAdd(out[i-1][0], out[i-1][1], dbl[0], dbl[1]);
|
||||
out[i][0] <== p[0];
|
||||
out[i][1] <== p[1];
|
||||
}
|
||||
}
|
||||
@ -1,21 +1,3 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
Source: https://en.wikipedia.org/wiki/Montgomery_curve
|
||||
@ -85,7 +67,6 @@ template Montgomery2Edwards() {
|
||||
|
||||
*/
|
||||
|
||||
/* in1 must be != in2 */
|
||||
template MontgomeryAdd() {
|
||||
signal input in1[2];
|
||||
signal input in2[2];
|
||||
@ -1,22 +1,3 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
template MultiMux3(n) {
|
||||
signal input c[n][8]; // Constants
|
||||
signal input s[3]; // Selector
|
||||
@ -1,21 +1,6 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
template MultiMux4(n) {
|
||||
signal input c[n][16]; // Constants
|
||||
48
circuit/pedersen.circom
Normal file
48
circuit/pedersen.circom
Normal file
@ -0,0 +1,48 @@
|
||||
|
||||
include "escalarmul.circom";
|
||||
|
||||
template Pedersen(n) {
|
||||
signal input in[n];
|
||||
signal output out[2];
|
||||
|
||||
var nexps = ((n-1) \ 250) + 1;
|
||||
var nlastbits = n - (nexps-1)*250;
|
||||
|
||||
component escalarMuls[nexps];
|
||||
|
||||
var PBASE = [
|
||||
[ 6842263847932328569390632736104801120816056295876316310227967232893658007436,
|
||||
10520112236148895828506510766039255961372323270202387671483666293012156799229],
|
||||
[ 7512553369533424708326990019377586455744651641787163924108944444109352325495,
|
||||
242060483180498555826438209654403949979206323274480625257315595534333598496],
|
||||
[ 480315709862415282411588615813248553518720286084247594626493599605932342246,
|
||||
15016559215090999873142530067666085992648246670781771102893391410239675444873],
|
||||
[ 8311398801616893527636419786153024398643144699386228070202625261657263599049,
|
||||
11125962584728296601438821974884453267303385157860713577195820780853779600315],
|
||||
[ 1924118814882677827825936037840538695314492559747259292440881566152665343441,
|
||||
17232376423406964731689089286495480735310130852288107159412732879983310795144]
|
||||
];
|
||||
|
||||
var i;
|
||||
var j;
|
||||
var nexpbits;
|
||||
for (i=0; i<nexps; i++) {
|
||||
nexpbits = (i == nexps-1) ? nlastbits : 250;
|
||||
escalarMuls[i] = EscalarMul(nexpbits, PBASE[i]);
|
||||
|
||||
for (j=0; j<nexpbits; j++) {
|
||||
escalarMuls[i].in[j] <== in[250*i + j];
|
||||
}
|
||||
|
||||
if (i==0) {
|
||||
escalarMuls[i].inp[0] <== 0;
|
||||
escalarMuls[i].inp[1] <== 1;
|
||||
} else {
|
||||
escalarMuls[i].inp[0] <== escalarMuls[i-1].out[0];
|
||||
escalarMuls[i].inp[1] <== escalarMuls[i-1].out[1];
|
||||
}
|
||||
}
|
||||
|
||||
escalarMuls[nexps-1].out[0] ==> out[0];
|
||||
escalarMuls[nexps-1].out[1] ==> out[1];
|
||||
}
|
||||
@ -1,22 +1,3 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
include "montgomery.circom";
|
||||
include "mux3.circom";
|
||||
include "babyjub.circom";
|
||||
@ -108,7 +89,6 @@ template Window4() {
|
||||
}
|
||||
|
||||
|
||||
/* nWindows must not exceed 50 */
|
||||
template Segment(nWindows) {
|
||||
signal input in[nWindows*4];
|
||||
signal input base[2];
|
||||
@ -178,16 +158,16 @@ template Pedersen(n) {
|
||||
signal output out[2];
|
||||
|
||||
var BASE = [
|
||||
[10457101036533406547632367118273992217979173478358440826365724437999023779287,19824078218392094440610104313265183977899662750282163392862422243483260492317],
|
||||
[2671756056509184035029146175565761955751135805354291559563293617232983272177,2663205510731142763556352975002641716101654201788071096152948830924149045094],
|
||||
[5802099305472655231388284418920769829666717045250560929368476121199858275951,5980429700218124965372158798884772646841287887664001482443826541541529227896],
|
||||
[7107336197374528537877327281242680114152313102022415488494307685842428166594,2857869773864086953506483169737724679646433914307247183624878062391496185654],
|
||||
[20265828622013100949498132415626198973119240347465898028410217039057588424236,1160461593266035632937973507065134938065359936056410650153315956301179689506],
|
||||
[1487999857809287756929114517587739322941449154962237464737694709326309567994,14017256862867289575056460215526364897734808720610101650676790868051368668003],
|
||||
[14618644331049802168996997831720384953259095788558646464435263343433563860015,13115243279999696210147231297848654998887864576952244320558158620692603342236],
|
||||
[6814338563135591367010655964669793483652536871717891893032616415581401894627,13660303521961041205824633772157003587453809761793065294055279768121314853695],
|
||||
[3571615583211663069428808372184817973703476260057504149923239576077102575715,11981351099832644138306422070127357074117642951423551606012551622164230222506],
|
||||
[18597552580465440374022635246985743886550544261632147935254624835147509493269,6753322320275422086923032033899357299485124665258735666995435957890214041481]
|
||||
[7889815880984390413826091016397158135734961432619494935997950708325418623781,8846020814737052626835496416415322522216827521798085437978304928900248828704],
|
||||
[12932435660254426850246080929365951045207624124386035886549006330955720993567,15876660444082442781217588393435527739441124986236154572507597829115005542086],
|
||||
[2482397177297734131621151094340467680859038448217226675361423673093734165962,10039279516804305991696249700635360957313934801940294703211894781106216299926],
|
||||
[17157815998940296936592098789990444736073034804807810484873853349962905015352,6488208869655503622669430389521947006738035600928015942696596112432120303604],
|
||||
[264004460746169389447419243214191481604172623204375600962322511417379874376,2415858116338771134001541482988382151008857516531390792628421155957250972277],
|
||||
[4135925743285698117252356077971179769271452015650275231796007492648697405139,10188226868678337759614729372197905253307539893323271103976079007344248400845],
|
||||
[1774758779250924961062140611815304699163957993414252473010092444201412186500,4347026286058522695608532575722049241297833321096891696953943795644684841805],
|
||||
[7879866447646097585900946926276218605564915618236971624614091698429769712458,2093592432852088858177276030443845730480437238346603396739626046140688969347],
|
||||
[8298560996095230984182228319122592575131718101813938808256495049817179791777,1767915891871602626938298102360238720016341966012238026281701463959008338852],
|
||||
[10415885340847357003805466620366840573458521568359796855704531856219635265921,3432650026491357206165099540731361444311747596326968441647905394914712226413]
|
||||
]
|
||||
|
||||
var nSegments = ((n-1)\200)+1;
|
||||
@ -1,23 +1,4 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
include "bitify.circom";
|
||||
include "../node_modules/circom/circuits/bitify.circom";
|
||||
include "aliascheck.circom";
|
||||
include "compconstant.circom";
|
||||
include "babyjub.circom";
|
||||
16
circuit/sign.circom
Normal file
16
circuit/sign.circom
Normal file
@ -0,0 +1,16 @@
|
||||
include "compconstant.circom";
|
||||
|
||||
template Sign() {
|
||||
signal input in[254];
|
||||
signal output sign;
|
||||
|
||||
component comp = CompConstant(10944121435919637611123202872628637544274182200208017171849102093287904247808);
|
||||
|
||||
var i;
|
||||
|
||||
for (i=0; i<254; i++) {
|
||||
comp.in[i] <== in[i];
|
||||
}
|
||||
|
||||
sign <== comp.out;
|
||||
}
|
||||
@ -1,830 +0,0 @@
|
||||
# CircomLib/Circuits
|
||||
|
||||
## Description
|
||||
|
||||
- This folder contains circuit templates for standard operations and many cryptographic primitives.
|
||||
- Below you can find specifications of each function. In the representation of elements, there are three tyes:
|
||||
- Binary
|
||||
- String
|
||||
- Field element (the field is specified in each case. We consider 2 possible fields: Fp and Fr, where p... and r... .)
|
||||
|
||||
## Table of Contents
|
||||
|
||||
[TOC]
|
||||
|
||||
## Jordi
|
||||
|
||||
* compconstant - Returns 1 if `in` (expanded to binary array) > `ct`
|
||||
* aliascheck - check if `in` (expanded to binary array) oveflowed its 254 bits (<= -1)
|
||||
* babyjub - twisted Edwards curve 168700.x^2 + y^2 = 1 + 168696.x^2.y^2
|
||||
* BabyAdd - (`xout`,`yout`) = (`x1`,`y1`) + (`x2`,`y2`)
|
||||
* BabyDbl - (`xout`,`yout`) = 2*(`x`,`y`)
|
||||
* BabyCheck - check that (`x`,`y`) is on the curve
|
||||
* binsub - binary subtraction
|
||||
* gates - logical gates
|
||||
* mimc - SNARK-friendly hash Minimal Multiplicative Complexity.
|
||||
* https://eprint.iacr.org/2016/492.pdf
|
||||
* zcash/zcash#2233
|
||||
* smt - Sparse Merkle Tree
|
||||
* https://ethresear.ch/t/optimizing-sparse-merkle-trees/3751
|
||||
* montgomery https://en.wikipedia.org/wiki/Montgomery_curve
|
||||
|
||||
## Circuits
|
||||
|
||||
### sha256
|
||||
|
||||
Folder containing the implementation of sha256 hash circuit.
|
||||
|
||||
### smt
|
||||
|
||||
Folder containing the circuit implementation of Sparse Merkle Trees.
|
||||
|
||||
### aliascheck
|
||||
|
||||
- `AliasCheck()`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
### 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?)
|
||||
|
||||
|
||||
- `BabyAdd()`
|
||||
|
||||
- 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
|
||||
|
||||
(`xout`, `yout`) = (`x1`,`y1`) + (`x2`,`y2`)
|
||||
= ((`x1y2`+`y1x2`)/(1+`dx1x2y1y2`)),(`y1y2`-`ax1x2`)/(1-`dx1x2y1y2`))
|
||||
|
||||
- SCHEMA
|
||||
```
|
||||
var a var d
|
||||
| |
|
||||
| |
|
||||
______v_________v_______
|
||||
input x1 ----> | |
|
||||
input y1 ----> | BabyAdd() | ----> output xout
|
||||
input x2 ----> | | ----> output yout
|
||||
input y2 ----> |________________________|
|
||||
```
|
||||
|
||||
- INPUTS
|
||||
|
||||
| Input | Representation | Description | |
|
||||
| ------------- | ------------- | ------------- | ------------- |
|
||||
| `x1` | Bigint | Field element of Fp | First 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. |
|
||||
| `y2` | Bigint | Field element of Fp | Second coordinate of a point (x2, y2) on E. |
|
||||
|
||||
Requirement: at least `x1`!=`x2` or `y1`!=`y2`.
|
||||
|
||||
- OUTPUT
|
||||
|
||||
| Input | Representation | Description | |
|
||||
| ------------- | ------------- | ------------- | ------------- |
|
||||
| `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). |
|
||||
|
||||
- BENCHMARKS (constraints)
|
||||
|
||||
- EXAMPLE
|
||||
|
||||
- `BabyDbl()`
|
||||
- DESCRIPTION : doubles a point (`xout`,`yout`) = 2*(`x`,`y`).
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `BabyCheck()`
|
||||
|
||||
- DESCRIPTION : checks if a given point is in the curve.
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `BabyPbk()`
|
||||
|
||||
- DESCRIPTION: : given a private key, it returns the associated public key.
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
|
||||
### binsub
|
||||
|
||||
- `BinSub(n)`
|
||||
|
||||
- DESCRIPTION: binary substraction.
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
### binsum
|
||||
|
||||
- `nbits(a)`
|
||||
|
||||
- DESCRIPTION : binary sum.
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `BinSum(n, ops)`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
### bitify
|
||||
|
||||
- `Num2Bits()`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `Num2Bits_strict()`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `Bits2Num()`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `Bits2Num_strict()`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `Num2BitsNeg()`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
### comparators
|
||||
|
||||
- `IsZero() `
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `IsEqual()`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `ForceEqualIfEnabled()`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `LessThan()`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `GreaterThan()`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `GreaterEqThan()`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
### compconstant
|
||||
|
||||
- `CompConstant(ct)`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
### eddsa
|
||||
|
||||
Edwards Digital Signature Algorithm in Baby Jubjbub (link a eddsa)
|
||||
|
||||
- `EdDSAVerifier(n)`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
### eddsamimc
|
||||
|
||||
- `EdDSAMiMCVerifier()`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
### eddsamimcsponge
|
||||
|
||||
- `EdDSAMiMCSpongeVerifier()`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
### eddsaposeidon
|
||||
|
||||
- `EdDSAPoseidonVerifier()`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
### escalarmul
|
||||
|
||||
- `EscalarMulWindow(base, k)`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `EscalarMul(n, base)`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
### escalarmulany
|
||||
|
||||
- `Multiplexor2()`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `BitElementMulAny()`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `SegmentMulAny(n)`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `EscalarMulAny(n)`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
### escalarmulfix
|
||||
|
||||
- `WindowMulFix()`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `SegmentMulFix(nWindows)`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `EscalarMulFix(n, BASE)`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
### escalarmulw4table
|
||||
|
||||
- `pointAdd`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `EscalarMulW4Table`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
### gates
|
||||
|
||||
- `XOR`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `AND`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `OR`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `NOT`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `NAND`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `NOR`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `MultiAND`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
### mimc
|
||||
|
||||
Implementation of MiMC-7 hash in Fp being... (link to description of the hash)
|
||||
|
||||
- `MiMC7(nrounds)`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `MultiMiMC7(nInputs, nRounds)`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
### mimcsponge
|
||||
|
||||
- `MiMCSponge(nInputs, nOutputs)`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `MiMCFeistel(nrounds)`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
### montgomery
|
||||
|
||||
- `Edwards2Montgomery()`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `Montgomery2Edwards()`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `MontgomeryAdd()`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `MontgomeryDouble()`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
### multiplexer
|
||||
|
||||
- `log2(a)`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `EscalarProduct(w)`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `Decoder(w)`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `Multiplexer(wIn, nIn)`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
### mux1
|
||||
|
||||
- `MultiMux1(n)`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `Mux1()`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
### mux2
|
||||
|
||||
- `MultiMux2(n)`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `Mux2()`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
### mux3
|
||||
|
||||
- `MultiMux3(n)`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `Mux3()`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
### mux4
|
||||
|
||||
- `MultiMux4(n)`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `Mux4()`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
### pedersen_old
|
||||
|
||||
Old version of the Pedersen hash (do not use any
|
||||
more?).
|
||||
|
||||
### pedersen
|
||||
|
||||
- `Window4()`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `Segment(nWindows)`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `Pedersen(n)`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
### pointbits
|
||||
|
||||
- `sqrt(n)`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `Bits2Point()`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `Bits2Point_Strict()`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `Point2Bits`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `Point2Bits_Strict`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
### poseidon
|
||||
|
||||
Implementation of Poseidon hash function (LINK)
|
||||
|
||||
- `Sigma()`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `Ark(t, C, r)`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `Mix(t, M)`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
- `Poseidon(nInputs)`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
### sign
|
||||
|
||||
- `Sign()`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
|
||||
### switcher
|
||||
|
||||
- `Switcher()`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
- INPUT
|
||||
- OUTPUT
|
||||
- BENCHMARKS
|
||||
- EXAMPLE
|
||||
@ -1,43 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
include "compconstant.circom";
|
||||
|
||||
|
||||
template AliasCheck() {
|
||||
signal input in[254];
|
||||
|
||||
component compConstant = CompConstant(-1);
|
||||
|
||||
for (var i=0; i<254; i++) in[i] ==> compConstant.in[i];
|
||||
|
||||
compConstant.out === 0;
|
||||
}
|
||||
|
||||
template AliasCheckBabyJub() {
|
||||
signal input in[251];
|
||||
signal input enabled;
|
||||
|
||||
component compConstant = CompConstant(2736030358979909402780800718157159386076813972158567259200215660948447373040);
|
||||
|
||||
for (var i=0; i<251; i++) in[i] ==> compConstant.in[i];
|
||||
for (var i=0; i<3; i++) 0 ==> compConstant.in[251+i];
|
||||
|
||||
compConstant.out*enabled === 0;
|
||||
}
|
||||
@ -1,106 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
include "bitify.circom";
|
||||
include "escalarmulfix.circom";
|
||||
|
||||
template BabyAdd() {
|
||||
signal input x1;
|
||||
signal input y1;
|
||||
signal input x2;
|
||||
signal input y2;
|
||||
signal output xout;
|
||||
signal output yout;
|
||||
|
||||
signal beta;
|
||||
signal gamma;
|
||||
signal delta;
|
||||
signal tau;
|
||||
|
||||
var a = 168700;
|
||||
var d = 168696;
|
||||
|
||||
beta <== x1*y2;
|
||||
gamma <== y1*x2;
|
||||
delta <== (-a*x1+y1)*(x2 + y2);
|
||||
tau <== beta * gamma;
|
||||
|
||||
xout <-- (beta + gamma) / (1+ d*tau);
|
||||
(1+ d*tau) * xout === (beta + gamma);
|
||||
|
||||
yout <-- (delta + a*beta - gamma) / (1-d*tau);
|
||||
(1-d*tau)*yout === (delta + a*beta - gamma);
|
||||
}
|
||||
|
||||
template BabyDbl() {
|
||||
signal input x;
|
||||
signal input y;
|
||||
signal output xout;
|
||||
signal output yout;
|
||||
|
||||
component adder = BabyAdd();
|
||||
adder.x1 <== x;
|
||||
adder.y1 <== y;
|
||||
adder.x2 <== x;
|
||||
adder.y2 <== y;
|
||||
|
||||
adder.xout ==> xout;
|
||||
adder.yout ==> yout;
|
||||
}
|
||||
|
||||
|
||||
template BabyCheck() {
|
||||
signal input x;
|
||||
signal input y;
|
||||
|
||||
signal x2;
|
||||
signal y2;
|
||||
|
||||
var a = 168700;
|
||||
var d = 168696;
|
||||
|
||||
x2 <== x*x;
|
||||
y2 <== y*y;
|
||||
|
||||
a*x2 + y2 === 1 + d*x2*y2;
|
||||
}
|
||||
|
||||
// Extracts the public key from private key, as mentioned in https://tools.ietf.org/html/rfc8032
|
||||
template BabyPbk() {
|
||||
signal private input in;
|
||||
signal output Ax;
|
||||
signal output Ay;
|
||||
|
||||
var BASE8 = [
|
||||
5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||
16950150798460657717958625567821834550301663161624707787222815936182638968203
|
||||
];
|
||||
|
||||
component pvkBits = Num2Bits(253);
|
||||
pvkBits.in <== in;
|
||||
|
||||
component mulFix = EscalarMulFix(253, BASE8);
|
||||
|
||||
var i;
|
||||
for (i=0; i<253; i++) {
|
||||
mulFix.e[i] <== pvkBits.out[i];
|
||||
}
|
||||
Ax <== mulFix.out[0];
|
||||
Ay <== mulFix.out[1];
|
||||
}
|
||||
@ -1,71 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
This component creates a binary substraction.
|
||||
|
||||
|
||||
Main Constraint:
|
||||
(in[0][0] * 2^0 + in[0][1] * 2^1 + ..... + in[0][n-1] * 2^(n-1)) +
|
||||
+ 2^n
|
||||
- (in[1][0] * 2^0 + in[1][1] * 2^1 + ..... + in[1][n-1] * 2^(n-1))
|
||||
===
|
||||
out[0] * 2^0 + out[1] * 2^1 + + out[n-1] *2^(n-1) + aux
|
||||
|
||||
|
||||
out[0] * (out[0] - 1) === 0
|
||||
out[1] * (out[0] - 1) === 0
|
||||
.
|
||||
.
|
||||
.
|
||||
out[n-1] * (out[n-1] - 1) === 0
|
||||
aux * (aux-1) == 0
|
||||
|
||||
*/
|
||||
|
||||
template BinSub(n) {
|
||||
signal input in[2][n];
|
||||
signal output out[n];
|
||||
|
||||
signal aux;
|
||||
|
||||
var lin = 2**n;
|
||||
var lout = 0;
|
||||
|
||||
for (var i=0; i<n; i++) {
|
||||
lin = lin + in[0][i]*(2**i);
|
||||
lin = lin - in[1][i]*(2**i);
|
||||
}
|
||||
|
||||
for (var i=0; i<n; i++) {
|
||||
out[i] <-- (lin >> i) & 1;
|
||||
|
||||
// Ensure out is binary
|
||||
out[i] * (out[i] - 1) === 0;
|
||||
|
||||
lout = lout + out[i]*(2**i);
|
||||
}
|
||||
|
||||
aux <-- (lin >> n) & 1;
|
||||
aux*(aux-1) === 0;
|
||||
lout = lout + aux*(2**n);
|
||||
|
||||
// Ensure the sum;
|
||||
lin === lout;
|
||||
}
|
||||
@ -1,95 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
Binary Sum
|
||||
==========
|
||||
|
||||
This component creates a binary sum componet of ops operands and n bits each operand.
|
||||
|
||||
e is Number of carries: Depends on the number of operands in the input.
|
||||
|
||||
Main Constraint:
|
||||
in[0][0] * 2^0 + in[0][1] * 2^1 + ..... + in[0][n-1] * 2^(n-1) +
|
||||
+ in[1][0] * 2^0 + in[1][1] * 2^1 + ..... + in[1][n-1] * 2^(n-1) +
|
||||
+ ..
|
||||
+ in[ops-1][0] * 2^0 + in[ops-1][1] * 2^1 + ..... + in[ops-1][n-1] * 2^(n-1) +
|
||||
===
|
||||
out[0] * 2^0 + out[1] * 2^1 + + out[n+e-1] *2(n+e-1)
|
||||
|
||||
To waranty binary outputs:
|
||||
|
||||
out[0] * (out[0] - 1) === 0
|
||||
out[1] * (out[0] - 1) === 0
|
||||
.
|
||||
.
|
||||
.
|
||||
out[n+e-1] * (out[n+e-1] - 1) == 0
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
This function calculates the number of extra bits in the output to do the full sum.
|
||||
*/
|
||||
|
||||
/* a must be < Nq/2, where Nq is the number of elements in the scalar field */
|
||||
function nbits(a) {
|
||||
var n = 1;
|
||||
var r = 0;
|
||||
while (n-1<a) {
|
||||
r++;
|
||||
n *= 2;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/* n must be such that (2**(n+1) -2) < Nq/ops, where Nq is the number of bits in the scalar field */
|
||||
template BinSum(n, ops) {
|
||||
var nout = nbits((2**n -1)*ops);
|
||||
signal input in[ops][n];
|
||||
signal output out[nout];
|
||||
|
||||
var lin = 0;
|
||||
var lout = 0;
|
||||
|
||||
var k;
|
||||
var j;
|
||||
|
||||
for (k=0; k<n; k++) {
|
||||
for (j=0; j<ops; j++) {
|
||||
lin += in[j][k] * 2**k;
|
||||
}
|
||||
}
|
||||
|
||||
for (k=0; k<nout; k++) {
|
||||
out[k] <-- (lin >> k) & 1;
|
||||
|
||||
// Ensure out is binary
|
||||
out[k] * (out[k] - 1) === 0;
|
||||
|
||||
lout += out[k] * 2**k;
|
||||
}
|
||||
|
||||
// Ensure the sum;
|
||||
|
||||
lin === lout;
|
||||
}
|
||||
@ -1,103 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
include "comparators.circom";
|
||||
include "aliascheck.circom";
|
||||
|
||||
|
||||
/* This doesn't check aliasing, so for n > 253 there are multiple bit strings for each number */
|
||||
template Num2Bits(n) {
|
||||
signal input in;
|
||||
signal output out[n];
|
||||
var lc1=0;
|
||||
|
||||
for (var i = 0; i<n; i++) {
|
||||
out[i] <-- (in >> i) & 1;
|
||||
out[i] * (out[i] -1 ) === 0;
|
||||
lc1 += out[i] * 2**i;
|
||||
}
|
||||
|
||||
lc1 === in;
|
||||
}
|
||||
|
||||
template Num2Bits_strict() {
|
||||
signal input in;
|
||||
signal output out[254];
|
||||
|
||||
component aliasCheck = AliasCheck();
|
||||
component n2b = Num2Bits(254);
|
||||
in ==> n2b.in;
|
||||
|
||||
for (var i=0; i<254; i++) {
|
||||
n2b.out[i] ==> out[i];
|
||||
n2b.out[i] ==> aliasCheck.in[i];
|
||||
}
|
||||
}
|
||||
|
||||
template Bits2Num(n) {
|
||||
signal input in[n];
|
||||
signal output out;
|
||||
var lc1=0;
|
||||
|
||||
for (var i = 0; i<n; i++) {
|
||||
lc1 += in[i] * 2**i;
|
||||
}
|
||||
|
||||
lc1 ==> out;
|
||||
}
|
||||
|
||||
template Bits2Num_strict() {
|
||||
signal input in[n];
|
||||
signal output out;
|
||||
|
||||
component aliasCheck = AliasCheck();
|
||||
component b2n = Bits2Num(254);
|
||||
|
||||
for (var i=0; i<254; i++) {
|
||||
in[i] ==> b2n.in[i];
|
||||
in[i] ==> aliasCheck.in[i];
|
||||
}
|
||||
|
||||
b2n.out ==> out;
|
||||
}
|
||||
|
||||
/* n must not exceed 253 */
|
||||
template Num2BitsNeg(n) {
|
||||
signal input in;
|
||||
signal output out[n];
|
||||
var lc1=0;
|
||||
|
||||
component isZero;
|
||||
|
||||
isZero = IsZero();
|
||||
|
||||
var neg = n == 0 ? 0 : 2**n - in;
|
||||
|
||||
for (var i = 0; i<n; i++) {
|
||||
out[i] <-- (neg >> i) & 1;
|
||||
out[i] * (out[i] -1 ) === 0;
|
||||
lc1 += out[i] * 2**i;
|
||||
}
|
||||
|
||||
in ==> isZero.in;
|
||||
|
||||
|
||||
|
||||
lc1 + isZero.out * 2**n === 2**n - in;
|
||||
}
|
||||
@ -1,139 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
include "bitify.circom";
|
||||
include "binsum.circom";
|
||||
|
||||
template IsZero() {
|
||||
signal input in;
|
||||
signal output out;
|
||||
|
||||
signal inv;
|
||||
|
||||
inv <-- in!=0 ? 1/in : 0;
|
||||
|
||||
out <== -in*inv +1;
|
||||
in*out === 0;
|
||||
}
|
||||
|
||||
|
||||
template IsEqual() {
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
component isz = IsZero();
|
||||
|
||||
in[1] - in[0] ==> isz.in;
|
||||
|
||||
isz.out ==> out;
|
||||
}
|
||||
|
||||
template ForceEqualIfEnabled() {
|
||||
signal input enabled;
|
||||
signal input in[2];
|
||||
|
||||
component isz = IsZero();
|
||||
|
||||
in[1] - in[0] ==> isz.in;
|
||||
|
||||
(1 - isz.out)*enabled === 0;
|
||||
}
|
||||
|
||||
/*
|
||||
// N is the number of bits the input have.
|
||||
// The MSF is the sign bit.
|
||||
template LessThan(n) {
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
component num2Bits0;
|
||||
component num2Bits1;
|
||||
|
||||
component adder;
|
||||
|
||||
adder = BinSum(n, 2);
|
||||
|
||||
num2Bits0 = Num2Bits(n);
|
||||
num2Bits1 = Num2BitsNeg(n);
|
||||
|
||||
in[0] ==> num2Bits0.in;
|
||||
in[1] ==> num2Bits1.in;
|
||||
|
||||
var i;
|
||||
for (i=0;i<n;i++) {
|
||||
num2Bits0.out[i] ==> adder.in[0][i];
|
||||
num2Bits1.out[i] ==> adder.in[1][i];
|
||||
}
|
||||
|
||||
adder.out[n-1] ==> out;
|
||||
}
|
||||
*/
|
||||
|
||||
template LessThan(n) {
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
component n2b = Num2Bits(n*2+1);
|
||||
|
||||
n2b.in <== in[0]+ (1<<n) - in[1];
|
||||
|
||||
out <== 1-n2b.out[n];
|
||||
}
|
||||
|
||||
|
||||
|
||||
// N is the number of bits the input have.
|
||||
// The MSF is the sign bit.
|
||||
template LessEqThan(n) {
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
component lt = LessThan(n);
|
||||
|
||||
lt.in[0] <== in[0];
|
||||
lt.in[1] <== in[1]+1;
|
||||
lt.out ==> out;
|
||||
}
|
||||
|
||||
// N is the number of bits the input have.
|
||||
// The MSF is the sign bit.
|
||||
template GreaterThan(n) {
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
component lt = LessThan(n);
|
||||
|
||||
lt.in[0] <== in[1];
|
||||
lt.in[1] <== in[0];
|
||||
lt.out ==> out;
|
||||
}
|
||||
|
||||
// N is the number of bits the input have.
|
||||
// The MSF is the sign bit.
|
||||
template GreaterEqThan(n) {
|
||||
signal input in[2];
|
||||
signal output out;
|
||||
|
||||
component lt = LessThan(n);
|
||||
|
||||
lt.in[0] <== in[1];
|
||||
lt.in[1] <== in[0]+1;
|
||||
lt.out ==> out;
|
||||
}
|
||||
|
||||
@ -1,122 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
include "aliascheck.circom";
|
||||
include "pointbits.circom";
|
||||
include "mimc.circom";
|
||||
include "bitify.circom";
|
||||
include "escalarmulany.circom";
|
||||
include "escalarmulfix.circom";
|
||||
|
||||
template EdDSAMiMCVerifier() {
|
||||
signal input enabled;
|
||||
signal input Ax;
|
||||
signal input Ay;
|
||||
|
||||
signal input S;
|
||||
signal input R8x;
|
||||
signal input R8y;
|
||||
|
||||
signal input M;
|
||||
|
||||
var i;
|
||||
|
||||
// Ensure S<Subgroup Order
|
||||
|
||||
component snum2bits = Num2Bits(251);
|
||||
snum2bits.in <== S;
|
||||
|
||||
component aliasCheck = AliasCheckBabyJub();
|
||||
aliasCheck.enabled <== 1;
|
||||
|
||||
for (i=0; i<251; i++) {
|
||||
snum2bits.out[i] ==> aliasCheck.in[i];
|
||||
}
|
||||
|
||||
// Calculate the h = H(R,A, msg)
|
||||
|
||||
component hash = MultiMiMC7(5, 91);
|
||||
hash.in[0] <== R8x;
|
||||
hash.in[1] <== R8y;
|
||||
hash.in[2] <== Ax;
|
||||
hash.in[3] <== Ay;
|
||||
hash.in[4] <== M;
|
||||
hash.k <== 0;
|
||||
|
||||
component h2bits = Num2Bits_strict();
|
||||
h2bits.in <== hash.out;
|
||||
|
||||
// Calculate second part of the right side: right2 = h*8*A
|
||||
|
||||
// Multiply by 8 by adding it 3 times. This also ensure that the result is in
|
||||
// the subgroup.
|
||||
component dbl1 = BabyDbl();
|
||||
dbl1.x <== Ax;
|
||||
dbl1.y <== Ay;
|
||||
component dbl2 = BabyDbl();
|
||||
dbl2.x <== dbl1.xout;
|
||||
dbl2.y <== dbl1.yout;
|
||||
component dbl3 = BabyDbl();
|
||||
dbl3.x <== dbl2.xout;
|
||||
dbl3.y <== dbl2.yout;
|
||||
|
||||
// We check that A is not zero.
|
||||
component isZero = IsZero();
|
||||
isZero.in <== dbl3.x;
|
||||
isZero.out === 0;
|
||||
|
||||
component mulAny = EscalarMulAny(254);
|
||||
for (i=0; i<254; i++) {
|
||||
mulAny.e[i] <== h2bits.out[i];
|
||||
}
|
||||
mulAny.p[0] <== dbl3.xout;
|
||||
mulAny.p[1] <== dbl3.yout;
|
||||
|
||||
|
||||
// Compute the right side: right = R8 + right2
|
||||
|
||||
component addRight = BabyAdd();
|
||||
addRight.x1 <== R8x;
|
||||
addRight.y1 <== R8y;
|
||||
addRight.x2 <== mulAny.out[0];
|
||||
addRight.y2 <== mulAny.out[1];
|
||||
|
||||
// Calculate left side of equation left = S*B8
|
||||
|
||||
var BASE8 = [
|
||||
5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||
16950150798460657717958625567821834550301663161624707787222815936182638968203
|
||||
];
|
||||
component mulFix = EscalarMulFix(251, BASE8);
|
||||
for (i=0; i<251; i++) {
|
||||
mulFix.e[i] <== snum2bits.out[i];
|
||||
}
|
||||
|
||||
// Do the comparation left == right if enabled;
|
||||
|
||||
component eqCheckX = ForceEqualIfEnabled();
|
||||
eqCheckX.enabled <== enabled;
|
||||
eqCheckX.in[0] <== mulFix.out[0];
|
||||
eqCheckX.in[1] <== addRight.xout;
|
||||
|
||||
component eqCheckY = ForceEqualIfEnabled();
|
||||
eqCheckY.enabled <== enabled;
|
||||
eqCheckY.in[0] <== mulFix.out[1];
|
||||
eqCheckY.in[1] <== addRight.yout;
|
||||
}
|
||||
@ -1,122 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
include "aliascheck.circom";
|
||||
include "pointbits.circom";
|
||||
include "mimcsponge.circom";
|
||||
include "bitify.circom";
|
||||
include "escalarmulany.circom";
|
||||
include "escalarmulfix.circom";
|
||||
|
||||
template EdDSAMiMCSpongeVerifier() {
|
||||
signal input enabled;
|
||||
signal input Ax;
|
||||
signal input Ay;
|
||||
|
||||
signal input S;
|
||||
signal input R8x;
|
||||
signal input R8y;
|
||||
|
||||
signal input M;
|
||||
|
||||
var i;
|
||||
|
||||
// Ensure S<Subgroup Order
|
||||
|
||||
component snum2bits = Num2Bits(251);
|
||||
snum2bits.in <== S;
|
||||
|
||||
component aliasCheck = AliasCheckBabyJub();
|
||||
aliasCheck.enabled <== 1;
|
||||
|
||||
for (i=0; i<251; i++) {
|
||||
snum2bits.out[i] ==> aliasCheck.in[i];
|
||||
}
|
||||
|
||||
// Calculate the h = H(R,A, msg)
|
||||
|
||||
component hash = MiMCSponge(5, 1);
|
||||
hash.ins[0] <== R8x;
|
||||
hash.ins[1] <== R8y;
|
||||
hash.ins[2] <== Ax;
|
||||
hash.ins[3] <== Ay;
|
||||
hash.ins[4] <== M;
|
||||
hash.k <== 0;
|
||||
|
||||
component h2bits = Num2Bits_strict();
|
||||
h2bits.in <== hash.outs[0];
|
||||
|
||||
// Calculate second part of the right side: right2 = h*8*A
|
||||
|
||||
// Multiply by 8 by adding it 3 times. This also ensure that the result is in
|
||||
// the subgroup.
|
||||
component dbl1 = BabyDbl();
|
||||
dbl1.x <== Ax;
|
||||
dbl1.y <== Ay;
|
||||
component dbl2 = BabyDbl();
|
||||
dbl2.x <== dbl1.xout;
|
||||
dbl2.y <== dbl1.yout;
|
||||
component dbl3 = BabyDbl();
|
||||
dbl3.x <== dbl2.xout;
|
||||
dbl3.y <== dbl2.yout;
|
||||
|
||||
// We check that A is not zero.
|
||||
component isZero = IsZero();
|
||||
isZero.in <== dbl3.x;
|
||||
isZero.out === 0;
|
||||
|
||||
component mulAny = EscalarMulAny(254);
|
||||
for (i=0; i<254; i++) {
|
||||
mulAny.e[i] <== h2bits.out[i];
|
||||
}
|
||||
mulAny.p[0] <== dbl3.xout;
|
||||
mulAny.p[1] <== dbl3.yout;
|
||||
|
||||
|
||||
// Compute the right side: right = R8 + right2
|
||||
|
||||
component addRight = BabyAdd();
|
||||
addRight.x1 <== R8x;
|
||||
addRight.y1 <== R8y;
|
||||
addRight.x2 <== mulAny.out[0];
|
||||
addRight.y2 <== mulAny.out[1];
|
||||
|
||||
// Calculate left side of equation left = S*B8
|
||||
|
||||
var BASE8 = [
|
||||
5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||
16950150798460657717958625567821834550301663161624707787222815936182638968203
|
||||
];
|
||||
component mulFix = EscalarMulFix(251, BASE8);
|
||||
for (i=0; i<251; i++) {
|
||||
mulFix.e[i] <== snum2bits.out[i];
|
||||
}
|
||||
|
||||
// Do the comparation left == right if enabled;
|
||||
|
||||
component eqCheckX = ForceEqualIfEnabled();
|
||||
eqCheckX.enabled <== enabled;
|
||||
eqCheckX.in[0] <== mulFix.out[0];
|
||||
eqCheckX.in[1] <== addRight.xout;
|
||||
|
||||
component eqCheckY = ForceEqualIfEnabled();
|
||||
eqCheckY.enabled <== enabled;
|
||||
eqCheckY.in[0] <== mulFix.out[1];
|
||||
eqCheckY.in[1] <== addRight.yout;
|
||||
}
|
||||
@ -1,121 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
include "compconstant.circom";
|
||||
include "poseidon.circom";
|
||||
include "bitify.circom";
|
||||
include "escalarmulany.circom";
|
||||
include "escalarmulfix.circom";
|
||||
|
||||
template EdDSAPoseidonVerifier() {
|
||||
signal input enabled;
|
||||
signal input Ax;
|
||||
signal input Ay;
|
||||
|
||||
signal input S;
|
||||
signal input R8x;
|
||||
signal input R8y;
|
||||
|
||||
signal input M;
|
||||
|
||||
var i;
|
||||
|
||||
// Ensure S<Subgroup Order
|
||||
|
||||
component snum2bits = Num2Bits(251);
|
||||
snum2bits.in <== S;
|
||||
|
||||
component aliasCheck = AliasCheckBabyJub();
|
||||
aliasCheck.enabled <== enabled;
|
||||
|
||||
for (i=0; i<251; i++) {
|
||||
snum2bits.out[i] ==> aliasCheck.in[i];
|
||||
}
|
||||
|
||||
// Calculate the h = H(R,A, msg)
|
||||
|
||||
component hash = Poseidon(5);
|
||||
|
||||
hash.inputs[0] <== R8x;
|
||||
hash.inputs[1] <== R8y;
|
||||
hash.inputs[2] <== Ax;
|
||||
hash.inputs[3] <== Ay;
|
||||
hash.inputs[4] <== M;
|
||||
|
||||
component h2bits = Num2Bits_strict();
|
||||
h2bits.in <== hash.out;
|
||||
|
||||
// Calculate second part of the right side: right2 = h*8*A
|
||||
|
||||
// Multiply by 8 by adding it 3 times. This also ensure that the result is in
|
||||
// the subgroup.
|
||||
component dbl1 = BabyDbl();
|
||||
dbl1.x <== Ax;
|
||||
dbl1.y <== Ay;
|
||||
component dbl2 = BabyDbl();
|
||||
dbl2.x <== dbl1.xout;
|
||||
dbl2.y <== dbl1.yout;
|
||||
component dbl3 = BabyDbl();
|
||||
dbl3.x <== dbl2.xout;
|
||||
dbl3.y <== dbl2.yout;
|
||||
|
||||
// We check that A is not zero.
|
||||
component isZero = IsZero();
|
||||
isZero.in <== dbl3.x;
|
||||
isZero.out*enabled === 0;
|
||||
|
||||
component mulAny = EscalarMulAny(254);
|
||||
for (i=0; i<254; i++) {
|
||||
mulAny.e[i] <== h2bits.out[i];
|
||||
}
|
||||
mulAny.p[0] <== dbl3.xout;
|
||||
mulAny.p[1] <== dbl3.yout;
|
||||
|
||||
|
||||
// Compute the right side: right = R8 + right2
|
||||
|
||||
component addRight = BabyAdd();
|
||||
addRight.x1 <== R8x;
|
||||
addRight.y1 <== R8y;
|
||||
addRight.x2 <== mulAny.out[0];
|
||||
addRight.y2 <== mulAny.out[1];
|
||||
|
||||
// Calculate left side of equation left = S*B8
|
||||
|
||||
var BASE8 = [
|
||||
5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||
16950150798460657717958625567821834550301663161624707787222815936182638968203
|
||||
];
|
||||
component mulFix = EscalarMulFix(251, BASE8);
|
||||
for (i=0; i<251; i++) {
|
||||
mulFix.e[i] <== snum2bits.out[i];
|
||||
}
|
||||
|
||||
// Do the comparation left == right if enabled;
|
||||
|
||||
component eqCheckX = ForceEqualIfEnabled();
|
||||
eqCheckX.enabled <== enabled;
|
||||
eqCheckX.in[0] <== mulFix.out[0];
|
||||
eqCheckX.in[1] <== addRight.xout;
|
||||
|
||||
component eqCheckY = ForceEqualIfEnabled();
|
||||
eqCheckY.enabled <== enabled;
|
||||
eqCheckY.in[0] <== mulFix.out[1];
|
||||
eqCheckY.in[1] <== addRight.yout;
|
||||
}
|
||||
@ -1,51 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
function pointAdd(x1,y1,x2,y2) {
|
||||
var a = 168700;
|
||||
var d = 168696;
|
||||
|
||||
var res[2];
|
||||
res[0] = (x1*y2 + y1*x2) / (1 + d*x1*x2*y1*y2);
|
||||
res[1] = (y1*y2 - a*x1*x2) / (1 - d*x1*x2*y1*y2);
|
||||
return res;
|
||||
}
|
||||
|
||||
function EscalarMulW4Table(base, k) {
|
||||
var out[16][2];
|
||||
|
||||
var i;
|
||||
var p[2];
|
||||
|
||||
var dbl = base;
|
||||
|
||||
for (i=0; i<k*4; i++) {
|
||||
dbl = pointAdd(dbl[0], dbl[1], dbl[0], dbl[1]);
|
||||
}
|
||||
|
||||
out[0][0] = 0;
|
||||
out[0][1] = 1;
|
||||
for (i=1; i<16; i++) {
|
||||
p = pointAdd(out[i-1][0], out[i-1][1], dbl[0], dbl[1]);
|
||||
out[i][0] = p[0];
|
||||
out[i][1] = p[1];
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
@ -1,92 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
template XOR() {
|
||||
signal input a;
|
||||
signal input b;
|
||||
signal output out;
|
||||
|
||||
out <== a + b - 2*a*b;
|
||||
}
|
||||
|
||||
template AND() {
|
||||
signal input a;
|
||||
signal input b;
|
||||
signal output out;
|
||||
|
||||
out <== a*b;
|
||||
}
|
||||
|
||||
template OR() {
|
||||
signal input a;
|
||||
signal input b;
|
||||
signal output out;
|
||||
|
||||
out <== a + b - a*b;
|
||||
}
|
||||
|
||||
template NOT() {
|
||||
signal input in;
|
||||
signal output out;
|
||||
|
||||
out <== 1 + in - 2*in;
|
||||
}
|
||||
|
||||
template NAND() {
|
||||
signal input a;
|
||||
signal input b;
|
||||
signal output out;
|
||||
|
||||
out <== 1 - a*b;
|
||||
}
|
||||
|
||||
template NOR() {
|
||||
signal input a;
|
||||
signal input b;
|
||||
signal output out;
|
||||
|
||||
out <== a*b + 1 - a - b;
|
||||
}
|
||||
|
||||
template MultiAND(n) {
|
||||
signal input in[n];
|
||||
signal output out;
|
||||
if (n==1) {
|
||||
out <== in[0];
|
||||
} else if (n==2) {
|
||||
component and1 = AND();
|
||||
and1.a <== in[0];
|
||||
and1.b <== in[1];
|
||||
out <== and1.out;
|
||||
} else {
|
||||
component and2 = AND();
|
||||
component ands[2];
|
||||
var n1 = n\2;
|
||||
var n2 = n-n\2;
|
||||
ands[0] = MultiAND(n1);
|
||||
ands[1] = MultiAND(n2);
|
||||
for (var 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];
|
||||
and2.a <== ands[0].out;
|
||||
and2.b <== ands[1].out;
|
||||
out <== and2.out;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,155 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
template MiMC7(nrounds) {
|
||||
signal input x_in;
|
||||
signal input k;
|
||||
signal output out;
|
||||
|
||||
var c = [
|
||||
0,
|
||||
20888961410941983456478427210666206549300505294776164667214940546594746570981,
|
||||
15265126113435022738560151911929040668591755459209400716467504685752745317193,
|
||||
8334177627492981984476504167502758309043212251641796197711684499645635709656,
|
||||
1374324219480165500871639364801692115397519265181803854177629327624133579404,
|
||||
11442588683664344394633565859260176446561886575962616332903193988751292992472,
|
||||
2558901189096558760448896669327086721003508630712968559048179091037845349145,
|
||||
11189978595292752354820141775598510151189959177917284797737745690127318076389,
|
||||
3262966573163560839685415914157855077211340576201936620532175028036746741754,
|
||||
17029914891543225301403832095880481731551830725367286980611178737703889171730,
|
||||
4614037031668406927330683909387957156531244689520944789503628527855167665518,
|
||||
19647356996769918391113967168615123299113119185942498194367262335168397100658,
|
||||
5040699236106090655289931820723926657076483236860546282406111821875672148900,
|
||||
2632385916954580941368956176626336146806721642583847728103570779270161510514,
|
||||
17691411851977575435597871505860208507285462834710151833948561098560743654671,
|
||||
11482807709115676646560379017491661435505951727793345550942389701970904563183,
|
||||
8360838254132998143349158726141014535383109403565779450210746881879715734773,
|
||||
12663821244032248511491386323242575231591777785787269938928497649288048289525,
|
||||
3067001377342968891237590775929219083706800062321980129409398033259904188058,
|
||||
8536471869378957766675292398190944925664113548202769136103887479787957959589,
|
||||
19825444354178182240559170937204690272111734703605805530888940813160705385792,
|
||||
16703465144013840124940690347975638755097486902749048533167980887413919317592,
|
||||
13061236261277650370863439564453267964462486225679643020432589226741411380501,
|
||||
10864774797625152707517901967943775867717907803542223029967000416969007792571,
|
||||
10035653564014594269791753415727486340557376923045841607746250017541686319774,
|
||||
3446968588058668564420958894889124905706353937375068998436129414772610003289,
|
||||
4653317306466493184743870159523234588955994456998076243468148492375236846006,
|
||||
8486711143589723036499933521576871883500223198263343024003617825616410932026,
|
||||
250710584458582618659378487568129931785810765264752039738223488321597070280,
|
||||
2104159799604932521291371026105311735948154964200596636974609406977292675173,
|
||||
16313562605837709339799839901240652934758303521543693857533755376563489378839,
|
||||
6032365105133504724925793806318578936233045029919447519826248813478479197288,
|
||||
14025118133847866722315446277964222215118620050302054655768867040006542798474,
|
||||
7400123822125662712777833064081316757896757785777291653271747396958201309118,
|
||||
1744432620323851751204287974553233986555641872755053103823939564833813704825,
|
||||
8316378125659383262515151597439205374263247719876250938893842106722210729522,
|
||||
6739722627047123650704294650168547689199576889424317598327664349670094847386,
|
||||
21211457866117465531949733809706514799713333930924902519246949506964470524162,
|
||||
13718112532745211817410303291774369209520657938741992779396229864894885156527,
|
||||
5264534817993325015357427094323255342713527811596856940387954546330728068658,
|
||||
18884137497114307927425084003812022333609937761793387700010402412840002189451,
|
||||
5148596049900083984813839872929010525572543381981952060869301611018636120248,
|
||||
19799686398774806587970184652860783461860993790013219899147141137827718662674,
|
||||
19240878651604412704364448729659032944342952609050243268894572835672205984837,
|
||||
10546185249390392695582524554167530669949955276893453512788278945742408153192,
|
||||
5507959600969845538113649209272736011390582494851145043668969080335346810411,
|
||||
18177751737739153338153217698774510185696788019377850245260475034576050820091,
|
||||
19603444733183990109492724100282114612026332366576932662794133334264283907557,
|
||||
10548274686824425401349248282213580046351514091431715597441736281987273193140,
|
||||
1823201861560942974198127384034483127920205835821334101215923769688644479957,
|
||||
11867589662193422187545516240823411225342068709600734253659804646934346124945,
|
||||
18718569356736340558616379408444812528964066420519677106145092918482774343613,
|
||||
10530777752259630125564678480897857853807637120039176813174150229243735996839,
|
||||
20486583726592018813337145844457018474256372770211860618687961310422228379031,
|
||||
12690713110714036569415168795200156516217175005650145422920562694422306200486,
|
||||
17386427286863519095301372413760745749282643730629659997153085139065756667205,
|
||||
2216432659854733047132347621569505613620980842043977268828076165669557467682,
|
||||
6309765381643925252238633914530877025934201680691496500372265330505506717193,
|
||||
20806323192073945401862788605803131761175139076694468214027227878952047793390,
|
||||
4037040458505567977365391535756875199663510397600316887746139396052445718861,
|
||||
19948974083684238245321361840704327952464170097132407924861169241740046562673,
|
||||
845322671528508199439318170916419179535949348988022948153107378280175750024,
|
||||
16222384601744433420585982239113457177459602187868460608565289920306145389382,
|
||||
10232118865851112229330353999139005145127746617219324244541194256766741433339,
|
||||
6699067738555349409504843460654299019000594109597429103342076743347235369120,
|
||||
6220784880752427143725783746407285094967584864656399181815603544365010379208,
|
||||
6129250029437675212264306655559561251995722990149771051304736001195288083309,
|
||||
10773245783118750721454994239248013870822765715268323522295722350908043393604,
|
||||
4490242021765793917495398271905043433053432245571325177153467194570741607167,
|
||||
19596995117319480189066041930051006586888908165330319666010398892494684778526,
|
||||
837850695495734270707668553360118467905109360511302468085569220634750561083,
|
||||
11803922811376367215191737026157445294481406304781326649717082177394185903907,
|
||||
10201298324909697255105265958780781450978049256931478989759448189112393506592,
|
||||
13564695482314888817576351063608519127702411536552857463682060761575100923924,
|
||||
9262808208636973454201420823766139682381973240743541030659775288508921362724,
|
||||
173271062536305557219323722062711383294158572562695717740068656098441040230,
|
||||
18120430890549410286417591505529104700901943324772175772035648111937818237369,
|
||||
20484495168135072493552514219686101965206843697794133766912991150184337935627,
|
||||
19155651295705203459475805213866664350848604323501251939850063308319753686505,
|
||||
11971299749478202793661982361798418342615500543489781306376058267926437157297,
|
||||
18285310723116790056148596536349375622245669010373674803854111592441823052978,
|
||||
7069216248902547653615508023941692395371990416048967468982099270925308100727,
|
||||
6465151453746412132599596984628739550147379072443683076388208843341824127379,
|
||||
16143532858389170960690347742477978826830511669766530042104134302796355145785,
|
||||
19362583304414853660976404410208489566967618125972377176980367224623492419647,
|
||||
1702213613534733786921602839210290505213503664731919006932367875629005980493,
|
||||
10781825404476535814285389902565833897646945212027592373510689209734812292327,
|
||||
4212716923652881254737947578600828255798948993302968210248673545442808456151,
|
||||
7594017890037021425366623750593200398174488805473151513558919864633711506220,
|
||||
18979889247746272055963929241596362599320706910852082477600815822482192194401,
|
||||
13602139229813231349386885113156901793661719180900395818909719758150455500533
|
||||
];
|
||||
|
||||
var t;
|
||||
signal t2[nrounds];
|
||||
signal t4[nrounds];
|
||||
signal t6[nrounds];
|
||||
signal t7[nrounds-1];
|
||||
|
||||
for (var i=0; i<nrounds; i++) {
|
||||
t = (i==0) ? k+x_in : k + t7[i-1] + c[i];
|
||||
t2[i] <== t*t;
|
||||
t4[i] <== t2[i]*t2[i];
|
||||
t6[i] <== t4[i]*t2[i];
|
||||
if (i<nrounds-1) {
|
||||
t7[i] <== t6[i]*t;
|
||||
} else {
|
||||
out <== t6[i]*t + k;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template MultiMiMC7(nInputs, nRounds) {
|
||||
signal input in[nInputs];
|
||||
signal input k;
|
||||
signal output out;
|
||||
signal r[nInputs +1];
|
||||
|
||||
component mims[nInputs];
|
||||
|
||||
r[0] <== k;
|
||||
for (var i=0; i<nInputs; i++) {
|
||||
mims[i] = MiMC7(nRounds);
|
||||
mims[i].x_in <== in[i];
|
||||
mims[i].k <== r[i];
|
||||
r[i+1] <== r[i] + in[i] + mims[i].out;
|
||||
}
|
||||
|
||||
out <== r[nInputs];
|
||||
}
|
||||
@ -1,290 +0,0 @@
|
||||
// implements MiMC-2n/n as hash using a sponge construction.
|
||||
// log_5(21888242871839275222246405745257275088548364400416034343698204186575808495617) ~= 110
|
||||
// => nRounds should be 220
|
||||
template MiMCSponge(nInputs, nOutputs) {
|
||||
signal input ins[nInputs];
|
||||
signal input k;
|
||||
signal output outs[nOutputs];
|
||||
|
||||
var nRounds = 220;
|
||||
|
||||
// S = R||C
|
||||
component S[nInputs + nOutputs - 1];
|
||||
|
||||
for (var i = 0; i < nInputs; i++) {
|
||||
S[i] = MiMCFeistel(nRounds);
|
||||
S[i].k <== k;
|
||||
if (i == 0) {
|
||||
S[i].xL_in <== ins[0];
|
||||
S[i].xR_in <== 0;
|
||||
} else {
|
||||
S[i].xL_in <== S[i-1].xL_out + ins[i];
|
||||
S[i].xR_in <== S[i-1].xR_out;
|
||||
}
|
||||
}
|
||||
|
||||
outs[0] <== S[nInputs - 1].xL_out;
|
||||
|
||||
for (var i = 0; i < nOutputs - 1; i++) {
|
||||
S[nInputs + i] = MiMCFeistel(nRounds);
|
||||
S[nInputs + i].k <== k;
|
||||
S[nInputs + i].xL_in <== S[nInputs + i - 1].xL_out;
|
||||
S[nInputs + i].xR_in <== S[nInputs + i - 1].xR_out;
|
||||
outs[i + 1] <== S[nInputs + i].xL_out;
|
||||
}
|
||||
}
|
||||
|
||||
template MiMCFeistel(nrounds) {
|
||||
signal input xL_in;
|
||||
signal input xR_in;
|
||||
signal input k;
|
||||
signal output xL_out;
|
||||
signal output xR_out;
|
||||
|
||||
// doesn't contain the first and last round constants, which are always zero
|
||||
var c_partial = [
|
||||
7120861356467848435263064379192047478074060781135320967663101236819528304084,
|
||||
5024705281721889198577876690145313457398658950011302225525409148828000436681,
|
||||
17980351014018068290387269214713820287804403312720763401943303895585469787384,
|
||||
19886576439381707240399940949310933992335779767309383709787331470398675714258,
|
||||
1213715278223786725806155661738676903520350859678319590331207960381534602599,
|
||||
18162138253399958831050545255414688239130588254891200470934232514682584734511,
|
||||
7667462281466170157858259197976388676420847047604921256361474169980037581876,
|
||||
7207551498477838452286210989212982851118089401128156132319807392460388436957,
|
||||
9864183311657946807255900203841777810810224615118629957816193727554621093838,
|
||||
4798196928559910300796064665904583125427459076060519468052008159779219347957,
|
||||
17387238494588145257484818061490088963673275521250153686214197573695921400950,
|
||||
10005334761930299057035055370088813230849810566234116771751925093634136574742,
|
||||
11897542014760736209670863723231849628230383119798486487899539017466261308762,
|
||||
16771780563523793011283273687253985566177232886900511371656074413362142152543,
|
||||
749264854018824809464168489785113337925400687349357088413132714480582918506,
|
||||
3683645737503705042628598550438395339383572464204988015434959428676652575331,
|
||||
7556750851783822914673316211129907782679509728346361368978891584375551186255,
|
||||
20391289379084797414557439284689954098721219201171527383291525676334308303023,
|
||||
18146517657445423462330854383025300323335289319277199154920964274562014376193,
|
||||
8080173465267536232534446836148661251987053305394647905212781979099916615292,
|
||||
10796443006899450245502071131975731672911747129805343722228413358507805531141,
|
||||
5404287610364961067658660283245291234008692303120470305032076412056764726509,
|
||||
4623894483395123520243967718315330178025957095502546813929290333264120223168,
|
||||
16845753148201777192406958674202574751725237939980634861948953189320362207797,
|
||||
4622170486584704769521001011395820886029808520586507873417553166762370293671,
|
||||
16688277490485052681847773549197928630624828392248424077804829676011512392564,
|
||||
11878652861183667748838188993669912629573713271883125458838494308957689090959,
|
||||
2436445725746972287496138382764643208791713986676129260589667864467010129482,
|
||||
1888098689545151571063267806606510032698677328923740058080630641742325067877,
|
||||
148924106504065664829055598316821983869409581623245780505601526786791681102,
|
||||
18875020877782404439294079398043479420415331640996249745272087358069018086569,
|
||||
15189693413320228845990326214136820307649565437237093707846682797649429515840,
|
||||
19669450123472657781282985229369348220906547335081730205028099210442632534079,
|
||||
5521922218264623411380547905210139511350706092570900075727555783240701821773,
|
||||
4144769320246558352780591737261172907511489963810975650573703217887429086546,
|
||||
10097732913112662248360143041019433907849917041759137293018029019134392559350,
|
||||
1720059427972723034107765345743336447947522473310069975142483982753181038321,
|
||||
6302388219880227251325608388535181451187131054211388356563634768253301290116,
|
||||
6745410632962119604799318394592010194450845483518862700079921360015766217097,
|
||||
10858157235265583624235850660462324469799552996870780238992046963007491306222,
|
||||
20241898894740093733047052816576694435372877719072347814065227797906130857593,
|
||||
10165780782761211520836029617746977303303335603838343292431760011576528327409,
|
||||
2832093654883670345969792724123161241696170611611744759675180839473215203706,
|
||||
153011722355526826233082383360057587249818749719433916258246100068258954737,
|
||||
20196970640587451358539129330170636295243141659030208529338914906436009086943,
|
||||
3180973917010545328313139835982464870638521890385603025657430208141494469656,
|
||||
17198004293191777441573635123110935015228014028618868252989374962722329283022,
|
||||
7642160509228669138628515458941659189680509753651629476399516332224325757132,
|
||||
19346204940546791021518535594447257347218878114049998691060016493806845179755,
|
||||
11501810868606870391127866188394535330696206817602260610801897042898616817272,
|
||||
3113973447392053821824427670386252797811804954746053461397972968381571297505,
|
||||
6545064306297957002139416752334741502722251869537551068239642131448768236585,
|
||||
5203908808704813498389265425172875593837960384349653691918590736979872578408,
|
||||
2246692432011290582160062129070762007374502637007107318105405626910313810224,
|
||||
11760570435432189127645691249600821064883781677693087773459065574359292849137,
|
||||
5543749482491340532547407723464609328207990784853381797689466144924198391839,
|
||||
8837549193990558762776520822018694066937602576881497343584903902880277769302,
|
||||
12855514863299373699594410385788943772765811961581749194183533625311486462501,
|
||||
5363660674689121676875069134269386492382220935599781121306637800261912519729,
|
||||
13162342403579303950549728848130828093497701266240457479693991108217307949435,
|
||||
916941639326869583414469202910306428966657806899788970948781207501251816730,
|
||||
15618589556584434434009868216186115416835494805174158488636000580759692174228,
|
||||
8959562060028569701043973060670353733575345393653685776974948916988033453971,
|
||||
16390754464333401712265575949874369157699293840516802426621216808905079127650,
|
||||
168282396747788514908709091757591226095443902501365500003618183905496160435,
|
||||
8327443473179334761744301768309008451162322941906921742120510244986704677004,
|
||||
17213012626801210615058753489149961717422101711567228037597150941152495100640,
|
||||
10394369641533736715250242399198097296122982486516256408681925424076248952280,
|
||||
17784386835392322654196171115293700800825771210400152504776806618892170162248,
|
||||
16533189939837087893364000390641148516479148564190420358849587959161226782982,
|
||||
18725396114211370207078434315900726338547621160475533496863298091023511945076,
|
||||
7132325028834551397904855671244375895110341505383911719294705267624034122405,
|
||||
148317947440800089795933930720822493695520852448386394775371401743494965187,
|
||||
19001050671757720352890779127693793630251266879994702723636759889378387053056,
|
||||
18824274411769830274877839365728651108434404855803844568234862945613766611460,
|
||||
12771414330193951156383998390424063470766226667986423961689712557338777174205,
|
||||
11332046574800279729678603488745295198038913503395629790213378101166488244657,
|
||||
9607550223176946388146938069307456967842408600269548190739947540821716354749,
|
||||
8756385288462344550200229174435953103162307705310807828651304665320046782583,
|
||||
176061952957067086877570020242717222844908281373122372938833890096257042779,
|
||||
12200212977482648306758992405065921724409841940671166017620928947866825250857,
|
||||
10868453624107875516866146499877130701929063632959660262366632833504750028858,
|
||||
2016095394399807253596787752134573207202567875457560571095586743878953450738,
|
||||
21815578223768330433802113452339488275704145896544481092014911825656390567514,
|
||||
4923772847693564777744725640710197015181591950368494148029046443433103381621,
|
||||
1813584943682214789802230765734821149202472893379265320098816901270224589984,
|
||||
10810123816265612772922113403831964815724109728287572256602010709288980656498,
|
||||
1153669123397255702524721206511185557982017410156956216465120456256288427021,
|
||||
5007518659266430200134478928344522649876467369278722765097865662497773767152,
|
||||
2511432546938591792036639990606464315121646668029252285288323664350666551637,
|
||||
32883284540320451295484135704808083452381176816565850047310272290579727564,
|
||||
10484856914279112612610993418405543310546746652738541161791501150994088679557,
|
||||
2026733759645519472558796412979210009170379159866522399881566309631434814953,
|
||||
14731806221235869882801331463708736361296174006732553130708107037190460654379,
|
||||
14740327483193277147065845135561988641238516852487657117813536909482068950652,
|
||||
18787428285295558781869865751953016580493190547148386433580291216673009884554,
|
||||
3804047064713122820157099453648459188816376755739202017447862327783289895072,
|
||||
16709604795697901641948603019242067672006293290826991671766611326262532802914,
|
||||
11061717085931490100602849654034280576915102867237101935487893025907907250695,
|
||||
2821730726367472966906149684046356272806484545281639696873240305052362149654,
|
||||
17467794879902895769410571945152708684493991588672014763135370927880883292655,
|
||||
1571520786233540988201616650622796363168031165456869481368085474420849243232,
|
||||
10041051776251223165849354194892664881051125330236567356945669006147134614302,
|
||||
3981753758468103976812813304477670033098707002886030847251581853700311567551,
|
||||
4365864398105436789177703571412645548020537580493599380018290523813331678900,
|
||||
2391801327305361293476178683853802679507598622000359948432171562543560193350,
|
||||
214219368547551689972421167733597094823289857206402800635962137077096090722,
|
||||
18192064100315141084242006659317257023098826945893371479835220462302399655674,
|
||||
15487549757142039139328911515400805508248576685795694919457041092150651939253,
|
||||
10142447197759703415402259672441315777933858467700579946665223821199077641122,
|
||||
11246573086260753259993971254725613211193686683988426513880826148090811891866,
|
||||
6574066859860991369704567902211886840188702386542112593710271426704432301235,
|
||||
11311085442652291634822798307831431035776248927202286895207125867542470350078,
|
||||
20977948360215259915441258687649465618185769343138135384346964466965010873779,
|
||||
792781492853909872425531014397300057232399608769451037135936617996830018501,
|
||||
5027602491523497423798779154966735896562099398367163998686335127580757861872,
|
||||
14595204575654316237672764823862241845410365278802914304953002937313300553572,
|
||||
13973538843621261113924259058427434053808430378163734641175100160836376897004,
|
||||
16395063164993626722686882727042150241125309409717445381854913964674649318585,
|
||||
8465768840047024550750516678171433288207841931251654898809033371655109266663,
|
||||
21345603324471810861925019445720576814602636473739003852898308205213912255830,
|
||||
21171984405852590343970239018692870799717057961108910523876770029017785940991,
|
||||
10761027113757988230637066281488532903174559953630210849190212601991063767647,
|
||||
6678298831065390834922566306988418588227382406175769592902974103663687992230,
|
||||
4993662582188632374202316265508850988596880036291765531885657575099537176757,
|
||||
18364168158495573675698600238443218434246806358811328083953887470513967121206,
|
||||
3506345610354615013737144848471391553141006285964325596214723571988011984829,
|
||||
248732676202643792226973868626360612151424823368345645514532870586234380100,
|
||||
10090204501612803176317709245679152331057882187411777688746797044706063410969,
|
||||
21297149835078365363970699581821844234354988617890041296044775371855432973500,
|
||||
16729368143229828574342820060716366330476985824952922184463387490091156065099,
|
||||
4467191506765339364971058668792642195242197133011672559453028147641428433293,
|
||||
8677548159358013363291014307402600830078662555833653517843708051504582990832,
|
||||
1022951765127126818581466247360193856197472064872288389992480993218645055345,
|
||||
1888195070251580606973417065636430294417895423429240431595054184472931224452,
|
||||
4221265384902749246920810956363310125115516771964522748896154428740238579824,
|
||||
2825393571154632139467378429077438870179957021959813965940638905853993971879,
|
||||
19171031072692942278056619599721228021635671304612437350119663236604712493093,
|
||||
10780807212297131186617505517708903709488273075252405602261683478333331220733,
|
||||
18230936781133176044598070768084230333433368654744509969087239465125979720995,
|
||||
16901065971871379877929280081392692752968612240624985552337779093292740763381,
|
||||
146494141603558321291767829522948454429758543710648402457451799015963102253,
|
||||
2492729278659146790410698334997955258248120870028541691998279257260289595548,
|
||||
2204224910006646535594933495262085193210692406133533679934843341237521233504,
|
||||
16062117410185840274616925297332331018523844434907012275592638570193234893570,
|
||||
5894928453677122829055071981254202951712129328678534592916926069506935491729,
|
||||
4947482739415078212217504789923078546034438919537985740403824517728200332286,
|
||||
16143265650645676880461646123844627780378251900510645261875867423498913438066,
|
||||
397690828254561723549349897112473766901585444153303054845160673059519614409,
|
||||
11272653598912269895509621181205395118899451234151664604248382803490621227687,
|
||||
15566927854306879444693061574322104423426072650522411176731130806720753591030,
|
||||
14222898219492484180162096141564251903058269177856173968147960855133048449557,
|
||||
16690275395485630428127725067513114066329712673106153451801968992299636791385,
|
||||
3667030990325966886479548860429670833692690972701471494757671819017808678584,
|
||||
21280039024501430842616328642522421302481259067470872421086939673482530783142,
|
||||
15895485136902450169492923978042129726601461603404514670348703312850236146328,
|
||||
7733050956302327984762132317027414325566202380840692458138724610131603812560,
|
||||
438123800976401478772659663183448617575635636575786782566035096946820525816,
|
||||
814913922521637742587885320797606426167962526342166512693085292151314976633,
|
||||
12368712287081330853637674140264759478736012797026621876924395982504369598764,
|
||||
2494806857395134874309386694756263421445039103814920780777601708371037591569,
|
||||
16101132301514338989512946061786320637179843435886825102406248183507106312877,
|
||||
6252650284989960032925831409804233477770646333900692286731621844532438095656,
|
||||
9277135875276787021836189566799935097400042171346561246305113339462708861695,
|
||||
10493603554686607050979497281838644324893776154179810893893660722522945589063,
|
||||
8673089750662709235894359384294076697329948991010184356091130382437645649279,
|
||||
9558393272910366944245875920138649617479779893610128634419086981339060613250,
|
||||
19012287860122586147374214541764572282814469237161122489573881644994964647218,
|
||||
9783723818270121678386992630754842961728702994964214799008457449989291229500,
|
||||
15550788416669474113213749561488122552422887538676036667630838378023479382689,
|
||||
15016165746156232864069722572047169071786333815661109750860165034341572904221,
|
||||
6506225705710197163670556961299945987488979904603689017479840649664564978574,
|
||||
10796631184889302076168355684722130903785890709107732067446714470783437829037,
|
||||
19871836214837460419845806980869387567383718044439891735114283113359312279540,
|
||||
20871081766843466343749609089986071784031203517506781251203251608363835140622,
|
||||
5100105771517691442278432864090229416166996183792075307747582375962855820797,
|
||||
8777887112076272395250620301071581171386440850451972412060638225741125310886,
|
||||
5300440870136391278944213332144327695659161151625757537632832724102670898756,
|
||||
1205448543652932944633962232545707633928124666868453915721030884663332604536,
|
||||
5542499997310181530432302492142574333860449305424174466698068685590909336771,
|
||||
11028094245762332275225364962905938096659249161369092798505554939952525894293,
|
||||
19187314764836593118404597958543112407224947638377479622725713735224279297009,
|
||||
17047263688548829001253658727764731047114098556534482052135734487985276987385,
|
||||
19914849528178967155534624144358541535306360577227460456855821557421213606310,
|
||||
2929658084700714257515872921366736697080475676508114973627124569375444665664,
|
||||
15092262360719700162343163278648422751610766427236295023221516498310468956361,
|
||||
21578580340755653236050830649990190843552802306886938815497471545814130084980,
|
||||
1258781501221760320019859066036073675029057285507345332959539295621677296991,
|
||||
3819598418157732134449049289585680301176983019643974929528867686268702720163,
|
||||
8653175945487997845203439345797943132543211416447757110963967501177317426221,
|
||||
6614652990340435611114076169697104582524566019034036680161902142028967568142,
|
||||
19212515502973904821995111796203064175854996071497099383090983975618035391558,
|
||||
18664315914479294273286016871365663486061896605232511201418576829062292269769,
|
||||
11498264615058604317482574216318586415670903094838791165247179252175768794889,
|
||||
10814026414212439999107945133852431304483604215416531759535467355316227331774,
|
||||
17566185590731088197064706533119299946752127014428399631467913813769853431107,
|
||||
14016139747289624978792446847000951708158212463304817001882956166752906714332,
|
||||
8242601581342441750402731523736202888792436665415852106196418942315563860366,
|
||||
9244680976345080074252591214216060854998619670381671198295645618515047080988,
|
||||
12216779172735125538689875667307129262237123728082657485828359100719208190116,
|
||||
10702811721859145441471328511968332847175733707711670171718794132331147396634,
|
||||
6479667912792222539919362076122453947926362746906450079329453150607427372979,
|
||||
15117544653571553820496948522381772148324367479772362833334593000535648316185,
|
||||
6842203153996907264167856337497139692895299874139131328642472698663046726780,
|
||||
12732823292801537626009139514048596316076834307941224506504666470961250728055,
|
||||
6936272626871035740815028148058841877090860312517423346335878088297448888663,
|
||||
17297554111853491139852678417579991271009602631577069694853813331124433680030,
|
||||
16641596134749940573104316021365063031319260205559553673368334842484345864859,
|
||||
7400481189785154329569470986896455371037813715804007747228648863919991399081,
|
||||
2273205422216987330510475127669563545720586464429614439716564154166712854048,
|
||||
15162538063742142685306302282127534305212832649282186184583465569986719234456,
|
||||
5628039096440332922248578319648483863204530861778160259559031331287721255522,
|
||||
16085392195894691829567913404182676871326863890140775376809129785155092531260,
|
||||
14227467863135365427954093998621993651369686288941275436795622973781503444257,
|
||||
18224457394066545825553407391290108485121649197258948320896164404518684305122,
|
||||
274945154732293792784580363548970818611304339008964723447672490026510689427,
|
||||
11050822248291117548220126630860474473945266276626263036056336623671308219529,
|
||||
2119542016932434047340813757208803962484943912710204325088879681995922344971
|
||||
];
|
||||
|
||||
var t;
|
||||
signal t2[nrounds];
|
||||
signal t4[nrounds];
|
||||
signal xL[nrounds-1];
|
||||
signal xR[nrounds-1];
|
||||
|
||||
var c;
|
||||
for (var i=0; i<nrounds; i++) {
|
||||
if ((i == 0) || (i == nrounds - 1)) {
|
||||
c = 0;
|
||||
} else {
|
||||
c = c_partial[i - 1];
|
||||
}
|
||||
t = (i==0) ? k+xL_in : k + xL[i-1] + c;
|
||||
t2[i] <== t*t;
|
||||
t4[i] <== t2[i]*t2[i];
|
||||
if (i<nrounds-1) {
|
||||
xL[i] <== ((i==0) ? xR_in : xR[i-1]) + t4[i]*t;
|
||||
xR[i] <== (i==0) ? xL_in : xL[i-1];
|
||||
} else {
|
||||
xR_out <== xR[i-1] + t4[i]*t;
|
||||
xL_out <== xL[i-1];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,113 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// --> Assignation without constraint
|
||||
// <-- Assignation without constraint
|
||||
// === Constraint
|
||||
// <== Assignation with constraint
|
||||
// ==> Assignation with constraint
|
||||
// All variables are members of the field F[p]
|
||||
// https://github.com/zcash-hackworks/sapling-crypto
|
||||
// https://github.com/ebfull/bellman
|
||||
|
||||
/*
|
||||
function log2(a) {
|
||||
if (a==0) {
|
||||
return 0;
|
||||
}
|
||||
let n = 1;
|
||||
let r = 1;
|
||||
while (n<a) {
|
||||
r++;
|
||||
n *= 2;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
*/
|
||||
|
||||
template EscalarProduct(w) {
|
||||
signal input in1[w];
|
||||
signal input in2[w];
|
||||
signal output out;
|
||||
signal aux[w];
|
||||
var lc = 0;
|
||||
for (var i=0; i<w; i++) {
|
||||
aux[i] <== in1[i]*in2[i];
|
||||
lc = lc + aux[i];
|
||||
}
|
||||
out <== lc;
|
||||
}
|
||||
|
||||
template Decoder(w) {
|
||||
signal input inp;
|
||||
signal output out[w];
|
||||
signal output success;
|
||||
var lc=0;
|
||||
|
||||
for (var i=0; i<w; i++) {
|
||||
out[i] <-- (inp == i) ? 1 : 0;
|
||||
out[i] * (inp-i) === 0;
|
||||
lc = lc + out[i];
|
||||
}
|
||||
|
||||
lc ==> success;
|
||||
success * (success -1) === 0;
|
||||
}
|
||||
|
||||
|
||||
template Multiplexer(wIn, nIn) {
|
||||
signal input inp[nIn][wIn];
|
||||
signal input sel;
|
||||
signal output out[wIn];
|
||||
component dec = Decoder(nIn);
|
||||
component ep[wIn];
|
||||
|
||||
for (var k=0; k<wIn; k++) {
|
||||
ep[k] = EscalarProduct(nIn);
|
||||
}
|
||||
|
||||
sel ==> dec.inp;
|
||||
for (var j=0; j<wIn; j++) {
|
||||
for (var k=0; k<nIn; k++) {
|
||||
inp[k][j] ==> ep[j].in1[k];
|
||||
dec.out[k] ==> ep[j].in2[k];
|
||||
}
|
||||
ep[j].out ==> out[j];
|
||||
}
|
||||
dec.success === 1;
|
||||
}
|
||||
@ -1,47 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
template MultiMux1(n) {
|
||||
signal input c[n][2]; // Constants
|
||||
signal input s; // Selector
|
||||
signal output out[n];
|
||||
|
||||
for (var i=0; i<n; i++) {
|
||||
|
||||
out[i] <== (c[i][1] - c[i][0])*s + c[i][0];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
template Mux1() {
|
||||
var i;
|
||||
signal input c[2]; // Constants
|
||||
signal input s; // Selector
|
||||
signal output out;
|
||||
|
||||
component mux = MultiMux1(1);
|
||||
|
||||
for (i=0; i<2; i++) {
|
||||
mux.c[0][i] <== c[i];
|
||||
}
|
||||
|
||||
s ==> mux.s;
|
||||
|
||||
mux.out[0] ==> out;
|
||||
}
|
||||
@ -1,62 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
template MultiMux2(n) {
|
||||
signal input c[n][4]; // Constants
|
||||
signal input s[2]; // Selector
|
||||
signal output out[n];
|
||||
|
||||
signal a10[n];
|
||||
signal a1[n];
|
||||
signal a0[n];
|
||||
signal a[n];
|
||||
|
||||
signal s10;
|
||||
s10 <== s[1] * s[0];
|
||||
|
||||
for (var i=0; i<n; i++) {
|
||||
|
||||
a10[i] <== ( c[i][ 3]-c[i][ 2]-c[i][ 1]+c[i][ 0] ) * s10;
|
||||
a1[i] <== ( c[i][ 2]-c[i][ 0] ) * s[1];
|
||||
a0[i] <== ( c[i][ 1]-c[i][ 0] ) * s[0];
|
||||
a[i] <== ( c[i][ 0] )
|
||||
|
||||
out[i] <== ( a10[i] + a1[i] + a0[i] + a[i] );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
template Mux2() {
|
||||
var i;
|
||||
signal input c[4]; // Constants
|
||||
signal input s[2]; // Selector
|
||||
signal output out;
|
||||
|
||||
component mux = MultiMux2(1);
|
||||
|
||||
for (i=0; i<4; i++) {
|
||||
mux.c[0][i] <== c[i];
|
||||
}
|
||||
|
||||
for (i=0; i<2; i++) {
|
||||
s[i] ==> mux.s[i];
|
||||
}
|
||||
|
||||
mux.out[0] ==> out;
|
||||
}
|
||||
@ -1,66 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
include "escalarmul.circom";
|
||||
|
||||
template Pedersen(n) {
|
||||
signal input in[n];
|
||||
signal output out[2];
|
||||
|
||||
var nexps = ((n-1) \ 250) + 1;
|
||||
var nlastbits = n - (nexps-1)*250;
|
||||
|
||||
component escalarMuls[nexps];
|
||||
|
||||
var PBASE = [
|
||||
[10457101036533406547632367118273992217979173478358440826365724437999023779287,19824078218392094440610104313265183977899662750282163392862422243483260492317],
|
||||
[2671756056509184035029146175565761955751135805354291559563293617232983272177,2663205510731142763556352975002641716101654201788071096152948830924149045094],
|
||||
[5802099305472655231388284418920769829666717045250560929368476121199858275951,5980429700218124965372158798884772646841287887664001482443826541541529227896],
|
||||
[7107336197374528537877327281242680114152313102022415488494307685842428166594,2857869773864086953506483169737724679646433914307247183624878062391496185654],
|
||||
[20265828622013100949498132415626198973119240347465898028410217039057588424236,1160461593266035632937973507065134938065359936056410650153315956301179689506],
|
||||
[1487999857809287756929114517587739322941449154962237464737694709326309567994,14017256862867289575056460215526364897734808720610101650676790868051368668003],
|
||||
[14618644331049802168996997831720384953259095788558646464435263343433563860015,13115243279999696210147231297848654998887864576952244320558158620692603342236],
|
||||
[6814338563135591367010655964669793483652536871717891893032616415581401894627,13660303521961041205824633772157003587453809761793065294055279768121314853695],
|
||||
[3571615583211663069428808372184817973703476260057504149923239576077102575715,11981351099832644138306422070127357074117642951423551606012551622164230222506],
|
||||
[18597552580465440374022635246985743886550544261632147935254624835147509493269,6753322320275422086923032033899357299485124665258735666995435957890214041481]
|
||||
];
|
||||
|
||||
var i;
|
||||
var j;
|
||||
var nexpbits;
|
||||
for (i=0; i<nexps; i++) {
|
||||
nexpbits = (i == nexps-1) ? nlastbits : 250;
|
||||
escalarMuls[i] = EscalarMul(nexpbits, PBASE[i]);
|
||||
|
||||
for (j=0; j<nexpbits; j++) {
|
||||
escalarMuls[i].in[j] <== in[250*i + j];
|
||||
}
|
||||
|
||||
if (i==0) {
|
||||
escalarMuls[i].inp[0] <== 0;
|
||||
escalarMuls[i].inp[1] <== 1;
|
||||
} else {
|
||||
escalarMuls[i].inp[0] <== escalarMuls[i-1].out[0];
|
||||
escalarMuls[i].inp[1] <== escalarMuls[i-1].out[1];
|
||||
}
|
||||
}
|
||||
|
||||
escalarMuls[nexps-1].out[0] ==> out[0];
|
||||
escalarMuls[nexps-1].out[1] ==> out[1];
|
||||
}
|
||||
@ -1,97 +0,0 @@
|
||||
include "./poseidon_constants.circom";
|
||||
|
||||
template Sigma() {
|
||||
signal input in;
|
||||
signal output out;
|
||||
|
||||
signal in2;
|
||||
signal in4;
|
||||
|
||||
in2 <== in*in;
|
||||
in4 <== in2*in2;
|
||||
|
||||
out <== in4*in;
|
||||
}
|
||||
|
||||
template Ark(t, C, r) {
|
||||
signal input in[t];
|
||||
signal output out[t];
|
||||
|
||||
for (var i=0; i<t; i++) {
|
||||
out[i] <== in[i] + C[i + r];
|
||||
}
|
||||
}
|
||||
|
||||
template Mix(t, M) {
|
||||
signal input in[t];
|
||||
signal output out[t];
|
||||
|
||||
var lc;
|
||||
for (var i=0; i<t; i++) {
|
||||
lc = 0;
|
||||
for (var j=0; j<t; j++) {
|
||||
lc += M[j][i]*in[j];
|
||||
}
|
||||
out[i] <== lc;
|
||||
}
|
||||
}
|
||||
|
||||
template Poseidon(nInputs) {
|
||||
signal input inputs[nInputs];
|
||||
signal output out;
|
||||
|
||||
// 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
|
||||
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 mix[nRoundsF + nRoundsP - 1];
|
||||
|
||||
var k;
|
||||
|
||||
for (var i=0; i<nRoundsF + nRoundsP - 1; i++) {
|
||||
ark[i] = Ark(t, C, t*i);
|
||||
for (var j=0; j<t; j++) {
|
||||
if (i==0) {
|
||||
if (j<nInputs) {
|
||||
ark[i].in[j] <== inputs[j];
|
||||
} else {
|
||||
ark[i].in[j] <== 0;
|
||||
}
|
||||
} else {
|
||||
ark[i].in[j] <== mix[i-1].out[j];
|
||||
}
|
||||
}
|
||||
|
||||
if (i < nRoundsF/2 || i >= nRoundsP + nRoundsF/2) {
|
||||
k = i < nRoundsF/2 ? i : i - nRoundsP;
|
||||
mix[i] = Mix(t, M);
|
||||
for (var j=0; j<t; j++) {
|
||||
sigmaF[k][j] = Sigma();
|
||||
sigmaF[k][j].in <== ark[i].out[j];
|
||||
mix[i].in[j] <== sigmaF[k][j].out;
|
||||
}
|
||||
} else {
|
||||
k = i - nRoundsF/2;
|
||||
mix[i] = Mix(t, M);
|
||||
sigmaP[k] = Sigma();
|
||||
sigmaP[k].in <== ark[i].out[0];
|
||||
mix[i].in[0] <== sigmaP[k].out;
|
||||
for (var j=1; j<t; j++) {
|
||||
mix[i].in[j] <== ark[i].out[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@ -1,46 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Ch
|
||||
|
||||
000 0
|
||||
001 1
|
||||
010 0
|
||||
011 1
|
||||
100 0
|
||||
101 0
|
||||
110 1
|
||||
111 1
|
||||
|
||||
out = a&b ^ (!a)&c =>
|
||||
|
||||
out = a*(b-c) + c
|
||||
|
||||
*/
|
||||
|
||||
template Ch(n) {
|
||||
signal input a[n];
|
||||
signal input b[n];
|
||||
signal input c[n];
|
||||
signal output out[n];
|
||||
|
||||
for (var k=0; k<n; k++) {
|
||||
out[k] <== a[k] * (b[k]-c[k]) + c[k];
|
||||
}
|
||||
}
|
||||
@ -1,52 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
template H(x) {
|
||||
signal output out[32];
|
||||
var c = [0x6a09e667,
|
||||
0xbb67ae85,
|
||||
0x3c6ef372,
|
||||
0xa54ff53a,
|
||||
0x510e527f,
|
||||
0x9b05688c,
|
||||
0x1f83d9ab,
|
||||
0x5be0cd19];
|
||||
|
||||
for (var i=0; i<32; i++) {
|
||||
out[i] <== (c[x] >> i) & 1;
|
||||
}
|
||||
}
|
||||
|
||||
template K(x) {
|
||||
signal output out[32];
|
||||
var c = [
|
||||
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
|
||||
];
|
||||
|
||||
for (var i=0; i<32; i++) {
|
||||
out[i] <== (c[x] >> i) & 1;
|
||||
}
|
||||
}
|
||||
@ -1,34 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
include "sha256_2.jaz";
|
||||
|
||||
template Main() {
|
||||
signal private input a;
|
||||
signal private input b;
|
||||
signal output out;
|
||||
|
||||
component sha256_2 = SHA256_2();
|
||||
|
||||
sha256_2.a <== a;
|
||||
sha256_2.b <== a;
|
||||
out <== sha256_2.out;
|
||||
}
|
||||
|
||||
component main = Main();
|
||||
@ -1,44 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Maj function for sha256
|
||||
|
||||
out = a&b ^ a&c ^ b&c =>
|
||||
|
||||
out = a*b + a*c + b*c - 2*a*b*c =>
|
||||
|
||||
out = a*( b + c - 2*b*c ) + b*c =>
|
||||
|
||||
mid = b*c
|
||||
out = a*( b + c - 2*mid ) + mid
|
||||
|
||||
*/
|
||||
|
||||
template Maj(n) {
|
||||
signal input a[n];
|
||||
signal input b[n];
|
||||
signal input c[n];
|
||||
signal output out[n];
|
||||
signal mid[n];
|
||||
|
||||
for (var k=0; k<n; k++) {
|
||||
mid[k] <== b[k]*c[k];
|
||||
out[k] <== a[k] * (b[k]+c[k]-2*mid[k]) + mid[k];
|
||||
}
|
||||
}
|
||||
@ -1,27 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
template RotR(n, r) {
|
||||
signal input in[n];
|
||||
signal output out[n];
|
||||
|
||||
for (var i=0; i<n; i++) {
|
||||
out[i] <== in[ (i+r)%n ];
|
||||
}
|
||||
}
|
||||
@ -1,81 +0,0 @@
|
||||
|
||||
|
||||
include "constants.circom";
|
||||
include "sha256compression.circom";
|
||||
|
||||
template Sha256(nBits) {
|
||||
signal input in[nBits];
|
||||
signal output out[256];
|
||||
|
||||
var i;
|
||||
var k;
|
||||
var nBlocks;
|
||||
var bitsLastBlock;
|
||||
|
||||
|
||||
nBlocks = ((nBits + 64)\512)+1;
|
||||
|
||||
signal paddedIn[nBlocks*512];
|
||||
|
||||
for (k=0; k<nBits; k++) {
|
||||
paddedIn[k] <== in[k];
|
||||
}
|
||||
paddedIn[nBits] <== 1;
|
||||
|
||||
for (k=nBits+1; k<nBlocks*512-64; k++) {
|
||||
paddedIn[k] <== 0;
|
||||
}
|
||||
|
||||
for (k = 0; k< 64; k++) {
|
||||
paddedIn[nBlocks*512 - k -1] <== (nBits >> k)&1;
|
||||
}
|
||||
|
||||
component ha0 = H(0);
|
||||
component hb0 = H(1);
|
||||
component hc0 = H(2);
|
||||
component hd0 = H(3);
|
||||
component he0 = H(4);
|
||||
component hf0 = H(5);
|
||||
component hg0 = H(6);
|
||||
component hh0 = H(7);
|
||||
|
||||
component sha256compression[nBlocks];
|
||||
|
||||
for (i=0; i<nBlocks; i++) {
|
||||
|
||||
sha256compression[i] = Sha256compression() ;
|
||||
|
||||
if (i==0) {
|
||||
for (k=0; k<32; k++ ) {
|
||||
sha256compression[i].hin[0*32+k] <== ha0.out[k];
|
||||
sha256compression[i].hin[1*32+k] <== hb0.out[k];
|
||||
sha256compression[i].hin[2*32+k] <== hc0.out[k];
|
||||
sha256compression[i].hin[3*32+k] <== hd0.out[k];
|
||||
sha256compression[i].hin[4*32+k] <== he0.out[k];
|
||||
sha256compression[i].hin[5*32+k] <== hf0.out[k];
|
||||
sha256compression[i].hin[6*32+k] <== hg0.out[k];
|
||||
sha256compression[i].hin[7*32+k] <== hh0.out[k];
|
||||
}
|
||||
} else {
|
||||
for (k=0; k<32; k++ ) {
|
||||
sha256compression[i].hin[32*0+k] <== sha256compression[i-1].out[32*0+31-k];
|
||||
sha256compression[i].hin[32*1+k] <== sha256compression[i-1].out[32*1+31-k];
|
||||
sha256compression[i].hin[32*2+k] <== sha256compression[i-1].out[32*2+31-k];
|
||||
sha256compression[i].hin[32*3+k] <== sha256compression[i-1].out[32*3+31-k];
|
||||
sha256compression[i].hin[32*4+k] <== sha256compression[i-1].out[32*4+31-k];
|
||||
sha256compression[i].hin[32*5+k] <== sha256compression[i-1].out[32*5+31-k];
|
||||
sha256compression[i].hin[32*6+k] <== sha256compression[i-1].out[32*6+31-k];
|
||||
sha256compression[i].hin[32*7+k] <== sha256compression[i-1].out[32*7+31-k];
|
||||
}
|
||||
}
|
||||
|
||||
for (k=0; k<512; k++) {
|
||||
sha256compression[i].inp[k] <== paddedIn[i*512+k];
|
||||
}
|
||||
}
|
||||
|
||||
for (k=0; k<256; k++) {
|
||||
out[k] <== sha256compression[nBlocks-1].out[k];
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,90 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
include "constants.circom";
|
||||
include "sha256compression.circom";
|
||||
include "../bitify.circom"
|
||||
|
||||
template Sha256_2() {
|
||||
signal input a;
|
||||
signal input b;
|
||||
signal output out;
|
||||
|
||||
var i;
|
||||
var k;
|
||||
|
||||
component bits2num = Bits2Num(216);
|
||||
component num2bits[2];
|
||||
|
||||
num2bits[0] = Num2Bits(216);
|
||||
num2bits[1] = Num2Bits(216);
|
||||
|
||||
num2bits[0].in <== a;
|
||||
num2bits[1].in <== b;
|
||||
|
||||
|
||||
component sha256compression = Sha256compression() ;
|
||||
|
||||
component ha0 = H(0);
|
||||
component hb0 = H(1);
|
||||
component hc0 = H(2);
|
||||
component hd0 = H(3);
|
||||
component he0 = H(4);
|
||||
component hf0 = H(5);
|
||||
component hg0 = H(6);
|
||||
component hh0 = H(7);
|
||||
|
||||
for (k=0; k<32; k++ ) {
|
||||
sha256compression.hin[0*32+k] <== ha0.out[k];
|
||||
sha256compression.hin[1*32+k] <== hb0.out[k];
|
||||
sha256compression.hin[2*32+k] <== hc0.out[k];
|
||||
sha256compression.hin[3*32+k] <== hd0.out[k];
|
||||
sha256compression.hin[4*32+k] <== he0.out[k];
|
||||
sha256compression.hin[5*32+k] <== hf0.out[k];
|
||||
sha256compression.hin[6*32+k] <== hg0.out[k];
|
||||
sha256compression.hin[7*32+k] <== hh0.out[k];
|
||||
}
|
||||
|
||||
for (i=0; i<216; i++) {
|
||||
sha256compression.inp[i] <== num2bits[0].out[215-i];
|
||||
sha256compression.inp[i+216] <== num2bits[1].out[215-i];
|
||||
}
|
||||
|
||||
sha256compression.inp[432] <== 1;
|
||||
|
||||
for (i=433; i<503; i++) {
|
||||
sha256compression.inp[i] <== 0;
|
||||
}
|
||||
|
||||
sha256compression.inp[503] <== 1;
|
||||
sha256compression.inp[504] <== 1;
|
||||
sha256compression.inp[505] <== 0;
|
||||
sha256compression.inp[506] <== 1;
|
||||
sha256compression.inp[507] <== 1;
|
||||
sha256compression.inp[508] <== 0;
|
||||
sha256compression.inp[509] <== 0;
|
||||
sha256compression.inp[510] <== 0;
|
||||
sha256compression.inp[511] <== 0;
|
||||
|
||||
for (i=0; i<216; i++) {
|
||||
bits2num.in[i] <== sha256compression.out[255-i];
|
||||
}
|
||||
|
||||
out <== bits2num.out;
|
||||
}
|
||||
@ -1,156 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
include "constants.circom";
|
||||
include "t1.circom";
|
||||
include "t2.circom";
|
||||
include "../binsum.circom";
|
||||
include "sigmaplus.circom";
|
||||
|
||||
template Sha256compression() {
|
||||
signal input hin[256];
|
||||
signal input inp[512];
|
||||
signal output out[256];
|
||||
signal a[65][32];
|
||||
signal b[65][32];
|
||||
signal c[65][32];
|
||||
signal d[65][32];
|
||||
signal e[65][32];
|
||||
signal f[65][32];
|
||||
signal g[65][32];
|
||||
signal h[65][32];
|
||||
signal w[64][32];
|
||||
|
||||
var i;
|
||||
|
||||
component sigmaPlus[48];
|
||||
for (i=0; i<48; i++) sigmaPlus[i] = SigmaPlus();
|
||||
|
||||
component ct_k[64];
|
||||
for (i=0; i<64; i++) ct_k[i] = K(i);
|
||||
|
||||
component t1[64];
|
||||
for (i=0; i<64; i++) t1[i] = T1();
|
||||
|
||||
component t2[64];
|
||||
for (i=0; i<64; i++) t2[i] = T2();
|
||||
|
||||
component suma[64];
|
||||
for (i=0; i<64; i++) suma[i] = BinSum(32, 2);
|
||||
|
||||
component sume[64];
|
||||
for (i=0; i<64; i++) sume[i] = BinSum(32, 2);
|
||||
|
||||
component fsum[8];
|
||||
for (i=0; i<8; i++) fsum[i] = BinSum(32, 2);
|
||||
|
||||
var k;
|
||||
var t;
|
||||
|
||||
for (t=0; t<64; t++) {
|
||||
if (t<16) {
|
||||
for (k=0; k<32; k++) {
|
||||
w[t][k] <== inp[t*32+31-k];
|
||||
}
|
||||
} else {
|
||||
for (k=0; k<32; k++) {
|
||||
sigmaPlus[t-16].in2[k] <== w[t-2][k];
|
||||
sigmaPlus[t-16].in7[k] <== w[t-7][k];
|
||||
sigmaPlus[t-16].in15[k] <== w[t-15][k];
|
||||
sigmaPlus[t-16].in16[k] <== w[t-16][k];
|
||||
w[t][k] <== sigmaPlus[t-16].out[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (k=0; k<32; k++ ) {
|
||||
a[0][k] <== hin[k];
|
||||
b[0][k] <== hin[32*1 + k];
|
||||
c[0][k] <== hin[32*2 + k];
|
||||
d[0][k] <== hin[32*3 + k];
|
||||
e[0][k] <== hin[32*4 + k];
|
||||
f[0][k] <== hin[32*5 + k];
|
||||
g[0][k] <== hin[32*6 + k];
|
||||
h[0][k] <== hin[32*7 + k];
|
||||
}
|
||||
|
||||
for (t = 0; t<64; t++) {
|
||||
for (k=0; k<32; k++) {
|
||||
t1[t].h[k] <== h[t][k];
|
||||
t1[t].e[k] <== e[t][k];
|
||||
t1[t].f[k] <== f[t][k];
|
||||
t1[t].g[k] <== g[t][k];
|
||||
t1[t].k[k] <== ct_k[t].out[k];
|
||||
t1[t].w[k] <== w[t][k];
|
||||
|
||||
t2[t].a[k] <== a[t][k];
|
||||
t2[t].b[k] <== b[t][k];
|
||||
t2[t].c[k] <== c[t][k];
|
||||
}
|
||||
|
||||
for (k=0; k<32; k++) {
|
||||
sume[t].in[0][k] <== d[t][k];
|
||||
sume[t].in[1][k] <== t1[t].out[k];
|
||||
|
||||
suma[t].in[0][k] <== t1[t].out[k];
|
||||
suma[t].in[1][k] <== t2[t].out[k];
|
||||
}
|
||||
|
||||
for (k=0; k<32; k++) {
|
||||
h[t+1][k] <== g[t][k];
|
||||
g[t+1][k] <== f[t][k];
|
||||
f[t+1][k] <== e[t][k];
|
||||
e[t+1][k] <== sume[t].out[k];
|
||||
d[t+1][k] <== c[t][k];
|
||||
c[t+1][k] <== b[t][k];
|
||||
b[t+1][k] <== a[t][k];
|
||||
a[t+1][k] <== suma[t].out[k];
|
||||
}
|
||||
}
|
||||
|
||||
for (k=0; k<32; k++) {
|
||||
fsum[0].in[0][k] <== hin[32*0+k];
|
||||
fsum[0].in[1][k] <== a[64][k];
|
||||
fsum[1].in[0][k] <== hin[32*1+k];
|
||||
fsum[1].in[1][k] <== b[64][k];
|
||||
fsum[2].in[0][k] <== hin[32*2+k];
|
||||
fsum[2].in[1][k] <== c[64][k];
|
||||
fsum[3].in[0][k] <== hin[32*3+k];
|
||||
fsum[3].in[1][k] <== d[64][k];
|
||||
fsum[4].in[0][k] <== hin[32*4+k];
|
||||
fsum[4].in[1][k] <== e[64][k];
|
||||
fsum[5].in[0][k] <== hin[32*5+k];
|
||||
fsum[5].in[1][k] <== f[64][k];
|
||||
fsum[6].in[0][k] <== hin[32*6+k];
|
||||
fsum[6].in[1][k] <== g[64][k];
|
||||
fsum[7].in[0][k] <== hin[32*7+k];
|
||||
fsum[7].in[1][k] <== h[64][k];
|
||||
}
|
||||
|
||||
for (k=0; k<32; k++) {
|
||||
out[31-k] <== fsum[0].out[k];
|
||||
out[32+31-k] <== fsum[1].out[k];
|
||||
out[64+31-k] <== fsum[2].out[k];
|
||||
out[96+31-k] <== fsum[3].out[k];
|
||||
out[128+31-k] <== fsum[4].out[k];
|
||||
out[160+31-k] <== fsum[5].out[k];
|
||||
out[192+31-k] <== fsum[6].out[k];
|
||||
out[224+31-k] <== fsum[7].out[k];
|
||||
}
|
||||
}
|
||||
@ -1,32 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
template ShR(n, r) {
|
||||
signal input in[n];
|
||||
signal output out[n];
|
||||
|
||||
for (var i=0; i<n; i++) {
|
||||
if (i+r >= n) {
|
||||
out[i] <== 0;
|
||||
} else {
|
||||
out[i] <== in[ i+r ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,68 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
include "xor3.circom";
|
||||
include "rotate.circom";
|
||||
include "shift.circom";
|
||||
|
||||
template SmallSigma(ra, rb, rc) {
|
||||
signal input in[32];
|
||||
signal output out[32];
|
||||
|
||||
component xor3 = Xor3(32);
|
||||
|
||||
component rota = RotR(32, ra);
|
||||
component rotb = RotR(32, rb);
|
||||
component shrc = ShR(32, rc);
|
||||
|
||||
for (var k=0; k<32; k++) {
|
||||
rota.in[k] <== in[k];
|
||||
rotb.in[k] <== in[k];
|
||||
shrc.in[k] <== in[k];
|
||||
|
||||
xor3.a[k] <== rota.out[k];
|
||||
xor3.b[k] <== rotb.out[k];
|
||||
xor3.c[k] <== shrc.out[k];
|
||||
|
||||
out[k] <== xor3.out[k];
|
||||
}
|
||||
}
|
||||
|
||||
template BigSigma(ra, rb, rc) {
|
||||
signal input in[32];
|
||||
signal output out[32];
|
||||
|
||||
component xor3 = Xor3(32);
|
||||
|
||||
component rota = RotR(32, ra);
|
||||
component rotb = RotR(32, rb);
|
||||
component rotc = RotR(32, rc);
|
||||
|
||||
for (var k=0; k<32; k++) {
|
||||
rota.in[k] <== in[k];
|
||||
rotb.in[k] <== in[k];
|
||||
rotc.in[k] <== in[k];
|
||||
|
||||
xor3.a[k] <== rota.out[k];
|
||||
xor3.b[k] <== rotb.out[k];
|
||||
xor3.c[k] <== rotc.out[k];
|
||||
|
||||
out[k] <== xor3.out[k];
|
||||
}
|
||||
}
|
||||
@ -1,45 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
include "../binsum.circom"
|
||||
include "sigma.circom"
|
||||
|
||||
template SigmaPlus() {
|
||||
signal input in2[32];
|
||||
signal input in7[32];
|
||||
signal input in15[32];
|
||||
signal input in16[32];
|
||||
signal output out[32];
|
||||
|
||||
component sum = BinSum(32, 4);
|
||||
component sigma1 = SmallSigma(17,19,10);
|
||||
component sigma0 = SmallSigma(7, 18, 3);
|
||||
|
||||
for (var k=0; k<32; k++) {
|
||||
sigma1.in[k] <== in2[k];
|
||||
sigma0.in[k] <== in15[k];
|
||||
|
||||
sum.in[0][k] <== sigma1.out[k];
|
||||
sum.in[1][k] <== in7[k];
|
||||
sum.in[2][k] <== sigma0.out[k];
|
||||
sum.in[3][k] <== in16[k];
|
||||
|
||||
out[k] <== sum.out[k];
|
||||
}
|
||||
}
|
||||
@ -1,52 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
include "../binsum.circom";
|
||||
include "sigma.circom";
|
||||
include "ch.circom";
|
||||
|
||||
template T1() {
|
||||
signal input h[32];
|
||||
signal input e[32];
|
||||
signal input f[32];
|
||||
signal input g[32];
|
||||
signal input k[32];
|
||||
signal input w[32];
|
||||
signal output out[32];
|
||||
|
||||
component sum = BinSum(32, 5);
|
||||
component ch = Ch(32);
|
||||
|
||||
component bigsigma1 = BigSigma(6, 11, 25);
|
||||
|
||||
for (var ki=0; ki<32; ki++) {
|
||||
bigsigma1.in[ki] <== e[ki];
|
||||
ch.a[ki] <== e[ki];
|
||||
ch.b[ki] <== f[ki];
|
||||
ch.c[ki] <== g[ki]
|
||||
|
||||
sum.in[0][ki] <== h[ki];
|
||||
sum.in[1][ki] <== bigsigma1.out[ki];
|
||||
sum.in[2][ki] <== ch.out[ki];
|
||||
sum.in[3][ki] <== k[ki];
|
||||
sum.in[4][ki] <== w[ki];
|
||||
|
||||
out[ki] <== sum.out[ki];
|
||||
}
|
||||
}
|
||||
@ -1,47 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
include "../binsum.circom";
|
||||
include "sigma.circom";
|
||||
include "maj.circom"
|
||||
|
||||
template T2() {
|
||||
signal input a[32];
|
||||
signal input b[32];
|
||||
signal input c[32];
|
||||
signal output out[32];
|
||||
|
||||
component sum = BinSum(32, 2);
|
||||
|
||||
component bigsigma0 = BigSigma(2, 13, 22);
|
||||
component maj = Maj(32);
|
||||
|
||||
for (var k=0; k<32; k++) {
|
||||
|
||||
bigsigma0.in[k] <== a[k];
|
||||
maj.a[k] <== a[k];
|
||||
maj.b[k] <== b[k];
|
||||
maj.c[k] <== c[k];
|
||||
|
||||
sum.in[0][k] <== bigsigma0.out[k];
|
||||
sum.in[1][k] <== maj.out[k];
|
||||
|
||||
out[k] <== sum.out[k];
|
||||
}
|
||||
}
|
||||
@ -1,44 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Xor3 function for sha256
|
||||
|
||||
out = a ^ b ^ c =>
|
||||
|
||||
out = a+b+c - 2*a*b - 2*a*c - 2*b*c + 4*a*b*c =>
|
||||
|
||||
out = a*( 1 - 2*b - 2*c + 4*b*c ) + b + c - 2*b*c =>
|
||||
|
||||
mid = b*c
|
||||
out = a*( 1 - 2*b -2*c + 4*mid ) + b + c - 2 * mid
|
||||
|
||||
*/
|
||||
|
||||
template Xor3(n) {
|
||||
signal input a[n];
|
||||
signal input b[n];
|
||||
signal input c[n];
|
||||
signal output out[n];
|
||||
signal mid[n];
|
||||
|
||||
for (var k=0; k<n; k++) {
|
||||
mid[k] <== b[k]*c[k];
|
||||
out[k] <== a[k] * (1 -2*b[k] -2*c[k] +4*mid[k]) + b[k] + c[k] -2*mid[k];
|
||||
}
|
||||
}
|
||||
@ -1,35 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
include "compconstant.circom";
|
||||
|
||||
template Sign() {
|
||||
signal input in[254];
|
||||
signal output sign;
|
||||
|
||||
component comp = CompConstant(10944121435919637611123202872628637544274182200208017171849102093287904247808);
|
||||
|
||||
var i;
|
||||
|
||||
for (i=0; i<254; i++) {
|
||||
comp.in[i] <== in[i];
|
||||
}
|
||||
|
||||
sign <== comp.out;
|
||||
}
|
||||
@ -1,57 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
include "../mimc.circom";
|
||||
|
||||
|
||||
/*
|
||||
Hash1 = H(1 | key | value)
|
||||
*/
|
||||
|
||||
template SMTHash1() {
|
||||
signal input key;
|
||||
signal input value;
|
||||
signal output out;
|
||||
|
||||
component h = MultiMiMC7(2, 91); // Constant
|
||||
h.in[0] <== key;
|
||||
h.in[1] <== value;
|
||||
h.k <== 1;
|
||||
|
||||
out <== h.out;
|
||||
}
|
||||
|
||||
/*
|
||||
This component is used to create the 2 nodes.
|
||||
|
||||
Hash2 = H(Hl | Hr)
|
||||
*/
|
||||
|
||||
template SMTHash2() {
|
||||
signal input L;
|
||||
signal input R;
|
||||
signal output out;
|
||||
|
||||
component h = MultiMiMC7(2, 91); // Constant
|
||||
h.in[0] <== L;
|
||||
h.in[1] <== R;
|
||||
h.k <== 0;
|
||||
|
||||
out <== h.out;
|
||||
}
|
||||
@ -1,56 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
include "../poseidon.circom";
|
||||
|
||||
|
||||
/*
|
||||
Hash1 = H(1 | key | value)
|
||||
*/
|
||||
|
||||
template SMTHash1() {
|
||||
signal input key;
|
||||
signal input value;
|
||||
signal output out;
|
||||
|
||||
component h = Poseidon(3); // Constant
|
||||
h.inputs[0] <== key;
|
||||
h.inputs[1] <== value;
|
||||
h.inputs[2] <== 1;
|
||||
|
||||
out <== h.out;
|
||||
}
|
||||
|
||||
/*
|
||||
This component is used to create the 2 nodes.
|
||||
|
||||
Hash2 = H(Hl | Hr)
|
||||
*/
|
||||
|
||||
template SMTHash2() {
|
||||
signal input L;
|
||||
signal input R;
|
||||
signal output out;
|
||||
|
||||
component h = Poseidon(2); // Constant
|
||||
h.inputs[0] <== L;
|
||||
h.inputs[1] <== R;
|
||||
|
||||
out <== h.out;
|
||||
}
|
||||
@ -1,100 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
This component finds the level where the oldInsert is done.
|
||||
The rules are:
|
||||
|
||||
levIns[i] == 1 if its level and all the child levels have a sibling of 0 and
|
||||
the parent level has a sibling != 0. Considere that the root level always has
|
||||
a parent with a sibling != 0.
|
||||
|
||||
|
||||
┌──────────────┐
|
||||
│ │
|
||||
│ │───▶ levIns[0] <== (1-done[i])
|
||||
│ │
|
||||
└──────────────┘
|
||||
▲
|
||||
│
|
||||
│
|
||||
done[0]
|
||||
|
||||
|
||||
|
||||
done[i-1] <== levIns[i] + done[i]
|
||||
▲
|
||||
│
|
||||
│
|
||||
┌───────────┐ ┌──────────────┐
|
||||
│ │ │ │
|
||||
sibling[i-1]───▶│IsZero[i-1]│─▶│ │───▶ levIns[i] <== (1-done[i])*(1-isZero[i-1].out)
|
||||
│ │ │ │
|
||||
└───────────┘ └──────────────┘
|
||||
▲
|
||||
│
|
||||
│
|
||||
done[i]
|
||||
|
||||
|
||||
|
||||
done[n-2] <== levIns[n-1]
|
||||
▲
|
||||
│
|
||||
│
|
||||
┌───────────┐ ┌──────────────┐
|
||||
│ │ │ │
|
||||
sibling[n-2]───▶│IsZero[n-2]│─▶│ │────▶ levIns[n-1] <== (1-isZero[n-2].out)
|
||||
│ │ │ │
|
||||
└───────────┘ └──────────────┘
|
||||
|
||||
┌───────────┐
|
||||
│ │
|
||||
sibling[n-1]───▶│IsZero[n-1]│────▶ === 0
|
||||
│ │
|
||||
└───────────┘
|
||||
|
||||
*/
|
||||
|
||||
template SMTLevIns(nLevels) {
|
||||
signal input enabled;
|
||||
signal input siblings[nLevels];
|
||||
signal output levIns[nLevels];
|
||||
signal done[nLevels-1]; // Indicates if the insLevel has aready been detected.
|
||||
|
||||
component isZero[nLevels];
|
||||
|
||||
for (var i=0; i<nLevels; i++) {
|
||||
isZero[i] = IsZero();
|
||||
isZero[i].in <== siblings[i];
|
||||
}
|
||||
|
||||
// The last level must always have a sibling of 0. If not, then it cannot be inserted.
|
||||
(isZero[nLevels-1].out - 1) * enabled === 0;
|
||||
|
||||
levIns[nLevels-1] <== (1-isZero[nLevels-2].out);
|
||||
done[nLevels-2] <== levIns[nLevels-1];
|
||||
for (var i=nLevels-2; i>0; i--) {
|
||||
levIns[i] <== (1-done[i])*(1-isZero[i-1].out)
|
||||
done[i-1] <== levIns[i] + done[i];
|
||||
}
|
||||
|
||||
levIns[0] <== (1-done[0]);
|
||||
}
|
||||
@ -1,258 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************************************
|
||||
|
||||
SMTProcessor: Sparse Merkle Tree processor is a component to verify an insert/update/delete elements
|
||||
into the Sparse Merkle tree.
|
||||
|
||||
|
||||
Insert to an empty leaf
|
||||
=======================
|
||||
|
||||
STATE OLD STATE NEW STATE
|
||||
===== ========= =========
|
||||
|
||||
oldRoot newRoot
|
||||
▲ ▲
|
||||
│ │
|
||||
┌───────┐ ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓
|
||||
top │Sibling├────▶┃ Hash ┃◀─┐ │Sibling├────▶┃ Hash ┃◀─┐
|
||||
└───────┘ ┗━━━━━━━┛ │ └───────┘ ┗━━━━━━━┛ │
|
||||
│ │
|
||||
│ │
|
||||
┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓ ┌───────┐
|
||||
top ┌─────▶┃ Hash ┃◀──┤Sibling│ ┌─────▶┃ Hash ┃◀──┤Sibling│
|
||||
│ ┗━━━━━━━┛ └───────┘ │ ┗━━━━━━━┛ └───────┘
|
||||
│ │
|
||||
│ │
|
||||
┌───────┐ ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓
|
||||
top │Sibling├──▶┃ Hash ┃◀─────┐ │Sibling├──▶┃ Hash ┃◀─────┐
|
||||
└───────┘ ┗━━━━━━━┛ │ └───────┘ ┗━━━━━━━┛ │
|
||||
│ │
|
||||
│ │
|
||||
┌────┴────┐ ┌────┴────┐
|
||||
old0 │ 0 │ │New1Leaf │
|
||||
└─────────┘ └─────────┘
|
||||
|
||||
|
||||
┏━━━━━━━┓ ┏━━━━━━━┓
|
||||
na ┃ Hash ┃ ┃ Hash ┃
|
||||
┗━━━━━━━┛ ┗━━━━━━━┛
|
||||
|
||||
|
||||
┏━━━━━━━┓ ┏━━━━━━━┓
|
||||
na ┃ Hash ┃ ┃ Hash ┃
|
||||
┗━━━━━━━┛ ┗━━━━━━━┛
|
||||
|
||||
|
||||
|
||||
Insert to a used leaf.
|
||||
=====================
|
||||
|
||||
STATE OLD STATE NEW STATE
|
||||
===== ========= =========
|
||||
|
||||
|
||||
oldRoot newRoot
|
||||
▲ ▲
|
||||
│ │
|
||||
┌───────┐ ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓
|
||||
top │Sibling├────▶┃ Hash ┃◀─┐ │Sibling├────▶┃ Hash ┃◀─┐
|
||||
└───────┘ ┗━━━━━━━┛ │ └───────┘ ┗━━━━━━━┛ │
|
||||
│ │
|
||||
│ │
|
||||
┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓ ┌───────┐
|
||||
top ┌─────▶┃ Hash ┃◀──┤Sibling│ ┌─────▶┃ Hash ┃◀──┤Sibling│
|
||||
│ ┗━━━━━━━┛ └───────┘ │ ┗━━━━━━━┛ └───────┘
|
||||
│ │
|
||||
│ │
|
||||
┌───────┐ ┏━━━┻━━━┓ ┌───────┐ ┏━━━┻━━━┓
|
||||
top │Sibling├──▶┃ Hash ┃◀─────┐ │Sibling├──▶┃ Hash ┃◀─────┐
|
||||
└───────┘ ┗━━━━━━━┛ │ └───────┘ ┗━━━━━━━┛ │
|
||||
│ │
|
||||
│ │
|
||||
┌────┴────┐ ┏━━━┻━━━┓ ┌───────┐
|
||||
bot │Old1Leaf │ ┌─────▶┃ Hash ┃◀──┼─ 0 │
|
||||
└─────────┘ │ ┗━━━━━━━┛ └───────┘
|
||||
│
|
||||
│
|
||||
┏━━━━━━━┓ ┌───────┐ ┏━━━┻━━━┓
|
||||
bot ┃ Hash ┃ │ 0 ─┼──▶┃ Hash ┃◀─────┐
|
||||
┗━━━━━━━┛ └───────┘ ┗━━━━━━━┛ │
|
||||
│
|
||||
│
|
||||
┏━━━━━━━┓ ┏━━━┻━━━┓ ┌───────┐
|
||||
bot ┃ Hash ┃ ┌─────▶┃ Hash ┃◀──│ 0 │
|
||||
┗━━━━━━━┛ │ ┗━━━━━━━┛ └───────┘
|
||||
│
|
||||
│
|
||||
┏━━━━━━━┓ ┌─────────┐ ┏━━━┻━━━┓ ┌─────────┐
|
||||
new1 ┃ Hash ┃ │Old1Leaf ├──▶┃ Hash ┃◀──│New1Leaf │
|
||||
┗━━━━━━━┛ └─────────┘ ┗━━━━━━━┛ └─────────┘
|
||||
|
||||
|
||||
┏━━━━━━━┓ ┏━━━━━━━┓
|
||||
na ┃ Hash ┃ ┃ Hash ┃
|
||||
┗━━━━━━━┛ ┗━━━━━━━┛
|
||||
|
||||
|
||||
┏━━━━━━━┓ ┏━━━━━━━┓
|
||||
na ┃ Hash ┃ ┃ Hash ┃
|
||||
┗━━━━━━━┛ ┗━━━━━━━┛
|
||||
|
||||
|
||||
Fnction
|
||||
fnc[0] fnc[1]
|
||||
0 0 NOP
|
||||
0 1 UPDATE
|
||||
1 0 INSERT
|
||||
1 1 DELETE
|
||||
|
||||
|
||||
***************************************************************************************************/
|
||||
|
||||
include "../gates.circom";
|
||||
include "../bitify.circom";
|
||||
include "../comparators.circom";
|
||||
include "../switcher.circom";
|
||||
include "smtlevins.circom";
|
||||
include "smtprocessorlevel.circom";
|
||||
include "smtprocessorsm.circom";
|
||||
include "smthash_poseidon.circom";
|
||||
|
||||
template SMTProcessor(nLevels) {
|
||||
signal input oldRoot;
|
||||
signal output newRoot;
|
||||
signal input siblings[nLevels];
|
||||
signal input oldKey;
|
||||
signal input oldValue;
|
||||
signal input isOld0;
|
||||
signal input newKey;
|
||||
signal input newValue;
|
||||
signal input fnc[2];
|
||||
|
||||
signal enabled;
|
||||
|
||||
enabled <== fnc[0] + fnc[1] - fnc[0]*fnc[1]
|
||||
|
||||
component hash1Old = SMTHash1();
|
||||
hash1Old.key <== oldKey;
|
||||
hash1Old.value <== oldValue;
|
||||
|
||||
component hash1New = SMTHash1();
|
||||
hash1New.key <== newKey;
|
||||
hash1New.value <== newValue;
|
||||
|
||||
component n2bOld = Num2Bits_strict();
|
||||
component n2bNew = Num2Bits_strict();
|
||||
|
||||
n2bOld.in <== oldKey;
|
||||
n2bNew.in <== newKey;
|
||||
|
||||
component smtLevIns = SMTLevIns(nLevels);
|
||||
for (var i=0; i<nLevels; i++) smtLevIns.siblings[i] <== siblings[i];
|
||||
smtLevIns.enabled <== enabled;
|
||||
|
||||
component xors[nLevels];
|
||||
for (var i=0; i<nLevels; i++) {
|
||||
xors[i] = XOR();
|
||||
xors[i].a <== n2bOld.out[i];
|
||||
xors[i].b <== n2bNew.out[i];
|
||||
}
|
||||
|
||||
component sm[nLevels];
|
||||
for (var i=0; i<nLevels; i++) {
|
||||
sm[i] = SMTProcessorSM();
|
||||
if (i==0) {
|
||||
sm[i].prev_top <== enabled;
|
||||
sm[i].prev_old0 <== 0;
|
||||
sm[i].prev_bot <== 0;
|
||||
sm[i].prev_new1 <== 0;
|
||||
sm[i].prev_na <== 1-enabled;
|
||||
sm[i].prev_upd <== 0;
|
||||
} else {
|
||||
sm[i].prev_top <== sm[i-1].st_top;
|
||||
sm[i].prev_old0 <== sm[i-1].st_old0;
|
||||
sm[i].prev_bot <== sm[i-1].st_bot;
|
||||
sm[i].prev_new1 <== sm[i-1].st_new1;
|
||||
sm[i].prev_na <== sm[i-1].st_na;
|
||||
sm[i].prev_upd <== sm[i-1].st_upd;
|
||||
}
|
||||
sm[i].is0 <== isOld0;
|
||||
sm[i].xor <== xors[i].out;
|
||||
sm[i].fnc[0] <== fnc[0];
|
||||
sm[i].fnc[1] <== fnc[1];
|
||||
sm[i].levIns <== smtLevIns.levIns[i];
|
||||
}
|
||||
sm[nLevels-1].st_na + sm[nLevels-1].st_new1 + sm[nLevels-1].st_old0 +sm[nLevels-1].st_upd === 1;
|
||||
|
||||
component levels[nLevels];
|
||||
for (var i=nLevels-1; i != -1; i--) {
|
||||
levels[i] = SMTProcessorLevel();
|
||||
|
||||
levels[i].st_top <== sm[i].st_top;
|
||||
levels[i].st_old0 <== sm[i].st_old0;
|
||||
levels[i].st_bot <== sm[i].st_bot;
|
||||
levels[i].st_new1 <== sm[i].st_new1;
|
||||
levels[i].st_na <== sm[i].st_na;
|
||||
levels[i].st_upd <== sm[i].st_upd;
|
||||
|
||||
levels[i].sibling <== siblings[i];
|
||||
levels[i].old1leaf <== hash1Old.out;
|
||||
levels[i].new1leaf <== hash1New.out;
|
||||
|
||||
levels[i].newlrbit <== n2bNew.out[i];
|
||||
if (i==nLevels-1) {
|
||||
levels[i].oldChild <== 0;
|
||||
levels[i].newChild <== 0;
|
||||
} else {
|
||||
levels[i].oldChild <== levels[i+1].oldRoot;
|
||||
levels[i].newChild <== levels[i+1].newRoot;
|
||||
}
|
||||
}
|
||||
|
||||
component topSwitcher = Switcher();
|
||||
|
||||
topSwitcher.sel <== fnc[0]*fnc[1];
|
||||
topSwitcher.L <== levels[0].oldRoot;
|
||||
topSwitcher.R <== levels[0].newRoot;
|
||||
|
||||
component checkOldInput = ForceEqualIfEnabled();
|
||||
checkOldInput.enabled <== enabled;
|
||||
checkOldInput.in[0] <== oldRoot;
|
||||
checkOldInput.in[1] <== topSwitcher.outL;
|
||||
|
||||
newRoot <== enabled * (topSwitcher.outR - oldRoot) + oldRoot;
|
||||
|
||||
// topSwitcher.outL === oldRoot*enabled;
|
||||
// topSwitcher.outR === newRoot*enabled;
|
||||
|
||||
// Ckeck keys are equal if updating
|
||||
component areKeyEquals = IsEqual();
|
||||
areKeyEquals.in[0] <== oldKey;
|
||||
areKeyEquals.in[1] <== newKey;
|
||||
|
||||
component keysOk = MultiAND(3);
|
||||
keysOk.in[0] <== 1-fnc[0];
|
||||
keysOk.in[1] <== fnc[1];
|
||||
keysOk.in[2] <== 1-areKeyEquals.out;
|
||||
|
||||
keysOk.out === 0;
|
||||
}
|
||||
@ -1,94 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/******
|
||||
|
||||
SMTProcessorLevel
|
||||
|
||||
This circuit has 2 hash
|
||||
|
||||
Outputs according to the state.
|
||||
|
||||
State oldRoot newRoot
|
||||
===== ======= =======
|
||||
top H'(oldChild, sibling) H'(newChild, sibling)
|
||||
old0 0 new1leaf
|
||||
bot old1leaf H'(newChild, 0)
|
||||
new1 old1leaf H'(new1leaf, old1leaf)
|
||||
na 0 0
|
||||
|
||||
upd old1leaf new1leaf
|
||||
|
||||
H' is the Hash function with the inputs shifted acordingly.
|
||||
|
||||
*****/
|
||||
|
||||
|
||||
template SMTProcessorLevel() {
|
||||
signal input st_top;
|
||||
signal input st_old0;
|
||||
signal input st_bot;
|
||||
signal input st_new1;
|
||||
signal input st_na;
|
||||
signal input st_upd;
|
||||
|
||||
signal output oldRoot;
|
||||
signal output newRoot;
|
||||
signal input sibling;
|
||||
signal input old1leaf;
|
||||
signal input new1leaf;
|
||||
signal input newlrbit;
|
||||
signal input oldChild;
|
||||
signal input newChild;
|
||||
|
||||
signal aux[4];
|
||||
|
||||
component oldProofHash = SMTHash2();
|
||||
component newProofHash = SMTHash2();
|
||||
|
||||
component oldSwitcher = Switcher();
|
||||
component newSwitcher = Switcher();
|
||||
|
||||
// Old side
|
||||
|
||||
oldSwitcher.L <== oldChild;
|
||||
oldSwitcher.R <== sibling;
|
||||
|
||||
oldSwitcher.sel <== newlrbit;
|
||||
oldProofHash.L <== oldSwitcher.outL;
|
||||
oldProofHash.R <== oldSwitcher.outR;
|
||||
|
||||
aux[0] <== old1leaf * (st_bot + st_new1 + st_upd);
|
||||
oldRoot <== aux[0] + oldProofHash.out * st_top;
|
||||
|
||||
// New side
|
||||
|
||||
aux[1] <== newChild * ( st_top + st_bot);
|
||||
newSwitcher.L <== aux[1] + new1leaf*st_new1;
|
||||
|
||||
aux[2] <== sibling*st_top;
|
||||
newSwitcher.R <== aux[2] + old1leaf*st_new1;
|
||||
|
||||
newSwitcher.sel <== newlrbit;
|
||||
newProofHash.L <== newSwitcher.outL;
|
||||
newProofHash.R <== newSwitcher.outR;
|
||||
|
||||
aux[3] <== newProofHash.out * (st_top + st_bot + st_new1);
|
||||
newRoot <== aux[3] + new1leaf * (st_old0 + st_upd);
|
||||
}
|
||||
@ -1,164 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/***************************************************************************************************
|
||||
Each level on a SMTProcessor has a state.
|
||||
|
||||
The state of the level depends on the state of te botom level and on `xor` and
|
||||
`is0` signals.
|
||||
|
||||
`isOldLev` 1 when is the level where oldLeaf is.
|
||||
|
||||
`xor` signal is 0 if the index bit at the current level is the same in the old
|
||||
and the new index, and 1 if it is different.
|
||||
|
||||
`is0` signal, is 1 if we are inserting/deleting in an empty leaf and 0 if we
|
||||
are inserting/deleting in a leaf that contains an element.
|
||||
|
||||
The states are:
|
||||
|
||||
top: While the index bits of the old and new insex in the top level is the same, whe are in the top state.
|
||||
old0: When the we reach insert level, we go to old0 state
|
||||
if `is0`=1.
|
||||
btn: Once in insert level and `is0` =0 we go to btn or new1 level if xor=1
|
||||
new1: This level is reached when xor=1. Here is where we insert/delete the hash of the
|
||||
old and the new trees with just one element.
|
||||
na: Not appliable. After processing it, we go to the na level.
|
||||
|
||||
|
||||
Fnction
|
||||
fnc[0] fnc[1]
|
||||
0 0 NOP
|
||||
0 1 UPDATE
|
||||
1 0 INSERT
|
||||
1 1 DELETE
|
||||
|
||||
|
||||
###########
|
||||
# #
|
||||
┌────────────────────────────▶# upd #─────────────────────┐
|
||||
│ ## ## │
|
||||
│ ######### │
|
||||
levIns=1 │ │
|
||||
fnc[0]=0 │ │ any
|
||||
│ │
|
||||
│ │
|
||||
│ │
|
||||
│ ########### │
|
||||
│ levIns=1 # # │
|
||||
levIns=0 │ is0=1 ┌────────────▶# old0 #────────┐ │ any
|
||||
┌─────┐ │ fnc[0]=1│ ## ## │ │ ┌──────┐
|
||||
│ │ │ │ ######### │ any │ │ │
|
||||
│ ▼ │ │ │ ▼ ▼ │
|
||||
│ ########### │ │ ########### │
|
||||
│ # # ────────────┘ └────────▶# #│
|
||||
└──# top # # na #
|
||||
## ## ───────────────────┐ levIns=1 ┌──▶## ##
|
||||
######### │ is0=0 │ #########
|
||||
│ │ fnc[0]=1 │
|
||||
│ │ xor=1 ########### │ any
|
||||
│ └──────────────────▶# # │
|
||||
│ # new1 #──┘
|
||||
│ ## ##
|
||||
└────────────────────────────────┐ #########
|
||||
levIns=1 │ ▲
|
||||
is0=0 │ ┌─────┘
|
||||
fnc[0]=1 │ ###########│ xor=1
|
||||
xor=0 │ # #
|
||||
▼# btn #
|
||||
## ##
|
||||
#########◀───────┐
|
||||
│ │
|
||||
│ │
|
||||
└────────────┘
|
||||
xor=0
|
||||
|
||||
***************************************************************************************************/
|
||||
|
||||
template SMTProcessorSM() {
|
||||
signal input xor;
|
||||
signal input is0;
|
||||
signal input levIns;
|
||||
signal input fnc[2];
|
||||
|
||||
signal input prev_top;
|
||||
signal input prev_old0;
|
||||
signal input prev_bot;
|
||||
signal input prev_new1;
|
||||
signal input prev_na;
|
||||
signal input prev_upd;
|
||||
|
||||
signal output st_top;
|
||||
signal output st_old0;
|
||||
signal output st_bot;
|
||||
signal output st_new1;
|
||||
signal output st_na;
|
||||
signal output st_upd;
|
||||
|
||||
signal aux1;
|
||||
signal aux2;
|
||||
|
||||
aux1 <== prev_top * levIns;
|
||||
aux2 <== aux1*fnc[0]; // prev_top * levIns * fnc[0]
|
||||
|
||||
// st_top = prev_top*(1-levIns)
|
||||
// = + prev_top
|
||||
// - prev_top * levIns = aux1
|
||||
|
||||
st_top <== prev_top - aux1;
|
||||
|
||||
// st_old0 = prev_top * levIns * is0 * fnc[0]
|
||||
// = + prev_top * levIns * is0 * fnc[0] = aux2 * is0
|
||||
|
||||
st_old0 <== aux2 * is0; // prev_top * levIns * is0 * fnc[0]
|
||||
|
||||
// st_new1 = prev_top * levIns * (1-is0)*fnc[0] * xor + prev_bot*xor =
|
||||
// = + prev_top * levIns * fnc[0] * xor = aux2 * xor
|
||||
// - prev_top * levIns * is0 * fnc[0] * xor = st_old0 * xor
|
||||
// + prev_bot * xor = prev_bot * xor
|
||||
|
||||
st_new1 <== (aux2 - st_old0 + prev_bot)*xor;
|
||||
|
||||
|
||||
// st_bot = prev_top * levIns * (1-is0)*fnc[0] * (1-xor) + prev_bot*(1-xor);
|
||||
// = + prev_top * levIns * fnc[0]
|
||||
// - prev_top * levIns * is0 * fnc[0]
|
||||
// - prev_top * levIns * fnc[0] * xor
|
||||
// + prev_top * levIns * is0 * fnc[0] * xor
|
||||
// + prev_bot
|
||||
// - prev_bot * xor
|
||||
|
||||
st_bot <== (1-xor) * (aux2 - st_old0 + prev_bot)
|
||||
|
||||
|
||||
// st_upd = prev_top * (1-fnc[0]) *levIns;
|
||||
// = + prev_top * levIns
|
||||
// - prev_top * levIns * fnc[0]
|
||||
|
||||
st_upd <== aux1 - aux2
|
||||
|
||||
// st_na = prev_new1 + prev_old0 + prev_na + prev_upd;
|
||||
// = + prev_new1
|
||||
// + prev_old0
|
||||
// + prev_na
|
||||
// + prev_upd
|
||||
|
||||
st_na <== prev_new1 + prev_old0 + prev_na + prev_upd;
|
||||
|
||||
}
|
||||
@ -1,135 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
SMTVerifier is a component to verify inclusion/exclusion of an element in the tree
|
||||
|
||||
|
||||
fnc: 0 -> VERIFY INCLUSION
|
||||
1 -> VERIFY NOT INCLUSION
|
||||
|
||||
*/
|
||||
|
||||
|
||||
include "../gates.circom";
|
||||
include "../bitify.circom";
|
||||
include "../comparators.circom";
|
||||
include "../switcher.circom";
|
||||
include "smtlevins.circom";
|
||||
include "smtverifierlevel.circom";
|
||||
include "smtverifiersm.circom";
|
||||
include "smthash_poseidon.circom";
|
||||
|
||||
template SMTVerifier(nLevels) {
|
||||
signal input enabled;
|
||||
signal input root;
|
||||
signal input siblings[nLevels];
|
||||
signal input oldKey;
|
||||
signal input oldValue;
|
||||
signal input isOld0;
|
||||
signal input key;
|
||||
signal input value;
|
||||
signal input fnc;
|
||||
|
||||
component hash1Old = SMTHash1();
|
||||
hash1Old.key <== oldKey;
|
||||
hash1Old.value <== oldValue;
|
||||
|
||||
component hash1New = SMTHash1();
|
||||
hash1New.key <== key;
|
||||
hash1New.value <== value;
|
||||
|
||||
component n2bOld = Num2Bits_strict();
|
||||
component n2bNew = Num2Bits_strict();
|
||||
|
||||
n2bOld.in <== oldKey;
|
||||
n2bNew.in <== key;
|
||||
|
||||
component smtLevIns = SMTLevIns(nLevels);
|
||||
for (var i=0; i<nLevels; i++) smtLevIns.siblings[i] <== siblings[i];
|
||||
smtLevIns.enabled <== enabled;
|
||||
|
||||
component sm[nLevels];
|
||||
for (var i=0; i<nLevels; i++) {
|
||||
sm[i] = SMTVerifierSM();
|
||||
if (i==0) {
|
||||
sm[i].prev_top <== enabled;
|
||||
sm[i].prev_i0 <== 0;
|
||||
sm[i].prev_inew <== 0;
|
||||
sm[i].prev_iold <== 0;
|
||||
sm[i].prev_na <== 1-enabled;
|
||||
} else {
|
||||
sm[i].prev_top <== sm[i-1].st_top;
|
||||
sm[i].prev_i0 <== sm[i-1].st_i0;
|
||||
sm[i].prev_inew <== sm[i-1].st_inew;
|
||||
sm[i].prev_iold <== sm[i-1].st_iold;
|
||||
sm[i].prev_na <== sm[i-1].st_na;
|
||||
}
|
||||
sm[i].is0 <== isOld0;
|
||||
sm[i].fnc <== fnc;
|
||||
sm[i].levIns <== smtLevIns.levIns[i];
|
||||
}
|
||||
sm[nLevels-1].st_na + sm[nLevels-1].st_iold + sm[nLevels-1].st_inew + sm[nLevels-1].st_i0 === 1;
|
||||
|
||||
component levels[nLevels];
|
||||
for (var i=nLevels-1; i != -1; i--) {
|
||||
levels[i] = SMTVerifierLevel();
|
||||
|
||||
levels[i].st_top <== sm[i].st_top;
|
||||
levels[i].st_i0 <== sm[i].st_i0;
|
||||
levels[i].st_inew <== sm[i].st_inew;
|
||||
levels[i].st_iold <== sm[i].st_iold;
|
||||
levels[i].st_na <== sm[i].st_na;
|
||||
|
||||
levels[i].sibling <== siblings[i];
|
||||
levels[i].old1leaf <== hash1Old.out;
|
||||
levels[i].new1leaf <== hash1New.out;
|
||||
|
||||
levels[i].lrbit <== n2bNew.out[i];
|
||||
if (i==nLevels-1) {
|
||||
levels[i].child <== 0;
|
||||
} else {
|
||||
levels[i].child <== levels[i+1].root;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check that if checking for non inclussuin and isOld0==0 then key!=old
|
||||
component areKeyEquals = IsEqual();
|
||||
areKeyEquals.in[0] <== oldKey;
|
||||
areKeyEquals.in[1] <== key;
|
||||
|
||||
component keysOk = MultiAND(4);
|
||||
keysOk.in[0] <== fnc;
|
||||
keysOk.in[1] <== 1-isOld0;
|
||||
keysOk.in[2] <== areKeyEquals.out;
|
||||
keysOk.in[3] <== enabled;
|
||||
|
||||
keysOk.out === 0;
|
||||
|
||||
// Check the root
|
||||
component checkRoot = ForceEqualIfEnabled();
|
||||
checkRoot.enabled <== enabled;
|
||||
checkRoot.in[0] <== levels[0].root;
|
||||
checkRoot.in[1] <== root;
|
||||
|
||||
// levels[0].root === root;
|
||||
|
||||
}
|
||||
@ -1,71 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/******
|
||||
|
||||
SMTVerifierLevel
|
||||
|
||||
This circuit has 1 hash
|
||||
|
||||
Outputs according to the state.
|
||||
|
||||
State root
|
||||
===== =======
|
||||
top H'(child, sibling)
|
||||
i0 0
|
||||
iold old1leaf
|
||||
inew new1leaf
|
||||
na 0
|
||||
|
||||
H' is the Hash function with the inputs shifted acordingly.
|
||||
|
||||
*****/
|
||||
|
||||
|
||||
template SMTVerifierLevel() {
|
||||
signal input st_top;
|
||||
signal input st_i0;
|
||||
signal input st_iold;
|
||||
signal input st_inew;
|
||||
signal input st_na;
|
||||
|
||||
signal output root;
|
||||
signal input sibling;
|
||||
signal input old1leaf;
|
||||
signal input new1leaf;
|
||||
signal input lrbit;
|
||||
signal input child;
|
||||
|
||||
signal aux[2];
|
||||
|
||||
component proofHash = SMTHash2();
|
||||
component switcher = Switcher();
|
||||
|
||||
switcher.L <== child;
|
||||
switcher.R <== sibling;
|
||||
|
||||
switcher.sel <== lrbit;
|
||||
proofHash.L <== switcher.outL;
|
||||
proofHash.R <== switcher.outR;
|
||||
|
||||
aux[0] <== proofHash.out * st_top;
|
||||
aux[1] <== old1leaf*st_iold;
|
||||
|
||||
root <== aux[0] + aux[1] + new1leaf*st_inew;
|
||||
}
|
||||
@ -1,105 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
Each level in the SMTVerifier has a state.
|
||||
|
||||
This is the state machine.
|
||||
|
||||
The signals are
|
||||
|
||||
levIns: 1 if we are in the level where the insertion should happen
|
||||
xor: 1 if the bitKey of the old and new keys are different in this level
|
||||
is0: Input that indicates that the oldKey is 0
|
||||
fnc: 0 -> VERIFY INCLUSION
|
||||
1 -> VERIFY NOT INCLUSION
|
||||
|
||||
err state is not a state itself. It's a lack of state.
|
||||
|
||||
The end of the last level will have to be `na`
|
||||
|
||||
levIns=0 any
|
||||
┌────┐ ┌────┐
|
||||
│ │ │ │
|
||||
│ ▼ levIns=1 ▼ │
|
||||
│ ########### is0=1 ########### ########### │
|
||||
│ # # fnc=1 # # any # # │
|
||||
└──# top # ─────────────────────▶# i0 #───────────────▶# na #──┘
|
||||
## ## ──────────┐ ## ## ┌───────▶## ##
|
||||
########─────────────┐│ ######### │┌────────▶#########
|
||||
││ levIns=1 ││
|
||||
││ is0=0 ########### ││
|
||||
││ fnc=1 # # any│
|
||||
│└──────────▶ # iold #────────┘│
|
||||
│ ## ## │
|
||||
│ ######### │
|
||||
│ │
|
||||
│ levIns=1 ########### │
|
||||
│ fnc=0 # # any
|
||||
└────────────▶# inew #─────────┘
|
||||
## ##
|
||||
#########
|
||||
|
||||
*/
|
||||
|
||||
|
||||
template SMTVerifierSM() {
|
||||
signal input is0;
|
||||
signal input levIns;
|
||||
signal input fnc;
|
||||
|
||||
signal input prev_top;
|
||||
signal input prev_i0;
|
||||
signal input prev_iold;
|
||||
signal input prev_inew;
|
||||
signal input prev_na;
|
||||
|
||||
signal output st_top;
|
||||
signal output st_i0;
|
||||
signal output st_iold;
|
||||
signal output st_inew;
|
||||
signal output st_na;
|
||||
|
||||
signal prev_top_lev_ins;
|
||||
signal prev_top_lev_ins_fnc;
|
||||
|
||||
prev_top_lev_ins <== prev_top * levIns;
|
||||
prev_top_lev_ins_fnc <== prev_top_lev_ins*fnc; // prev_top * levIns * fnc
|
||||
|
||||
// st_top = prev_top * (1-levIns)
|
||||
// = + prev_top
|
||||
// - prev_top * levIns
|
||||
st_top <== prev_top - prev_top_lev_ins;
|
||||
|
||||
// st_inew = prev_top * levIns * (1-fnc)
|
||||
// = + prev_top * levIns
|
||||
// - prev_top * levIns * fnc
|
||||
st_inew <== prev_top_lev_ins - prev_top_lev_ins_fnc;
|
||||
|
||||
// st_iold = prev_top * levIns * (1-is0)*fnc
|
||||
// = + prev_top * levIns * fnc
|
||||
// - prev_top * levIns * fnc * is0
|
||||
st_iold <== prev_top_lev_ins_fnc * (1 - is0);
|
||||
|
||||
// st_i0 = prev_top * levIns * is0
|
||||
// = + prev_top * levIns * is0
|
||||
st_i0 <== prev_top_lev_ins * is0;
|
||||
|
||||
st_na <== prev_na + prev_inew + prev_iold + prev_i0;
|
||||
}
|
||||
@ -1,40 +0,0 @@
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
|
||||
circom is a free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
circom is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
Assume sel is binary.
|
||||
|
||||
If sel == 0 then outL = L and outR=R
|
||||
If sel == 1 then outL = R and outR=L
|
||||
|
||||
*/
|
||||
|
||||
template Switcher() {
|
||||
signal input sel;
|
||||
signal input L;
|
||||
signal input R;
|
||||
signal output outL;
|
||||
signal output outR;
|
||||
|
||||
signal aux;
|
||||
|
||||
aux <== (R-L)*sel; // We create aux in order to have only one multiplication
|
||||
outL <== aux + L;
|
||||
outR <== -aux + R;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
9
index.js
9
index.js
@ -1,9 +0,0 @@
|
||||
exports.smt = require("./src/smt");
|
||||
exports.eddsa = require("./src/eddsa");
|
||||
exports.mimc7 = require("./src/mimc7");
|
||||
exports.mimcsponge = require("./src/mimcsponge");
|
||||
exports.babyJub = require("./src/babyjub");
|
||||
exports.pedersenHash = require("./src/pedersenHash");
|
||||
exports.SMT = require("./src/smt").SMT;
|
||||
exports.SMTMemDB = require("./src/smt_memdb");
|
||||
exports.poseidon = require("./src/poseidon");
|
||||
3657
package-lock.json
generated
3657
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
66
package.json
66
package.json
@ -1,39 +1,31 @@
|
||||
{
|
||||
"name": "@tornado/circomlib",
|
||||
"version": "0.0.21",
|
||||
"description": "Basic circuits library for Circom",
|
||||
"main": "index.js",
|
||||
"directories": {
|
||||
"test": "test"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha --max-old-space-size=4000"
|
||||
},
|
||||
"keywords": [
|
||||
"pedersen",
|
||||
"hash",
|
||||
"ethereum",
|
||||
"circuit",
|
||||
"circom",
|
||||
"zksnark"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://git.tornado.ws/tornado-packages/circomlib.git"
|
||||
},
|
||||
"author": "0Kims",
|
||||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
"blake-hash": "^1.1.0",
|
||||
"blake2b": "^2.1.3",
|
||||
"@tornado/snarkjs": "0.1.20",
|
||||
"typedarray-to-buffer": "^3.1.5",
|
||||
"web3": "^1.2.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"circom": "0.0.35",
|
||||
"eslint-plugin-mocha": "^5.2.0",
|
||||
"ganache-cli": "^6.4.4",
|
||||
"mocha": "^5.2.0"
|
||||
}
|
||||
"name": "cirpedersen",
|
||||
"version": "0.0.3",
|
||||
"description": "Pesersen Circuit for Circom",
|
||||
"main": "index.js",
|
||||
"directories": {
|
||||
"test": "test"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"keywords": [
|
||||
"pedersen",
|
||||
"hash",
|
||||
"ethereum",
|
||||
"circuit",
|
||||
"circom",
|
||||
"zksnark"
|
||||
],
|
||||
"author": "Jordi Baylina",
|
||||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
"blake-hash": "^1.1.0",
|
||||
"circom": "0.0.21",
|
||||
"snarkjs": "0.1.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint-plugin-mocha": "^5.2.0",
|
||||
"mocha": "^5.2.0"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
const bn128 = require("@tornado/snarkjs").bn128;
|
||||
const bigInt = require("@tornado/snarkjs").bigInt;
|
||||
const bn128 = require("snarkjs").bn128;
|
||||
const bigInt = require("snarkjs").bigInt;
|
||||
|
||||
exports.addPoint = addPoint;
|
||||
exports.mulPointEscalar = mulPointEscalar;
|
||||
@ -7,51 +7,32 @@ exports.inCurve = inCurve;
|
||||
exports.inSubgroup = inSubgroup;
|
||||
exports.packPoint = packPoint;
|
||||
exports.unpackPoint = unpackPoint;
|
||||
exports.Generator = [
|
||||
bigInt("995203441582195749578291179787384436505546430278305826713579947235728471134"),
|
||||
bigInt("5472060717959818805561601436314318772137091100104008585924551046643952123905"),
|
||||
];
|
||||
exports.Base8 = [
|
||||
bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
||||
bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203"),
|
||||
bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
|
||||
bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475")
|
||||
];
|
||||
exports.order = bigInt("21888242871839275222246405745257275088614511777268538073601725287587578984328");
|
||||
exports.subOrder = exports.order.shr(3);
|
||||
exports.p = bn128.r;
|
||||
exports.A = bigInt("168700");
|
||||
exports.D = bigInt("168696");
|
||||
|
||||
function addPoint(a, b) {
|
||||
|
||||
function addPoint(a,b) {
|
||||
const q = bn128.r;
|
||||
const cta = bigInt("168700");
|
||||
const d = bigInt("168696");
|
||||
|
||||
const res = [];
|
||||
|
||||
/* does the equivalent of:
|
||||
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[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);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
function mulPointEscalar(base, e) {
|
||||
let res = [bigInt("0"), bigInt("1")];
|
||||
let res = [bigInt("0"),bigInt("1")];
|
||||
let rem = bigInt(e);
|
||||
let exp = base;
|
||||
|
||||
while (!rem.isZero()) {
|
||||
while (! rem.isZero()) {
|
||||
if (rem.isOdd()) {
|
||||
res = addPoint(res, exp);
|
||||
}
|
||||
@ -64,17 +45,22 @@ function mulPointEscalar(base, e) {
|
||||
|
||||
function inSubgroup(P) {
|
||||
if (!inCurve(P)) return false;
|
||||
const res = mulPointEscalar(P, exports.subOrder);
|
||||
return res[0].equals(bigInt(0)) && res[1].equals(bigInt(1));
|
||||
const res= mulPointEscalar(P, exports.subOrder);
|
||||
return (res[0].equals(bigInt(0))) && (res[1].equals(bigInt(1)));
|
||||
}
|
||||
|
||||
function inCurve(P) {
|
||||
const F = bn128.Fr;
|
||||
|
||||
const a = bigInt("168700");
|
||||
const d = bigInt("168696");
|
||||
|
||||
const x2 = F.square(P[0]);
|
||||
const y2 = F.square(P[1]);
|
||||
|
||||
if (!F.equals(F.add(F.mul(exports.A, x2), y2), F.add(F.one, F.mul(F.mul(x2, y2), exports.D)))) return false;
|
||||
if (!F.equals(
|
||||
F.add(F.mul(a, x2), y2),
|
||||
F.add(F.one, F.mul(F.mul(x2, y2), d)))) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -95,14 +81,19 @@ function unpackPoint(_buff) {
|
||||
const P = new Array(2);
|
||||
if (buff[31] & 0x80) {
|
||||
sign = true;
|
||||
buff[31] = buff[31] & 0x7f;
|
||||
buff[31] = buff[31] & 0x7F;
|
||||
}
|
||||
P[1] = bigInt.leBuff2int(buff);
|
||||
if (P[1].greaterOrEquals(exports.p)) return null;
|
||||
|
||||
const a = bigInt("168700");
|
||||
const d = bigInt("168696");
|
||||
|
||||
const y2 = F.square(P[1]);
|
||||
|
||||
let x = F.sqrt(F.div(F.sub(F.one, y2), F.sub(exports.A, F.mul(exports.D, y2))));
|
||||
let x = F.sqrt(F.div(
|
||||
F.sub(F.one, y2),
|
||||
F.sub(a, F.mul(d, y2))));
|
||||
|
||||
if (x == null) return null;
|
||||
|
||||
|
||||
176
src/eddsa.js
176
src/eddsa.js
@ -1,34 +1,31 @@
|
||||
const createBlakeHash = require("blake-hash");
|
||||
const bigInt = require("@tornado/snarkjs").bigInt;
|
||||
const bigInt = require("snarkjs").bigInt;
|
||||
const babyJub = require("./babyjub");
|
||||
const pedersenHash = require("./pedersenHash").hash;
|
||||
const mimc7 = require("./mimc7");
|
||||
const poseidon = require("./poseidon.js");
|
||||
const mimcsponge = require("./mimcsponge");
|
||||
const crypto = require("crypto");
|
||||
|
||||
exports.prv2pub = prv2pub;
|
||||
exports.cratePrvKey = cratePrvKey;
|
||||
exports.prv2pub= prv2pub;
|
||||
exports.sign = sign;
|
||||
exports.signMiMC = signMiMC;
|
||||
exports.signPoseidon = signPoseidon;
|
||||
exports.signMiMCSponge = signMiMCSponge;
|
||||
exports.verify = verify;
|
||||
exports.verifyMiMC = verifyMiMC;
|
||||
exports.verifyPoseidon = verifyPoseidon;
|
||||
exports.verifyMiMCSponge = verifyMiMCSponge;
|
||||
exports.packSignature = packSignature;
|
||||
exports.unpackSignature = unpackSignature;
|
||||
exports.pruneBuffer = pruneBuffer;
|
||||
|
||||
|
||||
function cratePrvKey() {
|
||||
return crypto.randomBytes(32);
|
||||
}
|
||||
|
||||
function pruneBuffer(_buff) {
|
||||
const buff = Buffer.from(_buff);
|
||||
buff[0] = buff[0] & 0xf8;
|
||||
buff[31] = buff[31] & 0x7f;
|
||||
buff[0] = buff[0] & 0xF8;
|
||||
buff[31] = buff[31] & 0x7F;
|
||||
buff[31] = buff[31] | 0x40;
|
||||
return buff;
|
||||
}
|
||||
|
||||
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);
|
||||
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
|
||||
return A;
|
||||
@ -36,13 +33,11 @@ function prv2pub(prv) {
|
||||
|
||||
function sign(prv, msg) {
|
||||
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 A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(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);
|
||||
r = r.mod(babyJub.subOrder);
|
||||
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
|
||||
@ -53,70 +48,7 @@ function sign(prv, msg) {
|
||||
const S = r.add(hm.mul(s)).mod(babyJub.subOrder);
|
||||
return {
|
||||
R8: R8,
|
||||
S: S,
|
||||
};
|
||||
}
|
||||
|
||||
function signMiMC(prv, msg) {
|
||||
const h1 = createBlakeHash("blake512").update(prv).digest();
|
||||
const sBuff = pruneBuffer(h1.slice(0, 32));
|
||||
const s = bigInt.leBuff2int(sBuff);
|
||||
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
|
||||
|
||||
const msgBuff = bigInt.leInt2Buff(msg, 32);
|
||||
const rBuff = createBlakeHash("blake512")
|
||||
.update(Buffer.concat([h1.slice(32, 64), msgBuff]))
|
||||
.digest();
|
||||
let r = bigInt.leBuff2int(rBuff);
|
||||
r = r.mod(babyJub.subOrder);
|
||||
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
|
||||
const hm = mimc7.multiHash([R8[0], R8[1], A[0], A[1], msg]);
|
||||
const S = r.add(hm.mul(s)).mod(babyJub.subOrder);
|
||||
return {
|
||||
R8: R8,
|
||||
S: S,
|
||||
};
|
||||
}
|
||||
|
||||
function signMiMCSponge(prv, msg) {
|
||||
const h1 = createBlakeHash("blake512").update(prv).digest();
|
||||
const sBuff = pruneBuffer(h1.slice(0, 32));
|
||||
const s = bigInt.leBuff2int(sBuff);
|
||||
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
|
||||
|
||||
const msgBuff = bigInt.leInt2Buff(msg, 32);
|
||||
const rBuff = createBlakeHash("blake512")
|
||||
.update(Buffer.concat([h1.slice(32, 64), msgBuff]))
|
||||
.digest();
|
||||
let r = bigInt.leBuff2int(rBuff);
|
||||
r = r.mod(babyJub.subOrder);
|
||||
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
|
||||
const hm = mimcsponge.multiHash([R8[0], R8[1], A[0], A[1], msg]);
|
||||
const S = r.add(hm.mul(s)).mod(babyJub.subOrder);
|
||||
return {
|
||||
R8: R8,
|
||||
S: S,
|
||||
};
|
||||
}
|
||||
|
||||
function signPoseidon(prv, msg) {
|
||||
const h1 = createBlakeHash("blake512").update(prv).digest();
|
||||
const sBuff = pruneBuffer(h1.slice(0, 32));
|
||||
const s = bigInt.leBuff2int(sBuff);
|
||||
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
|
||||
|
||||
const msgBuff = bigInt.leInt2Buff(msg, 32);
|
||||
const rBuff = createBlakeHash("blake512")
|
||||
.update(Buffer.concat([h1.slice(32, 64), msgBuff]))
|
||||
.digest();
|
||||
let r = bigInt.leBuff2int(rBuff);
|
||||
r = r.mod(babyJub.subOrder);
|
||||
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
|
||||
const hm = poseidon([R8[0], R8[1], A[0], A[1], msg]);
|
||||
const S = r.add(hm.mul(s)).mod(babyJub.subOrder);
|
||||
return {
|
||||
R8: R8,
|
||||
S: S,
|
||||
S: S
|
||||
};
|
||||
}
|
||||
|
||||
@ -124,12 +56,12 @@ function verify(msg, sig, A) {
|
||||
// Check parameters
|
||||
if (typeof sig != "object") return false;
|
||||
if (!Array.isArray(sig.R8)) return false;
|
||||
if (sig.R8.length != 2) return false;
|
||||
if (sig.R8.length!= 2) return false;
|
||||
if (!babyJub.inCurve(sig.R8)) return false;
|
||||
if (!Array.isArray(A)) return false;
|
||||
if (A.length != 2) return false;
|
||||
if (A.length!= 2) return false;
|
||||
if (!babyJub.inCurve(A)) return false;
|
||||
if (sig.S >= babyJub.subOrder) return false;
|
||||
if (sig.S>= babyJub.subOrder) return false;
|
||||
|
||||
const R8p = babyJub.packPoint(sig.R8);
|
||||
const Ap = babyJub.packPoint(A);
|
||||
@ -145,72 +77,6 @@ function verify(msg, sig, A) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function verifyMiMC(msg, sig, A) {
|
||||
// Check parameters
|
||||
if (typeof sig != "object") return false;
|
||||
if (!Array.isArray(sig.R8)) return false;
|
||||
if (sig.R8.length != 2) return false;
|
||||
if (!babyJub.inCurve(sig.R8)) return false;
|
||||
if (!Array.isArray(A)) return false;
|
||||
if (A.length != 2) return false;
|
||||
if (!babyJub.inCurve(A)) return false;
|
||||
if (sig.S >= babyJub.subOrder) return false;
|
||||
|
||||
const hm = mimc7.multiHash([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
|
||||
|
||||
const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
|
||||
let Pright = babyJub.mulPointEscalar(A, hm.mul(bigInt("8")));
|
||||
Pright = babyJub.addPoint(sig.R8, Pright);
|
||||
|
||||
if (!Pleft[0].equals(Pright[0])) return false;
|
||||
if (!Pleft[1].equals(Pright[1])) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function verifyPoseidon(msg, sig, A) {
|
||||
// Check parameters
|
||||
if (typeof sig != "object") return false;
|
||||
if (!Array.isArray(sig.R8)) return false;
|
||||
if (sig.R8.length != 2) return false;
|
||||
if (!babyJub.inCurve(sig.R8)) return false;
|
||||
if (!Array.isArray(A)) return false;
|
||||
if (A.length != 2) return false;
|
||||
if (!babyJub.inCurve(A)) return false;
|
||||
if (sig.S >= babyJub.subOrder) return false;
|
||||
|
||||
const hm = poseidon([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
|
||||
|
||||
const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
|
||||
let Pright = babyJub.mulPointEscalar(A, hm.mul(bigInt("8")));
|
||||
Pright = babyJub.addPoint(sig.R8, Pright);
|
||||
|
||||
if (!Pleft[0].equals(Pright[0])) return false;
|
||||
if (!Pleft[1].equals(Pright[1])) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function verifyMiMCSponge(msg, sig, A) {
|
||||
// Check parameters
|
||||
if (typeof sig != "object") return false;
|
||||
if (!Array.isArray(sig.R8)) return false;
|
||||
if (sig.R8.length != 2) return false;
|
||||
if (!babyJub.inCurve(sig.R8)) return false;
|
||||
if (!Array.isArray(A)) return false;
|
||||
if (A.length != 2) return false;
|
||||
if (!babyJub.inCurve(A)) return false;
|
||||
if (sig.S >= babyJub.subOrder) return false;
|
||||
|
||||
const hm = mimcsponge.multiHash([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
|
||||
|
||||
const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
|
||||
let Pright = babyJub.mulPointEscalar(A, hm.mul(bigInt("8")));
|
||||
Pright = babyJub.addPoint(sig.R8, Pright);
|
||||
|
||||
if (!Pleft[0].equals(Pright[0])) return false;
|
||||
if (!Pleft[1].equals(Pright[1])) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function packSignature(sig) {
|
||||
const R8p = babyJub.packPoint(sig.R8);
|
||||
const Sp = bigInt.leInt2Buff(sig.S, 32);
|
||||
@ -219,7 +85,9 @@ function packSignature(sig) {
|
||||
|
||||
function unpackSignature(sigBuff) {
|
||||
return {
|
||||
R8: babyJub.unpackPoint(sigBuff.slice(0, 32)),
|
||||
S: bigInt.leBuff2int(sigBuff.slice(32, 64)),
|
||||
R8: babyJub.unpackPoint(sigBuff.slice(0,32)),
|
||||
S: bigInt.leBuff2int(sigBuff.slice(32,64))
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
208
src/evmasm.js
208
src/evmasm.js
@ -1,208 +0,0 @@
|
||||
// Copyright (c) 2018 Jordi Baylina
|
||||
// License: LGPL-3.0+
|
||||
//
|
||||
|
||||
|
||||
const Web3Utils = require("web3-utils");
|
||||
|
||||
class Contract {
|
||||
constructor() {
|
||||
this.code = [];
|
||||
this.labels = {};
|
||||
this.pendingLabels = {};
|
||||
}
|
||||
|
||||
createTxData() {
|
||||
let C;
|
||||
|
||||
// Check all labels are defined
|
||||
const pendingLabels = Object.keys(this.pendingLabels);
|
||||
if (pendingLabels.length>0) {
|
||||
throw new Error("Lables not defined: "+ pendingLabels.join(", "));
|
||||
}
|
||||
|
||||
let setLoaderLength = 0;
|
||||
let genLoadedLength = -1;
|
||||
|
||||
while (genLoadedLength!=setLoaderLength) {
|
||||
setLoaderLength = genLoadedLength;
|
||||
C = new module.exports();
|
||||
C.codesize();
|
||||
C.push(setLoaderLength);
|
||||
C.push(0);
|
||||
C.codecopy();
|
||||
|
||||
C.push(this.code.length);
|
||||
C.push(0);
|
||||
C.return();
|
||||
genLoadedLength = C.code.length;
|
||||
}
|
||||
|
||||
return Web3Utils.bytesToHex(C.code.concat(this.code));
|
||||
}
|
||||
|
||||
stop() { this.code.push(0x00); }
|
||||
add() { this.code.push(0x01); }
|
||||
mul() { this.code.push(0x02); }
|
||||
sub() { this.code.push(0x03); }
|
||||
div() { this.code.push(0x04); }
|
||||
sdiv() { this.code.push(0x05); }
|
||||
mod() { this.code.push(0x06); }
|
||||
smod() { this.code.push(0x07); }
|
||||
addmod() { this.code.push(0x08); }
|
||||
mulmod() { this.code.push(0x09); }
|
||||
exp() { this.code.push(0x0a); }
|
||||
signextend() { this.code.push(0x0b); }
|
||||
|
||||
lt() { this.code.push(0x10); }
|
||||
gt() { this.code.push(0x11); }
|
||||
slt() { this.code.push(0x12); }
|
||||
sgt() { this.code.push(0x13); }
|
||||
eq() { this.code.push(0x14); }
|
||||
iszero() { this.code.push(0x15); }
|
||||
and() { this.code.push(0x16); }
|
||||
or() { this.code.push(0x17); }
|
||||
shor() { this.code.push(0x18); }
|
||||
not() { this.code.push(0x19); }
|
||||
byte() { this.code.push(0x1a); }
|
||||
|
||||
keccak() { this.code.push(0x20); }
|
||||
sha3() { this.code.push(0x20); } // alias
|
||||
|
||||
address() { this.code.push(0x30); }
|
||||
balance() { this.code.push(0x31); }
|
||||
origin() { this.code.push(0x32); }
|
||||
caller() { this.code.push(0x33); }
|
||||
callvalue() { this.code.push(0x34); }
|
||||
calldataload() { this.code.push(0x35); }
|
||||
calldatasize() { this.code.push(0x36); }
|
||||
calldatacopy() { this.code.push(0x37); }
|
||||
codesize() { this.code.push(0x38); }
|
||||
codecopy() { this.code.push(0x39); }
|
||||
gasprice() { this.code.push(0x3a); }
|
||||
extcodesize() { this.code.push(0x3b); }
|
||||
extcodecopy() { this.code.push(0x3c); }
|
||||
returndatasize() { this.code.push(0x3d); }
|
||||
returndatacopy() { this.code.push(0x3e); }
|
||||
|
||||
blockhash() { this.code.push(0x40); }
|
||||
coinbase() { this.code.push(0x41); }
|
||||
timestamp() { this.code.push(0x42); }
|
||||
number() { this.code.push(0x43); }
|
||||
difficulty() { this.code.push(0x44); }
|
||||
gaslimit() { this.code.push(0x45); }
|
||||
|
||||
pop() { this.code.push(0x50); }
|
||||
mload() { this.code.push(0x51); }
|
||||
mstore() { this.code.push(0x52); }
|
||||
mstore8() { this.code.push(0x53); }
|
||||
sload() { this.code.push(0x54); }
|
||||
sstore() { this.code.push(0x55); }
|
||||
|
||||
_pushLabel(label) {
|
||||
if (typeof this.labels[label] != "undefined") {
|
||||
this.push(this.labels[label]);
|
||||
} else {
|
||||
this.pendingLabels[label] = this.pendingLabels[label] || [];
|
||||
this.pendingLabels[label].push(this.code.length);
|
||||
this.push("0x000000");
|
||||
}
|
||||
}
|
||||
|
||||
_fillLabel(label) {
|
||||
if (!this.pendingLabels[label]) return;
|
||||
|
||||
let dst = this.labels[label];
|
||||
|
||||
const dst3 = [dst >> 16, (dst >> 8) & 0xFF, dst & 0xFF];
|
||||
|
||||
this.pendingLabels[label].forEach((p) => {
|
||||
for (let i=0; i<3; i++) {
|
||||
this.code[p+i+1] = dst3[i];
|
||||
}
|
||||
});
|
||||
|
||||
delete this.pendingLabels[label];
|
||||
}
|
||||
|
||||
|
||||
jmp(label) {
|
||||
if (typeof label !== "undefined") {
|
||||
this._pushLabel(label);
|
||||
}
|
||||
this.code.push(0x56);
|
||||
}
|
||||
|
||||
jmpi(label) {
|
||||
if (typeof label !== "undefined") {
|
||||
this._pushLabel(label);
|
||||
}
|
||||
this.code.push(0x57);
|
||||
}
|
||||
|
||||
pc() { this.code.push(0x58); }
|
||||
msize() { this.code.push(0x59); }
|
||||
gas() { this.code.push(0x5a); }
|
||||
label(name) {
|
||||
if (typeof this.labels[name] != "undefined") {
|
||||
throw new Error("Label already defined");
|
||||
}
|
||||
this.labels[name] = this.code.length;
|
||||
this.code.push(0x5b);
|
||||
|
||||
this._fillLabel(name);
|
||||
}
|
||||
|
||||
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));
|
||||
if (d.length == 0 || d.length > 32) {
|
||||
throw new Error("Assertion failed");
|
||||
}
|
||||
this.code = this.code.concat([0x5F + d.length], d);
|
||||
}
|
||||
|
||||
dup(n) {
|
||||
if (n < 0 || n >= 16) {
|
||||
throw new Error("Assertion failed");
|
||||
}
|
||||
this.code.push(0x80 + n);
|
||||
}
|
||||
|
||||
swap(n) {
|
||||
if (n < 1 || n > 16) {
|
||||
throw new Error("Assertion failed");
|
||||
}
|
||||
this.code.push(0x8f + n);
|
||||
}
|
||||
|
||||
log0() { this.code.push(0xa0); }
|
||||
log1() { this.code.push(0xa1); }
|
||||
log2() { this.code.push(0xa2); }
|
||||
log3() { this.code.push(0xa3); }
|
||||
log4() { this.code.push(0xa4); }
|
||||
|
||||
create() { this.code.push(0xf0); }
|
||||
call() { this.code.push(0xf1); }
|
||||
callcode() { this.code.push(0xf2); }
|
||||
return() { this.code.push(0xf3); }
|
||||
delegatecall() { this.code.push(0xf4); }
|
||||
|
||||
staticcall() { this.code.push(0xfa); }
|
||||
revert() { this.code.push(0xfd); }
|
||||
invalid() { this.code.push(0xfe); }
|
||||
selfdestruct() { this.code.push(0xff); }
|
||||
}
|
||||
|
||||
module.exports = Contract;
|
||||
|
||||
@ -1,572 +0,0 @@
|
||||
// Copyright (c) 2018 Jordi Baylina
|
||||
// License: LGPL-3.0+
|
||||
//
|
||||
|
||||
const Contract = require("./evmasm");
|
||||
const G2 = require("@tornado/snarkjs").bn128.G2;
|
||||
const bigInt = require("@tornado/snarkjs").bigInt;
|
||||
|
||||
function toHex256(a) {
|
||||
let S = a.toString(16);
|
||||
while (S.length < 64) S = "0" + S;
|
||||
return "0x" + S;
|
||||
}
|
||||
|
||||
function createCode(P, w) {
|
||||
const C = new Contract();
|
||||
|
||||
const NPOINTS = 1 << (w - 1);
|
||||
|
||||
const VAR_POS = C.allocMem(32);
|
||||
const VAR_POINTS = C.allocMem(NPOINTS * 4 * 32);
|
||||
const savedP = C.allocMem(32);
|
||||
const savedZ3 = C.allocMem(32);
|
||||
|
||||
// Check selector
|
||||
C.push("0x0100000000000000000000000000000000000000000000000000000000");
|
||||
C.push(0);
|
||||
C.calldataload();
|
||||
C.div();
|
||||
C.push("b65c7c74"); // mulexp(uint256)
|
||||
C.eq();
|
||||
C.jmpi("start");
|
||||
C.invalid();
|
||||
|
||||
C.label("start");
|
||||
|
||||
storeVals();
|
||||
|
||||
C.push(Math.floor(255 / w) * w); // pos := 255
|
||||
C.push(VAR_POS);
|
||||
C.mstore();
|
||||
|
||||
C.push("21888242871839275222246405745257275088696311157297823662689037894645226208583");
|
||||
C.push(0);
|
||||
C.push(0);
|
||||
C.push(0);
|
||||
C.push(0);
|
||||
C.push(0);
|
||||
C.push(0);
|
||||
|
||||
C.label("begin_loop"); // ACC_X ACC_Y ACC_Z q
|
||||
|
||||
C.internalCall("double");
|
||||
|
||||
// g = (e>>pos)&MASK
|
||||
C.push(4);
|
||||
C.calldataload(); // e ACC_X ACC_Y ACC_Z q
|
||||
|
||||
C.push(VAR_POS);
|
||||
C.mload(); // pos e ACC_X ACC_Y ACC_Z q
|
||||
C.shr();
|
||||
|
||||
C.push(NPOINTS - 1);
|
||||
C.and(); // g ACC_X ACC_Y ACC_Z q
|
||||
|
||||
C.internalCall("add"); // acc_x acc_y acc_z
|
||||
|
||||
C.push(VAR_POS);
|
||||
C.mload(); // 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.eq(); // eq 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.sub(); // pos acc_x acc_y acc_z
|
||||
C.push(VAR_POS);
|
||||
C.mstore(); // acc_x acc_y acc_z
|
||||
C.jmp("begin_loop");
|
||||
C.label("after_loop"); // pos acc_x acc_y acc_z
|
||||
C.pop(); // acc_x acc_y acc_z
|
||||
|
||||
C.internalCall("affine"); // acc_x acc_y
|
||||
|
||||
C.push(0);
|
||||
C.mstore();
|
||||
C.push(20);
|
||||
C.mstore();
|
||||
C.push(40);
|
||||
C.mstore();
|
||||
C.push(60);
|
||||
C.mstore();
|
||||
|
||||
C.push("0x80");
|
||||
C.push("0x00");
|
||||
C.return();
|
||||
|
||||
double();
|
||||
addPoint();
|
||||
affine();
|
||||
|
||||
return C.createTxData();
|
||||
|
||||
function add(a, b, q) {
|
||||
C.dup(q);
|
||||
C.dup(a + 1 + 1);
|
||||
C.dup(b + 1 + 2);
|
||||
C.addmod();
|
||||
C.dup(q + 1);
|
||||
C.dup(a + 2);
|
||||
C.dup(b + 3);
|
||||
C.addmod();
|
||||
}
|
||||
|
||||
function sub(a, b, q) {
|
||||
C.dup(q); // q
|
||||
C.dup(a + 1 + 1); // ai q
|
||||
C.dub(q + 2); // q ai q
|
||||
C.dup(b + 1 + 3); // bi q ai q
|
||||
C.sub(); // -bi ai q
|
||||
C.addmod(); // ci
|
||||
C.dup(q + 1); // q ci
|
||||
C.dup(a + 2); // ar q ci
|
||||
C.dup(q + 3); // q ar q ci
|
||||
C.dup(b + 4); // br q ar q ci
|
||||
C.sub(); // -br ar q ci
|
||||
C.addmod(); // cr ci
|
||||
}
|
||||
|
||||
function mul(a, b, q) {
|
||||
C.dup(q); // q
|
||||
C.dup(q + 1); // q q
|
||||
C.dup(a + 2); // ar q q
|
||||
C.dup(b + 1 + 3); // bi ar q q
|
||||
C.mulmod(); // ci1 q
|
||||
C.dup(q + 2); // q ci1 q
|
||||
C.dup(a + 1 + 3); // ai q ci1 q
|
||||
C.dup(b + 4); // ar ai q ci1 q
|
||||
C.mulmod(); // ci2 ci1 q
|
||||
C.addmod(); // ci
|
||||
C.dup(q + 1); // q ci
|
||||
C.dup(q + 2); // q q ci
|
||||
C.dup(q + 3); // q q q ci
|
||||
C.dup(a + 1 + 4); // ai q q ci
|
||||
C.dup(b + 1 + 5); // bi ai q q ci
|
||||
C.mulmod(); // cr2 q q ci
|
||||
C.sub(); // -cr2 q ci
|
||||
C.dup(q + 3); // q -cr2 q ci
|
||||
C.dup(a + 4); // ar q -cr2 q ci
|
||||
C.dup(b + 5); // br ar q -cr2 q ci
|
||||
C.mulmod(); // cr1 -cr2 q ci
|
||||
C.addmod(); // cr ci
|
||||
}
|
||||
|
||||
function square(a, q) {
|
||||
C.dup(q); // q
|
||||
C.dup(q + 1); // q q
|
||||
C.dup(a + 2); // ar q q
|
||||
C.dup(a + 1 + 3); // ai ar q q
|
||||
C.mulmod(); // arai q
|
||||
C.dup(0); // arai arai q
|
||||
C.addmod(); // ci
|
||||
C.dup(q + 1); // q ci
|
||||
C.dup(q + 2); // q q ci
|
||||
C.dup(q + 3); // q q q ci
|
||||
C.dup(a + 1 + 4); // ai q q ci
|
||||
C.dup(a + 1 + 5); // ai ai q q ci
|
||||
C.mulmod(); // cr2 q q ci
|
||||
C.sub(); // -cr2 q ci
|
||||
C.dup(q + 3); // q -cr2 q ci
|
||||
C.dup(a + 4); // ar q -cr2 q ci
|
||||
C.dup(a + 5); // br ar q -cr2 q ci
|
||||
C.mulmod(); // cr1 -cr2 q ci
|
||||
C.addmod(); // cr ci
|
||||
}
|
||||
|
||||
function add1(a, q) {
|
||||
C.dup(a + 1); // im
|
||||
C.dup(1 + q); // q
|
||||
C.dup(2 + a); // re q im
|
||||
C.push(1); // 1 re q im
|
||||
C.addmod();
|
||||
}
|
||||
|
||||
function cmp(a, b) {
|
||||
C.dup(a);
|
||||
C.dup(b);
|
||||
C.eq();
|
||||
C.dup(a + 1);
|
||||
C.dup(a + 1);
|
||||
C.and();
|
||||
}
|
||||
|
||||
function rm(a) {
|
||||
if (a > 0) C.swap(a);
|
||||
C.pop();
|
||||
if (a > 0) C.swap(a);
|
||||
C.pop();
|
||||
}
|
||||
|
||||
function double() {
|
||||
C.label("double"); // xR, xI, yR, yI, zR zI, q
|
||||
|
||||
C.dup(4);
|
||||
C.iszero();
|
||||
C.dup(6);
|
||||
C.iszero();
|
||||
C.and();
|
||||
C.jumpi("enddouble"); // X Y Z q
|
||||
|
||||
// Z3 = 2*Y*Z // Remove Z
|
||||
mul(2, 4, 6); // yz X Y Z q
|
||||
rm(6); // X Y yz q
|
||||
|
||||
add(4, 4, 6); // 2yz X Y yz q
|
||||
rm(6); // X Y Z3 q
|
||||
|
||||
// A = X^2
|
||||
square(0, 6); // A X Y Z3 q
|
||||
|
||||
// B = Y^2 // Remove Y
|
||||
square(4, 8); // B A X Y Z3 q
|
||||
rm(6); // A X B Z3 q
|
||||
|
||||
// C = B^2
|
||||
square(4, 8); // C A X B Z3 q
|
||||
|
||||
// D = (X+B)^2-A-C // Remove X, Remove B
|
||||
add(4, 6, 10); // X+B C A X B Z3 q
|
||||
rm(6); // C A X+B B Z3 q
|
||||
rm(6); // 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
|
||||
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
|
||||
sub(2, 4, 8); // (X+B)^2-A-C A (X+B)^2-A C Z3 q
|
||||
rm(4); // A D C Z3 q
|
||||
|
||||
// D = D+D
|
||||
add(2, 2, 8); // D+D A D C Z3 q
|
||||
rm(4); // A D C Z3 q
|
||||
|
||||
// E=A+A+A
|
||||
add(0, 0, 8); // 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(0); // E D C Z3 q
|
||||
|
||||
// F=E^2
|
||||
square(0, 8); // F E D C Z3 q
|
||||
|
||||
// X3= F - 2*D // Remove F
|
||||
add(4, 4, 10); // 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(0); // X3 E D C Z3 q
|
||||
|
||||
// Y3 = E * (D - X3) - 8 * C // Remove D C E
|
||||
|
||||
sub(4, 0, 10); // D-X3 X3 E D 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
|
||||
rm(6); // X3 E 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
|
||||
rm(6); // 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
|
||||
add(4, 4, 8); // 8C X3 E*(D-X3) 4C 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
|
||||
rm(6); // X3 E*(D-X3) Y3 Z3 q
|
||||
rm(2); // X3 Y3 Z3 q
|
||||
|
||||
C.label("enddouble");
|
||||
C.returnCall();
|
||||
}
|
||||
|
||||
function addPoint() {
|
||||
// p, xR, xI, yR, yI, zR zI, q
|
||||
|
||||
C.dup(0); // p p X2 Y2 Z2 q
|
||||
|
||||
C.push(savedP);
|
||||
C.mstore();
|
||||
|
||||
C.iszero(); // X2 Y2 Z2 q
|
||||
C.jumpi("endpadd");
|
||||
|
||||
C.dup(4);
|
||||
C.iszero();
|
||||
C.dup(6);
|
||||
C.iszero();
|
||||
C.and();
|
||||
C.jumpi("returnP"); // X2 Y2 Z2 q
|
||||
|
||||
// lastZ3 = (Z2+1)^2 - Z2^2
|
||||
add1(4, 6); // 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
|
||||
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
|
||||
|
||||
saveZ3(); // Z2^2 (Z2+1)^2 X2 Y2 Z2 q
|
||||
rm(2); // Z2^2 X2 Y2 Z2 q
|
||||
|
||||
// U2 = X2
|
||||
// S2 = Y2 // Z2^2 U2 S2 Z2 q
|
||||
|
||||
// U1 = X1 * Z2^2
|
||||
loadX(); // 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
|
||||
|
||||
mul(2, 8, 10); // Z2^3 U1 Z2^2 U2 S2 Z2 q
|
||||
rm(4); // U1 Z2^3 U2 S2 Z2 q
|
||||
rm(8); // Z2^3 U2 S2 U1 q
|
||||
|
||||
// S1 = Y1 * Z1^3
|
||||
loadY(); // 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(0); // S1 U2 S2 U1 q
|
||||
|
||||
cmp(0, 4); // 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.jumpi("double1"); // S1 U2 S2 U1 q
|
||||
|
||||
// Returns the double
|
||||
|
||||
// H = U2-U1 // Remove U2
|
||||
C.sub(4, 8, 10); // H S1 U2 S2 U1 q
|
||||
rm(4); // S1 H S2 U1 q
|
||||
|
||||
// // r = 2 * (S2-S1) // Remove S2
|
||||
C.sub(4, 4, 8); // S1-S2 S1 H 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
|
||||
rm(6); // S1 H r U1 q
|
||||
|
||||
// I = (2 * H)^2
|
||||
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
|
||||
rm(2); // I S1 H r U1 q
|
||||
|
||||
// V = U1 * I
|
||||
mul(8, 0, 10); // V I S1 H r U1 q
|
||||
rm(10); // I S1 H r V q
|
||||
|
||||
// J = H * I // Remove I
|
||||
mul(4, 0, 10); // J I S1 H r V q
|
||||
rm(2); // J S1 H r V q
|
||||
|
||||
// X3 = r^2 - J - 2 * V
|
||||
|
||||
// S1J2 = (S1*J)*2 // Remove S1
|
||||
mul(2, 0, 10); // S1*J J S1 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
|
||||
rm(4); // J S1J2 H r V q
|
||||
|
||||
// X3 = r^2 - J - 2 * V
|
||||
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
|
||||
rm(2); // r^2-J 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
|
||||
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(0); // X3 S1J2 H r V q
|
||||
|
||||
// Y3 = r * (V-X3)-S1J2
|
||||
|
||||
sub(8, 0, 10); // V-X3 X3 S1J2 H r V q
|
||||
rm(10); // 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); // 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(0); // H Y3 X3 q
|
||||
|
||||
// Z3 = lastZ * H
|
||||
loadZ3(); // lastZ3 H Y3 X3 q
|
||||
mul(0, 2, 8); // Z3 lastZ3 H Y3 X3 q
|
||||
rm(4); // lastZ3 Z3 Y3 X3 q
|
||||
rm(0); // Z3 Y3 X3 q
|
||||
|
||||
C.swap(1);
|
||||
C.swap(5);
|
||||
C.swap(1);
|
||||
C.swap(4); // X3 Y3 Z3 q
|
||||
|
||||
// returns the point in memory
|
||||
C.label("returnP"); // X Y Z q
|
||||
rm(0);
|
||||
rm(0);
|
||||
rm(0);
|
||||
C.push(0);
|
||||
C.push(1);
|
||||
loadX();
|
||||
loadY();
|
||||
C.jump("endpadd");
|
||||
|
||||
C.label("double1"); // S1 U2 S2 U1 q
|
||||
rm(0);
|
||||
rm(0);
|
||||
rm(0);
|
||||
rm(0);
|
||||
C.push(0);
|
||||
C.push(1);
|
||||
loadX();
|
||||
loadY();
|
||||
C.jump("double");
|
||||
|
||||
C.label("endpadd");
|
||||
C.returnCall();
|
||||
|
||||
function loadX() {
|
||||
C.push(savedP);
|
||||
C.mload(); // p
|
||||
C.push(32);
|
||||
C.mul(); // P*32
|
||||
C.push(VAR_POINTS + 32);
|
||||
C.add(); // P*32+32
|
||||
C.dup(); // P*32+32 P*32+32
|
||||
C.mload(); // im P*32+32
|
||||
C.swap(1); // P*32+32 im
|
||||
C.push(0x20); // 32 P*32+32 im
|
||||
C.sub(); // P*32 im
|
||||
C.mload(); // re im
|
||||
}
|
||||
|
||||
function loadY() {
|
||||
C.push(savedP);
|
||||
C.mload(); // p
|
||||
C.push(32);
|
||||
C.mul(); // P*32
|
||||
C.push(VAR_POINTS + 32 * 3);
|
||||
C.add(); // P*32+32
|
||||
C.dup(); // P*32+32 P*32+32
|
||||
C.mload(); // im P*32+32
|
||||
C.swap(1); // P*32+32 im
|
||||
C.push(0x20); // 32 P*32+32 im
|
||||
C.sub(); // P*32 im
|
||||
C.mload(); // re im
|
||||
}
|
||||
|
||||
function loadZ3() {
|
||||
C.push(savedZ3 + 32);
|
||||
C.mload(); // p
|
||||
C.push(savedZ3);
|
||||
C.mload();
|
||||
}
|
||||
|
||||
function saveZ3() {
|
||||
C.push(savedZ3);
|
||||
C.mstore();
|
||||
C.push(savedZ3 + 32);
|
||||
C.mstore();
|
||||
}
|
||||
}
|
||||
|
||||
function affine() {
|
||||
// X Y Z q
|
||||
// If Z2=0 return 0
|
||||
C.label("affine");
|
||||
C.dup(4);
|
||||
C.dup(5 + 1);
|
||||
C.or();
|
||||
C.jumpi("notZero"); // X Y Z q
|
||||
rm(0);
|
||||
rm(0);
|
||||
C.push(0);
|
||||
C.push(0);
|
||||
|
||||
C.jmp("endAffine");
|
||||
C.label("notZero");
|
||||
|
||||
inverse2(4, 6); // 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
|
||||
rm(4); // Z2_inv Z3_inv X Y Z q
|
||||
C.push(1);
|
||||
C.push(0); // 1 Z2_inv Z3_inv X Y Z q
|
||||
rm(10); // 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
|
||||
mul(0, 4, 10); // XI Z2_inv Z3_inv X YI 1 q
|
||||
rm(6); // Z2_inv Z3_inv XI YI 1 q
|
||||
rm(0); // Z3_inv XI YI 1 q
|
||||
rm(0); // XI YI 1 q
|
||||
C.label("endAffine");
|
||||
C.returnCall();
|
||||
}
|
||||
|
||||
function inverse2(a, q) {
|
||||
C.dup(q); // q
|
||||
C.dup(q + 1); // q q
|
||||
C.push(2); // 2 q q
|
||||
C.sub(); // q-2 q
|
||||
C.dup(q + 2); // 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 + 5); // ar ar q q q-2 q
|
||||
C.mulmod(); // 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 + 6); // ai ai q t0 q q-2 q
|
||||
C.mulmod(); // t1 t0 q q-2 q
|
||||
|
||||
C.addmod(); // t2 q-2 q
|
||||
C.expmod(); // t3
|
||||
|
||||
C.dup(q + 1); // q t3
|
||||
C.dup(q + 2); // q q t3
|
||||
C.dup(q + 3); // q q q t3
|
||||
C.dup(1); // t3 q q q t3
|
||||
C.sub(); // -t3 q q t3
|
||||
C.dup(a + 1 + 3); // ai -t3 q q t3
|
||||
C.mulmod(); // ii q t3
|
||||
C.swap(2); // t3 q ii
|
||||
C.dup(a + 3); // ar t3 q ii
|
||||
C.mulmod(); // ir ii
|
||||
}
|
||||
|
||||
function storeVals() {
|
||||
C.push(VAR_POINTS); // p
|
||||
for (let i = 0; i < NPOINTS; i++) {
|
||||
const MP = G2.affine(G2.mulScalar(P, bigInt(i)));
|
||||
for (let j = 0; j < 2; j++) {
|
||||
for (let k = 0; k < 2; k++) {
|
||||
C.push(toHex256(MP[j][k])); // MP[0][0] p
|
||||
C.dup(1); // p MP[0][0] p
|
||||
C.mstore(); // p
|
||||
C.push(32); // 32 p
|
||||
C.add(); // p+32
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.abi = [
|
||||
{
|
||||
constant: true,
|
||||
inputs: [
|
||||
{
|
||||
name: "escalar",
|
||||
type: "uint256",
|
||||
},
|
||||
],
|
||||
name: "mulexp",
|
||||
outputs: [
|
||||
{
|
||||
name: "",
|
||||
type: "uint256",
|
||||
},
|
||||
{
|
||||
name: "",
|
||||
type: "uint256",
|
||||
},
|
||||
],
|
||||
payable: false,
|
||||
stateMutability: "pure",
|
||||
type: "function",
|
||||
},
|
||||
];
|
||||
|
||||
module.exports.createCode = createCode;
|
||||
58
src/mimc7.js
58
src/mimc7.js
@ -1,58 +0,0 @@
|
||||
const bn128 = require("@tornado/snarkjs").bn128;
|
||||
const bigInt = require("@tornado/snarkjs").bigInt;
|
||||
const Web3Utils = require("web3-utils");
|
||||
const F = bn128.Fr;
|
||||
|
||||
const SEED = "mimc";
|
||||
const NROUNDS = 91;
|
||||
|
||||
exports.getIV = (seed) => {
|
||||
if (typeof seed === "undefined") seed = SEED;
|
||||
const c = Web3Utils.keccak256(seed + "_iv");
|
||||
const cn = bigInt(Web3Utils.toBN(c).toString());
|
||||
const iv = cn.mod(F.q);
|
||||
return iv;
|
||||
};
|
||||
|
||||
exports.getConstants = (seed, nRounds) => {
|
||||
if (typeof seed === "undefined") seed = SEED;
|
||||
if (typeof nRounds === "undefined") nRounds = NROUNDS;
|
||||
const cts = new Array(nRounds);
|
||||
let c = Web3Utils.keccak256(SEED);
|
||||
for (let i = 1; i < nRounds; i++) {
|
||||
c = Web3Utils.keccak256(c);
|
||||
|
||||
const n1 = Web3Utils.toBN(c).mod(Web3Utils.toBN(F.q.toString()));
|
||||
const c2 = Web3Utils.padLeft(Web3Utils.toHex(n1), 64);
|
||||
cts[i] = bigInt(Web3Utils.toBN(c2).toString());
|
||||
}
|
||||
cts[0] = bigInt(0);
|
||||
return cts;
|
||||
};
|
||||
|
||||
const cts = exports.getConstants(SEED, 91);
|
||||
|
||||
exports.hash = (_x_in, _k) => {
|
||||
const x_in = bigInt(_x_in);
|
||||
const k = bigInt(_k);
|
||||
let r;
|
||||
for (let i = 0; i < NROUNDS; i++) {
|
||||
const c = cts[i];
|
||||
const t = i == 0 ? F.add(x_in, k) : F.add(F.add(r, k), c);
|
||||
r = F.exp(t, 7);
|
||||
}
|
||||
return F.affine(F.add(r, k));
|
||||
};
|
||||
|
||||
exports.multiHash = (arr, key) => {
|
||||
let r;
|
||||
if (typeof key === "undefined") {
|
||||
r = F.zero;
|
||||
} else {
|
||||
r = key;
|
||||
}
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
r = F.add(F.add(r, arr[i]), exports.hash(bigInt(arr[i]), r));
|
||||
}
|
||||
return F.affine(r);
|
||||
};
|
||||
@ -1,114 +0,0 @@
|
||||
// Copyright (c) 2018 Jordi Baylina
|
||||
// License: LGPL-3.0+
|
||||
//
|
||||
|
||||
const Web3Utils = require("web3-utils");
|
||||
|
||||
const Contract = require("./evmasm");
|
||||
|
||||
function createCode(seed, n) {
|
||||
|
||||
let ci = Web3Utils.keccak256(seed);
|
||||
|
||||
const C = new Contract();
|
||||
|
||||
C.push(0x44);
|
||||
C.push("0x00");
|
||||
C.push("0x00");
|
||||
C.calldatacopy();
|
||||
C.push("0x0100000000000000000000000000000000000000000000000000000000");
|
||||
C.push("0x00");
|
||||
C.mload();
|
||||
C.div();
|
||||
C.push("0xd15ca109"); // MiMCpe7(uint256,uint256)
|
||||
// C.push("0x8c42199e"); // MiMCpe7(uint256,uint256,uint256)
|
||||
C.eq();
|
||||
C.jmpi("start");
|
||||
C.invalid();
|
||||
|
||||
C.label("start");
|
||||
C.push("0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001"); // q
|
||||
C.push("0x24");
|
||||
C.mload(); // k q
|
||||
|
||||
|
||||
C.dup(1); // q k q
|
||||
C.dup(0); // q q k q
|
||||
C.push("0x04");
|
||||
C.mload(); // x q q k q
|
||||
C.dup(3); // k x q q k q
|
||||
C.addmod(); // t=x+k q k q
|
||||
C.dup(1); // q t q k q
|
||||
C.dup(0); // q q t q k q
|
||||
C.dup(2); // t q q t q k q
|
||||
C.dup(0); // t t q q t q k q
|
||||
C.mulmod(); // a=t^2 q t q k q
|
||||
C.dup(1); // q a q t q k q
|
||||
C.dup(1); // a q a q t q k q
|
||||
C.dup(0); // a a q a q t q k q
|
||||
C.mulmod(); // b=t^4 a q t q k q
|
||||
C.mulmod(); // c=t^6 t q k q
|
||||
C.mulmod(); // r=t^7 k q
|
||||
|
||||
for (let i=0; i<n-1; i++) {
|
||||
ci = Web3Utils.keccak256(ci);
|
||||
C.dup(2); // q r k q
|
||||
C.dup(0); // q q r k q
|
||||
C.dup(0); // q q q r k q
|
||||
C.swap(3); // r q q q k q
|
||||
C.push(ci); // c r q q k q
|
||||
C.addmod(); // s=c+r q q k q
|
||||
C.dup(3); // k s q q k q
|
||||
C.addmod(); // t=s+k q k q
|
||||
C.dup(1); // q t q k q
|
||||
C.dup(0); // q q t q k q
|
||||
C.dup(2); // t q q t q k q
|
||||
C.dup(0); // t t q q t q k q
|
||||
C.mulmod(); // a=t^2 q t q k q
|
||||
C.dup(1); // q a q t q k q
|
||||
C.dup(1); // a q a q t q k q
|
||||
C.dup(0); // a a q a q t q k q
|
||||
C.mulmod(); // b=t^4 a q t q k q
|
||||
C.mulmod(); // c=t^6 t q k q
|
||||
C.mulmod(); // r=t^7 k q
|
||||
}
|
||||
|
||||
C.addmod(); // res=t^7+k
|
||||
C.push("0x00");
|
||||
C.mstore(); // Save it to pos 0;
|
||||
C.push("0x20");
|
||||
C.push("0x00");
|
||||
C.return();
|
||||
|
||||
return C.createTxData();
|
||||
}
|
||||
|
||||
module.exports.abi = [
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "in_x",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "in_k",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "MiMCpe7",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "out_x",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "pure",
|
||||
"type": "function"
|
||||
}
|
||||
];
|
||||
|
||||
module.exports.createCode = createCode;
|
||||
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
const mimc7 = require("./mimc7.js");
|
||||
|
||||
console.log("IV: "+mimc7.getIV().toString());
|
||||
@ -1,13 +0,0 @@
|
||||
const mimc7 = require("./mimc7.js");
|
||||
|
||||
const nRounds = 91;
|
||||
let S = "[\n";
|
||||
const cts = mimc7.getConstants();
|
||||
for (let i=0; i<nRounds; i++) {
|
||||
S = S + cts[i].toString();
|
||||
if (i<nRounds-1) S = S + ",";
|
||||
S=S+"\n";
|
||||
}
|
||||
S = S + "]\n";
|
||||
|
||||
console.log(S);
|
||||
@ -1,13 +0,0 @@
|
||||
const mimcGenContract = require("./mimc_gencontract");
|
||||
|
||||
const SEED = "mimc";
|
||||
|
||||
let nRounds;
|
||||
if (typeof process.argv[2] != "undefined") {
|
||||
nRounds = parseInt(process.argv[2]);
|
||||
} else {
|
||||
nRounds = 91;
|
||||
}
|
||||
|
||||
console.log(mimcGenContract.createCode(SEED, nRounds));
|
||||
|
||||
@ -1,86 +0,0 @@
|
||||
const bn128 = require("@tornado/snarkjs").bn128;
|
||||
const bigInt = require("@tornado/snarkjs").bigInt;
|
||||
const Web3Utils = require("web3-utils");
|
||||
const F = bn128.Fr;
|
||||
|
||||
const SEED = "mimcsponge";
|
||||
const NROUNDS = 220;
|
||||
|
||||
exports.getIV = (seed) => {
|
||||
if (typeof seed === "undefined") seed = SEED;
|
||||
const c = Web3Utils.keccak256(seed + "_iv");
|
||||
const cn = bigInt(Web3Utils.toBN(c).toString());
|
||||
const iv = cn.mod(F.q);
|
||||
return iv;
|
||||
};
|
||||
|
||||
exports.getConstants = (seed, nRounds) => {
|
||||
if (typeof seed === "undefined") seed = SEED;
|
||||
if (typeof nRounds === "undefined") nRounds = NROUNDS;
|
||||
const cts = new Array(nRounds);
|
||||
let c = Web3Utils.keccak256(SEED);
|
||||
for (let i = 1; i < nRounds; i++) {
|
||||
c = Web3Utils.keccak256(c);
|
||||
|
||||
const n1 = Web3Utils.toBN(c).mod(Web3Utils.toBN(F.q.toString()));
|
||||
const c2 = Web3Utils.padLeft(Web3Utils.toHex(n1), 64);
|
||||
cts[i] = bigInt(Web3Utils.toBN(c2).toString());
|
||||
}
|
||||
cts[0] = bigInt(0);
|
||||
cts[cts.length - 1] = bigInt(0);
|
||||
return cts;
|
||||
};
|
||||
|
||||
const cts = exports.getConstants(SEED, NROUNDS);
|
||||
|
||||
exports.hash = (_xL_in, _xR_in, _k) => {
|
||||
let xL = bigInt(_xL_in);
|
||||
let xR = bigInt(_xR_in);
|
||||
const k = bigInt(_k);
|
||||
for (let i = 0; i < NROUNDS; i++) {
|
||||
const c = cts[i];
|
||||
const t = i == 0 ? F.add(xL, k) : F.add(F.add(xL, k), c);
|
||||
const xR_tmp = bigInt(xR);
|
||||
if (i < NROUNDS - 1) {
|
||||
xR = xL;
|
||||
xL = F.add(xR_tmp, F.exp(t, 5));
|
||||
} else {
|
||||
xR = F.add(xR_tmp, F.exp(t, 5));
|
||||
}
|
||||
}
|
||||
return {
|
||||
xL: F.affine(xL),
|
||||
xR: F.affine(xR),
|
||||
};
|
||||
};
|
||||
|
||||
exports.multiHash = (arr, key, numOutputs) => {
|
||||
if (typeof numOutputs === "undefined") {
|
||||
numOutputs = 1;
|
||||
}
|
||||
if (typeof key === "undefined") {
|
||||
key = F.zero;
|
||||
}
|
||||
|
||||
let R = F.zero;
|
||||
let C = F.zero;
|
||||
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
R = F.add(R, bigInt(arr[i]));
|
||||
const S = exports.hash(R, C, key);
|
||||
R = S.xL;
|
||||
C = S.xR;
|
||||
}
|
||||
let outputs = [R];
|
||||
for (let i = 1; i < numOutputs; i++) {
|
||||
const S = exports.hash(R, C, key);
|
||||
R = S.xL;
|
||||
C = S.xR;
|
||||
outputs.push(R);
|
||||
}
|
||||
if (numOutputs == 1) {
|
||||
return F.affine(outputs[0]);
|
||||
} else {
|
||||
return outputs.map((x) => F.affine(x));
|
||||
}
|
||||
};
|
||||
@ -1,116 +0,0 @@
|
||||
// Copyright (c) 2018 Jordi Baylina
|
||||
// License: LGPL-3.0+
|
||||
//
|
||||
|
||||
const Web3Utils = require("web3-utils");
|
||||
|
||||
const Contract = require("./evmasm");
|
||||
|
||||
function createCode(seed, n) {
|
||||
|
||||
let ci = Web3Utils.keccak256(seed);
|
||||
|
||||
const C = new Contract();
|
||||
|
||||
C.push(0x64);
|
||||
C.push("0x00");
|
||||
C.push("0x00");
|
||||
C.calldatacopy();
|
||||
C.push("0x0100000000000000000000000000000000000000000000000000000000");
|
||||
C.push("0x00");
|
||||
C.mload();
|
||||
C.div();
|
||||
C.push("0xf47d33b5"); // MiMCSponge(uint256,uint256)
|
||||
C.eq();
|
||||
C.jmpi("start");
|
||||
C.invalid();
|
||||
|
||||
C.label("start");
|
||||
C.push("0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001"); // q
|
||||
C.push("0x04");
|
||||
C.mload(); // xL q
|
||||
C.dup(1); // q xL q
|
||||
C.push("0x24");
|
||||
C.mload(); // xR q xL q
|
||||
C.dup(1); // q xR q xL q
|
||||
C.dup(3); // xL q xR q xL q
|
||||
C.dup(1); // q xL q xR q xL q
|
||||
C.dup(0); // q q xL q xR q xL q
|
||||
C.dup(2); // xL q q xL q xR q xL q
|
||||
C.dup(0); // xL xL q q xL q xR q xL q
|
||||
C.mulmod(); // b=xL^2 q xL q xR q xL q
|
||||
C.dup(0); // b b q xL q xR q xL q
|
||||
C.mulmod(); // c=xL^4 xL q xR q xL q
|
||||
C.mulmod(); // d=xL^5 xR q xL q
|
||||
C.addmod(); // e=xL^5+xR xL q (for next round: xL xR q)
|
||||
|
||||
for (let i=0; i<n-1; i++) {
|
||||
if (i < n-2) {
|
||||
ci = Web3Utils.keccak256(ci);
|
||||
} else {
|
||||
ci = "0x00";
|
||||
}
|
||||
C.swap(1); // xR xL q
|
||||
C.dup(2); // q xR xL q
|
||||
C.dup(2); // xL q xR xL q
|
||||
C.push(ci); // ci xL q xR xL q
|
||||
C.addmod(); // a=ci+xL xR xL q
|
||||
C.dup(3); // q a xR xL q
|
||||
C.swap(1); // a q xR xL q
|
||||
C.dup(1); // q a q xR xL q
|
||||
C.dup(0); // q q a q xR xL q
|
||||
C.dup(2); // a q q a q xR xL q
|
||||
C.dup(0); // a a q q a q xR xL q
|
||||
C.mulmod(); // b=a^2 q a q xR xL q
|
||||
C.dup(0); // b b q a q xR xL q
|
||||
C.mulmod(); // c=a^4 a q xR xL q
|
||||
C.mulmod(); // d=a^5 xR xL q
|
||||
C.dup(3); // q d xR xL q
|
||||
C.swap(2); // xR d q xL q
|
||||
C.addmod(); // e=a^5+xR xL q (for next round: xL xR q)
|
||||
}
|
||||
|
||||
C.push("0x20");
|
||||
C.mstore(); // Save it to pos 0;
|
||||
C.push("0x00");
|
||||
C.mstore(); // Save it to pos 1;
|
||||
C.push("0x40");
|
||||
C.push("0x00");
|
||||
C.return();
|
||||
|
||||
return C.createTxData();
|
||||
}
|
||||
|
||||
module.exports.abi = [
|
||||
{
|
||||
"constant": true,
|
||||
"inputs": [
|
||||
{
|
||||
"name": "xL_in",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "xR_in",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "MiMCSponge",
|
||||
"outputs": [
|
||||
{
|
||||
"name": "xL",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "xR",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"payable": false,
|
||||
"stateMutability": "pure",
|
||||
"type": "function"
|
||||
}
|
||||
];
|
||||
|
||||
module.exports.createCode = createCode;
|
||||
|
||||
|
||||
@ -1,13 +0,0 @@
|
||||
const mimcsponge = require("./mimcsponge.js");
|
||||
|
||||
const nRounds = 220;
|
||||
let S = "[\n";
|
||||
const cts = mimcsponge.getConstants();
|
||||
for (let i=0; i<nRounds; i++) {
|
||||
S = S + cts[i].toString();
|
||||
if (i<nRounds-1) S = S + ",";
|
||||
S=S+"\n";
|
||||
}
|
||||
S = S + "]\n";
|
||||
|
||||
console.log(S);
|
||||
@ -1,13 +0,0 @@
|
||||
const mimcGenContract = require("./mimcsponge_gencontract");
|
||||
|
||||
const SEED = "mimcsponge";
|
||||
|
||||
let nRounds;
|
||||
if (typeof process.argv[2] != "undefined") {
|
||||
nRounds = parseInt(process.argv[2]);
|
||||
} else {
|
||||
nRounds = 220;
|
||||
}
|
||||
|
||||
console.log(mimcGenContract.createCode(SEED, nRounds));
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
const bn128 = require("@tornado/snarkjs").bn128;
|
||||
const bigInt = require("@tornado/snarkjs").bigInt;
|
||||
const bn128 = require("snarkjs").bn128;
|
||||
const bigInt = require("snarkjs").bigInt;
|
||||
const babyJub = require("./babyjub");
|
||||
const assert = require("assert");
|
||||
const createBlakeHash = require("blake-hash");
|
||||
|
||||
const GENPOINT_PREFIX = "PedersenGenerator";
|
||||
const GENPOINT_PREFIX = "Iden3_PedersenGenerator";
|
||||
const windowSize = 4;
|
||||
const nWindowsPerSegment = 50;
|
||||
|
||||
@ -11,39 +12,39 @@ exports.hash = pedersenHash;
|
||||
exports.getBasePoint = getBasePoint;
|
||||
|
||||
function pedersenHash(msg) {
|
||||
const bitsPerSegment = windowSize * nWindowsPerSegment;
|
||||
const bitsPerSegment = windowSize*nWindowsPerSegment;
|
||||
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 = [bigInt.zero,bigInt.one];
|
||||
|
||||
for (let s = 0; s < nSegments; s++) {
|
||||
for (let s=0; s<nSegments; s++) {
|
||||
let nWindows;
|
||||
if (s == nSegments - 1) {
|
||||
nWindows = Math.floor((bits.length - (nSegments - 1) * bitsPerSegment - 1) / windowSize) + 1;
|
||||
if (s == nSegments-1) {
|
||||
nWindows = Math.floor(((bits.length - (nSegments - 1)*bitsPerSegment) - 1) / windowSize) +1;
|
||||
} else {
|
||||
nWindows = nWindowsPerSegment;
|
||||
}
|
||||
let escalar = bigInt.zero;
|
||||
let exp = bigInt.one;
|
||||
for (let w = 0; w < nWindows; w++) {
|
||||
let o = s * bitsPerSegment + w * windowSize;
|
||||
for (let w=0; w<nWindows; w++) {
|
||||
let o = s*bitsPerSegment + w*windowSize;
|
||||
let acc = bigInt.one;
|
||||
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]) {
|
||||
acc = acc.add(bigInt.one.shl(b));
|
||||
acc = acc.add( bigInt.one.shl(b) );
|
||||
}
|
||||
o++;
|
||||
}
|
||||
if (o < bits.length) {
|
||||
if (o<bits.length) {
|
||||
if (bits[o]) {
|
||||
acc = acc.neg();
|
||||
}
|
||||
o++;
|
||||
}
|
||||
escalar = escalar.add(acc.mul(exp));
|
||||
exp = exp.shl(windowSize + 1);
|
||||
exp = exp.shl(windowSize+1);
|
||||
}
|
||||
|
||||
if (escalar.lesser(bigInt.zero)) {
|
||||
@ -59,22 +60,20 @@ function pedersenHash(msg) {
|
||||
let bases = [];
|
||||
|
||||
function getBasePoint(pointIdx) {
|
||||
if (pointIdx < bases.length) return bases[pointIdx];
|
||||
let p = null;
|
||||
if (pointIdx<bases.length) return bases[pointIdx];
|
||||
let p= null;
|
||||
let tryIdx = 0;
|
||||
while (p == null) {
|
||||
while (p==null) {
|
||||
const S = GENPOINT_PREFIX + "_" + padLeftZeros(pointIdx, 32) + "_" + padLeftZeros(tryIdx, 32);
|
||||
const h = createBlakeHash("blake256").update(S).digest();
|
||||
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);
|
||||
tryIdx++;
|
||||
}
|
||||
|
||||
const p8 = babyJub.mulPointEscalar(p, 8);
|
||||
|
||||
if (!babyJub.inSubgroup(p8)) {
|
||||
throw new Error("Point not in curve");
|
||||
}
|
||||
assert(babyJub.inSubgroup(p8), "Point not in curve");
|
||||
|
||||
bases[pointIdx] = p8;
|
||||
return p8;
|
||||
@ -82,7 +81,7 @@ function getBasePoint(pointIdx) {
|
||||
|
||||
function padLeftZeros(idx, n) {
|
||||
let sidx = "" + idx;
|
||||
while (sidx.length < n) sidx = "0" + sidx;
|
||||
while (sidx.length<n) sidx = "0"+sidx;
|
||||
return sidx;
|
||||
}
|
||||
|
||||
@ -91,17 +90,21 @@ Input a buffer
|
||||
Returns an array of booleans. 0 is LSB of first byte and so on.
|
||||
*/
|
||||
function buffer2bits(buff) {
|
||||
const res = new Array(buff.length * 8);
|
||||
for (let i = 0; i < buff.length; i++) {
|
||||
const res = new Array(buff.length*8);
|
||||
for (let i=0; i<buff.length; i++) {
|
||||
const b = buff[i];
|
||||
res[i * 8] = b & 0x01;
|
||||
res[i * 8 + 1] = b & 0x02;
|
||||
res[i * 8 + 2] = b & 0x04;
|
||||
res[i * 8 + 3] = b & 0x08;
|
||||
res[i * 8 + 4] = b & 0x10;
|
||||
res[i * 8 + 5] = b & 0x20;
|
||||
res[i * 8 + 6] = b & 0x40;
|
||||
res[i * 8 + 7] = b & 0x80;
|
||||
res[i*8] = b & 0x01;
|
||||
res[i*8+1] = b & 0x02;
|
||||
res[i*8+2] = b & 0x04;
|
||||
res[i*8+3] = b & 0x08;
|
||||
res[i*8+4] = b & 0x10;
|
||||
res[i*8+5] = b & 0x20;
|
||||
res[i*8+6] = b & 0x40;
|
||||
res[i*8+7] = b & 0x80;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1,48 +0,0 @@
|
||||
const assert = require("assert");
|
||||
const bn128 = require("@tornado/snarkjs").bn128;
|
||||
const bigInt = require("@tornado/snarkjs").bigInt;
|
||||
const F = bn128.Fr;
|
||||
const { unstringifyBigInts } = require("@tornado/snarkjs");
|
||||
|
||||
// Prime 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001
|
||||
// const F = new ZqField(Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
|
||||
|
||||
// Parameters are generated by a reference script https://extgit.iaik.tugraz.at/krypto/hadeshash/-/blob/master/code/generate_parameters_grain.sage
|
||||
// Used like so: sage generate_parameters_grain.sage 1 0 254 2 8 56 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001
|
||||
const { C, M } = unstringifyBigInts(require("./poseidon_constants.json"));
|
||||
|
||||
// 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;
|
||||
|
||||
const pow5 = (a) => F.mul(a, F.square(F.square(a, a)));
|
||||
|
||||
function poseidon(inputs) {
|
||||
assert(inputs.length > 0);
|
||||
assert(inputs.length < 5);
|
||||
|
||||
const t = inputs.length + 1;
|
||||
const nRoundsF = N_ROUNDS_F;
|
||||
const nRoundsP = N_ROUNDS_P;
|
||||
|
||||
let state = [...inputs.map((a) => bigInt(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 F.affine(state[0]);
|
||||
}
|
||||
|
||||
module.exports = poseidon;
|
||||
@ -1,706 +0,0 @@
|
||||
{
|
||||
"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"
|
||||
]
|
||||
]
|
||||
]
|
||||
}
|
||||
@ -1,213 +0,0 @@
|
||||
// Copyright (c) 2018 Jordi Baylina
|
||||
// License: LGPL-3.0+
|
||||
//
|
||||
|
||||
const Contract = require("./evmasm");
|
||||
const { unstringifyBigInts } = require("@tornado/snarkjs");
|
||||
const Web3Utils = require("web3-utils");
|
||||
|
||||
const { C: K, M } = unstringifyBigInts(require("./poseidon_constants.json"));
|
||||
|
||||
const N_ROUNDS_F = 8;
|
||||
const N_ROUNDS_P = 35;
|
||||
|
||||
function toHex256(a) {
|
||||
if (typeof a === "string" && a.startsWith("0x")) {
|
||||
return a;
|
||||
}
|
||||
let S = a.toString(16);
|
||||
while (S.length < 64) S = "0" + S;
|
||||
return "0x" + S;
|
||||
}
|
||||
|
||||
function createCode(nInputs) {
|
||||
if (nInputs < 1 || nInputs > 4) throw new Error("Invalid number of inputs. Must be 1<=nInputs<=8");
|
||||
const t = nInputs + 1;
|
||||
const nRoundsF = N_ROUNDS_F;
|
||||
const nRoundsP = N_ROUNDS_P;
|
||||
|
||||
const C = new Contract();
|
||||
|
||||
function saveM() {
|
||||
for (let i = 0; i < t; i++) {
|
||||
for (let j = 0; j < t; j++) {
|
||||
C.push(toHex256(M[t - 2][j][i]));
|
||||
C.push((1 + i * t + j) * 32);
|
||||
C.mstore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function ark(r) {
|
||||
// st, q
|
||||
for (let i = 0; i < t; i++) {
|
||||
C.dup(t); // q, st, q
|
||||
C.push(toHex256(K[t - 2][r * t + i])); // K, q, st, q
|
||||
C.dup(2 + i); // st[i], K, q, st, q
|
||||
C.addmod(); // newSt[i], st, q
|
||||
C.swap(1 + i); // xx, st, q
|
||||
C.pop();
|
||||
}
|
||||
}
|
||||
|
||||
function sigma(p) {
|
||||
// sq, q
|
||||
C.dup(t); // q, st, q
|
||||
C.dup(1 + p); // st[p] , q , st, q
|
||||
C.dup(1); // q, st[p] , q , st, q
|
||||
C.dup(0); // q, q, st[p] , q , st, q
|
||||
C.dup(2); // st[p] , q, q, st[p] , q , st, q
|
||||
C.dup(0); // st[p] , st[p] , q, q, st[p] , q , st, q
|
||||
C.mulmod(); // st2[p], q, st[p] , q , st, q
|
||||
C.dup(0); // st2[p], st2[p], q, st[p] , q , st, q
|
||||
C.mulmod(); // st4[p], st[p] , q , st, q
|
||||
C.mulmod(); // st5[p], st, q
|
||||
C.swap(1 + p);
|
||||
C.pop(); // newst, q
|
||||
}
|
||||
|
||||
function mix() {
|
||||
C.label("mix");
|
||||
for (let i = 0; i < t; i++) {
|
||||
for (let j = 0; j < t; j++) {
|
||||
if (j == 0) {
|
||||
C.dup(i + t); // q, newSt, oldSt, q
|
||||
C.push((1 + i * t + j) * 32);
|
||||
C.mload(); // M, q, newSt, oldSt, q
|
||||
C.dup(2 + i + j); // oldSt[j], M, q, newSt, oldSt, q
|
||||
C.mulmod(); // acc, newSt, oldSt, q
|
||||
} else {
|
||||
C.dup(1 + i + t); // q, acc, newSt, oldSt, q
|
||||
C.push((1 + i * t + j) * 32);
|
||||
C.mload(); // M, q, acc, newSt, oldSt, q
|
||||
C.dup(3 + i + j); // oldSt[j], M, q, acc, newSt, oldSt, q
|
||||
C.mulmod(); // aux, acc, newSt, oldSt, q
|
||||
C.dup(2 + i + t); // q, aux, acc, newSt, oldSt, q
|
||||
C.swap(2); // acc, aux, q, newSt, oldSt, q
|
||||
C.addmod(); // acc, newSt, oldSt, q
|
||||
}
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < t; i++) {
|
||||
C.swap(t - i + (t - i - 1));
|
||||
C.pop();
|
||||
}
|
||||
C.push(0);
|
||||
C.mload();
|
||||
C.jmp();
|
||||
}
|
||||
|
||||
// Check selector
|
||||
C.push("0x0100000000000000000000000000000000000000000000000000000000");
|
||||
C.push(0);
|
||||
C.calldataload();
|
||||
C.div();
|
||||
C.dup(0);
|
||||
C.push(Web3Utils.keccak256(`poseidon(uint256[${nInputs}])`).slice(0, 10)); // poseidon(uint256[n])
|
||||
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.invalid();
|
||||
|
||||
C.label("start");
|
||||
|
||||
saveM();
|
||||
|
||||
C.push("0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001"); // q
|
||||
|
||||
// Load t values from the call data.
|
||||
// The function has a single array param param
|
||||
// [Selector (4)] [item1 (32)] [item2 (32)] ....
|
||||
// Stack positions 0-nInputs.
|
||||
for (let i = 0; i < t; i++) {
|
||||
C.push(0x04 + 0x20 * (nInputs - i));
|
||||
C.calldataload();
|
||||
}
|
||||
|
||||
for (let i = 0; i < nRoundsF + nRoundsP - 1; i++) {
|
||||
ark(i);
|
||||
if (i < nRoundsF / 2 || i >= nRoundsP + nRoundsF / 2) {
|
||||
for (let j = 0; j < t; j++) {
|
||||
sigma(j);
|
||||
}
|
||||
} else {
|
||||
sigma(0);
|
||||
}
|
||||
const strLabel = "aferMix" + i;
|
||||
C._pushLabel(strLabel);
|
||||
C.push(0);
|
||||
C.mstore();
|
||||
C.jmp("mix");
|
||||
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.mstore(); // Save it to pos 0;
|
||||
C.push("0x20");
|
||||
C.push("0x00");
|
||||
C.return();
|
||||
|
||||
mix();
|
||||
|
||||
return C.createTxData();
|
||||
}
|
||||
|
||||
function generateABI(nInputs) {
|
||||
return [
|
||||
{
|
||||
constant: true,
|
||||
inputs: [
|
||||
{
|
||||
internalType: `bytes32[${nInputs}]`,
|
||||
name: "input",
|
||||
type: `bytes32[${nInputs}]`,
|
||||
},
|
||||
],
|
||||
name: "poseidon",
|
||||
outputs: [
|
||||
{
|
||||
internalType: "bytes32",
|
||||
name: "",
|
||||
type: "bytes32",
|
||||
},
|
||||
],
|
||||
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;
|
||||
@ -1,13 +0,0 @@
|
||||
const poseidonGenContract = require("./poseidon_gencontract");
|
||||
|
||||
if (process.argv.length != 3) {
|
||||
console.log("Usage: node poseidon_gencontract.js [numberOfInputs]");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const nInputs = Number(process.argv[2]);
|
||||
|
||||
console.log(nInputs);
|
||||
|
||||
console.log(poseidonGenContract.createCode(nInputs));
|
||||
|
||||
@ -1,22 +0,0 @@
|
||||
|
||||
|
||||
const Poseidon = require("./poseidon.js");
|
||||
|
||||
const M = Poseidon.getMatrix();
|
||||
|
||||
let S = "[\n ";
|
||||
|
||||
for (let i=0; i<M.length; i++) {
|
||||
const LC = M[i];
|
||||
S = S + "[\n";
|
||||
for (let j=0; j<LC.length; j++) {
|
||||
S = S + " " + M[i][j].toString();
|
||||
if (j<LC.length-1) S = S + ",";
|
||||
S = S + "\n";
|
||||
}
|
||||
S = S + " ]";
|
||||
if (i<M.length-1) S = S + ",";
|
||||
}
|
||||
S=S+ "\n]\n";
|
||||
|
||||
console.log(S);
|
||||
306
src/smt.js
306
src/smt.js
@ -1,306 +0,0 @@
|
||||
const bigInt = require("@tornado/snarkjs").bigInt;
|
||||
|
||||
const SMTMemDB = require("./smt_memdb");
|
||||
const { hash0, hash1 } = require("./smt_hashes_poseidon");
|
||||
|
||||
class SMT {
|
||||
constructor(db, root) {
|
||||
this.db = db;
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
_splitBits(_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);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
async update(_key, _newValue) {
|
||||
const key = bigInt(_key);
|
||||
const newValue = bigInt(_newValue);
|
||||
|
||||
const resFind = await this.find(key);
|
||||
const res = {};
|
||||
res.oldRoot = this.root;
|
||||
res.oldKey = key;
|
||||
res.oldValue = resFind.foundValue;
|
||||
res.newKey = key;
|
||||
res.newValue = newValue;
|
||||
res.siblings = resFind.siblings;
|
||||
|
||||
const ins = [];
|
||||
const dels = [];
|
||||
|
||||
let rtOld = hash1(key, resFind.foundValue);
|
||||
let rtNew = hash1(key, newValue);
|
||||
ins.push([rtNew, [1, key, newValue]]);
|
||||
dels.push(rtOld);
|
||||
|
||||
const keyBits = this._splitBits(key);
|
||||
for (let level = resFind.siblings.length - 1; level >= 0; level--) {
|
||||
let oldNode, newNode;
|
||||
const sibling = resFind.siblings[level];
|
||||
if (keyBits[level]) {
|
||||
oldNode = [sibling, rtOld];
|
||||
newNode = [sibling, rtNew];
|
||||
} else {
|
||||
oldNode = [rtOld, sibling];
|
||||
newNode = [rtNew, sibling];
|
||||
}
|
||||
rtOld = hash0(oldNode[0], oldNode[1]);
|
||||
rtNew = hash0(newNode[0], newNode[1]);
|
||||
dels.push(rtOld);
|
||||
ins.push([rtNew, newNode]);
|
||||
}
|
||||
|
||||
res.newRoot = rtNew;
|
||||
|
||||
await this.db.multiIns(ins);
|
||||
await this.db.setRoot(rtNew);
|
||||
this.root = rtNew;
|
||||
await this.db.multiDel(dels);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
async delete(_key) {
|
||||
const key = bigInt(_key);
|
||||
|
||||
const resFind = await this.find(key);
|
||||
if (!resFind.found) throw new Error("Key does not exists");
|
||||
|
||||
const res = {
|
||||
siblings: [],
|
||||
delKey: key,
|
||||
delValue: resFind.foundValue,
|
||||
};
|
||||
|
||||
const dels = [];
|
||||
const ins = [];
|
||||
let rtOld = hash1(key, resFind.foundValue);
|
||||
let rtNew;
|
||||
dels.push(rtOld);
|
||||
|
||||
let mixed;
|
||||
if (resFind.siblings.length > 0) {
|
||||
const record = await this.db.get(resFind.siblings[resFind.siblings.length - 1]);
|
||||
if (record.length == 3 && record[0].equals(bigInt.one)) {
|
||||
mixed = false;
|
||||
res.oldKey = record[1];
|
||||
res.oldValue = record[2];
|
||||
res.isOld0 = false;
|
||||
rtNew = resFind.siblings[resFind.siblings.length - 1];
|
||||
} else if (record.length == 2) {
|
||||
mixed = true;
|
||||
res.oldKey = key;
|
||||
res.oldValue = bigInt(0);
|
||||
res.isOld0 = true;
|
||||
rtNew = bigInt.zero;
|
||||
} else {
|
||||
throw new Error("Invalid node. Database corrupted");
|
||||
}
|
||||
} else {
|
||||
rtNew = bigInt.zero;
|
||||
res.oldKey = key;
|
||||
res.oldValue = bigInt(0);
|
||||
res.isOld0 = true;
|
||||
}
|
||||
|
||||
const keyBits = this._splitBits(key);
|
||||
|
||||
for (let level = resFind.siblings.length - 1; level >= 0; level--) {
|
||||
let newSibling = resFind.siblings[level];
|
||||
if (level == resFind.siblings.length - 1 && !res.isOld0) {
|
||||
newSibling = bigInt.zero;
|
||||
}
|
||||
const oldSibling = resFind.siblings[level];
|
||||
if (keyBits[level]) {
|
||||
rtOld = hash0(oldSibling, rtOld);
|
||||
} else {
|
||||
rtOld = hash0(rtOld, oldSibling);
|
||||
}
|
||||
dels.push(rtOld);
|
||||
if (!newSibling.isZero()) {
|
||||
mixed = true;
|
||||
}
|
||||
|
||||
if (mixed) {
|
||||
res.siblings.unshift(resFind.siblings[level]);
|
||||
let newNode;
|
||||
if (keyBits[level]) {
|
||||
newNode = [newSibling, rtNew];
|
||||
} else {
|
||||
newNode = [rtNew, newSibling];
|
||||
}
|
||||
rtNew = hash0(newNode[0], newNode[1]);
|
||||
ins.push([rtNew, newNode]);
|
||||
}
|
||||
}
|
||||
|
||||
await this.db.multiIns(ins);
|
||||
await this.db.setRoot(rtNew);
|
||||
this.root = rtNew;
|
||||
await this.db.multiDel(dels);
|
||||
|
||||
res.newRoot = rtNew;
|
||||
res.oldRoot = rtOld;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
async insert(_key, _value) {
|
||||
const key = bigInt(_key);
|
||||
const value = bigInt(_value);
|
||||
let addedOne = false;
|
||||
const res = {};
|
||||
res.oldRoot = this.root;
|
||||
const newKeyBits = this._splitBits(key);
|
||||
|
||||
let rtOld;
|
||||
|
||||
const resFind = await this.find(key);
|
||||
|
||||
if (resFind.found) throw new Error("Key already exists");
|
||||
|
||||
res.siblings = resFind.siblings;
|
||||
let mixed;
|
||||
|
||||
if (!resFind.isOld0) {
|
||||
const oldKeyits = this._splitBits(resFind.notFoundKey);
|
||||
for (let i = res.siblings.length; oldKeyits[i] == newKeyBits[i]; i++) {
|
||||
res.siblings.push(bigInt.zero);
|
||||
}
|
||||
rtOld = hash1(resFind.notFoundKey, resFind.notFoundValue);
|
||||
res.siblings.push(rtOld);
|
||||
addedOne = true;
|
||||
mixed = false;
|
||||
} else if (res.siblings.length > 0) {
|
||||
mixed = true;
|
||||
rtOld = bigInt.zero;
|
||||
}
|
||||
|
||||
const inserts = [];
|
||||
const dels = [];
|
||||
|
||||
let rt = hash1(key, value);
|
||||
inserts.push([rt, [1, key, value]]);
|
||||
|
||||
for (let i = res.siblings.length - 1; i >= 0; i--) {
|
||||
if (i < res.siblings.length - 1 && !res.siblings[i].isZero()) {
|
||||
mixed = true;
|
||||
}
|
||||
if (mixed) {
|
||||
const oldSibling = resFind.siblings[i];
|
||||
if (newKeyBits[i]) {
|
||||
rtOld = hash0(oldSibling, rtOld);
|
||||
} else {
|
||||
rtOld = hash0(rtOld, oldSibling);
|
||||
}
|
||||
dels.push(rtOld);
|
||||
}
|
||||
|
||||
let newRt;
|
||||
if (newKeyBits[i]) {
|
||||
newRt = hash0(res.siblings[i], rt);
|
||||
inserts.push([newRt, [res.siblings[i], rt]]);
|
||||
} else {
|
||||
newRt = hash0(rt, res.siblings[i]);
|
||||
inserts.push([newRt, [rt, res.siblings[i]]]);
|
||||
}
|
||||
rt = newRt;
|
||||
}
|
||||
|
||||
if (addedOne) res.siblings.pop();
|
||||
while (res.siblings.length > 0 && res.siblings[res.siblings.length - 1].isZero()) {
|
||||
res.siblings.pop();
|
||||
}
|
||||
res.oldKey = resFind.notFoundKey;
|
||||
res.oldValue = resFind.notFoundValue;
|
||||
res.newRoot = rt;
|
||||
res.isOld0 = resFind.isOld0;
|
||||
|
||||
await this.db.multiIns(inserts);
|
||||
await this.db.setRoot(rt);
|
||||
this.root = rt;
|
||||
await this.db.multiDel(dels);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
async find(key) {
|
||||
const keyBits = this._splitBits(key);
|
||||
return await this._find(key, keyBits, this.root, 0);
|
||||
}
|
||||
|
||||
async _find(key, keyBits, root, level) {
|
||||
if (typeof root === "undefined") root = this.root;
|
||||
|
||||
let res;
|
||||
if (root.isZero()) {
|
||||
res = {
|
||||
found: false,
|
||||
siblings: [],
|
||||
notFoundKey: key,
|
||||
notFoundValue: bigInt.zero,
|
||||
isOld0: true,
|
||||
};
|
||||
return res;
|
||||
}
|
||||
|
||||
const record = await this.db.get(root);
|
||||
|
||||
if (record.length == 3 && record[0].equals(bigInt.one)) {
|
||||
if (record[1].equals(key)) {
|
||||
res = {
|
||||
found: true,
|
||||
siblings: [],
|
||||
foundValue: record[2],
|
||||
isOld0: false,
|
||||
};
|
||||
} else {
|
||||
res = {
|
||||
found: false,
|
||||
siblings: [],
|
||||
notFoundKey: record[1],
|
||||
notFoundValue: record[2],
|
||||
isOld0: false,
|
||||
};
|
||||
}
|
||||
} else {
|
||||
if (keyBits[level] == 0) {
|
||||
res = await this._find(key, keyBits, record[0], level + 1);
|
||||
res.siblings.unshift(record[1]);
|
||||
} else {
|
||||
res = await this._find(key, keyBits, record[1], level + 1);
|
||||
res.siblings.unshift(record[0]);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
async function loadFromFile(fileName) {}
|
||||
|
||||
async function newMemEmptyTrie() {
|
||||
const db = new SMTMemDB();
|
||||
const rt = await db.getRoot();
|
||||
const smt = new SMT(db, rt);
|
||||
return smt;
|
||||
}
|
||||
|
||||
module.exports.loadFromFile = loadFromFile;
|
||||
module.exports.newMemEmptyTrie = newMemEmptyTrie;
|
||||
module.exports.SMT = SMT;
|
||||
module.exports.SMTMemDB = SMTMemDB;
|
||||
@ -1,10 +0,0 @@
|
||||
const mimc7 = require("./mimc7");
|
||||
const bigInt = require("@tornado/snarkjs").bigInt;
|
||||
|
||||
exports.hash0 = function (left, right) {
|
||||
return mimc7.multiHash(left, right);
|
||||
};
|
||||
|
||||
exports.hash1 = function (key, value) {
|
||||
return mimc7.multiHash([key, value], bigInt.one);
|
||||
};
|
||||
@ -1,10 +0,0 @@
|
||||
const poseidon = require("./poseidon");
|
||||
const bigInt = require("@tornado/snarkjs").bigInt;
|
||||
|
||||
exports.hash0 = function (left, right) {
|
||||
return poseidon([left, right]);
|
||||
};
|
||||
|
||||
exports.hash1 = function (key, value) {
|
||||
return poseidon([key, value, bigInt.one]);
|
||||
};
|
||||
@ -1,58 +0,0 @@
|
||||
const bigInt = require("@tornado/snarkjs").bigInt;
|
||||
|
||||
class SMTMemDb {
|
||||
constructor() {
|
||||
this.nodes = {};
|
||||
this.root = bigInt(0);
|
||||
}
|
||||
|
||||
async getRoot() {
|
||||
return this.root;
|
||||
}
|
||||
|
||||
_key2str(k) {
|
||||
// const keyS = bigInt(key).leInt2Buff(32).toString("hex");
|
||||
const keyS = bigInt(k).toString();
|
||||
return keyS;
|
||||
}
|
||||
|
||||
_normalize(n) {
|
||||
for (let i = 0; i < n.length; i++) {
|
||||
n[i] = bigInt(n[i]);
|
||||
}
|
||||
}
|
||||
|
||||
async get(key) {
|
||||
const keyS = this._key2str(key);
|
||||
return this.nodes[keyS];
|
||||
}
|
||||
|
||||
async multiGet(keys) {
|
||||
const promises = [];
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
promises.push(this.get(keys[i]));
|
||||
}
|
||||
return await Promise.all(promises);
|
||||
}
|
||||
|
||||
async setRoot(rt) {
|
||||
this.root = rt;
|
||||
}
|
||||
|
||||
async multiIns(inserts) {
|
||||
for (let i = 0; i < inserts.length; i++) {
|
||||
const keyS = this._key2str(inserts[i][0]);
|
||||
this._normalize(inserts[i][1]);
|
||||
this.nodes[keyS] = inserts[i][1];
|
||||
}
|
||||
}
|
||||
|
||||
async multiDel(dels) {
|
||||
for (let i = 0; i < dels.length; i++) {
|
||||
const keyS = this._key2str(dels[i]);
|
||||
delete this.nodes[keyS];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = SMTMemDb;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user