diff --git a/core/txpool/validation.go b/core/txpool/validation.go index 59707c2bdc..ab6d93af8d 100644 --- a/core/txpool/validation.go +++ b/core/txpool/validation.go @@ -202,6 +202,9 @@ func validateBlobSidecarOsaka(hashes []common.Hash, sidecar *types.BlobTxSidecar if len(sidecar.Blobs) != len(hashes) { return fmt.Errorf("invalid number of %d blobs compared to %d blob hashes", len(sidecar.Blobs), len(hashes)) } + if len(sidecar.Commitments) != len(hashes) { + return fmt.Errorf("invalid number of %d commitments compared to %d blob hashes", len(sidecar.Commitments), len(hashes)) + } if len(sidecar.Proofs) != len(hashes)*kzg4844.CellProofsPerBlob { return fmt.Errorf("invalid number of %d blob proofs expected %d", len(sidecar.Proofs), len(hashes)*kzg4844.CellProofsPerBlob) } diff --git a/crypto/kzg4844/kzg4844.go b/crypto/kzg4844/kzg4844.go index 030eb56341..6637a589c6 100644 --- a/crypto/kzg4844/kzg4844.go +++ b/crypto/kzg4844/kzg4844.go @@ -155,6 +155,9 @@ func VerifyBlobProof(blob *Blob, commitment Commitment, proof Proof) error { return gokzgVerifyBlobProof(blob, commitment, proof) } +// VerifyCellProofs verifies a batch of proofs corresponding to the blobs and commitments. +// Expects length of blobs and commitments to be equal. +// Expects length of proofs be 128 * length of blobs. func VerifyCellProofs(blobs []*Blob, commitments []Commitment, proofs []Proof) error { if useCKZG.Load() { return ckzgVerifyCellProofBatch(blobs, commitments, proofs) diff --git a/crypto/kzg4844/kzg4844_ckzg_cgo.go b/crypto/kzg4844/kzg4844_ckzg_cgo.go index 621974d17f..2404a1a9a5 100644 --- a/crypto/kzg4844/kzg4844_ckzg_cgo.go +++ b/crypto/kzg4844/kzg4844_ckzg_cgo.go @@ -151,23 +151,37 @@ func ckzgComputeCellProofs(blob *Blob) ([]Proof, error) { } // ckzgVerifyCellProofs verifies that the blob data corresponds to the provided commitment. -func ckzgVerifyCellProofBatch(blobs []*Blob, commitments []Commitment, proofs []Proof) error { +func ckzgVerifyCellProofBatch(blobs []*Blob, commitments []Commitment, cellProofs []Proof) error { ckzgIniter.Do(ckzgInit) - - cells, err := ckzg.ComputeCells(blob) - if err != nil { - return err + var ( + proofs = make([]ckzg4844.Bytes48, len(cellProofs)) + commits = make([]ckzg4844.Bytes48, 0, len(cellProofs)) + cellIndices = make([]uint64, 0, len(cellProofs)) + cells = make([]ckzg4844.Cell, 0, len(cellProofs)) + ) + // Copy over the cell proofs + for i, proof := range cellProofs { + proofs[i] = (ckzg4844.Bytes48)(proof) } - cellIndices := make([]uint64, 0, len(cells)) - for range len(cells) { - cellIndices = append(cellIndices, 0) + // Blow up the commitments to be the same length as the proofs + for _, commitment := range commitments { + for range gokzg4844.CellsPerExtBlob { + commits = append(commits, (ckzg4844.Bytes48)(commitment)) + } } - kzgProofs := make([]ckzg4844.Bytes48, len(proofs)) - for _, proof := range proofs { - kzgProofs = append(kzgProofs, (ckzg4844.Bytes48)(proof)) + // Compute the cells and cell indices + for _, blob := range blobs { + cellsI, err := ckzg4844.ComputeCells((*ckzg4844.Blob)(blob)) + if err != nil { + return err + } + cells = append(cells, cellsI[:]...) + for idx := range len(cellsI) { + cellIndices = append(cellIndices, uint64(idx)) + } } - valid, err := ckzg4844.VerifyCellKZGProofBatch(([]ckzg4844.Bytes48)(commitment), cells, cellIndices, kzgProofs) + valid, err := ckzg4844.VerifyCellKZGProofBatch(commits, cellIndices, cells, proofs) if err != nil { return err } diff --git a/crypto/kzg4844/kzg4844_gokzg.go b/crypto/kzg4844/kzg4844_gokzg.go index 487d65da1d..9fbd6f654a 100644 --- a/crypto/kzg4844/kzg4844_gokzg.go +++ b/crypto/kzg4844/kzg4844_gokzg.go @@ -116,30 +116,35 @@ func gokzgComputeCellProofs(blob *Blob) ([]Proof, error) { } // gokzgVerifyCellProofs verifies that the blob data corresponds to the provided commitment. -func gokzgVerifyCellProofBatch(blobs []*Blob, commitments []Commitment, proofs []Proof) error { +func gokzgVerifyCellProofBatch(blobs []*Blob, commitments []Commitment, cellProofs []Proof) error { gokzgIniter.Do(gokzgInit) - var cellIndices []uint64 - var cells []*gokzg4844.Cell - for i, blob := range blobs { + var ( + proofs = make([]gokzg4844.KZGProof, len(cellProofs)) + commits = make([]gokzg4844.KZGCommitment, 0, len(cellProofs)) + cellIndices = make([]uint64, 0, len(cellProofs)) + cells = make([]*gokzg4844.Cell, 0, len(cellProofs)) + ) + // Copy over the cell proofs + for i, proof := range cellProofs { + proofs[i] = gokzg4844.KZGProof(proof) + } + // Blow up the commitments to be the same length as the proofs + for _, commitment := range commitments { + for range gokzg4844.CellsPerExtBlob { + commits = append(commits, gokzg4844.KZGCommitment(commitment)) + } + } + // Compute the cell and cell indices + for _, blob := range blobs { cellsI, err := context.ComputeCells((*gokzg4844.Blob)(blob), 2) if err != nil { return err } cells = append(cells, cellsI[:]...) - for range len(cellsI) { - cellIndices = append(cellIndices, uint64(i)) + for idx := range len(cellsI) { + cellIndices = append(cellIndices, uint64(idx)) } } - - comms := make([]gokzg4844.KZGCommitment, len(commitments)) - for i, commitment := range commitments { - comms[i] = gokzg4844.KZGCommitment(commitment) - } - pr := make([]gokzg4844.KZGProof, len(proofs)) - for i, proof := range proofs { - pr[i] = gokzg4844.KZGProof(proof) - } - - return context.VerifyCellKZGProofBatch(comms, cellIndices, cells[:], pr) + return context.VerifyCellKZGProofBatch(commits, cellIndices, cells[:], proofs) } diff --git a/crypto/kzg4844/kzg4844_test.go b/crypto/kzg4844/kzg4844_test.go index 96f56fdfd1..868d7fb868 100644 --- a/crypto/kzg4844/kzg4844_test.go +++ b/crypto/kzg4844/kzg4844_test.go @@ -203,22 +203,29 @@ func testKZGCells(t *testing.T, ckzg bool) { defer func(old bool) { useCKZG.Store(old) }(useCKZG.Load()) useCKZG.Store(ckzg) - blob := randBlob() + blob1 := randBlob() + blob2 := randBlob() - commitment, err := BlobToCommitment(blob) + commitment1, err := BlobToCommitment(blob1) if err != nil { t.Fatalf("failed to create KZG commitment from blob: %v", err) } - proof, err := ComputeCellProofs(blob) + commitment2, err := BlobToCommitment(blob2) + if err != nil { + t.Fatalf("failed to create KZG commitment from blob: %v", err) + } + + proofs1, err := ComputeCellProofs(blob1) if err != nil { t.Fatalf("failed to create KZG proof at point: %v", err) } - var commitments []Commitment - for range len(proof) { - commitments = append(commitments, commitment) + proofs2, err := ComputeCellProofs(blob2) + if err != nil { + t.Fatalf("failed to create KZG proof at point: %v", err) } - if err := VerifyCellProofs([]*Blob{blob}, commitments, proof); err != nil { + proofs := append(proofs1, proofs2...) + if err := VerifyCellProofs([]*Blob{blob1, blob2}, []Commitment{commitment1, commitment2}, proofs); err != nil { t.Fatalf("failed to verify KZG proof at point: %v", err) } }