Skip to content
Merged
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
18 changes: 10 additions & 8 deletions core/txpool/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand All @@ -210,14 +213,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
}
Expand Down
10 changes: 10 additions & 0 deletions crypto/kzg4844/kzg4844.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,16 @@ 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)
}
return gokzgVerifyCellProofBatch(blobs, commitments, proofs)
}

// ComputeCellProofs returns the KZG cell proofs that are used to verify the blob against
// the commitment.
//
Expand Down
41 changes: 41 additions & 0 deletions crypto/kzg4844/kzg4844_ckzg_cgo.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,44 @@ 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, cellProofs []Proof) error {
ckzgIniter.Do(ckzgInit)
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)
}
// 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))
}
}
// 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(commits, cellIndices, cells, proofs)
if err != nil {
return err
}
if !valid {
return errors.New("invalid proof")
}
return nil
}
5 changes: 5 additions & 0 deletions crypto/kzg4844/kzg4844_ckzg_nocgo.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
//
Expand Down
34 changes: 34 additions & 0 deletions crypto/kzg4844/kzg4844_gokzg.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,3 +114,37 @@ 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, cellProofs []Proof) error {
gokzgIniter.Do(gokzgInit)

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 idx := range len(cellsI) {
cellIndices = append(cellIndices, uint64(idx))
}
}
return context.VerifyCellKZGProofBatch(commits, cellIndices, cells[:], proofs)
}
36 changes: 36 additions & 0 deletions crypto/kzg4844/kzg4844_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,3 +193,39 @@ 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)

blob1 := randBlob()
blob2 := randBlob()

commitment1, err := BlobToCommitment(blob1)
if err != nil {
t.Fatalf("failed to create KZG commitment from blob: %v", err)
}
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)
}

proofs2, err := ComputeCellProofs(blob2)
if err != nil {
t.Fatalf("failed to create KZG proof at point: %v", err)
}
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)
}
}