Skip to content

Commit

Permalink
v2 blob header signer
Browse files Browse the repository at this point in the history
  • Loading branch information
ian-shim committed Oct 25, 2024
1 parent 6c956b7 commit fd11da8
Show file tree
Hide file tree
Showing 9 changed files with 147 additions and 88 deletions.
41 changes: 41 additions & 0 deletions core/auth.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
package core

import (
"bytes"
"errors"
"fmt"

geth "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/crypto"
)

type BlobRequestAuthenticator interface {
AuthenticateBlobRequest(header BlobAuthHeader) error
}
Expand All @@ -8,3 +18,34 @@ type BlobRequestSigner interface {
SignBlobRequest(header BlobAuthHeader) ([]byte, error)
GetAccountID() (string, error)
}

func VerifySignature(message []byte, accountAddr geth.Address, sig []byte) error {
// Ensure the signature is 65 bytes (Recovery ID is the last byte)
if len(sig) != 65 {
return fmt.Errorf("signature length is unexpected: %d", len(sig))
}

publicKeyBytes, err := hexutil.Decode(accountAddr.Hex())
if err != nil {
return fmt.Errorf("failed to decode public key (%v): %v", accountAddr.Hex(), err)
}

// Decode public key
pubKey, err := crypto.UnmarshalPubkey(publicKeyBytes)
if err != nil {
return fmt.Errorf("failed to decode public key (%v): %v", accountAddr.Hex(), err)
}

// Verify the signature
sigPublicKeyECDSA, err := crypto.SigToPub(message, sig)
if err != nil {
return fmt.Errorf("failed to recover public key from signature: %v", err)
}

if !bytes.Equal(pubKey.X.Bytes(), sigPublicKeyECDSA.X.Bytes()) || !bytes.Equal(pubKey.Y.Bytes(), sigPublicKeyECDSA.Y.Bytes()) {
return errors.New("signature doesn't match with provided public key")
}

return nil

}
4 changes: 2 additions & 2 deletions core/auth/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
func TestAuthentication(t *testing.T) {

// Make the authenticator
authenticator := auth.NewAuthenticator(auth.AuthConfig{})
authenticator := auth.NewAuthenticator()

// Make the signer
privateKeyHex := "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
Expand Down Expand Up @@ -43,7 +43,7 @@ func TestAuthentication(t *testing.T) {
func TestAuthenticationFail(t *testing.T) {

// Make the authenticator
authenticator := auth.NewAuthenticator(auth.AuthConfig{})
authenticator := auth.NewAuthenticator()

// Make the signer
privateKeyHex := "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
Expand Down
14 changes: 4 additions & 10 deletions core/auth/authenticator.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,12 @@ import (
"github.com/ethereum/go-ethereum/crypto"
)

type AuthConfig struct {
}

type authenticator struct {
config AuthConfig
}
type authenticator struct{}

func NewAuthenticator(config AuthConfig) core.BlobRequestAuthenticator {
var _ core.BlobRequestAuthenticator = &authenticator{}

return &authenticator{
config: config,
}
func NewAuthenticator() core.BlobRequestAuthenticator {
return &authenticator{}
}

func (*authenticator) AuthenticateBlobRequest(header core.BlobAuthHeader) error {
Expand Down
2 changes: 2 additions & 0 deletions core/auth/signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ func (s *LocalBlobRequestSigner) GetAccountID() (string, error) {

type LocalNoopSigner struct{}

var _ core.BlobRequestSigner = &LocalNoopSigner{}

func NewLocalNoopSigner() *LocalNoopSigner {
return &LocalNoopSigner{}
}
Expand Down
113 changes: 70 additions & 43 deletions core/auth/v2/auth_test.go
Original file line number Diff line number Diff line change
@@ -1,89 +1,116 @@
package v2_test

import (
"math/rand"
"math/big"
"testing"

"github.com/Layr-Labs/eigenda/core"
"github.com/Layr-Labs/eigenda/core/auth"
auth "github.com/Layr-Labs/eigenda/core/auth/v2"
corev2 "github.com/Layr-Labs/eigenda/core/v2"
"github.com/Layr-Labs/eigenda/encoding"
"github.com/consensys/gnark-crypto/ecc/bn254/fp"
"github.com/stretchr/testify/assert"
)

func TestAuthentication(t *testing.T) {

// Make the authenticator
authenticator := auth.NewAuthenticator(auth.AuthConfig{})
var (
privateKeyHex = "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
)

// Make the signer
privateKeyHex := "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
func TestAuthentication(t *testing.T) {
signer := auth.NewLocalBlobRequestSigner(privateKeyHex)
authenticator := auth.NewAuthenticator()

accountId, err := signer.GetAccountID()
assert.NoError(t, err)

testHeader := core.BlobAuthHeader{
BlobCommitments: encoding.BlobCommitments{},
AccountID: accountId,
Nonce: rand.Uint32(),
AuthenticationData: []byte{},
}
header := testHeader(t, accountId)

// Sign the header
signature, err := signer.SignBlobRequest(testHeader)
signature, err := signer.SignBlobRequest(header)
assert.NoError(t, err)

testHeader.AuthenticationData = signature
header.Signature = signature

err = authenticator.AuthenticateBlobRequest(testHeader)
err = authenticator.AuthenticateBlobRequest(header)
assert.NoError(t, err)

}

func TestAuthenticationFail(t *testing.T) {

// Make the authenticator
authenticator := auth.NewAuthenticator(auth.AuthConfig{})

// Make the signer
privateKeyHex := "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
signer := auth.NewLocalBlobRequestSigner(privateKeyHex)
authenticator := auth.NewAuthenticator()

accountId, err := signer.GetAccountID()
assert.NoError(t, err)

testHeader := core.BlobAuthHeader{
BlobCommitments: encoding.BlobCommitments{},
AccountID: accountId,
Nonce: rand.Uint32(),
AuthenticationData: []byte{},
}
header := testHeader(t, accountId)

privateKeyHex = "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcded"
signer = auth.NewLocalBlobRequestSigner(privateKeyHex)
wrongPrivateKeyHex := "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcded"
signer = auth.NewLocalBlobRequestSigner(wrongPrivateKeyHex)

// Sign the header
signature, err := signer.SignBlobRequest(testHeader)
signature, err := signer.SignBlobRequest(header)
assert.NoError(t, err)

testHeader.AuthenticationData = signature
header.Signature = signature

err = authenticator.AuthenticateBlobRequest(testHeader)
err = authenticator.AuthenticateBlobRequest(header)
assert.Error(t, err)

}

func TestNoopSignerFail(t *testing.T) {
signer := auth.NewLocalNoopSigner()
accountId, err := signer.GetAccountID()
assert.EqualError(t, err, "noop signer cannot get accountID")

testHeader := core.BlobAuthHeader{
BlobCommitments: encoding.BlobCommitments{},
AccountID: accountId,
Nonce: rand.Uint32(),
AuthenticationData: []byte{},
}
_, err = signer.SignBlobRequest(testHeader)
header := testHeader(t, accountId)

_, err = signer.SignBlobRequest(header)
assert.EqualError(t, err, "noop signer cannot sign blob request")
}

func testHeader(t *testing.T, accountID string) *corev2.BlobHeader {
var commitX, commitY fp.Element
_, err := commitX.SetString("21661178944771197726808973281966770251114553549453983978976194544185382599016")
assert.NoError(t, err)
_, err = commitY.SetString("9207254729396071334325696286939045899948985698134704137261649190717970615186")
assert.NoError(t, err)

commitment := &encoding.G1Commitment{
X: commitX,
Y: commitY,
}
var lengthXA0, lengthXA1, lengthYA0, lengthYA1 fp.Element
_, err = lengthXA0.SetString("10857046999023057135944570762232829481370756359578518086990519993285655852781")
assert.NoError(t, err)
_, err = lengthXA1.SetString("11559732032986387107991004021392285783925812861821192530917403151452391805634")
assert.NoError(t, err)
_, err = lengthYA0.SetString("8495653923123431417604973247489272438418190587263600148770280649306958101930")
assert.NoError(t, err)
_, err = lengthYA1.SetString("4082367875863433681332203403145435568316851327593401208105741076214120093531")
assert.NoError(t, err)

var lengthProof, lengthCommitment encoding.G2Commitment
lengthProof.X.A0 = lengthXA0
lengthProof.X.A1 = lengthXA1
lengthProof.Y.A0 = lengthYA0
lengthProof.Y.A1 = lengthYA1

lengthCommitment = lengthProof

return &corev2.BlobHeader{
BlobVersion: 0,
BlobCommitments: encoding.BlobCommitments{
Commitment: commitment,
LengthCommitment: &lengthCommitment,
LengthProof: &lengthProof,
Length: 50,
},
QuorumNumbers: []core.QuorumID{0, 1},
PaymentMetadata: core.PaymentMetadata{
AccountID: accountID,
BinIndex: 5,
CumulativePayment: big.NewInt(100),
},
Signature: []byte{},
}
}
37 changes: 15 additions & 22 deletions core/auth/v2/authenticator.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,55 +2,49 @@ package v2

import (
"bytes"
"encoding/binary"
"errors"
"fmt"

"github.com/Layr-Labs/eigenda/core"
core "github.com/Layr-Labs/eigenda/core/v2"

"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/crypto"
)

type AuthConfig struct {
}
type authenticator struct{}

type authenticator struct {
config AuthConfig
func NewAuthenticator() *authenticator {
return &authenticator{}
}

func NewAuthenticator(config AuthConfig) core.BlobRequestAuthenticator {

return &authenticator{
config: config,
}
}
var _ core.BlobRequestAuthenticator = &authenticator{}

func (*authenticator) AuthenticateBlobRequest(header core.BlobAuthHeader) error {
sig := header.AuthenticationData
func (*authenticator) AuthenticateBlobRequest(header *core.BlobHeader) error {
sig := header.Signature

// Ensure the signature is 65 bytes (Recovery ID is the last byte)
if len(sig) != 65 {
return fmt.Errorf("signature length is unexpected: %d", len(sig))
}

buf := make([]byte, 4)
binary.BigEndian.PutUint32(buf, header.Nonce)
hash := crypto.Keccak256(buf)
blobKey, err := header.BlobKey()
if err != nil {
return fmt.Errorf("failed to get blob key: %v", err)
}

publicKeyBytes, err := hexutil.Decode(header.AccountID)
publicKeyBytes, err := hexutil.Decode(header.PaymentMetadata.AccountID)
if err != nil {
return fmt.Errorf("failed to decode public key (%v): %v", header.AccountID, err)
return fmt.Errorf("failed to decode public key (%v): %v", header.PaymentMetadata.AccountID, err)
}

// Decode public key
pubKey, err := crypto.UnmarshalPubkey(publicKeyBytes)
if err != nil {
return fmt.Errorf("failed to decode public key (%v): %v", header.AccountID, err)
return fmt.Errorf("failed to decode public key (%v): %v", header.PaymentMetadata.AccountID, err)
}

// Verify the signature
sigPublicKeyECDSA, err := crypto.SigToPub(hash, sig)
sigPublicKeyECDSA, err := crypto.SigToPub(blobKey[:], sig)
if err != nil {
return fmt.Errorf("failed to recover public key from signature: %v", err)
}
Expand All @@ -60,5 +54,4 @@ func (*authenticator) AuthenticateBlobRequest(header core.BlobAuthHeader) error
}

return nil

}
18 changes: 10 additions & 8 deletions core/auth/v2/signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package v2

import (
"crypto/ecdsa"
"encoding/binary"
"fmt"
"log"

Expand Down Expand Up @@ -30,13 +29,14 @@ func NewLocalBlobRequestSigner(privateKeyHex string) *LocalBlobRequestSigner {
}
}

func (s *LocalBlobRequestSigner) SignBlobRequest(header core.BlobHeader) ([]byte, error) {
// Message you want to sign

hash := crypto.Keccak256(buf)
func (s *LocalBlobRequestSigner) SignBlobRequest(header *core.BlobHeader) ([]byte, error) {
blobKey, err := header.BlobKey()
if err != nil {
return nil, fmt.Errorf("failed to get blob key: %v", err)
}

// Sign the hash using the private key
sig, err := crypto.Sign(hash, s.PrivateKey)
// Sign the blob key using the private key
sig, err := crypto.Sign(blobKey[:], s.PrivateKey)
if err != nil {
return nil, fmt.Errorf("failed to sign hash: %v", err)
}
Expand All @@ -53,11 +53,13 @@ func (s *LocalBlobRequestSigner) GetAccountID() (string, error) {

type LocalNoopSigner struct{}

var _ core.BlobRequestSigner = &LocalNoopSigner{}

func NewLocalNoopSigner() *LocalNoopSigner {
return &LocalNoopSigner{}
}

func (s *LocalNoopSigner) SignBlobRequest(header core.BlobHeader) ([]byte, error) {
func (s *LocalNoopSigner) SignBlobRequest(header *core.BlobHeader) ([]byte, error) {
return nil, fmt.Errorf("noop signer cannot sign blob request")
}

Expand Down
4 changes: 2 additions & 2 deletions core/v2/auth.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package v2

type BlobRequestAuthenticator interface {
AuthenticateBlobRequest(header BlobHeader) error
AuthenticateBlobRequest(header *BlobHeader) error
}

type BlobRequestSigner interface {
SignBlobRequest(header BlobHeader) ([]byte, error)
SignBlobRequest(header *BlobHeader) ([]byte, error)
GetAccountID() (string, error)
}
Loading

0 comments on commit fd11da8

Please sign in to comment.