github.com/aergoio/aergo@v1.3.1/account/key/sign.go (about)

     1  package key
     2  
     3  import (
     4  	"encoding/binary"
     5  
     6  	"github.com/aergoio/aergo/types"
     7  	"github.com/btcsuite/btcd/btcec"
     8  	sha256 "github.com/minio/sha256-simd"
     9  )
    10  
    11  //Sign return sign with key in the store
    12  func (ks *Store) Sign(addr Address, pass string, hash []byte) ([]byte, error) {
    13  	k, err := ks.getKey(addr, pass)
    14  	if k == nil {
    15  		return nil, err
    16  	}
    17  	key, _ := btcec.PrivKeyFromBytes(btcec.S256(), k)
    18  	sign, err := key.Sign(hash)
    19  	if err != nil {
    20  		return nil, err
    21  	}
    22  	return sign.Serialize(), nil
    23  }
    24  
    25  func SignTx(tx *types.Tx, key *aergokey) error {
    26  	hash := CalculateHashWithoutSign(tx.Body)
    27  	sign, err := key.Sign(hash)
    28  	if err != nil {
    29  		return err
    30  	}
    31  	tx.Body.Sign = sign.Serialize()
    32  	tx.Hash = tx.CalculateTxHash()
    33  	return nil
    34  }
    35  
    36  //SignTx return transaction which signed with unlocked key. if requester is nil, requester is assumed to tx.Account
    37  func (ks *Store) SignTx(tx *types.Tx, requester []byte) error {
    38  	addr := tx.Body.Account
    39  	if requester != nil {
    40  		addr = requester
    41  	}
    42  	keyPair, exist := ks.unlocked[types.EncodeAddress(addr)]
    43  	if !exist {
    44  		return types.ErrShouldUnlockAccount
    45  	}
    46  	return SignTx(tx, keyPair.key)
    47  }
    48  
    49  //VerifyTx return result to varify sign
    50  func VerifyTx(tx *types.Tx) error {
    51  	return VerifyTxWithAddress(tx, tx.Body.Account)
    52  }
    53  
    54  func VerifyTxWithAddress(tx *types.Tx, address []byte) error {
    55  	txBody := tx.Body
    56  	hash := CalculateHashWithoutSign(txBody)
    57  	sign, err := btcec.ParseSignature(txBody.Sign, btcec.S256())
    58  	if err != nil {
    59  		return err
    60  	}
    61  	pubkey, err := btcec.ParsePubKey(address, btcec.S256())
    62  	if err != nil {
    63  		return err
    64  	}
    65  	if !sign.Verify(hash, pubkey) {
    66  		return types.ErrSignNotMatch
    67  	}
    68  	return nil
    69  }
    70  
    71  //VerifyTx return result to varify sign
    72  func (ks *Store) VerifyTx(tx *types.Tx) error {
    73  	return VerifyTx(tx)
    74  }
    75  
    76  //CalculateHashWithoutSign return hash of tx without sign field
    77  func CalculateHashWithoutSign(txBody *types.TxBody) []byte {
    78  	h := sha256.New()
    79  	binary.Write(h, binary.LittleEndian, txBody.Nonce)
    80  	h.Write(txBody.Account)
    81  	h.Write(txBody.Recipient)
    82  	h.Write(txBody.Amount)
    83  	h.Write(txBody.Payload)
    84  	binary.Write(h, binary.LittleEndian, txBody.GasLimit)
    85  	h.Write(txBody.GasPrice)
    86  	binary.Write(h, binary.LittleEndian, txBody.Type)
    87  	h.Write(txBody.ChainIdHash)
    88  	return h.Sum(nil)
    89  }