Глоссарий / Справочник разработчика
OP_HASH160
- Что такое OP_HASH160?
- OP_HASH160 применяет SHA-256 к верхнему элементу стека, а затем RIPEMD-160 к полученному результату и оставляет дайджест из 20 байт, тот же отпечаток, который несет внутри каждый адрес, начинающийся с 1 или 3.
Один байт, 0xa9, заменяет две из самых изученных хеш-функций в криптографии. Эта пара сжимает выходной результат из 32 байт до 20 и страхует от слабости в любом из двух алгоритмов ценой примерно 80 бит стойкости к коллизиям вместо 128. Именно поэтому адрес биткоина достаточно короток, чтобы прочитать его вслух по телефону.
Как это работает
OP_HASH160 снимает со стека один элемент любой длины и помещает туда ровно 20 байт, и один и тот же вход всегда дает один и тот же дайджест.
Две функции происходят из не связанных между собой линий разработки. RIPEMD-160 опубликовала в 1996 году европейская академическая команда, работавшая открыто; SHA-256 появилась в NSA и была стандартизирована NIST в 2001 году. Связать их было консервативным выбором. Структурная брешь в одной из них все равно оставила бы другую между атакующим и полезной подделкой, и за три десятилетия ни одна из них не была взломана так, чтобы это угрожало данной конструкции.
Сокращение размера не косметическое. Экономия двенадцати байт на каждом выходе имела значение, когда цель состояла в том, чтобы сохранять постоянный глобальный реестр небольшим, и поэтому классический скрипт блокировки занимает 25 байт, а не 37.
У двадцати байт есть потолок. Поиск двух входов с общим дайджестом в 160 бит требует порядка 2 в степени 80 операций, а не 2 в степени 128, что приемлемо, когда только вы выбираете ключ, который хешируется, и куда менее приемлемо, когда контрагент помогает выбрать скрипт, на который дается обязательство. Именно поэтому segregated witness в P2WSH перевел обязательства по скриптам на один SHA-256 в 32 байта, сохранив более короткую форму для выходов с одним ключом.
Где это встречается
OP_HASH160 присутствует в двух шаблонах скриптов, а ее результат находится внутри почти каждого адреса, который вы когда-либо копировали.
Устаревшие выходы выполняют ее над публичным ключом. Выходы pay-to-script-hash выполняют ее над скриптом погашения. В обоих случаях адрес, который вы видите, представляет собой этот дайджест в 20 байт с байтом версии впереди, 0x00 для адресов, начинающихся с 1, и 0x05 для начинающихся с 3, обернутый в контрольную сумму Base58Check. Нативные segwit-выходы с одним ключом несут те же 20 байт вообще без опкода, потому что правила для этого типа выхода встроены в валидатор, а не записаны как скрипт.
Taproot сломал эту привычку. Выход bc1p фиксирует публичный ключ в 32 байта без промежуточного шага хеширования, поэтому адрес Taproot не содержит hash160 нигде.
Это также практическая причина, по которой проверка адреса на экране аппаратного кошелька работает. Два адреса, различающиеся хоть в чем-то, дают два несвязанных дайджеста, поэтому подмененный адрес не может выглядеть почти правильным; сравнения первых и последних нескольких символов на устройстве с тем, что показывает компьютер, достаточно, чтобы поймать вредоносное ПО буфера обмена.
OP_HASH160 vs SHA-256
SHA-256 является хеш-функцией; OP_HASH160 является инструкцией, которая вызывает ее один раз. Эта функция встречается по всему биткоину без участия скрипта: доказательство работы дважды хеширует ею заголовок блока, идентификаторы транзакций представляют собой двойное ее применение, а деревья Меркла строятся из нее. Опкод существует только внутри Bitcoin Script, выполняется только при расходовании выхода и всегда дает 20 байт, а не 32. Композиция, которую он выполняет, RIPEMD-160 от SHA-256, достаточно распространена, чтобы иметь собственное имя в коде кошельков, hash160, которое стоит узнавать, читая список функций библиотеки.