Anatomie HD peněženky (BIP 32/39/44/84)
Deterministicky hierarchistická peněženka je software, který dokáže z tzv. počáteční entropie (následně zakonzerované ve slovech seedu) generovat prakticky neomezené množství klíčových párů a tedy i adres.
Při prvním spuštění (inicializaci) si taková peněženka, ideálně z několika různých zdrojů, vygeneruje zpravidla mezi 128 a 256 bity entropie. Za to ještě přidá prvních 4 až 8 bitů hashe (SHA256) této entropie, které slouží jako „kontrolní součet“. Toto číslo si následně rozdělíme na 12 až 24 částí po 11 bitech tak, aby každá část odpovídala pořadí slova ze slovníku 2048 slov. Tato slova seedu jsou zobrazená uživateli, který je v ideálním případě bezpečně a trvanlivě zaznamená a uchová. Taktéž peněženka si těchto 132 až 264 bitů dat uloží do své paměti.
Po inicializaci (a následně i při každém další spuštění) může být uživatel vyzván k zadání passphrase (pokud si její použití povolil). Poté je zavolána funkce PBKDF2 s hashováním HMAC-SHA512 a počtem iterací 2048. Na vstupu je jako parametr password řetězec slov seedu a jako parametr salt řetězec passphrase (v případě vypnuté passphrase prázdný) předsazený řetězcem "mnemonic". Výstupem funkce je 512bitový seed.
Když je pak seed jako message společně s řetězcem znaků „Bitcoin seed“ jako key přiveden na vstup funkce HMAC-SHA512, dostaneme opět 512bitové číslo, jehož levých 256 bitů představuje hlavní soukromý klíč (master private key) a pravých 256 bitů představuje hlavní kód řetězu (master chain code). Z hlavního soukromého klíče je pak možné standardním způsobem vypočítat veřejný klíč. Kombinace kteréhokoliv z klíčů s korespondujícím kódem řetězu se pak nazývá rozšířený klíč (extended key).
S rozšířenými klíči již můžeme generovat dle libosti jejich potomky, přičemž u potomků soukromého klíče se rozlišuje mezi tvrzeným a netvrzeným odvozením. Zabývat se nyní musíme něčím, čemu se říká derivační cesta. Díky standardizovaným derivačním cestám dospěje každá kompatibilní peněženka z daného seedu (kombinace slov seedu a passphrase) vždy ke stejné sadě klíčů, resp. adres.
Podle BIPu 44 je standardní formát derivační cesty:
m / purpose' / coin_type' / account' / change / address_index
Apostrof nám značí tvrzené odvození, které lze provádět pouze se znalostí soukromého klíče. Malé m je hlavní rozšířený klíč (master). Purpose je index účelu – 44 je vyhrazena pro původní (legacy) BTC adresy, 48 pro adresy skriptu (typicky zapouzdřený segwit, nebo nějaký multisig), 84 pak vede k nejnovějším adresám native segwit. Index coin_type rozlišuje mezi hlavní síti mainnet (0) a testovací sítí testnet (1). Index account je pořadové číslo účtu. Všechny indexy jsou rozsahu 4 bajty, přičemž pro tvrzené odvozování jsou vyhrazeny indexy od 231 do 232−1. To dává dost prostoru pro odvození 2 147 483 647 účtů. Index change roven nule odvozuje adresy ke zveřejnění (ty, které peněženka zobrazuje při kliknutí na tlačítko Přijmout), jednička jsou vnitřní adresy užívané peněženkou k uzamčení zbytku při útratě příliš velkého UTXO. Konečně poslední index již čísluje jednotlivé adresy. Těch může být opět 2 147 483 647 pod každým účtem. Nemusíte se tedy bát používat pro každou transakci novou adresu tak, jak to stanovují best practices Bitcoinu.
Odvozování potomků provádíme již představenou funkcí HMAC-SHA512 a jako key slouží ve všech případech kód řetězu. Liší se vstupy do message a to, co provádíme s výstupem.
Netvrzené odvození ze soukromého rozšířeného klíče provedeme tak, že do message vložíme veřejný klíč a index. K levým 256 bitům výstupu přičteme rodičovský soukromý klíč – to celé modulo řádem grupy. Tím získáme soukromý klíč potomka, kódem řetězu potomka je pravých 256 bitů výstupu.
Tvrzené odvození ze soukromého rozšířeného klíče se liší od netvrzeného pouze tím, že do message vložíme nulový bajt, po něm soukromý klíč a index z vyhrazeného rozsahu. S výstupem si již počínáme stejně.
A konečně odvození potomka od veřejného klíče provedeme tak, že do message vložíme serializovaný veřejný klíč a index. Levých 256 bitů použijeme jako skalár pro násobení generátoru grupy, výsledný bod přičteme k veřejnému klíči rodiče a dostaneme veřejný klíč potomka, pravých 256 bitů je opět kódem řetězu potomka.
Pro přenos rozšířených klíčů se použije následující serializace zakódovaná v Base58Check:
- 4 bajty verze – 0x0488ade4 pro soukromý klíč se zakóduje jako xprv; 0x0488b21e pro veřejný klíč bude xpub
- 1 bajt hloubky – počtu odvození od hlavního klíče
- 4 bajty otisku rodiče – první 4 bajty RIPEMD160 ze SHA256 rodičovského klíče (0x00000000 pro hlavní klíč)
- 4 bajty pro index tohoto potomka (0x00000000 pro hlavní klíč)
- 32 bajtů pro kód řetězu
- 33 bajtů pro klíč (v případě soukromého předsazeno 0x00)