def new_commitment_tx(node, current_channel, cost, secret_hash):

    remote_peer = current_channel.peer

    # Create input using the output from the funding tx
    tx_in = TxIn(bytes.fromhex(current_channel.funding_tx.id()), 0)

    # Create 3 outputs. 1 to nodeA and 1 to nodeB and 1 to an HTLC script
    script_1 = p2pkh_script(decode_base58(node.address))
    tx_out_1 = TxOut(amount=current_channel.local_amt - cost,
                     script_pubkey=script_1)

    script_2 = p2pkh_script(decode_base58(remote_peer.btc_addr.decode()))
    tx_out_2 = TxOut(amount=current_channel.remote_amt, script_pubkey=script_2)

    #script_3 HTLC
    script_3 = Script([
        99, 168, secret_hash, 136, 118, 169,
        hash160(remote_peer.public_key.sec()), 103,
        encode_varint(1000), 177, 117, 118, 169,
        hash160(node.public_key.sec()), 104, 136, 172
    ])
    tx_out_3 = TxOut(amount=cost, script_pubkey=script_3)

    # Construct the commitment tx object
    commitment_tx = Tx(1, [tx_in], [tx_out_1, tx_out_2, tx_out_3], 0, True)

    #sign it
    commitment_tx.tx_ins[0].script_sig = get_script_sig(
        commitment_tx, node.private_key)

    return commitment_tx
Example #2
0
 def child(self, index, hardened=False):
     if index >= 0x80000000:
         raise ValueError('child number should always be less than 2^31')
     sec = self.private_key.point.sec()
     fingerprint = hash160(sec)[:4]
     if hardened:
         index += 0x80000000
         pk = self.private_key.secret.to_bytes(32, 'big')
         data = b'\x00' + pk + index.to_bytes(4, 'big')
         raw = HMAC(key=self.chain_code, msg=data,
                    digestmod=sha512).digest()
     else:
         data = sec + index.to_bytes(4, 'big')
         raw = HMAC(key=self.chain_code, msg=data,
                    digestmod=sha512).digest()
     secret = (int.from_bytes(raw[:32], 'big') +
               self.private_key.secret) % N
     private_key = PrivateKey(secret=secret, compressed=True)
     chain_code = raw[32:]
     depth = self.depth + 1
     child_number = index
     return HDPrivateKey(
         private_key=private_key,
         chain_code=chain_code,
         depth=depth,
         fingerprint=fingerprint,
         child_number=child_number,
         testnet=self.testnet,
     )
Example #3
0
def op_hash160(stack):
    # if stack is empty, return False
    if len(stack) < 1:
        return False
    element = stack.pop()
    stack.append(hash160(element))
    return True
Example #4
0
 def verify_input(self, input_index):
     '''Returns whether the input has a valid signature'''
     # get the relevant input
     tx_in = self.tx_ins[input_index]
     # get the number of signatures required. This is available in tx_in.script_sig.num_sigs_required()
     sigs_required = tx_in.script_sig.num_sigs_required()
     # iterate over the sigs required and check each signature
     for sig_num in range(sigs_required):
         # get the point from the sec format
         sec = tx_in.sec_pubkey(index=sig_num)
         # get the sec_pubkey at current signature index
         point = S256Point.parse(sec)
         # get the der sig and hash_type from input
         # get the der_signature at current signature index
         der, hash_type = tx_in.der_signature(index=sig_num)
         # get the signature from der format
         signature = Signature.parse(der)
         # get the hash to sign
         if tx_in.is_segwit():
             h160 = hash160(tx_in.script_sig.redeem_script())
             if h160 != tx_in.script_pubkey(self.testnet).elements[1]:
                 return False
             pubkey_h160 = tx_in.script_sig.redeem_script()[-20:]
             if pubkey_h160 != point.h160():
                 return False
             z = self.sig_hash_bip143(input_index, hash_type)
         else:
             z = self.sig_hash(input_index, hash_type)
         # use point.verify on the hash to sign and signature
         if not point.verify(z, signature):
             return False
     return True
