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