1
2
3
4
5 package bn256
6
7
8
9
10
11 import (
12 "math/big"
13 )
14
15
16
17 type gfP6 struct {
18 x, y, z *gfP2
19 }
20
21 func newGFp6(pool *bnPool) *gfP6 {
22 return &gfP6{newGFp2(pool), newGFp2(pool), newGFp2(pool)}
23 }
24
25 func (e *gfP6) String() string {
26 return "(" + e.x.String() + "," + e.y.String() + "," + e.z.String() + ")"
27 }
28
29 func (e *gfP6) Put(pool *bnPool) {
30 e.x.Put(pool)
31 e.y.Put(pool)
32 e.z.Put(pool)
33 }
34
35 func (e *gfP6) Set(a *gfP6) *gfP6 {
36 e.x.Set(a.x)
37 e.y.Set(a.y)
38 e.z.Set(a.z)
39 return e
40 }
41
42 func (e *gfP6) SetZero() *gfP6 {
43 e.x.SetZero()
44 e.y.SetZero()
45 e.z.SetZero()
46 return e
47 }
48
49 func (e *gfP6) SetOne() *gfP6 {
50 e.x.SetZero()
51 e.y.SetZero()
52 e.z.SetOne()
53 return e
54 }
55
56 func (e *gfP6) Minimal() {
57 e.x.Minimal()
58 e.y.Minimal()
59 e.z.Minimal()
60 }
61
62 func (e *gfP6) IsZero() bool {
63 return e.x.IsZero() && e.y.IsZero() && e.z.IsZero()
64 }
65
66 func (e *gfP6) IsOne() bool {
67 return e.x.IsZero() && e.y.IsZero() && e.z.IsOne()
68 }
69
70 func (e *gfP6) Negative(a *gfP6) *gfP6 {
71 e.x.Negative(a.x)
72 e.y.Negative(a.y)
73 e.z.Negative(a.z)
74 return e
75 }
76
77 func (e *gfP6) Frobenius(a *gfP6, pool *bnPool) *gfP6 {
78 e.x.Conjugate(a.x)
79 e.y.Conjugate(a.y)
80 e.z.Conjugate(a.z)
81
82 e.x.Mul(e.x, xiTo2PMinus2Over3, pool)
83 e.y.Mul(e.y, xiToPMinus1Over3, pool)
84 return e
85 }
86
87
88 func (e *gfP6) FrobeniusP2(a *gfP6) *gfP6 {
89
90 e.x.MulScalar(a.x, xiTo2PSquaredMinus2Over3)
91
92 e.y.MulScalar(a.y, xiToPSquaredMinus1Over3)
93 e.z.Set(a.z)
94 return e
95 }
96
97 func (e *gfP6) Add(a, b *gfP6) *gfP6 {
98 e.x.Add(a.x, b.x)
99 e.y.Add(a.y, b.y)
100 e.z.Add(a.z, b.z)
101 return e
102 }
103
104 func (e *gfP6) Sub(a, b *gfP6) *gfP6 {
105 e.x.Sub(a.x, b.x)
106 e.y.Sub(a.y, b.y)
107 e.z.Sub(a.z, b.z)
108 return e
109 }
110
111 func (e *gfP6) Double(a *gfP6) *gfP6 {
112 e.x.Double(a.x)
113 e.y.Double(a.y)
114 e.z.Double(a.z)
115 return e
116 }
117
118 func (e *gfP6) Mul(a, b *gfP6, pool *bnPool) *gfP6 {
119
120
121
122
123 v0 := newGFp2(pool)
124 v0.Mul(a.z, b.z, pool)
125 v1 := newGFp2(pool)
126 v1.Mul(a.y, b.y, pool)
127 v2 := newGFp2(pool)
128 v2.Mul(a.x, b.x, pool)
129
130 t0 := newGFp2(pool)
131 t0.Add(a.x, a.y)
132 t1 := newGFp2(pool)
133 t1.Add(b.x, b.y)
134 tz := newGFp2(pool)
135 tz.Mul(t0, t1, pool)
136
137 tz.Sub(tz, v1)
138 tz.Sub(tz, v2)
139 tz.MulXi(tz, pool)
140 tz.Add(tz, v0)
141
142 t0.Add(a.y, a.z)
143 t1.Add(b.y, b.z)
144 ty := newGFp2(pool)
145 ty.Mul(t0, t1, pool)
146 ty.Sub(ty, v0)
147 ty.Sub(ty, v1)
148 t0.MulXi(v2, pool)
149 ty.Add(ty, t0)
150
151 t0.Add(a.x, a.z)
152 t1.Add(b.x, b.z)
153 tx := newGFp2(pool)
154 tx.Mul(t0, t1, pool)
155 tx.Sub(tx, v0)
156 tx.Add(tx, v1)
157 tx.Sub(tx, v2)
158
159 e.x.Set(tx)
160 e.y.Set(ty)
161 e.z.Set(tz)
162
163 t0.Put(pool)
164 t1.Put(pool)
165 tx.Put(pool)
166 ty.Put(pool)
167 tz.Put(pool)
168 v0.Put(pool)
169 v1.Put(pool)
170 v2.Put(pool)
171 return e
172 }
173
174 func (e *gfP6) MulScalar(a *gfP6, b *gfP2, pool *bnPool) *gfP6 {
175 e.x.Mul(a.x, b, pool)
176 e.y.Mul(a.y, b, pool)
177 e.z.Mul(a.z, b, pool)
178 return e
179 }
180
181 func (e *gfP6) MulGFP(a *gfP6, b *big.Int) *gfP6 {
182 e.x.MulScalar(a.x, b)
183 e.y.MulScalar(a.y, b)
184 e.z.MulScalar(a.z, b)
185 return e
186 }
187
188
189 func (e *gfP6) MulTau(a *gfP6, pool *bnPool) {
190 tz := newGFp2(pool)
191 tz.MulXi(a.x, pool)
192 ty := newGFp2(pool)
193 ty.Set(a.y)
194 e.y.Set(a.z)
195 e.x.Set(ty)
196 e.z.Set(tz)
197 tz.Put(pool)
198 ty.Put(pool)
199 }
200
201 func (e *gfP6) Square(a *gfP6, pool *bnPool) *gfP6 {
202 v0 := newGFp2(pool).Square(a.z, pool)
203 v1 := newGFp2(pool).Square(a.y, pool)
204 v2 := newGFp2(pool).Square(a.x, pool)
205
206 c0 := newGFp2(pool).Add(a.x, a.y)
207 c0.Square(c0, pool)
208 c0.Sub(c0, v1)
209 c0.Sub(c0, v2)
210 c0.MulXi(c0, pool)
211 c0.Add(c0, v0)
212
213 c1 := newGFp2(pool).Add(a.y, a.z)
214 c1.Square(c1, pool)
215 c1.Sub(c1, v0)
216 c1.Sub(c1, v1)
217 xiV2 := newGFp2(pool).MulXi(v2, pool)
218 c1.Add(c1, xiV2)
219
220 c2 := newGFp2(pool).Add(a.x, a.z)
221 c2.Square(c2, pool)
222 c2.Sub(c2, v0)
223 c2.Add(c2, v1)
224 c2.Sub(c2, v2)
225
226 e.x.Set(c2)
227 e.y.Set(c1)
228 e.z.Set(c0)
229
230 v0.Put(pool)
231 v1.Put(pool)
232 v2.Put(pool)
233 c0.Put(pool)
234 c1.Put(pool)
235 c2.Put(pool)
236 xiV2.Put(pool)
237
238 return e
239 }
240
241 func (e *gfP6) Invert(a *gfP6, pool *bnPool) *gfP6 {
242
243
244
245
246
247
248
249
250
251
252
253
254
255 t1 := newGFp2(pool)
256
257 A := newGFp2(pool)
258 A.Square(a.z, pool)
259 t1.Mul(a.x, a.y, pool)
260 t1.MulXi(t1, pool)
261 A.Sub(A, t1)
262
263 B := newGFp2(pool)
264 B.Square(a.x, pool)
265 B.MulXi(B, pool)
266 t1.Mul(a.y, a.z, pool)
267 B.Sub(B, t1)
268
269 C := newGFp2(pool)
270 C.Square(a.y, pool)
271 t1.Mul(a.x, a.z, pool)
272 C.Sub(C, t1)
273
274 F := newGFp2(pool)
275 F.Mul(C, a.y, pool)
276 F.MulXi(F, pool)
277 t1.Mul(A, a.z, pool)
278 F.Add(F, t1)
279 t1.Mul(B, a.x, pool)
280 t1.MulXi(t1, pool)
281 F.Add(F, t1)
282
283 F.Invert(F, pool)
284
285 e.x.Mul(C, F, pool)
286 e.y.Mul(B, F, pool)
287 e.z.Mul(A, F, pool)
288
289 t1.Put(pool)
290 A.Put(pool)
291 B.Put(pool)
292 C.Put(pool)
293 F.Put(pool)
294
295 return e
296 }
297
View as plain text