Example #5
0
def op_hash160(stack):
    if len(stack) < 1:
        return False
    element = stack.pop()
    h160 = hash160(element)
    stack.append(h160)
    return True
Example #6
0
    def address(self, compressed=True, testnet=False):
        # get the sec
        # hash160 the sec
        # raw is hash 160 prepended w/ b'\x00' for mainnet, b'\x6f' for testnet
        # checksum is first 4 bytes of double_sha256 of raw
        # encode_base58 the raw + checksum
        # return as a string, you can use .decode('ascii') to do this.
        '''Returns the address string'''
        # get the sec format
        sec = self.sec(compressed)
        # hash160 the result
        h160 = hash160(sec)
        # prepend b'\x00' for mainnet b'\x6f' for testnet
        if testnet:
            prefix = b'\x6f'
        else:
            prefix = b'\x00'
        raw = prefix + h160

        # get the double_sha256 of the prefix + h160, first 4 bytes are the checksum
        checksum = double_sha256(raw)[:4]
        # append checksum
        # encode_base58 the whole thing
        sum = encode_base58(raw + checksum).decode('ascii')
        return (sum)
Example #7
0
 def derive_pub_child(self, i):
     if i >= HARD_CAP:
         return ValueError("Chosen i is not in range [0, 2**32-1]")
     # Not quite sure if this is true
     # if int.from_bytes(self.child_num, 'big') >= SOFT_CAP:
     # 	raise TypeError("Hardened Public Keys cannot derive child keys. Use Extended Private key.")
     if i >= SOFT_CAP:
         raise TypeError(
             "Hardened Keys cannot be be derived from Extended Pub Keys. Use Extended Private key."
         )
     else:
         ii = hmac.new(self.chaincode,
                       self.key + i.to_bytes(4, 'big'),
                       digestmod=sha512).digest()
     fingerprint = hash160(self.key)[:4]
     # edge case: invalid keys
     key_num = int.from_bytes(ii[:32], 'big')
     point = key_num * G
     if key_num >= N or point.x is None:
         raise ValueError(INVALID_KEY_MSG)
     child_key = point + S256Point.parse(self.key)
     child_chaincode = ii[32:]
     #assemble new xpub
     child_xpub = self.pfx
     child_xpub += (self.depth[0] + 1).to_bytes(1, 'big')
     child_xpub += fingerprint
     child_xpub += i.to_bytes(4, 'big')
     child_xpub += child_chaincode
     child_xpub += child_key.sec()
     checksum = hash256(child_xpub)[:4]
     child_xpub += checksum
     return self.__class__(child_xpub)
Example #8
0
    def derive_priv_child(self, i):
        if i >= HARD_CAP:
            return ValueError("Chosen i is not in range [0, 2**32-1]")
        if i >= SOFT_CAP:  # hardened
            ii = hmac.new(self.chaincode,
                          self.key + i.to_bytes(4, 'big'),
                          digestmod=sha512).digest()
        else:  #unhardened
            ii = hmac.new(self.chaincode,
                          self.to_priv_key().point.sec() +
                          i.to_bytes(4, 'big'),
                          digestmod=sha512).digest()

        key = (int.from_bytes(ii[:32], 'big') +
               int.from_bytes(self.key, 'big')) % N  # from ecc.py
        fingerprint = hash160(self.to_pub_key().sec())[:4]
        child_xprv = self.pfx
        child_xprv += (self.depth[0] + 1).to_bytes(1, 'big')
        child_xprv += fingerprint
        child_xprv += i.to_bytes(4, 'big')
        # add chaincode
        child_xprv += ii[32:]
        # add key
        child_xprv += b"\x00" + key.to_bytes(32, 'big')
        checksum = hash256(child_xprv)[:4]
        child_xprv += checksum
        return self.__class__(child_xprv)
