Skip to content

Commit

Permalink
Efficient Fiat-Shamir challenges using hashing (ethereum#15)
Browse files Browse the repository at this point in the history
By avoiding ssz merklelization, we significantly reduce the latency of generating FS
challenges.

Before:
```
BenchmarkVerifyMultiple/8-6           16          69890960 ns/op        25221325 B/op     399904 allocs/op
BenchmarkVerifyMultiple/16-6                   8         138506286 ns/op        50439658 B/op     799792 allocs/op
```

After:
```
BenchmarkVerifyMultiple/8-6 	      27	  41349482 ns/op	22059083 B/op	  301451 allocs/op
BenchmarkVerifyMultiple/16-6         	      14	  80868200 ns/op	44114668 B/op	  602909 allocs/op
```
  • Loading branch information
Inphi authored Aug 25, 2022
1 parent df336b7 commit fce14ba
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 12 deletions.
55 changes: 43 additions & 12 deletions core/types/data_blob.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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 {
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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))

Expand All @@ -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]
}
Expand Down
13 changes: 13 additions & 0 deletions core/types/hashing.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
}

0 comments on commit fce14ba

Please sign in to comment.