cryptofun/bn128/fq12.go
bn128/fq12.goRaw
1package bn128
2
3import (
4 "math/big"
5)
6
7// Fq12 uses the same algorithms than Fq2, but with [2][3][2]*big.Int data structure
8
9// Fq12 is Field 12
10type Fq12 struct {
11 F Fq6
12 Fq2 Fq2
13 NonResidue [2]*big.Int
14}
15
16// NewFq12 generates a new Fq12
17func NewFq12(f Fq6, fq2 Fq2, nonResidue [2]*big.Int) Fq12 {
18 fq12 := Fq12{
19 f,
20 fq2,
21 nonResidue,
22 }
23 return fq12
24}
25
26// Zero returns a Zero value on the Fq12
27func (fq12 Fq12) Zero() [2][3][2]*big.Int {
28 return [2][3][2]*big.Int{fq12.F.Zero(), fq12.F.Zero()}
29}
30
31// One returns a One value on the Fq12
32func (fq12 Fq12) One() [2][3][2]*big.Int {
33 return [2][3][2]*big.Int{fq12.F.One(), fq12.F.One()}
34}
35
36func (fq12 Fq12) mulByNonResidue(a [3][2]*big.Int) [3][2]*big.Int {
37 return [3][2]*big.Int{
38 fq12.Fq2.Mul(fq12.NonResidue, a[2]),
39 a[0],
40 a[1],
41 }
42}
43
44// Add performs an addition on the Fq12
45func (fq12 Fq12) Add(a, b [2][3][2]*big.Int) [2][3][2]*big.Int {
46 return [2][3][2]*big.Int{
47 fq12.F.Add(a[0], b[0]),
48 fq12.F.Add(a[1], b[1]),
49 }
50}
51
52// Double performs a doubling on the Fq12
53func (fq12 Fq12) Double(a [2][3][2]*big.Int) [2][3][2]*big.Int {
54 return fq12.Add(a, a)
55}
56
57// Sub performs a substraction on the Fq12
58func (fq12 Fq12) Sub(a, b [2][3][2]*big.Int) [2][3][2]*big.Int {
59 return [2][3][2]*big.Int{
60 fq12.F.Sub(a[0], b[0]),
61 fq12.F.Sub(a[1], b[1]),
62 }
63}
64
65// Neg performs a negation on the Fq12
66func (fq12 Fq12) Neg(a [2][3][2]*big.Int) [2][3][2]*big.Int {
67 return fq12.Sub(fq12.Zero(), a)
68}
69
70// Mul performs a multiplication on the Fq12
71func (fq12 Fq12) Mul(a, b [2][3][2]*big.Int) [2][3][2]*big.Int {
72 // Multiplication and Squaring on Pairing-Friendly [2]*big.Ints.pdf; Section 3 (Karatsuba)
73 v0 := fq12.F.Mul(a[0], b[0])
74 v1 := fq12.F.Mul(a[1], b[1])
75 return [2][3][2]*big.Int{
76 fq12.F.Add(v0, fq12.mulByNonResidue(v1)),
77 fq12.F.Sub(
78 fq12.F.Mul(
79 fq12.F.Add(a[0], a[1]),
80 fq12.F.Add(b[0], b[1])),
81 fq12.F.Add(v0, v1)),
82 }
83}
84
85// Inverse returns the inverse on the Fq12
86func (fq12 Fq12) Inverse(a [2][3][2]*big.Int) [2][3][2]*big.Int {
87 t0 := fq12.F.Square(a[0])
88 t1 := fq12.F.Square(a[1])
89 t2 := fq12.F.Sub(t0, fq12.mulByNonResidue(t1))
90 t3 := fq12.F.Inverse(t2)
91 return [2][3][2]*big.Int{
92 fq12.F.Mul(a[0], t3),
93 fq12.F.Neg(fq12.F.Mul(a[1], t3)),
94 }
95}
96
97// Div performs a division on the Fq12
98func (fq12 Fq12) Div(a, b [2][3][2]*big.Int) [2][3][2]*big.Int {
99 return fq12.Mul(a, fq12.Inverse(b))
100}
101
102// Square performs a square operation on the Fq12
103func (fq12 Fq12) Square(a [2][3][2]*big.Int) [2][3][2]*big.Int {
104 ab := fq12.F.Mul(a[0], a[1])
105
106 return [2][3][2]*big.Int{
107 fq12.F.Sub(
108 fq12.F.Mul(
109 fq12.F.Add(a[0], a[1]),
110 fq12.F.Add(
111 a[0],
112 fq12.mulByNonResidue(a[1]))),
113 fq12.F.Add(
114 ab,
115 fq12.mulByNonResidue(ab))),
116 fq12.F.Add(ab, ab),
117 }
118}