def get_passphrase(): while True: my_encoded_and_normalized_passphrase = get_passphrase_inner() if my_encoded_and_normalized_passphrase == b'': return b'' print ("Do you want to see the hash of your passphrase now?") print ("(Security risk: the hash can help attackers bruteforce your passphrase.)") print ("Answer \"short\" if you want to see only two words of the hash.") answer = yes_or_short_or_no() if answer == "yes": print ("The hash of your passphrase is:", key_to_english(blake2b(my_encoded_and_normalized_passphrase,digest_size=8).digest()), "\n") elif answer == "short": splitted_hash = key_to_english(blake2b(my_encoded_and_normalized_passphrase,digest_size=8).digest()).split() print ("The hash of your passphrase is: (only first two words)", splitted_hash[0], splitted_hash[1], "\n") print ("Do you want to continue with this passphrase?") answer = yes_or_no() if answer == "yes": return my_encoded_and_normalized_passphrase else: continue
def test1(self): data = [('EB33F77EE73D4053', 'TIDE ITCH SLOW REIN RULE MOT'), ('CCAC2AED591056BE4F90FD441C534766', 'RASH BUSH MILK LOOK BAD BRIM AVID GAFF BAIT ROT POD LOVE'), ('EFF81F9BFBC65350920CDD7416DE8009', 'TROD MUTE TAIL WARM CHAR KONG HAAG CITY BORE O TEAL AWL')] for key_hex, words in data: key_bin = binascii.a2b_hex(key_hex) w2 = key_to_english(key_bin) self.assertEqual(w2, words) k2 = english_to_key(words) self.assertEqual(k2, key_bin)
def get_big_enough_chunk_of_salt(): while True: mysalt = read_salt() mysalt_len = len(mysalt) print ("\nThe size of the salt is", mysalt_len, "bytes.") print ("The salt in hex format: ", binascii.b2a_hex(mysalt).decode("utf-8")) print ("The salt:", mysalt) print ("The hash of the salt is:", key_to_english(blake2b(mysalt,digest_size=8).digest()), "\n") if mysalt_len < 16: print ("The salt is too small. It should be at least 16 bytes.") else: break return mysalt
def print_128_bit_secret(label,my_128_bit_secret): my_128_bit_secret_HEX = binascii.b2a_hex(my_128_bit_secret).decode("utf-8") print ("\n\nThe", label, "128-bit digest in hex format:", my_128_bit_secret_HEX) print ("\nThe", label, "128-bit digest in base64 format:", binascii.b2a_base64(my_128_bit_secret).decode("utf-8")) print ("\nThe", label, "128-bit digest in BIP39 mnemonic format:\n\n", mnemonic.Mnemonic('english').to_mnemonic(my_128_bit_secret)) print ("\n\nThe", label, "128-bit digest in RFC1751 mnemonic format:\n\n", key_to_english(my_128_bit_secret)) my_128_bit_secret_decimal = string_to_number(my_128_bit_secret) print ("\n\nThe", label, "128-bit digest in decimal format:\n\n", my_128_bit_secret_decimal) if my_128_bit_secret_decimal < 1000000000: print ("Warning! The key is too small! Do not use, small entropy!.")
def print_the_secrets(my_256_bit_secret): print ("\n\n========== 128-bit digests (12 BIP39 words): ==========") print ("\n\nThe two 128-bit digests are created by cutting the 256-bit digest.") print_128_bit_secret("FIRST",my_256_bit_secret[0:16]) print_128_bit_secret("SECOND",my_256_bit_secret[16:32]) print ("\n\nFor better security use only the 256-bit digest (24 BIP39 words).") print ("Don't forget that the two 128-bit digests were created by cutting the 256-bit digest in half.") print ("\n\n========== The same 256-bit digest in different formats: ==========") # we need it also for bitcoin.encode_privkey() my_256_bit_secret_HEX = binascii.b2a_hex(my_256_bit_secret).decode("utf-8") print ("\n\nThe 256-bit digest in hex format:", my_256_bit_secret_HEX) print ("\nThe 256-bit digest in base64 format:", binascii.b2a_base64(my_256_bit_secret).decode("utf-8")) print ("\nThe 256-bit digest in BIP39 mnemonic format:\n\n", mnemonic.Mnemonic('english').to_mnemonic(my_256_bit_secret)) print ("\n\nThe 256-bit digest in RFC1751 mnemonic format:\n\n", key_to_english(my_256_bit_secret)) CURVE_ORDER = 115792089237316195423570985008687907852837564279074904382605163141518161494337 my_256_bit_secret_decimal = string_to_number(my_256_bit_secret) print ("\n\nThe 256-bit digest in decimal format:\n\n", my_256_bit_secret_decimal) if my_256_bit_secret_decimal < ( CURVE_ORDER - 1000000000 ): if my_256_bit_secret_decimal > 1000000000: print ("Looks ok for a SECP256k1 private key.") else: print ("Looks too small for a private key.") else: print ("Looks too big for a SECP256k1 private key.") my_256_bit_secret_WIF = bitcoin.encode_privkey(my_256_bit_secret_HEX,"wif_compressed") print ("\n\nThe 256-bit digest in compressed WIF format:\n\n", my_256_bit_secret_WIF) print ("\nThe address derived from the above WIF key:",bitcoin.privkey_to_address(my_256_bit_secret_WIF))
mypassphrase_bytestring = get_passphrase() digest_512_bits = SlowKDF(mypassphrase_bytestring, mysalt, mymemory_stage_1, iterations_stage_1) if external_key_stretching == "yes": # up to 65535 - every number is encoded in two bytes second_stage_bytes = mymemory_stage_2.to_bytes( 2, 'big') + iterations_stage_2.to_bytes(2, 'big') data_for_export_192_bits = second_stage_bytes + make_digest_for_export_160_bits( digest_512_bits) print("\n\nRFC1751 words:\n\n", key_to_english(data_for_export_192_bits)) print( "\n\nHash for detecting errors:\t", key_to_english( blake2b(data_for_export_192_bits, digest_size=8).digest())) print( "\nPlease run the doubleslow-external.py script on the powerful computer and enter the above RFC1751 words there. Then, write below the output from the doubleslow-external.py script. \n\n" ) while True: try: words = input("RFC1751 words: ") digest_external = english_to_key(words) except ValueError as detail:
while True: try: words = input("RFC1751 words: ") input_data_192_bits = english_to_key(words) except ValueError as detail: print(detail) continue the_length_of_the_input = len(input_data_192_bits) if the_length_of_the_input != 24: print("We expected 24 bytes, got", the_length_of_the_input, "instead. Can't continue.") quit() print("\nThe word sequence looks valid. The hash is:\n\n", key_to_english(blake2b(input_data_192_bits, digest_size=8).digest())) answer = input( "\n\nPlease verify that the hash is correct and type \"yes\" to continue: " ).lower() if answer == "yes": break elif answer == "quit": quit() else: continue mymemory_stage_2 = int.from_bytes(input_data_192_bits[0:2], 'big') iterations_stage_2 = int.from_bytes(input_data_192_bits[2:4], 'big') input_digest = input_data_192_bits[4:]