1 package ff
2
3 import "fmt"
4
5
6 const Fp6Size = 3 * Fp2Size
7
8 type Fp6 [3]Fp2
9
10 func (z Fp6) String() string { return fmt.Sprintf("\n0: %v\n1: %v\n2: %v", z[0], z[1], z[2]) }
11 func (z *Fp6) SetOne() { z[0].SetOne(); z[1] = Fp2{}; z[2] = Fp2{} }
12 func (z Fp6) IsZero() int { return z.IsEqual(&Fp6{}) }
13 func (z Fp6) IsEqual(x *Fp6) int {
14 return z[0].IsEqual(&x[0]) & z[1].IsEqual(&x[1]) & z[2].IsEqual(&x[2])
15 }
16 func (z *Fp6) Neg() { z[0].Neg(); z[1].Neg(); z[2].Neg() }
17 func (z *Fp6) Add(x, y *Fp6) { z[0].Add(&x[0], &y[0]); z[1].Add(&x[1], &y[1]); z[2].Add(&x[2], &y[2]) }
18 func (z *Fp6) Sub(x, y *Fp6) { z[0].Sub(&x[0], &y[0]); z[1].Sub(&x[1], &y[1]); z[2].Sub(&x[2], &y[2]) }
19 func (z *Fp6) MulBeta() {
20 t := z[2]
21 t.MulBeta()
22 z[2] = z[1]
23 z[1] = z[0]
24 z[0] = t
25 }
26
27 func (z *Fp6) Mul(x, y *Fp6) {
28
29
30
31
32
33
34
35
36
37
38
39
40
41 aL, aM, aH := &x[0], &x[1], &x[2]
42 bL, bM, bH := &y[0], &y[1], &y[2]
43 aLM, aLH, aMH := &Fp2{}, &Fp2{}, &Fp2{}
44 bLM, bLH, bMH := &Fp2{}, &Fp2{}, &Fp2{}
45 aLM.Add(aL, aM)
46 aLH.Add(aL, aH)
47 aMH.Add(aM, aH)
48 bLM.Add(bL, bM)
49 bLH.Add(bL, bH)
50 bMH.Add(bM, bH)
51
52 c0, c1, c2 := &Fp2{}, &Fp2{}, &Fp2{}
53 c5, c3, c4 := &z[0], &z[1], &z[2]
54 c0.Mul(aL, bL)
55 c1.Mul(aM, bM)
56 c2.Mul(aH, bH)
57 c3.Mul(aLM, bLM)
58 c4.Mul(aLH, bLH)
59 c5.Mul(aMH, bMH)
60
61 z[2].Add(c4, c1)
62 z[2].Sub(&z[2], c0)
63 z[2].Sub(&z[2], c2)
64 c2.MulBeta()
65 c2.Sub(c2, c0)
66 z[1].Sub(c3, c1)
67 z[1].Add(&z[1], c2)
68 z[0].Sub(c5, c1)
69 z[0].MulBeta()
70 z[0].Sub(&z[0], c2)
71 }
72
73 func (z *Fp6) Sqr(x *Fp6) {
74
75
76
77
78
79 aL, aM, aH := &x[0], &x[1], &x[2]
80 c0, c2, c4 := &z[0], &z[1], &z[2]
81 c3, c5, tt := &Fp2{}, &Fp2{}, &Fp2{}
82 tt.Add(aL, aH)
83 tt.Sub(tt, aM)
84
85 c3.Mul(aL, aM)
86 c5.Mul(aM, aH)
87 c0.Sqr(aL)
88 c2.Sqr(aH)
89 c4.Sqr(tt)
90
91 c5.Add(c5, c5)
92 c3.Add(c3, c3)
93 tt.Add(c3, c5)
94 z[2].Add(tt, c4)
95 z[2].Sub(&z[2], c0)
96 z[2].Sub(&z[2], c2)
97 c5.MulBeta()
98 z[0].Add(c5, c0)
99 c2.MulBeta()
100 z[1].Add(c2, c3)
101 }
102
103 func (z *Fp6) Inv(x *Fp6) {
104 aL, aM, aH := &x[0], &x[1], &x[2]
105 c0, c1, c2 := &Fp2{}, &Fp2{}, &Fp2{}
106 t0, t1, t2 := &Fp2{}, &Fp2{}, &Fp2{}
107 c0.Sqr(aL)
108 c1.Sqr(aH)
109 c2.Sqr(aM)
110 t0.Mul(aM, aH)
111 t1.Mul(aL, aM)
112 t2.Mul(aL, aH)
113 t0.MulBeta()
114 c0.Sub(c0, t0)
115 c1.MulBeta()
116 c1.Sub(c1, t1)
117 c2.Sub(c2, t2)
118
119 t0.Mul(aM, c2)
120 t1.Mul(aH, c1)
121 t2.Mul(aL, c0)
122 t0.Add(t0, t1)
123 t0.MulBeta()
124 t0.Add(t0, t2)
125 t0.Inv(t0)
126 z[0].Mul(c0, t0)
127 z[1].Mul(c1, t0)
128 z[2].Mul(c2, t0)
129 }
130
131 func (z *Fp6) Frob(x *Fp6) {
132 z[0].Frob(&x[0])
133 z[1].Frob(&x[1])
134 z[2].Frob(&x[2])
135 z[1].Mul(&z[1], &Fp2{Fp{}, frob6V1})
136 z[2].Mul(&z[2], &Fp2{frob6V2, Fp{}})
137 }
138
139 func (z *Fp6) CMov(x, y *Fp6, b int) {
140 z[0].CMov(&x[0], &y[0], b)
141 z[1].CMov(&x[1], &y[1], b)
142 z[2].CMov(&x[2], &y[2], b)
143 }
144
145 func (z Fp6) MarshalBinary() (b []byte, e error) {
146 var b0, b1, b2 []byte
147 if b2, e = z[2].MarshalBinary(); e == nil {
148 if b1, e = z[1].MarshalBinary(); e == nil {
149 if b0, e = z[0].MarshalBinary(); e == nil {
150 return append(append(b2, b1...), b0...), e
151 }
152 }
153 }
154 return
155 }
156
157 func (z *Fp6) UnmarshalBinary(b []byte) error {
158 if len(b) < Fp6Size {
159 return errInputLength
160 }
161 return errFirst(
162 z[2].UnmarshalBinary(b[0*Fp2Size:1*Fp2Size]),
163 z[1].UnmarshalBinary(b[1*Fp2Size:2*Fp2Size]),
164 z[0].UnmarshalBinary(b[2*Fp2Size:3*Fp2Size]),
165 )
166 }
167
168 var (
169
170
171 frob6V1 = Fp{fpMont{
172 0xcd03c9e48671f071, 0x5dab22461fcda5d2, 0x587042afd3851b95,
173 0x8eb60ebe01bacb9e, 0x03f97d6e83d050d2, 0x18f0206554638741,
174 }}
175
176
177
178 frob6V2 = Fp{fpMont{
179 0x890dc9e4867545c3, 0x2af322533285a5d5, 0x50880866309b7e2c,
180 0xa20d1b8c7e881024, 0x14e4f04fe2db9068, 0x14e56d3f1564853a,
181 }}
182 )
183
View as plain text