Skip to content

Commit 6170bfe

Browse files
0xmountaintopfjl
andauthored
crypto/kzg4844: add helpers for versioned blob hashes (ethereum#28827) (#876)
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. Co-authored-by: Felix Lange <[email protected]>
1 parent 77ad2ef commit 6170bfe

File tree

7 files changed

+31
-39
lines changed

7 files changed

+31
-39
lines changed

core/state_transition.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
cmath "github.com/ethereum/go-ethereum/common/math"
2727
"github.com/ethereum/go-ethereum/core/types"
2828
"github.com/ethereum/go-ethereum/core/vm"
29+
"github.com/ethereum/go-ethereum/crypto/kzg4844"
2930
"github.com/ethereum/go-ethereum/log"
3031
"github.com/ethereum/go-ethereum/params"
3132
)
@@ -369,9 +370,8 @@ func (st *StateTransition) preCheck() error {
369370
return errors.New("blob transaction missing blob hashes")
370371
}
371372
for i, hash := range msg.BlobHashes {
372-
if hash[0] != params.BlobTxHashVersion {
373-
return fmt.Errorf("blob %d hash version mismatch (have %d, supported %d)",
374-
i, hash[0], params.BlobTxHashVersion)
373+
if !kzg4844.IsValidVersionedHash(hash[:]) {
374+
return fmt.Errorf("blob %d has invalid hash version", i)
375375
}
376376
}
377377
}

core/txpool/blobpool/blobpool_test.go

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -51,21 +51,9 @@ var (
5151
emptyBlob = kzg4844.Blob{}
5252
emptyBlobCommit, _ = kzg4844.BlobToCommitment(emptyBlob)
5353
emptyBlobProof, _ = kzg4844.ComputeBlobProof(emptyBlob, emptyBlobCommit)
54-
emptyBlobVHash = blobHash(emptyBlobCommit)
54+
emptyBlobVHash = kzg4844.CalcBlobHashV1(sha256.New(), &emptyBlobCommit)
5555
)
5656

57-
func blobHash(commit kzg4844.Commitment) common.Hash {
58-
hasher := sha256.New()
59-
hasher.Write(commit[:])
60-
hash := hasher.Sum(nil)
61-
62-
var vhash common.Hash
63-
vhash[0] = params.BlobTxHashVersion
64-
copy(vhash[1:], hash[1:])
65-
66-
return vhash
67-
}
68-
6957
// Chain configuration with Cancun enabled.
7058
//
7159
// TODO(karalabe): replace with params.MainnetChainConfig after Cancun.

core/txpool/validation.go

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -144,17 +144,10 @@ func validateBlobSidecar(hashes []common.Hash, sidecar *types.BlobTxSidecar) err
144144
// Blob quantities match up, validate that the provers match with the
145145
// transaction hash before getting to the cryptography
146146
hasher := sha256.New()
147-
for i, want := range hashes {
148-
hasher.Write(sidecar.Commitments[i][:])
149-
hash := hasher.Sum(nil)
150-
hasher.Reset()
151-
152-
var vhash common.Hash
153-
vhash[0] = params.BlobTxHashVersion
154-
copy(vhash[1:], hash[1:])
155-
156-
if vhash != want {
157-
return fmt.Errorf("blob %d: computed hash %#x mismatches transaction one %#x", i, vhash, want)
147+
for i, vhash := range hashes {
148+
computed := kzg4844.CalcBlobHashV1(hasher, &sidecar.Commitments[i])
149+
if vhash != computed {
150+
return fmt.Errorf("blob %d: computed hash %#x mismatches transaction one %#x", i, computed, vhash)
158151
}
159152
}
160153
// Blob commitments match with the hashes in the transaction, verify the

core/types/tx_blob.go

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,10 @@ type BlobTxSidecar struct {
6161

6262
// BlobHashes computes the blob hashes of the given blobs.
6363
func (sc *BlobTxSidecar) BlobHashes() []common.Hash {
64+
hasher := sha256.New()
6465
h := make([]common.Hash, len(sc.Commitments))
6566
for i := range sc.Blobs {
66-
h[i] = blobHash(&sc.Commitments[i])
67+
h[i] = kzg4844.CalcBlobHashV1(hasher, &sc.Commitments[i])
6768
}
6869
return h
6970
}
@@ -235,12 +236,3 @@ func (tx *BlobTx) decode(input []byte) error {
235236
}
236237
return nil
237238
}
238-
239-
func blobHash(commit *kzg4844.Commitment) common.Hash {
240-
hasher := sha256.New()
241-
hasher.Write(commit[:])
242-
var vhash common.Hash
243-
hasher.Sum(vhash[:0])
244-
vhash[0] = params.BlobTxHashVersion
245-
return vhash
246-
}

crypto/kzg4844/kzg4844.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ package kzg4844
2020
import (
2121
"embed"
2222
"errors"
23+
"hash"
2324
"sync/atomic"
2425
)
2526

@@ -108,3 +109,21 @@ func VerifyBlobProof(blob Blob, commitment Commitment, proof Proof) error {
108109
}
109110
return gokzgVerifyBlobProof(blob, commitment, proof)
110111
}
112+
113+
// CalcBlobHashV1 calculates the 'versioned blob hash' of a commitment.
114+
// The given hasher must be a sha256 hash instance, otherwise the result will be invalid!
115+
func CalcBlobHashV1(hasher hash.Hash, commit *Commitment) (vh [32]byte) {
116+
if hasher.Size() != 32 {
117+
panic("wrong hash size")
118+
}
119+
hasher.Reset()
120+
hasher.Write(commit[:])
121+
hasher.Sum(vh[:0])
122+
vh[0] = 0x01 // version
123+
return vh
124+
}
125+
126+
// IsValidVersionedHash checks that h is a structurally-valid versioned blob hash.
127+
func IsValidVersionedHash(h []byte) bool {
128+
return len(h) == 32 && h[0] == 0x01
129+
}

eth/downloader/queue.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"github.com/ethereum/go-ethereum/common"
3030
"github.com/ethereum/go-ethereum/common/prque"
3131
"github.com/ethereum/go-ethereum/core/types"
32+
"github.com/ethereum/go-ethereum/crypto/kzg4844"
3233
"github.com/ethereum/go-ethereum/log"
3334
"github.com/ethereum/go-ethereum/metrics"
3435
"github.com/ethereum/go-ethereum/params"
@@ -810,7 +811,7 @@ func (q *queue) DeliverBodies(id string, txLists [][]*types.Transaction, txListH
810811
return errInvalidBody
811812
}
812813
for _, hash := range tx.BlobHashes() {
813-
if hash[0] != params.BlobTxHashVersion {
814+
if !kzg4844.IsValidVersionedHash(hash[:]) {
814815
return errInvalidBody
815816
}
816817
}

params/protocol_params.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,6 @@ const (
166166

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

0 commit comments

Comments
 (0)