November 24, 2021

Триптих Максималиста: Трактат об альткоинах. Что такое криптовалюты?

Автор Эндрю Поэлстра. Оригинал

Иллюстратор Ольга Московченко

Это продолжение части "Что такое криптосистемы?".

3. Что такое криптовалюты?

С появлением современной криптографии идея о том, что информация может быть физически реальной и ценной, переместилась из темных залов философских факультетов в конкретный мир бизнеса. Все мы знакомы с экономической деятельностью, обеспечиваемой безопасным обменом данными: переговоры, контракты, транзакции, продажи и команды можно проводить через общедоступный Интернет, не опасаясь подделки или перехвата. Мы также знакомы с финансовыми последствиями потери или кражи секретных данных.

С появлением такой криптографической валюты, как Биткоин, в январе 2009 года [3] понятие ценной информации стало конкретным. Можно хранить и обменивать взаимозаменяемое средство сбережения, используя общедоступные средства связи, с криптографической, а не физической защитой, предотвращающей мошенничество или кражу. Вместо того, чтобы говорить «этот ключ шифрования стоит 10 000 долларов, потому что именно таковы будут наши издержки, если его зашифрованные данные будут раскрыты», теперь можно сказать: «этот ключ стоит 10 000 долларов, но его стоимость можно разделить, отправив только 20 долларов другой стороне, оставив себе остальное".

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

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

Сложность самой криптосистемы усугубляется тем фактом, что обмен ценностями обязательно требует учета экономических соображений. Поэтому криптовалюты необходимо анализировать не только с точки зрения вычислительной надежности и безопасности, но также с точки зрения экономической надежности и безопасности. То есть разработана ли криптовалюта таким образом, чтобы стимулы в ней были согласованы с целью обеспечения безопасности системы, а не с целью ее подрыва?

Чтобы проиллюстрировать сложность Биткоина и дать обзор его работы (в разделах 5 и 6 будет более подробное рассмотрение), мы разбили криптосистему на составляющие ее алгоритмы. Криптосистема в целом запускается каждым валидирующим «полным» узлом в сети. Мы предполагаем существование компьютерной сети, с помощью которой узлы могут обмениваться данными. (На практике узлы Биткоина используют одноранговую сеть и общаются по «биткоин-протоколу».)

Схема одноранговой peer-to-peer (p2p) сети

Такое разбиение неизбежно субъективно и дает неполное представление о системе [4], но дидактически необходимо. Важно подчеркнуть, что это одна криптосистема, и безопасность (экономическая и вычислительная) каждого компонента привязана к безопасности каждого другого компонента. Следовательно, любой, кто надеется изменить один компонент, должен понимать всю систему и иметь техническую подготовку для анализа и реализации изменения.

Теперь давайте дадим обзор каждого компонента Биткоина, оставив подробное обсуждение криптографии для последующих разделов.

Установка. Когда биткоин-узел впервые запускается, он создает две структуры данных, взвешенное хэш-дерево, называемое блокчейном, и базу данных, называемую набором utxo, при этом обе структуры изначально пусты. Элементы блокчейна называются блоками; элементы набора utxo называются utxos или неизрасходованными выходами транзакций. Смысл этих условий скоро прояснится.

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

Вещание. Каждый раз, когда узел видит транзакцию в сети, он запускает свой алгоритм проверки транзакции. Если проверка успешна, узел передает транзакцию каждому из своих партнеров (после небольшой задержки, чтобы предотвратить атаки лавинной рассылки).

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

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

Поскольку биткоин-транзакции - это финансовые транзакции, они часто представляют собой выполнение более сложных контрактов, чем «единственный владелец некоторой монеты подписал согласие на то, чтобы ее потратить». Поэтому система подписи Биткоина содержит выразительный язык сценариев на основе стека. Часто язык Биткоин-скриптов рассматривается как язык программирования; однако его криптографическая функция должна сводиться к цифровой подписи, и, следовательно, его наиболее важными атрибутами является то, что подписи на основе скриптов являются публично проверяемыми и принципиально не поддающимися подделке*.

