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

move more CL eip-4844 methods from prysm to shared lib #50

Merged
merged 1 commit into from
Nov 16, 2022
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
12 changes: 1 addition & 11 deletions crypto/kzg/kzg.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,20 +185,10 @@ func ComputeAggregatedPolyAndCommitment(blobs Polynomials, commitments KZGCommit
return aggregatedPoly, aggregatedCommitmentG1, &evaluationChallenge, nil
}

type commitmentSequenceImpl []KZGCommitment

func (s commitmentSequenceImpl) At(i int) KZGCommitment {
return s[i]
}

func (s commitmentSequenceImpl) Len() int {
return len(s)
}

// ComputeAggregateKZGProofFromPolynomials implements compute_aggregate_kzg_proof from the EIP-4844
// consensus spec, only operating over blobs that are already parsed into a polynomial.
func ComputeAggregateKZGProofFromPolynomials(blobs Polynomials) (KZGProof, error) {
commitments := make(commitmentSequenceImpl, len(blobs))
commitments := make(KZGCommitmentSequenceImpl, len(blobs))
for i, b := range blobs {
commitments[i] = PolynomialToKZGCommitment(Polynomial(b))
}
Expand Down
98 changes: 97 additions & 1 deletion crypto/kzg/kzg_bytes.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package kzg

import (
"bytes"
"crypto/sha256"
"errors"
"fmt"

"github.com/ethereum/go-ethereum/params"
"github.com/protolambda/go-kzg/bls"
"github.com/protolambda/ztyp/codec"
)

// The custom types from EIP-4844 consensus spec:
Expand Down Expand Up @@ -39,8 +41,22 @@ type KZGCommitmentSequence interface {
At(int) KZGCommitment
}

type KZGCommitmentSequenceImpl []KZGCommitment

func (s KZGCommitmentSequenceImpl) At(i int) KZGCommitment {
return s[i]
}

func (s KZGCommitmentSequenceImpl) Len() int {
return len(s)
}

const (
PrecompileInputLength = 192
BlobTxType = 5
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have this defined in core/types/transaction.go. Is the redefine here so once we move this to go-kzg we don't have to depend on geth?

Copy link
Collaborator Author

@roberto-bayardo roberto-bayardo Nov 16, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that and it would introduce a circular dependency. Probably the one in core/types should be using this one? [edit] no looks like core/types wants to define all different tx types itself. I think it's ok to have in both places for now.

PrecompileInputLength = 192
BlobVersionedHashesOffset = 258 // offset the versioned_hash_offset in a serialized blob tx

blobMessageLen = 192 // size in bytes of "message" within the serialized blob tx
)

var (
Expand Down Expand Up @@ -180,3 +196,83 @@ func ValidateBlobsSidecar(slot Slot, beaconBlockRoot Root, expectedKZGCommitment
}
return nil
}

// TxPeekBlobVersionedHashes implements tx_peek_blob_versioned_hashes from EIP-4844 consensus spec:
// https://github.com/ethereum/consensus-specs/blob/dev/specs/eip4844/beacon-chain.md#tx_peek_blob_versioned_hashes
//
// Format of the blob tx relevant to this function is as follows:
// 0: type (value should always be BlobTxType, 1 byte)
// 1: message offset (value should always be 69, 4 bytes)
// 5: ECDSA signature (65 bytes)
// 70: start of "message" (192 bytes)
// 258: start of the versioned hash offset within "message" (4 bytes)
// 262-: rest of the tx following message
func TxPeekBlobVersionedHashes(tx []byte) ([]VersionedHash, error) {
// we start our reader at the versioned hash offset within the serialized tx
if len(tx) < BlobVersionedHashesOffset {
return nil, errors.New("blob tx invalid: too short")
}
if tx[0] != BlobTxType {
return nil, errors.New("invalid blob tx type")
}
dr := codec.NewDecodingReader(bytes.NewReader(tx[BlobVersionedHashesOffset:]), uint64(len(tx)-BlobVersionedHashesOffset))

// read the offset to the versioned hashes
var offset uint32
offset, err := dr.ReadOffset()
if err != nil {
return nil, fmt.Errorf("could not read versioned hashes offset: %v", err)
}

// Advance dr to the versioned hash list. We subtract blobMessageLen from the offset here to
// account for the fact that the offset is relative to the position of "message" (70) and we
// are currently positioned at the end of it (262).
skip := uint64(offset) - blobMessageLen
skipped, err := dr.Skip(skip)
if err != nil {
return nil, fmt.Errorf("could not skip to versioned hashes: %v", err)
}
if skip != uint64(skipped) {
return nil, fmt.Errorf("did not skip to versioned hashes. want %v got %v", skip, skipped)
}

// read the list of hashes one by one until we hit the end of the data
hashes := []VersionedHash{}
tmp := make([]byte, 32)
for dr.Scope() > 0 {
if _, err = dr.Read(tmp); err != nil {
return nil, fmt.Errorf("could not read versioned hashes: %v", err)
}
var h VersionedHash
copy(h[:], tmp)
hashes = append(hashes, h)
}

return hashes, nil
}

// VerifyKZGCommitmentsAgainstTransactions implements verify_kzg_commitments_against_transactions
// from the EIP-4844 consensus spec:
// https://github.com/ethereum/consensus-specs/blob/dev/specs/eip4844/beacon-chain.md#verify_kzg_commitments_against_transactions
func VerifyKZGCommitmentsAgainstTransactions(transactions [][]byte, kzgCommitments KZGCommitmentSequence) error {
var versionedHashes []VersionedHash
var err error
for _, tx := range transactions {
if tx[0] == BlobTxType {
versionedHashes, err = TxPeekBlobVersionedHashes(tx)
if err != nil {
return err
}
}
}
if kzgCommitments.Len() != len(versionedHashes) {
return errors.New("invalid number of blob versioned hashes")
}
for i := 0; i < kzgCommitments.Len(); i++ {
h := KZGToVersionedHash(kzgCommitments.At(i))
if h != versionedHashes[i] {
return errors.New("invalid version hashes vs kzg")
}
}
return nil
}