Skip to content

Commit

Permalink
Migrate remaining EIP-4844 consensus spec code into kzg_new,
Browse files Browse the repository at this point in the history
updated to include the latest consensus spec updates.
  • Loading branch information
roberto-bayardo committed Nov 11, 2022
1 parent 7601916 commit 7db9eaf
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 154 deletions.
123 changes: 26 additions & 97 deletions core/types/data_blob.go
Expand Up @@ -209,6 +209,15 @@ func (blob *Blob) UnmarshalText(text []byte) error {

type BlobKzgs []KZGCommitment

func (li BlobKzgs) toKZGCommitmentSequence() []kzg.KZGCommitment {
l := len(li)
kzgs := make([]kzg.KZGCommitment, l)
for i := 0; i < l; i++ {
kzgs[i] = kzg.KZGCommitment(li[i])
}
return kzgs
}

func (li *BlobKzgs) Deserialize(dr *codec.DecodingReader) error {
return dr.List(func() codec.Deserializable {
i := len(*li)
Expand All @@ -227,7 +236,7 @@ func (li BlobKzgs) ByteLength() uint64 {
return uint64(len(li)) * 48
}

func (li *BlobKzgs) FixedLength() uint64 {
func (li BlobKzgs) FixedLength() uint64 {
return 0
}

Expand Down Expand Up @@ -305,38 +314,24 @@ func (blobs Blobs) ComputeCommitmentsAndAggregatedProof() (commitments []KZGComm
if !ok {
return nil, nil, KZGProof{}, errors.New("invalid blob for commitment")
}
commitments[i] = KZGCommitment(kzg.BlobToKZGCommitment(frs))
versionedHashes[i] = common.Hash(kzg.KZGToVersionedHash(kzg.KZGCommitment(commitments[i])))
c := kzg.BlobToKZGCommitment(frs)
commitments[i] = KZGCommitment(c)
versionedHashes[i] = common.Hash(kzg.KZGToVersionedHash(c))
}

var kzgProof KZGProof
if len(blobs) != 0 {
aggregatePoly, aggregateCommitmentG1, err := computeAggregateKzgCommitment(blobs, commitments)
if err != nil {
// TODO: Execution layer shouldn't be responsible for computing the proof, it should
// be done in the CL.
polys, ok := blobs.toKZGBlobSequence()
if !ok {
return nil, nil, KZGProof{}, err
}

var aggregateCommitment KZGCommitment
copy(aggregateCommitment[:], bls.ToCompressedG1(aggregateCommitmentG1))

var aggregateBlob Blob
for i := range aggregatePoly {
aggregateBlob[i] = bls.FrTo32(&aggregatePoly[i])
}
sum, err := sszHash(&PolynomialAndCommitment{aggregateBlob, aggregateCommitment})
proof, err := kzg.ComputeAggregateKZGProof(polys)
if err != nil {
return nil, nil, KZGProof{}, err
}
z := kzg.BytesToBLSField(sum)

var y bls.Fr
kzg.EvaluatePolyInEvaluationForm(&y, aggregatePoly[:], z)

aggProofG1, err := kzg.ComputeProof(aggregatePoly, z)
if err != nil {
return nil, nil, KZGProof{}, err
}
copy(kzgProof[:], bls.ToCompressedG1(aggProofG1))
kzgProof = KZGProof(proof)
}

return commitments, versionedHashes, kzgProof, nil
Expand All @@ -363,27 +358,6 @@ func (b *BlobsAndCommitments) FixedLength() uint64 {
return 0
}

type PolynomialAndCommitment struct {
b Blob
c KZGCommitment
}

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 @@ -448,31 +422,16 @@ func (b *BlobTxWrapData) verifyBlobs(inner TxData) error {
if err := b.verifyVersionedHash(inner); err != nil {
return err
}

aggregatePoly, aggregateCommitmentG1, err := computeAggregateKzgCommitment(b.Blobs, b.BlobKzgs)
if err != nil {
return fmt.Errorf("failed to compute aggregate commitment: %v", err)
}
var aggregateBlob Blob
for i := range aggregatePoly {
aggregateBlob[i] = bls.FrTo32(&aggregatePoly[i])
}
var aggregateCommitment KZGCommitment
copy(aggregateCommitment[:], bls.ToCompressedG1(aggregateCommitmentG1))
sum, err := sszHash(&PolynomialAndCommitment{aggregateBlob, aggregateCommitment})
if err != nil {
return err
polys, ok := b.Blobs.toKZGBlobSequence()
if !ok {
return errors.New("could not convert blobs to blob sequence")
}
z := kzg.BytesToBLSField(sum)

var y bls.Fr
kzg.EvaluatePolyInEvaluationForm(&y, aggregatePoly[:], z)

aggregateProofG1, err := bls.FromCompressedG1(b.KzgAggregatedProof[:])
kzgs := b.BlobKzgs.toKZGCommitmentSequence()
ok, err := kzg.VerifyAggregateKZGProof(polys, kzgs, kzg.KZGProof(b.KzgAggregatedProof))
if err != nil {
return fmt.Errorf("aggregate proof parse error: %v", err)
return fmt.Errorf("error during proof verification: %v", err)
}
if !kzg.VerifyKZGProofFromPoints(aggregateCommitmentG1, z, &y, aggregateProofG1) {
if !ok {
return errors.New("failed to verify kzg")
}
return nil
Expand Down Expand Up @@ -514,33 +473,3 @@ func (b *BlobTxWrapData) encodeTyped(w io.Writer, txdata TxData) error {
}
return EncodeSSZ(w, &wrapped)
}

func computeAggregateKzgCommitment(blobs Blobs, commitments []KZGCommitment) ([]bls.Fr, *bls.G1Point, error) {
// create challenges
sum, err := sszHash(&BlobsAndCommitments{blobs, commitments})
if err != nil {
return nil, nil, err
}
r := kzg.BytesToBLSField(sum)

powers := kzg.ComputePowers(r, len(blobs))

commitmentsG1 := make([]bls.G1Point, len(commitments))
for i := 0; i < len(commitmentsG1); i++ {
p, _ := bls.FromCompressedG1(commitments[i][:])
bls.CopyG1(&commitmentsG1[i], p)
}
aggregateCommitmentG1 := bls.LinCombG1(commitmentsG1, powers)
var aggregateCommitment KZGCommitment
copy(aggregateCommitment[:], bls.ToCompressedG1(aggregateCommitmentG1))

polys, ok := blobs.toKZGBlobSequence()
if !ok {
return nil, nil, err
}
aggregatePoly, err := bls.PolyLinComb(polys, powers)
if err != nil {
return nil, nil, err
}
return aggregatePoly, aggregateCommitmentG1, nil
}
49 changes: 0 additions & 49 deletions crypto/kzg/kzg.go
Expand Up @@ -2,12 +2,8 @@ package kzg

import (
"encoding/json"
"errors"
"math/big"
"math/bits"

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

"github.com/protolambda/go-kzg/bls"
)

Expand Down Expand Up @@ -71,48 +67,3 @@ func bitReversalPermutation(l []bls.G1Point) []bls.G1Point {

return out
}

// Compute KZG proof at point `z` with `polynomial` being in evaluation form.
// compute_kzg_proof from the EIP-4844 spec.
func ComputeProof(eval []bls.Fr, z *bls.Fr) (*bls.G1Point, error) {
if len(eval) != params.FieldElementsPerBlob {
return nil, errors.New("invalid eval polynomial for proof")
}

// To avoid overflow/underflow, convert elements into int
var poly [params.FieldElementsPerBlob]big.Int
for i := range poly {
frToBig(&poly[i], &eval[i])
}
var zB big.Int
frToBig(&zB, z)

// Shift our polynomial first (in evaluation form we can't handle the division remainder)
var yB big.Int
var y bls.Fr
EvaluatePolyInEvaluationForm(&y, eval, z)
frToBig(&yB, &y)
var polyShifted [params.FieldElementsPerBlob]big.Int

for i := range polyShifted {
polyShifted[i].Mod(new(big.Int).Sub(&poly[i], &yB), BLSModulus)
}

var denomPoly [params.FieldElementsPerBlob]big.Int
for i := range denomPoly {
// Make sure we won't induce a division by zero later. Shouldn't happen if using Fiat-Shamir challenges
if Domain[i].Cmp(&zB) == 0 {
return nil, errors.New("inavlid z challenge")
}
denomPoly[i].Mod(new(big.Int).Sub(Domain[i], &zB), BLSModulus)
}

// Calculate quotient polynomial by doing point-by-point division
var quotientPoly [params.FieldElementsPerBlob]bls.Fr
for i := range quotientPoly {
var tmp big.Int
blsDiv(&tmp, &polyShifted[i], &denomPoly[i])
_ = BigToFr(&quotientPoly[i], &tmp)
}
return bls.LinCombG1(kzgSetupLagrange, quotientPoly[:]), nil
}

0 comments on commit 7db9eaf

Please sign in to comment.