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 }