func main() { if len(os.Args) < 3 { fmt.Println("Specify at least two parameters:") fmt.Println(" 1) The base58 encoded bitcoin addres, that the signature was made with") fmt.Println(" 2) The base64 encoded signature for the message...") fmt.Println("If you specify a 3rd parameter - this will be assumed to be the message you want to verify") fmt.Println("If you do not specify a 3rd parameter - the message will be read from stdin") return } ad, er := btc.NewAddrFromString(os.Args[1]) if er != nil { println("Address:", er.Error()) return } nv, btcsig, er := btc.ParseMessageSignature(os.Args[2]) if er != nil { println("ParseMessageSignature:", er.Error()) return } var msg []byte if len(os.Args) < 4 { msg, _ = ioutil.ReadAll(os.Stdin) } else { msg = []byte(os.Args[3]) } hash := make([]byte, 32) 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) } }
func main() { key, _ := hex.DecodeString("040eaebcd1df2df853d66ce0e1b0fda07f67d1cabefde98514aad795b86a6ea66dbeb26b67d7a00e2447baeccc8a4cef7cd3cad67376ac1c5785aeebb4f6441c16") sig, _ := hex.DecodeString("3045022100fe00e013c244062847045ae7eb73b03fca583e9aa5dbd030a8fd1c6dfcf11b1002207d0d04fed8fa1e93007468d5a9e134b0a7023b6d31db4e50942d43a250f4d07c01") msg, _ := hex.DecodeString("3382219555ddbb5b00e0090f469e590ba1eae03c7f28ab937de330aa60294ed6") sta := time.Now() for i := 0; i < CNT; i++ { if !btc.EcdsaVerify(key, sig, msg) { println("Verify error") return } } sto := time.Now() println((sto.UnixNano()-sta.UnixNano())/int64(CNT*1000), "us per ECDSA_Verify") }
func multisig_sign() { tx := raw_tx_from_file(*rawtx) if tx == nil { println("ERROR: Cannot decode the raw multisig transaction") println("Always use -msign <addr> along with -raw multi2sign.txt") return } ad2s, e := btc.NewAddrFromString(*multisign) if e != nil { println("BTC addr:", e.Error()) return } var privkey *ecdsa.PrivateKey //var compr bool for i := range publ_addrs { if publ_addrs[i].Hash160 == ad2s.Hash160 { privkey = new(ecdsa.PrivateKey) pub, e := btc.NewPublicKey(publ_addrs[i].Pubkey) if e != nil { println("PubKey:", e.Error()) return } privkey.PublicKey = pub.PublicKey privkey.D = new(big.Int).SetBytes(priv_keys[i][:]) //compr = compressed_key[i] break } } if privkey == nil { println("You do not know a key for address", ad2s.String()) return } for i := range tx.TxIn { ms, er := btc.NewMultiSigFromScript(tx.TxIn[i].ScriptSig) if er != nil { println("WARNING: Input", i, "- not multisig:", er.Error()) continue } hash := tx.SignatureHash(ms.P2SH(), i, btc.SIGHASH_ALL) //fmt.Println("Input number", i, len(ms.Signatures), " - hash to sign:", hex.EncodeToString(hash)) btcsig := &btc.Signature{HashType: 0x01} btcsig.R, btcsig.S, e = btc.EcdsaSign(privkey, hash) if e != nil { println(e.Error()) return } ms.Signatures = append(ms.Signatures, btcsig) tx.TxIn[i].ScriptSig = ms.Bytes() } // Now re-order the signatures as they shall be: for i := range tx.TxIn { ms, er := btc.NewMultiSigFromScript(tx.TxIn[i].ScriptSig) if er != nil { //println(er.Error()) continue } hash := tx.SignatureHash(ms.P2SH(), i, btc.SIGHASH_ALL) //fmt.Println("Input number", i, " - hash to sign:", hex.EncodeToString(hash)) //fmt.Println(" ... number of signatures:", len(ms.Signatures)) var sigs []*btc.Signature for ki := range ms.PublicKeys { //pk := btc.NewPublicKey(ms.PublicKeys[ki]) //fmt.Println(ki, hex.EncodeToString(ms.PublicKeys[ki])) var sig *btc.Signature for si := range ms.Signatures { if btc.EcdsaVerify(ms.PublicKeys[ki], ms.Signatures[si].Bytes(), hash) { //fmt.Println("Key number", ki, "has signature number", si) sig = ms.Signatures[si] break } } if sig != nil { sigs = append(sigs, sig) } else if *verbose { fmt.Println("WARNING: Key number", ki, "has no matching signature") } if !*allowextramsigns && uint(len(sigs)) >= ms.SigsNeeded { break } } if len(ms.Signatures) > len(sigs) { fmt.Println("WARNING: Some signatures are obsolete and will be removed", len(ms.Signatures), "=>", len(sigs)) } else if len(ms.Signatures) < len(sigs) { fmt.Println("It appears that same key is re-used.", len(sigs)-len(ms.Signatures), "more signatures were added") } ms.Signatures = sigs tx.TxIn[i].ScriptSig = ms.Bytes() } write_tx_file(tx) }
func main() { var msg []byte flag.Parse() if *help || *addr == "" || *sign == "" { flag.PrintDefaults() return } ad, er := btc.NewAddrFromString(*addr) 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) 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) } }