From aed730c634bb4f3866daa8e432f34ecd63f0a1b8 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Tue, 9 May 2023 10:48:55 -0400 Subject: [PATCH] feat: use addresses in signed topic validator --- waku/v2/protocol/relay/validators.go | 36 ++++++++++++++++++----- waku/v2/protocol/relay/validators_test.go | 27 +++++++++-------- 2 files changed, 43 insertions(+), 20 deletions(-) diff --git a/waku/v2/protocol/relay/validators.go b/waku/v2/protocol/relay/validators.go index 6e99fd36..dac50714 100644 --- a/waku/v2/protocol/relay/validators.go +++ b/waku/v2/protocol/relay/validators.go @@ -1,6 +1,7 @@ package relay import ( + "bytes" "context" "crypto/ecdsa" "crypto/elliptic" @@ -14,6 +15,7 @@ import ( pubsub "github.com/libp2p/go-libp2p-pubsub" "github.com/libp2p/go-libp2p/core/peer" "github.com/waku-org/go-waku/waku/v2/hash" + "github.com/waku-org/go-waku/waku/v2/protocol" "github.com/waku-org/go-waku/waku/v2/protocol/pb" "github.com/waku-org/go-waku/waku/v2/timesource" "go.uber.org/zap" @@ -54,8 +56,9 @@ func withinTimeWindow(t timesource.Timesource, msg *pb.WakuMessage) bool { type validatorFn = func(ctx context.Context, peerID peer.ID, message *pubsub.Message) bool -func validatorFnBuilder(t timesource.Timesource, topic string, publicKey *ecdsa.PublicKey) validatorFn { - pubkBytes := crypto.FromECDSAPub(publicKey) +func validatorFnBuilder(t timesource.Timesource, publicKey *ecdsa.PublicKey) (validatorFn, error) { + address := crypto.PubkeyToAddress(*publicKey) + topic := protocol.NewNamedShardingPubsubTopic(address.String() + "/proto").String() return func(ctx context.Context, peerID peer.ID, message *pubsub.Message) bool { msg := new(pb.WakuMessage) err := proto.Unmarshal(message.Data, msg) @@ -70,13 +73,26 @@ func validatorFnBuilder(t timesource.Timesource, topic string, publicKey *ecdsa. msgHash := MsgHash(topic, msg) signature := msg.Meta - return secp256k1.VerifySignature(pubkBytes, msgHash, signature) - } + pubKey, err := crypto.SigToPub(msgHash, signature) + if err != nil { + return false + } + + msgAddress := crypto.PubkeyToAddress(*pubKey) + + return bytes.Equal(msgAddress.Bytes(), address.Bytes()) + }, nil } func (w *WakuRelay) AddSignedTopicValidator(topic string, publicKey *ecdsa.PublicKey) error { w.log.Info("adding validator to signed topic", zap.String("topic", topic), zap.String("publicKey", hex.EncodeToString(elliptic.Marshal(publicKey.Curve, publicKey.X, publicKey.Y)))) - err := w.pubsub.RegisterTopicValidator(topic, validatorFnBuilder(w.timesource, topic, publicKey)) + + fn, err := validatorFnBuilder(w.timesource, publicKey) + if err != nil { + return err + } + + err = w.pubsub.RegisterTopicValidator(topic, fn) if err != nil { return err } @@ -88,13 +104,19 @@ func (w *WakuRelay) AddSignedTopicValidator(topic string, publicKey *ecdsa.Publi return nil } -func SignMessage(privKey *ecdsa.PrivateKey, topic string, msg *pb.WakuMessage) error { +func SignMessage(privKey *ecdsa.PrivateKey, msg *pb.WakuMessage) error { + topic := PrivKeyToTopic(privKey) msgHash := MsgHash(topic, msg) sign, err := secp256k1.Sign(msgHash, crypto.FromECDSA(privKey)) if err != nil { return err } - msg.Meta = sign[0:64] // Drop the V in R||S||V + msg.Meta = sign return nil } + +func PrivKeyToTopic(privKey *ecdsa.PrivateKey) string { + address := crypto.PubkeyToAddress(privKey.PublicKey) + return protocol.NewNamedShardingPubsubTopic(address.String() + "/proto").String() +} diff --git a/waku/v2/protocol/relay/validators_test.go b/waku/v2/protocol/relay/validators_test.go index 6377d6b7..352b1b1f 100644 --- a/waku/v2/protocol/relay/validators_test.go +++ b/waku/v2/protocol/relay/validators_test.go @@ -1,7 +1,6 @@ package relay import ( - "bytes" "context" "encoding/hex" "testing" @@ -43,7 +42,6 @@ func TestMsgHash(t *testing.T) { payload, _ := hex.DecodeString("1A12E077D0E89F9CAC11FBBB6A676C86120B5AD3E248B1F180E98F15EE43D2DFCF62F00C92737B2FF6F59B3ABA02773314B991C41DC19ADB0AD8C17C8E26757B") contentTopic := "content-topic" - pubsubTopic := "pubsub-topic" ephemeral := true timestamp := time.Unix(0, 1683208172339052800) @@ -54,19 +52,20 @@ func TestMsgHash(t *testing.T) { Ephemeral: ephemeral, } - err := SignMessage(prvKey, pubsubTopic, msg) + err := SignMessage(prvKey, msg) require.NoError(t, err) - expectedSignature, _ := hex.DecodeString("127FA211B2514F0E974A055392946DC1A14052182A6ABEFB8A6CD7C51DA1BF2E40595D28EF1A9488797C297EED3AAC45430005FB3A7F037BDD9FC4BD99F59E63") - require.True(t, bytes.Equal(expectedSignature, msg.Meta)) + // expectedSignature, _ := hex.DecodeString("127FA211B2514F0E974A055392946DC1A14052182A6ABEFB8A6CD7C51DA1BF2E40595D28EF1A9488797C297EED3AAC45430005FB3A7F037BDD9FC4BD99F59E63") + // require.True(t, bytes.Equal(expectedSignature, msg.Meta)) msgData, _ := proto.Marshal(msg) - expectedMessageHash, _ := hex.DecodeString("662F8C20A335F170BD60ABC1F02AD66F0C6A6EE285DA2A53C95259E7937C0AE9") - messageHash := MsgHash(pubsubTopic, msg) - require.True(t, bytes.Equal(expectedMessageHash, messageHash)) + //expectedMessageHash, _ := hex.DecodeString("662F8C20A335F170BD60ABC1F02AD66F0C6A6EE285DA2A53C95259E7937C0AE9") + //messageHash := MsgHash(pubsubTopic, msg) + //require.True(t, bytes.Equal(expectedMessageHash, messageHash)) - myValidator := validatorFnBuilder(NewFakeTimesource(timestamp), pubsubTopic, &prvKey.PublicKey) + myValidator, err := validatorFnBuilder(NewFakeTimesource(timestamp), &prvKey.PublicKey) + require.NoError(t, err) result := myValidator(context.Background(), "", &pubsub.Message{ Message: &pubsub_pb.Message{ Data: msgData, @@ -75,8 +74,9 @@ func TestMsgHash(t *testing.T) { require.True(t, result) // Exceed 5m window in both directions - now5m1sInPast := timestamp.Add(-5 * time.Minute).Add(-1 * time.Minute) - myValidator = validatorFnBuilder(NewFakeTimesource(now5m1sInPast), pubsubTopic, &prvKey.PublicKey) + now5m1sInPast := timestamp.Add(-5 * time.Minute).Add(-1 * time.Second) + myValidator, err = validatorFnBuilder(NewFakeTimesource(now5m1sInPast), &prvKey.PublicKey) + require.NoError(t, err) result = myValidator(context.Background(), "", &pubsub.Message{ Message: &pubsub_pb.Message{ Data: msgData, @@ -84,8 +84,9 @@ func TestMsgHash(t *testing.T) { }) require.False(t, result) - now5m1sInFuture := timestamp.Add(5 * time.Minute).Add(1 * time.Minute) - myValidator = validatorFnBuilder(NewFakeTimesource(now5m1sInFuture), pubsubTopic, &prvKey.PublicKey) + now5m1sInFuture := timestamp.Add(5 * time.Minute).Add(1 * time.Second) + myValidator, err = validatorFnBuilder(NewFakeTimesource(now5m1sInFuture), &prvKey.PublicKey) + require.NoError(t, err) result = myValidator(context.Background(), "", &pubsub.Message{ Message: &pubsub_pb.Message{ Data: msgData,