cryptofun/bn128/fq6.go
bn128/fq6.goRaw
1package bn128
2
3import (
4 "math/big"
5)
6
7// Fq6 is Field 6
8type Fq6 struct {
9 F Fq2
10 NonResidue [2]*big.Int
11}
12
13// NewFq6 generates a new Fq6
14func NewFq6(f Fq2, nonResidue [2]*big.Int) Fq6 {
15 fq6 := Fq6{
16 f,
17 nonResidue,
18 }
19 return fq6
20}
21
22// Zero returns a Zero value on the Fq6
23func (fq6 Fq6) Zero() [3][2]*big.Int {
24 return [3][2]*big.Int{fq6.F.Zero(), fq6.F.Zero(), fq6.F.Zero()}
25}
26
27// One returns a One value on the Fq6
28func (fq6 Fq6) One() [3][2]*big.Int {
29 return [3][2]*big.Int{fq6.F.One(), fq6.F.One(), fq6.F.One()}
30}
31
32func (fq6 Fq6) mulByNonResidue(a [2]*big.Int) [2]*big.Int {
33 return fq6.F.Mul(fq6.NonResidue, a)
34}
35
36// Add performs an addition on the Fq6
37func (fq6 Fq6) Add(a, b [3][2]*big.Int) [3][2]*big.Int {
38 return [3][2]*big.Int{
39 fq6.F.Add(a[0], b[0]),
40 fq6.F.Add(a[1], b[1]),
41 fq6.F.Add(a[2], b[2]),
42 }
43}
44
45// Sub performs a substraction on the Fq6
46func (fq6 Fq6) Sub(a, b [3][2]*big.Int) [3][2]*big.Int {
47 return [3][2]*big.Int{
48 fq6.F.Sub(a[0], b[0]),
49 fq6.F.Sub(a[1], b[1]),
50 fq6.F.Sub(a[2], b[2]),
51 }
52}
53
54// Neg performs a negation on the Fq6
55func (fq6 Fq6) Neg(a [3][2]*big.Int) [3][2]*big.Int {
56 return fq6.Sub(fq6.Zero(), a)
57}
58
59// Mul performs a multiplication on the Fq6
60func (fq6 Fq6) Mul(a, b [3][2]*big.Int) [3][2]*big.Int {
61 v0 := fq6.F.Mul(a[0], b[0])
62 v1 := fq6.F.Mul(a[1], b[1])
63 v2 := fq6.F.Mul(a[2], b[2])
64 return [3][2]*big.Int{
65 fq6.F.Add(
66 v0,
67 fq6.mulByNonResidue(
68 fq6.F.Sub(
69 fq6.F.Mul(
70 fq6.F.Add(a[1], a[2]),
71 fq6.F.Add(b[1], b[2])),
72 fq6.F.Add(v1, v2)))),
73
74 fq6.F.Add(
75 fq6.F.Sub(
76 fq6.F.Mul(
77 fq6.F.Add(a[0], a[1]),
78 fq6.F.Add(b[0], b[1])),
79 fq6.F.Add(v0, v1)),
80 fq6.mulByNonResidue(v2)),
81
82 fq6.F.Add(
83 fq6.F.Sub(
84 fq6.F.Mul(
85 fq6.F.Add(a[0], a[2]),
86 fq6.F.Add(b[0], b[2])),
87 fq6.F.Add(v0, v2)),
88 v1),
89 }
90}
91
92// Inverse returns the inverse on the Fq6
93func (fq6 Fq6) Inverse(a [3][2]*big.Int) [3][2]*big.Int {
94 t0 := fq6.F.Square(a[0])
95 t1 := fq6.F.Square(a[1])
96 t2 := fq6.F.Square(a[2])
97 t3 := fq6.F.Mul(a[0], a[1])
98 t4 := fq6.F.Mul(a[0], a[2])
99 t5 := fq6.F.Mul(a[1], a[2])
100
101 c0 := fq6.F.Sub(t0, fq6.mulByNonResidue(t5))
102 c1 := fq6.F.Sub(fq6.mulByNonResidue(t2), t3)
103 c2 := fq6.F.Sub(t1, t4)
104
105 t6 := fq6.F.Inverse(
106 fq6.F.Add(
107 fq6.F.Mul(a[0], c0),
108 fq6.mulByNonResidue(
109 fq6.F.Add(
110 fq6.F.Mul(a[2], c1),
111 fq6.F.Mul(a[1], c2)))))
112 return [3][2]*big.Int{
113 fq6.F.Mul(t6, c0),
114 fq6.F.Mul(t6, c1),
115 fq6.F.Mul(t6, c2),
116 }
117}
118
119// Div performs a division on the Fq6
120func (fq6 Fq6) Div(a, b [3][2]*big.Int) [3][2]*big.Int {
121 return fq6.Mul(a, fq6.Inverse(b))
122}
123
124// Square performs a square operation on the Fq6
125func (fq6 Fq6) Square(a [3][2]*big.Int) [3][2]*big.Int {
126 s0 := fq6.F.Square(a[0])
127 ab := fq6.F.Mul(a[0], a[1])
128 s1 := fq6.F.Add(ab, ab)
129 s2 := fq6.F.Square(
130 fq6.F.Add(
131 fq6.F.Sub(a[0], a[1]),
132 a[2]))
133 bc := fq6.F.Mul(a[1], a[2])
134 s3 := fq6.F.Add(bc, bc)
135 s4 := fq6.F.Square(a[2])
136
137 return [3][2]*big.Int{
138 fq6.F.Add(
139 s0,
140 fq6.mulByNonResidue(s3)),
141 fq6.F.Add(
142 s1,
143 fq6.mulByNonResidue(s4)),
144 fq6.F.Sub(
145 fq6.F.Add(
146 fq6.F.Add(s1, s2),
147 s3),
148 fq6.F.Add(s0, s4)),
149 }
150}