From a67f95dca069fcc32014e1e9cf2c7d6200f4cec8 Mon Sep 17 00:00:00 2001 From: MariusVanDerWijden Date: Mon, 12 May 2025 19:45:30 +0200 Subject: [PATCH] crypto/kzg4844: verify cell proofs --- core/txpool/validation.go | 15 +++++++------- crypto/kzg4844/kzg4844.go | 7 +++++++ crypto/kzg4844/kzg4844_ckzg_cgo.go | 27 ++++++++++++++++++++++++++ crypto/kzg4844/kzg4844_ckzg_nocgo.go | 5 +++++ crypto/kzg4844/kzg4844_gokzg.go | 29 ++++++++++++++++++++++++++++ crypto/kzg4844/kzg4844_test.go | 29 ++++++++++++++++++++++++++++ 6 files changed, 104 insertions(+), 8 deletions(-) diff --git a/core/txpool/validation.go b/core/txpool/validation.go index 64e85a0e6e..59707c2bdc 100644 --- a/core/txpool/validation.go +++ b/core/txpool/validation.go @@ -210,14 +210,13 @@ func validateBlobSidecarOsaka(hashes []common.Hash, sidecar *types.BlobTxSidecar } // Blob commitments match with the hashes in the transaction, verify the // blobs themselves via KZG - for i := range sidecar.Blobs { - // TODO verify the cell proof here - _ = i - /* - if err := kzg4844.VerifyBlobProof(&sidecar.Blobs[i], sidecar.Commitments[i], sidecar.Proofs[i]); err != nil { - return fmt.Errorf("invalid blob %d: %v", i, err) - } - */ + var blobs []*kzg4844.Blob + for _, blob := range sidecar.Blobs { + blobs = append(blobs, &blob) + } + + if err := kzg4844.VerifyCellProofs(blobs, sidecar.Commitments, sidecar.Proofs); err != nil { + return err } return nil } diff --git a/crypto/kzg4844/kzg4844.go b/crypto/kzg4844/kzg4844.go index 5e14fbbd5e..030eb56341 100644 --- a/crypto/kzg4844/kzg4844.go +++ b/crypto/kzg4844/kzg4844.go @@ -155,6 +155,13 @@ func VerifyBlobProof(blob *Blob, commitment Commitment, proof Proof) error { return gokzgVerifyBlobProof(blob, commitment, proof) } +func VerifyCellProofs(blobs []*Blob, commitments []Commitment, proofs []Proof) error { + if useCKZG.Load() { + return ckzgVerifyCellProofBatch(blobs, commitments, proofs) + } + return gokzgVerifyCellProofBatch(blobs, commitments, proofs) +} + // ComputeCellProofs returns the KZG cell proofs that are used to verify the blob against // the commitment. // diff --git a/crypto/kzg4844/kzg4844_ckzg_cgo.go b/crypto/kzg4844/kzg4844_ckzg_cgo.go index 49a7046fe0..621974d17f 100644 --- a/crypto/kzg4844/kzg4844_ckzg_cgo.go +++ b/crypto/kzg4844/kzg4844_ckzg_cgo.go @@ -149,3 +149,30 @@ func ckzgComputeCellProofs(blob *Blob) ([]Proof, error) { } return p, nil } + +// ckzgVerifyCellProofs verifies that the blob data corresponds to the provided commitment. +func ckzgVerifyCellProofBatch(blobs []*Blob, commitments []Commitment, proofs []Proof) error { + ckzgIniter.Do(ckzgInit) + + cells, err := ckzg.ComputeCells(blob) + if err != nil { + return err + } + cellIndices := make([]uint64, 0, len(cells)) + for range len(cells) { + cellIndices = append(cellIndices, 0) + } + kzgProofs := make([]ckzg4844.Bytes48, len(proofs)) + for _, proof := range proofs { + kzgProofs = append(kzgProofs, (ckzg4844.Bytes48)(proof)) + } + + valid, err := ckzg4844.VerifyCellKZGProofBatch(([]ckzg4844.Bytes48)(commitment), cells, cellIndices, kzgProofs) + if err != nil { + return err + } + if !valid { + return errors.New("invalid proof") + } + return nil +} diff --git a/crypto/kzg4844/kzg4844_ckzg_nocgo.go b/crypto/kzg4844/kzg4844_ckzg_nocgo.go index 6f4bd3b823..3b12e1c2ad 100644 --- a/crypto/kzg4844/kzg4844_ckzg_nocgo.go +++ b/crypto/kzg4844/kzg4844_ckzg_nocgo.go @@ -61,6 +61,11 @@ func ckzgVerifyBlobProof(blob *Blob, commitment Commitment, proof Proof) error { panic("unsupported platform") } +// ckzgVerifyCellProofBatch verifies that the blob data corresponds to the provided commitment. +func ckzgVerifyCellProofBatch(blobs []*Blob, commitments []Commitment, proof []Proof) error { + panic("unsupported platform") +} + // ckzgComputeCellProofs returns the KZG cell proofs that are used to verify the blob against // the commitment. // diff --git a/crypto/kzg4844/kzg4844_gokzg.go b/crypto/kzg4844/kzg4844_gokzg.go index 46a38a8913..487d65da1d 100644 --- a/crypto/kzg4844/kzg4844_gokzg.go +++ b/crypto/kzg4844/kzg4844_gokzg.go @@ -114,3 +114,32 @@ func gokzgComputeCellProofs(blob *Blob) ([]Proof, error) { } return p, nil } + +// gokzgVerifyCellProofs verifies that the blob data corresponds to the provided commitment. +func gokzgVerifyCellProofBatch(blobs []*Blob, commitments []Commitment, proofs []Proof) error { + gokzgIniter.Do(gokzgInit) + + var cellIndices []uint64 + var cells []*gokzg4844.Cell + for i, 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)) + } + } + + 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) +} diff --git a/crypto/kzg4844/kzg4844_test.go b/crypto/kzg4844/kzg4844_test.go index a6782d4768..96f56fdfd1 100644 --- a/crypto/kzg4844/kzg4844_test.go +++ b/crypto/kzg4844/kzg4844_test.go @@ -193,3 +193,32 @@ func benchmarkVerifyBlobProof(b *testing.B, ckzg bool) { VerifyBlobProof(blob, commitment, proof) } } + +func TestCKZGCells(t *testing.T) { testKZGCells(t, true) } +func TestGoKZGCells(t *testing.T) { testKZGCells(t, false) } +func testKZGCells(t *testing.T, ckzg bool) { + if ckzg && !ckzgAvailable { + t.Skip("CKZG unavailable in this test build") + } + defer func(old bool) { useCKZG.Store(old) }(useCKZG.Load()) + useCKZG.Store(ckzg) + + blob := randBlob() + + commitment, err := BlobToCommitment(blob) + if err != nil { + t.Fatalf("failed to create KZG commitment from blob: %v", err) + } + proof, err := ComputeCellProofs(blob) + 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) + } + if err := VerifyCellProofs([]*Blob{blob}, commitments, proof); err != nil { + t.Fatalf("failed to verify KZG proof at point: %v", err) + } +}