MultiversX Tracker is Live!

Lost 3 words out of 12, and not sure of order, mnemonic seed

Bitcoin Stack Exchange

Bitcoin News / Bitcoin Stack Exchange 146 Views

Since you have the checksum, and a majority of the words, I believe working with the binary or hex would be faster.

I don't know how much you know, or don't, so I'm going to start from the beginning, but I'm going to keep it simple by not including information that is not needed for this task.

A seed phrase is created by using a random number of some length, between 128 bits to 256 bits. This number is then hashed, and a portion of it is taken from the begining and extends the size of the original number.

These extra bits are the checksum.

For a seed phrase that is 12 words long, this checksum is 4 bits in length, and the original number is 128 bits long. For a total of 132 bits.

Eleven bits are needed to select a word.

Having the last word means, not only do you have the checksum, you have 7 other bits that precede it.

Your first three words being known, you also have the first 33 bits in order.

I do question if you mean you are missing the words 9, 10, and 11; or if these missing words are intended to be mixed in the assorted known words. In your code, your order your words as such:

[first 3 words] [5 words assorted order] [random 2 words] [last word]

If this is the case, I would

  1. convert my words into their numbers
  2. do a permutation on the known words (permutation will eliminate redundant checks)
  3. increment a number and append it for the missing section (include padding)
  4. append the first 7 bits from the last word
  5. hash for checksum and compare returned checksum to original checksum

If I have a match, I might log this seed. But I would prefer do a check for a balance at that time.

