Compare commits
18 Commits
audit
...
feat/audit
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3478226049 | ||
|
|
3c2b566e68 | ||
|
|
15eadfe50c | ||
|
|
a1d4d1dca7 | ||
|
|
eeecd07cae | ||
|
|
d6e6a3b3f4 | ||
|
|
b928421c58 | ||
|
|
8445381431 | ||
|
|
42e96c2e1f | ||
|
|
5ec0744303 | ||
|
|
451fb51a0d | ||
|
|
ba656fefbe | ||
|
|
5d626852ae | ||
|
|
de9c7dda46 | ||
|
|
e3eb834322 | ||
|
|
01a5530213 | ||
|
|
50a725c174 | ||
|
|
c4ce4cd946 |
@@ -512,7 +512,7 @@ Implementation of MiMC-7 hash in Fp being... (link to description of the hash)
|
||||
|
||||
### mimcsponge
|
||||
|
||||
- `MiMCSponge(nInputs, nRounds, nOutputs)`
|
||||
- `MiMCSponge(nInputs, nOutputs)`
|
||||
|
||||
- DESCRIPTION
|
||||
- SCHEMA
|
||||
|
||||
@@ -21,7 +21,6 @@ include "compconstant.circom";
|
||||
|
||||
|
||||
template AliasCheck() {
|
||||
|
||||
signal input in[254];
|
||||
|
||||
component compConstant = CompConstant(-1);
|
||||
@@ -30,3 +29,15 @@ template AliasCheck() {
|
||||
|
||||
compConstant.out === 0;
|
||||
}
|
||||
|
||||
template AliasCheckBabyJub() {
|
||||
signal input in[251];
|
||||
signal input enabled;
|
||||
|
||||
component compConstant = CompConstant(2736030358979909402780800718157159386076813972158567259200215660948447373040);
|
||||
|
||||
for (var i=0; i<251; i++) in[i] ==> compConstant.in[i];
|
||||
for (var i=0; i<3; i++) 0 ==> compConstant.in[251+i];
|
||||
|
||||
compConstant.out*enabled === 0;
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ template BabyCheck() {
|
||||
a*x2 + y2 === 1 + d*x2*y2;
|
||||
}
|
||||
|
||||
// Extracts the public key from private key
|
||||
// Extracts the public key from private key, as mentioned in https://tools.ietf.org/html/rfc8032
|
||||
template BabyPbk() {
|
||||
signal private input in;
|
||||
signal output Ax;
|
||||
|
||||
@@ -50,6 +50,7 @@ To waranty binary outputs:
|
||||
This function calculates the number of extra bits in the output to do the full sum.
|
||||
*/
|
||||
|
||||
/* a must be < Nq/2, where Nq is the number of elements in the scalar field */
|
||||
function nbits(a) {
|
||||
var n = 1;
|
||||
var r = 0;
|
||||
@@ -61,6 +62,7 @@ function nbits(a) {
|
||||
}
|
||||
|
||||
|
||||
/* n must be such that (2**(n+1) -2) < Nq/ops, where Nq is the number of bits in the scalar field */
|
||||
template BinSum(n, ops) {
|
||||
var nout = nbits((2**n -1)*ops);
|
||||
signal input in[ops][n];
|
||||
|
||||
@@ -21,6 +21,7 @@ include "comparators.circom";
|
||||
include "aliascheck.circom";
|
||||
|
||||
|
||||
/* This doesn't check aliasing, so for n > 253 there are multiple bit strings for each number */
|
||||
template Num2Bits(n) {
|
||||
signal input in;
|
||||
signal output out[n];
|
||||
@@ -76,6 +77,7 @@ template Bits2Num_strict() {
|
||||
b2n.out ==> out;
|
||||
}
|
||||
|
||||
/* n must not exceed 253 */
|
||||
template Num2BitsNeg(n) {
|
||||
signal input in;
|
||||
signal output out[n];
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
include "compconstant.circom";
|
||||
include "aliascheck.circom";
|
||||
include "pointbits.circom";
|
||||
include "pedersen.circom";
|
||||
include "escalarmulany.circom";
|
||||
@@ -40,12 +40,15 @@ template EdDSAVerifier(n) {
|
||||
|
||||
// Ensure S<Subgroup Order
|
||||
|
||||
component compConstant = CompConstant(2736030358979909402780800718157159386076813972158567259200215660948447373040);
|
||||
component aliasCheck = AliasCheckBabyJub();
|
||||
aliasCheck.enabled <== 1;
|
||||
|
||||
for (i=0; i<254; i++) {
|
||||
S[i] ==> compConstant.in[i];
|
||||
for (i=0; i<251; i++) {
|
||||
S[i] ==> aliasCheck.in[i];
|
||||
}
|
||||
compConstant.out === 0;
|
||||
S[251] === 0;
|
||||
S[252] === 0;
|
||||
S[253] === 0;
|
||||
S[254] === 0;
|
||||
S[255] === 0;
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
include "compconstant.circom";
|
||||
include "aliascheck.circom";
|
||||
include "pointbits.circom";
|
||||
include "mimc.circom";
|
||||
include "bitify.circom";
|
||||
@@ -39,16 +39,15 @@ template EdDSAMiMCVerifier() {
|
||||
|
||||
// Ensure S<Subgroup Order
|
||||
|
||||
component snum2bits = Num2Bits(253);
|
||||
component snum2bits = Num2Bits(251);
|
||||
snum2bits.in <== S;
|
||||
|
||||
component compConstant = CompConstant(2736030358979909402780800718157159386076813972158567259200215660948447373040);
|
||||
component aliasCheck = AliasCheckBabyJub();
|
||||
aliasCheck.enabled <== 1;
|
||||
|
||||
for (i=0; i<253; i++) {
|
||||
snum2bits.out[i] ==> compConstant.in[i];
|
||||
for (i=0; i<251; i++) {
|
||||
snum2bits.out[i] ==> aliasCheck.in[i];
|
||||
}
|
||||
compConstant.in[253] <== 0;
|
||||
compConstant.out === 0;
|
||||
|
||||
// Calculate the h = H(R,A, msg)
|
||||
|
||||
@@ -104,8 +103,8 @@ template EdDSAMiMCVerifier() {
|
||||
5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||
16950150798460657717958625567821834550301663161624707787222815936182638968203
|
||||
];
|
||||
component mulFix = EscalarMulFix(253, BASE8);
|
||||
for (i=0; i<253; i++) {
|
||||
component mulFix = EscalarMulFix(251, BASE8);
|
||||
for (i=0; i<251; i++) {
|
||||
mulFix.e[i] <== snum2bits.out[i];
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
include "compconstant.circom";
|
||||
include "aliascheck.circom";
|
||||
include "pointbits.circom";
|
||||
include "mimcsponge.circom";
|
||||
include "bitify.circom";
|
||||
@@ -39,20 +39,19 @@ template EdDSAMiMCSpongeVerifier() {
|
||||
|
||||
// Ensure S<Subgroup Order
|
||||
|
||||
component snum2bits = Num2Bits(253);
|
||||
component snum2bits = Num2Bits(251);
|
||||
snum2bits.in <== S;
|
||||
|
||||
component compConstant = CompConstant(2736030358979909402780800718157159386076813972158567259200215660948447373040);
|
||||
component aliasCheck = AliasCheckBabyJub();
|
||||
aliasCheck.enabled <== 1;
|
||||
|
||||
for (i=0; i<253; i++) {
|
||||
snum2bits.out[i] ==> compConstant.in[i];
|
||||
for (i=0; i<251; i++) {
|
||||
snum2bits.out[i] ==> aliasCheck.in[i];
|
||||
}
|
||||
compConstant.in[253] <== 0;
|
||||
compConstant.out === 0;
|
||||
|
||||
// Calculate the h = H(R,A, msg)
|
||||
|
||||
component hash = MiMCSponge(5, 220, 1);
|
||||
component hash = MiMCSponge(5, 1);
|
||||
hash.ins[0] <== R8x;
|
||||
hash.ins[1] <== R8y;
|
||||
hash.ins[2] <== Ax;
|
||||
@@ -104,8 +103,8 @@ template EdDSAMiMCSpongeVerifier() {
|
||||
5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||
16950150798460657717958625567821834550301663161624707787222815936182638968203
|
||||
];
|
||||
component mulFix = EscalarMulFix(253, BASE8);
|
||||
for (i=0; i<253; i++) {
|
||||
component mulFix = EscalarMulFix(251, BASE8);
|
||||
for (i=0; i<251; i++) {
|
||||
mulFix.e[i] <== snum2bits.out[i];
|
||||
}
|
||||
|
||||
|
||||
@@ -38,16 +38,15 @@ template EdDSAPoseidonVerifier() {
|
||||
|
||||
// Ensure S<Subgroup Order
|
||||
|
||||
component snum2bits = Num2Bits(253);
|
||||
component snum2bits = Num2Bits(251);
|
||||
snum2bits.in <== S;
|
||||
|
||||
component compConstant = CompConstant(2736030358979909402780800718157159386076813972158567259200215660948447373040);
|
||||
component aliasCheck = AliasCheckBabyJub();
|
||||
aliasCheck.enabled <== enabled;
|
||||
|
||||
for (i=0; i<253; i++) {
|
||||
snum2bits.out[i] ==> compConstant.in[i];
|
||||
for (i=0; i<251; i++) {
|
||||
snum2bits.out[i] ==> aliasCheck.in[i];
|
||||
}
|
||||
compConstant.in[253] <== 0;
|
||||
compConstant.out*enabled === 0;
|
||||
|
||||
// Calculate the h = H(R,A, msg)
|
||||
|
||||
@@ -103,8 +102,8 @@ template EdDSAPoseidonVerifier() {
|
||||
5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||
16950150798460657717958625567821834550301663161624707787222815936182638968203
|
||||
];
|
||||
component mulFix = EscalarMulFix(253, BASE8);
|
||||
for (i=0; i<253; i++) {
|
||||
component mulFix = EscalarMulFix(251, BASE8);
|
||||
for (i=0; i<251; i++) {
|
||||
mulFix.e[i] <== snum2bits.out[i];
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
Copyright 2018 0KIMS association.
|
||||
|
||||
This file is part of circom (Zero Knowledge Circuit Compiler).
|
||||
@@ -71,7 +71,7 @@ template EscalarMulWindow(base, k) {
|
||||
signal input sel[4];
|
||||
signal output out[2];
|
||||
|
||||
component table;
|
||||
var table;
|
||||
component mux;
|
||||
component adder;
|
||||
|
||||
@@ -86,8 +86,8 @@ template EscalarMulWindow(base, k) {
|
||||
}
|
||||
|
||||
for (i=0; i<16; i++) {
|
||||
table.out[i][0] ==> mux.c[0][i];
|
||||
table.out[i][1] ==> mux.c[1][i];
|
||||
mux.c[0][i] <== table[i][0];
|
||||
mux.c[1][i] <== table[i][1];
|
||||
}
|
||||
|
||||
in[0] ==> adder.x1;
|
||||
|
||||
@@ -44,6 +44,7 @@ include "babyjub.circom";
|
||||
A good way to see it is that the accumulator input of the adder >= 2^247*B and the other input
|
||||
is the output of the windows that it's going to be <= 2^246*B
|
||||
*/
|
||||
/* base must not be the neutral element nor points of small order */
|
||||
template WindowMulFix() {
|
||||
signal input in[3];
|
||||
signal input base[2];
|
||||
@@ -133,11 +134,12 @@ template WindowMulFix() {
|
||||
|
||||
/*
|
||||
This component does a multiplication of a escalar times a fix base
|
||||
nWindows must not exceed 82
|
||||
Signals:
|
||||
e: The scalar in bits
|
||||
base: the base point in edwards format
|
||||
out: The result
|
||||
dbl: Point in Edwards to be linked to the next segment.
|
||||
dbl: Point in Montgomery to be linked to the next segment.
|
||||
*/
|
||||
|
||||
template SegmentMulFix(nWindows) {
|
||||
@@ -236,7 +238,7 @@ template EscalarMulFix(n, BASE) {
|
||||
signal output out[2]; // Point (Twisted format)
|
||||
|
||||
var nsegments = (n-1)\246 +1; // 249 probably would work. But I'm not sure and for security I keep 246
|
||||
var nlastsegment = n - (nsegments-1)*249;
|
||||
var nlastsegment = n - (nsegments-1)*246;
|
||||
|
||||
component segments[nsegments];
|
||||
|
||||
@@ -250,13 +252,13 @@ template EscalarMulFix(n, BASE) {
|
||||
|
||||
for (s=0; s<nsegments; s++) {
|
||||
|
||||
nseg = (s < nsegments-1) ? 249 : nlastsegment;
|
||||
nseg = (s < nsegments-1) ? 246 : nlastsegment;
|
||||
nWindows = ((nseg - 1)\3)+1;
|
||||
|
||||
segments[s] = SegmentMulFix(nWindows);
|
||||
|
||||
for (i=0; i<nseg; i++) {
|
||||
segments[s].e[i] <== e[s*249+i];
|
||||
segments[s].e[i] <== e[s*246+i];
|
||||
}
|
||||
|
||||
for (i = nseg; i<nWindows*3; i++) {
|
||||
|
||||
@@ -27,8 +27,8 @@ function pointAdd(x1,y1,x2,y2) {
|
||||
return res;
|
||||
}
|
||||
|
||||
template EscalarMulW4Table(base, k) {
|
||||
signal output out[16][2];
|
||||
function EscalarMulW4Table(base, k) {
|
||||
var out[16][2];
|
||||
|
||||
var i;
|
||||
var p[2];
|
||||
@@ -39,11 +39,13 @@ template EscalarMulW4Table(base, k) {
|
||||
dbl = pointAdd(dbl[0], dbl[1], dbl[0], dbl[1]);
|
||||
}
|
||||
|
||||
out[0][0] <== 0;
|
||||
out[0][1] <== 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];
|
||||
out[i][0] = p[0];
|
||||
out[i][1] = p[1];
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
// implements MiMC-2n/n as hash using a sponge construction.
|
||||
// log_5(21888242871839275222246405745257275088548364400416034343698204186575808495617) ~= 110
|
||||
// => nRounds should be 220
|
||||
template MiMCSponge(nInputs, nRounds, nOutputs) {
|
||||
template MiMCSponge(nInputs, nOutputs) {
|
||||
signal input ins[nInputs];
|
||||
signal input k;
|
||||
signal output outs[nOutputs];
|
||||
|
||||
var nRounds = 220;
|
||||
|
||||
// S = R||C
|
||||
component S[nInputs + nOutputs - 1];
|
||||
|
||||
@@ -39,8 +41,8 @@ template MiMCFeistel(nrounds) {
|
||||
signal output xL_out;
|
||||
signal output xR_out;
|
||||
|
||||
var c = [
|
||||
0,
|
||||
// doesn't contain the first and last round constants, which are always zero
|
||||
var c_partial = [
|
||||
7120861356467848435263064379192047478074060781135320967663101236819528304084,
|
||||
5024705281721889198577876690145313457398658950011302225525409148828000436681,
|
||||
17980351014018068290387269214713820287804403312720763401943303895585469787384,
|
||||
@@ -258,8 +260,7 @@ template MiMCFeistel(nrounds) {
|
||||
18224457394066545825553407391290108485121649197258948320896164404518684305122,
|
||||
274945154732293792784580363548970818611304339008964723447672490026510689427,
|
||||
11050822248291117548220126630860474473945266276626263036056336623671308219529,
|
||||
2119542016932434047340813757208803962484943912710204325088879681995922344971,
|
||||
0
|
||||
2119542016932434047340813757208803962484943912710204325088879681995922344971
|
||||
];
|
||||
|
||||
var t;
|
||||
@@ -268,13 +269,19 @@ template MiMCFeistel(nrounds) {
|
||||
signal xL[nrounds-1];
|
||||
signal xR[nrounds-1];
|
||||
|
||||
var c;
|
||||
for (var i=0; i<nrounds; i++) {
|
||||
t = (i==0) ? k+xL_in : k + xL[i-1] + c[i];
|
||||
if ((i == 0) || (i == nrounds - 1)) {
|
||||
c = 0;
|
||||
} else {
|
||||
c = c_partial[i - 1];
|
||||
}
|
||||
t = (i==0) ? k+xL_in : k + xL[i-1] + c;
|
||||
t2[i] <== t*t;
|
||||
t4[i] <== t2[i]*t2[i];
|
||||
if (i<nrounds-1) {
|
||||
xL[i] <== ((i==0) ? xR_in : xR[i-1]) + t4[i]*t;
|
||||
xR[i] = (i==0) ? xL_in : xL[i-1];
|
||||
xR[i] <== (i==0) ? xL_in : xL[i-1];
|
||||
} else {
|
||||
xR_out <== xR[i-1] + t4[i]*t;
|
||||
xL_out <== xL[i-1];
|
||||
|
||||
@@ -85,6 +85,7 @@ template Montgomery2Edwards() {
|
||||
|
||||
*/
|
||||
|
||||
/* in1 must be != in2 */
|
||||
template MontgomeryAdd() {
|
||||
signal input in1[2];
|
||||
signal input in2[2];
|
||||
|
||||
@@ -108,6 +108,7 @@ template Window4() {
|
||||
}
|
||||
|
||||
|
||||
/* nWindows must not exceed 50 */
|
||||
template Segment(nWindows) {
|
||||
signal input in[nWindows*4];
|
||||
signal input base[2];
|
||||
|
||||
26
package-lock.json
generated
26
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "circomlib",
|
||||
"version": "0.0.18",
|
||||
"version": "0.0.20",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -348,9 +348,9 @@
|
||||
}
|
||||
},
|
||||
"big-integer": {
|
||||
"version": "1.6.44",
|
||||
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.44.tgz",
|
||||
"integrity": "sha512-7MzElZPTyJ2fNvBkPxtFQ2fWIkVmuzw41+BZHSzpEq3ymB2MfeKp1+yXl/tS75xCx+WnyV+yb0kp+K1C3UNwmQ=="
|
||||
"version": "1.6.46",
|
||||
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.46.tgz",
|
||||
"integrity": "sha512-Vj2TNtZ8Y0XaL6HCkzJiEqfykjtv/9wVCWIutMe+QVIXLPe2tCLEzULtYvcX9WRtmNIj3Jqi5tNjIsR0N4QOsg=="
|
||||
},
|
||||
"binary-extensions": {
|
||||
"version": "1.13.1",
|
||||
@@ -601,9 +601,9 @@
|
||||
}
|
||||
},
|
||||
"circom": {
|
||||
"version": "0.0.28",
|
||||
"resolved": "https://registry.npmjs.org/circom/-/circom-0.0.28.tgz",
|
||||
"integrity": "sha512-cYivdFVPUAVsGFgx3/W3BQe50fwiu+w8Mq9rWA/UYLWwjAgY0Ctk+obpxGL5v9ZHJpO6pvmczLnOXmV/KqiB5g==",
|
||||
"version": "0.0.34",
|
||||
"resolved": "https://registry.npmjs.org/circom/-/circom-0.0.34.tgz",
|
||||
"integrity": "sha512-R7yNW8PtX2xREtLYWZ/o5cfKHT/qa+CveXsGVAX1ej7mPrTat9mlEMXEy2vX//IuP9/cnYTY/KxJ2SN05PUeGA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"big-integer": "^1.6.32",
|
||||
@@ -3929,9 +3929,9 @@
|
||||
"integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg=="
|
||||
},
|
||||
"p-limit": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz",
|
||||
"integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==",
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz",
|
||||
"integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==",
|
||||
"requires": {
|
||||
"p-try": "^2.0.0"
|
||||
}
|
||||
@@ -4703,9 +4703,9 @@
|
||||
}
|
||||
},
|
||||
"snarkjs": {
|
||||
"version": "0.1.18",
|
||||
"resolved": "https://registry.npmjs.org/snarkjs/-/snarkjs-0.1.18.tgz",
|
||||
"integrity": "sha512-JWZMBvPPIL424+QCY0PtreIiHTRoX4h4qYvKv3nqKPVZl0T7sw3B/ZeizrCVRz7Jr9vrwZxmzJ0XIg6D1yC8Mg==",
|
||||
"version": "0.1.20",
|
||||
"resolved": "https://registry.npmjs.org/snarkjs/-/snarkjs-0.1.20.tgz",
|
||||
"integrity": "sha512-tYmWiVm1sZiB44aIh5w/3HUaTntTUC4fv+CWs4rR0gfkt2KbHTpArOqZW++/Lxujrn9IypXVhdKVUr/eE6Hxfg==",
|
||||
"requires": {
|
||||
"big-integer": "^1.6.43",
|
||||
"chai": "^4.2.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "circomlib",
|
||||
"version": "0.0.18",
|
||||
"version": "0.0.20",
|
||||
"description": "Basic circuits library for Circom",
|
||||
"main": "index.js",
|
||||
"directories": {
|
||||
@@ -31,7 +31,7 @@
|
||||
"web3": "^1.0.0-beta.55"
|
||||
},
|
||||
"devDependencies": {
|
||||
"circom": "0.0.32",
|
||||
"circom": "0.0.35",
|
||||
"eslint-plugin-mocha": "^5.2.0",
|
||||
"ganache-cli": "^6.4.4",
|
||||
"mocha": "^5.2.0"
|
||||
|
||||
@@ -20,34 +20,29 @@ function createCode(seed, n) {
|
||||
C.push("0x00");
|
||||
C.mload();
|
||||
C.div();
|
||||
C.push("0x3f1a1187"); // MiMCSponge(uint256,uint256,uint256)
|
||||
C.push("0xf47d33b5"); // MiMCSponge(uint256,uint256)
|
||||
C.eq();
|
||||
C.jmpi("start");
|
||||
C.invalid();
|
||||
|
||||
C.label("start");
|
||||
C.push("0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001"); // q
|
||||
C.push("0x44");
|
||||
C.mload(); // k q
|
||||
C.push("0x04");
|
||||
C.mload(); // xL k q
|
||||
C.dup(2); // q xL k q
|
||||
C.mload(); // xL q
|
||||
C.dup(1); // q xL q
|
||||
C.push("0x24");
|
||||
C.mload(); // xR q xL k q
|
||||
C.dup(1); // q xR q xL k q
|
||||
C.dup(0); // q q xR q xL k q
|
||||
C.dup(4); // xL q q xR q xL k q
|
||||
C.dup(6); // k xL q q xR q xL k q
|
||||
C.addmod(); // t=k+xL q xR q xL k q
|
||||
C.dup(1); // q t q xR q xL k q
|
||||
C.dup(0); // q q t q xR q xL k q
|
||||
C.dup(2); // t q q t q xR q xL k q
|
||||
C.dup(0); // t t q q t q xR q xL k q
|
||||
C.mulmod(); // b=t^2 q t q xR q xL k q
|
||||
C.dup(0); // b b q t q xR q xL k q
|
||||
C.mulmod(); // c=t^4 t q xR q xL k q
|
||||
C.mulmod(); // d=t^5 xR q xL k q
|
||||
C.addmod(); // e=t^5+xR xL k q (for next round: xL xR k q)
|
||||
C.mload(); // xR q xL q
|
||||
C.dup(1); // q xR q xL q
|
||||
C.dup(3); // xL q xR q xL q
|
||||
C.dup(1); // q xL q xR q xL q
|
||||
C.dup(0); // q q xL q xR q xL q
|
||||
C.dup(2); // xL q q xL q xR q xL q
|
||||
C.dup(0); // xL xL q q xL q xR q xL q
|
||||
C.mulmod(); // b=xL^2 q xL q xR q xL q
|
||||
C.dup(0); // b b q xL q xR q xL q
|
||||
C.mulmod(); // c=xL^4 xL q xR q xL q
|
||||
C.mulmod(); // d=xL^5 xR q xL q
|
||||
C.addmod(); // e=xL^5+xR xL q (for next round: xL xR q)
|
||||
|
||||
for (let i=0; i<n-1; i++) {
|
||||
if (i < n-2) {
|
||||
@@ -55,27 +50,24 @@ function createCode(seed, n) {
|
||||
} else {
|
||||
ci = "0x00";
|
||||
}
|
||||
C.swap(1); // xR xL k q
|
||||
C.dup(3); // q xR xL k q
|
||||
C.dup(3); // k q xR xL k q
|
||||
C.dup(1); // q k q xR xL k q
|
||||
C.dup(4); // xL q k q xR xL k q
|
||||
C.push(ci); // ci xL q k q xR xL k q
|
||||
C.addmod(); // a=ci+xL k q xR xL k q
|
||||
C.addmod(); // t=a+k xR xL k q
|
||||
C.dup(4); // q t xR xL k q
|
||||
C.swap(1); // t q xR xL k q
|
||||
C.dup(1); // q t q xR xL k q
|
||||
C.dup(0); // q q t q xR xL k q
|
||||
C.dup(2); // t q q t q xR xL k q
|
||||
C.dup(0); // t t q q t q xR xL k q
|
||||
C.mulmod(); // b=t^2 q t q xR xL k q
|
||||
C.dup(0); // b b q t q xR xL k q
|
||||
C.mulmod(); // c=t^4 t q xR xL k q
|
||||
C.mulmod(); // d=t^5 xR xL k q
|
||||
C.dup(4); // q d xR xL k q
|
||||
C.swap(2); // xR d q xL k q
|
||||
C.addmod(); // e=t^5+xR xL k q (for next round: xL xR k q)
|
||||
C.swap(1); // xR xL q
|
||||
C.dup(2); // q xR xL q
|
||||
C.dup(2); // xL q xR xL q
|
||||
C.push(ci); // ci xL q xR xL q
|
||||
C.addmod(); // a=ci+xL xR xL q
|
||||
C.dup(3); // q a xR xL q
|
||||
C.swap(1); // a q xR xL q
|
||||
C.dup(1); // q a q xR xL q
|
||||
C.dup(0); // q q a q xR xL q
|
||||
C.dup(2); // a q q a q xR xL q
|
||||
C.dup(0); // a a q q a q xR xL q
|
||||
C.mulmod(); // b=a^2 q a q xR xL q
|
||||
C.dup(0); // b b q a q xR xL q
|
||||
C.mulmod(); // c=a^4 a q xR xL q
|
||||
C.mulmod(); // d=a^5 xR xL q
|
||||
C.dup(3); // q d xR xL q
|
||||
C.swap(2); // xR d q xL q
|
||||
C.addmod(); // e=a^5+xR xL q (for next round: xL xR q)
|
||||
}
|
||||
|
||||
C.push("0x20");
|
||||
@@ -100,10 +92,6 @@ module.exports.abi = [
|
||||
{
|
||||
"name": "xR_in",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"name": "k",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "MiMCSponge",
|
||||
|
||||
@@ -27,6 +27,14 @@ class SMTMemDb {
|
||||
return this.nodes[keyS];
|
||||
}
|
||||
|
||||
async multiGet(keys) {
|
||||
const promises = [];
|
||||
for (let i=0; i<keys.length; i++) {
|
||||
promises.push(this.get(keys[i]));
|
||||
}
|
||||
return await Promise.all(promises);
|
||||
}
|
||||
|
||||
async setRoot(rt) {
|
||||
this.root = rt;
|
||||
}
|
||||
|
||||
@@ -56,7 +56,8 @@ describe("Aliascheck test", () => {
|
||||
circuit.calculateWitness({in: inp});
|
||||
assert(false);
|
||||
} catch(err) {
|
||||
assert.equal(err.message, "Constraint doesn't match: 1 != 0");
|
||||
assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message) );
|
||||
assert(err.message.indexOf("1 != 0") >= 0);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -67,7 +68,8 @@ describe("Aliascheck test", () => {
|
||||
circuit.calculateWitness({in: inp});
|
||||
assert(false);
|
||||
} catch(err) {
|
||||
assert.equal(err.message, "Constraint doesn't match: 1 != 0");
|
||||
assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message) );
|
||||
assert(err.message.indexOf("1 != 0") >= 0);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
75
test/aliascheckbabyjub.js
Normal file
75
test/aliascheckbabyjub.js
Normal file
@@ -0,0 +1,75 @@
|
||||
const chai = require("chai");
|
||||
const path = require("path");
|
||||
const snarkjs = require("snarkjs");
|
||||
const compiler = require("circom");
|
||||
|
||||
const assert = chai.assert;
|
||||
|
||||
const bigInt = snarkjs.bigInt;
|
||||
|
||||
function print(circuit, w, s) {
|
||||
console.log(s + ": " + w[circuit.getSignalIdx(s)]);
|
||||
}
|
||||
|
||||
function getBits(v, n) {
|
||||
const res = [];
|
||||
for (let i=0; i<n; i++) {
|
||||
if (v.shr(i).isOdd()) {
|
||||
res.push(bigInt.one);
|
||||
} else {
|
||||
res.push(bigInt.zero);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
const r = bigInt("2736030358979909402780800718157159386076813972158567259200215660948447373041");
|
||||
|
||||
describe("Aliascheck test", () => {
|
||||
let circuit;
|
||||
before( async() => {
|
||||
const cirDef = await compiler(path.join(__dirname, "circuits", "aliascheckbabyjub_test.circom"));
|
||||
|
||||
circuit = new snarkjs.Circuit(cirDef);
|
||||
|
||||
console.log("NConstrains: " + circuit.nConstraints);
|
||||
});
|
||||
|
||||
it("Satisfy the aliastest 0", async () => {
|
||||
const inp = getBits(bigInt.zero, 251);
|
||||
circuit.calculateWitness({in: inp});
|
||||
});
|
||||
|
||||
it("Satisfy the aliastest 3", async () => {
|
||||
const inp = getBits(bigInt(3), 251);
|
||||
circuit.calculateWitness({in: inp});
|
||||
});
|
||||
|
||||
it("Satisfy the aliastest r-1", async () => {
|
||||
const inp = getBits(r.sub(bigInt.one), 251);
|
||||
circuit.calculateWitness({in: inp});
|
||||
});
|
||||
|
||||
it("Nhot not satisfy an input of r", async () => {
|
||||
const inp = getBits(r, 251);
|
||||
try {
|
||||
circuit.calculateWitness({in: inp});
|
||||
assert(false);
|
||||
} catch(err) {
|
||||
assert(err.message.indexOf("Constraint doesn't match") >= 0);
|
||||
assert(err.message.indexOf("1 != 0") >= 0);
|
||||
}
|
||||
});
|
||||
|
||||
it("Nhot not satisfy all ones", async () => {
|
||||
const inp = getBits(bigInt(1).shl(251).sub(bigInt(1)), 251);
|
||||
try {
|
||||
circuit.calculateWitness({in: inp});
|
||||
assert(false);
|
||||
} catch(err) {
|
||||
assert(err.message.indexOf("Constraint doesn't match") >= 0);
|
||||
assert(err.message.indexOf("1 != 0") >= 0);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
@@ -100,11 +100,12 @@ describe("Baby Jub test", function () {
|
||||
circuitTest.calculateWitness({x: 1, y: 0});
|
||||
assert(false, "Should be a valid point");
|
||||
} catch(err) {
|
||||
assert.equal(err.message, "Constraint doesn't match: 168700 != 1");
|
||||
assert(/Constraint\sdoesn't\smatch(.*)168700\s!=\s1/.test(err.message) );
|
||||
assert(err.message.indexOf("168700 != 1") >= 0);
|
||||
}
|
||||
});
|
||||
|
||||
it("Should extract the public key from the private one", async () => {
|
||||
it("Should extract the public key from the private one", async () => {
|
||||
|
||||
const rawpvk = Buffer.from("0001020304050607080900010203040506070809000102030405060708090021", "hex");
|
||||
const pvk = eddsa.pruneBuffer(createBlakeHash("blake512").update(rawpvk).digest().slice(0,32));
|
||||
|
||||
@@ -23,7 +23,7 @@ describe("Sum test", () => {
|
||||
it("Should create a sum circuit", async () => {
|
||||
|
||||
const cirDef = await compiler(path.join(__dirname, "circuits", "sum_test.circom"));
|
||||
assert.equal(cirDef.nVars, 101);
|
||||
assert.equal(cirDef.nVars, 97); // 32 (in1) + 32(in2) + 32(out) + 1 (carry)
|
||||
|
||||
const circuit = new snarkjs.Circuit(cirDef);
|
||||
|
||||
|
||||
3
test/circuits/aliascheckbabyjub_test.circom
Normal file
3
test/circuits/aliascheckbabyjub_test.circom
Normal file
@@ -0,0 +1,3 @@
|
||||
include "../../circuits/aliascheck.circom";
|
||||
|
||||
component main = AliasCheckBabyJub()
|
||||
3
test/circuits/eddsamimcsponge_test.circom
Normal file
3
test/circuits/eddsamimcsponge_test.circom
Normal file
@@ -0,0 +1,3 @@
|
||||
include "../../circuits/eddsamimcsponge.circom";
|
||||
|
||||
component main = EdDSAMiMCSpongeVerifier();
|
||||
@@ -8,7 +8,7 @@ template Main() {
|
||||
var i;
|
||||
|
||||
var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||
16950150798460657717958625567821834550301663161624707787222815936182638968203]
|
||||
16950150798460657717958625567821834550301663161624707787222815936182638968203];
|
||||
|
||||
component escalarMul = EscalarMul(256, base);
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ template Main() {
|
||||
signal output out[2];
|
||||
|
||||
var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||
16950150798460657717958625567821834550301663161624707787222815936182638968203]
|
||||
16950150798460657717958625567821834550301663161624707787222815936182638968203];
|
||||
|
||||
|
||||
component n2b = Num2Bits(253);
|
||||
|
||||
@@ -8,7 +8,7 @@ template Main() {
|
||||
var i;
|
||||
|
||||
var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||
16950150798460657717958625567821834550301663161624707787222815936182638968203]
|
||||
16950150798460657717958625567821834550301663161624707787222815936182638968203];
|
||||
|
||||
component escalarMul = EscalarMul(256, base);
|
||||
|
||||
|
||||
@@ -7,10 +7,10 @@ template Main() {
|
||||
var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||
16950150798460657717958625567821834550301663161624707787222815936182638968203];
|
||||
|
||||
component escalarMul = EscalarMulW4Table(base, 0);
|
||||
var escalarMul = EscalarMulW4Table(base, 0);
|
||||
for (var i=0; i<16; i++) {
|
||||
out[i][0] <== escalarMul.out[i][0]*in;
|
||||
out[i][1] <== escalarMul.out[i][1]*in;
|
||||
out[i][0] <== escalarMul[i][0]*in;
|
||||
out[i][1] <== escalarMul[i][1]*in;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,10 +7,10 @@ template Main() {
|
||||
var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
|
||||
16950150798460657717958625567821834550301663161624707787222815936182638968203];
|
||||
|
||||
component escalarMul = EscalarMulW4Table(base, 3);
|
||||
var escalarMul = EscalarMulW4Table(base, 3);
|
||||
for (var i=0; i<16; i++) {
|
||||
out[i][0] <== escalarMul.out[i][0]*in;
|
||||
out[i][1] <== escalarMul.out[i][1]*in;
|
||||
out[i][0] <== escalarMul[i][0]*in;
|
||||
out[i][1] <== escalarMul[i][1]*in;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
include "../../circuits/mimcsponge.circom"
|
||||
|
||||
component main = MiMCSponge(2, 220, 3);
|
||||
component main = MiMCSponge(2, 3);
|
||||
|
||||
@@ -67,7 +67,7 @@ describe("EdDSA MiMC test", function () {
|
||||
M: msg});
|
||||
assert(false);
|
||||
} catch(err) {
|
||||
assert.equal(err.message, "Constraint doesn't match: 1 != 0");
|
||||
assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message) );
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
99
test/eddsamimcsponge.js
Normal file
99
test/eddsamimcsponge.js
Normal file
@@ -0,0 +1,99 @@
|
||||
const chai = require("chai");
|
||||
const path = require("path");
|
||||
const snarkjs = require("snarkjs");
|
||||
const compiler = require("circom");
|
||||
|
||||
const eddsa = require("../src/eddsa.js");
|
||||
|
||||
const assert = chai.assert;
|
||||
|
||||
const bigInt = snarkjs.bigInt;
|
||||
|
||||
describe("EdDSA MiMCSponge test", function () {
|
||||
let circuit;
|
||||
|
||||
this.timeout(100000);
|
||||
|
||||
before( async () => {
|
||||
const cirDef = await compiler(path.join(__dirname, "circuits", "eddsamimcsponge_test.circom"));
|
||||
|
||||
circuit = new snarkjs.Circuit(cirDef);
|
||||
|
||||
console.log("NConstrains EdDSA MiMCSponge: " + circuit.nConstraints);
|
||||
});
|
||||
|
||||
it("Sign a single number", async () => {
|
||||
const msg = bigInt(1234);
|
||||
|
||||
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
||||
|
||||
const pubKey = eddsa.prv2pub(prvKey);
|
||||
|
||||
const signature = eddsa.signMiMCSponge(prvKey, msg);
|
||||
|
||||
assert(eddsa.verifyMiMCSponge(msg, signature, pubKey));
|
||||
|
||||
const w = circuit.calculateWitness({
|
||||
enabled: 1,
|
||||
Ax: pubKey[0],
|
||||
Ay: pubKey[1],
|
||||
R8x: signature.R8[0],
|
||||
R8y: signature.R8[1],
|
||||
S: signature.S,
|
||||
M: msg});
|
||||
|
||||
assert(circuit.checkWitness(w));
|
||||
});
|
||||
|
||||
it("Detect Invalid signature", async () => {
|
||||
const msg = bigInt(1234);
|
||||
|
||||
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
||||
|
||||
const pubKey = eddsa.prv2pub(prvKey);
|
||||
|
||||
|
||||
const signature = eddsa.signMiMCSponge(prvKey, msg);
|
||||
|
||||
assert(eddsa.verifyMiMCSponge(msg, signature, pubKey));
|
||||
try {
|
||||
const w = circuit.calculateWitness({
|
||||
enabled: 1,
|
||||
Ax: pubKey[0],
|
||||
Ay: pubKey[1],
|
||||
R8x: signature.R8[0].add(bigInt(1)),
|
||||
R8y: signature.R8[1],
|
||||
S: signature.S,
|
||||
M: msg});
|
||||
assert(false);
|
||||
} catch(err) {
|
||||
assert(err.message.indexOf("Constraint doesn't match") >= 0);
|
||||
assert(err.message.indexOf("1 != 0") >= 0);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
it("Test a dissabled circuit with a bad signature", async () => {
|
||||
const msg = bigInt(1234);
|
||||
|
||||
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
||||
|
||||
const pubKey = eddsa.prv2pub(prvKey);
|
||||
|
||||
|
||||
const signature = eddsa.signMiMCSponge(prvKey, msg);
|
||||
|
||||
assert(eddsa.verifyMiMCSponge(msg, signature, pubKey));
|
||||
|
||||
const w = circuit.calculateWitness({
|
||||
enabled: 0,
|
||||
Ax: pubKey[0],
|
||||
Ay: pubKey[1],
|
||||
R8x: signature.R8[0].add(bigInt(1)),
|
||||
R8y: signature.R8[1],
|
||||
S: signature.S,
|
||||
M: msg});
|
||||
|
||||
assert(circuit.checkWitness(w));
|
||||
});
|
||||
});
|
||||
@@ -67,7 +67,7 @@ describe("EdDSA Poseidon test", function () {
|
||||
M: msg});
|
||||
assert(false);
|
||||
} catch(err) {
|
||||
assert.equal(err.message, "Constraint doesn't match: 1 != 0");
|
||||
assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message) );
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@ describe("Exponentioation test", () => {
|
||||
|
||||
const w = circuit.calculateWitness({in: 1});
|
||||
|
||||
assert(circuit.checkWitness(w));
|
||||
|
||||
let g = [bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
||||
bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")]
|
||||
|
||||
@@ -46,12 +48,12 @@ describe("Exponentioation test", () => {
|
||||
for (let i=0; i<16; i++) {
|
||||
const xout1 = w[circuit.getSignalIdx(`main.out[${i}][0]`)];
|
||||
const yout1 = w[circuit.getSignalIdx(`main.out[${i}][1]`)];
|
||||
/*
|
||||
console.log(xout1.toString());
|
||||
console.log(yout1.toString());
|
||||
console.log(dbl[0]);
|
||||
console.log(dbl[1]);
|
||||
*/
|
||||
|
||||
// console.log(xout1.toString());
|
||||
// console.log(yout1.toString());
|
||||
// console.log(dbl[0]);
|
||||
// console.log(dbl[1]);
|
||||
|
||||
assert(xout1.equals(dbl[0]));
|
||||
assert(yout1.equals(dbl[1]));
|
||||
|
||||
@@ -74,6 +76,8 @@ describe("Exponentioation test", () => {
|
||||
|
||||
const w = circuit.calculateWitness({in: 1});
|
||||
|
||||
assert(circuit.checkWitness(w));
|
||||
|
||||
let g = [snarkjs.bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
|
||||
snarkjs.bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")]
|
||||
|
||||
@@ -87,12 +91,12 @@ describe("Exponentioation test", () => {
|
||||
const xout1 = w[circuit.getSignalIdx(`main.out[${i}][0]`)];
|
||||
const yout1 = w[circuit.getSignalIdx(`main.out[${i}][1]`)];
|
||||
|
||||
/*
|
||||
console.log(xout1.toString());
|
||||
console.log(yout1.toString());
|
||||
console.log(dbl[0]);
|
||||
console.log(dbl[1]);
|
||||
*/
|
||||
|
||||
// console.log(xout1.toString());
|
||||
// console.log(yout1.toString());
|
||||
// console.log(dbl[0]);
|
||||
// console.log(dbl[1]);
|
||||
|
||||
assert(xout1.equals(dbl[0]));
|
||||
assert(yout1.equals(dbl[1]));
|
||||
|
||||
@@ -102,7 +106,7 @@ describe("Exponentioation test", () => {
|
||||
});
|
||||
|
||||
it("Should exponentiate g^31", async () => {
|
||||
const cirDef = await compiler(path.join(__dirname, "circuits", "escalarmul_test.circom"));
|
||||
const cirDef = await compiler(path.join(__dirname, "circuits", "escalarmul_test.circom"), {reduceConstraints: true});
|
||||
|
||||
// console.log(JSON.stringify(cirDef, null, 1));
|
||||
|
||||
@@ -146,12 +150,12 @@ describe("Exponentioation test", () => {
|
||||
c = addPoint(c,c);
|
||||
}
|
||||
c = addPoint(c,g);
|
||||
/*
|
||||
console.log(xout2.toString());
|
||||
console.log(yout2.toString());
|
||||
console.log(c[0].toString());
|
||||
console.log(c[1].toString());
|
||||
*/
|
||||
|
||||
// console.log(xout2.toString());
|
||||
// console.log(yout2.toString());
|
||||
// console.log(c[0].toString());
|
||||
// console.log(c[1].toString());
|
||||
|
||||
assert(xout2.equals(c[0]));
|
||||
assert(yout2.equals(c[1]));
|
||||
|
||||
|
||||
@@ -33,8 +33,8 @@ describe("MiMC Sponge Smart contract test", () => {
|
||||
});
|
||||
|
||||
it("Shold calculate the mimc correctly", async () => {
|
||||
const res = await mimc.methods.MiMCSponge(1,2,3).call();
|
||||
const res2 = await mimcjs.hash(1,2,3);
|
||||
const res = await mimc.methods.MiMCSponge(1,2).call();
|
||||
const res2 = await mimcjs.hash(1,2, 0);
|
||||
|
||||
assert.equal(res.xL.toString(), res2.xL.toString());
|
||||
assert.equal(res.xR.toString(), res2.xR.toString());
|
||||
|
||||
@@ -43,6 +43,8 @@ describe("Mux4 test", () => {
|
||||
for (let i=0; i<16; i++) {
|
||||
const w = circuit.calculateWitness({ "selector": i });
|
||||
|
||||
assert(circuit.checkWitness(w));
|
||||
|
||||
assert(w[0].equals(bigInt(1)));
|
||||
|
||||
// console.log(i + " -> " + w[circuit.getSignalIdx("main.out")].toString());
|
||||
@@ -96,6 +98,8 @@ describe("Mux4 test", () => {
|
||||
for (let i=0; i<4; i++) {
|
||||
const w = circuit.calculateWitness({ "selector": i });
|
||||
|
||||
assert(circuit.checkWitness(w));
|
||||
|
||||
assert(w[0].equals(bigInt(1)));
|
||||
|
||||
// console.log(i + " -> " + w[circuit.getSignalIdx("main.out")].toString());
|
||||
@@ -118,6 +122,8 @@ describe("Mux4 test", () => {
|
||||
for (let i=0; i<2; i++) {
|
||||
const w = circuit.calculateWitness({ "selector": i });
|
||||
|
||||
assert(circuit.checkWitness(w));
|
||||
|
||||
assert(w[0].equals(bigInt(1)));
|
||||
|
||||
// console.log(i + " -> " + w[circuit.getSignalIdx("main.out")].toString());
|
||||
|
||||
23
test/rawsmt3.circom
Normal file
23
test/rawsmt3.circom
Normal file
@@ -0,0 +1,23 @@
|
||||
|
||||
include "../circuits/smt/smtverifier.circom";
|
||||
template SMT(nLevels) {
|
||||
signal input root;
|
||||
signal input mtp[nLevels];
|
||||
signal input hi;
|
||||
signal input hv;
|
||||
|
||||
component smtClaimExists = SMTVerifier(nLevels);
|
||||
smtClaimExists.enabled <== 1;
|
||||
smtClaimExists.fnc <== 0;
|
||||
smtClaimExists.root <== root;
|
||||
for (var i=0; i<nLevels; i++) {
|
||||
smtClaimExists.siblings[i] <== mtp[i];
|
||||
}
|
||||
smtClaimExists.oldKey <== 0;
|
||||
smtClaimExists.oldValue <== 0;
|
||||
smtClaimExists.isOld0 <== 0;
|
||||
|
||||
smtClaimExists.key <== hi;
|
||||
smtClaimExists.value <== hv;
|
||||
}
|
||||
component main = SMT(4);
|
||||
@@ -111,5 +111,28 @@ describe("SMT test", function () {
|
||||
assert(circuit.checkWitness(w));
|
||||
});
|
||||
|
||||
it("Check inclussion Adria case", async () => {
|
||||
const e1_hi= bigInt("17124152697573569611556136390143205198134245887034837071647643529178599000839");
|
||||
const e1_hv= bigInt("19650379996168153643111744440707177573540245771926102415571667548153444658179");
|
||||
|
||||
const e2ok_hi= bigInt("16498254692537945203721083102154618658340563351558973077349594629411025251262");
|
||||
const e2ok_hv= bigInt("19650379996168153643111744440707177573540245771926102415571667548153444658179");
|
||||
|
||||
const e2fail_hi= bigInt("17195092312975762537892237130737365903429674363577646686847513978084990105579");
|
||||
const e2fail_hv= bigInt("19650379996168153643111744440707177573540245771926102415571667548153444658179");
|
||||
|
||||
const tree1 = await smt.newMemEmptyTrie();
|
||||
await tree1.insert(e1_hi,e1_hv);
|
||||
await tree1.insert(e2ok_hi,e2ok_hv);
|
||||
|
||||
await testInclusion(tree1, e2ok_hi, circuit);
|
||||
|
||||
const tree2 = await smt.newMemEmptyTrie();
|
||||
await tree2.insert(e1_hi,e1_hv);
|
||||
await tree2.insert(e2fail_hi,e2fail_hv);
|
||||
|
||||
await testInclusion(tree2, e2fail_hi, circuit);
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
98
test/smtverifier_adria.js
Normal file
98
test/smtverifier_adria.js
Normal file
@@ -0,0 +1,98 @@
|
||||
const path = require("path");
|
||||
const snarkjs = require("snarkjs");
|
||||
const compiler = require("circom");
|
||||
const fs = require("fs")
|
||||
|
||||
const bigInt = snarkjs.bigInt;
|
||||
const smt = require("../src/smt.js");
|
||||
|
||||
const circuitSource = `
|
||||
include "../circuits/smt/smtverifier.circom";
|
||||
template SMT(nLevels) {
|
||||
signal input root;
|
||||
signal input mtp[nLevels];
|
||||
signal input hi;
|
||||
signal input hv;
|
||||
|
||||
component smtClaimExists = SMTVerifier(nLevels);
|
||||
smtClaimExists.enabled <== 1;
|
||||
smtClaimExists.fnc <== 0;
|
||||
smtClaimExists.root <== root;
|
||||
for (var i=0; i<nLevels; i++) {
|
||||
smtClaimExists.siblings[i] <== mtp[i];
|
||||
}
|
||||
smtClaimExists.oldKey <== 0;
|
||||
smtClaimExists.oldValue <== 0;
|
||||
smtClaimExists.isOld0 <== 0;
|
||||
|
||||
smtClaimExists.key <== hi;
|
||||
smtClaimExists.value <== hv;
|
||||
}
|
||||
component main = SMT(4);
|
||||
`;
|
||||
|
||||
describe("smt3test", function () {
|
||||
this.timeout(200000);
|
||||
|
||||
let circuitFileName;
|
||||
|
||||
before( async () => {
|
||||
circuitFileName = path.join(__dirname, ".", "rawsmt3.circom");
|
||||
fs.writeFileSync(circuitFileName,circuitSource);
|
||||
});
|
||||
|
||||
const levels = 4;
|
||||
async function testsmt3(e1, e2) {
|
||||
let tree = await smt.newMemEmptyTrie();
|
||||
|
||||
// insert e1, e2
|
||||
await tree.insert(e1.hi, e1.hv);
|
||||
await tree.insert(e2.hi, e2.hv);
|
||||
|
||||
// generate proof for e1
|
||||
const findInfo = await tree.find(e1.hi);
|
||||
const siblings = findInfo.siblings;
|
||||
while (siblings.length < levels) siblings.push(bigInt(0));
|
||||
|
||||
const input = {
|
||||
root: tree.root,
|
||||
mtp: siblings,
|
||||
hi: e1.hi,
|
||||
hv: e1.hv,
|
||||
};
|
||||
|
||||
const compiledCircuit = await compiler(
|
||||
circuitFileName,
|
||||
{ reduceConstraints: false }
|
||||
);
|
||||
|
||||
const circuit = new snarkjs.Circuit(compiledCircuit);
|
||||
const witness = circuit.calculateWitness(input);
|
||||
circuit.checkWitness(witness);
|
||||
}
|
||||
|
||||
it("TestSmts", async () => {
|
||||
|
||||
const e1 = {
|
||||
hi: bigInt("17124152697573569611556136390143205198134245887034837071647643529178599000839"),
|
||||
hv: bigInt("19650379996168153643111744440707177573540245771926102415571667548153444658179"),
|
||||
};
|
||||
|
||||
const e2ok = {
|
||||
hi: bigInt("16498254692537945203721083102154618658340563351558973077349594629411025251262"),
|
||||
hv: bigInt("19650379996168153643111744440707177573540245771926102415571667548153444658179"),
|
||||
};
|
||||
|
||||
const e2fail = {
|
||||
hi: bigInt("17195092312975762537892237130737365903429674363577646686847513978084990105579"),
|
||||
hv: bigInt("19650379996168153643111744440707177573540245771926102415571667548153444658179"),
|
||||
};
|
||||
|
||||
console.log("test e1, e2ok");
|
||||
await testsmt3(e1, e2ok);
|
||||
|
||||
console.log("test e1, e2fail");
|
||||
await testsmt3(e1, e2fail);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user