github.com/consensys/gnark-crypto@v0.14.0/internal/generator/tower/template/fq12over6over2/tests/fq2.go.tmpl (about)

     1  {{$Name := .Curve.Name}}
     2  
     3  import (
     4  	"testing"
     5  	"crypto/rand"
     6  
     7  	"github.com/consensys/gnark-crypto/ecc/{{toLower $Name}}/fp"
     8  	"github.com/leanovate/gopter"
     9  	"github.com/leanovate/gopter/prop"
    10  )
    11  
    12  // ------------------------------------------------------------
    13  // tests
    14  
    15  const (
    16  	nbFuzzShort = 10
    17  	nbFuzz = 50
    18  )
    19  
    20  func TestE2ReceiverIsOperand(t *testing.T) {
    21  
    22  	t.Parallel()
    23  	parameters := gopter.DefaultTestParameters()
    24  	if testing.Short() {
    25  		parameters.MinSuccessfulTests = nbFuzzShort
    26  	} else {
    27  		parameters.MinSuccessfulTests = nbFuzz
    28  	}
    29  
    30  	properties := gopter.NewProperties(parameters)
    31  
    32  	genA := GenE2()
    33  	genB := GenE2()
    34  	genfp := GenFp()
    35  
    36  	properties.Property("[{{ toUpper $Name}}] Having the receiver as operand (addition) should output the same result", prop.ForAll(
    37  		func(a, b *E2) bool {
    38  			var c, d E2
    39  			d.Set(a)
    40  			c.Add(a, b)
    41  			a.Add(a, b)
    42  			b.Add(&d, b)
    43  			return a.Equal(b) && a.Equal(&c) && b.Equal(&c)
    44  		},
    45  		genA,
    46  		genB,
    47  	))
    48  
    49  	properties.Property("[{{ toUpper $Name}}] Having the receiver as operand (sub) should output the same result", prop.ForAll(
    50  		func(a, b *E2) bool {
    51  			var c, d E2
    52  			d.Set(a)
    53  			c.Sub(a, b)
    54  			a.Sub(a, b)
    55  			b.Sub(&d, b)
    56  			return a.Equal(b) && a.Equal(&c) && b.Equal(&c)
    57  		},
    58  		genA,
    59  		genB,
    60  	))
    61  
    62  	properties.Property("[{{ toUpper $Name}}] Having the receiver as operand (mul) should output the same result", prop.ForAll(
    63  		func(a, b *E2) bool {
    64  			var c, d E2
    65  			d.Set(a)
    66  			c.Mul(a, b)
    67  			a.Mul(a, b)
    68  			b.Mul(&d, b)
    69  			return a.Equal(b) && a.Equal(&c) && b.Equal(&c)
    70  		},
    71  		genA,
    72  		genB,
    73  	))
    74  
    75  	properties.Property("[{{ toUpper $Name}}] Having the receiver as operand (square) should output the same result", prop.ForAll(
    76  		func(a *E2) bool {
    77  			var b E2
    78  			b.Square(a)
    79  			a.Square(a)
    80  			return a.Equal(&b)
    81  		},
    82  		genA,
    83  	))
    84  
    85  	properties.Property("[{{ toUpper $Name}}] Having the receiver as operand (neg) should output the same result", prop.ForAll(
    86  		func(a *E2) bool {
    87  			var b E2
    88  			b.Neg(a)
    89  			a.Neg(a)
    90  			return a.Equal(&b)
    91  		},
    92  		genA,
    93  	))
    94  
    95  	properties.Property("[{{ toUpper $Name}}] Having the receiver as operand (double) should output the same result", prop.ForAll(
    96  		func(a *E2) bool {
    97  			var b E2
    98  			b.Double(a)
    99  			a.Double(a)
   100  			return a.Equal(&b)
   101  		},
   102  		genA,
   103  	))
   104  
   105  	properties.Property("[{{ toUpper $Name}}] Having the receiver as operand (mul by non residue) should output the same result", prop.ForAll(
   106  		func(a *E2) bool {
   107  			var b E2
   108  			b.MulByNonResidue(a)
   109  			a.MulByNonResidue(a)
   110  			return a.Equal(&b)
   111  		},
   112  		genA,
   113  	))
   114  
   115  	properties.Property("[{{ toUpper $Name}}] Having the receiver as operand (mul by non residue inverse) should output the same result", prop.ForAll(
   116  		func(a *E2) bool {
   117  			var b E2
   118  			b.MulByNonResidueInv(a)
   119  			a.MulByNonResidueInv(a)
   120  			return a.Equal(&b)
   121  		},
   122  		genA,
   123  	))
   124  
   125  	properties.Property("[{{ toUpper $Name}}] Having the receiver as operand (Inverse) should output the same result", prop.ForAll(
   126  		func(a *E2) bool {
   127  			var b E2
   128  			b.Inverse(a)
   129  			a.Inverse(a)
   130  			return a.Equal(&b)
   131  		},
   132  		genA,
   133  	))
   134  
   135  	properties.Property("[{{ toUpper $Name}}] Having the receiver as operand (Conjugate) should output the same result", prop.ForAll(
   136  		func(a *E2) bool {
   137  			var b E2
   138  			b.Conjugate(a)
   139  			a.Conjugate(a)
   140  			return a.Equal(&b)
   141  		},
   142  		genA,
   143  	))
   144  
   145  	properties.Property("[{{ toUpper $Name}}] Having the receiver as operand (mul by element) should output the same result", prop.ForAll(
   146  		func(a *E2, b fp.Element) bool {
   147  			var c E2
   148  			c.MulByElement(a, &b)
   149  			a.MulByElement(a, &b)
   150  			return a.Equal(&c)
   151  		},
   152  		genA,
   153  		genfp,
   154  	))
   155  
   156  	properties.Property("[{{ toUpper $Name}}] Having the receiver as operand (Sqrt) should output the same result", prop.ForAll(
   157  		func(a *E2) bool {
   158  			var b, c, d, s E2
   159  
   160  			s.Square(a)
   161  			a.Set(&s)
   162  			b.Set(&s)
   163  
   164  			a.Sqrt(a)
   165  			b.Sqrt(&b)
   166  
   167  			c.Square(a)
   168  			d.Square(&b)
   169  			return c.Equal(&d)
   170  		},
   171  		genA,
   172  	))
   173  
   174  	properties.TestingRun(t, gopter.ConsoleReporter(false))
   175  
   176  
   177  }
   178  
   179  func TestE2MulMaxed(t *testing.T) {
   180  	// let's pick a and b, with maxed A0 and A1
   181  	var a,b E2
   182  	fpMaxValue := fp.Element{
   183  		{{- range $i := .Curve.Fp.NbWordsIndexesFull}}
   184  		{{index $.Curve.Fp.Q $i}},{{end}}
   185  	}
   186  	fpMaxValue[0]--
   187  
   188  	a.A0 = fpMaxValue
   189  	a.A1 = fpMaxValue
   190  	b.A0 = fpMaxValue
   191  	b.A1 = fpMaxValue
   192  
   193  
   194  
   195  	var c, d E2
   196  	d.Inverse(&b)
   197  	c.Set(&a)
   198  	c.Mul(&c, &b).Mul(&c, &d)
   199  	if !c.Equal(&a) {
   200  		t.Fatal("mul with max fp failed")
   201  	}
   202  }
   203  
   204  func TestE2Ops(t *testing.T) {
   205  
   206  	t.Parallel()
   207  	parameters := gopter.DefaultTestParameters()
   208  	if testing.Short() {
   209  		parameters.MinSuccessfulTests = nbFuzzShort
   210  	} else {
   211  		parameters.MinSuccessfulTests = nbFuzz
   212  	}
   213  
   214  	properties := gopter.NewProperties(parameters)
   215  
   216  	genA := GenE2()
   217  	genB := GenE2()
   218  	genfp := GenFp()
   219  
   220  	properties.Property("[{{ toUpper $Name }}] sub & add should leave an element invariant", prop.ForAll(
   221  		func(a, b *E2) bool {
   222  			var c E2
   223  			c.Set(a)
   224  			c.Add(&c, b).Sub(&c, b)
   225  			return c.Equal(a)
   226  		},
   227  		genA,
   228  		genB,
   229  	))
   230  
   231  	properties.Property("[{{ toUpper $Name }}] mul & inverse should leave an element invariant", prop.ForAll(
   232  		func(a, b *E2) bool {
   233  			var c, d E2
   234  			d.Inverse(b)
   235  			c.Set(a)
   236  			c.Mul(&c, b).Mul(&c, &d)
   237  			return c.Equal(a)
   238  		},
   239  		genA,
   240  		genB,
   241  	))
   242  
   243  	properties.Property("[{{ toUpper $Name }}] BatchInvertE2 should output the same result as Inverse", prop.ForAll(
   244  		func(a, b, c *E2) bool {
   245  
   246  			batch := BatchInvertE2([]E2{*a, *b, *c})
   247  			a.Inverse(a)
   248  			b.Inverse(b)
   249  			c.Inverse(c)
   250  			return a.Equal(&batch[0]) && b.Equal(&batch[1]) && c.Equal(&batch[2])
   251  		},
   252  		genA,
   253  		genA,
   254  		genA,
   255  	))
   256  
   257  	{{if or (eq $Name "bn254") (eq $Name "bls12-381")}}
   258  
   259  	properties.Property("[{{ toUpper $Name }}] mulGeneric & mul should be equal", prop.ForAll(
   260  		func(a, b *E2) bool {
   261  			var c, d E2
   262  			mulGenericE2(&c, a, b)
   263  			d.Mul(a, b)
   264  			return d.Equal(&c)
   265  		},
   266  		genA,
   267  		genB,
   268  	))
   269  
   270  	{{ end }}
   271  
   272  	properties.Property("[{{ toUpper $Name }}] inverse twice should leave an element invariant", prop.ForAll(
   273  		func(a *E2) bool {
   274  			var b E2
   275  			b.Inverse(a).Inverse(&b)
   276  			return a.Equal(&b)
   277  		},
   278  		genA,
   279  	))
   280  
   281  	properties.Property("[{{ toUpper $Name }}] neg twice should leave an element invariant", prop.ForAll(
   282  		func(a *E2) bool {
   283  			var b E2
   284  			b.Neg(a).Neg(&b)
   285  			return a.Equal(&b)
   286  		},
   287  		genA,
   288  	))
   289  
   290  	properties.Property("[{{ toUpper $Name }}] square and mul should output the same result", prop.ForAll(
   291  		func(a *E2) bool {
   292  			var b, c E2
   293  			b.Mul(a, a)
   294  			c.Square(a)
   295  			return b.Equal(&c)
   296  		},
   297  		genA,
   298  	))
   299  
   300  	properties.Property("[{{ toUpper $Name }}] MulByElement MulByElement inverse should leave an element invariant", prop.ForAll(
   301  		func(a *E2, b fp.Element) bool {
   302  			var c E2
   303  			var d fp.Element
   304  			d.Inverse(&b)
   305  			c.MulByElement(a, &b).MulByElement(&c, &d)
   306  			return c.Equal(a)
   307  		},
   308  		genA,
   309  		genfp,
   310  	))
   311  
   312  	properties.Property("[{{ toUpper $Name }}] Double and mul by 2 should output the same result", prop.ForAll(
   313  		func(a *E2) bool {
   314  			var b E2
   315  			var c fp.Element
   316  			c.SetUint64(2)
   317  			b.Double(a)
   318  			a.MulByElement(a, &c)
   319  			return a.Equal(&b)
   320  		},
   321  		genA,
   322  	))
   323  
   324  	properties.Property("[{{ toUpper $Name }}] Mulbynonres mulbynonresinv should leave the element invariant", prop.ForAll(
   325  		func(a *E2) bool {
   326  			var b E2
   327  			b.MulByNonResidue(a).MulByNonResidueInv(&b)
   328  			return a.Equal(&b)
   329  		},
   330  		genA,
   331  	))
   332  
   333  	properties.Property("[{{ toUpper $Name }}] a + pi(a), a-pi(a) should be real", prop.ForAll(
   334  		func(a *E2) bool {
   335  			var b, c, d E2
   336  			var e, f fp.Element
   337  			b.Conjugate(a)
   338  			c.Add(a, &b)
   339  			d.Sub(a, &b)
   340  			e.Double(&a.A0)
   341  			f.Double(&a.A1)
   342  			return c.A1.IsZero() && d.A0.IsZero() && e.Equal(&c.A0) && f.Equal(&d.A1)
   343  		},
   344  		genA,
   345  	))
   346  
   347  	properties.Property("[{{ toUpper $Name }}] Legendre on square should output 1", prop.ForAll(
   348  		func(a *E2) bool {
   349  			var b E2
   350  			b.Square(a)
   351  			c := b.Legendre()
   352  			return c == 1
   353  		},
   354  		genA,
   355  	))
   356  
   357  	properties.Property("[{{ toUpper $Name }}] square(sqrt) should leave an element invariant", prop.ForAll(
   358  		func(a *E2) bool {
   359  			var b, c, d, e E2
   360  			b.Square(a)
   361  			c.Sqrt(&b)
   362  			d.Square(&c)
   363  			e.Neg(a)
   364  			return (c.Equal(a) || c.Equal(&e)) && d.Equal(&b)
   365  		},
   366  		genA,
   367  	))
   368  
   369  	properties.Property("[{{ toUpper $Name }}] neg(E2) == neg(E2.A0, E2.A1)", prop.ForAll(
   370  		func(a *E2) bool {
   371  			var b, c E2
   372  			b.Neg(a)
   373  			c.A0.Neg(&a.A0)
   374  			c.A1.Neg(&a.A1)
   375  			return c.Equal(&b)
   376  		},
   377  		genA,
   378  	))
   379  
   380  	properties.Property("[{{ toUpper $Name }}] Cmp and LexicographicallyLargest should be consistent", prop.ForAll(
   381  		func(a *E2) bool {
   382  			var negA E2
   383  			negA.Neg(a)
   384  			cmpResult := a.Cmp(&negA)
   385  			lResult := a.LexicographicallyLargest()
   386  			if lResult && cmpResult == 1 {
   387  				return true
   388  			}
   389  			if !lResult && cmpResult !=1 {
   390  				return true
   391  			}
   392  			return false
   393  		},
   394  		genA,
   395  	))
   396  
   397  	properties.TestingRun(t, gopter.ConsoleReporter(false))
   398  
   399  }
   400  
   401  // ------------------------------------------------------------
   402  // benches
   403  
   404  func BenchmarkE2Add(b *testing.B) {
   405  	var a, c E2
   406  _,_=	a.SetRandom()
   407  _,_=	c.SetRandom()
   408  	b.ResetTimer()
   409  	for i := 0; i < b.N; i++ {
   410  		a.Add(&a, &c)
   411  	}
   412  }
   413  
   414  func BenchmarkE2Sub(b *testing.B) {
   415  	var a, c E2
   416  _,_=	a.SetRandom()
   417  _,_=	c.SetRandom()
   418  	b.ResetTimer()
   419  	for i := 0; i < b.N; i++ {
   420  		a.Sub(&a, &c)
   421  	}
   422  }
   423  
   424  func BenchmarkE2Mul(b *testing.B) {
   425  	var a, c E2
   426  _,_=	a.SetRandom()
   427  _,_=	c.SetRandom()
   428  	b.ResetTimer()
   429  	for i := 0; i < b.N; i++ {
   430  		a.Mul(&a, &c)
   431  	}
   432  }
   433  
   434  func BenchmarkE2MulByElement(b *testing.B) {
   435  	var a E2
   436  	var c fp.Element
   437  _,_=	c.SetRandom()
   438  _,_=	a.SetRandom()
   439  	b.ResetTimer()
   440  	for i := 0; i < b.N; i++ {
   441  		a.MulByElement(&a, &c)
   442  	}
   443  }
   444  
   445  func BenchmarkE2Square(b *testing.B) {
   446  	var a E2
   447  _,_=	a.SetRandom()
   448  	b.ResetTimer()
   449  	for i := 0; i < b.N; i++ {
   450  		a.Square(&a)
   451  	}
   452  }
   453  
   454  func BenchmarkE2Sqrt(b *testing.B) {
   455  	var a E2
   456  _,_=	a.SetRandom()
   457  	b.ResetTimer()
   458  	for i := 0; i < b.N; i++ {
   459  		a.Sqrt(&a)
   460  	}
   461  }
   462  
   463  func BenchmarkE2Exp(b *testing.B) {
   464  	var x E2
   465  _,_=	x.SetRandom()
   466  	b1, _ := rand.Int(rand.Reader, fp.Modulus())
   467  	b.ResetTimer()
   468  	for i := 0; i < b.N; i++ {
   469  		x.Exp(x, b1)
   470  	}
   471  }
   472  
   473  
   474  
   475  func BenchmarkE2Inverse(b *testing.B) {
   476  	var a E2
   477  _,_=	a.SetRandom()
   478  	b.ResetTimer()
   479  	for i := 0; i < b.N; i++ {
   480  		a.Inverse(&a)
   481  	}
   482  }
   483  
   484  func BenchmarkE2MulNonRes(b *testing.B) {
   485  	var a E2
   486  _,_=	a.SetRandom()
   487  	b.ResetTimer()
   488  	for i := 0; i < b.N; i++ {
   489  		a.MulByNonResidue(&a)
   490  	}
   491  }
   492  
   493  func BenchmarkE2MulNonResInv(b *testing.B) {
   494  	var a E2
   495  _,_=	a.SetRandom()
   496  	b.ResetTimer()
   497  	for i := 0; i < b.N; i++ {
   498  		a.MulByNonResidueInv(&a)
   499  	}
   500  }
   501  
   502  func BenchmarkE2Conjugate(b *testing.B) {
   503  	var a E2
   504  _,_=	a.SetRandom()
   505  	b.ResetTimer()
   506  	for i := 0; i < b.N; i++ {
   507  		a.Conjugate(&a)
   508  	}
   509  }
   510  {{ template "base" .}}