Криптография в Monero

Тема в разделе "Мануалы", создана пользователем Mr. Pickles, 12 дек 2019.

  1. Mr. Pickles

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

    Регистрация:
    11 сен 2017
    Сообщения:
    718
    Симпатии:
    221
    Monero использует целый ряд криптографических примитивов для различных вариантов использования.

    В сравнении с другими альткоинами криптография Monero считается консервативной, надёжной и устойчивой.

    В сравнении с Bitcoin Monero использует гораздо больше примитивов, и некоторые из них являются более продвинутыми, особенно те, что связаны с анонимностью и доказательством работы. Некоторые из них нестандартны (плохо ли, хорошо ли), были выбраны умышленно и зачастую являются наследием протокола CryptoNote.

    Асимметричная криптография в Monero

    Автор и близко не является криптографом. Следует скептически относиться к точности предлагаемой информации.

    Перед тем как мы перейдём непосредственно к специфичным для Monero вещам, добавим немного контекста. В нашем случае мы говорим об асимметричной криптографии. «Асимметричная» означает просто то, что используются два ключа:
    • приватный ключ (используется в первую очередь для подписания данных и для дешифровки данных);
    • публичный ключ (используется в первую очередь для верификации подписи и для шифрования данных).
    Это контрастирует с симметричной криптографией, предполагающей использование одного ключа, являющегося секретом, совместно используемым сторонами.

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

    С недавних пор асимметричная криптография стала брать за основу математическое определение эллиптических кривых. Кривая Edwards25519 имеет свою специфику, хорошо исследована, стандартизована и используется Monero.

    Использование приватных ключей в Monero

    Автор и близко не является криптографом. Следует скептически относиться к точности предлагаемой информации.

    В случае с Monero корневой приватный ключ генерируется случайным образом. Другие приватные ключи детерминировано выводятся на основе корневого приватного ключа.

    Приватный ключ необходимо хранить в секрете.

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

    Приватный ключ — скалярная величина, а это значит, что он однозначен.

    В уравнениях скалярные величины представлены строчными буквами.

    Связь с Ed25519

    Будучи просто случайным целым числом, приватный ключ не является чем-то специфическим для какой-либо определённой схемы в асимметричной криптографии.

    В контексте криптографии на эллиптических кривых, используемой Monero, приватный ключ является числом, на которое умножается базовая точка G. Результатом умножения является публичный ключ P (ещё одна точка на кривой). Умножение точки на число имеет специальное определение в криптографии на эллиптических кривых. Подробную информацию можно найти в этом руководстве.

    Надёжность ключа

    Перед выведением публичного ключа приватный ключ обрабатывается по модулю 1, где 1 является максимальной скалярной величиной, допустимой для кривой edwards25519.

    1 является числом порядка 2^252, таким образом, эффективная надёжность ключа составляет 252 бита, а не 256 бит. Это стандартная ситуация для криптографии на эллиптических кривых, и, скорее, является косметическим нюансом, а не проблемой.

    Шифрование

    В контексте, в котором с этим вопросом сталкивается пользователь, целое число приватного ключа:
    1. Берётся по модулю 1 во избежание поделки.
    2. Выражается как массив из 32 байт в формате следования, начиная с младшего (первый байт является наименее значимым).
    3. Преобразуется в шестнадцатеричную форму, например:
    Код:
    b3588a87056fb21dc4d052d59e83b54293882e646b543c29478e4cf45c28a402
    Приватный ключ траты

    Приватный ключ траты используется для траты Monero.

    Если конкретнее, он используется для построения одноразовых приватных ключей, позволяющих тратить соответствующие выходы.

    Приватный ключ просмотра

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

    Одноразовые приватные ключи

    Одноразовые приватные ключи как конструкция используются в скрытых адресах.

    Использование публичных ключей в Monero

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

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

    Публичный ключ является точкой (x, y) на эллиптической кривой.

    В уравнениях точки представлены прописными буквами.

    В контексте, в котором с публичными ключами сталкивается пользователь, они шифруются в шестнадцатеричном формате, где байты следуют, начиная с младшего, например:
    Код:
    016a941812293cf9a86071060fb090ab38d67945e659968cb8cf30e1bc725683
    Выведение публичного ключа

    Допустим:
    • P является публичным ключом;
    • x является приватным ключом;
    • G является «базовой точкой»; это просто константа, специфичная для edwards25519; эта точка находится на эллиптической кривой.
    Тогда:

    P = xG

    Публичный ключ является просто базовой точкой (G), умноженной на приватный ключ (x). Умножение точки представляет собой добавление точки к себе самой некоторое количество раз.

    Тем не менее такое сложение не является простым векторным сложением. Существует довольно конкретное определение, хорошо описанное в этой статье. Важно то, что результатом сложения всегда будет точка на эллиптической кривой. Например, G + G уже будет другой точкой на кривой.

    Варианты использования

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

    В качестве основы для создания пары ключей Monero использует эллиптическую кривую edwards25519.

    В свою очередь, сама кривая основана на схеме подписи Ed25519. Несмотря на то, что используется не изменённая версия кривой, в остальном Monero не совсем следует схеме Ed25519.

    Кривая edwards25519 бирационально эквивалентна кривой Curve25519.

    Определение

    Это стандартное определение кривой edwards25519, и тут нет ничего специфичного для Monero, кроме согласованных названий. Согласованные названия взяты из документа CryptoNote и широко используются в литературе по Monero.

    Уравнение кривой
    Код:
    −x^2 + y^2 = 1 − (121665/121666) * x^2 * y^2
    Примечание:
    • Кривая является двумерной (ничего особенного, как и все кривые, которые изучались в средней школе).
    • Кривая отражается ниже оси y из-за y^2 части уравнения (не является полиномом).
    Базовая точка G

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

    Следует отметить, что в данном случае достаточно указать значение y и знак значения x, так как определённый x может быть вычислен при помощи уравнения кривой.

    G = (x, 4/5) — берётся точка с положительным x

    Шестнадцатеричное представление базовой точки:
    Код:
    5866666666666666666666666666666666666666666666666666666666666666
    Порядок базовой точки, равный целому числу: 1.

    С точки зрения расположения «полотно», на котором рисуется кривая, должно иметь конечное «разрешение», таким образом, координаты точки должны «обёртываться» в некоторой точке. Это достигается за счёт значения по модулю 1 (L в нижнем регистре). Другими словами, 1 определяет максимальную скалярную величину, которую мы можем использовать.
    Код:
    l = 2^252 + 27742317777372353535851937790883648493
    
    # => 7237005577332262213973186563042994240857116359379907606001950938285454250989
    1 является простым числом, которое указывают авторы кривой.

    На практике оно обозначает надёжность приватного ключа.

    Общее количество точек на кривой

    Общее количество точек на кривой также обозначается простым числом:

    q = 2^255 - 19

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

    Реализация

    Monero использует (очевидно, изменённый) вариант реализации Ref10, предложенный Дэниелом Дж. Бернштейном (Daniel J. Bernstein).

    Справочный материал
    Образ приватного ключа Monero

    Образ приватного ключа служит для обнаружения попыток двойной траты.

    В случае с Monero средства всегда отправляются на одноразовый публичный ключ P. Соответствующий одноразовый приватный ключ x специфичен для не потраченного выхода.

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

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

    Такая схема необходима, поскольку Monero использует кольцевые подписи, которые позволяют узнать, кто точно подписал транзакцию. Вот почему простая проверка на предмет двойной траты, используемая, например, Bitcoin, в данном случае не сработает.

    Определение

    I = x*Hp(P)

    Где:
    • I является образом приватного ключа (или «образом ключа» для краткости);
    • x является одноразовым приватным ключом, используемым для разблокировки не потраченного выхода;
    • P является одноразовым публичным ключом не потраченного выхода;
    • Hp() является хеш-функцией, принимающей точку на эллиптической кривой в качестве аргумента.
    P мы вычисляем следующим образом:

    P = xG

    где G является базовой точкой на кривой edwards25519.

    Заменяем P на xG и получаем:

    I = x*Hp(xG)

    Образ ключа I является одноразовой функцией приватного ключа x.

    Справочный материал
    Base58

    Base58 является схемой шифрования из двоичного в текстовый формат. Она подобна схеме Base64, но была изменена во избежание одновременного использования не алфавитно-числовых символов и букв, которые могут выглядеть схоже при печати. Для этого из схемы Base64 были исключены следующие символы: I O l 0 + /

    Base58 требует строгого указания формата. Это приводит к тому, что одни варианты реализации несовместимы с другими, например, с точки зрения алфавитного порядка.

    С подробностями можно ознакомиться в Wikipedia.

    Base58 в Monero

    Monero использует собственный вариант Base58.

    В случае с Monero шифрование Base58 происходит в 8-байтовых блоках, за исключением последнего блока, который составляют оставшиеся (8 или меньшее количество) байтов.

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

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

    Подробную информацию можно найти по следующим ссылкам для базового варианта реализации Base58 на C++ и для неофициального варианта реализации Base58 на Python.
    Генератор псевдослучайных чисел Monero

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

    Начальное число берётся из источников энтропии, обеспечиваемых операционной системой. В случае с Linux и MacOS начальное число берётся из /dev/urandom. В случае с Windows для получения начального числа используется вызов WinAPI CryptGenRandom.

    Повторного извлечения начального числа не происходит.

    Предостережение
    • Это касается исходного варианта реализации на C++ для Monero. Следует отметить, что существует множество альтернативных вариантов реализации для создания приватного ключа, включая JavaScript, Python, Android/Java, но их необходимо исследовать на предмет правильности от случая к случаю.
    • В исходном коде Monero вы также можете найти генератор случайных байтов на базе lipsodium. Он является частью встроенной библиотеки и, очевидно, не используется в фактическом коде Monero.
    Справочный материал
    Хеш-функция Keccak-256

    В качестве хеш-функции Monero использует Keccak. В частности, в большинстве случаев используется функция Keccak-256, обеспечивающая 32-байтовые хеши.

    Keccak является лучшей хеш-функцией, разработанной специалистами не из АНБ. Функция Keccak победила в конкурсе NIST (Национальный институт науки и техники), став официальной функцией SHA3.

    Варианты использования

    Monero не использует функцию Keccak для доказательства работы. Функция используется:
    • генератором случайных чисел;
    • для хеширования блоков;
    • для хеширования транзакций;
    • с образами приватных ключей скрытых адресов (для защиты от двойной траты);
    • с контрольной суммой публичных адресов;
    • в RingCT;
    • в multisig
    • в Bulletproofs
    ...и, вероятно, для многих других вещей.
    Keckack-256 и SHA3-256

    SHA3-256 является функцией Keccak-256, но с изменённым NIST заполнением. Поэтому оригинальная версия Keccak-256 выдаёт значение хеша отличное от того, которое выдаёт функция SHA3-256 c изменённым NIST.

    Monero использует оригинальную версию Keccak-256. Стандарт NIST был опубликован только в августе 2015, в то время как Monero появилась 18 апреля 2014.

    Справочный материал
    Источник: Cryptography in Monero

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

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