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

peerDAS: Replace cKZG by goKZG #14804

Draft
wants to merge 5 commits into
base: peerDAS
Choose a base branch
from
Draft
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
9 changes: 8 additions & 1 deletion WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,14 @@ load("@com_github_atlassian_bazel_tools//gometalinter:deps.bzl", "gometalinter_d

gometalinter_dependencies()

load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository")

go_repository(
name = "com_github_crate_crypto_go_eth_kzg",
importpath = "github.com/crate-crypto/go-eth-kzg",
sum = "h1:ywfe8ydSxtrPyJfQL+kdC0SxJX0C7C8eVdcLTrdkIiA=",
version = "v1.1.0",
)

gazelle_dependencies()

Expand Down
2 changes: 1 addition & 1 deletion beacon-chain/blockchain/kzg/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ go_library(
visibility = ["//visibility:public"],
deps = [
"//consensus-types/blocks:go_default_library",
"@com_github_crate_crypto_go_eth_kzg//:go_default_library",
"@com_github_crate_crypto_go_kzg_4844//:go_default_library",
"@com_github_ethereum_c_kzg_4844//bindings/go:go_default_library",
"@com_github_ethereum_go_ethereum//common/hexutil:go_default_library",
"@com_github_ethereum_go_ethereum//crypto/kzg4844:go_default_library",
"@com_github_pkg_errors//:go_default_library",
Expand Down
98 changes: 60 additions & 38 deletions beacon-chain/blockchain/kzg/kzg.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@ package kzg
import (
"errors"

ckzg4844 "github.com/ethereum/c-kzg-4844/v2/bindings/go"
goethkzg "github.com/crate-crypto/go-eth-kzg"
"github.com/ethereum/go-ethereum/crypto/kzg4844"
)

// BytesPerBlob is the number of bytes in a single blob.
const BytesPerBlob = ckzg4844.BytesPerBlob
// BytesPerBlob is the number of bytes in a single (non extended) blob.
const BytesPerBlob = goethkzg.BytesPerCell * goethkzg.CellsPerExtBlob / 2

// Blob represents a serialized chunk of data.
type Blob [BytesPerBlob]byte

// BytesPerCell is the number of bytes in a single cell.
const BytesPerCell = ckzg4844.BytesPerCell
const BytesPerCell = goethkzg.BytesPerCell

// Cell represents a chunk of an encoded Blob.
type Cell [BytesPerCell]byte
Expand All @@ -26,10 +26,10 @@ type Commitment [48]byte
type Proof [48]byte

// Bytes48 is a 48-byte array.
type Bytes48 = ckzg4844.Bytes48
type Bytes48 = [48]byte

// Bytes32 is a 32-byte array.
type Bytes32 = ckzg4844.Bytes32
type Bytes32 = [32]byte

// CellsAndProofs represents the Cells and Proofs corresponding to
// a single blob.
Expand Down Expand Up @@ -57,55 +57,77 @@ func ComputeBlobKZGProof(blob *Blob, commitment Commitment) (Proof, error) {
}

func ComputeCellsAndKZGProofs(blob *Blob) (CellsAndProofs, error) {
ckzgBlob := (*ckzg4844.Blob)(blob)
ckzgCells, ckzgProofs, err := ckzg4844.ComputeCellsAndKZGProofs(ckzgBlob)
goEthKZGBlob := (*goethkzg.Blob)(blob)
cells, proofs, err := goEthKZGContext.ComputeCellsAndKZGProofs(goEthKZGBlob, 0)
if err != nil {
return CellsAndProofs{}, err
}

return makeCellsAndProofs(ckzgCells[:], ckzgProofs[:])
return makeCellsAndProofsGoEthKZG(cells[:], proofs[:])
}

func VerifyCellKZGProofBatch(commitmentsBytes []Bytes48, cellIndices []uint64, cells []Cell, proofsBytes []Bytes48) (bool, error) {
// Convert `Cell` type to `ckzg4844.Cell`
ckzgCells := make([]ckzg4844.Cell, len(cells))
for i := range cells {
ckzgCells[i] = ckzg4844.Cell(cells[i])
// Convert c-kzg cells/proofs to the CellsAndProofs type defined in this package.
func makeCellsAndProofsGoEthKZG(goethkzgCells []*goethkzg.Cell, goethkzgProofs []goethkzg.KZGProof) (CellsAndProofs, error) {
if len(goethkzgCells) != len(goethkzgProofs) {
return CellsAndProofs{}, errors.New("different number of cells/proofs")
}

return ckzg4844.VerifyCellKZGProofBatch(commitmentsBytes, cellIndices, ckzgCells, proofsBytes)
var cells []Cell
var proofs []Proof
for i := range goethkzgCells {
cells = append(cells, Cell(*goethkzgCells[i]))
proofs = append(proofs, Proof(goethkzgProofs[i]))
}

return CellsAndProofs{
Cells: cells,
Proofs: proofs,
}, nil
}

func RecoverCellsAndKZGProofs(cellIndices []uint64, partialCells []Cell) (CellsAndProofs, error) {
// Convert `Cell` type to `ckzg4844.Cell`
ckzgPartialCells := make([]ckzg4844.Cell, len(partialCells))
for i := range partialCells {
ckzgPartialCells[i] = ckzg4844.Cell(partialCells[i])
func convertBytes48SliceToKZGCommitmentSlice(bytes48Slice []Bytes48) []goethkzg.KZGCommitment {
commitments := make([]goethkzg.KZGCommitment, len(bytes48Slice))
for i, b48 := range bytes48Slice {
copy(commitments[i][:], b48[:])
}
return commitments
}

ckzgCells, ckzgProofs, err := ckzg4844.RecoverCellsAndKZGProofs(cellIndices, ckzgPartialCells)
if err != nil {
return CellsAndProofs{}, err
func convertCellSliceToPointers(cells []Cell) []*goethkzg.Cell {
cellPointers := make([]*goethkzg.Cell, len(cells))
for i := range cells {
kzgCell := goethkzg.Cell(cells[i])
cellPointers[i] = &kzgCell
}
return cellPointers
}

return makeCellsAndProofs(ckzgCells[:], ckzgProofs[:])
func convertBytes48SliceToKZGProofSlice(bytes48Slice []Bytes48) []goethkzg.KZGProof {
commitments := make([]goethkzg.KZGProof, len(bytes48Slice))
for i, b48 := range bytes48Slice {
copy(commitments[i][:], b48[:])
}
return commitments
}

// Convert cells/proofs to the CellsAndProofs type defined in this package.
func makeCellsAndProofs(ckzgCells []ckzg4844.Cell, ckzgProofs []ckzg4844.KZGProof) (CellsAndProofs, error) {
if len(ckzgCells) != len(ckzgProofs) {
return CellsAndProofs{}, errors.New("different number of cells/proofs")
func VerifyCellKZGProofBatch(commitmentsBytes []Bytes48, cellIndices []uint64, cells []Cell, proofsBytes []Bytes48) (bool, error) {
kzgCommitments := convertBytes48SliceToKZGCommitmentSlice(commitmentsBytes)
kzgCells := convertCellSliceToPointers(cells)
kzgProofs := convertBytes48SliceToKZGProofSlice(proofsBytes)

err := goEthKZGContext.VerifyCellKZGProofBatch(kzgCommitments, cellIndices, kzgCells, kzgProofs)
if err != nil {
return false, err
}
// TODO: This conforms to the c-kzg API, I think we should change this to only return an error
return true, nil
}

var cells []Cell
var proofs []Proof
for i := range ckzgCells {
cells = append(cells, Cell(ckzgCells[i]))
proofs = append(proofs, Proof(ckzgProofs[i]))
func RecoverCellsAndKZGProofs(cellIndices []uint64, partialCells []Cell) (CellsAndProofs, error) {
kzgCells := convertCellSliceToPointers(partialCells)
cells, proofs, err := goEthKZGContext.RecoverCellsAndComputeKZGProofs(cellIndices, kzgCells, 0)
if err != nil {
return CellsAndProofs{}, err
}

return CellsAndProofs{
Cells: cells,
Proofs: proofs,
}, nil
return makeCellsAndProofsGoEthKZG(cells[:], proofs[:])
}
13 changes: 5 additions & 8 deletions beacon-chain/blockchain/kzg/trusted_setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import (
_ "embed"
"encoding/json"

goethkzg "github.com/crate-crypto/go-eth-kzg"
GoKZG "github.com/crate-crypto/go-kzg-4844"
CKZG "github.com/ethereum/c-kzg-4844/v2/bindings/go"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/pkg/errors"
)
Expand All @@ -14,6 +14,7 @@ var (
//go:embed trusted_setup.json
embeddedTrustedSetup []byte // 1.2Mb
kzgContext *GoKZG.Context
goEthKZGContext *goethkzg.Context
kzgLoaded bool
)

Expand Down Expand Up @@ -52,13 +53,9 @@ func Start() error {
copy(g2MonomialBytes[i*(len(g2)-2)/2:], hexutil.MustDecode(g2))
}
if !kzgLoaded {
// TODO: Provide a configuration option for this.
var precompute uint = 8

// Free the current trusted setup before running this method. CKZG
// panics if the same setup is run multiple times.
if err = CKZG.LoadTrustedSetup(g1MonomialBytes, g1LagrangeBytes, g2MonomialBytes, precompute); err != nil {
panic(err)
goEthKZGContext, err = goethkzg.NewContext4096Secure()
if err != nil {
return errors.Wrap(err, "could not initialize go-eth-kzg context")
}
}
kzgLoaded = true
Expand Down
1 change: 0 additions & 1 deletion beacon-chain/core/peerdas/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ go_library(
"@com_github_prometheus_client_golang//prometheus:go_default_library",
"@com_github_prometheus_client_golang//prometheus/promauto:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@org_golang_x_sync//errgroup:go_default_library",
],
)

Expand Down
76 changes: 29 additions & 47 deletions beacon-chain/core/peerdas/helpers.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package peerdas

import (
"context"
"encoding/binary"
"fmt"
"math"
Expand All @@ -11,7 +10,6 @@ import (

fieldparams "github.com/prysmaticlabs/prysm/v5/config/fieldparams"
"github.com/sirupsen/logrus"
"golang.org/x/sync/errgroup"

"github.com/ethereum/go-ethereum/p2p/enode"
"github.com/ethereum/go-ethereum/p2p/enr"
Expand Down Expand Up @@ -212,22 +210,15 @@ func DataColumnSidecars(signedBlock interfaces.ReadOnlySignedBeaconBlock, blobs
// Compute cells and proofs.
cellsAndProofs := make([]kzg.CellsAndProofs, blobsCount)

eg, _ := errgroup.WithContext(context.Background())
for i := range blobs {
blobIndex := i
eg.Go(func() error {
blob := &blobs[blobIndex]
blobCellsAndProofs, err := kzg.ComputeCellsAndKZGProofs(blob)
if err != nil {
return errors.Wrap(err, "compute cells and KZG proofs")
}
blob := &blobs[blobIndex]
blobCellsAndProofs, err := kzg.ComputeCellsAndKZGProofs(blob)
if err != nil {
return nil, errors.Wrap(err, "compute cells and KZG proofs")
}

cellsAndProofs[blobIndex] = blobCellsAndProofs
return nil
})
}
if err := eg.Wait(); err != nil {
return nil, err
cellsAndProofs[blobIndex] = blobCellsAndProofs
}

// Get the column sidecars.
Expand Down Expand Up @@ -612,8 +603,6 @@ func RecoverCellsAndProofs(
dataColumnSideCars []*ethpb.DataColumnSidecar,
blockRoot [fieldparams.RootLength]byte,
) ([]kzg.CellsAndProofs, error) {
var wg errgroup.Group

dataColumnSideCarsCount := len(dataColumnSideCars)

if dataColumnSideCarsCount == 0 {
Expand All @@ -633,44 +622,37 @@ func RecoverCellsAndProofs(
// Recover cells and compute proofs in parallel.
recoveredCellsAndProofs := make([]kzg.CellsAndProofs, blobCount)

for blobIndex := 0; blobIndex < blobCount; blobIndex++ {
for blobIndex := range blobCount {
bIndex := blobIndex
wg.Go(func() error {
start := time.Now()

cellsIndices := make([]uint64, 0, dataColumnSideCarsCount)
cells := make([]kzg.Cell, 0, dataColumnSideCarsCount)
start := time.Now()

for _, sidecar := range dataColumnSideCars {
// Build the cell indices.
cellsIndices = append(cellsIndices, sidecar.ColumnIndex)
cellsIndices := make([]uint64, 0, dataColumnSideCarsCount)
cells := make([]kzg.Cell, 0, dataColumnSideCarsCount)

// Get the cell.
column := sidecar.DataColumn
cell := column[bIndex]
for _, sidecar := range dataColumnSideCars {
// Build the cell indices.
cellsIndices = append(cellsIndices, sidecar.ColumnIndex)

cells = append(cells, kzg.Cell(cell))
}
// Get the cell.
column := sidecar.DataColumn
cell := column[bIndex]

// Recover the cells and proofs for the corresponding blob
cellsAndProofs, err := kzg.RecoverCellsAndKZGProofs(cellsIndices, cells)
cells = append(cells, kzg.Cell(cell))
}

if err != nil {
return errors.Wrapf(err, "recover cells and KZG proofs for blob %d", bIndex)
}
// Recover the cells and proofs for the corresponding blob
cellsAndProofs, err := kzg.RecoverCellsAndKZGProofs(cellsIndices, cells)

recoveredCellsAndProofs[bIndex] = cellsAndProofs
log.WithFields(logrus.Fields{
"elapsed": time.Since(start),
"index": bIndex,
"root": fmt.Sprintf("%x", blockRoot),
}).Debug("Recovered cells and proofs")
return nil
})
}
if err != nil {
return nil, errors.Wrapf(err, "recover cells and KZG proofs for blob %d", bIndex)
}

if err := wg.Wait(); err != nil {
return nil, err
recoveredCellsAndProofs[bIndex] = cellsAndProofs
log.WithFields(logrus.Fields{
"elapsed": time.Since(start),
"index": bIndex,
"root": fmt.Sprintf("%x", blockRoot),
}).Debug("Recovered cells and proofs")
}

return recoveredCellsAndProofs, nil
Expand Down
Loading
Loading