diff --git a/core/types/data_blob.go b/core/types/data_blob.go index e53e40bf5ad1..5892f5287304 100644 --- a/core/types/data_blob.go +++ b/core/types/data_blob.go @@ -377,9 +377,12 @@ func (blobs Blobs) ComputeCommitmentsAndAggregatedProof() (commitments []KZGComm for i := range aggregatePoly { aggregateBlob[i] = bls.FrTo32(&aggregatePoly[i]) } - root := tree.GetHashFn().HashTreeRoot(&aggregateBlob, &aggregateCommitment) + sum, err := sszHash(&PolynomialAndCommitment{aggregateBlob, aggregateCommitment}) + if err != nil { + return nil, nil, KZGProof{}, err + } var z bls.Fr - hashToFr(&z, root) + hashToFr(&z, sum) var y bls.Fr kzg.EvaluatePolyInEvaluationForm(&y, aggregatePoly[:], &z) @@ -399,8 +402,20 @@ type BlobsAndCommitments struct { BlobKzgs BlobKzgs } -func (h *BlobsAndCommitments) HashTreeRoot(hFn tree.HashFn) tree.Root { - return hFn.HashTreeRoot(&h.Blobs, &h.BlobKzgs) +func (b *BlobsAndCommitments) HashTreeRoot(hFn tree.HashFn) tree.Root { + return hFn.HashTreeRoot(&b.Blobs, &b.BlobKzgs) +} + +func (b *BlobsAndCommitments) Serialize(w *codec.EncodingWriter) error { + return w.Container(&b.Blobs, &b.BlobKzgs) +} + +func (b *BlobsAndCommitments) ByteLength() uint64 { + return codec.ContainerLength(&b.Blobs, &b.BlobKzgs) +} + +func (b *BlobsAndCommitments) FixedLength() uint64 { + return 0 } type PolynomialAndCommitment struct { @@ -412,6 +427,18 @@ func (p *PolynomialAndCommitment) HashTreeRoot(hFn tree.HashFn) tree.Root { return hFn.HashTreeRoot(&p.b, &p.c) } +func (p *PolynomialAndCommitment) Serialize(w *codec.EncodingWriter) error { + return w.Container(&p.b, &p.c) +} + +func (p *PolynomialAndCommitment) ByteLength() uint64 { + return codec.ContainerLength(&p.b, &p.c) +} + +func (p *PolynomialAndCommitment) FixedLength() uint64 { + return 0 +} + type BlobTxWrapper struct { Tx SignedBlobTx BlobKzgs BlobKzgs @@ -487,10 +514,12 @@ func (b *BlobTxWrapData) verifyBlobs(inner TxData) error { } var aggregateCommitment KZGCommitment copy(aggregateCommitment[:], bls.ToCompressedG1(aggregateCommitmentG1)) - hasher := PolynomialAndCommitment{aggregateBlob, aggregateCommitment} - root := hasher.HashTreeRoot(tree.GetHashFn()) + sum, err := sszHash(&PolynomialAndCommitment{aggregateBlob, aggregateCommitment}) + if err != nil { + return err + } var z bls.Fr - hashToFr(&z, root) + hashToFr(&z, sum) var y bls.Fr kzg.EvaluatePolyInEvaluationForm(&y, aggregatePoly[:], &z) @@ -555,10 +584,12 @@ func computePowers(r *bls.Fr, n int) []bls.Fr { func computeAggregateKzgCommitment(blobs Blobs, commitments []KZGCommitment) ([]bls.Fr, *bls.G1Point, error) { // create challenges - hasher := BlobsAndCommitments{blobs, commitments} - root := hasher.HashTreeRoot(tree.GetHashFn()) + sum, err := sszHash(&BlobsAndCommitments{blobs, commitments}) + if err != nil { + return nil, nil, err + } var r bls.Fr - hashToFr(&r, root) + hashToFr(&r, sum) powers := computePowers(&r, len(blobs)) @@ -579,9 +610,9 @@ func computeAggregateKzgCommitment(blobs Blobs, commitments []KZGCommitment) ([] return aggregatePoly, aggregateCommitmentG1, nil } -func hashToFr(out *bls.Fr, root tree.Root) { +func hashToFr(out *bls.Fr, h [32]byte) { // re-interpret as little-endian - var b [32]byte = root + var b [32]byte = h for i := 0; i < 16; i++ { b[31-i], b[i] = b[i], b[31-i] } diff --git a/core/types/hashing.go b/core/types/hashing.go index 3915a474e66d..1ad4c6bf9c25 100644 --- a/core/types/hashing.go +++ b/core/types/hashing.go @@ -18,8 +18,10 @@ package types import ( "bytes" + "crypto/sha256" "sync" + "github.com/protolambda/ztyp/codec" "github.com/protolambda/ztyp/tree" "github.com/ethereum/go-ethereum/common" @@ -126,3 +128,14 @@ func DeriveSha(list DerivableList, hasher TrieHasher) common.Hash { } return hasher.Hash() } + +// sszHash returns the hash ot the raw serialized ssz-container (i.e. without merkelization) +func sszHash(c codec.Serializable) ([32]byte, error) { + sha := sha256.New() + if err := c.Serialize(codec.NewEncodingWriter(sha)); err != nil { + return [32]byte{}, err + } + var sum [32]byte + copy(sum[:], sha.Sum(nil)) + return sum, nil +}