September 3, 2022

Биткоин: работа продолжается. Глава 4

Технические инновации из окопов

Фото автора

Перевод NADO Book by Sjors Provoost.

Проект перевода организован HypeCoinNews.

Программные библиотеки

libsecp256k1 — это библиотека, о которой некоторые люди, возможно, слышали мимоходом, но многие на самом деле толком не вникают в нее и не понимают ее важности. В этой главе мы обсудим, что это такое и почему это важно для Биткоина. Но прежде чем заняться этим, было бы полезно сделать обзор библиотек в целом.

Библиотека — это многократно используемая часть программного обеспечения. Согласно Techopedia, «Программная библиотека — это набор данных и программного кода, который используется для разработки программ и приложений». Примером этого в мире криптографии является OpenSSL: это часть программного обеспечения, которая позволяет вам выполнять различные криптографические операции — от создания случайных чисел до подписи чего угодно при помощи каких угодно кривых. Библиотека сама по себе не является программой, поскольку она ничего не делает независимо. Однако другие программы могут использовать такую библиотеку, как OpenSSL, или ее подмножество, для выполнения желаемых действий без необходимости самостоятельно писать весь код.

В случае OpenSSL пользователи загружают Bitcoin Core, самое популярное программное обеспечение, используемое для подключения к сети Биткоина. Его бинарный файл содержит элементы, специфичные для Bitcoin Core, а также множество соответствующих библиотек. Одной из таких библиотек является OpenSSL. Или, скорее, была, как мы объясним позже.

С самого начала OpenSSL использовалась в Биткоине для всего, что связано с криптографией, например, для подписи транзакций и создания безопасных случайных приватных ключей. Сатоши пришлось выбрать одну из криптографических кривых, предлагаемых библиотекой. По разным причинам, о которых мы можем только догадываться, Сатоши не выбрал более совершенную схему подписи Шнорра — эта тема будет рассмотрена в главе 11 — потому что OpenSSL не поддерживал ее, и для нее не существовало другой библиотеки.

см. раздел «Выбор правильной эллиптической кривой» в этой статье Виталика Бутерина (написанной до создания им Эфириума): Сатоши выбрал кривую secp256k1. В результате ему не пришлось самому писать необходимый криптографический функционал — чего никогда не хочется делать самому, потому что это опасно.

Необходимая библиотека включается в загружаемый файл каждой новой версии Bitcoin Core. Не все программы включают в себя все свои библиотеки. Альтернативой является использование библиотек, которые уже присутствуют на вашем компьютере, что уменьшает объем загрузки, поскольку библиотеку не нужно загружать повторно. Однако это может создать проблемы.

Наиболее очевидная проблема не включения всех библиотек в загрузку заключается в том, что у пользователя может не быть одной или нескольких требуемых библиотек. Затем им нужно будет дать указание загрузить их, а это плохой пользовательский опыт. С другой стороны, на самом деле это обычный опыт в жизни разработчиков программного обеспечения, которые тратят большую часть своего времени на поиск библиотек и других компонентов для профессиональных инструментов, которые они пытаются установить. Опыт часто является рекурсивным, когда каждая библиотека, в свою очередь, зависит от еще одной библиотеки.

Другая проблема заключается в том, что библиотеки могут меняться, и в самом деле меняются. Библиотека в вашей системе может быть слишком старой или слишком новой. Возможно, изменились важные вещи, из-за которых библиотека больше не будет совместима с программой, которая на нее опирается.

Изменения в библиотеках с течением времени затрудняют компиляцию и запуск старых версий Bitcoin Core, даже если исходный код доступен. Это будет проблемой для будущих археологов кода.

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

Включение библиотек в загрузку означает, что у вас всегда будет правильная версия. Вот почему ваш компьютер, вероятно, содержит множество копий и версий одних и тех же библиотек.

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

Кто-то там в мире поддерживает библиотеку. У них нет времени тестировать каждое из своих изменений в каждом программном пакете, использующем их библиотеку. Поэтому, если вы не обращаете внимания на то, что делают те, кто сопровождают библиотеку — либо просматривая изменения в примечаниях к выпуску, либо проверяя сам код — они могут вам что-нибудь сломать.

