Skip to content

Commit

Permalink
fix(grpc): sign and verify message by ed25519
Browse files Browse the repository at this point in the history
  • Loading branch information
Shivam Mantri authored and Shivam Mantri committed Jan 14, 2025
1 parent 0b9353e commit 02396aa
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 15 deletions.
66 changes: 51 additions & 15 deletions www/grpc/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package grpc
import (
"context"
"fmt"
"github.com/pactus-project/pactus/crypto/ed25519"
"strings"

"github.com/pactus-project/pactus/crypto/bls"
pactus "github.com/pactus-project/pactus/www/grpc/gen/go"
Expand All @@ -23,12 +25,31 @@ func newUtilsServer(server *Server) *utilServer {
func (*utilServer) SignMessageWithPrivateKey(_ context.Context,
req *pactus.SignMessageWithPrivateKeyRequest,
) (*pactus.SignMessageWithPrivateKeyResponse, error) {
prvKey, err := bls.PrivateKeyFromString(req.PrivateKey)
if err != nil {
return nil, status.Error(codes.InvalidArgument, "invalid private key")
var sig string

maybeBLSPrivateKey := func(str string) bool {
return strings.Contains(strings.ToLower(str), "secret1p")
}

sig := prvKey.Sign([]byte(req.Message)).String()
maybeEd25519PrivateKey := func(str string) bool {
return strings.Contains(strings.ToLower(str), "secret1r")
}
switch {
case maybeBLSPrivateKey(req.PrivateKey):
blsPrv, err := bls.PrivateKeyFromString(req.PrivateKey)
if err != nil {
return nil, status.Error(codes.InvalidArgument, "invalid private key")
}
sig = blsPrv.Sign([]byte(req.Message)).String()
case maybeEd25519PrivateKey(req.PrivateKey):
ed25519Prv, err := ed25519.PrivateKeyFromString(req.PrivateKey)
if err != nil {
return nil, status.Error(codes.InvalidArgument, "invalid private key")
}
sig = ed25519Prv.Sign([]byte(req.Message)).String()
default:
return nil, status.Error(codes.InvalidArgument, "invalid private key")

Check warning on line 51 in www/grpc/utils.go

View check run for this annotation

Codecov / codecov/patch

www/grpc/utils.go#L50-L51

Added lines #L50 - L51 were not covered by tests
}

return &pactus.SignMessageWithPrivateKeyResponse{
Signature: sig,
Expand All @@ -38,20 +59,35 @@ func (*utilServer) SignMessageWithPrivateKey(_ context.Context,
func (*utilServer) VerifyMessage(_ context.Context,
req *pactus.VerifyMessageRequest,
) (*pactus.VerifyMessageResponse, error) {
sig, err := bls.SignatureFromString(req.Signature)
if err != nil {
return nil, status.Error(codes.InvalidArgument, "signature is invalid")
}
blsPub, err := bls.PublicKeyFromString(req.PublicKey)

pub, err := bls.PublicKeyFromString(req.PublicKey)
if err != nil {

Check failure on line 64 in www/grpc/utils.go

View workflow job for this annotation

GitHub Actions / linting

`if err != nil` has complex nested blocks (complexity: 6) (nestif)

Check failure on line 64 in www/grpc/utils.go

View workflow job for this annotation

GitHub Actions / build-linux

`if err != nil` has complex nested blocks (complexity: 6) (nestif)
return nil, status.Error(codes.InvalidArgument, "public key is invalid")
}
ed25519Pub, err := ed25519.PublicKeyFromString(req.PublicKey)
if err != nil {
return nil, status.Error(codes.InvalidArgument, "public key is invalid")
}

Check warning on line 68 in www/grpc/utils.go

View check run for this annotation

Codecov / codecov/patch

www/grpc/utils.go#L67-L68

Added lines #L67 - L68 were not covered by tests

sig, err := ed25519.SignatureFromString(req.Signature)
if err != nil {
return nil, status.Error(codes.InvalidArgument, "signature is invalid")
}

Check warning on line 73 in www/grpc/utils.go

View check run for this annotation

Codecov / codecov/patch

www/grpc/utils.go#L72-L73

Added lines #L72 - L73 were not covered by tests

if err := pub.Verify([]byte(req.Message), sig); err == nil {
return &pactus.VerifyMessageResponse{
IsValid: true,
}, nil
if err = ed25519Pub.Verify([]byte(req.Message), sig); err == nil {
return &pactus.VerifyMessageResponse{
IsValid: true,
}, nil
}
} else {
sig, err := bls.SignatureFromString(req.Signature)
if err != nil {
return nil, status.Error(codes.InvalidArgument, "signature is invalid")
}

Check warning on line 84 in www/grpc/utils.go

View check run for this annotation

Codecov / codecov/patch

www/grpc/utils.go#L83-L84

Added lines #L83 - L84 were not covered by tests

if err = blsPub.Verify([]byte(req.Message), sig); err == nil {
return &pactus.VerifyMessageResponse{
IsValid: true,
}, nil
}
}

return &pactus.VerifyMessageResponse{
Expand Down
73 changes: 73 additions & 0 deletions www/grpc/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,42 @@ func TestSignMessageWithPrivateKey(t *testing.T) {
td.StopServer()
}

func TestSignMessageWithED25519PrivateKey(t *testing.T) {
conf := testConfig()
td := setup(t, conf)
conn, client := td.utilClient(t)

msg := "pactus"
prvStr := "SECRET1RYY62A96X25ZAL4DPL5Z63G83GCSFCCQ7K0CMQD3MFNLYK3A6R26QUUK3Y0"
invalidPrvStr := "INVSECRET1RYY62A96X25ZAL4DPL5Z63G83GCSFCCQ7K0CMQD3MFNLYK3A6R26QUUK3Y0"
expectedSig := "361aaa09c408bfcf7e79dd90c583eeeaefe7c732ca5643cfb2ea7a6d22105b874a412080525a855bbd5df94110a7d0083d6e386e016ecf8b7f522c339f79d305"

t.Run("", func(t *testing.T) {
res, err := client.SignMessageWithPrivateKey(context.Background(),
&pactus.SignMessageWithPrivateKeyRequest{
Message: msg,
PrivateKey: prvStr,
})

assert.Nil(t, err)
assert.Equal(t, expectedSig, res.Signature)
})

t.Run("", func(t *testing.T) {
res, err := client.SignMessageWithPrivateKey(context.Background(),
&pactus.SignMessageWithPrivateKeyRequest{
Message: msg,
PrivateKey: invalidPrvStr,
})

assert.NotNil(t, err)
assert.Nil(t, res)
})

assert.Nil(t, conn.Close(), "Error closing connection")
td.StopServer()
}

func TestVerifyMessage(t *testing.T) {
conf := testConfig()
td := setup(t, conf)
Expand Down Expand Up @@ -84,6 +120,43 @@ func TestVerifyMessage(t *testing.T) {
td.StopServer()
}

func TestVerifyED25519Message(t *testing.T) {
conf := testConfig()
td := setup(t, conf)
conn, client := td.utilClient(t)

msg := "pactus"
pubStr := "public1rvqxnpfph8tnc3ck55z85w285t5jetylmmktr9wlzs0zvx7kx500szxfudh"
sigStr := "361aaa09c408bfcf7e79dd90c583eeeaefe7c732ca5643cfb2ea7a6d22105b874a412080525a855bbd5df94110a7d0083d6e386e016ecf8b7f522c339f79d305"
invalidSigStr := "001aaa09c408bfcf7e79dd90c583eeeaefe7c732ca5643cfb2ea7a6d22105b874a412080525a855bbd5df94110a7d0083d6e386e016ecf8b7f522c339f79d305"

t.Run("valid message", func(t *testing.T) {
res, err := client.VerifyMessage(context.Background(),
&pactus.VerifyMessageRequest{
Message: msg,
Signature: sigStr,
PublicKey: pubStr,
})
assert.Nil(t, err)
assert.True(t, res.IsValid)
})

t.Run("invalid message", func(t *testing.T) {
res, err := client.VerifyMessage(context.Background(),
&pactus.VerifyMessageRequest{
Message: msg,
Signature: invalidSigStr,
PublicKey: pubStr,
})

assert.Nil(t, err)
assert.False(t, res.IsValid)
})

assert.Nil(t, conn.Close(), "Error closing connection")
td.StopServer()
}

func TestBLSPublicKeyAggregation(t *testing.T) {
ts := testsuite.NewTestSuite(t)
conf := testConfig()
Expand Down

0 comments on commit 02396aa

Please sign in to comment.