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
83 it("secp256k1q binary or", async () => {
84 const tv = buildTestVector2(secp256k1q, "bor");
85 await tester(secp256k1q, tv);
86 });
87 it("mnt6753q binary or", async () => {
88 const tv = buildTestVector2(mnt6753q, "bor");
89 await tester(mnt6753q, tv);
90 });
91 it("bn128r binary xor", async () => {
92 const tv = buildTestVector2(bn128r, "bxor");
93 await tester(bn128r, tv);
94 });
95 it("secp256k1q binary xor", async () => {
96 const tv = buildTestVector2(secp256k1q, "bxor");
97 await tester(secp256k1q, tv);
98 });
99 it("mnt6753q binary xor", async () => {
100 const tv = buildTestVector2(mnt6753q, "bxor");
101 await tester(mnt6753q, tv);
102 });
103 it("bn128r eq", async () => {
104 const tv = buildTestVector2(bn128r, "eq");
105 await tester(bn128r, tv);
106 });
107 it("secp256k1q eq", async () => {
108 const tv = buildTestVector2(secp256k1q, "eq");
109 await tester(secp256k1q, tv);
110 });
111*/
112 it("mnt6753q eq", async () => {
113 const tv = buildTestVector2(mnt6753q, "eq");
114 await tester(mnt6753q, tv);
115 });
116/*
117 it("bn128r neq", async () => {
118 const tv = buildTestVector2(bn128r, "neq");
119 await tester(bn128r, tv);
120 });
121 it("secp256k1q neq", async () => {
122 const tv = buildTestVector2(secp256k1q, "neq");
123 await tester(secp256k1q, tv);
124 });
125*/
126 it("mnt6753q neq", async () => {
127 const tv = buildTestVector2(mnt6753q, "neq");
128 await tester(mnt6753q, tv);
129 });
130/*
131 it("bn128r lt", async () => {
132 const tv = buildTestVector2(bn128r, "lt");
133 await tester(bn128r, tv);
134 });
135 it("secp256k1q lt", async () => {
136 const tv = buildTestVector2(secp256k1q, "lt");
137 await tester(secp256k1q, tv);
138 });
139*/
140 it("mnt6753q lt", async () => {
141 const tv = buildTestVector2(mnt6753q, "lt");
142 await tester(mnt6753q, tv);
143 });
144/*
145 it("bn128r gt", async () => {
146 const tv = buildTestVector2(bn128r, "gt");
147 await tester(bn128r, tv);
148 });
149 it("secp256k1q gt", async () => {
150 const tv = buildTestVector2(secp256k1q, "gt");
151 await tester(secp256k1q, tv);
152 });
153*/
154 it("mnt6753q gt", async () => {
155 const tv = buildTestVector2(mnt6753q, "gt");
156 await tester(mnt6753q, tv);
157 });
158/*
159 it("bn128r leq", async () => {
160 const tv = buildTestVector2(bn128r, "leq");
161 await tester(bn128r, tv);
162 });
163 it("secp256k1q leq", async () => {
164 const tv = buildTestVector2(secp256k1q, "leq");
165 await tester(secp256k1q, tv);
166 });
167*/
168 it("mnt6753q leq", async () => {
169 const tv = buildTestVector2(mnt6753q, "leq");
170 await tester(mnt6753q, tv);
171 });
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*/
182 it("mnt6753q geq", async () => {
183 const tv = buildTestVector2(mnt6753q, "geq");
184 await tester(mnt6753q, tv);
185 });
186});
187
188function buildTestVector2(p, op) {
189 const F = new ZqField(p);
190 const tv = [];
191 const nums = getCriticalNumbers(p, 2);
192
193 const excludeZero = ["div", "mod"].indexOf(op) >= 0;
194
195 for (let i=0; i<nums.length; i++) {
196 for (let j=0; j<nums.length; j++) {
197 if ((excludeZero)&&(nums[j][0].isZero())) continue;
198 tv.push([
199 [nums[i][1], nums[j][1], op],
200 F[op](nums[i][0], nums[j][0])
201 ]);
202 }
203 }
204
205 return tv;
206}
207
208function buildTestVector1(p, op) {
209 const F = new ZqField(p);
210 const tv = [];
211 const nums = getCriticalNumbers(p, 2);
212
213 const excludeZero = ["inv"].indexOf(op) >= 0;
214
215 for (let i=0; i<nums.length; i++) {
216 if ((excludeZero)&&(nums[i][0].isZero())) continue;
217 tv.push([
218 [nums[i][1], op],
219 F[op](nums[i][0])
220 ]);
221 }
222
223 return tv;
224}
225
226function getCriticalNumbers(p, lim) {
227 const numbers = [];
228
229 addFrontier(0);
230 addFrontier(bigInt.one.shiftLeft(31));
231 addFrontier(p.minus(bigInt.one.shiftLeft(31)));
232 addFrontier(bigInt.one.shiftLeft(32));
233 addFrontier(p.minus(bigInt.one.shiftLeft(32)));
234 addFrontier(bigInt.one.shiftLeft(63));
235 addFrontier(p.minus(bigInt.one.shiftLeft(63)));
236 addFrontier(bigInt.one.shiftLeft(64));
237 addFrontier(p.minus(bigInt.one.shiftLeft(64)));
238 addFrontier(bigInt.one.shiftLeft(p.bitLength()-1));
239 addFrontier(p.shiftRight(1));
240
241 function addFrontier(f) {
242 for (let i=-lim; i<=lim; i++) {
243 let n = bigInt(f).add(bigInt(i));
244 n = n.mod(p);
245 if (n.isNegative()) n = p.add(n);
246 addNumber(n);
247 }
248 }
249
250 return numbers;
251
252 function addNumber(n) {
253 if (n.lt(bigInt("80000000", 16)) ) {
254 addShortPositive(n);
255 addShortMontgomeryPositive(n);
256 }
257 if (n.geq(p.minus(bigInt("80000000", 16))) ) {
258 addShortNegative(n);
259 addShortMontgomeryNegative(n);
260 }
261 addLongNormal(n);
262 addLongMontgomery(n);
263
264 function addShortPositive(a) {
265 numbers.push([a, "0x"+a.toString(16)]);
266 }
267
268 function addShortMontgomeryPositive(a) {
269 let S = "0x" + bigInt("40", 16).shiftLeft(56).add(a).toString(16);
270 S = S + "," + getLongString(toMontgomery(a));
271 numbers.push([a, S]);
272 }
273
274 function addShortNegative(a) {
275 const b = bigInt("80000000", 16 ).add(a.minus( p.minus(bigInt("80000000", 16 ))));
276 numbers.push([a, "0x"+b.toString(16)]);
277 }
278
279 function addShortMontgomeryNegative(a) {
280 const b = bigInt("80000000", 16 ).add(a.minus( p.minus(bigInt("80000000", 16 ))));
281 let S = "0x" + bigInt("40", 16).shiftLeft(56).add(b).toString(16);
282 S = S + "," + getLongString(toMontgomery(a));
283 numbers.push([a, S]);
284 }
285
286 function addLongNormal(a) {
287 let S = "0x" + bigInt("80", 16).shiftLeft(56).toString(16);
288 S = S + "," + getLongString(a);
289 numbers.push([a, S]);
290 }
291
292
293 function addLongMontgomery(a) {
294
295 let S = "0x" + bigInt("C0", 16).shiftLeft(56).toString(16);
296 S = S + "," + getLongString(toMontgomery(a));
297 numbers.push([a, S]);
298 }
299
300 function getLongString(a) {
301 if (a.isZero()) {
302 return "0x0";
303 }
304 let r = a;
305 let S = "";
306 while (!r.isZero()) {
307 if (S!= "") S = S+",";
308 S += "0x" + r.and(bigInt("FFFFFFFFFFFFFFFF", 16)).toString(16);
309 r = r.shiftRight(64);
310 }
311 return S;
312 }
313
314 function toMontgomery(a) {
315 const n64 = Math.floor((p.bitLength() - 1) / 64)+1;
316 const R = bigInt.one.shiftLeft(n64*64);
317 return a.times(R).mod(p);
318 }
319
320 }
321}
322