Квентин Массейс. Сборщики налогов, около 1500 г.
Это первая из серии статей, задача которой – дать более глубокое представление о механизмах работы приватных протоколов CoinJoin, Monero, Zcash и Mimblewimble. Здесь мы дадим концептуальное и более детализированные объяснение того, как денежные переводы, записи о которых хранятся в публичном реестре, могут быть анонимными, но при этом поддаваться проверке любой заинтересованной стороной – два, казалось бы, противоречащих друг другу требования. Первая статья посвящена CoinJoin — приватному протоколу, использующему только простые, без дополнительного функционала, транзакции Биткойна.
Вкратце, если много букв:
- Биткойн-транзакции передают право на проведение UTXO (Unspent Transaction Output, непотраченный выход транзакции);
- Деанонимизация нескольких Биткойн-адресов может привести к серьёзной утечке конфиденциальных данных, так как большинство транзакций возможно отследить;
- По меньшей мере 15% блокчейна Биткойна можно деанонимизировать;
- Биткойн-транзакции могут содержать UTXO, принадлежащие разным адресам;
- CoinJoin объединяет UTXO выхода от разных участников в одну транзакцию, что препятствует идентификации получателей каждого из платежей;
- Основным недостатком CoinJoin является то, что он требует участия другой стороны для создания микширующей транзакции (хотя отправитель и получатель могут сохранять полную анонимность).
Назад, к основам: UTXO
Для начала рассмотрим более подробно рабочий механизм основанных на UTXO транзакций в Биткойне. Структура транзакций и схема подписи, которую мы описываем, специфичны для Биткойна (а если точнее, то для его версий до введения поддержки SegWit). Тем не менее учёт на основе UTXO будет нашей базовой моделью, поскольку она принята всеми койнами, которые мы будем рассматривать в следующих статьях серии.
Вместо того, чтобы вести список счетов с остатками на них (как это делается в Ethereum), реестр Биткойна содержит информацию о том, какой адрес владеет каждым UTXO (означает неизрасходованный выход транзакции, т.е. часть входящих средств, которая ещё не была потрачена пользователем). Когда Элис отправляет Бобу 1 BTC, она создаёт транзакцию с несколькими UTXO, которыми она владеет – скажем, utxo_1, utxo_2 – в качестве входов транзакции и двумя новыми UTXO (utxo_Bob и utxo_Alice) в качестве её выходов. Значение utxo_Bob – 1 BTC, а utxo_Alice – это «сдача».
Когда майнинговый узел получает транзакцию Элис, он выполняет простую проверку того, что:
Более сложная часть заключается в том, чтобы гарантировать, что только Боб имеет право потратить utxo_Bob в будущем. Эта проблема решается через использование «умного» механизма скриптов разблокировки, включаемых в каждую транзакцию при её создании. Этот скрипт представляет собой микропрограмму с небольшим количеством инструкций, написанную на не-Тьюринг-полном языке. Для того чтобы включить UTXO в качестве одного из входов в новую транзакцию, нужно включить в неё некоторые данные, чтобы скрипт разблокировки UTXO возвращал ответ True (примечание: это относится к транзакциям Биткойна до SegWit. В современных транзакциях используется несколько иная схема. Хотя транзакции старого типа по-прежнему признаются сетью как валидные).
Например, разблокирующий скрипт utxo_Bob (прикреплённый Элис) может выглядеть как
<Открытый ключ Боба> OP_CHECKSIG
Обратите внимание, что он содержит только публичную информацию, так что Элис может прикрепить этот скрипт к utxo_Bob, поскольку она знает адрес кошелька Боба (который, грубо говоря, представляет собой модульное хеширование его открытого ключа). В свою очередь, Боб может подтвердить, что он действительно собирается получить право потратить utxo_Bob после включения транзакции в блок, и блок принимается. Опуская многие технические подробности, которые можно найти, например, здесь или здесь (англ.), описанный выше сценарий приблизительно указывает на то, что для того чтобы потратить utxo_Bob как вход, необходимо предоставить некоторые дополнительные данные sig, так что значение выражения
return secp256k1.verify(sig, <открытый ключ Боба>, sha256(sha256(tx)))
оценивается как истинное (True). Дело в том, что предоставить sig может только человек, который знает секретный ключ Боба. Это практически гарантировано, поскольку значение sha256 (sha256 (tx)) носит в достаточной мере произвольный характер, а алгоритм ECDSA достаточно безопасен. Например, хакер может попытаться найти значение sig, прочёсывая транзакции, подписанные Бобом ранее. Но такая наивная попытка обречена на неудачу, поскольку все хеши формы sha256 (sha256 (tx)) разные. С другой стороны, для Боба это рутинная задача – генерировать sig с помощью своего закрытого ключа и любой последовательности байтов, в частности sha256 (sha256 (tx)). Так что без необходимости прямой коммуникации с Элис (и даже не будучи онлайн!) Боб может смело принимать биткойны на свой публично объявленный адрес и быть уверенным, что никто, кроме него, не может потратить эти средства.
Биткойн безопасен, но не анонимен
Давайте начнём с того, что опишем потенциальные утечки анонимности, которые могут использовать специалисты в области блокчейн-аналитики (в порядке уменьшения степени серьёзности):
Сатоши Накамото утверждал, что, поскольку любой человек может анонимно создать Биткойн-адрес, то фактор 1) не несёт в себе серьёзной угрозы для конфиденциальности пользователей. Это могло быть правдой в то время, когда пользователи получали свои биткойны главным образом путём майнинга. Сегодня, из-за вездесущих политик KYC/AML (идентификации клиента и противодействия «отмыванию» денег), навязанных крупным криптобиржам, многие Биткойн-адреса можно связать с реальными личностями пользователей. Хуже того: просто анализируя общедоступные профили в BitcoinTalk и Twitter, используя методы интеллектуального анализа данных, можно получить довольно много информации о владельцах Биткойн-адресов. Если же сочетать это с фактором 2), то можно отследить удивительно много транзакций. Плохие новости для тех, кто думал, что «даркнет» означает, что правоохранительные органы остаются в неведении относительно личностей контрагентов транзакций (извините, Dread Pirate Roberts). Bitfury утверждают, что могут деанонимизировать не менее 16% всех Биткойн-адресов.
Обратите внимание, что, если 1), по крайней мере, требует парсинга данных, то информация о 2), 3), и 4) совершенно открыта (для обычных Биткойн-транзакций) и свободно доступна (часто это даже преподносится как «фича» общедоступных распределённых реестров).
CoinJoin
По крайней мере для Биткойн-транзакций, фактор 1) сильно зависит от 2). Действительно: при простом перемещении средств со счёта А на счёт Б (или, что ещё лучше, на несколько счетов), вероятно, сеть должна быть достаточно безопасной, если трудно доказать даже сам факт осуществления такого перевода. Но если все транзакции Биткойна хранятся в открытом реестре, то как тогда можно скрыть денежные переводы?
Идея, которая позже легла в основу CoinJoin, была предложена Грегом Максвеллом в начале 2013 года. Есть довольно много коммерческих решений для повышения анонимности при пользовании Биткойном. Здесь представлен их всеобъемлющий и актуальный обзор. Большинство из них в той или иной форме опираются на идею CoinJoin главным образом потому, что она не требует каких-либо изменений на уровне протокола Биткойна.
Идея заключается в следующем. Напомним, что Биткойн-транзакция представляет собой список UTXO – входов (расходуемых средств) и выходов. Отправитель предоставляет разблокирующий скрипт для каждого входа UTXO и блокирует каждый UTXO выхода. Транзакция действительна, если:
[Правило 1] все входы успешно разблокированы [Правило 2] общая сумма входов равна сумме выходов.Не то чтобы эти два правила говорили о том, что все входы должны исходить от одного адреса, или о том, что все выходы должны быть каким-то образом связаны. Значит, вполне кошерно будет включить в одну транзакцию разные UTXO, исходящие из разных несвязанных между собой адресов. Теперь предположим, что Элис хочет отправить 1 BTC Бобу и в то же время Кэрол хочет отправить 1 BTC Дейву. И Элис, и Кэрол, не хотели бы оставлять лишних следов, поэтому, вместо того, чтобы отправить отслеживаемые транзакции
tx1: A->B; tx2: C->D
они могут сформировать одну транзакцию следующего вида:
tx: {
inputs: [
{1BTC; <Alice’ Sig>},
{1BTC; <Carol’s Sig>},
],
outputs: [
{1BTC; <Bob’s PK>},
{1BTC; <Dave’s PK>}
]
}
И в этом случае невозможно сказать, отправляет ли Элис средства Бобу или Дейву, и это же относится к Кэрол. Иллюстративный псевдокод, приведённый выше, чрезвычайно далёк от того, чтобы быть действительной Биткойн-транзакцией, однако достаточен для того, чтобы передать принцип работы CoinJoin.
Оригинальное объяснение Грега Максвелла.
Недостатки CoinJoin
Главный недостаток CoinJoin заключается в необходимости найти другого контрагента, который готов участвовать в такой микширующей транзакции. Без достаточно большого числа участвующих адресов кластерный анализ всё ещё может выявить получателей (или, по крайней мере, существенно сузить их круг).
Далее. Редко бывает так, что Элис нужно отправить Бобу круглое число биткойнов. Для совершения небольшого платежа может потребоваться несколько смешанных транзакций с разными контрагентами, что увеличивает общую сложность и сокращает «анонимное множество» (anonymity set, т.е. набор транзакций, неотличимых от транзакции Элис).
Оба этих вопроса решаются в Monero, Zcash и Mimblewimble, но очень разными способами. Оставляя подробности для следующих статей, позволим себе небольшой тизер:
- Monero и ZCash (задействуя совершенно разные методы) используют очень контринтуитивный факт, заключающийся, грубо говоря, в том, что и [Правило 1], и [Правило 2] возможно проверить, не зная ни открытых ключей, ни перечисляемых сумм. Monero – это как CoinJoin на криптографических стероидах (со скрытыми значениями UTXO и ложными контрагентами). В Zcash используются zk-proof, за счёт чего генерируется большее анонимное множество.
- MimbleWimble – это совершенно другой зверь, хотя его базовые криптографические примитивы похожи на используемые в Monero. В Mimblewimble вообще нет секретных ключей и адресов в обычном смысле. Вместо этого, право потратить конкретный UTXO реализуется сложным, но удивительно эффективным (с точки зрения хранения и обработки данных) способом.
Дисклэймер: автор берёт на себя ответственность за все возможные неточности, хотя и старался обойтись без них.
: EthClassic