Example #1
0
def deriveAddress(privateKey, compressed, blockChain):
    """
    Turn a private key into an address.
    privateKey must be in binary format.
    """
    privKey = CECKey()
    privKey.set_secretbytes(privateKey)
    privKey.set_compressed(compressed)
    publicKey = privKey.get_pubkey()
    hash1 = hashlib.sha256(publicKey).digest()

    ripemd160 = hashlib.new('ripemd160')
    ripemd160.update(hash1)
    ripe = ripemd160.digest()

    if blockChain == 'bitcoin':
        ripeWithNetworkPrefix = b'\x00' + ripe
    elif blockChain.startswith('testnet'):
        ripeWithNetworkPrefix = b'\x6F' + ripe
    else:
        raise Exception("'blockChain' parameter is not set correctly")

    checksum = hashlib.sha256(
        hashlib.sha256(ripeWithNetworkPrefix).digest()).digest()[:4]
    binaryBitcoinAddress = ripeWithNetworkPrefix + checksum
    numberOfZeroBytesOnBinaryBitcoinAddress = 0
    while binaryBitcoinAddress[0:1] == b'\x00':  # while the first byte is null
        numberOfZeroBytesOnBinaryBitcoinAddress += 1
        binaryBitcoinAddress = binaryBitcoinAddress[
            1:]  # take off the first byte
    base58encoded = encode(binaryBitcoinAddress)  # encode into base58
    return "1" * numberOfZeroBytesOnBinaryBitcoinAddress + base58encoded
Example #2
0
def construct_auth_wrapper_truncated(metadata: AddressMetadata,
                                     keypair: CECKey):
    """Return the complete AuthWrapper object and the digest of the metadata."""
    raw_metadata = metadata.SerializeToString()
    signature, digest = sign_metadata(raw_metadata, keypair)
    public_key = keypair.get_pubkey()
    auth_wrapper = AuthWrapper(pub_key=public_key,
                               payload_digest=digest,
                               scheme=1,
                               signature=signature)
    return auth_wrapper, digest
Example #3
0
def pk_scriptdecompress(pk):
    # https://github.com/bitcoin/bitcoin/blob/5961b23898ee7c0af2626c46d5d70e80136578d3/src/compressor.cpp#L118
    xpk = bytes(bytearray([pk[0] - 2]) + pk[1:])

    pk = CPubKey(xpk)
    cec = CECKey()
    cec.set_compressed(True)
    res = cec.set_pubkey(pk)
    if res is None:
        raise Exception(ssl_get_error())
    cec.set_compressed(False)
    pubkey = cec.get_pubkey()
    return CPubKey(pubkey, _cec_key=cec)
Example #4
0
def generate_random_keypair():
    """Generate a random bitcoin address, a ECDSA keypair."""

    # Generate keys
    secret = os.urandom(16)
    keypair = CECKey()
    keypair.set_compressed(True)
    keypair.set_secretbytes(secret)
    public_key = keypair.get_pubkey()

    # Generate key addr
    key_addr = str(P2PKHBitcoinAddress.from_pubkey(public_key))
    return key_addr, keypair
Example #5
0
def get_btc_address():
    '''return new btc address and save secret used to generate address'''
    # Generate & Save random address and secret
    secret = base + '_' + str(randint(100000, 9999999999))
    h = hashlib.sha256(secret).digest()
    # key = CBitcoinSecret.from_secret_bytes(h)
    key = CECKey()
    key.set_secretbytes(h)
    address = P2PKHBitcoinAddress.from_pubkey(key.get_pubkey())

    cred = {"Address": address, "Secret": secret}
    # Save generated secret key
    with open("config_keys.txt", "a") as f:
        f.write(str(cred) + '\n')

    return str(address), key, secret
