Skip to content

Commit 9ea1faa

Browse files
move more low-level kzg stuff into kzg_new (#48)
* start using custom types from the 4844 spec * move ComputePowers into kzg_new * 1) move BlobsToKZGCommitment functionality into kzg_new and make it more closely follow the spec. 2) Remove the BlobsBatch stuff which seems only to be for legacy benchmarking. * Replace kzg-related data_blob.go type methods Parse, ComputeCommitment, and Point, so we can move methods that depend on them into the kzg package. * Remove ComputeCommitments which is unused. * Add BytesToBLSField go kzg_new, use it instead of hashToFr
1 parent e8e85fe commit 9ea1faa

File tree

6 files changed

+101
-227
lines changed

6 files changed

+101
-227
lines changed

core/types/data_blob.go

Lines changed: 25 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"errors"
66
"fmt"
77
"io"
8-
"math/big"
98

109
"github.com/ethereum/go-ethereum/common"
1110
"github.com/ethereum/go-ethereum/common/hexutil"
@@ -58,12 +57,8 @@ func (p *KZGCommitment) UnmarshalText(text []byte) error {
5857
return hexutil.UnmarshalFixedText("KZGCommitment", text, p[:])
5958
}
6059

61-
func (p *KZGCommitment) Point() (*bls.G1Point, error) {
62-
return bls.FromCompressedG1(p[:])
63-
}
64-
6560
func (c KZGCommitment) ComputeVersionedHash() common.Hash {
66-
return kzg.KZGToVersionedHash(c)
61+
return common.Hash(kzg.KZGToVersionedHash(kzg.KZGCommitment(c)))
6762
}
6863

6964
// Compressed BLS12-381 G1 element
@@ -108,10 +103,6 @@ func (p *KZGProof) UnmarshalText(text []byte) error {
108103
return hexutil.UnmarshalFixedText("KZGProof", text, p[:])
109104
}
110105

111-
func (p *KZGProof) Point() (*bls.G1Point, error) {
112-
return bls.FromCompressedG1(p[:])
113-
}
114-
115106
type BLSFieldElement [32]byte
116107

117108
func (p BLSFieldElement) MarshalText() ([]byte, error) {
@@ -165,18 +156,15 @@ func (blob *Blob) HashTreeRoot(hFn tree.HashFn) tree.Root {
165156
}, params.FieldElementsPerBlob)
166157
}
167158

