Skip to content

Commit

Permalink
Remove unnecessary code
Browse files Browse the repository at this point in the history
Signed-off-by: litt3 <[email protected]>
  • Loading branch information
litt3 committed Dec 19, 2024
1 parent 60b8790 commit 1b1bca2
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 147 deletions.
155 changes: 17 additions & 138 deletions api/clients/verification/verification_utils.go
Original file line number Diff line number Diff line change
@@ -1,76 +1,44 @@
package verification

Check failure on line 1 in api/clients/verification/verification_utils.go

View workflow job for this annotation

GitHub Actions / Linter

: # github.com/Layr-Labs/eigenda/api/clients/verification [github.com/Layr-Labs/eigenda/api/clients/verification.test]

import (
"errors"
"fmt"
"github.com/Layr-Labs/eigenda/encoding"
"slices"

core "github.com/Layr-Labs/eigenda/core/v2"
"github.com/ethereum/go-ethereum/crypto"

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

"github.com/consensys/gnark-crypto/ecc"
"github.com/consensys/gnark-crypto/ecc/bn254"

disperserpb "github.com/Layr-Labs/eigenda/api/grpc/disperser/v2"
"github.com/Layr-Labs/eigenda/encoding/kzg/verifier"
"github.com/Layr-Labs/eigenda/encoding/rs"
)

