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

crypto/kzg4844: add helpers for versioned blob hashes #28827

Merged
merged 2 commits into from
Jan 19, 2024
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions core/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
cmath "github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto/kzg4844"
"github.com/ethereum/go-ethereum/params"
)

Expand Down Expand Up @@ -319,9 +320,8 @@ func (st *StateTransition) preCheck() error {
return errors.New("blob transaction missing blob hashes")
}
for i, hash := range msg.BlobHashes {
if hash[0] != params.BlobTxHashVersion {
return fmt.Errorf("blob %d hash version mismatch (have %d, supported %d)",
i, hash[0], params.BlobTxHashVersion)
if !kzg4844.IsValidVersionedHash(hash[:]) {
return fmt.Errorf("blob %d has invalid hash version", i)
}
}
}
Expand Down
14 changes: 1 addition & 13 deletions core/txpool/blobpool/blobpool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,21 +51,9 @@ var (
emptyBlob = kzg4844.Blob{}
emptyBlobCommit, _ = kzg4844.BlobToCommitment(emptyBlob)
emptyBlobProof, _ = kzg4844.ComputeBlobProof(emptyBlob, emptyBlobCommit)
emptyBlobVHash = blobHash(emptyBlobCommit)
emptyBlobVHash = kzg4844.CalcBlobHashV1(sha256.New(), &emptyBlobCommit)
)

func blobHash(commit kzg4844.Commitment) common.Hash {
hasher := sha256.New()
hasher.Write(commit[:])
hash := hasher.Sum(nil)

var vhash common.Hash
vhash[0] = params.BlobTxHashVersion
copy(vhash[1:], hash[1:])

return vhash
}

// Chain configuration with Cancun enabled.
//
// TODO(karalabe): replace with params.MainnetChainConfig after Cancun.
Expand Down
15 changes: 4 additions & 11 deletions core/txpool/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,17 +143,10 @@ func validateBlobSidecar(hashes []common.Hash, sidecar *types.BlobTxSidecar) err
// Blob quantities match up, validate that the provers match with the
// transaction hash before getting to the cryptography
hasher := sha256.New()
for i, want := range hashes {
hasher.Write(sidecar.Commitments[i][:])
hash := hasher.Sum(nil)
hasher.Reset()

var vhash common.Hash
vhash[0] = params.BlobTxHashVersion
copy(vhash[1:], hash[1:])

if vhash != want {
return fmt.Errorf("blob %d: computed hash %#x mismatches transaction one %#x", i, vhash, want)
for i, vhash := range hashes {
computed := kzg4844.CalcBlobHashV1(hasher, &sidecar.Commitments[i])
if vhash != computed {
return fmt.Errorf("blob %d: computed hash %#x mismatches transaction one %#x", i, computed, vhash)
}
}
// Blob commitments match with the hashes in the transaction, verify the
Expand Down
12 changes: 2 additions & 10 deletions core/types/tx_blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,10 @@ type BlobTxSidecar struct {

// BlobHashes computes the blob hashes of the given blobs.
func (sc *BlobTxSidecar) BlobHashes() []common.Hash {
hasher := sha256.New()
h := make([]common.Hash, len(sc.Commitments))
for i := range sc.Blobs {
h[i] = blobHash(&sc.Commitments[i])
h[i] = kzg4844.CalcBlobHashV1(hasher, &sc.Commitments[i])
}
return h
}
Expand Down Expand Up @@ -235,12 +236,3 @@ func (tx *BlobTx) decode(input []byte) error {
}
return nil
}

func blobHash(commit *kzg4844.Commitment) common.Hash {
hasher := sha256.New()
hasher.Write(commit[:])
var vhash common.Hash
hasher.Sum(vhash[:0])
vhash[0] = params.BlobTxHashVersion
return vhash
}
19 changes: 19 additions & 0 deletions crypto/kzg4844/kzg4844.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package kzg4844
import (
"embed"
"errors"
"hash"
"sync/atomic"
)

Expand Down Expand Up @@ -108,3 +109,21 @@ func VerifyBlobProof(blob Blob, commitment Commitment, proof Proof) error {
}
return gokzgVerifyBlobProof(blob, commitment, proof)
}

// CalcBlobHashV1 calculates the 'versioned blob hash' of a commitment.
// The given hasher must be a sha256 hash instance, otherwise the result will be invalid!
func CalcBlobHashV1(hasher hash.Hash, commit *Commitment) (vh [32]byte) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Ahh why not return common.Hash here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I wanted to avoid importing common since it isn't otherwise imported in the package.

if hasher.Size() != 32 {
panic("wrong hash size")
}
hasher.Reset()
hasher.Write(commit[:])
hasher.Sum(vh[:0])
vh[0] = 0x01 // version
return vh
}

// IsValidVersionedHash checks that h is a structurally-valid versioned blob hash.
func IsValidVersionedHash(h []byte) bool {
return len(h) == 32 && h[0] == 0x01
}
3 changes: 2 additions & 1 deletion eth/downloader/queue.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/prque"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto/kzg4844"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/metrics"
"github.com/ethereum/go-ethereum/params"
Expand Down Expand Up @@ -810,7 +811,7 @@ func (q *queue) DeliverBodies(id string, txLists [][]*types.Transaction, txListH
return errInvalidBody
}
for _, hash := range tx.BlobHashes() {
if hash[0] != params.BlobTxHashVersion {
if !kzg4844.IsValidVersionedHash(hash[:]) {
return errInvalidBody
}
}
Expand Down
1 change: 0 additions & 1 deletion params/protocol_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,6 @@ const (

BlobTxBytesPerFieldElement = 32 // Size in bytes of a field element
BlobTxFieldElementsPerBlob = 4096 // Number of field elements stored in a single data blob
BlobTxHashVersion = 0x01 // Version byte of the commitment hash
BlobTxBlobGasPerBlob = 1 << 17 // Gas consumption of a single data blob (== blob byte size)
BlobTxMinBlobGasprice = 1 // Minimum gas price for data blobs
BlobTxBlobGaspriceUpdateFraction = 3338477 // Controls the maximum rate of change for blob gas price
Expand Down