github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/api/message.go (about) 1 package api 2 3 import ( 4 "context" 5 "crypto/ed25519" 6 "encoding/hex" 7 "strings" 8 9 "github.com/bytom/bytom/blockchain/signers" 10 "github.com/bytom/bytom/common" 11 "github.com/bytom/bytom/consensus" 12 "github.com/bytom/bytom/crypto" 13 "github.com/bytom/bytom/crypto/ed25519/chainkd" 14 chainjson "github.com/bytom/bytom/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 }