cryptofun/bn128/fq2.go
bn128/fq2.goRaw
1package bn128
2
3import (
4 "bytes"
5 "math/big"
6)
7
8// Fq2 is Field 2
9type Fq2 struct {
10 F Fq
11 NonResidue *big.Int
12}
13
14// NewFq2 generates a new Fq2
15func NewFq2(f Fq, nonResidue *big.Int) Fq2 {
16 fq2 := Fq2{
17 f,
18 nonResidue,
19 }
20 return fq2
21}
22
23// Zero returns a Zero value on the Fq2
24func (fq2 Fq2) Zero() [2]*big.Int {
25 return [2]*big.Int{fq2.F.Zero(), fq2.F.Zero()}
26}
27
28// One returns a One value on the Fq2
29func (fq2 Fq2) One() [2]*big.Int {
30 return [2]*big.Int{fq2.F.One(), fq2.F.One()}
31}
32
33func (fq2 Fq2) mulByNonResidue(a *big.Int) *big.Int {
34 return fq2.F.Mul(fq2.NonResidue, a)
35}
36
37// Add performs an addition on the Fq2
38func (fq2 Fq2) Add(a, b [2]*big.Int) [2]*big.Int {
39 return [2]*big.Int{
40 fq2.F.Add(a[0], b[0]),
41 fq2.F.Add(a[1], b[1]),
42 }
43}
44
45// Double performs a doubling on the Fq2
46func (fq2 Fq2) Double(a [2]*big.Int) [2]*big.Int {
47 return fq2.Add(a, a)
48}
49
50// Sub performs a substraction on the Fq2
51func (fq2 Fq2) Sub(a, b [2]*big.Int) [2]*big.Int {
52 return [2]*big.Int{
53 fq2.F.Sub(a[0], b[0]),
54 fq2.F.Sub(a[1], b[1]),
55 }
56}
57
58// Neg performs a negation on the Fq2
59func (fq2 Fq2) Neg(a [2]*big.Int) [2]*big.Int {
60 return fq2.Sub(fq2.Zero(), a)
61}
62
63// Mul performs a multiplication on the Fq2
64func (fq2 Fq2) Mul(a, b [2]*big.Int) [2]*big.Int {
65 // Multiplication and Squaring on Pairing-Friendly.pdf; Section 3 (Karatsuba)
66 v0 := fq2.F.Mul(a[0], b[0])
67 v1 := fq2.F.Mul(a[1], b[1])
68 return [2]*big.Int{
69 fq2.F.Add(v0, fq2.mulByNonResidue(v1)),
70 fq2.F.Sub(
71 fq2.F.Mul(
72 fq2.F.Add(a[0], a[1]),
73 fq2.F.Add(b[0], b[1])),
74 fq2.F.Add(v0, v1)),
75 }
76}
77func (fq2 Fq2) MulScalar(base [2]*big.Int, e *big.Int) [2]*big.Int {
78 res := fq2.Zero()
79 rem := e
80 exp := base
81
82 for !bytes.Equal(rem.Bytes(), big.NewInt(int64(0)).Bytes()) {
83 // if rem % 2 == 1
84 if bytes.Equal(new(big.Int).Rem(rem, big.NewInt(int64(2))).Bytes(), big.NewInt(int64(1)).Bytes()) {
85 res = fq2.Add(res, exp)
86 }
87 exp = fq2.Double(exp)
88 rem = rem.Rsh(rem, 1) // rem = rem >> 1
89 }
90 return res
91}
92
93// Inverse returns the inverse on the Fq2
94func (fq2 Fq2) Inverse(a [2]*big.Int) [2]*big.Int {
95 t0 := fq2.F.Square(a[0])
96 t1 := fq2.F.Square(a[1])
97 t2 := fq2.F.Sub(t0, fq2.mulByNonResidue(t1))
98 t3 := fq2.F.Inverse(t2)
99 return [2]*big.Int{
100 fq2.F.Mul(a[0], t3),
101 fq2.F.Neg(fq2.F.Mul(a[1], t3)),
102 }
103}
104
105// Div performs a division on the Fq2
106func (fq2 Fq2) Div(a, b [2]*big.Int) [2]*big.Int {
107 return fq2.Mul(a, fq2.Inverse(b))
108}
109
110// Square performs a square operation on the Fq2
111func (fq2 Fq2) Square(a [2]*big.Int) [2]*big.Int {
112 ab := fq2.F.Mul(a[0], a[1])
113
114 return [2]*big.Int{
115 fq2.F.Sub(
116 fq2.F.Mul(
117 fq2.F.Add(a[0], a[1]),
118 fq2.F.Add(
119 a[0],
120 fq2.mulByNonResidue(a[1]))),
121 fq2.F.Add(
122 ab,
123 fq2.mulByNonResidue(ab))),
124 fq2.F.Add(ab, ab),
125 }
126}
127
128func (fq2 Fq2) IsZero(a [2]*big.Int) bool {
129 return fq2.F.IsZero(a[0]) && fq2.F.IsZero(a[1])
130}
131
132func (fq2 Fq2) Affine(a [2]*big.Int) [2]*big.Int {
133 return [2]*big.Int{
134 fq2.F.Affine(a[0]),
135 fq2.F.Affine(a[1]),
136 }
137}
138func (fq2 Fq2) Equal(a, b [2]*big.Int) bool {
139 return fq2.F.Equal(a[0], b[0]) && fq2.F.Equal(a[1], b[1])
140}