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