168-
func (blob *Blob) ComputeCommitment() (commitment KZGCommitment, ok bool) {
159+
// Convert a blob to kzg.Blob
160+
func (blob *Blob) ToKZGBlob() (kzg.Blob, bool) {
169161
frs := make([]bls.Fr, len(blob))
170162
for i, elem := range blob {
171163
if !bls.FrFrom32(&frs[i], elem) {
172-
return KZGCommitment{}, false
164+
return []bls.Fr{}, false
173165
}
174166
}
175-
// data is presented in eval form
176-
commitmentG1 := kzg.BlobToKzg(frs)
177-
var out KZGCommitment
178-
copy(out[:], bls.ToCompressedG1(commitmentG1))
179-
return out, true
167+
return kzg.Blob(frs), true
180168
}
181169

182170
func (blob *Blob) MarshalText() ([]byte, error) {
@@ -219,33 +207,8 @@ func (blob *Blob) UnmarshalText(text []byte) error {
219207
return nil
220208
}
221209

222-
// Parse blob into Fr elements array
223-
func (blob *Blob) Parse() (out []bls.Fr, err error) {
224-
out = make([]bls.Fr, params.FieldElementsPerBlob)
225-
for i, chunk := range blob {
226-
ok := bls.FrFrom32(&out[i], chunk)
227-
if !ok {
228-
return nil, errors.New("internal error commitments")
229-
}
230-
}
231-
return out, nil
232-
}
233-
234210
type BlobKzgs []KZGCommitment
235211

236-
// Extract the crypto material underlying these commitments
237-
func (li BlobKzgs) Parse() ([]*bls.G1Point, error) {
238-
out := make([]*bls.G1Point, len(li))
239-
for i, c := range li {
240-
p, err := c.Point()
241-
if err != nil {
242-
return nil, fmt.Errorf("failed to parse commitment %d: %v", i, err)
243-
}
244-
out[i] = p
245-
}
246-
return out, nil
247-
}
248-
249212
func (li *BlobKzgs) Deserialize(dr *codec.DecodingReader) error {
250213
return dr.List(func() codec.Deserializable {
251214
i := len(*li)
@@ -283,16 +246,16 @@ func (li BlobKzgs) copy() BlobKzgs {
283246
type Blobs []Blob
284247

285248
// Extract the crypto material underlying these blobs
286-
func (blobs Blobs) Parse() ([][]bls.Fr, error) {
249+
func (blobs Blobs) toKZGBlobSequence() ([][]bls.Fr, bool) {
287250
out := make([][]bls.Fr, len(blobs))
288251
for i, b := range blobs {
289-
blob, err := b.Parse()
290-
if err != nil {
291-
return nil, fmt.Errorf("failed to parse blob %d: %v", i, err)
252+
blob, ok := b.ToKZGBlob()
253+
if !ok {
254+
return nil, false
292255
}
293256
out[i] = blob
294257
}
295-
return out, nil
258+
return out, true
296259
}
297260

298261
func (a *Blobs) Deserialize(dr *codec.DecodingReader) error {
@@ -333,31 +296,17 @@ func (blobs Blobs) copy() Blobs {
333296
return cpy
334297
}
335298

336-
// Return KZG commitments and versioned hashes that correspond to these blobs
337-
func (blobs Blobs) ComputeCommitments() (commitments []KZGCommitment, versionedHashes []common.Hash, ok bool) {
338-
commitments = make([]KZGCommitment, len(blobs))
339-
versionedHashes = make([]common.Hash, len(blobs))
340-
for i, blob := range blobs {
341-
commitments[i], ok = blob.ComputeCommitment()
342-
if !ok {
343-
return nil, nil, false
344-
}
345-
versionedHashes[i] = commitments[i].ComputeVersionedHash()
346-
}
347-
return commitments, versionedHashes, true
348-
}
349-
350299
// Return KZG commitments, versioned hashes and the aggregated KZG proof that correspond to these blobs
351300
func (blobs Blobs) ComputeCommitmentsAndAggregatedProof() (commitments []KZGCommitment, versionedHashes []common.Hash, aggregatedProof KZGProof, err error) {
352301
commitments = make([]KZGCommitment, len(blobs))
353302
versionedHashes = make([]common.Hash, len(blobs))
354303
for i, blob := range blobs {
355-
var ok bool
356-
commitments[i], ok = blob.ComputeCommitment()
304+
frs, ok := blob.ToKZGBlob()
357305
if !ok {
358306
return nil, nil, KZGProof{}, errors.New("invalid blob for commitment")
359307
}
360-
versionedHashes[i] = commitments[i].ComputeVersionedHash()
308+
commitments[i] = KZGCommitment(kzg.BlobToKZGCommitment(frs))
309+
versionedHashes[i] = common.Hash(kzg.KZGToVersionedHash(kzg.KZGCommitment(commitments[i])))
361310
}
362311

363312
var kzgProof KZGProof
@@ -378,13 +327,12 @@ func (blobs Blobs) ComputeCommitmentsAndAggregatedProof() (commitments []KZGComm
378327
if err != nil {
379328
return nil, nil, KZGProof{}, err
380329
}
381-
var z bls.Fr
382-
hashToFr(&z, sum)
330+
z := kzg.BytesToBLSField(sum)
383331

384332
var y bls.Fr
385-
kzg.EvaluatePolyInEvaluationForm(&y, aggregatePoly[:], &z)
333+
kzg.EvaluatePolyInEvaluationForm(&y, aggregatePoly[:], z)
386334

387-
aggProofG1, err := kzg.ComputeProof(aggregatePoly, &z)
335+
aggProofG1, err := kzg.ComputeProof(aggregatePoly, z)
388336
if err != nil {
389337
return nil, nil, KZGProof{}, err
390338
}
@@ -515,17 +463,16 @@ func (b *BlobTxWrapData) verifyBlobs(inner TxData) error {
515463
if err != nil {
516464
return err
517465
}
518-
var z bls.Fr
519-
hashToFr(&z, sum)
466+
z := kzg.BytesToBLSField(sum)
520467

521468
var y bls.Fr
522-
kzg.EvaluatePolyInEvaluationForm(&y, aggregatePoly[:], &z)
469+
kzg.EvaluatePolyInEvaluationForm(&y, aggregatePoly[:], z)
523470

524-
aggregateProofG1, err := b.KzgAggregatedProof.Point()
471+
aggregateProofG1, err := bls.FromCompressedG1(b.KzgAggregatedProof[:])
525472
if err != nil {
526473
return fmt.Errorf("aggregate proof parse error: %v", err)
527474
}
528-
if !kzg.VerifyKZGProofFromPoints(aggregateCommitmentG1, &z, &y, aggregateProofG1) {
475+
if !kzg.VerifyKZGProofFromPoints(aggregateCommitmentG1, z, &y, aggregateProofG1) {
529476
return errors.New("failed to verify kzg")
530477
}
531478
return nil
@@ -568,39 +515,27 @@ func (b *BlobTxWrapData) encodeTyped(w io.Writer, txdata TxData) error {
568515
return EncodeSSZ(w, &wrapped)
569516
}
570517

571-
func computePowers(r *bls.Fr, n int) []bls.Fr {
572-
var currentPower bls.Fr
573-
bls.AsFr(&currentPower, 1)
574-
powers := make([]bls.Fr, n)
575-
for i := range powers {
576-
powers[i] = currentPower
577-
bls.MulModFr(&currentPower, &currentPower, r)
578-
}
579-
return powers
580-
}
581-
582518
func computeAggregateKzgCommitment(blobs Blobs, commitments []KZGCommitment) ([]bls.Fr, *bls.G1Point, error) {
583519
// create challenges
584520
sum, err := sszHash(&BlobsAndCommitments{blobs, commitments})
585521
if err != nil {
586522
return nil, nil, err
587523
}
588-
var r bls.Fr
589-
hashToFr(&r, sum)
524+
r := kzg.BytesToBLSField(sum)
590525

591-
powers := computePowers(&r, len(blobs))
526+
powers := kzg.ComputePowers(r, len(blobs))
592527

593528
commitmentsG1 := make([]bls.G1Point, len(commitments))
594529
for i := 0; i < len(commitmentsG1); i++ {
595-
p, _ := commitments[i].Point()
530+
p, _ := bls.FromCompressedG1(commitments[i][:])
596531
bls.CopyG1(&commitmentsG1[i], p)
597532
}
598533
aggregateCommitmentG1 := bls.LinCombG1(commitmentsG1, powers)
599534
var aggregateCommitment KZGCommitment
600535
copy(aggregateCommitment[:], bls.ToCompressedG1(aggregateCommitmentG1))
601536

602-
polys, err := blobs.Parse()
603-
if err != nil {
537+
polys, ok := blobs.toKZGBlobSequence()
538+
if !ok {
604539
return nil, nil, err
605540
}
606541
aggregatePoly, err := bls.PolyLinComb(polys, powers)
@@ -609,13 +544,3 @@ func computeAggregateKzgCommitment(blobs Blobs, commitments []KZGCommitment) ([]
609544
}
610545
return aggregatePoly, aggregateCommitmentG1, nil
611546
}
612-
613-
func hashToFr(out *bls.Fr, h [32]byte) {
614-
// re-interpret as little-endian
615-
var b [32]byte = h
616-
for i := 0; i < 16; i++ {
617-
b[31-i], b[i] = b[i], b[31-i]
618-
}
619-
zB := new(big.Int).Mod(new(big.Int).SetBytes(b[:]), kzg.BLSModulus)
620-
_ = kzg.BigToFr(out, zB)
621-
}

crypto/kzg/kzg.go

Lines changed: 0 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@ package kzg
33
import (
44
"encoding/json"
55
"errors"
6-
"fmt"
76
"math/big"
87
"math/bits"
9-
"sync"
108

119
"github.com/ethereum/go-ethereum/params"
1210

@@ -45,68 +43,6 @@ func init() {
4543
initDomain()
4644
}
4745

48-
// Convert polynomial in evaluation form to KZG commitment
49-
func BlobToKzg(eval []bls.Fr) *bls.G1Point {
50-
return bls.LinCombG1(kzgSetupLagrange, eval)
51-
}
52-
53-
type BlobsBatch struct {
54-
sync.Mutex
55-
init bool
56-
aggregateCommitment bls.G1Point
57-
aggregateBlob [params.FieldElementsPerBlob]bls.Fr
58-
}
59-
60-
func (batch *BlobsBatch) Join(commitments []*bls.G1Point, blobs [][]bls.Fr) error {
61-
batch.Lock()
62-
defer batch.Unlock()
63-
if len(commitments) != len(blobs) {
64-
return fmt.Errorf("expected commitments len %d to equal blobs len %d", len(commitments), len(blobs))
65-
}
66-
if !batch.init && len(commitments) > 0 {
67-
batch.init = true
68-
bls.CopyG1(&batch.aggregateCommitment, commitments[0])
69-
copy(batch.aggregateBlob[:], blobs[0])
70-
commitments = commitments[1:]
71-
blobs = blobs[1:]
72-
}
73-
for i, commit := range commitments {
74-
batch.join(commit, blobs[i])
75-
}
76-
return nil
77-
}
78-
79-
func (batch *BlobsBatch) join(commitment *bls.G1Point, blob []bls.Fr) {
80-
// we multiply the input we are joining with a random scalar, so we can add it to the aggregate safely
81-
randomScalar := bls.RandomFr()
82-
83-
// TODO: instead of computing the lin-comb of the commitments on the go, we could buffer
84-
// the random scalar and commitment, and run a LinCombG1 over all of them during Verify()
85-
var tmpG1 bls.G1Point
86-
bls.MulG1(&tmpG1, commitment, randomScalar)
87-
bls.AddG1(&batch.aggregateCommitment, &batch.aggregateCommitment, &tmpG1)
88-
89-
var tmpFr bls.Fr
90-
for i := 0; i < params.FieldElementsPerBlob; i++ {
91-
bls.MulModFr(&tmpFr, &blob[i], randomScalar)
92-
bls.AddModFr(&batch.aggregateBlob[i], &batch.aggregateBlob[i], &tmpFr)
93-
}
94-
}
95-
96-
func (batch *BlobsBatch) Verify() error {
97-
batch.Lock()
98-
defer batch.Unlock()
99-
if !batch.init {
100-
return nil // empty batch
101-
}
102-
// Compute both MSMs and check equality
103-
lResult := bls.LinCombG1(kzgSetupLagrange, batch.aggregateBlob[:])
104-
if !bls.EqualG1(lResult, &batch.aggregateCommitment) {
105-
return errors.New("BlobsBatch failed to Verify")
106-
}
107-
return nil
108-
}
109-
11046
// Bit-reversal permutation helper functions
11147

11248
// Check if `value` is a power of two integer.

0 commit comments

Comments
 (0)