Пост

BIP39. Мнемонические фразы

BIP39. Мнемонические фразы

Каждый раз, когда вы настраиваете свой криптокошелек, то вам предоставляется мнемоническая фраза из 12 (в некоторых случаях 24) слов и предлагается сохранить её в надёжном месте. Эти мнемоники в дальнейшем используются для восстановления аккаунтов и связанного с ними баланса.

Один набор мнемоник может быть использован для создания нескольких адресов. Этот метод генерации аккаунта был введен в Bitcoin Improvement Proposal (BIP) 39. Если кратко, то BIP39 определяет формулу для генерации мнемонической фразы. Затем из этой фразы генерируется сид (seed). Сид используется для создания закрытых/открытых ключей.

BIP39 был представлен как средство для создания детерминированных кошельков. Это метод создания понятный человеку мнемонической фразы — легкой для чтения и записи — из случайных данных, которая служит резервной копией для восстановления всего кошелька.

Как работает BIP39?

BIP39 работает, генерируя мнемоническую фразу — группу легко запоминающихся слов — из случайного числа, обычно от 128 до 256 бит. Чем больше бит, тем оно надежнее, но также и тем больше слов в исходной фразе.

Это удобно тем, что фразу:

1
scale interest rifle cricket coyote stumble right salad type initial rocket game

гораздо проще запомнить и воспроизвести, чем шестнадцатеричный сид:

1
ba8f63a81ba219bc8cddf20c617859cb3623e78ccd86a7dc62193bb809b85cf11ed5759325283cea01aedaf94194e633666f1a283f98a3ff77545f48d69b2e7b

Формула детерминирована, что означает что одна и та же мнемоническая фраза всего будет приведена к одному и тому же сиду. Если кошелек будет утерян, то всегда можно будет восстановить все ключи с помощью одной лишь фразы.

Генерация энтропии

Чем больше энтропия - тем более безопасна фраза, но и тем она длиннее. Для генерации фраз из 12-24 слов нужно 128-256 бит энтропии. Для примера возьмем 128 бит и 12 слов. Энтропия в hex и бинарном виде:

1
hex: 0xd28f1fd94601532cf7c82ef109b63a00 

То же самое в 128 битах:

1
2
3
4
5
d    2    8    f    1    f    d    9    4    6    0    1    5    3    2    c
1101 0010 1000 1111 0001 1111 1101 1001 0100 0110 0000 0001 0101 0011 0010 1100 

f    7    c    8    2    e    f    1    0    9    b    6    3    a    0    0
1111 0111 1100 1000 0010 1110 1111 0001 0000 1001 1011 0110 0011 1010 0000 0000

Считаем чек-сумму

checksum = first (length of entropy in bits/32) bits of SHA256 of entropy

В нашем случае длина энтропии = 128, делим на 32 = 4 бита. Берем sha256 от бинарного представления нашей энтропии. В нашем случае первые 4 бита от хэша будет 0101. Добавляем эту чек-сумму в конец исходной энтропии:

1
110100101000111100011111110110010100011000000001010100110010110011110111110010000010111011110001000010011011011000111010000000000101

Разбиваем на группы

Далее разбиваем получившуюся последовательность на группы по 11 бит. Сейчас у нас 132 бита = 128+4. Должно получиться 12 групп по 11 бит:

1
11010010100 01111000111 11110110010 10001100000 00010101001 10010110011 11011111001 00000101110 11110001000 01001101101 10001110100 00000000101

Конвертируем каждую группу бит в десятеричное представление:

1
2
3
4
5
1684        967         1970        1120        169         1203      
11010010100 01111000111 11110110010 10001100000 00010101001 10010110011

1785        46          1928        621         1140        5
11011111001 00000101110 11110001000 01001101101 10001110100 00000000101

Все десятеричные числа находятся в диапазоне от 0 до 2047. Они используются как индексы из словаря мнемоников.

Находим слова

Выбираем слова из словаря. В нашем примере с английским языком получим следующее:

1
2
3
4
5
1684        967         1970        1120        169         1203      
spoon       jump        wagon       metal       benefit     nose

1785        46          1928        621         1140        5
tennis      alarm       valve       ethics      model       absent

Финальная фраза из 12 слов:

spoon jump wagon metal benefit nose tennis alarm valve ethics model absent

Алгоритм BIP39

  1. Генерируем случайное число.
  2. Конвертируем его в бинарное представление.
  3. Получаем чек-сумму от бинарного представления.
  4. Добавляем чек-сумму в конец исходного бинарного числа.
  5. Разделяем бинарную последовательность на группы по 11 бит.
  6. Каждая 11-битная группа соотносится со словом из предопределенного списка из 2048 слов.
  7. Результирующий список слов и будет мнемонической фразой.

