Skip to content

Commit 48d9efc

Browse files
authored
Merge pull request #83 from ConsenSys/experiment/BLS24
[BLS24] Fp24 tower
2 parents f861edf + 9b1873b commit 48d9efc

File tree

19 files changed

+899
-827
lines changed

19 files changed

+899
-827
lines changed

ecc/bls24-315/bls24-315.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,10 @@ type E2 = fptower.E2
7979
// E4 is a degree two finite field extension of fp2
8080
type E4 = fptower.E4
8181

82-
// E8 is a degree two finite field extension of fp4
83-
type E8 = fptower.E8
82+
// E12 is a degree three finite field extension of fp4
83+
type E12 = fptower.E12
8484

85-
// E24 is a degree three finite field extension of fp8
85+
// E24 is a degree two finite field extension of fp6
8686
type E24 = fptower.E24
8787

8888
func init() {
Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
// Copyright 2020 ConsenSys Software Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package fptower
16+
17+
import (
18+
"math/big"
19+
)
20+
21+
// E12 is a degree three finite field extension of fp4
22+
type E12 struct {
23+
C0, C1, C2 E4
24+
}
25+
26+
// Equal returns true if z equals x, fasle otherwise
27+
func (z *E12) Equal(x *E12) bool {
28+
return z.C0.Equal(&x.C0) && z.C1.Equal(&x.C1) && z.C2.Equal(&x.C2)
29+
}
30+
31+
// String puts E12 elmt in string form
32+
func (z *E12) String() string {
33+
return (z.C0.String() + "+(" + z.C1.String() + ")*w+(" + z.C2.String() + ")*w**2")
34+
}
35+
36+
// SetString sets a E12 elmt from stringf
37+
func (z *E12) SetString(s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11 string) *E12 {
38+
z.C0.SetString(s0, s1, s2, s3)
39+
z.C1.SetString(s4, s5, s6, s7)
40+
z.C2.SetString(s8, s9, s10, s11)
41+
return z
42+
}
43+
44+
// Set Sets a E12 elmt form another E12 elmt
45+
func (z *E12) Set(x *E12) *E12 {
46+
z.C0 = x.C0
47+
z.C1 = x.C1
48+
z.C2 = x.C2
49+
return z
50+
}
51+
52+
// SetOne sets z to 1 in Montgomery form and returns z
53+
func (z *E12) SetOne() *E12 {
54+
*z = E12{}
55+
z.C0.B0.A0.SetOne()
56+
return z
57+
}
58+
59+
// SetRandom set z to a random elmt
60+
func (z *E12) SetRandom() (*E12, error) {
61+
if _, err := z.C0.SetRandom(); err != nil {
62+
return nil, err
63+
}
64+
if _, err := z.C1.SetRandom(); err != nil {
65+
return nil, err
66+
}
67+
if _, err := z.C2.SetRandom(); err != nil {
68+
return nil, err
69+
}
70+
return z, nil
71+
}
72+
73+
// ToMont converts to Mont form
74+
func (z *E12) ToMont() *E12 {
75+
z.C0.ToMont()
76+
z.C1.ToMont()
77+
z.C2.ToMont()
78+
return z
79+
}
80+
81+
// FromMont converts from Mont form
82+
func (z *E12) FromMont() *E12 {
83+
z.C0.FromMont()
84+
z.C1.FromMont()
85+
z.C2.FromMont()
86+
return z
87+
}
88+
89+
// Add adds two elements of E12
90+
func (z *E12) Add(x, y *E12) *E12 {
91+
z.C0.Add(&x.C0, &y.C0)
92+
z.C1.Add(&x.C1, &y.C1)
93+
z.C2.Add(&x.C2, &y.C2)
94+
return z
95+
}
96+
97+
// Neg negates the E12 number
98+
func (z *E12) Neg(x *E12) *E12 {
99+
z.C0.Neg(&x.C0)
100+
z.C1.Neg(&x.C1)
101+
z.C2.Neg(&x.C2)
102+
return z
103+
}
104+
105+
// Sub two elements of E12
106+
func (z *E12) Sub(x, y *E12) *E12 {
107+
z.C0.Sub(&x.C0, &y.C0)
108+
z.C1.Sub(&x.C1, &y.C1)
109+
z.C2.Sub(&x.C2, &y.C2)
110+
return z
111+
}
112+
113+
// Double doubles an element in E12
114+
func (z *E12) Double(x *E12) *E12 {
115+
z.C0.Double(&x.C0)
116+
z.C1.Double(&x.C1)
117+
z.C2.Double(&x.C2)
118+
return z
119+
}
120+
121+
// MulByNonResidue mul x by (0,1,0)
122+
func (z *E12) MulByNonResidue(x *E12) *E12 {
123+
z.C2, z.C1, z.C0 = x.C1, x.C0, x.C2
124+
z.C0.MulByNonResidue(&z.C0)
125+
return z
126+
}
127+
128+
// Mul sets z to the E12 product of x,y, returns z
129+
func (z *E12) Mul(x, y *E12) *E12 {
130+
// Algorithm 13 from https://eprint.iacr.org/2010/354.pdf
131+
var t0, t1, t2, c0, c1, c2, tmp E4
132+
t0.Mul(&x.C0, &y.C0)
133+
t1.Mul(&x.C1, &y.C1)
134+
t2.Mul(&x.C2, &y.C2)
135+
136+
c0.Add(&x.C1, &x.C2)
137+
tmp.Add(&y.C1, &y.C2)
138+
c0.Mul(&c0, &tmp).Sub(&c0, &t1).Sub(&c0, &t2).MulByNonResidue(&c0).Add(&c0, &t0)
139+
140+
c1.Add(&x.C0, &x.C1)
141+
tmp.Add(&y.C0, &y.C1)
142+
c1.Mul(&c1, &tmp).Sub(&c1, &t0).Sub(&c1, &t1)
143+
tmp.MulByNonResidue(&t2)
144+
c1.Add(&c1, &tmp)
145+
146+
tmp.Add(&x.C0, &x.C2)
147+
c2.Add(&y.C0, &y.C2).Mul(&c2, &tmp).Sub(&c2, &t0).Sub(&c2, &t2).Add(&c2, &t1)
148+
149+
z.C0.Set(&c0)
150+
z.C1.Set(&c1)
151+
z.C2.Set(&c2)
152+
153+
return z
154+
}
155+
156+
// Square sets z to the E12 product of x,x, returns z
157+
func (z *E12) Square(x *E12) *E12 {
158+
159+
// Algorithm 16 from https://eprint.iacr.org/2010/354.pdf
160+
var c4, c5, c1, c2, c3, c0 E4
161+
c4.Mul(&x.C0, &x.C1).Double(&c4)
162+
c5.Square(&x.C2)
163+
c1.MulByNonResidue(&c5).Add(&c1, &c4)
164+
c2.Sub(&c4, &c5)
165+
c3.Square(&x.C0)
166+
c4.Sub(&x.C0, &x.C1).Add(&c4, &x.C2)
167+
c5.Mul(&x.C1, &x.C2).Double(&c5)
168+
c4.Square(&c4)
169+
c0.MulByNonResidue(&c5).Add(&c0, &c3)
170+
z.C2.Add(&c2, &c4).Add(&z.C2, &c5).Sub(&z.C2, &c3)
171+
z.C0.Set(&c0)
172+
z.C1.Set(&c1)
173+
174+
return z
175+
}
176+
177+
// Inverse an element in E12
178+
func (z *E12) Inverse(x *E12) *E12 {
179+
// Algorithm 17 from https://eprint.iacr.org/2010/354.pdf
180+
// step 9 is wrong in the paper it's t1-t4
181+
var t0, t1, t2, t3, t4, t5, t6, c0, c1, c2, d1, d2 E4
182+
t0.Square(&x.C0)
183+
t1.Square(&x.C1)
184+
t2.Square(&x.C2)
185+
t3.Mul(&x.C0, &x.C1)
186+
t4.Mul(&x.C0, &x.C2)
187+
t5.Mul(&x.C1, &x.C2)
188+
c0.MulByNonResidue(&t5).Sub(&t0, &c0)
189+
c1.MulByNonResidue(&t2).Sub(&c1, &t3)
190+
c2.Sub(&t1, &t4)
191+
t6.Mul(&x.C0, &c0)
192+
d1.Mul(&x.C2, &c1)
193+
d2.Mul(&x.C1, &c2)
194+
d1.Add(&d1, &d2).MulByNonResidue(&d1)
195+
t6.Add(&t6, &d1)
196+
t6.Inverse(&t6)
197+
z.C0.Mul(&c0, &t6)
198+
z.C1.Mul(&c1, &t6)
199+
z.C2.Mul(&c2, &t6)
200+
201+
return z
202+
}
203+
204+
// Exp sets z=x**e and returns it
205+
func (z *E12) Exp(x *E12, e big.Int) *E12 {
206+
var res E12
207+
res.SetOne()
208+
b := e.Bytes()
209+
for i := range b {
210+
w := b[i]
211+
mask := byte(0x80)
212+
for j := 7; j >= 0; j-- {
213+
res.Square(&res)
214+
if (w&mask)>>j != 0 {
215+
res.Mul(&res, x)
216+
}
217+
mask = mask >> 1
218+
}
219+
}
220+
z.Set(&res)
221+
return z
222+
}
223+
224+
// InverseUnitary inverse a unitary element
225+
func (z *E12) InverseUnitary(x *E12) *E12 {
226+
return z.Conjugate(x)
227+
}
228+
229+
// Conjugate set z to x conjugated and return z
230+
func (z *E12) Conjugate(x *E12) *E12 {
231+
z.C0.Conjugate(&x.C0)
232+
z.C1.Conjugate(&x.C1).Neg(&z.C1)
233+
z.C2.Conjugate(&x.C2)
234+
return z
235+
}
236+
237+
// MulBy01 multiplication by sparse element (c0,c1,0)
238+
func (z *E12) MulBy01(c0, c1 *E4) *E12 {
239+
240+
var a, b, tmp, t0, t1, t2 E4
241+
242+
a.Mul(&z.C0, c0)
243+
b.Mul(&z.C1, c1)
244+
245+
tmp.Add(&z.C1, &z.C2)
246+
t0.Mul(c1, &tmp)
247+
t0.Sub(&t0, &b)
248+
t0.MulByNonResidue(&t0)
249+
t0.Add(&t0, &a)
250+
251+
tmp.Add(&z.C0, &z.C2)
252+
t2.Mul(c0, &tmp)
253+
t2.Sub(&t2, &a)
254+
t2.Add(&t2, &b)
255+
256+
t1.Add(c0, c1)
257+
tmp.Add(&z.C0, &z.C1)
258+
t1.Mul(&t1, &tmp)
259+
t1.Sub(&t1, &a)
260+
t1.Sub(&t1, &b)
261+
262+
z.C0.Set(&t0)
263+
z.C1.Set(&t1)
264+
z.C2.Set(&t2)
265+
266+
return z
267+
}
268+
269+
// MulByE2 multiplies an element in E12 by an element in E2
270+
func (z *E12) MulByE2(x *E12, y *E4) *E12 {
271+
var yCopy E4
272+
yCopy.Set(y)
273+
z.C0.Mul(&x.C0, &yCopy)
274+
z.C1.Mul(&x.C1, &yCopy)
275+
z.C2.Mul(&x.C2, &yCopy)
276+
return z
277+
}

0 commit comments

Comments
 (0)