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

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