Ich versuche, bei der Wiederherstellung einer Brieftasche zu helfen, bei der der Besitzer nur 11 der 12 Wörter in der Seed-Phrase aufgeschrieben hat. Anfangs dachte ich, die Aufgabe wäre schnell und gut definiert, aber sie scheint etwas komplexer zu sein, als ich angenommen hatte, und Referenzmaterial ist ziemlich spärlich. Für den Fall, dass jemand anderes ein ähnliches Problem wie ich hat, möchte ich diesen Beitrag hinterlassen, in dem die Schritte aufgeführt sind, die ich befolgt habe (mit funktionierenden Codebeispielen).
Die Brieftasche, mit der ich es zu tun habe, ist Breadwallet, die anscheinend eine andere (ältere) Mnemonik-zu-HD-Master-Private-Key-Ableitungsstrategie als die meisten modernen Brieftaschen verwendet. Im Moment werde ich mich nur auf die Wiederherstellung teilweiser Breadwallet-Phrasen konzentrieren, aber ich plane, die Antwort schließlich zu erweitern, um auch neuere Ableitungsstrategien ( BIP44 ) abzudecken.
(Die in diesem Beitrag verwendete Sprache ist Python)
Breadwallet verwendet BIP39 , um den 128-Bit-Master-Seed aus der 12-Wort-Mnemonik zu generieren. Der Master-Seed wird dann verwendet, um mithilfe von BIP32 eine Reihe von Wallets/Konten zu generieren, die Adressketten enthalten .
Importieren Sie zunächst hashlib und binascii, wir werden sie später brauchen.
import hashlib
from binascii import hexlify, unhexlify
Nehmen wir an, Sie haben 11 der 12 Wörter in Ihrer Startphrase. Der Einfachheit halber verwende ich die ersten 11 Wörter in der BIP39-Wortliste:
partial_seed_phrase = [ 'abandon', 'ability', 'able', 'about', 'above', 'absent', 'absorb', 'abstract', 'absurd', 'abuse', 'access' ]
Die Wortliste enthält 2048 Einträge, was jedem Wort 11 Entropiebits gibt (2 11 = 2048). Die 12 Wörter haben insgesamt 12*11 = 132 Bit Entropie. Der HD-Master-Seed ist 128 Bit lang, und am Ende ist eine 4-Bit-Prüfsumme angehängt, die die Gesamtbits auf 132 erhöht. So weit, so gut.
Wenn wir davon ausgehen, dass wordlist
es sich um eine Liste mit 2048 Elementen handelt (aus Platzgründen weggelassen), können wir den Index (in Dezimalzahl) der Elemente in finden partial_seed_phrase
:
mnemonic_in_decimal = map(wordlist.index, partial_seed_phrase)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Konvertieren wir mnemonic_in_decimal
in ein Array von 11 Bit breiten Binärzahlen.
mnemonic_in_binary = map('{0:011b}'.format, mnemonic_in_decimal)
# ['00000000000', '00000000001', '00000000010', '00000000011', '00000000100', '00000000101', '00000000110', '00000000111', '00000001000', '00000001001', '00000001010']
Wir wissen, dass ein einzelnes Wort (11 Bit) an einer unbekannten Stelle in diesem Array fehlt. Unter nicht idealen Umständen müssten wir jede der 12 Stellen auf das fehlende Wort gegen jeweils 2048 mögliche Wörter prüfen, für insgesamt 24576 (12*2048 = 24576) potenzielle Master-Seeds.
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:]
Zum Glück haben wir eine 4-Bit-Prüfsumme, was bedeutet, dass nur einer von 16 Seeds (2 4 = 16) gültig ist. Das bedeutet, dass wir am Ende eine Gesamtsumme von ungefähr 1536 Master-Seeds (24576/16 = 1536) haben werden, um auf Geldmittel zu prüfen. Die Prüfsumme wird aus den ersten Bits (in diesem Fall 4) abgeleitet, die durch Anwenden der SHA-256-Hash-Funktion auf den Seed zurückgegeben werden, sodass die endgültige Anzahl gültiger Master-Seeds variieren kann, aber im Durchschnitt bei etwa 1/16 liegt insgesamt mögliche Samen.
[ Mehr folgt später, wenn jemand helfen möchte, Beschreibungen oder Code für einen der folgenden Schritte zu schreiben, würde ich es schätzen! ]
Machen:
Ostende-aa
WohnenInformationen
rny