Из мнемоники в сид

Мнемоническая фраза имеет смысл только когда из неё можно получить сид. А из сида уже вывести закрытые и открытые ключи. 512-битовый сид получается из Password-Based Key Derivation Function (PBKDF2). На вход функции подаются:

  • хэш-функция (HMAC-SHA512)
  • пароль (наша мнемоническая фраза)
  • соль
  • кол-во итераций хэш-функции (2048)

Из этого списка новое для нас - соль. Соль - возможность добавить дополнительный уровень безопасности кошелькам. Для создания соли строка "mnemonic" объединяется с необязательной парольной фразой по вашему выбору. Если вы ее не укажете, парольной фразой по умолчанию будет пустая строка.

В PHP у нас уже есть нативная функция для работы с PBKDF2 - hash_pbkdf2. Получение сида из мнемонической фразы на PHP:

1
2
3
4
5
$mnemonic = 'spoon jump wagon metal benefit nose tennis alarm valve ethics model absent';

$salt = "mnemonic" . $passphrase;
echo "Seed: " . hash_pbkdf2("sha512", $mnemonic, $salt, 2048, 64 * 2, false) . PHP_EOL;

Для пустой парольной фразы (когда sault="mnemonic") получим следующий сид:

1
d0b894aaed90f6a4c3956ca342c4b48208367fcaa72c4df79fac24a1e9c1425808002acd871c69e531f91ec9c6b69c8d20f765bb36bc30e58eb0dd34d5bf5d9f

Код выше вернет нам набор из 64 байтов (512 бит) в hex формате. Далее можно из этого 512 битового сида получать множество приватных и публичных ключей.

BIP39 в PHP

Для работы с мнемоническими фразами в PHP есть библиотека bitcoin-php:

1
composer require protonlabs/bitcoin

Генерация мнемонической фразы из энтропии:

1
2
3
4
5
6
7
8
9
10
11
use BitWasp\Bitcoin\Crypto\Random\Random;
use BitWasp\Bitcoin\Mnemonic\Bip39\Bip39Mnemonic;
use BitWasp\Bitcoin\Mnemonic\MnemonicFactory;

$random = new Random();
$entropy = $random->bytes(Bip39Mnemonic::MAX_ENTROPY_BYTE_LEN);

$bip39 = MnemonicFactory::bip39();
$mnemonic = $bip39->entropyToMnemonic($entropy);

echo "Mnemonic: " . $mnemonic . PHP_EOL;

Получаем фразу:

1
Mnemonic: spoon jump wagon metal benefit nose tennis alarm valve ethics model absent

Получение сида из этой фразы:

1
2
3
4
5
6
use BitWasp\Bitcoin\Mnemonic\Bip39\Bip39SeedGenerator;

$mnemonic = 'spoon jump wagon metal benefit nose tennis alarm valve ethics model absent';  
$seedGenerator = new Bip39SeedGenerator();  
$seed = $seedGenerator->getSeed($mnemonic);  
echo "Seed: " . $seed->getHex() . PHP_EOL;

Выведет следующее:

1
d0b894aaed90f6a4c3956ca342c4b48208367fcaa72c4df79fac24a1e9c1425808002acd871c69e531f91ec9c6b69c8d20f765bb36bc30e58eb0dd34d5bf5d9f

Получение энтропии из фразы:

1
2
3
4
5
use BitWasp\Bitcoin\Mnemonic\MnemonicFactory;

$bip39 = MnemonicFactory::bip39();  
$entropy = $bip39->mnemonicToEntropy($mnemonic);  
echo "Entropy: " . $entropy->getHex() . PHP_EOL; // Entropy: d28f1fd94601532cf7c82ef109b63a00

Проверить себя можно в онлайн Mnemonic Code Converter:

Что дальше?

BIP39 описывает, как строится сид фраза. С BIP39 связаны два других известных стандарта: BIP32 и BIP44:

  • BIP32 (“Hierarchical deterministic wallets”) — предлагает фреймворк для иерархических детерминированных кошельков (HD Wallets) для Bitcoin, чтобы код кошелька мог управлять несколькими отдельными учетными записями Bitcoin с помощью одной сид фразы.
  • BIP44 (“Multi-account hierarchy for deterministic wallets”) определяет ту же организационную иерархию для управления несколькими аккаунтами в детерминированных кошельках, но уже для других блокчейнов помимо Bitcoin (например Ethereum или Tron).

Вместе BIP32 и BIP44 добавляют гибкости, приватности и совместимости в HD кошельки. Таким образом HD кошельки расширяют возможности детерминированных кошельков, позволяя управлять огромным количеством ключей, все из которых получены из исходной мнемонической фразы (BIP39).

© Некоторые права защищены.

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