OSDN Git Service

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