snarkjs/src/f2field.js
src/f2field.jsRaw
1const bigInt = require("big-integer");
2
3class F2Field {
4 constructor(F, nonResidue) {
5 this.F = F;
6 this.zero = [this.F.zero, this.F.zero];
7 this.one = [this.F.one, this.F.zero];
8 this.nonResidue = nonResidue;
9 }
10
11 e(c0, c1) {
12 return [bigInt(c0), bigInt(c1)];
13 }
14
15 copy(a) {
16 return [this.F.copy(a[0]), this.F.copy(a[1])];
17 }
18
19 add(a, b) {
20 return [
21 this.F.add(a[0], b[0]),
22 this.F.add(a[1], b[1])
23 ];
24 }
25
26 sub(a, b) {
27 return [
28 this.F.sub(a[0], b[0]),
29 this.F.sub(a[1], b[1])
30 ];
31 }
32
33 neg(a) {
34 return this.sub(this.zero, a);
35 }
36
37 mul(a, b) {
38 const aA = this.F.mul(a[0] , b[0]);
39 const bB = this.F.mul(a[1] , b[1]);
40
41 return [
42 this.F.add( aA , this.F.mul(this.nonResidue , bB)),
43 this.F.sub(
44 this.F.mul(
45 this.F.add(a[0], a[1]),
46 this.F.add(b[0], b[1])),
47 this.F.add(aA, bB))];
48 }
49
50 inverse(a) {
51 const t0 = this.F.square(a[0]);
52 const t1 = this.F.square(a[1]);
53 const t2 = this.F.sub(t0, this.F.mul(this.nonResidue, t1));
54 const t3 = this.F.inverse(t2);
55 return [
56 this.F.mul(a[0], t3),
57 this.F.neg(this.F.mul( a[1], t3)) ];
58 }
59
60 div(a, b) {
61 return this.mul(a, this.inverse(b));
62 }
63
64 square(a) {
65 const ab = this.F.mul(a[0] , a[1]);
66
67 /*
68 [
69 (a + b) * (a + non_residue * b) - ab - non_residue * ab,
70 ab + ab
71 ];
72 */
73
74 return [
75 this.F.sub(
76 this.F.mul(
77 this.F.add(a[0], a[1]) ,
78 this.F.add(
79 a[0] ,
80 this.F.mul(this.nonResidue , a[1]))),
81 this.F.add(
82 ab,
83 this.F.mul(this.nonResidue, ab))),
84 this.F.add(ab, ab)
85 ];
86 }
87
88 isZero(a) {
89 return this.F.isZero(a[0]) && this.F.isZero(a[1]);
90 }
91
92 equals(a, b) {
93 return this.F.equals(a[0], b[0]) && this.F.equals(a[1], b[1]);
94 }
95
96 affine(a) {
97 return [this.F.affine(a[0]), this.F.affine(a[1])];
98 }
99
100 toString(a) {
101 const cp = this.affine(a);
102 return `[ ${this.F.toString(cp[0])} , ${this.F.toString(cp[1])} ]`;
103 }
104}
105
106module.exports = F2Field;