github.com/calmw/ethereum@v0.1.1/crypto/kzg4844/kzg4844_test.go (about)

     1  // Copyright 2023 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package kzg4844
    18  
    19  import (
    20  	"crypto/rand"
    21  	"testing"
    22  
    23  	"github.com/consensys/gnark-crypto/ecc/bls12-381/fr"
    24  	gokzg4844 "github.com/crate-crypto/go-kzg-4844"
    25  )
    26  
    27  func randFieldElement() [32]byte {
    28  	bytes := make([]byte, 32)
    29  	_, err := rand.Read(bytes)
    30  	if err != nil {
    31  		panic("failed to get random field element")
    32  	}
    33  	var r fr.Element
    34  	r.SetBytes(bytes)
    35  
    36  	return gokzg4844.SerializeScalar(r)
    37  }
    38  
    39  func randBlob() Blob {
    40  	var blob Blob
    41  	for i := 0; i < len(blob); i += gokzg4844.SerializedScalarSize {
    42  		fieldElementBytes := randFieldElement()
    43  		copy(blob[i:i+gokzg4844.SerializedScalarSize], fieldElementBytes[:])
    44  	}
    45  	return blob
    46  }
    47  
    48  func TestCKZGWithPoint(t *testing.T)  { testKZGWithPoint(t, true) }
    49  func TestGoKZGWithPoint(t *testing.T) { testKZGWithPoint(t, false) }
    50  
    51  func testKZGWithPoint(t *testing.T, ckzg bool) {
    52  	if ckzg && !ckzgAvailable {
    53  		t.Skip("CKZG unavailable in this test build")
    54  	}
    55  	defer func(old bool) { useCKZG.Store(old) }(useCKZG.Load())
    56  	useCKZG.Store(ckzg)
    57  
    58  	blob := randBlob()
    59  
    60  	commitment, err := BlobToCommitment(blob)
    61  	if err != nil {
    62  		t.Fatalf("failed to create KZG commitment from blob: %v", err)
    63  	}
    64  	point := randFieldElement()
    65  	proof, claim, err := ComputeProof(blob, point)
    66  	if err != nil {
    67  		t.Fatalf("failed to create KZG proof at point: %v", err)
    68  	}
    69  	if err := VerifyProof(commitment, point, claim, proof); err != nil {
    70  		t.Fatalf("failed to verify KZG proof at point: %v", err)
    71  	}
    72  }
    73  
    74  func TestCKZGWithBlob(t *testing.T)  { testKZGWithBlob(t, true) }
    75  func TestGoKZGWithBlob(t *testing.T) { testKZGWithBlob(t, false) }
    76  
    77  func testKZGWithBlob(t *testing.T, ckzg bool) {
    78  	if ckzg && !ckzgAvailable {
    79  		t.Skip("CKZG unavailable in this test build")
    80  	}
    81  	defer func(old bool) { useCKZG.Store(old) }(useCKZG.Load())
    82  	useCKZG.Store(ckzg)
    83  
    84  	blob := randBlob()
    85  
    86  	commitment, err := BlobToCommitment(blob)
    87  	if err != nil {
    88  		t.Fatalf("failed to create KZG commitment from blob: %v", err)
    89  	}
    90  	proof, err := ComputeBlobProof(blob, commitment)
    91  	if err != nil {
    92  		t.Fatalf("failed to create KZG proof for blob: %v", err)
    93  	}
    94  	if err := VerifyBlobProof(blob, commitment, proof); err != nil {
    95  		t.Fatalf("failed to verify KZG proof for blob: %v", err)
    96  	}
    97  }
    98  
    99  func BenchmarkCKZGBlobToCommitment(b *testing.B)  { benchmarkBlobToCommitment(b, true) }
   100  func BenchmarkGoKZGBlobToCommitment(b *testing.B) { benchmarkBlobToCommitment(b, false) }
   101  func benchmarkBlobToCommitment(b *testing.B, ckzg bool) {
   102  	if ckzg && !ckzgAvailable {
   103  		b.Skip("CKZG unavailable in this test build")
   104  	}
   105  	defer func(old bool) { useCKZG.Store(old) }(useCKZG.Load())
   106  	useCKZG.Store(ckzg)
   107  
   108  	blob := randBlob()
   109  	for i := 0; i < b.N; i++ {
   110  		BlobToCommitment(blob)
   111  	}
   112  }
   113  
   114  func BenchmarkCKZGComputeProof(b *testing.B)  { benchmarkComputeProof(b, true) }
   115  func BenchmarkGoKZGComputeProof(b *testing.B) { benchmarkComputeProof(b, false) }
   116  func benchmarkComputeProof(b *testing.B, ckzg bool) {
   117  	if ckzg && !ckzgAvailable {
   118  		b.Skip("CKZG unavailable in this test build")
   119  	}
   120  	defer func(old bool) { useCKZG.Store(old) }(useCKZG.Load())
   121  	useCKZG.Store(ckzg)
   122  
   123  	var (
   124  		blob  = randBlob()
   125  		point = randFieldElement()
   126  	)
   127  	for i := 0; i < b.N; i++ {
   128  		ComputeProof(blob, point)
   129  	}
   130  }
   131  
   132  func BenchmarkCKZGVerifyProof(b *testing.B)  { benchmarkVerifyProof(b, true) }
   133  func BenchmarkGoKZGVerifyProof(b *testing.B) { benchmarkVerifyProof(b, false) }
   134  func benchmarkVerifyProof(b *testing.B, ckzg bool) {
   135  	if ckzg && !ckzgAvailable {
   136  		b.Skip("CKZG unavailable in this test build")
   137  	}
   138  	defer func(old bool) { useCKZG.Store(old) }(useCKZG.Load())
   139  	useCKZG.Store(ckzg)
   140  
   141  	var (
   142  		blob            = randBlob()
   143  		point           = randFieldElement()
   144  		commitment, _   = BlobToCommitment(blob)
   145  		proof, claim, _ = ComputeProof(blob, point)
   146  	)
   147  	for i := 0; i < b.N; i++ {
   148  		VerifyProof(commitment, point, claim, proof)
   149  	}
   150  }
   151  
   152  func BenchmarkCKZGComputeBlobProof(b *testing.B)  { benchmarkComputeBlobProof(b, true) }
   153  func BenchmarkGoKZGComputeBlobProof(b *testing.B) { benchmarkComputeBlobProof(b, false) }
   154  func benchmarkComputeBlobProof(b *testing.B, ckzg bool) {
   155  	if ckzg && !ckzgAvailable {
   156  		b.Skip("CKZG unavailable in this test build")
   157  	}
   158  	defer func(old bool) { useCKZG.Store(old) }(useCKZG.Load())
   159  	useCKZG.Store(ckzg)
   160  
   161  	var (
   162  		blob          = randBlob()
   163  		commitment, _ = BlobToCommitment(blob)
   164  	)
   165  	for i := 0; i < b.N; i++ {
   166  		ComputeBlobProof(blob, commitment)
   167  	}
   168  }
   169  
   170  func BenchmarkCKZGVerifyBlobProof(b *testing.B)  { benchmarkVerifyBlobProof(b, true) }
   171  func BenchmarkGoKZGVerifyBlobProof(b *testing.B) { benchmarkVerifyBlobProof(b, false) }
   172  func benchmarkVerifyBlobProof(b *testing.B, ckzg bool) {
   173  	if ckzg && !ckzgAvailable {
   174  		b.Skip("CKZG unavailable in this test build")
   175  	}
   176  	defer func(old bool) { useCKZG.Store(old) }(useCKZG.Load())
   177  	useCKZG.Store(ckzg)
   178  
   179  	var (
   180  		blob          = randBlob()
   181  		commitment, _ = BlobToCommitment(blob)
   182  		proof, _      = ComputeBlobProof(blob, commitment)
   183  	)
   184  	for i := 0; i < b.N; i++ {
   185  		VerifyBlobProof(blob, commitment, proof)
   186  	}
   187  }