Browse Source

Merge branch 'c_build'

master
Jordi Baylina 4 years ago
parent
commit
0bf26ea5ec
No known key found for this signature in database GPG Key ID: 7480C80C1BE43112
79 changed files with 4052 additions and 4564 deletions
  1. +1
    -5
      .eslintrc.js
  2. +1
    -1
      circuits/babyjub.circom
  3. +4
    -2
      circuits/binsub.circom
  4. +9
    -2
      circuits/binsum.circom
  5. +6
    -2
      circuits/bitify.circom
  6. +3
    -4
      circuits/compconstant.circom
  7. +1
    -1
      circuits/eddsa.circom
  8. +1
    -1
      circuits/eddsamimc.circom
  9. +1
    -1
      circuits/eddsamimcsponge.circom
  10. +1
    -1
      circuits/eddsaposeidon.circom
  11. +1
    -1
      circuits/escalarmul.circom
  12. +3
    -3
      circuits/escalarmulfix.circom
  13. +1
    -1
      circuits/escalarmulw4table.circom
  14. +3
    -2
      circuits/gates.circom
  15. +1
    -1
      circuits/mimc.circom
  16. +5
    -3
      circuits/mimcsponge.circom
  17. +4
    -4
      circuits/pedersen.circom
  18. +1
    -1
      circuits/pedersen_old.circom
  19. +1
    -1
      circuits/pointbits.circom
  20. +13
    -8
      circuits/poseidon.circom
  21. +2
    -2
      circuits/sha256/constants.circom
  22. +3
    -0
      circuits/sha256/sha256compression.circom
  23. +15
    -7
      circuits/sha256/sigma.circom
  24. +7
    -3
      circuits/sha256/sigmaplus.circom
  25. +9
    -4
      circuits/sha256/t1.circom
  26. +8
    -5
      circuits/sha256/t2.circom
  27. +4
    -2
      circuits/smt/smtlevins.circom
  28. +6
    -4
      circuits/smt/smtprocessor.circom
  29. +5
    -3
      circuits/smt/smtverifier.circom
  30. +2844
    -3342
      package-lock.json
  31. +5
    -4
      package.json
  32. +33
    -15
      src/babyjub.js
  33. +32
    -30
      src/eddsa.js
  34. +9
    -8
      src/mimc7.js
  35. +21
    -21
      src/mimcsponge.js
  36. +5
    -6
      src/pedersenHash.js
  37. +11
    -9
      src/poseidon.js
  38. +2
    -2
      src/smt.js
  39. +1
    -1
      src/smt_hashes_mimc.js
  40. +1
    -1
      src/smt_hashes_poseidon.js
  41. +1
    -1
      src/smt_memdb.js
  42. +87
    -0
      src/utils.js
  43. +18
    -19
      test/aliascheck.js
  44. +45
    -58
      test/babyjub.js
  45. +43
    -45
      test/babyjub_js.js
  46. +30
    -35
      test/binsub.js
  47. +20
    -18
      test/binsum.js
  48. +6
    -1
      test/circuits/binsub_test.circom
  49. +1
    -1
      test/circuits/escalarmul_test.circom
  50. +2
    -2
      test/circuits/escalarmul_test_min.circom
  51. +2
    -2
      test/circuits/escalarmulfix_test.circom
  52. +1
    -1
      test/circuits/escalarmulw4table.circom
  53. +2
    -2
      test/circuits/escalarmulw4table_test.circom
  54. +3
    -3
      test/circuits/escalarmulw4table_test3.circom
  55. +258
    -0
      test/circuits/in.json
  56. +6
    -1
      test/circuits/sum_test.circom
  57. +121
    -130
      test/comparators.js
  58. +6
    -13
      test/eddsa.js
  59. +4
    -4
      test/eddsa_js.js
  60. +14
    -16
      test/eddsamimc.js
  61. +16
    -15
      test/eddsaposeidon.js
  62. +49
    -107
      test/escalarmul.js
  63. +11
    -24
      test/escalarmulany.js
  64. +19
    -41
      test/escalarmulfix.js
  65. +5
    -15
      test/mimccircuit.js
  66. +9
    -30
      test/mimcspongecircuit.js
  67. +31
    -39
      test/montgomery.js
  68. +22
    -57
      test/multiplexer.js
  69. +19
    -42
      test/pedersen.js
  70. +10
    -35
      test/pedersen2.js
  71. +6
    -16
      test/point2bits.js
  72. +21
    -36
      test/poseidoncircuit.js
  73. +0
    -23
      test/rawsmt3.circom
  74. +14
    -33
      test/sha256.js
  75. +25
    -34
      test/sign.js
  76. +2
    -3
      test/smtjs.js
  77. +24
    -33
      test/smtprocessor.js
  78. +15
    -17
      test/smtverifier.js
  79. +0
    -98
      test/smtverifier_adria.js

+ 1
- 5
.eslintrc.js