Example #9
0
 def test_example_9(self):
     sec = bytes.fromhex('025CBDF0646E5DB4EAA398F365F2EA7A0E3D419B7E0330E39CE92BDDEDCAC4F9BC')
     h160 = hash160(sec)
     raw = b"\x00" + h160
     raw = raw + hash256(raw)[:4]
     addr = encode_base58(raw)
     self.assertEqual(addr, b'19ZewH8Kk1PDbSNdJ97FP4EiCjTRaZMZQA')
Example #10
0
 def verify(self, z, sig):
     if isinstance(z, str):
         # Hash string and convert to int
         z = int.from_bytes(hash160(z.encode()), 'big')
     u = z * pow(sig.s, N - 2, N) % N
     v = sig.r * pow(sig.s, N - 2, N) % N
     return (u * G + v * self).x.num == sig.r
Example #11
0
 def test_address_p2wpkh(self):
     secret = b'[email protected] test1'
     private_key = PrivateKey(little_endian_to_int(hash256(secret)))
     point = private_key.point
     h160 = hash160(point.sec())
     script_pubkey = p2wpkh_script(h160)
     self.assertEqual(script_pubkey.address(testnet=True),
                      'tb1q3845h8hm5uqgjh7jkq4pkrftlrcgvjf442jh4z')
Example #12
0
def op_hash160(stack):
    # check that there's at least 1 element on the stack
    # pop off the top element from the stack
    # push a hash160 of the popped off element to the stack
    if len(stack) < 1:
        return False
    stack.append(hash160(stack.pop()))
    return True
Example #13
0
 def test_exercise_1(self):
     bit_field_size = 10
     bit_field = [0] * bit_field_size
     for item in (b'hello world', b'goodbye'):
         h = hash160(item)
         bit = int.from_bytes(h, 'big') % bit_field_size
         bit_field[bit] = 1
     self.assertEqual(bit_field, [1, 1, 0, 0, 0, 0, 0, 0, 0, 0])
Example #14
0
def address(self, compressed=True, testnet=False):
    sec = self.sec(compressed)
    h160 = hash160(sec)
    if testnet:
        prefix = b'\x6f'
    else:
        prefix = b'\x00'
    return encode_base58_checksum(prefix + h160)
Example #15
0
 def address(self, compressed=True, testnet=False):
     h160 = hash160(self.sec(compressed=compressed))
     if testnet:
         prefix = b'\x6f'
     else:
         prefix = b'\x00'
     raw = prefix + h160
     raw = raw + double_sha256(raw)[:4]
     return encode_base58(raw).decode('ascii')
Example #16
0
def op_hash160(stack: list) -> bool:
    # check that there's at least 1 element on the stack
    if len(stack) < 1:
        return False
    # pop off the top element from the stack
    element = stack.pop()
    # push a hash160 of the popped off element to the stack
    stack.append(hash160(element))
    return True
Example #17
0
 def test_address_p2sh_p2wpkh(self):
     secret = b'[email protected] test1'
     private_key = PrivateKey(little_endian_to_int(hash256(secret)))
     point = private_key.point
     real_h160 = hash160(point.sec())
     redeem_script = p2wpkh_script(real_h160)
     h160 = redeem_script.hash160()
     self.assertEqual(
         p2sh_script(h160).address(testnet=True),
         '2N3a8NdfeA7SAurCGsd5k9AEYvbszipz3Jz')
def op_hash160(stack):
    # check that there's at least 1 element on the stack
    if len(stack) < 1:
        return False
    element = stack.pop()
    stack.append(hash160(element))
    return True
    # pop off the top element from the stack
    # push a hash160 of the popped off element to the stack
    raise NotImplementedError
Example #19
0
def op_hash160(stack):
    # check to see if there's at least 1 element
    if len(stack) < 1:
        return False
    # get the element on the top with stack.pop()
    element = stack.pop()
    # add the hash160 of the element to the end of the stack
    h160 = hash160(element)
    stack.append(h160)
    return True
