github.com/consensys/gnark-crypto@v0.14.0/internal/generator/kzg/template/kzg.test.go.tmpl (about)

     1  import (
     2  	"crypto/sha256"
     3  	"github.com/stretchr/testify/assert"
     4  	"github.com/stretchr/testify/require"
     5  	"math/big"
     6  	"testing"
     7  	"bytes"
     8  
     9  	"github.com/consensys/gnark-crypto/ecc"
    10  	"github.com/consensys/gnark-crypto/ecc/{{ .Name }}"
    11  	"github.com/consensys/gnark-crypto/ecc/{{ .Name }}/fr"
    12  	"github.com/consensys/gnark-crypto/ecc/{{ .Name }}/fr/fft"
    13  
    14  	"github.com/consensys/gnark-crypto/utils/testutils"
    15  )
    16  
    17  // Test SRS re-used across tests of the KZG scheme
    18  var testSrs *SRS
    19  var bAlpha *big.Int
    20  
    21  func init() {
    22  	const srsSize = 230
    23  	bAlpha = new(big.Int).SetInt64(42) // randomise ?
    24  	testSrs, _ = NewSRS(ecc.NextPowerOfTwo(srsSize), bAlpha)
    25  }
    26  
    27  
    28  func TestToLagrangeG1(t *testing.T) {
    29  	assert := require.New(t)
    30  
    31  	const size = 32
    32  
    33  	// convert the test SRS to Lagrange form
    34  	lagrange, err := ToLagrangeG1(testSrs.Pk.G1[:size])
    35  	assert.NoError(err)
    36  
    37  	// generate the Lagrange SRS manually and compare
    38  	w, err := fr.Generator(uint64(size))
    39  	assert.NoError(err)
    40  
    41  	var li, n, d, one, acc, alpha fr.Element
    42  	alpha.SetBigInt(bAlpha)
    43  	li.SetUint64(uint64(size)).Inverse(&li)
    44  	one.SetOne()
    45  	n.Exp(alpha, big.NewInt(int64(size))).Sub(&n, &one)
    46  	d.Sub(&alpha, &one)
    47  	li.Mul(&li, &n).Div(&li, &d)
    48  	expectedSrsLagrange := make([]{{ .CurvePackage }}.G1Affine, size)
    49  	_, _, g1Gen, _ := {{ .CurvePackage }}.Generators()
    50  	var s big.Int
    51  	acc.SetOne()
    52  	for i := 0; i < size; i++ {
    53  		li.BigInt(&s)
    54  		expectedSrsLagrange[i].ScalarMultiplication(&g1Gen, &s)
    55  
    56  		li.Mul(&li, &w).Mul(&li, &d)
    57  		acc.Mul(&acc, &w)
    58  		d.Sub(&alpha, &acc)
    59  		li.Div(&li, &d)
    60  	}
    61  
    62  	for i := 0; i < size; i++ {
    63  		assert.True(expectedSrsLagrange[i].Equal(&lagrange[i]), "error lagrange conversion")
    64  	}
    65  }
    66  
    67  func TestCommitLagrange(t *testing.T) {
    68  
    69  	assert := require.New(t)
    70  
    71  	// sample a sparse polynomial (here in Lagrange form)
    72  	size := 64
    73  	pol := make([]fr.Element, size)
    74  	pol[0].SetRandom()
    75  	for i := 0; i < size; i = i+8 {
    76  		pol[i].SetRandom()
    77  	}
    78  
    79  	// commitment using Lagrange SRS
    80  	lagrange, err := ToLagrangeG1(testSrs.Pk.G1[:size])
    81  	assert.NoError(err)
    82  	var pkLagrange ProvingKey
    83  	pkLagrange.G1 = lagrange
    84  
    85  	digestLagrange, err := Commit(pol, pkLagrange)
    86  	assert.NoError(err)
    87  
    88  	// commitment using canonical SRS
    89  	d := fft.NewDomain(uint64(size))
    90  	d.FFTInverse(pol, fft.DIF)
    91  	fft.BitReverse(pol)
    92  	digestCanonical, err := Commit(pol, testSrs.Pk)
    93  	assert.NoError(err)
    94  
    95  	// compare the results
    96  	assert.True(digestCanonical.Equal(&digestLagrange), "error CommitLagrange")
    97  }
    98  
    99  func TestDividePolyByXminusA(t *testing.T) {
   100  
   101  	const pSize = 230
   102  
   103  	// build random polynomial
   104  	pol := make([]fr.Element, pSize)
   105  	pol[0].SetRandom()
   106  	for i := 1; i < pSize; i++ {
   107  		pol[i] = pol[i-1]
   108  	}
   109  
   110  	// evaluate the polynomial at a random point
   111  	var point fr.Element
   112  	point.SetRandom()
   113  	evaluation := eval(pol, point)
   114  
   115  	// probabilistic test (using Schwartz Zippel lemma, evaluation at one point is enough)
   116  	var randPoint, xminusa fr.Element
   117  	randPoint.SetRandom()
   118  	polRandpoint := eval(pol, randPoint)
   119  	polRandpoint.Sub(&polRandpoint, &evaluation) // f(rand)-f(point)
   120  
   121  	// compute f-f(a)/x-a
   122  	// h re-uses the memory of pol
   123  	h := dividePolyByXminusA(pol, evaluation, point)
   124  
   125  	if len(h) != 229 {
   126  		t.Fatal("inconsistent size of quotient")
   127  	}
   128  
   129  	hRandPoint := eval(h, randPoint)
   130  	xminusa.Sub(&randPoint, &point) // rand-point
   131  
   132  	// f(rand)-f(point)	==? h(rand)*(rand-point)
   133  	hRandPoint.Mul(&hRandPoint, &xminusa)
   134  
   135  	if !hRandPoint.Equal(&polRandpoint) {
   136  		t.Fatal("Error f-f(a)/x-a")
   137  	}
   138  }
   139  
   140  func TestSerializationSRS(t *testing.T) {
   141  	// create a SRS
   142  	srs, err := NewSRS(64, new(big.Int).SetInt64(42))
   143  	assert.NoError(t, err)
   144  	t.Run("proving key round-trip", testutils.SerializationRoundTrip(&srs.Pk))
   145  	t.Run("proving key raw round-trip", testutils.SerializationRoundTripRaw(&srs.Pk))
   146  	t.Run("verifying key round-trip", testutils.SerializationRoundTrip(&srs.Vk))
   147  	t.Run("whole SRS round-trip", testutils.SerializationRoundTrip(srs))
   148  	t.Run("unsafe whole SRS round-trip", testutils.UnsafeBinaryMarshalerRoundTrip(srs))
   149  }
   150  
   151  func TestCommit(t *testing.T) {
   152  
   153  	// create a polynomial
   154  	f := make([]fr.Element, 60)
   155  	for i := 0; i < 60; i++ {
   156  		f[i].SetRandom()
   157  	}
   158  
   159  	// commit using the method from KZG
   160  	_kzgCommit, err := Commit(f, testSrs.Pk)
   161  	if err != nil {
   162  		t.Fatal(err)
   163  	}
   164  	var kzgCommit {{ .CurvePackage }}.G1Affine
   165  	kzgCommit.Unmarshal(_kzgCommit.Marshal())
   166  
   167  	// check commitment using manual commit
   168  	var x fr.Element
   169  	x.SetString("42")
   170  	fx := eval(f, x)
   171  	var fxbi big.Int
   172  	fx.BigInt(&fxbi)
   173  	var manualCommit {{ .CurvePackage }}.G1Affine
   174  	manualCommit.Set(&testSrs.Vk.G1)
   175  	manualCommit.ScalarMultiplication(&manualCommit, &fxbi)
   176  
   177  	// compare both results
   178  	if !kzgCommit.Equal(&manualCommit) {
   179  		t.Fatal("error KZG commitment")
   180  	}
   181  
   182  }
   183  
   184  func TestVerifySinglePoint(t *testing.T) {
   185  
   186  	// create a polynomial
   187  	f := randomPolynomial(60)
   188  
   189  	// commit the polynomial
   190  	digest, err := Commit(f, testSrs.Pk)
   191  	if err != nil {
   192  		t.Fatal(err)
   193  	}
   194  
   195  	// compute opening proof at a random point
   196  	var point fr.Element
   197  	point.SetString("4321")
   198  	proof, err := Open(f, point, testSrs.Pk)
   199  	if err != nil {
   200  		t.Fatal(err)
   201  	}
   202  
   203  	// verify the claimed valued
   204  	expected := eval(f, point)
   205  	if !proof.ClaimedValue.Equal(&expected) {
   206  		t.Fatal("inconsistent claimed value")
   207  	}
   208  
   209  	// verify correct proof
   210  	err = Verify(&digest, &proof, point, testSrs.Vk)
   211  	if err != nil {
   212  		t.Fatal(err)
   213  	}
   214  
   215  	{
   216  		// verify wrong proof
   217  		proof.ClaimedValue.Double(&proof.ClaimedValue)
   218  		err = Verify(&digest, &proof, point, testSrs.Vk)
   219  		if err == nil {
   220  			t.Fatal("verifying wrong proof should have failed")
   221  		}
   222  	}
   223  	{
   224  		// verify wrong proof with quotient set to zero
   225  		// see https://cryptosubtlety.medium.com/00-8d4adcf4d255
   226  		proof.H.X.SetZero()
   227  		proof.H.Y.SetZero()
   228  		err = Verify(&digest, &proof, point, testSrs.Vk)
   229  		if err == nil {
   230  			t.Fatal("verifying wrong proof should have failed")
   231  		}
   232  	}
   233  }
   234  
   235  func TestVerifySinglePointQuickSRS(t *testing.T) {
   236  
   237  	size := 64
   238  	srs, err := NewSRS(64, big.NewInt(-1))
   239  	if err != nil {
   240  		t.Fatal(err)
   241  	}
   242  
   243  	// random polynomial
   244  	p := make([]fr.Element, size)
   245  	for i := 0; i < size; i++ {
   246  		p[i].SetRandom()
   247  	}
   248  
   249  	// random value
   250  	var x fr.Element
   251  	x.SetRandom()
   252  
   253  	// verify valid proof
   254  	d, err := Commit(p, srs.Pk)
   255  	if err != nil {
   256  		t.Fatal(err)
   257  	}
   258  	proof, err := Open(p, x, srs.Pk)
   259  	if err != nil {
   260  		t.Fatal(err)
   261  	}
   262  	err = Verify(&d, &proof, x, srs.Vk)
   263  	if err != nil {
   264  		t.Fatal(err)
   265  	}
   266  
   267  	// verify wrong proof
   268  	proof.ClaimedValue.SetRandom()
   269  	err = Verify(&d, &proof, x, srs.Vk)
   270  	if err == nil {
   271  		t.Fatal(err)
   272  	}
   273  
   274  }
   275  
   276  func TestBatchVerifySinglePoint(t *testing.T) {
   277  
   278  	size := 40
   279  
   280  	// create polynomials
   281  	f := make([][]fr.Element, 10)
   282  	for i := range f {
   283  		f[i] = randomPolynomial(size)
   284  	}
   285  
   286  	// commit the polynomials
   287  	digests := make([]Digest, len(f))
   288  	for i := range f {
   289  		digests[i], _ = Commit(f[i], testSrs.Pk)
   290  
   291  	}
   292  
   293  	// pick a hash function
   294  	hf := sha256.New()
   295  
   296  	// compute opening proof at a random point
   297  	var point fr.Element
   298  	point.SetString("4321")
   299  	proof, err := BatchOpenSinglePoint(f, digests, point, hf, testSrs.Pk)
   300  	if err != nil {
   301  		t.Fatal(err)
   302  	}
   303  
   304  	var salt fr.Element
   305  	salt.SetRandom()
   306  	proofExtendedTranscript, err := BatchOpenSinglePoint(f, digests, point, hf, testSrs.Pk, salt.Marshal())
   307  	if err != nil {
   308  		t.Fatal(err)
   309  	}
   310  
   311  	// verify the claimed values
   312  	for i := range f {
   313  		expectedClaim := eval(f[i], point)
   314  		if !expectedClaim.Equal(&proof.ClaimedValues[i]) {
   315  			t.Fatal("inconsistent claimed values")
   316  		}
   317  	}
   318  
   319  	// verify correct proof
   320  	err = BatchVerifySinglePoint(digests, &proof, point, hf, testSrs.Vk)
   321  	if err != nil {
   322  		t.Fatal(err)
   323  	}
   324  
   325  	// verify correct proof with extended transcript
   326  	err = BatchVerifySinglePoint(digests, &proofExtendedTranscript, point, hf, testSrs.Vk, salt.Marshal())
   327  	if err != nil {
   328  		t.Fatal(err)
   329  	}
   330  
   331  	{
   332  		// verify wrong proof
   333  		proof.ClaimedValues[0].Double(&proof.ClaimedValues[0])
   334  		err = BatchVerifySinglePoint(digests, &proof, point, hf, testSrs.Vk)
   335  		if err == nil {
   336  			t.Fatal("verifying wrong proof should have failed")
   337  		}
   338  	}
   339  	{
   340  		// verify wrong proof with quotient set to zero
   341  		// see https://cryptosubtlety.medium.com/00-8d4adcf4d255
   342  		proof.H.X.SetZero()
   343  		proof.H.Y.SetZero()
   344  		err = BatchVerifySinglePoint(digests, &proof, point, hf, testSrs.Vk)
   345  		if err == nil {
   346  			t.Fatal("verifying wrong proof should have failed")
   347  		}
   348  	}
   349  }
   350  
   351  func TestBatchVerifyMultiPoints(t *testing.T) {
   352  
   353  	// create polynomials
   354  	f := make([][]fr.Element, 10)
   355  	for i := 0; i < 10; i++ {
   356  		f[i] = randomPolynomial(40)
   357  	}
   358  
   359  	// commit the polynomials
   360  	digests := make([]Digest, 10)
   361  	for i := 0; i < 10; i++ {
   362  		digests[i], _ = Commit(f[i], testSrs.Pk)
   363  	}
   364  
   365  	// pick a hash function
   366  	hf := sha256.New()
   367  
   368  	// compute 2 batch opening proofs at 2 random points
   369  	points := make([]fr.Element, 2)
   370  	batchProofs := make([]BatchOpeningProof, 2)
   371  	points[0].SetRandom()
   372  	batchProofs[0], _ = BatchOpenSinglePoint(f[:5], digests[:5], points[0], hf, testSrs.Pk)
   373  	points[1].SetRandom()
   374  	batchProofs[1], _ = BatchOpenSinglePoint(f[5:], digests[5:], points[1], hf, testSrs.Pk)
   375  
   376  	// fold the 2 batch opening proofs
   377  	proofs := make([]OpeningProof, 2)
   378  	foldedDigests := make([]Digest, 2)
   379  	proofs[0], foldedDigests[0], _ = FoldProof(digests[:5], &batchProofs[0], points[0], hf)
   380  	proofs[1], foldedDigests[1], _ = FoldProof(digests[5:], &batchProofs[1], points[1], hf)
   381  
   382  	// check that the individual batch proofs are correct
   383  	err := Verify(&foldedDigests[0], &proofs[0], points[0], testSrs.Vk)
   384  	if err != nil {
   385  		t.Fatal(err)
   386  	}
   387  	err = Verify(&foldedDigests[1], &proofs[1], points[1], testSrs.Vk)
   388  	if err != nil {
   389  		t.Fatal(err)
   390  	}
   391  
   392  	// batch verify correct folded proofs
   393  	err = BatchVerifyMultiPoints(foldedDigests, proofs, points, testSrs.Vk)
   394  	if err != nil {
   395  		t.Fatal(err)
   396  	}
   397  
   398  	{
   399  		// batch verify tampered folded proofs
   400  		proofs[0].ClaimedValue.Double(&proofs[0].ClaimedValue)
   401  
   402  		err = BatchVerifyMultiPoints(foldedDigests, proofs, points, testSrs.Vk)
   403  		if err == nil {
   404  			t.Fatal(err)
   405  		}
   406  	}
   407  	{
   408  		// batch verify tampered folded proofs with quotients set to infinity
   409  		// see https://cryptosubtlety.medium.com/00-8d4adcf4d255
   410  		proofs[0].H.X.SetZero()
   411  		proofs[0].H.Y.SetZero()
   412  		proofs[1].H.X.SetZero()
   413  		proofs[1].H.Y.SetZero()
   414  		err = BatchVerifyMultiPoints(foldedDigests, proofs, points, testSrs.Vk)
   415  		if err == nil {
   416  			t.Fatal(err)
   417  		}
   418  	}
   419  }
   420  
   421  func TestUnsafeToBytesTruncating(t *testing.T) {
   422  	assert := require.New(t)
   423  	srs, err := NewSRS(ecc.NextPowerOfTwo(1 << 10), big.NewInt(-1))
   424  	assert.NoError(err)
   425  
   426  	// marshal the SRS, but explicitly with less points.
   427  	var buf bytes.Buffer
   428  	err = srs.WriteDump(&buf, 1 << 9)
   429  	assert.NoError(err)
   430  
   431  	r := bytes.NewReader(buf.Bytes())
   432  
   433  	// unmarshal the SRS
   434  	var newSRS SRS
   435  	err = newSRS.ReadDump(r)
   436  	assert.NoError(err)
   437  
   438  	// check that the SRS proving key has only 1 << 9 points
   439  	assert.Equal(1<<9, len(newSRS.Pk.G1))
   440  
   441  	// ensure they are equal to the original SRS
   442  	assert.Equal(srs.Pk.G1[:1<<9], newSRS.Pk.G1)
   443  
   444  	// read even less points.
   445  	var newSRSPartial SRS
   446  	r = bytes.NewReader(buf.Bytes())
   447  	err = newSRSPartial.ReadDump(r, 1 << 8)
   448  	assert.NoError(err)
   449  
   450  	// check that the SRS proving key has only 1 << 8 points
   451  	assert.Equal(1<<8, len(newSRSPartial.Pk.G1))
   452  
   453  	// ensure they are equal to the original SRS
   454  	assert.Equal(srs.Pk.G1[:1<<8], newSRSPartial.Pk.G1)
   455  }
   456  
   457  const benchSize = 1 << 16
   458  
   459  func BenchmarkSRSGen(b *testing.B) {
   460  
   461  	b.Run("real SRS", func(b *testing.B) {
   462  		b.ResetTimer()
   463  		for i := 0; i < b.N; i++ {
   464  			NewSRS(ecc.NextPowerOfTwo(benchSize), new(big.Int).SetInt64(42))
   465  		}
   466  	})
   467  	b.Run("quick SRS", func(b *testing.B) {
   468  		b.ResetTimer()
   469  		for i := 0; i < b.N; i++ {
   470  			NewSRS(ecc.NextPowerOfTwo(benchSize), big.NewInt(-1))
   471  		}
   472  	})
   473  }
   474  
   475  func BenchmarkKZGCommit(b *testing.B) {
   476  
   477  	b.Run("real SRS", func(b *testing.B){
   478  		srs, err := NewSRS(ecc.NextPowerOfTwo(benchSize), new(big.Int).SetInt64(42))
   479  		assert.NoError(b, err)
   480  		// random polynomial
   481  		p := randomPolynomial(benchSize / 2)
   482  
   483  		b.ResetTimer()
   484  		for i := 0; i < b.N; i++ {
   485  			_, _ = Commit(p, srs.Pk)
   486  		}
   487  	})
   488  	b.Run("quick SRS", func(b *testing.B){
   489  		srs, err := NewSRS(ecc.NextPowerOfTwo(benchSize), big.NewInt(-1))
   490  		assert.NoError(b, err)
   491  		// random polynomial
   492  		p := randomPolynomial(benchSize / 2)
   493  
   494  		b.ResetTimer()
   495  		for i := 0; i < b.N; i++ {
   496  			_, _ = Commit(p, srs.Pk)
   497  		}
   498  	})
   499  }
   500  
   501  func BenchmarkDivideByXMinusA(b *testing.B) {
   502  	const pSize = 1 << 22
   503  
   504  	// build random polynomial
   505  	pol := make([]fr.Element, pSize)
   506  	pol[0].SetRandom()
   507  	for i := 1; i < pSize; i++ {
   508  		pol[i] = pol[i-1]
   509  	}
   510  	var a, fa fr.Element
   511  	a.SetRandom()
   512  	fa.SetRandom()
   513  
   514  	b.ResetTimer()
   515  	for i := 0; i < b.N; i++ {
   516  		dividePolyByXminusA(pol, fa, a)
   517  		pol = pol[:pSize]
   518  		pol[pSize-1] = pol[0]
   519  	}
   520  }
   521  
   522  func BenchmarkKZGOpen(b *testing.B) {
   523  	srs, err := NewSRS(ecc.NextPowerOfTwo(benchSize), new(big.Int).SetInt64(42))
   524  	assert.NoError(b, err)
   525  
   526  	// random polynomial
   527  	p := randomPolynomial(benchSize / 2)
   528  	var r fr.Element
   529  	r.SetRandom()
   530  
   531  	b.ResetTimer()
   532  	for i := 0; i < b.N; i++ {
   533  		_, _ = Open(p, r, srs.Pk)
   534  	}
   535  }
   536  
   537  func BenchmarkKZGVerify(b *testing.B) {
   538  	srs, err := NewSRS(ecc.NextPowerOfTwo(benchSize), new(big.Int).SetInt64(42))
   539  	assert.NoError(b, err)
   540  
   541  	// random polynomial
   542  	p := randomPolynomial(benchSize / 2)
   543  	var r fr.Element
   544  	r.SetRandom()
   545  
   546  	// commit
   547  	comm, err := Commit(p, srs.Pk)
   548  	assert.NoError(b, err)
   549  
   550  	// open
   551  	openingProof, err := Open(p, r, srs.Pk)
   552  	assert.NoError(b, err)
   553  
   554  	b.ResetTimer()
   555  	for i := 0; i < b.N; i++ {
   556  		Verify(&comm, &openingProof, r, srs.Vk)
   557  	}
   558  }
   559  
   560  func BenchmarkKZGBatchOpen10(b *testing.B) {
   561  	srs, err := NewSRS(ecc.NextPowerOfTwo(benchSize), new(big.Int).SetInt64(42))
   562  	assert.NoError(b, err)
   563  
   564  	// 10 random polynomials
   565  	var ps [10][]fr.Element
   566  	for i := 0; i < 10; i++ {
   567  		ps[i] = randomPolynomial(benchSize / 2)
   568  	}
   569  
   570  	// commitments
   571  	var commitments [10]Digest
   572  	for i := 0; i < 10; i++ {
   573  		commitments[i], _ = Commit(ps[i], srs.Pk)
   574  	}
   575  
   576  	// pick a hash function
   577  	hf := sha256.New()
   578  
   579  	var r fr.Element
   580  	r.SetRandom()
   581  
   582  	b.ResetTimer()
   583  	for i := 0; i < b.N; i++ {
   584  		BatchOpenSinglePoint(ps[:], commitments[:], r, hf, srs.Pk)
   585  	}
   586  }
   587  
   588  func BenchmarkKZGBatchVerify10(b *testing.B) {
   589  	srs, err := NewSRS(ecc.NextPowerOfTwo(benchSize), new(big.Int).SetInt64(42))
   590  	if err != nil {
   591  		b.Fatal(err)
   592  	}
   593  
   594  	// 10 random polynomials
   595  	var ps [10][]fr.Element
   596  	for i := 0; i < 10; i++ {
   597  		ps[i] = randomPolynomial(benchSize / 2)
   598  	}
   599  
   600  	// commitments
   601  	var commitments [10]Digest
   602  	for i := 0; i < 10; i++ {
   603  		commitments[i], _ = Commit(ps[i], srs.Pk)
   604  	}
   605  
   606  	// pick a hash function
   607  	hf := sha256.New()
   608  
   609  	var r fr.Element
   610  	r.SetRandom()
   611  
   612  	proof, err := BatchOpenSinglePoint(ps[:], commitments[:], r, hf, srs.Pk)
   613  	if err != nil {
   614  		b.Fatal(err)
   615  	}
   616  
   617  	b.ResetTimer()
   618  	for i := 0; i < b.N; i++ {
   619  		BatchVerifySinglePoint(commitments[:], &proof, r, hf, testSrs.Vk)
   620  	}
   621  }
   622  
   623  func randomPolynomial(size int) []fr.Element {
   624  	f := make([]fr.Element, size)
   625  	for i := 0; i < size; i++ {
   626  		f[i].SetRandom()
   627  	}
   628  	return f
   629  }
   630  
   631  
   632  func BenchmarkToLagrangeG1(b *testing.B) {
   633  	const size = 1 << 14
   634  
   635  	var samplePoints [size]{{ .CurvePackage }}.G1Affine
   636  	fillBenchBasesG1(samplePoints[:])
   637  	b.ResetTimer()
   638  
   639  	for i := 0; i < b.N; i++ {
   640  		if _, err := ToLagrangeG1(samplePoints[:]); err != nil {
   641  			b.Fatal(err)
   642  		}
   643  	}
   644  }
   645  
   646  func BenchmarkSerializeSRS(b *testing.B) {
   647  	// let's create a quick SRS
   648  	srs, err := NewSRS(ecc.NextPowerOfTwo(1 << 24), big.NewInt(-1))
   649  	if err != nil {
   650  		b.Fatal(err)
   651  	}
   652  
   653  	// now we can benchmark the WriteTo, WriteRawTo and WriteDump methods
   654  	b.Run("WriteTo", func(b *testing.B) {
   655  		b.ResetTimer()
   656  		var buf bytes.Buffer
   657  		for i := 0; i < b.N; i++ {
   658  			buf.Reset()
   659  			_, err := srs.WriteTo(&buf)
   660  			if err != nil {
   661  				b.Fatal(err)
   662  			}
   663  		}
   664  	})
   665  
   666  	b.Run("WriteRawTo", func(b *testing.B) {
   667  		b.ResetTimer()
   668  		var buf bytes.Buffer
   669  		for i := 0; i < b.N; i++ {
   670  			buf.Reset()
   671  			_, err := srs.WriteRawTo(&buf)
   672  			if err != nil {
   673  				b.Fatal(err)
   674  			}
   675  		}
   676  	})
   677  
   678  	b.Run("WriteDump", func(b *testing.B) {
   679  		b.ResetTimer()
   680  		var buf bytes.Buffer
   681  		for i := 0; i < b.N; i++ {
   682  			buf.Reset()
   683  			if err := srs.WriteDump(&buf); err != nil {
   684  				b.Fatal(err)
   685  			}
   686  		}
   687  	})
   688  
   689  }
   690  
   691  func BenchmarkDeserializeSRS(b *testing.B) {
   692  	// let's create a quick SRS
   693  	srs, err := NewSRS(ecc.NextPowerOfTwo(1 << 24), big.NewInt(-1))
   694  	if err != nil {
   695  		b.Fatal(err)
   696  	}
   697  	
   698  	b.Run("UnsafeReadFrom", func(b *testing.B) {
   699  		var buf bytes.Buffer
   700  		if _, err := srs.WriteRawTo(&buf); err != nil {
   701  			b.Fatal(err)
   702  		}
   703  		b.ResetTimer()
   704  		for i := 0; i < b.N; i++ {
   705  			var newSRS SRS
   706  			_, err := newSRS.UnsafeReadFrom(bytes.NewReader(buf.Bytes()))
   707  			if err != nil {
   708  				b.Fatal(err)
   709  			}
   710  		}
   711  	})
   712  
   713  	b.Run("ReadDump", func(b *testing.B) {
   714  		var buf bytes.Buffer
   715  		err := srs.WriteDump(&buf)
   716  		if err != nil {
   717  			b.Fatal(err)
   718  		}
   719  		data := buf.Bytes()
   720  		b.ResetTimer()
   721  		for i := 0; i < b.N; i++ {
   722  			var newSRS SRS
   723  			if err := newSRS.ReadDump(bytes.NewReader(data)); err != nil {
   724  				b.Fatal(err)
   725  			}
   726  		}
   727  	})
   728  }
   729  
   730  
   731  func fillBenchBasesG1(samplePoints []{{ .CurvePackage }}.G1Affine) {
   732  	var r big.Int
   733  	r.SetString("340444420969191673093399857471996460938405", 10)
   734  	samplePoints[0].ScalarMultiplication(&samplePoints[0], &r)
   735  
   736  	one := samplePoints[0].X
   737  	one.SetOne()
   738  
   739  	for i := 1; i < len(samplePoints); i++ {
   740  		samplePoints[i].X.Add(&samplePoints[i-1].X, &one)
   741  		samplePoints[i].Y.Sub(&samplePoints[i-1].Y, &one)
   742  	}
   743  }