Замечу, что webtricks иногда вносит правки в свою статью, которые будут отслеживаться мною в этой теме.
Обзор работы Автор:
webtricks
Рассматриваемая работа под авторством webtricks посвящена иерархически детерминированным кошелькам биткойна.
Ее автор напоминает всем, что первые кошельки для биткойна можно было представлять себе как группу приватных ключей. Отсюда следовало то , что при генерации новых ключей пользователю приходилось сталкиваться с громоздким и обременительным процессом, подразумевающим под собой создание резервной копии каждого приватного ключа. С появленим иерархически детерминированых (HD) кошельков этот процесс упростился. Детерминированный кошелек подразумевает создание всех его адресов из единой отправной точки –единой начальной фразы , которую принято обозначать как SEED фраза или просто SEED. webtricks отмечает, что на сегодняшний день детерминированные адреса создаются в более чем 95% некастодиальных кошельков, подчеркивая при этом, что если в некоторых кошельках это не так, то такими кошельками пользоваться не стоит.
Весь процесс получения биткойн адресов сопровождается многочисленными примерами авторского кода, написанного на Javascript. Такой подход позволяет протестировать этот процесс на персональном компьютере без необходимости загрузки или развертывания какой-либо сторонней утилиты.
9 частей, на которые разбито содержание статьи: 1. Генерация случайной последовательности или энтропии.2. Получение контрольной суммы и сборка выходной последовательности (выходного вектора).3. Преобразование выходного вектора в мнемонические коды. 4. PBKDF2 или функция удлинения ключа. 5. Приватный/секретный Мастер-Ключ, Публичный/открытый Мастер-ключ и Кодирующая Цепочка (Chain Code). 6. Путь деривации/порождения (Derivation Path) и BIP-44. 7. Порождение Дочернего Приватного Ключа (Child Private Key Derivation). 8. Создание биткойн-адресов из приватных ключей. 9. JavaScript коды.1. Генерация случайной последовательности или энтропии.
Автор начинает эту часть с того, что первые слова, сказанные им в самом начале статьи, о том, что отправной точкой иерархического кошелька служит начальная фраза, или как говорят мнемоника, не совсем правдивы. Чтобы получить мнемонику, сначала нужно сгенерировать энтропию. Защита кошелька, должна быть основана на чем-то непредсказуемом, поэтому используется энтропия в 128-256 бит. Самый простой способ получить энтропию - это подбросить монетку. Нужно взять монету и подбросить ее 128 раз, а затем записать ноль, если она ляжет решкой, и единицу, если выпадет орел. После 128 подбрасываний получится случайная последовательность нулей и единиц c требуемой энтропией, которая есть не что иное, как мера “случайности”. Чтобы повысить безопасность своего кошелька, тоже самое можно проделать и 256 раз, (чем больше энтропия, тем выше безопасность). Чтобы лучше понять этот процесс, можно посмотреть на нижерасположенную картинку:
![](https://ip.bitcointalk.org/?u=https%3A%2F%2Fi.imgur.com%2F4T4lIbP.png&t=665&c=kHc0hOZMsvR0Pg)
Далее автор отмечает, что полученная последовательность нулей и единиц является четко выраженной отправной точкой, но она должна быть сгенерирована как можно более случайным образом. Если используется слабый генератор случайных чисел, хакеры могут легко взломать такую последовательность (имеется в виду догадаться о ней) и украсть средства.
2. Получение контрольной суммы и сборка выходной последовательности (выходного вектора).
Автор указывает, что получив 128-битную энтропию, нужно сгенерировать для нее контрольную сумму. Контрольная сумма - это не что иное как сигнатура, прикрепляемая к объектудля того, чтобы убедиться, что пользователь не ошибся при его копировании. Чтобы найти сигнатуру полученной энтропии, нужно, согласно BIP-39, получить ее хэш используя функцию хеширования SHA-256. Но прежде всего необходимо преобразовать запись для рассматриваемой энтропии, а именно из двоичной (Base2) перейти в шестнадцатеричную ( Base16) систему исчисления. Base2 означает, что для выражения числа используется 2 символа, «0» и «1». В свою очередь Base16 для выражения числа использует 16 символов: 0,1,2,3,4,5,6,7,8,9, a, b, c, d, e, f. е
Рисунок внизу показывает, как выполняется такое преобразование:
![](https://ip.bitcointalk.org/?u=https%3A%2F%2Fi.imgur.com%2FI2HzUOk.png&t=665&c=EM711TesVoquwQ)
Можно увидеть, что 0001 в Base2 (в двоичной системе) представлено в шестнадцатеричной системе счисления символом 1, 0010 представлено символом 2 и так далее. Итак, энтропия в шестнадцатеричном формате представляется как 91d3785bf884c639f600b3e587083265. Важный момент здесь тот, что обе записи представляют одно и то же, но системы исчисления для них отличаются.
Далее автор возвращается непосредственно к вопросу контрольной суммы для обсуждаемой энтропии и приводит результат ее (энтропии) хеширования функцией SHA-256:
SHA-256 hash от 0x91d3785bf884c639f600b3e587083265 = effdb98e4c4ac27c670f704c39a2e0ba8b85bc4561a7a02a6297e465ed155d30
Хэш - это 256-битное число, представленное 64-мя шестнадцатеричными символами. Другими словами, каждый шестнадцатеричный символ представляет 4 бита. Согласно BIP-39, вместо использования всего хеша, только первые (величина энтропии / 32) бита хеша используются в качестве контрольной суммы. Величина энтропии здесь равна 128, что при делении на 32 дает 4. Итак, в качестве контрольной суммы берутся только первые четыре бита хэша. Если величина энтропии была бы равна 256, то в качестве контрольной суммы брались бы 256/32 или первые 8 бит хеша.
Как уже говорилось, каждый шестнадцатеричный символ представлен четырьмя битами, первые четыре бита рассматриваемого хэша в шестнадцатеричном формате представлены символом «e». Поэтому контрольная сумма хэша - это «e» в шестнадцатеричном формате и 1110 в двоичном. Добавление этой контрольной суммы в конец последовательности создаст выходную последовательность, выраженную в шестнадцатеричной системе, как 0x91d3785bf884c639f600b3e587083265e, или в Base2 как:
![](https://ip.bitcointalk.org/?u=https%3A%2F%2Fi.imgur.com%2FrgP7r2F.png&t=665&c=7afvqllfpnP6yQ)
3. Преобразование выходного вектора в мнемонические коды.
webtricks напоминает, что полученный размер выходного вектора составляет 132 бита, и Следующий шаг который необходимо предпринять, это его разбиение на отдельные кусочки размером в 11 бит. 132 поделенное на 11 дает 12, поэтому получается 12 фрагментов. (Если использовать 256-битную энтропию, получится 24 фрагмента.)
Вот эти 12 фрагментов:
10010001110
10011011110
00010110111
11110001000
01001100011
00011100111
11011000000
00010110011
11100101100
00111000010
00001100100
11001011110
каждый из них - это двоичное число. Наименьшее значение, которое может быть представлено фрагментом это 00000000000, или 0 в десятичной системе, к то время как максимальное значение это 11111111111, или 2047 в десятичной системе. Таким образом, каждый фрагмент может принимать значение от 0 до 2047. BIP-39 определяет 2048 слов, отображаемых числами от 0 до 2047. Числовые отображения этих слов представлены в таблице
BIP-39 WORDS, размещенной автором на странице его персонального сайта.
Из таблицы можно увидеть, что десятичные значения наших блоков: 1166, 1246, 183, 1928, 611, 231, 1728, 179, 1836, 450, 100, 1630.Выбирая соответствующие им слова, можно получить следующий мнемонический код:
mushroom orange black valve erase brother submit biology tortoise debate arrive slim
4. PBKDF2 или функция удлинения/растяжения ключа
PBKDF2 (основанная на пароле функция формирования ключа./ Password-based Key Derivation Function) используется как мера защиты . Для повышения защищенности мнемонического кода в этой функции может использоваться «парольная фраза». Много полезного о PBKDF2 можно почерпнуть из
Википедии.
Автор ясно дает понять, что, в процессе создания адресов биткойна, функция PBKDF2 применяется для удлинения мнемонического кода, при этом используются 2048 итераций алгоритма HMAC-SHA512. Алгоритм принимает два параметра: один из них это мнемонический код, второй – модификатор входа хеш-функции или кратко соль (salt). Если пользователь отказывается от использования пароля , то в качестве соли выступает строка со значением 'mnemonic'. Но, если в качестве пароля пользователь решит использовать скажем слово «webby», то соль превратится в 'mnemonicwebby', парольная фраза подцепляется к концу строчки 'mnemonic'.
Следовательно, функция PBKDF2 примет следующий вид:
DK = PBKDF2(PRF, Password, Salt, c, dkLen)
Или с конкретными значениями, взятыми для PRF, Password, Salt, c and dkLen:
DK = PBKDF2(HMAC, 'mushroom orange black valve erase brother submit biology tortoise debate arrive slim', 'mnemonic', 2048, 64)
где PRF - псевдослучайная функция (здесь HMAC)
Password - это мнемонический код
Соль - это строка 'mnemonic'
c – число итераций, 2048 для PBKDF2
dkLen - желаемая длина ( в байтах) производимого ключа (поскольку на выходе необходимо получить SEED размером в 512-бит, параметру dkLen предписано значение в 64 байта, 1 байт = 8 бит).
DK относится к результирующему ключу или SEED размером в 512-бит. Для использованных параметров он равен:
65729d81d461591bac7384dea43dbd44438053cd1fdc113e0769c49c5fde025ba331eed2077497634e619948437d0448e769a86c0cbbecf01b13fd53540743b3
5. Приватный/Секретный Мастер-Ключ, Публичный/Открытый Мастер-ключ и Кодирующая Цепочка (Chain Code).
Автор еще раз напоминает, что основной целью использования SEED является получение иерархической древовидной структуры, в которой каждый приватный (секретный, закрытый) или публичный (открытый) ключ порождается своим родителем, и который в свою очередь порождает дочерние элементы (ключи). На вершине иерархии находится Master Private Key. Это секретный ключ первого уровня, у которого нет родителя.
Для нахождения этого ключа и Chain Code используется криптографическая функция HMAC-SHA512, которая в качестве одного из двух своих параметров использует 512-битный SEED, полученный в разделе 4. Вторым ее параметром служит фиксированная строка, а именно 'Bitcoin seed'.
HMAC(SEED, 'Bitcoin seed') = Hash
Результирующий хеш, размером в 512-бит, принимает вид:
a0ccf14c939faa07b896cd5fb306a37fb3f9cb041196c5364d0cca9dbd82e53a5bc9d1368631ae579f02ed8e46a56dd9dd9de8ac59e3c4e18247ff96988bdf1f
Далее webtricks обращает внимание на то, что размер получаемой таким образом выходной последовательности составляет 512 бит или 128 шестнадцатеричных символов. Первые 256 бит (первые 64 шестнадцатеричныхсимвола) и служат секретным мастер ключом (Master Private Key), в то время как следующие за ними 256 бит используется как кодирующая цепочка (Chain Code).
Отсюда,
Master Private Key: a0ccf14c939faa07b896cd5fb306a37fb3f9cb041196c5364d0cca9dbd82e53a
Chain Code: 5bc9d1368631ae579f02ed8e46a56dd9dd9de8ac59e3c4e18247ff96988bdf1f
Используя криптографию на эллиптических кривых (Elliptic Curve Cryptography) можно из секретного мастер ключа получить открытый мастер ключ (Master Public Key). webtricks отсылает читателя к созданной им
теме по ECC, чтобы проследить как открытый ключ получается из секретного ключа. Тот же самый процесс справедлив для открытого мастер ключа.
Наш Master Public Key: 03d1cc1f6bdea4d17eb7f2573d676f9ddb087f8b784c912c4466407781d8acfe38
6. Путь деривации/порождения (Derivation Path) и BIP-44.
webtricks проводит аналогию пути деривации и обычной карты, указывающей путь, который ведет к искомой точке через множество дорог, а в данном случае через дочерние элементы, получаемого из секретного мастер ключа, к адресу биткойна. Согласно BIP-44 этот путь для основной сети Bitcoin можно определить следующим образом:
Path format: m / purpose' / coin_type' / account' / change / address_index
Bitcoin Main-net format: m / 44' / 0' / 0' / 0 / address_index
Наглядное представление об этом пути можно получить из нижеследующей картинки :
......................................................................../............ | . |
| |