github.com/consensys/gnark-crypto@v0.14.0/ecc/bls12-381/twistededwards/point_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 twistededwards
    18  
    19  import (
    20  	"crypto/rand"
    21  	"math/big"
    22  	"testing"
    23  
    24  	"github.com/consensys/gnark-crypto/ecc/bls12-381/fr"
    25  	"github.com/leanovate/gopter"
    26  	"github.com/leanovate/gopter/prop"
    27  )
    28  
    29  // ------------------------------------------------------------
    30  // tests
    31  
    32  const (
    33  	nbFuzzShort = 10
    34  	nbFuzz      = 100
    35  )
    36  
    37  func TestReceiverIsOperand(t *testing.T) {
    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  	// affine
    49  	properties.Property("Equal affine: having the receiver as operand should output the same result", prop.ForAll(
    50  		func() bool {
    51  			params := GetEdwardsCurve()
    52  			var p1 PointAffine
    53  			p1.Set(&params.Base)
    54  
    55  			return p1.Equal(&p1) && p1.Equal(&params.Base)
    56  		},
    57  	))
    58  
    59  	properties.Property("Add affine: having the receiver as operand should output the same result", prop.ForAll(
    60  		func() bool {
    61  
    62  			params := GetEdwardsCurve()
    63  
    64  			var p1, p2, p3 PointAffine
    65  			p1.Set(&params.Base)
    66  			p2.Set(&params.Base)
    67  			p3.Set(&params.Base)
    68  
    69  			res := true
    70  
    71  			p3.Add(&p1, &p2)
    72  			p1.Add(&p1, &p2)
    73  			res = res && p3.Equal(&p1)
    74  
    75  			p1.Set(&params.Base)
    76  			p2.Add(&p1, &p2)
    77  			res = res && p2.Equal(&p3)
    78  
    79  			return res
    80  		},
    81  	))
    82  
    83  	properties.Property("Double affine: having the receiver as operand should output the same result", prop.ForAll(
    84  		func() bool {
    85  
    86  			params := GetEdwardsCurve()
    87  
    88  			var p1, p2 PointAffine
    89  			p1.Set(&params.Base)
    90  			p2.Set(&params.Base)
    91  
    92  			p2.Double(&p1)
    93  			p1.Double(&p1)
    94  
    95  			return p2.Equal(&p1)
    96  		},
    97  	))
    98  
    99  	properties.Property("Neg affine: having the receiver as operand should output the same result", prop.ForAll(
   100  		func() bool {
   101  
   102  			params := GetEdwardsCurve()
   103  
   104  			var p1, p2 PointAffine
   105  			p1.Set(&params.Base)
   106  			p2.Set(&params.Base)
   107  
   108  			p2.Neg(&p1)
   109  			p1.Neg(&p1)
   110  
   111  			return p2.Equal(&p1)
   112  		},
   113  	))
   114  
   115  	properties.Property("Neg affine: having the receiver as operand should output the same result", prop.ForAll(
   116  		func() bool {
   117  
   118  			params := GetEdwardsCurve()
   119  
   120  			var p1, p2 PointAffine
   121  			p1.Set(&params.Base)
   122  			p2.Set(&params.Base)
   123  
   124  			var s big.Int
   125  			s.SetUint64(10)
   126  
   127  			p2.ScalarMultiplication(&p1, &s)
   128  			p1.ScalarMultiplication(&p1, &s)
   129  
   130  			return p2.Equal(&p1)
   131  		},
   132  	))
   133  	properties.TestingRun(t, gopter.ConsoleReporter(false))
   134  
   135  	// projective
   136  	properties.Property("Equal projective: having the receiver as operand should output the same result", prop.ForAll(
   137  		func() bool {
   138  			params := GetEdwardsCurve()
   139  			var p1, baseProj PointProj
   140  			p1.FromAffine(&params.Base)
   141  			baseProj.FromAffine(&params.Base)
   142  
   143  			return p1.Equal(&p1) && p1.Equal(&baseProj)
   144  		},
   145  	))
   146  
   147  	properties.Property("Add projective: having the receiver as operand should output the same result", prop.ForAll(
   148  		func() bool {
   149  
   150  			params := GetEdwardsCurve()
   151  
   152  			var p1, p2, p3 PointProj
   153  			p1.FromAffine(&params.Base)
   154  			p2.FromAffine(&params.Base)
   155  			p3.FromAffine(&params.Base)
   156  
   157  			res := true
   158  
   159  			p3.Add(&p1, &p2)
   160  			p1.Add(&p1, &p2)
   161  			res = res && p3.Equal(&p1)
   162  
   163  			p1.FromAffine(&params.Base)
   164  			p2.Add(&p1, &p2)
   165  			res = res && p2.Equal(&p3)
   166  
   167  			return res
   168  		},
   169  	))
   170  
   171  	properties.Property("Double projective: having the receiver as operand should output the same result", prop.ForAll(
   172  		func() bool {
   173  
   174  			params := GetEdwardsCurve()
   175  
   176  			var p1, p2 PointProj
   177  			p1.FromAffine(&params.Base)
   178  			p2.FromAffine(&params.Base)
   179  
   180  			p2.Double(&p1)
   181  			p1.Double(&p1)
   182  
   183  			return p2.Equal(&p1)
   184  		},
   185  	))
   186  
   187  	properties.Property("Neg projective: having the receiver as operand should output the same result", prop.ForAll(
   188  		func() bool {
   189  
   190  			params := GetEdwardsCurve()
   191  
   192  			var p1, p2 PointProj
   193  			p1.FromAffine(&params.Base)
   194  			p2.FromAffine(&params.Base)
   195  
   196  			p2.Neg(&p1)
   197  			p1.Neg(&p1)
   198  
   199  			return p2.Equal(&p1)
   200  		},
   201  	))
   202  
   203  	// extended
   204  	properties.Property("Equal extended: having the receiver as operand should output the same result", prop.ForAll(
   205  		func() bool {
   206  			params := GetEdwardsCurve()
   207  			var p1, baseProj PointProj
   208  			p1.FromAffine(&params.Base)
   209  			baseProj.FromAffine(&params.Base)
   210  
   211  			return p1.Equal(&p1) && p1.Equal(&baseProj)
   212  		},
   213  	))
   214  
   215  	properties.Property("Add extended: having the receiver as operand should output the same result", prop.ForAll(
   216  		func() bool {
   217  
   218  			params := GetEdwardsCurve()
   219  
   220  			var p1, p2, p3 PointProj
   221  			p1.FromAffine(&params.Base)
   222  			p2.FromAffine(&params.Base)
   223  			p3.FromAffine(&params.Base)
   224  
   225  			res := true
   226  
   227  			p3.Add(&p1, &p2)
   228  			p1.Add(&p1, &p2)
   229  			res = res && p3.Equal(&p1)
   230  
   231  			p1.FromAffine(&params.Base)
   232  			p2.Add(&p1, &p2)
   233  			res = res && p2.Equal(&p3)
   234  
   235  			return res
   236  		},
   237  	))
   238  
   239  	properties.Property("Double extended: having the receiver as operand should output the same result", prop.ForAll(
   240  		func() bool {
   241  
   242  			params := GetEdwardsCurve()
   243  
   244  			var p1, p2 PointProj
   245  			p1.FromAffine(&params.Base)
   246  			p2.FromAffine(&params.Base)
   247  
   248  			p2.Double(&p1)
   249  			p1.Double(&p1)
   250  
   251  			return p2.Equal(&p1)
   252  		},
   253  	))
   254  
   255  	properties.Property("Neg extended: having the receiver as operand should output the same result", prop.ForAll(
   256  		func() bool {
   257  
   258  			params := GetEdwardsCurve()
   259  
   260  			var p1, p2 PointProj
   261  			p1.FromAffine(&params.Base)
   262  			p2.FromAffine(&params.Base)
   263  
   264  			p2.Neg(&p1)
   265  			p1.Neg(&p1)
   266  
   267  			return p2.Equal(&p1)
   268  		},
   269  	))
   270  
   271  	properties.TestingRun(t, gopter.ConsoleReporter(false))
   272  
   273  }
   274  
   275  func TestField(t *testing.T) {
   276  	t.Parallel()
   277  	parameters := gopter.DefaultTestParameters()
   278  	if testing.Short() {
   279  		parameters.MinSuccessfulTests = nbFuzzShort
   280  	} else {
   281  		parameters.MinSuccessfulTests = nbFuzz
   282  	}
   283  
   284  	properties := gopter.NewProperties(parameters)
   285  	genS := GenBigInt()
   286  
   287  	properties.Property("MulByA(x) should match Mul(x, curve.A)", prop.ForAll(
   288  		func(s big.Int) bool {
   289  
   290  			params := GetEdwardsCurve()
   291  
   292  			var z1, z2 fr.Element
   293  			z1.SetBigInt(&s)
   294  			z2.Mul(&z1, &params.A)
   295  			mulByA(&z1)
   296  
   297  			return z1.Equal(&z2)
   298  		},
   299  		genS,
   300  	))
   301  
   302  	properties.TestingRun(t, gopter.ConsoleReporter(false))
   303  }
   304  
   305  func TestOps(t *testing.T) {
   306  
   307  	parameters := gopter.DefaultTestParameters()
   308  	if testing.Short() {
   309  		parameters.MinSuccessfulTests = nbFuzzShort
   310  	} else {
   311  		parameters.MinSuccessfulTests = nbFuzz
   312  	}
   313  
   314  	properties := gopter.NewProperties(parameters)
   315  	genS1 := GenBigInt()
   316  	genS2 := GenBigInt()
   317  
   318  	// affine
   319  	properties.Property("(affine) 0+0=2*0=0", prop.ForAll(
   320  		func(s1 big.Int) bool {
   321  
   322  			var p1, p2, zero PointAffine
   323  			zero.setInfinity()
   324  
   325  			p1.Add(&zero, &zero)
   326  			p2.Double(&zero)
   327  
   328  			return p1.IsOnCurve() && p1.Equal(&zero) && p1.Equal(&p2)
   329  		},
   330  		genS1,
   331  	))
   332  
   333  	properties.Property("(affine) P+0=P", prop.ForAll(
   334  		func(s1 big.Int) bool {
   335  
   336  			params := GetEdwardsCurve()
   337  
   338  			var p1, p2, zero PointAffine
   339  			p1.ScalarMultiplication(&params.Base, &s1)
   340  			zero.setInfinity()
   341  
   342  			p2.Add(&p1, &zero)
   343  
   344  			return p2.IsOnCurve() && p2.Equal(&p1)
   345  		},
   346  		genS1,
   347  	))
   348  
   349  	properties.Property("(affine) P+(-P)=O", prop.ForAll(
   350  		func(s1 big.Int) bool {
   351  
   352  			params := GetEdwardsCurve()
   353  
   354  			var p1, p2 PointAffine
   355  			p1.ScalarMultiplication(&params.Base, &s1)
   356  			p2.Neg(&p1)
   357  
   358  			p1.Add(&p1, &p2)
   359  
   360  			var one fr.Element
   361  			one.SetOne()
   362  
   363  			return p1.IsOnCurve() && p1.IsZero()
   364  		},
   365  		genS1,
   366  	))
   367  
   368  	properties.Property("(affine) P+P=2*P", prop.ForAll(
   369  		func(s big.Int) bool {
   370  
   371  			params := GetEdwardsCurve()
   372  
   373  			var p1, p2, inf PointAffine
   374  			p1.ScalarMultiplication(&params.Base, &s)
   375  			p2.ScalarMultiplication(&params.Base, &s)
   376  
   377  			p1.Add(&p1, &p2)
   378  			p2.Double(&p2)
   379  
   380  			return p1.IsOnCurve() && p1.Equal(&p2) && !p1.Equal(&inf)
   381  		},
   382  		genS1,
   383  	))
   384  
   385  	properties.Property("(affine) [a]P+[b]P = [a+b]P", prop.ForAll(
   386  		func(s1, s2 big.Int) bool {
   387  
   388  			params := GetEdwardsCurve()
   389  
   390  			var p1, p2, p3, inf PointAffine
   391  			inf.X.SetZero()
   392  			inf.Y.SetZero()
   393  			p1.ScalarMultiplication(&params.Base, &s1)
   394  			p2.ScalarMultiplication(&params.Base, &s2)
   395  			p3.Set(&params.Base)
   396  
   397  			p2.Add(&p1, &p2)
   398  
   399  			s1.Add(&s1, &s2)
   400  			p3.ScalarMultiplication(&params.Base, &s1)
   401  
   402  			return p2.IsOnCurve() && p3.Equal(&p2) && !p3.Equal(&inf)
   403  		},
   404  		genS1,
   405  		genS2,
   406  	))
   407  
   408  	properties.Property("(affine) [a]P+[-a]P = O", prop.ForAll(
   409  		func(s1 big.Int) bool {
   410  
   411  			params := GetEdwardsCurve()
   412  
   413  			var p1, p2, inf PointAffine
   414  			inf.X.SetZero()
   415  			inf.Y.SetOne()
   416  			p1.ScalarMultiplication(&params.Base, &s1)
   417  			s1.Neg(&s1)
   418  			p2.ScalarMultiplication(&params.Base, &s1)
   419  
   420  			p2.Add(&p1, &p2)
   421  
   422  			return p2.IsOnCurve() && p2.Equal(&inf)
   423  		},
   424  		genS1,
   425  	))
   426  
   427  	properties.Property("(affine) [5]P=[2][2]P+P", prop.ForAll(
   428  		func(s1 big.Int) bool {
   429  
   430  			params := GetEdwardsCurve()
   431  
   432  			var p1, p2 PointAffine
   433  			p1.ScalarMultiplication(&params.Base, &s1)
   434  
   435  			five := big.NewInt(5)
   436  			p2.Double(&p1).Double(&p2).Add(&p2, &p1)
   437  			p1.ScalarMultiplication(&p1, five)
   438  
   439  			return p2.IsOnCurve() && p2.Equal(&p1)
   440  		},
   441  		genS1,
   442  	))
   443  
   444  	// projective
   445  	properties.Property("(projective) 0+0=2*0=0", prop.ForAll(
   446  		func(s1 big.Int) bool {
   447  
   448  			var p1, p2, zero PointProj
   449  			zero.setInfinity()
   450  
   451  			p1.Add(&zero, &zero)
   452  			p2.Double(&zero)
   453  
   454  			return p1.Equal(&zero) && p1.Equal(&p2)
   455  		},
   456  		genS1,
   457  	))
   458  
   459  	properties.Property("(projective) P+0=P", prop.ForAll(
   460  		func(s1 big.Int) bool {
   461  
   462  			params := GetEdwardsCurve()
   463  
   464  			var baseProj, p1, p2, zero PointProj
   465  			baseProj.FromAffine(&params.Base)
   466  			p1.ScalarMultiplication(&baseProj, &s1)
   467  			zero.setInfinity()
   468  
   469  			p2.Add(&p1, &zero)
   470  
   471  			return p2.Equal(&p1)
   472  		},
   473  		genS1,
   474  	))
   475  
   476  	properties.Property("(projective) P+(-P)=O", prop.ForAll(
   477  		func(s1 big.Int) bool {
   478  
   479  			params := GetEdwardsCurve()
   480  
   481  			var baseProj, p1, p2, p PointProj
   482  			baseProj.FromAffine(&params.Base)
   483  			p1.ScalarMultiplication(&baseProj, &s1)
   484  			p2.Neg(&p1)
   485  
   486  			p.Add(&p1, &p2)
   487  
   488  			return p.IsZero()
   489  		},
   490  		genS1,
   491  	))
   492  
   493  	properties.Property("(projective) P+P=2*P", prop.ForAll(
   494  
   495  		func(s big.Int) bool {
   496  
   497  			params := GetEdwardsCurve()
   498  
   499  			var baseProj, p1, p2, p PointProj
   500  			baseProj.FromAffine(&params.Base)
   501  			p.ScalarMultiplication(&baseProj, &s)
   502  
   503  			p1.Add(&p, &p)
   504  			p2.Double(&p)
   505  
   506  			return p1.Equal(&p2)
   507  		},
   508  		genS1,
   509  	))
   510  
   511  	properties.Property("(projective) [5]P=[2][2]P+P", prop.ForAll(
   512  		func(s1 big.Int) bool {
   513  
   514  			params := GetEdwardsCurve()
   515  
   516  			var baseProj, p1, p2 PointProj
   517  			baseProj.FromAffine(&params.Base)
   518  			p1.ScalarMultiplication(&baseProj, &s1)
   519  
   520  			five := big.NewInt(5)
   521  			p2.Double(&p1).Double(&p2).Add(&p2, &p1)
   522  			p1.ScalarMultiplication(&p1, five)
   523  
   524  			return p2.Equal(&p1)
   525  		},
   526  		genS1,
   527  	))
   528  
   529  	// extended
   530  	properties.Property("(extended) 0+0=0", prop.ForAll(
   531  		func(s1 big.Int) bool {
   532  
   533  			var p1, zero PointExtended
   534  			zero.setInfinity()
   535  
   536  			p1.Add(&zero, &zero)
   537  
   538  			return p1.Equal(&zero)
   539  		},
   540  		genS1,
   541  	))
   542  
   543  	properties.Property("(extended) P+0=P", prop.ForAll(
   544  		func(s1 big.Int) bool {
   545  
   546  			params := GetEdwardsCurve()
   547  
   548  			var baseExtended, p1, p2, zero PointExtended
   549  			baseExtended.FromAffine(&params.Base)
   550  			p1.ScalarMultiplication(&baseExtended, &s1)
   551  			zero.setInfinity()
   552  
   553  			p2.Add(&p1, &zero)
   554  
   555  			return p2.Equal(&p1)
   556  		},
   557  		genS1,
   558  	))
   559  
   560  	properties.Property("(extended) P+(-P)=O", prop.ForAll(
   561  		func(s1 big.Int) bool {
   562  
   563  			params := GetEdwardsCurve()
   564  
   565  			var baseExtended, p1, p2, p PointExtended
   566  			baseExtended.FromAffine(&params.Base)
   567  			p1.ScalarMultiplication(&baseExtended, &s1)
   568  			p2.Neg(&p1)
   569  
   570  			p.Add(&p1, &p2)
   571  
   572  			return p.IsZero()
   573  		},
   574  		genS1,
   575  	))
   576  
   577  	properties.Property("(extended) P+P=2*P", prop.ForAll(
   578  
   579  		func(s big.Int) bool {
   580  
   581  			params := GetEdwardsCurve()
   582  
   583  			var baseExtended, p1, p2, p PointExtended
   584  			baseExtended.FromAffine(&params.Base)
   585  			p.ScalarMultiplication(&baseExtended, &s)
   586  
   587  			p1.Add(&p, &p)
   588  			p2.Double(&p)
   589  
   590  			return p1.Equal(&p2)
   591  		},
   592  		genS1,
   593  	))
   594  
   595  	properties.Property("(extended) [5]P=[2][2]P+P", prop.ForAll(
   596  		func(s1 big.Int) bool {
   597  
   598  			params := GetEdwardsCurve()
   599  
   600  			var baseExtended, p1, p2 PointExtended
   601  			baseExtended.FromAffine(&params.Base)
   602  			p1.ScalarMultiplication(&baseExtended, &s1)
   603  
   604  			five := big.NewInt(5)
   605  			p2.Double(&p1).Double(&p2).Add(&p2, &p1)
   606  			p1.ScalarMultiplication(&p1, five)
   607  
   608  			return p2.Equal(&p1)
   609  		},
   610  		genS1,
   611  	))
   612  
   613  	// mixed affine+extended
   614  	properties.Property("(mixed affine+extended) P+(-P)=O", prop.ForAll(
   615  		func(s big.Int) bool {
   616  
   617  			params := GetEdwardsCurve()
   618  
   619  			var baseExtended, pExtended, p PointExtended
   620  			var pAffine PointAffine
   621  			baseExtended.FromAffine(&params.Base)
   622  			pExtended.ScalarMultiplication(&baseExtended, &s)
   623  			pAffine.ScalarMultiplication(&params.Base, &s)
   624  			pAffine.Neg(&pAffine)
   625  
   626  			p.MixedAdd(&pExtended, &pAffine)
   627  
   628  			return p.IsZero()
   629  		},
   630  		genS1,
   631  	))
   632  
   633  	properties.Property("(mixed affine+extended) P+P=2*P", prop.ForAll(
   634  		func(s big.Int) bool {
   635  
   636  			params := GetEdwardsCurve()
   637  
   638  			var baseExtended, pExtended, p, p2 PointExtended
   639  			var pAffine PointAffine
   640  			baseExtended.FromAffine(&params.Base)
   641  			pExtended.ScalarMultiplication(&baseExtended, &s)
   642  			pAffine.ScalarMultiplication(&params.Base, &s)
   643  
   644  			p.MixedAdd(&pExtended, &pAffine)
   645  			p2.MixedDouble(&pExtended)
   646  
   647  			return p.Equal(&p2)
   648  		},
   649  		genS1,
   650  	))
   651  
   652  	// mixed affine+projective
   653  	properties.Property("(mixed affine+proj) P+(-P)=O", prop.ForAll(
   654  		func(s big.Int) bool {
   655  
   656  			params := GetEdwardsCurve()
   657  
   658  			var baseProj, pProj, p PointProj
   659  			var pAffine PointAffine
   660  			baseProj.FromAffine(&params.Base)
   661  			pProj.ScalarMultiplication(&baseProj, &s)
   662  			pAffine.ScalarMultiplication(&params.Base, &s)
   663  			pAffine.Neg(&pAffine)
   664  
   665  			p.MixedAdd(&pProj, &pAffine)
   666  
   667  			return p.IsZero()
   668  		},
   669  		genS1,
   670  	))
   671  
   672  	properties.Property("(mixed affine+proj) P+P=2*P", prop.ForAll(
   673  		func(s big.Int) bool {
   674  
   675  			params := GetEdwardsCurve()
   676  
   677  			var baseProj, pProj, p, p2 PointProj
   678  			var pAffine PointAffine
   679  			baseProj.FromAffine(&params.Base)
   680  			pProj.ScalarMultiplication(&baseProj, &s)
   681  			pAffine.ScalarMultiplication(&params.Base, &s)
   682  
   683  			p.MixedAdd(&pProj, &pAffine)
   684  			p2.Double(&pProj)
   685  
   686  			return p.Equal(&p2)
   687  		},
   688  		genS1,
   689  	))
   690  
   691  	properties.Property("scalar multiplication in Proj vs Ext should be consistent", prop.ForAll(
   692  		func(s big.Int) bool {
   693  
   694  			params := GetEdwardsCurve()
   695  
   696  			var baseProj PointProj
   697  			var baseExt PointExtended
   698  			var p1, p2 PointAffine
   699  			baseProj.FromAffine(&params.Base)
   700  			baseProj.ScalarMultiplication(&baseProj, &s)
   701  			baseExt.FromAffine(&params.Base)
   702  			baseExt.ScalarMultiplication(&baseExt, &s)
   703  
   704  			p1.FromProj(&baseProj)
   705  			p2.FromExtended(&baseExt)
   706  
   707  			return p1.Equal(&p2)
   708  		},
   709  		genS1,
   710  	))
   711  
   712  	properties.TestingRun(t, gopter.ConsoleReporter(false))
   713  
   714  }
   715  
   716  func TestMarshal(t *testing.T) {
   717  	t.Parallel()
   718  	initOnce.Do(initCurveParams)
   719  
   720  	var point, unmarshalPoint PointAffine
   721  	point.Set(&curveParams.Base)
   722  	for i := 0; i < 20; i++ {
   723  		b := point.Marshal()
   724  		unmarshalPoint.Unmarshal(b)
   725  		if !point.Equal(&unmarshalPoint) {
   726  			t.Fatal("error unmarshal(marshal(point))")
   727  		}
   728  		point.Add(&point, &curveParams.Base)
   729  	}
   730  }
   731  
   732  // GenBigInt generates a big.Int
   733  // TODO @thomas we use fr size as max bound here
   734  func GenBigInt() gopter.Gen {
   735  	return func(genParams *gopter.GenParameters) *gopter.GenResult {
   736  		var s big.Int
   737  		var b [fr.Bytes]byte
   738  		_, err := rand.Read(b[:]) //#nosec G404 weak rng is fine here
   739  		if err != nil {
   740  			panic(err)
   741  		}
   742  		s.SetBytes(b[:])
   743  		genResult := gopter.NewGenResult(s, gopter.NoShrinker)
   744  		return genResult
   745  	}
   746  }
   747  
   748  // ------------------------------------------------------------
   749  // benches
   750  
   751  func BenchmarkProjEqual(b *testing.B) {
   752  	params := GetEdwardsCurve()
   753  
   754  	var scalar fr.Element
   755  	if _, err := scalar.SetRandom(); err != nil {
   756  		b.Fatalf("error generating random scalar: %v", err)
   757  	}
   758  
   759  	var baseProj PointProj
   760  	baseProj.FromAffine(&params.Base)
   761  	var a PointProj
   762  	a.ScalarMultiplication(&baseProj, big.NewInt(42))
   763  
   764  	b.Run("equal", func(b *testing.B) {
   765  		aZScaled := a
   766  		aZScaled.X.Mul(&aZScaled.X, &scalar)
   767  		aZScaled.Y.Mul(&aZScaled.Y, &scalar)
   768  		aZScaled.Z.Mul(&aZScaled.Z, &scalar)
   769  
   770  		// Check the setup.
   771  		if !a.Equal(&aZScaled) {
   772  			b.Fatalf("invalid test setup")
   773  		}
   774  
   775  		b.ResetTimer()
   776  		for i := 0; i < b.N; i++ {
   777  			a.Equal(&aZScaled)
   778  		}
   779  	})
   780  
   781  	b.Run("not equal", func(b *testing.B) {
   782  		var aPlus1 PointProj
   783  		aPlus1.Add(&a, &baseProj)
   784  
   785  		// Check the setup.
   786  		if a.Equal(&aPlus1) {
   787  			b.Fatalf("invalid test setup")
   788  		}
   789  
   790  		b.ResetTimer()
   791  		for i := 0; i < b.N; i++ {
   792  			a.Equal(&aPlus1)
   793  		}
   794  	})
   795  }
   796  
   797  func BenchmarkScalarMulExtended(b *testing.B) {
   798  	params := GetEdwardsCurve()
   799  	var a PointExtended
   800  	var s big.Int
   801  	a.FromAffine(&params.Base)
   802  	s.SetString("52435875175126190479447705081859658376581184513", 10)
   803  	s.Add(&s, &params.Order)
   804  
   805  	var doubleAndAdd PointExtended
   806  
   807  	b.ResetTimer()
   808  	for j := 0; j < b.N; j++ {
   809  		doubleAndAdd.ScalarMultiplication(&a, &s)
   810  	}
   811  }
   812  
   813  func BenchmarkScalarMulProjective(b *testing.B) {
   814  	params := GetEdwardsCurve()
   815  	var a PointProj
   816  	var s big.Int
   817  	a.FromAffine(&params.Base)
   818  	s.SetString("52435875175126190479447705081859658376581184513", 10)
   819  	s.Add(&s, &params.Order)
   820  
   821  	var doubleAndAdd PointProj
   822  
   823  	b.ResetTimer()
   824  	for j := 0; j < b.N; j++ {
   825  		doubleAndAdd.ScalarMultiplication(&a, &s)
   826  	}
   827  }
   828  
   829  func BenchmarkNeg(b *testing.B) {
   830  	params := GetEdwardsCurve()
   831  	var s big.Int
   832  	s.SetString("52435875175126190479447705081859658376581184513", 10)
   833  
   834  	b.Run("Affine", func(b *testing.B) {
   835  		var point PointAffine
   836  		point.ScalarMultiplication(&params.Base, &s)
   837  
   838  		b.ResetTimer()
   839  		for i := 0; i < b.N; i++ {
   840  			point.Neg(&point)
   841  		}
   842  	})
   843  	b.Run("Projective", func(b *testing.B) {
   844  		var baseProj PointProj
   845  		baseProj.FromAffine(&params.Base)
   846  		var point PointProj
   847  		point.ScalarMultiplication(&baseProj, &s)
   848  
   849  		b.ResetTimer()
   850  		for i := 0; i < b.N; i++ {
   851  			point.Neg(&point)
   852  		}
   853  	})
   854  	b.Run("Extended", func(b *testing.B) {
   855  		var baseProj PointExtended
   856  		baseProj.FromAffine(&params.Base)
   857  		var point PointExtended
   858  		point.ScalarMultiplication(&baseProj, &s)
   859  
   860  		b.ResetTimer()
   861  		for i := 0; i < b.N; i++ {
   862  			point.Neg(&point)
   863  		}
   864  	})
   865  }
   866  
   867  func BenchmarkMixedAdd(b *testing.B) {
   868  	params := GetEdwardsCurve()
   869  	var s big.Int
   870  	s.SetString("52435875175126190479447705081859658376581184513", 10)
   871  	var point PointAffine
   872  	point.ScalarMultiplication(&params.Base, &s)
   873  
   874  	b.Run("Projective", func(b *testing.B) {
   875  		var accum PointProj
   876  		accum.setInfinity()
   877  
   878  		b.ResetTimer()
   879  		for i := 0; i < b.N; i++ {
   880  			accum.MixedAdd(&accum, &point)
   881  		}
   882  	})
   883  	b.Run("Extended", func(b *testing.B) {
   884  		var accum PointExtended
   885  		accum.setInfinity()
   886  
   887  		b.ResetTimer()
   888  		for i := 0; i < b.N; i++ {
   889  			accum.MixedAdd(&accum, &point)
   890  		}
   891  	})
   892  }
   893  
   894  func BenchmarkAdd(b *testing.B) {
   895  	params := GetEdwardsCurve()
   896  	var s big.Int
   897  	s.SetString("52435875175126190479447705081859658376581184513", 10)
   898  
   899  	b.Run("Affine", func(b *testing.B) {
   900  		var point PointAffine
   901  		point.ScalarMultiplication(&params.Base, &s)
   902  		var accum PointAffine
   903  		accum.setInfinity()
   904  
   905  		b.ResetTimer()
   906  		for i := 0; i < b.N; i++ {
   907  			accum.Add(&accum, &point)
   908  		}
   909  	})
   910  	b.Run("Projective", func(b *testing.B) {
   911  		var pointAff PointAffine
   912  		pointAff.ScalarMultiplication(&params.Base, &s)
   913  		var accum, point PointProj
   914  		point.FromAffine(&pointAff)
   915  		accum.setInfinity()
   916  
   917  		b.ResetTimer()
   918  		for i := 0; i < b.N; i++ {
   919  			accum.Add(&accum, &point)
   920  		}
   921  	})
   922  	b.Run("Extended", func(b *testing.B) {
   923  		var pointAff PointAffine
   924  		pointAff.ScalarMultiplication(&params.Base, &s)
   925  		var accum, point PointExtended
   926  		point.FromAffine(&pointAff)
   927  		accum.setInfinity()
   928  
   929  		b.ResetTimer()
   930  		for i := 0; i < b.N; i++ {
   931  			accum.Add(&accum, &point)
   932  		}
   933  	})
   934  }
   935  
   936  func BenchmarkIsOnCurve(b *testing.B) {
   937  	params := GetEdwardsCurve()
   938  	var s big.Int
   939  	s.SetString("52435875175126190479447705081859658376581184513", 10)
   940  
   941  	b.Run("positive", func(b *testing.B) {
   942  		var point PointAffine
   943  		point.ScalarMultiplication(&params.Base, &s)
   944  
   945  		if !point.IsOnCurve() {
   946  			b.Fatal("point should must be on curve")
   947  		}
   948  
   949  		b.ResetTimer()
   950  		for i := 0; i < b.N; i++ {
   951  			_ = point.IsOnCurve()
   952  		}
   953  	})
   954  
   955  	b.Run("negative", func(b *testing.B) {
   956  		var point PointAffine
   957  		point.ScalarMultiplication(&params.Base, &s)
   958  		point.X.Add(&point.X, &point.X)
   959  
   960  		if point.IsOnCurve() {
   961  			b.Fatal("point should not be on curve")
   962  		}
   963  
   964  		b.ResetTimer()
   965  		for i := 0; i < b.N; i++ {
   966  			_ = point.IsOnCurve()
   967  		}
   968  	})
   969  }