github.com/klaytn/klaytn@v1.12.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  func testKZGWithPoint(t *testing.T, ckzg bool) {
    51  	if ckzg && !ckzgAvailable {
    52  		t.Skip("CKZG unavailable in this test build")
    53  	}
    54  	defer func(old bool) { useCKZG.Store(old) }(useCKZG.Load())
    55  	useCKZG.Store(ckzg)
    56  
    57  	blob := randBlob()
    58  
    59  	commitment, err := BlobToCommitment(blob)
    60  	if err != nil {
    61  		t.Fatalf("failed to create KZG commitment from blob: %v", err)
    62  	}
    63  	point := randFieldElement()
    64  	proof, claim, err := ComputeProof(blob, point)
    65  	if err != nil {
    66  		t.Fatalf("failed to create KZG proof at point: %v", err)
    67  	}
    68  	if err := VerifyProof(commitment, point, claim, proof); err != nil {
    69  		t.Fatalf("failed to verify KZG proof at point: %v", err)
    70  	}
    71  }
    72  
    73  func TestCKZGWithBlob(t *testing.T)  { testKZGWithBlob(t, true) }
    74  func TestGoKZGWithBlob(t *testing.T) { testKZGWithBlob(t, false) }
    75  func testKZGWithBlob(t *testing.T, ckzg bool) {
    76  	if ckzg && !ckzgAvailable {
    77  		t.Skip("CKZG unavailable in this test build")
    78  	}
    79  	defer func(old bool) { useCKZG.Store(old) }(useCKZG.Load())
    80  	useCKZG.Store(ckzg)
    81  
    82  	blob := randBlob()
    83  
    84  	commitment, err := BlobToCommitment(blob)
    85  	if err != nil {
    86  		t.Fatalf("failed to create KZG commitment from blob: %v", err)
    87  	}
    88  	proof, err := ComputeBlobProof(blob, commitment)
    89  	if err != nil {
    90  		t.Fatalf("failed to create KZG proof for blob: %v", err)
    91  	}
    92  	if err := VerifyBlobProof(blob, commitment, proof); err != nil {
    93  		t.Fatalf("failed to verify KZG proof for blob: %v", err)
    94  	}
    95  }
    96  
    97  func BenchmarkCKZGBlobToCommitment(b *testing.B)  { benchmarkBlobToCommitment(b, true) }
    98  func BenchmarkGoKZGBlobToCommitment(b *testing.B) { benchmarkBlobToCommitment(b, false) }
    99  func benchmarkBlobToCommitment(b *testing.B, ckzg bool) {
   100  	if ckzg && !ckzgAvailable {
   101  		b.Skip("CKZG unavailable in this test build")
   102  	}
   103  	defer func(old bool) { useCKZG.Store(old) }(useCKZG.Load())
   104  	useCKZG.Store(ckzg)
   105  
   106  	blob := randBlob()
   107  
   108  	b.ResetTimer()
   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  
   128  	b.ResetTimer()
   129  	for i := 0; i < b.N; i++ {
   130  		ComputeProof(blob, point)
   131  	}
   132  }
   133  
   134  func BenchmarkCKZGVerifyProof(b *testing.B)  { benchmarkVerifyProof(b, true) }
   135  func BenchmarkGoKZGVerifyProof(b *testing.B) { benchmarkVerifyProof(b, false) }
   136  func benchmarkVerifyProof(b *testing.B, ckzg bool) {
   137  	if ckzg && !ckzgAvailable {
   138  		b.Skip("CKZG unavailable in this test build")
   139  	}
   140  	defer func(old bool) { useCKZG.Store(old) }(useCKZG.Load())
   141  	useCKZG.Store(ckzg)
   142  
   143  	var (
   144  		blob            = randBlob()
   145  		point           = randFieldElement()
   146  		commitment, _   = BlobToCommitment(blob)
   147  		proof, claim, _ = ComputeProof(blob, point)
   148  	)
   149  
   150  	b.ResetTimer()
   151  	for i := 0; i < b.N; i++ {
   152  		VerifyProof(commitment, point, claim, proof)
   153  	}
   154  }
   155  
   156  func BenchmarkCKZGComputeBlobProof(b *testing.B)  { benchmarkComputeBlobProof(b, true) }
   157  func BenchmarkGoKZGComputeBlobProof(b *testing.B) { benchmarkComputeBlobProof(b, false) }
   158  func benchmarkComputeBlobProof(b *testing.B, ckzg bool) {
   159  	if ckzg && !ckzgAvailable {
   160  		b.Skip("CKZG unavailable in this test build")
   161  	}
   162  	defer func(old bool) { useCKZG.Store(old) }(useCKZG.Load())
   163  	useCKZG.Store(ckzg)
   164  
   165  	var (
   166  		blob          = randBlob()
   167  		commitment, _ = BlobToCommitment(blob)
   168  	)
   169  
   170  	b.ResetTimer()
   171  	for i := 0; i < b.N; i++ {
   172  		ComputeBlobProof(blob, commitment)
   173  	}
   174  }
   175  
   176  func BenchmarkCKZGVerifyBlobProof(b *testing.B)  { benchmarkVerifyBlobProof(b, true) }
   177  func BenchmarkGoKZGVerifyBlobProof(b *testing.B) { benchmarkVerifyBlobProof(b, false) }
   178  func benchmarkVerifyBlobProof(b *testing.B, ckzg bool) {
   179  	if ckzg && !ckzgAvailable {
   180  		b.Skip("CKZG unavailable in this test build")
   181  	}
   182  	defer func(old bool) { useCKZG.Store(old) }(useCKZG.Load())
   183  	useCKZG.Store(ckzg)
   184  
   185  	var (
   186  		blob          = randBlob()
   187  		commitment, _ = BlobToCommitment(blob)
   188  		proof, _      = ComputeBlobProof(blob, commitment)
   189  	)
   190  
   191  	b.ResetTimer()
   192  	for i := 0; i < b.N; i++ {
   193  		VerifyBlobProof(blob, commitment, proof)
   194  	}
   195  }