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