snarkjs/src/f2field.js
src/f2field.jsRaw
1const fUtils = require("./futils.js");
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 _mulByNonResidue(a) {
12 return this.F.mul(this.nonResidue, a);
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 double(a) {
27 return this.add(a,a);
28 }
29
30 sub(a, b) {
31 return [
32 this.F.sub(a[0], b[0]),
33 this.F.sub(a[1], b[1])
34 ];
35 }
36
37 neg(a) {
38 return this.sub(this.zero, a);
39 }
40
41 mul(a, b) {
42 const aA = this.F.mul(a[0] , b[0]);
43 const bB = this.F.mul(a[1] , b[1]);
44
45 return [
46 this.F.add( aA , this._mulByNonResidue(bB)),
47 this.F.sub(
48 this.F.mul(
49 this.F.add(a[0], a[1]),
50 this.F.add(b[0], b[1])),
51 this.F.add(aA, bB))];
52 }
53
54 inverse(a) {
55 const t0 = this.F.square(a[0]);
56 const t1 = this.F.square(a[1]);
57 const t2 = this.F.sub(t0, this._mulByNonResidue(t1));
58 const t3 = this.F.inverse(t2);
59 return [
60 this.F.mul(a[0], t3),
61 this.F.neg(this.F.mul( a[1], t3)) ];
62 }
63
64 div(a, b) {
65 return this.mul(a, this.inverse(b));
66 }
67
68 square(a) {
69 const ab = this.F.mul(a[0] , a[1]);
70
71 /*
72 [
73 (a + b) * (a + non_residue * b) - ab - non_residue * ab,
74 ab + ab
75 ];
76 */
77
78 return [
79 this.F.sub(
80 this.F.mul(
81 this.F.add(a[0], a[1]) ,
82 this.F.add(
83 a[0] ,
84 this._mulByNonResidue(a[1]))),
85 this.F.add(
86 ab,
87 this._mulByNonResidue(ab))),
88 this.F.add(ab, ab)
89 ];
90 }
91
92 isZero(a) {
93 return this.F.isZero(a[0]) && this.F.isZero(a[1]);
94 }
95
96 equals(a, b) {
97 return this.F.equals(a[0], b[0]) && this.F.equals(a[1], b[1]);
98 }
99
100 affine(a) {
101 return [this.F.affine(a[0]), this.F.affine(a[1])];
102 }
103
104 mulEscalar(base, e) {
105 return fUtils.mulEscalar(this, base, e);
106 }
107
108 exp(base, e) {
109 return fUtils.exp(this, base, e);
110 }
111
112 toString(a) {
113 const cp = this.affine(a);
114 return `[ ${this.F.toString(cp[0])} , ${this.F.toString(cp[1])} ]`;
115 }
116}
117
118module.exports = F2Field;