Глоссарий / Адреса и ключи
Код цепочки
- Что такое код цепочки?
- Код цепочки представляет собой 32 байта дополнительной энтропии, которые сопровождают каждый ключ в HD-кошельке и подмешиваются при выводе каждого дочернего ключа так, что ключи нельзя угадать по соседним.
Определено в BIP-32.
Половина каждого расширенного ключа вовсе не является ключом. BIP-32 делит 512-битный хеш на 256-битный ключ и 256-битный код цепочки, и строка xpub несет и то и другое, всего 111 символов. Если вы когда-либо передаете xpub, вы передаете вместе с ним и код цепочки, и именно это позволяет получателю выводить ваши будущие адреса.
Как это работает
Код цепочки выполняет свою работу внутри одного вызова HMAC. Вывод дочернего ключа запускает HMAC-SHA512, где ключом служит код цепочки родителя, а сообщением служат публичный ключ родителя плюс четырехбайтовый индекс. Результат из 64 байт делится посередине: левые 32 байта прибавляются к приватному ключу родителя по модулю порядка кривой и дают приватный ключ потомка, а правые 32 байта становятся собственным кодом цепочки потомка, который тот будет использовать для своих дочерних ключей.
Смысл соли в том, кому позволено идти по дереву. Публичный ключ сам по себе ничего не выводит, потому что функция вывода не запустится без соответствующего кода цепочки. Поэтому расширенный публичный ключ не является просто публичным ключом с более длинным названием. Это публичный ключ плюс его код цепочки, и передача этой пары кому-либо превращает одну точку на кривой в неограниченную перечислимую ветвь адресов, которые вы еще не использовали.
BIP-32 описывает острую грань, которая из этого следует. Если злоумышленник располагает вашим расширенным публичным ключом и вдобавок получит один нежесткий дочерний приватный ключ, то вычитание выведенного смещения восстанавливает родительский приватный ключ, а вместе с ним каждый соседний и каждый нижестоящий ключ. Жесткий вывод существует, чтобы перерезать этот путь: на жестком шаге хешируемое сообщение содержит приватный ключ родителя, а не публичный, поэтому никакой объем публичного материала не позволяет никому подняться вверх.
Где это видно
Вы никогда не вводите код цепочки вручную, и ни один потребительский кошелек не показывает его отдельно. Он путешествует внутри расширенного ключа. Строки Base58Check, начинающиеся с xpub или xprv, декодируются в 78 байт, разложенных так: 4 байта версии, 1 байт глубины, отпечаток родителя из 4 байт, номер потомка из 4 байт, код цепочки из 32 байт и, наконец, ключ из 33 байт, из-за чего xpub занимает 111 символов текста.
Поле становится видимым как поле в инструментах для разработчиков. RPC deriveaddresses в Bitcoin Core работает с дескрипторами, в которые встроены расширенные ключи, библиотеки вроде python-bip32 возвращают код цепочки отдельным атрибутом, а устройство подписи, экспортирующее счет для конфигурации только для просмотра, экспортирует ровно эту пару.
Правильный уровень осторожности здесь тот же, что вы применили бы к полной истории транзакций, а не тот, что применили бы к паролю. Код цепочки не может подписывать, поэтому сам по себе он не приведет к потере средств. В руках аналитической фирмы, облачной резервной копии или любого, кто вставил xpub в заявку в службу поддержки, он раскрывает каждый платеж на этой ветви, прошлый и будущий, и отозвать доступ потом невозможно.
Код цепочки vs приватный ключ
И код цепочки, и приватный ключ представляют собой по 32 байта, которые выглядят случайными, и тратить может только один из них. Приватный ключ создает подписи. Код цепочки не создает ничего, кроме дальнейшего вывода, и именно поэтому его недооценивают: поскольку он не может перемещать средства, расширенные публичные ключи вставляют в общие электронные таблицы, отчеты об ошибках и телефонные приложения люди, которые никогда не сделали бы того же с ключом. Результатом становится постоянное окно в их финансы, а не кража, и эти два сбоя заслуживают разных названий.