The reason I would log them (note below on why I wouldn't), and this is homework for you. I don't know how you went about going from seed to address when you created your address initially. I am not confident that you will get an address match if you stumbled upon your correct seed without this information. This is only because you might have used a different tool than you are now, which may have used a different derivation path. The tool you have in your code uses:

DEFAULT_DERIVATION_PATH = "m/44'/394'/0'/0/0"
DEFAULT_BECH32_HRP = "cro"

Source: https://github.com/crypto-org-chain/chainlibpy/blob/master/chainlibpy/wallet.py

Note: A permutation of 5 words from a list of 5 words will yield 120 iterations To get through 33 missing bits, you'll go through 8,589,934,592 rounds to finish that search space. For a grand total of 1,030,792,151,040 attempts at max, if it happened to be the last one, my computer should be able to finish that entire space in a night. This would be the reason why you should figure out how your seed words where converted to your address, on a bad day with long words, it could push into several terrabytes and take much longer for all those reads and writes to disk.

from hashlib import sha256
from binascii import unhexlify
from itertools import permutations
#Wordlist, ideally you'd save as a file and import
#wordlist = [2048 words]
#Settings
FIRST_THREE = ["word", "word", "word"]
KNOWN_FIVE = ["word", "word", "word", "word", "word"]
# I kept as list so I don't have to write a dynamic function to operate on lists or strings
LAST_WORD = ["word"]
#Returns a list of same length with strings of binary without the "0b" binary prefix
bin_formatter = lambda my_words: [format(wordlist.index(word), "011b") for word in my_words]
def main(): #Initialize setup # 1. convert words into their numbers main_section = {} # First section can be joined because it will not change main_section["first_section"] = "".join(bin_formatter(FIRST_THREE)) # 2. Handling the permutation now, will join on each iteration main_section["second_section"] = permutations(bin_formatter(KNOWN_FIVE), 5) # 1.3 Last section is split into the 7 bits and checksum bits main_section["last_section"] = {} _temp_last_word = bin_formatter(LAST_WORD)[0] main_section["last_section"]["primary_bits"], main_section["last_section"]["checksum"] = _temp_last_word[:7], _temp_last_word[7:] #Main loop over permutations for ss in main_section["second_section"]: # 3. increment a number and append it for the missing section (include padding) for missing in range(8589934592): #Using format to exclude "0b" prefix; specifying to add enough 0's to make it 33 bits long, zeros are added on left side missing_binary = format(missing, "033b") # 4. append the first 7 bits from the last word binary_representation = main_section["first_section"] + "".join(ss) + missing_binary + main_section["last_section"]["primary_bits"] #Hash prep hex_representation = format(int(binary_representation, 2), "032x") computer_ready_bytes = unhexlify(hex_representation) # 5. hash for checksum and compare returned checksum to original checksum hash_result = sha256(computer_ready_bytes).hexdigest() #One hex symbol is equivalent to 4 bits, convert it to int then to binary with padding checksum_result = format(int(hash_result[0], 16), '04b') if main_section["last_section"]["checksum"] == checksum_result: #append to file #perform confirmation steps #whichever suits you
main()

Working Example, nearly identical code above, but with test case built-in. Wordlist is imported, I put a gist with the english wordlist with "\n" character stripped, place this file in same folder and execute. https://gist.github.com/Gerschel/030f703deab4d47500748b7958f5c17c

from hashlib import sha256
from binascii import unhexlify
from itertools import permutations
#Test words
#['vague', 'salute', 'start', 'title', 'opinion', 'fancy', 'skate', 'arrange', 'meadow', 'absent', 'segment', 'blush']
#Missing target
target = ["meadow", "absent", "segment"]
#Test bits
#'11110000101101111101101101010010111100010111100110110110101001011111001010000000011000101000100110100000000101110000110010001100'
#Test checksum
#'0100'
#Test full bits
#'111100001011011111011011010100101111000101111001101101101010010111110010100000000110001010001001101000000001011100001100100011000100'
#Wordlist, ideally you'd save as a file and import
from english import wordlist
#Settings
FIRST_THREE = ["vague", "salute", "start"]
KNOWN_FIVE = ["title", "opinion", "fancy", "skate", "arrange"]
# I kept as list so I don't have to write a dynamic function to operate on lists or strings
LAST_WORD = ["blush"]
#Returns a list of same length with strings of binary without the "0b" binary prefix
bin_formatter = lambda my_words: [format(wordlist.index(word), "011b") for word in my_words]
def main(): #Initialize setup # 1. convert words into their numbers main_section = {} # First section can be joined because it will not change main_section["first_section"] = "".join(bin_formatter(FIRST_THREE)) # 2. Handling the permutation now, will join on each iteration main_section["second_section"] = permutations(bin_formatter(KNOWN_FIVE), 5) # 1.3 Last section is split into the 7 bits and checksum bits main_section["last_section"] = {} _temp_last_word = bin_formatter(LAST_WORD)[0] main_section["last_section"]["primary_bits"], main_section["last_section"]["checksum"] = _temp_last_word[:7], _temp_last_word[7:] #Main loop over permutations found = False for ss in main_section["second_section"]: # 3. increment a number and append it for the missing section (include padding) for missing in range(4615000000,4619000000): #Using format to exclude "0b" prefix; specifying to add enough 0's to make it 33 bits long, zeros are added on left side missing_binary = format(missing, "033b") # 4. append the first 7 bits from the last word binary_representation = main_section["first_section"] + "".join(ss) + missing_binary + main_section["last_section"]["primary_bits"] #Hash prep hex_representation = format(int(binary_representation, 2), "032x") computer_ready_bytes = unhexlify(hex_representation) # 5. hash for checksum and compare returned checksum to original checksum hash_result = sha256(computer_ready_bytes).hexdigest() #One hex symbol is equivalent to 4 bits, convert it to int then to binary with padding checksum_result = format(int(hash_result[0], 16), '04b') if main_section["last_section"]["checksum"] == checksum_result: res_words = [] bits = binary_representation + checksum_result for e in range(0, len(bits), 11): res_words.append(wordlist[int(bits[e: e+11], 2)]) if res_words[8:11] == target: found = True break print(f"Match: {res_words[8:11] == target}\t\t {res_words[8:11]}", end="\r") if found: print(res_words) break
main()

Get BONUS $200 for FREE!

You can get bonuses upto $100 FREE BONUS when you:
πŸ’° Install these recommended apps:
πŸ’² SocialGood - 100% Crypto Back on Everyday Shopping
πŸ’² xPortal - The DeFi For The Next Billion
πŸ’² CryptoTab Browser - Lightweight, fast, and ready to mine!
πŸ’° Register on these recommended exchanges:
🟑 Binance🟑 Bitfinex🟑 Bitmart🟑 Bittrex🟑 Bitget
🟑 CoinEx🟑 Crypto.com🟑 Gate.io🟑 Huobi🟑 Kucoin.



Comments