OSDN Git Service

Hulk did something
[bytom/vapor.git] / api / message.go
diff --git a/api/message.go b/api/message.go
new file mode 100644 (file)
index 0000000..44489be
--- /dev/null
@@ -0,0 +1,86 @@
+package api
+
+import (
+       "context"
+       "encoding/hex"
+       "strings"
+
+       "github.com/vapor/blockchain/signers"
+       "github.com/vapor/common"
+       "github.com/vapor/consensus"
+       "github.com/vapor/crypto"
+       "github.com/vapor/crypto/ed25519"
+       "github.com/vapor/crypto/ed25519/chainkd"
+       chainjson "github.com/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})
+}