Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use slices instead of pointers to arrays to pass blobs by reference #6

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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[:])
}

Expand Down
24 changes: 12 additions & 12 deletions bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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)
}
})

Expand All @@ -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])
}
})

Expand All @@ -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 {
Expand All @@ -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)
}
Expand Down
20 changes: 10 additions & 10 deletions consensus_specs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand Down
18 changes: 9 additions & 9 deletions examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,39 +12,39 @@ 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)
}

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
}
Expand Down
4 changes: 2 additions & 2 deletions fiatshamir.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
8 changes: 4 additions & 4 deletions fiatshamir_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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{
Expand All @@ -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[:])
Expand Down
6 changes: 3 additions & 3 deletions prove.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
10 changes: 7 additions & 3 deletions serialization.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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]
Expand Down Expand Up @@ -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
}
4 changes: 2 additions & 2 deletions serialization_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
Loading