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