tlnbase: verify remote signature - electrum - Electrum Bitcoin wallet HTML git clone https://git.parazyd.org/electrum DIR Log DIR Files DIR Refs DIR Submodules --- DIR commit 21be384603fa044fbf99768a60152686f23a2995 DIR parent e9bad2e862db17087d2b11a2e5abef79476119c5 HTML Author: ThomasV <thomasv@electrum.org> Date: Sat, 21 Apr 2018 14:33:41 +0200 lnbase: verify remote signature Diffstat: M lib/lnbase.py | 43 +++++++++++++++---------------- M lib/tests/test_lnbase.py | 10 +++++----- 2 files changed, 26 insertions(+), 27 deletions(-) --- DIR diff --git a/lib/lnbase.py b/lib/lnbase.py t@@ -428,9 +428,10 @@ def make_received_htlc(revocation_pubkey, remote_htlcpubkey, local_htlcpubkey, p def make_commitment(ctn, local_funding_pubkey, remote_funding_pubkey, remotepubkey, - payment_basepoint, remote_payment_basepoint, revocation_pubkey, delayed_pubkey, + payment_basepoint, remote_payment_basepoint, + revocation_pubkey, delayed_pubkey, to_self_delay, funding_txid, funding_pos, funding_satoshis, - local_amount, remote_amount, to_self_delay, dust_limit_satoshis, htlcs=[]): + local_amount, remote_amount, dust_limit_satoshis, htlcs=[]): pubkeys = sorted([bh2u(local_funding_pubkey), bh2u(remote_funding_pubkey)]) obs = get_obscured_ctn(ctn, payment_basepoint, remote_payment_basepoint) locktime = (0x20 << 24) + (obs & 0xffffff) t@@ -467,7 +468,7 @@ def make_commitment(ctn, local_funding_pubkey, remote_funding_pubkey, remotepubk class Peer(PrintError): - def __init__(self, host, port, pubkey, request_initial_sync=True, network=None): + def __init__(self, host, port, pubkey, request_initial_sync=False, network=None): self.host = host self.port = port self.privkey = os.urandom(32) + b"\x01" t@@ -746,8 +747,8 @@ class Peer(PrintError): remotepubkey = derive_pubkey(remote_payment_basepoint, per_commitment_point_first) revocation_pubkey = derive_blinded_pubkey(revocation_basepoint, remote_per_commitment_point) remote_revocation_pubkey = derive_blinded_pubkey(remote_revocation_basepoint, per_commitment_point_first) - local_delayedpubkey = derive_pubkey(delayed_payment_basepoint, remote_per_commitment_point) - remote_delayedpubkey = derive_pubkey(remote_delayed_payment_basepoint, per_commitment_point_first) + local_delayedpubkey = derive_pubkey(delayed_payment_basepoint, per_commitment_point_first) + remote_delayedpubkey = derive_pubkey(remote_delayed_payment_basepoint, remote_per_commitment_point) # compute amounts htlcs = [] fee = local_feerate * overall_weight(len(htlcs)) // 1000 t@@ -758,20 +759,19 @@ class Peer(PrintError): # remote commitment transaction remote_ctx = make_commitment( ctn, - remote_funding_pubkey, funding_pubkey, # will be sorted - localpubkey, # used in to_remote - base_point, remote_payment_basepoint, # used by obscured ctn - revocation_pubkey, remote_delayedpubkey, # used by to_local script + remote_funding_pubkey, funding_pubkey, localpubkey, + base_point, remote_payment_basepoint, + revocation_pubkey, remote_delayedpubkey, remote_delay, funding_txid, funding_index, funding_satoshis, - remote_amount, local_amount, remote_delay, remote_dust_limit_satoshis) + remote_amount, local_amount, remote_dust_limit_satoshis) remote_ctx.sign({bh2u(funding_pubkey): (funding_privkey, True)}) sig_index = pubkeys.index(bh2u(funding_pubkey)) sig = bytes.fromhex(remote_ctx.inputs()[0]["signatures"][sig_index]) r, s = sigdecode_der(sig[:-1], SECP256k1.generator.order()) sig_64 = sigencode_string_canonize(r, s, SECP256k1.generator.order()) - funding_txid = bytes.fromhex(funding_txid)[::-1] - channel_id = int.from_bytes(funding_txid, byteorder="big") ^ funding_index - self.send_message(gen_msg("funding_created", temporary_channel_id=temp_channel_id, funding_txid=funding_txid, funding_output_index=funding_index, signature=sig_64)) + funding_txid_bytes = bytes.fromhex(funding_txid)[::-1] + channel_id = int.from_bytes(funding_txid_bytes, byteorder="big") ^ funding_index + self.send_message(gen_msg("funding_created", temporary_channel_id=temp_channel_id, funding_txid=funding_txid_bytes, funding_output_index=funding_index, signature=sig_64)) self.funding_signed[channel_id] = asyncio.Future() try: payload = await self.funding_signed[channel_id] t@@ -779,27 +779,26 @@ class Peer(PrintError): del self.funding_signed[channel_id] self.print_error('received funding_signed') remote_sig = payload['signature'] - # todo: check signature against local ctx + # verify remote signature local_ctx = make_commitment( ctn, - funding_pubkey, remote_funding_pubkey, - remotepubkey, + funding_pubkey, remote_funding_pubkey, remotepubkey, base_point, remote_payment_basepoint, - revocation_pubkey, local_delayedpubkey, + remote_revocation_pubkey, local_delayedpubkey, to_self_delay, funding_txid, funding_index, funding_satoshis, - local_amount, remote_amount, to_self_delay, dust_limit_satoshis) - self.print_error('Done making commitment') - + local_amount, remote_amount, dust_limit_satoshis) + pre_hash = bitcoin.Hash(bfh(local_ctx.serialize_preimage(0))) + if not bitcoin.verify_signature(remote_funding_pubkey, remote_sig, pre_hash): + raise Exception('verifying remote signature failed.') # broadcast funding tx self.local_funding_locked[channel_id] = asyncio.Future() self.remote_funding_locked[channel_id] = asyncio.Future() success, _txid = self.network.broadcast(funding_tx) assert success # wait until we see confirmations - def on_network_update(event, *args): if event == 'updated': - conf = wallet.get_tx_height(bh2u(funding_txid[::-1]))[1] + conf = wallet.get_tx_height(funding_txid)[1] if conf >= funding_txn_minimum_depth: async def set_local_funding_locked_result(): try: DIR diff --git a/lib/tests/test_lnbase.py b/lib/tests/test_lnbase.py t@@ -68,9 +68,9 @@ class Test_LNBase(unittest.TestCase): commitment_number, local_funding_pubkey, remote_funding_pubkey, remotepubkey, local_payment_basepoint, remote_payment_basepoint, - local_revocation_pubkey, local_delayedpubkey, + local_revocation_pubkey, local_delayedpubkey, local_delay, funding_tx_id, funding_output_index, funding_amount_satoshi, - local_amount, remote_amount, local_delay, local_dust_limit_satoshi) + local_amount, remote_amount, local_dust_limit_satoshi) self.sign_and_insert_remote_sig(our_commit_tx, remote_funding_pubkey, remote_signature, local_funding_pubkey, local_funding_privkey) ref_commit_tx_str = '02000000000101bef67e4e2fb9ddeeb3461973cd4c62abb35050b1add772995b820b584a488489000000000038b02b8002c0c62d0000000000160014ccf1af2f2aabee14bb40fa3851ab2301de84311054a56a00000000002200204adb4e2f00643db396dd120d4e7dc17625f5f2c11a40d857accc862d6b7dd80e0400473044022051b75c73198c6deee1a875871c3961832909acd297c6b908d59e3319e5185a46022055c419379c5051a78d00dbbce11b5b664a0c22815fbcc6fcef6b1937c383693901483045022100f51d2e566a70ba740fc5d8c0f07b9b93d2ed741c3c0860c613173de7d39e7968022041376d520e9c0e1ad52248ddf4b22e12be8763007df977253ef45a4ca3bdb7c001475221023da092f6980e58d2c037173180e9a465476026ee50f96695963e8efe436f54eb21030e9f7b623d2ccc7c9bd44d66d5ce21ce504c0acf6385a132cec6d3c39fa711c152ae3e195220' self.assertEqual(str(our_commit_tx), ref_commit_tx_str) t@@ -158,10 +158,10 @@ class Test_LNBase(unittest.TestCase): commitment_number, local_funding_pubkey, remote_funding_pubkey, remotepubkey, local_payment_basepoint, remote_payment_basepoint, - local_revocation_pubkey, local_delayedpubkey, + local_revocation_pubkey, local_delayedpubkey, loccal_delay, funding_tx_id, funding_output_index, funding_amount_satoshi, - local_amount, remote_amount, - local_delay, local_dust_limit_satoshi, htlcs=htlcs) + local_amount, remote_amount, local_dust_limit_satoshi, + htlcs=htlcs) self.sign_and_insert_remote_sig(our_commit_tx, remote_funding_pubkey, remote_signature, local_funding_pubkey, local_funding_privkey) self.assertEqual(str(our_commit_tx), output_commit_tx)