Example #6
0
    def sign(self, template, privateKeys):

        # convert all of the privateKeys to a standard binary format for us to work with
        privateKeysBinary = convertPrivateKeysToBinaryFormat(
            privateKeys, self.blockChain)
        """
        keyCollection is a dictionary where the key of the dict is an address and the value is a 
        tuple with (privKey, compressed)
            where `privKey` is the private key in binary format
            and `compressed` is a bool indicating whether or not the corresponding public key is compressed.
        """
        keyCollection = generateKeyCollection(privateKeysBinary,
                                              self.blockChain)

        if not 'inputs' in template:
            raise Exception(
                "This template has no inputs. There is nothing to sign.")

        for inputIndex in range(len(
                template['inputs'])):  # For each input in the template...
            for signatureIndex in range(
                    len(template['inputs'][inputIndex]
                        ['signatures'])):  # For each signature in the input...
                address = template['inputs'][inputIndex]['signatures'][
                    signatureIndex][
                        'address']  # Get the address out of the template to make this code easier to read
                if address in keyCollection:  # if we have the private key needed for this signature..
                    privateKeyBinary, compressed = keyCollection[address]
                    privKey = CECKey(
                    )  # This CECKey object type is from the python-bitcoinlib library
                    privKey.set_secretbytes(privateKeyBinary)
                    privKey.set_compressed(compressed)
                    hash_to_sign = template['inputs'][inputIndex][
                        'signatures'][signatureIndex]['hash_to_sign']
                    signature = privKey.sign(unhexlify(hash_to_sign))

                    # We now have the signature. Let's put the signature and the pubkey into the template.
                    template['inputs'][inputIndex]['signatures'][
                        signatureIndex]['signature'] = hexlify(
                            signature).decode('ascii')
                    template['inputs'][inputIndex]['signatures'][
                        signatureIndex]['public_key'] = hexlify(
                            privKey.get_pubkey()).decode('ascii')
        return template
Example #7
0
BASE_URL_B = "http://0.0.0.0:8081"
bitcoin.SelectParams("regtest")

# Init Bitcoin RPC
rpc_user = "******"
rpc_password = "******"
rpc_connection = AuthServiceProxy("http://%s:%[email protected]:18443" %
                                  (rpc_user, rpc_password))

# Generate keys
secret = os.urandom(16)
keypair = CECKey()
keypair.set_compressed(True)
keypair.set_secretbytes(secret)
private_key = keypair.get_privkey()
public_key = keypair.get_pubkey()

# Generate key addr
key_addr = str(P2PKHBitcoinAddress.from_pubkey(public_key))

# Construct Payload
header = Header(name="Something wicked", value="this way comes")
entry = Entry(headers=[header], entry_data=b'This gonna be so f*****g fast')
timestamp = int(time())
metadata = AddressMetadata(timestamp=timestamp, ttl=3000, entries=[entry])

# Sign
raw_metadata = metadata.SerializeToString()
digest = sha256(raw_metadata).digest()
signature, _ = keypair.sign_compact(digest)
#my_netcode = "mainnet"
bitcoin.SelectParams(my_netcode)

my_params = bitcoin.params
my_privkey_prefix = bytes(bytearray([my_params.BASE58_PREFIXES['SECRET_KEY']]))
my_pubaddr_prefix = bytes(bytearray([my_params.BASE58_PREFIXES['PUBKEY_ADDR']]))

# Create the (in)famous correct brainwallet secret key.
h = hashlib.sha256(b'correct horse battery staple').digest()
seckey = CBitcoinSecret.from_secret_bytes(h)

cec_key = CECKey()
cec_key.set_secretbytes(h)

print("Secret key  hex: ", seckey.hex());
btc_addr = encoding.public_pair_to_bitcoin_address(cec_key.get_pubkey(), address_prefix=my_pubaddr_prefix)
print("Bitcoin address: ", btc_addr)

# Create a redeemScript, with public key and checksig op code (0xac)
# Similar to a scriptPubKey the redeemScript must be satisfied for the funds to be spent.
txin_redeemScript = CScript([seckey.pub, OP_CHECKSIG])
print("Public key of address #", seckey.pub.hex())
# 0x21 + secret.pub + OP_CHECKSIG (0x87)
print("Tx-in Redeem Script: ", b2x(txin_redeemScript))

# Create the magic P2SH scriptPubKey format from that redeemScript. You should
# look at the CScript.to_p2sh_scriptPubKey() function in bitcoin.core.script to
# understand what's happening, as well as read BIP16:
# https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki
txin_scriptPubKey = txin_redeemScript.to_p2sh_scriptPubKey()
print("Redeem script hash160 #", b2x(bitcoin.core.Hash160(txin_redeemScript)))
cec_key.set_secretbytes(bitcoin.core.x(my_secret_exp))

print("Private Key dec: ", random_nbr)
print("Private Key hex: ", my_secret_exp)
privkey_wif = encoding.secret_exponent_to_wif(eval('0x' + my_secret_exp),
                                              wif_prefix=my_privkey_prefix)
print("Private key WIF: ", privkey_wif)
privkey_wif = encoding.secret_exponent_to_wif(eval('0x' + my_secret_exp),
                                              False,
                                              wif_prefix=my_privkey_prefix)
print("   uncompressed: ", privkey_wif)

cec_key.set_compressed(True)

print()
pubkey_pair = encoding.sec_to_public_pair(cec_key.get_pubkey())
print("Public key pair: ", pubkey_pair)