Example #20
0
 def sign(self, z):
     if isinstance(z, str):
         # Hash string and convert to int
         z = int.from_bytes(hash160(z.encode()), 'big')
     k = randint(0, 2**256)
     r = (k * G).x.num
     s = (z + r * self.secret) * pow(k, N - 2, N) % N
     if s * 2 > N:
         s = N - s
     return Signature(r, s)
Example #21
0
 def getaddress(self, testnet=False, compressed=True):
     comp = self.point.sec(compressed)
     h160 = hash160(comp)
     prefix = b'\00'
     if testnet:
         prefix = b'\x6f'
     else:
         prefix = b'\00'
     raw = prefix + h160
     checksum = double_sha256(raw)[:4]
     total = raw + checksum
     return encode_base58(total)
Example #22
0
def getaddress(x, y, testnet=True, compressed=True):
    p = S256Point(x, y)
    comp = p.sec(compressed)
    h160 = hash160(comp)
    prefix = b'\00'
    if testnet:
        prefix = b'\x6f'
    else:
        prefix = b'\00'
    raw = prefix + h160
    checksum = double_sha256(raw)[:4]
    total = raw + checksum
    return encode_base58(total)
Example #23
0
 def address(self, compressed=True, testnet=False):
     '''Returns the address string'''
     # get the sec
     sec = self.sec(compressed)
     # hash160 the sec
     h160 = hash160(sec)
     # prefix is b'\x00' for mainnet, b'\x6f' for testnet
     if testnet:
         prefix = b'\x6f'
     else:
         prefix = b'\x00'
     # return the encode_base58_checksum of the prefix and h160
     return encode_base58_checksum(prefix + h160)
def check_htlc_and_get_secret_hash(node, commitment_tx, channel):
    tx_in = commitment_tx.tx_ins[0]
    tx_out_1 = commitment_tx.tx_outs[1]
    tx_out_2 = commitment_tx.tx_outs[2]

    if (
            tx_in.prev_tx.hex() == channel.funding_tx.id()
    ):  #checks that it is spending from the correct 2-of-2 multisig tx (the funding tx)
        if (tx_out_1.script_pubkey.cmds[2] == decode_base58(node.address)
                and tx_out_1.amount == channel.local_amt):
            if (tx_out_2.script_pubkey.cmds[6] == hash160(
                    node.public_key.sec())):
                return tx_out_2.script_pubkey.cmds[2]
    return None
Example #25
0
 def address(self, compressed=True, testnet=False):
     '''Returns the address string'''
     # get the sec / hash160 the sec
     h160 = hash160(self.sec(compressed=compressed))
     # raw is hash 160 prepended w/ b'\x00' for mainnet, b'\x6f' for testnet
     if testnet:
         prefix = b'\x6f'
     else:
         prefix = b'\x00'
     raw = prefix + h160
     # checksum is first 4 bytes of double_sha256 of raw
     checksum = double_sha256(raw)[:4]
     # encode_base58 the raw + checksum
     return encode_base58(raw + checksum).decode('ascii')
Example #26
0
def KeyToAddr(privkey, prefix):
    '''Returns the address string'''
    # get the sec
    sec = privkey.point.sec(compressed=True)
    # hash160 the sec
    h160 = hash160(sec)

    raw = prefix + h160
    # checksum is first 4 bytes of double_sha256 of raw
    checksum = double_sha256(raw)[:4]
    # encode_base58 the raw + checksum
    address = encode_base58(raw + checksum)
    # return as a string, you can use .decode('ascii') to do this.

    return address.decode('ascii')
