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