Что такое Tornado Cash?
⠀
Одной из особенностей блокчейна является то, что ее реестр, содержащий все когда-либо имевшие место транзакции, виден глобально, то есть можно отслеживать средства по мере их перехода из рук в руки, а в некоторых случаях полностью деанонимизировать пользователей.
⠀
Tornado Cash — это сервис, который смешивает разные потоки потенциально идентифицируемой криптовалюты и таким образом не дает отследить переход криптовалюты с одного адреса на другой.
⠀
Tornado Cash — является децентрализованным криптомиксером, это значит, что он использует смарт-контракты, которые принимают криптовалюту, а затем позволяют выводить их на другие адреса. Поскольку вывод средств производится из пулов ликвидности смарт-контрактов проекта, невозможно узнать, кто является первоначальным отправителем. Это скрывает поток средств и затрудняет их отслеживание.
⠀
Анонимная связка адреса отправителя и адреса получателя возможна благодаря технологии доказательства с нулевым разглашением (Zero-knowledge proof). Доказательство с нулевым разглашением позволяет вам доказать истинность утверждения, не раскрывая содержание утверждения и не раскрывая, как вы обнаружили истину. Конкретно Tornado Cash использует протокол zk-SNARK.
⠀
Важно отметить, что, используя zk-SNARK, Tornado Cash позволяет вам вносить в контракт фиксированные суммы ETH, DAI, USDC или USDT. Когда вы вносите деньги (Deposit), вы получите резервный код, который вам понадобится для вывода (Withdrawal) средств позже.
⠀
Почему фиксированные суммы? Например, вы внесли 0,1 ETH, а также помимо вас это сделали еще 303 человека. А поскольку процес передачи средств в смарт-контракт являтся общедоступной информацией, когда вы вносите 0,1 ETH, эти 0,1 ETH позже можно будет отследить до этой группы из 303 человек, но не до вас напрямую.
⠀
Алгоритм работы
⠀
Размещение (Deposit)
⠀
Прежде чем Алиса вложит деньги в Tornado Cash, ей нужно будет выбрать два случайных числа: secret и nulifier, а затем она вычислит хэш этих двух случайных чисел.
⠀
Чтобы внести(разместить) депозит в Tornado Cash, Алиса отправит 1 ETH и хэш чисел secret и nulifier. Пускай в нашем примере это будет 0x404.
⠀

⠀⠀
Отправленный эфериум хранится в смарт-контракте, как и хэши, которые необходимы для определения обязательств, хэш позже будет использоваться для вывода этого 1 ETH из Tornado Cash.
⠀⠀
Вывод средств
⠀⠀
Прежде чем разобрать вывод средств, рассмотрим, как бы это могло бы быть сделано неправильно, то есть компрометируя выводящего средства, а потом посмотрим, как это сделать правильно.
⠀⠀
Итак, неправильный путь это когда выводящий средства, передаст в смарт контракт числа secret и nulifier, а смарт-контракт проверит, что хэш есть в хранилище смарт-контракта и отдаст нужное кол-во ETH. Подобный процесс раскрывает личность выводящего деньги из смарт-контракта. Например, мы знаем, что Алиса разместила в смарт-контракте хэш 0x404,а позже появляется анонимный пользователь передающий secret и nulifier, так что хеш secret и nulifier равен 0x404, но поскольку хеш-функция является односторонней функцией, это означает, что единственный человек, который знает secret и nulifier, который хэширует в 0x404 - это Алиса. Именно так личность пользователя раскрывается при снятии средств. Итак, как мы можем решить эту проблему.
⠀⠀
Если каким-то образом есть возможность доказать, что я знаю secret и nulifier, так что hash (secret,nulifier) есть в смарт-контракте, но без раскрытия secret и nulifier. Тогда анонимный пользователь мог бы отсылать в смарт-контракт некое доказательство что он знает secret и nulifier без фактической отправки этих чисел или хэша, а смарт-контракт проверял бы, действительно ли доказательство, при этом смарт-контракт не знал бы, предназначено ли доказательство для 0x404 или для 0x403 или 0x505, которые также записаны в смарт-контракт, другими словами, доказательство не раскрывало бы личность анонимного пользователя.
⠀⠀

