circom/test/fieldasm.js
test/fieldasm.jsRaw
1const tester = require("../ports/c/buildasm/buildzqfieldtester.js");
2
3const ZqField = require("fflib").ZqField;
4
5const bigInt = require("big-integer");
6
7const bn128q = new bigInt("21888242871839275222246405745257275088696311157297823662689037894645226208583");
8const bn128r = new bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
9const secp256k1q = new bigInt("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16);
10const secp256k1r = new bigInt("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16);
11const mnt6753q = new bigInt("41898490967918953402344214791240637128170709919953949071783502921025352812571106773058893763790338921418070971888458477323173057491593855069696241854796396165721416325350064441470418137846398469611935719059908164220784476160001");
12const mnt6753r = new bigInt("41898490967918953402344214791240637128170709919953949071783502921025352812571106773058893763790338921418070971888253786114353726529584385201591605722013126468931404347949840543007986327743462853720628051692141265303114721689601");
13
14describe("field asm test", function () {
15 this.timeout(1000000000);
16 it("bn128r add", async () => {
17 const tv = buildTestVector2(bn128r, "add");
18 await tester(bn128r, tv);
19 });
20/*
21 it("secp256k1q add", async () => {
22 const tv = buildTestVector2(secp256k1q, "add");
23 await tester(secp256k1q, tv);
24 });
25 it("mnt6753q add", async () => {
26 const tv = buildTestVector2(mnt6753q, "add");
27 await tester(mnt6753q, tv);
28 });
29 it("bn128r sub", async () => {
30 const tv = buildTestVector2(bn128r, "sub");
31 await tester(bn128r, tv);
32 });
33 it("secp256k1q sub", async () => {
34 const tv = buildTestVector2(secp256k1q, "sub");
35 await tester(secp256k1q, tv);
36 });
37 it("mnt6753q sub", async () => {
38 const tv = buildTestVector2(mnt6753q, "sub");
39 await tester(mnt6753q, tv);
40 });
41 it("bn128r neg", async () => {
42 const tv = buildTestVector1(bn128r, "neg");
43 await tester(bn128r, tv);
44 });
45 it("secp256k1q neg", async () => {
46 const tv = buildTestVector1(secp256k1q, "neg");
47 await tester(secp256k1q, tv);
48 });
49 it("mnt6753q neg", async () => {
50 const tv = buildTestVector1(mnt6753q, "neg");
51 await tester(mnt6753q, tv);
52 });
53 it("bn128r mul", async () => {
54 const tv = buildTestVector2(bn128r, "mul");
55 await tester(bn128r, tv);
56 });
57 it("secp256k1q mul", async () => {
58 const tv = buildTestVector2(secp256k1q, "mul");
59 await tester(secp256k1q, tv);
60 });
61 it("mnt6753q mul", async () => {
62 const tv = buildTestVector2(mnt6753q, "mul");
63 await tester(mnt6753q, tv);
64 });
65 it("bn128r binary and", async () => {
66 const tv = buildTestVector2(bn128r, "band");
67 await tester(bn128r, tv);
68 });
69 it("secp256k1q binary and", async () => {
70 const tv = buildTestVector2(secp256k1q, "band");
71 await tester(secp256k1q, tv);
72 });
73 it("mnt6753q binary and", async () => {
74 const tv = buildTestVector2(mnt6753q, "band");
75 await tester(mnt6753q, tv);
76 });
77 it("bn128r binary or", async () => {
78 const tv = buildTestVector2(bn128r, "bor");
79 await tester(bn128r, tv);
80 });
81 it("secp256k1q binary or", async () => {
82 const tv = buildTestVector2(secp256k1q, "bor");
83 await tester(secp256k1q, tv);
84 });
85 it("mnt6753q binary or", async () => {
86 const tv = buildTestVector2(mnt6753q, "bor");
87 await tester(mnt6753q, tv);
88 });
89 it("bn128r binary xor", async () => {
90 const tv = buildTestVector2(bn128r, "bxor");
91 await tester(bn128r, tv);
92 });
93 it("secp256k1q binary xor", async () => {
94 const tv = buildTestVector2(secp256k1q, "bxor");
95 await tester(secp256k1q, tv);
96 });
97 it("mnt6753q binary xor", async () => {
98 const tv = buildTestVector2(mnt6753q, "bxor");
99 await tester(mnt6753q, tv);
100 });
101 it("bn128r binary not", async () => {
102 const tv = buildTestVector1(bn128r, "bnot");
103 await tester(bn128r, tv);
104 });
105 it("secp256k1q binary not", async () => {
106 const tv = buildTestVector1(secp256k1q, "bnot");
107 await tester(secp256k1q, tv);
108 });
109 it("mnt6753q binary not", async () => {
110 const tv = buildTestVector1(mnt6753q, "bnot");
111 await tester(mnt6753q, tv);
112 });
113 it("bn128r eq", async () => {
114 const tv = buildTestVector2(bn128r, "eq");
115 await tester(bn128r, tv);
116 });
117 it("secp256k1q eq", async () => {
118 const tv = buildTestVector2(secp256k1q, "eq");
119 await tester(secp256k1q, tv);
120 });
121 it("mnt6753q eq", async () => {
122 const tv = buildTestVector2(mnt6753q, "eq");
123 await tester(mnt6753q, tv);
124 });
125 it("bn128r neq", async () => {
126 const tv = buildTestVector2(bn128r, "neq");
127 await tester(bn128r, tv);
128 });
129 it("secp256k1q neq", async () => {
130 const tv = buildTestVector2(secp256k1q, "neq");
131 await tester(secp256k1q, tv);
132 });
133 it("mnt6753q neq", async () => {
134 const tv = buildTestVector2(mnt6753q, "neq");
135 await tester(mnt6753q, tv);
136 });
137 it("bn128r lt", async () => {
138 const tv = buildTestVector2(bn128r, "lt");
139 await tester(bn128r, tv);
140 });
141 it("secp256k1q lt", async () => {
142 const tv = buildTestVector2(secp256k1q, "lt");
143 await tester(secp256k1q, tv);
144 });
145 it("mnt6753q lt", async () => {
146 const tv = buildTestVector2(mnt6753q, "lt");
147 await tester(mnt6753q, tv);
148 });
149 it("bn128r gt", async () => {
150 const tv = buildTestVector2(bn128r, "gt");
151 await tester(bn128r, tv);
152 });
153 it("secp256k1q gt", async () => {
154 const tv = buildTestVector2(secp256k1q, "gt");
155 await tester(secp256k1q, tv);
156 });
157 it("mnt6753q gt", async () => {
158 const tv = buildTestVector2(mnt6753q, "gt");
159 await tester(mnt6753q, tv);
160 });
161 it("bn128r leq", async () => {
162 const tv = buildTestVector2(bn128r, "leq");
163 await tester(bn128r, tv);
164 });
165 it("secp256k1q leq", async () => {
166 const tv = buildTestVector2(secp256k1q, "leq");
167 await tester(secp256k1q, tv);
168 });
169 it("mnt6753q leq", async () => {
170 const tv = buildTestVector2(mnt6753q, "leq");
171 await tester(mnt6753q, tv);
172 });
173 it("bn128r geq", async () => {
174 const tv = buildTestVector2(bn128r, "geq");
175 await tester(bn128r, tv);
176 });
177 it("secp256k1q geq", async () => {
178 const tv = buildTestVector2(secp256k1q, "geq");
179 await tester(secp256k1q, tv);
180 });
181 it("mnt6753q geq", async () => {
182 const tv = buildTestVector2(mnt6753q, "geq");
183 await tester(mnt6753q, tv);
184 });
185 it("bn128r logical and", async () => {
186 const tv = buildTestVector2(bn128r, "land");
187 await tester(bn128r, tv);
188 });
189 it("secp256k1q logical and", async () => {
190 const tv = buildTestVector2(secp256k1q, "land");
191 await tester(secp256k1q, tv);
192 });
193 it("mnt6753q logical and", async () => {
194 const tv = buildTestVector2(mnt6753q, "land");
195 await tester(mnt6753q, tv);
196 });
197 it("bn128r logical or", async () => {
198 const tv = buildTestVector2(bn128r, "lor");
199 await tester(bn128r, tv);
200 });
201 it("secp256k1q logical or", async () => {
202 const tv = buildTestVector2(secp256k1q, "lor");
203 await tester(secp256k1q, tv);
204 });
205 it("mnt6753q logical or", async () => {
206 const tv = buildTestVector2(mnt6753q, "lor");
207 await tester(mnt6753q, tv);
208 });
209 it("bn128r logical not", async () => {
210 const tv = buildTestVector1(bn128r, "lnot");
211 await tester(bn128r, tv);
212 });
213 it("secp256k1q logical not", async () => {
214 const tv = buildTestVector1(secp256k1q, "lnot");
215 await tester(secp256k1q, tv);
216 });
217 it("mnt6753q logical not", async () => {
218 const tv = buildTestVector1(mnt6753q, "lnot");
219 await tester(mnt6753q, tv);
220 });
221 it("bn128r idiv", async () => {
222 const tv = buildTestVector2(bn128r, "idiv");
223 await tester(bn128r, tv);
224 });
225 it("secp256k1q idiv", async () => {
226 const tv = buildTestVector2(secp256k1q, "idiv");
227 await tester(secp256k1q, tv);
228 });
229 it("mnt6753q idiv", async () => {
230 const tv = buildTestVector2(mnt6753q, "idiv");
231 await tester(mnt6753q, tv);
232 });
233 it("bn128r inv", async () => {
234 const tv = buildTestVector1(bn128r, "inv");
235 await tester(bn128r, tv);
236 });
237 it("secp256k1q inv", async () => {
238 const tv = buildTestVector1(secp256k1q, "inv");
239 await tester(secp256k1q, tv);
240 });
241 it("mnt6753q inv", async () => {
242 const tv = buildTestVector1(mnt6753q, "inv");
243 await tester(mnt6753q, tv);
244 });
245 it("bn128r div", async () => {
246 const tv = buildTestVector2(bn128r, "div");
247 await tester(bn128r, tv);
248 });
249 it("secp256k1q div", async () => {
250 const tv = buildTestVector2(secp256k1q, "div");
251 await tester(secp256k1q, tv);
252 });
253 it("mnt6753q div", async () => {
254 const tv = buildTestVector2(mnt6753q, "div");
255 await tester(mnt6753q, tv);
256 });
257 it("bn128r square", async () => {
258 const tv = buildTestVector1(bn128r, "square");
259 await tester(bn128r, tv);
260 });
261 it("secp256k1q square", async () => {
262 const tv = buildTestVector1(secp256k1q, "square");
263 await tester(secp256k1q, tv);
264 });
265 it("mnt6753q square", async () => {
266 const tv = buildTestVector1(mnt6753q, "square");
267 await tester(mnt6753q, tv);
268 });
269*/
270 it("bn128r shl", async () => {
271 const tv = buildTestVector2(bn128r, "shl");
272 await tester(bn128r, tv);
273 });
274/*
275 it("secp256k1q shl", async () => {
276 const tv = buildTestVector2(secp256k1q, "shl");
277 await tester(secp256k1q, tv);
278 });
279 it("mnt6753q shl", async () => {
280 const tv = buildTestVector2(mnt6753q, "shl");
281 await tester(mnt6753q, tv);
282 });
283*/
284 it("bn128r shr", async () => {
285 const tv = buildTestVector2(bn128r, "shr");
286 await tester(bn128r, tv);
287 });
288/*
289 it("secp256k1q shr", async () => {
290 const tv = buildTestVector2(secp256k1q, "shr");
291 await tester(secp256k1q, tv);
292 });
293 it("mnt6753q shr", async () => {
294 const tv = buildTestVector2(mnt6753q, "shr");
295 await tester(mnt6753q, tv);
296 });
297 it("mnt6753q band", async () => {
298 const tv = buildTestVector2(mnt6753q, "band");
299 await tester(mnt6753q, tv);
300 });
301 it("mnt6753q bor", async () => {
302 const tv = buildTestVector2(mnt6753q, "bor");
303 await tester(mnt6753q, tv);
304 });
305 it("mnt6753q bxor", async () => {
306 const tv = buildTestVector2(mnt6753q, "bxor");
307 await tester(mnt6753q, tv);
308 });
309 it("mnt6753q bnot", async () => {
310 const tv = buildTestVector1(mnt6753q, "bnot");
311 await tester(mnt6753q, tv);
312 });
313*/
314});
315
316function buildTestVector2(p, op) {
317 const F = new ZqField(p);
318 const tv = [];
319 const nums = getCriticalNumbers(p, 2);
320
321 const excludeZero = ["div", "mod", "idiv"].indexOf(op) >= 0;
322
323 for (let i=0; i<nums.length; i++) {
324 for (let j=0; j<nums.length; j++) {
325 if ((excludeZero)&&(nums[j][0].isZero())) continue;
326 tv.push([
327 [nums[i][1], nums[j][1], op],
328 F[op](nums[i][0], nums[j][0])
329 ]);
330 }
331 }
332
333 return tv;
334}
335
336function buildTestVector1(p, op) {
337 const F = new ZqField(p);
338 const tv = [];
339 const nums = getCriticalNumbers(p, 2);
340
341 const excludeZero = ["inv"].indexOf(op) >= 0;
342
343 for (let i=0; i<nums.length; i++) {
344 if ((excludeZero)&&(nums[i][0].isZero())) continue;
345 tv.push([
346 [nums[i][1], op],
347 F[op](nums[i][0])
348 ]);
349 }
350
351 return tv;
352}
353
354function getCriticalNumbers(p, lim) {
355 const numbers = [];
356
357 addFrontier(0);
358 addFrontier(bigInt(32));
359 addFrontier(bigInt(64));
360 addFrontier(bigInt(p.bitLength()));
361 addFrontier(bigInt.one.shiftLeft(31));
362 addFrontier(p.minus(bigInt.one.shiftLeft(31)));
363 addFrontier(bigInt.one.shiftLeft(32));
364 addFrontier(p.minus(bigInt.one.shiftLeft(32)));
365 addFrontier(bigInt.one.shiftLeft(63));
366 addFrontier(p.minus(bigInt.one.shiftLeft(63)));
367 addFrontier(bigInt.one.shiftLeft(64));
368 addFrontier(p.minus(bigInt.one.shiftLeft(64)));
369 addFrontier(bigInt.one.shiftLeft(p.bitLength()-1));
370 addFrontier(p.shiftRight(1));
371
372 function addFrontier(f) {
373 for (let i=-lim; i<=lim; i++) {
374 let n = bigInt(f).add(bigInt(i));
375 n = n.mod(p);
376 if (n.isNegative()) n = p.add(n);
377 addNumber(n);
378 }
379 }
380
381 return numbers;
382
383 function addNumber(n) {
384 if (n.lt(bigInt("80000000", 16)) ) {
385 addShortPositive(n);
386 addShortMontgomeryPositive(n);
387 }
388 if (n.geq(p.minus(bigInt("80000000", 16))) ) {
389 addShortNegative(n);
390 addShortMontgomeryNegative(n);
391 }
392 addLongNormal(n);
393 addLongMontgomery(n);
394
395 function addShortPositive(a) {
396 numbers.push([a, "0x"+a.toString(16)]);
397 }
398
399 function addShortMontgomeryPositive(a) {
400 let S = "0x" + bigInt("40", 16).shiftLeft(56).add(a).toString(16);
401 S = S + "," + getLongString(toMontgomery(a));
402 numbers.push([a, S]);
403 }
404
405 function addShortNegative(a) {
406 const b = bigInt("80000000", 16 ).add(a.minus( p.minus(bigInt("80000000", 16 ))));
407 numbers.push([a, "0x"+b.toString(16)]);
408 }
409
410 function addShortMontgomeryNegative(a) {
411 const b = bigInt("80000000", 16 ).add(a.minus( p.minus(bigInt("80000000", 16 ))));
412 let S = "0x" + bigInt("40", 16).shiftLeft(56).add(b).toString(16);
413 S = S + "," + getLongString(toMontgomery(a));
414 numbers.push([a, S]);
415 }
416
417 function addLongNormal(a) {
418 let S = "0x" + bigInt("80", 16).shiftLeft(56).toString(16);
419 S = S + "," + getLongString(a);
420 numbers.push([a, S]);
421 }
422
423
424 function addLongMontgomery(a) {
425
426 let S = "0x" + bigInt("C0", 16).shiftLeft(56).toString(16);
427 S = S + "," + getLongString(toMontgomery(a));
428 numbers.push([a, S]);
429 }
430
431 function getLongString(a) {
432 if (a.isZero()) {
433 return "0x0";
434 }
435 let r = a;
436 let S = "";
437 while (!r.isZero()) {
438 if (S!= "") S = S+",";
439 S += "0x" + r.and(bigInt("FFFFFFFFFFFFFFFF", 16)).toString(16);
440 r = r.shiftRight(64);
441 }
442 return S;
443 }
444
445 function toMontgomery(a) {
446 const n64 = Math.floor((p.bitLength() - 1) / 64)+1;
447 const R = bigInt.one.shiftLeft(n64*64);
448 return a.times(R).mod(p);
449 }
450
451 }
452}
453