mirror of
https://github.com/arnaucube/circomlib.git
synced 2026-02-07 11:16:45 +01:00
Merge other basic circuits here
This commit is contained in:
14
circuits/aliascheck.circom
Normal file
14
circuits/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
circuits/babyjub.circom
Normal file
64
circuits/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;
|
||||
}
|
||||
93
circuits/binsum.circom
Normal file
93
circuits/binsum.circom
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
function nbits(a) {
|
||||
var n = 1;
|
||||
var r = 0;
|
||||
while (n-1<a) {
|
||||
r++;
|
||||
n *= 2;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
72
circuits/bitify.circom
Normal file
72
circuits/bitify.circom
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
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";
|
||||
|
||||
|
||||
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 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 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;
|
||||
}
|
||||
55
circuits/comparators.circom
Normal file
55
circuits/comparators.circom
Normal file
@@ -0,0 +1,55 @@
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
// 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;
|
||||
}
|
||||
56
circuits/compconstant.circom
Normal file
56
circuits/compconstant.circom
Normal file
@@ -0,0 +1,56 @@
|
||||
|
||||
include "bitify.circom";
|
||||
|
||||
// Returns 1 if in (in binary) > ct
|
||||
|
||||
template CompConstant(ct) {
|
||||
signal input in[254];
|
||||
signal output out;
|
||||
|
||||
signal parts[127];
|
||||
signal sout;
|
||||
|
||||
var clsb;
|
||||
var cmsb;
|
||||
var slsb;
|
||||
var smsb;
|
||||
|
||||
var sum=0;
|
||||
|
||||
var b = (1 << 128) -1;
|
||||
var a = 1;
|
||||
var e = 1;
|
||||
var i;
|
||||
|
||||
for (i=0;i<127; i++) {
|
||||
clsb = (ct >> (i*2)) & 1;
|
||||
cmsb = (ct >> (i*2+1)) & 1;
|
||||
slsb = in[i*2];
|
||||
smsb = in[i*2+1];
|
||||
|
||||
|
||||
if ((cmsb==0)&(clsb==0)) {
|
||||
parts[i] <== -b*smsb*slsb + b*smsb + b*slsb;
|
||||
} else if ((cmsb==0)&(clsb==1)) {
|
||||
parts[i] <== a*smsb*slsb - a*slsb + b*smsb - a*smsb + a;
|
||||
} else if ((cmsb==1)&(clsb==0)) {
|
||||
parts[i] <== b*smsb*slsb - a*smsb + a;
|
||||
} else {
|
||||
parts[i] <== -a*smsb*slsb + a;
|
||||
}
|
||||
|
||||
sum = sum + parts[i];
|
||||
|
||||
b = b -e;
|
||||
a = a +e;
|
||||
e = e*2;
|
||||
}
|
||||
|
||||
sout <== sum;
|
||||
|
||||
component num2bits = Num2Bits(135);
|
||||
|
||||
num2bits.in <== sout;
|
||||
|
||||
out <== num2bits.out[127];
|
||||
}
|
||||
119
circuits/eddsa.circom
Normal file
119
circuits/eddsa.circom
Normal file
@@ -0,0 +1,119 @@
|
||||
include "compconstant.circom";
|
||||
include "pointbits.circom";
|
||||
include "pedersen.circom";
|
||||
include "escalarmulany.circom";
|
||||
include "escalarmulfix.circom";
|
||||
|
||||
template EdDSAVerifier(n) {
|
||||
signal input msg[n];
|
||||
|
||||
signal input A[256];
|
||||
signal input R8[256];
|
||||
signal input S[256];
|
||||
|
||||
signal Ax;
|
||||
signal Ay;
|
||||
|
||||
signal R8x;
|
||||
signal R8y;
|
||||
|
||||
var i;
|
||||
|
||||
// Ensure S<Subgroup Order
|
||||
|
||||
component compConstant = CompConstant(2736030358979909402780800718157159386076813972158567259200215660948447373040);
|
||||
|
||||
for (i=0; i<254; i++) {
|
||||
S[i] ==> compConstant.in[i];
|
||||
}
|
||||
compConstant.out === 0;
|
||||
S[254] === 0;
|
||||
S[255] === 0;
|
||||
|
||||
// Convert A to Field elements (And verify A)
|
||||
|
||||
component bits2pointA = Bits2Point_Strict();
|
||||
|
||||
for (i=0; i<256; i++) {
|
||||
bits2pointA.in[i] <== A[i];
|
||||
}
|
||||
Ax <== bits2pointA.out[0];
|
||||
Ay <== bits2pointA.out[1];
|
||||
|
||||
// Convert R8 to Field elements (And verify R8)
|
||||
|
||||
component bits2pointR8 = Bits2Point_Strict();
|
||||
|
||||
for (i=0; i<256; i++) {
|
||||
bits2pointR8.in[i] <== R8[i];
|
||||
}
|
||||
R8x <== bits2pointR8.out[0];
|
||||
R8y <== bits2pointR8.out[1];
|
||||
|
||||
// Calculate the h = H(R,A, msg)
|
||||
|
||||
component hash = Pedersen(512+n);
|
||||
|
||||
for (i=0; i<256; i++) {
|
||||
hash.in[i] <== R8[i];
|
||||
hash.in[256+i] <== A[i];
|
||||
}
|
||||
for (i=0; i<n; i++) {
|
||||
hash.in[512+i] <== msg[i];
|
||||
}
|
||||
|
||||
component point2bitsH = Point2Bits_Strict();
|
||||
point2bitsH.in[0] <== hash.out[0];
|
||||
point2bitsH.in[1] <== hash.out[1];
|
||||
|
||||
// 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(256);
|
||||
for (i=0; i<256; i++) {
|
||||
mulAny.e[i] <== point2bitsH.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 = [
|
||||
17777552123799933955779906779655732241715742912184938656739573121738514868268,
|
||||
2626589144620713026669568689430873010625803728049924121243784502389097019475
|
||||
];
|
||||
component mulFix = EscalarMulFix(256, BASE8);
|
||||
for (i=0; i<256; i++) {
|
||||
mulFix.e[i] <== S[i];
|
||||
}
|
||||
|
||||
// Do the comparation left == right
|
||||
|
||||
mulFix.out[0] === addRight.xout;
|
||||
mulFix.out[1] === addRight.yout;
|
||||
}
|
||||
146
circuits/escalarmul.circom
Normal file
146
circuits/escalarmul.circom
Normal file
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
|
||||
┏━━━━━━━━━━━┓
|
||||
┃ ┃
|
||||
┃ ┃
|
||||
(inx, iny) ══════════════════════════════════════════▶┃ EC Point ┃
|
||||
┃ ╠═▶ (outx, outy)
|
||||
╔══▶┃ Adder ┃
|
||||
║ ┃ ┃
|
||||
║ ┃ ┃
|
||||
║ ┃ ┃
|
||||
┏━━━━━━━━━━━┓ ┏━━━━━━━━━━━━┓ ║ ┗━━━━━━━━━━━┛
|
||||
┃ ┃ ┃ ┃ ║
|
||||
┃ ┃ ┃ ┃ ║
|
||||
┃ ╠═══(p0x,p0y)═══▶┃ ┃ ║
|
||||
┃ ╠═══(p1x,p1y)═══▶┃ ┃ ║
|
||||
┃ ╠═══(p2x,p2y)═══▶┃ ┃ ║
|
||||
┃ ╠═══(p3x,p3y)═══▶┃ ┃ ║
|
||||
┃ ╠═══(p4x,p4y)═══▶┃ ┃ ║
|
||||
┃ ╠═══(p5x,p5y)═══▶┃ ┃ ║
|
||||
┃ ╠═══(p6x,p6y)═══▶┃ ┃ ║
|
||||
┃ Constant ╠═══(p7x,p7y)═══▶┃ ┃ ║
|
||||
┃ Points ┃ ┃ Mux4 ╠══╝
|
||||
┃ ╠═══(p8x,p8y)═══▶┃ ┃
|
||||
┃ ╠═══(p9x,p9y)═══▶┃ ┃
|
||||
┃ ╠══(p10x,p10y)══▶┃ ┃
|
||||
┃ ╠══(p11x,p11y)══▶┃ ┃
|
||||
┃ ╠══(p12x,p12y)══▶┃ ┃
|
||||
┃ ╠══(p13x,p13y)══▶┃ ┃
|
||||
┃ ╠══(p14x,p14y)══▶┃ ┃
|
||||
┃ ╠══(p15x,p15y)══▶┃ ┃
|
||||
┃ ┃ ┃ ┃
|
||||
┃ ┃ ┃ ┃
|
||||
┗━━━━━━━━━━━┛ ┗━━━━━━━━━━━━┛
|
||||
▲ ▲ ▲ ▲
|
||||
│ │ │ │
|
||||
s0 ─────────────────────────────────┘ │ │ │
|
||||
s1 ────────────────────────────────────┘ │ │
|
||||
s2 ───────────────────────────────────────┘ │
|
||||
s3 ──────────────────────────────────────────┘
|
||||
|
||||
|
||||
*/
|
||||
|
||||
include "mux4.circom";
|
||||
include "escalarmulw4table.circom";
|
||||
include "babyjub.circom";
|
||||
|
||||
template EscalarMulWindow(base, k) {
|
||||
|
||||
signal input in[2];
|
||||
signal input sel[4];
|
||||
signal output out[2];
|
||||
|
||||
component table;
|
||||
component mux;
|
||||
component adder;
|
||||
|
||||
var i;
|
||||
|
||||
table = EscalarMulW4Table(base, k);
|
||||
mux = MultiMux4(2);
|
||||
adder = BabyAdd();
|
||||
|
||||
for (i=0; i<4; i++) {
|
||||
sel[i] ==> mux.s[i];
|
||||
}
|
||||
|
||||
for (i=0; i<16; i++) {
|
||||
table.out[i][0] ==> mux.c[0][i];
|
||||
table.out[i][1] ==> mux.c[1][i];
|
||||
}
|
||||
|
||||
in[0] ==> adder.x1;
|
||||
in[1] ==> adder.y1;
|
||||
|
||||
mux.out[0] ==> adder.x2;
|
||||
mux.out[1] ==> adder.y2;
|
||||
|
||||
adder.xout ==> out[0];
|
||||
adder.yout ==> out[1];
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
|
||||
┏━━━━━━━━━┓ ┏━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━━━━━┓
|
||||
┃ ┃ ┃ ┃ ┃ ┃
|
||||
inp ════▶┃Window(0)┃═════▶┃Window(1)┃════════ . . . . ═════════▶┃ Window(nBlocks-1) ┃═════▶ out
|
||||
┃ ┃ ┃ ┃ ┃ ┃
|
||||
┗━━━━━━━━━┛ ┗━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━━━━━┛
|
||||
▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
|
||||
in[0]─────────┘ │ │ │ │ │ │ │ │ │ │ │
|
||||
in[1]───────────┘ │ │ │ │ │ │ │ │ │ │
|
||||
in[2]─────────────┘ │ │ │ │ │ │ │ 0 0
|
||||
in[3]───────────────┘ │ │ │ │ │ │
|
||||
in[4]──────────────────────────┘ │ │ │ │ │
|
||||
in[5]────────────────────────────┘ │ │ │ │
|
||||
in[6]──────────────────────────────┘ │ │ │
|
||||
in[7]────────────────────────────────┘ │ │
|
||||
. │ │
|
||||
. │ │
|
||||
in[n-2]─────────────────────────────────────────────────────────────────────┘ │
|
||||
in[n-1]───────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
*/
|
||||
|
||||
template EscalarMul(n, base) {
|
||||
signal input in[n];
|
||||
signal input inp[2]; // Point input to be added
|
||||
signal output out[2];
|
||||
|
||||
var nBlocks = ((n-1)>>2)+1;
|
||||
var i;
|
||||
var j;
|
||||
|
||||
component windows[nBlocks];
|
||||
|
||||
// Construct the windows
|
||||
for (i=0; i<nBlocks; i++) {
|
||||
windows[i] = EscalarMulWindow(base, i);
|
||||
}
|
||||
|
||||
// Connect the selectors
|
||||
for (i=0; i<nBlocks; i++) {
|
||||
for (j=0; j<4; j++) {
|
||||
if (i*4+j >= n) {
|
||||
windows[i].sel[j] <== 0;
|
||||
} else {
|
||||
windows[i].sel[j] <== in[i*4+j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Start with generator
|
||||
windows[0].in[0] <== inp[0];
|
||||
windows[0].in[1] <== inp[1];
|
||||
|
||||
for(i=0; i<nBlocks-1; i++) {
|
||||
windows[i].out[0] ==> windows[i+1].in[0];
|
||||
windows[i].out[1] ==> windows[i+1].in[1];
|
||||
}
|
||||
|
||||
windows[nBlocks-1].out[0] ==> out[0];
|
||||
windows[nBlocks-1].out[1] ==> out[1];
|
||||
}
|
||||
174
circuits/escalarmulany.circom
Normal file
174
circuits/escalarmulany.circom
Normal file
@@ -0,0 +1,174 @@
|
||||
|
||||
include "montgomery.circom";
|
||||
include "babyjub.circom";
|
||||
|
||||
template Multiplexor2() {
|
||||
signal input sel;
|
||||
signal input in[2][2];
|
||||
signal output out[2];
|
||||
|
||||
out[0] <== (in[1][0] - in[0][0])*sel + in[0][0];
|
||||
out[1] <== (in[1][1] - in[0][1])*sel + in[0][1];
|
||||
}
|
||||
|
||||
template BitElementMulAny() {
|
||||
signal input sel;
|
||||
signal input dblIn[2];
|
||||
signal input addIn[2];
|
||||
signal output dblOut[2];
|
||||
signal output addOut[2];
|
||||
|
||||
component doubler = MontgomeryDouble();
|
||||
component adder = MontgomeryAdd();
|
||||
component selector = Multiplexor2();
|
||||
|
||||
|
||||
sel ==> selector.sel;
|
||||
|
||||
dblIn[0] ==> doubler.in[0];
|
||||
dblIn[1] ==> doubler.in[1];
|
||||
doubler.out[0] ==> adder.in1[0];
|
||||
doubler.out[1] ==> adder.in1[1];
|
||||
addIn[0] ==> adder.in2[0];
|
||||
addIn[1] ==> adder.in2[1];
|
||||
addIn[0] ==> selector.in[0][0];
|
||||
addIn[1] ==> selector.in[0][1];
|
||||
adder.out[0] ==> selector.in[1][0];
|
||||
adder.out[1] ==> selector.in[1][1];
|
||||
|
||||
doubler.out[0] ==> dblOut[0];
|
||||
doubler.out[1] ==> dblOut[1];
|
||||
selector.out[0] ==> addOut[0];
|
||||
selector.out[1] ==> addOut[1];
|
||||
}
|
||||
|
||||
// p is montgomery point
|
||||
// n must be <= 248
|
||||
// returns out in twisted edwards
|
||||
// Double is in montgomery to be linked;
|
||||
|
||||
template SegmentMulAny(n) {
|
||||
signal input e[n];
|
||||
signal input p[2];
|
||||
signal output out[2];
|
||||
signal output dbl[2];
|
||||
|
||||
component bits[n-1];
|
||||
|
||||
component e2m = Edwards2Montgomery();
|
||||
|
||||
p[0] ==> e2m.in[0];
|
||||
p[1] ==> e2m.in[1];
|
||||
|
||||
var i;
|
||||
|
||||
bits[0] = BitElementMulAny();
|
||||
e2m.out[0] ==> bits[0].dblIn[0]
|
||||
e2m.out[1] ==> bits[0].dblIn[1]
|
||||
e2m.out[0] ==> bits[0].addIn[0]
|
||||
e2m.out[1] ==> bits[0].addIn[1]
|
||||
e[1] ==> bits[0].sel;
|
||||
|
||||
for (i=1; i<n-1; i++) {
|
||||
bits[i] = BitElementMulAny();
|
||||
|
||||
bits[i-1].dblOut[0] ==> bits[i].dblIn[0]
|
||||
bits[i-1].dblOut[1] ==> bits[i].dblIn[1]
|
||||
bits[i-1].addOut[0] ==> bits[i].addIn[0]
|
||||
bits[i-1].addOut[1] ==> bits[i].addIn[1]
|
||||
e[i+1] ==> bits[i].sel;
|
||||
}
|
||||
|
||||
bits[n-2].dblOut[0] ==> dbl[0];
|
||||
bits[n-2].dblOut[1] ==> dbl[1];
|
||||
|
||||
component m2e = Montgomery2Edwards();
|
||||
|
||||
bits[n-2].addOut[0] ==> m2e.in[0];
|
||||
bits[n-2].addOut[1] ==> m2e.in[1];
|
||||
|
||||
component eadder = BabyAdd();
|
||||
|
||||
m2e.out[0] ==> eadder.x1;
|
||||
m2e.out[1] ==> eadder.y1;
|
||||
-p[0] ==> eadder.x2;
|
||||
p[1] ==> eadder.y2;
|
||||
|
||||
component lastSel = Multiplexor2();
|
||||
|
||||
e[0] ==> lastSel.sel;
|
||||
eadder.xout ==> lastSel.in[0][0];
|
||||
eadder.yout ==> lastSel.in[0][1];
|
||||
m2e.out[0] ==> lastSel.in[1][0];
|
||||
m2e.out[1] ==> lastSel.in[1][1];
|
||||
|
||||
lastSel.out[0] ==> out[0];
|
||||
lastSel.out[1] ==> out[1];
|
||||
}
|
||||
|
||||
// This function assumes that p is in the subgroup and it is different to 0
|
||||
|
||||
template EscalarMulAny(n) {
|
||||
signal input e[n]; // Input in binary format
|
||||
signal input p[2]; // Point (Twisted format)
|
||||
signal output out[2]; // Point (Twisted format)
|
||||
|
||||
var nsegments = (n-1)\148 +1;
|
||||
var nlastsegment = n - (nsegments-1)*148;
|
||||
|
||||
component segments[nsegments];
|
||||
component doublers[nsegments-1];
|
||||
component m2e[nsegments-1];
|
||||
component adders[nsegments-1];
|
||||
|
||||
var s;
|
||||
var i;
|
||||
var nseg;
|
||||
|
||||
for (s=0; s<nsegments; s++) {
|
||||
|
||||
nseg = (s < nsegments-1) ? 148 : nlastsegment;
|
||||
|
||||
segments[s] = SegmentMulAny(nseg);
|
||||
|
||||
for (i=0; i<nseg; i++) {
|
||||
e[s*148+i] ==> segments[s].e[i];
|
||||
}
|
||||
|
||||
if (s==0) {
|
||||
p[0] ==> segments[s].p[0];
|
||||
p[1] ==> segments[s].p[1];
|
||||
} else {
|
||||
doublers[s-1] = MontgomeryDouble();
|
||||
m2e[s-1] = Montgomery2Edwards();
|
||||
adders[s-1] = BabyAdd();
|
||||
|
||||
segments[s-1].dbl[0] ==> doublers[s-1].in[0];
|
||||
segments[s-1].dbl[1] ==> doublers[s-1].in[1];
|
||||
|
||||
doublers[s-1].out[0] ==> m2e[s-1].in[0];
|
||||
doublers[s-1].out[1] ==> m2e[s-1].in[1];
|
||||
|
||||
m2e[s-1].out[0] ==> segments[s].p[0];
|
||||
m2e[s-1].out[1] ==> segments[s].p[1];
|
||||
|
||||
if (s==1) {
|
||||
segments[s-1].out[0] ==> adders[s-1].x1;
|
||||
segments[s-1].out[1] ==> adders[s-1].y1;
|
||||
} else {
|
||||
adders[s-2].xout ==> adders[s-1].x1;
|
||||
adders[s-2].yout ==> adders[s-1].y1;
|
||||
}
|
||||
segments[s].out[0] ==> adders[s-1].x2;
|
||||
segments[s].out[1] ==> adders[s-1].y2;
|
||||
}
|
||||
}
|
||||
|
||||
if (nsegments == 1) {
|
||||
segments[0].out[0] ==> out[0];
|
||||
segments[0].out[1] ==> out[1];
|
||||
} else {
|
||||
adders[nsegments-2].xout ==> out[0];
|
||||
adders[nsegments-2].yout ==> out[1];
|
||||
}
|
||||
}
|
||||
258
circuits/escalarmulfix.circom
Normal file
258
circuits/escalarmulfix.circom
Normal file
@@ -0,0 +1,258 @@
|
||||
include "mux3.circom";
|
||||
include "montgomery.circom";
|
||||
include "babyjub.circom";
|
||||
|
||||
/*
|
||||
Window of 3 elements, it calculates
|
||||
out = base + base*in[0] + 2*base*in[1] + 4*base*in[2]
|
||||
out4 = 4*base
|
||||
|
||||
The result should be compensated.
|
||||
*/
|
||||
template WindowMulFix() {
|
||||
signal input in[3];
|
||||
signal input base[2];
|
||||
signal output out[2];
|
||||
signal output out8[2]; // Returns 8*Base (To be linked)
|
||||
|
||||
component mux = MultiMux3(2);
|
||||
|
||||
mux.s[0] <== in[0];
|
||||
mux.s[1] <== in[1];
|
||||
mux.s[2] <== in[2];
|
||||
|
||||
component dbl2 = MontgomeryDouble();
|
||||
component adr3 = MontgomeryAdd();
|
||||
component adr4 = MontgomeryAdd();
|
||||
component adr5 = MontgomeryAdd();
|
||||
component adr6 = MontgomeryAdd();
|
||||
component adr7 = MontgomeryAdd();
|
||||
component adr8 = MontgomeryAdd();
|
||||
|
||||
// in[0] -> 1*BASE
|
||||
|
||||
mux.c[0][0] <== base[0];
|
||||
mux.c[1][0] <== base[1];
|
||||
|
||||
// in[1] -> 2*BASE
|
||||
dbl2.in[0] <== base[0];
|
||||
dbl2.in[1] <== base[1];
|
||||
mux.c[0][1] <== dbl2.out[0];
|
||||
mux.c[1][1] <== dbl2.out[1];
|
||||
|
||||
// in[2] -> 3*BASE
|
||||
adr3.in1[0] <== base[0];
|
||||
adr3.in1[1] <== base[1];
|
||||
adr3.in2[0] <== dbl2.out[0];
|
||||
adr3.in2[1] <== dbl2.out[1];
|
||||
mux.c[0][2] <== adr3.out[0];
|
||||
mux.c[1][2] <== adr3.out[1];
|
||||
|
||||
// in[3] -> 4*BASE
|
||||
adr4.in1[0] <== base[0];
|
||||
adr4.in1[1] <== base[1];
|
||||
adr4.in2[0] <== adr3.out[0];
|
||||
adr4.in2[1] <== adr3.out[1];
|
||||
mux.c[0][3] <== adr4.out[0];
|
||||
mux.c[1][3] <== adr4.out[1];
|
||||
|
||||
// in[4] -> 5*BASE
|
||||
adr5.in1[0] <== base[0];
|
||||
adr5.in1[1] <== base[1];
|
||||
adr5.in2[0] <== adr4.out[0];
|
||||
adr5.in2[1] <== adr4.out[1];
|
||||
mux.c[0][4] <== adr5.out[0];
|
||||
mux.c[1][4] <== adr5.out[1];
|
||||
|
||||
// in[5] -> 6*BASE
|
||||
adr6.in1[0] <== base[0];
|
||||
adr6.in1[1] <== base[1];
|
||||
adr6.in2[0] <== adr5.out[0];
|
||||
adr6.in2[1] <== adr5.out[1];
|
||||
mux.c[0][5] <== adr6.out[0];
|
||||
mux.c[1][5] <== adr6.out[1];
|
||||
|
||||
// in[6] -> 7*BASE
|
||||
adr7.in1[0] <== base[0];
|
||||
adr7.in1[1] <== base[1];
|
||||
adr7.in2[0] <== adr6.out[0];
|
||||
adr7.in2[1] <== adr6.out[1];
|
||||
mux.c[0][6] <== adr7.out[0];
|
||||
mux.c[1][6] <== adr7.out[1];
|
||||
|
||||
// in[7] -> 8*BASE
|
||||
adr8.in1[0] <== base[0];
|
||||
adr8.in1[1] <== base[1];
|
||||
adr8.in2[0] <== adr7.out[0];
|
||||
adr8.in2[1] <== adr7.out[1];
|
||||
mux.c[0][7] <== adr8.out[0];
|
||||
mux.c[1][7] <== adr8.out[1];
|
||||
|
||||
out8[0] <== adr8.out[0];
|
||||
out8[1] <== adr8.out[1];
|
||||
|
||||
out[0] <== mux.out[0];
|
||||
out[1] <== mux.out[1];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This component does a multiplication of a escalar times a fix base
|
||||
Signals:
|
||||
e: The scalar in bits
|
||||
base: the base point in edwards format
|
||||
out: The result
|
||||
dbl: Point in Edwards to be linked to the next segment.
|
||||
*/
|
||||
|
||||
template SegmentMulFix(nWindows) {
|
||||
signal input e[nWindows*3];
|
||||
signal input base[2];
|
||||
signal output out[2];
|
||||
signal output dbl[2];
|
||||
|
||||
var i;
|
||||
var j;
|
||||
|
||||
// Convert the base to montgomery
|
||||
|
||||
component e2m = Edwards2Montgomery();
|
||||
e2m.in[0] <== base[0];
|
||||
e2m.in[1] <== base[1];
|
||||
|
||||
component windows[nWindows];
|
||||
component adders[nWindows-1];
|
||||
component cadders[nWindows-1];
|
||||
for (i=0; i<nWindows; i++) {
|
||||
windows[i] = WindowMulFix();
|
||||
if (i==0) {
|
||||
windows[i].base[0] <== e2m.out[0];
|
||||
windows[i].base[1] <== e2m.out[1];
|
||||
} else {
|
||||
windows[i].base[0] <== windows[i-1].out8[0];
|
||||
windows[i].base[1] <== windows[i-1].out8[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];
|
||||
}
|
||||
}
|
||||
|
||||
component m2e = Montgomery2Edwards();
|
||||
component cm2e = Montgomery2Edwards();
|
||||
|
||||
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];
|
||||
cAdd.y1 <== m2e.out[1];
|
||||
cAdd.x2 <== -cm2e.out[0];
|
||||
cAdd.y2 <== cm2e.out[1];
|
||||
|
||||
|
||||
cAdd.xout ==> out[0];
|
||||
cAdd.yout ==> out[1];
|
||||
|
||||
windows[nWindows-1].out8[0] ==> dbl[0];
|
||||
windows[nWindows-1].out8[1] ==> dbl[1];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This component multiplies a escalar times a fixed point BASE (twisted edwards format)
|
||||
Signals
|
||||
e: The escalar in binary format
|
||||
out: The output point in twisted edwards
|
||||
*/
|
||||
template EscalarMulFix(n, BASE) {
|
||||
signal input e[n]; // Input in binary format
|
||||
signal output out[2]; // Point (Twisted format)
|
||||
|
||||
var nsegments = (n-1)\249 +1;
|
||||
var nlastsegment = n - (nsegments-1)*249;
|
||||
|
||||
component segments[nsegments];
|
||||
|
||||
component m2e[nsegments-1];
|
||||
component adders[nsegments-1];
|
||||
|
||||
var s;
|
||||
var i;
|
||||
var nseg;
|
||||
var nWindows
|
||||
|
||||
for (s=0; s<nsegments; s++) {
|
||||
|
||||
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*249+i];
|
||||
}
|
||||
|
||||
for (i = nseg; i<nWindows*3; i++) {
|
||||
segments[s].e[i] <== 0;
|
||||
}
|
||||
|
||||
if (s==0) {
|
||||
segments[s].base[0] <== BASE[0];
|
||||
segments[s].base[1] <== BASE[1];
|
||||
} else {
|
||||
m2e[s-1] = Montgomery2Edwards();
|
||||
adders[s-1] = BabyAdd();
|
||||
|
||||
segments[s-1].dbl[0] ==> m2e[s-1].in[0];
|
||||
segments[s-1].dbl[1] ==> m2e[s-1].in[1];
|
||||
|
||||
m2e[s-1].out[0] ==> segments[s].base[0];
|
||||
m2e[s-1].out[1] ==> segments[s].base[1];
|
||||
|
||||
if (s==1) {
|
||||
segments[s-1].out[0] ==> adders[s-1].x1;
|
||||
segments[s-1].out[1] ==> adders[s-1].y1;
|
||||
} else {
|
||||
adders[s-2].xout ==> adders[s-1].x1;
|
||||
adders[s-2].yout ==> adders[s-1].y1;
|
||||
}
|
||||
segments[s].out[0] ==> adders[s-1].x2;
|
||||
segments[s].out[1] ==> adders[s-1].y2;
|
||||
}
|
||||
}
|
||||
|
||||
if (nsegments == 1) {
|
||||
segments[0].out[0] ==> out[0];
|
||||
segments[0].out[1] ==> out[1];
|
||||
} else {
|
||||
adders[nsegments-2].xout ==> out[0];
|
||||
adders[nsegments-2].yout ==> out[1];
|
||||
}
|
||||
}
|
||||
30
circuits/escalarmulw4table.circom
Normal file
30
circuits/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];
|
||||
}
|
||||
}
|
||||
67
circuits/gates.circom
Normal file
67
circuits/gates.circom
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
286
circuits/mimc.circom
Normal file
286
circuits/mimc.circom
Normal file
@@ -0,0 +1,286 @@
|
||||
|
||||
|
||||
|
||||
|
||||
template MiMC7(nrounds) {
|
||||
signal input x_in;
|
||||
signal input k;
|
||||
signal output out;
|
||||
|
||||
var c = [
|
||||
0x0000000000000000000000000000000000000000000000000000000000000000,
|
||||
0x2573c33972da08a17b379c84ef2ac8f5b1da7feb7a0f65820f5106065947e745,
|
||||
0x21ac176a3dfade8c2846270deb9bda2c1fa8fe29504ed1abef144ae541da6fb0,
|
||||
0x1fcd4c98bb955979dfaebd9403cc2dd58025fc615a06014feaa543fc9565b744,
|
||||
0x1899ead9379f4e15c5468c709087eeaa61fa8efa361a71dac432c6145bb20d63,
|
||||
0x1b82d1cfcf057d24682f9cc3aab8fcdb35129359b5ba5578eb0fb20885c7c261,
|
||||
0x3023bd978dce3b40760481f90709bfd4b1894665493edc70f0890dd0817ab973,
|
||||
0x217a46b7998bbd8ce17073e7296cef81681da9dc4ca055abaf28345f8bf0cbe7,
|
||||
0x1614c499d51b5125df6214f41cd51ac79e07565171758d80b091b9a3029a5422,
|
||||
0x05dfffcee509e641a30504f9c239340af6cd43cc6b7f03feb65235c4b9bccd86,
|
||||
0x248d5e6f74e607401c9bdc79bd5d2e899028fc26e7db9437c7738e60b7a90b37,
|
||||
0x0dd9d1bbccd01bb58caf364938ccc55e74953f0ae52ee145beaecbfbe683e777,
|
||||
0x0bd18dd6afccd76ae3a159cac4bb1ec1158def927f5b8a529a4697ba3294805b,
|
||||
0x00ce7b4a2643c23fab142b955293492bda5b775cea46ef3e9bc803301935d987,
|
||||
0x24927ca97213de091fac3153a76dd4dd6c9933b1bc298148ece271dd80623f8d,
|
||||
0x035e884c65a79c58a895b27d4ef671b1661dac72281f4c4458ae2a0be14c4555,
|
||||
0x008427f6c5e2fa34dc787fcef8cdf0ae2b5686cb80cc069a59a9b8af37ec0d42,
|
||||
0x01e0bf5c000e7390c86635a3d63c2b42362c2f43f8ea2cdfab4728f901443dc1,
|
||||
0x05e5f9e17e59bb89922f0c52aaef5728129fe284e4c2cea2b3f50d9f1bf04280,
|
||||
0x1ed43af042061416a934f6d4afe097b32b42a916075441fbaf2016405a03121c,
|
||||
0x05c2929b4c8610d3f2bbc7f0d8046937feb4bdfaca9d6e1434aab696950f0d94,
|
||||
0x0f5df25a785d5fdfaede0ff3e0853a35f66c8b140ca82b1c7648a1496ba902cd,
|
||||
0x1d9177a9c7d2cbcdc6bf2ce3bdb93066598c0c00096084f32a08c00065fcb640,
|
||||
0x0ad36f853cb652ca4d8c87d3a64a2a9f7dd849d5f6dbced160001672661f0257,
|
||||
0x061d5c826fb0716891996013195a349f17e89197e1e0b0826ba0bb3a69ba42e2,
|
||||
0x16603fd47dcb9c87f50541b78211b9d5f57ef5536d888efa4f626e2fbf239089,
|
||||
0x056cee578203bca4df16a390cfa63e85931e6e78d300d8b61128d37028d45813,
|
||||
0x1243ed309d9d4e9371159fb9f9a3245a4cc00b36954bff7c7da88b6c476752cf,
|
||||
0x0ad05b9f6ac744163ceb578e4dc7fd79415e038284e72ee9725dad919f4ddacb,
|
||||
0x0e9feebe1c929460bfb50e7b2055f342858e7f1390e85a117cd0259d3e9d1ed3,
|
||||
0x290888d2474655e8348a0dc2f3c663ff488390ac2ffb8616b8989622cf5e45de,
|
||||
0x1ea4564ef6a12b38236cef7ff9638ace2feb8620d6fc43f00899db7d8857d665,
|
||||
0x0a88eb25fd9e1853a6fb3be2a64d7833d08d6bb471c062f81abd8b83cf1ac184,
|
||||
0x24b95adf13d6e7cddac8aa314cdbc7919e129d2ff4fe25f0e13850b3c355aa49,
|
||||
0x0e8be6948bcc439176fdf51e97933bd4d9aecf6c2a229e10726a941eab8035f3,
|
||||
0x0576ca71206b818ec4fe2c114b1385cb45b0c75a4264344102aacdb1dc75c40d,
|
||||
0x1127019d23d0e8c78a5c920422417be24242f5361b5b9b4c65673c3ca6f5c877,
|
||||
0x03308b8e26f82269cc957ce50c9025bfb1bcadf536e73fcbb3755b31d274c1c7,
|
||||
0x2946f2c0596dffcdc46c9f149b53ee838f37479d156ba9cec0956c6647d632f8,
|
||||
0x02f45b1bf152730a9e598de1cfd6dd29673341513a702563b415c5c71accf46e,
|
||||
0x0f0080f25c9a57ec936c87c99c2ab62f63a5b315dae3351f095ee2fa4be67e1f,
|
||||
0x0d90b434ba57abe6b35c15ae3652f730732714372fc7a97e2c02088856d62014,
|
||||
0x1865dafc3484c977adfa0aaf7c67af83db678adbcde788fb0d3d24891a17cc0c,
|
||||
0x12ed55fd63570eab6520dfa5cfad9966f2adcceb4eec664f4e4a071d5d70b82e,
|
||||
0x19b0bb01d39832937c9da2bd1acb87446db2e30c7170cbfa403d6431e6053a62,
|
||||
0x1906ec1e76ad9371267a5a206e38b76d446a868c9be4be98a234910865e1b877,
|
||||
0x23f62fe89f2a36259878a077482a5f6ff85740e5d8f9d9ffacbb9263b18a86af,
|
||||
0x2f4b20c57d3038c70271187292b4a94e56019730dcfdee59ad28bf2371f89b73,
|
||||
0x2188c593ba388bb539b6a3e89cf9eec31520abc006e25b21ef0b9ec0ba795ead,
|
||||
0x19f9d9dccd162b2c6132a1ad6eb0bb693540838aeeb50ff9cd78fd2e70f2539d,
|
||||
0x0a459c91a19aab5685a042bf3310782d078934c7bcbea3ddbccee2dd5d1d0ae4,
|
||||
0x12677a533b2dc95d090c277d3076a99a3555dbdee415667fe6ddd91419836801,
|
||||
0x08bef6949f3fb6e74f0f1b5b2b414bbbdee5871055b533b973b299419af4fafc,
|
||||
0x14ba2da4075ea3c3422f12d6d2b2753caf962f80bef50bb246e6a3f58999317b,
|
||||
0x2ca11bf0295867199deb7681e102f655079722dfd08e55b5897c9f0461307d8c,
|
||||
0x2b59a960a82ae74b6f33ceff6ad156bf7f0c8989ce351bce650e9d5e5c05a3ac,
|
||||
0x013235db83fed0cf34a42d87ea9e662fbd700eae3174a4bf07f4f0e541ba4c98,
|
||||
0x014081d1be424ddcfa6e71181af3a4efaf7b7f7dfdb78788f106170bbfc6c458,
|
||||
0x021b8e121f282676a983b9a3a5d18fc33e6080afe3824cf82a0d527e5f92be3e,
|
||||
0x25da0ea238d74268ea3df1b43f15145d7d1b7984560c9b96ecdb92a7c154c0fc,
|
||||
0x223b40a33fd0c17b639bd1c44b2cd66214a31791b42ab5605d253bd043112c78,
|
||||
0x24e8c7cc3a48d2472b27a165590bfe81bc8f0560b1ec7c8a2dcebc8e088255f6,
|
||||
0x203df46cb4b2681cdf63d8bc380f696b852b076a0788456e52f980cb39406b56,
|
||||
0x102171b10649730b641ad5fca7509a8be02617e64b6a2c530f8dfcb96381d8fb,
|
||||
0x21483341bf6330c095667236cb25c2fb795950be20db2993d00f95e9db86d548,
|
||||
0x0b01bfd7cd717115b6b9f104d4d75da9a48cc0d84ab5c97d2b33254192bc4003,
|
||||
0x2ea24cc861e05aebbe83fa8f2d75443ea497101032c1d9c0bd1a23861c8864ed,
|
||||
0x04372690ea0d050a30f2c25d0ce905916b435eb5fc81c9c759edbf45107a8d85,
|
||||
0x051ee6ddc890879beccdf7178672856cff03f1462c6227e57950fa5888fc6fd5,
|
||||
0x1d57b69d317b1c45b61a53f963282305293eb647f29e776700655830e0e70614,
|
||||
0x2fbd442d418657365ff66249f800158dae372a9b80b5939c7872e73cbfb06df9,
|
||||
0x26f45b678433c5787d044a18a0bd60bb9434b4db98cb6b32c37ff5bc42b6e290,
|
||||
0x0a0b76699ae7b56e0b819136a3a5badc4ca25b67edbd3d19f2c77542fb77f90a,
|
||||
0x25f6a09fef3227202e1166260c94310c9ef9eea578a8b7986010951bdbc9d9e0,
|
||||
0x0d21807eda562f2939928a7e21168e2458d97219c521e3b7ea73cef17f74f6c3,
|
||||
0x2d97038dd52fc0d78fd61b1a12b8b5b8125a5515b72b0f36413392b5f06d26b8,
|
||||
0x1f207513cafcfe669a7e3c7c46cfbecfe21d89072dd56231a7084e52607852d4,
|
||||
0x226f83c016c2dcbc3a5d8c5799309ac7a995b450cab5d5d159c12a3536972cca,
|
||||
0x081541ea31c74625d97d43fa971a1c51906b245f097e9f283a8d2119b9779467,
|
||||
0x297dcdcfdb36b89b2c046d650e21b611738780776bc135512a490b1c8ce15e14,
|
||||
0x2d617064044226599099fd5bbaa46de5db333365ded2acdbd22e39d7812880cb,
|
||||
0x0fbe2fcdbe3a75f13235d1b450aedfaeeb3ab5cc8d5a1f635e2ed543d6df94b6,
|
||||
0x2fc42a33bd8bc618576cdf920700a758d10ddf00a9ecdda6e6cf2245a99be703,
|
||||
0x304b634102263d927acda39750beabcf6e4da71dfe8fd057fb65b416d4240381,
|
||||
0x072eaeea0b3f4a6308fe024a62e958a00063a2783d5c95f8662254e0d7bdad31,
|
||||
0x12dd36ba1c45d2859450ece52afaceb6fc4eafd5d22e981534c11b800af49622,
|
||||
0x16592d9f596f8e7db1195b598c9a5ab550ce58db40a3e01771a4b92f4447407f,
|
||||
0x1cde4e85920302e735f5ae8ab90cdfe9f291bd6333277b28f99a23d2768e164b,
|
||||
0x090b13387c1e63908026da15e43e91f4d7e046d11a7f2e19c11adb804b2e834f,
|
||||
0x2fbccbb27a0fdebc61bdd69d766303495d4661a4535dea0cfd0f7c978da0aae8,
|
||||
0x26a9feed3a8e11a6b42ce9c9dfc1dc0fa01f9f9748e672056aee55943b617950,
|
||||
0x0a93928c9eacdfec490adcedeff1d4864e1770e48df6665ddfc3595fb26e73a9,
|
||||
0x04ffe5957639c3155892d3c5812236d688c2c4d142f8c8feba1be04aacbb9f0a,
|
||||
0x114b0e6b5a2bbfc49cd03f3a0e8a8afd263d9361ce3631b352f87d3f3090f968,
|
||||
0x20e9116c087ae3c97f130ae383d8a18c7421608e76cca8c2f4a51bbe3735f8ca,
|
||||
0x0b4af594cf9b1d509214dc943a94edb449416cae97408e72f1fe2990b4213c18,
|
||||
0x0e9af7c41aa75f036b67dd6f1e741d8e55792777a08d68b2fd0a5c8b03ca1d37,
|
||||
0x28964cd6cb5113ba250e6d4993c9a76e4333b961657eec7fe1987fad1482a795,
|
||||
0x22b3e76214c678461c1b1176025e273fd8bc8eeb251eafacc9274198aa979467,
|
||||
0x2d4382055d99f2fb3107682ccd712d9ddd834ae6006740b7ff53a47674d6426b,
|
||||
0x2f276050872b35b18e0d21ae6c5a979cfbdff6f88f8725f925be61c2efbadaeb,
|
||||
0x047923ac3092cd3b292535059b9ad97b9d74c38e552326b35df34bf10548fee0,
|
||||
0x2d3d346b809cdcb8d9d34eab9c7b54a7f92bcefe01129ea97ab04a800453937c,
|
||||
0x0c36a5b386d0b2f14728ed12c0cda1466f6e28a2b1626e7ece1d11a921695a31,
|
||||
0x1aef33f82b69dfc7e51f5b647fd93e39cd81b100bc36620fa676eb57b64771da,
|
||||
0x1a101b37be684aa86df8be0545043e33c0b86aa5930d94ac71306f99f00add35,
|
||||
0x0626cddb01a255c1274a35b9842b1ece727ee158981d36bb17d17023bdf0ca15,
|
||||
0x166f76eb2cdad17b7e1b4aad949b117310ef06b945c09d9bed79d9560cc3cd1e,
|
||||
0x1aa6ae14d82811c36fce8923a0e9632e0b320505d135fe8df7d6dce57212a69c,
|
||||
0x1e3332f6c23a8c0ceb3417e68c92261c5c005c43b9a676fa7019e95b9983e40f,
|
||||
0x18f23783cbbcad4f561c9239314d6866c0a92eac0c53f9732ce8748aacc64ae9,
|
||||
0x111d3bc2fc48feb3474865322c695ea5eaa6bebbd6da0c381920bc2d00e99776,
|
||||
0x23b009813f17fd7138fb74df56c3247ef031ca124aa75d6ce4a8db63fef9c54d,
|
||||
0x28ae7ec0874ce406eefa32e96b84aa77057c351b3f3aea6e8005d3b65ce6309c,
|
||||
0x05a2d755f5e520b53b2765bfed7ccc7090cd5b2155460148ea73fd7eb7f89f9e,
|
||||
0x100022a693424e0b0213f4992ed3d53334f9e1997825c86532b44a234523f6d4,
|
||||
0x2d0c51264d581af3a64cfc0a5ca2eeaf6521a2d6100f4c323fb1ba6503303a42,
|
||||
0x02ef717f6ac82e29b261aa0b28188ec299585edd9823847f900d36507f8194d8,
|
||||
0x11b7074ac17782921a05a998d52ea6079628692bee9846bb03eb8e11ce802360,
|
||||
0x14cee5e6d15a6c706654e7b5b0d350748c90f9b48fdde11d5e04c7cdb21864c7,
|
||||
0x1183348c529c73a33319edd671e99991614fcc663d458b1c22e1677b6aebf924,
|
||||
0x2325e0728102551f9fdf661e3459eb70c4dd5d3985f685e206b64b41cecd44eb,
|
||||
0x20c1eab09b138e3653be1f4909c4cc5ec0a697eae83b6e926b78f81779d24911,
|
||||
0x11c9e1d7edfd62875d01d773152203c4524b33d118f83b169ad1aed293d81b19,
|
||||
0x070c9ff7fa280e4055a23e8bc9f6c317d2ac3221d2990e8accdf8c84cffc1e2f,
|
||||
0x254af914dd424ceeb5438a50c61f50c7f56136da4615cfab12e61a5db6cff638,
|
||||
0x28fb40fb9f010d97ddc38071fe5207fb78797ca71f534ccbc2bbdf6c115a4d16,
|
||||
0x2d4c3d71cdf56c3d5956c6b4f6d5e855562f1794311e172a55294b6bbd7eb9e1,
|
||||
0x1ace5d5fd5fc6b15f0b359d46171a9a92bc0190cf2dca0dbdac5a96a9b31ce17,
|
||||
0x2b481ad328c016e5e0dd9a5be16da951b70af7dced31f7899cad9aebd251e78b,
|
||||
0x173a51b6fd6ebccf78666457f4ca4d64023fc2e83540e17cb7ca12fa85869172,
|
||||
0x139e2b576a2e5491952e78bb78065545f6f0e3a8c9b8519770c486cf92698e7f,
|
||||
0x1bea94b6c53410f9112a63c2fddbe7eced47f17405c2db63db1b7051559b8109,
|
||||
0x1d1c53d42e47093d961525be7c19d765cb2d43228a863edf220a7f6f38501a27,
|
||||
0x2a91572dcc79f87408894c8d360b93cd9a5d8042b9d72b48c18838bd6fec0667,
|
||||
0x269d5f30f099282511c4eccd423d5f3d64e2f8153a3e1fdedcc1d476fbd02ec8,
|
||||
0x1950225dc9af9cccb17ccb8a9227a7384a78d93bd40bad6e9eec430416cc45c3,
|
||||
0x20d36ac727d921193d4a2a45fbe123170ffb83e8f23fb4948215e7b8881e4bee,
|
||||
0x18f4c2af29258c0dc4f14b1f538a3503b57f444c467520da8b047fa398062f31,
|
||||
0x2bf4dcfbd1dbfdd6d6f08b43c4aee9818c915589105d33d6088cfe27921e5279,
|
||||
0x191ed15cd07da3cdf8dbdea430c203fdffe64c01c7bb38053d11da051836ff91,
|
||||
0x0eb85c12fefbee535e54702aff8ed5e6b6b3431a07d7473a1f20630672bb177d,
|
||||
0x0e9d55dddb28d570572ed245a163ac213b281774e8f1ae82bca0c43263a30f08,
|
||||
0x0001a2000bed5bea95515b5da6c8fdcb359a1f06f952313acff9c899b40dac23,
|
||||
0x15fa1f0c3855cb2de7fc732236d310474c7995230f80d1112f19a407bf42bed7,
|
||||
0x150c310e70221783e2042d1fc3824c19421a46ce668fdcda3b16db0af86845b7,
|
||||
0x1e054c1bb6c893e1e104662de7b1275ae1dee43ca17e8f16ee093b4894f3440b,
|
||||
0x16c9b293066013054c9979c8d046d1f20a41364fcc64186eeb2a98b3026857f3,
|
||||
0x2ca9b4bb10dc2c1d0186e6bb50876dcf510c70629c6bf8481db3a830dfd7b15c,
|
||||
0x2be7e344645273fab7c289ed00ba62f5d272ffdedcb0ec1d4e0a4d42902c8ef7,
|
||||
0x187681a205e2b817fce1590ffd8e71bc2b7e3029d9053170af0c3d4f23b0b076,
|
||||
0x041e20737b8c090cf62e341f3339515ec3fc886cf7b2ccd61738c8801fd74dcd,
|
||||
0x109f5415950efdbf4c7162646e46ac7eb04b8ed8ac1eb52f34c8dd5b1d40f2b0,
|
||||
0x2caa2202f0f455109e092b0581d5aa71c7c500831a217a1ccba50d9dade9c667,
|
||||
0x2d4c3333cf741e7c0b86ac0f962368322704d1e09c0212181c82eb62ca426ae6,
|
||||
0x15704173948ee1c2ff0072e43a8da316d50a7d59c0e47e0d6d045fce33d251cb,
|
||||
0x1b7beea1f3d1073553d6a0756ff8be081b3a4ed4bc882927faf1e298a159ed28,
|
||||
0x28a5660731ec0e6658d707a7426b44ee10a8d977131c6d9573da6c78fc813946,
|
||||
0x1c25e36d652690ba17330b8f416f0de50a118087e8683418dc566a1317fb0d57,
|
||||
0x0560867e3051cb4a1abfb67dc385ddf9bbc2c66afc78ef1c7be32cc5bb26ee5c,
|
||||
0x020d0d9f2151ed7330fc4cacbb9b6d95ed0c914739cf0411256254424bbc105c,
|
||||
0x00ce7eb2024c8a6e75097583cb82de4058f87d46f2709bebf26e6ebae3e8f136,
|
||||
0x04d78c43b841fff58081606a44fdefde0aea13c52cc3387527b22d2205b843b5,
|
||||
0x2259d75915d33431cd5aad3b0d90f0069197e190113ee3ad2c99f0e2b3f72195,
|
||||
0x178df288dc79e1c87e5f052da31c98b3bfb533721923b7e3869c2112e7e85326,
|
||||
0x11d668d143812697fd24ef1a20103b6c76339f652080fa63742802c1ecdcf0de,
|
||||
0x0cdc41f4f4042ce1c5db5bb57972bf5594ace8acdd18017319e6b2cb658088b6,
|
||||
0x1a54ebce705e92e10f7f665b3cbc66007c9d30da4a94926642dd7fceffeda68f,
|
||||
0x279a8f5f37202edab28c806177a0ad8c2ddb65431b8187f5ea77fb192e1cc93d,
|
||||
0x110f2b2bbfa6c4cbcdb3ae38931c217eb0d57c8657d5030cd774b421f057658e,
|
||||
0x286352ab3c8d4acac74af412e2653056ae23a8d6e79b57cf5c4e9e89c0461c7f,
|
||||
0x22aaf44d434a8c6947615bf82c5f48018174cbd10b8318418e20a1ab80fbb3a5,
|
||||
0x082066e1285be2fd943557f5759e60210a5e7df9f555e1d3d5b11a0245099143,
|
||||
0x03aeb70346c3d88d586efcace591ff711b2f4545729a1e8fe6a77a36b3f9cdb1,
|
||||
0x0b2d2bc2d90f3e14f39ca85cd7fefa45a8e92a885c42daa99d003b969f42597d,
|
||||
0x176403ebf4f777060fe4abe354ce6040fa9ecfc5786ae16cf688eb0eefba94f2,
|
||||
0x2f50f3e014c57024665b5772aa6debbf7ab97d0cee8afbc398aea0c8c3d0a9d1,
|
||||
0x113d1852aeee168d5fcf9e2e14145e7d2ba384f6f05e8e07bed66acd2c3bc491,
|
||||
0x22376402c1dc96acbaa37c274e21b1543029b2d966b33ba918ace6f234fc384d,
|
||||
0x1072c07f09517532c90fe00ea49cc84254c90f4ca2edbbcd49c8a1eb1f697902,
|
||||
0x1f9333b7dea348b385995653f86f9c2e3be223912afd11bb18c800d8866ff29c,
|
||||
0x2c9c33a9c2feacdba47389b4bc20c79b0b7cc26936200bf69ea5a27c4749be7f,
|
||||
0x0f73f26b06c75f4fd57c980c89d171fd02e7c8119c435f49a24cc479a4833234,
|
||||
0x1cb90811236a470d88b7c715fb3a74a9b6a492acdb910c873b984246fcfee4c2,
|
||||
0x22dbf55d5677d6d1e0cac605667f3a6404a56fa414f9ff0dab8596af82c684dd,
|
||||
0x2da8726ebf2c743deb43ad984666314494a9996600e24948d5c1177241f5cfd5,
|
||||
0x2aa9d68806873b74f3973e10537494a226f5c13cc8c7958b9044e57d6d380d6f,
|
||||
0x16373afa12990e5f280009e6146acc709566c771f029871a6a862f0d920b5c1c,
|
||||
0x29054bafcf9f9af1d86cd6ce179538de6149cc12e87f1941f2e9d70d8ee25243,
|
||||
0x234f73766998d7f080a96b9b20e8185e50eda5d93c7a20742185d8dce045fa89,
|
||||
0x29e0fd2afa0655695aa558855310120c43d05c2c12b1af5680392be9d711159e,
|
||||
0x24a4b6c48ce3aa487d4292414db1bbaa4edb2356217f9803882ad186c025a4ec,
|
||||
0x0109813f99a5e5d3e3b3c5f20090c179b5509a1e87f5be4767ad9f2769335eed,
|
||||
0x068176b175eb6d4f6be7790c7f9ceac335486fb5d2651e5ed3292c1bb52921d4,
|
||||
0x2b0331e9393832024612fa348c6cb1c7e3bc0f8233b04f83dfee9c2da005b250,
|
||||
0x2ca724a465a514d4ef71dca994432a392b20dd976fe4d6f3214280c285ec94a0,
|
||||
0x086c36ffbc668a2207f1d8a3464376167d8b418ea5030ff496da344a458490d6,
|
||||
0x1533706df2390af82e10275246db4319db1b28208c59c28a0dfc7d0635803990,
|
||||
0x05f13219f8a4b1025b442d1cf526957a9a595ba140fc1d90f8c886746bc35a7b,
|
||||
0x16933f8cceda41f5b4d047a1c0a2d10958563f5db08066fd9416fda4e40c68aa,
|
||||
0x233096e4dceee0b3ae560189bd64c91160c350779c28f93b35d5b4a7f7712e94,
|
||||
0x07fa6f6727f8e91bdf362538575a2743fec75aa8add0bd1f1a227e65fc4adcb0,
|
||||
0x1c490af994c52e36d21c4d5b4a1fb657a49ccf5a810f7044a889b07b5a538d4a,
|
||||
0x042a23d3d8acfbe670b16e77ba7cb966315b1ca5fd963265fe1f59eed4a2a3ec,
|
||||
0x105ff3b04c267b649d03b17f609749bed73d5a2c373a1f89818033b165f48ed6,
|
||||
0x1b172978ac949fdc51202f3929bf56d0ce14ab07434f4633e6f68a9559a07a7a,
|
||||
0x2e575563c3bccb0e5181a47fb1ee752a7a671ecc91c17716ac56e12852ad1561,
|
||||
0x2a2b0706edbd2b7eaa1f6c6a2ac566d926234c6a169615d5b7e79adb6ef93369,
|
||||
0x05ace2fb7ba01279fd52d1433c42fe1fcbf27a8823fbdf788556570e3884e7c9,
|
||||
0x0092f357e8f0c781bff9b90c76a4e41462fe92ea6cb36d02adb7b598ffd40046,
|
||||
0x200dd359583eb7422dac26b8dc26c6ea284703005a706ea1600935dd0fc1f87b,
|
||||
0x01067478a6f9a5a999e3fe87378fde5abf0d8ed56c3c1a648cee62e502e88f5b,
|
||||
0x17eb93ae32e75ce3654d7f193d53c38543be71a154f43d30e67738c8abe4d659,
|
||||
0x10b1f942bd7dfef88b4ef8cef12e074a3150ca31784ff3bb69cf661b01b96f87,
|
||||
0x0e8b9809e17f9e7a04cb57e409eaab82a9d57302de26e5dd32666082ecb74f62,
|
||||
0x042af5396847cc6ce227776d9f7481b65e0b8ce2858d2a4328c25d549b3b6fe6,
|
||||
0x25fde7074f082a309bd857ff071df88b6e4004dba38650a51e117d0726785c43,
|
||||
0x193eb81682f0c88ff6d3cef9dbe71962860e31b5f5dea07df62608e81f4cd331,
|
||||
0x21a8ccb0264455242659b69703301b0ca924be63a5e033de8bad89a3fcfe5da9,
|
||||
0x2945dd17e8a6095ab7879bb2ad6d6575c3cb92074651a1b6a452daf6d6eef668,
|
||||
0x0e7bd7ddcd5b487190dfdf53bc0fb3d1efd2470210b6272ac945748aa894043c,
|
||||
0x1d4f0e42124ba8ba193527db8b16283d39d77951a866b4729add8fad99ccecf8,
|
||||
0x18c44546876964fb6a85492705c67d2e144128519d7a03ddd924cea47aee0dc9,
|
||||
0x0d1428693bd58b2a6ceeae2745cc89a2d07bad0065228253a21564b47160acd3,
|
||||
0x0246968a12a67b005dd5691d71f53d950f1ac2ce0de5835ec8883861f2761e91,
|
||||
0x22127a11cecaadaadaeaeb5592f823851e5b80db5f1f4adf0f5ff013aab6acd3,
|
||||
0x0bae45f539ac68829b01f9755858401af76b27d983739227478aab249c5cd08b,
|
||||
0x2ffcb6c8e1671e47683a0e7d02c4170a5af758c42cea101754cf36fce6542291,
|
||||
0x2673edfbf2cecc6d140e50891dd56178bb5f7daad2c7f7e82e02074174cbccbb,
|
||||
0x02b132b8e30f9f07a0d51d755f652159c92e5fdd4107629912fa62c01591ab02,
|
||||
0x079975637ccf42371e03c052a87310457c844122a1ebdaddb8070f44fd7730a4,
|
||||
0x1beaf69915ca77b58358a696bbf84bc9ce1a478958f6ccd057c21ab826425236,
|
||||
0x06e513a6c2fbb3d0160bd05263cfa95ccf6e1caef5fcc6a839a05ffe59a47fcf,
|
||||
0x0d1f54c6d986976670ac11ae9fd04fe131d6690d7377b068231bed92f4c5ba0b,
|
||||
0x14bbd8a734f6a043f95e69e2155cb65e4fb84cc24ac1f5c8ac6547bc303b1ef2,
|
||||
0x19358e657a98d9a2244a27018a7f50758609350167ced03314211dd3fe9242d9,
|
||||
0x00bca3b42d08f0f682e6e6eca315671ebf31f6cf36843cfe6073ba0f69fd8717,
|
||||
0x018b4b1a387530808b953aa56733ecb3cd95a61205cb8b08aa89328b3c879757,
|
||||
0x05310ae64e8e05eddce42e9370e761c965533a8685d3c2460e9e2393da1f8a37,
|
||||
0x200a4c9a209660e05188ccc9e350d0ba746af52666790c365c8812d6a40ed5ea,
|
||||
0x251adeccfc3943428ed6279b2ff500eaee11cf8f37910e0b57e5ade99dba36b2,
|
||||
0x2df3081bd4a97303a068d662abf23fef7f33ecb67c83645e5ab3095a86925064,
|
||||
0x02f7b09f7ee3d2732996fa175b5c1de3a415a5b8ad83a67323d621c8692c2c73,
|
||||
0x2e2a507997465da1205a02c06ffe5013de1dbc0f5df299bf331300be45b31a1b,
|
||||
0x2f99f8cb42eda5a401e00a826eec343c792bdba07965b0790487151ca065c0cc,
|
||||
0x0f50f142de63f8a59e8107dc287971fe48a95bd5debcc7c5874f380c5360f6a3,
|
||||
0x2172e7f369505b0ffdbac165ffbefd6b9f285206dadd6ff5c1b78aa9f6fb6809,
|
||||
0x25d612d3e96dd530ed39801e24756613e5592ea44d982308cd0a9e27aab457f2,
|
||||
0x2a513a7791c225df3b710369e4ffc3b332233d34044d0aad2cfe808a17025810,
|
||||
0x1f765b73e2e1678499e4f3a58d317817a72a67bf318d75c51bd8175f8d4c5cbc,
|
||||
0x20d3476e397dc3ce21614423e55c4f46f08fc7f9c3cb7516fecb7f2889190817,
|
||||
0x17fe12fcf94ba294d2f65b0d88f500b9bcc2423cba34a68656b17c18fe38739f,
|
||||
0x093d25c02dd5376c2a3902df7dd688bb4c0578f20bf5ea4f06614223d5075fe0,
|
||||
0x02ad0b364a6ab3e48f3f8e8f4e9ed136b2b4acc67835340dff16d9f3b8e73f2d,
|
||||
0x07b4f0e8282ee161bc085709e3c7309da10da3c6c5c879142acdb517a3fd00c5,
|
||||
0x19ea14ce82444de5bd3173fe477d6819079ec48fd02c336a38ee3524d65b443e
|
||||
];
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
123
circuits/montgomery.circom
Normal file
123
circuits/montgomery.circom
Normal file
@@ -0,0 +1,123 @@
|
||||
|
||||
/*
|
||||
Source: https://en.wikipedia.org/wiki/Montgomery_curve
|
||||
|
||||
1 + y 1 + y
|
||||
[u, v] = [ ------- , ---------- ]
|
||||
1 - y (1 - y)x
|
||||
|
||||
*/
|
||||
|
||||
template Edwards2Montgomery() {
|
||||
signal input in[2];
|
||||
signal output out[2];
|
||||
|
||||
out[0] <-- (1 + in[1]) / (1 - in[1]);
|
||||
out[1] <-- out[0] / in[0];
|
||||
|
||||
|
||||
out[0] * (1-in[1]) === (1 + in[1]);
|
||||
out[1] * in[0] === out[0];
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
u u - 1
|
||||
[x, y] = [ ---, ------- ]
|
||||
v u + 1
|
||||
|
||||
*/
|
||||
template Montgomery2Edwards() {
|
||||
signal input in[2];
|
||||
signal output out[2];
|
||||
|
||||
out[0] <-- in[0] / in[1];
|
||||
out[1] <-- (in[0] - 1) / (in[0] + 1);
|
||||
|
||||
out[0] * in[1] === in[0];
|
||||
out[1] * (in[0] + 1) === in[0] - 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
x2 - x1
|
||||
lamda = ---------
|
||||
y2 - y1
|
||||
|
||||
x3 + A + x1 + x2
|
||||
x3 = B * lamda^2 - A - x1 -x2 => lamda^2 = ------------------
|
||||
B
|
||||
|
||||
y3 = (2*x1 + x2 + A)*lamda - B*lamda^3 - y1 =>
|
||||
|
||||
|
||||
=> y3 = lamda * ( 2*x1 + x2 + A - x3 - A - x1 - x2) - y1 =>
|
||||
|
||||
=> y3 = lamda * ( x1 - x3 ) - y1
|
||||
|
||||
----------
|
||||
|
||||
y2 - y1
|
||||
lamda = ---------
|
||||
x2 - x1
|
||||
|
||||
x3 = B * lamda^2 - A - x1 -x2
|
||||
|
||||
y3 = lamda * ( x1 - x3 ) - y1
|
||||
|
||||
*/
|
||||
|
||||
template MontgomeryAdd() {
|
||||
signal input in1[2];
|
||||
signal input in2[2];
|
||||
signal output out[2];
|
||||
|
||||
var a = 168700;
|
||||
var d = 168696;
|
||||
|
||||
var A = (2 * (a + d)) / (a - d);
|
||||
var B = 4 / (a - d);
|
||||
|
||||
signal lamda;
|
||||
|
||||
lamda <-- (in2[1] - in1[1]) / (in2[0] - in1[0]);
|
||||
lamda * (in2[0] - in1[0]) === (in2[1] - in1[1]);
|
||||
|
||||
out[0] <== B*lamda*lamda - A - in1[0] -in2[0];
|
||||
out[1] <== lamda * (in1[0] - out[0]) - in1[1];
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
x1_2 = x1*x1
|
||||
|
||||
3*x1_2 + 2*A*x1 + 1
|
||||
lamda = ---------------------
|
||||
2*B*y1
|
||||
|
||||
x3 = B * lamda^2 - A - x1 -x1
|
||||
|
||||
y3 = lamda * ( x1 - x3 ) - y1
|
||||
|
||||
*/
|
||||
template MontgomeryDouble() {
|
||||
signal input in[2];
|
||||
signal output out[2];
|
||||
|
||||
var a = 168700;
|
||||
var d = 168696;
|
||||
|
||||
var A = (2 * (a + d)) / (a - d);
|
||||
var B = 4 / (a - d);
|
||||
|
||||
signal lamda;
|
||||
signal x1_2;
|
||||
|
||||
x1_2 <== in[0] * in[0];
|
||||
|
||||
lamda <-- (3*x1_2 + 2*A*in[0] + 1 ) / (2*B*in[1]);
|
||||
lamda * (2*B*in[1]) === (3*x1_2 + 2*A*in[0] + 1 );
|
||||
|
||||
out[0] <== B*lamda*lamda - A - 2*in[0];
|
||||
out[1] <== lamda * (in[0] - out[0]) - in[1];
|
||||
}
|
||||
93
circuits/multiplexer.circom
Normal file
93
circuits/multiplexer.circom
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
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 Multiplexor(wIn, nIn) {
|
||||
signal input inp[nIn][wIn];
|
||||
signal input sel;
|
||||
signal output out[wIn];
|
||||
component Decoder(nIn) dec;
|
||||
component EscalarProduct(nIn) ep[wIn];
|
||||
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;
|
||||
}
|
||||
|
||||
component Multiplexor(8,3) main;
|
||||
|
||||
|
||||
55
circuits/mux3.circom
Normal file
55
circuits/mux3.circom
Normal file
@@ -0,0 +1,55 @@
|
||||
template MultiMux3(n) {
|
||||
signal input c[n][8]; // Constants
|
||||
signal input s[3]; // Selector
|
||||
signal output out[n];
|
||||
|
||||
signal a210[n];
|
||||
signal a21[n];
|
||||
signal a20[n];
|
||||
signal a2[n];
|
||||
|
||||
signal a10[n];
|
||||
signal a1[n];
|
||||
signal a0[n];
|
||||
signal a[n];
|
||||
|
||||
// 4 constrains for the intermediary variables
|
||||
signal s10;
|
||||
s10 <== s[1] * s[0];
|
||||
|
||||
for (var i=0; i<n; i++) {
|
||||
|
||||
a210[i] <== ( c[i][ 7]-c[i][ 6]-c[i][ 5]+c[i][ 4] - c[i][ 3]+c[i][ 2]+c[i][ 1]-c[i][ 0] ) * s10;
|
||||
a21[i] <== ( c[i][ 6]-c[i][ 4]-c[i][ 2]+c[i][ 0] ) * s[1];
|
||||
a20[i] <== ( c[i][ 5]-c[i][ 4]-c[i][ 1]+c[i][ 0] ) * s[0];
|
||||
a2[i] <== ( c[i][ 4]-c[i][ 0] );
|
||||
|
||||
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] <== ( a210[i] + a21[i] + a20[i] + a2[i] ) * s[2] +
|
||||
( a10[i] + a1[i] + a0[i] + a[i] );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
template Mux3() {
|
||||
var i;
|
||||
signal input c[8]; // Constants
|
||||
signal input s[3]; // Selector
|
||||
signal output out;
|
||||
|
||||
component mux = MultiMux3(1);
|
||||
|
||||
for (i=0; i<8; i++) {
|
||||
mux.c[0][i] <== c[i];
|
||||
}
|
||||
|
||||
for (i=0; i<3; i++) {
|
||||
s[i] ==> mux.s[i];
|
||||
}
|
||||
|
||||
mux.out[0] ==> out;
|
||||
}
|
||||
103
circuits/mux4.circom
Normal file
103
circuits/mux4.circom
Normal file
@@ -0,0 +1,103 @@
|
||||
|
||||
|
||||
|
||||
|
||||
template MultiMux4(n) {
|
||||
signal input c[n][16]; // Constants
|
||||
signal input s[4]; // Selector
|
||||
signal output out[n];
|
||||
|
||||
signal a3210[n];
|
||||
signal a321[n];
|
||||
signal a320[n];
|
||||
signal a310[n];
|
||||
signal a32[n];
|
||||
signal a31[n];
|
||||
signal a30[n];
|
||||
signal a3[n];
|
||||
|
||||
signal a210[n];
|
||||
signal a21[n];
|
||||
signal a20[n];
|
||||
signal a10[n];
|
||||
signal a2[n];
|
||||
signal a1[n];
|
||||
signal a0[n];
|
||||
signal a[n];
|
||||
|
||||
// 4 constrains for the intermediary variables
|
||||
signal s10;
|
||||
s10 <== s[1] * s[0];
|
||||
signal s20;
|
||||
s20 <== s[2] * s[0];
|
||||
signal s21;
|
||||
s21 <== s[2] * s[1];
|
||||
signal s210;
|
||||
s210 <== s21 * s[0];
|
||||
|
||||
|
||||
for (var i=0; i<n; i++) {
|
||||
|
||||
a3210[i] <== ( c[i][15]-c[i][14]-c[i][13]+c[i][12] - c[i][11]+c[i][10]+c[i][ 9]-c[i][ 8]
|
||||
-c[i][ 7]+c[i][ 6]+c[i][ 5]-c[i][ 4] + c[i][ 3]-c[i][ 2]-c[i][ 1]+c[i][ 0] ) * s210;
|
||||
a321[i] <== ( c[i][14]-c[i][12]-c[i][10]+c[i][ 8] - c[i][ 6]+c[i][ 4]+c[i][ 2]-c[i][ 0] ) * s21;
|
||||
a320[i] <== ( c[i][13]-c[i][12]-c[i][ 9]+c[i][ 8] - c[i][ 5]+c[i][ 4]+c[i][ 1]-c[i][ 0] ) * s20;
|
||||
a310[i] <== ( c[i][11]-c[i][10]-c[i][ 9]+c[i][ 8] - c[i][ 3]+c[i][ 2]+c[i][ 1]-c[i][ 0] ) * s10;
|
||||
a32[i] <== ( c[i][12]-c[i][ 8]-c[i][ 4]+c[i][ 0] ) * s[2];
|
||||
a31[i] <== ( c[i][10]-c[i][ 8]-c[i][ 2]+c[i][ 0] ) * s[1];
|
||||
a30[i] <== ( c[i][ 9]-c[i][ 8]-c[i][ 1]+c[i][ 0] ) * s[0];
|
||||
a3[i] <== ( c[i][ 8]-c[i][ 0] );
|
||||
|
||||
a210[i] <== ( c[i][ 7]-c[i][ 6]-c[i][ 5]+c[i][ 4] - c[i][ 3]+c[i][ 2]+c[i][ 1]-c[i][ 0] ) * s210;
|
||||
a21[i] <== ( c[i][ 6]-c[i][ 4]-c[i][ 2]+c[i][ 0] ) * s21;
|
||||
a20[i] <== ( c[i][ 5]-c[i][ 4]-c[i][ 1]+c[i][ 0] ) * s20;
|
||||
a10[i] <== ( c[i][ 3]-c[i][ 2]-c[i][ 1]+c[i][ 0] ) * s10;
|
||||
a2[i] <== ( c[i][ 4]-c[i][ 0] ) * s[2];
|
||||
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] <== ( a3210[i] + a321[i] + a320[i] + a310[i] + a32[i] + a31[i] + a30[i] + a3[i] ) * s[3] +
|
||||
( a210[i] + a21[i] + a20[i] + a10[i] + a2[i] + a1[i] + a0[i] + a[i] );
|
||||
|
||||
/*
|
||||
out[i] <== ( s210 * ( c[i][15]-c[i][14]-c[i][13]+c[i][12] - c[i][11]+c[i][10]+c[i][ 9]-c[i][ 8]
|
||||
-c[i][ 7]+c[i][ 6]+c[i][ 5]-c[i][ 4] + c[i][ 3]-c[i][ 2]-c[i][ 1]+c[i][ 0] ) +
|
||||
s21 * ( c[i][14]-c[i][12]-c[i][10]+c[i][ 8] - c[i][ 6]+c[i][ 4]+c[i][ 2]-c[i][ 0] ) +
|
||||
s20 * ( c[i][13]-c[i][12]-c[i][ 9]+c[i][ 8] - c[i][ 5]+c[i][ 4]+c[i][ 1]-c[i][ 0] ) +
|
||||
s10 * ( c[i][11]-c[i][10]-c[i][ 9]+c[i][ 8] - c[i][ 3]+c[i][ 2]+c[i][ 1]-c[i][ 0] ) +
|
||||
s[2] * ( c[i][12]-c[i][ 8]-c[i][ 4]+c[i][ 0] ) +
|
||||
s[1] * ( c[i][10]-c[i][ 8]-c[i][ 2]+c[i][ 0] ) +
|
||||
s[0] * ( c[i][ 9]-c[i][ 8]-c[i][ 1]+c[i][ 0] ) +
|
||||
( c[i][ 8]-c[i][ 0] ) ) * s[3] +
|
||||
( s210 * ( c[i][ 7]-c[i][ 6]-c[i][ 5]+c[i][ 4] - c[i][ 3]+c[i][ 2]+c[i][ 1]-c[i][ 0] ) +
|
||||
s21 * ( c[i][ 6]-c[i][ 4]-c[i][ 2]+c[i][ 0] ) +
|
||||
s20 * ( c[i][ 5]-c[i][ 4]-c[i][ 1]+c[i][ 0] ) +
|
||||
s10 * ( c[i][ 3]-c[i][ 2]-c[i][ 1]+c[i][ 0] ) +
|
||||
s[2] * ( c[i][ 4]-c[i][ 0] ) +
|
||||
s[1] * ( c[i][ 2]-c[i][ 0] ) +
|
||||
s[0] * ( c[i][ 1]-c[i][ 0] ) +
|
||||
( c[i][ 0] ));
|
||||
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
template Mux4() {
|
||||
var i;
|
||||
signal input c[16]; // Constants
|
||||
signal input s[4]; // Selector
|
||||
signal output out;
|
||||
|
||||
component mux = MultiMux4(1);
|
||||
|
||||
for (i=0; i<16; i++) {
|
||||
mux.c[0][i] <== c[i];
|
||||
}
|
||||
|
||||
for (i=0; i<4; i++) {
|
||||
s[i] ==> mux.s[i];
|
||||
}
|
||||
|
||||
mux.out[0] ==> out;
|
||||
}
|
||||
236
circuits/pedersen.circom
Normal file
236
circuits/pedersen.circom
Normal file
@@ -0,0 +1,236 @@
|
||||
include "montgomery.circom";
|
||||
include "mux3.circom";
|
||||
include "babyjub.circom";
|
||||
|
||||
template Window4() {
|
||||
signal input in[4];
|
||||
signal input base[2];
|
||||
signal output out[2];
|
||||
signal output out8[2]; // Returns 8*Base (To be linked)
|
||||
|
||||
component mux = MultiMux3(2);
|
||||
|
||||
mux.s[0] <== in[0];
|
||||
mux.s[1] <== in[1];
|
||||
mux.s[2] <== in[2];
|
||||
|
||||
component dbl2 = MontgomeryDouble();
|
||||
component adr3 = MontgomeryAdd();
|
||||
component adr4 = MontgomeryAdd();
|
||||
component adr5 = MontgomeryAdd();
|
||||
component adr6 = MontgomeryAdd();
|
||||
component adr7 = MontgomeryAdd();
|
||||
component adr8 = MontgomeryAdd();
|
||||
|
||||
// in[0] -> 1*BASE
|
||||
|
||||
mux.c[0][0] <== base[0];
|
||||
mux.c[1][0] <== base[1];
|
||||
|
||||
// in[1] -> 2*BASE
|
||||
dbl2.in[0] <== base[0];
|
||||
dbl2.in[1] <== base[1];
|
||||
mux.c[0][1] <== dbl2.out[0];
|
||||
mux.c[1][1] <== dbl2.out[1];
|
||||
|
||||
// in[2] -> 3*BASE
|
||||
adr3.in1[0] <== base[0];
|
||||
adr3.in1[1] <== base[1];
|
||||
adr3.in2[0] <== dbl2.out[0];
|
||||
adr3.in2[1] <== dbl2.out[1];
|
||||
mux.c[0][2] <== adr3.out[0];
|
||||
mux.c[1][2] <== adr3.out[1];
|
||||
|
||||
// in[3] -> 4*BASE
|
||||
adr4.in1[0] <== base[0];
|
||||
adr4.in1[1] <== base[1];
|
||||
adr4.in2[0] <== adr3.out[0];
|
||||
adr4.in2[1] <== adr3.out[1];
|
||||
mux.c[0][3] <== adr4.out[0];
|
||||
mux.c[1][3] <== adr4.out[1];
|
||||
|
||||
// in[4] -> 5*BASE
|
||||
adr5.in1[0] <== base[0];
|
||||
adr5.in1[1] <== base[1];
|
||||
adr5.in2[0] <== adr4.out[0];
|
||||
adr5.in2[1] <== adr4.out[1];
|
||||
mux.c[0][4] <== adr5.out[0];
|
||||
mux.c[1][4] <== adr5.out[1];
|
||||
|
||||
// in[5] -> 6*BASE
|
||||
adr6.in1[0] <== base[0];
|
||||
adr6.in1[1] <== base[1];
|
||||
adr6.in2[0] <== adr5.out[0];
|
||||
adr6.in2[1] <== adr5.out[1];
|
||||
mux.c[0][5] <== adr6.out[0];
|
||||
mux.c[1][5] <== adr6.out[1];
|
||||
|
||||
// in[6] -> 7*BASE
|
||||
adr7.in1[0] <== base[0];
|
||||
adr7.in1[1] <== base[1];
|
||||
adr7.in2[0] <== adr6.out[0];
|
||||
adr7.in2[1] <== adr6.out[1];
|
||||
mux.c[0][6] <== adr7.out[0];
|
||||
mux.c[1][6] <== adr7.out[1];
|
||||
|
||||
// in[7] -> 8*BASE
|
||||
adr8.in1[0] <== base[0];
|
||||
adr8.in1[1] <== base[1];
|
||||
adr8.in2[0] <== adr7.out[0];
|
||||
adr8.in2[1] <== adr7.out[1];
|
||||
mux.c[0][7] <== adr8.out[0];
|
||||
mux.c[1][7] <== adr8.out[1];
|
||||
|
||||
out8[0] <== adr8.out[0];
|
||||
out8[1] <== adr8.out[1];
|
||||
|
||||
out[0] <== mux.out[0];
|
||||
out[1] <== - mux.out[1]*2*in[3] + mux.out[1]; // Negate y if in[3] is one
|
||||
}
|
||||
|
||||
|
||||
template Segment(nWindows) {
|
||||
signal input in[nWindows*4];
|
||||
signal input base[2];
|
||||
signal output out[2];
|
||||
|
||||
var i;
|
||||
var j;
|
||||
|
||||
// Convert the base to montgomery
|
||||
|
||||
component e2m = Edwards2Montgomery();
|
||||
e2m.in[0] <== base[0];
|
||||
e2m.in[1] <== base[1];
|
||||
|
||||
component windows[nWindows];
|
||||
component doublers1[nWindows-1];
|
||||
component doublers2[nWindows-1];
|
||||
component adders[nWindows-1];
|
||||
for (i=0; i<nWindows; i++) {
|
||||
windows[i] = Window4();
|
||||
if (i==0) {
|
||||
windows[i].base[0] <== e2m.out[0];
|
||||
windows[i].base[1] <== e2m.out[1];
|
||||
} else {
|
||||
doublers1[i-1] = MontgomeryDouble();
|
||||
doublers2[i-1] = MontgomeryDouble();
|
||||
doublers1[i-1].in[0] <== windows[i-1].out8[0];
|
||||
doublers1[i-1].in[1] <== windows[i-1].out8[1];
|
||||
doublers2[i-1].in[0] <== doublers1[i-1].out[0];
|
||||
doublers2[i-1].in[1] <== doublers1[i-1].out[1];
|
||||
|
||||
windows[i].base[0] <== doublers2[i-1].out[0];
|
||||
windows[i].base[1] <== doublers2[i-1].out[1];
|
||||
|
||||
adders[i-1] = MontgomeryAdd();
|
||||
if (i==1) {
|
||||
adders[i-1].in1[0] <== windows[0].out[0];
|
||||
adders[i-1].in1[1] <== windows[0].out[1];
|
||||
} else {
|
||||
adders[i-1].in1[0] <== adders[i-2].out[0];
|
||||
adders[i-1].in1[1] <== adders[i-2].out[1];
|
||||
}
|
||||
adders[i-1].in2[0] <== windows[i].out[0];
|
||||
adders[i-1].in2[1] <== windows[i].out[1];
|
||||
}
|
||||
for (j=0; j<4; j++) {
|
||||
windows[i].in[j] <== in[4*i+j];
|
||||
}
|
||||
}
|
||||
|
||||
component m2e = Montgomery2Edwards();
|
||||
|
||||
if (nWindows > 1) {
|
||||
m2e.in[0] <== adders[nWindows-2].out[0];
|
||||
m2e.in[1] <== adders[nWindows-2].out[1];
|
||||
} else {
|
||||
m2e.in[0] <== windows[0].out[0];
|
||||
m2e.in[1] <== windows[0].out[1];
|
||||
}
|
||||
|
||||
out[0] <== m2e.out[0];
|
||||
out[1] <== m2e.out[1];
|
||||
}
|
||||
|
||||
template Pedersen(n) {
|
||||
signal input in[n];
|
||||
signal output out[2];
|
||||
|
||||
var BASE = [
|
||||
[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;
|
||||
|
||||
component segments[nSegments];
|
||||
|
||||
var i;
|
||||
var j;
|
||||
var nBits;
|
||||
var nWindows;
|
||||
for (i=0; i<nSegments; i++) {
|
||||
nBits = (i == (nSegments-1)) ? n - (nSegments-1)*200 : 200;
|
||||
nWindows = ((nBits - 1)\4)+1;
|
||||
segments[i] = Segment(nWindows);
|
||||
segments[i].base[0] <== BASE[i][0];
|
||||
segments[i].base[1] <== BASE[i][1];
|
||||
for (j = 0; j<nBits; j++) {
|
||||
segments[i].in[j] <== in[i*200+j];
|
||||
}
|
||||
// Fill padding bits
|
||||
for (j = nBits; j < nWindows*4; j++) {
|
||||
segments[i].in[j] <== 0;
|
||||
}
|
||||
}
|
||||
|
||||
component adders[nSegments-1];
|
||||
|
||||
for (i=0; i<nSegments-1; i++) {
|
||||
adders[i] = BabyAdd();
|
||||
if (i==0) {
|
||||
adders[i].x1 <== segments[0].out[0];
|
||||
adders[i].y1 <== segments[0].out[1];
|
||||
adders[i].x2 <== segments[1].out[0];
|
||||
adders[i].y2 <== segments[1].out[1];
|
||||
} else {
|
||||
adders[i].x1 <== adders[i-1].xout;
|
||||
adders[i].y1 <== adders[i-1].yout;
|
||||
adders[i].x2 <== segments[i+1].out[0];
|
||||
adders[i].y2 <== segments[i+1].out[1];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
coponent packPoint = PackPoint();
|
||||
|
||||
if (nSegments>1) {
|
||||
packPoint.in[0] <== adders[nSegments-2].xout;
|
||||
packPoint.in[1] <== adders[nSegments-2].yout;
|
||||
} else {
|
||||
packPoint.in[0] <== segments[0].out[0];
|
||||
packPoint.in[1] <== segments[0].out[1];
|
||||
}
|
||||
|
||||
out[0] <== packPoint.out[0];
|
||||
out[1] <== packPoint.out[1];
|
||||
*/
|
||||
|
||||
if (nSegments>1) {
|
||||
out[0] <== adders[nSegments-2].xout;
|
||||
out[1] <== adders[nSegments-2].yout;
|
||||
} else {
|
||||
out[0] <== segments[0].out[0];
|
||||
out[1] <== segments[0].out[1];
|
||||
}
|
||||
}
|
||||
|
||||
48
circuits/pedersen_old.circom
Normal file
48
circuits/pedersen_old.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];
|
||||
}
|
||||
144
circuits/pointbits.circom
Normal file
144
circuits/pointbits.circom
Normal file
@@ -0,0 +1,144 @@
|
||||
include "bitify.circom";
|
||||
include "aliascheck.circom";
|
||||
include "compconstant.circom";
|
||||
include "babyjub.circom";
|
||||
|
||||
|
||||
function sqrt(n) {
|
||||
|
||||
if (n == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Test that have solution
|
||||
var res = n ** ((-1) >> 1);
|
||||
// if (res!=1) assert(false, "SQRT does not exists");
|
||||
if (res!=1) return 0;
|
||||
|
||||
var m = 28;
|
||||
var c = 19103219067921713944291392827692070036145651957329286315305642004821462161904;
|
||||
var t = n ** 81540058820840996586704275553141814055101440848469862132140264610111;
|
||||
var r = n ** ((81540058820840996586704275553141814055101440848469862132140264610111+1)>>1);
|
||||
var sq;
|
||||
var i;
|
||||
var b;
|
||||
var j;
|
||||
|
||||
while ((r != 0)&&(t != 1)) {
|
||||
sq = t*t;
|
||||
i = 1;
|
||||
while (sq!=1) {
|
||||
i++;
|
||||
sq = sq*sq;
|
||||
}
|
||||
|
||||
// b = c ^ m-i-1
|
||||
b = c;
|
||||
for (j=0; j< m-i-1; j ++) b = b*b;
|
||||
|
||||
m = i;
|
||||
c = b*b;
|
||||
t = t*c;
|
||||
r = r*b;
|
||||
}
|
||||
|
||||
if (r > ((-1) >> 1)) {
|
||||
r = -r;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
template Bits2Point() {
|
||||
signal input in[256];
|
||||
signal output out[2];
|
||||
}
|
||||
|
||||
template Bits2Point_Strict() {
|
||||
signal input in[256];
|
||||
signal output out[2];
|
||||
|
||||
var i;
|
||||
|
||||
// Check aliasing
|
||||
component aliasCheckY = AliasCheck();
|
||||
for (i=0; i<254; i++) {
|
||||
aliasCheckY.in[i] <== in[i];
|
||||
}
|
||||
in[254] === 0;
|
||||
|
||||
component b2nY = Bits2Num(254);
|
||||
for (i=0; i<254; i++) {
|
||||
b2nY.in[i] <== in[i];
|
||||
}
|
||||
|
||||
out[1] <== b2nY.out;
|
||||
|
||||
var a = 168700;
|
||||
var d = 168696;
|
||||
|
||||
var y2 = out[1] * out[1];
|
||||
|
||||
var x = sqrt( (1-y2)/(a - d*y2) );
|
||||
|
||||
if (in[255] == 1) x = -x;
|
||||
|
||||
out[0] <-- x;
|
||||
|
||||
component babyCheck = BabyCheck();
|
||||
babyCheck.x <== out[0];
|
||||
babyCheck.y <== out[1];
|
||||
|
||||
component n2bX = Num2Bits(254);
|
||||
n2bX.in <== out[0];
|
||||
component aliasCheckX = AliasCheck();
|
||||
for (i=0; i<254; i++) {
|
||||
aliasCheckX.in[i] <== n2bX.out[i];
|
||||
}
|
||||
|
||||
component signCalc = CompConstant(10944121435919637611123202872628637544274182200208017171849102093287904247808);
|
||||
for (i=0; i<254; i++) {
|
||||
signCalc.in[i] <== n2bX.out[i];
|
||||
}
|
||||
|
||||
signCalc.out === in[255];
|
||||
}
|
||||
|
||||
|
||||
template Point2Bits() {
|
||||
signal input in[2];
|
||||
signal output out[256];
|
||||
|
||||
|
||||
}
|
||||
|
||||
template Point2Bits_Strict() {
|
||||
signal input in[2];
|
||||
signal output out[256];
|
||||
|
||||
var i;
|
||||
|
||||
component n2bX = Num2Bits(254);
|
||||
n2bX.in <== in[0];
|
||||
component n2bY = Num2Bits(254);
|
||||
n2bY.in <== in[1];
|
||||
|
||||
component aliasCheckX = AliasCheck();
|
||||
component aliasCheckY = AliasCheck();
|
||||
for (i=0; i<254; i++) {
|
||||
aliasCheckX.in[i] <== n2bX.out[i];
|
||||
aliasCheckY.in[i] <== n2bY.out[i];
|
||||
}
|
||||
|
||||
component signCalc = CompConstant(10944121435919637611123202872628637544274182200208017171849102093287904247808);
|
||||
for (i=0; i<254; i++) {
|
||||
signCalc.in[i] <== n2bX.out[i];
|
||||
}
|
||||
|
||||
for (i=0; i<254; i++) {
|
||||
out[i] <== n2bY.out[i];
|
||||
}
|
||||
out[254] <== 0;
|
||||
out[255] <== signCalc.out;
|
||||
}
|
||||
46
circuits/sha256/ch.circom
Normal file
46
circuits/sha256/ch.circom
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
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];
|
||||
}
|
||||
}
|
||||
52
circuits/sha256/constants.circom
Normal file
52
circuits/sha256/constants.circom
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
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;
|
||||
}
|
||||
}
|
||||
34
circuits/sha256/main.circom
Normal file
34
circuits/sha256/main.circom
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
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();
|
||||
44
circuits/sha256/maj.circom
Normal file
44
circuits/sha256/maj.circom
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
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];
|
||||
}
|
||||
}
|
||||
27
circuits/sha256/rotate.circom
Normal file
27
circuits/sha256/rotate.circom
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
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 ];
|
||||
}
|
||||
}
|
||||
67
circuits/sha256/sha256_2.circom
Normal file
67
circuits/sha256/sha256_2.circom
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
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 "sha256compression.circom";
|
||||
include "../bitify.circom"
|
||||
|
||||
template Sha256_2() {
|
||||
signal input a;
|
||||
signal input b;
|
||||
signal output out;
|
||||
|
||||
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() ;
|
||||
|
||||
var i;
|
||||
|
||||
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;
|
||||
}
|
||||
164
circuits/sha256/sha256compression.circom
Normal file
164
circuits/sha256/sha256compression.circom
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
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 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 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 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] <== ha0.out[k]
|
||||
b[0][k] <== hb0.out[k]
|
||||
c[0][k] <== hc0.out[k]
|
||||
d[0][k] <== hd0.out[k]
|
||||
e[0][k] <== he0.out[k]
|
||||
f[0][k] <== hf0.out[k]
|
||||
g[0][k] <== hg0.out[k]
|
||||
h[0][k] <== hh0.out[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] <== ha0.out[k];
|
||||
fsum[0].in[1][k] <== a[64][k];
|
||||
fsum[1].in[0][k] <== hb0.out[k];
|
||||
fsum[1].in[1][k] <== b[64][k];
|
||||
fsum[2].in[0][k] <== hc0.out[k];
|
||||
fsum[2].in[1][k] <== c[64][k];
|
||||
fsum[3].in[0][k] <== hd0.out[k];
|
||||
fsum[3].in[1][k] <== d[64][k];
|
||||
fsum[4].in[0][k] <== he0.out[k];
|
||||
fsum[4].in[1][k] <== e[64][k];
|
||||
fsum[5].in[0][k] <== hf0.out[k];
|
||||
fsum[5].in[1][k] <== f[64][k];
|
||||
fsum[6].in[0][k] <== hg0.out[k];
|
||||
fsum[6].in[1][k] <== g[64][k];
|
||||
fsum[7].in[0][k] <== hh0.out[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];
|
||||
}
|
||||
}
|
||||
32
circuits/sha256/shift.circom
Normal file
32
circuits/sha256/shift.circom
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
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 ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
68
circuits/sha256/sigma.circom
Normal file
68
circuits/sha256/sigma.circom
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
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];
|
||||
}
|
||||
}
|
||||
45
circuits/sha256/sigmaplus.circom
Normal file
45
circuits/sha256/sigmaplus.circom
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
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];
|
||||
}
|
||||
}
|
||||
52
circuits/sha256/t1.circom
Normal file
52
circuits/sha256/t1.circom
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
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];
|
||||
}
|
||||
}
|
||||
47
circuits/sha256/t2.circom
Normal file
47
circuits/sha256/t2.circom
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
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];
|
||||
}
|
||||
}
|
||||
44
circuits/sha256/xor3.circom
Normal file
44
circuits/sha256/xor3.circom
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
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];
|
||||
}
|
||||
}
|
||||
16
circuits/sign.circom
Normal file
16
circuits/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;
|
||||
}
|
||||
186
circuits/smt/smtinsert.circom
Normal file
186
circuits/smt/smtinsert.circom
Normal file
@@ -0,0 +1,186 @@
|
||||
/***************************************************************************************************
|
||||
|
||||
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 ┃◀─────┐
|
||||
└───────┘ ┗━━━━━━━┛ │ └───────┘ ┗━━━━━━━┛ │
|
||||
│ │
|
||||
│ │
|
||||
┌────┴────┐ ┏━━━┻━━━┓ ┌───────┐
|
||||
old1 │Old1Leaf │ ┌─────▶┃ Hash ┃◀──┼─ 0 │
|
||||
└─────────┘ │ ┗━━━━━━━┛ └───────┘
|
||||
│
|
||||
│
|
||||
┏━━━━━━━┓ ┌───────┐ ┏━━━┻━━━┓
|
||||
bot ┃ Hash ┃ │ 0 ─┼──▶┃ Hash ┃◀─────┐
|
||||
┗━━━━━━━┛ └───────┘ ┗━━━━━━━┛ │
|
||||
│
|
||||
│
|
||||
┏━━━━━━━┓ ┏━━━┻━━━┓ ┌───────┐
|
||||
bot ┃ Hash ┃ ┌─────▶┃ Hash ┃◀──│ 0 │
|
||||
┗━━━━━━━┛ │ ┗━━━━━━━┛ └───────┘
|
||||
│
|
||||
│
|
||||
┏━━━━━━━┓ ┌─────────┐ ┏━━━┻━━━┓ ┌─────────┐
|
||||
new1 ┃ Hash ┃ │Old1Leaf ├──▶┃ Hash ┃◀──│New1Leaf │
|
||||
┗━━━━━━━┛ └─────────┘ ┗━━━━━━━┛ └─────────┘
|
||||
|
||||
|
||||
┏━━━━━━━┓ ┏━━━━━━━┓
|
||||
na ┃ Hash ┃ ┃ Hash ┃
|
||||
┗━━━━━━━┛ ┗━━━━━━━┛
|
||||
|
||||
|
||||
┏━━━━━━━┓ ┏━━━━━━━┓
|
||||
na ┃ Hash ┃ ┃ Hash ┃
|
||||
┗━━━━━━━┛ ┗━━━━━━━┛
|
||||
|
||||
***************************************************************************************************/
|
||||
|
||||
include "../node_modules/circom/circuits/gates.circom";
|
||||
include "../node_modules/circom/circuits/bitify.circom";
|
||||
|
||||
template SMTInsert(nLevels) {
|
||||
signal input oldRoot;
|
||||
signal input newRoot;
|
||||
signal input siblings[nLevels];
|
||||
signal input oldHKey;
|
||||
signal input oldHValue;
|
||||
signal input newHKey;
|
||||
signal input newHValue;
|
||||
|
||||
component hash1Old = SMTHash1();
|
||||
hash1Old.l <== oldHKey;
|
||||
hash1Old.r <== oldHValue;
|
||||
|
||||
component hash1New = SMTHash1();
|
||||
hash1New.l <== newHKey;
|
||||
hash1New.r <== newHValue;
|
||||
|
||||
component n2bOld = Num2BinStrinct();
|
||||
component n2bNew = Num2BinStrinct();
|
||||
|
||||
component dmtLevIns = SMTLevIns(nLevels);
|
||||
for (var i=0; i<nLevels; i++) dmtLevIns.siblings[i] <== siblings[i];
|
||||
|
||||
component xors[nLevels];
|
||||
for (var i=0; i<nLevels; i++) {
|
||||
xors[i] = XOR();
|
||||
xors[i].a <== n2bOld.out[i];
|
||||
xors[i].a <== n2bNew.out[i];
|
||||
}
|
||||
|
||||
component isOld0 = IsZero();
|
||||
isOld0.in <== oldHValue;
|
||||
|
||||
component sm[nLevels];
|
||||
for (var i=0; i<sm; i++) {
|
||||
sm[i] = SMTInsertSM();
|
||||
if (i==0) {
|
||||
sm[i].prevst_top <== 1;
|
||||
sm[i].prevst_old1 <== 0;
|
||||
sm[i].prevst_old0 <== 0;
|
||||
sm[i].prevst_bot <== 0;
|
||||
sm[i].prevst_new1 <== 0;
|
||||
sm[i].prevst_na <== 0;
|
||||
} else {
|
||||
sm[i].prevst_top <== sm[i-1].st_top;
|
||||
sm[i].prevst_old1 <== sm[i-1].st_old1;
|
||||
sm[i].prevst_old0 <== sm[i-1].st_old0;
|
||||
sm[i].prevst_bot <== sm[i-1].st_bot;
|
||||
sm[i].prevst_new1 <== sm[i-1].st_new1;
|
||||
sm[i].prevst_na <== sm[i-1].st_na;
|
||||
}
|
||||
sm[i].is0 <== isOld0.out;
|
||||
sm[i].xor <== xors[i].out;
|
||||
sm[i].levIns <== dmtLevIns.out[i];
|
||||
}
|
||||
sm[nLevels-1].prevst_na === 1;
|
||||
|
||||
component levels[nLevels];
|
||||
for (var i=nLevels-1; i != -1; i--) {
|
||||
levels[i] = SMTInsertLevel();
|
||||
|
||||
levels[i].st_top <== sm[i].st_top;
|
||||
levels[i].st_old1 <== sm[i].st_old1;
|
||||
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].sibling <== siblings[i];
|
||||
levels[i].old1leaf <== hash1Old.out;
|
||||
levels[i].new1leaf <== hash1New.out;
|
||||
|
||||
levels[i].new1lrbit <== 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;
|
||||
}
|
||||
}
|
||||
|
||||
levels[0].oldRoot === oldRoot;
|
||||
levels[0].newRoot === newRoot;
|
||||
}
|
||||
76
circuits/smt/smtinsertlevel.circom
Normal file
76
circuits/smt/smtinsertlevel.circom
Normal file
@@ -0,0 +1,76 @@
|
||||
|
||||
|
||||
/******
|
||||
|
||||
SMTInsertLevel
|
||||
|
||||
This circuit has 2 has
|
||||
|
||||
Outputs according to the state.
|
||||
|
||||
State oldRoot newRoot
|
||||
===== ======= =======
|
||||
top H'(oldChild, sibling) H'(newChild, sibling)
|
||||
old1 old1leaf H'(newChild, 0)
|
||||
old0 0 new1leaf
|
||||
bot 0 H'(newChild, 0)
|
||||
new1 0 H'(new1leaf, old1leaf)
|
||||
na 0 0
|
||||
|
||||
H' is the Hash function with the inputs shifted acordingly.
|
||||
|
||||
*****/
|
||||
|
||||
|
||||
template SMTInsertLevel() {
|
||||
signal input st_top;
|
||||
signal input st_old1;
|
||||
signal input st_old0;
|
||||
signal input st_bot;
|
||||
signal input st_new1;
|
||||
signal input st_na;
|
||||
|
||||
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.inL <== oldChild;
|
||||
oldSwitcher.inR <== sibling;
|
||||
|
||||
oldSwitcher.sel <== newlrbit;
|
||||
oldProofHash.L <== oldSwitcher.outL;
|
||||
oldProofHash.R <== oldSwitcher.outR;
|
||||
|
||||
aux[0] <== old1 * st_old1;
|
||||
oldRoot <== aux[0] + oldProofHash.out * st_top;
|
||||
|
||||
// New side
|
||||
|
||||
aux[1] <== newChild * ( st_top + st_old1 + st_but);
|
||||
oldSwitcher.inL <== aux[1] + new1leaf*st_new1;
|
||||
|
||||
aux[2] <== sibling*st_top;
|
||||
oldSwitcher.inR <== aux[2] + old1leaf*st_new1;
|
||||
|
||||
newProofHash.sel <== newlrbit;
|
||||
newProofHash.L <== newProofHash.outL;
|
||||
newProofHash.R <== newProofHash.outR;
|
||||
|
||||
aux[3] <== newProofHash.out * (st_top + st_old1 + st_bot + st_new1);
|
||||
newRoot <== aux[3] + new1leaf * st_old0;
|
||||
}
|
||||
58
circuits/smt/smtinsertsm.circom
Normal file
58
circuits/smt/smtinsertsm.circom
Normal file
@@ -0,0 +1,58 @@
|
||||
/***************************************************************************************************
|
||||
Each level on a SMTInsert 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 in an empty leaf and 0 if we are inserting
|
||||
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 and old1: When the we reach insert level, we go to old0 and old1 states
|
||||
according to `is0` signal.
|
||||
btn: Once in old1 we go to btn until xor=1
|
||||
new1: This level is reached when xor=1. Here is where we insert the hash of the
|
||||
old and the new trees with just one element.
|
||||
na: Not appliable. After inserting it, we go to the na level.
|
||||
|
||||
|
||||
|
||||
###########
|
||||
levIns==curLevel # #
|
||||
xor=0 is0=1 ┌────────────▶# old0 #────────┐
|
||||
┌─────┐ │ ## ## │
|
||||
│ │ │ ######### │ any
|
||||
│ ▼ │ │
|
||||
│ ########### │ │ ###########
|
||||
│ # # ────────────┘ └────────▶# #
|
||||
└──# top # # na #
|
||||
## ## ────┐ ┌──▶## ##
|
||||
######### │ │ #########
|
||||
│ │
|
||||
│ ########### ########### │ any
|
||||
levIns==curLevel │ # # xor=1 # # │
|
||||
is0=0 └───▶# old1 #─────────────▶# new1 #──┘
|
||||
## ## ## ##
|
||||
#########──┐ #########
|
||||
│ ▲
|
||||
│ ┌─────┘
|
||||
any │ ###########│ xor=1
|
||||
│ # #
|
||||
└─▶# btn #
|
||||
## ##
|
||||
#########◀───────┐
|
||||
│ │
|
||||
│ │
|
||||
└────────────┘
|
||||
xor=0
|
||||
|
||||
***************************************************************************************************/
|
||||
|
||||
state
|
||||
80
circuits/smt/smtlevins.circom
Normal file
80
circuits/smt/smtlevins.circom
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
|
||||
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 siblins[nLevels];
|
||||
signal output levIns[nLevels];
|
||||
signal done[nLevels-1]; // Indicates if the insLevel has aready been detecetd.
|
||||
|
||||
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-2].out === 1;
|
||||
|
||||
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]);
|
||||
}
|
||||
Reference in New Issue
Block a user