github.com/consensys/gnark-crypto@v0.14.0/field/goldilocks/element_test.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 goldilocks
    18  
    19  import (
    20  	"crypto/rand"
    21  	"encoding/json"
    22  	"fmt"
    23  	"math/big"
    24  	"math/bits"
    25  
    26  	"testing"
    27  
    28  	"github.com/leanovate/gopter"
    29  	ggen "github.com/leanovate/gopter/gen"
    30  	"github.com/leanovate/gopter/prop"
    31  
    32  	"github.com/stretchr/testify/require"
    33  )
    34  
    35  // -------------------------------------------------------------------------------------------------
    36  // benchmarks
    37  // most benchmarks are rudimentary and should sample a large number of random inputs
    38  // or be run multiple times to ensure it didn't measure the fastest path of the function
    39  
    40  var benchResElement Element
    41  
    42  func BenchmarkElementSelect(b *testing.B) {
    43  	var x, y Element
    44  	x.SetRandom()
    45  	y.SetRandom()
    46  
    47  	b.ResetTimer()
    48  	for i := 0; i < b.N; i++ {
    49  		benchResElement.Select(i%3, &x, &y)
    50  	}
    51  }
    52  
    53  func BenchmarkElementSetRandom(b *testing.B) {
    54  	var x Element
    55  	x.SetRandom()
    56  
    57  	b.ResetTimer()
    58  	for i := 0; i < b.N; i++ {
    59  		_, _ = x.SetRandom()
    60  	}
    61  }
    62  
    63  func BenchmarkElementSetBytes(b *testing.B) {
    64  	var x Element
    65  	x.SetRandom()
    66  	bb := x.Bytes()
    67  	b.ResetTimer()
    68  
    69  	for i := 0; i < b.N; i++ {
    70  		benchResElement.SetBytes(bb[:])
    71  	}
    72  
    73  }
    74  
    75  func BenchmarkElementMulByConstants(b *testing.B) {
    76  	b.Run("mulBy3", func(b *testing.B) {
    77  		benchResElement.SetRandom()
    78  		b.ResetTimer()
    79  		for i := 0; i < b.N; i++ {
    80  			MulBy3(&benchResElement)
    81  		}
    82  	})
    83  	b.Run("mulBy5", func(b *testing.B) {
    84  		benchResElement.SetRandom()
    85  		b.ResetTimer()
    86  		for i := 0; i < b.N; i++ {
    87  			MulBy5(&benchResElement)
    88  		}
    89  	})
    90  	b.Run("mulBy13", func(b *testing.B) {
    91  		benchResElement.SetRandom()
    92  		b.ResetTimer()
    93  		for i := 0; i < b.N; i++ {
    94  			MulBy13(&benchResElement)
    95  		}
    96  	})
    97  }
    98  
    99  func BenchmarkElementInverse(b *testing.B) {
   100  	var x Element
   101  	x.SetRandom()
   102  	benchResElement.SetRandom()
   103  	b.ResetTimer()
   104  
   105  	for i := 0; i < b.N; i++ {
   106  		benchResElement.Inverse(&x)
   107  	}
   108  
   109  }
   110  
   111  func BenchmarkElementButterfly(b *testing.B) {
   112  	var x Element
   113  	x.SetRandom()
   114  	benchResElement.SetRandom()
   115  	b.ResetTimer()
   116  	for i := 0; i < b.N; i++ {
   117  		Butterfly(&x, &benchResElement)
   118  	}
   119  }
   120  
   121  func BenchmarkElementExp(b *testing.B) {
   122  	var x Element
   123  	x.SetRandom()
   124  	benchResElement.SetRandom()
   125  	b1, _ := rand.Int(rand.Reader, Modulus())
   126  	b.ResetTimer()
   127  	for i := 0; i < b.N; i++ {
   128  		benchResElement.Exp(x, b1)
   129  	}
   130  }
   131  
   132  func BenchmarkElementDouble(b *testing.B) {
   133  	benchResElement.SetRandom()
   134  	b.ResetTimer()
   135  	for i := 0; i < b.N; i++ {
   136  		benchResElement.Double(&benchResElement)
   137  	}
   138  }
   139  
   140  func BenchmarkElementAdd(b *testing.B) {
   141  	var x Element
   142  	x.SetRandom()
   143  	benchResElement.SetRandom()
   144  	b.ResetTimer()
   145  	for i := 0; i < b.N; i++ {
   146  		benchResElement.Add(&x, &benchResElement)
   147  	}
   148  }
   149  
   150  func BenchmarkElementSub(b *testing.B) {
   151  	var x Element
   152  	x.SetRandom()
   153  	benchResElement.SetRandom()
   154  	b.ResetTimer()
   155  	for i := 0; i < b.N; i++ {
   156  		benchResElement.Sub(&x, &benchResElement)
   157  	}
   158  }
   159  
   160  func BenchmarkElementNeg(b *testing.B) {
   161  	benchResElement.SetRandom()
   162  	b.ResetTimer()
   163  	for i := 0; i < b.N; i++ {
   164  		benchResElement.Neg(&benchResElement)
   165  	}
   166  }
   167  
   168  func BenchmarkElementDiv(b *testing.B) {
   169  	var x Element
   170  	x.SetRandom()
   171  	benchResElement.SetRandom()
   172  	b.ResetTimer()
   173  	for i := 0; i < b.N; i++ {
   174  		benchResElement.Div(&x, &benchResElement)
   175  	}
   176  }
   177  
   178  func BenchmarkElementFromMont(b *testing.B) {
   179  	benchResElement.SetRandom()
   180  	b.ResetTimer()
   181  	for i := 0; i < b.N; i++ {
   182  		benchResElement.fromMont()
   183  	}
   184  }
   185  
   186  func BenchmarkElementSquare(b *testing.B) {
   187  	benchResElement.SetRandom()
   188  	b.ResetTimer()
   189  	for i := 0; i < b.N; i++ {
   190  		benchResElement.Square(&benchResElement)
   191  	}
   192  }
   193  
   194  func BenchmarkElementSqrt(b *testing.B) {
   195  	var a Element
   196  	a.SetUint64(4)
   197  	a.Neg(&a)
   198  	b.ResetTimer()
   199  	for i := 0; i < b.N; i++ {
   200  		benchResElement.Sqrt(&a)
   201  	}
   202  }
   203  
   204  func BenchmarkElementMul(b *testing.B) {
   205  	x := Element{
   206  		18446744065119617025,
   207  	}
   208  	benchResElement.SetOne()
   209  	b.ResetTimer()
   210  	for i := 0; i < b.N; i++ {
   211  		benchResElement.Mul(&benchResElement, &x)
   212  	}
   213  }
   214  
   215  func BenchmarkElementCmp(b *testing.B) {
   216  	x := Element{
   217  		18446744065119617025,
   218  	}
   219  	benchResElement = x
   220  	benchResElement[0] = 0
   221  	b.ResetTimer()
   222  	for i := 0; i < b.N; i++ {
   223  		benchResElement.Cmp(&x)
   224  	}
   225  }
   226  
   227  func TestElementCmp(t *testing.T) {
   228  	var x, y Element
   229  
   230  	if x.Cmp(&y) != 0 {
   231  		t.Fatal("x == y")
   232  	}
   233  
   234  	one := One()
   235  	y.Sub(&y, &one)
   236  
   237  	if x.Cmp(&y) != -1 {
   238  		t.Fatal("x < y")
   239  	}
   240  	if y.Cmp(&x) != 1 {
   241  		t.Fatal("x < y")
   242  	}
   243  
   244  	x = y
   245  	if x.Cmp(&y) != 0 {
   246  		t.Fatal("x == y")
   247  	}
   248  
   249  	x.Sub(&x, &one)
   250  	if x.Cmp(&y) != -1 {
   251  		t.Fatal("x < y")
   252  	}
   253  	if y.Cmp(&x) != 1 {
   254  		t.Fatal("x < y")
   255  	}
   256  }
   257  
   258  func TestElementNegZero(t *testing.T) {
   259  	var a, b Element
   260  	b.SetZero()
   261  	for a.IsZero() {
   262  		a.SetRandom()
   263  	}
   264  	a.Neg(&b)
   265  	if !a.IsZero() {
   266  		t.Fatal("neg(0) != 0")
   267  	}
   268  }
   269  
   270  // -------------------------------------------------------------------------------------------------
   271  // Gopter tests
   272  // most of them are generated with a template
   273  
   274  const (
   275  	nbFuzzShort = 200
   276  	nbFuzz      = 1000
   277  )
   278  
   279  // special values to be used in tests
   280  var staticTestValues []Element
   281  
   282  func init() {
   283  	staticTestValues = append(staticTestValues, Element{}) // zero
   284  	staticTestValues = append(staticTestValues, One())     // one
   285  	staticTestValues = append(staticTestValues, rSquare)   // r²
   286  	var e, one Element
   287  	one.SetOne()
   288  	e.Sub(&qElement, &one)
   289  	staticTestValues = append(staticTestValues, e) // q - 1
   290  	e.Double(&one)
   291  	staticTestValues = append(staticTestValues, e) // 2
   292  
   293  	{
   294  		a := qElement
   295  		a[0]--
   296  		staticTestValues = append(staticTestValues, a)
   297  	}
   298  	staticTestValues = append(staticTestValues, Element{0})
   299  	staticTestValues = append(staticTestValues, Element{1})
   300  	staticTestValues = append(staticTestValues, Element{2})
   301  
   302  	{
   303  		a := qElement
   304  		a[0]--
   305  		staticTestValues = append(staticTestValues, a)
   306  	}
   307  
   308  	{
   309  		a := qElement
   310  		a[0] = 0
   311  		staticTestValues = append(staticTestValues, a)
   312  	}
   313  
   314  }
   315  
   316  func TestElementReduce(t *testing.T) {
   317  	testValues := make([]Element, len(staticTestValues))
   318  	copy(testValues, staticTestValues)
   319  
   320  	for i := range testValues {
   321  		s := testValues[i]
   322  		expected := s
   323  		reduce(&s)
   324  		_reduceGeneric(&expected)
   325  		if !s.Equal(&expected) {
   326  			t.Fatal("reduce failed: asm and generic impl don't match")
   327  		}
   328  	}
   329  
   330  	t.Parallel()
   331  	parameters := gopter.DefaultTestParameters()
   332  	if testing.Short() {
   333  		parameters.MinSuccessfulTests = nbFuzzShort
   334  	} else {
   335  		parameters.MinSuccessfulTests = nbFuzz
   336  	}
   337  
   338  	properties := gopter.NewProperties(parameters)
   339  
   340  	genA := genFull()
   341  
   342  	properties.Property("reduce should output a result smaller than modulus", prop.ForAll(
   343  		func(a Element) bool {
   344  			b := a
   345  			reduce(&a)
   346  			_reduceGeneric(&b)
   347  			return a.smallerThanModulus() && a.Equal(&b)
   348  		},
   349  		genA,
   350  	))
   351  
   352  	properties.TestingRun(t, gopter.ConsoleReporter(false))
   353  
   354  }
   355  
   356  func TestElementEqual(t *testing.T) {
   357  	t.Parallel()
   358  	parameters := gopter.DefaultTestParameters()
   359  	if testing.Short() {
   360  		parameters.MinSuccessfulTests = nbFuzzShort
   361  	} else {
   362  		parameters.MinSuccessfulTests = nbFuzz
   363  	}
   364  
   365  	properties := gopter.NewProperties(parameters)
   366  
   367  	genA := gen()
   368  	genB := gen()
   369  
   370  	properties.Property("x.Equal(&y) iff x == y; likely false for random pairs", prop.ForAll(
   371  		func(a testPairElement, b testPairElement) bool {
   372  			return a.element.Equal(&b.element) == (a.element == b.element)
   373  		},
   374  		genA,
   375  		genB,
   376  	))
   377  
   378  	properties.Property("x.Equal(&y) if x == y", prop.ForAll(
   379  		func(a testPairElement) bool {
   380  			b := a.element
   381  			return a.element.Equal(&b)
   382  		},
   383  		genA,
   384  	))
   385  
   386  	properties.TestingRun(t, gopter.ConsoleReporter(false))
   387  }
   388  
   389  func TestElementBytes(t *testing.T) {
   390  	t.Parallel()
   391  	parameters := gopter.DefaultTestParameters()
   392  	if testing.Short() {
   393  		parameters.MinSuccessfulTests = nbFuzzShort
   394  	} else {
   395  		parameters.MinSuccessfulTests = nbFuzz
   396  	}
   397  
   398  	properties := gopter.NewProperties(parameters)
   399  
   400  	genA := gen()
   401  
   402  	properties.Property("SetBytes(Bytes()) should stay constant", prop.ForAll(
   403  		func(a testPairElement) bool {
   404  			var b Element
   405  			bytes := a.element.Bytes()
   406  			b.SetBytes(bytes[:])
   407  			return a.element.Equal(&b)
   408  		},
   409  		genA,
   410  	))
   411  
   412  	properties.TestingRun(t, gopter.ConsoleReporter(false))
   413  }
   414  
   415  func TestElementInverseExp(t *testing.T) {
   416  	// inverse must be equal to exp^-2
   417  	exp := Modulus()
   418  	exp.Sub(exp, new(big.Int).SetUint64(2))
   419  
   420  	invMatchExp := func(a testPairElement) bool {
   421  		var b Element
   422  		b.Set(&a.element)
   423  		a.element.Inverse(&a.element)
   424  		b.Exp(b, exp)
   425  
   426  		return a.element.Equal(&b)
   427  	}
   428  
   429  	t.Parallel()
   430  	parameters := gopter.DefaultTestParameters()
   431  	if testing.Short() {
   432  		parameters.MinSuccessfulTests = nbFuzzShort
   433  	} else {
   434  		parameters.MinSuccessfulTests = nbFuzz
   435  	}
   436  	properties := gopter.NewProperties(parameters)
   437  	genA := gen()
   438  	properties.Property("inv == exp^-2", prop.ForAll(invMatchExp, genA))
   439  	properties.TestingRun(t, gopter.ConsoleReporter(false))
   440  
   441  	parameters.MinSuccessfulTests = 1
   442  	properties = gopter.NewProperties(parameters)
   443  	properties.Property("inv(0) == 0", prop.ForAll(invMatchExp, ggen.OneConstOf(testPairElement{})))
   444  	properties.TestingRun(t, gopter.ConsoleReporter(false))
   445  
   446  }
   447  
   448  func mulByConstant(z *Element, c uint8) {
   449  	var y Element
   450  	y.SetUint64(uint64(c))
   451  	z.Mul(z, &y)
   452  }
   453  
   454  func TestElementMulByConstants(t *testing.T) {
   455  
   456  	t.Parallel()
   457  	parameters := gopter.DefaultTestParameters()
   458  	if testing.Short() {
   459  		parameters.MinSuccessfulTests = nbFuzzShort
   460  	} else {
   461  		parameters.MinSuccessfulTests = nbFuzz
   462  	}
   463  
   464  	properties := gopter.NewProperties(parameters)
   465  
   466  	genA := gen()
   467  
   468  	implemented := []uint8{0, 1, 2, 3, 5, 13}
   469  	properties.Property("mulByConstant", prop.ForAll(
   470  		func(a testPairElement) bool {
   471  			for _, c := range implemented {
   472  				var constant Element
   473  				constant.SetUint64(uint64(c))
   474  
   475  				b := a.element
   476  				b.Mul(&b, &constant)
   477  
   478  				aa := a.element
   479  				mulByConstant(&aa, c)
   480  
   481  				if !aa.Equal(&b) {
   482  					return false
   483  				}
   484  			}
   485  
   486  			return true
   487  		},
   488  		genA,
   489  	))
   490  
   491  	properties.Property("MulBy3(x) == Mul(x, 3)", prop.ForAll(
   492  		func(a testPairElement) bool {
   493  			var constant Element
   494  			constant.SetUint64(3)
   495  
   496  			b := a.element
   497  			b.Mul(&b, &constant)
   498  
   499  			MulBy3(&a.element)
   500  
   501  			return a.element.Equal(&b)
   502  		},
   503  		genA,
   504  	))
   505  
   506  	properties.Property("MulBy5(x) == Mul(x, 5)", prop.ForAll(
   507  		func(a testPairElement) bool {
   508  			var constant Element
   509  			constant.SetUint64(5)
   510  
   511  			b := a.element
   512  			b.Mul(&b, &constant)
   513  
   514  			MulBy5(&a.element)
   515  
   516  			return a.element.Equal(&b)
   517  		},
   518  		genA,
   519  	))
   520  
   521  	properties.Property("MulBy13(x) == Mul(x, 13)", prop.ForAll(
   522  		func(a testPairElement) bool {
   523  			var constant Element
   524  			constant.SetUint64(13)
   525  
   526  			b := a.element
   527  			b.Mul(&b, &constant)
   528  
   529  			MulBy13(&a.element)
   530  
   531  			return a.element.Equal(&b)
   532  		},
   533  		genA,
   534  	))
   535  
   536  	properties.TestingRun(t, gopter.ConsoleReporter(false))
   537  
   538  }
   539  
   540  func TestElementLegendre(t *testing.T) {
   541  	t.Parallel()
   542  	parameters := gopter.DefaultTestParameters()
   543  	if testing.Short() {
   544  		parameters.MinSuccessfulTests = nbFuzzShort
   545  	} else {
   546  		parameters.MinSuccessfulTests = nbFuzz
   547  	}
   548  
   549  	properties := gopter.NewProperties(parameters)
   550  
   551  	genA := gen()
   552  
   553  	properties.Property("legendre should output same result than big.Int.Jacobi", prop.ForAll(
   554  		func(a testPairElement) bool {
   555  			return a.element.Legendre() == big.Jacobi(&a.bigint, Modulus())
   556  		},
   557  		genA,
   558  	))
   559  
   560  	properties.TestingRun(t, gopter.ConsoleReporter(false))
   561  
   562  }
   563  
   564  func TestElementBitLen(t *testing.T) {
   565  	t.Parallel()
   566  	parameters := gopter.DefaultTestParameters()
   567  	if testing.Short() {
   568  		parameters.MinSuccessfulTests = nbFuzzShort
   569  	} else {
   570  		parameters.MinSuccessfulTests = nbFuzz
   571  	}
   572  
   573  	properties := gopter.NewProperties(parameters)
   574  
   575  	genA := gen()
   576  
   577  	properties.Property("BitLen should output same result than big.Int.BitLen", prop.ForAll(
   578  		func(a testPairElement) bool {
   579  			return a.element.fromMont().BitLen() == a.bigint.BitLen()
   580  		},
   581  		genA,
   582  	))
   583  
   584  	properties.TestingRun(t, gopter.ConsoleReporter(false))
   585  
   586  }
   587  
   588  func TestElementButterflies(t *testing.T) {
   589  
   590  	t.Parallel()
   591  	parameters := gopter.DefaultTestParameters()
   592  	if testing.Short() {
   593  		parameters.MinSuccessfulTests = nbFuzzShort
   594  	} else {
   595  		parameters.MinSuccessfulTests = nbFuzz
   596  	}
   597  
   598  	properties := gopter.NewProperties(parameters)
   599  
   600  	genA := gen()
   601  
   602  	properties.Property("butterfly0 == a -b; a +b", prop.ForAll(
   603  		func(a, b testPairElement) bool {
   604  			a0, b0 := a.element, b.element
   605  
   606  			_butterflyGeneric(&a.element, &b.element)
   607  			Butterfly(&a0, &b0)
   608  
   609  			return a.element.Equal(&a0) && b.element.Equal(&b0)
   610  		},
   611  		genA,
   612  		genA,
   613  	))
   614  
   615  	properties.TestingRun(t, gopter.ConsoleReporter(false))
   616  
   617  }
   618  
   619  func TestElementLexicographicallyLargest(t *testing.T) {
   620  	t.Parallel()
   621  	parameters := gopter.DefaultTestParameters()
   622  	if testing.Short() {
   623  		parameters.MinSuccessfulTests = nbFuzzShort
   624  	} else {
   625  		parameters.MinSuccessfulTests = nbFuzz
   626  	}
   627  
   628  	properties := gopter.NewProperties(parameters)
   629  
   630  	genA := gen()
   631  
   632  	properties.Property("element.Cmp should match LexicographicallyLargest output", prop.ForAll(
   633  		func(a testPairElement) bool {
   634  			var negA Element
   635  			negA.Neg(&a.element)
   636  
   637  			cmpResult := a.element.Cmp(&negA)
   638  			lResult := a.element.LexicographicallyLargest()
   639  
   640  			if lResult && cmpResult == 1 {
   641  				return true
   642  			}
   643  			if !lResult && cmpResult != 1 {
   644  				return true
   645  			}
   646  			return false
   647  		},
   648  		genA,
   649  	))
   650  
   651  	properties.TestingRun(t, gopter.ConsoleReporter(false))
   652  
   653  }
   654  
   655  func TestElementAdd(t *testing.T) {
   656  	t.Parallel()
   657  	parameters := gopter.DefaultTestParameters()
   658  	if testing.Short() {
   659  		parameters.MinSuccessfulTests = nbFuzzShort
   660  	} else {
   661  		parameters.MinSuccessfulTests = nbFuzz
   662  	}
   663  
   664  	properties := gopter.NewProperties(parameters)
   665  
   666  	genA := gen()
   667  	genB := gen()
   668  
   669  	properties.Property("Add: having the receiver as operand should output the same result", prop.ForAll(
   670  		func(a, b testPairElement) bool {
   671  			var c, d Element
   672  			d.Set(&a.element)
   673  
   674  			c.Add(&a.element, &b.element)
   675  			a.element.Add(&a.element, &b.element)
   676  			b.element.Add(&d, &b.element)
   677  
   678  			return a.element.Equal(&b.element) && a.element.Equal(&c) && b.element.Equal(&c)
   679  		},
   680  		genA,
   681  		genB,
   682  	))
   683  
   684  	properties.Property("Add: operation result must match big.Int result", prop.ForAll(
   685  		func(a, b testPairElement) bool {
   686  			{
   687  				var c Element
   688  
   689  				c.Add(&a.element, &b.element)
   690  
   691  				var d, e big.Int
   692  				d.Add(&a.bigint, &b.bigint).Mod(&d, Modulus())
   693  
   694  				if c.BigInt(&e).Cmp(&d) != 0 {
   695  					return false
   696  				}
   697  			}
   698  
   699  			// fixed elements
   700  			// a is random
   701  			// r takes special values
   702  			testValues := make([]Element, len(staticTestValues))
   703  			copy(testValues, staticTestValues)
   704  
   705  			for i := range testValues {
   706  				r := testValues[i]
   707  				var d, e, rb big.Int
   708  				r.BigInt(&rb)
   709  
   710  				var c Element
   711  				c.Add(&a.element, &r)
   712  				d.Add(&a.bigint, &rb).Mod(&d, Modulus())
   713  
   714  				if c.BigInt(&e).Cmp(&d) != 0 {
   715  					return false
   716  				}
   717  			}
   718  			return true
   719  		},
   720  		genA,
   721  		genB,
   722  	))
   723  
   724  	properties.Property("Add: operation result must be smaller than modulus", prop.ForAll(
   725  		func(a, b testPairElement) bool {
   726  			var c Element
   727  
   728  			c.Add(&a.element, &b.element)
   729  
   730  			return c.smallerThanModulus()
   731  		},
   732  		genA,
   733  		genB,
   734  	))
   735  
   736  	specialValueTest := func() {
   737  		// test special values against special values
   738  		testValues := make([]Element, len(staticTestValues))
   739  		copy(testValues, staticTestValues)
   740  
   741  		for i := range testValues {
   742  			a := testValues[i]
   743  			var aBig big.Int
   744  			a.BigInt(&aBig)
   745  			for j := range testValues {
   746  				b := testValues[j]
   747  				var bBig, d, e big.Int
   748  				b.BigInt(&bBig)
   749  
   750  				var c Element
   751  				c.Add(&a, &b)
   752  				d.Add(&aBig, &bBig).Mod(&d, Modulus())
   753  
   754  				if c.BigInt(&e).Cmp(&d) != 0 {
   755  					t.Fatal("Add failed special test values")
   756  				}
   757  			}
   758  		}
   759  	}
   760  
   761  	properties.TestingRun(t, gopter.ConsoleReporter(false))
   762  	specialValueTest()
   763  
   764  }
   765  
   766  func TestElementSub(t *testing.T) {
   767  	t.Parallel()
   768  	parameters := gopter.DefaultTestParameters()
   769  	if testing.Short() {
   770  		parameters.MinSuccessfulTests = nbFuzzShort
   771  	} else {
   772  		parameters.MinSuccessfulTests = nbFuzz
   773  	}
   774  
   775  	properties := gopter.NewProperties(parameters)
   776  
   777  	genA := gen()
   778  	genB := gen()
   779  
   780  	properties.Property("Sub: having the receiver as operand should output the same result", prop.ForAll(
   781  		func(a, b testPairElement) bool {
   782  			var c, d Element
   783  			d.Set(&a.element)
   784  
   785  			c.Sub(&a.element, &b.element)
   786  			a.element.Sub(&a.element, &b.element)
   787  			b.element.Sub(&d, &b.element)
   788  
   789  			return a.element.Equal(&b.element) && a.element.Equal(&c) && b.element.Equal(&c)
   790  		},
   791  		genA,
   792  		genB,
   793  	))
   794  
   795  	properties.Property("Sub: operation result must match big.Int result", prop.ForAll(
   796  		func(a, b testPairElement) bool {
   797  			{
   798  				var c Element
   799  
   800  				c.Sub(&a.element, &b.element)
   801  
   802  				var d, e big.Int
   803  				d.Sub(&a.bigint, &b.bigint).Mod(&d, Modulus())
   804  
   805  				if c.BigInt(&e).Cmp(&d) != 0 {
   806  					return false
   807  				}
   808  			}
   809  
   810  			// fixed elements
   811  			// a is random
   812  			// r takes special values
   813  			testValues := make([]Element, len(staticTestValues))
   814  			copy(testValues, staticTestValues)
   815  
   816  			for i := range testValues {
   817  				r := testValues[i]
   818  				var d, e, rb big.Int
   819  				r.BigInt(&rb)
   820  
   821  				var c Element
   822  				c.Sub(&a.element, &r)
   823  				d.Sub(&a.bigint, &rb).Mod(&d, Modulus())
   824  
   825  				if c.BigInt(&e).Cmp(&d) != 0 {
   826  					return false
   827  				}
   828  			}
   829  			return true
   830  		},
   831  		genA,
   832  		genB,
   833  	))
   834  
   835  	properties.Property("Sub: operation result must be smaller than modulus", prop.ForAll(
   836  		func(a, b testPairElement) bool {
   837  			var c Element
   838  
   839  			c.Sub(&a.element, &b.element)
   840  
   841  			return c.smallerThanModulus()
   842  		},
   843  		genA,
   844  		genB,
   845  	))
   846  
   847  	specialValueTest := func() {
   848  		// test special values against special values
   849  		testValues := make([]Element, len(staticTestValues))
   850  		copy(testValues, staticTestValues)
   851  
   852  		for i := range testValues {
   853  			a := testValues[i]
   854  			var aBig big.Int
   855  			a.BigInt(&aBig)
   856  			for j := range testValues {
   857  				b := testValues[j]
   858  				var bBig, d, e big.Int
   859  				b.BigInt(&bBig)
   860  
   861  				var c Element
   862  				c.Sub(&a, &b)
   863  				d.Sub(&aBig, &bBig).Mod(&d, Modulus())
   864  
   865  				if c.BigInt(&e).Cmp(&d) != 0 {
   866  					t.Fatal("Sub failed special test values")
   867  				}
   868  			}
   869  		}
   870  	}
   871  
   872  	properties.TestingRun(t, gopter.ConsoleReporter(false))
   873  	specialValueTest()
   874  
   875  }
   876  
   877  func TestElementMul(t *testing.T) {
   878  	t.Parallel()
   879  	parameters := gopter.DefaultTestParameters()
   880  	if testing.Short() {
   881  		parameters.MinSuccessfulTests = nbFuzzShort
   882  	} else {
   883  		parameters.MinSuccessfulTests = nbFuzz
   884  	}
   885  
   886  	properties := gopter.NewProperties(parameters)
   887  
   888  	genA := gen()
   889  	genB := gen()
   890  
   891  	properties.Property("Mul: having the receiver as operand should output the same result", prop.ForAll(
   892  		func(a, b testPairElement) bool {
   893  			var c, d Element
   894  			d.Set(&a.element)
   895  
   896  			c.Mul(&a.element, &b.element)
   897  			a.element.Mul(&a.element, &b.element)
   898  			b.element.Mul(&d, &b.element)
   899  
   900  			return a.element.Equal(&b.element) && a.element.Equal(&c) && b.element.Equal(&c)
   901  		},
   902  		genA,
   903  		genB,
   904  	))
   905  
   906  	properties.Property("Mul: operation result must match big.Int result", prop.ForAll(
   907  		func(a, b testPairElement) bool {
   908  			{
   909  				var c Element
   910  
   911  				c.Mul(&a.element, &b.element)
   912  
   913  				var d, e big.Int
   914  				d.Mul(&a.bigint, &b.bigint).Mod(&d, Modulus())
   915  
   916  				if c.BigInt(&e).Cmp(&d) != 0 {
   917  					return false
   918  				}
   919  			}
   920  
   921  			// fixed elements
   922  			// a is random
   923  			// r takes special values
   924  			testValues := make([]Element, len(staticTestValues))
   925  			copy(testValues, staticTestValues)
   926  
   927  			for i := range testValues {
   928  				r := testValues[i]
   929  				var d, e, rb big.Int
   930  				r.BigInt(&rb)
   931  
   932  				var c Element
   933  				c.Mul(&a.element, &r)
   934  				d.Mul(&a.bigint, &rb).Mod(&d, Modulus())
   935  
   936  				// checking generic impl against asm path
   937  				var cGeneric Element
   938  				_mulGeneric(&cGeneric, &a.element, &r)
   939  				if !cGeneric.Equal(&c) {
   940  					// need to give context to failing error.
   941  					return false
   942  				}
   943  
   944  				if c.BigInt(&e).Cmp(&d) != 0 {
   945  					return false
   946  				}
   947  			}
   948  			return true
   949  		},
   950  		genA,
   951  		genB,
   952  	))
   953  
   954  	properties.Property("Mul: operation result must be smaller than modulus", prop.ForAll(
   955  		func(a, b testPairElement) bool {
   956  			var c Element
   957  
   958  			c.Mul(&a.element, &b.element)
   959  
   960  			return c.smallerThanModulus()
   961  		},
   962  		genA,
   963  		genB,
   964  	))
   965  
   966  	properties.Property("Mul: assembly implementation must be consistent with generic one", prop.ForAll(
   967  		func(a, b testPairElement) bool {
   968  			var c, d Element
   969  			c.Mul(&a.element, &b.element)
   970  			_mulGeneric(&d, &a.element, &b.element)
   971  			return c.Equal(&d)
   972  		},
   973  		genA,
   974  		genB,
   975  	))
   976  
   977  	specialValueTest := func() {
   978  		// test special values against special values
   979  		testValues := make([]Element, len(staticTestValues))
   980  		copy(testValues, staticTestValues)
   981  
   982  		for i := range testValues {
   983  			a := testValues[i]
   984  			var aBig big.Int
   985  			a.BigInt(&aBig)
   986  			for j := range testValues {
   987  				b := testValues[j]
   988  				var bBig, d, e big.Int
   989  				b.BigInt(&bBig)
   990  
   991  				var c Element
   992  				c.Mul(&a, &b)
   993  				d.Mul(&aBig, &bBig).Mod(&d, Modulus())
   994  
   995  				// checking asm against generic impl
   996  				var cGeneric Element
   997  				_mulGeneric(&cGeneric, &a, &b)
   998  				if !cGeneric.Equal(&c) {
   999  					t.Fatal("Mul failed special test values: asm and generic impl don't match")
  1000  				}
  1001  
  1002  				if c.BigInt(&e).Cmp(&d) != 0 {
  1003  					t.Fatal("Mul failed special test values")
  1004  				}
  1005  			}
  1006  		}
  1007  	}
  1008  
  1009  	properties.TestingRun(t, gopter.ConsoleReporter(false))
  1010  	specialValueTest()
  1011  
  1012  }
  1013  
  1014  func TestElementDiv(t *testing.T) {
  1015  	t.Parallel()
  1016  	parameters := gopter.DefaultTestParameters()
  1017  	if testing.Short() {
  1018  		parameters.MinSuccessfulTests = nbFuzzShort
  1019  	} else {
  1020  		parameters.MinSuccessfulTests = nbFuzz
  1021  	}
  1022  
  1023  	properties := gopter.NewProperties(parameters)
  1024  
  1025  	genA := gen()
  1026  	genB := gen()
  1027  
  1028  	properties.Property("Div: having the receiver as operand should output the same result", prop.ForAll(
  1029  		func(a, b testPairElement) bool {
  1030  			var c, d Element
  1031  			d.Set(&a.element)
  1032  
  1033  			c.Div(&a.element, &b.element)
  1034  			a.element.Div(&a.element, &b.element)
  1035  			b.element.Div(&d, &b.element)
  1036  
  1037  			return a.element.Equal(&b.element) && a.element.Equal(&c) && b.element.Equal(&c)
  1038  		},
  1039  		genA,
  1040  		genB,
  1041  	))
  1042  
  1043  	properties.Property("Div: operation result must match big.Int result", prop.ForAll(
  1044  		func(a, b testPairElement) bool {
  1045  			{
  1046  				var c Element
  1047  
  1048  				c.Div(&a.element, &b.element)
  1049  
  1050  				var d, e big.Int
  1051  				d.ModInverse(&b.bigint, Modulus())
  1052  				d.Mul(&d, &a.bigint).Mod(&d, Modulus())
  1053  
  1054  				if c.BigInt(&e).Cmp(&d) != 0 {
  1055  					return false
  1056  				}
  1057  			}
  1058  
  1059  			// fixed elements
  1060  			// a is random
  1061  			// r takes special values
  1062  			testValues := make([]Element, len(staticTestValues))
  1063  			copy(testValues, staticTestValues)
  1064  
  1065  			for i := range testValues {
  1066  				r := testValues[i]
  1067  				var d, e, rb big.Int
  1068  				r.BigInt(&rb)
  1069  
  1070  				var c Element
  1071  				c.Div(&a.element, &r)
  1072  				d.ModInverse(&rb, Modulus())
  1073  				d.Mul(&d, &a.bigint).Mod(&d, Modulus())
  1074  
  1075  				if c.BigInt(&e).Cmp(&d) != 0 {
  1076  					return false
  1077  				}
  1078  			}
  1079  			return true
  1080  		},
  1081  		genA,
  1082  		genB,
  1083  	))
  1084  
  1085  	properties.Property("Div: operation result must be smaller than modulus", prop.ForAll(
  1086  		func(a, b testPairElement) bool {
  1087  			var c Element
  1088  
  1089  			c.Div(&a.element, &b.element)
  1090  
  1091  			return c.smallerThanModulus()
  1092  		},
  1093  		genA,
  1094  		genB,
  1095  	))
  1096  
  1097  	specialValueTest := func() {
  1098  		// test special values against special values
  1099  		testValues := make([]Element, len(staticTestValues))
  1100  		copy(testValues, staticTestValues)
  1101  
  1102  		for i := range testValues {
  1103  			a := testValues[i]
  1104  			var aBig big.Int
  1105  			a.BigInt(&aBig)
  1106  			for j := range testValues {
  1107  				b := testValues[j]
  1108  				var bBig, d, e big.Int
  1109  				b.BigInt(&bBig)
  1110  
  1111  				var c Element
  1112  				c.Div(&a, &b)
  1113  				d.ModInverse(&bBig, Modulus())
  1114  				d.Mul(&d, &aBig).Mod(&d, Modulus())
  1115  
  1116  				if c.BigInt(&e).Cmp(&d) != 0 {
  1117  					t.Fatal("Div failed special test values")
  1118  				}
  1119  			}
  1120  		}
  1121  	}
  1122  
  1123  	properties.TestingRun(t, gopter.ConsoleReporter(false))
  1124  	specialValueTest()
  1125  
  1126  }
  1127  
  1128  func TestElementExp(t *testing.T) {
  1129  	t.Parallel()
  1130  	parameters := gopter.DefaultTestParameters()
  1131  	if testing.Short() {
  1132  		parameters.MinSuccessfulTests = nbFuzzShort
  1133  	} else {
  1134  		parameters.MinSuccessfulTests = nbFuzz
  1135  	}
  1136  
  1137  	properties := gopter.NewProperties(parameters)
  1138  
  1139  	genA := gen()
  1140  	genB := gen()
  1141  
  1142  	properties.Property("Exp: having the receiver as operand should output the same result", prop.ForAll(
  1143  		func(a, b testPairElement) bool {
  1144  			var c, d Element
  1145  			d.Set(&a.element)
  1146  
  1147  			c.Exp(a.element, &b.bigint)
  1148  			a.element.Exp(a.element, &b.bigint)
  1149  			b.element.Exp(d, &b.bigint)
  1150  
  1151  			return a.element.Equal(&b.element) && a.element.Equal(&c) && b.element.Equal(&c)
  1152  		},
  1153  		genA,
  1154  		genB,
  1155  	))
  1156  
  1157  	properties.Property("Exp: operation result must match big.Int result", prop.ForAll(
  1158  		func(a, b testPairElement) bool {
  1159  			{
  1160  				var c Element
  1161  
  1162  				c.Exp(a.element, &b.bigint)
  1163  
  1164  				var d, e big.Int
  1165  				d.Exp(&a.bigint, &b.bigint, Modulus())
  1166  
  1167  				if c.BigInt(&e).Cmp(&d) != 0 {
  1168  					return false
  1169  				}
  1170  			}
  1171  
  1172  			// fixed elements
  1173  			// a is random
  1174  			// r takes special values
  1175  			testValues := make([]Element, len(staticTestValues))
  1176  			copy(testValues, staticTestValues)
  1177  
  1178  			for i := range testValues {
  1179  				r := testValues[i]
  1180  				var d, e, rb big.Int
  1181  				r.BigInt(&rb)
  1182  
  1183  				var c Element
  1184  				c.Exp(a.element, &rb)
  1185  				d.Exp(&a.bigint, &rb, Modulus())
  1186  
  1187  				if c.BigInt(&e).Cmp(&d) != 0 {
  1188  					return false
  1189  				}
  1190  			}
  1191  			return true
  1192  		},
  1193  		genA,
  1194  		genB,
  1195  	))
  1196  
  1197  	properties.Property("Exp: operation result must be smaller than modulus", prop.ForAll(
  1198  		func(a, b testPairElement) bool {
  1199  			var c Element
  1200  
  1201  			c.Exp(a.element, &b.bigint)
  1202  
  1203  			return c.smallerThanModulus()
  1204  		},
  1205  		genA,
  1206  		genB,
  1207  	))
  1208  
  1209  	specialValueTest := func() {
  1210  		// test special values against special values
  1211  		testValues := make([]Element, len(staticTestValues))
  1212  		copy(testValues, staticTestValues)
  1213  
  1214  		for i := range testValues {
  1215  			a := testValues[i]
  1216  			var aBig big.Int
  1217  			a.BigInt(&aBig)
  1218  			for j := range testValues {
  1219  				b := testValues[j]
  1220  				var bBig, d, e big.Int
  1221  				b.BigInt(&bBig)
  1222  
  1223  				var c Element
  1224  				c.Exp(a, &bBig)
  1225  				d.Exp(&aBig, &bBig, Modulus())
  1226  
  1227  				if c.BigInt(&e).Cmp(&d) != 0 {
  1228  					t.Fatal("Exp failed special test values")
  1229  				}
  1230  			}
  1231  		}
  1232  	}
  1233  
  1234  	properties.TestingRun(t, gopter.ConsoleReporter(false))
  1235  	specialValueTest()
  1236  
  1237  }
  1238  
  1239  func TestElementSquare(t *testing.T) {
  1240  	t.Parallel()
  1241  	parameters := gopter.DefaultTestParameters()
  1242  	if testing.Short() {
  1243  		parameters.MinSuccessfulTests = nbFuzzShort
  1244  	} else {
  1245  		parameters.MinSuccessfulTests = nbFuzz
  1246  	}
  1247  
  1248  	properties := gopter.NewProperties(parameters)
  1249  
  1250  	genA := gen()
  1251  
  1252  	properties.Property("Square: having the receiver as operand should output the same result", prop.ForAll(
  1253  		func(a testPairElement) bool {
  1254  
  1255  			var b Element
  1256  
  1257  			b.Square(&a.element)
  1258  			a.element.Square(&a.element)
  1259  			return a.element.Equal(&b)
  1260  		},
  1261  		genA,
  1262  	))
  1263  
  1264  	properties.Property("Square: operation result must match big.Int result", prop.ForAll(
  1265  		func(a testPairElement) bool {
  1266  			var c Element
  1267  			c.Square(&a.element)
  1268  
  1269  			var d, e big.Int
  1270  			d.Mul(&a.bigint, &a.bigint).Mod(&d, Modulus())
  1271  
  1272  			return c.BigInt(&e).Cmp(&d) == 0
  1273  		},
  1274  		genA,
  1275  	))
  1276  
  1277  	properties.Property("Square: operation result must be smaller than modulus", prop.ForAll(
  1278  		func(a testPairElement) bool {
  1279  			var c Element
  1280  			c.Square(&a.element)
  1281  			return c.smallerThanModulus()
  1282  		},
  1283  		genA,
  1284  	))
  1285  
  1286  	specialValueTest := func() {
  1287  		// test special values
  1288  		testValues := make([]Element, len(staticTestValues))
  1289  		copy(testValues, staticTestValues)
  1290  
  1291  		for i := range testValues {
  1292  			a := testValues[i]
  1293  			var aBig big.Int
  1294  			a.BigInt(&aBig)
  1295  			var c Element
  1296  			c.Square(&a)
  1297  
  1298  			var d, e big.Int
  1299  			d.Mul(&aBig, &aBig).Mod(&d, Modulus())
  1300  
  1301  			if c.BigInt(&e).Cmp(&d) != 0 {
  1302  				t.Fatal("Square failed special test values")
  1303  			}
  1304  		}
  1305  	}
  1306  
  1307  	properties.TestingRun(t, gopter.ConsoleReporter(false))
  1308  	specialValueTest()
  1309  
  1310  }
  1311  
  1312  func TestElementInverse(t *testing.T) {
  1313  	t.Parallel()
  1314  	parameters := gopter.DefaultTestParameters()
  1315  	if testing.Short() {
  1316  		parameters.MinSuccessfulTests = nbFuzzShort
  1317  	} else {
  1318  		parameters.MinSuccessfulTests = nbFuzz
  1319  	}
  1320  
  1321  	properties := gopter.NewProperties(parameters)
  1322  
  1323  	genA := gen()
  1324  
  1325  	properties.Property("Inverse: having the receiver as operand should output the same result", prop.ForAll(
  1326  		func(a testPairElement) bool {
  1327  
  1328  			var b Element
  1329  
  1330  			b.Inverse(&a.element)
  1331  			a.element.Inverse(&a.element)
  1332  			return a.element.Equal(&b)
  1333  		},
  1334  		genA,
  1335  	))
  1336  
  1337  	properties.Property("Inverse: operation result must match big.Int result", prop.ForAll(
  1338  		func(a testPairElement) bool {
  1339  			var c Element
  1340  			c.Inverse(&a.element)
  1341  
  1342  			var d, e big.Int
  1343  			d.ModInverse(&a.bigint, Modulus())
  1344  
  1345  			return c.BigInt(&e).Cmp(&d) == 0
  1346  		},
  1347  		genA,
  1348  	))
  1349  
  1350  	properties.Property("Inverse: operation result must be smaller than modulus", prop.ForAll(
  1351  		func(a testPairElement) bool {
  1352  			var c Element
  1353  			c.Inverse(&a.element)
  1354  			return c.smallerThanModulus()
  1355  		},
  1356  		genA,
  1357  	))
  1358  
  1359  	specialValueTest := func() {
  1360  		// test special values
  1361  		testValues := make([]Element, len(staticTestValues))
  1362  		copy(testValues, staticTestValues)
  1363  
  1364  		for i := range testValues {
  1365  			a := testValues[i]
  1366  			var aBig big.Int
  1367  			a.BigInt(&aBig)
  1368  			var c Element
  1369  			c.Inverse(&a)
  1370  
  1371  			var d, e big.Int
  1372  			d.ModInverse(&aBig, Modulus())
  1373  
  1374  			if c.BigInt(&e).Cmp(&d) != 0 {
  1375  				t.Fatal("Inverse failed special test values")
  1376  			}
  1377  		}
  1378  	}
  1379  
  1380  	properties.TestingRun(t, gopter.ConsoleReporter(false))
  1381  	specialValueTest()
  1382  
  1383  }
  1384  
  1385  func TestElementSqrt(t *testing.T) {
  1386  	t.Parallel()
  1387  	parameters := gopter.DefaultTestParameters()
  1388  	if testing.Short() {
  1389  		parameters.MinSuccessfulTests = nbFuzzShort
  1390  	} else {
  1391  		parameters.MinSuccessfulTests = nbFuzz
  1392  	}
  1393  
  1394  	properties := gopter.NewProperties(parameters)
  1395  
  1396  	genA := gen()
  1397  
  1398  	properties.Property("Sqrt: having the receiver as operand should output the same result", prop.ForAll(
  1399  		func(a testPairElement) bool {
  1400  
  1401  			b := a.element
  1402  
  1403  			b.Sqrt(&a.element)
  1404  			a.element.Sqrt(&a.element)
  1405  			return a.element.Equal(&b)
  1406  		},
  1407  		genA,
  1408  	))
  1409  
  1410  	properties.Property("Sqrt: operation result must match big.Int result", prop.ForAll(
  1411  		func(a testPairElement) bool {
  1412  			var c Element
  1413  			c.Sqrt(&a.element)
  1414  
  1415  			var d, e big.Int
  1416  			d.ModSqrt(&a.bigint, Modulus())
  1417  
  1418  			return c.BigInt(&e).Cmp(&d) == 0
  1419  		},
  1420  		genA,
  1421  	))
  1422  
  1423  	properties.Property("Sqrt: operation result must be smaller than modulus", prop.ForAll(
  1424  		func(a testPairElement) bool {
  1425  			var c Element
  1426  			c.Sqrt(&a.element)
  1427  			return c.smallerThanModulus()
  1428  		},
  1429  		genA,
  1430  	))
  1431  
  1432  	specialValueTest := func() {
  1433  		// test special values
  1434  		testValues := make([]Element, len(staticTestValues))
  1435  		copy(testValues, staticTestValues)
  1436  
  1437  		for i := range testValues {
  1438  			a := testValues[i]
  1439  			var aBig big.Int
  1440  			a.BigInt(&aBig)
  1441  			var c Element
  1442  			c.Sqrt(&a)
  1443  
  1444  			var d, e big.Int
  1445  			d.ModSqrt(&aBig, Modulus())
  1446  
  1447  			if c.BigInt(&e).Cmp(&d) != 0 {
  1448  				t.Fatal("Sqrt failed special test values")
  1449  			}
  1450  		}
  1451  	}
  1452  
  1453  	properties.TestingRun(t, gopter.ConsoleReporter(false))
  1454  	specialValueTest()
  1455  
  1456  }
  1457  
  1458  func TestElementDouble(t *testing.T) {
  1459  	t.Parallel()
  1460  	parameters := gopter.DefaultTestParameters()
  1461  	if testing.Short() {
  1462  		parameters.MinSuccessfulTests = nbFuzzShort
  1463  	} else {
  1464  		parameters.MinSuccessfulTests = nbFuzz
  1465  	}
  1466  
  1467  	properties := gopter.NewProperties(parameters)
  1468  
  1469  	genA := gen()
  1470  
  1471  	properties.Property("Double: having the receiver as operand should output the same result", prop.ForAll(
  1472  		func(a testPairElement) bool {
  1473  
  1474  			var b Element
  1475  
  1476  			b.Double(&a.element)
  1477  			a.element.Double(&a.element)
  1478  			return a.element.Equal(&b)
  1479  		},
  1480  		genA,
  1481  	))
  1482  
  1483  	properties.Property("Double: operation result must match big.Int result", prop.ForAll(
  1484  		func(a testPairElement) bool {
  1485  			var c Element
  1486  			c.Double(&a.element)
  1487  
  1488  			var d, e big.Int
  1489  			d.Lsh(&a.bigint, 1).Mod(&d, Modulus())
  1490  
  1491  			return c.BigInt(&e).Cmp(&d) == 0
  1492  		},
  1493  		genA,
  1494  	))
  1495  
  1496  	properties.Property("Double: operation result must be smaller than modulus", prop.ForAll(
  1497  		func(a testPairElement) bool {
  1498  			var c Element
  1499  			c.Double(&a.element)
  1500  			return c.smallerThanModulus()
  1501  		},
  1502  		genA,
  1503  	))
  1504  
  1505  	specialValueTest := func() {
  1506  		// test special values
  1507  		testValues := make([]Element, len(staticTestValues))
  1508  		copy(testValues, staticTestValues)
  1509  
  1510  		for i := range testValues {
  1511  			a := testValues[i]
  1512  			var aBig big.Int
  1513  			a.BigInt(&aBig)
  1514  			var c Element
  1515  			c.Double(&a)
  1516  
  1517  			var d, e big.Int
  1518  			d.Lsh(&aBig, 1).Mod(&d, Modulus())
  1519  
  1520  			if c.BigInt(&e).Cmp(&d) != 0 {
  1521  				t.Fatal("Double failed special test values")
  1522  			}
  1523  		}
  1524  	}
  1525  
  1526  	properties.TestingRun(t, gopter.ConsoleReporter(false))
  1527  	specialValueTest()
  1528  
  1529  }
  1530  
  1531  func TestElementNeg(t *testing.T) {
  1532  	t.Parallel()
  1533  	parameters := gopter.DefaultTestParameters()
  1534  	if testing.Short() {
  1535  		parameters.MinSuccessfulTests = nbFuzzShort
  1536  	} else {
  1537  		parameters.MinSuccessfulTests = nbFuzz
  1538  	}
  1539  
  1540  	properties := gopter.NewProperties(parameters)
  1541  
  1542  	genA := gen()
  1543  
  1544  	properties.Property("Neg: having the receiver as operand should output the same result", prop.ForAll(
  1545  		func(a testPairElement) bool {
  1546  
  1547  			var b Element
  1548  
  1549  			b.Neg(&a.element)
  1550  			a.element.Neg(&a.element)
  1551  			return a.element.Equal(&b)
  1552  		},
  1553  		genA,
  1554  	))
  1555  
  1556  	properties.Property("Neg: operation result must match big.Int result", prop.ForAll(
  1557  		func(a testPairElement) bool {
  1558  			var c Element
  1559  			c.Neg(&a.element)
  1560  
  1561  			var d, e big.Int
  1562  			d.Neg(&a.bigint).Mod(&d, Modulus())
  1563  
  1564  			return c.BigInt(&e).Cmp(&d) == 0
  1565  		},
  1566  		genA,
  1567  	))
  1568  
  1569  	properties.Property("Neg: operation result must be smaller than modulus", prop.ForAll(
  1570  		func(a testPairElement) bool {
  1571  			var c Element
  1572  			c.Neg(&a.element)
  1573  			return c.smallerThanModulus()
  1574  		},
  1575  		genA,
  1576  	))
  1577  
  1578  	specialValueTest := func() {
  1579  		// test special values
  1580  		testValues := make([]Element, len(staticTestValues))
  1581  		copy(testValues, staticTestValues)
  1582  
  1583  		for i := range testValues {
  1584  			a := testValues[i]
  1585  			var aBig big.Int
  1586  			a.BigInt(&aBig)
  1587  			var c Element
  1588  			c.Neg(&a)
  1589  
  1590  			var d, e big.Int
  1591  			d.Neg(&aBig).Mod(&d, Modulus())
  1592  
  1593  			if c.BigInt(&e).Cmp(&d) != 0 {
  1594  				t.Fatal("Neg failed special test values")
  1595  			}
  1596  		}
  1597  	}
  1598  
  1599  	properties.TestingRun(t, gopter.ConsoleReporter(false))
  1600  	specialValueTest()
  1601  
  1602  }
  1603  
  1604  func TestElementFixedExp(t *testing.T) {
  1605  
  1606  	t.Parallel()
  1607  	parameters := gopter.DefaultTestParameters()
  1608  	if testing.Short() {
  1609  		parameters.MinSuccessfulTests = nbFuzzShort
  1610  	} else {
  1611  		parameters.MinSuccessfulTests = nbFuzz
  1612  	}
  1613  
  1614  	properties := gopter.NewProperties(parameters)
  1615  
  1616  	var (
  1617  		_bLegendreExponentElement *big.Int
  1618  		_bSqrtExponentElement     *big.Int
  1619  	)
  1620  
  1621  	_bLegendreExponentElement, _ = new(big.Int).SetString("7fffffff80000000", 16)
  1622  	const sqrtExponentElement = "7fffffff"
  1623  	_bSqrtExponentElement, _ = new(big.Int).SetString(sqrtExponentElement, 16)
  1624  
  1625  	genA := gen()
  1626  
  1627  	properties.Property(fmt.Sprintf("expBySqrtExp must match Exp(%s)", sqrtExponentElement), prop.ForAll(
  1628  		func(a testPairElement) bool {
  1629  			c := a.element
  1630  			d := a.element
  1631  			c.expBySqrtExp(c)
  1632  			d.Exp(d, _bSqrtExponentElement)
  1633  			return c.Equal(&d)
  1634  		},
  1635  		genA,
  1636  	))
  1637  
  1638  	properties.Property("expByLegendreExp must match Exp(7fffffff80000000)", prop.ForAll(
  1639  		func(a testPairElement) bool {
  1640  			c := a.element
  1641  			d := a.element
  1642  			c.expByLegendreExp(c)
  1643  			d.Exp(d, _bLegendreExponentElement)
  1644  			return c.Equal(&d)
  1645  		},
  1646  		genA,
  1647  	))
  1648  
  1649  	properties.TestingRun(t, gopter.ConsoleReporter(false))
  1650  }
  1651  
  1652  func TestElementHalve(t *testing.T) {
  1653  
  1654  	t.Parallel()
  1655  	parameters := gopter.DefaultTestParameters()
  1656  	if testing.Short() {
  1657  		parameters.MinSuccessfulTests = nbFuzzShort
  1658  	} else {
  1659  		parameters.MinSuccessfulTests = nbFuzz
  1660  	}
  1661  
  1662  	properties := gopter.NewProperties(parameters)
  1663  
  1664  	genA := gen()
  1665  	var twoInv Element
  1666  	twoInv.SetUint64(2)
  1667  	twoInv.Inverse(&twoInv)
  1668  
  1669  	properties.Property("z.Halve must match z / 2", prop.ForAll(
  1670  		func(a testPairElement) bool {
  1671  			c := a.element
  1672  			d := a.element
  1673  			c.Halve()
  1674  			d.Mul(&d, &twoInv)
  1675  			return c.Equal(&d)
  1676  		},
  1677  		genA,
  1678  	))
  1679  
  1680  	properties.TestingRun(t, gopter.ConsoleReporter(false))
  1681  }
  1682  
  1683  func combineSelectionArguments(c int64, z int8) int {
  1684  	if z%3 == 0 {
  1685  		return 0
  1686  	}
  1687  	return int(c)
  1688  }
  1689  
  1690  func TestElementSelect(t *testing.T) {
  1691  	t.Parallel()
  1692  	parameters := gopter.DefaultTestParameters()
  1693  	if testing.Short() {
  1694  		parameters.MinSuccessfulTests = nbFuzzShort
  1695  	} else {
  1696  		parameters.MinSuccessfulTests = nbFuzz
  1697  	}
  1698  
  1699  	properties := gopter.NewProperties(parameters)
  1700  
  1701  	genA := genFull()
  1702  	genB := genFull()
  1703  	genC := ggen.Int64() //the condition
  1704  	genZ := ggen.Int8()  //to make zeros artificially more likely
  1705  
  1706  	properties.Property("Select: must select correctly", prop.ForAll(
  1707  		func(a, b Element, cond int64, z int8) bool {
  1708  			condC := combineSelectionArguments(cond, z)
  1709  
  1710  			var c Element
  1711  			c.Select(condC, &a, &b)
  1712  
  1713  			if condC == 0 {
  1714  				return c.Equal(&a)
  1715  			}
  1716  			return c.Equal(&b)
  1717  		},
  1718  		genA,
  1719  		genB,
  1720  		genC,
  1721  		genZ,
  1722  	))
  1723  
  1724  	properties.Property("Select: having the receiver as operand should output the same result", prop.ForAll(
  1725  		func(a, b Element, cond int64, z int8) bool {
  1726  			condC := combineSelectionArguments(cond, z)
  1727  
  1728  			var c, d Element
  1729  			d.Set(&a)
  1730  			c.Select(condC, &a, &b)
  1731  			a.Select(condC, &a, &b)
  1732  			b.Select(condC, &d, &b)
  1733  			return a.Equal(&b) && a.Equal(&c) && b.Equal(&c)
  1734  		},
  1735  		genA,
  1736  		genB,
  1737  		genC,
  1738  		genZ,
  1739  	))
  1740  
  1741  	properties.TestingRun(t, gopter.ConsoleReporter(false))
  1742  }
  1743  
  1744  func TestElementSetInt64(t *testing.T) {
  1745  
  1746  	t.Parallel()
  1747  	parameters := gopter.DefaultTestParameters()
  1748  	if testing.Short() {
  1749  		parameters.MinSuccessfulTests = nbFuzzShort
  1750  	} else {
  1751  		parameters.MinSuccessfulTests = nbFuzz
  1752  	}
  1753  
  1754  	properties := gopter.NewProperties(parameters)
  1755  
  1756  	genA := gen()
  1757  
  1758  	properties.Property("z.SetInt64 must match z.SetString", prop.ForAll(
  1759  		func(a testPairElement, v int64) bool {
  1760  			c := a.element
  1761  			d := a.element
  1762  
  1763  			c.SetInt64(v)
  1764  			d.SetString(fmt.Sprintf("%v", v))
  1765  
  1766  			return c.Equal(&d)
  1767  		},
  1768  		genA, ggen.Int64(),
  1769  	))
  1770  
  1771  	properties.TestingRun(t, gopter.ConsoleReporter(false))
  1772  }
  1773  
  1774  func TestElementSetInterface(t *testing.T) {
  1775  
  1776  	t.Parallel()
  1777  	parameters := gopter.DefaultTestParameters()
  1778  	if testing.Short() {
  1779  		parameters.MinSuccessfulTests = nbFuzzShort
  1780  	} else {
  1781  		parameters.MinSuccessfulTests = nbFuzz
  1782  	}
  1783  
  1784  	properties := gopter.NewProperties(parameters)
  1785  
  1786  	genA := gen()
  1787  	genInt := ggen.Int
  1788  	genInt8 := ggen.Int8
  1789  	genInt16 := ggen.Int16
  1790  	genInt32 := ggen.Int32
  1791  	genInt64 := ggen.Int64
  1792  
  1793  	genUint := ggen.UInt
  1794  	genUint8 := ggen.UInt8
  1795  	genUint16 := ggen.UInt16
  1796  	genUint32 := ggen.UInt32
  1797  	genUint64 := ggen.UInt64
  1798  
  1799  	properties.Property("z.SetInterface must match z.SetString with int8", prop.ForAll(
  1800  		func(a testPairElement, v int8) bool {
  1801  			c := a.element
  1802  			d := a.element
  1803  
  1804  			c.SetInterface(v)
  1805  			d.SetString(fmt.Sprintf("%v", v))
  1806  
  1807  			return c.Equal(&d)
  1808  		},
  1809  		genA, genInt8(),
  1810  	))
  1811  
  1812  	properties.Property("z.SetInterface must match z.SetString with int16", prop.ForAll(
  1813  		func(a testPairElement, v int16) bool {
  1814  			c := a.element
  1815  			d := a.element
  1816  
  1817  			c.SetInterface(v)
  1818  			d.SetString(fmt.Sprintf("%v", v))
  1819  
  1820  			return c.Equal(&d)
  1821  		},
  1822  		genA, genInt16(),
  1823  	))
  1824  
  1825  	properties.Property("z.SetInterface must match z.SetString with int32", prop.ForAll(
  1826  		func(a testPairElement, v int32) bool {
  1827  			c := a.element
  1828  			d := a.element
  1829  
  1830  			c.SetInterface(v)
  1831  			d.SetString(fmt.Sprintf("%v", v))
  1832  
  1833  			return c.Equal(&d)
  1834  		},
  1835  		genA, genInt32(),
  1836  	))
  1837  
  1838  	properties.Property("z.SetInterface must match z.SetString with int64", prop.ForAll(
  1839  		func(a testPairElement, v int64) bool {
  1840  			c := a.element
  1841  			d := a.element
  1842  
  1843  			c.SetInterface(v)
  1844  			d.SetString(fmt.Sprintf("%v", v))
  1845  
  1846  			return c.Equal(&d)
  1847  		},
  1848  		genA, genInt64(),
  1849  	))
  1850  
  1851  	properties.Property("z.SetInterface must match z.SetString with int", prop.ForAll(
  1852  		func(a testPairElement, v int) bool {
  1853  			c := a.element
  1854  			d := a.element
  1855  
  1856  			c.SetInterface(v)
  1857  			d.SetString(fmt.Sprintf("%v", v))
  1858  
  1859  			return c.Equal(&d)
  1860  		},
  1861  		genA, genInt(),
  1862  	))
  1863  
  1864  	properties.Property("z.SetInterface must match z.SetString with uint8", prop.ForAll(
  1865  		func(a testPairElement, v uint8) bool {
  1866  			c := a.element
  1867  			d := a.element
  1868  
  1869  			c.SetInterface(v)
  1870  			d.SetString(fmt.Sprintf("%v", v))
  1871  
  1872  			return c.Equal(&d)
  1873  		},
  1874  		genA, genUint8(),
  1875  	))
  1876  
  1877  	properties.Property("z.SetInterface must match z.SetString with uint16", prop.ForAll(
  1878  		func(a testPairElement, v uint16) bool {
  1879  			c := a.element
  1880  			d := a.element
  1881  
  1882  			c.SetInterface(v)
  1883  			d.SetString(fmt.Sprintf("%v", v))
  1884  
  1885  			return c.Equal(&d)
  1886  		},
  1887  		genA, genUint16(),
  1888  	))
  1889  
  1890  	properties.Property("z.SetInterface must match z.SetString with uint32", prop.ForAll(
  1891  		func(a testPairElement, v uint32) bool {
  1892  			c := a.element
  1893  			d := a.element
  1894  
  1895  			c.SetInterface(v)
  1896  			d.SetString(fmt.Sprintf("%v", v))
  1897  
  1898  			return c.Equal(&d)
  1899  		},
  1900  		genA, genUint32(),
  1901  	))
  1902  
  1903  	properties.Property("z.SetInterface must match z.SetString with uint64", prop.ForAll(
  1904  		func(a testPairElement, v uint64) bool {
  1905  			c := a.element
  1906  			d := a.element
  1907  
  1908  			c.SetInterface(v)
  1909  			d.SetString(fmt.Sprintf("%v", v))
  1910  
  1911  			return c.Equal(&d)
  1912  		},
  1913  		genA, genUint64(),
  1914  	))
  1915  
  1916  	properties.Property("z.SetInterface must match z.SetString with uint", prop.ForAll(
  1917  		func(a testPairElement, v uint) bool {
  1918  			c := a.element
  1919  			d := a.element
  1920  
  1921  			c.SetInterface(v)
  1922  			d.SetString(fmt.Sprintf("%v", v))
  1923  
  1924  			return c.Equal(&d)
  1925  		},
  1926  		genA, genUint(),
  1927  	))
  1928  
  1929  	properties.TestingRun(t, gopter.ConsoleReporter(false))
  1930  
  1931  	{
  1932  		assert := require.New(t)
  1933  		var e Element
  1934  		r, err := e.SetInterface(nil)
  1935  		assert.Nil(r)
  1936  		assert.Error(err)
  1937  
  1938  		var ptE *Element
  1939  		var ptB *big.Int
  1940  
  1941  		r, err = e.SetInterface(ptE)
  1942  		assert.Nil(r)
  1943  		assert.Error(err)
  1944  		ptE = new(Element).SetOne()
  1945  		r, err = e.SetInterface(ptE)
  1946  		assert.NoError(err)
  1947  		assert.True(r.IsOne())
  1948  
  1949  		r, err = e.SetInterface(ptB)
  1950  		assert.Nil(r)
  1951  		assert.Error(err)
  1952  
  1953  	}
  1954  }
  1955  
  1956  func TestElementNegativeExp(t *testing.T) {
  1957  	t.Parallel()
  1958  
  1959  	parameters := gopter.DefaultTestParameters()
  1960  	if testing.Short() {
  1961  		parameters.MinSuccessfulTests = nbFuzzShort
  1962  	} else {
  1963  		parameters.MinSuccessfulTests = nbFuzz
  1964  	}
  1965  
  1966  	properties := gopter.NewProperties(parameters)
  1967  
  1968  	genA := gen()
  1969  
  1970  	properties.Property("x⁻ᵏ == 1/xᵏ", prop.ForAll(
  1971  		func(a, b testPairElement) bool {
  1972  
  1973  			var nb, d, e big.Int
  1974  			nb.Neg(&b.bigint)
  1975  
  1976  			var c Element
  1977  			c.Exp(a.element, &nb)
  1978  
  1979  			d.Exp(&a.bigint, &nb, Modulus())
  1980  
  1981  			return c.BigInt(&e).Cmp(&d) == 0
  1982  		},
  1983  		genA, genA,
  1984  	))
  1985  
  1986  	properties.TestingRun(t, gopter.ConsoleReporter(false))
  1987  }
  1988  
  1989  func TestElementNewElement(t *testing.T) {
  1990  	assert := require.New(t)
  1991  
  1992  	t.Parallel()
  1993  
  1994  	e := NewElement(1)
  1995  	assert.True(e.IsOne())
  1996  
  1997  	e = NewElement(0)
  1998  	assert.True(e.IsZero())
  1999  }
  2000  
  2001  func TestElementBatchInvert(t *testing.T) {
  2002  	assert := require.New(t)
  2003  
  2004  	t.Parallel()
  2005  
  2006  	// ensure batchInvert([x]) == invert(x)
  2007  	for i := int64(-1); i <= 2; i++ {
  2008  		var e, eInv Element
  2009  		e.SetInt64(i)
  2010  		eInv.Inverse(&e)
  2011  
  2012  		a := []Element{e}
  2013  		aInv := BatchInvert(a)
  2014  
  2015  		assert.True(aInv[0].Equal(&eInv), "batchInvert != invert")
  2016  
  2017  	}
  2018  
  2019  	// test x * x⁻¹ == 1
  2020  	tData := [][]int64{
  2021  		{-1, 1, 2, 3},
  2022  		{0, -1, 1, 2, 3, 0},
  2023  		{0, -1, 1, 0, 2, 3, 0},
  2024  		{-1, 1, 0, 2, 3},
  2025  		{0, 0, 1},
  2026  		{1, 0, 0},
  2027  		{0, 0, 0},
  2028  	}
  2029  
  2030  	for _, t := range tData {
  2031  		a := make([]Element, len(t))
  2032  		for i := 0; i < len(a); i++ {
  2033  			a[i].SetInt64(t[i])
  2034  		}
  2035  
  2036  		aInv := BatchInvert(a)
  2037  
  2038  		assert.True(len(aInv) == len(a))
  2039  
  2040  		for i := 0; i < len(a); i++ {
  2041  			if a[i].IsZero() {
  2042  				assert.True(aInv[i].IsZero(), "0⁻¹ != 0")
  2043  			} else {
  2044  				assert.True(a[i].Mul(&a[i], &aInv[i]).IsOne(), "x * x⁻¹ != 1")
  2045  			}
  2046  		}
  2047  	}
  2048  
  2049  	parameters := gopter.DefaultTestParameters()
  2050  	if testing.Short() {
  2051  		parameters.MinSuccessfulTests = nbFuzzShort
  2052  	} else {
  2053  		parameters.MinSuccessfulTests = nbFuzz
  2054  	}
  2055  
  2056  	properties := gopter.NewProperties(parameters)
  2057  
  2058  	genA := gen()
  2059  
  2060  	properties.Property("batchInvert --> x * x⁻¹ == 1", prop.ForAll(
  2061  		func(tp testPairElement, r uint8) bool {
  2062  
  2063  			a := make([]Element, r)
  2064  			if r != 0 {
  2065  				a[0] = tp.element
  2066  
  2067  			}
  2068  			one := One()
  2069  			for i := 1; i < len(a); i++ {
  2070  				a[i].Add(&a[i-1], &one)
  2071  			}
  2072  
  2073  			aInv := BatchInvert(a)
  2074  
  2075  			assert.True(len(aInv) == len(a))
  2076  
  2077  			for i := 0; i < len(a); i++ {
  2078  				if a[i].IsZero() {
  2079  					if !aInv[i].IsZero() {
  2080  						return false
  2081  					}
  2082  				} else {
  2083  					if !a[i].Mul(&a[i], &aInv[i]).IsOne() {
  2084  						return false
  2085  					}
  2086  				}
  2087  			}
  2088  			return true
  2089  		},
  2090  		genA, ggen.UInt8(),
  2091  	))
  2092  
  2093  	properties.TestingRun(t, gopter.ConsoleReporter(false))
  2094  }
  2095  
  2096  func TestElementFromMont(t *testing.T) {
  2097  
  2098  	t.Parallel()
  2099  	parameters := gopter.DefaultTestParameters()
  2100  	if testing.Short() {
  2101  		parameters.MinSuccessfulTests = nbFuzzShort
  2102  	} else {
  2103  		parameters.MinSuccessfulTests = nbFuzz
  2104  	}
  2105  
  2106  	properties := gopter.NewProperties(parameters)
  2107  
  2108  	genA := gen()
  2109  
  2110  	properties.Property("Assembly implementation must be consistent with generic one", prop.ForAll(
  2111  		func(a testPairElement) bool {
  2112  			c := a.element
  2113  			d := a.element
  2114  			c.fromMont()
  2115  			_fromMontGeneric(&d)
  2116  			return c.Equal(&d)
  2117  		},
  2118  		genA,
  2119  	))
  2120  
  2121  	properties.Property("x.fromMont().toMont() == x", prop.ForAll(
  2122  		func(a testPairElement) bool {
  2123  			c := a.element
  2124  			c.fromMont().toMont()
  2125  			return c.Equal(&a.element)
  2126  		},
  2127  		genA,
  2128  	))
  2129  
  2130  	properties.TestingRun(t, gopter.ConsoleReporter(false))
  2131  }
  2132  
  2133  func TestElementJSON(t *testing.T) {
  2134  	assert := require.New(t)
  2135  
  2136  	type S struct {
  2137  		A Element
  2138  		B [3]Element
  2139  		C *Element
  2140  		D *Element
  2141  	}
  2142  
  2143  	// encode to JSON
  2144  	var s S
  2145  	s.A.SetString("-1")
  2146  	s.B[2].SetUint64(42)
  2147  	s.D = new(Element).SetUint64(8000)
  2148  
  2149  	encoded, err := json.Marshal(&s)
  2150  	assert.NoError(err)
  2151  	// we may need to adjust "42" and "8000" values for some moduli; see Text() method for more details.
  2152  	formatValue := func(v int64) string {
  2153  		var a big.Int
  2154  		a.SetInt64(v)
  2155  		a.Mod(&a, Modulus())
  2156  		const maxUint16 = 65535
  2157  		var aNeg big.Int
  2158  		aNeg.Neg(&a).Mod(&aNeg, Modulus())
  2159  		if aNeg.Uint64() != 0 && aNeg.Uint64() <= maxUint16 {
  2160  			return "-" + aNeg.Text(10)
  2161  		}
  2162  		return a.Text(10)
  2163  	}
  2164  	expected := fmt.Sprintf("{\"A\":%s,\"B\":[0,0,%s],\"C\":null,\"D\":%s}", formatValue(-1), formatValue(42), formatValue(8000))
  2165  	assert.Equal(expected, string(encoded))
  2166  
  2167  	// decode valid
  2168  	var decoded S
  2169  	err = json.Unmarshal([]byte(expected), &decoded)
  2170  	assert.NoError(err)
  2171  
  2172  	assert.Equal(s, decoded, "element -> json -> element round trip failed")
  2173  
  2174  	// decode hex and string values
  2175  	withHexValues := "{\"A\":\"-1\",\"B\":[0,\"0x00000\",\"0x2A\"],\"C\":null,\"D\":\"8000\"}"
  2176  
  2177  	var decodedS S
  2178  	err = json.Unmarshal([]byte(withHexValues), &decodedS)
  2179  	assert.NoError(err)
  2180  
  2181  	assert.Equal(s, decodedS, " json with strings  -> element  failed")
  2182  
  2183  }
  2184  
  2185  type testPairElement struct {
  2186  	element Element
  2187  	bigint  big.Int
  2188  }
  2189  
  2190  func gen() gopter.Gen {
  2191  	return func(genParams *gopter.GenParameters) *gopter.GenResult {
  2192  		var g testPairElement
  2193  
  2194  		g.element = Element{
  2195  			genParams.NextUint64(),
  2196  		}
  2197  		if qElement[0] != ^uint64(0) {
  2198  			g.element[0] %= (qElement[0] + 1)
  2199  		}
  2200  
  2201  		for !g.element.smallerThanModulus() {
  2202  			g.element = Element{
  2203  				genParams.NextUint64(),
  2204  			}
  2205  			if qElement[0] != ^uint64(0) {
  2206  				g.element[0] %= (qElement[0] + 1)
  2207  			}
  2208  		}
  2209  
  2210  		g.element.BigInt(&g.bigint)
  2211  		genResult := gopter.NewGenResult(g, gopter.NoShrinker)
  2212  		return genResult
  2213  	}
  2214  }
  2215  
  2216  func genFull() gopter.Gen {
  2217  	return func(genParams *gopter.GenParameters) *gopter.GenResult {
  2218  
  2219  		genRandomFq := func() Element {
  2220  			var g Element
  2221  
  2222  			g = Element{
  2223  				genParams.NextUint64(),
  2224  			}
  2225  
  2226  			if qElement[0] != ^uint64(0) {
  2227  				g[0] %= (qElement[0] + 1)
  2228  			}
  2229  
  2230  			for !g.smallerThanModulus() {
  2231  				g = Element{
  2232  					genParams.NextUint64(),
  2233  				}
  2234  				if qElement[0] != ^uint64(0) {
  2235  					g[0] %= (qElement[0] + 1)
  2236  				}
  2237  			}
  2238  
  2239  			return g
  2240  		}
  2241  		a := genRandomFq()
  2242  
  2243  		var carry uint64
  2244  		a[0], _ = bits.Add64(a[0], qElement[0], carry)
  2245  
  2246  		genResult := gopter.NewGenResult(a, gopter.NoShrinker)
  2247  		return genResult
  2248  	}
  2249  }