* На самом деле язык скриптов Биткоина достаточно выразителен, чтобы создавать подписи, которые можно подделать с разной степенью простоты; утрированным примером могут выступать транзакции, выходы которых может потратить кто угодно. С другой стороны, транзакции типа “оплата по конкретному адресу” должны иметь выходы, которые не может потратить никто, кроме владельца целевого адреса. Таким образом, «принципиальная неподделываемость» - не совсем правильное требование безопасности для биткоин-подписей. Здесь есть кое-что более тонкое.

Этот язык имеет возможность отправлять и извлекать данные, выполнять простые условия, а также запускать некоторые традиционные криптографические примитивы. Простые биткоин-транзакции могут быть не более чем тонкой оболочкой этих примитивов; например, традиционные транзакции «оплата по адресу» проверяют (а) то, что транзакция подписана традиционной подписью ECDSA, и (б) что из ключа подписи может быть получен корректный адрес.

Подтверждение транзакций. По сути, биткоин-транзакция состоит из двух основных частей: входов и выходов. Поскольку входы относятся к выходам других транзакций, мы сначала рассмотрим выходы.

Для пояснения, на схеме In -- вход транзакции, Out -- выход.

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

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

Входы более сложны: они состоят из (а) ссылки на выход существующей транзакции и (б) скрипта, который помещает значения в стек. Чтобы проверить вход, сначала проверяется, что указанный выход транзакции не был израсходован, то есть он отображается в наборе utxo. Затем этот выходной скрипт объединяется со скриптом входа, и объединенный скрипт запускается с использованием алгоритма оценки скрипта. Если алгоритм принимает скрипт, транзакция считается валидной.

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

Генерация транзакции. Чтобы создать транзакцию, узел выбирает выходы из своего набора utxo, которые он может потратить (например, выходы, скрипты которых требуют цифровой подписи, а узел владеет необходимым ключом). Он выбирает достаточно выходов, чтобы их общая стоимость была больше или равна сумме, которую нужно потратить.

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

Любое несоответствие между суммой на входах и суммой на выходах считается комиссией сети. Чтобы уменьшить ее, узел может добавить дополнительный выход для «сдачи», который он может потратить самостоятельно.

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

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

Для криптосистемы Биткоина критически важно, что все узлы согласны с результатом алгоритма проверки блоков - и, соответственно, все узлы согласны с алгоритмами проверки транзакции, оценки скриптов и расчета сложности. То есть эти алгоритмы являются консенсусными. Подробнее об этом мы поговорим в разделе 6.

Блок взвешивается в блокчейне в соответствии с его сложностью.

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

Чтобы создать блок, узел собирает список транзакций, которые получены через сеть Биткоина, и все они проходят алгоритм проверки транзакции. Узел также создает транзакцию coinbase, которая не имеет входов, и выходы которой могут быть потрачены самим узлом.

Эти транзакции хэшируются, и полученный хэш помещается вместе с меткой времени и одноразовым случайным числом (nonce) в заголовок блока. Чтобы новый блок прошел алгоритм проверки блока, его хэш должен попадать в узкий диапазон, определяемый алгоритмом вычисления сложности. Для этого блок хэшируется до тошноты с перебором различных значений nonce, пока не будет найден хэш, который попадает в требуемый диапазон. Это вычисление называется доказательством работы (proof-of-work), и безопасность Биткоина зависит от его соответствия нескольким тонким математическим свойствам, которые будут обсуждаться в разделе 6.

Расчет сложности. Есть две причины, по которым биткоин-блоки сопровождаются proof-of-work. Одна из них - создать альтернативные издержки для увеличения блокчейна, вынуждая потенциальных злоумышленников работать над одной из ветвей блокчейна. Другая - замедлить темп увеличения блокчейна, чтобы вся сеть могла быть осведомлена о каждом блоке до того, как он будет добавлен. Proof-of-work также обеспечивает естественный способ взвешивания каждого блока, так что для каждой ветки в блокчейне можно вычислить «суммарную работу». Чем выше суммарная работа ветки, тем больше участников (статистически) требуется для ее совместного создания, и, следовательно, «наибольшая суммарная работа» является заменителем понятий «известна большинству людей» [6]* и «труднее всего подделать».

