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// Code generated by consensys/gnark-crypto DO NOT EDIT
16
17package fptower
18
19// E6 is a degree three finite field extension of fp2
20type E6 struct {
21	B0, B1, B2 E2
22}
23
24// Equal returns true if z equals x, fasle otherwise
25func (z *E6) Equal(x *E6) bool {
26	return z.B0.Equal(&x.B0) && z.B1.Equal(&x.B1) && z.B2.Equal(&x.B2)
27}
28
29// SetString sets a E6 elmt from stringf
30func (z *E6) SetString(s1, s2, s3, s4, s5, s6 string) *E6 {
31	z.B0.SetString(s1, s2)
32	z.B1.SetString(s3, s4)
33	z.B2.SetString(s5, s6)
34	return z
35}
36
37// Set Sets a E6 elmt form another E6 elmt
38func (z *E6) Set(x *E6) *E6 {
39	z.B0 = x.B0
40	z.B1 = x.B1
41	z.B2 = x.B2
42	return z
43}
44
45// SetOne sets z to 1 in Montgomery form and returns z
46func (z *E6) SetOne() *E6 {
47	*z = E6{}
48	z.B0.A0.SetOne()
49	return z
50}
51
52// SetRandom set z to a random elmt
53func (z *E6) SetRandom() (*E6, error) {
54	if _, err := z.B0.SetRandom(); err != nil {
55		return nil, err
56	}
57	if _, err := z.B1.SetRandom(); err != nil {
58		return nil, err
59	}
60	if _, err := z.B2.SetRandom(); err != nil {
61		return nil, err
62	}
63	return z, nil
64}
65
66// ToMont converts to Mont form
67func (z *E6) ToMont() *E6 {
68	z.B0.ToMont()
69	z.B1.ToMont()
70	z.B2.ToMont()
71	return z
72}
73
74// FromMont converts from Mont form
75func (z *E6) FromMont() *E6 {
76	z.B0.FromMont()
77	z.B1.FromMont()
78	z.B2.FromMont()
79	return z
80}
81
82// Add adds two elements of E6
83func (z *E6) Add(x, y *E6) *E6 {
84	z.B0.Add(&x.B0, &y.B0)
85	z.B1.Add(&x.B1, &y.B1)
86	z.B2.Add(&x.B2, &y.B2)
87	return z
88}
89
90// Neg negates the E6 number
91func (z *E6) Neg(x *E6) *E6 {
92	z.B0.Neg(&x.B0)
93	z.B1.Neg(&x.B1)
94	z.B2.Neg(&x.B2)
95	return z
96}
97
98// Sub two elements of E6
99func (z *E6) Sub(x, y *E6) *E6 {
100	z.B0.Sub(&x.B0, &y.B0)
101	z.B1.Sub(&x.B1, &y.B1)
102	z.B2.Sub(&x.B2, &y.B2)
103	return z
104}
105
106// Double doubles an element in E6
107func (z *E6) Double(x *E6) *E6 {
108	z.B0.Double(&x.B0)
109	z.B1.Double(&x.B1)
110	z.B2.Double(&x.B2)
111	return z
112}
113
114// String puts E6 elmt in string form
115func (z *E6) String() string {
116	return (z.B0.String() + "+(" + z.B1.String() + ")*v+(" + z.B2.String() + ")*v**2")
117}
118
119// MulByNonResidue mul x by (0,1,0)
120func (z *E6) MulByNonResidue(x *E6) *E6 {
121	z.B2, z.B1, z.B0 = x.B1, x.B0, x.B2
122	z.B0.MulByNonResidue(&z.B0)
123	return z
124}
125
126// Mul sets z to the E6 product of x,y, returns z
127func (z *E6) Mul(x, y *E6) *E6 {
128	// Algorithm 13 from https://eprint.iacr.org/2010/354.pdf
129	var t0, t1, t2, c0, c1, c2, tmp E2
130	t0.Mul(&x.B0, &y.B0)
131	t1.Mul(&x.B1, &y.B1)
132	t2.Mul(&x.B2, &y.B2)
133
134	c0.Add(&x.B1, &x.B2)
135	tmp.Add(&y.B1, &y.B2)
136	c0.Mul(&c0, &tmp).Sub(&c0, &t1).Sub(&c0, &t2).MulByNonResidue(&c0).Add(&c0, &t0)
137
138	c1.Add(&x.B0, &x.B1)
139	tmp.Add(&y.B0, &y.B1)
140	c1.Mul(&c1, &tmp).Sub(&c1, &t0).Sub(&c1, &t1)
141	tmp.MulByNonResidue(&t2)
142	c1.Add(&c1, &tmp)
143
144	tmp.Add(&x.B0, &x.B2)
145	c2.Add(&y.B0, &y.B2).Mul(&c2, &tmp).Sub(&c2, &t0).Sub(&c2, &t2).Add(&c2, &t1)
146
147	z.B0.Set(&c0)
148	z.B1.Set(&c1)
149	z.B2.Set(&c2)
150
151	return z
152}
153
154// Square sets z to the E6 product of x,x, returns z
155func (z *E6) Square(x *E6) *E6 {
156
157	// Algorithm 16 from https://eprint.iacr.org/2010/354.pdf
158	var c4, c5, c1, c2, c3, c0 E2
159	c4.Mul(&x.B0, &x.B1).Double(&c4)
160	c5.Square(&x.B2)
161	c1.MulByNonResidue(&c5).Add(&c1, &c4)
162	c2.Sub(&c4, &c5)
163	c3.Square(&x.B0)
164	c4.Sub(&x.B0, &x.B1).Add(&c4, &x.B2)
165	c5.Mul(&x.B1, &x.B2).Double(&c5)
166	c4.Square(&c4)
167	c0.MulByNonResidue(&c5).Add(&c0, &c3)
168	z.B2.Add(&c2, &c4).Add(&z.B2, &c5).Sub(&z.B2, &c3)
169	z.B0.Set(&c0)
170	z.B1.Set(&c1)
171
172	return z
173}
174
175// Inverse an element in E6
176func (z *E6) Inverse(x *E6) *E6 {
177	// Algorithm 17 from https://eprint.iacr.org/2010/354.pdf
178	// step 9 is wrong in the paper it's t1-t4
179	var t0, t1, t2, t3, t4, t5, t6, c0, c1, c2, d1, d2 E2
180	t0.Square(&x.B0)
181	t1.Square(&x.B1)
182	t2.Square(&x.B2)
183	t3.Mul(&x.B0, &x.B1)
184	t4.Mul(&x.B0, &x.B2)
185	t5.Mul(&x.B1, &x.B2)
186	c0.MulByNonResidue(&t5).Neg(&c0).Add(&c0, &t0)
187	c1.MulByNonResidue(&t2).Sub(&c1, &t3)
188	c2.Sub(&t1, &t4)
189	t6.Mul(&x.B0, &c0)
190	d1.Mul(&x.B2, &c1)
191	d2.Mul(&x.B1, &c2)
192	d1.Add(&d1, &d2).MulByNonResidue(&d1)
193	t6.Add(&t6, &d1)
194	t6.Inverse(&t6)
195	z.B0.Mul(&c0, &t6)
196	z.B1.Mul(&c1, &t6)
197	z.B2.Mul(&c2, &t6)
198
199	return z
200}
201