Example #27
0
    def verify_input(self, input_index):
        '''Returns whether the input has a valid signature'''
        # Exercise 1.1: get the relevant input
        tx_in = self.tx_ins[input_index]
        # Exercise 6.2: get the number of signatures required. This is available in tx_in.script_sig.num_sigs_required()
        if tx_in.script_sig.type() == 'blank':
            if tx_in.script_pubkey().type() == 'p2wpkh':
                sigs_required = 1
                # TODO: refactor
                # witness program verification
                if hash160(tx_in.script_witness[1]) != tx_in.script_pubkey().elements[-1]:
                    return False

                point = S256Point.parse(tx_in.script_witness[1])
                der, hash_type = tx_in.der_signature()
                signature = Signature.parse(der)
                z = self.sig_hash(input_index, hash_type)
                if not point.verify(z, signature):
                    return False

            #elif tx_in.script_pubkey().type() == 'p2wsh':
            #    sigs_required = 1
            #    point = S256Point.parse(tx_in.script_witness[1])
            #    der, hash_type = tx_in.der_signature()
            #    signature = Signature.parse(der)
            #    z = self.sig_hash(input_index, hash_type)
            #    if not point.verify(z, signature):
            #        return False
            else:
                raise RuntimeError("other witness type not yet supported")
        else:
            sigs_required = tx_in.script_sig.num_sigs_required()
            # Exercise 6.2: iterate over the sigs required and check each signature
            for sig_num in range(sigs_required):
                # Exercise 1.1: get the point from the sec format (tx_in.sec_pubkey())
                # Exercise 6.2: get the sec_pubkey at current signature index (check sec_pubkey function)
                point = S256Point.parse(tx_in.sec_pubkey(index=sig_num))
                # Exercise 1.1: get the der sig and hash_type from input
                # Exercise 6.2: get the der_signature at current signature index (check der_signature function)
                der, hash_type = tx_in.der_signature(index=sig_num)
                # Exercise 1.1: get the signature from der format
                signature = Signature.parse(der)
                # Exercise 1.1: get the hash to sign
                z = self.sig_hash(input_index, hash_type)
                # Exercise 1.1: use point.verify on the hash to sign and signature
                if not point.verify(z, signature):
                    return False
        return True
Example #28
0
 def child(self, index):
     if index >= 0x80000000:
         raise ValueError('child number should always be less than 2^31')
     sec = self.point.sec()
     data = sec + index.to_bytes(4, 'big')
     raw = HMAC(key=self.chain_code, msg=data, digestmod=sha512).digest()
     point = PrivateKey(int.from_bytes(raw[:32], 'big')).point + self.point
     chain_code = raw[32:]
     depth = self.depth + 1
     fingerprint = hash160(sec)[:4]
     child_number = index
     return HDPublicKey(
         point=point,
         chain_code=chain_code,
         depth=depth,
         fingerprint=fingerprint,
         child_number=child_number,
     )
Example #29
0
def op_hash160(stack: List[Any]) -> bool:
    """
    convert top element into hash160 value

    Parameters
    ----------
    stack : List[Any]
        [description]

    Returns
    -------
    bool
        [description]
    """

    if len(stack) < 1:
        return False
    element = stack.pop()
    stack.append(hash160(element))
    return True
Example #30
0
 def address(self, testnet=False):
     '''Returns the address corresponding to the script'''
     sig_type = self.type()
     if sig_type == 'p2pkh':
         # hash160 is the 3rd element
         h160 = self.elements[2]
         # convert to p2pkh address using h160_to_p2pkh_address (remember testnet)
         return h160_to_p2pkh_address(h160, testnet)
     elif sig_type == 'p2sh':
         # hash160 is the 2nd element
         h160 = self.elements[1]
         # convert to p2sh address using h160_to_p2sh_address (remember testnet)
         return h160_to_p2sh_address(h160, testnet)
     elif sig_type == 'p2pk':
         return h160_to_p2pkh_address(hash160(self.elements[0]), testnet)
     elif sig_type == 'p2wpkh':
         import segwit_addr
         if self.elements[0] == b'':
             witver = 0
         else:
             assert 0
         return segwit_addr.encode("bc", witver, self.elements[1])