Większość użytkowników portfeli sprzętowych Ledger Nano wcześniej czy później dochodzi do etapu w którym zastanawia się czy do zdefiniowania nowego portfela można użyć zestawu własnych słów seed. Niektórzy z nas przypuszczalnie poszli o krok dalej i w ramach doświadczenia użyli losowo wybranych słów korzystając z opcji odtwarzania portfela. Wtedy niemal na pewno po zatwierdzeniu ostatniego słowa ujrzeli komunikat:
"Recovery phrase is invalid, retry"
Czy zatem oznacza to że użycie własnego seed do wygenerowania portfela jest niemożliwe? I tu miła niespodzianka. Jest to możliwe, choć z pewnymi ograniczeniami. Ale zacznijmy od początku. Pierwszym ograniczeniem, choć o tym zapewne wszyscy użytkownicy Ledger Nano wiedzą, jest fakt że wyrazy definiujące nasz seed muszą spełniać standard opisany w BIP39 (ang. Bitcoin Improvement Proposal numer 39 – więcej na temat tego czym są bitcoin improvement proposals możesz znaleźć tutaj). BIP39 jest to nic innego jak zestaw 2048 słów pochodzących z języka angielskiego, który został wyselekcjonowany w taki sposób że pierwsze 4 litery każdego wyrazu jednoznacznie go identyfikują. Mówiąc innymi słowy w żadnym z tych 2048 wyrazów pierwsze 4 litery nigdy się nie powtarzają. Co ważne – warunek ten uwzględnia także występujące w zbiorze wyrazy trzyliterowe. Dzięki tak zdefiniowanej selekcji wyrazy te w zamyśle mają być łatwiejsze do zapamiętania w sytuacji, gdy chcemy zapamiętać ich pewną sekwencję. A przecież dokładnie tym właśnie jest nasz seed.
Drugie ograniczenie jest takie że ostatni wyraz definujący nasz seed nie jest dowolny, ale stanowi tzw. sumę kontrolną (ang. checksum) zestawu wszystkich słów go poprzedzających. Inaczej rzecz ujmując jest on ściśle określoną wypadkową sekwencji poprzedzających go słów, z tym że nie tylko sam wybór słów ma tutaj znaczenie, ale także ich kolejność w sekwencji. To właśnie ten warunek stanowi przyczynę komunikatu błędu, który wyskakuje ilekroć próbujemy wprowadzić własne (albo losowe) słowa przy tworzeniu portfela. Zwykle warunek sumy kontrolnej dla danego zestawu słów jest spełniony przez więcej niż jeden wyraz, ale szansa na jego wyznaczenie w drodze losowania jest niewielka. Ilość słów spełniających warunek sumy kontrolnej zależy ściśle od liczby wyrazów składających się na nasz seed. W przypadku seed składającego się z 24 wyrazów (najlepszy z punktu widzenia poziomu bezpieczeństwa) istnieje zawsze dokładnie 8 słów spełniających warunek sumy kontrolnej. Zatem szansa na wylosowanie dowolnego z nich ze zbioru 2048 wyrazów jest jak 8 do 2048, czyli dokładnie 0,00390625. Coż, nic dziwnego że zobaczyłeś komunikat błędu.
Jak zatem wyznaczyć słowo stanowiące sumę kontrolną dla samodzielnie wybranej sekwencji słów? Dla przykładu wybierzmy ze zbioru BIP39 losowy zestaw 23 wyrazów:
Każdemu z nich odpowiada jego indeks – numer wynikający z kolejności alfabetycznej wyrazów w specyfikacji BIP39. Ważne, żeby numeracja rozpoczynała się w tym przypadku od wartości 0. Indeksy należy wyrazić w systemie binarnym. Jako że mówimy o 2048 elementach, to każde binarne słowo indeksu musi składać się z 11 bitów. Zatem odnajdujemy:
W następnym kroku łączymy ze sobą kolejne indeksy binarne w jeden ciąg zachowując przy tym kolejność wyrazów naszego seed. Uzyskujemy w ten sposób 253-bitowe słowo:
Otrzymany wynik uzupełniamy na końcu o 3 dodatkowe bity dowolnej wartości.
Czy pamiętasz jak wspomnieliśmy o tym że dla 24 elementowego seed istnieje dokładnie 8 możliwych
wyrazów stanowiących jego sumę kontrolną? Liczba 8 wynika właśnie z tych trzech bitów.
Kolejne poszukiwane wyrazy wyznaczymy podstawiając w tym miejscu 000, 001, 010, 011, 100, 101, 110 i 111.
Na potrzeby naszego przykładu wybieramy 000.
Po dopisaniu tych 3 bitów uzyskujemy 256 bitowe słowo binarne:
Tak przygotowaną wartość poddajemy operacji haszowania (ang. hashing) w standardzie SHA256 (ang. secure hashing algorithm, 256-bitowe wyjście). Algorytm SHA256 stanowi podstawowy fundament technologii blockchain. Więcej na temat tego czym jest SHA256 możesz przeczytać w tym miejscu. W wyniku przeprowadzonej operacji haszowania otrzymujemy słowo wyrażone w systemie hexadecymalnym:
Z tego rezultatu bierzemy pierwsze 8 bitów, którym odpowiadają znaki 27 czyli:
Do nich dopisujemy, tym razem na początku, te same 3 bity, które wcześniej dopisaliśmy na końcu połączonych 23 indeksów.
W wyniku tego uzyskujemy:
co w kodzie binarnym wynosi 39. Jest to wartość indeksu poszukiwanego przez nas słowa, które stanowi sumę kontrolną i zarazem ostatni 24 element naszego seed. Nie zapominajmy że numer pierwszego elementu ma w naszym przypadku wartość 0 czyli przy standardowej numeracji rozpoczynającej się od 1 nasz poszukiwany element to 40. Odnajdujemy na liście BIP39 wyznaczony indeks i otrzymujemy odpowiadające mu słowo: agent Ostatecznie 24-wyrazowy seed zbudowany z samodzielnie wybranych przez nas 23 słów to:
Dla pozostałych 3-bitowych kombinacji ostatnim 24 wyrazem naszej sekwencji będzie odpowiednio: