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