Перевод Конфиденциальные транзакции или «отправляем неизвестно сколько, неизвестно кому и неизвестно куда»

Тема в разделе "Статьи", создана пользователем Mr. Pickles, 12 окт 2018.

  1. Mr. Pickles

    Команда форума Модератор Редактор

    Регистрация:
    11 сен 2017
    Сообщения:
    283
    Симпатии:
    97
    Мы продолжаем серию статей, посвящённых внутренним механизмам работы блокчейна Monero, и сегодня мы поговорим о RingCT (сокращение, используемое для обозначения кольцевых конфиденциальных транзакций — Ring Confidential Transactions), алгоритме, являющимся улучшенной версией кольцевых подписей и позволяющем скрывать сумму, которая передаётся при проведении транзакции.

    1.jpeg

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

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

    Что такое RingCT?

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

    Безусловно, идея сама по себе не нова. Одним из первых подобное предложил ведущий разработчик Bitcoin Грег Максвелл (Greg Maxwell), который описал похожий алгоритм в статье Confidential Transactions (Конфиденциальные транзакции). Текущий вариант реализации RingCT представляет собой модификацию этой идеи, которая, как нам подсказывает название, предусматривает использование кольцевых подписей (очевидно, без них не обойтись).

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

    Впервые эта возможность была реализована в протоколе Monero в январе 2017 и в сентябре того же года после хардфорка до версии 6 и стала единственным способом проведения транзакций.

    RingCT использует сразу несколько механизмов, позволяющих скрыть сумму транзакции: MLSAGs (сокращение, для обозначения подписей многоуровневой связанной спонтанной анонимной группы — Multilayered Linkable Spontaneous Anonymous Group signatures), схему обязательств Педерсена, а также доказательства диапазона (range proofs).

    В случае с Monero есть два основных типа транзакций RingCT: TypeSimple и TypeFull. В настоящее время Simple (простой тип) используется для транзакций со множеством входов, а Full (полный тип) — для транзакций с одним входом. Оба типа немного отличаются друг от друга. Отличие состоит в том, как подтверждаются транзакции, а также как за ними закрепляются подписи. Но в целом оба типа одинаковы. Как написано в работе Zero to Monero (Monero с нуля), которая является лучшим руководством по этой криптовалюте, само решение ограничить транзакции типа TypeFull одним входом было принято в спешке, и это вполне может измениться в будущем.

    MLSAGs

    Давайте вспомним, что такое входы транзакции. При проведении транзакции одновременно тратится и генерируется определённая сумма средств. Сгенерированные средства называют выходами, а выходы, которые тратятся во время транзакции становятся её входами (будьте внимательны, тут просто запутаться.).

    Основная функция кольцевых подписей любого типа заключается в том, что они позволяют производить так называемое «смешивание транзакций». Это означает, что когда вы отправляете кому-либо средства, система создаёт несколько «фальшивых» выходов, которые также используются в транзакции. Таким образом, создаётся «дымовая завеса», и третья сторона не может отследить реального отправителя. Другими словами, каждый потенциальный вход относится ко множеству входов, но реально тратится только один из них.

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

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

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

    Давайте просмотрим, как формируется кольцевая подпись. Для примера возьмём транзакцию, при проведении которой тратится 2 реальных выхода и используется m–1 случайных выходов для смешивания. В данном случае мы обозначаем публичные ключи выходов, которые тратятся:
    2.png
    и соответствующие образы ключей:
    3.png
    соответственно. Таким образом, мы получаем матрицу 2×m. Сначала нам необходимо вычислить так называемые «вызовы» для каждой пары выходов:
    4.png
    Рисунок 1. Вычисление вызовов

    Мы начинаем вычисления с выходов, которые будут потрачены, используя их публичные ключи
    5.png
    и два случайных числа
    6.png
    Это даёт нам ряд значений
    7.png
    которые мы затем используем для вычисления «вызовов».
    8.png
    для следующей пары выходов. На рисунке 1 мы использовали разные цвета, чтобы вам проще было понять, какие значения заменяются. Все последующие значения вычисляются по кругу по тем же самым формулам, поэтому «вызовы» для реальной пары выходов будут последними.

    Как можно увидеть, во всех столбцах, кроме того, что содержит реальные выходы, у нас есть случайно сгенерированные числа.
    9.png
    которые мы также используем для столбца π. Теперь преобразуем α в s.
    10.png
    Рисунок 2.Воспроизведение s

    Подпись сама по себе является последовательностью всех вычисленных значений:
    11.png
    Рисунок 3.Формирование подписи MLSAG

    Затем эти данные добавляются в транзакцию.

    Как видим, наша подпись MLSAG содержит всего один «вызов», co, что гарантирует, что подпись, которая уже достаточно длинна, не станет ещё длиннее. Теперь, чтобы убедиться в том, что транзакция законна, мы можем восстановить значения
    12.png
    Теперь кольцо является полным, а подпись верифицирована.

    В случае с транзакциями TypeFull в матрицу добавляется ещё один ряд. А теперь давайте перейдём к следующему компоненту RingCT. Вернёмся к TypeFull чуть позже.

    Обязательства Педерсена

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

    В случае с Monero обязательства используются для того, чтобы скрыть суммы проводимых транзакций. Разработчиками был выбран самый распространённый вариант — обязательства Педерсена. Довольно интересно, что сначала теми же разработчиками предлагалось скрывать сумму, используя только смешивание, то есть путём добавления в любую транзакцию некоторого количества выходов со случайными суммами. До сих пор остаётся открытым вопрос, делает ли выбранное решение размер транзакции меньше.

    В целом обязательство выглядит следующим образом:
    13.png
    где C является значением самого обязательства, a — значением, которое мы собираемся скрыть, H является фиксированной точкой на эллиптической кривой (дополнительным генератором), а x — некой случайной маской, случайно сгенерированным коэффициентом, который добавляет очередной уровень сокрытия целевого значения и значительно усложняет процесс восстановления оригинального значения при помощи грубой силы.

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

    Простые RingCT

    В случае с транзакциями RingCT типа TypeSimple, если нам необходимо гарантировать, что сумма всех созданных выходов будет равна сумме всех входов (то есть при проведении транзакции деньги не будут созданы из воздуха), мы можем просто проверить соответствие сумм их обязательствам, то есть:
    14.png
    Обязательство по комиссии вычисляется немного по-другому, без маски:
    15.png
    Где a является публично доступной суммой комиссии.

    Этот подход позволяет доказать каждому, что мы используем ту же сумму, не раскрывая её.

    Чтобы предельно всё прояснить, рассмотрим пример. Предположим, при проведении транзакции тратятся два выхода (то есть они становятся входами) на 10 и 5 XMR, соответственно. При этом генерируется три выхода общим достоинством 12 XMR, скажем, по 3, 4 и 5 XMR. В то же самое время отправитель устанавливает размер комиссии 3 XMR. Таким образом, сумма, которая тратится, равна сгенерированной сумме плюс комиссии, то есть 15 XMR. Попытаемся вычислить обязательства и разницу соответствующих сумм:
    16.png
    Рисунок 4.Разница сумм по соответствующим обязательствам

    Нам необходимо, чтобы суммы были одинаковыми, поэтому кошелёк генерирует ряд случайных чисел
    17.png
    а мы вычисляем остаток
    18.png
    Используя эти маски, мы можем доказать, что нами не было сгенерировано больше средств, чем мы потратили. При этом мы не раскрываем точной суммы. Здорово, не так ли?

    Полные RingCT

    В случае с транзакциями типа TypeFull всё немного усложняется: кошелёк не производит повторного вычисления обязательств для входов, но использует те, что были вычислены во время генерирования. Это означает, что разница соответствующих сумм не будет нулевой, но станет следующей:
    19.png
    где z является разницей масок, связанных со входами и выходами. Если мы возьмём zG в качестве публичного ключа (который им и является по факту), то z будет приватным ключом. Таким образом, нам известны публичные и соответствующие приватные ключи. С такими данными мы можем применить их к кольцевой подписи MLSAG наряду с публичными ключами выходов, которые будут смешаны:
    20.png
    Рисунок 5. Данные, подписанные кольцевой подписью

    Таким образом, действительная кольцевая подпись гарантирует, что нам известны все приватные ключи для одного из столбцов, и нам может быть известен только приватный ключ, связанный с последним рядом, если транзакция не генерирует больше средств, чем тратится. Между прочим, вот и ответ на вопрос, почему в этом случае нам не нужно, чтобы разница между соответствующими суммами по обязательствам была нулевой: если zG = 0, то столбец с реальными выходами будет раскрыт.

    Но как получателю определить, сколько денег ему было отправлено? Это просто: отправитель и получатель обмениваются ключами по протоколу Диффи-Хеллмана, а затем используют ключ транзакции и ключ просмотра получателя, чтобы вычислить скрытое значение.

    Доказательства диапазона

    А теперь что может произойти, если мы используем отрицательное число в качестве суммы обязательств? Это может привести к созданию дополнительных монет! Такой результат был бы неприемлемым, следовательно, нам нужно гарантировать, что числа, используемые нами, никогда не будут отрицательными (безусловно, не раскрывая сумм). Другими словами, нам требуется доказать, что сумма находится в пределах
    21.png
    Для этого сумма каждого выхода делится на двоичные цифры, а затем обязательства для каждого разряда числа вычисляются по отдельности. Это будет проще понять на примере.

    Предположим, мы создаём выход 5 XMR, и все суммы, которые мы получаем, будут достаточно маленькими, чтобы уложиться в 4 бита (в реальности это составляет 64 бита). Мы вычисляем обязательства для каждого разряда числа и «общее обязательство» для всей суммы:
    22.png
    Рисунок 6. Побитовые обязательство

    Затем каждое обязательство смешивается со своим заменителем.
    23.png
    а каждая пара подписывается кольцевой подписью Борромео, которая является ещё одним типом кольцевой подписи, предложенной Грегом Максвеллом в 2015 г. (узнать об этом больше можно здесь):
    24.png
    Рисунок 7. Подписание обязательств

    Это метод, позволяющий гарантировать, что все обязательства касаются суммы, не превышающей пределов
    25.png
    называется «доказательствами диапазона».

    Что дальше?

    В своём текущем варианте реализации доказательства диапазона занимают очень много места, 6176 байт на выход. Это приводит к исключительному росту размера транзакций и, как следствие, к росту комиссий. Чтобы ограничить размер транзакций, разработчики Monero собираются перейти от использования подписей Борромео к Bulletproofs, механизму доказательства диапазона, не использующему побитовой обработки. По некоторым оценкам это сократит размер доказательств диапазона на 94%. В июле этого года технология прошла аудит, который проводился компанией Kudelski Security. В результате не было выявлено каких-либо серьёзных недостатков как в самой технологии, так и в её реализации. Bulletproofs уже используется в тестовой сети и, вероятнее всего, механизм будет реализован в основной сети во время следующего хардфорка.

    Далее, в нашей серии статей мы поговорим о других аспектах блокчейна Monero, например, об архитектуре кошельков и библиотеке libwallet, а также о перспективах сети.

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

    Источник: Monero: Confidential Transactions, or Send I Know Not What to Someone I Know Not Whither

    Перевод:
    Mr. Pickles (@v1docq47)
    Редактирование:
    Agent LvM (@LvMi4)
    Коррекция:
    Kukima (@Kukima)
     
    #1 Mr. Pickles, 12 окт 2018
    Последнее редактирование: 12 окт 2018
    TheFuzzStone и tooman нравится это.
  • О нас

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