(pub_key_x, pub_key_y) = pubkey_pair
compressed_indicator = True if (pub_key_y % 2) == 0 else False
print("Public key y parity? ", 'even' if compressed_indicator else 'odd')

#print("Private key hexlify: ", hexlify(cec_key.get_privkey()))
print("Public  key    hex: ", bitcoin.core.b2x(cec_key.get_pubkey()))
cec_key.set_compressed(False)
print("      uncompressed: ", bitcoin.core.b2x(cec_key.get_pubkey()))

addr_compressed = encoding.public_pair_to_bitcoin_address(
    pubkey_pair, True, address_prefix=my_pubaddr_prefix)
addr_uncompressed = encoding.public_pair_to_bitcoin_address(
    pubkey_pair, False, address_prefix=my_pubaddr_prefix)
Example #10
0
def preimage_client():

    # Setup socket
    context = zmq.Context()
    socket = context.socket(zmq.REQ)
    socket.connect("ipc:///tmp/TumbleBit_tx")

    # Setup keys
    data = open("./keys/EC_private_test.bin", "rb").read()
    alice = CECKey()
    alice.set_privkey(data)

    data = open("./keys/EC_private_test2.bin", "rb").read()
    bob = CECKey()
    bob.set_privkey(data)

    # Setup Images & Hashes
    preimages = [(sha256("test" + str(x)))[:16] for x in range(1, 16)]
    hashes = [ripemd160(x) for x in preimages]

    serial_hashes = ""
    for i in range(len(hashes)):
        serial_hashes += hashes[i]

    serial_preimages = ""
    for i in range(len(preimages)):
        serial_preimages += preimages[i]

    # Phase 1 -- Setup
    msg = [
        b"setup_preimage",
        alice.get_pubkey(),
        bob.get_pubkey(), serial_hashes
    ]
    socket.send_multipart(msg)

    reply = socket.recv_multipart()
    redeem_script = reply[0]
    fund_tx = reply[1]

    # print "Done with PHASE1"

    # Phase 2 -- Get TX sighash
    address = "mweZnPjTeyGHVS2d3SojAGujY36sd3wQ49"

    msg = [b"get_tx", redeem_script, address, fund_tx]
    socket.send_multipart(msg)

    reply = socket.recv_multipart()
    tx = reply[0]
    sighash = reply[1]

    # print "Done with PHASE2"

    # Sign
    alice_sig = alice.sign(sighash)  # Used for refund
    bob_sig = bob.sign(sighash)  # Used for redeem

    # Phase 3 -- Spending tx
    msg = [b"spend_preimage", serial_preimages, bob_sig, tx, redeem_script]
    socket.send_multipart(msg)

    reply = socket.recv()
    spending_tx = reply

    # print "Done with PHASE3"

    # Phase 4 -- Refunding tx
    msg = [b"send_refund_tx", alice_sig, tx, redeem_script]
    socket.send_multipart(msg)

    reply = socket.recv()
    refund_tx = reply

    # print "Done with PHASE4"

    print "PREIMAGE: Spending tx is: %s" % binascii.hexlify(spending_tx)
    print "\n\n"
    print "PREIMAGE: Refund tx is: %s" % binascii.hexlify(refund_tx)

    # Clean up
    socket.close()
    context.term()
Example #11
0
def escrow_example():
    '''
    P2SH Address:
    2MzDcMCxcZnNnAZzFqsyuyZ4vuNCB6Qjvxd

    Funding tx:
    db1b045ea09581a51a5b5f851e7e3a64542123885e071fd6d4ff7428703a2504
    Spending tx nlocktime = 30:

    Refund TX:
    23daa9d3868255bab14d5dfe46f7fb787aaef49b17d0014902e36e4491440311
    '''
    SelectParams('testnet')

    tx = TX(test=True)

    print "=" * 50
    print("=" * 10 + "  ESCROW EXAMPLE")
    print "=" * 50 + "\n"

    # Setup keys
    data = open("./keys/EC_private_test.bin", "rb").read()
    alice = CECKey()
    alice.set_privkey(data)

    data = open("./keys/EC_private_test2.bin", "rb").read()
    bob = CECKey()
    bob.set_privkey(data)

    amount = 0.001  # In bitcoins

    redeem_script, p2sh_address = tx.setup_escrow(alice.get_pubkey(),
                                                  bob.get_pubkey(), amount, 30)

    # Funding tx id + redeeming bitcoin address
    funding_tx = "db1b045ea09581a51a5b5f851e7e3a6" + \
                 "4542123885e071fd6d4ff7428703a2504"
    address = "mweZnPjTeyGHVS2d3SojAGujY36sd3wQ49"

    # Note: Make sure pick correct vout - default is 0
    tx2, sighash = tx.get_tx(redeem_script,
                             address,
                             amount - 0.0001,
                             funding_tx,
                             20,
                             vout=1)

    # Sign
    alice_sig = alice.sign(sighash)
    bob_sig = bob.sign(sighash)

    print "P2SH %s" % p2sh_address
    print "Redeem script:\n%s\n" % binascii.hexlify(redeem_script)
    print "Redeem script Hash:\n%s\n" % binascii.hexlify(
        sha256(sha256(redeem_script)))

    redeem_tx = tx.spend_escrow(alice_sig, bob_sig, tx2, redeem_script)
    print "REDEEM TX is:\n%s\n" % binascii.hexlify(redeem_tx)

    refunded_tx = tx.refund_tx(alice_sig, tx2, redeem_script)
    print "REFUND TX is:\n%s\n" % binascii.hexlify(refunded_tx)
    print "=" * 50 + "\n\n"
