Глоссарий / Адреса и ключи
Ужестченная и неужестченная деривация
- Что такое ужестченная и неужестченная деривация?
- Ужестченная и неужестченная деривация делят индексы дочерних ключей BIP-32 пополам: неужестченные дочерние ключи можно вычислить из расширенного публичного ключа, ужестченные нельзя.
Определено в BIP-32.
Ужестчение представляет собой границу в пути деривации, а не параметр, который включают и выключают. BIP-32 был присвоен 11 февраля 2012 года только с неужестченной деривацией; приватная деривация для индексов от 0x80000000 и выше была добавлена 16 апреля 2013 года, а такие ключи были переименованы в ужестченные 15 января 2014 года. То, где проходит эта граница, определяет, какую часть кошелька раскрывает расширенный публичный ключ, которым вы поделились.
Как это работает
У неужестченной деривации есть одно свойство, которого ужестченная деривация намеренно лишена, и BIP-32 записывает это различие как алгебраическое тождество. Обозначьте через N() нейтрализацию, шаг, который отбрасывает приватную половину расширенного ключа и сохраняет цепной код длиной 32 байта. На неужестченных уровнях N(m/a/b/c) равно N(m)/a/b/c, поэтому нейтрализация до деривации и нейтрализация после деривации дают один и тот же ключ. На ужестченном уровне такая перестановка нарушается: N(m/a') нельзя превратить в N(m)/a', потому что публичная деривация определена только для не ужестченных дочерних ключей и для всего остального возвращает ошибку.
С технической стороны два режима различаются одним полем. Оба используют цепной код родительского ключа в качестве ключа для HMAC-SHA512 и добавляют индекс длиной 4 байта. Неужестченный режим подает сжатый публичный ключ родителя; ужестченный режим подает секрет родителя, дополненный ведущим нулевым байтом до той же ширины 33 байта. Ничто, имеющее только xpub, не обладает вторым входным значением, поэтому деривация останавливается на границе.
BIP-32 необычно прямо говорит о том, что неужестченные ключи не защищают. В разделе о безопасности два свойства перечислены как отсутствующие, а не как присутствующие: имея родительский расширенный публичный ключ и дочерний публичный ключ, найти индекс нетрудно, а имея тот же родительский расширенный публичный ключ и любой один неужестченный дочерний приватный ключ, восстановить родительский расширенный приватный ключ тоже нетрудно. Первое стоит вам приватности. Второе стоит вам ветви.
Где это встречается
Именно неужестченные уровни делают экспорт расширенного публичного ключа осмысленным, и BIP-32 посвящает раздел схемам совместного использования, построенным на них. Аудитор, получивший расширенные публичные ключи счетов, видит каждый платеж, поступающий на каждый счет и уходящий с него, и ни одного секретного ключа. Две компании, которые часто торгуют друг с другом, могут совместно использовать внешнюю цепочку одного счета как постоянный адрес для платежей, так что ни одной из них не нужно запрашивать новый адрес для каждого перевода. Интернет-магазин может передать такой же ключ своему веб-серверу, который затем генерирует адреса для получения средств, которые он не имеет права тратить.
Структура, помещающая границу на уровень счета, является рекомендацией, а не правилом. BIP-32 называет свою структуру из мастер-ключа, счета, цепочки и подцепочки только ориентировочной и говорит реализациям, что они могут отступать от нее для конкретных нужд, поэтому один соответствующий требованиям кошелек может ужестчать больше уровней, чем соответствующий кошелек рядом.
Об одной ловушке совместимости стоит знать, потому что спецификацию исправляли из-за нее дважды. Тестовые векторы для ужестченной деривации с ведущими нулями были добавлены 24 февраля 2017 года и снова 4 ноября 2020 года. Входное значение для ужестченного режима имеет фиксированную длину 33 байта: нулевой байт, за которым следует секрет длиной 32 байта, поэтому программа, которая отбрасывает ведущий ноль вместо того, чтобы сохранять эту ширину, хеширует другие данные, получает другую ветвь и обнаруживает пустой кошелек, когда кто-то восстанавливает эту сид-фразу в другой программе. Неужестченная деривация никогда не сталкивается с этой ошибкой, потому что сжатый публичный ключ всегда начинается с 0x02 или 0x03 и поэтому не имеет ведущего нуля, который можно потерять.