github.com/consensys/gnark-crypto@v0.14.0/internal/generator/edwards/template/tests/point.go.tmpl (about)

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