Skip to content

Commit

Permalink
crypto/kzg4844: add helpers for versioned blob hashes (ethereum#28827)
Browse files Browse the repository at this point in the history
The code to compute a versioned hash was duplicated a couple times, and also had a small
issue: if we ever change params.BlobTxHashVersion, it will most likely also cause changes
to the actual hash computation. So it's a bit useless to have this constant in params.
  • Loading branch information
fjl authored and Dergarcon committed Jan 31, 2024
1 parent 2776748 commit 763ddfb
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 39 deletions.
6 changes: 3 additions & 3 deletions core/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,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 @@ -324,9 +325,8 @@ func (st *StateTransition) preCheck() error {
return ErrMissingBlobHashes
}
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) {
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

0 comments on commit 763ddfb

Please sign in to comment.