def test_conversions(self): entropy = '10101011' * 32 str_entropy = str_from_entropy(entropy) self.assertEqual(len(str_entropy), 256) self.assertEqual(str_entropy, entropy) bytes_entropy = _bytes_from_entropy(entropy) self.assertEqual(len(bytes_entropy), 32) int_entropy = _int_from_entropy(entropy) self.assertEqual(int_entropy.bit_length(), 256) str_entropy = str_from_entropy(bytes_entropy) self.assertEqual(len(str_entropy), 256) self.assertEqual(str_entropy, entropy) bytes_entropy = _bytes_from_entropy(bytes_entropy) self.assertEqual(len(bytes_entropy), 32) int_entropy = _int_from_entropy(bytes_entropy) self.assertEqual(int_entropy.bit_length(), 256) str_entropy = str_from_entropy(int_entropy) self.assertEqual(len(str_entropy), 256) self.assertEqual(str_entropy, entropy) bytes_entropy = _bytes_from_entropy(int_entropy) self.assertEqual(len(bytes_entropy), 32) int_entropy = _int_from_entropy(int_entropy) self.assertEqual(int_entropy.bit_length(), 256)
def test_exceptions(self): entropy = '00101010' * 31 entropy = entropy[2:] # 246 bits str_entropy = str_from_entropy(entropy, 246) bytes_entropy = _bytes_from_entropy(entropy, 246) int_entropy = _int_from_entropy(entropy, 246) invalid_entropy = tuple() self.assertRaises(ValueError, str_from_entropy, str_entropy) self.assertRaises(ValueError, str_from_entropy, bytes_entropy) self.assertRaises(ValueError, str_from_entropy, -1 * int_entropy) self.assertEqual(len(str_from_entropy(int_entropy)), 256) self.assertRaises(TypeError, str_from_entropy, invalid_entropy) self.assertRaises(ValueError, _int_from_entropy, str_entropy) self.assertRaises(ValueError, _int_from_entropy, bytes_entropy) self.assertRaises(ValueError, _int_from_entropy, -1 * int_entropy) self.assertEqual(_int_from_entropy(int_entropy), int_entropy) self.assertRaises(TypeError, _int_from_entropy, invalid_entropy) self.assertRaises(ValueError, _bytes_from_entropy, str_entropy) self.assertRaises(ValueError, _bytes_from_entropy, bytes_entropy) self.assertRaises(ValueError, _bytes_from_entropy, -1 * int_entropy) self.assertEqual(len(_bytes_from_entropy(int_entropy)), 32) self.assertRaises(TypeError, _bytes_from_entropy, invalid_entropy)
def test_leading_zeros(self): entropy = '00101010' * 32 str_entropy = str_from_entropy(entropy, 256) self.assertEqual(len(str_entropy), 256) self.assertEqual(str_entropy, entropy) bytes_entropy = bytes_from_entropy(entropy, 256) self.assertEqual(len(bytes_entropy), 32) int_entropy = int_from_entropy(entropy) self.assertEqual(int_entropy.bit_length(), 254) str_entropy = str_from_entropy(bytes_entropy, 256) self.assertEqual(len(str_entropy), 256) self.assertEqual(str_entropy, entropy) bytes_entropy = bytes_from_entropy(bytes_entropy, 256) self.assertEqual(len(bytes_entropy), 32) int_entropy = int_from_entropy(bytes_entropy) self.assertEqual(int_entropy.bit_length(), 254) str_entropy = str_from_entropy(int_entropy, 254) self.assertEqual(len(str_entropy), 254) self.assertEqual(str_entropy, entropy[2:]) bytes_entropy = bytes_from_entropy(int_entropy, 254) self.assertEqual(len(bytes_entropy), 32) int_entropy = int_from_entropy(int_entropy) self.assertEqual(int_entropy.bit_length(), 254)
def test_leading_zeros(self): entropy = '00101010' * 32 str_entropy = str_from_entropy(entropy) self.assertEqual(len(str_entropy), 256) self.assertEqual(str_entropy, entropy) bytes_entropy = _bytes_from_entropy(entropy) self.assertEqual(len(bytes_entropy), 32) int_entropy = _int_from_entropy(entropy) self.assertEqual(int_entropy.bit_length(), 254) str_entropy = str_from_entropy(bytes_entropy) self.assertEqual(len(str_entropy), 256) self.assertEqual(str_entropy, entropy) bytes_entropy = _bytes_from_entropy(bytes_entropy) self.assertEqual(len(bytes_entropy), 32) int_entropy = _int_from_entropy(bytes_entropy) self.assertEqual(int_entropy.bit_length(), 254) str_entropy = str_from_entropy(int_entropy, 254) self.assertEqual(len(str_entropy), 254) self.assertEqual(str_entropy, entropy[2:]) bytes_entropy = _bytes_from_entropy(int_entropy, 254) self.assertEqual(len(bytes_entropy), 32) int_entropy = _int_from_entropy(int_entropy) self.assertEqual(int_entropy.bit_length(), 254) # the 32 bytes integer has its leftmost bit set to 0 int_entropy = random.getrandbits(255) self.assertEqual(len(str_from_entropy(int_entropy)), 256) # 257 bits int_entropy = 1 << 256 str_entropy = str_from_entropy(int_entropy) self.assertEqual(len(str_entropy), 256) exp_int_entropy = int_entropy >> 1 self.assertEqual(_int_from_entropy(str_entropy), exp_int_entropy)
def electrum_mnemonic_from_raw_entropy(raw_entropy: GenericEntropy, lang: str, eversion: str) -> str: # electrum considers entropy as integer, losing any leading zero # https://github.com/spesmilo/electrum/blob/master/lib/mnemonic.py int_entropy = int_from_entropy(raw_entropy) assert eversion in ELECTRUM_MNEMONIC_VERSIONS, "unknown electrum mnemonic version" invalid = True while invalid: str_entropy = str_from_entropy(int_entropy) indexes = mnemonic_dict.indexes_from_entropy(str_entropy, lang) mnemonic = mnemonic_dict.mnemonic_from_indexes(indexes, lang) # version validity check s = hmac.new(b"Seed version", mnemonic.encode('utf8'), sha512).hexdigest() if s.startswith(ELECTRUM_MNEMONIC_VERSIONS[eversion]): invalid = False # next trial int_entropy += 1 return mnemonic
def test_exceptionss(self): entropy = '00101010' * 31 entropy = entropy[2:] # 246 bits str_entropy = str_from_entropy(entropy) bytes_entropy = bytes_from_entropy(entropy) int_entropy = int_from_entropy(bytes_entropy) invalid_entropy = tuple() self.assertRaises(ValueError, str_from_entropy, str_entropy, 256) self.assertRaises(ValueError, str_from_entropy, bytes_entropy, 256) self.assertRaises(ValueError, str_from_entropy, -1*int_entropy, 256) self.assertRaises(ValueError, str_from_entropy, int_entropy, 256) self.assertRaises(TypeError, str_from_entropy, invalid_entropy, 256) self.assertRaises(ValueError, int_from_entropy, -1*int_entropy) self.assertRaises(TypeError, int_from_entropy, invalid_entropy) self.assertRaises(ValueError, bytes_from_entropy, str_entropy, 256) self.assertRaises(ValueError, bytes_from_entropy, bytes_entropy, 256) self.assertRaises(ValueError, bytes_from_entropy, -1*int_entropy, 256) self.assertRaises(ValueError, bytes_from_entropy, int_entropy, 256) self.assertRaises(TypeError, bytes_from_entropy, invalid_entropy, 256)
def mnemonic_from_raw_entropy(raw_entropy: GenericEntropy, lang: str, eversion: str) -> str: # electrum considers entropy as integer, losing any leading zero # https://github.com/spesmilo/electrum/blob/master/lib/mnemonic.py int_entropy = int_from_entropy(raw_entropy) if eversion not in ELECTRUM_MNEMONIC_VERSIONS: m = f"mnemonic version '{eversion}' not in electrum allowed " m += f"mnemonic versions {list(ELECTRUM_MNEMONIC_VERSIONS.keys())}" raise ValueError(m) invalid = True while invalid: str_entropy = str_from_entropy(int_entropy) indexes = mnemonic_dict.indexes_from_entropy(str_entropy, lang) mnemonic = mnemonic_dict.mnemonic_from_indexes(indexes, lang) # version validity check s = hmac.new(b"Seed version", mnemonic.encode('utf8'), sha512).hexdigest() if s.startswith(ELECTRUM_MNEMONIC_VERSIONS[eversion]): invalid = False # next trial int_entropy += 1 return mnemonic
def entropy_from_raw_entropy(raw_entropy: GenericEntropy) -> Entropy: raw_entropy = str_from_entropy(raw_entropy, _allowed_raw_entr_bits) checksum = _raw_entropy_checksum(raw_entropy) return raw_entropy + checksum