def tx_make_input_signature(tx, idx, script, privkey_str, hashcode): """ Sign a single input of a transaction, given the serialized tx, the input index, the output's scriptPubkey, and the hashcode. privkey_str must be a hex-encoded private key TODO: move to virtualchain Return the hex signature. """ pk = virtualchain.BitcoinPrivateKey(str(privkey_str)) pubk = pk.public_key() priv = pk.to_hex() pub = pubk.to_hex() addr = pubk.address() signing_tx = bitcoin.signature_form(tx, idx, script, hashcode) txhash = bitcoin.bin_txhash(signing_tx, hashcode) # sign using uncompressed private key pk_uncompressed_hex, pubk_uncompressed_hex = get_uncompressed_private_and_public_keys( priv) sigb64 = sign_digest(txhash.encode('hex'), priv) # sanity check assert verify_digest(txhash.encode('hex'), pubk_uncompressed_hex, sigb64) sig_r, sig_s = decode_signature(sigb64) sig_bin = ecdsa.util.sigencode_der(sig_r, sig_s, ecdsa.SECP256k1.order) sig = sig_bin.encode('hex') + bitcoin.encode(hashcode, 16, 2) return sig
def sign_donation_tx(tx, i, priv): from bitcoin.main import fast_multiply, decode_privkey, G, inv, N from bitcoin.transaction import der_encode_sig k = sign_k hashcode = btc.SIGHASH_ALL i = int(i) if len(priv) <= 33: priv = btc.safe_hexlify(priv) pub = btc.privkey_to_pubkey(priv) address = btc.pubkey_to_address(pub) signing_tx = btc.signature_form( tx, i, btc.mk_pubkey_script(address), hashcode) msghash = btc.bin_txhash(signing_tx, hashcode) z = btc.hash_to_int(msghash) # k = deterministic_generate_k(msghash, priv) r, y = fast_multiply(G, k) s = inv(k, N) * (z + r * decode_privkey(priv)) % N rawsig = 27 + (y % 2), r, s sig = der_encode_sig(*rawsig) + btc.encode(hashcode, 16, 2) # sig = ecdsa_tx_sign(signing_tx, priv, hashcode) txobj = btc.deserialize(tx) txobj["ins"][i]["script"] = btc.serialize_script([sig, pub]) return btc.serialize(txobj)
def sign_donation_tx(tx, i, priv): from bitcoin.main import fast_multiply, decode_privkey, G, inv, N from bitcoin.transaction import der_encode_sig k = sign_k hashcode = btc.SIGHASH_ALL i = int(i) if len(priv) <= 33: priv = btc.safe_hexlify(priv) pub = btc.privkey_to_pubkey(priv) address = btc.pubkey_to_address(pub) signing_tx = btc.signature_form(tx, i, btc.mk_pubkey_script(address), hashcode) msghash = btc.bin_txhash(signing_tx, hashcode) z = btc.hash_to_int(msghash) # k = deterministic_generate_k(msghash, priv) r, y = fast_multiply(G, k) s = inv(k, N) * (z + r * decode_privkey(priv)) % N rawsig = 27 + (y % 2), r, s sig = der_encode_sig(*rawsig) + btc.encode(hashcode, 16, 2) # sig = ecdsa_tx_sign(signing_tx, priv, hashcode) txobj = btc.deserialize(tx) txobj["ins"][i]["script"] = btc.serialize_script([sig, pub]) return btc.serialize(txobj)
def sign(tx, i, priv, t="default", script="", hashcode=SIGHASH_ALL): i = int(i) #if (not is_python2 and isinstance(re, bytes)) or not re.match('^[0-9a-fA-F]*$', tx): if not re.match('^[0-9a-fA-F]*$', tx): return binascii.unhexlify( custom_sign(safe_hexlify(tx), i, priv, hashcode)) if len(priv) <= 33: priv = b.safe_hexlify(priv) pub = b.privkey_to_pubkey(priv) address = b.pubkey_to_address(pub) if t not in ["atomic_1", "atomic_2"]: script = b.mk_pubkey_script(address) if script == "": error() signing_tx = b.signature_form( tx, i, script, hashcode) #mk_pubkey_scrip needs to be our custom scriptn sig = b.ecdsa_tx_sign(signing_tx, priv, hashcode) txobj = b.deserialize(tx) if t == "atomic_1": txobj["ins"][i]["script"] = b.serialize_script([sig]) if t == "atomic_2": old_sig = txobj["ins"][i]["script"] txobj["ins"][i]["script"] = b.serialize_script([old_sig, sig, 1]) else: txobj["ins"][i]["script"] = b.serialize_script([sig, pub]) return b.serialize(txobj)
def tx_make_input_signature(tx, idx, script, privkey_str, hashcode): """ Sign a single input of a transaction, given the serialized tx, the input index, the output's scriptPubkey, and the hashcode. TODO: move to virtualchain Return the hex signature. """ pk = virtualchain.BitcoinPrivateKey(str(privkey_str)) pubk = pk.public_key() priv = pk.to_hex() pub = pubk.to_hex() addr = pubk.address() signing_tx = bitcoin.signature_form(tx, idx, script, hashcode) txhash = bitcoin.bin_txhash(signing_tx, hashcode) # sign using uncompressed private key pk_uncompressed_hex, pubk_uncompressed_hex = get_uncompressed_private_and_public_keys( priv) sk = ecdsa.SigningKey.from_string(pk_uncompressed_hex.decode('hex'), curve=ecdsa.SECP256k1) sig_bin = sk.sign_digest(txhash, sigencode=ecdsa.util.sigencode_der) # enforce low-s sig_r, sig_s = ecdsa.util.sigdecode_der(sig_bin, ecdsa.SECP256k1.order) if sig_s * 2 >= ecdsa.SECP256k1.order: log.debug("High-S to low-S") sig_s = ecdsa.SECP256k1.order - sig_s sig_bin = ecdsa.util.sigencode_der(sig_r, sig_s, ecdsa.SECP256k1.order) # sanity check vk = ecdsa.VerifyingKey.from_string( pubk_uncompressed_hex[2:].decode('hex'), curve=ecdsa.SECP256k1) assert vk.verify_digest(sig_bin, txhash, sigdecode=ecdsa.util.sigdecode_der ), "Failed to verify signature ({}, {})".format( sig_r, sig_s) sig = sig_bin.encode('hex') + bitcoin.encode(hashcode, 16, 2) return sig
def sign(tx, i, priv, t="default", script="", hashcode=SIGHASH_ALL): i = int(i) #if (not is_python2 and isinstance(re, bytes)) or not re.match('^[0-9a-fA-F]*$', tx): if not re.match('^[0-9a-fA-F]*$', tx): return binascii.unhexlify(custom_sign(safe_hexlify(tx), i, priv, hashcode)) if len(priv) <= 33: priv = b.safe_hexlify(priv) pub = b.privkey_to_pubkey(priv) address = b.pubkey_to_address(pub) if t not in ["atomic_1", "atomic_2"]: script=b.mk_pubkey_script(address) if script=="": error() signing_tx = b.signature_form(tx, i, script, hashcode)#mk_pubkey_scrip needs to be our custom scriptn sig = b.ecdsa_tx_sign(signing_tx, priv, hashcode) txobj = b.deserialize(tx) if t=="atomic_1": txobj["ins"][i]["script"] = b.serialize_script([sig]) if t=="atomic_2": old_sig = txobj["ins"][i]["script"] txobj["ins"][i]["script"] = b.serialize_script([old_sig, sig, 1]) else: txobj["ins"][i]["script"] = b.serialize_script([sig, pub]) return b.serialize(txobj)