def on_auth_received(self, nick, offer, commitment, cr, amount, kphex):
        """Receives data on proposed transaction offer from daemon, verifies
        commitment, returns necessary data to send ioauth message (utxos etc)
        """
        #deserialize the commitment revelation
        cr_dict = PoDLE.deserialize_revelation(cr)
        #check the validity of the proof of discrete log equivalence
        tries = jm_single().config.getint("POLICY", "taker_utxo_retries")

        def reject(msg):
            jlog.info("Counterparty commitment not accepted, reason: " + msg)
            return (False, )

        if not verify_podle(str(cr_dict['P']),
                            str(cr_dict['P2']),
                            str(cr_dict['sig']),
                            str(cr_dict['e']),
                            str(commitment),
                            index_range=range(tries)):
            reason = "verify_podle failed"
            return reject(reason)
        #finally, check that the proffered utxo is real, old enough, large enough,
        #and corresponds to the pubkey
        res = jm_single().bc_interface.query_utxo_set([cr_dict['utxo']],
                                                      includeconf=True)
        if len(res) != 1 or not res[0]:
            reason = "authorizing utxo is not valid"
            return reject(reason)
        age = jm_single().config.getint("POLICY", "taker_utxo_age")
        if res[0]['confirms'] < age:
            reason = "commitment utxo not old enough: " + str(
                res[0]['confirms'])
            return reject(reason)
        reqd_amt = int(
            amount *
            jm_single().config.getint("POLICY", "taker_utxo_amtpercent") /
            100.0)
        if res[0]['value'] < reqd_amt:
            reason = "commitment utxo too small: " + str(res[0]['value'])
            return reject(reason)
        if res[0]['address'] != self.wallet.pubkey_to_address(cr_dict['P']):
            reason = "Invalid podle pubkey: " + str(cr_dict['P'])
            return reject(reason)

        # authorisation of taker passed
        #Find utxos for the transaction now:
        utxos, cj_addr, change_addr = self.oid_to_order(offer, amount)
        if not utxos:
            #could not find funds
            return (False, )
        self.wallet.update_cache_index()
        # Construct data for auth request back to taker.
        # 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 = utxos[utxos.keys()[0]]['address']
        auth_key = self.wallet.get_key_from_addr(auth_address)
        auth_pub = btc.privtopub(auth_key)
        btc_sig = btc.ecdsa_sign(kphex, auth_key)
        return (True, utxos, auth_pub, cj_addr, change_addr, btc_sig)
Exemple #2
0
 def start_encryption(self, nick, maker_pk):
     if nick not in self.active_orders.keys():
         log.debug("Counterparty not part of this transaction. Ignoring")
         return
     try:
         self.crypto_boxes[nick] = [
             maker_pk,
             as_init_encryption(self.kp, init_pubkey(maker_pk))
         ]
     except NaclError as e:
         log.debug("Unable to setup crypto box with " + nick + ": " +
                   repr(e))
         self.msgchan.send_error(nick, "invalid nacl pubkey: " + maker_pk)
         return
     # send authorisation request
     log.debug("Starting auth, utxos: " + pprint.pformat(self.input_utxos))
     if self.auth_addr:
         my_btc_addr = self.auth_addr
     else:
         my_btc_addr = self.input_utxos.itervalues().next()['address']
     log.debug("Trying to get privkey")
     my_btc_priv = self.wallet.get_key_from_addr(my_btc_addr)
     log.debug("Trying to get pubkey")
     my_btc_pub = btc.privtopub(my_btc_priv)
     log.debug("Got pubkey: " + str(my_btc_pub))
     my_btc_sig = btc.ecdsa_sign(self.kp.hex_pk(), my_btc_priv)
     self.msgchan.send_auth(nick, my_btc_pub, my_btc_sig)
 def get_addr(self, mixing_depth, forchange, i):
     """Construct a p2sh-p2wpkh style address for the
     keypair corresponding to mixing depth mixing_depth,
     branch forchange and index i
     """
     pub = btc.privtopub(self.get_key(mixing_depth, forchange, i))
     return btc.pubkey_to_p2sh_p2wpkh_address(pub, magicbyte=self.get_vbyte())
