github.com/consensys/gnark-crypto@v0.14.0/ecc/bls12-381/bandersnatch/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 bandersnatch
    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  	properties.Property("(projective) GLV and double-and-add scalar multiplications give the same results", prop.ForAll(
   529  		func(s1 big.Int) bool {
   530  
   531  			params := GetEdwardsCurve()
   532  
   533  			var baseProj, p1, p2 PointProj
   534  			baseProj.FromAffine(&params.Base)
   535  
   536  			p1.scalarMulWindowed(&baseProj, &s1)
   537  			p2.scalarMulGLV(&baseProj, &s1)
   538  
   539  			return p2.Equal(&p1)
   540  
   541  		},
   542  		genS1,
   543  	))
   544  
   545  	// extended
   546  	properties.Property("(extended) 0+0=0", prop.ForAll(
   547  		func(s1 big.Int) bool {
   548  
   549  			var p1, zero PointExtended
   550  			zero.setInfinity()
   551  
   552  			p1.Add(&zero, &zero)
   553  
   554  			return p1.Equal(&zero)
   555  		},
   556  		genS1,
   557  	))
   558  
   559  	properties.Property("(extended) P+0=P", prop.ForAll(
   560  		func(s1 big.Int) bool {
   561  
   562  			params := GetEdwardsCurve()
   563  
   564  			var baseExtended, p1, p2, zero PointExtended
   565  			baseExtended.FromAffine(&params.Base)
   566  			p1.ScalarMultiplication(&baseExtended, &s1)
   567  			zero.setInfinity()
   568  
   569  			p2.Add(&p1, &zero)
   570  
   571  			return p2.Equal(&p1)
   572  		},
   573  		genS1,
   574  	))
   575  
   576  	properties.Property("(extended) P+(-P)=O", prop.ForAll(
   577  		func(s1 big.Int) bool {
   578  
   579  			params := GetEdwardsCurve()
   580  
   581  			var baseExtended, p1, p2, p PointExtended
   582  			baseExtended.FromAffine(&params.Base)
   583  			p1.ScalarMultiplication(&baseExtended, &s1)
   584  			p2.Neg(&p1)
   585  
   586  			p.Add(&p1, &p2)
   587  
   588  			return p.IsZero()
   589  		},
   590  		genS1,
   591  	))
   592  
   593  	properties.Property("(extended) P+P=2*P", prop.ForAll(
   594  
   595  		func(s big.Int) bool {
   596  
   597  			params := GetEdwardsCurve()
   598  
   599  			var baseExtended, p1, p2, p PointExtended
   600  			baseExtended.FromAffine(&params.Base)
   601  			p.ScalarMultiplication(&baseExtended, &s)
   602  
   603  			p1.Add(&p, &p)
   604  			p2.Double(&p)
   605  
   606  			return p1.Equal(&p2)
   607  		},
   608  		genS1,
   609  	))
   610  
   611  	properties.Property("(extended) [5]P=[2][2]P+P", prop.ForAll(
   612  		func(s1 big.Int) bool {
   613  
   614  			params := GetEdwardsCurve()
   615  
   616  			var baseExtended, p1, p2 PointExtended
   617  			baseExtended.FromAffine(&params.Base)
   618  			p1.ScalarMultiplication(&baseExtended, &s1)
   619  
   620  			five := big.NewInt(5)
   621  			p2.Double(&p1).Double(&p2).Add(&p2, &p1)
   622  			p1.ScalarMultiplication(&p1, five)
   623  
   624  			return p2.Equal(&p1)
   625  		},
   626  		genS1,
   627  	))
   628  	properties.Property("(extended) GLV and double-and-add scalar multiplications give the same results", prop.ForAll(
   629  		func(s1 big.Int) bool {
   630  
   631  			params := GetEdwardsCurve()
   632  
   633  			var baseExtended, p1, p2 PointExtended
   634  			baseExtended.FromAffine(&params.Base)
   635  
   636  			p1.scalarMulWindowed(&baseExtended, &s1)
   637  			p2.scalarMulGLV(&baseExtended, &s1)
   638  
   639  			return p2.Equal(&p1)
   640  
   641  		},
   642  		genS1,
   643  	))
   644  
   645  	// mixed affine+extended
   646  	properties.Property("(mixed affine+extended) P+(-P)=O", prop.ForAll(
   647  		func(s big.Int) bool {
   648  
   649  			params := GetEdwardsCurve()
   650  
   651  			var baseExtended, pExtended, p PointExtended
   652  			var pAffine PointAffine
   653  			baseExtended.FromAffine(&params.Base)
   654  			pExtended.ScalarMultiplication(&baseExtended, &s)
   655  			pAffine.ScalarMultiplication(&params.Base, &s)
   656  			pAffine.Neg(&pAffine)
   657  
   658  			p.MixedAdd(&pExtended, &pAffine)
   659  
   660  			return p.IsZero()
   661  		},
   662  		genS1,
   663  	))
   664  
   665  	properties.Property("(mixed affine+extended) P+P=2*P", prop.ForAll(
   666  		func(s big.Int) bool {
   667  
   668  			params := GetEdwardsCurve()
   669  
   670  			var baseExtended, pExtended, p, p2 PointExtended
   671  			var pAffine PointAffine
   672  			baseExtended.FromAffine(&params.Base)
   673  			pExtended.ScalarMultiplication(&baseExtended, &s)
   674  			pAffine.ScalarMultiplication(&params.Base, &s)
   675  
   676  			p.MixedAdd(&pExtended, &pAffine)
   677  			p2.MixedDouble(&pExtended)
   678  
   679  			return p.Equal(&p2)
   680  		},
   681  		genS1,
   682  	))
   683  
   684  	// mixed affine+projective
   685  	properties.Property("(mixed affine+proj) P+(-P)=O", prop.ForAll(
   686  		func(s big.Int) bool {
   687  
   688  			params := GetEdwardsCurve()
   689  
   690  			var baseProj, pProj, p PointProj
   691  			var pAffine PointAffine
   692  			baseProj.FromAffine(&params.Base)
   693  			pProj.ScalarMultiplication(&baseProj, &s)
   694  			pAffine.ScalarMultiplication(&params.Base, &s)
   695  			pAffine.Neg(&pAffine)
   696  
   697  			p.MixedAdd(&pProj, &pAffine)
   698  
   699  			return p.IsZero()
   700  		},
   701  		genS1,
   702  	))
   703  
   704  	properties.Property("(mixed affine+proj) P+P=2*P", prop.ForAll(
   705  		func(s big.Int) bool {
   706  
   707  			params := GetEdwardsCurve()
   708  
   709  			var baseProj, pProj, p, p2 PointProj
   710  			var pAffine PointAffine
   711  			baseProj.FromAffine(&params.Base)
   712  			pProj.ScalarMultiplication(&baseProj, &s)
   713  			pAffine.ScalarMultiplication(&params.Base, &s)
   714  
   715  			p.MixedAdd(&pProj, &pAffine)
   716  			p2.Double(&pProj)
   717  
   718  			return p.Equal(&p2)
   719  		},
   720  		genS1,
   721  	))
   722  
   723  	properties.Property("scalar multiplication in Proj vs Ext should be consistent", prop.ForAll(
   724  		func(s big.Int) bool {
   725  
   726  			params := GetEdwardsCurve()
   727  
   728  			var baseProj PointProj
   729  			var baseExt PointExtended
   730  			var p1, p2 PointAffine
   731  			baseProj.FromAffine(&params.Base)
   732  			baseProj.ScalarMultiplication(&baseProj, &s)
   733  			baseExt.FromAffine(&params.Base)
   734  			baseExt.ScalarMultiplication(&baseExt, &s)
   735  
   736  			p1.FromProj(&baseProj)
   737  			p2.FromExtended(&baseExt)
   738  
   739  			return p1.Equal(&p2)
   740  		},
   741  		genS1,
   742  	))
   743  
   744  	properties.TestingRun(t, gopter.ConsoleReporter(false))
   745  
   746  }
   747  
   748  func TestMarshal(t *testing.T) {
   749  	t.Parallel()
   750  	initOnce.Do(initCurveParams)
   751  
   752  	var point, unmarshalPoint PointAffine
   753  	point.Set(&curveParams.Base)
   754  	for i := 0; i < 20; i++ {
   755  		b := point.Marshal()
   756  		unmarshalPoint.Unmarshal(b)
   757  		if !point.Equal(&unmarshalPoint) {
   758  			t.Fatal("error unmarshal(marshal(point))")
   759  		}
   760  		point.Add(&point, &curveParams.Base)
   761  	}
   762  }
   763  
   764  // GenBigInt generates a big.Int
   765  // TODO @thomas we use fr size as max bound here
   766  func GenBigInt() gopter.Gen {
   767  	return func(genParams *gopter.GenParameters) *gopter.GenResult {
   768  		var s big.Int
   769  		var b [fr.Bytes]byte
   770  		_, err := rand.Read(b[:]) //#nosec G404 weak rng is fine here
   771  		if err != nil {
   772  			panic(err)
   773  		}
   774  		s.SetBytes(b[:])
   775  		genResult := gopter.NewGenResult(s, gopter.NoShrinker)
   776  		return genResult
   777  	}
   778  }
   779  
   780  // ------------------------------------------------------------
   781  // benches
   782  
   783  func BenchmarkProjEqual(b *testing.B) {
   784  	params := GetEdwardsCurve()
   785  
   786  	var scalar fr.Element
   787  	if _, err := scalar.SetRandom(); err != nil {
   788  		b.Fatalf("error generating random scalar: %v", err)
   789  	}
   790  
   791  	var baseProj PointProj
   792  	baseProj.FromAffine(&params.Base)
   793  	var a PointProj
   794  	a.ScalarMultiplication(&baseProj, big.NewInt(42))
   795  
   796  	b.Run("equal", func(b *testing.B) {
   797  		aZScaled := a
   798  		aZScaled.X.Mul(&aZScaled.X, &scalar)
   799  		aZScaled.Y.Mul(&aZScaled.Y, &scalar)
   800  		aZScaled.Z.Mul(&aZScaled.Z, &scalar)
   801  
   802  		// Check the setup.
   803  		if !a.Equal(&aZScaled) {
   804  			b.Fatalf("invalid test setup")
   805  		}
   806  
   807  		b.ResetTimer()
   808  		for i := 0; i < b.N; i++ {
   809  			a.Equal(&aZScaled)
   810  		}
   811  	})
   812  
   813  	b.Run("not equal", func(b *testing.B) {
   814  		var aPlus1 PointProj
   815  		aPlus1.Add(&a, &baseProj)
   816  
   817  		// Check the setup.
   818  		if a.Equal(&aPlus1) {
   819  			b.Fatalf("invalid test setup")
   820  		}
   821  
   822  		b.ResetTimer()
   823  		for i := 0; i < b.N; i++ {
   824  			a.Equal(&aPlus1)
   825  		}
   826  	})
   827  }
   828  
   829  func BenchmarkScalarMulExtended(b *testing.B) {
   830  	params := GetEdwardsCurve()
   831  	var a PointExtended
   832  	var s big.Int
   833  	a.FromAffine(&params.Base)
   834  	s.SetString("52435875175126190479447705081859658376581184513", 10)
   835  	s.Add(&s, &params.Order)
   836  
   837  	var doubleAndAdd PointExtended
   838  
   839  	b.ResetTimer()
   840  	for j := 0; j < b.N; j++ {
   841  		doubleAndAdd.ScalarMultiplication(&a, &s)
   842  	}
   843  }
   844  
   845  func BenchmarkScalarMulProjective(b *testing.B) {
   846  	params := GetEdwardsCurve()
   847  	var a PointProj
   848  	var s big.Int
   849  	a.FromAffine(&params.Base)
   850  	s.SetString("52435875175126190479447705081859658376581184513", 10)
   851  	s.Add(&s, &params.Order)
   852  
   853  	var doubleAndAdd PointProj
   854  
   855  	b.ResetTimer()
   856  	for j := 0; j < b.N; j++ {
   857  		doubleAndAdd.ScalarMultiplication(&a, &s)
   858  	}
   859  }
   860  
   861  func BenchmarkNeg(b *testing.B) {
   862  	params := GetEdwardsCurve()
   863  	var s big.Int
   864  	s.SetString("52435875175126190479447705081859658376581184513", 10)
   865  
   866  	b.Run("Affine", func(b *testing.B) {
   867  		var point PointAffine
   868  		point.ScalarMultiplication(&params.Base, &s)
   869  
   870  		b.ResetTimer()
   871  		for i := 0; i < b.N; i++ {
   872  			point.Neg(&point)
   873  		}
   874  	})
   875  	b.Run("Projective", func(b *testing.B) {
   876  		var baseProj PointProj
   877  		baseProj.FromAffine(&params.Base)
   878  		var point PointProj
   879  		point.ScalarMultiplication(&baseProj, &s)
   880  
   881  		b.ResetTimer()
   882  		for i := 0; i < b.N; i++ {
   883  			point.Neg(&point)
   884  		}
   885  	})
   886  	b.Run("Extended", func(b *testing.B) {
   887  		var baseProj PointExtended
   888  		baseProj.FromAffine(&params.Base)
   889  		var point PointExtended
   890  		point.ScalarMultiplication(&baseProj, &s)
   891  
   892  		b.ResetTimer()
   893  		for i := 0; i < b.N; i++ {
   894  			point.Neg(&point)
   895  		}
   896  	})
   897  }
   898  
   899  func BenchmarkMixedAdd(b *testing.B) {
   900  	params := GetEdwardsCurve()
   901  	var s big.Int
   902  	s.SetString("52435875175126190479447705081859658376581184513", 10)
   903  	var point PointAffine
   904  	point.ScalarMultiplication(&params.Base, &s)
   905  
   906  	b.Run("Projective", func(b *testing.B) {
   907  		var accum PointProj
   908  		accum.setInfinity()
   909  
   910  		b.ResetTimer()
   911  		for i := 0; i < b.N; i++ {
   912  			accum.MixedAdd(&accum, &point)
   913  		}
   914  	})
   915  	b.Run("Extended", func(b *testing.B) {
   916  		var accum PointExtended
   917  		accum.setInfinity()
   918  
   919  		b.ResetTimer()
   920  		for i := 0; i < b.N; i++ {
   921  			accum.MixedAdd(&accum, &point)
   922  		}
   923  	})
   924  }
   925  
   926  func BenchmarkAdd(b *testing.B) {
   927  	params := GetEdwardsCurve()
   928  	var s big.Int
   929  	s.SetString("52435875175126190479447705081859658376581184513", 10)
   930  
   931  	b.Run("Affine", func(b *testing.B) {
   932  		var point PointAffine
   933  		point.ScalarMultiplication(&params.Base, &s)
   934  		var accum PointAffine
   935  		accum.setInfinity()
   936  
   937  		b.ResetTimer()
   938  		for i := 0; i < b.N; i++ {
   939  			accum.Add(&accum, &point)
   940  		}
   941  	})
   942  	b.Run("Projective", func(b *testing.B) {
   943  		var pointAff PointAffine
   944  		pointAff.ScalarMultiplication(&params.Base, &s)
   945  		var accum, point PointProj
   946  		point.FromAffine(&pointAff)
   947  		accum.setInfinity()
   948  
   949  		b.ResetTimer()
   950  		for i := 0; i < b.N; i++ {
   951  			accum.Add(&accum, &point)
   952  		}
   953  	})
   954  	b.Run("Extended", func(b *testing.B) {
   955  		var pointAff PointAffine
   956  		pointAff.ScalarMultiplication(&params.Base, &s)
   957  		var accum, point PointExtended
   958  		point.FromAffine(&pointAff)
   959  		accum.setInfinity()
   960  
   961  		b.ResetTimer()
   962  		for i := 0; i < b.N; i++ {
   963  			accum.Add(&accum, &point)
   964  		}
   965  	})
   966  }
   967  
   968  func BenchmarkIsOnCurve(b *testing.B) {
   969  	params := GetEdwardsCurve()
   970  	var s big.Int
   971  	s.SetString("52435875175126190479447705081859658376581184513", 10)
   972  
   973  	b.Run("positive", func(b *testing.B) {
   974  		var point PointAffine
   975  		point.ScalarMultiplication(&params.Base, &s)
   976  
   977  		if !point.IsOnCurve() {
   978  			b.Fatal("point should must be on curve")
   979  		}
   980  
   981  		b.ResetTimer()
   982  		for i := 0; i < b.N; i++ {
   983  			_ = point.IsOnCurve()
   984  		}
   985  	})
   986  
   987  	b.Run("negative", func(b *testing.B) {
   988  		var point PointAffine
   989  		point.ScalarMultiplication(&params.Base, &s)
   990  		point.X.Add(&point.X, &point.X)
   991  
   992  		if point.IsOnCurve() {
   993  			b.Fatal("point should not be on curve")
   994  		}
   995  
   996  		b.ResetTimer()
   997  		for i := 0; i < b.N; i++ {
   998  			_ = point.IsOnCurve()
   999  		}
  1000  	})
  1001  }