def is_mnemonic_checksum_valid(mnemonic, language='english', word_list_dir=None, word_list=None): if word_list is None: word_list = load_word_list(language, word_list_dir) elif not isinstance(word_list, list) or len(word_list) != 2048: raise TypeError("invalid word list type") mnemonic = mnemonic.split() word_count = len(mnemonic) if word_count not in [12, 15, 18, 21, 24]: raise ValueError( 'Number of words must be one of the following: [12, 15, 18, 21, 24]' ) codes = {w: c for c, w in enumerate(word_list)} entropy_int = 0 bit_size = word_count * 11 chk_sum_bit_len = word_count * 11 % 32 for w in mnemonic: entropy_int = (entropy_int << 11) | codes[w] chk_sum = entropy_int & (2**chk_sum_bit_len - 1) entropy_int = entropy_int >> chk_sum_bit_len entropy = entropy_int.to_bytes((bit_size - chk_sum_bit_len) // 8, byteorder="big") if (sha256(entropy)[0] >> (8 - chk_sum_bit_len)) != chk_sum: return False return True
def entropy_to_mnemonic(entropy, language='english', word_list_dir=None, word_list=None): """ Convert entropy to mnemonic words string. :param str,bytes entropy: random entropy HEX encoded or bytes string. :param str language: (optional) uses word list language (chinese_simplified, chinese_traditional, english, french, italian, japanese, korean, spanish), by default is english. :param str word_list_dir: (optional) path to a directory containing a list of words, by default None (use BIP39 standard list) :param list word_list: (optional) already loaded word list, by default None :return: mnemonic words string. """ if isinstance(entropy, str): entropy = bytes.fromhex(entropy) if not isinstance(entropy, bytes): raise TypeError("entropy should be bytes or hex encoded string") if len(entropy) not in [16, 20, 24, 28, 32]: raise ValueError( 'entropy length should be one of the following: [16, 20, 24, 28, 32]') if word_list is None: word_list = load_word_list(language, word_list_dir) elif not isinstance(word_list, list) or len(word_list) != 2048: raise TypeError("invalid word list type") i = int.from_bytes(entropy, byteorder="big") # append checksum b = len(entropy) * 8 // 32 i = (i << b) | (sha256(entropy)[0] >> (8 - b)) return " ".join([word_list[i.__rshift__(((d - 1) * 11)) & 2047] for d in range(int((len(entropy) * 8 + 8) // 11), 0, -1)])
def script_to_hash(script, witness=False, hex=True): """ Encode script to hash HASH160 or SHA256 in dependency of the witness. :param script: script in bytes or HEX encoded string. :param witness: (optional) If set to True return SHA256 hash for P2WSH, by default is False. :param hex: (optional) If set to True return key in HEX format, by default is True. :param sub_script: sub_script which is necessary to remove from target script in bytes or HEX encoded string. :return: script in bytes or HEX encoded string corresponding to the format of target script. """ script = get_bytes(script) return sha256(script, hex) if witness else hash160(script, hex)
def __init__(self, script, testnet=False, witness_version=0): self.witness_version = witness_version self.testnet = testnet if isinstance(script, str): script = bytes.fromhex(script) self.script = script self.script_hex = self.script.hex() if witness_version is None: self.hash = hash160(self.script) else: self.hash = sha256(self.script) self.script_opcodes = decode_script(self.script) self.script_opcodes_asm = decode_script(self.script, 1) self.address = hash_to_address(self.hash, script_hash=True, witness_version=self.witness_version, testnet=self.testnet)
def mnemonic_to_entropy(mnemonic, language='english', word_list_dir=None, word_list=None, hex=True, checksum=True): """ Converting mnemonic words to entropy. :param str mnemonic: mnemonic words string (space separated) :param str language: (optional) uses word list language (chinese_simplified, chinese_traditional, english, french, italian, japanese, korean, spanish), by default is english. :param str word_list_dir: (optional) path to a directory containing a list of words, by default None (use BIP39 standard list) :param list word_list: (optional) already loaded word list, by default None :param boolean hex: return HEX encoded string result flag, by default True. :return: bytes string. """ if word_list is None: word_list = load_word_list(language, word_list_dir) elif not isinstance(word_list, list) or len(word_list) != 2048: raise TypeError("invalid word list type") mnemonic = mnemonic.split() word_count = len(mnemonic) if word_count not in [12, 15, 18, 21, 24]: raise ValueError( 'Number of words must be one of the following: [12, 15, 18, 21, 24]' ) codes = {w: c for c, w in enumerate(word_list)} entropy_int = 0 bit_size = word_count * 11 chk_sum_bit_len = word_count * 11 % 32 for w in mnemonic: entropy_int = (entropy_int << 11) | codes[w] chk_sum = entropy_int & (2**chk_sum_bit_len - 1) entropy_int = entropy_int >> chk_sum_bit_len entropy = entropy_int.to_bytes((bit_size - chk_sum_bit_len) // 8, byteorder="big") if checksum: if (sha256(entropy)[0] >> (8 - chk_sum_bit_len)) != chk_sum: raise ValueError("invalid mnemonic checksum") return entropy if not hex else entropy.hex()
def __sign_p2sh_p2wsh_multisig(self, n, private_key, public_key, redeem_script, sighash_type, amount): self["segwit"] = True script_code = int_to_var_int(len(redeem_script)) + redeem_script sighash = self.sig_hash_segwit(n, amount, script_pub_key=script_code, sighash_type=sighash_type) sighash = bytes.fromhex(sighash) if isinstance(sighash, str) else sighash sig = [sign_message(sighash, p, 0) + bytes([sighash_type]) for p in private_key] self["vIn"][n]['signatures'] = [s if self["format"] == "raw" else s.hex() for s in sig] if "txInWitness" not in self["vIn"][n]: self["vIn"][n]["txInWitness"] = [] witness = self.__get_multisig_script_sig__(self["vIn"][n]["txInWitness"], public_key, sig, script_code, redeem_script, n, amount) if self["format"] == "raw": self["vIn"][n]['txInWitness'] = list(witness) else: self["vIn"][n]["txInWitness"] = list([w.hex() for w in witness]) # calculate P2SH redeem script from P2WSH redeem script return op_push_data(b"\x00" + op_push_data(sha256(redeem_script)))