func main() { var msg []byte flag.Parse() if *help || *addr == "" || *sign == "" { flag.PrintDefaults() return } ad, er := btc.NewAddrFromString(*addr) if !*litecoin && ad != nil && ad.Version == ltc.AddrVerPubkey(false) { *litecoin = true } if er != nil { println("Address:", er.Error()) flag.PrintDefaults() return } nv, btcsig, er := btc.ParseMessageSignature(*sign) if er != nil { println("ParseMessageSignature:", er.Error()) return } if *mess != "" { msg = []byte(*mess) } else if *mfil != "" { msg, er = ioutil.ReadFile(*mfil) if er != nil { println(er.Error()) return } } else { fmt.Println("Enter the message:") msg, _ = ioutil.ReadAll(os.Stdin) } if *unix { fmt.Println("Enforcing Unix text format") msg = []byte(strings.Replace(string(msg), "\r", "", -1)) } hash := make([]byte, 32) if *litecoin { ltc.HashFromMessage(msg, hash) } else { btc.HashFromMessage(msg, hash) } compressed := false if nv >= 31 { //println("compressed key") nv -= 4 compressed = true } pub := btcsig.RecoverPublicKey(hash[:], int(nv-27)) if pub != nil { pk := pub.Bytes(compressed) ok := btc.EcdsaVerify(pk, btcsig.Bytes(), hash) if ok { sa := btc.NewAddrFromPubkey(pk, ad.Version) if ad.Hash160 != sa.Hash160 { fmt.Println("BAD signature for", ad.String()) os.Exit(1) } else { fmt.Println("Good signature for", sa.String()) } } else { println("BAD signature") os.Exit(1) } } else { println("BAD, BAD, BAD signature") os.Exit(1) } }
// this function signs either a message or a raw transaction hash func sign_message() { var hash []byte if *signhash != "" { var er error hash, er = hex.DecodeString(*signhash) if er != nil { println("Incorrect content of -hash parameter") println(er.Error()) return } } ad2s, e := btc.NewAddrFromString(*signaddr) if e != nil { println(e.Error()) if *signhash != "" { println("Always use -sign <addr> along with -hash <msghash>") } return } var privkey []byte var compr bool for i := range publ_addrs { if publ_addrs[i].Hash160 == ad2s.Hash160 { privkey = priv_keys[i][:] compr = compressed_key[i] // Sign raw hash? if hash != nil { txsig := new(btc.Signature) txsig.HashType = 0x01 r, s, e := btc.EcdsaSign(privkey, hash) if e != nil { println(e.Error()) return } txsig.R.Set(r) txsig.S.Set(s) fmt.Println("PublicKey:", hex.EncodeToString(publ_addrs[i].Pubkey)) fmt.Println(hex.EncodeToString(txsig.Bytes())) return } break } } if privkey == nil { println("You do not have a private key for", ad2s.String()) return } var msg []byte if *message == "" { msg, _ = ioutil.ReadAll(os.Stdin) } else { msg = []byte(*message) } hash = make([]byte, 32) if litecoin { ltc.HashFromMessage(msg, hash) } else { btc.HashFromMessage(msg, hash) } btcsig := new(btc.Signature) var sb [65]byte sb[0] = 27 if compr { sb[0] += 4 } r, s, e := btc.EcdsaSign(privkey, hash) if e != nil { println(e.Error()) return } btcsig.R.Set(r) btcsig.S.Set(s) rd := btcsig.R.Bytes() sd := btcsig.S.Bytes() copy(sb[1+32-len(rd):], rd) copy(sb[1+64-len(sd):], sd) rpk := btcsig.RecoverPublicKey(hash[:], 0) sa := btc.NewAddrFromPubkey(rpk.Bytes(compr), ad2s.Version) if sa.Hash160 == ad2s.Hash160 { fmt.Println(base64.StdEncoding.EncodeToString(sb[:])) return } rpk = btcsig.RecoverPublicKey(hash[:], 1) sa = btc.NewAddrFromPubkey(rpk.Bytes(compr), ad2s.Version) if sa.Hash160 == ad2s.Hash160 { sb[0]++ fmt.Println(base64.StdEncoding.EncodeToString(sb[:])) return } println("Something went wrong. The message has not been signed.") }
// this function signs either a message or a raw hash func sign_message() { var hash []byte var signkey *btc.PrivateAddr signkey = address_to_key(*signaddr) if signkey == nil { println("You do not have a private key for", *signaddr) return } if *signhash != "" { hash, er := hex.DecodeString(*signhash) if er != nil { println("Incorrect content of -hash parameter") println(er.Error()) return } else if len(hash) > 0 { txsig := new(btc.Signature) txsig.HashType = 0x01 r, s, e := btc.EcdsaSign(signkey.Key, hash) if e != nil { println(e.Error()) return } txsig.R.Set(r) txsig.S.Set(s) fmt.Println("PublicKey:", hex.EncodeToString(signkey.BtcAddr.Pubkey)) fmt.Println(hex.EncodeToString(txsig.Bytes())) return } } var msg []byte if *message == "" { msg, _ = ioutil.ReadAll(os.Stdin) } else { msg = []byte(*message) } hash = make([]byte, 32) if litecoin { ltc.HashFromMessage(msg, hash) } else { btc.HashFromMessage(msg, hash) } btcsig := new(btc.Signature) var sb [65]byte sb[0] = 27 if signkey.IsCompressed() { sb[0] += 4 } r, s, e := btc.EcdsaSign(signkey.Key, hash) if e != nil { println(e.Error()) return } btcsig.R.Set(r) btcsig.S.Set(s) rd := btcsig.R.Bytes() sd := btcsig.S.Bytes() copy(sb[1+32-len(rd):], rd) copy(sb[1+64-len(sd):], sd) rpk := btcsig.RecoverPublicKey(hash[:], 0) sa := btc.NewAddrFromPubkey(rpk.Bytes(signkey.IsCompressed()), signkey.BtcAddr.Version) if sa.Hash160 == signkey.BtcAddr.Hash160 { fmt.Println(base64.StdEncoding.EncodeToString(sb[:])) return } rpk = btcsig.RecoverPublicKey(hash[:], 1) sa = btc.NewAddrFromPubkey(rpk.Bytes(signkey.IsCompressed()), signkey.BtcAddr.Version) if sa.Hash160 == signkey.BtcAddr.Hash160 { sb[0]++ fmt.Println(base64.StdEncoding.EncodeToString(sb[:])) return } println("Something went wrong. The message has not been signed.") }