github.com/consensys/gnark-crypto@v0.14.0/field/generator/internal/templates/element/base.go (about)

     1  package element
     2  
     3  const Base = `
     4  
     5  import (
     6  	"math/big"
     7  	"math/bits"
     8  	"io"
     9  	"crypto/rand"
    10  	"encoding/binary"
    11  	"strconv"
    12  	"errors"
    13  	"reflect"
    14  	"strings"
    15  
    16  	"github.com/consensys/gnark-crypto/field/hash"
    17  	"github.com/consensys/gnark-crypto/field/pool"
    18  	"github.com/bits-and-blooms/bitset"
    19  )
    20  
    21  // {{.ElementName}} represents a field element stored on {{.NbWords}} words (uint64)
    22  //
    23  // {{.ElementName}} are assumed to be in Montgomery form in all methods.
    24  //
    25  // Modulus q =
    26  //
    27  // 	q[base10] = {{.Modulus}}
    28  // 	q[base16] = 0x{{.ModulusHex}}
    29  //
    30  // Warning
    31  //
    32  // 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.
    33  type {{.ElementName}} [{{.NbWords}}]uint64
    34  
    35  const (
    36  	Limbs = {{.NbWords}} 	// number of 64 bits words needed to represent a {{.ElementName}}
    37  	Bits = {{.NbBits}} 		// number of bits needed to represent a {{.ElementName}}
    38  	Bytes = {{.NbBytes}} 	// number of bytes needed to represent a {{.ElementName}}
    39  )
    40  
    41  
    42  // Field modulus q
    43  const (
    44  {{- range $i := $.NbWordsIndexesFull}}
    45  	q{{$i}} uint64 = {{index $.Q $i}}
    46  	{{- if eq $.NbWords 1}}
    47  		q uint64 = q0
    48  	{{- end}}
    49  {{- end}}
    50  )
    51  
    52  var q{{.ElementName}} = {{.ElementName}}{
    53  	{{- range $i := $.NbWordsIndexesFull}}
    54  	q{{$i}},{{end}}
    55  }
    56  
    57  var _modulus big.Int 		// q stored as big.Int
    58  
    59  // Modulus returns q as a big.Int
    60  //
    61  // 	q[base10] = {{.Modulus}}
    62  // 	q[base16] = 0x{{.ModulusHex}}
    63  func Modulus() *big.Int {
    64  	return new(big.Int).Set(&_modulus)
    65  }
    66  
    67  // q + r'.r = 1, i.e., qInvNeg = - q⁻¹ mod r
    68  // used for Montgomery reduction
    69  const qInvNeg uint64 = {{index .QInverse 0}}
    70  
    71  func init() {
    72  	_modulus.SetString("{{.ModulusHex}}", 16)
    73  }
    74  
    75  // New{{.ElementName}} returns a new {{.ElementName}} from a uint64 value
    76  //
    77  // it is equivalent to
    78  // 		var v {{.ElementName}}
    79  // 		v.SetUint64(...)
    80  func New{{.ElementName}}(v uint64) {{.ElementName}} {
    81  	z := {{.ElementName}}{v}
    82  	z.Mul(&z, &rSquare)
    83  	return z
    84  }
    85  
    86  // SetUint64 sets z to v and returns z
    87  func (z *{{.ElementName}}) SetUint64(v uint64) *{{.ElementName}} {
    88  	//  sets z LSB to v (non-Montgomery form) and convert z to Montgomery form
    89  	*z = {{.ElementName}}{v}
    90  	return z.Mul(z, &rSquare) // z.toMont()
    91  }
    92  
    93  // SetInt64 sets z to v and returns z
    94  func (z *{{.ElementName}}) SetInt64(v int64) *{{.ElementName}} {
    95  
    96  	// absolute value of v
    97  	m := v >> 63
    98  	z.SetUint64(uint64((v ^ m) - m))
    99  
   100  	if m != 0 {
   101  		// v is negative
   102  		z.Neg(z)
   103  	}
   104  
   105  	return z
   106  }
   107  
   108  // Set z = x and returns z
   109  func (z *{{.ElementName}}) Set(x *{{.ElementName}}) *{{.ElementName}} {
   110  	{{- range $i := .NbWordsIndexesFull}}
   111  		z[{{$i}}] = x[{{$i}}]
   112  	{{- end}}
   113  	return z
   114  }
   115  
   116  // SetInterface converts provided interface into {{.ElementName}}
   117  // returns an error if provided type is not supported
   118  // supported types:
   119  //  {{.ElementName}}
   120  //  *{{.ElementName}}
   121  //  uint64
   122  //  int
   123  //  string (see SetString for valid formats)
   124  //  *big.Int
   125  //  big.Int
   126  //  []byte
   127  func (z *{{.ElementName}}) SetInterface(i1 interface{}) (*{{.ElementName}}, error) {
   128  	if i1 == nil {
   129  		return nil, errors.New("can't set {{.PackageName}}.{{.ElementName}} with <nil>")
   130  	}
   131  
   132  	switch c1 := i1.(type) {
   133  	case {{.ElementName}}:
   134  		return z.Set(&c1), nil
   135  	case *{{.ElementName}}:
   136  		if c1 == nil {
   137  			return nil, errors.New("can't set {{.PackageName}}.{{.ElementName}} with <nil>")
   138  		}
   139  		return z.Set(c1), nil
   140  	case uint8:
   141  		return z.SetUint64(uint64(c1)), nil
   142  	case uint16:
   143  		return z.SetUint64(uint64(c1)), nil
   144  	case uint32:
   145  		return z.SetUint64(uint64(c1)), nil
   146  	case uint:
   147  		return z.SetUint64(uint64(c1)), nil
   148  	case uint64:
   149  		return z.SetUint64(c1), nil
   150  	case int8:
   151  		return z.SetInt64(int64(c1)), nil
   152  	case int16:
   153  		return z.SetInt64(int64(c1)), nil
   154  	case int32:
   155  		return z.SetInt64(int64(c1)), nil
   156  	case int64:
   157  		return z.SetInt64(c1), nil
   158  	case int:
   159  		return z.SetInt64(int64(c1)), nil
   160  	case string:
   161  		return z.SetString(c1)
   162  	case *big.Int:
   163  		if c1 == nil {
   164  			return nil, errors.New("can't set {{.PackageName}}.{{.ElementName}} with <nil>")
   165  		}
   166  		return z.SetBigInt(c1), nil
   167  	case big.Int:
   168  		return z.SetBigInt(&c1), nil
   169  	case []byte:
   170  		return z.SetBytes(c1), nil
   171  	default:
   172  		return nil, errors.New("can't set {{.PackageName}}.{{.ElementName}} from type " + reflect.TypeOf(i1).String())
   173  	}
   174  }
   175  
   176  // SetZero z = 0
   177  func (z *{{.ElementName}}) SetZero() *{{.ElementName}} {
   178  	{{- range $i := .NbWordsIndexesFull}}
   179  		z[{{$i}}] = 0
   180  	{{- end}}
   181  	return z
   182  }
   183  
   184  // SetOne z = 1 (in Montgomery form)
   185  func (z *{{.ElementName}}) SetOne() *{{.ElementName}} {
   186  	{{- range $i := .NbWordsIndexesFull}}
   187  		z[{{$i}}] = {{index $.One $i}}
   188  	{{- end}}
   189  	return z
   190  }
   191  
   192  
   193  // Div z = x*y⁻¹ (mod q)
   194  func (z *{{.ElementName}}) Div( x, y *{{.ElementName}}) *{{.ElementName}} {
   195  	var yInv {{.ElementName}}
   196  	yInv.Inverse( y)
   197  	z.Mul( x, &yInv)
   198  	return z
   199  }
   200  
   201  // Equal returns z == x; constant-time
   202  func (z *{{.ElementName}}) Equal(x *{{.ElementName}}) bool {
   203  	return z.NotEqual(x) == 0
   204  }
   205  
   206  // NotEqual returns 0 if and only if z == x; constant-time
   207  func (z *{{.ElementName}}) NotEqual(x *{{.ElementName}}) uint64 {
   208  return {{- range $i :=  reverse .NbWordsIndexesNoZero}}(z[{{$i}}] ^ x[{{$i}}]) | {{end}}(z[0] ^ x[0])
   209  }
   210  
   211  // IsZero returns z == 0
   212  func (z *{{.ElementName}}) IsZero() bool {
   213  	return ( {{- range $i :=  reverse .NbWordsIndexesNoZero}} z[{{$i}}] | {{end}}z[0]) == 0
   214  }
   215  
   216  // IsOne returns z == 1
   217  func (z *{{.ElementName}}) IsOne() bool {
   218  	{{- if eq .NbWords 1}}
   219  	return z[0] == {{index $.One 0}}
   220  	{{- else}}
   221  	return ( {{- range $i := reverse .NbWordsIndexesNoZero -}}{{if ne (index $.One $i) 0}}(z[{{$i}}] ^ {{index $.One $i}}) | {{else}}z[{{$i}}] | {{end}}{{- end}}(z[0] ^ {{index $.One 0}}) ) == 0
   222  	{{- end}}
   223  }
   224  
   225  // IsUint64 reports whether z can be represented as an uint64.
   226  func (z *{{.ElementName}}) IsUint64() bool {
   227  	{{- if eq .NbWords 1}}
   228  		return true
   229  	{{- else}}
   230  		zz := *z
   231  		zz.fromMont()
   232  		return zz.FitsOnOneWord()
   233  	{{- end}}
   234  }
   235  
   236  // Uint64 returns the uint64 representation of x. If x cannot be represented in a uint64, the result is undefined.
   237  func (z *{{.ElementName}}) Uint64() uint64 {
   238  	return z.Bits()[0]
   239  }
   240  
   241  // FitsOnOneWord reports whether z words (except the least significant word) are 0
   242  //
   243  // It is the responsibility of the caller to convert from Montgomery to Regular form if needed.
   244  func (z *{{.ElementName}}) FitsOnOneWord() bool {
   245  	{{- if eq .NbWords 1}}
   246  		return true
   247  	{{- else}}
   248  		return ( {{- range $i :=  reverse .NbWordsIndexesNoZero}} z[{{$i}}] {{- if ne $i 1}}|{{- end}} {{end}}) == 0
   249  	{{- end}}
   250  }
   251  
   252  // Cmp compares (lexicographic order) z and x and returns:
   253  //
   254  //   -1 if z <  x
   255  //    0 if z == x
   256  //   +1 if z >  x
   257  //
   258  func (z *{{.ElementName}}) Cmp(x *{{.ElementName}}) int {
   259  	_z := z.Bits()
   260  	_x := x.Bits()
   261  	{{- range $i := reverse $.NbWordsIndexesFull}}
   262  	if _z[{{$i}}] > _x[{{$i}}] {
   263  		return 1
   264  	} else if _z[{{$i}}] < _x[{{$i}}] {
   265  		return -1
   266  	}
   267  	{{- end}}
   268  	return 0
   269  }
   270  
   271  // LexicographicallyLargest returns true if this element is strictly lexicographically
   272  // larger than its negation, false otherwise
   273  func (z *{{.ElementName}}) LexicographicallyLargest() bool {
   274  	// adapted from github.com/zkcrypto/bls12_381
   275  	// we check if the element is larger than (q-1) / 2
   276  	// if z - (((q -1) / 2) + 1) have no underflow, then z > (q-1) / 2
   277  
   278  	_z := z.Bits()
   279  
   280  	var b uint64
   281  	_, b = bits.Sub64(_z[0], {{index .QMinusOneHalvedP 0}}, 0)
   282  	{{- range $i := .NbWordsIndexesNoZero}}
   283  		_, b = bits.Sub64(_z[{{$i}}], {{index $.QMinusOneHalvedP $i}}, b)
   284  	{{- end}}
   285  
   286  	return b == 0
   287  }
   288  
   289  // SetRandom sets z to a uniform random value in [0, q).
   290  //
   291  // This might error only if reading from crypto/rand.Reader errors,
   292  // in which case, value of z is undefined.
   293  func (z *{{.ElementName}}) SetRandom() (*{{.ElementName}}, error) {
   294  	// this code is generated for all modulus
   295  	// and derived from go/src/crypto/rand/util.go
   296  
   297  	// l is number of limbs * 8; the number of bytes needed to reconstruct {{.NbWords}} uint64
   298  	const l = {{mul 8 .NbWords}}
   299  
   300  	// bitLen is the maximum bit length needed to encode a value < q.
   301  	const bitLen = {{.NbBits}}
   302  
   303  	// k is the maximum byte length needed to encode a value < q.
   304  	const k = (bitLen + 7) / 8
   305  
   306  	// b is the number of bits in the most significant byte of q-1.
   307  	b := uint(bitLen % 8)
   308  	if b == 0 {
   309  		b = 8
   310  	}
   311  
   312  	var bytes [l]byte
   313  
   314  	for {
   315  		// note that bytes[k:l] is always 0
   316  		if _, err := io.ReadFull(rand.Reader, bytes[:k]); err != nil {
   317  			return nil, err
   318  		}
   319  
   320  		// Clear unused bits in in the most significant byte to increase probability
   321  		// that the candidate is < q.
   322  		bytes[k-1] &= uint8(int(1<<b) - 1)
   323  
   324  		{{- range $i :=  .NbWordsIndexesFull}}
   325  			{{- $k := add $i 1}}
   326  			z[{{$i}}] = binary.LittleEndian.Uint64(bytes[{{mul $i 8}}:{{mul $k 8}}])
   327  		{{- end}}
   328  
   329  		if !z.smallerThanModulus() {
   330  			continue // ignore the candidate and re-sample
   331  		}
   332  
   333  		return z, nil
   334  	}
   335  }
   336  
   337  // smallerThanModulus returns true if z < q
   338  // This is not constant time
   339  func (z *{{.ElementName}}) smallerThanModulus() bool {
   340  	{{- if eq $.NbWords 1}}
   341  		return z[0] < q
   342  	{{- else}}
   343  	return ({{- range $i := reverse .NbWordsIndexesNoZero}} z[{{$i}}] < q{{$i}} || ( z[{{$i}}] == q{{$i}} && (
   344  	{{- end}}z[0] < q0 {{- range $i :=  .NbWordsIndexesNoZero}} )) {{- end}} )
   345  	{{-  end }}
   346  }
   347  
   348  // One returns 1
   349  func One() {{.ElementName}} {
   350  	var one {{.ElementName}}
   351  	one.SetOne()
   352  	return one
   353  }
   354  
   355  // Halve sets z to z / 2 (mod q)
   356  func (z *{{.ElementName}}) Halve()  {
   357  	{{- if not (and (eq .NbWords 1) (.NoCarry))}}
   358  		var carry uint64
   359  	{{- end}}
   360  
   361  	if z[0]&1 == 1 {
   362  		{{- template "add_q" dict "all" . "V1" "z" }}
   363  	}
   364  	{{- rsh "z" .NbWords}}
   365  
   366  	{{- if not .NoCarry}}
   367  		if carry != 0 {
   368  			// when we added q, the result was larger than our available limbs
   369  			// when we shift right, we need to set the highest bit
   370  			z[{{.NbWordsLastIndex}}] |= (1 << 63)
   371  		}
   372  	{{end}}
   373  }
   374  
   375  {{ define "add_q" }}
   376  	// {{$.V1}} = {{$.V1}} + q
   377  	{{- range $i := $.all.NbWordsIndexesFull }}
   378  		{{- $carryIn := ne $i 0}}
   379  		{{- $carryOut := or (ne $i $.all.NbWordsLastIndex) (and (eq $i $.all.NbWordsLastIndex) (not $.all.NoCarry))}}
   380  		{{$.V1}}[{{$i}}], {{- if $carryOut}}carry{{- else}}_{{- end}} = bits.Add64({{$.V1}}[{{$i}}], q{{$i}}, {{- if $carryIn}}carry{{- else}}0{{- end}})
   381  	{{- end}}
   382  {{ end }}
   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 *{{.ElementName}}) fromMont() *{{.ElementName}} {
   389  	fromMont(z)
   390  	return z
   391  }
   392  
   393  // Add z = x + y (mod q)
   394  func (z *{{.ElementName}}) Add( x, y *{{.ElementName}}) *{{.ElementName}} {
   395  	{{ $hasCarry := or (not $.NoCarry) (gt $.NbWords 1)}}
   396  	{{- if $hasCarry}}
   397  		var carry uint64
   398  	{{- end}}
   399  	{{- range $i := iterate 0 $.NbWords}}
   400  		{{- $hasCarry := or (not $.NoCarry) (lt $i $.NbWordsLastIndex)}}
   401  		z[{{$i}}], {{- if $hasCarry}}carry{{- else}}_{{- end}} = bits.Add64(x[{{$i}}], y[{{$i}}], {{- if eq $i 0}}0{{- else}}carry{{- end}})
   402  	{{- end}}
   403  
   404  	{{- if eq $.NbWords 1}}
   405  		if {{- if not .NoCarry}} carry != 0 ||{{- end }} z[0] >= q {
   406  			z[0] -= q
   407  		}
   408  	{{- else}}
   409  		{{- if not .NoCarry}}
   410  			// if we overflowed the last addition, z >= q
   411  			// if z >= q, z = z - q
   412  			if carry != 0 {
   413  				var b uint64
   414  				// we overflowed, so z >= q
   415  				{{- range $i := iterate 0 $.NbWords}}
   416  					{{- $hasBorrow := lt $i $.NbWordsLastIndex}}
   417  					z[{{$i}}], {{- if $hasBorrow}}b{{- else}}_{{- end}} = bits.Sub64(z[{{$i}}], q{{$i}}, {{- if eq $i 0}}0{{- else}}b{{- end}})
   418  				{{- end}}
   419  				return z
   420  			}
   421  		{{- end}}
   422  
   423  		{{ template "reduce" .}}
   424  	{{- end}}
   425  	return z
   426  }
   427  
   428  // Double z = x + x (mod q), aka Lsh 1
   429  func (z *{{.ElementName}}) Double( x *{{.ElementName}}) *{{.ElementName}} {
   430  	{{- if eq .NbWords 1}}
   431  	if x[0] & (1 << 63) == (1 << 63) {
   432  		// if highest bit is set, then we have a carry to x + x, we shift and subtract q
   433  		z[0] = (x[0] << 1) - q
   434  	} else {
   435  		// highest bit is not set, but x + x can still be >= q
   436  		z[0] = (x[0] << 1)
   437  		if z[0] >= q {
   438  			z[0] -= q
   439  		}
   440  	}
   441  	{{- else}}
   442  	{{ $hasCarry := or (not $.NoCarry) (gt $.NbWords 1)}}
   443  	{{- if $hasCarry}}
   444  		var carry uint64
   445  	{{- end}}
   446  	{{- range $i := iterate 0 $.NbWords}}
   447  		{{- $hasCarry := or (not $.NoCarry) (lt $i $.NbWordsLastIndex)}}
   448  		z[{{$i}}], {{- if $hasCarry}}carry{{- else}}_{{- end}} = bits.Add64(x[{{$i}}], x[{{$i}}], {{- if eq $i 0}}0{{- else}}carry{{- end}})
   449  	{{- end}}
   450  	{{- if not .NoCarry}}
   451  		// if we overflowed the last addition, z >= q
   452  		// if z >= q, z = z - q
   453  		if carry != 0 {
   454  			var b uint64
   455  			// we overflowed, so z >= q
   456  			{{- range $i := iterate 0 $.NbWords}}
   457  				{{- $hasBorrow := lt $i $.NbWordsLastIndex}}
   458  				z[{{$i}}], {{- if $hasBorrow}}b{{- else}}_{{- end}} = bits.Sub64(z[{{$i}}], q{{$i}}, {{- if eq $i 0}}0{{- else}}b{{- end}})
   459  			{{- end}}
   460  			return z
   461  		}
   462  	{{- end}}
   463  
   464  	{{ template "reduce" .}}
   465  	{{- end}}
   466  	return z
   467  }
   468  
   469  
   470  // Sub z = x - y (mod q)
   471  func (z *{{.ElementName}}) Sub( x, y *{{.ElementName}}) *{{.ElementName}} {
   472  	var b uint64
   473  	z[0], b = bits.Sub64(x[0], y[0], 0)
   474  	{{- range $i := .NbWordsIndexesNoZero}}
   475  		z[{{$i}}], b = bits.Sub64(x[{{$i}}], y[{{$i}}], b)
   476  	{{- end}}
   477  	if b != 0 {
   478  		{{- if eq .NbWords 1}}
   479  			z[0] += q
   480  		{{- else}}
   481  			var c uint64
   482  			z[0], c = bits.Add64(z[0], q0, 0)
   483  			{{- range $i := .NbWordsIndexesNoZero}}
   484  				{{- if eq $i $.NbWordsLastIndex}}
   485  					z[{{$i}}], _ = bits.Add64(z[{{$i}}], q{{$i}}, c)
   486  				{{- else}}
   487  					z[{{$i}}], c = bits.Add64(z[{{$i}}], q{{$i}}, c)
   488  				{{- end}}
   489  			{{- end}}
   490  		{{- end}}
   491  	}
   492  	return z
   493  }
   494  
   495  // Neg z = q - x
   496  func (z *{{.ElementName}}) Neg( x *{{.ElementName}}) *{{.ElementName}} {
   497  	if x.IsZero() {
   498  		z.SetZero()
   499  		return z
   500  	}
   501  	{{- if eq .NbWords 1}}
   502  		z[0] = q - x[0]
   503  	{{- else}}
   504  		var borrow uint64
   505  		z[0], borrow = bits.Sub64(q0, x[0], 0)
   506  		{{- range $i := .NbWordsIndexesNoZero}}
   507  			{{- if eq $i $.NbWordsLastIndex}}
   508  				z[{{$i}}], _ = bits.Sub64(q{{$i}}, x[{{$i}}], borrow)
   509  			{{- else}}
   510  				z[{{$i}}], borrow = bits.Sub64(q{{$i}}, x[{{$i}}], borrow)
   511  			{{- end}}
   512  		{{- end}}
   513  	{{- end}}
   514  	return z
   515  }
   516  
   517  // Select is a constant-time conditional move.
   518  // If c=0, z = x0. Else z = x1
   519  func (z *{{.ElementName}}) Select(c int, x0 *{{.ElementName}}, x1 *{{.ElementName}}) *{{.ElementName}} {
   520  	cC := uint64( (int64(c) | -int64(c)) >> 63 )	// "canonicized" into: 0 if c=0, -1 otherwise
   521  	{{- range $i := .NbWordsIndexesFull }}
   522  	z[{{$i}}] = x0[{{$i}}] ^ cC & (x0[{{$i}}] ^ x1[{{$i}}])
   523  	{{- end}}
   524  	return z
   525  }
   526  
   527  // _mulGeneric is unoptimized textbook CIOS
   528  // it is a fallback solution on x86 when ADX instruction set is not available
   529  // and is used for testing purposes.
   530  func _mulGeneric(z,x,y *{{.ElementName}}) {
   531  	{{ mul_doc false }}
   532  	{{ template "mul_cios" dict "all" . "V1" "x" "V2" "y"}}
   533  	{{ template "reduce"  . }}
   534  }
   535  
   536  
   537  func _fromMontGeneric(z *{{.ElementName}}) {
   538  	// the following lines implement z = z * 1
   539  	// with a modified CIOS montgomery multiplication
   540  	// see Mul for algorithm documentation
   541  	{{- range $j := .NbWordsIndexesFull}}
   542  	{
   543  		// m = z[0]n'[0] mod W
   544  		m := z[0] * qInvNeg
   545  		C := madd0(m, q0, z[0])
   546  		{{- range $i := $.NbWordsIndexesNoZero}}
   547  			C, z[{{sub $i 1}}] = madd2(m, q{{$i}}, z[{{$i}}], C)
   548  		{{- end}}
   549  		z[{{sub $.NbWords 1}}] = C
   550  	}
   551  	{{- end}}
   552  
   553  	{{ template "reduce" .}}
   554  }
   555  
   556  func _reduceGeneric(z *{{.ElementName}})  {
   557  	{{ template "reduce"  . }}
   558  }
   559  
   560  // BatchInvert returns a new slice with every element inverted.
   561  // Uses Montgomery batch inversion trick
   562  func BatchInvert(a []{{.ElementName}}) []{{.ElementName}} {
   563  	res := make([]{{.ElementName}}, len(a))
   564  	if len(a) == 0 {
   565  		return res
   566  	}
   567  
   568  	zeroes := bitset.New(uint(len(a)))
   569  	accumulator := One()
   570  
   571  	for i:=0; i < len(a); i++ {
   572  		if a[i].IsZero() {
   573  			zeroes.Set(uint(i))
   574  			continue
   575  		}
   576  		res[i] = accumulator
   577  		accumulator.Mul(&accumulator, &a[i])
   578  	}
   579  
   580  	accumulator.Inverse(&accumulator)
   581  
   582  	for i := len(a) - 1; i >= 0; i-- {
   583  		if zeroes.Test(uint(i)) {
   584  			continue
   585  		}
   586  		res[i].Mul(&res[i], &accumulator)
   587  		accumulator.Mul(&accumulator, &a[i])
   588  	}
   589  
   590  	return res
   591  }
   592  
   593  func _butterflyGeneric(a, b *{{.ElementName}}) {
   594  	t := *a
   595  	a.Add(a, b)
   596  	b.Sub(&t, b)
   597  }
   598  
   599  // BitLen returns the minimum number of bits needed to represent z
   600  // returns 0 if z == 0
   601  func (z *{{.ElementName}}) BitLen() int {
   602  	{{- range $i := reverse .NbWordsIndexesNoZero}}
   603  	if z[{{$i}}] != 0 {
   604  		return {{mul $i 64}} + bits.Len64(z[{{$i}}])
   605  	}
   606  	{{- end}}
   607  	return bits.Len64(z[0])
   608  }
   609  
   610  // Hash msg to count prime field elements.
   611  // https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-5.2
   612  func Hash(msg, dst []byte, count int) ([]{{.ElementName}}, error) {
   613  	// 128 bits of security
   614  	// L = ceil((ceil(log2(p)) + k) / 8), where k is the security parameter = 128
   615  	const Bytes = 1 + (Bits-1)/8
   616  	const L = 16 + Bytes
   617  
   618  	lenInBytes := count * L
   619  	pseudoRandomBytes, err := hash.ExpandMsgXmd(msg, dst, lenInBytes)
   620  	if err != nil {
   621  		return nil, err
   622  	}
   623  
   624  	// get temporary big int from the pool
   625  	vv := pool.BigInt.Get()
   626  
   627  	res := make([]{{.ElementName}}, count)
   628  	for i := 0; i < count; i++ {
   629  		vv.SetBytes(pseudoRandomBytes[i*L : (i+1)*L])
   630  		res[i].SetBigInt(vv)
   631  	}
   632  
   633  	// release object into pool
   634  	pool.BigInt.Put(vv)
   635  
   636  	return res, nil
   637  }
   638  
   639  
   640  {{ define "rsh V nbWords" }}
   641  	// {{$.V}} = {{$.V}} >> 1
   642  	{{- $lastIndex := sub .nbWords 1}}
   643  	{{- range $i :=  iterate 0 $lastIndex}}
   644  		{{$.V}}[{{$i}}] = {{$.V}}[{{$i}}] >> 1 | {{$.V}}[{{(add $i 1)}}] << 63
   645  	{{- end}}
   646  	{{$.V}}[{{$lastIndex}}] >>= 1
   647  {{ end }}
   648  
   649  
   650  
   651  `