diff --git a/README.md b/README.md index 3d388cfd..8bf0d6c1 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -![Compiles](https://github.com/Layr-Labs/eigenda-proxy/actions/workflows/build.yml/badge.svg) -![Unit Tests](https://github.com/Layr-Labs/eigenda-proxy/actions/workflows/unit-tests.yml/badge.svg) -![Linter](https://github.com/Layr-Labs/eigenda-proxy/actions/workflows/lint.yml/badge.svg) -![Integration Tests](https://github.com/Layr-Labs/eigenda-proxy/actions/workflows/holesky-test.yml/badge.svg) +[![Compiles](https://github.com/Layr-Labs/eigenda-proxy/actions/workflows/build.yml/badge.svg)](https://github.com/Layr-Labs/eigenda-proxy/actions/workflows/build.yml) +[![Unit Tests](https://github.com/Layr-Labs/eigenda-proxy/actions/workflows/unit-tests.yml/badge.svg)](https://github.com/Layr-Labs/eigenda-proxy/actions/workflows/unit-tests.yml) +[![Linter](https://github.com/Layr-Labs/eigenda-proxy/actions/workflows/lint.yml/badge.svg)](https://github.com/Layr-Labs/eigenda-proxy/actions/workflows/lint.yml) +[![Integration Tests](https://github.com/Layr-Labs/eigenda-proxy/actions/workflows/holesky-test.yml/badge.svg)](https://github.com/Layr-Labs/eigenda-proxy/actions/workflows/holesky-test.yml) # EigenDA Proxy diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..9a7925e3 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,19 @@ +# Security Policy + +## Version Information + +Please see [Releases](https://github.com/Layr-Labs/eigenda-proxy/releases) + +## Audit reports + +Audit reports are published in the `docs/audits` folder: https://github.com/Layr-Labs/eigenda-proxy/main/docs/audits + +| Date | Report Link | +| ------- | ----------- | +| 202501 | [pdf](https://github.com/Layr-Labs/eigenda-proxy/blob/main/docs/audits/Sigma_Prime_EigenDA_Proxy_Security_Assessment_Report.pdf) | + +## Reporting a Vulnerability + +**Please do not file a public ticket** mentioning the vulnerability. + +Please report security vulnerabilities to security@eigenlabs.org with the all the relavent details included in the email. diff --git a/docs/audits/Sigma_Prime_EigenDA_Proxy_Security_Assessment_Report.pdf b/docs/audits/Sigma_Prime_EigenDA_Proxy_Security_Assessment_Report.pdf new file mode 100644 index 00000000..74575b18 Binary files /dev/null and b/docs/audits/Sigma_Prime_EigenDA_Proxy_Security_Assessment_Report.pdf differ diff --git a/store/generated_key/eigenda/eigenda.go b/store/generated_key/eigenda/eigenda.go index b67ce1d2..9ff5c9bb 100644 --- a/store/generated_key/eigenda/eigenda.go +++ b/store/generated_key/eigenda/eigenda.go @@ -59,7 +59,12 @@ func (e Store) Get(ctx context.Context, key []byte) ([]byte, error) { return nil, fmt.Errorf("failed to decode DA cert to RLP format: %w", err) } - decodedBlob, err := e.client.GetBlob(ctx, cert.BlobVerificationProof.BatchMetadata.BatchHeaderHash, cert.BlobVerificationProof.BlobIndex) + err = cert.NoNilFields() + if err != nil { + return nil, fmt.Errorf("failed to verify DA cert: %w", err) + } + + decodedBlob, err := e.client.GetBlob(ctx, cert.BlobVerificationProof.GetBatchMetadata().GetBatchHeaderHash(), cert.BlobVerificationProof.GetBlobIndex()) if err != nil { return nil, fmt.Errorf("EigenDA client failed to retrieve decoded blob: %w", err) } @@ -119,7 +124,12 @@ func (e Store) Put(ctx context.Context, value []byte) ([]byte, error) { } cert := (*verify.Certificate)(blobInfo) - err = e.verifier.VerifyCommitment(cert.BlobHeader.Commitment, encodedBlob) + err = cert.NoNilFields() + if err != nil { + return nil, fmt.Errorf("failed to verify DA cert: %w", err) + } + + err = e.verifier.VerifyCommitment(cert.BlobHeader.GetCommitment(), encodedBlob) if err != nil { return nil, fmt.Errorf("failed to verify commitment: %w", err) } @@ -158,7 +168,7 @@ func (e Store) Verify(ctx context.Context, key []byte, value []byte) error { } // verify kzg data commitment - err = e.verifier.VerifyCommitment(cert.BlobHeader.Commitment, encodedBlob) + err = e.verifier.VerifyCommitment(cert.BlobHeader.GetCommitment(), encodedBlob) if err != nil { return fmt.Errorf("failed to verify commitment: %w", err) } diff --git a/verify/certificate.go b/verify/certificate.go index 9defd894..88259252 100644 --- a/verify/certificate.go +++ b/verify/certificate.go @@ -1,6 +1,7 @@ package verify import ( + "fmt" "math/big" "github.com/Layr-Labs/eigenda/api/grpc/disperser" @@ -29,6 +30,32 @@ type BlobHeader struct { type Certificate disperser.BlobInfo +// NoNilFields ... checks if any referenced fields in the certificate +// are nil and returns an error if so +func (c *Certificate) NoNilFields() error { + if c.BlobVerificationProof == nil { + return fmt.Errorf("BlobVerificationProof is nil") + } + + if c.BlobVerificationProof.BatchMetadata == nil { + return fmt.Errorf("BlobVerificationProof.BatchMetadata is nil") + } + + if c.BlobVerificationProof.BatchMetadata.BatchHeader == nil { + return fmt.Errorf("BlobVerificationProof.BatchMetadata.BatchHeader is nil") + } + + if c.BlobHeader == nil { + return fmt.Errorf("BlobHeader is nil") + } + + if c.BlobHeader.Commitment == nil { + return fmt.Errorf("BlobHeader.Commitment is nil") + } + + return nil +} + func (c *Certificate) BlobIndex() uint32 { return c.BlobVerificationProof.BlobIndex } diff --git a/verify/cli.go b/verify/cli.go index 39b994de..d931e431 100644 --- a/verify/cli.go +++ b/verify/cli.go @@ -11,17 +11,13 @@ import ( "github.com/Layr-Labs/eigenda/encoding/kzg" ) -var ( +const ( BytesPerSymbol = 31 MaxCodingRatio = 8 - MaxSRSPoints = 1 << 28 // 2^28 - MaxAllowedBlobSize = uint64(MaxSRSPoints * BytesPerSymbol / MaxCodingRatio) + SrsOrder = 1 << 28 // 2^28 + MaxAllowedBlobSize = uint64(SrsOrder * BytesPerSymbol / MaxCodingRatio) ) -// TODO: should this live in the resources pkg? -// So that if we ever change the SRS files there we can change this value -const srsOrder = 268435456 // 2 ^ 32 - var ( // cert verification flags CertVerificationDisabledFlagName = withFlagPrefix("cert-verification-disabled") @@ -125,7 +121,7 @@ func ReadConfig(ctx *cli.Context, edaClientConfig clients.EigenDAClientConfig) C G1Path: ctx.String(G1PathFlagName), G2PowerOf2Path: ctx.String(G2PowerOf2PathFlagName), CacheDir: ctx.String(CachePathFlagName), - SRSOrder: srsOrder, + SRSOrder: SrsOrder, SRSNumberToLoad: MaxBlobLengthBytes / 32, // # of fr.Elements NumWorker: uint64(runtime.GOMAXPROCS(0)), // #nosec G115 } diff --git a/verify/verifier.go b/verify/verifier.go index a79c9f84..84f3863b 100644 --- a/verify/verifier.go +++ b/verify/verifier.go @@ -124,21 +124,30 @@ func (v *Verifier) Commit(blob []byte) (*bn254.G1Affine, error) { // Verify regenerates a commitment from the blob and asserts equivalence // to the commitment in the certificate // TODO: Optimize implementation by opening a point on the commitment instead -func (v *Verifier) VerifyCommitment(expectedCommit *common.G1Commitment, blob []byte) error { +func (v *Verifier) VerifyCommitment(certCommitment *common.G1Commitment, blob []byte) error { actualCommit, err := v.Commit(blob) if err != nil { return err } - expectedX := &fp.Element{} - expectedX.Unmarshal(expectedCommit.X) - expectedY := &fp.Element{} - expectedY.Unmarshal(expectedCommit.Y) + certCommitmentX := &fp.Element{} + certCommitmentX.Unmarshal(certCommitment.X) + certCommitmentY := &fp.Element{} + certCommitmentY.Unmarshal(certCommitment.Y) + + certCommitmentAffine := bn254.G1Affine{ + X: *certCommitmentX, + Y: *certCommitmentY, + } + + if !certCommitmentAffine.IsOnCurve() { + return fmt.Errorf("commitment (x,y) field elements are not on the BN254 curve") + } errMsg := "" - if !actualCommit.X.Equal(expectedX) || !actualCommit.Y.Equal(expectedY) { - errMsg += fmt.Sprintf("field elements do not match, x actual commit: %x, x expected commit: %x, ", actualCommit.X.Marshal(), expectedX.Marshal()) - errMsg += fmt.Sprintf("y actual commit: %x, y expected commit: %x", actualCommit.Y.Marshal(), expectedY.Marshal()) + if !actualCommit.X.Equal(certCommitmentX) || !actualCommit.Y.Equal(certCommitmentY) { + errMsg += fmt.Sprintf("field elements do not match, x actual commit: %x, x expected commit: %x, ", actualCommit.X.Marshal(), certCommitmentX.Marshal()) + errMsg += fmt.Sprintf("y actual commit: %x, y expected commit: %x", actualCommit.Y.Marshal(), certCommitmentY.Marshal()) return fmt.Errorf("%s", errMsg) }