Затем, когда вы загружаете библиотеку вместе с остальной частью Bitcoin Core, ваш компьютер теперь использует эту измененную часть библиотеки. Но что, если разработчики Bitcoin Core не заметили именно это изменение, произошедшее с библиотекой? В итоге внезапно того поведения, которого они ожидали от Bitcoin Core, в реальности не происходит.

Большинство приводящих к поломкам изменений в библиотеках - случайности, но не все. В главе 9 более подробно рассматривается процесс проверки внешнего кода, от которого зависит софт, и возможные атаки со стороны мошенников, предоставляющих такой код.

Критическое изменение в поведении библиотеки особенно проблематично, когда оно приводит к изменению интерпретации правил блокчейна: Bitcoin Core будет считать конкретный блок валидным в одной версии библиотеки, а в другой — тот же блок недействителен. Это приводит к разделению цепи.

Именно это произошло со старой версией Bitcoin Core: в OpenSSL была ошибка, из-за которой разработчикам Bitcoin Core пришлось обновить OpenSSL, поскольку старая версия попросту перестала быть безопасной. Разработчики Core не знали, что новая версия OpenSSL также включала ещё одно другое изменение.

Это конкретное изменение касалось того, как обрабатывались подписи и считались ли они действительными. Первоначальная версия OpenSSL была не строгой, поэтому она принимала подписи как действительные, даже если они не соответствовали точным спецификациям. Они не могли быть подписаны кем-то другим, поэтому речь шла не о краже средств, а скорее о том, что реализация была не строгой в математическом смысле.

Так вот, новая версия стала крайне придирчивой. Если вы использовали программное обеспечение Биткоина для создания транзакции, это не было проблемой, потому что любая биткоин-транзакция была подписана строго в соответствии с протоколом. И если бы вы решили проверить эти транзакции с помощью старого программного обеспечения, оно бы увидело неаккуратную версию, которая также была сделана с помощью старого программного обеспечения, и у него не было бы претензий к этой транзакции. Однако новое программное обеспечение сказало бы, что транзакция недействительна, потому что не приняло бы эти неаккуратные подписи. Таким образом внезапно произошел случайный софт-форк, то есть то, что происходит, когда ранее действительные транзакции становятся недействительными.

К счастью, некоторые разработчики вовремя узнали об этой проблеме. Если бы они этого не заметили, то после включения обновленной библиотеки OpenSSL в бинарный файл свежего релиза Bitcoin Core мог бы произойти большой раскол цепочки. Вместо этого было принято несколько мер по обезвреживанию этой бомбы замедленного действия.

Во-первых, пользователи по-прежнему могли загружать бинарный файл Bitcoin Core, как обычно, поскольку он поставлялся в комплекте со старой версией OpenSSL. Несмотря на то, что в этой версии была ошибка безопасности, не стоит забывать, что каждая часть программного обеспечения на компьютере может предпочесть использовать свою собственную версию OpenSSL. Скажем, вот эта конкретная ошибка повлияла на программное обеспечение браузера, но не на Bitcoin Core, поэтому браузер должен был бы немедленно загрузить новую версию, в то время как Bitcoin Core мог бы подождать еще немного.

Во-вторых, тем, кто предпочитает компилировать собственное программное обеспечение из исходного кода, были предложены два возможных обходных пути. Можно было или отключить обновление OpenSSL, или использовать достаточно свежую версию исходного кода, которая теперь содержала исправление, устраняющее проблему.

В-третьих, был предложен софт-форк BIP 66, и он действительно был успешно активирован (подробнее об активации софт-форка читайте в главе 12). Этот форк требовал соответствия всех будущих подписей более строгому стандарту, чтобы их могли принимать как старые, так и новые версии OpenSSL.

