Введение: Недавно Виталик и некоторые ученые совместно опубликовали новую статью, упоминая, как Tornado Cash реализует схему противодействия отмыванию денег (в сущности, позволяя совершившему вывод доказать, что его депозит принадлежит к набору, который не содержит грязные деньги), но в статье отсутствует подробная интерпретация бизнес-логики и принципов работы Tornado Cash, что оставляет некоторых читателей в замешательстве.
Стоит отметить, что проекты конфиденциальности, представленные Tornado, действительно используют свойство нулевого разглашения алгоритма ZK-SNARK, в то время как большинство проектов, помеченных ZK, используют только лаконичность ZK-SNARK. Люди часто путают разницу между доказательством валидности и ZK, и Tornado служит отличным примером для понимания применения ZK. Автор этой статьи писал о принципах Tornado в 2022 году для Web3Caff Research, а сегодня выбирает и расширяет некоторые разделы из этой статьи, организуя их в эту статью, чтобы систематически понимать Tornado Cash.
Ссылка на оригинал статьи: https://research.web3caff.com/zh/archives/2663?ref=157
Tornado Cash использует протокол смешивания монет на основе доказательств с нулевым разглашением, причем его старая версия была запущена в 2019 году, а новая бета-версия была выпущена к концу 2021 года. Старая версия Tornado достигла высокого уровня децентрализации, поскольку ее контракты на цепочке являются открытыми и не контролируются никаким механизмом мультиподписи, а ее код фронтенда также является открытым и резервируется в сети IPFS. Из-за более простой и понятной структуры старой версии Tornado данный материал сосредотачивается на ее объяснении. Основная идея Tornado заключается в том, чтобы смешивать большое количество действий по депозиту и выводу вместе. После депонирования токенов в Tornado депозиторы представляют доказательство ZK, чтобы доказать, что они сделали депозит, а затем выводят их на новый адрес, тем самым разрывая связь между адресами депозита и вывода.
Более конкретно, Торнадо действует как стеклянный ящик, наполненный монетами, которые внесли многие люди. Мы можем видеть, кто внес монеты, но поскольку монеты сильно гомогенизированы, трудно проследить, какая монета была внесена кем, если кто-то незнакомый снимает монету.
(Источник: rareskills)Этот сценарий довольно распространен; например, когда мы обмениваем ETH в пуле Uniswap, мы не можем знать, чей ETH мы получаем, потому что многие предоставили ликвидность Uniswap. Однако разница заключается в том, что каждый раз, когда вы обмениваете токены на Uniswap, вам нужно использовать другие токены в качестве эквивалентной стоимости, и вы не можете «конфиденциально» передавать средства кому-то еще; в то время как с миксером вам нужно только показать доказательство депозита для вывода. Чтобы действия по депозиту и выводу выглядели однородно, каждый депозит в пул Tornado и каждый вывод из него поддерживаются в постоянном объеме. Например, если в пуле 100 вкладчиков и 100 выводящих, хотя они видимы, они кажутся независимыми, и сумма, внесенная и выведенная каждым из них, одинакова.
Это может затруднить прослеживаемость переводов средств, предлагая естественное удобство для анонимизации транзакций. Основной вопрос: как выводящая сторона докажет, что она сделала депозит?
Адрес, с которого производится вывод, не связан ни с одним из адресов депозита, так как может быть определена их право на вывод? Самым прямым методом кажется то, чтобы тот, кто делает вывод, раскрыл, какая запись депозита принадлежит ему, но это непосредственно раскроет его личность. Здесь в игру вступают доказательства нулевого знания. Представив доказательство ZK о том, что у них есть запись депозита в контракте Tornado, которая еще не была выведена, выводитель может успешно начать вывод. Доказательства нулевого знания по своей сути защищают конфиденциальность, раскрывая только то, что человек действительно внес депозит в фондовый пул, не раскрывая, кому из депозиторов он соответствует.
Для доказательства того, что "Я сделал депозит в фондовом пуле Tornado", можно перевести как "Моя запись депозита может быть найдена в контракте Tornado." Если мы используем Cn для представления записи депозита, проблема заключается в следующем: учитывая, что набор записей депозитов Tornado - {C1, C2, …C100…}, человек, желающий снять деньги, Боб, доказывает, что он использовал свой ключ для генерации некоторого Cn в записях депозитов, не раскрывая, какой именно Cn. Это связано со специальным свойством доказательства Merkle. Все записи депозитов Tornado включены в построенное на цепи дерево Меркля, при этом эти записи являются его листовыми узлами нижнего уровня. Общее количество листьев составляет около 2^20 > 1 миллиона, большинство из которых находятся в пустом состоянии (получили начальное значение). Всякий раз, когда происходит новый депозит, контракт записывает его уникальное значение, Commitment, в лист и затем обновляет корень дерева Меркля.
Например, если месторождение Боба было 10 000-м в истории Tornado, характеристическое значение Cn, связанное с этим месторождением, было бы введено в 10 000-й листовой узел дерева Меркла, т.е. C10000 = Cn. Затем контракт автоматически вычисляет новый корень и обновляет его. Чтобы сэкономить вычислительные ресурсы, контракт Tornado кэширует данные из пакета ранее измененных узлов, таких как Fs1, Fs2 и Fs0 на схеме ниже.
(Источник: RareSkills)
Доказательство Меркля по своей природе является кратким и легким, используя простоту структур данных деревьев в процессах поиска/отслеживания. Чтобы внешне доказать, что транзакция TD существует в Дереве Меркля, необходимо предоставить только Доказательство Меркля, соответствующее Корню, что довольно просто. Если Дерево Меркля особенно крупное, с 2^20 степенью листьев нижнего уровня (т. е. 1 миллион записей о депозите), Доказательство Меркля будет содержать только значения 21 узла, что очень коротко.
Для того чтобы доказать, что транзакция H3 действительно содержится в дереве Меркля, необходимо продемонстрировать, что с использованием H3 и других частей данных на дереве Меркля можно сгенерировать Корень, и данные, необходимые для генерации Корня (включая Td), составляют доказательство Меркля. Когда Боб снимает средства, ему необходимо доказать, что его сертификат соответствует хэшу депозита Cn, записанному в дереве Меркля в учетной книге Tornado. Другими словами, ему необходимо доказать две вещи: Cn существует во внеплановом дереве Меркля Tornado на цепи, конкретно, путем построения доказательства Меркля, содержащего Cn; Cn связан с депозитным сертификатом Боба.
Во фронтенд-коде пользовательского интерфейса Tornado множество функциональностей предварительно реализованы. Когда депозитор открывает веб-страницу Tornado Cash и нажимает кнопку депозита, сопровождающий фронтенд-код генерирует два случайных числа, K и r, локально. Затем он вычисляет значение Cn=Hash(K, r) и передает Cn (называемый обязательством на диаграмме ниже) контракту Tornado, который вставляет его в дерево Меркла, записанное последним. По сути, K и r действуют как частные ключи. Они критичны, и система призывает пользователей сохранить их надежно. K и r снова понадобятся при выводе.
(Опция encryptedNote позволяет пользователям зашифровать учетные данные K и r с помощью закрытого ключа и хранить их в блокчейне, чтобы предотвратить их забвение) Важно отметить, что все эти операции происходят вне блокчейна, а это означает, что контракт Tornado и внешние наблюдатели не знают о K и r. Утечка K и r сродни краже приватных ключей кошелька.
Получив депозит от пользователя и представив Cn=Хэш(K, r), контракт Tornado записывает Cn в нижний слой дерева Меркля в качестве нового листового узла, обновляя также значение корня. Таким образом, Cn напрямую связан с действием депозита пользователя, позволяя посторонним знать, какой пользователь соответствует каждому Cn, кто внес токены в миксер, и записи депозита Cn каждого депозитария.
В процессе вывода средств выводящий средства вводит учетные данные/закрытый ключ (случайные числа K и r, сгенерированные во время депозита) на веб-странице веб-интерфейса. Программа в коде фронтенда Tornado Cash использует K и r, Cn=Hash(K, r) и доказательство Меркла, соответствующее Cn, в качестве входных параметров для генерации ZK Proof. Это доказывает, что Cn существует в дереве Меркла как депозитная запись, а K и r являются учетными данными, соответствующими Cn. Этот шаг, по сути, доказывает: я знаю ключ, соответствующий записи депозита на дереве Меркла. Когда ZK Proof передается в контракт Tornado, эти четыре параметра скрыты, защищая конфиденциальность. Генерация ZK Proof включает в себя дополнительные параметры, в том числе корень Меркла, записанный в контракте Tornado в момент вывода, пользовательский адрес получателя A и идентификатор nf для предотвращения атак с воспроизведением. Эти три параметра публикуются в блокчейне, что не ставит под угрозу конфиденциальность.
Важно отметить, что вместо одного случайного числа для генерации Cn используются два случайных числа, K и r, что обеспечивает повышенную безопасность от столкновений. A представляет собой адрес получателя средств, выбранный снявшим их. Идентификатор nf, предназначенный для предотвращения атак повторной передачи, рассчитывается как nf=Hash(K), где K - одно из двух случайных чисел, используемых на этапе депонирования для генерации Cn. Это прямо связывает nf с Cn, устанавливая однозначную корреляцию между каждым Cn и соответствующим ему nf. Цель предотвращения атак повторной передачи заключается в том, что функция миксера сохраняет ассоциацию между суммами вывода и конкретными листьями дерева Меркля (Cn) неизвестной, что позволяет злоупотреблять повторными выводами до исчерпания пула средств.
Идентификатор nf функционирует аналогично одноразовому номеру, связанному с каждым адресом Ethereum, предотвращая повторное воспроизведение транзакций. Когда происходит вывод средств, проверка гарантирует, что представленный nf не был использован ранее; Если не использовано, вывод действителен, и NF записывается. Любая попытка сгенерировать nf, не связанную с каким-либо зарегистрированным депозитом Cn, не приведет к получению действительного доказательства ZK, что сделает вывод неуспешным.
Если кто-то случайным образом создает незаписанный невзаимозаменяемый (nf) контракт, это будет работать? Конечно, нет. Когда снимающий средства генерирует Доказательство нулевого знания (ZK Proof), он должен убедиться, что nf равно Hash (K), где случайное число K связано с записью депозита Cn. Это означает, что nf связан с записанным депозитом Cn. Если кто-то производит nf произвольно, этот nf не будет соответствовать никаким записям о депозите, что делает невозможным генерацию действительного ZK Proof. Следовательно, процесс вывода не может быть успешно завершен, и операция вывода завершится неудачей. Некоторые могут спросить: возможно ли продолжить без nf? Поскольку снимающему средства необходимо представить ZK proof во время вывода, чтобы доказать свое отношение к определенному Cn, почему бы просто не проверить, было ли представлено соответствующее Доказательство ZK на блокчейне каждый раз при выводе? Однако данный подход чрезвычайно затратен, поскольку контракт Tornado Cash не постоянно хранит прошлые ZK Proofs из-за значительного расхода места для хранения. Сравнение каждого нового ZK Proof, представленного на блокчейн с существующими доказательствами, менее эффективно, чем установка небольшого идентификатора, например nf, и его постоянное хранение.
Согласно примеру кода функции вывода, необходимые параметры и бизнес-логика следующие: Пользователь отправляет доказательство ZK и nf (NullifierHash) = Hash (K), указывает адрес получателя для вывода и доказательство ZK скрывает значения Cn, K и r, что делает невозможным для посторонних определить личность пользователя. Получатель часто использует новый чистый адрес, который не раскрывает личную информацию.
Однако есть небольшая проблема: когда пользователи выводят средства, чтобы остаться ненаблюдаемыми, они часто инициируют транзакцию вывода с только что созданного адреса. В этот момент новому адресу не хватает ETH для оплаты комиссии за газ. Поэтому при инициировании вывода адрес вывода должен явно объявить реле, чтобы оплатить комиссию за газ от его имени. После этого контракт миксера вычитает часть из вывода пользователя для компенсации реле.
В заключение, Tornado Cash может затруднить связь между снимающими и вкладчиками. В ситуациях с большим пользовательским базисом это похоже на то, как преступник смешивается с толпой в оживленном районе, что делает сложным для полиции отслеживание. Процесс вывода включает использование ZK-SNARKs, причем скрытая часть свидетеля содержит критическую информацию о снимающем, что является ключевым аспектом всего миксера. В настоящее время Tornado кажется одним из наиболее изобретательных проектов прикладного уровня, связанных с ZK.
Partilhar
Введение: Недавно Виталик и некоторые ученые совместно опубликовали новую статью, упоминая, как Tornado Cash реализует схему противодействия отмыванию денег (в сущности, позволяя совершившему вывод доказать, что его депозит принадлежит к набору, который не содержит грязные деньги), но в статье отсутствует подробная интерпретация бизнес-логики и принципов работы Tornado Cash, что оставляет некоторых читателей в замешательстве.
Стоит отметить, что проекты конфиденциальности, представленные Tornado, действительно используют свойство нулевого разглашения алгоритма ZK-SNARK, в то время как большинство проектов, помеченных ZK, используют только лаконичность ZK-SNARK. Люди часто путают разницу между доказательством валидности и ZK, и Tornado служит отличным примером для понимания применения ZK. Автор этой статьи писал о принципах Tornado в 2022 году для Web3Caff Research, а сегодня выбирает и расширяет некоторые разделы из этой статьи, организуя их в эту статью, чтобы систематически понимать Tornado Cash.
Ссылка на оригинал статьи: https://research.web3caff.com/zh/archives/2663?ref=157
Tornado Cash использует протокол смешивания монет на основе доказательств с нулевым разглашением, причем его старая версия была запущена в 2019 году, а новая бета-версия была выпущена к концу 2021 года. Старая версия Tornado достигла высокого уровня децентрализации, поскольку ее контракты на цепочке являются открытыми и не контролируются никаким механизмом мультиподписи, а ее код фронтенда также является открытым и резервируется в сети IPFS. Из-за более простой и понятной структуры старой версии Tornado данный материал сосредотачивается на ее объяснении. Основная идея Tornado заключается в том, чтобы смешивать большое количество действий по депозиту и выводу вместе. После депонирования токенов в Tornado депозиторы представляют доказательство ZK, чтобы доказать, что они сделали депозит, а затем выводят их на новый адрес, тем самым разрывая связь между адресами депозита и вывода.
Более конкретно, Торнадо действует как стеклянный ящик, наполненный монетами, которые внесли многие люди. Мы можем видеть, кто внес монеты, но поскольку монеты сильно гомогенизированы, трудно проследить, какая монета была внесена кем, если кто-то незнакомый снимает монету.
(Источник: rareskills)Этот сценарий довольно распространен; например, когда мы обмениваем ETH в пуле Uniswap, мы не можем знать, чей ETH мы получаем, потому что многие предоставили ликвидность Uniswap. Однако разница заключается в том, что каждый раз, когда вы обмениваете токены на Uniswap, вам нужно использовать другие токены в качестве эквивалентной стоимости, и вы не можете «конфиденциально» передавать средства кому-то еще; в то время как с миксером вам нужно только показать доказательство депозита для вывода. Чтобы действия по депозиту и выводу выглядели однородно, каждый депозит в пул Tornado и каждый вывод из него поддерживаются в постоянном объеме. Например, если в пуле 100 вкладчиков и 100 выводящих, хотя они видимы, они кажутся независимыми, и сумма, внесенная и выведенная каждым из них, одинакова.
Это может затруднить прослеживаемость переводов средств, предлагая естественное удобство для анонимизации транзакций. Основной вопрос: как выводящая сторона докажет, что она сделала депозит?
Адрес, с которого производится вывод, не связан ни с одним из адресов депозита, так как может быть определена их право на вывод? Самым прямым методом кажется то, чтобы тот, кто делает вывод, раскрыл, какая запись депозита принадлежит ему, но это непосредственно раскроет его личность. Здесь в игру вступают доказательства нулевого знания. Представив доказательство ZK о том, что у них есть запись депозита в контракте Tornado, которая еще не была выведена, выводитель может успешно начать вывод. Доказательства нулевого знания по своей сути защищают конфиденциальность, раскрывая только то, что человек действительно внес депозит в фондовый пул, не раскрывая, кому из депозиторов он соответствует.
Для доказательства того, что "Я сделал депозит в фондовом пуле Tornado", можно перевести как "Моя запись депозита может быть найдена в контракте Tornado." Если мы используем Cn для представления записи депозита, проблема заключается в следующем: учитывая, что набор записей депозитов Tornado - {C1, C2, …C100…}, человек, желающий снять деньги, Боб, доказывает, что он использовал свой ключ для генерации некоторого Cn в записях депозитов, не раскрывая, какой именно Cn. Это связано со специальным свойством доказательства Merkle. Все записи депозитов Tornado включены в построенное на цепи дерево Меркля, при этом эти записи являются его листовыми узлами нижнего уровня. Общее количество листьев составляет около 2^20 > 1 миллиона, большинство из которых находятся в пустом состоянии (получили начальное значение). Всякий раз, когда происходит новый депозит, контракт записывает его уникальное значение, Commitment, в лист и затем обновляет корень дерева Меркля.
Например, если месторождение Боба было 10 000-м в истории Tornado, характеристическое значение Cn, связанное с этим месторождением, было бы введено в 10 000-й листовой узел дерева Меркла, т.е. C10000 = Cn. Затем контракт автоматически вычисляет новый корень и обновляет его. Чтобы сэкономить вычислительные ресурсы, контракт Tornado кэширует данные из пакета ранее измененных узлов, таких как Fs1, Fs2 и Fs0 на схеме ниже.
(Источник: RareSkills)
Доказательство Меркля по своей природе является кратким и легким, используя простоту структур данных деревьев в процессах поиска/отслеживания. Чтобы внешне доказать, что транзакция TD существует в Дереве Меркля, необходимо предоставить только Доказательство Меркля, соответствующее Корню, что довольно просто. Если Дерево Меркля особенно крупное, с 2^20 степенью листьев нижнего уровня (т. е. 1 миллион записей о депозите), Доказательство Меркля будет содержать только значения 21 узла, что очень коротко.
Для того чтобы доказать, что транзакция H3 действительно содержится в дереве Меркля, необходимо продемонстрировать, что с использованием H3 и других частей данных на дереве Меркля можно сгенерировать Корень, и данные, необходимые для генерации Корня (включая Td), составляют доказательство Меркля. Когда Боб снимает средства, ему необходимо доказать, что его сертификат соответствует хэшу депозита Cn, записанному в дереве Меркля в учетной книге Tornado. Другими словами, ему необходимо доказать две вещи: Cn существует во внеплановом дереве Меркля Tornado на цепи, конкретно, путем построения доказательства Меркля, содержащего Cn; Cn связан с депозитным сертификатом Боба.
Во фронтенд-коде пользовательского интерфейса Tornado множество функциональностей предварительно реализованы. Когда депозитор открывает веб-страницу Tornado Cash и нажимает кнопку депозита, сопровождающий фронтенд-код генерирует два случайных числа, K и r, локально. Затем он вычисляет значение Cn=Hash(K, r) и передает Cn (называемый обязательством на диаграмме ниже) контракту Tornado, который вставляет его в дерево Меркла, записанное последним. По сути, K и r действуют как частные ключи. Они критичны, и система призывает пользователей сохранить их надежно. K и r снова понадобятся при выводе.
(Опция encryptedNote позволяет пользователям зашифровать учетные данные K и r с помощью закрытого ключа и хранить их в блокчейне, чтобы предотвратить их забвение) Важно отметить, что все эти операции происходят вне блокчейна, а это означает, что контракт Tornado и внешние наблюдатели не знают о K и r. Утечка K и r сродни краже приватных ключей кошелька.
Получив депозит от пользователя и представив Cn=Хэш(K, r), контракт Tornado записывает Cn в нижний слой дерева Меркля в качестве нового листового узла, обновляя также значение корня. Таким образом, Cn напрямую связан с действием депозита пользователя, позволяя посторонним знать, какой пользователь соответствует каждому Cn, кто внес токены в миксер, и записи депозита Cn каждого депозитария.
В процессе вывода средств выводящий средства вводит учетные данные/закрытый ключ (случайные числа K и r, сгенерированные во время депозита) на веб-странице веб-интерфейса. Программа в коде фронтенда Tornado Cash использует K и r, Cn=Hash(K, r) и доказательство Меркла, соответствующее Cn, в качестве входных параметров для генерации ZK Proof. Это доказывает, что Cn существует в дереве Меркла как депозитная запись, а K и r являются учетными данными, соответствующими Cn. Этот шаг, по сути, доказывает: я знаю ключ, соответствующий записи депозита на дереве Меркла. Когда ZK Proof передается в контракт Tornado, эти четыре параметра скрыты, защищая конфиденциальность. Генерация ZK Proof включает в себя дополнительные параметры, в том числе корень Меркла, записанный в контракте Tornado в момент вывода, пользовательский адрес получателя A и идентификатор nf для предотвращения атак с воспроизведением. Эти три параметра публикуются в блокчейне, что не ставит под угрозу конфиденциальность.
Важно отметить, что вместо одного случайного числа для генерации Cn используются два случайных числа, K и r, что обеспечивает повышенную безопасность от столкновений. A представляет собой адрес получателя средств, выбранный снявшим их. Идентификатор nf, предназначенный для предотвращения атак повторной передачи, рассчитывается как nf=Hash(K), где K - одно из двух случайных чисел, используемых на этапе депонирования для генерации Cn. Это прямо связывает nf с Cn, устанавливая однозначную корреляцию между каждым Cn и соответствующим ему nf. Цель предотвращения атак повторной передачи заключается в том, что функция миксера сохраняет ассоциацию между суммами вывода и конкретными листьями дерева Меркля (Cn) неизвестной, что позволяет злоупотреблять повторными выводами до исчерпания пула средств.
Идентификатор nf функционирует аналогично одноразовому номеру, связанному с каждым адресом Ethereum, предотвращая повторное воспроизведение транзакций. Когда происходит вывод средств, проверка гарантирует, что представленный nf не был использован ранее; Если не использовано, вывод действителен, и NF записывается. Любая попытка сгенерировать nf, не связанную с каким-либо зарегистрированным депозитом Cn, не приведет к получению действительного доказательства ZK, что сделает вывод неуспешным.
Если кто-то случайным образом создает незаписанный невзаимозаменяемый (nf) контракт, это будет работать? Конечно, нет. Когда снимающий средства генерирует Доказательство нулевого знания (ZK Proof), он должен убедиться, что nf равно Hash (K), где случайное число K связано с записью депозита Cn. Это означает, что nf связан с записанным депозитом Cn. Если кто-то производит nf произвольно, этот nf не будет соответствовать никаким записям о депозите, что делает невозможным генерацию действительного ZK Proof. Следовательно, процесс вывода не может быть успешно завершен, и операция вывода завершится неудачей. Некоторые могут спросить: возможно ли продолжить без nf? Поскольку снимающему средства необходимо представить ZK proof во время вывода, чтобы доказать свое отношение к определенному Cn, почему бы просто не проверить, было ли представлено соответствующее Доказательство ZK на блокчейне каждый раз при выводе? Однако данный подход чрезвычайно затратен, поскольку контракт Tornado Cash не постоянно хранит прошлые ZK Proofs из-за значительного расхода места для хранения. Сравнение каждого нового ZK Proof, представленного на блокчейн с существующими доказательствами, менее эффективно, чем установка небольшого идентификатора, например nf, и его постоянное хранение.
Согласно примеру кода функции вывода, необходимые параметры и бизнес-логика следующие: Пользователь отправляет доказательство ZK и nf (NullifierHash) = Hash (K), указывает адрес получателя для вывода и доказательство ZK скрывает значения Cn, K и r, что делает невозможным для посторонних определить личность пользователя. Получатель часто использует новый чистый адрес, который не раскрывает личную информацию.
Однако есть небольшая проблема: когда пользователи выводят средства, чтобы остаться ненаблюдаемыми, они часто инициируют транзакцию вывода с только что созданного адреса. В этот момент новому адресу не хватает ETH для оплаты комиссии за газ. Поэтому при инициировании вывода адрес вывода должен явно объявить реле, чтобы оплатить комиссию за газ от его имени. После этого контракт миксера вычитает часть из вывода пользователя для компенсации реле.
В заключение, Tornado Cash может затруднить связь между снимающими и вкладчиками. В ситуациях с большим пользовательским базисом это похоже на то, как преступник смешивается с толпой в оживленном районе, что делает сложным для полиции отслеживание. Процесс вывода включает использование ZK-SNARKs, причем скрытая часть свидетеля содержит критическую информацию о снимающем, что является ключевым аспектом всего миксера. В настоящее время Tornado кажется одним из наиболее изобретательных проектов прикладного уровня, связанных с ZK.