OSDN Git Service

Merge pull request #15 from Bytom/dev_ci
[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 )
15
16 // SignMsgResp is response for sign message
17 type SignMsgResp struct {
18         Signature   string       `json:"signature"`
19         DerivedXPub chainkd.XPub `json:"derived_xpub"`
20 }
21
22 func (a *API) signMessage(ctx context.Context, ins struct {
23         Address  string `json:"address"`
24         Message  string `json:"message"`
25         Password string `json:"password"`
26 }) Response {
27         cp, err := a.wallet.AccountMgr.GetLocalCtrlProgramByAddress(ins.Address)
28         if err != nil {
29                 return NewErrorResponse(err)
30         }
31
32         account, err := a.wallet.AccountMgr.GetAccountByProgram(cp)
33         if err != nil {
34                 return NewErrorResponse(err)
35         }
36
37         path, err := signers.Path(account.Signer, signers.AccountKeySpace, cp.Change, cp.KeyIndex)
38         if err != nil {
39                 return NewErrorResponse(err)
40         }
41         derivedXPubs := chainkd.DeriveXPubs(account.XPubs, path)
42
43         sig, err := a.wallet.Hsm.XSign(account.XPubs[0], path, []byte(ins.Message), ins.Password)
44         if err != nil {
45                 return NewErrorResponse(err)
46         }
47         return NewSuccessResponse(SignMsgResp{
48                 Signature:   hex.EncodeToString(sig),
49                 DerivedXPub: derivedXPubs[0],
50         })
51 }
52
53 // VerifyMsgResp is response for verify message
54 type VerifyMsgResp struct {
55         VerifyResult bool `json:"result"`
56 }
57
58 func (a *API) verifyMessage(ctx context.Context, ins struct {
59         Address     string       `json:"address"`
60         DerivedXPub chainkd.XPub `json:"derived_xpub"`
61         Message     string       `json:"message"`
62         Signature   string       `json:"signature"`
63 }) Response {
64         sig, err := hex.DecodeString(ins.Signature)
65         if err != nil {
66                 return NewErrorResponse(err)
67         }
68
69         derivedPK := ins.DerivedXPub.PublicKey()
70         pubHash := crypto.Ripemd160(derivedPK)
71         addressPubHash, err := common.NewAddressWitnessPubKeyHash(pubHash, &consensus.ActiveNetParams)
72         if err != nil {
73                 return NewErrorResponse(err)
74         }
75
76         address := addressPubHash.EncodeAddress()
77         if address != strings.TrimSpace(ins.Address) {
78                 return NewSuccessResponse(VerifyMsgResp{VerifyResult: false})
79         }
80
81         if ed25519.Verify(ins.DerivedXPub.PublicKey(), []byte(ins.Message), sig) {
82                 return NewSuccessResponse(VerifyMsgResp{VerifyResult: true})
83         }
84         return NewSuccessResponse(VerifyMsgResp{VerifyResult: false})
85 }