github.com/piotrnar/gocoin@v0.0.0-20240512203912-faa0448c5e96/wallet/signmsg.go (about)

     1  package main
     2  
     3  import (
     4  	"encoding/base64"
     5  	"encoding/hex"
     6  	"fmt"
     7  	"io/ioutil"
     8  	"os"
     9  
    10  	"github.com/piotrnar/gocoin/lib/btc"
    11  	"github.com/piotrnar/gocoin/lib/others/ltc"
    12  )
    13  
    14  // sign_message signs either a message or a raw hash.
    15  func sign_message() {
    16  	var hash []byte
    17  	var signkey *btc.PrivateAddr = address_to_key(*signaddr)
    18  	if signkey == nil {
    19  		println("You do not have a private key for", *signaddr)
    20  		return
    21  	}
    22  
    23  	if *signhash != "" {
    24  		hash, er := hex.DecodeString(*signhash)
    25  		if er != nil {
    26  			println("Incorrect content of -hash parameter")
    27  			println(er.Error())
    28  			return
    29  		} else if len(hash) > 0 {
    30  			txsig := new(btc.Signature)
    31  			txsig.HashType = 0x01
    32  			r, s, e := btc.EcdsaSign(signkey.Key, hash)
    33  			if e != nil {
    34  				println(e.Error())
    35  				return
    36  			}
    37  			txsig.R.Set(r)
    38  			txsig.S.Set(s)
    39  			fmt.Println("PublicKey:", hex.EncodeToString(signkey.BtcAddr.Pubkey))
    40  			fmt.Println(hex.EncodeToString(txsig.Bytes()))
    41  			return
    42  		}
    43  	}
    44  
    45  	var msg []byte
    46  	if *message == "" {
    47  		msg, _ = ioutil.ReadAll(os.Stdin)
    48  	} else {
    49  		msg = []byte(*message)
    50  	}
    51  
    52  	hash = make([]byte, 32)
    53  	if litecoin {
    54  		ltc.HashFromMessage(msg, hash)
    55  	} else {
    56  		btc.HashFromMessage(msg, hash)
    57  	}
    58  
    59  	btcsig := new(btc.Signature)
    60  	var sb [65]byte
    61  	sb[0] = 27
    62  	if signkey.IsCompressed() {
    63  		sb[0] += 4
    64  	}
    65  
    66  	r, s, e := btc.EcdsaSign(signkey.Key, hash)
    67  	if e != nil {
    68  		println(e.Error())
    69  		return
    70  	}
    71  	btcsig.R.Set(r)
    72  	btcsig.S.Set(s)
    73  
    74  	rd := btcsig.R.Bytes()
    75  	sd := btcsig.S.Bytes()
    76  	copy(sb[1+32-len(rd):], rd)
    77  	copy(sb[1+64-len(sd):], sd)
    78  
    79  	rpk := btcsig.RecoverPublicKey(hash[:], 0)
    80  	sa := btc.NewAddrFromPubkey(rpk.Bytes(signkey.IsCompressed()), signkey.BtcAddr.Version)
    81  	if sa.Hash160 == signkey.BtcAddr.Hash160 {
    82  		fmt.Println(base64.StdEncoding.EncodeToString(sb[:]))
    83  		return
    84  	}
    85  
    86  	rpk = btcsig.RecoverPublicKey(hash[:], 1)
    87  	sa = btc.NewAddrFromPubkey(rpk.Bytes(signkey.IsCompressed()), signkey.BtcAddr.Version)
    88  	if sa.Hash160 == signkey.BtcAddr.Hash160 {
    89  		sb[0]++
    90  		fmt.Println(base64.StdEncoding.EncodeToString(sb[:]))
    91  		return
    92  	}
    93  	println("Something went wrong. The message has not been signed.")
    94  }