arnaucube
arnaucube/circomPublic Self-hosted repository
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    it("bn128r add", async () => {
 17        const tv = buildTestVector2(bn128r, "add");
 18        await tester(bn128r, tv);
 19    });
 20    it("secp256k1q add", async () => {
 21        const tv = buildTestVector2(secp256k1q, "add");
 22        await tester(secp256k1q, tv);
 23    });
 24    it("mnt6753q add", async () => {
 25        const tv = buildTestVector2(mnt6753q, "add");
 26        await tester(mnt6753q, tv);
 27    });
 28    it("bn128r sub", async () => {
 29        const tv = buildTestVector2(bn128r, "sub");
 30        await tester(bn128r, tv);
 31    });
 32    it("secp256k1q sub", async () => {
 33        const tv = buildTestVector2(secp256k1q, "sub");
 34        await tester(secp256k1q, tv);
 35    });
 36    it("mnt6753q sub", async () => {
 37        const tv = buildTestVector2(mnt6753q, "sub");
 38        await tester(mnt6753q, tv);
 39    });
 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});
271
272function buildTestVector2(p, op) {
273    const F = new ZqField(p);
274    const tv = [];
275    const nums = getCriticalNumbers(p, 2);
276
277    const excludeZero = ["div", "mod", "idiv"].indexOf(op) >= 0;
278
279    for (let i=0; i<nums.length; i++) {
280        for (let j=0; j<nums.length; j++) {
281            if ((excludeZero)&&(nums[j][0].isZero())) continue;
282            tv.push([
283                [nums[i][1], nums[j][1], op],
284                F[op](nums[i][0], nums[j][0])
285            ]);
286        }
287    }
288
289    return tv;
290}
291
292function buildTestVector1(p, op) {
293    const F = new ZqField(p);
294    const tv = [];
295    const nums = getCriticalNumbers(p, 2);
296
297    const excludeZero = ["inv"].indexOf(op) >= 0;
298
299    for (let i=0; i<nums.length; i++) {
300        if ((excludeZero)&&(nums[i][0].isZero())) continue;
301        tv.push([
302            [nums[i][1], op],
303            F[op](nums[i][0])
304        ]);
305    }
306
307    return tv;
308}
309
310function getCriticalNumbers(p, lim) {
311    const numbers = [];
312
313    addFrontier(0);
314    addFrontier(bigInt.one.shiftLeft(31));
315    addFrontier(p.minus(bigInt.one.shiftLeft(31)));
316    addFrontier(bigInt.one.shiftLeft(32));
317    addFrontier(p.minus(bigInt.one.shiftLeft(32)));
318    addFrontier(bigInt.one.shiftLeft(63));
319    addFrontier(p.minus(bigInt.one.shiftLeft(63)));
320    addFrontier(bigInt.one.shiftLeft(64));
321    addFrontier(p.minus(bigInt.one.shiftLeft(64)));
322    addFrontier(bigInt.one.shiftLeft(p.bitLength()-1));
323    addFrontier(p.shiftRight(1));
324
325    function addFrontier(f) {
326        for (let i=-lim; i<=lim; i++) {
327            let n = bigInt(f).add(bigInt(i));
328            n = n.mod(p);
329            if (n.isNegative()) n = p.add(n);
330            addNumber(n);
331        }
332    }
333
334    return numbers;
335
336    function addNumber(n) {
337        if (n.lt(bigInt("80000000", 16)) ) {
338            addShortPositive(n);
339            addShortMontgomeryPositive(n);
340        }
341        if (n.geq(p.minus(bigInt("80000000", 16))) ) {
342            addShortNegative(n);
343            addShortMontgomeryNegative(n);
344        }
345        addLongNormal(n);
346        addLongMontgomery(n);
347
348        function addShortPositive(a) {
349            numbers.push([a, "0x"+a.toString(16)]);
350        }
351
352        function addShortMontgomeryPositive(a) {
353            let S = "0x" + bigInt("40", 16).shiftLeft(56).add(a).toString(16);
354            S = S + "," + getLongString(toMontgomery(a));
355            numbers.push([a, S]);
356        }
357
358        function addShortNegative(a) {
359            const b = bigInt("80000000", 16 ).add(a.minus(  p.minus(bigInt("80000000", 16 ))));
360            numbers.push([a, "0x"+b.toString(16)]);
361        }
362
363        function addShortMontgomeryNegative(a) {
364            const b = bigInt("80000000", 16 ).add(a.minus(  p.minus(bigInt("80000000", 16 ))));
365            let S = "0x" + bigInt("40", 16).shiftLeft(56).add(b).toString(16);
366            S = S + "," + getLongString(toMontgomery(a));
367            numbers.push([a, S]);
368        }
369
370        function addLongNormal(a) {
371            let S = "0x" + bigInt("80", 16).shiftLeft(56).toString(16);
372            S = S + "," + getLongString(a);
373            numbers.push([a, S]);
374        }
375
376
377        function addLongMontgomery(a) {
378
379            let S = "0x" + bigInt("C0", 16).shiftLeft(56).toString(16);
380            S = S + "," + getLongString(toMontgomery(a));
381            numbers.push([a, S]);
382        }
383
384        function getLongString(a) {
385            if (a.isZero()) {
386                return "0x0";
387            }
388            let r = a;
389            let S = "";
390            while (!r.isZero()) {
391                if (S!= "") S = S+",";
392                S += "0x" + r.and(bigInt("FFFFFFFFFFFFFFFF", 16)).toString(16);
393                r = r.shiftRight(64);
394            }
395            return S;
396        }
397
398        function toMontgomery(a) {
399            const n64 = Math.floor((p.bitLength() - 1) / 64)+1;
400            const R = bigInt.one.shiftLeft(n64*64);
401            return a.times(R).mod(p);
402        }
403
404    }
405}
406