-
Notifications
You must be signed in to change notification settings - Fork 9
/
message.go
86 lines (74 loc) · 2.44 KB
/
message.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package api
import (
"context"
"encoding/hex"
"strings"
"github.com/bytom/vapor/blockchain/signers"
"github.com/bytom/vapor/common"
"github.com/bytom/vapor/consensus"
"github.com/bytom/vapor/crypto"
"github.com/bytom/vapor/crypto/ed25519"
"github.com/bytom/vapor/crypto/ed25519/chainkd"
chainjson "github.com/bytom/vapor/encoding/json"
)
// SignMsgResp is response for sign message
type SignMsgResp struct {
Signature string `json:"signature"`
DerivedXPub chainkd.XPub `json:"derived_xpub"`
}
func (a *API) signMessage(ctx context.Context, ins struct {
Address string `json:"address"`
Message chainjson.HexBytes `json:"message"`
Password string `json:"password"`
}) Response {
cp, err := a.wallet.AccountMgr.GetLocalCtrlProgramByAddress(ins.Address)
if err != nil {
return NewErrorResponse(err)
}
account, err := a.wallet.AccountMgr.GetAccountByProgram(cp)
if err != nil {
return NewErrorResponse(err)
}
path, err := signers.Path(account.Signer, signers.AccountKeySpace, cp.Change, cp.KeyIndex)
if err != nil {
return NewErrorResponse(err)
}
derivedXPubs := chainkd.DeriveXPubs(account.XPubs, path)
sig, err := a.wallet.Hsm.XSign(account.XPubs[0], path, ins.Message, ins.Password)
if err != nil {
return NewErrorResponse(err)
}
return NewSuccessResponse(SignMsgResp{
Signature: hex.EncodeToString(sig),
DerivedXPub: derivedXPubs[0],
})
}
// VerifyMsgResp is response for verify message
type VerifyMsgResp struct {
VerifyResult bool `json:"result"`
}
func (a *API) verifyMessage(ctx context.Context, ins struct {
Address string `json:"address"`
DerivedXPub chainkd.XPub `json:"derived_xpub"`
Message chainjson.HexBytes `json:"message"`
Signature string `json:"signature"`
}) Response {
sig, err := hex.DecodeString(ins.Signature)
if err != nil {
return NewErrorResponse(err)
}
derivedPK := ins.DerivedXPub.PublicKey()
pubHash := crypto.Ripemd160(derivedPK)
addressPubHash, err := common.NewAddressWitnessPubKeyHash(pubHash, &consensus.ActiveNetParams)
if err != nil {
return NewErrorResponse(err)
}
address := addressPubHash.EncodeAddress()
if address != strings.TrimSpace(ins.Address) {
return NewSuccessResponse(VerifyMsgResp{VerifyResult: false})
}
if ed25519.Verify(ins.DerivedXPub.PublicKey(), ins.Message, sig) {
return NewSuccessResponse(VerifyMsgResp{VerifyResult: true})
}
return NewSuccessResponse(VerifyMsgResp{VerifyResult: false})
}