Skip to content
This repository has been archived by the owner on May 13, 2022. It is now read-only.

Commit

Permalink
Maker uses one of input utxos for authorization pubkey, not coinjoin …
Browse files Browse the repository at this point in the history
…pubkey, addresses e.g. issue 88
  • Loading branch information
AdamISZ committed Jul 12, 2016
1 parent 43f6b2a commit 7d83041
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 26 deletions.
15 changes: 9 additions & 6 deletions joinmarket/maker.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,15 @@ def auth_counterparty(self, nick, i_utxo_pubkey, btc_sig, i_utxo, p2, s, e):
# (but input utxo pubkey is checked in verify_unsigned_tx).

# Send auth request to taker
# TODO the next 2 lines are a little inefficient.
btc_key = self.maker.wallet.get_key_from_addr(self.cj_addr)
btc_pub = btc.privtopub(btc_key)
btc_sig = btc.ecdsa_sign(self.kp.hex_pk(), btc_key)
self.maker.msgchan.send_ioauth(nick, self.utxos.keys(), btc_pub,
self.change_addr, btc_sig)
# Need to choose an input utxo pubkey to sign with
# (no longer using the coinjoin pubkey from 0.2.0)
# Just choose the first utxo in self.utxos and retrieve key from wallet.
auth_address = self.utxos[self.utxos.keys()[0]]['address']
auth_key = self.maker.wallet.get_key_from_addr(auth_address)
auth_pub = btc.privtopub(auth_key)
btc_sig = btc.ecdsa_sign(self.kp.hex_pk(), auth_key)
self.maker.msgchan.send_ioauth(nick, self.utxos.keys(), auth_pub,
self.cj_addr, self.change_addr, btc_sig)
return True

def recv_tx(self, nick, txhex):
Expand Down
23 changes: 12 additions & 11 deletions joinmarket/message_channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,9 +293,9 @@ def send_pubkey(self, nick, pubkey):
self.active_channels[nick].privmsg(nick, 'pubkey', pubkey)

@check_privmsg
def send_ioauth(self, nick, utxo_list, cj_pubkey, change_addr, sig):
self.active_channels[nick].send_ioauth(nick, utxo_list, cj_pubkey,
change_addr, sig)
def send_ioauth(self, nick, utxo_list, auth_pub, cj_addr, change_addr, sig):
self.active_channels[nick].send_ioauth(nick, utxo_list, auth_pub,
cj_addr, change_addr, sig)

@check_privmsg
def send_sigs(self, nick, sig_list):
Expand Down Expand Up @@ -731,9 +731,9 @@ def cancel_orders(self, oid_list):
def send_pubkey(self, nick, pubkey):
self.privmsg(nick, 'pubkey', pubkey)

def send_ioauth(self, nick, utxo_list, cj_pubkey, change_addr, sig):
authmsg = (str(','.join(utxo_list)) + ' ' + cj_pubkey + ' ' +
change_addr + ' ' + sig)
def send_ioauth(self, nick, utxo_list, auth_pub, cj_addr, change_addr, sig):
authmsg = str(','.join(utxo_list)) + ' ' + ' '.join([auth_pub,
cj_addr, change_addr, sig])
self.privmsg(nick, 'ioauth', authmsg)

def send_sigs(self, nick, sig_list):
Expand Down Expand Up @@ -914,12 +914,13 @@ def on_privmsg(self, nick, message):
self.on_pubkey(nick, maker_pk)
elif _chunks[0] == 'ioauth':
utxo_list = _chunks[1].split(',')
cj_pub = _chunks[2]
change_addr = _chunks[3]
btc_sig = _chunks[4]
auth_pub = _chunks[2]
cj_addr = _chunks[3]
change_addr = _chunks[4]
btc_sig = _chunks[5]
if self.on_ioauth:
self.on_ioauth(nick, utxo_list, cj_pub, change_addr,
btc_sig)
self.on_ioauth(nick, utxo_list, auth_pub, cj_addr,
change_addr, btc_sig)
elif _chunks[0] == 'sig':
sig = _chunks[1]
if self.on_sig:
Expand Down
31 changes: 22 additions & 9 deletions joinmarket/taker.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,17 +104,21 @@ def start_encryption(self, nick, maker_pk):
self.msgchan.send_auth(nick, my_btc_pub, my_btc_sig, self.auth_utxo,
self.podle['P2'], self.podle['sig'], self.podle['e'])