@ -1,7 +1,4 @@
module.exports = { module.exports = {
"plugins": [
"mocha"
],
"env": { "env": {
"es6": true, "es6": true,
"node": true, "node": true,
@ -27,7 +24,6 @@ module.exports = {
"semi": [ "semi": [
"error", "error",
"always" "always"
],
"mocha/no-exclusive-tests": "error"
]
} }
}; };

+ 1
- 1
circuits/babyjub.circom

@ -87,7 +87,7 @@ template BabyPbk() {
signal output Ax; signal output Ax;
signal output Ay; signal output Ay;
var BASE8 = [
var BASE8[2] = [
5299619240641551281634865583518297030282874472190772894086521144482721001553, 5299619240641551281634865583518297030282874472190772894086521144482721001553,
16950150798460657717958625567821834550301663161624707787222815936182638968203 16950150798460657717958625567821834550301663161624707787222815936182638968203
]; ];

+ 4
- 2
circuits/binsub.circom

@ -48,12 +48,14 @@ template BinSub(n) {
var lin = 2**n; var lin = 2**n;
var lout = 0; var lout = 0;
for (var i=0; i<n; i++) {
var i;
for (i=0; i<n; i++) {
lin = lin + in[0][i]*(2**i); lin = lin + in[0][i]*(2**i);
lin = lin - in[1][i]*(2**i); lin = lin - in[1][i]*(2**i);
} }
for (var i=0; i<n; i++) {
for (i=0; i<n; i++) {
out[i] <-- (lin >> i) & 1; out[i] <-- (lin >> i) & 1;
// Ensure out is binary // Ensure out is binary

+ 9
- 2
circuits/binsum.circom

@ -72,19 +72,26 @@ template BinSum(n, ops) {
var k; var k;
var j; var j;
var e2;
e2 = 1;
for (k=0; k<n; k++) { for (k=0; k<n; k++) {
for (j=0; j<ops; j++) { for (j=0; j<ops; j++) {
lin += in[j][k] * 2**k;
lin += in[j][k] * e2;
} }
e2 = e2 + e2;
} }
e2 = 1;
for (k=0; k<nout; k++) { for (k=0; k<nout; k++) {
out[k] <-- (lin >> k) & 1; out[k] <-- (lin >> k) & 1;
// Ensure out is binary // Ensure out is binary
out[k] * (out[k] - 1) === 0; out[k] * (out[k] - 1) === 0;
lout += out[k] * 2**k;
lout += out[k] * e2;
e2 = e2+e2;
} }
// Ensure the sum; // Ensure the sum;

+ 6
- 2
circuits/bitify.circom

@ -26,10 +26,12 @@ template Num2Bits(n) {
signal output out[n]; signal output out[n];
var lc1=0; var lc1=0;
var e2=1;
for (var i = 0; i<n; i++) { for (var i = 0; i<n; i++) {
out[i] <-- (in >> i) & 1; out[i] <-- (in >> i) & 1;
out[i] * (out[i] -1 ) === 0; out[i] * (out[i] -1 ) === 0;
lc1 += out[i] * 2**i;
lc1 += out[i] * e2;
e2 = e2+e2;
} }
lc1 === in; lc1 === in;
@ -54,8 +56,10 @@ template Bits2Num(n) {
signal output out; signal output out;
var lc1=0; var lc1=0;
var e2 = 1;
for (var i = 0; i<n; i++) { for (var i = 0; i<n; i++) {
lc1 += in[i] * 2**i;
lc1 += in[i] * e2;
e2 = e2 + e2;
} }
lc1 ==> out; lc1 ==> out;

+ 3
- 4
circuits/compconstant.circom

@ -46,12 +46,11 @@ template CompConstant(ct) {
slsb = in[i*2]; slsb = in[i*2];
smsb = in[i*2+1]; smsb = in[i*2+1];
if ((cmsb==0)&(clsb==0)) {
if ((cmsb==0)&&(clsb==0)) {
parts[i] <== -b*smsb*slsb + b*smsb + b*slsb; parts[i] <== -b*smsb*slsb + b*smsb + b*slsb;
} else if ((cmsb==0)&(clsb==1)) {
} else if ((cmsb==0)&&(clsb==1)) {
parts[i] <== a*smsb*slsb - a*slsb + b*smsb - a*smsb + a; parts[i] <== a*smsb*slsb - a*slsb + b*smsb - a*smsb + a;
} else if ((cmsb==1)&(clsb==0)) {
} else if ((cmsb==1)&&(clsb==0)) {
parts[i] <== b*smsb*slsb - a*smsb + a; parts[i] <== b*smsb*slsb - a*smsb + a;
} else { } else {
parts[i] <== -a*smsb*slsb + a; parts[i] <== -a*smsb*slsb + a;

+ 1
- 1
circuits/eddsa.circom

@ -122,7 +122,7 @@ template EdDSAVerifier(n) {
// Calculate left side of equation left = S*B8 // Calculate left side of equation left = S*B8
var BASE8 = [
var BASE8[2] = [
5299619240641551281634865583518297030282874472190772894086521144482721001553, 5299619240641551281634865583518297030282874472190772894086521144482721001553,
16950150798460657717958625567821834550301663161624707787222815936182638968203 16950150798460657717958625567821834550301663161624707787222815936182638968203
]; ];

+ 1
- 1
circuits/eddsamimc.circom

@ -100,7 +100,7 @@ template EdDSAMiMCVerifier() {
// Calculate left side of equation left = S*B8 // Calculate left side of equation left = S*B8
var BASE8 = [
var BASE8[2] = [
5299619240641551281634865583518297030282874472190772894086521144482721001553, 5299619240641551281634865583518297030282874472190772894086521144482721001553,
16950150798460657717958625567821834550301663161624707787222815936182638968203 16950150798460657717958625567821834550301663161624707787222815936182638968203
]; ];

+ 1
- 1
circuits/eddsamimcsponge.circom

@ -100,7 +100,7 @@ template EdDSAMiMCSpongeVerifier() {
// Calculate left side of equation left = S*B8 // Calculate left side of equation left = S*B8
var BASE8 = [
var BASE8[2] = [
5299619240641551281634865583518297030282874472190772894086521144482721001553, 5299619240641551281634865583518297030282874472190772894086521144482721001553,
16950150798460657717958625567821834550301663161624707787222815936182638968203 16950150798460657717958625567821834550301663161624707787222815936182638968203
]; ];

+ 1
- 1
circuits/eddsaposeidon.circom

@ -99,7 +99,7 @@ template EdDSAPoseidonVerifier() {
// Calculate left side of equation left = S*B8 // Calculate left side of equation left = S*B8
var BASE8 = [
var BASE8[2] = [
5299619240641551281634865583518297030282874472190772894086521144482721001553, 5299619240641551281634865583518297030282874472190772894086521144482721001553,
16950150798460657717958625567821834550301663161624707787222815936182638968203 16950150798460657717958625567821834550301663161624707787222815936182638968203
]; ];

+ 1
- 1
circuits/escalarmul.circom

@ -71,7 +71,7 @@ template EscalarMulWindow(base, k) {
signal input sel[4]; signal input sel[4];
signal output out[2]; signal output out[2];
var table;
var table[16][2];
component mux; component mux;
component adder; component adder;

+ 3
- 3
circuits/escalarmulfix.circom

@ -176,6 +176,9 @@ template SegmentMulFix(nWindows) {
cadders[i].in1[0] <== cadders[i-1].out[0]; cadders[i].in1[0] <== cadders[i-1].out[0];
cadders[i].in1[1] <== cadders[i-1].out[1]; cadders[i].in1[1] <== cadders[i-1].out[1];
} }
for (j=0; j<3; j++) {
windows[i].in[j] <== e[3*i+j];
}
if (i<nWindows-1) { if (i<nWindows-1) {
cadders[i].in2[0] <== windows[i].out8[0]; cadders[i].in2[0] <== windows[i].out8[0];
cadders[i].in2[1] <== windows[i].out8[1]; cadders[i].in2[1] <== windows[i].out8[1];
@ -185,9 +188,6 @@ template SegmentMulFix(nWindows) {
cadders[i].in2[0] <== dblLast.out[0]; cadders[i].in2[0] <== dblLast.out[0];
cadders[i].in2[1] <== dblLast.out[1]; cadders[i].in2[1] <== dblLast.out[1];
} }
for (j=0; j<3; j++) {
windows[i].in[j] <== e[3*i+j];
}
} }
for (i=0; i<nWindows; i++) { for (i=0; i<nWindows; i++) {

+ 1
- 1
circuits/escalarmulw4table.circom

@ -33,7 +33,7 @@ function EscalarMulW4Table(base, k) {
var i; var i;
var p[2]; var p[2];
var dbl = base;
var dbl[2] = base;
for (i=0; i<k*4; i++) { for (i=0; i<k*4; i++) {
dbl = pointAdd(dbl[0], dbl[1], dbl[0], dbl[1]); dbl = pointAdd(dbl[0], dbl[1], dbl[0], dbl[1]);

+ 3
- 2
circuits/gates.circom

@ -67,6 +67,7 @@ template NOR() {
template MultiAND(n) { template MultiAND(n) {
signal input in[n]; signal input in[n];
signal output out; signal output out;
var i;
if (n==1) { if (n==1) {
out <== in[0]; out <== in[0];
} else if (n==2) { } else if (n==2) {
@ -81,8 +82,8 @@ template MultiAND(n) {
var n2 = n-n\2; var n2 = n-n\2;
ands[0] = MultiAND(n1); ands[0] = MultiAND(n1);
ands[1] = MultiAND(n2); ands[1] = MultiAND(n2);
for (var i=0; i<n1; i++) ands[0].in[i] <== in[i];
for (var i=0; i<n2; i++) ands[1].in[i] <== in[n1+i];
for (i=0; i<n1; i++) ands[0].in[i] <== in[i];
for (i=0; i<n2; i++) ands[1].in[i] <== in[n1+i];
and2.a <== ands[0].out; and2.a <== ands[0].out;
and2.b <== ands[1].out; and2.b <== ands[1].out;
out <== and2.out; out <== and2.out;

+ 1
- 1
circuits/mimc.circom

@ -22,7 +22,7 @@ template MiMC7(nrounds) {
signal input k; signal input k;
signal output out; signal output out;
var c = [
var c[91] = [
0, 0,
20888961410941983456478427210666206549300505294776164667214940546594746570981, 20888961410941983456478427210666206549300505294776164667214940546594746570981,
15265126113435022738560151911929040668591755459209400716467504685752745317193, 15265126113435022738560151911929040668591755459209400716467504685752745317193,

+ 5
- 3
circuits/mimcsponge.circom

@ -6,10 +6,12 @@ template MiMCSponge(nInputs, nRounds, nOutputs) {
signal input k; signal input k;
signal output outs[nOutputs]; signal output outs[nOutputs];
var i;
// S = R||C // S = R||C
component S[nInputs + nOutputs - 1]; component S[nInputs + nOutputs - 1];
for (var i = 0; i < nInputs; i++) {
for (i = 0; i < nInputs; i++) {
S[i] = MiMCFeistel(nRounds); S[i] = MiMCFeistel(nRounds);
S[i].k <== k; S[i].k <== k;
if (i == 0) { if (i == 0) {
@ -23,7 +25,7 @@ template MiMCSponge(nInputs, nRounds, nOutputs) {
outs[0] <== S[nInputs - 1].xL_out; outs[0] <== S[nInputs - 1].xL_out;
for (var i = 0; i < nOutputs - 1; i++) {
for (i = 0; i < nOutputs - 1; i++) {
S[nInputs + i] = MiMCFeistel(nRounds); S[nInputs + i] = MiMCFeistel(nRounds);
S[nInputs + i].k <== k; S[nInputs + i].k <== k;
S[nInputs + i].xL_in <== S[nInputs + i - 1].xL_out; S[nInputs + i].xL_in <== S[nInputs + i - 1].xL_out;
@ -40,7 +42,7 @@ template MiMCFeistel(nrounds) {
signal output xR_out; signal output xR_out;
// doesn't contain the first and last round constants, which are always zero // doesn't contain the first and last round constants, which are always zero
var c_partial = [
var c_partial[218] = [
7120861356467848435263064379192047478074060781135320967663101236819528304084, 7120861356467848435263064379192047478074060781135320967663101236819528304084,
5024705281721889198577876690145313457398658950011302225525409148828000436681, 5024705281721889198577876690145313457398658950011302225525409148828000436681,
17980351014018068290387269214713820287804403312720763401943303895585469787384, 17980351014018068290387269214713820287804403312720763401943303895585469787384,

+ 4
- 4
circuits/pedersen.circom

@ -128,6 +128,9 @@ template Segment(nWindows) {
component adders[nWindows-1]; component adders[nWindows-1];
for (i=0; i<nWindows; i++) { for (i=0; i<nWindows; i++) {
windows[i] = Window4(); windows[i] = Window4();
for (j=0; j<4; j++) {
windows[i].in[j] <== in[4*i+j];
}
if (i==0) { if (i==0) {
windows[i].base[0] <== e2m.out[0]; windows[i].base[0] <== e2m.out[0];
windows[i].base[1] <== e2m.out[1]; windows[i].base[1] <== e2m.out[1];
@ -153,9 +156,6 @@ template Segment(nWindows) {
adders[i-1].in2[0] <== windows[i].out[0]; adders[i-1].in2[0] <== windows[i].out[0];
adders[i-1].in2[1] <== windows[i].out[1]; adders[i-1].in2[1] <== windows[i].out[1];
} }
for (j=0; j<4; j++) {
windows[i].in[j] <== in[4*i+j];
}
} }
component m2e = Montgomery2Edwards(); component m2e = Montgomery2Edwards();
@ -176,7 +176,7 @@ template Pedersen(n) {
signal input in[n]; signal input in[n];
signal output out[2]; signal output out[2];
var BASE = [
var BASE[10][2] = [
[10457101036533406547632367118273992217979173478358440826365724437999023779287,19824078218392094440610104313265183977899662750282163392862422243483260492317], [10457101036533406547632367118273992217979173478358440826365724437999023779287,19824078218392094440610104313265183977899662750282163392862422243483260492317],
[2671756056509184035029146175565761955751135805354291559563293617232983272177,2663205510731142763556352975002641716101654201788071096152948830924149045094], [2671756056509184035029146175565761955751135805354291559563293617232983272177,2663205510731142763556352975002641716101654201788071096152948830924149045094],
[5802099305472655231388284418920769829666717045250560929368476121199858275951,5980429700218124965372158798884772646841287887664001482443826541541529227896], [5802099305472655231388284418920769829666717045250560929368476121199858275951,5980429700218124965372158798884772646841287887664001482443826541541529227896],

+ 1
- 1
circuits/pedersen_old.circom

@ -28,7 +28,7 @@ template Pedersen(n) {
component escalarMuls[nexps]; component escalarMuls[nexps];
var PBASE = [
var PBASE[10][2] = [
[10457101036533406547632367118273992217979173478358440826365724437999023779287,19824078218392094440610104313265183977899662750282163392862422243483260492317], [10457101036533406547632367118273992217979173478358440826365724437999023779287,19824078218392094440610104313265183977899662750282163392862422243483260492317],
[2671756056509184035029146175565761955751135805354291559563293617232983272177,2663205510731142763556352975002641716101654201788071096152948830924149045094], [2671756056509184035029146175565761955751135805354291559563293617232983272177,2663205510731142763556352975002641716101654201788071096152948830924149045094],
[5802099305472655231388284418920769829666717045250560929368476121199858275951,5980429700218124965372158798884772646841287887664001482443826541541529227896], [5802099305472655231388284418920769829666717045250560929368476121199858275951,5980429700218124965372158798884772646841287887664001482443826541541529227896],

+ 1
- 1
circuits/pointbits.circom

@ -61,7 +61,7 @@ function sqrt(n) {
r = r*b; r = r*b;
} }
if (r > ((-1) >> 1)) {
if (r < 0 ) {
r = -r; r = -r;
} }

+ 13
- 8
circuits/poseidon.circom

@ -25,9 +25,12 @@ template Mix(t, M) {
signal output out[t]; signal output out[t];
var lc; var lc;
for (var i=0; i<t; i++) {
var i;
var j;
for (i=0; i<t; i++) {
lc = 0; lc = 0;
for (var j=0; j<t; j++) {
for (j=0; j<t; j++) {
lc = lc + M[i][j]*in[j]; lc = lc + M[i][j]*in[j];
} }
out[i] <== lc; out[i] <== lc;
@ -40,7 +43,7 @@ template Mix(t, M) {
template Poseidon(nInputs, t, nRoundsF, nRoundsP) { template Poseidon(nInputs, t, nRoundsF, nRoundsP) {
var C = [
var C[65] = [
14397397413755236225575615486459253198602422701513067526754101844196324375522, 14397397413755236225575615486459253198602422701513067526754101844196324375522,
10405129301473404666785234951972711717481302463898292859783056520670200613128, 10405129301473404666785234951972711717481302463898292859783056520670200613128,
5179144822360023508491245509308555580251733042407187134628755730783052214509, 5179144822360023508491245509308555580251733042407187134628755730783052214509,
@ -108,7 +111,7 @@ template Poseidon(nInputs, t, nRoundsF, nRoundsP) {
10635360132728137321700090133109897687122647659471659996419791842933639708516 10635360132728137321700090133109897687122647659471659996419791842933639708516
]; ];
var M = [
var M[6][6] = [
[ [
19167410339349846567561662441069598364702008768579734801591448511131028229281, 19167410339349846567561662441069598364702008768579734801591448511131028229281,
14183033936038168803360723133013092560869148726790180682363054735190196956789, 14183033936038168803360723133013092560869148726790180682363054735190196956789,
@ -163,13 +166,15 @@ template Poseidon(nInputs, t, nRoundsF, nRoundsP) {
component sigmaP[nRoundsP]; component sigmaP[nRoundsP];
component mix[nRoundsF + nRoundsP]; component mix[nRoundsF + nRoundsP];
var i;
var j;
var k; var k;
for (var i=0; i<(nRoundsF + nRoundsP); i++) {
for (i=0; i<(nRoundsF + nRoundsP); i++) {
ark[i] = Ark(t, C[i]); ark[i] = Ark(t, C[i]);
mix[i] = Mix(t, M); mix[i] = Mix(t, M);
for (var j=0; j<t; j++) {
for (j=0; j<t; j++) {
if (i==0) { if (i==0) {
if (j<nInputs) { if (j<nInputs) {
ark[i].in[j] <== inputs[j]; ark[i].in[j] <== inputs[j];
@ -183,7 +188,7 @@ template Poseidon(nInputs, t, nRoundsF, nRoundsP) {
if ((i<(nRoundsF/2)) || (i>= (nRoundsP + nRoundsF/2))) { if ((i<(nRoundsF/2)) || (i>= (nRoundsP + nRoundsF/2))) {
k= i<nRoundsF/2 ? i : (i-nRoundsP); k= i<nRoundsF/2 ? i : (i-nRoundsP);
for (var j=0; j<t; j++) {
for (j=0; j<t; j++) {
sigmaF[k][j] = Sigma(); sigmaF[k][j] = Sigma();
sigmaF[k][j].in <== ark[i].out[j]; sigmaF[k][j].in <== ark[i].out[j];
mix[i].in[j] <== sigmaF[k][j].out; mix[i].in[j] <== sigmaF[k][j].out;
@ -193,7 +198,7 @@ template Poseidon(nInputs, t, nRoundsF, nRoundsP) {
sigmaP[k] = Sigma(); sigmaP[k] = Sigma();
sigmaP[k].in <== ark[i].out[0]; sigmaP[k].in <== ark[i].out[0];
mix[i].in[0] <== sigmaP[k].out; mix[i].in[0] <== sigmaP[k].out;
for (var j=1; j<t; j++) {
for (j=1; j<t; j++) {
mix[i].in[j] <== ark[i].out[j]; mix[i].in[j] <== ark[i].out[j];
} }
} }

+ 2
- 2
circuits/sha256/constants.circom

@ -19,7 +19,7 @@
template H(x) { template H(x) {
signal output out[32]; signal output out[32];
var c = [0x6a09e667,
var c[8] = [0x6a09e667,
0xbb67ae85, 0xbb67ae85,
0x3c6ef372, 0x3c6ef372,
0xa54ff53a, 0xa54ff53a,
@ -35,7 +35,7 @@ template H(x) {
template K(x) { template K(x) {
signal output out[32]; signal output out[32];
var c = [
var c[64] = [
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,

+ 3
- 0
circuits/sha256/sha256compression.circom

@ -74,6 +74,9 @@ template Sha256compression() {
sigmaPlus[t-16].in7[k] <== w[t-7][k]; sigmaPlus[t-16].in7[k] <== w[t-7][k];
sigmaPlus[t-16].in15[k] <== w[t-15][k]; sigmaPlus[t-16].in15[k] <== w[t-15][k];
sigmaPlus[t-16].in16[k] <== w[t-16][k]; sigmaPlus[t-16].in16[k] <== w[t-16][k];
}
for (k=0; k<32; k++) {
w[t][k] <== sigmaPlus[t-16].out[k]; w[t][k] <== sigmaPlus[t-16].out[k];
} }
} }

+ 15
- 7
circuits/sha256/sigma.circom

@ -24,22 +24,26 @@ include "shift.circom";
template SmallSigma(ra, rb, rc) { template SmallSigma(ra, rb, rc) {
signal input in[32]; signal input in[32];
signal output out[32]; signal output out[32];
component xor3 = Xor3(32);
var k;
component rota = RotR(32, ra); component rota = RotR(32, ra);
component rotb = RotR(32, rb); component rotb = RotR(32, rb);
component shrc = ShR(32, rc); component shrc = ShR(32, rc);
for (var k=0; k<32; k++) {
for (k=0; k<32; k++) {
rota.in[k] <== in[k]; rota.in[k] <== in[k];
rotb.in[k] <== in[k]; rotb.in[k] <== in[k];
shrc.in[k] <== in[k]; shrc.in[k] <== in[k];
}
component xor3 = Xor3(32);
for (k=0; k<32; k++) {
xor3.a[k] <== rota.out[k]; xor3.a[k] <== rota.out[k];
xor3.b[k] <== rotb.out[k]; xor3.b[k] <== rotb.out[k];
xor3.c[k] <== shrc.out[k]; xor3.c[k] <== shrc.out[k];
}
for (k=0; k<32; k++) {
out[k] <== xor3.out[k]; out[k] <== xor3.out[k];
} }
} }
@ -47,22 +51,26 @@ template SmallSigma(ra, rb, rc) {
template BigSigma(ra, rb, rc) { template BigSigma(ra, rb, rc) {
signal input in[32]; signal input in[32];
signal output out[32]; signal output out[32];
component xor3 = Xor3(32);
var k;
component rota = RotR(32, ra); component rota = RotR(32, ra);
component rotb = RotR(32, rb); component rotb = RotR(32, rb);
component rotc = RotR(32, rc); component rotc = RotR(32, rc);
for (var k=0; k<32; k++) {
for (k=0; k<32; k++) {
rota.in[k] <== in[k]; rota.in[k] <== in[k];
rotb.in[k] <== in[k]; rotb.in[k] <== in[k];
rotc.in[k] <== in[k]; rotc.in[k] <== in[k];
}
component xor3 = Xor3(32);
for (k=0; k<32; k++) {
xor3.a[k] <== rota.out[k]; xor3.a[k] <== rota.out[k];
xor3.b[k] <== rotb.out[k]; xor3.b[k] <== rotb.out[k];
xor3.c[k] <== rotc.out[k]; xor3.c[k] <== rotc.out[k];
}
for (k=0; k<32; k++) {
out[k] <== xor3.out[k]; out[k] <== xor3.out[k];
} }
} }

+ 7
- 3
circuits/sha256/sigmaplus.circom

@ -26,20 +26,24 @@ template SigmaPlus() {
signal input in15[32]; signal input in15[32];
signal input in16[32]; signal input in16[32];
signal output out[32]; signal output out[32];
var k;
component sum = BinSum(32, 4);
component sigma1 = SmallSigma(17,19,10); component sigma1 = SmallSigma(17,19,10);
component sigma0 = SmallSigma(7, 18, 3); component sigma0 = SmallSigma(7, 18, 3);
for (var k=0; k<32; k++) {
for (k=0; k<32; k++) {
sigma1.in[k] <== in2[k]; sigma1.in[k] <== in2[k];
sigma0.in[k] <== in15[k]; sigma0.in[k] <== in15[k];
}
component sum = BinSum(32, 4);
for (k=0; k<32; k++) {
sum.in[0][k] <== sigma1.out[k]; sum.in[0][k] <== sigma1.out[k];
sum.in[1][k] <== in7[k]; sum.in[1][k] <== in7[k];
sum.in[2][k] <== sigma0.out[k]; sum.in[2][k] <== sigma0.out[k];
sum.in[3][k] <== in16[k]; sum.in[3][k] <== in16[k];
}
for (k=0; k<32; k++) {
out[k] <== sum.out[k]; out[k] <== sum.out[k];
} }
} }

+ 9
- 4
circuits/sha256/t1.circom

@ -30,23 +30,28 @@ template T1() {
signal input w[32]; signal input w[32];
signal output out[32]; signal output out[32];
component sum = BinSum(32, 5);
component ch = Ch(32);
var ki;
component ch = Ch(32);
component bigsigma1 = BigSigma(6, 11, 25); component bigsigma1 = BigSigma(6, 11, 25);
for (var ki=0; ki<32; ki++) {
for (ki=0; ki<32; ki++) {
bigsigma1.in[ki] <== e[ki]; bigsigma1.in[ki] <== e[ki];
ch.a[ki] <== e[ki]; ch.a[ki] <== e[ki];
ch.b[ki] <== f[ki]; ch.b[ki] <== f[ki];
ch.c[ki] <== g[ki]
ch.c[ki] <== g[ki];
}
component sum = BinSum(32, 5);
for (ki=0; ki<32; ki++) {
sum.in[0][ki] <== h[ki]; sum.in[0][ki] <== h[ki];
sum.in[1][ki] <== bigsigma1.out[ki]; sum.in[1][ki] <== bigsigma1.out[ki];
sum.in[2][ki] <== ch.out[ki]; sum.in[2][ki] <== ch.out[ki];
sum.in[3][ki] <== k[ki]; sum.in[3][ki] <== k[ki];
sum.in[4][ki] <== w[ki]; sum.in[4][ki] <== w[ki];
}
for (ki=0; ki<32; ki++) {
out[ki] <== sum.out[ki]; out[ki] <== sum.out[ki];
} }
} }

+ 8
- 5
circuits/sha256/t2.circom

@ -26,22 +26,25 @@ template T2() {
signal input b[32]; signal input b[32];
signal input c[32]; signal input c[32];
signal output out[32]; signal output out[32];
component sum = BinSum(32, 2);
var k;
component bigsigma0 = BigSigma(2, 13, 22); component bigsigma0 = BigSigma(2, 13, 22);
component maj = Maj(32); component maj = Maj(32);
for (var k=0; k<32; k++) {
for (k=0; k<32; k++) {
bigsigma0.in[k] <== a[k]; bigsigma0.in[k] <== a[k];
maj.a[k] <== a[k]; maj.a[k] <== a[k];
maj.b[k] <== b[k]; maj.b[k] <== b[k];
maj.c[k] <== c[k]; maj.c[k] <== c[k];
}
component sum = BinSum(32, 2);
for (k=0; k<32; k++) {
sum.in[0][k] <== bigsigma0.out[k]; sum.in[0][k] <== bigsigma0.out[k];
sum.in[1][k] <== maj.out[k]; sum.in[1][k] <== maj.out[k];
}
for (k=0; k<32; k++) {
out[k] <== sum.out[k]; out[k] <== sum.out[k];
} }
} }

+ 4
- 2
circuits/smt/smtlevins.circom

@ -79,9 +79,11 @@ template SMTLevIns(nLevels) {
signal output levIns[nLevels]; signal output levIns[nLevels];
signal done[nLevels-1]; // Indicates if the insLevel has aready been detected. signal done[nLevels-1]; // Indicates if the insLevel has aready been detected.
var i;
component isZero[nLevels]; component isZero[nLevels];
for (var i=0; i<nLevels; i++) {
for (i=0; i<nLevels; i++) {
isZero[i] = IsZero(); isZero[i] = IsZero();
isZero[i].in <== siblings[i]; isZero[i].in <== siblings[i];
} }
@ -91,7 +93,7 @@ template SMTLevIns(nLevels) {
levIns[nLevels-1] <== (1-isZero[nLevels-2].out); levIns[nLevels-1] <== (1-isZero[nLevels-2].out);
done[nLevels-2] <== levIns[nLevels-1]; done[nLevels-2] <== levIns[nLevels-1];
for (var i=nLevels-2; i>0; i--) {
for (i=nLevels-2; i>0; i--) {
levIns[i] <== (1-done[i])*(1-isZero[i-1].out) levIns[i] <== (1-done[i])*(1-isZero[i-1].out)
done[i-1] <== levIns[i] + done[i]; done[i-1] <== levIns[i] + done[i];
} }

+ 6
- 4
circuits/smt/smtprocessor.circom

@ -150,6 +150,8 @@ template SMTProcessor(nLevels) {
signal enabled; signal enabled;
var i;
enabled <== fnc[0] + fnc[1] - fnc[0]*fnc[1] enabled <== fnc[0] + fnc[1] - fnc[0]*fnc[1]
component hash1Old = SMTHash1(); component hash1Old = SMTHash1();
@ -167,18 +169,18 @@ template SMTProcessor(nLevels) {
n2bNew.in <== newKey; n2bNew.in <== newKey;
component smtLevIns = SMTLevIns(nLevels); component smtLevIns = SMTLevIns(nLevels);
for (var i=0; i<nLevels; i++) smtLevIns.siblings[i] <== siblings[i];
for (i=0; i<nLevels; i++) smtLevIns.siblings[i] <== siblings[i];
smtLevIns.enabled <== enabled; smtLevIns.enabled <== enabled;
component xors[nLevels]; component xors[nLevels];
for (var i=0; i<nLevels; i++) {
for (i=0; i<nLevels; i++) {
xors[i] = XOR(); xors[i] = XOR();
xors[i].a <== n2bOld.out[i]; xors[i].a <== n2bOld.out[i];
xors[i].b <== n2bNew.out[i]; xors[i].b <== n2bNew.out[i];
} }
component sm[nLevels]; component sm[nLevels];
for (var i=0; i<nLevels; i++) {
for (i=0; i<nLevels; i++) {
sm[i] = SMTProcessorSM(); sm[i] = SMTProcessorSM();
if (i==0) { if (i==0) {
sm[i].prev_top <== enabled; sm[i].prev_top <== enabled;
@ -204,7 +206,7 @@ template SMTProcessor(nLevels) {
sm[nLevels-1].st_na + sm[nLevels-1].st_new1 + sm[nLevels-1].st_old0 +sm[nLevels-1].st_upd === 1; sm[nLevels-1].st_na + sm[nLevels-1].st_new1 + sm[nLevels-1].st_old0 +sm[nLevels-1].st_upd === 1;
component levels[nLevels]; component levels[nLevels];
for (var i=nLevels-1; i != -1; i--) {
for (i=nLevels-1; i != -1; i--) {
levels[i] = SMTProcessorLevel(); levels[i] = SMTProcessorLevel();
levels[i].st_top <== sm[i].st_top; levels[i].st_top <== sm[i].st_top;

+ 5
- 3
circuits/smt/smtverifier.circom

@ -48,6 +48,8 @@ template SMTVerifier(nLevels) {
signal input value; signal input value;
signal input fnc; signal input fnc;
var i;
component hash1Old = SMTHash1(); component hash1Old = SMTHash1();
hash1Old.key <== oldKey; hash1Old.key <== oldKey;
hash1Old.value <== oldValue; hash1Old.value <== oldValue;
@ -63,11 +65,11 @@ template SMTVerifier(nLevels) {
n2bNew.in <== key; n2bNew.in <== key;
component smtLevIns = SMTLevIns(nLevels); component smtLevIns = SMTLevIns(nLevels);
for (var i=0; i<nLevels; i++) smtLevIns.siblings[i] <== siblings[i];
for (i=0; i<nLevels; i++) smtLevIns.siblings[i] <== siblings[i];
smtLevIns.enabled <== enabled; smtLevIns.enabled <== enabled;
component sm[nLevels]; component sm[nLevels];
for (var i=0; i<nLevels; i++) {
for (i=0; i<nLevels; i++) {
sm[i] = SMTVerifierSM(); sm[i] = SMTVerifierSM();
if (i==0) { if (i==0) {
sm[i].prev_top <== enabled; sm[i].prev_top <== enabled;
@ -89,7 +91,7 @@ template SMTVerifier(nLevels) {
sm[nLevels-1].st_na + sm[nLevels-1].st_iold + sm[nLevels-1].st_inew + sm[nLevels-1].st_i0 === 1; sm[nLevels-1].st_na + sm[nLevels-1].st_iold + sm[nLevels-1].st_inew + sm[nLevels-1].st_i0 === 1;
component levels[nLevels]; component levels[nLevels];
for (var i=nLevels-1; i != -1; i--) {
for (i=nLevels-1; i != -1; i--) {
levels[i] = SMTVerifierLevel(); levels[i] = SMTVerifierLevel();
levels[i].st_top <== sm[i].st_top; levels[i].st_top <== sm[i].st_top;

+ 2844
- 3342
package-lock.json
File diff suppressed because it is too large
View File


+ 5
- 4
package.json

@ -26,14 +26,15 @@
"dependencies": { "dependencies": {
"blake-hash": "^1.1.0", "blake-hash": "^1.1.0",
"blake2b": "^2.1.3", "blake2b": "^2.1.3",
"circom": "0.0.35",
"circom": "0.5.2",
"ffjavascript": "0.0.3",
"snarkjs": "^0.1.20", "snarkjs": "^0.1.20",
"typedarray-to-buffer": "^3.1.5", "typedarray-to-buffer": "^3.1.5",
"web3": "^1.0.0-beta.55"
"web3": "^1.2.6"
}, },
"devDependencies": { "devDependencies": {
"eslint-plugin-mocha": "^5.2.0",
"ganache-cli": "^6.4.4",
"eslint": "^6.8.0",
"ganache-cli": "^6.9.1",
"mocha": "^5.2.0" "mocha": "^5.2.0"
} }
} }

+ 33
- 15
src/babyjub.js

@ -1,5 +1,6 @@
const bn128 = require("snarkjs").bn128;
const bigInt = require("snarkjs").bigInt;
const bigInt = require("big-integer");
const ZqField = require("ffjavascript").ZqField;
const utils = require("./utils.js");
exports.addPoint = addPoint; exports.addPoint = addPoint;
exports.mulPointEscalar = mulPointEscalar; exports.mulPointEscalar = mulPointEscalar;
@ -16,14 +17,14 @@ exports.Base8 = [
bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203") bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")
]; ];
exports.order = bigInt("21888242871839275222246405745257275088614511777268538073601725287587578984328"); exports.order = bigInt("21888242871839275222246405745257275088614511777268538073601725287587578984328");
exports.subOrder = exports.order.shr(3);
exports.p = bn128.r;
exports.subOrder = exports.order.shiftRight(3);
exports.p = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
exports.A = bigInt("168700"); exports.A = bigInt("168700");
exports.D = bigInt("168696"); exports.D = bigInt("168696");
function addPoint(a,b) { function addPoint(a,b) {
const q = bn128.r;
const F = new ZqField(exports.p);
const res = []; const res = [];
@ -31,8 +32,25 @@ function addPoint(a,b) {
res[0] = bigInt((a[0]*b[1] + b[0]*a[1]) * bigInt(bigInt("1") + d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q); res[0] = bigInt((a[0]*b[1] + b[0]*a[1]) * bigInt(bigInt("1") + d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q);
res[1] = bigInt((a[1]*b[1] - cta*a[0]*b[0]) * bigInt(bigInt("1") - d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q); res[1] = bigInt((a[1]*b[1] - cta*a[0]*b[0]) * bigInt(bigInt("1") - d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q);
*/ */
res[0] = bigInt((bigInt(a[0]).mul(b[1]).add(bigInt(b[0]).mul(a[1]))).mul(bigInt(bigInt("1").add(exports.D.mul(a[0]).mul(b[0]).mul(a[1]).mul(b[1]))).inverse(q))).affine(q);
res[1] = bigInt((bigInt(a[1]).mul(b[1]).sub(exports.A.mul(a[0]).mul(b[0]))).mul(bigInt(bigInt("1").sub(exports.D.mul(a[0]).mul(b[0]).mul(a[1]).mul(b[1]))).inverse(q))).affine(q);
const beta = F.mul(a[0],b[1]);
const gamma = F.mul(a[1],b[0]);
const delta = F.mul(
F.sub(a[1], F.mul(exports.A, a[0])),
F.add(b[0], b[1])
);
const tau = F.mul(beta, gamma);
const dtau = F.mul(exports.D, tau);
res[0] = F.div(
F.add(beta, gamma),
F.add(bigInt.one, dtau)
);
res[1] = F.div(
F.add(delta, F.sub(F.mul(exports.A,beta), gamma)),
F.sub(bigInt.one, dtau)
);
return res; return res;
} }
@ -47,7 +65,7 @@ function mulPointEscalar(base, e) {
res = addPoint(res, exp); res = addPoint(res, exp);
} }
exp = addPoint(exp, exp); exp = addPoint(exp, exp);
rem = rem.shr(1);
rem = rem.shiftRight(1);
} }
return res; return res;
@ -60,12 +78,12 @@ function inSubgroup(P) {
} }
function inCurve(P) { function inCurve(P) {
const F = bn128.Fr;
const F = new ZqField(exports.p);
const x2 = F.square(P[0]); const x2 = F.square(P[0]);
const y2 = F.square(P[1]); const y2 = F.square(P[1]);
if (!F.equals(
if (!F.eq(
F.add(F.mul(exports.A, x2), y2), F.add(F.mul(exports.A, x2), y2),
F.add(F.one, F.mul(F.mul(x2, y2), exports.D)))) return false; F.add(F.one, F.mul(F.mul(x2, y2), exports.D)))) return false;
@ -73,15 +91,15 @@ function inCurve(P) {
} }
function packPoint(P) { function packPoint(P) {
const buff = bigInt.leInt2Buff(P[1], 32);
if (P[0].greater(exports.p.shr(1))) {
const buff = utils.leInt2Buff(P[1], 32);
if (P[0].greater(exports.p.shiftRight(1))) {
buff[31] = buff[31] | 0x80; buff[31] = buff[31] | 0x80;
} }
return buff; return buff;
} }
function unpackPoint(_buff) { function unpackPoint(_buff) {
const F = bn128.Fr;
const F = new ZqField(exports.p);
const buff = Buffer.from(_buff); const buff = Buffer.from(_buff);
let sign = false; let sign = false;
@ -90,7 +108,7 @@ function unpackPoint(_buff) {
sign = true; sign = true;
buff[31] = buff[31] & 0x7F; buff[31] = buff[31] & 0x7F;
} }
P[1] = bigInt.leBuff2int(buff);
P[1] = utils.leBuff2int(buff);
if (P[1].greaterOrEquals(exports.p)) return null; if (P[1].greaterOrEquals(exports.p)) return null;
const y2 = F.square(P[1]); const y2 = F.square(P[1]);
@ -103,7 +121,7 @@ function unpackPoint(_buff) {
if (sign) x = F.neg(x); if (sign) x = F.neg(x);
P[0] = F.affine(x);
P[0] = x;
return P; return P;
} }

+ 32
- 30
src/eddsa.js

@ -1,11 +1,13 @@
const createBlakeHash = require("blake-hash"); const createBlakeHash = require("blake-hash");
const bigInt = require("snarkjs").bigInt;
const bigInt = require("big-integer");
const babyJub = require("./babyjub"); const babyJub = require("./babyjub");
const utils = require("./utils");
const pedersenHash = require("./pedersenHash").hash; const pedersenHash = require("./pedersenHash").hash;
const mimc7 = require("./mimc7"); const mimc7 = require("./mimc7");
const poseidon = require("./poseidon.js"); const poseidon = require("./poseidon.js");
const mimcsponge = require("./mimcsponge"); const mimcsponge = require("./mimcsponge");
exports.prv2pub= prv2pub; exports.prv2pub= prv2pub;
exports.sign = sign; exports.sign = sign;
exports.signMiMC = signMiMC; exports.signMiMC = signMiMC;
@ -30,26 +32,26 @@ function pruneBuffer(_buff) {
function prv2pub(prv) { function prv2pub(prv) {
const sBuff = pruneBuffer(createBlakeHash("blake512").update(prv).digest().slice(0,32)); const sBuff = pruneBuffer(createBlakeHash("blake512").update(prv).digest().slice(0,32));
let s = bigInt.leBuff2int(sBuff);
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
let s = utils.leBuff2int(sBuff);
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shiftRight(3));
return A; return A;
} }
function sign(prv, msg) { function sign(prv, msg) {
const h1 = createBlakeHash("blake512").update(prv).digest(); const h1 = createBlakeHash("blake512").update(prv).digest();
const sBuff = pruneBuffer(h1.slice(0,32)); const sBuff = pruneBuffer(h1.slice(0,32));
const s = bigInt.leBuff2int(sBuff);
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
const s = utils.leBuff2int(sBuff);
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shiftRight(3));
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msg])).digest(); const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msg])).digest();
let r = bigInt.leBuff2int(rBuff);
let r = utils.leBuff2int(rBuff);
r = r.mod(babyJub.subOrder); r = r.mod(babyJub.subOrder);
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r); const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
const R8p = babyJub.packPoint(R8); const R8p = babyJub.packPoint(R8);
const Ap = babyJub.packPoint(A); const Ap = babyJub.packPoint(A);
const hmBuff = pedersenHash(Buffer.concat([R8p, Ap, msg])); const hmBuff = pedersenHash(Buffer.concat([R8p, Ap, msg]));
const hm = bigInt.leBuff2int(hmBuff);
const S = r.add(hm.mul(s)).mod(babyJub.subOrder);
const hm = utils.leBuff2int(hmBuff);
const S = r.add(hm.times(s)).mod(babyJub.subOrder);
return { return {
R8: R8, R8: R8,
S: S S: S
@ -59,16 +61,16 @@ function sign(prv, msg) {
function signMiMC(prv, msg) { function signMiMC(prv, msg) {
const h1 = createBlakeHash("blake512").update(prv).digest(); const h1 = createBlakeHash("blake512").update(prv).digest();
const sBuff = pruneBuffer(h1.slice(0,32)); const sBuff = pruneBuffer(h1.slice(0,32));
const s = bigInt.leBuff2int(sBuff);
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
const s = utils.leBuff2int(sBuff);
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shiftRight(3));
const msgBuff = bigInt.leInt2Buff(msg, 32);
const msgBuff = utils.leInt2Buff(msg, 32);
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest(); const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
let r = bigInt.leBuff2int(rBuff);
let r = utils.leBuff2int(rBuff);
r = r.mod(babyJub.subOrder); r = r.mod(babyJub.subOrder);
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r); const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
const hm = mimc7.multiHash([R8[0], R8[1], A[0], A[1], msg]); const hm = mimc7.multiHash([R8[0], R8[1], A[0], A[1], msg]);
const S = r.add(hm.mul(s)).mod(babyJub.subOrder);
const S = r.add(hm.times(s)).mod(babyJub.subOrder);
return { return {
R8: R8, R8: R8,
S: S S: S
@ -78,16 +80,16 @@ function signMiMC(prv, msg) {
function signMiMCSponge(prv, msg) { function signMiMCSponge(prv, msg) {
const h1 = createBlakeHash("blake512").update(prv).digest(); const h1 = createBlakeHash("blake512").update(prv).digest();
const sBuff = pruneBuffer(h1.slice(0,32)); const sBuff = pruneBuffer(h1.slice(0,32));
const s = bigInt.leBuff2int(sBuff);
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
const s = utils.leBuff2int(sBuff);
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shiftRight(3));
const msgBuff = bigInt.leInt2Buff(msg, 32);
const msgBuff = utils.leInt2Buff(msg, 32);
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest(); const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
let r = bigInt.leBuff2int(rBuff);
let r = utils.leBuff2int(rBuff);
r = r.mod(babyJub.subOrder); r = r.mod(babyJub.subOrder);
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r); const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
const hm = mimcsponge.multiHash([R8[0], R8[1], A[0], A[1], msg]); const hm = mimcsponge.multiHash([R8[0], R8[1], A[0], A[1], msg]);
const S = r.add(hm.mul(s)).mod(babyJub.subOrder);
const S = r.add(hm.times(s)).mod(babyJub.subOrder);
return { return {
R8: R8, R8: R8,
S: S S: S
@ -97,17 +99,17 @@ function signMiMCSponge(prv, msg) {
function signPoseidon(prv, msg) { function signPoseidon(prv, msg) {
const h1 = createBlakeHash("blake512").update(prv).digest(); const h1 = createBlakeHash("blake512").update(prv).digest();
const sBuff = pruneBuffer(h1.slice(0,32)); const sBuff = pruneBuffer(h1.slice(0,32));
const s = bigInt.leBuff2int(sBuff);
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shr(3));
const s = utils.leBuff2int(sBuff);
const A = babyJub.mulPointEscalar(babyJub.Base8, s.shiftRight(3));
const msgBuff = bigInt.leInt2Buff(msg, 32);
const msgBuff = utils.leInt2Buff(msg, 32);
const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest(); const rBuff = createBlakeHash("blake512").update(Buffer.concat([h1.slice(32,64), msgBuff])).digest();
let r = bigInt.leBuff2int(rBuff);
let r = utils.leBuff2int(rBuff);
r = r.mod(babyJub.subOrder); r = r.mod(babyJub.subOrder);
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r); const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
const hash = poseidon.createHash(6, 8, 57); const hash = poseidon.createHash(6, 8, 57);
const hm = hash([R8[0], R8[1], A[0], A[1], msg]); const hm = hash([R8[0], R8[1], A[0], A[1], msg]);
const S = r.add(hm.mul(s)).mod(babyJub.subOrder);
const S = r.add(hm.times(s)).mod(babyJub.subOrder);
return { return {
R8: R8, R8: R8,
S: S S: S
@ -128,10 +130,10 @@ function verify(msg, sig, A) {
const R8p = babyJub.packPoint(sig.R8); const R8p = babyJub.packPoint(sig.R8);
const Ap = babyJub.packPoint(A); const Ap = babyJub.packPoint(A);
const hmBuff = pedersenHash(Buffer.concat([R8p, Ap, msg])); const hmBuff = pedersenHash(Buffer.concat([R8p, Ap, msg]));
const hm = bigInt.leBuff2int(hmBuff);
const hm = utils.leBuff2int(hmBuff);
const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S); const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
let Pright = babyJub.mulPointEscalar(A, hm.mul(bigInt("8")));
let Pright = babyJub.mulPointEscalar(A, hm.times(bigInt("8")));
Pright = babyJub.addPoint(sig.R8, Pright); Pright = babyJub.addPoint(sig.R8, Pright);
if (!Pleft[0].equals(Pright[0])) return false; if (!Pleft[0].equals(Pright[0])) return false;
@ -153,7 +155,7 @@ function verifyMiMC(msg, sig, A) {
const hm = mimc7.multiHash([sig.R8[0], sig.R8[1], A[0], A[1], msg]); const hm = mimc7.multiHash([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S); const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
let Pright = babyJub.mulPointEscalar(A, hm.mul(bigInt("8")));
let Pright = babyJub.mulPointEscalar(A, hm.times(bigInt("8")));
Pright = babyJub.addPoint(sig.R8, Pright); Pright = babyJub.addPoint(sig.R8, Pright);
if (!Pleft[0].equals(Pright[0])) return false; if (!Pleft[0].equals(Pright[0])) return false;
@ -177,7 +179,7 @@ function verifyPoseidon(msg, sig, A) {
const hm = hash([sig.R8[0], sig.R8[1], A[0], A[1], msg]); const hm = hash([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S); const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
let Pright = babyJub.mulPointEscalar(A, hm.mul(bigInt("8")));
let Pright = babyJub.mulPointEscalar(A, hm.times(bigInt("8")));
Pright = babyJub.addPoint(sig.R8, Pright); Pright = babyJub.addPoint(sig.R8, Pright);
if (!Pleft[0].equals(Pright[0])) return false; if (!Pleft[0].equals(Pright[0])) return false;
@ -199,7 +201,7 @@ function verifyMiMCSponge(msg, sig, A) {
const hm = mimcsponge.multiHash([sig.R8[0], sig.R8[1], A[0], A[1], msg]); const hm = mimcsponge.multiHash([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S); const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
let Pright = babyJub.mulPointEscalar(A, hm.mul(bigInt("8")));
let Pright = babyJub.mulPointEscalar(A, hm.times(bigInt("8")));
Pright = babyJub.addPoint(sig.R8, Pright); Pright = babyJub.addPoint(sig.R8, Pright);
if (!Pleft[0].equals(Pright[0])) return false; if (!Pleft[0].equals(Pright[0])) return false;
@ -209,14 +211,14 @@ function verifyMiMCSponge(msg, sig, A) {
function packSignature(sig) { function packSignature(sig) {
const R8p = babyJub.packPoint(sig.R8); const R8p = babyJub.packPoint(sig.R8);
const Sp = bigInt.leInt2Buff(sig.S, 32);
const Sp = utils.leInt2Buff(sig.S, 32);
return Buffer.concat([R8p, Sp]); return Buffer.concat([R8p, Sp]);
} }
function unpackSignature(sigBuff) { function unpackSignature(sigBuff) {
return { return {
R8: babyJub.unpackPoint(sigBuff.slice(0,32)), R8: babyJub.unpackPoint(sigBuff.slice(0,32)),
S: bigInt.leBuff2int(sigBuff.slice(32,64))
S: utils.leBuff2int(sigBuff.slice(32,64))
}; };
} }

+ 9
- 8
src/mimc7.js

@ -1,7 +1,8 @@
const bn128 = require("snarkjs").bn128;
const bigInt = require("snarkjs").bigInt;
const bigInt = require("big-integer");
const ZqField = require("ffjavascript").ZqField;
const Web3Utils = require("web3-utils"); const Web3Utils = require("web3-utils");
const F = bn128.Fr;
const F = new ZqField(bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
const SEED = "mimc"; const SEED = "mimc";
const NROUNDS = 91; const NROUNDS = 91;
@ -10,7 +11,7 @@ exports.getIV = (seed) => {
if (typeof seed === "undefined") seed = SEED; if (typeof seed === "undefined") seed = SEED;
const c = Web3Utils.keccak256(seed+"_iv"); const c = Web3Utils.keccak256(seed+"_iv");
const cn = bigInt(Web3Utils.toBN(c).toString()); const cn = bigInt(Web3Utils.toBN(c).toString());
const iv = cn.mod(F.q);
const iv = cn.mod(F.p);
return iv; return iv;
}; };
@ -22,7 +23,7 @@ exports.getConstants = (seed, nRounds) => {
for (let i=1; i<nRounds; i++) { for (let i=1; i<nRounds; i++) {
c = Web3Utils.keccak256(c); c = Web3Utils.keccak256(c);
const n1 = Web3Utils.toBN(c).mod(Web3Utils.toBN(F.q.toString()));
const n1 = Web3Utils.toBN(c).mod(Web3Utils.toBN(F.p.toString()));
const c2 = Web3Utils.padLeft(Web3Utils.toHex(n1), 64); const c2 = Web3Utils.padLeft(Web3Utils.toHex(n1), 64);
cts[i] = bigInt(Web3Utils.toBN(c2).toString()); cts[i] = bigInt(Web3Utils.toBN(c2).toString());
} }
@ -39,9 +40,9 @@ exports.hash = (_x_in, _k) =>{
for (let i=0; i<NROUNDS; i++) { for (let i=0; i<NROUNDS; i++) {
const c = cts[i]; const c = cts[i];
const t = (i==0) ? F.add(x_in, k) : F.add(F.add(r, k), c); const t = (i==0) ? F.add(x_in, k) : F.add(F.add(r, k), c);
r = F.exp(t, 7);
r = F.pow(t, 7);
} }
return F.affine(F.add(r, k));
return F.add(r, k);
}; };
exports.multiHash = (arr, key) => { exports.multiHash = (arr, key) => {
@ -60,5 +61,5 @@ exports.multiHash = (arr, key) => {
exports.hash(bigInt(arr[i]), r) exports.hash(bigInt(arr[i]), r)
); );
} }
return F.affine(r);
return r;
}; };

+ 21
- 21
src/mimcsponge.js

@ -1,7 +1,7 @@
const bn128 = require("snarkjs").bn128;
const bigInt = require("snarkjs").bigInt;
const bigInt = require("big-integer");
const Web3Utils = require("web3-utils"); const Web3Utils = require("web3-utils");
const F = bn128.Fr;
const ZqField = require("ffjavascript").ZqField;
const F = new ZqField(bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
const SEED = "mimcsponge"; const SEED = "mimcsponge";
const NROUNDS = 220; const NROUNDS = 220;
@ -10,7 +10,7 @@ exports.getIV = (seed) => {
if (typeof seed === "undefined") seed = SEED; if (typeof seed === "undefined") seed = SEED;
const c = Web3Utils.keccak256(seed+"_iv"); const c = Web3Utils.keccak256(seed+"_iv");
const cn = bigInt(Web3Utils.toBN(c).toString()); const cn = bigInt(Web3Utils.toBN(c).toString());
const iv = cn.mod(F.q);
const iv = cn.mod(F.p);
return iv; return iv;
}; };
@ -22,7 +22,7 @@ exports.getConstants = (seed, nRounds) => {
for (let i=1; i<nRounds; i++) { for (let i=1; i<nRounds; i++) {
c = Web3Utils.keccak256(c); c = Web3Utils.keccak256(c);
const n1 = Web3Utils.toBN(c).mod(Web3Utils.toBN(F.q.toString()));
const n1 = Web3Utils.toBN(c).mod(Web3Utils.toBN(F.p.toString()));
const c2 = Web3Utils.padLeft(Web3Utils.toHex(n1), 64); const c2 = Web3Utils.padLeft(Web3Utils.toHex(n1), 64);
cts[i] = bigInt(Web3Utils.toBN(c2).toString()); cts[i] = bigInt(Web3Utils.toBN(c2).toString());
} }
@ -42,21 +42,21 @@ exports.hash = (_xL_in, _xR_in, _k) =>{
const t = (i==0) ? F.add(xL, k) : F.add(F.add(xL, k), c); const t = (i==0) ? F.add(xL, k) : F.add(F.add(xL, k), c);
const xR_tmp = bigInt(xR); const xR_tmp = bigInt(xR);
if (i < (NROUNDS - 1)) { if (i < (NROUNDS - 1)) {
xR = xL;
xL = F.add(xR_tmp, F.exp(t, 5));
xR = xL;
xL = F.add(xR_tmp, F.pow(t, 5));
} else { } else {
xR = F.add(xR_tmp, F.exp(t, 5));
xR = F.add(xR_tmp, F.pow(t, 5));
} }
} }
return { return {
xL: F.affine(xL),
xR: F.affine(xR),
xL: F.normalize(xL),
xR: F.normalize(xR),
}; };
}; };
exports.multiHash = (arr, key, numOutputs) => { exports.multiHash = (arr, key, numOutputs) => {
if (typeof(numOutputs) === "undefined") { if (typeof(numOutputs) === "undefined") {
numOutputs = 1;
numOutputs = 1;
} }
if (typeof(key) === "undefined") { if (typeof(key) === "undefined") {
key = F.zero; key = F.zero;
@ -66,21 +66,21 @@ exports.multiHash = (arr, key, numOutputs) => {
let C = F.zero; let C = F.zero;
for (let i=0; i<arr.length; i++) { for (let i=0; i<arr.length; i++) {
R = F.add(R, bigInt(arr[i]));
const S = exports.hash(R, C, key);
R = S.xL;
C = S.xR;
R = F.add(R, bigInt(arr[i]));
const S = exports.hash(R, C, key);
R = S.xL;
C = S.xR;
} }
let outputs = [R]; let outputs = [R];
for (let i=1; i < numOutputs; i++) { for (let i=1; i < numOutputs; i++) {
const S = exports.hash(R, C, key);
R = S.xL;
C = S.xR;
outputs.push(R);
const S = exports.hash(R, C, key);
R = S.xL;
C = S.xR;
outputs.push(R);
} }
if (numOutputs == 1) { if (numOutputs == 1) {
return F.affine(outputs[0]);
return F.normalize(outputs[0]);
} else { } else {
return outputs.map(x => F.affine(x));
return outputs.map(x => F.normalize(x));
} }
}; };

+ 5
- 6
src/pedersenHash.js

@ -1,5 +1,4 @@
const bn128 = require("snarkjs").bn128;
const bigInt = require("snarkjs").bigInt;
const bigInt = require("big-integer");
const babyJub = require("./babyjub"); const babyJub = require("./babyjub");
const createBlakeHash = require("blake-hash"); const createBlakeHash = require("blake-hash");
@ -32,18 +31,18 @@ function pedersenHash(msg) {
let acc = bigInt.one; let acc = bigInt.one;
for (let b=0; ((b<windowSize-1)&&(o<bits.length)) ; b++) { for (let b=0; ((b<windowSize-1)&&(o<bits.length)) ; b++) {
if (bits[o]) { if (bits[o]) {
acc = acc.add( bigInt.one.shl(b) );
acc = acc.add( bigInt.one.shiftLeft(b) );
} }
o++; o++;
} }
if (o<bits.length) { if (o<bits.length) {
if (bits[o]) { if (bits[o]) {
acc = acc.neg();
acc = bigInt.zero.minus(acc);
} }
o++; o++;
} }
escalar = escalar.add(acc.mul(exp));
exp = exp.shl(windowSize+1);
escalar = escalar.add(acc.times(exp));
exp = exp.shiftLeft(windowSize+1);
} }
if (escalar.lesser(bigInt.zero)) { if (escalar.lesser(bigInt.zero)) {

+ 11
- 9
src/poseidon.js

@ -1,8 +1,10 @@
const bn128 = require("snarkjs").bn128;
const bigInt = require("snarkjs").bigInt;
const blake2b = require('blake2b');
const bigInt = require("big-integer");
const blake2b = require("blake2b");
const assert = require("assert"); const assert = require("assert");
const F = bn128.Fr;
const ZqField = require("ffjavascript").ZqField;
const utils = require("./utils");
const F = new ZqField(bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
const SEED = "poseidon"; const SEED = "poseidon";
const NROUNDSF = 8; const NROUNDSF = 8;
@ -12,11 +14,11 @@ const T = 6;
function getPseudoRandom(seed, n) { function getPseudoRandom(seed, n) {
const res = []; const res = [];
let input = Buffer.from(seed); let input = Buffer.from(seed);
let h = blake2b(32).update(input).digest()
let h = blake2b(32).update(input).digest();
while (res.length<n) { while (res.length<n) {
const n = F.affine(bigInt.leBuff2int(h));
const n = F.normalize(utils.leBuff2int(h));
res.push(n); res.push(n);
h = blake2b(32).update(h).digest()
h = blake2b(32).update(h).digest();
} }
return res; return res;
@ -50,7 +52,7 @@ exports.getMatrix = (t, seed, nRounds) => {
for (let i=0; i<t; i++) { for (let i=0; i<t; i++) {
M[i] = new Array(t); M[i] = new Array(t);
for (let j=0; j<t; j++) { for (let j=0; j<t; j++) {
M[i][j] = F.affine(F.inverse(F.sub(cmatrix[i], cmatrix[t+j])));
M[i][j] = F.normalize(F.inv(F.sub(cmatrix[i], cmatrix[t+j])));
} }
} }
return M; return M;
@ -111,7 +113,7 @@ exports.createHash = (t, nRoundsF, nRoundsP, seed) => {
} }
mix(state, M); mix(state, M);
} }
return F.affine(state[0]);
return F.normalize(state[0]);
}; };
}; };

+ 2
- 2
src/smt.js

@ -1,4 +1,4 @@
const bigInt = require("snarkjs").bigInt;
const bigInt = require("big-integer");
const SMTMemDB = require("./smt_memdb"); const SMTMemDB = require("./smt_memdb");
const {hash0, hash1} = require("./smt_hashes_poseidon"); const {hash0, hash1} = require("./smt_hashes_poseidon");
@ -21,7 +21,7 @@ class SMT {
} else { } else {
res.push(false); res.push(false);
} }
k = k.shr(1);
k = k.shiftRight(1);
} }
while (res.length<256) res.push(false); while (res.length<256) res.push(false);

+ 1
- 1
src/smt_hashes_mimc.js

@ -1,5 +1,5 @@
const mimc7 = require("./mimc7"); const mimc7 = require("./mimc7");
const bigInt = require("snarkjs").bigInt;
const bigInt = require("big-integer");
exports.hash0 = function (left, right) { exports.hash0 = function (left, right) {
return mimc7.multiHash(left, right); return mimc7.multiHash(left, right);

+ 1
- 1
src/smt_hashes_poseidon.js

@ -1,5 +1,5 @@
const Poseidon = require("./poseidon"); const Poseidon = require("./poseidon");
const bigInt = require("snarkjs").bigInt;
const bigInt = require("big-integer");
const hash = Poseidon.createHash(6, 8, 57); const hash = Poseidon.createHash(6, 8, 57);

+ 1
- 1
src/smt_memdb.js

@ -1,4 +1,4 @@
const bigInt = require("snarkjs").bigInt;
const bigInt = require("big-integer");
class SMTMemDb { class SMTMemDb {
constructor() { constructor() {

+ 87
- 0
src/utils.js

@ -0,0 +1,87 @@
const bigInt = require("big-integer");
module.exports.leBuff2int = leBuff2int;
module.exports.leInt2Buff = leInt2Buff;
module.exports.beBuff2int = beBuff2int;
module.exports.beInt2Buff = beInt2Buff;
module.exports.stringifyBigInts = stringifyBigInts;
module.exports.unstringifyBigInts = unstringifyBigInts;
function leBuff2int (buff) {
let res = bigInt.zero;
for (let i=0; i<buff.length; i++) {
const n = bigInt(buff[i]);
res = res.add(n.shiftLeft(i*8));
}
return res;
}
function leInt2Buff(n, len) {
let r = n;
let o =0;
const buff = Buffer.alloc(len);
while ((r.gt(bigInt.zero))&&(o<buff.length)) {
let c = Number(r.and(bigInt(255)));
buff[o] = c;
o++;
r = r.shiftRight(8);
}
if (r.gt(bigInt.zero)) throw new Error("Number does not feed in buffer");
return buff;
}
function beBuff2int (buff) {
let res = bigInt.zero;
for (let i=0; i<buff.length; i++) {
const n = bigInt(buff[buff.length - i - 1]);
res = res.add(n.shiftLeft(i*8));
}
return res;
}
function beInt2Buff(n, len) {
let r = n;
let o =len-1;
const buff = Buffer.alloc(len);
while ((r.greater(bigInt.zero))&&(o>=0)) {
let c = Number(r.and(bigInt(255)));
buff[o] = c;
o--;
r = r.shiftRight(8);
}
if (r.gt(bigInt.zero)) throw new Error("Number does not feed in buffer");
return buff;
}
function stringifyBigInts(o) {
if ((typeof(o) == "bigint") || o.isZero !== undefined) {
return o.toString(10);
} else if (Array.isArray(o)) {
return o.map(stringifyBigInts);
} else if (typeof o == "object") {
const res = {};
for (let k in o) {
res[k] = stringifyBigInts(o[k]);
}
return res;
} else {
return o;
}
}
function unstringifyBigInts(o) {
if ((typeof(o) == "string") && (/^[0-9]+$/.test(o) )) {
return bigInt(o);
} else if (Array.isArray(o)) {
return o.map(unstringifyBigInts);
} else if (typeof o == "object") {
const res = {};
for (let k in o) {
res[k] = unstringifyBigInts(o[k]);
}
return res;
} else {
return o;
}
}

+ 18
- 19
test/aliascheck.js

@ -1,11 +1,11 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs");
const compiler = require("circom");
const assert = chai.assert; const assert = chai.assert;
const bigInt = snarkjs.bigInt;
const bigInt = require("big-integer");
const tester = require("circom").tester;
function print(circuit, w, s) { function print(circuit, w, s) {
console.log(s + ": " + w[circuit.getSignalIdx(s)]); console.log(s + ": " + w[circuit.getSignalIdx(s)]);
@ -14,7 +14,7 @@ function print(circuit, w, s) {
function getBits(v, n) { function getBits(v, n) {
const res = []; const res = [];
for (let i=0; i<n; i++) { for (let i=0; i<n; i++) {
if (v.shr(i).isOdd()) {
if (v.shiftRight(i).isOdd()) {
res.push(bigInt.one); res.push(bigInt.one);
} else { } else {
res.push(bigInt.zero); res.push(bigInt.zero);
@ -25,46 +25,45 @@ function getBits(v, n) {
const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"); const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
describe("Aliascheck test", () => {
let circuit;
before( async() => {
const cirDef = await compiler(path.join(__dirname, "circuits", "aliascheck_test.circom"));
describe("Aliascheck test", function () {
this.timeout(100000);
circuit = new snarkjs.Circuit(cirDef);
let cir;
before( async() => {
console.log("NConstrains: " + circuit.nConstraints);
cir = await tester(path.join(__dirname, "circuits", "aliascheck_test.circom"));
}); });
it("Satisfy the aliastest 0", async () => { it("Satisfy the aliastest 0", async () => {
const inp = getBits(bigInt.zero, 254); const inp = getBits(bigInt.zero, 254);
circuit.calculateWitness({in: inp});
await cir.calculateWitness({in: inp}, true);
}); });
it("Satisfy the aliastest 3", async () => { it("Satisfy the aliastest 3", async () => {
const inp = getBits(bigInt(3), 254); const inp = getBits(bigInt(3), 254);
circuit.calculateWitness({in: inp});
await cir.calculateWitness({in: inp}, true);
}); });
it("Satisfy the aliastest q-1", async () => { it("Satisfy the aliastest q-1", async () => {
const inp = getBits(q.sub(bigInt.one), 254);
circuit.calculateWitness({in: inp});
const inp = getBits(q.minus(bigInt.one), 254);
await cir.calculateWitness({in: inp}, true);
}); });
it("Nhot not satisfy an input of q", async () => {
it("Should not satisfy an input of q", async () => {
const inp = getBits(q, 254); const inp = getBits(q, 254);
try { try {
circuit.calculateWitness({in: inp});
await cir.calculateWitness({in: inp}, true);
assert(false); assert(false);
} catch(err) { } catch(err) {
assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message) ); assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message) );
} }
}); });
it("Nhot not satisfy all ones", async () => {
it("Should not satisfy all ones", async () => {
const inp = getBits(bigInt(1).shl(254).sub(bigInt(1)), 254);
const inp = getBits(bigInt(1).shiftLeft(254).minus(bigInt.one), 254);
try { try {
circuit.calculateWitness({in: inp});
await cir.calculateWitness({in: inp}, true);
assert(false); assert(false);
} catch(err) { } catch(err) {
assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message) ); assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message) );

+ 45
- 58
test/babyjub.js

@ -1,103 +1,89 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs");
const compiler = require("circom");
const createBlakeHash = require("blake-hash"); const createBlakeHash = require("blake-hash");
const eddsa = require("../src/eddsa.js"); const eddsa = require("../src/eddsa.js");
const assert = chai.assert; const assert = chai.assert;
const bigInt = require("snarkjs").bigInt;
const bigInt = require("big-integer");
const tester = require("circom").tester;
const utils = require("../src/utils.js");
describe("Baby Jub test", function () { describe("Baby Jub test", function () {
let circuitAdd; let circuitAdd;
let circuitTest; let circuitTest;
let circuitPbk;
this.timeout(100000); this.timeout(100000);
before( async() => { before( async() => {
const cirDefAdd = await compiler(path.join(__dirname, "circuits", "babyadd_tester.circom"));
circuitAdd = new snarkjs.Circuit(cirDefAdd);
console.log("NConstrains BabyAdd: " + circuitAdd.nConstraints);
circuitAdd = await tester(path.join(__dirname, "circuits", "babyadd_tester.circom"));
const cirDefTest = await compiler(path.join(__dirname, "circuits", "babycheck_test.circom"));
circuitTest = new snarkjs.Circuit(cirDefTest);
console.log("NConstrains BabyTest: " + circuitTest.nConstraints);
const cirDefPbk = await compiler(path.join(__dirname, "circuits", "babypbk_test.circom"));
circuitPbk = new snarkjs.Circuit(cirDefPbk);
console.log("NConstrains BabyPbk: " + circuitPbk.nConstraints);
circuitTest = await tester(path.join(__dirname, "circuits", "babycheck_test.circom"));
circuitPbk = await tester(path.join(__dirname, "circuits", "babypbk_test.circom"));
}); });
it("Should add point (0,1) and (0,1)", async () => { it("Should add point (0,1) and (0,1)", async () => {
const input={ const input={
x1: snarkjs.bigInt(0),
y1: snarkjs.bigInt(1),
x2: snarkjs.bigInt(0),
y2: snarkjs.bigInt(1)
x1: bigInt(0),
y1: bigInt(1),
x2: bigInt(0),
y2: bigInt(1)
}; };
const w = circuitAdd.calculateWitness(input);
const xout = w[circuitAdd.getSignalIdx("main.xout")];
const yout = w[circuitAdd.getSignalIdx("main.yout")];
const w = await circuitAdd.calculateWitness(input, true);
assert(xout.equals(0));
assert(yout.equals(1));
await circuitAdd.assertOut(w, {xout: bigInt(0), yout: bigInt(1)});
}); });
it("Should add 2 same numbers", async () => { it("Should add 2 same numbers", async () => {
const input={ const input={
x1: snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
y1: snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
x2: snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
y2: snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475")
x1: bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
y1: bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
x2: bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
y2: bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475")
}; };
const w = circuitAdd.calculateWitness(input);
const w = await circuitAdd.calculateWitness(input, true);
const xout = w[circuitAdd.getSignalIdx("main.xout")];
const yout = w[circuitAdd.getSignalIdx("main.yout")];
await circuitAdd.assertOut(w, {
xout: bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
yout: bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889")
});
assert(xout.equals(snarkjs.bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365")));
assert(yout.equals(snarkjs.bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889")));
}); });
it("Should add 2 different numbers", async () => { it("Should add 2 different numbers", async () => {
const input={ const input={
x1: snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
y1: snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
x2: snarkjs.bigInt("16540640123574156134436876038791482806971768689494387082833631921987005038935"),
y2: snarkjs.bigInt("20819045374670962167435360035096875258406992893633759881276124905556507972311")
x1: bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
y1: bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
x2: bigInt("16540640123574156134436876038791482806971768689494387082833631921987005038935"),
y2: bigInt("20819045374670962167435360035096875258406992893633759881276124905556507972311")
}; };
const w = circuitAdd.calculateWitness(input);
const w = await circuitAdd.calculateWitness(input, true);
const xout = w[circuitAdd.getSignalIdx("main.xout")];
const yout = w[circuitAdd.getSignalIdx("main.yout")];
await circuitAdd.assertOut(w, {
xout: bigInt("7916061937171219682591368294088513039687205273691143098332585753343424131937"),
yout: bigInt("14035240266687799601661095864649209771790948434046947201833777492504781204499")
});
/*
console.log(xout.toString());
console.log(yout.toString());
*/
assert(xout.equals(snarkjs.bigInt("7916061937171219682591368294088513039687205273691143098332585753343424131937")));
assert(yout.equals(snarkjs.bigInt("14035240266687799601661095864649209771790948434046947201833777492504781204499")));
}); });
it("Should check 0 is a valid poiny", async() => {
const w = circuitTest.calculateWitness({x: 0, y:1});
assert(circuitTest.checkWitness(w));
it("Should check (0,1) is a valid point", async() => {
const w = await circuitTest.calculateWitness({x: 0, y:1}, true);
await circuitTest.checkConstraints(w);
}); });
it("Should check 0 is an invalid poiny", async() => {
it("Should check (1,0) is an invalid point", async() => {
try { try {
circuitTest.calculateWitness({x: 1, y: 0});
await circuitTest.calculateWitness({x: 1, y: 0}, true);
assert(false, "Should be a valid point"); assert(false, "Should be a valid point");
} catch(err) { } catch(err) {
assert(/Constraint\sdoesn't\smatch(.*)168700\s!=\s1/.test(err.message) ); assert(/Constraint\sdoesn't\smatch(.*)168700\s!=\s1/.test(err.message) );
@ -108,18 +94,19 @@ describe("Baby Jub test", function () {
const rawpvk = Buffer.from("0001020304050607080900010203040506070809000102030405060708090021", "hex"); const rawpvk = Buffer.from("0001020304050607080900010203040506070809000102030405060708090021", "hex");
const pvk = eddsa.pruneBuffer(createBlakeHash("blake512").update(rawpvk).digest().slice(0,32)); const pvk = eddsa.pruneBuffer(createBlakeHash("blake512").update(rawpvk).digest().slice(0,32));
const S = bigInt.leBuff2int(pvk).shr(3);
const S = utils.leBuff2int(pvk).shiftRight(3);
const A = eddsa.prv2pub(rawpvk); const A = eddsa.prv2pub(rawpvk);
const input = { const input = {
in : S,
Ax : A[0],
Ay : A[1]
}
in : S
};
const w = await circuitPbk.calculateWitness(input, true);
await circuitPbk.assertOut(w, {Ax : A[0], Ay: A[1]});
const w = circuitPbk.calculateWitness(input);
assert(circuitPbk.checkWitness(w));
await circuitPbk.checkConstraints(w);
}); });
}); });

+ 43
- 45
test/babyjub_js.js

@ -1,7 +1,5 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path");
const snarkjs = require("snarkjs");
const compiler = require("circom");
const bigInt = require("big-integer");
const babyjub = require("../src/babyjub.js"); const babyjub = require("../src/babyjub.js");
const assert = chai.assert; const assert = chai.assert;
@ -16,14 +14,14 @@ describe("Baby Jub js test", function () {
it("Should add point (0,1) and (0,1)", () => { it("Should add point (0,1) and (0,1)", () => {
const p1 = [ const p1 = [
snarkjs.bigInt(0),
snarkjs.bigInt(1)];
bigInt(0),
bigInt(1)];
const p2 = [ const p2 = [
snarkjs.bigInt(0),
snarkjs.bigInt(1)
bigInt(0),
bigInt(1)
]; ];
const out = babyjub.addPoint(p1, p2)
const out = babyjub.addPoint(p1, p2);
assert(out[0].equals(0)); assert(out[0].equals(0));
assert(out[1].equals(1)); assert(out[1].equals(1));
}); });
@ -41,43 +39,43 @@ describe("Baby Jub js test", function () {
it("Should add 2 same numbers", () => { it("Should add 2 same numbers", () => {
const p1 = [ const p1 = [
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
]; ];
const p2 = [ const p2 = [
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
]; ];
const out = babyjub.addPoint(p1, p2)
assert(out[0].equals(snarkjs.bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365")));
assert(out[1].equals(snarkjs.bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889")));
const out = babyjub.addPoint(p1, p2);
assert(out[0].equals(bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365")));
assert(out[1].equals(bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889")));
}); });
it("Should add 2 different numbers", () => { it("Should add 2 different numbers", () => {
const p1 = [ const p1 = [
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
]; ];
const p2 = [ const p2 = [
snarkjs.bigInt("16540640123574156134436876038791482806971768689494387082833631921987005038935"),
snarkjs.bigInt("20819045374670962167435360035096875258406992893633759881276124905556507972311"),
bigInt("16540640123574156134436876038791482806971768689494387082833631921987005038935"),
bigInt("20819045374670962167435360035096875258406992893633759881276124905556507972311"),
]; ];
const out = babyjub.addPoint(p1, p2)
const out = babyjub.addPoint(p1, p2);
assert(out[0].equals(snarkjs.bigInt("7916061937171219682591368294088513039687205273691143098332585753343424131937")));
assert(out[1].equals(snarkjs.bigInt("14035240266687799601661095864649209771790948434046947201833777492504781204499")));
assert(out[0].equals(bigInt("7916061937171219682591368294088513039687205273691143098332585753343424131937")));
assert(out[1].equals(bigInt("14035240266687799601661095864649209771790948434046947201833777492504781204499")));
}); });
it("should mulPointEscalar 0", () => { it("should mulPointEscalar 0", () => {
const p = [ const p = [
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
]; ];
const r = babyjub.mulPointEscalar(p, snarkjs.bigInt("3"));
const r = babyjub.mulPointEscalar(p, bigInt("3"));
let r2 = babyjub.addPoint(p, p); let r2 = babyjub.addPoint(p, p);
r2 = babyjub.addPoint(r2, p); r2 = babyjub.addPoint(r2, p);
assert.equal(r2[0].toString(), r[0].toString()); assert.equal(r2[0].toString(), r[0].toString());
@ -88,65 +86,65 @@ describe("Baby Jub js test", function () {
it("should mulPointEscalar 1", () => { it("should mulPointEscalar 1", () => {
const p = [ const p = [
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
]; ];
const r = babyjub.mulPointEscalar(p, snarkjs.bigInt("14035240266687799601661095864649209771790948434046947201833777492504781204499"));
const r = babyjub.mulPointEscalar(p, bigInt("14035240266687799601661095864649209771790948434046947201833777492504781204499"));
assert.equal(r[0].toString(), "17070357974431721403481313912716834497662307308519659060910483826664480189605"); assert.equal(r[0].toString(), "17070357974431721403481313912716834497662307308519659060910483826664480189605");
assert.equal(r[1].toString(), "4014745322800118607127020275658861516666525056516280575712425373174125159339"); assert.equal(r[1].toString(), "4014745322800118607127020275658861516666525056516280575712425373174125159339");
}); });
it("should mulPointEscalar 2", () => { it("should mulPointEscalar 2", () => {
const p = [ const p = [
snarkjs.bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
snarkjs.bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889"),
bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889"),
]; ];
const r = babyjub.mulPointEscalar(p, snarkjs.bigInt("20819045374670962167435360035096875258406992893633759881276124905556507972311"));
const r = babyjub.mulPointEscalar(p, bigInt("20819045374670962167435360035096875258406992893633759881276124905556507972311"));
assert.equal(r[0].toString(), "13563888653650925984868671744672725781658357821216877865297235725727006259983"); assert.equal(r[0].toString(), "13563888653650925984868671744672725781658357821216877865297235725727006259983");
assert.equal(r[1].toString(), "8442587202676550862664528699803615547505326611544120184665036919364004251662"); assert.equal(r[1].toString(), "8442587202676550862664528699803615547505326611544120184665036919364004251662");
}); });
it("should inCurve 1", () => { it("should inCurve 1", () => {
const p = [ const p = [
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
]; ];
assert(babyjub.inCurve(p)); assert(babyjub.inCurve(p));
}); });
it("should inCurve 2", () => { it("should inCurve 2", () => {
const p = [ const p = [
snarkjs.bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
snarkjs.bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889"),
bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889"),
]; ];
assert(babyjub.inCurve(p)); assert(babyjub.inCurve(p));
}); });
it("should inSubgroup 1", () => { it("should inSubgroup 1", () => {
const p = [ const p = [
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
]; ];
assert(babyjub.inSubgroup(p)); assert(babyjub.inSubgroup(p));
}); });
it("should inSubgroup 2", () => { it("should inSubgroup 2", () => {
const p = [ const p = [
snarkjs.bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
snarkjs.bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889"),
bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889"),
]; ];
assert(babyjub.inSubgroup(p)); assert(babyjub.inSubgroup(p));
}); });
it("should packPoint - unpackPoint 1", () => { it("should packPoint - unpackPoint 1", () => {
const p = [ const p = [
snarkjs.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
snarkjs.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"),
bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"),
]; ];
const buf = babyjub.packPoint(p); const buf = babyjub.packPoint(p);
assert.equal(buf.toString('hex'), '53b81ed5bffe9545b54016234682e7b2f699bd42a5e9eae27ff4051bc698ce85');
assert.equal(buf.toString("hex"), "53b81ed5bffe9545b54016234682e7b2f699bd42a5e9eae27ff4051bc698ce85");
const p2 = babyjub.unpackPoint(buf); const p2 = babyjub.unpackPoint(buf);
assert.equal(p2[0].toString(), "17777552123799933955779906779655732241715742912184938656739573121738514868268"); assert.equal(p2[0].toString(), "17777552123799933955779906779655732241715742912184938656739573121738514868268");
assert.equal(p2[1].toString(), "2626589144620713026669568689430873010625803728049924121243784502389097019475"); assert.equal(p2[1].toString(), "2626589144620713026669568689430873010625803728049924121243784502389097019475");
@ -154,11 +152,11 @@ describe("Baby Jub js test", function () {
it("should packPoint - unpackPoint 2", () => { it("should packPoint - unpackPoint 2", () => {
const p = [ const p = [
snarkjs.bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
snarkjs.bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889"),
bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365"),
bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889"),
]; ];
const buf = babyjub.packPoint(p); const buf = babyjub.packPoint(p);
assert.equal(buf.toString('hex'), 'e114eb17eddf794f063a68fecac515e3620e131976108555735c8b0773929709');
assert.equal(buf.toString("hex"), "e114eb17eddf794f063a68fecac515e3620e131976108555735c8b0773929709");
const p2 = babyjub.unpackPoint(buf); const p2 = babyjub.unpackPoint(buf);
assert.equal(p2[0].toString(), "6890855772600357754907169075114257697580319025794532037257385534741338397365"); assert.equal(p2[0].toString(), "6890855772600357754907169075114257697580319025794532037257385534741338397365");
assert.equal(p2[1].toString(), "4338620300185947561074059802482547481416142213883829469920100239455078257889"); assert.equal(p2[1].toString(), "4338620300185947561074059802482547481416142213883829469920100239455078257889");

+ 30
- 35
test/binsub.js

@ -1,55 +1,50 @@
const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs");
const compiler = require("circom");
const assert = chai.assert;
const bigInt = snarkjs.bigInt;
const bigInt = require("big-integer");
const tester = require("circom").tester;
function print(circuit, w, s) { function print(circuit, w, s) {
console.log(s + ": " + w[circuit.getSignalIdx(s)]); console.log(s + ": " + w[circuit.getSignalIdx(s)]);
} }
function checkSub(_a,_b, circuit) {
async function checkSub(_a,_b, circuit) {
let a=bigInt(_a); let a=bigInt(_a);
let b=bigInt(_b); let b=bigInt(_b);
if (a.lesser(bigInt.zero)) a = a.add(bigInt.one.shl(16));
if (b.lesser(bigInt.zero)) b = b.add(bigInt.one.shl(16));
const w = circuit.calculateWitness({a: a, b: b});
if (a.lesser(bigInt.zero)) a = a.add(bigInt.one.shiftLeft(16));
if (b.lesser(bigInt.zero)) b = b.add(bigInt.one.shiftLeft(16));
const w = await circuit.calculateWitness({a: a, b: b}, true);
let res = a.sub(b);
if (res.lesser(bigInt.zero)) res = res.add(bigInt.one.shl(16));
assert( w[circuit.getSignalIdx("main.out")].equals(bigInt(res)) );
let res = a.minus(b);
if (res.lesser(bigInt.zero)) res = res.add(bigInt.one.shiftLeft(16));
await circuit.assertOut(w, {out: bigInt(res)});
} }
describe("BinSub test", () => {
let circuit;
before( async() => {
const cirDef = await compiler(path.join(__dirname, "circuits", "binsub_test.circom"));
describe("BinSub test", function () {
circuit = new snarkjs.Circuit(cirDef);
this.timeout(100000);
console.log("NConstrains BinSub: " + circuit.nConstraints);
let circuit;
before( async() => {
circuit = await tester(path.join(__dirname, "circuits", "binsub_test.circom"));
}); });
it("Should check variuos ege cases", async () => { it("Should check variuos ege cases", async () => {
checkSub(0,0, circuit);
checkSub(1,0, circuit);
checkSub(-1,0, circuit);
checkSub(2,1, circuit);
checkSub(2,2, circuit);
checkSub(2,3, circuit);
checkSub(2,-1, circuit);
checkSub(2,-2, circuit);
checkSub(2,-3, circuit);
checkSub(-2,-3, circuit);
checkSub(-2,-2, circuit);
checkSub(-2,-1, circuit);
checkSub(-2,0, circuit);
checkSub(-2,1, circuit);
checkSub(-2,2, circuit);
checkSub(-2,3, circuit);
await checkSub(0,0, circuit);
await checkSub(1,0, circuit);
await checkSub(-1,0, circuit);
await checkSub(2,1, circuit);
await checkSub(2,2, circuit);
await checkSub(2,3, circuit);
await checkSub(2,-1, circuit);
await checkSub(2,-2, circuit);
await checkSub(2,-3, circuit);
await checkSub(-2,-3, circuit);
await checkSub(-2,-2, circuit);
await checkSub(-2,-1, circuit);
await checkSub(-2,0, circuit);
await checkSub(-2,1, circuit);
await checkSub(-2,2, circuit);
await checkSub(-2,3, circuit);
}); });

+ 20
- 18
test/binsum.js

@ -1,35 +1,37 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs");
const crypto = require("crypto");
const compiler = require("circom");
const tester = require("circom").tester;
const bigInt = require("big-integer");
const assert = chai.assert; const assert = chai.assert;
describe("Sum test", () => {
it("Should create a constant circuit", async () => {
describe("Binary sum test", function () {
const cirDef = await compiler(path.join(__dirname, "circuits", "constants_test.circom"));
assert.equal(cirDef.nVars, 2);
this.timeout(100000000);
const circuit = new snarkjs.Circuit(cirDef);
it("Should create a constant circuit", async () => {
const circuit = await tester(path.join(__dirname, "circuits", "constants_test.circom"));
await circuit.loadConstraints();
const witness = circuit.calculateWitness({ "in": "0xd807aa98" });
assert.equal(circuit.nVars, 2);
assert.equal(circuit.constraints.length, 1);
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt("0xd807aa98")));
const witness = await circuit.calculateWitness({ "in": bigInt("d807aa98", 16)}, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt("d807aa98", 16)));
}); });
it("Should create a sum circuit", async () => { it("Should create a sum circuit", async () => {
const circuit = await tester(path.join(__dirname, "circuits", "sum_test.circom"));
await circuit.loadConstraints();
const cirDef = await compiler(path.join(__dirname, "circuits", "sum_test.circom"));
assert.equal(cirDef.nVars, 97); // 32 (in1) + 32(in2) + 32(out) + 1 (carry)
const circuit = new snarkjs.Circuit(cirDef);
assert.equal(circuit.constraints.length, 97); // 32 (in1) + 32(in2) + 32(out) + 1 (carry)
const witness = circuit.calculateWitness({ "a": "111", "b": "222" });
const witness = await circuit.calculateWitness({ "a": "111", "b": "222" }, true);
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt("333")));
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt("333")));
}); });
}); });

+ 6
- 1
test/circuits/binsub_test.circom

@ -6,6 +6,8 @@ template A() {
signal input b; signal input b;
signal output out; signal output out;
var i;
component n2ba = Num2Bits(16); component n2ba = Num2Bits(16);
component n2bb = Num2Bits(16); component n2bb = Num2Bits(16);
component sub = BinSub(16); component sub = BinSub(16);
@ -14,9 +16,12 @@ template A() {
n2ba.in <== a; n2ba.in <== a;
n2bb.in <== b; n2bb.in <== b;
for (var i=0; i<16; i++) {
for (i=0; i<16; i++) {
sub.in[0][i] <== n2ba.out[i]; sub.in[0][i] <== n2ba.out[i];
sub.in[1][i] <== n2bb.out[i]; sub.in[1][i] <== n2bb.out[i];
}
for (i=0; i<16; i++) {
b2n.in[i] <== sub.out[i]; b2n.in[i] <== sub.out[i];
} }

+ 1
- 1
test/circuits/escalarmul_test.circom

@ -6,7 +6,7 @@ template Main() {
signal input in; signal input in;
signal output out[2]; signal output out[2];
var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
16950150798460657717958625567821834550301663161624707787222815936182638968203]; 16950150798460657717958625567821834550301663161624707787222815936182638968203];

+ 2
- 2
test/circuits/escalarmul_test_min.circom

@ -7,8 +7,8 @@ template Main() {
var i; var i;
var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
16950150798460657717958625567821834550301663161624707787222815936182638968203];
var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
16950150798460657717958625567821834550301663161624707787222815936182638968203];
component escalarMul = EscalarMul(256, base); component escalarMul = EscalarMul(256, base);

+ 2
- 2
test/circuits/escalarmulfix_test.circom

@ -6,8 +6,8 @@ template Main() {
signal input e; signal input e;
signal output out[2]; signal output out[2];
var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
16950150798460657717958625567821834550301663161624707787222815936182638968203]
var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
16950150798460657717958625567821834550301663161624707787222815936182638968203]
component n2b = Num2Bits(253); component n2b = Num2Bits(253);

+ 1
- 1
test/circuits/escalarmulw4table.circom

@ -1,6 +1,6 @@
include "../../circuits/escalarmulw4table.circom"; include "../../circuits/escalarmulw4table.circom";
var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
16950150798460657717958625567821834550301663161624707787222815936182638968203] 16950150798460657717958625567821834550301663161624707787222815936182638968203]
component main = EscalarMulW4Table(base, 0); component main = EscalarMulW4Table(base, 0);

+ 2
- 2
test/circuits/escalarmulw4table_test.circom

@ -4,10 +4,10 @@ include "../../circuits/escalarmulw4table.circom";
template Main() { template Main() {
signal input in; signal input in;
signal output out[16][2]; signal output out[16][2];
var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
16950150798460657717958625567821834550301663161624707787222815936182638968203]; 16950150798460657717958625567821834550301663161624707787222815936182638968203];
var escalarMul = EscalarMulW4Table(base, 0);
var escalarMul[16][2] = EscalarMulW4Table(base, 0);
for (var i=0; i<16; i++) { for (var i=0; i<16; i++) {
out[i][0] <== escalarMul[i][0]*in; out[i][0] <== escalarMul[i][0]*in;
out[i][1] <== escalarMul[i][1]*in; out[i][1] <== escalarMul[i][1]*in;

+ 3
- 3
test/circuits/escalarmulw4table_test3.circom

@ -4,10 +4,10 @@ include "../../circuits/escalarmulw4table.circom";
template Main() { template Main() {
signal input in; signal input in;
signal output out[16][2]; signal output out[16][2];
var base = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
16950150798460657717958625567821834550301663161624707787222815936182638968203];
var base[2] = [5299619240641551281634865583518297030282874472190772894086521144482721001553,
16950150798460657717958625567821834550301663161624707787222815936182638968203];
var escalarMul = EscalarMulW4Table(base, 3);
var escalarMul[16][2] = EscalarMulW4Table(base, 3);
for (var i=0; i<16; i++) { for (var i=0; i<16; i++) {
out[i][0] <== escalarMul[i][0]*in; out[i][0] <== escalarMul[i][0]*in;
out[i][1] <== escalarMul[i][1]*in; out[i][1] <== escalarMul[i][1]*in;

+ 258
- 0
test/circuits/in.json

@ -0,0 +1,258 @@
{
"in": [
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1",
"1"
]
}

+ 6
- 1
test/circuits/sum_test.circom

@ -6,6 +6,8 @@ template A() {
signal input b; signal input b;
signal output out; signal output out;
var i;
component n2ba = Num2Bits(32); component n2ba = Num2Bits(32);
component n2bb = Num2Bits(32); component n2bb = Num2Bits(32);
component sum = BinSum(32,2); component sum = BinSum(32,2);
@ -14,9 +16,12 @@ template A() {
n2ba.in <== a; n2ba.in <== a;
n2bb.in <== b; n2bb.in <== b;
for (var i=0; i<32; i++) {
for (i=0; i<32; i++) {
sum.in[0][i] <== n2ba.out[i]; sum.in[0][i] <== n2ba.out[i];
sum.in[1][i] <== n2bb.out[i]; sum.in[1][i] <== n2bb.out[i];
}
for (i=0; i<32; i++) {
b2n.in[i] <== sum.out[i]; b2n.in[i] <== sum.out[i];
} }

+ 121
- 130
test/comparators.js

@ -1,193 +1,184 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs");
const crypto = require("crypto");
const compiler = require("circom");
const tester = require("circom").tester;
const bigInt = require("big-integer");
const assert = chai.assert; const assert = chai.assert;
describe("Sum test", () => {
it("Should create a iszero circuit", async() => {
const cirDef = await compiler(path.join(__dirname, "circuits", "iszero.circom"));
describe("Comparators test", function () {
const circuit = new snarkjs.Circuit(cirDef);
this.timeout(100000);
it("Should create a iszero circuit", async() => {
const circuit = await tester(path.join(__dirname, "circuits", "iszero.circom"));
let witness; let witness;
witness = circuit.calculateWitness({ "in": 111});
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(0)));
witness = await circuit.calculateWitness({ "in": 111}, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(0)));
witness = circuit.calculateWitness({ "in": 0 });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(1)));
witness = await circuit.calculateWitness({ "in": 0 }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(1)));
}); });
it("Should create a isequal circuit", async() => { it("Should create a isequal circuit", async() => {
const cirDef = await compiler(path.join(__dirname, "circuits", "isequal.circom"));
const circuit = new snarkjs.Circuit(cirDef);
const circuit = await tester(path.join(__dirname, "circuits", "isequal.circom"));
let witness; let witness;
witness = circuit.calculateWitness({ "in[0]": "111", "in[1]": "222" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(0)));
witness = await circuit.calculateWitness({ "in": [111,222] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(0)));
witness = circuit.calculateWitness({ "in[0]": "444", "in[1]": "444" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(1)));
witness = await circuit.calculateWitness({ "in": [444,444] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(1)));
}); });
it("Should create a comparison lessthan", async() => { it("Should create a comparison lessthan", async() => {
const cirDef = await compiler(path.join(__dirname, "circuits", "lessthan.circom"));
const circuit = new snarkjs.Circuit(cirDef);
const circuit = await tester(path.join(__dirname, "circuits", "lessthan.circom"));
let witness; let witness;
witness = circuit.calculateWitness({ "in[0]": "333", "in[1]": "444" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(1)));
witness = await circuit.calculateWitness({ "in": [333,444] }), true;
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(1)));
witness = circuit.calculateWitness({ "in[0]": "1", "in[1]": "1" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(0)));
witness = await circuit.calculateWitness({ "in":[1,1] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(0)));
witness = circuit.calculateWitness({ "in[0]": "661", "in[1]": "660" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(0)));
witness = await circuit.calculateWitness({ "in": [661, 660] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(0)));
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "1" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(1)));
witness = await circuit.calculateWitness({ "in": [0, 1] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(1)));
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "444" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(1)));
witness = await circuit.calculateWitness({ "in": [0, 444] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(1)));
witness = circuit.calculateWitness({ "in[0]": "1", "in[1]": "0" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(0)));
witness = await circuit.calculateWitness({ "in": [1, 0] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(0)));
witness = circuit.calculateWitness({ "in[0]": "555", "in[1]": "0" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(0)));
witness = await circuit.calculateWitness({ "in": [555, 0] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(0)));
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "0" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(0)));
witness = await circuit.calculateWitness({ "in": [0, 0] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(0)));
}); });
it("Should create a comparison lesseqthan", async() => { it("Should create a comparison lesseqthan", async() => {
const cirDef = await compiler(path.join(__dirname, "circuits", "lesseqthan.circom"));
const circuit = new snarkjs.Circuit(cirDef);
const circuit = await tester(path.join(__dirname, "circuits", "lesseqthan.circom"));
let witness; let witness;
witness = circuit.calculateWitness({ "in[0]": "333", "in[1]": "444" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(1)));
witness = await circuit.calculateWitness({ "in": [333,444] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(1)));
witness = circuit.calculateWitness({ "in[0]": "1", "in[1]": "1" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(1)));
witness = await circuit.calculateWitness({ "in":[1,1] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(1)));
witness = circuit.calculateWitness({ "in[0]": "661", "in[1]": "660" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(0)));
witness = await circuit.calculateWitness({ "in": [661, 660] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(0)));
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "1" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(1)));
witness = await circuit.calculateWitness({ "in": [0, 1] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(1)));
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "444" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(1)));
witness = await circuit.calculateWitness({ "in": [0, 444] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(1)));
witness = circuit.calculateWitness({ "in[0]": "1", "in[1]": "0" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(0)));
witness = await circuit.calculateWitness({ "in": [1, 0] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(0)));
witness = circuit.calculateWitness({ "in[0]": "555", "in[1]": "0" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(0)));
witness = await circuit.calculateWitness({ "in": [555, 0] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(0)));
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "0" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(1)));
witness = await circuit.calculateWitness({ "in": [0, 0] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(1)));
}); });
it("Should create a comparison greaterthan", async() => { it("Should create a comparison greaterthan", async() => {
const cirDef = await compiler(path.join(__dirname, "circuits", "greaterthan.circom"));
const circuit = new snarkjs.Circuit(cirDef);
const circuit = await tester(path.join(__dirname, "circuits", "greaterthan.circom"));
let witness; let witness;
witness = circuit.calculateWitness({ "in[0]": "333", "in[1]": "444" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(0)));
witness = await circuit.calculateWitness({ "in": [333,444] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(0)));
witness = circuit.calculateWitness({ "in[0]": "1", "in[1]": "1" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(0)));
witness = await circuit.calculateWitness({ "in":[1,1] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(0)));
witness = circuit.calculateWitness({ "in[0]": "661", "in[1]": "660" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(1)));
witness = await circuit.calculateWitness({ "in": [661, 660] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(1)));
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "1" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(0)));
witness = await circuit.calculateWitness({ "in": [0, 1] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(0)));
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "444" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(0)));
witness = await circuit.calculateWitness({ "in": [0, 444] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(0)));
witness = circuit.calculateWitness({ "in[0]": "1", "in[1]": "0" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(1)));
witness = await circuit.calculateWitness({ "in": [1, 0] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(1)));
witness = circuit.calculateWitness({ "in[0]": "555", "in[1]": "0" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(1)));
witness = await circuit.calculateWitness({ "in": [555, 0] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(1)));
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "0" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(0)));
witness = await circuit.calculateWitness({ "in": [0, 0] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(0)));
}); });
it("Should create a comparison greatereqthan", async() => { it("Should create a comparison greatereqthan", async() => {
const cirDef = await compiler(path.join(__dirname, "circuits", "greatereqthan.circom"));
const circuit = new snarkjs.Circuit(cirDef);
console.log("NConstraints BalancesUpdater: " + circuit.nConstraints);
const circuit = await tester(path.join(__dirname, "circuits", "greatereqthan.circom"));
let witness; let witness;
witness = circuit.calculateWitness({ "in[0]": "333", "in[1]": "444" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(0)));
witness = await circuit.calculateWitness({ "in": [333,444] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(0)));
witness = circuit.calculateWitness({ "in[0]": "1", "in[1]": "1" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(1)));
witness = await circuit.calculateWitness({ "in":[1,1] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(1)));
witness = circuit.calculateWitness({ "in[0]": "661", "in[1]": "660" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(1)));
witness = await circuit.calculateWitness({ "in": [661, 660] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(1)));
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "1" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(0)));
witness = await circuit.calculateWitness({ "in": [0, 1] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(0)));
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "444" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(0)));
witness = await circuit.calculateWitness({ "in": [0, 444] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(0)));
witness = circuit.calculateWitness({ "in[0]": "1", "in[1]": "0" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(1)));
witness = await circuit.calculateWitness({ "in": [1, 0] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(1)));
witness = circuit.calculateWitness({ "in[0]": "555", "in[1]": "0" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(1)));
witness = await circuit.calculateWitness({ "in": [555, 0] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(1)));
witness = circuit.calculateWitness({ "in[0]": "0", "in[1]": "0" });
assert(witness[0].equals(snarkjs.bigInt(1)));
assert(witness[1].equals(snarkjs.bigInt(1)));
witness = await circuit.calculateWitness({ "in": [0, 0] }, true);
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(1)));
}); });
}); });

+ 6
- 13
test/eddsa.js

@ -1,16 +1,14 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs");
const compiler = require("circom");
// const crypto = require("crypto");
const tester = require("circom").tester;
const bigInt = require("big-integer");
const eddsa = require("../src/eddsa.js"); const eddsa = require("../src/eddsa.js");
const babyJub = require("../src/babyjub.js"); const babyJub = require("../src/babyjub.js");
const assert = chai.assert; const assert = chai.assert;
const bigInt = snarkjs.bigInt;
function print(circuit, w, s) { function print(circuit, w, s) {
console.log(s + ": " + w[circuit.getSignalIdx(s)]); console.log(s + ": " + w[circuit.getSignalIdx(s)]);
} }
@ -36,11 +34,7 @@ describe("EdDSA test", function () {
this.timeout(100000); this.timeout(100000);
before( async () => { before( async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "eddsa_test.circom"));
circuit = new snarkjs.Circuit(cirDef);
console.log("NConstrains EdDSA: " + circuit.nConstraints);
circuit = await tester(path.join(__dirname, "circuits", "eddsa_test.circom"));
}); });
it("Sign a single 10 bytes from 0 to 9", async () => { it("Sign a single 10 bytes from 0 to 9", async () => {
@ -66,9 +60,8 @@ describe("EdDSA test", function () {
const sBits = buffer2bits(pSignature.slice(32, 64)); const sBits = buffer2bits(pSignature.slice(32, 64));
const aBits = buffer2bits(pPubKey); const aBits = buffer2bits(pPubKey);
const w = circuit.calculateWitness({A: aBits, R8: r8Bits, S: sBits, msg: msgBits});
assert(circuit.checkWitness(w));
const w = await circuit.calculateWitness({A: aBits, R8: r8Bits, S: sBits, msg: msgBits}, true);
await circuit.checkConstraints(w);
}); });
}); });

+ 4
- 4
test/eddsa_js.js

@ -1,12 +1,12 @@
const chai = require("chai"); const chai = require("chai");
const snarkjs = require("snarkjs");
const eddsa = require("../src/eddsa.js"); const eddsa = require("../src/eddsa.js");
const babyJub = require("../src/babyjub.js"); const babyJub = require("../src/babyjub.js");
const assert = chai.assert; const assert = chai.assert;
const bigInt = snarkjs.bigInt;
const bigInt = require("big-integer");
const utils = require("../src/utils.js");
describe("EdDSA js test", function () { describe("EdDSA js test", function () {
@ -14,7 +14,7 @@ describe("EdDSA js test", function () {
it("Sign (using Mimc7) a single 10 bytes from 0 to 9", () => { it("Sign (using Mimc7) a single 10 bytes from 0 to 9", () => {
const msgBuf = Buffer.from("00010203040506070809", "hex"); const msgBuf = Buffer.from("00010203040506070809", "hex");
const msg = bigInt.leBuff2int(msgBuf);
const msg = utils.leBuff2int(msgBuf);
// const prvKey = crypto.randomBytes(32); // const prvKey = crypto.randomBytes(32);
@ -49,7 +49,7 @@ describe("EdDSA js test", function () {
it("Sign (using Poseidon) a single 10 bytes from 0 to 9", () => { it("Sign (using Poseidon) a single 10 bytes from 0 to 9", () => {
const msgBuf = Buffer.from("00010203040506070809", "hex"); const msgBuf = Buffer.from("00010203040506070809", "hex");
const msg = bigInt.leBuff2int(msgBuf);
const msg = utils.leBuff2int(msgBuf);
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex"); const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");

+ 14
- 16
test/eddsamimc.js

@ -1,25 +1,20 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs");
const compiler = require("circom");
const tester = require("circom").tester;
const bigInt = require("big-integer");
const eddsa = require("../src/eddsa.js"); const eddsa = require("../src/eddsa.js");
const assert = chai.assert; const assert = chai.assert;
const bigInt = snarkjs.bigInt;
describe("EdDSA MiMC test", function () { describe("EdDSA MiMC test", function () {
let circuit; let circuit;
this.timeout(100000); this.timeout(100000);
before( async () => { before( async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "eddsamimc_test.circom"));
circuit = new snarkjs.Circuit(cirDef);
console.log("NConstrains EdDSA MiMC: " + circuit.nConstraints);
circuit = await tester(path.join(__dirname, "circuits", "eddsamimc_test.circom"));
}); });
it("Sign a single number", async () => { it("Sign a single number", async () => {
@ -33,16 +28,18 @@ describe("EdDSA MiMC test", function () {
assert(eddsa.verifyMiMC(msg, signature, pubKey)); assert(eddsa.verifyMiMC(msg, signature, pubKey));
const w = circuit.calculateWitness({
const w = await circuit.calculateWitness({
enabled: 1, enabled: 1,
Ax: pubKey[0], Ax: pubKey[0],
Ay: pubKey[1], Ay: pubKey[1],
R8x: signature.R8[0], R8x: signature.R8[0],
R8y: signature.R8[1], R8y: signature.R8[1],
S: signature.S, S: signature.S,
M: msg});
M: msg}, true);
await circuit.checkConstraints(w);
assert(circuit.checkWitness(w));
}); });
it("Detect Invalid signature", async () => { it("Detect Invalid signature", async () => {
@ -57,14 +54,14 @@ describe("EdDSA MiMC test", function () {
assert(eddsa.verifyMiMC(msg, signature, pubKey)); assert(eddsa.verifyMiMC(msg, signature, pubKey));
try { try {
const w = circuit.calculateWitness({
const w = await circuit.calculateWitness({
enabled: 1, enabled: 1,
Ax: pubKey[0], Ax: pubKey[0],
Ay: pubKey[1], Ay: pubKey[1],
R8x: signature.R8[0].add(bigInt(1)), R8x: signature.R8[0].add(bigInt(1)),
R8y: signature.R8[1], R8y: signature.R8[1],
S: signature.S, S: signature.S,
M: msg});
M: msg}, true);
assert(false); assert(false);
} catch(err) { } catch(err) {
assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message) ); assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message) );
@ -84,15 +81,16 @@ describe("EdDSA MiMC test", function () {
assert(eddsa.verifyMiMC(msg, signature, pubKey)); assert(eddsa.verifyMiMC(msg, signature, pubKey));
const w = circuit.calculateWitness({
const w = await circuit.calculateWitness({
enabled: 0, enabled: 0,
Ax: pubKey[0], Ax: pubKey[0],
Ay: pubKey[1], Ay: pubKey[1],
R8x: signature.R8[0].add(bigInt(1)), R8x: signature.R8[0].add(bigInt(1)),
R8y: signature.R8[1], R8y: signature.R8[1],
S: signature.S, S: signature.S,
M: msg});
M: msg}, true);
await circuit.checkConstraints(w);
assert(circuit.checkWitness(w));
}); });
}); });

+ 16
- 15
test/eddsaposeidon.js

@ -1,25 +1,21 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs");
const compiler = require("circom");
const bigInt = require("big-integer");
const tester = require("circom").tester;
const eddsa = require("../src/eddsa.js"); const eddsa = require("../src/eddsa.js");
const assert = chai.assert; const assert = chai.assert;
const bigInt = snarkjs.bigInt;
describe("EdDSA Poseidon test", function () { describe("EdDSA Poseidon test", function () {
let circuit; let circuit;
this.timeout(100000); this.timeout(100000);
before( async () => { before( async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "eddsaposeidon_test.circom"));
circuit = new snarkjs.Circuit(cirDef);
circuit = await tester(path.join(__dirname, "circuits", "eddsaposeidon_test.circom"));
console.log("NConstrains EdDSA Poseidon: " + circuit.nConstraints);
}); });
it("Sign a single number", async () => { it("Sign a single number", async () => {
@ -33,16 +29,21 @@ describe("EdDSA Poseidon test", function () {
assert(eddsa.verifyPoseidon(msg, signature, pubKey)); assert(eddsa.verifyPoseidon(msg, signature, pubKey));
const w = circuit.calculateWitness({
const input = {
enabled: 1, enabled: 1,
Ax: pubKey[0], Ax: pubKey[0],
Ay: pubKey[1], Ay: pubKey[1],
R8x: signature.R8[0], R8x: signature.R8[0],
R8y: signature.R8[1], R8y: signature.R8[1],
S: signature.S, S: signature.S,
M: msg});
M: msg
};
// console.log(JSON.stringify(utils.stringifyBigInts(input)));
const w = await circuit.calculateWitness(input, true);
assert(circuit.checkWitness(w));
await circuit.checkConstraints(w);
}); });
it("Detect Invalid signature", async () => { it("Detect Invalid signature", async () => {
@ -57,14 +58,14 @@ describe("EdDSA Poseidon test", function () {
assert(eddsa.verifyPoseidon(msg, signature, pubKey)); assert(eddsa.verifyPoseidon(msg, signature, pubKey));
try { try {
circuit.calculateWitness({
await circuit.calculateWitness({
enabled: 1, enabled: 1,
Ax: pubKey[0], Ax: pubKey[0],
Ay: pubKey[1], Ay: pubKey[1],
R8x: signature.R8[0].add(bigInt(1)), R8x: signature.R8[0].add(bigInt(1)),
R8y: signature.R8[1], R8y: signature.R8[1],
S: signature.S, S: signature.S,
M: msg});
M: msg}, true);
assert(false); assert(false);
} catch(err) { } catch(err) {
assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message) ); assert(/Constraint\sdoesn't\smatch(.*)1\s!=\s0/.test(err.message) );
@ -84,15 +85,15 @@ describe("EdDSA Poseidon test", function () {
assert(eddsa.verifyPoseidon(msg, signature, pubKey)); assert(eddsa.verifyPoseidon(msg, signature, pubKey));
const w = circuit.calculateWitness({
const w = await circuit.calculateWitness({
enabled: 0, enabled: 0,
Ax: pubKey[0], Ax: pubKey[0],
Ay: pubKey[1], Ay: pubKey[1],
R8x: signature.R8[0].add(bigInt(1)), R8x: signature.R8[0].add(bigInt(1)),
R8y: signature.R8[1], R8y: signature.R8[1],
S: signature.S, S: signature.S,
M: msg});
M: msg}, true);
assert(circuit.checkWitness(w));
await circuit.checkConstraints(w);
}); });
}); });

+ 49
- 107
test/escalarmul.js

@ -1,172 +1,114 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs");
const compiler = require("circom");
const bigInt = require("big-integer");
const tester = require("circom").tester;
const babyJub = require("../src/babyjub.js");
const assert = chai.assert; const assert = chai.assert;
const bigInt = snarkjs.bigInt;
const q=bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
function addPoint(a,b) {
const cta = bigInt("168700");
const d = bigInt("168696");
const res = [];
res[0] = bigInt((a[0]*b[1] + b[0]*a[1]) * bigInt(bigInt.one + d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q);
res[1] = bigInt((a[1]*b[1] - cta*a[0]*b[0]) * bigInt(bigInt.one - d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q);
return res;
}
function print(circuit, w, s) { function print(circuit, w, s) {
console.log(s + ": " + w[circuit.getSignalIdx(s)]); console.log(s + ": " + w[circuit.getSignalIdx(s)]);
} }
describe("Exponentioation test", () => {
it("Should generate the Exponentiation table in k=0", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "escalarmulw4table_test.circom"));
describe("Exponentioation test", function () {
// console.log(JSON.stringify(cirDef, null, 1));
this.timeout(100000);
// assert.equal(cirDef.nVars, 2);
it("Should generate the Exponentiation table in k=0", async () => {
const circuit = new snarkjs.Circuit(cirDef);
const circuit = await tester(path.join(__dirname, "circuits", "escalarmulw4table_test.circom"));
console.log("NConstrains: " + circuit.nConstraints);
const w = await circuit.calculateWitness({in: 1});
const w = circuit.calculateWitness({in: 1});
await circuit.checkConstraints(w);
assert(circuit.checkWitness(w));
let g = [
bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")
];
let g = [bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")]
let dbl= [bigInt("0"), bigInt("1")];
dbl= [bigInt("0"), snarkjs.bigInt("1")];
const expectedOut = [];
for (let i=0; i<16; i++) { for (let i=0; i<16; i++) {
const xout1 = w[circuit.getSignalIdx(`main.out[${i}][0]`)];
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]);
assert(xout1.equals(dbl[0]));
assert(yout1.equals(dbl[1]));
dbl = addPoint([xout1, yout1],g);
expectedOut.push(dbl);
dbl = babyJub.addPoint(dbl,g);
} }
await circuit.assertOut(w, {out: expectedOut});
}); });
it("Should generate the Exponentiation table in k=3", async () => { it("Should generate the Exponentiation table in k=3", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "escalarmulw4table_test3.circom"));
// console.log(JSON.stringify(cirDef, null, 1));
// assert.equal(cirDef.nVars, 2);
const circuit = await tester(path.join(__dirname, "circuits", "escalarmulw4table_test3.circom"));
const circuit = new snarkjs.Circuit(cirDef);
const w = await circuit.calculateWitness({in: 1});
console.log("NConstrains: " + circuit.nConstraints);
await circuit.checkConstraints(w);
const w = circuit.calculateWitness({in: 1});
assert(circuit.checkWitness(w));
let g = [snarkjs.bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
snarkjs.bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")]
let g = [
bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")
];
for (let i=0; i<12;i++) { for (let i=0; i<12;i++) {
g = addPoint(g,g);
g = babyJub.addPoint(g,g);
} }
dbl= [snarkjs.bigInt("0"), snarkjs.bigInt("1")];
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]`)];
let dbl= [bigInt("0"), bigInt("1")];
const expectedOut = [];
// 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]));
for (let i=0; i<16; i++) {
expectedOut.push(dbl);
dbl = addPoint([xout1, yout1],g);
dbl = babyJub.addPoint(dbl,g);
} }
await circuit.assertOut(w, {out: expectedOut});
}); });
it("Should exponentiate g^31", async () => { it("Should exponentiate g^31", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "escalarmul_test.circom"), {reduceConstraints: true});
// console.log(JSON.stringify(cirDef, null, 1));
const circuit = await tester(path.join(__dirname, "circuits", "escalarmul_test.circom"));
// assert.equal(cirDef.nVars, 2);
const w = await circuit.calculateWitness({"in": 31});
const circuit = new snarkjs.Circuit(cirDef);
await circuit.checkConstraints(w);
console.log("NConstrains: " + circuit.nConstraints);
let g = [
bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")
];
const w = circuit.calculateWitness({"in": 31});
assert(circuit.checkWitness(w));
let g = [snarkjs.bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
snarkjs.bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")]
let c = [0n, 1n];
let c = [bigInt(0), bigInt(1)];
for (let i=0; i<31;i++) { for (let i=0; i<31;i++) {
c = addPoint(c,g);
c = babyJub.addPoint(c,g);
} }
const xout = w[circuit.getSignalIdx(`main.out[0]`)];
const yout = w[circuit.getSignalIdx(`main.out[1]`)];
await circuit.assertOut(w, {out: c});
/*
console.log(xout.toString());
console.log(yout.toString());
*/
assert(xout.equals(c[0]));
assert(yout.equals(c[1]));
console.log("-------")
const w2 = circuit.calculateWitness({"in": (1n<<252n)+1n});
const xout2 = w2[circuit.getSignalIdx(`main.out[0]`)];
const yout2 = w2[circuit.getSignalIdx(`main.out[1]`)];
const w2 = await circuit.calculateWitness({"in": bigInt(1).shiftLeft(252).add(bigInt.one)});
c = [g[0], g[1]]; c = [g[0], g[1]];
for (let i=0; i<252;i++) { for (let i=0; i<252;i++) {
c = addPoint(c,c);
c = babyJub.addPoint(c,c);
} }
c = addPoint(c,g);
// console.log(xout2.toString());
// console.log(yout2.toString());
// console.log(c[0].toString());
// console.log(c[1].toString());
c = babyJub.addPoint(c,g);
assert(xout2.equals(c[0]));
assert(yout2.equals(c[1]));
await circuit.assertOut(w2, {out: c});
}).timeout(10000000); }).timeout(10000000);
it("Number of constrains for 256 bits", async () => { it("Number of constrains for 256 bits", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "escalarmul_test_min.circom"));
const circuit = new snarkjs.Circuit(cirDef);
const circuit = await tester(path.join(__dirname, "circuits", "escalarmul_test_min.circom"));
console.log("NConstrains: " + circuit.nConstraints);
}).timeout(10000000); }).timeout(10000000);
}); });

+ 11
- 24
test/escalarmulany.js

@ -1,12 +1,7 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs");
const compiler = require("circom");
const assert = chai.assert;
const bigInt = snarkjs.bigInt;
const bigInt = require("big-integer");
const tester = require("circom").tester;
function print(circuit, w, s) { function print(circuit, w, s) {
console.log(s + ": " + w[circuit.getSignalIdx(s)]); console.log(s + ": " + w[circuit.getSignalIdx(s)]);
@ -18,41 +13,33 @@ describe("Escalarmul test", function () {
this.timeout(100000); this.timeout(100000);
let g = [ let g = [
snarkjs.bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
snarkjs.bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")
bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")
]; ];
before( async() => { before( async() => {
const cirDefEMulAny = await compiler(path.join(__dirname, "circuits", "escalarmulany_test.circom"));
circuitEMulAny = new snarkjs.Circuit(cirDefEMulAny);
console.log("NConstrains Escalarmul any: " + circuitEMulAny.nConstraints);
circuitEMulAny = await tester(path.join(__dirname, "circuits", "escalarmulany_test.circom"));
}); });
it("Should generate Same escalar mul", async () => { it("Should generate Same escalar mul", async () => {
const w = circuitEMulAny.calculateWitness({"e": 1, "p": g});
const w = await circuitEMulAny.calculateWitness({"e": 1, "p": g});
assert(circuitEMulAny.checkWitness(w));
await circuitEMulAny.checkConstraints(w);
const xout = w[circuitEMulAny.getSignalIdx("main.out[0]")];
const yout = w[circuitEMulAny.getSignalIdx("main.out[1]")];
await circuitEMulAny.assertOut(w, {out: g}, true);
assert(xout.equals(g[0]));
assert(yout.equals(g[1]));
}); });
it("If multiply by order should return 0", async () => { it("If multiply by order should return 0", async () => {
const r = bigInt("2736030358979909402780800718157159386076813972158567259200215660948447373041"); const r = bigInt("2736030358979909402780800718157159386076813972158567259200215660948447373041");
const w = circuitEMulAny.calculateWitness({"e": r, "p": g});
const w = await circuitEMulAny.calculateWitness({"e": r, "p": g});
assert(circuitEMulAny.checkWitness(w));
await circuitEMulAny.checkConstraints(w);
const xout = w[circuitEMulAny.getSignalIdx("main.out[0]")];
const yout = w[circuitEMulAny.getSignalIdx("main.out[1]")];
await circuitEMulAny.assertOut(w, {out: [0,1]}, true);
assert(xout.equals(bigInt.zero));
assert(yout.equals(bigInt.one));
}); });
}); });

+ 19
- 41
test/escalarmulfix.js

@ -1,14 +1,11 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs");
const compiler = require("circom");
const bigInt = require("big-integer");
const tester = require("circom").tester;
const babyjub = require("../src/babyjub"); const babyjub = require("../src/babyjub");
const assert = chai.assert; const assert = chai.assert;
const bigInt = snarkjs.bigInt;
function print(circuit, w, s) { function print(circuit, w, s) {
console.log(s + ": " + w[circuit.getSignalIdx(s)]); console.log(s + ": " + w[circuit.getSignalIdx(s)]);
} }
@ -19,35 +16,27 @@ describe("Escalarmul test", function () {
this.timeout(100000); this.timeout(100000);
before( async() => { before( async() => {
const cirDef = await compiler(path.join(__dirname, "circuits", "escalarmulfix_test.circom"));
circuit = new snarkjs.Circuit(cirDef);
console.log("NConstrains Escalarmul fix: " + circuit.nConstraints);
circuit = await tester(path.join(__dirname, "circuits", "escalarmulfix_test.circom"));
}); });
it("Should generate Same escalar mul", async () => { it("Should generate Same escalar mul", async () => {
const w = circuit.calculateWitness({"e": 0});
const w = await circuit.calculateWitness({"e": 0});
assert(circuit.checkWitness(w));
await circuit.checkConstraints(w);
const xout = w[circuit.getSignalIdx("main.out[0]")];
const yout = w[circuit.getSignalIdx("main.out[1]")];
await circuit.assertOut(w, {out: [0,1]}, true);
assert(xout.equals(0));
assert(yout.equals(1));
}); });
it("Should generate Same escalar mul", async () => { it("Should generate Same escalar mul", async () => {
const w = circuit.calculateWitness({"e": 1});
const w = await circuit.calculateWitness({"e": 1}, true);
assert(circuit.checkWitness(w));
await circuit.checkConstraints(w);
const xout = w[circuit.getSignalIdx("main.out[0]")];
const yout = w[circuit.getSignalIdx("main.out[1]")];
await circuit.assertOut(w, {out: babyjub.Base8});
assert(xout.equals(babyjub.Base8[0]));
assert(yout.equals(babyjub.Base8[1]));
}); });
it("Should generate scalar mul of a specific constant", async () => { it("Should generate scalar mul of a specific constant", async () => {
@ -58,17 +47,14 @@ describe("Escalarmul test", function () {
bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203") bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")
]; ];
const w = circuit.calculateWitness({"e": s});
assert(circuit.checkWitness(w));
const w = await circuit.calculateWitness({"e": s}, true);
const xout = w[circuit.getSignalIdx("main.out[0]")];
const yout = w[circuit.getSignalIdx("main.out[1]")];
await circuit.checkConstraints(w);
const expectedRes = babyjub.mulPointEscalar(base8, s); const expectedRes = babyjub.mulPointEscalar(base8, s);
assert(xout.equals(expectedRes[0]));
assert(yout.equals(expectedRes[1]));
await circuit.assertOut(w, {out: expectedRes});
}); });
it("Should generate scalar mul of the firsts 50 elements", async () => { it("Should generate scalar mul of the firsts 50 elements", async () => {
@ -81,31 +67,23 @@ describe("Escalarmul test", function () {
for (let i=0; i<50; i++) { for (let i=0; i<50; i++) {
const s = bigInt(i); const s = bigInt(i);
const w = circuit.calculateWitness({"e": s});
assert(circuit.checkWitness(w));
const w = await circuit.calculateWitness({"e": s}, true);
const xout = w[circuit.getSignalIdx("main.out[0]")];
const yout = w[circuit.getSignalIdx("main.out[1]")];
await circuit.checkConstraints(w);
const expectedRes = babyjub.mulPointEscalar(base8, s); const expectedRes = babyjub.mulPointEscalar(base8, s);
assert(xout.equals(expectedRes[0]));
assert(yout.equals(expectedRes[1]));
await circuit.assertOut(w, {out: expectedRes});
} }
}); });
it("If multiply by order should return 0", async () => { it("If multiply by order should return 0", async () => {
const w = circuit.calculateWitness({"e": babyjub.subOrder });
assert(circuit.checkWitness(w));
const w = await circuit.calculateWitness({"e": babyjub.subOrder }, true);
const xout = w[circuit.getSignalIdx("main.out[0]")];
const yout = w[circuit.getSignalIdx("main.out[1]")];
await circuit.checkConstraints(w);
assert(xout.equals(bigInt.zero));
assert(yout.equals(bigInt.one));
await circuit.assertOut(w, {out: [0,1]});
}); });
}); });

+ 5
- 15
test/mimccircuit.js

@ -1,35 +1,25 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs");
const compiler = require("circom");
const tester = require("circom").tester;
const mimcjs = require("../src/mimc7.js"); const mimcjs = require("../src/mimc7.js");
const assert = chai.assert;
describe("MiMC Circuit test", function () { describe("MiMC Circuit test", function () {
let circuit; let circuit;
this.timeout(100000); this.timeout(100000);
before( async () => { before( async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "mimc_test.circom"));
circuit = new snarkjs.Circuit(cirDef);
console.log("MiMC constraints: " + circuit.nConstraints);
circuit = await tester(path.join(__dirname, "circuits", "mimc_test.circom"));
}); });
it("Should check constrain", async () => { it("Should check constrain", async () => {
const w = circuit.calculateWitness({x_in: 1, k: 2});
const res = w[circuit.getSignalIdx("main.out")];
const w = await circuit.calculateWitness({x_in: 1, k: 2}, true);
const res2 = mimcjs.hash(1,2,91); const res2 = mimcjs.hash(1,2,91);
assert.equal(res.toString(), res2.toString());
assert(circuit.checkWitness(w));
await circuit.assertOut(w, {out: res2});
await circuit.checkConstraints(w);
}); });
}); });

+ 9
- 30
test/mimcspongecircuit.js

@ -1,11 +1,8 @@
const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs");
const compiler = require("circom");
const tester = require("circom").tester;
const mimcjs = require("../src/mimcsponge.js"); const mimcjs = require("../src/mimcsponge.js");
const assert = chai.assert;
describe("MiMC Sponge Circuit test", function () { describe("MiMC Sponge Circuit test", function () {
let circuit; let circuit;
@ -13,46 +10,28 @@ describe("MiMC Sponge Circuit test", function () {
this.timeout(100000); this.timeout(100000);
it("Should check permutation", async () => { it("Should check permutation", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "mimc_sponge_test.circom"));
circuit = new snarkjs.Circuit(cirDef);
circuit = await tester(path.join(__dirname, "circuits", "mimc_sponge_test.circom"));
console.log("MiMC Feistel constraints: " + circuit.nConstraints);
const w = circuit.calculateWitness({xL_in: 1, xR_in: 2, k: 3});
const xLout = w[circuit.getSignalIdx("main.xL_out")];
const xRout = w[circuit.getSignalIdx("main.xR_out")];
const w = await circuit.calculateWitness({xL_in: 1, xR_in: 2, k: 3});
const out2 = mimcjs.hash(1,2,3); const out2 = mimcjs.hash(1,2,3);
assert.equal(xLout.toString(), out2.xL.toString());
assert.equal(xRout.toString(), out2.xR.toString());
await circuit.assertOut(w, {xL_out: out2.xL, xR_out: out2.xR});
assert(circuit.checkWitness(w));
await circuit.checkConstraints(w);
}); });
it("Should check hash", async () => { it("Should check hash", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "mimc_sponge_hash_test.circom"));
circuit = new snarkjs.Circuit(cirDef);
circuit = await tester(path.join(__dirname, "circuits", "mimc_sponge_hash_test.circom"));
console.log("MiMC Sponge constraints: " + circuit.nConstraints);
const w = circuit.calculateWitness({ins: [1, 2], k: 0});
const o1 = w[circuit.getSignalIdx("main.outs[0]")];
const o2 = w[circuit.getSignalIdx("main.outs[1]")];
const o3 = w[circuit.getSignalIdx("main.outs[2]")];
const w = await circuit.calculateWitness({ins: [1, 2], k: 0});
const out2 = mimcjs.multiHash([1,2], 0, 3); const out2 = mimcjs.multiHash([1,2], 0, 3);
assert.equal(o1.toString(), out2[0].toString());
assert.equal(o2.toString(), out2[1].toString());
assert.equal(o3.toString(), out2[2].toString());
assert(circuit.checkWitness(w));
await circuit.assertOut(w, {outs: out2});
await circuit.checkConstraints(w);
}); });
}); });

+ 31
- 39
test/montgomery.js

@ -1,13 +1,11 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs");
const compiler = require("circom");
const bigInt = require("big-integer");
const tester = require("circom").tester;
const babyJub = require("../src/babyjub.js"); const babyJub = require("../src/babyjub.js");
const assert = chai.assert; const assert = chai.assert;
const bigInt = snarkjs.bigInt;
describe("Montgomery test", function () { describe("Montgomery test", function () {
let circuitE2M; let circuitE2M;
let circuitM2E; let circuitM2E;
@ -15,43 +13,37 @@ describe("Montgomery test", function () {
let circuitMDouble; let circuitMDouble;
let g = [ let g = [
snarkjs.bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
snarkjs.bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")];
bigInt("5299619240641551281634865583518297030282874472190772894086521144482721001553"),
bigInt("16950150798460657717958625567821834550301663161624707787222815936182638968203")
];
let mg, mg2, g2, g3, mg3; let mg, mg2, g2, g3, mg3;
this.timeout(100000); this.timeout(100000);
before( async() => { before( async() => {
const cirDefE2M = await compiler(path.join(__dirname, "circuits", "edwards2montgomery.circom"));
circuitE2M = new snarkjs.Circuit(cirDefE2M);
console.log("NConstrains Edwards -> Montgomery: " + circuitE2M.nConstraints);
const cirDefM2E = await compiler(path.join(__dirname, "circuits", "montgomery2edwards.circom"));
circuitM2E = new snarkjs.Circuit(cirDefM2E);
console.log("NConstrains Montgomery -> Edwards: " + circuitM2E.nConstraints);
const cirDefMAdd = await compiler(path.join(__dirname, "circuits", "montgomeryadd.circom"));
circuitMAdd = new snarkjs.Circuit(cirDefMAdd);
console.log("NConstrains Montgomery Add: " + circuitMAdd.nConstraints);
const cirDefMDouble = await compiler(path.join(__dirname, "circuits", "montgomerydouble.circom"));
circuitMDouble = new snarkjs.Circuit(cirDefMDouble);
console.log("NConstrains Montgomery Double: " + circuitMDouble.nConstraints);
circuitE2M = await tester(path.join(__dirname, "circuits", "edwards2montgomery.circom"));
await circuitE2M.loadSymbols();
circuitM2E = await tester(path.join(__dirname, "circuits", "montgomery2edwards.circom"));
await circuitM2E.loadSymbols();
circuitMAdd = await tester(path.join(__dirname, "circuits", "montgomeryadd.circom"));
await circuitMAdd.loadSymbols();
circuitMDouble = await tester(path.join(__dirname, "circuits", "montgomerydouble.circom"));
await circuitMDouble.loadSymbols();
}); });
it("Convert Edwards to Montgomery and back again", async () => { it("Convert Edwards to Montgomery and back again", async () => {
let w, xout, yout; let w, xout, yout;
w = circuitE2M.calculateWitness({ in: g});
w = await circuitE2M.calculateWitness({ in: g}, true);
xout = w[circuitE2M.getSignalIdx("main.out[0]")];
yout = w[circuitE2M.getSignalIdx("main.out[1]")];
xout = w[circuitE2M.symbols["main.out[0]"].varIdx];
yout = w[circuitE2M.symbols["main.out[1]"].varIdx];
mg = [xout, yout]; mg = [xout, yout];
w = circuitM2E.calculateWitness({ in: [xout, yout]});
w = await circuitM2E.calculateWitness({ in: [xout, yout]}, true);
xout = w[circuitM2E.getSignalIdx("main.out[0]")];
yout = w[circuitM2E.getSignalIdx("main.out[1]")];
xout = w[circuitM2E.symbols["main.out[0]"].varIdx];
yout = w[circuitM2E.symbols["main.out[1]"].varIdx];
assert(xout.equals(g[0])); assert(xout.equals(g[0]));
assert(yout.equals(g[1])); assert(yout.equals(g[1]));
@ -61,17 +53,17 @@ describe("Montgomery test", function () {
g2 = babyJub.addPoint(g,g); g2 = babyJub.addPoint(g,g);
w = circuitMDouble.calculateWitness({ in: mg});
w = await circuitMDouble.calculateWitness({ in: mg}, true);
xout = w[circuitE2M.getSignalIdx("main.out[0]")];
yout = w[circuitE2M.getSignalIdx("main.out[1]")];
xout = w[circuitE2M.symbols["main.out[0]"].varIdx];
yout = w[circuitE2M.symbols["main.out[1]"].varIdx];
mg2 = [xout, yout]; mg2 = [xout, yout];
w = circuitM2E.calculateWitness({ in: mg2});
w = await circuitM2E.calculateWitness({ in: mg2}, true);
xout = w[circuitM2E.getSignalIdx("main.out[0]")];
yout = w[circuitM2E.getSignalIdx("main.out[1]")];
xout = w[circuitM2E.symbols["main.out[0]"].varIdx];
yout = w[circuitM2E.symbols["main.out[1]"].varIdx];
assert(xout.equals(g2[0])); assert(xout.equals(g2[0]));
assert(yout.equals(g2[1])); assert(yout.equals(g2[1]));
@ -81,17 +73,17 @@ describe("Montgomery test", function () {
g3 = babyJub.addPoint(g,g2); g3 = babyJub.addPoint(g,g2);
w = circuitMAdd.calculateWitness({ in1: mg, in2: mg2});
w = await circuitMAdd.calculateWitness({ in1: mg, in2: mg2}, true);
xout = w[circuitMAdd.getSignalIdx("main.out[0]")];
yout = w[circuitMAdd.getSignalIdx("main.out[1]")];
xout = w[circuitMAdd.symbols["main.out[0]"].varIdx];
yout = w[circuitMAdd.symbols["main.out[1]"].varIdx];
mg3 = [xout, yout]; mg3 = [xout, yout];
w = circuitM2E.calculateWitness({ in: mg3});
w = await circuitM2E.calculateWitness({ in: mg3}, true);
xout = w[circuitM2E.getSignalIdx("main.out[0]")];
yout = w[circuitM2E.getSignalIdx("main.out[1]")];
xout = w[circuitM2E.symbols["main.out[0]"].varIdx];
yout = w[circuitM2E.symbols["main.out[1]"].varIdx];
assert(xout.equals(g3[0])); assert(xout.equals(g3[0]));
assert(yout.equals(g3[1])); assert(yout.equals(g3[1]));

+ 22
- 57
test/multiplexer.js

@ -1,25 +1,12 @@
const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs");
const compiler = require("circom");
const bigInt = require("big-integer");
const tester = require("circom").tester;
const assert = chai.assert;
const bigInt = snarkjs.bigInt;
describe("Mux4 test", () => {
describe("Mux4 test", function() {
this.timeout(100000);
it("Should create a constant multiplexer 4", async () => { it("Should create a constant multiplexer 4", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "mux4_1.circom"));
// console.log(JSON.stringify(cirDef, null, 1));
// assert.equal(cirDef.nVars, 2);
const circuit = new snarkjs.Circuit(cirDef);
console.log("NConstrains Mux4: " + circuit.nConstraints);
const circuit = await tester(path.join(__dirname, "circuits", "mux4_1.circom"));
const ct16 = [ const ct16 = [
bigInt("123"), bigInt("123"),
@ -41,24 +28,17 @@ describe("Mux4 test", () => {
]; ];
for (let i=0; i<16; i++) { for (let i=0; i<16; i++) {
const w = circuit.calculateWitness({ "selector": i });
const w = await circuit.calculateWitness({ "selector": i }, true);
assert(circuit.checkWitness(w));
await circuit.checkConstraints(w);
assert(w[0].equals(bigInt(1)));
// console.log(i + " -> " + w[circuit.getSignalIdx("main.out")].toString());
assert(w[circuit.getSignalIdx("main.out")].equals(ct16[i]));
await circuit.assertOut(w, {out: ct16[i]});
} }
}); });
it("Should create a constant multiplexer 3", async () => { it("Should create a constant multiplexer 3", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "mux3_1.circom"));
const circuit = new snarkjs.Circuit(cirDef);
console.log("NConstrains Mux3: " + circuit.nConstraints);
const circuit = await tester(path.join(__dirname, "circuits", "mux3_1.circom"));
const ct8 = [ const ct8 = [
bigInt("37"), bigInt("37"),
@ -72,23 +52,18 @@ describe("Mux4 test", () => {
]; ];
for (let i=0; i<8; i++) { for (let i=0; i<8; i++) {
const w = circuit.calculateWitness({ "selector": i });
const w = await circuit.calculateWitness({ "selector": i }, true);
assert(w[0].equals(bigInt(1)));
await circuit.checkConstraints(w);
// console.log(i + " -> " + w[circuit.getSignalIdx("main.out")].toString());
assert(w[circuit.getSignalIdx("main.out")].equals(ct8[i]));
await circuit.assertOut(w, {out: ct8[i]});
} }
}); });
it("Should create a constant multiplexer 2", async () => { it("Should create a constant multiplexer 2", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "mux2_1.circom"));
const circuit = new snarkjs.Circuit(cirDef);
console.log("NConstrains Mux2: " + circuit.nConstraints);
const circuit = await tester(path.join(__dirname, "circuits", "mux2_1.circom"));
const ct8 = [
const ct4 = [
bigInt("37"), bigInt("37"),
bigInt("47"), bigInt("47"),
bigInt("53"), bigInt("53"),
@ -96,38 +71,28 @@ describe("Mux4 test", () => {
]; ];
for (let i=0; i<4; i++) { for (let i=0; i<4; i++) {
const w = circuit.calculateWitness({ "selector": i });
assert(circuit.checkWitness(w));
const w = await circuit.calculateWitness({ "selector": i }, true);
assert(w[0].equals(bigInt(1)));
await circuit.checkConstraints(w);
// console.log(i + " -> " + w[circuit.getSignalIdx("main.out")].toString());
assert(w[circuit.getSignalIdx("main.out")].equals(ct8[i]));
await circuit.assertOut(w, {out: ct4[i]});
} }
}); });
it("Should create a constant multiplexer 1", async () => { it("Should create a constant multiplexer 1", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "mux1_1.circom"));
const circuit = await tester(path.join(__dirname, "circuits", "mux1_1.circom"));
const circuit = new snarkjs.Circuit(cirDef);
console.log("NConstrains Mux1: " + circuit.nConstraints);
const ct8 = [
const ct2 = [
bigInt("37"), bigInt("37"),
bigInt("47"), bigInt("47"),
]; ];
for (let i=0; i<2; i++) { for (let i=0; i<2; i++) {
const w = circuit.calculateWitness({ "selector": i });
assert(circuit.checkWitness(w));
const w = await circuit.calculateWitness({ "selector": i }, true);
assert(w[0].equals(bigInt(1)));
await circuit.checkConstraints(w);
// console.log(i + " -> " + w[circuit.getSignalIdx("main.out")].toString());
assert(w[circuit.getSignalIdx("main.out")].equals(ct8[i]));
await circuit.assertOut(w, {out: ct2[i]});
} }
}); });
}); });

+ 19
- 42
test/pedersen.js

@ -1,11 +1,8 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs");
const compiler = require("circom");
const assert = chai.assert;
const bigInt = snarkjs.bigInt;
const bigInt = require("big-integer");
const tester = require("circom").tester;
const babyJub = require("../src/babyjub.js"); const babyJub = require("../src/babyjub.js");
@ -22,79 +19,59 @@ describe("Double Pedersen test", function() {
let circuit; let circuit;
this.timeout(100000); this.timeout(100000);
before( async() => { before( async() => {
const cirDef = await compiler(path.join(__dirname, "circuits", "pedersen_test.circom"));
circuit = new snarkjs.Circuit(cirDef);
circuit = await tester(path.join(__dirname, "circuits", "pedersen_test.circom"));
console.log("NConstrains: " + circuit.nConstraints);
}); });
it("Should pedersen at zero", async () => { it("Should pedersen at zero", async () => {
let w, xout, yout;
let w;
w = circuit.calculateWitness({ in: ["0", "0"]});
w = await circuit.calculateWitness({ in: ["0", "0"]}, true);
xout = w[circuit.getSignalIdx("main.out[0]")];
yout = w[circuit.getSignalIdx("main.out[1]")];
await circuit.assertOut(w, {out: [0,1]});
assert(xout.equals("0"));
assert(yout.equals("1"));
}); });
it("Should pedersen at one first generator", async () => { it("Should pedersen at one first generator", async () => {
let w, xout, yout;
let w;
w = circuit.calculateWitness({ in: ["1", "0"]});
w = await circuit.calculateWitness({ in: ["1", "0"]}, true);
xout = bigInt(w[circuit.getSignalIdx("main.out[0]")]);
yout = bigInt(w[circuit.getSignalIdx("main.out[1]")]);
await circuit.assertOut(w, {out: PBASE[0]});
assert(xout.equals(PBASE[0][0]));
assert(yout.equals(PBASE[0][1]));
}); });
it("Should pedersen at one second generator", async () => { it("Should pedersen at one second generator", async () => {
let w, xout, yout;
w = circuit.calculateWitness({ in: ["0", "1"]});
let w;
xout = w[circuit.getSignalIdx("main.out[0]")];
yout = w[circuit.getSignalIdx("main.out[1]")];
w = await circuit.calculateWitness({ in: ["0", "1"]}, true);
assert(xout.equals(PBASE[1][0]));
assert(yout.equals(PBASE[1][1]));
await circuit.assertOut(w, {out: PBASE[1]});
}); });
it("Should pedersen at mixed generators", async () => { it("Should pedersen at mixed generators", async () => {
let w, xout, yout;
w = circuit.calculateWitness({ in: ["3", "7"]});
xout = w[circuit.getSignalIdx("main.out[0]")];
yout = w[circuit.getSignalIdx("main.out[1]")];
let w;
w = await circuit.calculateWitness({ in: ["3", "7"]}, true);
const r = babyJub.addPoint( const r = babyJub.addPoint(
babyJub.mulPointEscalar(PBASE[0], 3), babyJub.mulPointEscalar(PBASE[0], 3),
babyJub.mulPointEscalar(PBASE[1], 7) babyJub.mulPointEscalar(PBASE[1], 7)
); );
assert(xout.equals(r[0]));
assert(yout.equals(r[1]));
await circuit.assertOut(w, {out: r});
}); });
it("Should pedersen all ones", async () => { it("Should pedersen all ones", async () => {
let w, xout, yout;
let w;
const allOnes = bigInt("1").shl(250).sub(bigInt("1"));
w = circuit.calculateWitness({ in: [allOnes, allOnes]});
const allOnes = bigInt("1").shiftLeft(250).minus(bigInt("1"));
w = await circuit.calculateWitness({ in: [allOnes, allOnes]}, true);
xout = w[circuit.getSignalIdx("main.out[0]")];
yout = w[circuit.getSignalIdx("main.out[1]")];
const r2 = babyJub.addPoint( const r2 = babyJub.addPoint(
babyJub.mulPointEscalar(PBASE[0], allOnes), babyJub.mulPointEscalar(PBASE[0], allOnes),
babyJub.mulPointEscalar(PBASE[1], allOnes) babyJub.mulPointEscalar(PBASE[1], allOnes)
); );
assert(xout.equals(r2[0]));
assert(yout.equals(r2[1]));
await circuit.assertOut(w, {out: r2});
}); });
}); });

+ 10
- 35
test/pedersen2.js

@ -1,11 +1,7 @@
const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs");
const compiler = require("circom");
const assert = chai.assert;
const bigInt = snarkjs.bigInt;
const bigInt = require("big-integer");
const tester = require("circom").tester;
const babyJub = require("../src/babyjub.js"); const babyJub = require("../src/babyjub.js");
const pedersen = require("../src/pedersenHash.js"); const pedersen = require("../src/pedersenHash.js");
@ -15,60 +11,39 @@ describe("Pedersen test", function() {
let circuit; let circuit;
this.timeout(100000); this.timeout(100000);
before( async() => { before( async() => {
const cirDef = await compiler(path.join(__dirname, "circuits", "pedersen2_test.circom"));
circuit = new snarkjs.Circuit(cirDef);
console.log("NConstrains Pedersen2: " + circuit.nConstraints);
circuit = await tester(path.join(__dirname, "circuits", "pedersen2_test.circom"));
}); });
it("Should pedersen at zero", async () => { it("Should pedersen at zero", async () => {
let w, xout, yout;
w = circuit.calculateWitness({ in: 0});
let w;
xout = w[circuit.getSignalIdx("main.out[0]")];
yout = w[circuit.getSignalIdx("main.out[1]")];
w = await circuit.calculateWitness({ in: 0}, true);
const b = Buffer.alloc(32); const b = Buffer.alloc(32);
const h = pedersen.hash(b); const h = pedersen.hash(b);
const hP = babyJub.unpackPoint(h); const hP = babyJub.unpackPoint(h);
/*
console.log(`[${xout.toString()}, ${yout.toString()}]`);
console.log(`[${hP[0].toString()}, ${hP[1].toString()}]`);
*/
await circuit.assertOut(w, {out: hP});
assert(xout.equals(hP[0]));
assert(yout.equals(hP[1]));
}); });
it("Should pedersen with 253 ones", async () => { it("Should pedersen with 253 ones", async () => {
let w, xout, yout;
let w;
const n = bigInt.one.shl(253).sub(bigInt.one);
console.log(n.toString(16));
const n = bigInt.one.shiftLeft(253).minus(bigInt.one);
w = circuit.calculateWitness({ in: n});
xout = w[circuit.getSignalIdx("main.out[0]")];
yout = w[circuit.getSignalIdx("main.out[1]")];
w = await circuit.calculateWitness({ in: n}, true);
const b = Buffer.alloc(32); const b = Buffer.alloc(32);
for (let i=0; i<31; i++) b[i] = 0xFF; for (let i=0; i<31; i++) b[i] = 0xFF;
b[31] = 0x1F; b[31] = 0x1F;
const h = pedersen.hash(b); const h = pedersen.hash(b);
const hP = babyJub.unpackPoint(h); const hP = babyJub.unpackPoint(h);
/*
console.log(`[${xout.toString()}, ${yout.toString()}]`);
console.log(`[${hP[0].toString()}, ${hP[1].toString()}]`);
*/
await circuit.assertOut(w, {out: hP});
assert(xout.equals(hP[0]));
assert(yout.equals(hP[1]));
}); });
}); });

+ 6
- 16
test/point2bits.js

@ -1,11 +1,5 @@
const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs");
const compiler = require("circom");
const assert = chai.assert;
const bigInt = snarkjs.bigInt;
const tester = require("circom").tester;
const babyJub = require("../src/babyjub.js"); const babyJub = require("../src/babyjub.js");
@ -14,20 +8,16 @@ describe("Point 2 bits test", function() {
let circuit; let circuit;
this.timeout(100000); this.timeout(100000);
before( async() => { before( async() => {
const cirDef = await compiler(path.join(__dirname, "circuits", "pointbits_loopback.circom"));
circuit = new snarkjs.Circuit(cirDef);
console.log("NConstrains Point2Bits loopback: " + circuit.nConstraints);
circuit = await tester(path.join(__dirname, "circuits", "pointbits_loopback.circom"));
}); });
it("Should do the both convertions for 8Base", async () => { it("Should do the both convertions for 8Base", async () => {
const w = circuit.calculateWitness({ in: babyJub.Base8});
const w = await circuit.calculateWitness({ in: babyJub.Base8}, true);
assert(circuit.checkWitness(w));
await circuit.checkConstraints(w);
}); });
it("Should do the both convertions for Zero point", async () => { it("Should do the both convertions for Zero point", async () => {
const w = circuit.calculateWitness({ in: [0, 1]});
const w = await circuit.calculateWitness({ in: [0, 1]}, true);
assert(circuit.checkWitness(w));
await circuit.checkConstraints(w);
}); });
}); });

+ 21
- 36
test/poseidoncircuit.js

@ -1,8 +1,8 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs");
const compiler = require("circom");
var blake2b = require('blake2b');
var blake2b = require("blake2b");
const bigInt = require("big-integer");
const tester = require("circom").tester;
const poseidon = require("../src/poseidon.js"); const poseidon = require("../src/poseidon.js");
@ -11,9 +11,9 @@ const assert = chai.assert;
describe("Blake2b version test", function() { describe("Blake2b version test", function() {
it("Should give the expected output for blake2b version", async () => { it("Should give the expected output for blake2b version", async () => {
var output = new Uint8Array(32); var output = new Uint8Array(32);
var input = Buffer.from('poseidon_constants');
h = blake2b(output.length).update(input).digest('hex')
assert.equal('e57ba154fb2c47811dc1a2369b27e25a44915b4e4ece4eb8ec74850cb78e01b1', h);
var input = Buffer.from("poseidon_constants");
const h = blake2b(output.length).update(input).digest("hex");
assert.equal("e57ba154fb2c47811dc1a2369b27e25a44915b4e4ece4eb8ec74850cb78e01b1", h);
}); });
}); });
@ -24,68 +24,53 @@ describe("Poseidon Circuit test", function () {
this.timeout(100000); this.timeout(100000);
before( async () => { before( async () => {
const cirDef6 = await compiler(path.join(__dirname, "circuits", "poseidon6_test.circom"));
circuit6 = new snarkjs.Circuit(cirDef6);
console.log("Poseidon6 constraints: " + circuit6.nConstraints);
const cirDef3 = await compiler(path.join(__dirname, "circuits", "poseidon3_test.circom"));
circuit3 = new snarkjs.Circuit(cirDef3);
console.log("Poseidon3 constraints: " + circuit3.nConstraints);
circuit6 = await tester(path.join(__dirname, "circuits", "poseidon6_test.circom"));
circuit3 = await tester(path.join(__dirname, "circuits", "poseidon3_test.circom"));
}); });
it("Should check constrain of hash([1, 2]) t=6", async () => { it("Should check constrain of hash([1, 2]) t=6", async () => {
const w = circuit6.calculateWitness({inputs: [1, 2]});
const res = w[circuit6.getSignalIdx("main.out")];
const w = await circuit6.calculateWitness({inputs: [1, 2]}, true);
const hash = poseidon.createHash(6, 8, 57); const hash = poseidon.createHash(6, 8, 57);
const res2 = hash([1,2]); const res2 = hash([1,2]);
assert.equal("12242166908188651009877250812424843524687801523336557272219921456462821518061", res2.toString()); assert.equal("12242166908188651009877250812424843524687801523336557272219921456462821518061", res2.toString());
assert.equal(res.toString(), res2.toString());
assert(circuit6.checkWitness(w));
await circuit6.assertOut(w, {out : res2});
await circuit6.checkConstraints(w);
}); });
it("Should check constrain of hash([3, 4]) t=6", async () => { it("Should check constrain of hash([3, 4]) t=6", async () => {
const w = circuit6.calculateWitness({inputs: [3, 4]});
const res = w[circuit6.getSignalIdx("main.out")];
const w = await circuit6.calculateWitness({inputs: [3, 4]});
const hash = poseidon.createHash(6, 8, 57); const hash = poseidon.createHash(6, 8, 57);
const res2 = hash([3, 4]); const res2 = hash([3, 4]);
assert.equal("17185195740979599334254027721507328033796809509313949281114643312710535000993", res2.toString());
assert.equal(res.toString(), res2.toString());
assert(circuit6.checkWitness(w));
assert.equal("17185195740979599334254027721507328033796809509313949281114643312710535000993", res2.toString());
await circuit6.assertOut(w, {out : res2});
await circuit6.checkConstraints(w);
}); });
it("Should check constrain of hash([1, 2]) t=3", async () => { it("Should check constrain of hash([1, 2]) t=3", async () => {
const w = circuit3.calculateWitness({inputs: [1, 2]});
const res = w[circuit3.getSignalIdx("main.out")];
const w = await circuit3.calculateWitness({inputs: [1, 2]});
const hash = poseidon.createHash(3, 8, 57); const hash = poseidon.createHash(3, 8, 57);
const res2 = hash([1,2]); const res2 = hash([1,2]);
assert.equal("2104035019328376391822106787753454168168617545136592089411833517434990977743", res2.toString()); assert.equal("2104035019328376391822106787753454168168617545136592089411833517434990977743", res2.toString());
assert.equal(res.toString(), res2.toString());
assert(circuit3.checkWitness(w));
await circuit3.assertOut(w, {out : res2});
await circuit3.checkConstraints(w);
}); });
it("Should check constrain of hash([3, 4]) t=3", async () => { it("Should check constrain of hash([3, 4]) t=3", async () => {
const w = circuit3.calculateWitness({inputs: [3, 4]});
const res = w[circuit3.getSignalIdx("main.out")];
const w = await circuit3.calculateWitness({inputs: [3, 4]});
const hash = poseidon.createHash(3, 8, 57); const hash = poseidon.createHash(3, 8, 57);
const res2 = hash([3, 4]); const res2 = hash([3, 4]);
assert.equal("12456141564250880945411182508630957604732712316993112736876413121277158512223", res2.toString()); assert.equal("12456141564250880945411182508630957604732712316993112736876413121277158512223", res2.toString());
assert.equal(res.toString(), res2.toString());
assert(circuit3.checkWitness(w));
await circuit3.assertOut(w, {out : res2});
await circuit3.checkConstraints(w);
}); });
}); });

+ 0
- 23
test/rawsmt3.circom

@ -1,23 +0,0 @@
include "../circuits/smt/smtverifier.circom";
template SMT(nLevels) {
signal input root;
signal input mtp[nLevels];
signal input hi;
signal input hv;
component smtClaimExists = SMTVerifier(nLevels);
smtClaimExists.enabled <== 1;
smtClaimExists.fnc <== 0;
smtClaimExists.root <== root;
for (var i=0; i<nLevels; i++) {
smtClaimExists.siblings[i] <== mtp[i];
}
smtClaimExists.oldKey <== 0;
smtClaimExists.oldValue <== 0;
smtClaimExists.isOld0 <== 0;
smtClaimExists.key <== hi;
smtClaimExists.value <== hv;
}
component main = SMT(4);

+ 14
- 33
test/sha256.js

@ -3,12 +3,12 @@ const path = require("path");
const snarkjs = require("snarkjs"); const snarkjs = require("snarkjs");
const crypto = require("crypto"); const crypto = require("crypto");
const compiler = require("circom");
const assert = chai.assert; const assert = chai.assert;
const sha256 = require("./helpers/sha256"); const sha256 = require("./helpers/sha256");
const tester = require("circom").tester;
// const printSignal = require("./helpers/printsignal"); // const printSignal = require("./helpers/printsignal");
@ -34,7 +34,8 @@ function bitArray2buffer(a) {
} }
describe("SHA256 test", () => {
describe("SHA256 test", function () {
this.timeout(100000);
it("Should work bits to array and array to bits", async () => { it("Should work bits to array and array to bits", async () => {
@ -45,17 +46,13 @@ describe("SHA256 test", () => {
const a = buffer2bitArray(b); const a = buffer2bitArray(b);
const b2 = bitArray2buffer(a); const b2 = bitArray2buffer(a);
assert.equal(b.toString("hex"), b2.toString("hex"));
assert.equal(b.toString("hex"), b2.toString("hex"), true);
}); });
it("Should calculate a hash of 1 compressor", async () => { it("Should calculate a hash of 1 compressor", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "sha256_2_test.circom"));
const circuit = new snarkjs.Circuit(cirDef);
const cir = await tester(path.join(__dirname, "circuits", "sha256_2_test.circom"));
console.log("Vars: "+circuit.nVars);
console.log("Constraints: "+circuit.nConstraints);
const witness = circuit.calculateWitness({ "a": "1", "b": "2" });
const witness = await cir.calculateWitness({ "a": "1", "b": "2" }, true);
const b = new Buffer.alloc(54); const b = new Buffer.alloc(54);
b[26] = 1; b[26] = 1;
@ -74,16 +71,7 @@ describe("SHA256 test", () => {
}).timeout(1000000); }).timeout(1000000);
it("Should calculate a hash of 2 compressor", async () => { it("Should calculate a hash of 2 compressor", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "sha256_test512.circom"), {reduceConstraints:false} );
const circuit = new snarkjs.Circuit(cirDef);
console.log("Vars: "+circuit.nVars);
console.log("Constraints: "+circuit.nConstraints);
// const testStr = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
// const b = Buffer.from(testStr, 'utf8');
const cir = await tester(path.join(__dirname, "circuits", "sha256_test512.circom"));
const b = new Buffer.alloc(64); const b = new Buffer.alloc(64);
for (let i=0; i<64; i++) { for (let i=0; i<64; i++) {
@ -95,7 +83,7 @@ describe("SHA256 test", () => {
.digest("hex"); .digest("hex");
const arrIn = buffer2bitArray(b); const arrIn = buffer2bitArray(b);
const witness = circuit.calculateWitness({ "in": arrIn }, {logOutput: false});
const witness = await cir.calculateWitness({ "in": arrIn }, true);
const arrOut = witness.slice(1, 257); const arrOut = witness.slice(1, 257);
const hash2 = bitArray2buffer(arrOut).toString("hex"); const hash2 = bitArray2buffer(arrOut).toString("hex");
@ -103,32 +91,25 @@ describe("SHA256 test", () => {
assert.equal(hash, hash2); assert.equal(hash, hash2);
}).timeout(1000000); }).timeout(1000000);
it("Should calculate a hash of 2 compressor", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "sha256_test448.circom"), {reduceConstraints:false} );
const circuit = new snarkjs.Circuit(cirDef);
console.log("Vars: "+circuit.nVars);
console.log("Constraints: "+circuit.nConstraints);
it ("Should calculate a hash of 2 compressor", async () => {
const cir = await tester(path.join(__dirname, "circuits", "sha256_test448.circom"));
const testStr = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; const testStr = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
const b = Buffer.from(testStr, "utf8"); const b = Buffer.from(testStr, "utf8");
// for (let i=0; i<64; i++) {
// b[i] = i+1;
// }
const hash = crypto.createHash("sha256") const hash = crypto.createHash("sha256")
.update(b) .update(b)
.digest("hex"); .digest("hex");
const arrIn = buffer2bitArray(b); const arrIn = buffer2bitArray(b);
const witness = circuit.calculateWitness({ "in": arrIn } , {logOutput: false});
const witness = await cir.calculateWitness({ "in": arrIn }, true);
const arrOut = witness.slice(1, 257); const arrOut = witness.slice(1, 257);
const hash2 = bitArray2buffer(arrOut).toString("hex"); const hash2 = bitArray2buffer(arrOut).toString("hex");
assert.equal(hash, hash2); assert.equal(hash, hash2);
});
}).timeout(1000000);
}); });

+ 25
- 34
test/sign.js

@ -1,11 +1,6 @@
const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs");
const compiler = require("circom");
const assert = chai.assert;
const bigInt = snarkjs.bigInt;
const bigInt = require("big-integer");
const tester = require("circom").tester;
function print(circuit, w, s) { function print(circuit, w, s) {
console.log(s + ": " + w[circuit.getSignalIdx(s)]); console.log(s + ": " + w[circuit.getSignalIdx(s)]);
@ -14,7 +9,7 @@ function print(circuit, w, s) {
function getBits(v, n) { function getBits(v, n) {
const res = []; const res = [];
for (let i=0; i<n; i++) { for (let i=0; i<n; i++) {
if (v.shr(i).isOdd()) {
if (v.shiftRight(i).isOdd()) {
res.push(bigInt.one); res.push(bigInt.one);
} else { } else {
res.push(bigInt.zero); res.push(bigInt.zero);
@ -25,64 +20,60 @@ function getBits(v, n) {
const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"); const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
describe("Sign test", () => {
describe("Sign test", function() {
let circuit; let circuit;
before( async() => {
const cirDef = await compiler(path.join(__dirname, "circuits", "sign_test.circom"));
circuit = new snarkjs.Circuit(cirDef);
this.timeout(100000);
console.log("NConstrains: " + circuit.nConstraints);
before( async() => {
circuit = await tester(path.join(__dirname, "circuits", "sign_test.circom"));
}); });
it("Sign of 0", async () => { it("Sign of 0", async () => {
const inp = getBits(bigInt.zero, 254); const inp = getBits(bigInt.zero, 254);
const w = circuit.calculateWitness({in: inp});
const w = await circuit.calculateWitness({in: inp}, true);
assert( w[circuit.getSignalIdx("main.sign")].equals(bigInt(0)) );
await circuit.assertOut(w, {sign: 0});
}); });
it("Sign of 3", async () => { it("Sign of 3", async () => {
const inp = getBits(bigInt(3), 254); const inp = getBits(bigInt(3), 254);
const w = circuit.calculateWitness({in: inp});
const w = await circuit.calculateWitness({in: inp}, true);
assert( w[circuit.getSignalIdx("main.sign")].equals(bigInt(0)) );
await circuit.assertOut(w, {sign: 0});
}); });
it("Sign of q/2", async () => { it("Sign of q/2", async () => {
const inp = getBits(q.shr(bigInt.one), 254);
const w = circuit.calculateWitness({in: inp});
const inp = getBits(q.shiftRight(bigInt.one), 254);
const w = await circuit.calculateWitness({in: inp}, true);
assert( w[circuit.getSignalIdx("main.sign")].equals(bigInt(0)) );
await circuit.assertOut(w, {sign: 0});
}); });
it("Sign of q/2+1", async () => { it("Sign of q/2+1", async () => {
const inp = getBits(q.shr(bigInt.one).add(bigInt.one), 254);
const w = circuit.calculateWitness({in: inp});
const inp = getBits(q.shiftRight(bigInt.one).add(bigInt.one), 254);
const w = await circuit.calculateWitness({in: inp}, true);
assert( w[circuit.getSignalIdx("main.sign")].equals(bigInt(1)) );
await circuit.assertOut(w, {sign: 1});
}); });
it("Sign of q-1", async () => { it("Sign of q-1", async () => {
const inp = getBits(q.sub(bigInt.one), 254);
const w = circuit.calculateWitness({in: inp});
const inp = getBits(q.minus(bigInt.one), 254);
const w = await circuit.calculateWitness({in: inp}, true);
assert( w[circuit.getSignalIdx("main.sign")].equals(bigInt(1)) );
await circuit.assertOut(w, {sign: 1});
}); });
it("Sign of q", async () => { it("Sign of q", async () => {
const inp = getBits(q, 254); const inp = getBits(q, 254);
const w = circuit.calculateWitness({in: inp});
const w = await circuit.calculateWitness({in: inp}, true);
assert( w[circuit.getSignalIdx("main.sign")].equals(bigInt(1)) );
await circuit.assertOut(w, {sign: 1});
}); });
it("Sign of all ones", async () => { it("Sign of all ones", async () => {
const inp = getBits(bigInt(1).shl(254).sub(bigInt(1)), 254);
const w = circuit.calculateWitness({in: inp});
const inp = getBits(bigInt(1).shiftLeft(254).minus(bigInt(1)), 254);
const w = await circuit.calculateWitness({in: inp}, true);
assert( w[circuit.getSignalIdx("main.sign")].equals(bigInt(1)) );
await circuit.assertOut(w, {sign: 1});
}); });
}); });

+ 2
- 3
test/smtjs.js

@ -1,12 +1,11 @@
const chai = require("chai"); const chai = require("chai");
const snarkjs = require("snarkjs");
const bigInt = require("big-integer");
const smt = require("../src/smt.js"); const smt = require("../src/smt.js");
const assert = chai.assert; const assert = chai.assert;
const bigInt = snarkjs.bigInt;
function stringifyBigInts(o) { function stringifyBigInts(o) {
if ((typeof(o) == "bigint") || (o instanceof bigInt)) { if ((typeof(o) == "bigint") || (o instanceof bigInt)) {

+ 24
- 33
test/smtprocessor.js

@ -1,25 +1,23 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs");
const compiler = require("circom");
const bigInt = require("big-integer");
const tester = require("circom").tester;
const smt = require("../src/smt.js"); const smt = require("../src/smt.js");
const assert = chai.assert; const assert = chai.assert;
const bigInt = snarkjs.bigInt;
function print(circuit, w, s) { function print(circuit, w, s) {
console.log(s + ": " + w[circuit.getSignalIdx(s)]); console.log(s + ": " + w[circuit.getSignalIdx(s)]);
} }
async function testInsert(tree, key, value, circuit, log ) {
async function testInsert(tree, key, value, circuit ) {
const res = await tree.insert(key,value); const res = await tree.insert(key,value);
let siblings = res.siblings; let siblings = res.siblings;
while (siblings.length<10) siblings.push(bigInt(0)); while (siblings.length<10) siblings.push(bigInt(0));
const w = circuit.calculateWitness({
const w = await circuit.calculateWitness({
fnc: [1,0], fnc: [1,0],
oldRoot: res.oldRoot, oldRoot: res.oldRoot,
siblings: siblings, siblings: siblings,
@ -28,11 +26,12 @@ async function testInsert(tree, key, value, circuit, log ) {
isOld0: res.isOld0 ? 1 : 0, isOld0: res.isOld0 ? 1 : 0,
newKey: key, newKey: key,
newValue: value newValue: value
}, log);
}, true);
await circuit.checkConstraints(w);
await circuit.assertOut(w, {newRoot: res.newRoot});
const root1 = w[circuit.getSignalIdx("main.newRoot")];
assert(circuit.checkWitness(w));
assert(root1.equals(res.newRoot));
} }
async function testDelete(tree, key, circuit) { async function testDelete(tree, key, circuit) {
@ -40,7 +39,7 @@ async function testDelete(tree, key, circuit) {
let siblings = res.siblings; let siblings = res.siblings;
while (siblings.length<10) siblings.push(bigInt(0)); while (siblings.length<10) siblings.push(bigInt(0));
const w = circuit.calculateWitness({
const w = await circuit.calculateWitness({
fnc: [1,1], fnc: [1,1],
oldRoot: res.oldRoot, oldRoot: res.oldRoot,
siblings: siblings, siblings: siblings,
@ -49,12 +48,11 @@ async function testDelete(tree, key, circuit) {
isOld0: res.isOld0 ? 1 : 0, isOld0: res.isOld0 ? 1 : 0,
newKey: res.delKey, newKey: res.delKey,
newValue: res.delValue newValue: res.delValue
});
}, true);
const root1 = w[circuit.getSignalIdx("main.newRoot")];
await circuit.checkConstraints(w);
assert(circuit.checkWitness(w));
assert(root1.equals(res.newRoot));
await circuit.assertOut(w, {newRoot: res.newRoot});
} }
async function testUpdate(tree, key, newValue, circuit) { async function testUpdate(tree, key, newValue, circuit) {
@ -62,7 +60,7 @@ async function testUpdate(tree, key, newValue, circuit) {
let siblings = res.siblings; let siblings = res.siblings;
while (siblings.length<10) siblings.push(bigInt(0)); while (siblings.length<10) siblings.push(bigInt(0));
const w = circuit.calculateWitness({
const w = await circuit.calculateWitness({
fnc: [0,1], fnc: [0,1],
oldRoot: res.oldRoot, oldRoot: res.oldRoot,
siblings: siblings, siblings: siblings,
@ -73,25 +71,21 @@ async function testUpdate(tree, key, newValue, circuit) {
newValue: res.newValue newValue: res.newValue
}); });
const root1 = w[circuit.getSignalIdx("main.newRoot")];
await circuit.checkConstraints(w);
assert(circuit.checkWitness(w));
assert(root1.equals(res.newRoot));
await circuit.assertOut(w, {newRoot: res.newRoot});
} }
describe("SMT test", function () {
describe("SMT Processor test", function () {
let circuit; let circuit;
let tree; let tree;
this.timeout(10000000); this.timeout(10000000);
before( async () => { before( async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "smtprocessor10_test.circom"));
circuit = new snarkjs.Circuit(cirDef);
console.log("NConstrains SMTProcessor: " + circuit.nConstraints);
circuit = await tester(path.join(__dirname, "circuits", "smtprocessor10_test.circom"));
await circuit.loadSymbols();
tree = await smt.newMemEmptyTrie(); tree = await smt.newMemEmptyTrie();
}); });
@ -110,8 +104,6 @@ describe("SMT test", function () {
await testInsert(tree, key, value, circuit); await testInsert(tree, key, value, circuit);
}); });
it("Should remove an element", async () => { it("Should remove an element", async () => {
await testDelete(tree, 111, circuit); await testDelete(tree, 111, circuit);
await testDelete(tree, 333, circuit); await testDelete(tree, 333, circuit);
@ -179,7 +171,7 @@ describe("SMT test", function () {
it("Should match a NOp with random vals", async () => { it("Should match a NOp with random vals", async () => {
let siblings = []; let siblings = [];
while (siblings.length<10) siblings.push(bigInt(88)); while (siblings.length<10) siblings.push(bigInt(88));
const w = circuit.calculateWitness({
const w = await circuit.calculateWitness({
fnc: [0,0], fnc: [0,0],
oldRoot: 11, oldRoot: 11,
siblings: siblings, siblings: siblings,
@ -190,12 +182,12 @@ describe("SMT test", function () {
newValue: 77 newValue: 77
}); });
const root1 = w[circuit.getSignalIdx("main.oldRoot")];
const root2 = w[circuit.getSignalIdx("main.newRoot")];
const root1 = w[circuit.symbols["main.oldRoot"].varIdx];
const root2 = w[circuit.symbols["main.newRoot"].varIdx];
assert(circuit.checkWitness(w));
assert(root1.equals(root2));
await circuit.checkConstraints(w);
assert(root1.equals(root2));
}); });
it("Should update an element", async () => { it("Should update an element", async () => {
const tree1 = await smt.newMemEmptyTrie(); const tree1 = await smt.newMemEmptyTrie();
@ -213,5 +205,4 @@ describe("SMT test", function () {
await testUpdate(tree1, 9, 999, circuit); await testUpdate(tree1, 9, 999, circuit);
await testUpdate(tree1, 32, 323232, circuit); await testUpdate(tree1, 32, 323232, circuit);
}); });
}); });

+ 15
- 17
test/smtverifier.js

@ -1,14 +1,12 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const snarkjs = require("snarkjs");
const compiler = require("circom");
const bigInt = require("big-integer");
const tester = require("circom").tester;
const smt = require("../src/smt.js"); const smt = require("../src/smt.js");
const assert = chai.assert; const assert = chai.assert;
const bigInt = snarkjs.bigInt;
function print(circuit, w, s) { function print(circuit, w, s) {
console.log(s + ": " + w[circuit.getSignalIdx(s)]); console.log(s + ": " + w[circuit.getSignalIdx(s)]);
} }
@ -21,7 +19,7 @@ async function testInclusion(tree, key, circuit) {
let siblings = res.siblings; let siblings = res.siblings;
while (siblings.length<10) siblings.push(bigInt(0)); while (siblings.length<10) siblings.push(bigInt(0));
const w = circuit.calculateWitness({
const w = await circuit.calculateWitness({
enabled: 1, enabled: 1,
fnc: 0, fnc: 0,
root: tree.root, root: tree.root,
@ -31,9 +29,10 @@ async function testInclusion(tree, key, circuit) {
isOld0: 0, isOld0: 0,
key: key, key: key,
value: res.foundValue value: res.foundValue
});
}, true);
await circuit.checkConstraints(w);
assert(circuit.checkWitness(w));
} }
async function testExclusion(tree, key, circuit) { async function testExclusion(tree, key, circuit) {
@ -43,7 +42,7 @@ async function testExclusion(tree, key, circuit) {
let siblings = res.siblings; let siblings = res.siblings;
while (siblings.length<10) siblings.push(bigInt(0)); while (siblings.length<10) siblings.push(bigInt(0));
const w = circuit.calculateWitness({
const w = await circuit.calculateWitness({
enabled: 1, enabled: 1,
fnc: 1, fnc: 1,
root: tree.root, root: tree.root,
@ -55,21 +54,18 @@ async function testExclusion(tree, key, circuit) {
value: 0 value: 0
}); });
assert(circuit.checkWitness(w));
await circuit.checkConstraints(w);
} }
describe("SMT test", function () {
describe("SMT Verifier test", function () {
let circuit; let circuit;
let tree; let tree;
this.timeout(100000); this.timeout(100000);
before( async () => { before( async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "smtverifier10_test.circom"));
circuit = new snarkjs.Circuit(cirDef);
console.log("NConstrains SMTVerifier: " + circuit.nConstraints);
circuit = await tester(path.join(__dirname, "circuits", "smtverifier10_test.circom"));
tree = await smt.newMemEmptyTrie(); tree = await smt.newMemEmptyTrie();
await tree.insert(7,77); await tree.insert(7,77);
@ -97,7 +93,7 @@ describe("SMT test", function () {
let siblings = []; let siblings = [];
for (let i=0; i<10; i++) siblings.push(i); for (let i=0; i<10; i++) siblings.push(i);
const w = circuit.calculateWitness({
const w = await circuit.calculateWitness({
enabled: 0, enabled: 0,
fnc: 0, fnc: 0,
root: 1, root: 1,
@ -108,7 +104,9 @@ describe("SMT test", function () {
key: 44, key: 44,
value: 0 value: 0
}); });
assert(circuit.checkWitness(w));
await circuit.checkConstraints(w);
}); });
it("Check inclussion Adria case", async () => { it("Check inclussion Adria case", async () => {

+ 0
- 98
test/smtverifier_adria.js

@ -1,98 +0,0 @@
const path = require("path");
const snarkjs = require("snarkjs");
const compiler = require("circom");
const fs = require("fs")
const bigInt = snarkjs.bigInt;
const smt = require("../src/smt.js");
const circuitSource = `
include "../circuits/smt/smtverifier.circom";
template SMT(nLevels) {
signal input root;
signal input mtp[nLevels];
signal input hi;
signal input hv;
component smtClaimExists = SMTVerifier(nLevels);
smtClaimExists.enabled <== 1;
smtClaimExists.fnc <== 0;
smtClaimExists.root <== root;
for (var i=0; i<nLevels; i++) {
smtClaimExists.siblings[i] <== mtp[i];
}
smtClaimExists.oldKey <== 0;
smtClaimExists.oldValue <== 0;
smtClaimExists.isOld0 <== 0;
smtClaimExists.key <== hi;
smtClaimExists.value <== hv;
}
component main = SMT(4);
`;
describe("smt3test", function () {
this.timeout(200000);
let circuitFileName;
before( async () => {
circuitFileName = path.join(__dirname, ".", "rawsmt3.circom");
fs.writeFileSync(circuitFileName,circuitSource);
});
const levels = 4;
async function testsmt3(e1, e2) {
let tree = await smt.newMemEmptyTrie();
// insert e1, e2
await tree.insert(e1.hi, e1.hv);
await tree.insert(e2.hi, e2.hv);
// generate proof for e1
const findInfo = await tree.find(e1.hi);
const siblings = findInfo.siblings;
while (siblings.length < levels) siblings.push(bigInt(0));
const input = {
root: tree.root,
mtp: siblings,
hi: e1.hi,
hv: e1.hv,
};
const compiledCircuit = await compiler(
circuitFileName,
{ reduceConstraints: false }
);
const circuit = new snarkjs.Circuit(compiledCircuit);
const witness = circuit.calculateWitness(input);
circuit.checkWitness(witness);
}
it("TestSmts", async () => {
const e1 = {
hi: bigInt("17124152697573569611556136390143205198134245887034837071647643529178599000839"),
hv: bigInt("19650379996168153643111744440707177573540245771926102415571667548153444658179"),
};
const e2ok = {
hi: bigInt("16498254692537945203721083102154618658340563351558973077349594629411025251262"),
hv: bigInt("19650379996168153643111744440707177573540245771926102415571667548153444658179"),
};
const e2fail = {
hi: bigInt("17195092312975762537892237130737365903429674363577646686847513978084990105579"),
hv: bigInt("19650379996168153643111744440707177573540245771926102415571667548153444658179"),
};
console.log("test e1, e2ok");
await testsmt3(e1, e2ok);
console.log("test e1, e2fail");
await testsmt3(e1, e2fail);
});
});

Loading…
Cancel
Save