⠀⠀
Подобный механизм называется доказательством с нулевым разглашением, то есть, когда вы можете доказать, что вам известна какая-то информация, не раскрывая ничего о фактической информации. Конкретно Tornado Cash использует криптографический протокол zk-SNARK.
⠀⠀
Что за nulifier?
⠀⠀
Узнав, что смарт-контракт проверят действительно ли доказательство, но не знает для какого конкретно хэша, какой-нибудь хакер захотел бы много раз отправить одно и тоже доказательство, чтобы получить много ETH. Поэтому, чтобы предотвратить подобное двойное использование, когда вы отправляете доказательство для вывода, вам также нужно будет отправить хэш nulifier внутри доказательства.
⠀⠀

⠀⠀
И тогда "внутри" zk-SNARK будет проверятся:
⠀⠀
— что hash(secret,nulifier) есть в смарт-контракте;
— корректность, что хэш от nulifier == hash(nulifier).
⠀⠀
После этих проверок, смарт-контракт отдаст ETH и "запишет", что вывод средств был произведен.
⠀⠀
Хранение данных
⠀⠀
Для того, чтобы осуществлять большое количество проверок хэшей в Tornado Cash данные хранится в Merkle tree.
⠀⠀
Использование хеш-деревьев позволяет "малыми" затратами проверять принадлежности определённого блока данных к множеству.
⠀⠀
Поскольку различными блоками часто являются независимые данные, в нашем случае хэши вложенных средств, то нас интересует возможность проверить только один блок, не пересчитывая хеши для остальных узлов дерева. Пусть интересующий нас блок — это синий блок на картинке. Тогда доказательством его существования и валидности будут корневой хеш, а также верхние хеши других веток.
⠀⠀

Зеленым отмечены хэши которые понадобятся нам для проверки, что синий элемент принадлежит к множеству средств внутри Tornado Cash
⠀⠀
Доказательства с нулевым разглашением ZKPs
⠀⠀
Верхнеуровнево при создании ZKP проверяющий просит доказывающего выполнить ряд действий, которые могут быть выполнены точно только в том случае, если доказывающий знает основную информацию. Если доказывающий только догадывается о результате этих действий, то в конечном итоге тест верификатора с высокой степенью вероятности докажет, что они ошибочны.
⠀⠀

⠀⠀
Концептуальный пример для интуитивного понимания данных доказательства в условиях нулевого разглашения это представить себе пещеру с одним входом, но двумя путями (путь A и B), которые соединяются через общую дверь, запертую кодовой фразой. Алиса хочет доказать Бобу, что она знает код доступа к двери, но не раскрывая код Бобу. Для этого Боб стоит снаружи пещеры, а Алиса идет внутрь пещеры, выбирая один из двух путей (при этом Боб не знает, какой путь был выбран). Затем Боб просит Алису вернуться к входу в пещеру по одному из двух путей (выбранных случайным образом). Если Алиса изначально выбрала путь А к двери, но затем Боб просит ее вернуться по пути Б, единственный способ решить головоломку для Алисы — это знать код доступа к запертой двери. Этот процесс может быть повторен несколько раз, чтобы доказать, что Алиса знает код доступа к двери и не выбрала правильный путь изначально с высокой степенью вероятности.
⠀⠀
После завершения этого процесса Боб имеет высокую степень уверенности в том, что Алиса знает код доступа к двери, не раскрывая код доступа Бобу. Хотя это всего лишь концептуальный пример, ZKP используют ту же стратегию, но используют криптографию для подтверждения знаний о точке данных, не раскрывая сами данные.
⠀⠀
Итог
⠀⠀
Теперь у нас есть все, чтобы понять, как работает Tornado Cash (TC). Когда вы вносите 1 ETH по контракту Tornado Cash , вы представляете хэш доказательство. Этот хэш будет храниться в Merkle. Когда вы снимаете этот 1 ETH с другой учетной записи, вы должны предоставить 2 доказательства с нулевым разглашением. Первый доказывает, что дерево Меркель содержит ваши хэши. Это доказательство является доказательством с нулевым разглашением. Но этого недостаточно, потому что вам должно быть разрешено снять этот 1 ETH только один раз. Из-за этого вы должны предоставить nulifier, уникальный для доказательства. Контракт хранит этот nulifier,и это гарантирует, что вы не сможете снять внесенные деньги более одного раза.
⠀⠀
Заключение
⠀⠀
Санкции на смарт-контракт являются интересным прецедентом, так как смарт-контракт сам по себе автономен, и пока не ясно к каким образом должна выглядеть, например, полная блокировка сервиса на уровне сети Ethereum.
IvanRomanovich для Habr.com.





