Восстановление кошелька HD из частичной семенной фразы

Я пытаюсь помочь восстановить кошелек, где владелец только записал 11 из 12 слов в семенной фразе. Первоначально я думал, что задача будет быстрой и четко определенной, но, похоже, она немного сложнее, чем я предполагал, а справочный материал довольно скудный. В случае, если у кого-то есть аналогичная проблема с моей, я хочу оставить это сообщение, подробно описывая шаги, которые я выполнил (с образцами рабочего кода).

Кошелек, с которым я имею дело, - это Breadwallet, который, по-видимому, использует другую (более старую) стратегию деривации мнемосхемы-HD-master-private-key из большинства современных кошельков. На данный момент я собираюсь сосредоточиться на восстановлении частичных фраз Breadwallet, но я планирую в конечном итоге расширить ответ, чтобы охватить более новые стратегии деривации ( BIP44 ).

5 голосов | спросил LivingInformation 25 Jam1000000amMon, 25 Jan 2016 09:25:52 +030016 2016, 09:25:52

1 ответ


5

(Язык, используемый в этом сообщении, - Python)

Breadwallet использует BIP39 , чтобы генерировать 128-битное начальное семя из 12- слово мнемоника. Затем основное семя используется для создания набора кошельков /учетных записей, содержащих цепочки адресов, с помощью BIP32 .

https : //github.com/bitcoin/bips/raw/master/bip-0032/derivation.png


Во-первых, импортируйте hashlib и binascii, мы будем нуждаться в них позже.

import hashlib
from binascii import hexlify, unhexlify

Предположим, что у вас есть 11 из 12 слов в семенной фразе. Для простоты я буду использовать первые 11 слов в списке слов BIP39:

partial_seed_phrase = [ 'abandon', 'ability', 'able', 'about', 'above', 'absent', 'absorb', 'abstract', 'absurd', 'abuse', 'access' ]

Список слов содержит 2048 записей, которые дают каждому слову 11 бит энтропии (2 11 = 2048). 12 слов содержат 12 * 11 = 132 бита энтропии. Начальное семя HD имеет длину 128 бит, а к концу добавляется 4-битная контрольная сумма, которая суммирует до 132. До сих пор это было хорошо.

Если мы предположим, что wordlist - это список из 2048 элементов (опущено из-за ограничений пространства), мы можем найти индекс ( в десятичной форме) элементов в partial_seed_phrase:

mnemonic_in_decimal = map(wordlist.index, partial_seed_phrase)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Давайте преобразуем mnemonic_in_decimal в массив из двоичных чисел с шириной 11 бит.

mnemonic_in_binary = map('{0:011b}'.format, mnemonic_in_decimal)
# ['00000000000', '00000000001', '00000000010', '00000000011', '00000000100', '00000000101', '00000000110', '00000000111', '00000001000', '00000001001', '00000001010']

Мы знаем, что в некотором неизвестном месте в этом массиве отсутствует одно слово (11 бит). В неидеальных обстоятельствах мы должны были бы проверить каждое из 12 мест для пропущенного слова на 2048 возможных слов каждый, в общей сложности 24576 (12 * 2048 = 24576) потенциальных основных семян.

for missing_word_position in range(0,12):
    # The missing word belongs at some index from 0-11 in the final 12-word phrase

    for wordlist_index in range(0, 2048):
        # Iterate over all possibilities for the missing word

        missing_word_binary = '{0:011b}'.format(wordlist_index)
        front_half          = ''.join(mnemonic_in_binary[0:missing_word_position])
        back_half           = ''.join(mnemonic_in_binary[missing_word_position:12])
        seed_and_checksum   = front_half + missing_word_binary + back_half

        seed     = seed_and_checksum[0:128]
        checksum = seed_and_checksum[-4:]

К счастью, у нас есть 4-битная контрольная сумма, что означает, что только один из каждых 16 семян (2 4 = 16) будет действителен. Это означает, что мы получим итоговое общее количество примерно 1536 семян мастера (24576/16 = 1536) для проверки средств. Контрольная сумма выводится из первых битов (в этом случае 4), возвращенных путем применения хеш-функции SHA-256 к семени, поэтому конечное число допустимых основных семян может меняться, но в среднем будет составлять около 1/16 всего возможных семян.

[Позднее, если кто-то хочет помочь написать описания или код для любого из следующих шагов, я был бы признателен! ]

Сделать:

  1. Вычислить actual_checksum из первых 4 бит sha256 (seed)
  2. сравнить контрольную сумму с actual_checksum. Если они равны, нажмите семя в массив правильных семенных семян.
  3. Вычислить главный узел, который представляет собой HMAC-SHA512 (семя)
  4. Вычислить учетную запись с главного узла
  5. Вычислить цепочку кошельков из учетной записи
  6. Вычислить первые 5 закрытых ключей в цепочке кошельков
  7. Вычислить первые 5 открытых ключей из этих закрытых ключей
  8. Запишите описание и шаги для восстановления частичных фраз для кошельков BIP44
  9. Напишите программу, чтобы запросить локальную цепочку или интерактивный API-интерфейс blockchain. Передайте ему объединенный список сгенерированных открытых ключей и посмотрите, есть ли у них баланс.
ответил LivingInformation 25 Jam1000000amMon, 25 Jan 2016 09:25:52 +030016 2016, 09:25:52

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132