github.com/consensys/gnark-crypto@v0.14.0/ecc/bw6-756/internal/fptower/e3_test.go (about)

     1  package fptower
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/consensys/gnark-crypto/ecc/bw6-756/fp"
     7  	"github.com/leanovate/gopter"
     8  	"github.com/leanovate/gopter/prop"
     9  )
    10  
    11  // ------------------------------------------------------------
    12  // tests
    13  
    14  func TestE3ReceiverIsOperand(t *testing.T) {
    15  	t.Parallel()
    16  
    17  	parameters := gopter.DefaultTestParameters()
    18  	parameters.MinSuccessfulTests = 100
    19  
    20  	properties := gopter.NewProperties(parameters)
    21  
    22  	genA := GenE3()
    23  	genB := GenE3()
    24  	genfp := GenFp()
    25  
    26  	properties.Property("[BW756] Having the receiver as operand (addition) should output the same result", prop.ForAll(
    27  		func(a, b *E3) bool {
    28  			var c, d E3
    29  			d.Set(a)
    30  			c.Add(a, b)
    31  			a.Add(a, b)
    32  			b.Add(&d, b)
    33  			return a.Equal(b) && a.Equal(&c) && b.Equal(&c)
    34  		},
    35  		genA,
    36  		genB,
    37  	))
    38  
    39  	properties.Property("[BW756] Having the receiver as operand (sub) should output the same result", prop.ForAll(
    40  		func(a, b *E3) bool {
    41  			var c, d E3
    42  			d.Set(a)
    43  			c.Sub(a, b)
    44  			a.Sub(a, b)
    45  			b.Sub(&d, b)
    46  			return a.Equal(b) && a.Equal(&c) && b.Equal(&c)
    47  		},
    48  		genA,
    49  		genB,
    50  	))
    51  
    52  	properties.Property("[BW756] Having the receiver as operand (mul) should output the same result", prop.ForAll(
    53  		func(a, b *E3) bool {
    54  			var c, d E3
    55  			d.Set(a)
    56  			c.Mul(a, b)
    57  			a.Mul(a, b)
    58  			b.Mul(&d, b)
    59  			return a.Equal(b) && a.Equal(&c) && b.Equal(&c)
    60  		},
    61  		genA,
    62  		genB,
    63  	))
    64  
    65  	properties.Property("[BW756] Having the receiver as operand (square) should output the same result", prop.ForAll(
    66  		func(a *E3) bool {
    67  			var b E3
    68  			b.Square(a)
    69  			a.Square(a)
    70  			return a.Equal(&b)
    71  		},
    72  		genA,
    73  	))
    74  
    75  	properties.Property("[BW756] Having the receiver as operand (neg) should output the same result", prop.ForAll(
    76  		func(a *E3) bool {
    77  			var b E3
    78  			b.Neg(a)
    79  			a.Neg(a)
    80  			return a.Equal(&b)
    81  		},
    82  		genA,
    83  	))
    84  
    85  	properties.Property("[BW756] Having the receiver as operand (double) should output the same result", prop.ForAll(
    86  		func(a *E3) bool {
    87  			var b E3
    88  			b.Double(a)
    89  			a.Double(a)
    90  			return a.Equal(&b)
    91  		},
    92  		genA,
    93  	))
    94  
    95  	properties.Property("[BW756] Having the receiver as operand (mul by non residue) should output the same result", prop.ForAll(
    96  		func(a *E3) bool {
    97  			var b E3
    98  			b.MulByNonResidue(a)
    99  			a.MulByNonResidue(a)
   100  			return a.Equal(&b)
   101  		},
   102  		genA,
   103  	))
   104  
   105  	properties.Property("[BW756] Having the receiver as operand (Inverse) should output the same result", prop.ForAll(
   106  		func(a *E3) bool {
   107  			var b E3
   108  			b.Inverse(a)
   109  			a.Inverse(a)
   110  			return a.Equal(&b)
   111  		},
   112  		genA,
   113  	))
   114  
   115  	properties.Property("[BW756] Having the receiver as operand (mul by element) should output the same result", prop.ForAll(
   116  		func(a *E3, b fp.Element) bool {
   117  			var c E3
   118  			c.MulByElement(a, &b)
   119  			a.MulByElement(a, &b)
   120  			return a.Equal(&c)
   121  		},
   122  		genA,
   123  		genfp,
   124  	))
   125  
   126  	properties.TestingRun(t, gopter.ConsoleReporter(false))
   127  }
   128  
   129  func TestE3Ops(t *testing.T) {
   130  	t.Parallel()
   131  
   132  	parameters := gopter.DefaultTestParameters()
   133  	parameters.MinSuccessfulTests = 100
   134  
   135  	properties := gopter.NewProperties(parameters)
   136  
   137  	genA := GenE3()
   138  	genB := GenE3()
   139  	genfp := GenFp()
   140  
   141  	properties.Property("[BW756] sub & add should leave an element invariant", prop.ForAll(
   142  		func(a, b *E3) bool {
   143  			var c E3
   144  			c.Set(a)
   145  			c.Add(&c, b).Sub(&c, b)
   146  			return c.Equal(a)
   147  		},
   148  		genA,
   149  		genB,
   150  	))
   151  
   152  	properties.Property("[BW756] mul & inverse should leave an element invariant", prop.ForAll(
   153  		func(a, b *E3) bool {
   154  			var c, d E3
   155  			d.Inverse(b)
   156  			c.Set(a)
   157  			c.Mul(&c, b).Mul(&c, &d)
   158  			return c.Equal(a)
   159  		},
   160  		genA,
   161  		genB,
   162  	))
   163  
   164  	properties.Property("[BW756] inverse twice should leave an element invariant", prop.ForAll(
   165  		func(a *E3) bool {
   166  			var b E3
   167  			b.Inverse(a).Inverse(&b)
   168  			return a.Equal(&b)
   169  		},
   170  		genA,
   171  	))
   172  
   173  	properties.Property("[BW756] BatchInvertE3 should output the same result as Inverse", prop.ForAll(
   174  		func(a, b, c *E3) bool {
   175  
   176  			batch := BatchInvertE3([]E3{*a, *b, *c})
   177  			a.Inverse(a)
   178  			b.Inverse(b)
   179  			c.Inverse(c)
   180  			return a.Equal(&batch[0]) && b.Equal(&batch[1]) && c.Equal(&batch[2])
   181  		},
   182  		genA,
   183  		genA,
   184  		genA,
   185  	))
   186  
   187  	properties.Property("[BW756] neg twice should leave an element invariant", prop.ForAll(
   188  		func(a *E3) bool {
   189  			var b E3
   190  			b.Neg(a).Neg(&b)
   191  			return a.Equal(&b)
   192  		},
   193  		genA,
   194  	))
   195  
   196  	properties.Property("[BW756] square and mul should output the same result", prop.ForAll(
   197  		func(a *E3) bool {
   198  			var b, c E3
   199  			b.Mul(a, a)
   200  			c.Square(a)
   201  			return b.Equal(&c)
   202  		},
   203  		genA,
   204  	))
   205  
   206  	properties.Property("[BW756] MulByElement MulByElement inverse should leave an element invariant", prop.ForAll(
   207  		func(a *E3, b fp.Element) bool {
   208  			var c E3
   209  			var d fp.Element
   210  			d.Inverse(&b)
   211  			c.MulByElement(a, &b).MulByElement(&c, &d)
   212  			return c.Equal(a)
   213  		},
   214  		genA,
   215  		genfp,
   216  	))
   217  
   218  	properties.Property("[BW756] Double and mul by 2 should output the same result", prop.ForAll(
   219  		func(a *E3) bool {
   220  			var b E3
   221  			var c fp.Element
   222  			c.SetUint64(2)
   223  			b.Double(a)
   224  			a.MulByElement(a, &c)
   225  			return a.Equal(&b)
   226  		},
   227  		genA,
   228  	))
   229  
   230  	properties.Property("[BW756] Mulbynonres should be the same as multiplying by (0,1)", prop.ForAll(
   231  		func(a *E3) bool {
   232  			var b, c, d E3
   233  			b.A1.SetOne()
   234  			c.MulByNonResidue(a)
   235  			d.Mul(a, &b)
   236  			return c.Equal(&d)
   237  		},
   238  		genA,
   239  	))
   240  
   241  	properties.TestingRun(t, gopter.ConsoleReporter(false))
   242  }
   243  
   244  // ------------------------------------------------------------
   245  // benches
   246  
   247  func BenchmarkE3Add(b *testing.B) {
   248  	var a, c E3
   249  	_, _ = a.SetRandom()
   250  	_, _ = c.SetRandom()
   251  	b.ResetTimer()
   252  	for i := 0; i < b.N; i++ {
   253  		a.Add(&a, &c)
   254  	}
   255  }
   256  
   257  func BenchmarkE3Sub(b *testing.B) {
   258  	var a, c E3
   259  	_, _ = a.SetRandom()
   260  	_, _ = c.SetRandom()
   261  	b.ResetTimer()
   262  	for i := 0; i < b.N; i++ {
   263  		a.Sub(&a, &c)
   264  	}
   265  }
   266  
   267  func BenchmarkE3Mul(b *testing.B) {
   268  	var a, c E3
   269  	_, _ = a.SetRandom()
   270  	_, _ = c.SetRandom()
   271  	b.ResetTimer()
   272  	for i := 0; i < b.N; i++ {
   273  		a.Mul(&a, &c)
   274  	}
   275  }
   276  
   277  func BenchmarkE3MulByElement(b *testing.B) {
   278  	var a E3
   279  	var c fp.Element
   280  	_, _ = c.SetRandom()
   281  	_, _ = a.SetRandom()
   282  	b.ResetTimer()
   283  	for i := 0; i < b.N; i++ {
   284  		a.MulByElement(&a, &c)
   285  	}
   286  }
   287  
   288  func BenchmarkE3Square(b *testing.B) {
   289  	var a E3
   290  	_, _ = a.SetRandom()
   291  	b.ResetTimer()
   292  	for i := 0; i < b.N; i++ {
   293  		a.Square(&a)
   294  	}
   295  }
   296  
   297  func BenchmarkE3Inverse(b *testing.B) {
   298  	var a E3
   299  	_, _ = a.SetRandom()
   300  	b.ResetTimer()
   301  	for i := 0; i < b.N; i++ {
   302  		a.Inverse(&a)
   303  	}
   304  }
   305  
   306  func BenchmarkE3MulNonRes(b *testing.B) {
   307  	var a E3
   308  	_, _ = a.SetRandom()
   309  	b.ResetTimer()
   310  	for i := 0; i < b.N; i++ {
   311  		a.MulByNonResidue(&a)
   312  	}
   313  }