Example #12
0
def preimage_example():
    '''
    Refund test:
    P2SH Address:
    2MscMqe6Ag5NmZKCsELKDPJRJWnPR6GGD9B

    Funding tx:
    d49038dd9141f77c230208fe1cdd24937c61a1b63f40b8a87ab50971970ac2b7
    Spending tx nlocktime = 10:

    Refund TX:
    f77245db1c81b49c72464e61e3738a60f6e21c0bb744f8729def4a9877082e73

    Preimage test:
    P2SH Address:
    2NEFkj2gMZguX3QtFp31XKfnRdUpEoXTVNv

    Funding tx:
    91e6953fdcc15687ffc54e76d55ed4b92ef60cd483e0633ef226f7509513c7d2
    Spending tx nlocktime = 10:

    Spending TX:
    e006b7d1566045e136c13446114e51513f1453a7e2eb7e534d04bd7dc09532f7

    Other:
    1/
    P2SH Address: 2N6uq4bLT6UTqqxNo7YQ5TyRrFVWSRAFyxT
    Funding TX:
    8f717d1babd532b337cb80e743844f270129c744ebfc1ff7f6b43c1d855adc75
    Spending TX:
    b9cfbbdef00319db95c0beae8f73de4f7639eacc9b2006a70d64b494673921eb

    '''
    SelectParams('testnet')

    tx = TX(test=True)

    print "=" * 50
    print("=" * 10 + "  PREIMAGE EXAMPLE")
    print "=" * 50 + "\n"

    # Setup keys
    data = open("./keys/EC_private_test.bin", "rb").read()
    alice = CECKey()
    alice.set_privkey(data)

    data = open("./keys/EC_private_test2.bin", "rb").read()
    bob = CECKey()
    bob.set_privkey(data)

    preimages = [sha256("test" + str(x)) for x in range(1, 16)]
    hashes = [ripemd160(x) for x in preimages]

    # Serialize hashes
    serial_hashes = ""
    for i in range(len(hashes)):
        serial_hashes += hashes[i]
    tx.get_hashes_from_serial(serial_hashes, 15, 20)

    amount = 0.001  # In bitcoins
    redeem_script, funding_tx = tx.setup_preimage(alice.get_pubkey(),
                                                  bob.get_pubkey(), hashes,
                                                  amount, 10)

    # Funding tx id + redeeming bitcoin address
    funding_tx = "8f717d1babd532b337cb80e743844f270" + \
                 "129c744ebfc1ff7f6b43c1d855adc75"
    address = "mweZnPjTeyGHVS2d3SojAGujY36sd3wQ49"

    # Note: Make sure pick correct vout - default is 0
    tx2, sighash = tx.get_tx(redeem_script, address, amount - 0.0001,
                             funding_tx, 5)

    # Sign
    alice_sig = alice.sign(sighash)
    bob_sig = bob.sign(sighash)

    redeem_tx = tx.spend_preimage(preimages, bob_sig, tx2, redeem_script)
    print "REDEEM TX is:\n%s\n" % binascii.hexlify(redeem_tx)

    refunded_tx = tx.refund_tx(alice_sig, tx2, redeem_script)
    print "REFUND TX is:\n%s\n" % binascii.hexlify(refunded_tx)

    serial_keys = tx.get_keys_from_tx(redeem_tx)
    # print "SERIAL KEYS:\n%s\n" % binascii.hexlify(serial_keys)

    # # write to file to test in c++
    # target = open("keys.bin", 'wb')
    # target.write(serial_keys)
    # target.close()

    print "=" * 50 + "\n\n"