Этот инцидент был не слишком неожиданным, поскольку OpenSSL славится своими уязвимостями. Основная причина здесь в том, что эти библиотеки использовались всеми на протяжении десятилетий, но поддерживает их лишь маленькая кучка добровольцев с очень ограниченным бюджетом.

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

В случае с OpenSSL одна из причин наличия этих ошибок заключается в том, что в криптографическом коде вообще легко допустить ошибку. Более того, OpenSSL написан на C, так что если вы забудете точку с запятой - упс! - теперь вы пропускаете строку, и, возможно, эта строка действительно проверяла пароль. Известным примером этого является баг Heartbleed 2014 года, когда небольшая ошибка приводила к тому, что любой, владеющий ноу-хау, мог без пароля заполучить доступ к любому компьютеру в интернете.

Если ошибка в коде Биткоина не обнаружена и не исправлена вовремя, злоумышленник может вызвать внезапное разделение цепи. В приведенном выше примере кто-то мог бы передать транзакцию с подписью, которая действительна в соответствии со старыми версиями OpenSSL, но недействительна в соответствии с новыми версиями OpenSSL. Это привело бы к тому, что старые узлы примут блок, а новые узлы отклонят его. Разделение цепочки может быть вызвано всевозможными ошибками программирования, а не только изменениями в библиотеках. Было еще несколько близких случаев.

Пока все это происходило, Питер Вьюлле работал над библиотекой, которая была специально разработана для создания и проверки биткоин-подписей. Его первоначальная мотивация не имела ничего общего с безопасностью; он просто хотел, чтобы она работала быстрее, чем OpenSSL.

Он объясняет это в подкасте, записанном совместно с Chaincode. По сути, он хотел сделать библиотеку, которая была бы примерно в четыре раза быстрее. Он мог бы попытаться модифицировать сам код OpenSSL, но менять этот код — кошмар. Кроме того, код OpenSSL очень абстрактный: он должен поддерживать все виды криптографии. Поэтому, если вы хотите что-то изменить, вы должны описывать все вещи очень абстрактно.

Вместо этого Вьюлле решил по сути написать библиотеку с нуля, специально для кривой secp256k1. Она была добавлена в Bitcoin Core относительно рано — сначала только для проверки подписей, а затем и для их создания.

Это совпало с вышеупомянутой уязвимостью безопасности, и реакция сообщества была такова, что из-за этого огреха, который едва не стал серьезной проблемой, было бы хорошей идеей вовсе отказаться от OpenSSL для критически важных вопросов.

Хотя о подписании и проверке подписей позаботились отдельно, Биткоин по-прежнему полагался на OpenSSL в других вещах, хотя и гораздо меньшей степени, чем в прошлом. Но разработчики уже приняли решение со временем избавиться от оставшегося использования OpenSSL, скопировав или переписав различные части библиотеки, которые нужны Bitcoin Core. Этот процесс был завершен в 2019 году. Первой версией Bitcoin Core без OpenSSL, была 0.20.0, выпущенная в июне 2020 года.

Таким образом, libsecp256k1 от Вьюлле, изначально предназначенная для повышения производительности, превратилась в новую библиотеку для Биткоина, которая устраняет риски, связанные с OpenSSL. Однако это сопряжено с двумя собственными рисками:

  • Написание собственной криптографической библиотеки (это опасно даже вне сферы криптовалют).
  • Замена одной критической библиотеки на другую, потому что теперь даже малейшая разница в поведении может привести к разделению цепи.

Тем не менее, риск был сочтен оправданным, потому что другой вариант означал "ждать, пока в конечном итоге OpenSSL не скомпрометирует себя сама". Кроме того, многие хорошие криптографы аудировали libsecp256k1 и сравнили его с OpenSSL до ее внедрения. Она также используется Эфириумом и другими криптовалютами — в общем-то, любой криптовалютой, использующей эллиптическую кривую secp256k1.

Поддержите проект!

Шлите ваши сатоши, используя эту LNURL ссылку с сообщением "НАДО"/"NADO"

Используя страничку,просто пользователю @c3p0rs через @lntxbot, либо [email protected] если ваш кошелёк поддерживает LN адреса.