arnaucube
arnaucube/go-iden3-cryptoPublic Self-hosted repository
go-iden3-crypto/ff/element.go
ff/element.goRaw
  1// Copyright 2020 ConsenSys AG
  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// field modulus q =
 16//
 17// 21888242871839275222246405745257275088548364400416034343698204186575808495617
 18// Code generated by goff DO NOT EDIT
 19// goff version:  - build:
 20// Element are assumed to be in Montgomery form in all methods
 21
 22// Package ff (generated by goff) contains field arithmetics operations
 23package ff
 24
 25import (
 26	"crypto/rand"
 27	"encoding/binary"
 28	"io"
 29	"math/big"
 30	"math/bits"
 31	"sync"
 32
 33	"unsafe"
 34)
 35
 36// Element represents a field element stored on 4 words (uint64)
 37// Element are assumed to be in Montgomery form in all methods
 38type Element [4]uint64
 39
 40// ElementLimbs number of 64 bits words needed to represent Element
 41const ElementLimbs = 4
 42
 43// ElementBits number bits needed to represent Element
 44const ElementBits = 254
 45
 46// SetUint64 z = v, sets z LSB to v (non-Montgomery form) and convert z to Montgomery form
 47func (z *Element) SetUint64(v uint64) *Element {
 48	z[0] = v
 49	z[1] = 0
 50	z[2] = 0
 51	z[3] = 0
 52	return z.ToMont()
 53}
 54
 55// Set z = x
 56func (z *Element) Set(x *Element) *Element {
 57	z[0] = x[0]
 58	z[1] = x[1]
 59	z[2] = x[2]
 60	z[3] = x[3]
 61	return z
 62}
 63
 64// SetZero z = 0
 65func (z *Element) SetZero() *Element {
 66	z[0] = 0
 67	z[1] = 0
 68	z[2] = 0
 69	z[3] = 0
 70	return z
 71}
 72
 73// SetOne z = 1 (in Montgomery form)
 74func (z *Element) SetOne() *Element {
 75	z[0] = 12436184717236109307
 76	z[1] = 3962172157175319849
 77	z[2] = 7381016538464732718
 78	z[3] = 1011752739694698287
 79	return z
 80}
 81
 82// Neg z = q - x
 83func (z *Element) Neg(x *Element) *Element {
 84	if x.IsZero() {
 85		return z.SetZero()
 86	}
 87	var borrow uint64
 88	z[0], borrow = bits.Sub64(4891460686036598785, x[0], 0)
 89	z[1], borrow = bits.Sub64(2896914383306846353, x[1], borrow)
 90	z[2], borrow = bits.Sub64(13281191951274694749, x[2], borrow)
 91	z[3], _ = bits.Sub64(3486998266802970665, x[3], borrow)
 92	return z
 93}
 94
 95// Div z = x*y^-1 mod q
 96func (z *Element) Div(x, y *Element) *Element {
 97	var yInv Element
 98	yInv.Inverse(y)
 99	z.Mul(x, &yInv)
100	return z
101}
102
103// Equal returns z == x
104func (z *Element) Equal(x *Element) bool {
105	return (z[3] == x[3]) && (z[2] == x[2]) && (z[1] == x[1]) && (z[0] == x[0])
106}
107
108// IsZero returns z == 0
109func (z *Element) IsZero() bool {
110	return (z[3] | z[2] | z[1] | z[0]) == 0
111}
112
113// field modulus stored as big.Int
114var _elementModulusBigInt big.Int
115var onceelementModulus sync.Once
116
117func elementModulusBigInt() *big.Int {
118	onceelementModulus.Do(func() {
119		_elementModulusBigInt.SetString("21888242871839275222246405745257275088548364400416034343698204186575808495617", 10)
120	})
121	return &_elementModulusBigInt
122}
123
124// Inverse z = x^-1 mod q
125// Algorithm 16 in "Efficient Software-Implementation of Finite Fields with Applications to Cryptography"
126// if x == 0, sets and returns z = x
127func (z *Element) Inverse(x *Element) *Element {
128	if x.IsZero() {
129		return z.Set(x)
130	}
131
132	// initialize u = q
133	var u = Element{
134		4891460686036598785,
135		2896914383306846353,
136		13281191951274694749,
137		3486998266802970665,
138	}
139
140	// initialize s = r^2
141	var s = Element{
142		1997599621687373223,
143		6052339484930628067,
144		10108755138030829701,
145		150537098327114917,
146	}
147
148	// r = 0
149	r := Element{}
150
151	v := *x
152
153	var carry, borrow, t, t2 uint64
154	var bigger, uIsOne, vIsOne bool
155
156	for !uIsOne && !vIsOne {
157		for v[0]&1 == 0 {
158
159			// v = v >> 1
160			t2 = v[3] << 63
161			v[3] >>= 1
162			t = t2
163			t2 = v[2] << 63
164			v[2] = (v[2] >> 1) | t
165			t = t2
166			t2 = v[1] << 63
167			v[1] = (v[1] >> 1) | t
168			t = t2
169			v[0] = (v[0] >> 1) | t
170
171			if s[0]&1 == 1 {
172
173				// s = s + q
174				s[0], carry = bits.Add64(s[0], 4891460686036598785, 0)
175				s[1], carry = bits.Add64(s[1], 2896914383306846353, carry)
176				s[2], carry = bits.Add64(s[2], 13281191951274694749, carry)
177				s[3], _ = bits.Add64(s[3], 3486998266802970665, carry)
178
179			}
180
181			// s = s >> 1
182			t2 = s[3] << 63
183			s[3] >>= 1
184			t = t2
185			t2 = s[2] << 63
186			s[2] = (s[2] >> 1) | t
187			t = t2
188			t2 = s[1] << 63
189			s[1] = (s[1] >> 1) | t
190			t = t2
191			s[0] = (s[0] >> 1) | t
192
193		}
194		for u[0]&1 == 0 {
195
196			// u = u >> 1
197			t2 = u[3] << 63
198			u[3] >>= 1
199			t = t2
200			t2 = u[2] << 63
201			u[2] = (u[2] >> 1) | t
202			t = t2
203			t2 = u[1] << 63
204			u[1] = (u[1] >> 1) | t
205			t = t2
206			u[0] = (u[0] >> 1) | t
207
208			if r[0]&1 == 1 {
209
210				// r = r + q
211				r[0], carry = bits.Add64(r[0], 4891460686036598785, 0)
212				r[1], carry = bits.Add64(r[1], 2896914383306846353, carry)
213				r[2], carry = bits.Add64(r[2], 13281191951274694749, carry)
214				r[3], _ = bits.Add64(r[3], 3486998266802970665, carry)
215
216			}
217
218			// r = r >> 1
219			t2 = r[3] << 63
220			r[3] >>= 1
221			t = t2
222			t2 = r[2] << 63
223			r[2] = (r[2] >> 1) | t
224			t = t2
225			t2 = r[1] << 63
226			r[1] = (r[1] >> 1) | t
227			t = t2
228			r[0] = (r[0] >> 1) | t
229
230		}
231
232		// v >= u
233		bigger = !(v[3] < u[3] || (v[3] == u[3] && (v[2] < u[2] || (v[2] == u[2] && (v[1] < u[1] || (v[1] == u[1] && (v[0] < u[0])))))))
234
235		if bigger {
236
237			// v = v - u
238			v[0], borrow = bits.Sub64(v[0], u[0], 0)
239			v[1], borrow = bits.Sub64(v[1], u[1], borrow)
240			v[2], borrow = bits.Sub64(v[2], u[2], borrow)
241			v[3], _ = bits.Sub64(v[3], u[3], borrow)
242
243			// r >= s
244			bigger = !(r[3] < s[3] || (r[3] == s[3] && (r[2] < s[2] || (r[2] == s[2] && (r[1] < s[1] || (r[1] == s[1] && (r[0] < s[0])))))))
245
246			if bigger {
247
248				// s = s + q
249				s[0], carry = bits.Add64(s[0], 4891460686036598785, 0)
250				s[1], carry = bits.Add64(s[1], 2896914383306846353, carry)
251				s[2], carry = bits.Add64(s[2], 13281191951274694749, carry)
252				s[3], _ = bits.Add64(s[3], 3486998266802970665, carry)
253
254			}
255
256			// s = s - r
257			s[0], borrow = bits.Sub64(s[0], r[0], 0)
258			s[1], borrow = bits.Sub64(s[1], r[1], borrow)
259			s[2], borrow = bits.Sub64(s[2], r[2], borrow)
260			s[3], _ = bits.Sub64(s[3], r[3], borrow)
261
262		} else {
263
264			// u = u - v
265			u[0], borrow = bits.Sub64(u[0], v[0], 0)
266			u[1], borrow = bits.Sub64(u[1], v[1], borrow)
267			u[2], borrow = bits.Sub64(u[2], v[2], borrow)
268			u[3], _ = bits.Sub64(u[3], v[3], borrow)
269
270			// s >= r
271			bigger = !(s[3] < r[3] || (s[3] == r[3] && (s[2] < r[2] || (s[2] == r[2] && (s[1] < r[1] || (s[1] == r[1] && (s[0] < r[0])))))))
272
273			if bigger {
274
275				// r = r + q
276				r[0], carry = bits.Add64(r[0], 4891460686036598785, 0)
277				r[1], carry = bits.Add64(r[1], 2896914383306846353, carry)
278				r[2], carry = bits.Add64(r[2], 13281191951274694749, carry)
279				r[3], _ = bits.Add64(r[3], 3486998266802970665, carry)
280
281			}
282
283			// r = r - s
284			r[0], borrow = bits.Sub64(r[0], s[0], 0)
285			r[1], borrow = bits.Sub64(r[1], s[1], borrow)
286			r[2], borrow = bits.Sub64(r[2], s[2], borrow)
287			r[3], _ = bits.Sub64(r[3], s[3], borrow)
288
289		}
290		uIsOne = (u[0] == 1) && (u[3]|u[2]|u[1]) == 0
291		vIsOne = (v[0] == 1) && (v[3]|v[2]|v[1]) == 0
292	}
293
294	if uIsOne {
295		z.Set(&r)
296	} else {
297		z.Set(&s)
298	}
299
300	return z
301}
302
303// SetRandom sets z to a random element < q
304func (z *Element) SetRandom() *Element {
305	bytes := make([]byte, 32)
306	io.ReadFull(rand.Reader, bytes)
307	z[0] = binary.BigEndian.Uint64(bytes[0:8])
308	z[1] = binary.BigEndian.Uint64(bytes[8:16])
309	z[2] = binary.BigEndian.Uint64(bytes[16:24])
310	z[3] = binary.BigEndian.Uint64(bytes[24:32])
311	z[3] %= 3486998266802970665
312
313	// if z > q --> z -= q
314	if !(z[3] < 3486998266802970665 || (z[3] == 3486998266802970665 && (z[2] < 13281191951274694749 || (z[2] == 13281191951274694749 && (z[1] < 2896914383306846353 || (z[1] == 2896914383306846353 && (z[0] < 4891460686036598785))))))) {
315		var b uint64
316		z[0], b = bits.Sub64(z[0], 4891460686036598785, 0)
317		z[1], b = bits.Sub64(z[1], 2896914383306846353, b)
318		z[2], b = bits.Sub64(z[2], 13281191951274694749, b)
319		z[3], _ = bits.Sub64(z[3], 3486998266802970665, b)
320	}
321
322	return z
323}
324
325// Add z = x + y mod q
326func (z *Element) Add(x, y *Element) *Element {
327	var carry uint64
328
329	z[0], carry = bits.Add64(x[0], y[0], 0)
330	z[1], carry = bits.Add64(x[1], y[1], carry)
331	z[2], carry = bits.Add64(x[2], y[2], carry)
332	z[3], _ = bits.Add64(x[3], y[3], carry)
333
334	// if z > q --> z -= q
335	if !(z[3] < 3486998266802970665 || (z[3] == 3486998266802970665 && (z[2] < 13281191951274694749 || (z[2] == 13281191951274694749 && (z[1] < 2896914383306846353 || (z[1] == 2896914383306846353 && (z[0] < 4891460686036598785))))))) {
336		var b uint64
337		z[0], b = bits.Sub64(z[0], 4891460686036598785, 0)
338		z[1], b = bits.Sub64(z[1], 2896914383306846353, b)
339		z[2], b = bits.Sub64(z[2], 13281191951274694749, b)
340		z[3], _ = bits.Sub64(z[3], 3486998266802970665, b)
341	}
342	return z
343}
344
345// AddAssign z = z + x mod q
346func (z *Element) AddAssign(x *Element) *Element {
347	var carry uint64
348
349	z[0], carry = bits.Add64(z[0], x[0], 0)
350	z[1], carry = bits.Add64(z[1], x[1], carry)
351	z[2], carry = bits.Add64(z[2], x[2], carry)
352	z[3], _ = bits.Add64(z[3], x[3], carry)
353
354	// if z > q --> z -= q
355	if !(z[3] < 3486998266802970665 || (z[3] == 3486998266802970665 && (z[2] < 13281191951274694749 || (z[2] == 13281191951274694749 && (z[1] < 2896914383306846353 || (z[1] == 2896914383306846353 && (z[0] < 4891460686036598785))))))) {
356		var b uint64
357		z[0], b = bits.Sub64(z[0], 4891460686036598785, 0)
358		z[1], b = bits.Sub64(z[1], 2896914383306846353, b)
359		z[2], b = bits.Sub64(z[2], 13281191951274694749, b)
360		z[3], _ = bits.Sub64(z[3], 3486998266802970665, b)
361	}
362	return z
363}
364
365// Double z = x + x mod q, aka Lsh 1
366func (z *Element) Double(x *Element) *Element {
367	var carry uint64
368
369	z[0], carry = bits.Add64(x[0], x[0], 0)
370	z[1], carry = bits.Add64(x[1], x[1], carry)
371	z[2], carry = bits.Add64(x[2], x[2], carry)
372	z[3], _ = bits.Add64(x[3], x[3], carry)
373
374	// if z > q --> z -= q
375	if !(z[3] < 3486998266802970665 || (z[3] == 3486998266802970665 && (z[2] < 13281191951274694749 || (z[2] == 13281191951274694749 && (z[1] < 2896914383306846353 || (z[1] == 2896914383306846353 && (z[0] < 4891460686036598785))))))) {
376		var b uint64
377		z[0], b = bits.Sub64(z[0], 4891460686036598785, 0)
378		z[1], b = bits.Sub64(z[1], 2896914383306846353, b)
379		z[2], b = bits.Sub64(z[2], 13281191951274694749, b)
380		z[3], _ = bits.Sub64(z[3], 3486998266802970665, b)
381	}
382	return z
383}
384
385// Sub  z = x - y mod q
386func (z *Element) Sub(x, y *Element) *Element {
387	var b uint64
388	z[0], b = bits.Sub64(x[0], y[0], 0)
389	z[1], b = bits.Sub64(x[1], y[1], b)
390	z[2], b = bits.Sub64(x[2], y[2], b)
391	z[3], b = bits.Sub64(x[3], y[3], b)
392	if b != 0 {
393		var c uint64
394		z[0], c = bits.Add64(z[0], 4891460686036598785, 0)
395		z[1], c = bits.Add64(z[1], 2896914383306846353, c)
396		z[2], c = bits.Add64(z[2], 13281191951274694749, c)
397		z[3], _ = bits.Add64(z[3], 3486998266802970665, c)
398	}
399	return z
400}
401
402// SubAssign  z = z - x mod q
403func (z *Element) SubAssign(x *Element) *Element {
404	var b uint64
405	z[0], b = bits.Sub64(z[0], x[0], 0)
406	z[1], b = bits.Sub64(z[1], x[1], b)
407	z[2], b = bits.Sub64(z[2], x[2], b)
408	z[3], b = bits.Sub64(z[3], x[3], b)
409	if b != 0 {
410		var c uint64
411		z[0], c = bits.Add64(z[0], 4891460686036598785, 0)
412		z[1], c = bits.Add64(z[1], 2896914383306846353, c)
413		z[2], c = bits.Add64(z[2], 13281191951274694749, c)
414		z[3], _ = bits.Add64(z[3], 3486998266802970665, c)
415	}
416	return z
417}
418
419// Exp z = x^e mod q
420func (z *Element) Exp(x Element, e uint64) *Element {
421	if e == 0 {
422		return z.SetOne()
423	}
424
425	z.Set(&x)
426
427	l := bits.Len64(e) - 2
428	for i := l; i >= 0; i-- {
429		z.Square(z)
430		if e&(1<<uint(i)) != 0 {
431			z.MulAssign(&x)
432		}
433	}
434	return z
435}
436
437// FromMont converts z in place (i.e. mutates) from Montgomery to regular representation
438// sets and returns z = z * 1
439func (z *Element) FromMont() *Element {
440
441	// the following lines implement z = z * 1
442	// with a modified CIOS montgomery multiplication
443	{
444		// m = z[0]n'[0] mod W
445		m := z[0] * 14042775128853446655
446		C := madd0(m, 4891460686036598785, z[0])
447		C, z[0] = madd2(m, 2896914383306846353, z[1], C)
448		C, z[1] = madd2(m, 13281191951274694749, z[2], C)
449		C, z[2] = madd2(m, 3486998266802970665, z[3], C)
450		z[3] = C
451	}
452	{
453		// m = z[0]n'[0] mod W
454		m := z[0] * 14042775128853446655
455		C := madd0(m, 4891460686036598785, z[0])
456		C, z[0] = madd2(m, 2896914383306846353, z[1], C)
457		C, z[1] = madd2(m, 13281191951274694749, z[2], C)
458		C, z[2] = madd2(m, 3486998266802970665, z[3], C)
459		z[3] = C
460	}
461	{
462		// m = z[0]n'[0] mod W
463		m := z[0] * 14042775128853446655
464		C := madd0(m, 4891460686036598785, z[0])
465		C, z[0] = madd2(m, 2896914383306846353, z[1], C)
466		C, z[1] = madd2(m, 13281191951274694749, z[2], C)
467		C, z[2] = madd2(m, 3486998266802970665, z[3], C)
468		z[3] = C
469	}
470	{
471		// m = z[0]n'[0] mod W
472		m := z[0] * 14042775128853446655
473		C := madd0(m, 4891460686036598785, z[0])
474		C, z[0] = madd2(m, 2896914383306846353, z[1], C)
475		C, z[1] = madd2(m, 13281191951274694749, z[2], C)
476		C, z[2] = madd2(m, 3486998266802970665, z[3], C)
477		z[3] = C
478	}
479
480	// if z > q --> z -= q
481	if !(z[3] < 3486998266802970665 || (z[3] == 3486998266802970665 && (z[2] < 13281191951274694749 || (z[2] == 13281191951274694749 && (z[1] < 2896914383306846353 || (z[1] == 2896914383306846353 && (z[0] < 4891460686036598785))))))) {
482		var b uint64
483		z[0], b = bits.Sub64(z[0], 4891460686036598785, 0)
484		z[1], b = bits.Sub64(z[1], 2896914383306846353, b)
485		z[2], b = bits.Sub64(z[2], 13281191951274694749, b)
486		z[3], _ = bits.Sub64(z[3], 3486998266802970665, b)
487	}
488	return z
489}
490
491// ToMont converts z to Montgomery form
492// sets and returns z = z * r^2
493func (z *Element) ToMont() *Element {
494	var rSquare = Element{
495		1997599621687373223,
496		6052339484930628067,
497		10108755138030829701,
498		150537098327114917,
499	}
500	return z.MulAssign(&rSquare)
501}
502
503// ToRegular returns z in regular form (doesn't mutate z)
504func (z Element) ToRegular() Element {
505	return *z.FromMont()
506}
507
508// String returns the string form of an Element in Montgomery form
509func (z *Element) String() string {
510	var _z big.Int
511	return z.ToBigIntRegular(&_z).String()
512}
513
514// ToBigInt returns z as a big.Int in Montgomery form
515func (z *Element) ToBigInt(res *big.Int) *big.Int {
516	bits := (*[4]big.Word)(unsafe.Pointer(z))
517	return res.SetBits(bits[:])
518}
519
520// ToBigIntRegular returns z as a big.Int in regular form
521func (z Element) ToBigIntRegular(res *big.Int) *big.Int {
522	z.FromMont()
523	bits := (*[4]big.Word)(unsafe.Pointer(&z))
524	return res.SetBits(bits[:])
525}
526
527// SetBigInt sets z to v (regular form) and returns z in Montgomery form
528func (z *Element) SetBigInt(v *big.Int) *Element {
529	z.SetZero()
530
531	zero := big.NewInt(0)
532	q := elementModulusBigInt()
533
534	// copy input
535	vv := new(big.Int).Set(v)
536
537	// while v < 0, v+=q
538	for vv.Cmp(zero) == -1 {
539		vv.Add(vv, q)
540	}
541	// while v > q, v-=q
542	for vv.Cmp(q) == 1 {
543		vv.Sub(vv, q)
544	}
545	// if v == q, return 0
546	if vv.Cmp(q) == 0 {
547		return z
548	}
549	// v should
550	vBits := vv.Bits()
551	for i := 0; i < len(vBits); i++ {
552		z[i] = uint64(vBits[i])
553	}
554	return z.ToMont()
555}
556
557// SetString creates a big.Int with s (in base 10) and calls SetBigInt on z
558func (z *Element) SetString(s string) *Element {
559	x, ok := new(big.Int).SetString(s, 10)
560	if !ok {
561		panic("Element.SetString failed -> can't parse number in base10 into a big.Int")
562	}
563	return z.SetBigInt(x)
564}
565
566// Mul z = x * y mod q
567func (z *Element) Mul(x, y *Element) *Element {
568
569	var t [4]uint64
570	var c [3]uint64
571	{
572		// round 0
573		v := x[0]
574		c[1], c[0] = bits.Mul64(v, y[0])
575		m := c[0] * 14042775128853446655
576		c[2] = madd0(m, 4891460686036598785, c[0])
577		c[1], c[0] = madd1(v, y[1], c[1])
578		c[2], t[0] = madd2(m, 2896914383306846353, c[2], c[0])
579		c[1], c[0] = madd1(v, y[2], c[1])
580		c[2], t[1] = madd2(m, 13281191951274694749, c[2], c[0])
581		c[1], c[0] = madd1(v, y[3], c[1])
582		t[3], t[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1])
583	}
584	{
585		// round 1
586		v := x[1]
587		c[1], c[0] = madd1(v, y[0], t[0])
588		m := c[0] * 14042775128853446655
589		c[2] = madd0(m, 4891460686036598785, c[0])
590		c[1], c[0] = madd2(v, y[1], c[1], t[1])
591		c[2], t[0] = madd2(m, 2896914383306846353, c[2], c[0])
592		c[1], c[0] = madd2(v, y[2], c[1], t[2])
593		c[2], t[1] = madd2(m, 13281191951274694749, c[2], c[0])
594		c[1], c[0] = madd2(v, y[3], c[1], t[3])
595		t[3], t[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1])
596	}
597	{
598		// round 2
599		v := x[2]
600		c[1], c[0] = madd1(v, y[0], t[0])
601		m := c[0] * 14042775128853446655
602		c[2] = madd0(m, 4891460686036598785, c[0])
603		c[1], c[0] = madd2(v, y[1], c[1], t[1])
604		c[2], t[0] = madd2(m, 2896914383306846353, c[2], c[0])
605		c[1], c[0] = madd2(v, y[2], c[1], t[2])
606		c[2], t[1] = madd2(m, 13281191951274694749, c[2], c[0])
607		c[1], c[0] = madd2(v, y[3], c[1], t[3])
608		t[3], t[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1])
609	}
610	{
611		// round 3
612		v := x[3]
613		c[1], c[0] = madd1(v, y[0], t[0])
614		m := c[0] * 14042775128853446655
615		c[2] = madd0(m, 4891460686036598785, c[0])
616		c[1], c[0] = madd2(v, y[1], c[1], t[1])
617		c[2], z[0] = madd2(m, 2896914383306846353, c[2], c[0])
618		c[1], c[0] = madd2(v, y[2], c[1], t[2])
619		c[2], z[1] = madd2(m, 13281191951274694749, c[2], c[0])
620		c[1], c[0] = madd2(v, y[3], c[1], t[3])
621		z[3], z[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1])
622	}
623
624	// if z > q --> z -= q
625	if !(z[3] < 3486998266802970665 || (z[3] == 3486998266802970665 && (z[2] < 13281191951274694749 || (z[2] == 13281191951274694749 && (z[1] < 2896914383306846353 || (z[1] == 2896914383306846353 && (z[0] < 4891460686036598785))))))) {
626		var b uint64
627		z[0], b = bits.Sub64(z[0], 4891460686036598785, 0)
628		z[1], b = bits.Sub64(z[1], 2896914383306846353, b)
629		z[2], b = bits.Sub64(z[2], 13281191951274694749, b)
630		z[3], _ = bits.Sub64(z[3], 3486998266802970665, b)
631	}
632	return z
633}
634
635// MulAssign z = z * x mod q
636func (z *Element) MulAssign(x *Element) *Element {
637
638	var t [4]uint64
639	var c [3]uint64
640	{
641		// round 0
642		v := z[0]
643		c[1], c[0] = bits.Mul64(v, x[0])
644		m := c[0] * 14042775128853446655
645		c[2] = madd0(m, 4891460686036598785, c[0])
646		c[1], c[0] = madd1(v, x[1], c[1])
647		c[2], t[0] = madd2(m, 2896914383306846353, c[2], c[0])
648		c[1], c[0] = madd1(v, x[2], c[1])
649		c[2], t[1] = madd2(m, 13281191951274694749, c[2], c[0])
650		c[1], c[0] = madd1(v, x[3], c[1])
651		t[3], t[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1])
652	}
653	{
654		// round 1
655		v := z[1]
656		c[1], c[0] = madd1(v, x[0], t[0])
657		m := c[0] * 14042775128853446655
658		c[2] = madd0(m, 4891460686036598785, c[0])
659		c[1], c[0] = madd2(v, x[1], c[1], t[1])
660		c[2], t[0] = madd2(m, 2896914383306846353, c[2], c[0])
661		c[1], c[0] = madd2(v, x[2], c[1], t[2])
662		c[2], t[1] = madd2(m, 13281191951274694749, c[2], c[0])
663		c[1], c[0] = madd2(v, x[3], c[1], t[3])
664		t[3], t[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1])
665	}
666	{
667		// round 2
668		v := z[2]
669		c[1], c[0] = madd1(v, x[0], t[0])
670		m := c[0] * 14042775128853446655
671		c[2] = madd0(m, 4891460686036598785, c[0])
672		c[1], c[0] = madd2(v, x[1], c[1], t[1])
673		c[2], t[0] = madd2(m, 2896914383306846353, c[2], c[0])
674		c[1], c[0] = madd2(v, x[2], c[1], t[2])
675		c[2], t[1] = madd2(m, 13281191951274694749, c[2], c[0])
676		c[1], c[0] = madd2(v, x[3], c[1], t[3])
677		t[3], t[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1])
678	}
679	{
680		// round 3
681		v := z[3]
682		c[1], c[0] = madd1(v, x[0], t[0])
683		m := c[0] * 14042775128853446655
684		c[2] = madd0(m, 4891460686036598785, c[0])
685		c[1], c[0] = madd2(v, x[1], c[1], t[1])
686		c[2], z[0] = madd2(m, 2896914383306846353, c[2], c[0])
687		c[1], c[0] = madd2(v, x[2], c[1], t[2])
688		c[2], z[1] = madd2(m, 13281191951274694749, c[2], c[0])
689		c[1], c[0] = madd2(v, x[3], c[1], t[3])
690		z[3], z[2] = madd3(m, 3486998266802970665, c[0], c[2], c[1])
691	}
692
693	// if z > q --> z -= q
694	if !(z[3] < 3486998266802970665 || (z[3] == 3486998266802970665 && (z[2] < 13281191951274694749 || (z[2] == 13281191951274694749 && (z[1] < 2896914383306846353 || (z[1] == 2896914383306846353 && (z[0] < 4891460686036598785))))))) {
695		var b uint64
696		z[0], b = bits.Sub64(z[0], 4891460686036598785, 0)
697		z[1], b = bits.Sub64(z[1], 2896914383306846353, b)
698		z[2], b = bits.Sub64(z[2], 13281191951274694749, b)
699		z[3], _ = bits.Sub64(z[3], 3486998266802970665, b)
700	}
701	return z
702}
703
704// Square z = x * x mod q
705func (z *Element) Square(x *Element) *Element {
706
707	var p [4]uint64
708
709	var u, v uint64
710	{
711		// round 0
712		u, p[0] = bits.Mul64(x[0], x[0])
713		m := p[0] * 14042775128853446655
714		C := madd0(m, 4891460686036598785, p[0])
715		var t uint64
716		t, u, v = madd1sb(x[0], x[1], u)
717		C, p[0] = madd2(m, 2896914383306846353, v, C)
718		t, u, v = madd1s(x[0], x[2], t, u)
719		C, p[1] = madd2(m, 13281191951274694749, v, C)
720		_, u, v = madd1s(x[0], x[3], t, u)
721		p[3], p[2] = madd3(m, 3486998266802970665, v, C, u)
722	}
723	{
724		// round 1
725		m := p[0] * 14042775128853446655
726		C := madd0(m, 4891460686036598785, p[0])
727		u, v = madd1(x[1], x[1], p[1])
728		C, p[0] = madd2(m, 2896914383306846353, v, C)
729		var t uint64
730		t, u, v = madd2sb(x[1], x[2], p[2], u)
731		C, p[1] = madd2(m, 13281191951274694749, v, C)
732		_, u, v = madd2s(x[1], x[3], p[3], t, u)
733		p[3], p[2] = madd3(m, 3486998266802970665, v, C, u)
734	}
735	{
736		// round 2
737		m := p[0] * 14042775128853446655
738		C := madd0(m, 4891460686036598785, p[0])
739		C, p[0] = madd2(m, 2896914383306846353, p[1], C)
740		u, v = madd1(x[2], x[2], p[2])
741		C, p[1] = madd2(m, 13281191951274694749, v, C)
742		_, u, v = madd2sb(x[2], x[3], p[3], u)
743		p[3], p[2] = madd3(m, 3486998266802970665, v, C, u)
744	}
745	{
746		// round 3
747		m := p[0] * 14042775128853446655
748		C := madd0(m, 4891460686036598785, p[0])
749		C, z[0] = madd2(m, 2896914383306846353, p[1], C)
750		C, z[1] = madd2(m, 13281191951274694749, p[2], C)
751		u, v = madd1(x[3], x[3], p[3])
752		z[3], z[2] = madd3(m, 3486998266802970665, v, C, u)
753	}
754
755	// if z > q --> z -= q
756	if !(z[3] < 3486998266802970665 || (z[3] == 3486998266802970665 && (z[2] < 13281191951274694749 || (z[2] == 13281191951274694749 && (z[1] < 2896914383306846353 || (z[1] == 2896914383306846353 && (z[0] < 4891460686036598785))))))) {
757		var b uint64
758		z[0], b = bits.Sub64(z[0], 4891460686036598785, 0)
759		z[1], b = bits.Sub64(z[1], 2896914383306846353, b)
760		z[2], b = bits.Sub64(z[2], 13281191951274694749, b)
761		z[3], _ = bits.Sub64(z[3], 3486998266802970665, b)
762	}
763	return z
764}