Example #13
0
def escrow_client():
    # Setup socket
    context = zmq.Context()
    socket = context.socket(zmq.REQ)
    socket.connect("ipc:///tmp/TumbleBit_tx")

    # Setup keys
    data = open("./keys/EC_private_test.bin", "rb").read()
    alice = CECKey()
    alice.set_privkey(data)

    data = open("./keys/EC_private_test2.bin", "rb").read()
    bob = CECKey()
    bob.set_privkey(data)

    # Phase 1 -- Setup
    msg = [b"setup_escrow", alice.get_pubkey(), bob.get_pubkey()]
    socket.send_multipart(msg)

    reply = socket.recv_multipart()
    redeem_script = reply[0]
    fund_tx = reply[1]

    # print "Done with PHASE1"

    # Phase 2 -- Get TX sighash
    address = "mweZnPjTeyGHVS2d3SojAGujY36sd3wQ49"

    msg = [b"get_tx", redeem_script, address, fund_tx]
    socket.send_multipart(msg)

    reply = socket.recv_multipart()
    tx = reply[0]
    sighash = reply[1]

    # print "Done with PHASE2"

    # Sign
    alice_sig = alice.sign(sighash)
    bob_sig = bob.sign(sighash)

    # Phase 3 -- Spending tx
    msg = [b"spend_escrow", alice_sig, bob_sig, tx, redeem_script]
    socket.send_multipart(msg)

    reply = socket.recv()
    spending_tx = reply

    # print "Done with PHASE3"

    # Phase 4 -- Refunding tx
    msg = [b"send_refund_tx", alice_sig, tx, redeem_script]
    socket.send_multipart(msg)

    reply = socket.recv()
    refund_tx = reply

    # print "Done with PHASE4"

    print "ESCROW: Spending tx is: %s" % binascii.hexlify(spending_tx)
    print "\n\n"
    print "ESCROW: Refund tx is: %s" % binascii.hexlify(refund_tx)

    # Clean up
    socket.close()
    context.term()
Example #14
0
class EC(object):
    """
    Wrapper around python-bitcoinlib's CECKey class
    """
    def __init__(self):
        self.key = CECKey()
        self.init = False
        self.is_private = False

    def load_public_key(self, key_path):
        with open(key_path, 'rb') as f:
            temp_key = f.read()

            self.key.set_pubkey(temp_key)
            self.init = True

    def load_private_key(self, key_path):
        with open(key_path, 'rb') as f:
            temp_key = f.read()
            self.key.set_privkey(temp_key)

            self.init = True
            self.is_private = True

    def get_pubkey(self):
        return self.key.get_pubkey()

    def sign(self, msg):
        if self.init:
            if self.is_private:
                sig = self.key.sign(msg)
                return sig
            else:
                raise ValueError('Signing requires a private key')
        else:
            raise ValueError('No key is loaded.')

    def verify(self, msg, sig):
        if self.init:
            return self.key.verify(msg, sig) == 1
        else:
            raise ValueError('No key is loaded.')

    def serialize_sig(self, sig):
        """
        Takes in a signature in DER format and returns a byte
        string of R + S that should be 64 bytes in length
        """

        sig_struct = ECDSA_SIG_st()
        _ssl.d2i_ECDSA_SIG(ctypes.byref(ctypes.pointer(sig_struct)),
                           ctypes.byref(ctypes.c_char_p(sig)), len(sig))

        r = BNToBin(sig_struct.r, 32)
        s = BNToBin(sig_struct.s, 32)

        return r + s

    def deserialize_sig(self, serial_sig):
        """
        Converts a serial signature (R + S) into DER format

        Arguments:
            serial_sig (bytes): A 64 byte string that represents R and S where each
                                is 32 bytes

        Returns:
            A signature in der format

        Raises:
            Value error if serial sig is not 64 bytes
        """
        if len(serial_sig) == 64:
            sig_struct = ECDSA_SIG_st()

            r = BinToBN(serial_sig[:32])
            s = BinToBN(serial_sig[32:])

            sig_struct.r = r
            sig_struct.s = s

            derlen = _ssl.i2d_ECDSA_SIG(ctypes.pointer(sig_struct), 0)
            if derlen == 0:
                _ssl.ECDSA_SIG_free(sig_struct)
                return None

            der_sig = ctypes.create_string_buffer(derlen)
            _ssl.i2d_ECDSA_SIG(ctypes.pointer(sig_struct),
                               ctypes.byref(ctypes.pointer(der_sig)))
            return der_sig.raw
        else:
            raise ValueError('Serial sig has to be 64 bytes.')