* Питер Вюлле указал, что, поскольку хэш-мощность сети Биткойн увеличилась на много порядков, для наглядности в качестве суммарной работы можно использовать только недавно выполненную. Например, современный ASIC-майнер может легко превзойти суммарную работу первых 200 тысяч биткойн-блоков, ничего не публикуя. С другой стороны, шкала времени, в которой хэш-мощность изменяется на порядки, намного больше, чем шкала времени, в которой мы предполагаем, что сеть является синхронной, поэтому к тому времени, когда злоумышленник сможет индивидуально переписать ветку, она будет уже продолжена за пределы его досягаемости, и это продолжение уже будет видимым во всем мире. Поэтому к тому времени, когда разница между картиной, подразумеваемой полной суммарной работой, и той, которая подразумевается последней суммарной работой, разовьется, эта разница уже давно перестанет иметь значение.

По этим причинам биткоин-узлы могут достичь распределенного консенсуса о том, какой блокчейн «правильный», считая «правильность» синонимом наибольшей суммарной работы [7]*.

* Это описание функции proof-of-work далеко не является научным консенсусом. Все согласны с тем, что существуют математические доказательства того, что распределенный консенсус, обеспечиваемый криптографией, невозможен, и что Биткоин уклоняется от этой невозможности, вводя экономические концепции, такие как альтернативные издержки. Далеко не ясно, какова правильная формализация свойств безопасности (включая меры против цензуры и централизации), необходимых для proof-of-work, и достигает ли proof-of-work Биткоина этих целей. Для получения дополнительной информации см. недавнюю работу Эндрю Миллера.

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

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

Схема proof-of-work в Биткоине - это схема HashCash Адама Бэка (подробнее об этом см. раздел 6), и она работает за счет требования, чтобы хэш SHA256d заголовков валидных блоков находился в узком диапазоне. Параметр сложности обратно пропорционален размеру этого диапазона, и если предположить, что значения SHA256d равномерно случайны [8]*, размер этого диапазона прямо пропорционален вероятности того, что некий конкретный блок окажется валидным. Майнеры прочесывают пространство возможных заголовков блоков, перебирая параметр nonce, так что в интервале между любыми двумя валидными блоками майнеры могут коллективно перебрать многие квадриллионы невалидных.

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

Краткое изложение вышесказанного: если временные метки блоков находятся слишком близко друг к другу, вскоре сложность возрастает, а это означает, что диапазон валидных хэшей сокращается. И наоборот, если блоки расположены слишком далеко друг от друга, диапазон увеличивается. В результате возникает петля отрицательной обратной связи, которая заставляет блоки появляться в среднем каждые десять минут.

4. Криптография - это трудно

В этом разделе мы отойдем от специфики криптовалют и рассмотрим криптографию в целом. Современная криптография - увлекательная, но чрезвычайно тонкая область. Теоретическая криптография находится на пересечении компьютерных наук, алгебры, статистики, физики и философии, в то время как прикладная криптография включает все вышеперечисленное плюс проектирование софта, электротехнику, социальные науки и экономику [9]*.

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

[тут можно рассказать несколько историй об «очевидно» любительских криптосистемах, например altoz, о не очевидно любительских, например, о системе шифрования по ключу от компании Electrum, а также о профессиональных системах, скажем, об уязвимостях ECDSA] [еще можно рассказать несколько историй о серьезных криптосистемах, сломанных странным образом, например, об атаке TLS 1.0 по побочному каналу]


[3] Alexander Dent, Fundamental Problems in Provable Security and Cryptography, retrieved from the IACR preprint archive, 2006.

[4] Robert Pirsig, Zen and the Art of Motorcycle Maintenance, 1974

[5] *** здесь авторское примечание, которое перенесено в текст

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

Проект финансируется со средств аукциона газеты "Bitcoin Day" подаренной каналу @saul_freeberty. Поощрить переводчика вы можете с помощью LNURL-кода

https://lntxbot.com/@alexeynefedov
https://lntxbot.com/@tony_lightning