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}) }