Exemple #4
0
 def set_nick(self):
     self.nick_pubkey = btc.privtopub(self.nick_priv)
     self.nick_pkh_raw = hashlib.sha256(self.nick_pubkey).digest()[
                 :self.nick_hashlen]
     self.nick_pkh = btc.changebase(self.nick_pkh_raw, 256, 58)
     #right pad to maximum possible; b58 is not fixed length.
     #Use 'O' as one of the 4 not included chars in base58.
     self.nick_pkh += 'O' * (self.nick_maxencoded - len(self.nick_pkh))
     #The constructed length will be 1 + 1 + NICK_MAX_ENCODED
     self.nick = self.nick_header + str(self.jm_version) + self.nick_pkh
     jm_single().nickname = self.nick
Exemple #5
0
def donation_address(reusable_donation_pubkey=None): #pragma: no cover
    #Donation code currently disabled, so not tested.
    if not reusable_donation_pubkey:
        reusable_donation_pubkey = ('02be838257fbfddabaea03afbb9f16e852'
                                    '9dfe2de921260a5c46036d97b5eacf2a')
    sign_k = binascii.hexlify(os.urandom(32))
    c = btc.sha256(btc.multiply(sign_k, reusable_donation_pubkey, True))
    sender_pubkey = btc.add_pubkeys(
        [reusable_donation_pubkey, btc.privtopub(c + '01', True)], True)
    sender_address = btc.pubtoaddr(sender_pubkey, get_p2pk_vbyte())
    log.debug('sending coins to ' + sender_address)
    return sender_address, sign_k
Exemple #6
0
    def auth_counterparty(self, nick, i_utxo_pubkey, btc_sig):
        self.i_utxo_pubkey = i_utxo_pubkey

        if not btc.ecdsa_verify(self.taker_pk, btc_sig, self.i_utxo_pubkey):
            print('signature didnt match pubkey and message')
            return False
        # authorisation of taker passed
        # (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)
        return True
Exemple #7
0
    def auth_counterparty(self, nick, i_utxo_pubkey, btc_sig):
        self.i_utxo_pubkey = i_utxo_pubkey

        if not btc.ecdsa_verify(self.taker_pk, btc_sig, self.i_utxo_pubkey):
            print('signature didnt match pubkey and message')
            return False
        # authorisation of taker passed
        # (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)
        return True
Exemple #8
0
 def start_encryption(self, nick, maker_pk):
     if nick not in self.active_orders.keys():
         log.debug("Counterparty not part of this transaction. Ignoring")
         return
     try:
         self.crypto_boxes[nick] = [maker_pk, as_init_encryption(
             self.kp, init_pubkey(maker_pk))]
     except NaclError as e:
         log.debug("Unable to setup crypto box with " + nick + ": " + repr(e))
         self.msgchan.send_error(nick, "invalid nacl pubkey: " + maker_pk)
         return
     # send authorisation request
     log.debug("Starting auth, utxos: " + pprint.pformat(self.input_utxos))
     if self.auth_addr:
         my_btc_addr = self.auth_addr
     else:
         my_btc_addr = self.input_utxos.itervalues().next()['address']
     log.debug("Trying to get privkey")
     my_btc_priv = self.wallet.get_key_from_addr(my_btc_addr)
     log.debug("Trying to get pubkey")
     my_btc_pub = btc.privtopub(my_btc_priv)
     log.debug("Got pubkey: " + str(my_btc_pub))
     my_btc_sig = btc.ecdsa_sign(self.kp.hex_pk(), my_btc_priv)
     self.msgchan.send_auth(nick, my_btc_pub, my_btc_sig)