def on_JM_REQUEST_MSGSIG_VERIFY(self, msg, fullmsg, sig, pubkey, nick, hashlen, max_encoded, hostid): verif_result = True if not btc.ecdsa_verify(str(msg), sig, pubkey): # workaround for hostid, which sometimes is lowercase-only for some IRC connections if not btc.ecdsa_verify(str(msg[:-len(hostid)] + hostid.lower()), sig, pubkey): jlog.debug("nick signature verification failed, ignoring: " + str(nick)) verif_result = False #check that nick matches hash of pubkey nick_pkh_raw = btc.bin_sha256(pubkey)[:hashlen] nick_stripped = nick[2:2 + max_encoded] #strip right padding nick_unpadded = ''.join([x for x in nick_stripped if x != 'O']) if not nick_unpadded == btc.b58encode(nick_pkh_raw): jlog.debug("Nick hash check failed, expected: " + str(nick_unpadded) + ", got: " + str(btc.b58encode(nick_pkh_raw))) verif_result = False d = self.callRemote(commands.JMMsgSignatureVerify, verif_result=verif_result, nick=nick, fullmsg=fullmsg, hostid=hostid) self.defaultCallbacks(d) return {'accepted': True}
def make_valid_nick(i=0): nick_priv = hashlib.sha256(chr(i) * 16).hexdigest() + '01' nick_pubkey = bitcoin.privtopub(nick_priv) nick_pkh_raw = hashlib.sha256(nick_pubkey).digest()[:NICK_HASH_LENGTH] nick_pkh = bitcoin.b58encode(nick_pkh_raw) #right pad to maximum possible; b58 is not fixed length. #Use 'O' as one of the 4 not included chars in base58. nick_pkh += 'O' * (NICK_MAX_ENCODED - len(nick_pkh)) #The constructed length will be 1 + 1 + NICK_MAX_ENCODED return JOINMARKET_NICK_HEADER + str(JM_VERSION) + nick_pkh
def set_nick(self): self.nick_pubkey = btc.privtopub(self.nick_priv) self.nick_pkh_raw = btc.bin_sha256( self.nick_pubkey)[:self.nick_hashlen] self.nick_pkh = btc.b58encode(self.nick_pkh_raw) #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 informuser = getattr(self.client, "inform_user_details", None) if callable(informuser): informuser()
def get_dummy_nick(): """In Joinmarket-CS nick creation is negotiated between client and server/daemon so as to allow client to sign for messages; here we only ever publish an orderbook request, so no such need, but for better privacy, a conformant nick is created based on a random pseudo-pubkey.""" nick_pkh_raw = hashlib.sha256(os.urandom(10)).digest()[:NICK_HASH_LENGTH] nick_pkh = btc.b58encode(nick_pkh_raw) #right pad to maximum possible; b58 is not fixed length. #Use 'O' as one of the 4 not included chars in base58. nick_pkh += 'O' * (NICK_MAX_ENCODED - len(nick_pkh)) #The constructed length will be 1 + 1 + NICK_MAX_ENCODED nick = JOINMARKET_NICK_HEADER + str(JM_VERSION) + nick_pkh jm_single().nickname = nick return nick