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/*
 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