def verify_nick(self, nick, sig, message): if not btc.ecdsa_verify(message + str(self.hostid), sig[1], sig[0]): log.debug("nick signature verification failed, ignoring.") return False #check that nick matches hash of pubkey nick_pkh_raw = hashlib.sha256(sig[0]).digest()[:NICK_HASH_LENGTH] nick_stripped = nick[2:2+NICK_MAX_ENCODED] #strip right padding nick_unpadded = ''.join([x for x in nick_stripped if x != 'O']) if not nick_unpadded == btc.changebase(nick_pkh_raw, 256, 58): log.debug("Nick hash check failed, expected: " + str( nick_unpadded) + ", got: " + str( btc.changebase(nick_pkh_raw, 256, 58))) return False return True
def base_encoder_tests(self): self.assertEqual(b.encode(1029, 256), '\x04\x05') self.assertEqual(b.decode('DEADBEEF', 16), 3735928559) r = random.randrange(2**256) self.assertEqual(b.decode(b.changebase(b.encode(r, 16), 16, 58), 58), r) self.assertEqual(b.base58export(b.base58check(r, 101, 34)), r)
def segwit_txhash(tx): if isinstance(tx, str) and re.match('^[0-9a-fA-F]*$', tx): tx = changebase(tx, 16, 256) tx_hash = txhash(tx) tx = strip_witness_data(tx) tx_id = txhash(tx) return {'hash': tx_hash, 'txid': tx_id}
def serialize_extended_key(version_bytes, depth, parent_key_fingerprint, child_number, extended_key): depth = depth.to_bytes(1, byteorder='big') index = child_number.to_bytes(4, byteorder='big') serialized = version_bytes + depth + parent_key_fingerprint + index + extended_key checksum = bitcoin.bin_dbl_sha256(serialized)[0:4] serialized += checksum return bitcoin.changebase(serialized, 256, 58)
def deserialize_extended_key(extended_key): binary_key = bytearray(bitcoin.changebase(extended_key, 58, 256)) binary_verify_checksum(binary_key, 4) (version_bytes, depth, parent_key_fingerprint, child_number, chain_code, key, checksum) = struct.unpack( '@4sc4s4s32s33s4s', binary_key) if version_bytes != extended_public_key_version_bytes: exit_with_error("Invalid version bytes on extended key") return version_bytes, depth, parent_key_fingerprint, child_number, chain_code, key
def generate_wif_from_key(childKey, network,compressed=True): prefix = public_wif_prefix if network == Network.MAINNET else testnet_wif_prefix wif_binary = prefix.to_bytes(1,'big') + childKey if compressed: wif_binary += 0x01.to_bytes(1,'big') checksum = bitcoin.bin_dbl_sha256(wif_binary)[0:4] wif = bitcoin.changebase(wif_binary + checksum, 256, 58) return wif
def bin_to_b58check(self, inp, magicbyte=0, magicbyte_length=1): inp_fmtd = int(magicbyte).to_bytes(magicbyte_length, 'big') + inp checksum = bitcoin.bin_dbl_sha256(inp_fmtd)[:4] leadingzbytes = 0 for x in inp_fmtd: if x != 0: break leadingzbytes += 1 return '1' * leadingzbytes + bitcoin.changebase(inp_fmtd + checksum, 256, 58)
def bip38_decrypt(encrypted_privkey, passphrase, wif=False): """ BIP0038 non-ec-multiply decryption. Returns hex privkey. """ passphrase = normalize('NFC', unicode(passphrase)) if is_py2: passphrase = passphrase.encode('utf8') d = unhexlify(changebase(encrypted_privkey, 58, 16, 86)) d = d[2:] flagbyte = d[0:1] d = d[1:] # respect flagbyte, return correct pair if flagbyte == b'\xc0': compressed = False if flagbyte == b'\xe0': compressed = True addresshash = d[0:4] d = d[4:-4] key = scrypt.hash(passphrase,addresshash, 16384, 8, 8) derivedhalf1 = key[0:32] derivedhalf2 = key[32:64] encryptedhalf1 = d[0:16] encryptedhalf2 = d[16:32] aes = AES.new(derivedhalf2) decryptedhalf2 = aes.decrypt(encryptedhalf2) decryptedhalf1 = aes.decrypt(encryptedhalf1) priv = decryptedhalf1 + decryptedhalf2 priv = unhexlify('%064x' % (long(hexlify(priv), 16) ^ long(hexlify(derivedhalf1), 16))) pub = privtopub(priv) if compressed: pub = encode_pubkey(pub,'hex_compressed') addr = pubtoaddr(pub) if is_py2: ascii_key = addr else: ascii_key = bytes(addr,'ascii') if sha256(sha256(ascii_key).digest()).digest()[0:4] != addresshash: raise Exception('Bip38 password decrypt failed: Wrong password?') else: formatt = 'wif' if wif else 'hex' if compressed: return encode_privkey(priv, formatt + '_compressed') else: return encode_privkey(priv, formatt)
def __init__(self, configdata, nick): super(DummyMC, self).__init__(configdata) #hacked in here to allow auth without mc-collection nick_priv = hashlib.sha256(os.urandom(16)).hexdigest() + '01' nick_pubkey = btc.privtopub(nick_priv) nick_pkh_raw = hashlib.sha256(nick_pubkey).digest()[:NICK_HASH_LENGTH] nick_pkh = btc.changebase(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. 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_single().JM_VERSION) + nick_pkh jm_single().nickname = nick self.set_nick(nick, nick_priv, nick_pubkey)
def bip38_encrypt(privkey, passphrase): """ BIP0038 non-ec-multiply encryption. Returns BIP0038 encrypted privkey. """ privformat = get_privkey_format(privkey) if privformat in ['wif_compressed','hex_compressed']: compressed = True flagbyte = b'\xe0' if privformat == 'wif_compressed': privkey = encode_privkey(privkey,'hex_compressed') privformat = get_privkey_format(privkey) if privformat in ['wif', 'hex']: compressed = False flagbyte = b'\xc0' if privformat == 'wif': privkey = encode_privkey(privkey,'hex') privformat = get_privkey_format(privkey) pubkey = privtopub(privkey) addr = pubtoaddr(pubkey) passphrase = normalize('NFC', unicode(passphrase)) if is_py2: ascii_key = addr passphrase = passphrase.encode('utf8') else: ascii_key = bytes(addr,'ascii') salt = sha256(sha256(ascii_key).digest()).digest()[0:4] key = scrypt.hash(passphrase, salt, 16384, 8, 8) derivedhalf1, derivedhalf2 = key[:32], key[32:] aes = AES.new(derivedhalf2) encryptedhalf1 = aes.encrypt(unhexlify('%0.32x' % (long(privkey[0:32], 16) ^ long(hexlify(derivedhalf1[0:16]), 16)))) encryptedhalf2 = aes.encrypt(unhexlify('%0.32x' % (long(privkey[32:64], 16) ^ long(hexlify(derivedhalf1[16:32]), 16)))) payload = b'\x01' + b'\x42' + flagbyte + salt + encryptedhalf1 + encryptedhalf2 checksum = sha256(sha256(payload).digest()).digest()[:4] # b58check for encrypted privkey privatkey = hexlify(payload + checksum).decode('ascii') return changebase(privatkey, 16, 58)
def __init__(self, mchannels): self.mchannels = mchannels #To keep track of chosen channels #for private messaging counterparties. self.active_channels = {} #To keep track of message channel status; #0: not started 1: started 2: failed/broken/inactive self.mc_status = dict([(x, 0) for x in self.mchannels]) #To keep track of counterparties having at least once #made their presence known on a channel self.nicks_seen = {} for mc in self.mchannels: self.nicks_seen[mc] = set() #callback to mark nicks as seen when they privmsg mc.on_privmsg_trigger = self.on_privmsg #keep track of whether we want to deliberately #shut down the connections self.give_up = False #only allow on_welcome() to fire once. self.welcomed = False #control access self.mc_lock = threading.Lock() #Create an ephemeral keypair for the duration #of this run, same across all message channels, #and set the nickname for all message channels using it. self.nick_priv = hashlib.sha256(os.urandom(16)).hexdigest() + '01' self.nick_pubkey = btc.privtopub(self.nick_priv) self.nick_pkh_raw = hashlib.sha256(self.nick_pubkey).digest()[ :NICK_HASH_LENGTH] 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' * (NICK_MAX_ENCODED - len(self.nick_pkh)) #The constructed length will be 1 + 1 + NICK_MAX_ENCODED self.nick = JOINMARKET_NICK_HEADER + str( jm_single().JM_VERSION) + self.nick_pkh jm_single().nickname = self.nick for mc in self.mchannels: mc.set_nick(self.nick, self.nick_priv, self.nick_pubkey)
def base_encoder_tests(self): self.assertEqual(b.encode(1029,256),'\x04\x05') self.assertEqual(b.decode('DEADBEEF',16),3735928559) r = random.randrange(2**256) self.assertEqual(b.decode(b.changebase(b.encode(r,16),16,58),58),r) self.assertEqual(b.base58export(b.base58check(r,101,34)),r)
def is_segwit(tx, hashcode=None): if isinstance(tx, str) and re.match('^[0-9a-fA-F]*$', tx): tx = changebase(tx, 16, 256) return tx[4:6] == b'\x00\x01'
def test_changebase(st, frm, to, minlen, res): assert btc.changebase(st, frm, to, minlen) == res