github.com/consensys/gnark-crypto@v0.14.0/ecc/bls24-315/internal/fptower/e4_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  package fptower
    16  
    17  import (
    18  	"testing"
    19  
    20  	"github.com/consensys/gnark-crypto/ecc/bls24-315/fp"
    21  	"github.com/leanovate/gopter"
    22  	"github.com/leanovate/gopter/prop"
    23  )
    24  
    25  // ------------------------------------------------------------
    26  // tests
    27  
    28  func TestE4ReceiverIsOperand(t *testing.T) {
    29  	t.Parallel()
    30  
    31  	parameters := gopter.DefaultTestParameters()
    32  	parameters.MinSuccessfulTests = 100
    33  
    34  	properties := gopter.NewProperties(parameters)
    35  
    36  	genA := GenE4()
    37  	genB := GenE4()
    38  
    39  	properties.Property("[BLS24-315] Having the receiver as operand (addition) should output the same result", prop.ForAll(
    40  		func(a, b *E4) bool {
    41  			var c, d E4
    42  			d.Set(a)
    43  			c.Add(a, b)
    44  			a.Add(a, b)
    45  			b.Add(&d, b)
    46  			return a.Equal(b) && a.Equal(&c) && b.Equal(&c)
    47  		},
    48  		genA,
    49  		genB,
    50  	))
    51  
    52  	properties.Property("[BLS24-315] Having the receiver as operand (sub) should output the same result", prop.ForAll(
    53  		func(a, b *E4) bool {
    54  			var c, d E4
    55  			d.Set(a)
    56  			c.Sub(a, b)
    57  			a.Sub(a, b)
    58  			b.Sub(&d, b)
    59  			return a.Equal(b) && a.Equal(&c) && b.Equal(&c)
    60  		},
    61  		genA,
    62  		genB,
    63  	))
    64  
    65  	properties.Property("[BLS24-315] Having the receiver as operand (mul) should output the same result", prop.ForAll(
    66  		func(a, b *E4) bool {
    67  			var c, d E4
    68  			d.Set(a)
    69  			c.Mul(a, b)
    70  			a.Mul(a, b)
    71  			b.Mul(&d, b)
    72  			return a.Equal(b) && a.Equal(&c) && b.Equal(&c)
    73  		},
    74  		genA,
    75  		genB,
    76  	))
    77  
    78  	properties.Property("[BLS24-315] Having the receiver as operand (square) should output the same result", prop.ForAll(
    79  		func(a *E4) bool {
    80  			var b E4
    81  			b.Square(a)
    82  			a.Square(a)
    83  			return a.Equal(&b)
    84  		},
    85  		genA,
    86  	))
    87  
    88  	properties.Property("[BLS24-315] Having the receiver as operand (double) should output the same result", prop.ForAll(
    89  		func(a *E4) bool {
    90  			var b E4
    91  			b.Double(a)
    92  			a.Double(a)
    93  			return a.Equal(&b)
    94  		},
    95  		genA,
    96  	))
    97  
    98  	properties.Property("[BLS24-315] Having the receiver as operand (mul by non residue) should output the same result", prop.ForAll(
    99  		func(a *E4) bool {
   100  			var b E4
   101  			b.MulByNonResidue(a)
   102  			a.MulByNonResidue(a)
   103  			return a.Equal(&b)
   104  		},
   105  		genA,
   106  	))
   107  
   108  	properties.Property("[BLS24-315] Having the receiver as operand (mul by non residue inverse) should output the same result", prop.ForAll(
   109  		func(a *E4) bool {
   110  			var b E4
   111  			b.MulByNonResidueInv(a)
   112  			a.MulByNonResidueInv(a)
   113  			return a.Equal(&b)
   114  		},
   115  		genA,
   116  	))
   117  
   118  	properties.Property("[BLS24-315] Having the receiver as operand (Inverse) should output the same result", prop.ForAll(
   119  		func(a *E4) bool {
   120  			var b E4
   121  			b.Inverse(a)
   122  			a.Inverse(a)
   123  			return a.Equal(&b)
   124  		},
   125  		genA,
   126  	))
   127  
   128  	properties.Property("[BLS24-315] Having the receiver as operand (Conjugate) should output the same result", prop.ForAll(
   129  		func(a *E4) bool {
   130  			var b E4
   131  			b.Conjugate(a)
   132  			a.Conjugate(a)
   133  			return a.Equal(&b)
   134  		},
   135  		genA,
   136  	))
   137  
   138  	properties.Property("[BLS24-315] Having the receiver as operand (Sqrt) should output the same result", prop.ForAll(
   139  		func(a *E4) bool {
   140  			var b, c, d, s E4
   141  
   142  			s.Square(a)
   143  			a.Set(&s)
   144  			b.Set(&s)
   145  
   146  			a.Sqrt(a)
   147  			b.Sqrt(&b)
   148  
   149  			c.Square(a)
   150  			d.Square(&b)
   151  			return c.Equal(&d)
   152  		},
   153  		genA,
   154  	))
   155  
   156  	properties.TestingRun(t, gopter.ConsoleReporter(false))
   157  }
   158  
   159  func TestE4Ops(t *testing.T) {
   160  	t.Parallel()
   161  
   162  	parameters := gopter.DefaultTestParameters()
   163  	parameters.MinSuccessfulTests = 100
   164  
   165  	properties := gopter.NewProperties(parameters)
   166  
   167  	genA := GenE4()
   168  	genB := GenE4()
   169  
   170  	properties.Property("[BLS24-315] sub & add should leave an element invariant", prop.ForAll(
   171  		func(a, b *E4) bool {
   172  			var c E4
   173  			c.Set(a)
   174  			c.Add(&c, b).Sub(&c, b)
   175  			return c.Equal(a)
   176  		},
   177  		genA,
   178  		genB,
   179  	))
   180  
   181  	properties.Property("[BLS24-315] mul & inverse should leave an element invariant", prop.ForAll(
   182  		func(a, b *E4) bool {
   183  			var c, d E4
   184  			d.Inverse(b)
   185  			c.Set(a)
   186  			c.Mul(&c, b).Mul(&c, &d)
   187  			return c.Equal(a)
   188  		},
   189  		genA,
   190  		genB,
   191  	))
   192  
   193  	properties.Property("[BLS24-315] BatchInvertE4 should output the same result as Inverse", prop.ForAll(
   194  		func(a, b, c *E4) bool {
   195  
   196  			batch := BatchInvertE4([]E4{*a, *b, *c})
   197  			a.Inverse(a)
   198  			b.Inverse(b)
   199  			c.Inverse(c)
   200  			return a.Equal(&batch[0]) && b.Equal(&batch[1]) && c.Equal(&batch[2])
   201  		},
   202  		genA,
   203  		genA,
   204  		genB,
   205  	))
   206  
   207  	properties.Property("[BLS24-315] inverse twice should leave an element invariant", prop.ForAll(
   208  		func(a *E4) bool {
   209  			var b E4
   210  			b.Inverse(a).Inverse(&b)
   211  			return a.Equal(&b)
   212  		},
   213  		genA,
   214  	))
   215  
   216  	properties.Property("[BLS24-315] square and mul should output the same result", prop.ForAll(
   217  		func(a *E4) bool {
   218  			var b, c E4
   219  			b.Mul(a, a)
   220  			c.Square(a)
   221  			return b.Equal(&c)
   222  		},
   223  		genA,
   224  	))
   225  
   226  	properties.Property("[BLS24-315] Legendre on square should output 1", prop.ForAll(
   227  		func(a *E4) bool {
   228  			var b E4
   229  			b.Square(a)
   230  			c := b.Legendre()
   231  			return c == 1
   232  		},
   233  		genA,
   234  	))
   235  
   236  	properties.Property("[BLS24-315] square(sqrt) should leave an element invariant", prop.ForAll(
   237  		func(a *E4) bool {
   238  			var b, c, d, e E4
   239  			b.Square(a)
   240  			c.Sqrt(&b)
   241  			d.Square(&c)
   242  			e.Neg(a)
   243  			return (c.Equal(a) || c.Equal(&e)) && d.Equal(&b)
   244  		},
   245  		genA,
   246  	))
   247  
   248  	properties.Property("[BLS24-315] Mulbynonres mulbynonresinv should leave the element invariant", prop.ForAll(
   249  		func(a *E4) bool {
   250  			var b E4
   251  			b.MulByNonResidue(a).MulByNonResidueInv(&b)
   252  			return a.Equal(&b)
   253  		},
   254  		genA,
   255  	))
   256  
   257  	properties.Property("[BLS24-315] Frobenius of x in E4 should be equal to x^q", prop.ForAll(
   258  		func(a *E4) bool {
   259  			var b, c E4
   260  			q := fp.Modulus()
   261  			b.Frobenius(a)
   262  			c.Exp(*a, q)
   263  			return c.Equal(&b)
   264  		},
   265  		genA,
   266  	))
   267  
   268  	properties.TestingRun(t, gopter.ConsoleReporter(false))
   269  }
   270  
   271  // ------------------------------------------------------------
   272  // benches
   273  
   274  func BenchmarkE4Add(b *testing.B) {
   275  	var a, c E4
   276  	_, _ = a.SetRandom()
   277  	_, _ = c.SetRandom()
   278  	b.ResetTimer()
   279  	for i := 0; i < b.N; i++ {
   280  		a.Add(&a, &c)
   281  	}
   282  }
   283  
   284  func BenchmarkE4Sub(b *testing.B) {
   285  	var a, c E4
   286  	_, _ = a.SetRandom()
   287  	_, _ = c.SetRandom()
   288  	b.ResetTimer()
   289  	for i := 0; i < b.N; i++ {
   290  		a.Sub(&a, &c)
   291  	}
   292  }
   293  
   294  func BenchmarkE4Mul(b *testing.B) {
   295  	var a, c E4
   296  	_, _ = a.SetRandom()
   297  	_, _ = c.SetRandom()
   298  	b.ResetTimer()
   299  	for i := 0; i < b.N; i++ {
   300  		a.Mul(&a, &c)
   301  	}
   302  }
   303  
   304  func BenchmarkE4Square(b *testing.B) {
   305  	var a E4
   306  	_, _ = a.SetRandom()
   307  	b.ResetTimer()
   308  	for i := 0; i < b.N; i++ {
   309  		a.Square(&a)
   310  	}
   311  }
   312  
   313  func BenchmarkE4Sqrt(b *testing.B) {
   314  	var a E4
   315  	_, _ = a.SetRandom()
   316  	b.ResetTimer()
   317  	for i := 0; i < b.N; i++ {
   318  		a.Sqrt(&a)
   319  	}
   320  }
   321  
   322  func BenchmarkE4Inverse(b *testing.B) {
   323  	var a E4
   324  	_, _ = a.SetRandom()
   325  	b.ResetTimer()
   326  	for i := 0; i < b.N; i++ {
   327  		a.Inverse(&a)
   328  	}
   329  }
   330  
   331  func BenchmarkE4MulNonRes(b *testing.B) {
   332  	var a E4
   333  	_, _ = a.SetRandom()
   334  	b.ResetTimer()
   335  	for i := 0; i < b.N; i++ {
   336  		a.MulByNonResidue(&a)
   337  	}
   338  }
   339  
   340  func BenchmarkE4MulNonResInv(b *testing.B) {
   341  	var a E4
   342  	_, _ = a.SetRandom()
   343  	b.ResetTimer()
   344  	for i := 0; i < b.N; i++ {
   345  		a.MulByNonResidueInv(&a)
   346  	}
   347  }
   348  func BenchmarkE4Conjugate(b *testing.B) {
   349  	var a E4
   350  	_, _ = a.SetRandom()
   351  	b.ResetTimer()
   352  	for i := 0; i < b.N; i++ {
   353  		a.Conjugate(&a)
   354  	}
   355  }