From 8b10b212768393e9670e23635162c6c35006d1a9 Mon Sep 17 00:00:00 2001 From: yperbasis Date: Wed, 29 Jan 2025 23:01:24 +0100 Subject: [PATCH 1/2] Pass blobs by ref in VerifyBlobKZGProofBatch as well --- api_test.go | 2 +- bench_test.go | 12 ++++++------ consensus_specs_test.go | 4 ++-- examples_test.go | 4 ++-- verify.go | 8 ++++---- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/api_test.go b/api_test.go index eeb4e19..d0dbee6 100644 --- a/api_test.go +++ b/api_test.go @@ -74,7 +74,7 @@ func TestNonCanonicalSmoke(t *testing.T) { err = ctx.VerifyBlobKZGProof(blobBad, commitment, blobProof) require.Error(t, err, "expected an error since blob was not canonical") - err = ctx.VerifyBlobKZGProofBatch([]gokzg4844.Blob{*blobBad}, []gokzg4844.KZGCommitment{commitment}, []gokzg4844.KZGProof{blobProof}) + err = ctx.VerifyBlobKZGProofBatch([]*gokzg4844.Blob{blobBad}, []gokzg4844.KZGCommitment{commitment}, []gokzg4844.KZGProof{blobProof}) require.Error(t, err, "expected an error since blob was not canonical") } diff --git a/bench_test.go b/bench_test.go index bab0ed9..6e4166e 100644 --- a/bench_test.go +++ b/bench_test.go @@ -47,7 +47,7 @@ func GetRandBlob(seed int64) *gokzg4844.Blob { func Benchmark(b *testing.B) { const length = 64 - blobs := make([]gokzg4844.Blob, length) + blobs := make([]*gokzg4844.Blob, length) commitments := make([]gokzg4844.KZGCommitment, length) proofs := make([]gokzg4844.KZGProof, length) fields := make([]gokzg4844.Scalar, length) @@ -59,7 +59,7 @@ func Benchmark(b *testing.B) { proof, err := ctx.ComputeBlobKZGProof(blob, commitment, NumGoRoutines) require.NoError(b, err) - blobs[i] = *blob + blobs[i] = blob commitments[i] = commitment proofs[i] = proof fields[i] = GetRandFieldElement(int64(i)) @@ -72,21 +72,21 @@ func Benchmark(b *testing.B) { b.Run("BlobToKZGCommitment", func(b *testing.B) { b.ReportAllocs() for n := 0; n < b.N; n++ { - _, _ = ctx.BlobToKZGCommitment(&blobs[0], NumGoRoutines) + _, _ = ctx.BlobToKZGCommitment(blobs[0], NumGoRoutines) } }) b.Run("ComputeKZGProof", func(b *testing.B) { b.ReportAllocs() for n := 0; n < b.N; n++ { - _, _, _ = ctx.ComputeKZGProof(&blobs[0], fields[0], NumGoRoutines) + _, _, _ = ctx.ComputeKZGProof(blobs[0], fields[0], NumGoRoutines) } }) b.Run("ComputeBlobKZGProof", func(b *testing.B) { b.ReportAllocs() for n := 0; n < b.N; n++ { - _, _ = ctx.ComputeBlobKZGProof(&blobs[0], commitments[0], NumGoRoutines) + _, _ = ctx.ComputeBlobKZGProof(blobs[0], commitments[0], NumGoRoutines) } }) @@ -100,7 +100,7 @@ func Benchmark(b *testing.B) { b.Run("VerifyBlobKZGProof", func(b *testing.B) { b.ReportAllocs() for n := 0; n < b.N; n++ { - _ = ctx.VerifyBlobKZGProof(&blobs[0], commitments[0], proofs[0]) + _ = ctx.VerifyBlobKZGProof(blobs[0], commitments[0], proofs[0]) } }) diff --git a/consensus_specs_test.go b/consensus_specs_test.go index 73769a4..f7c761a 100644 --- a/consensus_specs_test.go +++ b/consensus_specs_test.go @@ -306,14 +306,14 @@ func TestVerifyBlobKZGProofBatch(t *testing.T) { require.NoError(t, err) testCaseValid := test.ProofIsValid != nil - var blobs []gokzg4844.Blob + var blobs []*gokzg4844.Blob for _, b := range test.Input.Blobs { blob, err := hexStrToBlob(b) if err != nil { require.False(t, testCaseValid) return } - blobs = append(blobs, *blob) + blobs = append(blobs, blob) } var commitments []gokzg4844.KZGCommitment diff --git a/examples_test.go b/examples_test.go index f9be068..8929f17 100644 --- a/examples_test.go +++ b/examples_test.go @@ -33,7 +33,7 @@ func TestBlobProveVerifySpecifiedPointIntegration(t *testing.T) { func TestBlobProveVerifyBatchIntegration(t *testing.T) { batchSize := 5 - blobs := make([]gokzg4844.Blob, batchSize) + blobs := make([]*gokzg4844.Blob, batchSize) commitments := make([]gokzg4844.KZGCommitment, batchSize) proofs := make([]gokzg4844.KZGProof, batchSize) @@ -44,7 +44,7 @@ func TestBlobProveVerifyBatchIntegration(t *testing.T) { proof, err := ctx.ComputeBlobKZGProof(blob, commitment, NumGoRoutines) require.NoError(t, err) - blobs[i] = *blob + blobs[i] = blob commitments[i] = commitment proofs[i] = proof } diff --git a/verify.go b/verify.go index ea54465..9be66aa 100644 --- a/verify.go +++ b/verify.go @@ -85,7 +85,7 @@ func (c *Context) VerifyBlobKZGProof(blob *Blob, blobCommitment KZGCommitment, k // VerifyBlobKZGProofBatch implements [verify_blob_kzg_proof_batch]. // // [verify_blob_kzg_proof_batch]: https://github.com/ethereum/consensus-specs/blob/017a8495f7671f5fff2075a9bfc9238c1a0982f8/specs/deneb/polynomial-commitments.md#verify_blob_kzg_proof_batch -func (c *Context) VerifyBlobKZGProofBatch(blobs []Blob, polynomialCommitments []KZGCommitment, kzgProofs []KZGProof) error { +func (c *Context) VerifyBlobKZGProofBatch(blobs []*Blob, polynomialCommitments []KZGCommitment, kzgProofs []KZGProof) error { // 1. Check that all components in the batch have the same size // blobsLen := len(blobs) @@ -114,7 +114,7 @@ func (c *Context) VerifyBlobKZGProofBatch(blobs []Blob, polynomialCommitments [] return err } - blob := &blobs[i] + blob := blobs[i] polynomial, err := DeserializeBlob(blob) if err != nil { return err @@ -149,7 +149,7 @@ func (c *Context) VerifyBlobKZGProofBatch(blobs []Blob, polynomialCommitments [] // go-routines in a more intricate way than done below for large batches. // // [verify_blob_kzg_proof_batch]: https://github.com/ethereum/consensus-specs/blob/017a8495f7671f5fff2075a9bfc9238c1a0982f8/specs/deneb/polynomial-commitments.md#verify_blob_kzg_proof_batch -func (c *Context) VerifyBlobKZGProofBatchPar(blobs []Blob, commitments []KZGCommitment, proofs []KZGProof) error { +func (c *Context) VerifyBlobKZGProofBatchPar(blobs []*Blob, commitments []KZGCommitment, proofs []KZGProof) error { // 1. Check that all components in the batch have the same size if len(commitments) != len(blobs) || len(proofs) != len(blobs) { return ErrBatchLengthCheck @@ -160,7 +160,7 @@ func (c *Context) VerifyBlobKZGProofBatchPar(blobs []Blob, commitments []KZGComm for i := range blobs { j := i // Capture the value of the loop variable errG.Go(func() error { - return c.VerifyBlobKZGProof(&blobs[j], commitments[j], proofs[j]) + return c.VerifyBlobKZGProof(blobs[j], commitments[j], proofs[j]) }) } From ce13be60bc86e2c05f8d03ea5eac84fe0003062c Mon Sep 17 00:00:00 2001 From: yperbasis Date: Thu, 30 Jan 2025 14:10:58 +0100 Subject: [PATCH 2/2] Use slices instead of pointers to arrays to pass blobs by reference --- api_test.go | 20 ++++++++++---------- bench_test.go | 16 ++++++++-------- consensus_specs_test.go | 20 ++++++++++---------- examples_test.go | 18 +++++++++--------- fiatshamir.go | 4 ++-- fiatshamir_test.go | 8 ++++---- prove.go | 6 +++--- serialization.go | 10 +++++++--- serialization_test.go | 4 ++-- verify.go | 6 +++--- 10 files changed, 58 insertions(+), 54 deletions(-) diff --git a/api_test.go b/api_test.go index d0dbee6..7bc4c60 100644 --- a/api_test.go +++ b/api_test.go @@ -40,23 +40,23 @@ func TestNonCanonicalSmoke(t *testing.T) { blobGood := GetRandBlob(123456789) blobBad := GetRandBlob(123456789) unreducedScalar := nonCanonicalScalar(123445) - modifyBlob(blobBad, unreducedScalar, 0) + modifyBlob(blobBad[:], unreducedScalar, 0) - commitment, err := ctx.BlobToKZGCommitment(blobGood, NumGoRoutines) + commitment, err := ctx.BlobToKZGCommitment(blobGood[:], NumGoRoutines) require.NoError(t, err) - _, err = ctx.BlobToKZGCommitment(blobBad, NumGoRoutines) + _, err = ctx.BlobToKZGCommitment(blobBad[:], NumGoRoutines) require.Error(t, err, "expected an error as we gave a non-canonical blob") inputPointGood := GetRandFieldElement(123) inputPointBad := createScalarNonCanonical(inputPointGood) - proof, claimedValueGood, err := ctx.ComputeKZGProof(blobGood, inputPointGood, NumGoRoutines) + proof, claimedValueGood, err := ctx.ComputeKZGProof(blobGood[:], inputPointGood, NumGoRoutines) require.NoError(t, err) claimedValueBad := createScalarNonCanonical(claimedValueGood) - _, _, err = ctx.ComputeKZGProof(blobGood, inputPointBad, NumGoRoutines) + _, _, err = ctx.ComputeKZGProof(blobGood[:], inputPointBad, NumGoRoutines) require.Error(t, err, "expected an error since input point was not canonical") - _, _, err = ctx.ComputeKZGProof(blobBad, inputPointGood, NumGoRoutines) + _, _, err = ctx.ComputeKZGProof(blobBad[:], inputPointGood, NumGoRoutines) require.Error(t, err, "expected an error since blob was not canonical") err = ctx.VerifyKZGProof(commitment, inputPointGood, claimedValueGood, proof) @@ -68,19 +68,19 @@ func TestNonCanonicalSmoke(t *testing.T) { err = ctx.VerifyKZGProof(commitment, inputPointBad, claimedValueGood, proof) require.Error(t, err, "expected an error since input point was not canonical") - blobProof, err := ctx.ComputeBlobKZGProof(blobBad, commitment, NumGoRoutines) + blobProof, err := ctx.ComputeBlobKZGProof(blobBad[:], commitment, NumGoRoutines) require.Error(t, err, "expected an error since blob was not canonical") - err = ctx.VerifyBlobKZGProof(blobBad, commitment, blobProof) + err = ctx.VerifyBlobKZGProof(blobBad[:], commitment, blobProof) require.Error(t, err, "expected an error since blob was not canonical") - err = ctx.VerifyBlobKZGProofBatch([]*gokzg4844.Blob{blobBad}, []gokzg4844.KZGCommitment{commitment}, []gokzg4844.KZGProof{blobProof}) + err = ctx.VerifyBlobKZGProofBatch([]gokzg4844.BlobRef{blobBad[:]}, []gokzg4844.KZGCommitment{commitment}, []gokzg4844.KZGProof{blobProof}) require.Error(t, err, "expected an error since blob was not canonical") } // Below are helper methods which allow us to change a serialized element into // its non-canonical counterpart by adding the modulus -func modifyBlob(blob *gokzg4844.Blob, newValue gokzg4844.Scalar, index int) { +func modifyBlob(blob gokzg4844.BlobRef, newValue gokzg4844.Scalar, index int) { copy(blob[index:index+gokzg4844.SerializedScalarSize], newValue[:]) } diff --git a/bench_test.go b/bench_test.go index 6e4166e..ae117b0 100644 --- a/bench_test.go +++ b/bench_test.go @@ -35,31 +35,31 @@ func GetRandFieldElement(seed int64) [32]byte { return gokzg4844.SerializeScalar(r) } -func GetRandBlob(seed int64) *gokzg4844.Blob { +func GetRandBlob(seed int64) gokzg4844.Blob { var blob gokzg4844.Blob bytesPerBlob := gokzg4844.ScalarsPerBlob * gokzg4844.SerializedScalarSize for i := 0; i < bytesPerBlob; i += gokzg4844.SerializedScalarSize { fieldElementBytes := GetRandFieldElement(seed + int64(i)) copy(blob[i:i+gokzg4844.SerializedScalarSize], fieldElementBytes[:]) } - return &blob + return blob } func Benchmark(b *testing.B) { const length = 64 - blobs := make([]*gokzg4844.Blob, length) + blobs := make([]gokzg4844.BlobRef, length) commitments := make([]gokzg4844.KZGCommitment, length) proofs := make([]gokzg4844.KZGProof, length) fields := make([]gokzg4844.Scalar, length) for i := 0; i < length; i++ { blob := GetRandBlob(int64(i)) - commitment, err := ctx.BlobToKZGCommitment(blob, NumGoRoutines) + commitment, err := ctx.BlobToKZGCommitment(blob[:], NumGoRoutines) require.NoError(b, err) - proof, err := ctx.ComputeBlobKZGProof(blob, commitment, NumGoRoutines) + proof, err := ctx.ComputeBlobKZGProof(blob[:], commitment, NumGoRoutines) require.NoError(b, err) - blobs[i] = blob + blobs[i] = blob[:] commitments[i] = commitment proofs[i] = proof fields[i] = GetRandFieldElement(int64(i)) @@ -126,7 +126,7 @@ func Benchmark(b *testing.B) { func BenchmarkDeserializeBlob(b *testing.B) { var ( blob = GetRandBlob(int64(13)) - first, err = gokzg4844.DeserializeBlob(blob) + first, err = gokzg4844.DeserializeBlob(blob[:]) second kzg.Polynomial ) if err != nil { @@ -135,7 +135,7 @@ func BenchmarkDeserializeBlob(b *testing.B) { b.ResetTimer() b.ReportAllocs() for n := 0; n < b.N; n++ { - second, err = gokzg4844.DeserializeBlob(blob) + second, err = gokzg4844.DeserializeBlob(blob[:]) if err != nil { b.Fatal(err) } diff --git a/consensus_specs_test.go b/consensus_specs_test.go index f7c761a..5f54606 100644 --- a/consensus_specs_test.go +++ b/consensus_specs_test.go @@ -52,7 +52,7 @@ func TestBlobToKZGCommitment(t *testing.T) { require.False(t, testCaseValid) return } - gotCommitment, err := ctx.BlobToKZGCommitment(blob, NumGoRoutines) + gotCommitment, err := ctx.BlobToKZGCommitment(blob[:], NumGoRoutines) if err != nil { require.False(t, testCaseValid) return @@ -98,7 +98,7 @@ func TestComputeKZGProof(t *testing.T) { require.False(t, testCaseValid) return } - proof, outputPoint, err := ctx.ComputeKZGProof(blob, inputPoint, NumGoRoutines) + proof, outputPoint, err := ctx.ComputeKZGProof(blob[:], inputPoint, NumGoRoutines) if err != nil { require.False(t, testCaseValid) return @@ -148,7 +148,7 @@ func TestComputeBlobKZGProof(t *testing.T) { require.False(t, testCaseValid) return } - proof, err := ctx.ComputeBlobKZGProof(blob, commitment, NumGoRoutines) + proof, err := ctx.ComputeBlobKZGProof(blob[:], commitment, NumGoRoutines) if err != nil { require.False(t, testCaseValid) return @@ -265,7 +265,7 @@ func TestVerifyBlobKZGProof(t *testing.T) { return } - err = ctx.VerifyBlobKZGProof(blob, commitment, proof) + err = ctx.VerifyBlobKZGProof(blob[:], commitment, proof) // Test specifically distinguish between the test failing // because of the pairing check and failing because of @@ -306,14 +306,14 @@ func TestVerifyBlobKZGProofBatch(t *testing.T) { require.NoError(t, err) testCaseValid := test.ProofIsValid != nil - var blobs []*gokzg4844.Blob + var blobs []gokzg4844.BlobRef for _, b := range test.Input.Blobs { blob, err := hexStrToBlob(b) if err != nil { require.False(t, testCaseValid) return } - blobs = append(blobs, blob) + blobs = append(blobs, blob[:]) } var commitments []gokzg4844.KZGCommitment @@ -355,18 +355,18 @@ func TestVerifyBlobKZGProofBatch(t *testing.T) { } } -func hexStrToBlob(hexStr string) (*gokzg4844.Blob, error) { +func hexStrToBlob(hexStr string) (gokzg4844.Blob, error) { var blob gokzg4844.Blob byts, err := hexStrToBytes(hexStr) if err != nil { - return nil, err + return blob, err } if len(blob) != len(byts) { - return nil, fmt.Errorf("blob does not have the correct length, %d ", len(byts)) + return blob, fmt.Errorf("blob does not have the correct length, %d ", len(byts)) } copy(blob[:], byts) - return &blob, nil + return blob, nil } func hexStrToScalar(hexStr string) (gokzg4844.Scalar, error) { diff --git a/examples_test.go b/examples_test.go index 8929f17..d5b2543 100644 --- a/examples_test.go +++ b/examples_test.go @@ -12,20 +12,20 @@ var ctx, _ = gokzg4844.NewContext4096Secure() func TestBlobProveVerifyRandomPointIntegration(t *testing.T) { blob := GetRandBlob(123) - commitment, err := ctx.BlobToKZGCommitment(blob, NumGoRoutines) + commitment, err := ctx.BlobToKZGCommitment(blob[:], NumGoRoutines) require.NoError(t, err) - proof, err := ctx.ComputeBlobKZGProof(blob, commitment, NumGoRoutines) + proof, err := ctx.ComputeBlobKZGProof(blob[:], commitment, NumGoRoutines) require.NoError(t, err) - err = ctx.VerifyBlobKZGProof(blob, commitment, proof) + err = ctx.VerifyBlobKZGProof(blob[:], commitment, proof) require.NoError(t, err) } func TestBlobProveVerifySpecifiedPointIntegration(t *testing.T) { blob := GetRandBlob(123) - commitment, err := ctx.BlobToKZGCommitment(blob, NumGoRoutines) + commitment, err := ctx.BlobToKZGCommitment(blob[:], NumGoRoutines) require.NoError(t, err) inputPoint := GetRandFieldElement(123) - proof, claimedValue, err := ctx.ComputeKZGProof(blob, inputPoint, NumGoRoutines) + proof, claimedValue, err := ctx.ComputeKZGProof(blob[:], inputPoint, NumGoRoutines) require.NoError(t, err) err = ctx.VerifyKZGProof(commitment, inputPoint, claimedValue, proof) require.NoError(t, err) @@ -33,18 +33,18 @@ func TestBlobProveVerifySpecifiedPointIntegration(t *testing.T) { func TestBlobProveVerifyBatchIntegration(t *testing.T) { batchSize := 5 - blobs := make([]*gokzg4844.Blob, batchSize) + blobs := make([]gokzg4844.BlobRef, batchSize) commitments := make([]gokzg4844.KZGCommitment, batchSize) proofs := make([]gokzg4844.KZGProof, batchSize) for i := 0; i < batchSize; i++ { blob := GetRandBlob(int64(i)) - commitment, err := ctx.BlobToKZGCommitment(blob, NumGoRoutines) + commitment, err := ctx.BlobToKZGCommitment(blob[:], NumGoRoutines) require.NoError(t, err) - proof, err := ctx.ComputeBlobKZGProof(blob, commitment, NumGoRoutines) + proof, err := ctx.ComputeBlobKZGProof(blob[:], commitment, NumGoRoutines) require.NoError(t, err) - blobs[i] = blob + blobs[i] = blob[:] commitments[i] = commitment proofs[i] = proof } diff --git a/fiatshamir.go b/fiatshamir.go index 331a68c..7efdc5e 100644 --- a/fiatshamir.go +++ b/fiatshamir.go @@ -19,11 +19,11 @@ const DomSepProtocol = "FSBLOBVERIFY_V1_" // [compute_challenge]: https://github.com/ethereum/consensus-specs/blob/017a8495f7671f5fff2075a9bfc9238c1a0982f8/specs/deneb/polynomial-commitments.md#compute_challenge // // [hash_to_bls_field]: https://github.com/ethereum/consensus-specs/blob/017a8495f7671f5fff2075a9bfc9238c1a0982f8/specs/deneb/polynomial-commitments.md#hash_to_bls_field -func computeChallenge(blob *Blob, commitment KZGCommitment) fr.Element { +func computeChallenge(blob BlobRef, commitment KZGCommitment) fr.Element { h := sha256.New() h.Write([]byte(DomSepProtocol)) h.Write(u64ToByteArray16(ScalarsPerBlob)) - h.Write(blob[:]) + h.Write(blob) h.Write(commitment[:]) digest := h.Sum(nil) diff --git a/fiatshamir_test.go b/fiatshamir_test.go index 12acae9..82c7914 100644 --- a/fiatshamir_test.go +++ b/fiatshamir_test.go @@ -12,9 +12,9 @@ import ( // If the way computeChallenge is computed is updated // then this test will fail func TestComputeChallengeInterop(t *testing.T) { - blob := &Blob{} + blob := Blob{} commitment := SerializeG1Point(bls12381.G1Affine{}) - challenge := computeChallenge(blob, KZGCommitment(commitment)) + challenge := computeChallenge(blob[:], KZGCommitment(commitment)) expected := []byte{ 0x04, 0xb7, 0xb2, 0x2a, 0xf6, 0x3d, 0x2b, 0x2f, 0x1c, 0xed, 0x8d, 0x55, 0x05, 0x60, 0xe5, 0xd1, @@ -38,7 +38,7 @@ func TestTo16Bytes(t *testing.T) { func BenchmarkComputeChallenge(b *testing.B) { var ( - blob = &Blob{} + blob = Blob{} commitment = SerializeG1Point(bls12381.G1Affine{}) challenge fr.Element want = []byte{ @@ -51,7 +51,7 @@ func BenchmarkComputeChallenge(b *testing.B) { b.ResetTimer() b.ReportAllocs() for n := 0; n < b.N; n++ { - challenge = computeChallenge(blob, KZGCommitment(commitment)) + challenge = computeChallenge(blob[:], KZGCommitment(commitment)) } have := SerializeScalar(challenge) require.Equal(b, want, have[:]) diff --git a/prove.go b/prove.go index 73d8b7d..333a5cc 100644 --- a/prove.go +++ b/prove.go @@ -10,7 +10,7 @@ import ( // value to a negative number or 0 will make it default to the number of CPUs. // // [blob_to_kzg_commitment]: https://github.com/ethereum/consensus-specs/blob/017a8495f7671f5fff2075a9bfc9238c1a0982f8/specs/deneb/polynomial-commitments.md#blob_to_kzg_commitment -func (c *Context) BlobToKZGCommitment(blob *Blob, numGoRoutines int) (KZGCommitment, error) { +func (c *Context) BlobToKZGCommitment(blob BlobRef, numGoRoutines int) (KZGCommitment, error) { // 1. Deserialization // // Deserialize blob into polynomial @@ -43,7 +43,7 @@ func (c *Context) BlobToKZGCommitment(blob *Blob, numGoRoutines int) (KZGCommitm // value to a negative number or 0 will make it default to the number of CPUs. // // [compute_blob_kzg_proof]: https://github.com/ethereum/consensus-specs/blob/017a8495f7671f5fff2075a9bfc9238c1a0982f8/specs/deneb/polynomial-commitments.md#compute_blob_kzg_proof -func (c *Context) ComputeBlobKZGProof(blob *Blob, blobCommitment KZGCommitment, numGoRoutines int) (KZGProof, error) { +func (c *Context) ComputeBlobKZGProof(blob BlobRef, blobCommitment KZGCommitment, numGoRoutines int) (KZGProof, error) { // 1. Deserialization // polynomial, err := DeserializeBlob(blob) @@ -82,7 +82,7 @@ func (c *Context) ComputeBlobKZGProof(blob *Blob, blobCommitment KZGCommitment, // value to a negative number or 0 will make it default to the number of CPUs. // // [compute_kzg_proof]: https://github.com/ethereum/consensus-specs/blob/017a8495f7671f5fff2075a9bfc9238c1a0982f8/specs/deneb/polynomial-commitments.md#compute_kzg_proof -func (c *Context) ComputeKZGProof(blob *Blob, inputPointBytes Scalar, numGoRoutines int) (KZGProof, Scalar, error) { +func (c *Context) ComputeKZGProof(blob BlobRef, inputPointBytes Scalar, numGoRoutines int) (KZGProof, Scalar, error) { // 1. Deserialization // polynomial, err := DeserializeBlob(blob) diff --git a/serialization.go b/serialization.go index c5c551e..977b338 100644 --- a/serialization.go +++ b/serialization.go @@ -55,6 +55,10 @@ type ( // [Blob]: https://github.com/ethereum/consensus-specs/blob/017a8495f7671f5fff2075a9bfc9238c1a0982f8/specs/deneb/polynomial-commitments.md#custom-types Blob [ScalarsPerBlob * SerializedScalarSize]byte + // Auxiliary type to pass blobs by reference (fast) rather than value (slow). + // The slice MUST be of the same length as a Blob, i.e. ScalarsPerBlob * SerializedScalarSize + BlobRef []byte + // KZGProof is a serialized commitment to the quotient polynomial. // // It matches [KZGProof] in the spec. @@ -107,7 +111,7 @@ func DeserializeKZGProof(proof KZGProof) (bls12381.G1Affine, error) { // DeserializeBlob implements [blob_to_polynomial]. // // [blob_to_polynomial]: https://github.com/ethereum/consensus-specs/blob/017a8495f7671f5fff2075a9bfc9238c1a0982f8/specs/deneb/polynomial-commitments.md#blob_to_polynomial -func DeserializeBlob(blob *Blob) (kzg.Polynomial, error) { +func DeserializeBlob(blob BlobRef) (kzg.Polynomial, error) { poly := make(kzg.Polynomial, ScalarsPerBlob) for i := 0; i < ScalarsPerBlob; i++ { chunk := blob[i*SerializedScalarSize : (i+1)*SerializedScalarSize] @@ -140,12 +144,12 @@ func SerializeScalar(element fr.Element) Scalar { // // Note: This method is never used in the API because we always expect a byte array and will never receive deserialized // field elements. We include it so that upstream fuzzers do not need to reimplement it. -func SerializePoly(poly kzg.Polynomial) *Blob { +func SerializePoly(poly kzg.Polynomial) Blob { var blob Blob for i := 0; i < ScalarsPerBlob; i++ { chunk := blob[i*SerializedScalarSize : (i+1)*SerializedScalarSize] serScalar := SerializeScalar(poly[i]) copy(chunk, serScalar[:]) } - return &blob + return blob } diff --git a/serialization_test.go b/serialization_test.go index d61612e..8414e7d 100644 --- a/serialization_test.go +++ b/serialization_test.go @@ -44,11 +44,11 @@ func TestSerializePolyRoundTrip(t *testing.T) { blobA := gokzg4844.SerializePoly(expectedPolyA) blobB := gokzg4844.SerializePoly(expectedPolyB) - gotPolyA, err := gokzg4844.DeserializeBlob(blobA) + gotPolyA, err := gokzg4844.DeserializeBlob(blobA[:]) if err != nil { t.Error(err) } - gotPolyB, err := gokzg4844.DeserializeBlob(blobB) + gotPolyB, err := gokzg4844.DeserializeBlob(blobB[:]) if err != nil { t.Error(err) } diff --git a/verify.go b/verify.go index 9be66aa..472b7c3 100644 --- a/verify.go +++ b/verify.go @@ -45,7 +45,7 @@ func (c *Context) VerifyKZGProof(blobCommitment KZGCommitment, inputPointBytes, // VerifyBlobKZGProof implements [verify_blob_kzg_proof]. // // [verify_blob_kzg_proof]: https://github.com/ethereum/consensus-specs/blob/017a8495f7671f5fff2075a9bfc9238c1a0982f8/specs/deneb/polynomial-commitments.md#verify_blob_kzg_proof -func (c *Context) VerifyBlobKZGProof(blob *Blob, blobCommitment KZGCommitment, kzgProof KZGProof) error { +func (c *Context) VerifyBlobKZGProof(blob BlobRef, blobCommitment KZGCommitment, kzgProof KZGProof) error { // 1. Deserialize // polynomial, err := DeserializeBlob(blob) @@ -85,7 +85,7 @@ func (c *Context) VerifyBlobKZGProof(blob *Blob, blobCommitment KZGCommitment, k // VerifyBlobKZGProofBatch implements [verify_blob_kzg_proof_batch]. // // [verify_blob_kzg_proof_batch]: https://github.com/ethereum/consensus-specs/blob/017a8495f7671f5fff2075a9bfc9238c1a0982f8/specs/deneb/polynomial-commitments.md#verify_blob_kzg_proof_batch -func (c *Context) VerifyBlobKZGProofBatch(blobs []*Blob, polynomialCommitments []KZGCommitment, kzgProofs []KZGProof) error { +func (c *Context) VerifyBlobKZGProofBatch(blobs []BlobRef, polynomialCommitments []KZGCommitment, kzgProofs []KZGProof) error { // 1. Check that all components in the batch have the same size // blobsLen := len(blobs) @@ -149,7 +149,7 @@ func (c *Context) VerifyBlobKZGProofBatch(blobs []*Blob, polynomialCommitments [ // go-routines in a more intricate way than done below for large batches. // // [verify_blob_kzg_proof_batch]: https://github.com/ethereum/consensus-specs/blob/017a8495f7671f5fff2075a9bfc9238c1a0982f8/specs/deneb/polynomial-commitments.md#verify_blob_kzg_proof_batch -func (c *Context) VerifyBlobKZGProofBatchPar(blobs []*Blob, commitments []KZGCommitment, proofs []KZGProof) error { +func (c *Context) VerifyBlobKZGProofBatchPar(blobs []BlobRef, commitments []KZGCommitment, proofs []KZGProof) error { // 1. Check that all components in the batch have the same size if len(commitments) != len(blobs) || len(proofs) != len(blobs) { return ErrBatchLengthCheck