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  }