You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

165 lines
8.0 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. /*
  2. Copyright 2018 0KIMS association.
  3. This file is part of circom (Zero Knowledge Circuit Compiler).
  4. circom is a free software: you can redistribute it and/or modify it
  5. under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. circom is distributed in the hope that it will be useful, but WITHOUT
  9. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
  11. License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with circom. If not, see <https://www.gnu.org/licenses/>.
  14. */
  15. /*
  16. ┏━━━━━━━━━━━┓
  17. ┃ ┃
  18. ┃ ┃
  19. (inx, iny) ══════════════════════════════════════════▶┃ EC Point ┃
  20. ┃ ╠═▶ (outx, outy)
  21. ╔══▶┃ Adder ┃
  22. ║ ┃ ┃
  23. ║ ┃ ┃
  24. ║ ┃ ┃
  25. ┏━━━━━━━━━━━┓ ┏━━━━━━━━━━━━┓ ║ ┗━━━━━━━━━━━┛
  26. ┃ ┃ ┃ ┃ ║
  27. ┃ ┃ ┃ ┃ ║
  28. ┃ ╠═══(p0x,p0y)═══▶┃ ┃ ║
  29. ┃ ╠═══(p1x,p1y)═══▶┃ ┃ ║
  30. ┃ ╠═══(p2x,p2y)═══▶┃ ┃ ║
  31. ┃ ╠═══(p3x,p3y)═══▶┃ ┃ ║
  32. ┃ ╠═══(p4x,p4y)═══▶┃ ┃ ║
  33. ┃ ╠═══(p5x,p5y)═══▶┃ ┃ ║
  34. ┃ ╠═══(p6x,p6y)═══▶┃ ┃ ║
  35. ┃ Constant ╠═══(p7x,p7y)═══▶┃ ┃ ║
  36. ┃ Points ┃ ┃ Mux4 ╠══╝
  37. ┃ ╠═══(p8x,p8y)═══▶┃ ┃
  38. ┃ ╠═══(p9x,p9y)═══▶┃ ┃
  39. ┃ ╠══(p10x,p10y)══▶┃ ┃
  40. ┃ ╠══(p11x,p11y)══▶┃ ┃
  41. ┃ ╠══(p12x,p12y)══▶┃ ┃
  42. ┃ ╠══(p13x,p13y)══▶┃ ┃
  43. ┃ ╠══(p14x,p14y)══▶┃ ┃
  44. ┃ ╠══(p15x,p15y)══▶┃ ┃
  45. ┃ ┃ ┃ ┃
  46. ┃ ┃ ┃ ┃
  47. ┗━━━━━━━━━━━┛ ┗━━━━━━━━━━━━┛
  48. ▲ ▲ ▲ ▲
  49. │ │ │ │
  50. s0 ─────────────────────────────────┘ │ │ │
  51. s1 ────────────────────────────────────┘ │ │
  52. s2 ───────────────────────────────────────┘ │
  53. s3 ──────────────────────────────────────────┘
  54. */
  55. include "mux4.circom";
  56. include "escalarmulw4table.circom";
  57. include "babyjub.circom";
  58. template EscalarMulWindow(base, k) {
  59. signal input in[2];
  60. signal input sel[4];
  61. signal output out[2];
  62. var table[16][2];
  63. component mux;
  64. component adder;
  65. var i;
  66. table = EscalarMulW4Table(base, k);
  67. mux = MultiMux4(2);
  68. adder = BabyAdd();
  69. for (i=0; i<4; i++) {
  70. sel[i] ==> mux.s[i];
  71. }
  72. for (i=0; i<16; i++) {
  73. mux.c[0][i] <== table[i][0];
  74. mux.c[1][i] <== table[i][1];
  75. }
  76. in[0] ==> adder.x1;
  77. in[1] ==> adder.y1;
  78. mux.out[0] ==> adder.x2;
  79. mux.out[1] ==> adder.y2;
  80. adder.xout ==> out[0];
  81. adder.yout ==> out[1];
  82. }
  83. /*
  84. ┏━━━━━━━━━┓ ┏━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━━━━━┓
  85. ┃ ┃ ┃ ┃ ┃ ┃
  86. inp ════▶┃Window(0)┃═════▶┃Window(1)┃════════ . . . . ═════════▶┃ Window(nBlocks-1) ┃═════▶ out
  87. ┃ ┃ ┃ ┃ ┃ ┃
  88. ┗━━━━━━━━━┛ ┗━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━━━━━┛
  89. ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
  90. in[0]─────────┘ │ │ │ │ │ │ │ │ │ │ │
  91. in[1]───────────┘ │ │ │ │ │ │ │ │ │ │
  92. in[2]─────────────┘ │ │ │ │ │ │ │ 0 0
  93. in[3]───────────────┘ │ │ │ │ │ │
  94. in[4]──────────────────────────┘ │ │ │ │ │
  95. in[5]────────────────────────────┘ │ │ │ │
  96. in[6]──────────────────────────────┘ │ │ │
  97. in[7]────────────────────────────────┘ │ │
  98. . │ │
  99. . │ │
  100. in[n-2]─────────────────────────────────────────────────────────────────────┘ │
  101. in[n-1]───────────────────────────────────────────────────────────────────────┘
  102. */
  103. template EscalarMul(n, base) {
  104. signal input in[n];
  105. signal input inp[2]; // Point input to be added
  106. signal output out[2];
  107. var nBlocks = ((n-1)>>2)+1;
  108. var i;
  109. var j;
  110. component windows[nBlocks];
  111. // Construct the windows
  112. for (i=0; i<nBlocks; i++) {
  113. windows[i] = EscalarMulWindow(base, i);
  114. }
  115. // Connect the selectors
  116. for (i=0; i<nBlocks; i++) {
  117. for (j=0; j<4; j++) {
  118. if (i*4+j >= n) {
  119. windows[i].sel[j] <== 0;
  120. } else {
  121. windows[i].sel[j] <== in[i*4+j];
  122. }
  123. }
  124. }
  125. // Start with generator
  126. windows[0].in[0] <== inp[0];
  127. windows[0].in[1] <== inp[1];
  128. for(i=0; i<nBlocks-1; i++) {
  129. windows[i].out[0] ==> windows[i+1].in[0];
  130. windows[i].out[1] ==> windows[i+1].in[1];
  131. }
  132. windows[nBlocks-1].out[0] ==> out[0];
  133. windows[nBlocks-1].out[1] ==> out[1];
  134. }