// VerifyBlobStatusReply verifies all blob data, as required to trust that the blob is valid
func VerifyBlobStatusReply(
// GenerateBlobCommitment computes a kzg-bn254 commitment of blob data using SRS
func GenerateBlobCommitment(
kzgVerifier *verifier.Verifier,
reply *disperserpb.BlobStatusReply,
// these bytes must represent the blob in coefficient form (i.e. IFFTed)
blobBytes []byte) error {

blobHeader, err := core.BlobHeaderFromProtobuf(reply.BlobVerificationInfo.BlobCertificate.BlobHeader)
if err != nil {
return fmt.Errorf("blob header from protobuf: %w", err)
}
blobKey, err := blobHeader.BlobKey()
if err != nil {
return fmt.Errorf("compute blob key: %w", err)
}

err = VerifyMerkleProof(
&blobKey,
reply.BlobVerificationInfo.InclusionProof,
reply.SignedBatch.Header.BatchRoot,
reply.BlobVerificationInfo.BlobIndex)
if err != nil {
return fmt.Errorf("verify merkle proof: %w", err)
}

commitments, err := encoding.BlobCommitmentsFromProtobuf(reply.BlobVerificationInfo.BlobCertificate.BlobHeader.Commitment)
if err != nil {
return fmt.Errorf("commitments from protobuf: %w", err)
}
blob []byte) (*encoding.G1Commitment, error) {

err = VerifyKzgCommitment(kzgVerifier, commitments.Commitment, blobBytes)
inputFr, err := rs.ToFrArray(blob)
if err != nil {
return fmt.Errorf("verify commitment: %w", err)
return nil, fmt.Errorf("convert bytes to field elements, %w", err)
}

if uint(len(blobBytes)) != commitments.Length {
return fmt.Errorf("actual blob length (%d) doesn't match claimed length in commitment (%d)", len(blobBytes), commitments.Length)
if len(kzgVerifier.Srs.G1) < len(inputFr) {
return nil, fmt.Errorf(
"insufficient SRS in memory: have %v, need %v",
len(kzgVerifier.Srs.G1),
len(inputFr))
}

err = kzgVerifier.VerifyBlobLength(*commitments)
var commitment bn254.G1Affine
_, err = commitment.MultiExp(kzgVerifier.Srs.G1[:len(inputFr)], inputFr, ecc.MultiExpConfig{})
if err != nil {
return fmt.Errorf("verify blob length: %w", err)
return nil, fmt.Errorf("MultiExp: %w", err)
}

return nil
return &encoding.G1Commitment{X: commitment.X, Y: commitment.Y}, nil
}

// VerifyKzgCommitment asserts that the claimed commitment from the certificate matches the commitment computed
// from the blob.
//
// TODO: Optimize implementation by opening a point on the commitment instead (don’t compute the g2 point. ask Bowen)
func VerifyKzgCommitment(
// GenerateAndCompareBlobCommitment generates the kzg-bn254 commitment of the blob, and compares it with a claimed
// commitment. An error is returned if there is a problem generating the commitment, or if the comparison fails.
func GenerateAndCompareBlobCommitment(
kzgVerifier *verifier.Verifier,
claimedCommitment *encoding.G1Commitment,
blobBytes []byte) error {
Expand All @@ -89,92 +57,3 @@ func VerifyKzgCommitment(
"commitment field elements do not match. computed commitment: (x: %x, y: %x), claimed commitment (x: %x, y: %x)",
computedCommitment.X, computedCommitment.Y, claimedCommitment.X, claimedCommitment.Y)
}

// GenerateBlobCommitment computes kzg-bn254 commitment of blob data using SRS
//
// The blob data input to this method should be in coefficient form (IFFTed)
func GenerateBlobCommitment(
kzgVerifier *verifier.Verifier,
blob []byte) (*bn254.G1Affine, error) {

inputFr, err := rs.ToFrArray(blob)
if err != nil {
return nil, fmt.Errorf("cannot convert bytes to field elements, %w", err)
}

if len(kzgVerifier.Srs.G1) < len(inputFr) {
return nil, fmt.Errorf(
"cannot verify commitment because the number of stored srs in the memory is insufficient, have %v need %v",
len(kzgVerifier.Srs.G1),
len(inputFr))
}

config := ecc.MultiExpConfig{}
var commitment bn254.G1Affine
_, err = commitment.MultiExp(kzgVerifier.Srs.G1[:len(inputFr)], inputFr, config)
if err != nil {
return nil, err
}

return &commitment, nil
}

// TODO: I don't think that any of the checks done in `verifySecurityParams` from the proxy code are necessary in v2. confirm this.

// VerifyMerkleProof verifies the blob batch inclusion proof against the claimed batch root
func VerifyMerkleProof(
// the key of the blob, which functions as the leaf in the batch merkle tree
blobKey *core.BlobKey,
// the inclusion proof, which contains the sibling hashes necessary to compute the root hash starting at the leaf
inclusionProof []byte,
// the claimed merkle root hash, which must be verified
claimedRoot []byte,
// the index of the blob in the batch. this informs whether the leaf being verified is a left or right child
blobIndex uint32) error {

generatedRoot, err := ProcessInclusionProof(inclusionProof, blobKey, uint64(blobIndex))
if err != nil {
return err
}

equal := slices.Equal(claimedRoot, generatedRoot.Bytes())
if !equal {
return fmt.Errorf("root hash mismatch, expected: %x, got: %x", claimedRoot, generatedRoot)
}

return nil
}

// ProcessInclusionProof computes the root hash, using the leaf and relevant inclusion proof
//
// This logic is implemented here, rather than using merkletree.VerifyProofUsing, in order to exactly mirror
// https://github.com/Layr-Labs/eigenlayer-contracts/blob/dev/src/contracts/libraries/Merkle.sol#L49-L76, which is the
// verification method that executes on chain. It is important that the offchain verification result exactly matches
// the onchain result
func ProcessInclusionProof(proof []byte, blobKey *core.BlobKey, index uint64) (common.Hash, error) {
if len(proof)%32 != 0 {
return common.Hash{}, errors.New("proof length should be a multiple of 32 bytes or 256 bits")
}

// computedHash starts out equal to the hash of the leaf (the blob key)
var computedHash common.Hash
copy(computedHash[:], blobKey[:])

// we then work our way up the merkle tree, to compute the root hash
for i := 0; i < len(proof); i += 32 {
var proofElement common.Hash
copy(proofElement[:], proof[i:i+32])

var combined []byte
if index%2 == 0 { // right
combined = append(computedHash.Bytes(), proofElement.Bytes()...)
} else { // left
combined = append(proofElement.Bytes(), computedHash.Bytes()...)
}

computedHash = crypto.Keccak256Hash(combined)
index /= 2
}

return computedHash, nil
}
17 changes: 8 additions & 9 deletions api/clients/verification/verification_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package verification

import (
"github.com/Layr-Labs/eigenda/common/testutils/random"
"github.com/Layr-Labs/eigenda/encoding"
"github.com/Layr-Labs/eigenda/encoding/kzg"
"github.com/Layr-Labs/eigenda/encoding/kzg/verifier"
"github.com/Layr-Labs/eigenda/encoding/utils/codec"
Expand All @@ -18,6 +17,7 @@ var (
[]byte("Fourscore and seven years ago our fathers brought forth, on this continent, a new nation, conceived in liberty, and dedicated to the proposition that all men are created equal. Now we are engaged in a great civil war, testing whether that nation, or any nation so conceived, and so dedicated, can long endure. We are met on a great battle-field of that war. We have come to dedicate a portion of that field, as a final resting-place for those who here gave their lives, that that nation might live. It is altogether fitting and proper that we should do this. But, in a larger sense, we cannot dedicate, we cannot consecrate—we cannot hallow—this ground. The brave men, living and dead, who struggled here, have consecrated it far above our poor power to add or detract. The world will little note, nor long remember what we say here, but it can never forget what they did here. It is for us the living, rather, to be dedicated here to the unfinished work which they who fought here have thus far so nobly advanced. It is rather for us to be here dedicated to the great task remaining before us—that from these honored dead we take increased devotion to that cause for which they here gave the last full measure of devotion—that we here highly resolve that these dead shall not have died in vain—that this nation, under God, shall have a new birth of freedom, and that government of the people, by the people, for the people, shall not perish from the earth."))

kzgConfig *kzg.KzgConfig
kzgVerifier *verifier.Verifier
testRandom *random.TestRandom
srsNumberToLoad uint64
)
Expand All @@ -41,6 +41,7 @@ func setup() {
testRandom = random.NewTestRandom()

Check failure on line 41 in api/clients/verification/verification_utils_test.go

View workflow job for this annotation

GitHub Actions / Linter

not enough arguments in call to random.NewTestRandom

Check failure on line 41 in api/clients/verification/verification_utils_test.go

View workflow job for this annotation

GitHub Actions / Linter

not enough arguments in call to random.NewTestRandom

Check failure on line 41 in api/clients/verification/verification_utils_test.go

View workflow job for this annotation

GitHub Actions / Unit Tests

not enough arguments in call to random.NewTestRandom
}

// randomlyModifyBytes picks a random byte from the input array, and increments it
func randomlyModifyBytes(inputBytes []byte) {
indexToModify := testRandom.Intn(len(inputBytes))
inputBytes[indexToModify] = inputBytes[indexToModify] + 1
Expand All @@ -57,7 +58,7 @@ func teardown() {
log.Println("Tearing down")
}

func TestVerifyKzgCommitmentSuccess(t *testing.T) {
func TestComputeAndCompareKzgCommitmentSuccess(t *testing.T) {
kzgVerifier, err := verifier.NewVerifier(kzgConfig, nil)
assert.NotNil(t, kzgVerifier)
assert.Nil(t, err)
Expand All @@ -66,17 +67,15 @@ func TestVerifyKzgCommitmentSuccess(t *testing.T) {
assert.NotNil(t, commitment)
assert.Nil(t, err)

g1Commitment := &encoding.G1Commitment{X: commitment.X, Y: commitment.Y}

// make sure the commitment verifies correctly
err = VerifyKzgCommitment(
err = GenerateAndCompareBlobCommitment(
kzgVerifier,
g1Commitment,
commitment,
gettysburgAddressBytes)
assert.Nil(t, err)
}

func TestVerifyKzgCommitmentFailure(t *testing.T) {
func TestComputeAndCompareKzgCommitmentFailure(t *testing.T) {
kzgVerifier, err := verifier.NewVerifier(kzgConfig, nil)
assert.NotNil(t, kzgVerifier)
assert.Nil(t, err)
Expand All @@ -87,9 +86,9 @@ func TestVerifyKzgCommitmentFailure(t *testing.T) {

// randomly modify the bytes, and make sure the commitment verification fails
randomlyModifyBytes(gettysburgAddressBytes)
err = VerifyKzgCommitment(
err = GenerateAndCompareBlobCommitment(
kzgVerifier,
&encoding.G1Commitment{X: commitment.X, Y: commitment.Y},
commitment,
gettysburgAddressBytes)
assert.NotNil(t, err)
}
Expand Down

0 comments on commit 1b1bca2

Please sign in to comment.