Skip to content

Commit d0e66e5

Browse files
BuidlWithShivamShivam Mantri
and
Shivam Mantri
authored
feat(grpc): support Ed25519 message signing and verification (#1667)
Co-authored-by: Shivam Mantri <shivam.mantri@Shivams-MacBook-Air.local>
1 parent 0b9353e commit d0e66e5

File tree

2 files changed

+124
-14
lines changed

2 files changed

+124
-14
lines changed

www/grpc/utils.go

+48-14
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ package grpc
22

33
import (
44
"context"
5+
"errors"
56
"fmt"
67

8+
"github.com/pactus-project/pactus/crypto"
79
"github.com/pactus-project/pactus/crypto/bls"
10+
"github.com/pactus-project/pactus/crypto/ed25519"
811
pactus "github.com/pactus-project/pactus/www/grpc/gen/go"
912
"google.golang.org/grpc/codes"
1013
"google.golang.org/grpc/status"
@@ -20,35 +23,28 @@ func newUtilsServer(server *Server) *utilServer {
2023
}
2124
}
2225

23-
func (*utilServer) SignMessageWithPrivateKey(_ context.Context,
26+
func (u *utilServer) SignMessageWithPrivateKey(_ context.Context,
2427
req *pactus.SignMessageWithPrivateKeyRequest,
2528
) (*pactus.SignMessageWithPrivateKeyResponse, error) {
26-
prvKey, err := bls.PrivateKeyFromString(req.PrivateKey)
29+
prvKey, err := u.privateKeyFromString(req.PrivateKey)
2730
if err != nil {
28-
return nil, status.Error(codes.InvalidArgument, "invalid private key")
31+
return nil, status.Error(codes.InvalidArgument, err.Error())
2932
}
30-
3133
sig := prvKey.Sign([]byte(req.Message)).String()
3234

3335
return &pactus.SignMessageWithPrivateKeyResponse{
3436
Signature: sig,
3537
}, nil
3638
}
3739

38-
func (*utilServer) VerifyMessage(_ context.Context,
40+
func (u *utilServer) VerifyMessage(_ context.Context,
3941
req *pactus.VerifyMessageRequest,
4042
) (*pactus.VerifyMessageResponse, error) {
41-
sig, err := bls.SignatureFromString(req.Signature)
42-
if err != nil {
43-
return nil, status.Error(codes.InvalidArgument, "signature is invalid")
44-
}
45-
46-
pub, err := bls.PublicKeyFromString(req.PublicKey)
43+
pubKey, sig, err := u.publicKeyAndSigFromString(req.PublicKey, req.Signature)
4744
if err != nil {
48-
return nil, status.Error(codes.InvalidArgument, "public key is invalid")
45+
return nil, status.Error(codes.InvalidArgument, err.Error())
4946
}
50-
51-
if err := pub.Verify([]byte(req.Message), sig); err == nil {
47+
if err = pubKey.Verify([]byte(req.Message), sig); err == nil {
5248
return &pactus.VerifyMessageResponse{
5349
IsValid: true,
5450
}, nil
@@ -101,3 +97,41 @@ func (*utilServer) BLSSignatureAggregation(_ context.Context,
10197
Signature: bls.SignatureAggregate(sigs...).String(),
10298
}, nil
10399
}
100+
101+
func (*utilServer) privateKeyFromString(prvStr string) (crypto.PrivateKey, error) {
102+
blsPrv, err := bls.PrivateKeyFromString(prvStr)
103+
if err == nil {
104+
return blsPrv, nil
105+
}
106+
107+
ed25519Prv, err := ed25519.PrivateKeyFromString(prvStr)
108+
if err == nil {
109+
return ed25519Prv, nil
110+
}
111+
112+
return nil, errors.New("invalid Private Key")
113+
}
114+
115+
func (*utilServer) publicKeyAndSigFromString(pubStr, sigStr string) (crypto.PublicKey, crypto.Signature, error) {
116+
blsPub, err := bls.PublicKeyFromString(pubStr)
117+
if err == nil {
118+
blsSig, err := bls.SignatureFromString(sigStr)
119+
if err != nil {
120+
return nil, nil, errors.New("invalid BLS signature")
121+
}
122+
123+
return blsPub, blsSig, nil
124+
}
125+
126+
ed25519Pub, err := ed25519.PublicKeyFromString(pubStr)
127+
if err == nil {
128+
ed25519Sig, err := ed25519.SignatureFromString(sigStr)
129+
if err != nil {
130+
return nil, nil, errors.New("invalid Ed25519 signature")
131+
}
132+
133+
return ed25519Pub, ed25519Sig, nil
134+
}
135+
136+
return nil, nil, errors.New("invalid Public Key")
137+
}

www/grpc/utils_test.go

+76
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,43 @@ func TestSignMessageWithPrivateKey(t *testing.T) {
4646
td.StopServer()
4747
}
4848

49+
func TestSignMessageWithED25519PrivateKey(t *testing.T) {
50+
conf := testConfig()
51+
td := setup(t, conf)
52+
conn, client := td.utilClient(t)
53+
54+
msg := "pactus"
55+
prvStr := "SECRET1RYY62A96X25ZAL4DPL5Z63G83GCSFCCQ7K0CMQD3MFNLYK3A6R26QUUK3Y0"
56+
invalidPrvStr := "INVSECRET1RYY62A96X25ZAL4DPL5Z63G83GCSFCCQ7K0CMQD3MFNLYK3A6R26QUUK3Y0"
57+
expectedSig := "361aaa09c408bfcf7e79dd90c583eeeaefe7c732ca5643cfb2ea7a6d22105b874a412080" +
58+
"525a855bbd5df94110a7d0083d6e386e016ecf8b7f522c339f79d305"
59+
60+
t.Run("", func(t *testing.T) {
61+
res, err := client.SignMessageWithPrivateKey(context.Background(),
62+
&pactus.SignMessageWithPrivateKeyRequest{
63+
Message: msg,
64+
PrivateKey: prvStr,
65+
})
66+
67+
assert.Nil(t, err)
68+
assert.Equal(t, expectedSig, res.Signature)
69+
})
70+
71+
t.Run("", func(t *testing.T) {
72+
res, err := client.SignMessageWithPrivateKey(context.Background(),
73+
&pactus.SignMessageWithPrivateKeyRequest{
74+
Message: msg,
75+
PrivateKey: invalidPrvStr,
76+
})
77+
78+
assert.NotNil(t, err)
79+
assert.Nil(t, res)
80+
})
81+
82+
assert.Nil(t, conn.Close(), "Error closing connection")
83+
td.StopServer()
84+
}
85+
4986
func TestVerifyMessage(t *testing.T) {
5087
conf := testConfig()
5188
td := setup(t, conf)
@@ -84,6 +121,45 @@ func TestVerifyMessage(t *testing.T) {
84121
td.StopServer()
85122
}
86123

124+
func TestVerifyED25519Message(t *testing.T) {
125+
conf := testConfig()
126+
td := setup(t, conf)
127+
conn, client := td.utilClient(t)
128+
129+
msg := "pactus"
130+
pubStr := "public1rvqxnpfph8tnc3ck55z85w285t5jetylmmktr9wlzs0zvx7kx500szxfudh"
131+
sigStr := "361aaa09c408bfcf7e79dd90c583eeeaefe7c732ca5643cfb2ea7a6d22105b874a41" +
132+
"2080525a855bbd5df94110a7d0083d6e386e016ecf8b7f522c339f79d305"
133+
invalidSigStr := "001aaa09c408bfcf7e79dd90c583eeeaefe7c732ca5643cfb2ea7a6d22105b" +
134+
"874a412080525a855bbd5df94110a7d0083d6e386e016ecf8b7f522c339f79d305"
135+
136+
t.Run("valid message", func(t *testing.T) {
137+
res, err := client.VerifyMessage(context.Background(),
138+
&pactus.VerifyMessageRequest{
139+
Message: msg,
140+
Signature: sigStr,
141+
PublicKey: pubStr,
142+
})
143+
assert.Nil(t, err)
144+
assert.True(t, res.IsValid)
145+
})
146+
147+
t.Run("invalid message", func(t *testing.T) {
148+
res, err := client.VerifyMessage(context.Background(),
149+
&pactus.VerifyMessageRequest{
150+
Message: msg,
151+
Signature: invalidSigStr,
152+
PublicKey: pubStr,
153+
})
154+
155+
assert.Nil(t, err)
156+
assert.False(t, res.IsValid)
157+
})
158+
159+
assert.Nil(t, conn.Close(), "Error closing connection")
160+
td.StopServer()
161+
}
162+
87163
func TestBLSPublicKeyAggregation(t *testing.T) {
88164
ts := testsuite.NewTestSuite(t)
89165
conf := testConfig()

0 commit comments

Comments
 (0)