-
Notifications
You must be signed in to change notification settings - Fork 1
/
ed25519-circom.patch
262 lines (242 loc) · 8.79 KB
/
ed25519-circom.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
diff --git a/circuits/chunkedsub.circom b/circuits/chunkedsub.circom
index bccda66..fdeb22b 100644
--- a/circuits/chunkedsub.circom
+++ b/circuits/chunkedsub.circom
@@ -7,14 +7,14 @@ template ChunkedSub(k, base) {
signal output out[k];
signal output underflow;
- component unit0 = ModSub(base);
+ component unit0 = ModSubBounded(base);
unit0.a <== a[0];
unit0.b <== b[0];
out[0] <== unit0.out;
component unit[k - 1];
for (var i = 1; i < k; i++) {
- unit[i - 1] = ModSubThree(base);
+ unit[i - 1] = ModSubThreeBounded(base);
unit[i - 1].a <== a[i];
unit[i - 1].b <== b[i];
if (i == 1) {
@@ -27,7 +27,7 @@ template ChunkedSub(k, base) {
underflow <== unit[k - 2].borrow;
}
-template ModSub(base) {
+template ModSubBounded(base) {
signal input a;
signal input b;
signal output out;
@@ -39,7 +39,7 @@ template ModSub(base) {
out <== borrow * (1 << base) + a - b;
}
-template ModSubThree(base) {
+template ModSubThreeBounded(base) {
signal input a;
signal input b;
signal input c;
@@ -53,4 +53,4 @@ template ModSubThree(base) {
lt.in[1] <== b_plus_c;
borrow <== lt.out;
out <== borrow * (1 << base) + a - b_plus_c;
-}
\ No newline at end of file
+}
diff --git a/circuits/modinv.circom b/circuits/modinv.circom
index bbfd7c6..f5d749e 100644
--- a/circuits/modinv.circom
+++ b/circuits/modinv.circom
@@ -12,7 +12,7 @@ template BigModInv51() {
var p[3] = [38685626227668133590597613, 38685626227668133590597631, 38685626227668133590597631];
// length k
- var inv[100] = mod_inv(85, 3, in, p);
+ var inv[100] = mod_inv_alternate(85, 3, in, p);
for (var i = 0; i < 3; i++) {
out[i] <-- inv[i];
}
diff --git a/circuits/utils.circom b/circuits/utils.circom
index 928475a..888b3a6 100644
--- a/circuits/utils.circom
+++ b/circuits/utils.circom
@@ -1,15 +1,15 @@
pragma circom 2.0.0;
-function SplitFn(in, n, m) {
+function SplitFnAlternate(in, n, m) {
return [in % (1 << n), (in \ (1 << n)) % (1 << m)];
}
-function SplitThreeFn(in, n, m, k) {
+function SplitThreeFnAlternate(in, n, m, k) {
return [in % (1 << n), (in \ (1 << n)) % (1 << m), (in \ (1 << n + m)) % (1 << k)];
}
// 1 if true, 0 if false
-function long_gt(n, k, a, b) {
+function long_gt_alternate(n, k, a, b) {
for (var i = k - 1; i >= 0; i--) {
if (a[i] > b[i]) {
return 1;
@@ -25,7 +25,7 @@ function long_gt(n, k, a, b) {
// a has k registers
// b has k registers
// a >= b
-function long_sub(n, k, a, b) {
+function long_sub_alternate(n, k, a, b) {
var diff[100];
var borrow[100];
for (var i = 0; i < k; i++) {
@@ -52,7 +52,7 @@ function long_sub(n, k, a, b) {
// a is a n-bit scalar
// b has k registers
-function long_scalar_mult(n, k, a, b) {
+function long_scalar_mult_alternate(n, k, a, b) {
var out[100];
for (var i = 0; i < 100; i++) {
out[i] = 0;
@@ -73,7 +73,7 @@ function long_scalar_mult(n, k, a, b) {
// out[1] has length k -- remainder
// implements algorithm of https://people.eecs.berkeley.edu/~fateman/282/F%20Wright%20notes/week4.pdf
// b[k-1] must be nonzero!
-function long_div(n, k, a, b) {
+function long_div_alternate(n, k, a, b) {
var out[2][100];
var remainder[200];
@@ -95,9 +95,9 @@ function long_div(n, k, a, b) {
}
}
- out[0][i] = short_div(n, k, dividend, b);
+ out[0][i] = short_div_alternate(n, k, dividend, b);
- var mult_shift[100] = long_scalar_mult(n, k, out[0][i], b);
+ var mult_shift[100] = long_scalar_mult_alternate(n, k, out[0][i], b);
var subtrahend[200];
for (var j = 0; j < 2 * k; j++) {
subtrahend[j] = 0;
@@ -107,7 +107,7 @@ function long_div(n, k, a, b) {
subtrahend[i + j] = mult_shift[j];
}
}
- remainder = long_sub(n, 2 * k, remainder, subtrahend);
+ remainder = long_sub_alternate(n, 2 * k, remainder, subtrahend);
}
for (var i = 0; i < k; i++) {
out[1][i] = remainder[i];
@@ -122,16 +122,16 @@ function long_div(n, k, a, b) {
// b has k registers
// assumes leading digit of b is at least 2 ** (n - 1)
// 0 <= a < (2**n) * b
-function short_div_norm(n, k, a, b) {
+function short_div_norm_alternate(n, k, a, b) {
var qhat = (a[k] * (1 << n) + a[k - 1]) \ b[k - 1];
if (qhat > (1 << n) - 1) {
qhat = (1 << n) - 1;
}
- var mult[100] = long_scalar_mult(n, k, qhat, b);
- if (long_gt(n, k + 1, mult, a) == 1) {
- mult = long_sub(n, k + 1, mult, b);
- if (long_gt(n, k + 1, mult, a) == 1) {
+ var mult[100] = long_scalar_mult_alternate(n, k, qhat, b);
+ if (long_gt_alternate(n, k + 1, mult, a) == 1) {
+ mult = long_sub_alternate(n, k + 1, mult, b);
+ if (long_gt_alternate(n, k + 1, mult, a) == 1) {
return qhat - 2;
} else {
return qhat - 1;
@@ -146,19 +146,19 @@ function short_div_norm(n, k, a, b) {
// b has k registers
// assumes leading digit of b is non-zero
// 0 <= a < (2**n) * b
-function short_div(n, k, a, b) {
+function short_div_alternate(n, k, a, b) {
var scale = (1 << n) \ (1 + b[k - 1]);
// k + 2 registers now
- var norm_a[200] = long_scalar_mult(n, k + 1, scale, a);
+ var norm_a[200] = long_scalar_mult_alternate(n, k + 1, scale, a);
// k + 1 registers now
- var norm_b[200] = long_scalar_mult(n, k, scale, b);
+ var norm_b[200] = long_scalar_mult_alternate(n, k, scale, b);
var ret;
if (norm_b[k] != 0) {
- ret = short_div_norm(n, k + 1, norm_a, norm_b);
+ ret = short_div_norm_alternate(n, k + 1, norm_a, norm_b);
} else {
- ret = short_div_norm(n, k, norm_a, norm_b);
+ ret = short_div_norm_alternate(n, k, norm_a, norm_b);
}
return ret;
}
@@ -167,7 +167,7 @@ function short_div(n, k, a, b) {
// a and b both have k registers
// out[0] has length 2 * k
// adapted from BigMulShortLong and LongToShortNoEndCarry2 witness computation
-function prod(n, k, a, b) {
+function prod_alternate(n, k, a, b) {
// first compute the intermediate values. taken from BigMulShortLong
var prod_val[100]; // length is 2 * k - 1
for (var i = 0; i < 2 * k - 1; i++) {
@@ -188,20 +188,20 @@ function prod(n, k, a, b) {
var split[100][3]; // first dimension has length 2 * k - 1
for (var i = 0; i < 2 * k - 1; i++) {
- split[i] = SplitThreeFn(prod_val[i], n, n, n);
+ split[i] = SplitThreeFnAlternate(prod_val[i], n, n, n);
}
var carry[100]; // length is 2 * k - 1
carry[0] = 0;
out[0] = split[0][0];
if (2 * k - 1 > 1) {
- var sumAndCarry[2] = SplitFn(split[0][1] + split[1][0], n, n);
+ var sumAndCarry[2] = SplitFnAlternate(split[0][1] + split[1][0], n, n);
out[1] = sumAndCarry[0];
carry[1] = sumAndCarry[1];
}
if (2 * k - 1 > 2) {
for (var i = 2; i < 2 * k - 1; i++) {
- var sumAndCarry[2] = SplitFn(split[i][0] + split[i-1][1] + split[i-2][2] + carry[i-1], n, n);
+ var sumAndCarry[2] = SplitFnAlternate(split[i][0] + split[i-1][1] + split[i-2][2] + carry[i-1], n, n);
out[i] = sumAndCarry[0];
carry[i] = sumAndCarry[1];
}
@@ -217,7 +217,7 @@ function prod(n, k, a, b) {
// k * n <= 500
// p is a prime
// computes a^e mod p
-function mod_exp(n, k, a, p, e) {
+function mod_exp_alternate(n, k, a, p, e) {
var eBits[500]; // length is k * n
for (var i = 0; i < k; i++) {
for (var j = 0; j < n; j++) {
@@ -236,18 +236,18 @@ function mod_exp(n, k, a, p, e) {
// multiply by a if bit is 0
if (eBits[i] == 1) {
var temp[200]; // length 2 * k
- temp = prod(n, k, out, a);
+ temp = prod_alternate(n, k, out, a);
var temp2[2][100];
- temp2 = long_div(n, k, temp, p);
+ temp2 = long_div_alternate(n, k, temp, p);
out = temp2[1];
}
// square, unless we're at the end
if (i > 0) {
var temp[200]; // length 2 * k
- temp = prod(n, k, out, out);
+ temp = prod_alternate(n, k, out, out);
var temp2[2][100];
- temp2 = long_div(n, k, temp, p);
+ temp2 = long_div_alternate(n, k, temp, p);
out = temp2[1];
}
@@ -262,7 +262,7 @@ function mod_exp(n, k, a, p, e) {
// p is a prime
// if a == 0 mod p, returns 0
// else computes inv = a^(p-2) mod p
-function mod_inv(n, k, a, p) {
+function mod_inv_alternate(n, k, a, p) {
var isZero = 1;
for (var i = 0; i < k; i++) {
if (a[i] != 0) {
@@ -293,8 +293,8 @@ function mod_inv(n, k, a, p) {
two[0] = 2;
var pMinusTwo[100];
- pMinusTwo = long_sub(n, k, pCopy, two); // length k
+ pMinusTwo = long_sub_alternate(n, k, pCopy, two); // length k
var out[100];
- out = mod_exp(n, k, a, pCopy, pMinusTwo);
+ out = mod_exp_alternate(n, k, a, pCopy, pMinusTwo);
return out;
}