github.com/consensys/gnark-crypto@v0.14.0/ecc/stark-curve/fr/element.go (about)

     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  
    17  package fr
    18  
    19  import (
    20  	"crypto/rand"
    21  	"encoding/binary"
    22  	"errors"
    23  	"io"
    24  	"math/big"
    25  	"math/bits"
    26  	"reflect"
    27  	"strconv"
    28  	"strings"
    29  
    30  	"github.com/bits-and-blooms/bitset"
    31  	"github.com/consensys/gnark-crypto/field/hash"
    32  	"github.com/consensys/gnark-crypto/field/pool"
    33  )
    34  
    35  // Element represents a field element stored on 4 words (uint64)
    36  //
    37  // Element are assumed to be in Montgomery form in all methods.
    38  //
    39  // Modulus q =
    40  //
    41  //	q[base10] = 3618502788666131213697322783095070105526743751716087489154079457884512865583
    42  //	q[base16] = 0x800000000000010ffffffffffffffffb781126dcae7b2321e66a241adc64d2f
    43  //
    44  // # Warning
    45  //
    46  // This code has not been audited and is provided as-is. In particular, there is no security guarantees such as constant time implementation or side-channel attack resistance.
    47  type Element [4]uint64
    48  
    49  const (
    50  	Limbs = 4   // number of 64 bits words needed to represent a Element
    51  	Bits  = 252 // number of bits needed to represent a Element
    52  	Bytes = 32  // number of bytes needed to represent a Element
    53  )
    54  
    55  // Field modulus q
    56  const (
    57  	q0 uint64 = 2190616671734353199
    58  	q1 uint64 = 13222870243701404210
    59  	q2 uint64 = 18446744073709551615
    60  	q3 uint64 = 576460752303423504
    61  )
    62  
    63  var qElement = Element{
    64  	q0,
    65  	q1,
    66  	q2,
    67  	q3,
    68  }
    69  
    70  var _modulus big.Int // q stored as big.Int
    71  
    72  // Modulus returns q as a big.Int
    73  //
    74  //	q[base10] = 3618502788666131213697322783095070105526743751716087489154079457884512865583
    75  //	q[base16] = 0x800000000000010ffffffffffffffffb781126dcae7b2321e66a241adc64d2f
    76  func Modulus() *big.Int {
    77  	return new(big.Int).Set(&_modulus)
    78  }
    79  
    80  // q + r'.r = 1, i.e., qInvNeg = - q⁻¹ mod r
    81  // used for Montgomery reduction
    82  const qInvNeg uint64 = 13504954208620504625
    83  
    84  func init() {
    85  	_modulus.SetString("800000000000010ffffffffffffffffb781126dcae7b2321e66a241adc64d2f", 16)
    86  }
    87  
    88  // NewElement returns a new Element from a uint64 value
    89  //
    90  // it is equivalent to
    91  //
    92  //	var v Element
    93  //	v.SetUint64(...)
    94  func NewElement(v uint64) Element {
    95  	z := Element{v}
    96  	z.Mul(&z, &rSquare)
    97  	return z
    98  }
    99  
   100  // SetUint64 sets z to v and returns z
   101  func (z *Element) SetUint64(v uint64) *Element {
   102  	//  sets z LSB to v (non-Montgomery form) and convert z to Montgomery form
   103  	*z = Element{v}
   104  	return z.Mul(z, &rSquare) // z.toMont()
   105  }
   106  
   107  // SetInt64 sets z to v and returns z
   108  func (z *Element) SetInt64(v int64) *Element {
   109  
   110  	// absolute value of v
   111  	m := v >> 63
   112  	z.SetUint64(uint64((v ^ m) - m))
   113  
   114  	if m != 0 {
   115  		// v is negative
   116  		z.Neg(z)
   117  	}
   118  
   119  	return z
   120  }
   121  
   122  // Set z = x and returns z
   123  func (z *Element) Set(x *Element) *Element {
   124  	z[0] = x[0]
   125  	z[1] = x[1]
   126  	z[2] = x[2]
   127  	z[3] = x[3]
   128  	return z
   129  }
   130  
   131  // SetInterface converts provided interface into Element
   132  // returns an error if provided type is not supported
   133  // supported types:
   134  //
   135  //	Element
   136  //	*Element
   137  //	uint64
   138  //	int
   139  //	string (see SetString for valid formats)
   140  //	*big.Int
   141  //	big.Int
   142  //	[]byte
   143  func (z *Element) SetInterface(i1 interface{}) (*Element, error) {
   144  	if i1 == nil {
   145  		return nil, errors.New("can't set fr.Element with <nil>")
   146  	}
   147  
   148  	switch c1 := i1.(type) {
   149  	case Element:
   150  		return z.Set(&c1), nil
   151  	case *Element:
   152  		if c1 == nil {
   153  			return nil, errors.New("can't set fr.Element with <nil>")
   154  		}
   155  		return z.Set(c1), nil
   156  	case uint8:
   157  		return z.SetUint64(uint64(c1)), nil
   158  	case uint16:
   159  		return z.SetUint64(uint64(c1)), nil
   160  	case uint32:
   161  		return z.SetUint64(uint64(c1)), nil
   162  	case uint:
   163  		return z.SetUint64(uint64(c1)), nil
   164  	case uint64:
   165  		return z.SetUint64(c1), nil
   166  	case int8:
   167  		return z.SetInt64(int64(c1)), nil
   168  	case int16:
   169  		return z.SetInt64(int64(c1)), nil
   170  	case int32:
   171  		return z.SetInt64(int64(c1)), nil
   172  	case int64:
   173  		return z.SetInt64(c1), nil
   174  	case int:
   175  		return z.SetInt64(int64(c1)), nil
   176  	case string:
   177  		return z.SetString(c1)
   178  	case *big.Int:
   179  		if c1 == nil {
   180  			return nil, errors.New("can't set fr.Element with <nil>")
   181  		}
   182  		return z.SetBigInt(c1), nil
   183  	case big.Int:
   184  		return z.SetBigInt(&c1), nil
   185  	case []byte:
   186  		return z.SetBytes(c1), nil
   187  	default:
   188  		return nil, errors.New("can't set fr.Element from type " + reflect.TypeOf(i1).String())
   189  	}
   190  }
   191  
   192  // SetZero z = 0
   193  func (z *Element) SetZero() *Element {
   194  	z[0] = 0
   195  	z[1] = 0
   196  	z[2] = 0
   197  	z[3] = 0
   198  	return z
   199  }
   200  
   201  // SetOne z = 1 (in Montgomery form)
   202  func (z *Element) SetOne() *Element {
   203  	z[0] = 5877859471073257295
   204  	z[1] = 14366136140576156654
   205  	z[2] = 8
   206  	z[3] = 576460752303422961
   207  	return z
   208  }
   209  
   210  // Div z = x*y⁻¹ (mod q)
   211  func (z *Element) Div(x, y *Element) *Element {
   212  	var yInv Element
   213  	yInv.Inverse(y)
   214  	z.Mul(x, &yInv)
   215  	return z
   216  }
   217  
   218  // Equal returns z == x; constant-time
   219  func (z *Element) Equal(x *Element) bool {
   220  	return z.NotEqual(x) == 0
   221  }
   222  
   223  // NotEqual returns 0 if and only if z == x; constant-time
   224  func (z *Element) NotEqual(x *Element) uint64 {
   225  	return (z[3] ^ x[3]) | (z[2] ^ x[2]) | (z[1] ^ x[1]) | (z[0] ^ x[0])
   226  }
   227  
   228  // IsZero returns z == 0
   229  func (z *Element) IsZero() bool {
   230  	return (z[3] | z[2] | z[1] | z[0]) == 0
   231  }
   232  
   233  // IsOne returns z == 1
   234  func (z *Element) IsOne() bool {
   235  	return ((z[3] ^ 576460752303422961) | (z[2] ^ 8) | (z[1] ^ 14366136140576156654) | (z[0] ^ 5877859471073257295)) == 0
   236  }
   237  
   238  // IsUint64 reports whether z can be represented as an uint64.
   239  func (z *Element) IsUint64() bool {
   240  	zz := *z
   241  	zz.fromMont()
   242  	return zz.FitsOnOneWord()
   243  }
   244  
   245  // Uint64 returns the uint64 representation of x. If x cannot be represented in a uint64, the result is undefined.
   246  func (z *Element) Uint64() uint64 {
   247  	return z.Bits()[0]
   248  }
   249  
   250  // FitsOnOneWord reports whether z words (except the least significant word) are 0
   251  //
   252  // It is the responsibility of the caller to convert from Montgomery to Regular form if needed.
   253  func (z *Element) FitsOnOneWord() bool {
   254  	return (z[3] | z[2] | z[1]) == 0
   255  }
   256  
   257  // Cmp compares (lexicographic order) z and x and returns:
   258  //
   259  //	-1 if z <  x
   260  //	 0 if z == x
   261  //	+1 if z >  x
   262  func (z *Element) Cmp(x *Element) int {
   263  	_z := z.Bits()
   264  	_x := x.Bits()
   265  	if _z[3] > _x[3] {
   266  		return 1
   267  	} else if _z[3] < _x[3] {
   268  		return -1
   269  	}
   270  	if _z[2] > _x[2] {
   271  		return 1
   272  	} else if _z[2] < _x[2] {
   273  		return -1
   274  	}
   275  	if _z[1] > _x[1] {
   276  		return 1
   277  	} else if _z[1] < _x[1] {
   278  		return -1
   279  	}
   280  	if _z[0] > _x[0] {
   281  		return 1
   282  	} else if _z[0] < _x[0] {
   283  		return -1
   284  	}
   285  	return 0
   286  }
   287  
   288  // LexicographicallyLargest returns true if this element is strictly lexicographically
   289  // larger than its negation, false otherwise
   290  func (z *Element) LexicographicallyLargest() bool {
   291  	// adapted from github.com/zkcrypto/bls12_381
   292  	// we check if the element is larger than (q-1) / 2
   293  	// if z - (((q -1) / 2) + 1) have no underflow, then z > (q-1) / 2
   294  
   295  	_z := z.Bits()
   296  
   297  	var b uint64
   298  	_, b = bits.Sub64(_z[0], 1095308335867176600, 0)
   299  	_, b = bits.Sub64(_z[1], 15834807158705477913, b)
   300  	_, b = bits.Sub64(_z[2], 9223372036854775807, b)
   301  	_, b = bits.Sub64(_z[3], 288230376151711752, b)
   302  
   303  	return b == 0
   304  }
   305  
   306  // SetRandom sets z to a uniform random value in [0, q).
   307  //
   308  // This might error only if reading from crypto/rand.Reader errors,
   309  // in which case, value of z is undefined.
   310  func (z *Element) SetRandom() (*Element, error) {
   311  	// this code is generated for all modulus
   312  	// and derived from go/src/crypto/rand/util.go
   313  
   314  	// l is number of limbs * 8; the number of bytes needed to reconstruct 4 uint64
   315  	const l = 32
   316  
   317  	// bitLen is the maximum bit length needed to encode a value < q.
   318  	const bitLen = 252
   319  
   320  	// k is the maximum byte length needed to encode a value < q.
   321  	const k = (bitLen + 7) / 8
   322  
   323  	// b is the number of bits in the most significant byte of q-1.
   324  	b := uint(bitLen % 8)
   325  	if b == 0 {
   326  		b = 8
   327  	}
   328  
   329  	var bytes [l]byte
   330  
   331  	for {
   332  		// note that bytes[k:l] is always 0
   333  		if _, err := io.ReadFull(rand.Reader, bytes[:k]); err != nil {
   334  			return nil, err
   335  		}
   336  
   337  		// Clear unused bits in in the most significant byte to increase probability
   338  		// that the candidate is < q.
   339  		bytes[k-1] &= uint8(int(1<<b) - 1)
   340  		z[0] = binary.LittleEndian.Uint64(bytes[0:8])
   341  		z[1] = binary.LittleEndian.Uint64(bytes[8:16])
   342  		z[2] = binary.LittleEndian.Uint64(bytes[16:24])
   343  		z[3] = binary.LittleEndian.Uint64(bytes[24:32])
   344  
   345  		if !z.smallerThanModulus() {
   346  			continue // ignore the candidate and re-sample
   347  		}
   348  
   349  		return z, nil
   350  	}
   351  }
   352  
   353  // smallerThanModulus returns true if z < q
   354  // This is not constant time
   355  func (z *Element) smallerThanModulus() bool {
   356  	return (z[3] < q3 || (z[3] == q3 && (z[2] < q2 || (z[2] == q2 && (z[1] < q1 || (z[1] == q1 && (z[0] < q0)))))))
   357  }
   358  
   359  // One returns 1
   360  func One() Element {
   361  	var one Element
   362  	one.SetOne()
   363  	return one
   364  }
   365  
   366  // Halve sets z to z / 2 (mod q)
   367  func (z *Element) Halve() {
   368  	var carry uint64
   369  
   370  	if z[0]&1 == 1 {
   371  		// z = z + q
   372  		z[0], carry = bits.Add64(z[0], q0, 0)
   373  		z[1], carry = bits.Add64(z[1], q1, carry)
   374  		z[2], carry = bits.Add64(z[2], q2, carry)
   375  		z[3], _ = bits.Add64(z[3], q3, carry)
   376  
   377  	}
   378  	// z = z >> 1
   379  	z[0] = z[0]>>1 | z[1]<<63
   380  	z[1] = z[1]>>1 | z[2]<<63
   381  	z[2] = z[2]>>1 | z[3]<<63
   382  	z[3] >>= 1
   383  
   384  }
   385  
   386  // fromMont converts z in place (i.e. mutates) from Montgomery to regular representation
   387  // sets and returns z = z * 1
   388  func (z *Element) fromMont() *Element {
   389  	fromMont(z)
   390  	return z
   391  }
   392  
   393  // Add z = x + y (mod q)
   394  func (z *Element) Add(x, y *Element) *Element {
   395  
   396  	var carry uint64
   397  	z[0], carry = bits.Add64(x[0], y[0], 0)
   398  	z[1], carry = bits.Add64(x[1], y[1], carry)
   399  	z[2], carry = bits.Add64(x[2], y[2], carry)
   400  	z[3], _ = bits.Add64(x[3], y[3], carry)
   401  
   402  	// if z ⩾ q → z -= q
   403  	if !z.smallerThanModulus() {
   404  		var b uint64
   405  		z[0], b = bits.Sub64(z[0], q0, 0)
   406  		z[1], b = bits.Sub64(z[1], q1, b)
   407  		z[2], b = bits.Sub64(z[2], q2, b)
   408  		z[3], _ = bits.Sub64(z[3], q3, b)
   409  	}
   410  	return z
   411  }
   412  
   413  // Double z = x + x (mod q), aka Lsh 1
   414  func (z *Element) Double(x *Element) *Element {
   415  
   416  	var carry uint64
   417  	z[0], carry = bits.Add64(x[0], x[0], 0)
   418  	z[1], carry = bits.Add64(x[1], x[1], carry)
   419  	z[2], carry = bits.Add64(x[2], x[2], carry)
   420  	z[3], _ = bits.Add64(x[3], x[3], carry)
   421  
   422  	// if z ⩾ q → z -= q
   423  	if !z.smallerThanModulus() {
   424  		var b uint64
   425  		z[0], b = bits.Sub64(z[0], q0, 0)
   426  		z[1], b = bits.Sub64(z[1], q1, b)
   427  		z[2], b = bits.Sub64(z[2], q2, b)
   428  		z[3], _ = bits.Sub64(z[3], q3, b)
   429  	}
   430  	return z
   431  }
   432  
   433  // Sub z = x - y (mod q)
   434  func (z *Element) Sub(x, y *Element) *Element {
   435  	var b uint64
   436  	z[0], b = bits.Sub64(x[0], y[0], 0)
   437  	z[1], b = bits.Sub64(x[1], y[1], b)
   438  	z[2], b = bits.Sub64(x[2], y[2], b)
   439  	z[3], b = bits.Sub64(x[3], y[3], b)
   440  	if b != 0 {
   441  		var c uint64
   442  		z[0], c = bits.Add64(z[0], q0, 0)
   443  		z[1], c = bits.Add64(z[1], q1, c)
   444  		z[2], c = bits.Add64(z[2], q2, c)
   445  		z[3], _ = bits.Add64(z[3], q3, c)
   446  	}
   447  	return z
   448  }
   449  
   450  // Neg z = q - x
   451  func (z *Element) Neg(x *Element) *Element {
   452  	if x.IsZero() {
   453  		z.SetZero()
   454  		return z
   455  	}
   456  	var borrow uint64
   457  	z[0], borrow = bits.Sub64(q0, x[0], 0)
   458  	z[1], borrow = bits.Sub64(q1, x[1], borrow)
   459  	z[2], borrow = bits.Sub64(q2, x[2], borrow)
   460  	z[3], _ = bits.Sub64(q3, x[3], borrow)
   461  	return z
   462  }
   463  
   464  // Select is a constant-time conditional move.
   465  // If c=0, z = x0. Else z = x1
   466  func (z *Element) Select(c int, x0 *Element, x1 *Element) *Element {
   467  	cC := uint64((int64(c) | -int64(c)) >> 63) // "canonicized" into: 0 if c=0, -1 otherwise
   468  	z[0] = x0[0] ^ cC&(x0[0]^x1[0])
   469  	z[1] = x0[1] ^ cC&(x0[1]^x1[1])
   470  	z[2] = x0[2] ^ cC&(x0[2]^x1[2])
   471  	z[3] = x0[3] ^ cC&(x0[3]^x1[3])
   472  	return z
   473  }
   474  
   475  // _mulGeneric is unoptimized textbook CIOS
   476  // it is a fallback solution on x86 when ADX instruction set is not available
   477  // and is used for testing purposes.
   478  func _mulGeneric(z, x, y *Element) {
   479  
   480  	// Implements CIOS multiplication -- section 2.3.2 of Tolga Acar's thesis
   481  	// https://www.microsoft.com/en-us/research/wp-content/uploads/1998/06/97Acar.pdf
   482  	//
   483  	// The algorithm:
   484  	//
   485  	// for i=0 to N-1
   486  	// 		C := 0
   487  	// 		for j=0 to N-1
   488  	// 			(C,t[j]) := t[j] + x[j]*y[i] + C
   489  	// 		(t[N+1],t[N]) := t[N] + C
   490  	//
   491  	// 		C := 0
   492  	// 		m := t[0]*q'[0] mod D
   493  	// 		(C,_) := t[0] + m*q[0]
   494  	// 		for j=1 to N-1
   495  	// 			(C,t[j-1]) := t[j] + m*q[j] + C
   496  	//
   497  	// 		(C,t[N-1]) := t[N] + C
   498  	// 		t[N] := t[N+1] + C
   499  	//
   500  	// → N is the number of machine words needed to store the modulus q
   501  	// → D is the word size. For example, on a 64-bit architecture D is 2	64
   502  	// → x[i], y[i], q[i] is the ith word of the numbers x,y,q
   503  	// → q'[0] is the lowest word of the number -q⁻¹ mod r. This quantity is pre-computed, as it does not depend on the inputs.
   504  	// → t is a temporary array of size N+2
   505  	// → C, S are machine words. A pair (C,S) refers to (hi-bits, lo-bits) of a two-word number
   506  
   507  	var t [5]uint64
   508  	var D uint64
   509  	var m, C uint64
   510  	// -----------------------------------
   511  	// First loop
   512  
   513  	C, t[0] = bits.Mul64(y[0], x[0])
   514  	C, t[1] = madd1(y[0], x[1], C)
   515  	C, t[2] = madd1(y[0], x[2], C)
   516  	C, t[3] = madd1(y[0], x[3], C)
   517  
   518  	t[4], D = bits.Add64(t[4], C, 0)
   519  
   520  	// m = t[0]n'[0] mod W
   521  	m = t[0] * qInvNeg
   522  
   523  	// -----------------------------------
   524  	// Second loop
   525  	C = madd0(m, q0, t[0])
   526  	C, t[0] = madd2(m, q1, t[1], C)
   527  	C, t[1] = madd2(m, q2, t[2], C)
   528  	C, t[2] = madd2(m, q3, t[3], C)
   529  
   530  	t[3], C = bits.Add64(t[4], C, 0)
   531  	t[4], _ = bits.Add64(0, D, C)
   532  	// -----------------------------------
   533  	// First loop
   534  
   535  	C, t[0] = madd1(y[1], x[0], t[0])
   536  	C, t[1] = madd2(y[1], x[1], t[1], C)
   537  	C, t[2] = madd2(y[1], x[2], t[2], C)
   538  	C, t[3] = madd2(y[1], x[3], t[3], C)
   539  
   540  	t[4], D = bits.Add64(t[4], C, 0)
   541  
   542  	// m = t[0]n'[0] mod W
   543  	m = t[0] * qInvNeg
   544  
   545  	// -----------------------------------
   546  	// Second loop
   547  	C = madd0(m, q0, t[0])
   548  	C, t[0] = madd2(m, q1, t[1], C)
   549  	C, t[1] = madd2(m, q2, t[2], C)
   550  	C, t[2] = madd2(m, q3, t[3], C)
   551  
   552  	t[3], C = bits.Add64(t[4], C, 0)
   553  	t[4], _ = bits.Add64(0, D, C)
   554  	// -----------------------------------
   555  	// First loop
   556  
   557  	C, t[0] = madd1(y[2], x[0], t[0])
   558  	C, t[1] = madd2(y[2], x[1], t[1], C)
   559  	C, t[2] = madd2(y[2], x[2], t[2], C)
   560  	C, t[3] = madd2(y[2], x[3], t[3], C)
   561  
   562  	t[4], D = bits.Add64(t[4], C, 0)
   563  
   564  	// m = t[0]n'[0] mod W
   565  	m = t[0] * qInvNeg
   566  
   567  	// -----------------------------------
   568  	// Second loop
   569  	C = madd0(m, q0, t[0])
   570  	C, t[0] = madd2(m, q1, t[1], C)
   571  	C, t[1] = madd2(m, q2, t[2], C)
   572  	C, t[2] = madd2(m, q3, t[3], C)
   573  
   574  	t[3], C = bits.Add64(t[4], C, 0)
   575  	t[4], _ = bits.Add64(0, D, C)
   576  	// -----------------------------------
   577  	// First loop
   578  
   579  	C, t[0] = madd1(y[3], x[0], t[0])
   580  	C, t[1] = madd2(y[3], x[1], t[1], C)
   581  	C, t[2] = madd2(y[3], x[2], t[2], C)
   582  	C, t[3] = madd2(y[3], x[3], t[3], C)
   583  
   584  	t[4], D = bits.Add64(t[4], C, 0)
   585  
   586  	// m = t[0]n'[0] mod W
   587  	m = t[0] * qInvNeg
   588  
   589  	// -----------------------------------
   590  	// Second loop
   591  	C = madd0(m, q0, t[0])
   592  	C, t[0] = madd2(m, q1, t[1], C)
   593  	C, t[1] = madd2(m, q2, t[2], C)
   594  	C, t[2] = madd2(m, q3, t[3], C)
   595  
   596  	t[3], C = bits.Add64(t[4], C, 0)
   597  	t[4], _ = bits.Add64(0, D, C)
   598  
   599  	if t[4] != 0 {
   600  		// we need to reduce, we have a result on 5 words
   601  		var b uint64
   602  		z[0], b = bits.Sub64(t[0], q0, 0)
   603  		z[1], b = bits.Sub64(t[1], q1, b)
   604  		z[2], b = bits.Sub64(t[2], q2, b)
   605  		z[3], _ = bits.Sub64(t[3], q3, b)
   606  		return
   607  	}
   608  
   609  	// copy t into z
   610  	z[0] = t[0]
   611  	z[1] = t[1]
   612  	z[2] = t[2]
   613  	z[3] = t[3]
   614  
   615  	// if z ⩾ q → z -= q
   616  	if !z.smallerThanModulus() {
   617  		var b uint64
   618  		z[0], b = bits.Sub64(z[0], q0, 0)
   619  		z[1], b = bits.Sub64(z[1], q1, b)
   620  		z[2], b = bits.Sub64(z[2], q2, b)
   621  		z[3], _ = bits.Sub64(z[3], q3, b)
   622  	}
   623  }
   624  
   625  func _fromMontGeneric(z *Element) {
   626  	// the following lines implement z = z * 1
   627  	// with a modified CIOS montgomery multiplication
   628  	// see Mul for algorithm documentation
   629  	{
   630  		// m = z[0]n'[0] mod W
   631  		m := z[0] * qInvNeg
   632  		C := madd0(m, q0, z[0])
   633  		C, z[0] = madd2(m, q1, z[1], C)
   634  		C, z[1] = madd2(m, q2, z[2], C)
   635  		C, z[2] = madd2(m, q3, z[3], C)
   636  		z[3] = C
   637  	}
   638  	{
   639  		// m = z[0]n'[0] mod W
   640  		m := z[0] * qInvNeg
   641  		C := madd0(m, q0, z[0])
   642  		C, z[0] = madd2(m, q1, z[1], C)
   643  		C, z[1] = madd2(m, q2, z[2], C)
   644  		C, z[2] = madd2(m, q3, z[3], C)
   645  		z[3] = C
   646  	}
   647  	{
   648  		// m = z[0]n'[0] mod W
   649  		m := z[0] * qInvNeg
   650  		C := madd0(m, q0, z[0])
   651  		C, z[0] = madd2(m, q1, z[1], C)
   652  		C, z[1] = madd2(m, q2, z[2], C)
   653  		C, z[2] = madd2(m, q3, z[3], C)
   654  		z[3] = C
   655  	}
   656  	{
   657  		// m = z[0]n'[0] mod W
   658  		m := z[0] * qInvNeg
   659  		C := madd0(m, q0, z[0])
   660  		C, z[0] = madd2(m, q1, z[1], C)
   661  		C, z[1] = madd2(m, q2, z[2], C)
   662  		C, z[2] = madd2(m, q3, z[3], C)
   663  		z[3] = C
   664  	}
   665  
   666  	// if z ⩾ q → z -= q
   667  	if !z.smallerThanModulus() {
   668  		var b uint64
   669  		z[0], b = bits.Sub64(z[0], q0, 0)
   670  		z[1], b = bits.Sub64(z[1], q1, b)
   671  		z[2], b = bits.Sub64(z[2], q2, b)
   672  		z[3], _ = bits.Sub64(z[3], q3, b)
   673  	}
   674  }
   675  
   676  func _reduceGeneric(z *Element) {
   677  
   678  	// if z ⩾ q → z -= q
   679  	if !z.smallerThanModulus() {
   680  		var b uint64
   681  		z[0], b = bits.Sub64(z[0], q0, 0)
   682  		z[1], b = bits.Sub64(z[1], q1, b)
   683  		z[2], b = bits.Sub64(z[2], q2, b)
   684  		z[3], _ = bits.Sub64(z[3], q3, b)
   685  	}
   686  }
   687  
   688  // BatchInvert returns a new slice with every element inverted.
   689  // Uses Montgomery batch inversion trick
   690  func BatchInvert(a []Element) []Element {
   691  	res := make([]Element, len(a))
   692  	if len(a) == 0 {
   693  		return res
   694  	}
   695  
   696  	zeroes := bitset.New(uint(len(a)))
   697  	accumulator := One()
   698  
   699  	for i := 0; i < len(a); i++ {
   700  		if a[i].IsZero() {
   701  			zeroes.Set(uint(i))
   702  			continue
   703  		}
   704  		res[i] = accumulator
   705  		accumulator.Mul(&accumulator, &a[i])
   706  	}
   707  
   708  	accumulator.Inverse(&accumulator)
   709  
   710  	for i := len(a) - 1; i >= 0; i-- {
   711  		if zeroes.Test(uint(i)) {
   712  			continue
   713  		}
   714  		res[i].Mul(&res[i], &accumulator)
   715  		accumulator.Mul(&accumulator, &a[i])
   716  	}
   717  
   718  	return res
   719  }
   720  
   721  func _butterflyGeneric(a, b *Element) {
   722  	t := *a
   723  	a.Add(a, b)
   724  	b.Sub(&t, b)
   725  }
   726  
   727  // BitLen returns the minimum number of bits needed to represent z
   728  // returns 0 if z == 0
   729  func (z *Element) BitLen() int {
   730  	if z[3] != 0 {
   731  		return 192 + bits.Len64(z[3])
   732  	}
   733  	if z[2] != 0 {
   734  		return 128 + bits.Len64(z[2])
   735  	}
   736  	if z[1] != 0 {
   737  		return 64 + bits.Len64(z[1])
   738  	}
   739  	return bits.Len64(z[0])
   740  }
   741  
   742  // Hash msg to count prime field elements.
   743  // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2
   744  func Hash(msg, dst []byte, count int) ([]Element, error) {
   745  	// 128 bits of security
   746  	// L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128
   747  	const Bytes = 1 + (Bits-1)/8
   748  	const L = 16 + Bytes
   749  
   750  	lenInBytes := count * L
   751  	pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes)
   752  	if err != nil {
   753  		return nil, err
   754  	}
   755  
   756  	// get temporary big int from the pool
   757  	vv := pool.BigInt.Get()
   758  
   759  	res := make([]Element, count)
   760  	for i := 0; i < count; i++ {
   761  		vv.SetBytes(pseudoRandomBytes[i*L : (i+1)*L])
   762  		res[i].SetBigInt(vv)
   763  	}
   764  
   765  	// release object into pool
   766  	pool.BigInt.Put(vv)
   767  
   768  	return res, nil
   769  }
   770  
   771  // Exp z = xᵏ (mod q)
   772  func (z *Element) Exp(x Element, k *big.Int) *Element {
   773  	if k.IsUint64() && k.Uint64() == 0 {
   774  		return z.SetOne()
   775  	}
   776  
   777  	e := k
   778  	if k.Sign() == -1 {
   779  		// negative k, we invert
   780  		// if k < 0: xᵏ (mod q) == (x⁻¹)ᵏ (mod q)
   781  		x.Inverse(&x)
   782  
   783  		// we negate k in a temp big.Int since
   784  		// Int.Bit(_) of k and -k is different
   785  		e = pool.BigInt.Get()
   786  		defer pool.BigInt.Put(e)
   787  		e.Neg(k)
   788  	}
   789  
   790  	z.Set(&x)
   791  
   792  	for i := e.BitLen() - 2; i >= 0; i-- {
   793  		z.Square(z)
   794  		if e.Bit(i) == 1 {
   795  			z.Mul(z, &x)
   796  		}
   797  	}
   798  
   799  	return z
   800  }
   801  
   802  // rSquare where r is the Montgommery constant
   803  // see section 2.3.2 of Tolga Acar's thesis
   804  // https://www.microsoft.com/en-us/research/wp-content/uploads/1998/06/97Acar.pdf
   805  var rSquare = Element{
   806  	6927015553468754061,
   807  	5808788430323081401,
   808  	13470454832524147387,
   809  	565735549540988526,
   810  }
   811  
   812  // toMont converts z to Montgomery form
   813  // sets and returns z = z * r²
   814  func (z *Element) toMont() *Element {
   815  	return z.Mul(z, &rSquare)
   816  }
   817  
   818  // String returns the decimal representation of z as generated by
   819  // z.Text(10).
   820  func (z *Element) String() string {
   821  	return z.Text(10)
   822  }
   823  
   824  // toBigInt returns z as a big.Int in Montgomery form
   825  func (z *Element) toBigInt(res *big.Int) *big.Int {
   826  	var b [Bytes]byte
   827  	binary.BigEndian.PutUint64(b[24:32], z[0])
   828  	binary.BigEndian.PutUint64(b[16:24], z[1])
   829  	binary.BigEndian.PutUint64(b[8:16], z[2])
   830  	binary.BigEndian.PutUint64(b[0:8], z[3])
   831  
   832  	return res.SetBytes(b[:])
   833  }
   834  
   835  // Text returns the string representation of z in the given base.
   836  // Base must be between 2 and 36, inclusive. The result uses the
   837  // lower-case letters 'a' to 'z' for digit values 10 to 35.
   838  // No prefix (such as "0x") is added to the string. If z is a nil
   839  // pointer it returns "<nil>".
   840  // If base == 10 and -z fits in a uint16 prefix "-" is added to the string.
   841  func (z *Element) Text(base int) string {
   842  	if base < 2 || base > 36 {
   843  		panic("invalid base")
   844  	}
   845  	if z == nil {
   846  		return "<nil>"
   847  	}
   848  
   849  	const maxUint16 = 65535
   850  	if base == 10 {
   851  		var zzNeg Element
   852  		zzNeg.Neg(z)
   853  		zzNeg.fromMont()
   854  		if zzNeg.FitsOnOneWord() && zzNeg[0] <= maxUint16 && zzNeg[0] != 0 {
   855  			return "-" + strconv.FormatUint(zzNeg[0], base)
   856  		}
   857  	}
   858  	zz := *z
   859  	zz.fromMont()
   860  	if zz.FitsOnOneWord() {
   861  		return strconv.FormatUint(zz[0], base)
   862  	}
   863  	vv := pool.BigInt.Get()
   864  	r := zz.toBigInt(vv).Text(base)
   865  	pool.BigInt.Put(vv)
   866  	return r
   867  }
   868  
   869  // BigInt sets and return z as a *big.Int
   870  func (z *Element) BigInt(res *big.Int) *big.Int {
   871  	_z := *z
   872  	_z.fromMont()
   873  	return _z.toBigInt(res)
   874  }
   875  
   876  // ToBigIntRegular returns z as a big.Int in regular form
   877  //
   878  // Deprecated: use BigInt(*big.Int) instead
   879  func (z Element) ToBigIntRegular(res *big.Int) *big.Int {
   880  	z.fromMont()
   881  	return z.toBigInt(res)
   882  }
   883  
   884  // Bits provides access to z by returning its value as a little-endian [4]uint64 array.
   885  // Bits is intended to support implementation of missing low-level Element
   886  // functionality outside this package; it should be avoided otherwise.
   887  func (z *Element) Bits() [4]uint64 {
   888  	_z := *z
   889  	fromMont(&_z)
   890  	return _z
   891  }
   892  
   893  // Bytes returns the value of z as a big-endian byte array
   894  func (z *Element) Bytes() (res [Bytes]byte) {
   895  	BigEndian.PutElement(&res, *z)
   896  	return
   897  }
   898  
   899  // Marshal returns the value of z as a big-endian byte slice
   900  func (z *Element) Marshal() []byte {
   901  	b := z.Bytes()
   902  	return b[:]
   903  }
   904  
   905  // Unmarshal is an alias for SetBytes, it sets z to the value of e.
   906  func (z *Element) Unmarshal(e []byte) {
   907  	z.SetBytes(e)
   908  }
   909  
   910  // SetBytes interprets e as the bytes of a big-endian unsigned integer,
   911  // sets z to that value, and returns z.
   912  func (z *Element) SetBytes(e []byte) *Element {
   913  	if len(e) == Bytes {
   914  		// fast path
   915  		v, err := BigEndian.Element((*[Bytes]byte)(e))
   916  		if err == nil {
   917  			*z = v
   918  			return z
   919  		}
   920  	}
   921  
   922  	// slow path.
   923  	// get a big int from our pool
   924  	vv := pool.BigInt.Get()
   925  	vv.SetBytes(e)
   926  
   927  	// set big int
   928  	z.SetBigInt(vv)
   929  
   930  	// put temporary object back in pool
   931  	pool.BigInt.Put(vv)
   932  
   933  	return z
   934  }
   935  
   936  // SetBytesCanonical interprets e as the bytes of a big-endian 32-byte integer.
   937  // If e is not a 32-byte slice or encodes a value higher than q,
   938  // SetBytesCanonical returns an error.
   939  func (z *Element) SetBytesCanonical(e []byte) error {
   940  	if len(e) != Bytes {
   941  		return errors.New("invalid fr.Element encoding")
   942  	}
   943  	v, err := BigEndian.Element((*[Bytes]byte)(e))
   944  	if err != nil {
   945  		return err
   946  	}
   947  	*z = v
   948  	return nil
   949  }
   950  
   951  // SetBigInt sets z to v and returns z
   952  func (z *Element) SetBigInt(v *big.Int) *Element {
   953  	z.SetZero()
   954  
   955  	var zero big.Int
   956  
   957  	// fast path
   958  	c := v.Cmp(&_modulus)
   959  	if c == 0 {
   960  		// v == 0
   961  		return z
   962  	} else if c != 1 && v.Cmp(&zero) != -1 {
   963  		// 0 < v < q
   964  		return z.setBigInt(v)
   965  	}
   966  
   967  	// get temporary big int from the pool
   968  	vv := pool.BigInt.Get()
   969  
   970  	// copy input + modular reduction
   971  	vv.Mod(v, &_modulus)
   972  
   973  	// set big int byte value
   974  	z.setBigInt(vv)
   975  
   976  	// release object into pool
   977  	pool.BigInt.Put(vv)
   978  	return z
   979  }
   980  
   981  // setBigInt assumes 0 ⩽ v < q
   982  func (z *Element) setBigInt(v *big.Int) *Element {
   983  	vBits := v.Bits()
   984  
   985  	if bits.UintSize == 64 {
   986  		for i := 0; i < len(vBits); i++ {
   987  			z[i] = uint64(vBits[i])
   988  		}
   989  	} else {
   990  		for i := 0; i < len(vBits); i++ {
   991  			if i%2 == 0 {
   992  				z[i/2] = uint64(vBits[i])
   993  			} else {
   994  				z[i/2] |= uint64(vBits[i]) << 32
   995  			}
   996  		}
   997  	}
   998  
   999  	return z.toMont()
  1000  }
  1001  
  1002  // SetString creates a big.Int with number and calls SetBigInt on z
  1003  //
  1004  // The number prefix determines the actual base: A prefix of
  1005  // ”0b” or ”0B” selects base 2, ”0”, ”0o” or ”0O” selects base 8,
  1006  // and ”0x” or ”0X” selects base 16. Otherwise, the selected base is 10
  1007  // and no prefix is accepted.
  1008  //
  1009  // For base 16, lower and upper case letters are considered the same:
  1010  // The letters 'a' to 'f' and 'A' to 'F' represent digit values 10 to 15.
  1011  //
  1012  // An underscore character ”_” may appear between a base
  1013  // prefix and an adjacent digit, and between successive digits; such
  1014  // underscores do not change the value of the number.
  1015  // Incorrect placement of underscores is reported as a panic if there
  1016  // are no other errors.
  1017  //
  1018  // If the number is invalid this method leaves z unchanged and returns nil, error.
  1019  func (z *Element) SetString(number string) (*Element, error) {
  1020  	// get temporary big int from the pool
  1021  	vv := pool.BigInt.Get()
  1022  
  1023  	if _, ok := vv.SetString(number, 0); !ok {
  1024  		return nil, errors.New("Element.SetString failed -> can't parse number into a big.Int " + number)
  1025  	}
  1026  
  1027  	z.SetBigInt(vv)
  1028  
  1029  	// release object into pool
  1030  	pool.BigInt.Put(vv)
  1031  
  1032  	return z, nil
  1033  }
  1034  
  1035  // MarshalJSON returns json encoding of z (z.Text(10))
  1036  // If z == nil, returns null
  1037  func (z *Element) MarshalJSON() ([]byte, error) {
  1038  	if z == nil {
  1039  		return []byte("null"), nil
  1040  	}
  1041  	const maxSafeBound = 15 // we encode it as number if it's small
  1042  	s := z.Text(10)
  1043  	if len(s) <= maxSafeBound {
  1044  		return []byte(s), nil
  1045  	}
  1046  	var sbb strings.Builder
  1047  	sbb.WriteByte('"')
  1048  	sbb.WriteString(s)
  1049  	sbb.WriteByte('"')
  1050  	return []byte(sbb.String()), nil
  1051  }
  1052  
  1053  // UnmarshalJSON accepts numbers and strings as input
  1054  // See Element.SetString for valid prefixes (0x, 0b, ...)
  1055  func (z *Element) UnmarshalJSON(data []byte) error {
  1056  	s := string(data)
  1057  	if len(s) > Bits*3 {
  1058  		return errors.New("value too large (max = Element.Bits * 3)")
  1059  	}
  1060  
  1061  	// we accept numbers and strings, remove leading and trailing quotes if any
  1062  	if len(s) > 0 && s[0] == '"' {
  1063  		s = s[1:]
  1064  	}
  1065  	if len(s) > 0 && s[len(s)-1] == '"' {
  1066  		s = s[:len(s)-1]
  1067  	}
  1068  
  1069  	// get temporary big int from the pool
  1070  	vv := pool.BigInt.Get()
  1071  
  1072  	if _, ok := vv.SetString(s, 0); !ok {
  1073  		return errors.New("can't parse into a big.Int: " + s)
  1074  	}
  1075  
  1076  	z.SetBigInt(vv)
  1077  
  1078  	// release object into pool
  1079  	pool.BigInt.Put(vv)
  1080  	return nil
  1081  }
  1082  
  1083  // A ByteOrder specifies how to convert byte slices into a Element
  1084  type ByteOrder interface {
  1085  	Element(*[Bytes]byte) (Element, error)
  1086  	PutElement(*[Bytes]byte, Element)
  1087  	String() string
  1088  }
  1089  
  1090  // BigEndian is the big-endian implementation of ByteOrder and AppendByteOrder.
  1091  var BigEndian bigEndian
  1092  
  1093  type bigEndian struct{}
  1094  
  1095  // Element interpret b is a big-endian 32-byte slice.
  1096  // If b encodes a value higher than q, Element returns error.
  1097  func (bigEndian) Element(b *[Bytes]byte) (Element, error) {
  1098  	var z Element
  1099  	z[0] = binary.BigEndian.Uint64((*b)[24:32])
  1100  	z[1] = binary.BigEndian.Uint64((*b)[16:24])
  1101  	z[2] = binary.BigEndian.Uint64((*b)[8:16])
  1102  	z[3] = binary.BigEndian.Uint64((*b)[0:8])
  1103  
  1104  	if !z.smallerThanModulus() {
  1105  		return Element{}, errors.New("invalid fr.Element encoding")
  1106  	}
  1107  
  1108  	z.toMont()
  1109  	return z, nil
  1110  }
  1111  
  1112  func (bigEndian) PutElement(b *[Bytes]byte, e Element) {
  1113  	e.fromMont()
  1114  	binary.BigEndian.PutUint64((*b)[24:32], e[0])
  1115  	binary.BigEndian.PutUint64((*b)[16:24], e[1])
  1116  	binary.BigEndian.PutUint64((*b)[8:16], e[2])
  1117  	binary.BigEndian.PutUint64((*b)[0:8], e[3])
  1118  }
  1119  
  1120  func (bigEndian) String() string { return "BigEndian" }
  1121  
  1122  // LittleEndian is the little-endian implementation of ByteOrder and AppendByteOrder.
  1123  var LittleEndian littleEndian
  1124  
  1125  type littleEndian struct{}
  1126  
  1127  func (littleEndian) Element(b *[Bytes]byte) (Element, error) {
  1128  	var z Element
  1129  	z[0] = binary.LittleEndian.Uint64((*b)[0:8])
  1130  	z[1] = binary.LittleEndian.Uint64((*b)[8:16])
  1131  	z[2] = binary.LittleEndian.Uint64((*b)[16:24])
  1132  	z[3] = binary.LittleEndian.Uint64((*b)[24:32])
  1133  
  1134  	if !z.smallerThanModulus() {
  1135  		return Element{}, errors.New("invalid fr.Element encoding")
  1136  	}
  1137  
  1138  	z.toMont()
  1139  	return z, nil
  1140  }
  1141  
  1142  func (littleEndian) PutElement(b *[Bytes]byte, e Element) {
  1143  	e.fromMont()
  1144  	binary.LittleEndian.PutUint64((*b)[0:8], e[0])
  1145  	binary.LittleEndian.PutUint64((*b)[8:16], e[1])
  1146  	binary.LittleEndian.PutUint64((*b)[16:24], e[2])
  1147  	binary.LittleEndian.PutUint64((*b)[24:32], e[3])
  1148  }
  1149  
  1150  func (littleEndian) String() string { return "LittleEndian" }
  1151  
  1152  var (
  1153  	_bLegendreExponentElement *big.Int
  1154  	_bSqrtExponentElement     *big.Int
  1155  )
  1156  
  1157  func init() {
  1158  	_bLegendreExponentElement, _ = new(big.Int).SetString("4000000000000087fffffffffffffffdbc08936e573d9190f335120d6e32697", 16)
  1159  	const sqrtExponentElement = "2000000000000043fffffffffffffffede0449b72b9ec8c8799a8906b71934c"
  1160  	_bSqrtExponentElement, _ = new(big.Int).SetString(sqrtExponentElement, 16)
  1161  }
  1162  
  1163  // Legendre returns the Legendre symbol of z (either +1, -1, or 0.)
  1164  func (z *Element) Legendre() int {
  1165  	var l Element
  1166  	// z^((q-1)/2)
  1167  	l.Exp(*z, _bLegendreExponentElement)
  1168  
  1169  	if l.IsZero() {
  1170  		return 0
  1171  	}
  1172  
  1173  	// if l == 1
  1174  	if l.IsOne() {
  1175  		return 1
  1176  	}
  1177  	return -1
  1178  }
  1179  
  1180  // Sqrt z = √x (mod q)
  1181  // if the square root doesn't exist (x is not a square mod q)
  1182  // Sqrt leaves z unchanged and returns nil
  1183  func (z *Element) Sqrt(x *Element) *Element {
  1184  	// q ≡ 3 (mod 4)
  1185  	// using  z ≡ ± x^((p+1)/4) (mod q)
  1186  	var y, square Element
  1187  	y.Exp(*x, _bSqrtExponentElement)
  1188  	// as we didn't compute the legendre symbol, ensure we found y such that y * y = x
  1189  	square.Square(&y)
  1190  	if square.Equal(x) {
  1191  		return z.Set(&y)
  1192  	}
  1193  	return nil
  1194  }
  1195  
  1196  const (
  1197  	k               = 32 // word size / 2
  1198  	signBitSelector = uint64(1) << 63
  1199  	approxLowBitsN  = k - 1
  1200  	approxHighBitsN = k + 1
  1201  )
  1202  
  1203  const (
  1204  	inversionCorrectionFactorWord0 = 8032106463353316320
  1205  	inversionCorrectionFactorWord1 = 8700016838315475554
  1206  	inversionCorrectionFactorWord2 = 5203325187556939076
  1207  	inversionCorrectionFactorWord3 = 310638733424303945
  1208  	invIterationsN                 = 18
  1209  )
  1210  
  1211  // Inverse z = x⁻¹ (mod q)
  1212  //
  1213  // if x == 0, sets and returns z = x
  1214  func (z *Element) Inverse(x *Element) *Element {
  1215  	// Implements "Optimized Binary GCD for Modular Inversion"
  1216  	// https://github.com/pornin/bingcd/blob/main/doc/bingcd.pdf
  1217  
  1218  	a := *x
  1219  	b := Element{
  1220  		q0,
  1221  		q1,
  1222  		q2,
  1223  		q3,
  1224  	} // b := q
  1225  
  1226  	u := Element{1}
  1227  
  1228  	// Update factors: we get [u; v] ← [f₀ g₀; f₁ g₁] [u; v]
  1229  	// cᵢ = fᵢ + 2³¹ - 1 + 2³² * (gᵢ + 2³¹ - 1)
  1230  	var c0, c1 int64
  1231  
  1232  	// Saved update factors to reduce the number of field multiplications
  1233  	var pf0, pf1, pg0, pg1 int64
  1234  
  1235  	var i uint
  1236  
  1237  	var v, s Element
  1238  
  1239  	// Since u,v are updated every other iteration, we must make sure we terminate after evenly many iterations
  1240  	// This also lets us get away with half as many updates to u,v
  1241  	// To make this constant-time-ish, replace the condition with i < invIterationsN
  1242  	for i = 0; i&1 == 1 || !a.IsZero(); i++ {
  1243  		n := max(a.BitLen(), b.BitLen())
  1244  		aApprox, bApprox := approximate(&a, n), approximate(&b, n)
  1245  
  1246  		// f₀, g₀, f₁, g₁ = 1, 0, 0, 1
  1247  		c0, c1 = updateFactorIdentityMatrixRow0, updateFactorIdentityMatrixRow1
  1248  
  1249  		for j := 0; j < approxLowBitsN; j++ {
  1250  
  1251  			// -2ʲ < f₀, f₁ ≤ 2ʲ
  1252  			// |f₀| + |f₁| < 2ʲ⁺¹
  1253  
  1254  			if aApprox&1 == 0 {
  1255  				aApprox /= 2
  1256  			} else {
  1257  				s, borrow := bits.Sub64(aApprox, bApprox, 0)
  1258  				if borrow == 1 {
  1259  					s = bApprox - aApprox
  1260  					bApprox = aApprox
  1261  					c0, c1 = c1, c0
  1262  					// invariants unchanged
  1263  				}
  1264  
  1265  				aApprox = s / 2
  1266  				c0 = c0 - c1
  1267  
  1268  				// Now |f₀| < 2ʲ⁺¹ ≤ 2ʲ⁺¹ (only the weaker inequality is needed, strictly speaking)
  1269  				// Started with f₀ > -2ʲ and f₁ ≤ 2ʲ, so f₀ - f₁ > -2ʲ⁺¹
  1270  				// Invariants unchanged for f₁
  1271  			}
  1272  
  1273  			c1 *= 2
  1274  			// -2ʲ⁺¹ < f₁ ≤ 2ʲ⁺¹
  1275  			// So now |f₀| + |f₁| < 2ʲ⁺²
  1276  		}
  1277  
  1278  		s = a
  1279  
  1280  		var g0 int64
  1281  		// from this point on c0 aliases for f0
  1282  		c0, g0 = updateFactorsDecompose(c0)
  1283  		aHi := a.linearCombNonModular(&s, c0, &b, g0)
  1284  		if aHi&signBitSelector != 0 {
  1285  			// if aHi < 0
  1286  			c0, g0 = -c0, -g0
  1287  			aHi = negL(&a, aHi)
  1288  		}
  1289  		// right-shift a by k-1 bits
  1290  		a[0] = (a[0] >> approxLowBitsN) | ((a[1]) << approxHighBitsN)
  1291  		a[1] = (a[1] >> approxLowBitsN) | ((a[2]) << approxHighBitsN)
  1292  		a[2] = (a[2] >> approxLowBitsN) | ((a[3]) << approxHighBitsN)
  1293  		a[3] = (a[3] >> approxLowBitsN) | (aHi << approxHighBitsN)
  1294  
  1295  		var f1 int64
  1296  		// from this point on c1 aliases for g0
  1297  		f1, c1 = updateFactorsDecompose(c1)
  1298  		bHi := b.linearCombNonModular(&s, f1, &b, c1)
  1299  		if bHi&signBitSelector != 0 {
  1300  			// if bHi < 0
  1301  			f1, c1 = -f1, -c1
  1302  			bHi = negL(&b, bHi)
  1303  		}
  1304  		// right-shift b by k-1 bits
  1305  		b[0] = (b[0] >> approxLowBitsN) | ((b[1]) << approxHighBitsN)
  1306  		b[1] = (b[1] >> approxLowBitsN) | ((b[2]) << approxHighBitsN)
  1307  		b[2] = (b[2] >> approxLowBitsN) | ((b[3]) << approxHighBitsN)
  1308  		b[3] = (b[3] >> approxLowBitsN) | (bHi << approxHighBitsN)
  1309  
  1310  		if i&1 == 1 {
  1311  			// Combine current update factors with previously stored ones
  1312  			// [F₀, G₀; F₁, G₁] ← [f₀, g₀; f₁, g₁] [pf₀, pg₀; pf₁, pg₁], with capital letters denoting new combined values
  1313  			// We get |F₀| = | f₀pf₀ + g₀pf₁ | ≤ |f₀pf₀| + |g₀pf₁| = |f₀| |pf₀| + |g₀| |pf₁| ≤ 2ᵏ⁻¹|pf₀| + 2ᵏ⁻¹|pf₁|
  1314  			// = 2ᵏ⁻¹ (|pf₀| + |pf₁|) < 2ᵏ⁻¹ 2ᵏ = 2²ᵏ⁻¹
  1315  			// So |F₀| < 2²ᵏ⁻¹ meaning it fits in a 2k-bit signed register
  1316  
  1317  			// c₀ aliases f₀, c₁ aliases g₁
  1318  			c0, g0, f1, c1 = c0*pf0+g0*pf1,
  1319  				c0*pg0+g0*pg1,
  1320  				f1*pf0+c1*pf1,
  1321  				f1*pg0+c1*pg1
  1322  
  1323  			s = u
  1324  
  1325  			// 0 ≤ u, v < 2²⁵⁵
  1326  			// |F₀|, |G₀| < 2⁶³
  1327  			u.linearComb(&u, c0, &v, g0)
  1328  			// |F₁|, |G₁| < 2⁶³
  1329  			v.linearComb(&s, f1, &v, c1)
  1330  
  1331  		} else {
  1332  			// Save update factors
  1333  			pf0, pg0, pf1, pg1 = c0, g0, f1, c1
  1334  		}
  1335  	}
  1336  
  1337  	// For every iteration that we miss, v is not being multiplied by 2ᵏ⁻²
  1338  	const pSq uint64 = 1 << (2 * (k - 1))
  1339  	a = Element{pSq}
  1340  	// If the function is constant-time ish, this loop will not run (no need to take it out explicitly)
  1341  	for ; i < invIterationsN; i += 2 {
  1342  		// could optimize further with mul by word routine or by pre-computing a table since with k=26,
  1343  		// we would multiply by pSq up to 13times;
  1344  		// on x86, the assembly routine outperforms generic code for mul by word
  1345  		// on arm64, we may loose up to ~5% for 6 limbs
  1346  		v.Mul(&v, &a)
  1347  	}
  1348  
  1349  	u.Set(x) // for correctness check
  1350  
  1351  	z.Mul(&v, &Element{
  1352  		inversionCorrectionFactorWord0,
  1353  		inversionCorrectionFactorWord1,
  1354  		inversionCorrectionFactorWord2,
  1355  		inversionCorrectionFactorWord3,
  1356  	})
  1357  
  1358  	// correctness check
  1359  	v.Mul(&u, z)
  1360  	if !v.IsOne() && !u.IsZero() {
  1361  		return z.inverseExp(u)
  1362  	}
  1363  
  1364  	return z
  1365  }
  1366  
  1367  // inverseExp computes z = x⁻¹ (mod q) = x**(q-2) (mod q)
  1368  func (z *Element) inverseExp(x Element) *Element {
  1369  	// e == q-2
  1370  	e := Modulus()
  1371  	e.Sub(e, big.NewInt(2))
  1372  
  1373  	z.Set(&x)
  1374  
  1375  	for i := e.BitLen() - 2; i >= 0; i-- {
  1376  		z.Square(z)
  1377  		if e.Bit(i) == 1 {
  1378  			z.Mul(z, &x)
  1379  		}
  1380  	}
  1381  
  1382  	return z
  1383  }
  1384  
  1385  // approximate a big number x into a single 64 bit word using its uppermost and lowermost bits
  1386  // if x fits in a word as is, no approximation necessary
  1387  func approximate(x *Element, nBits int) uint64 {
  1388  
  1389  	if nBits <= 64 {
  1390  		return x[0]
  1391  	}
  1392  
  1393  	const mask = (uint64(1) << (k - 1)) - 1 // k-1 ones
  1394  	lo := mask & x[0]
  1395  
  1396  	hiWordIndex := (nBits - 1) / 64
  1397  
  1398  	hiWordBitsAvailable := nBits - hiWordIndex*64
  1399  	hiWordBitsUsed := min(hiWordBitsAvailable, approxHighBitsN)
  1400  
  1401  	mask_ := uint64(^((1 << (hiWordBitsAvailable - hiWordBitsUsed)) - 1))
  1402  	hi := (x[hiWordIndex] & mask_) << (64 - hiWordBitsAvailable)
  1403  
  1404  	mask_ = ^(1<<(approxLowBitsN+hiWordBitsUsed) - 1)
  1405  	mid := (mask_ & x[hiWordIndex-1]) >> hiWordBitsUsed
  1406  
  1407  	return lo | mid | hi
  1408  }
  1409  
  1410  // linearComb z = xC * x + yC * y;
  1411  // 0 ≤ x, y < 2²⁵²
  1412  // |xC|, |yC| < 2⁶³
  1413  func (z *Element) linearComb(x *Element, xC int64, y *Element, yC int64) {
  1414  	// | (hi, z) | < 2 * 2⁶³ * 2²⁵² = 2³¹⁶
  1415  	// therefore | hi | < 2⁶⁰ ≤ 2⁶³
  1416  	hi := z.linearCombNonModular(x, xC, y, yC)
  1417  	z.montReduceSigned(z, hi)
  1418  }
  1419  
  1420  // montReduceSigned z = (xHi * r + x) * r⁻¹ using the SOS algorithm
  1421  // Requires |xHi| < 2⁶³. Most significant bit of xHi is the sign bit.
  1422  func (z *Element) montReduceSigned(x *Element, xHi uint64) {
  1423  	const signBitRemover = ^signBitSelector
  1424  	mustNeg := xHi&signBitSelector != 0
  1425  	// the SOS implementation requires that most significant bit is 0
  1426  	// Let X be xHi*r + x
  1427  	// If X is negative we would have initially stored it as 2⁶⁴ r + X (à la 2's complement)
  1428  	xHi &= signBitRemover
  1429  	// with this a negative X is now represented as 2⁶³ r + X
  1430  
  1431  	var t [2*Limbs - 1]uint64
  1432  	var C uint64
  1433  
  1434  	m := x[0] * qInvNeg
  1435  
  1436  	C = madd0(m, q0, x[0])
  1437  	C, t[1] = madd2(m, q1, x[1], C)
  1438  	C, t[2] = madd2(m, q2, x[2], C)
  1439  	C, t[3] = madd2(m, q3, x[3], C)
  1440  
  1441  	// m * qElement[3] ≤ (2⁶⁴ - 1) * (2⁶³ - 1) = 2¹²⁷ - 2⁶⁴ - 2⁶³ + 1
  1442  	// x[3] + C ≤ 2*(2⁶⁴ - 1) = 2⁶⁵ - 2
  1443  	// On LHS, (C, t[3]) ≤ 2¹²⁷ - 2⁶⁴ - 2⁶³ + 1 + 2⁶⁵ - 2 = 2¹²⁷ + 2⁶³ - 1
  1444  	// So on LHS, C ≤ 2⁶³
  1445  	t[4] = xHi + C
  1446  	// xHi + C < 2⁶³ + 2⁶³ = 2⁶⁴
  1447  
  1448  	// <standard SOS>
  1449  	{
  1450  		const i = 1
  1451  		m = t[i] * qInvNeg
  1452  
  1453  		C = madd0(m, q0, t[i+0])
  1454  		C, t[i+1] = madd2(m, q1, t[i+1], C)
  1455  		C, t[i+2] = madd2(m, q2, t[i+2], C)
  1456  		C, t[i+3] = madd2(m, q3, t[i+3], C)
  1457  
  1458  		t[i+Limbs] += C
  1459  	}
  1460  	{
  1461  		const i = 2
  1462  		m = t[i] * qInvNeg
  1463  
  1464  		C = madd0(m, q0, t[i+0])
  1465  		C, t[i+1] = madd2(m, q1, t[i+1], C)
  1466  		C, t[i+2] = madd2(m, q2, t[i+2], C)
  1467  		C, t[i+3] = madd2(m, q3, t[i+3], C)
  1468  
  1469  		t[i+Limbs] += C
  1470  	}
  1471  	{
  1472  		const i = 3
  1473  		m := t[i] * qInvNeg
  1474  
  1475  		C = madd0(m, q0, t[i+0])
  1476  		C, z[0] = madd2(m, q1, t[i+1], C)
  1477  		C, z[1] = madd2(m, q2, t[i+2], C)
  1478  		z[3], z[2] = madd2(m, q3, t[i+3], C)
  1479  	}
  1480  
  1481  	// if z ⩾ q → z -= q
  1482  	if !z.smallerThanModulus() {
  1483  		var b uint64
  1484  		z[0], b = bits.Sub64(z[0], q0, 0)
  1485  		z[1], b = bits.Sub64(z[1], q1, b)
  1486  		z[2], b = bits.Sub64(z[2], q2, b)
  1487  		z[3], _ = bits.Sub64(z[3], q3, b)
  1488  	}
  1489  	// </standard SOS>
  1490  
  1491  	if mustNeg {
  1492  		// We have computed ( 2⁶³ r + X ) r⁻¹ = 2⁶³ + X r⁻¹ instead
  1493  		var b uint64
  1494  		z[0], b = bits.Sub64(z[0], signBitSelector, 0)
  1495  		z[1], b = bits.Sub64(z[1], 0, b)
  1496  		z[2], b = bits.Sub64(z[2], 0, b)
  1497  		z[3], b = bits.Sub64(z[3], 0, b)
  1498  
  1499  		// Occurs iff x == 0 && xHi < 0, i.e. X = rX' for -2⁶³ ≤ X' < 0
  1500  
  1501  		if b != 0 {
  1502  			// z[3] = -1
  1503  			// negative: add q
  1504  			const neg1 = 0xFFFFFFFFFFFFFFFF
  1505  
  1506  			var carry uint64
  1507  
  1508  			z[0], carry = bits.Add64(z[0], q0, 0)
  1509  			z[1], carry = bits.Add64(z[1], q1, carry)
  1510  			z[2], carry = bits.Add64(z[2], q2, carry)
  1511  			z[3], _ = bits.Add64(neg1, q3, carry)
  1512  		}
  1513  	}
  1514  }
  1515  
  1516  const (
  1517  	updateFactorsConversionBias    int64 = 0x7fffffff7fffffff // (2³¹ - 1)(2³² + 1)
  1518  	updateFactorIdentityMatrixRow0       = 1
  1519  	updateFactorIdentityMatrixRow1       = 1 << 32
  1520  )
  1521  
  1522  func updateFactorsDecompose(c int64) (int64, int64) {
  1523  	c += updateFactorsConversionBias
  1524  	const low32BitsFilter int64 = 0xFFFFFFFF
  1525  	f := c&low32BitsFilter - 0x7FFFFFFF
  1526  	g := c>>32&low32BitsFilter - 0x7FFFFFFF
  1527  	return f, g
  1528  }
  1529  
  1530  // negL negates in place [x | xHi] and return the new most significant word xHi
  1531  func negL(x *Element, xHi uint64) uint64 {
  1532  	var b uint64
  1533  
  1534  	x[0], b = bits.Sub64(0, x[0], 0)
  1535  	x[1], b = bits.Sub64(0, x[1], b)
  1536  	x[2], b = bits.Sub64(0, x[2], b)
  1537  	x[3], b = bits.Sub64(0, x[3], b)
  1538  	xHi, _ = bits.Sub64(0, xHi, b)
  1539  
  1540  	return xHi
  1541  }
  1542  
  1543  // mulWNonModular multiplies by one word in non-montgomery, without reducing
  1544  func (z *Element) mulWNonModular(x *Element, y int64) uint64 {
  1545  
  1546  	// w := abs(y)
  1547  	m := y >> 63
  1548  	w := uint64((y ^ m) - m)
  1549  
  1550  	var c uint64
  1551  	c, z[0] = bits.Mul64(x[0], w)
  1552  	c, z[1] = madd1(x[1], w, c)
  1553  	c, z[2] = madd1(x[2], w, c)
  1554  	c, z[3] = madd1(x[3], w, c)
  1555  
  1556  	if y < 0 {
  1557  		c = negL(z, c)
  1558  	}
  1559  
  1560  	return c
  1561  }
  1562  
  1563  // linearCombNonModular computes a linear combination without modular reduction
  1564  func (z *Element) linearCombNonModular(x *Element, xC int64, y *Element, yC int64) uint64 {
  1565  	var yTimes Element
  1566  
  1567  	yHi := yTimes.mulWNonModular(y, yC)
  1568  	xHi := z.mulWNonModular(x, xC)
  1569  
  1570  	var carry uint64
  1571  	z[0], carry = bits.Add64(z[0], yTimes[0], 0)
  1572  	z[1], carry = bits.Add64(z[1], yTimes[1], carry)
  1573  	z[2], carry = bits.Add64(z[2], yTimes[2], carry)
  1574  	z[3], carry = bits.Add64(z[3], yTimes[3], carry)
  1575  
  1576  	yHi, _ = bits.Add64(xHi, yHi, carry)
  1577  
  1578  	return yHi
  1579  }