def auth_counterparty(self, nick, btc_sig, cj_pub):
def auth_counterparty(self, nick, btc_sig, auth_pub):
"""Validate the counterpartys claim to own the btc
address/pubkey that will be used for coinjoining
with an ecdsa verification."""
# crypto_boxes[nick][0] = maker_pubkey
if not btc.ecdsa_verify(self.crypto_boxes[nick][0], btc_sig, cj_pub):
with an ecdsa verification.
Note that this is only a first-step
authorisation; it checks the btc signature, but
the authorising pubkey is checked to be part of the
transactoin in recv_txio.
"""
if not btc.ecdsa_verify(self.crypto_boxes[nick][0], btc_sig, auth_pub):
log.debug('signature didnt match pubkey and message')
return False
return True

def recv_txio(self, nick, utxo_list, cj_pub, change_addr):
def recv_txio(self, nick, utxo_list, auth_pub, cj_addr, change_addr):
if nick not in self.nonrespondants:
log.debug(('recv_txio => nick={} not in '
'nonrespondants {}').format(nick, self.nonrespondants))
Expand All @@ -127,6 +131,16 @@ def recv_txio(self, nick, utxo_list, cj_pub, change_addr):
# when internal reviewing of makers is created, add it here to
# immediately quit; currently, the timeout thread suffices.
return
#Complete maker authorization:
#Extract the address fields from the utxos
#Construct the Bitcoin address for the auth_pub field
#Ensure that at least one address from utxos corresponds.
input_addresses = [d['address'] for d in utxo_data]
auth_address = btc.pubkey_to_address(auth_pub, get_p2pk_vbyte())
if not auth_address in input_addresses:
log.debug("ERROR maker's authorising pubkey is not included "
"in the transaction: " + str(auth_address))
return

total_input = sum([d['value'] for d in utxo_data])
real_cjfee = calc_cj_fee(self.active_orders[nick]['ordertype'],
Expand All @@ -149,7 +163,6 @@ def recv_txio(self, nick, utxo_list, cj_pub, change_addr):
'cjamount={:d} txfee={:d} realcjfee={:d}').format
log.debug(fmt(nick, total_input, self.cj_amount,
self.active_orders[nick]['txfee'], real_cjfee))
cj_addr = btc.pubtoaddr(cj_pub, get_p2pk_vbyte())
self.outputs.append({'address': cj_addr, 'value': self.cj_amount})
self.cjfee_total += real_cjfee
self.maker_txfee_contributions += self.active_orders[nick]['txfee']
Expand Down Expand Up @@ -597,14 +610,14 @@ def on_pubkey(self, nick, maker_pubkey):
time.sleep(0.5)
self.cjtx.start_encryption(nick, maker_pubkey)

def on_ioauth(self, nick, utxo_list, cj_pub, change_addr, btc_sig):
if not self.cjtx.auth_counterparty(nick, btc_sig, cj_pub):
def on_ioauth(self, nick, utxo_list, auth_pub, cj_addr, change_addr, btc_sig):
if not self.cjtx.auth_counterparty(nick, btc_sig, auth_pub):
fmt = ('Authenticated encryption with counterparty: {}'
' not established. TODO: send rejection message').format
log.debug(fmt(nick))
return
with self.cjtx.timeout_thread_lock:
self.cjtx.recv_txio(nick, utxo_list, cj_pub, change_addr)
self.cjtx.recv_txio(nick, utxo_list, auth_pub, cj_addr, change_addr)

def on_sig(self, nick, sig):
with self.cjtx.timeout_thread_lock:
Expand Down

0 comments on commit 7d83041

Please sign in to comment.