Русский
Русский
English
Статистика
Реклама

Симметричное шифрование

Recovery mode Разработка собственного алгоритма симметричного шифрования на Php

17.07.2020 02:15:28 | Автор: admin

Однажды, несколько лет назад, доводилось делать тестовое задание для трудоустройства на работу в одну компанию, где в качестве задания стояла задача разработать нестандартный алгоритм симметричного шифрования на высокоуровневом яп, идейно в чем-то непохожий на классику жанра операцию xor исходного сообщения и секретного ключа. Задание было худо бедно сделано, но сама идея создания интересного нетривиального алгоритма засела в голове надолго.
И, на данный момент из нее получилось то, что я назвал GenCoder.


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


Собственно, исходный код класса можно посмотреть здесь, а потестировать можно тут


Итак, задача (данного исследовательского эксперимента, так его назовем) стояла следующая:


Разработать собственный алгоритм обратимого шифрования, притом что:


  • Каждый раз одно и то же сообщение будет зашифровываться уникальным образом и не повторяться.
  • Внедрить так называемую "рандомизацию" секретного ключа найти способ как шифровать сообщения не постоянно одним и тем же секретным ключом, а некой секретной строкой, являющейся функцией от секретного ключа и исходного сообщения.
  • Как маловажное дополнение, сделать переменным по длине секретный ключ при с сохранением высокой криптостойкости алгоритма (в текущей версии от 64 до 100 символов).
  • Как было сказано выше, не привязываться к существующим решениям, а сделать нечто свое, без сложной математики, с простым и понятным алгоритмом.

Поехали.


Для разработки было выбрано симметричное шифрование.


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


Описываемый здесь алгоритм более похож на поточный шифр, хотя не является им в чистом виде.
Задумывая реализацию алгоритма, в самых общих чертах было понимание, что секретный ключ должен быть лишь одним из элементов финального аккорда в симфонии шифрования, но не самим этим аккордом. То есть в идеале, говоря образно, каждое сообщение должно по хорошему как бы само шифровать себя, а ключ должен быть лишь некой стартовой точкой этого алгоритма, если хотите, неким инициализирующим вектором.
Основная идея прелесть получившегося алгоритма заключается в том, что для каждого акта шифрования не используется один и тот же секретный ключ, а генерируется функция обхода исходного ключа, так называемая сигнатура пути обхода (pathKeySignature в коде), причем функция зависит от нескольких аргументов. А именно от сложной комбинации sha-512 хешей соли приложения, исходного сообщения, уникального идентификатора uniqid, а также от хешкодов отправителя и получателя сообщения.
Что такое сигнатура обхода ключа на пальцах? Если упростить, это фактически алгоритм обхода ключа. Например, берем первый символ ключа, затем 14-ый, затем 22-ой, затем 37-ой, затем 49-ый и т.д. Каждый новый такой обход уникален (в силу уникальности генерируемого pathKeySignature).
Кроме того, в алгоритм внесены элементы двухфакторного шифрования (более подходящего термина не нашел, речь идет о коротких пин-паролях у отправителя и получателя, подробнее ниже по тексту). Далее, непосредственно "под капотом" используется обычный xor-метод.


"Двухфакторность" проявляется в том, что для генерации сигнатуры пути используются небольшие пароли (pass1 и pass2, по 4 символа), притом, что получателю неизвестен пароль отправителя, а отправителю неизвестен пароль получателя, но притом они обмениваются функциями-хешкодами от соли приложения и пароля второй стороны.


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


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


private function attachKey($message, $salt)    {        return md5(hash('sha512', $message . uniqid() . $salt) . hash('sha512', $salt));    }    private function pathKeySignature($user_code_1, $user_code_2, $attach_key)    {        return hash('sha512', $user_code_1 . $attach_key . $user_code_2);    }

Собственно, наличие md5 хеш-функции может поначалу немного смутить, но этот элемент алгоритма отвечает лишь только за внесение хаотичности, лавинности изменений (как и sha512) в генерируемый attachKey. Функция uniqid отдает нам уникальный идентификатор, что по итогу позволяет шифровать одно и то же исходное сообщение каждый раз новым шифром, что в конечном счете гуд. Зачем так заморачиваться? Представьте, что вы разрабатываете свой месседжер с шифрованием. Шифрование одних и тех же сообщений одним и тем же конечным шифром если не прямая уязвимость, то явный шаг в ее сторону. Почему? Как правило, в данном контексте пользователи обмениваются весьма однотипным набором данных, из серии "привет!", "я понял", "ок", "скоро буду", "как дела?". Допустим, к примеру, у нас такой месседжер. Канал шифрования установлен, пользователь 1 отправил пользователю 2 шифрованное сообщение "0372985dee", пользователь 2 прочел сообщение и через 5 секунд ответил "0372985dee" обратно. Что зашифровано там? Ответ почти очевиден.
Это было лирическое отступление на тему уместности uniqid, возвращаемся к коду.


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


private function cipher($path_key_signature, $message, $generateKey)    {...        for ($i = 0; $i < count($message); $i++) {            if ($sign_key >= self::hash_length) $sign_key = 0;            $key_code_pos = hexdec($path_key_signature[$sign_key]);            $cur_key_pos = $cur_key_pos + $key_code_pos;            if ($cur_key_pos >= $key_length) {                $cur_key_pos = $cur_key_pos - $key_length;            }            $shifted_key_symbol = $generateKey[$cur_key_pos];            // byte shifting            $shifted_key_symbol = $this->byteShifting($i, $shifted_key_symbol);            $shifter = $this->mb_ord($message{$i}) ^ $this->mb_ord($shifted_key_symbol);            $cipher_message .= $this->mb_chr($shifter);            $sign_key++;        }        return $cipher_message;    }

Непосредственно в публичном методе шифрования не так много интересного, ибо все интересное а ля создание присоединяемого хеша attachKey и генерация пути обхода pathKeySignature описаны выше. Разве что, стоит отметить, что к выходящему наружу в незащищенный канал шифру конкатенируется $attach_key


public function codeMessage($message, $generateKey, $user1_pass, $receiver_hashcode)    {        $sender_hashcode = $this->sender_hashcode($user1_pass);        $attach_key = $this->attachKey($message, $this->salt);        $path_key_signature = $this->pathKeySignature($sender_hashcode, $receiver_hashcode, $attach_key);        $result_cipher = $this->cipher($path_key_signature, $message, $generateKey) . $attach_key;        $result_cipher = base64_encode($result_cipher);        return gzencode($result_cipher, 9);    }

Возможно, возникнет резонный вопрос. Почему бы не ограничиться в функции пути обхода просто одним attachKey, для чего добавлять туда хешкоды отправителя и получателя? Ответ находится тут же, "рядом" attachKey расположен фактически на виду в создаваемом шифре, и зная его, не составляет труда реконструировать последовательность прохождения ключа при шифре. Сам секретный ключ это, разумеется, напрямую восстановить не даст, но сведет на нет всю идею "рандомизации" ключа. Поэтому, нужен дополнительный фактор, которым являются хешкоды получателей. Они представляют собой своего рода второй секретный элемент алгоритма помимо ключа. Этакое своего рода двухфакторное шифрование.


Метод decodeMessage детально рассматривать не будем, он практически тривиален, если учитывать полную симметричность с методом шифрования только в обратной последовательности.


Алгоритм выглядит вполне законченным, по крайней мере для некоего теоретического эксперимента.
Плюсы:


  • Относительно быстр по скорости шифрования/дешифрования (об этом ниже)
  • Прост и понятен
  • Открыт для изучения и улучшения, ибо опенсорс

Минусы:


  • (скорее обстоятельство, чем недостаток) Требуется детальный анализ, чтобы понимать насколько он криптографически стоек.

В двух словах по поводу тестирования.
По скорости работы алгоритма относительно быстр (разумеется, все относительно и познается в сравнении, речь о скорости шифрования в рамках высокоуровнего яп вообще и в рамках php в частности). 2 мегабайта рандомного текста было зашифровано и расшифровано за 4 секунды, использовался при этом php 7.2. Система: Intel Core i7-8700 CPU @ 3.20GHz 12, параллельно еще работал браузер с кучей вкладок и виртуальная машина. Резюме скорость шифрования ~ 1 мб/сек на среднестатистическом железе на php7.0 и выше.

Подробнее..

Перевод Безопасность через неясность недооценивается

16.09.2020 02:22:50 | Автор: admin
В информационной безопасности мы выработали ряд аксиом, с которыми не принято спорить:

  • Никогда не внедряйте собственную криптографию.
  • Всегда используйте TLS.
  • Безопасность через неясность (security by obscurity) это плохо.

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

Риск, эшелонированная оборона и швейцарский сыр


Одной из главных задач ИБ является снижение рисков. Согласно методологии OWASP, риск возникновения проблемы рассчитывается по формуле:

Риск = Вероятность * Воздействие

По этой формуле, проблема удалённого выполнения кода (RCE) представляет больший риск, чем проблема межсайтового скриптинга, поскольку RCE несёт большее воздействие. Здесь всё просто. Но что насчёт метрики вероятности? Согласно OWASP, вероятность определяется так:

На самом высоком уровне это приблизительная оценка шансов, что конкретная уязвимость будет раскрыта и использована злоумышленником

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



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

Безопасность через неясность


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

Рассмотрим несколько сценариев:

  • На моём сервере SSH запускается на дефолтном порту 22, а учётные данные root:123456. Какова вероятность компрометации?

Вероятность почти 100%, так как хакеры по всему интернету брутят сервисы со стандартными учётными данными.

  • SSH работает на порту 22, а учётные данные utku:123456. Какова вероятность компрометации?

Ну, мы устранили опасность брутфорса со стандартными учётными данными. Вероятность и риск снижаются. Однако мы по-прежнему сталкиваемся с массой целевых атак. Кто-то может угадать имя пользователя utku, так как это моё настоящее имя.

  • SSH работает в порту 64323, а учетные данные utku:123456. Какова вероятность компрометации?

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


Как видите, многие склонны сканировать только стандартные и самые популярные порты. Таким образом, если вы измените порт с 22 на 64323, то устраните некоторые из потенциальных атак. Вы уменьшите вероятность и риск.

То же самое относится и к уязвимостям программного обеспечения. Если уязвимость обнаружена в протоколе Microsoft Remote Desktop Protocol, весь интернет начнёт сканировать порт 3389. Вы можете уменьшить риски, просто изменив порт по умолчанию.

Другие области применения


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

  • Обфускация кода: конечно, это общеизвестно. Хакеры тоже люди. Если вы хорошенько обфусцируете код, им придётся уделить больше времени на поиск проблем. В конце концов они могут сдаться.
  • Случайные имена переменных для веб-приложения: Вместо понятных имён переменных можно использовать случайные символы. Это может помочь точно так же, как обфускация кода.
  • Симметричное шифрование в базе данных: при записи данных в БД используйте функцию вроде encryption_algorithm(data, key). Аналогично, при считывании данных decryption_algorithm(data, key). Если злоумышленник получил доступ к внутреннему коду, то, очевидно, сможет расшифровать БД. Но если из-за какой-то уязвимости злоумышленник считывает данные из БД, но не видит внутренний код (например, через SQL-инъекцию), то полученные данные ничего ему не дадут.

Применение в реальной жизни


Безопасность через неясность широко используется в физической/реальной безопасности. Например, президент едет из пункта А в пункт Б с кортежем из 30-ти автомобилей. Но он не сидит в своей президентской машине, чтобы не стать лёгкой мишенью. Он может находиться в любой машине из кортежа, и это снижает риск нападения.



Животные также используют безопасность через неясность это камуфляж. Скрытность снижает вероятность быть убитым. Поэтому в процессе эволюции они приобрели такую способность.



Вывод


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

На пути к вершине Магма и Кузнечик на Эльбрусе

17.06.2021 16:13:58 | Автор: admin

В последнее время всё чаще появляются статьи о производительности российских процессоров Эльбрус на различных задачах. Тема криптографии пока что остаётся за кадром, хотя в разное время были упоминания то о высоких возможностях Эльбруса (некий ГОСТ лучше в 9 раз на Эльбрус-4С, чем на Intel Core i7-2600), то о плохой оптимизации компилятора и, соответственно, крайне низкой скорости реализованных алгоритмов (Кузнечик в 100 раз медленнее, чем на Intel?). Предлагаю наконец разобраться, что может Эльбрус, на примере двух ГОСТ алгоритмов симметричного шифрования.

Чтобы статья не вышла слишком большой, будем считать, что читатель имеет общее представление об архитектурах процессоров, в том числе знает об Эльбрусе. Если же нет, на сайте разработчика (компании МЦСТ) есть отличное руководство по программированию и книга об архитектуре в целом. Именно с этих материалов и началось моё знакомство с Эльбрусами. Также отмечу, что в современных процессорах очень много различных механизмов и особенностей, так что в статье буду касаться только тех, которые, на мой взгляд, важны при реализации выбранных алгоритмов.

Что может предложить архитектура Эльбрус

Для выполнения арифметических операций у Эльбруса есть 6 АЛУ (арифметико-логических устройств), способных выполнять операции параллельно. Начиная с версии 5 архитектуры появилась поддержка упакованных (SIMD) инструкций над 128-битными регистрами.

Для хранения промежуточных результатов присутствует большой регистровый файл: суммарно в процедуре можно использовать более 200 (64-битных) регистров общего назначения. Для SIMD вычислений используются те же самые регистры, а не отдельные, как это часто бывает. Соответственно, с 5 версии архитектуры все регистры стали 128-битными.

Задачу симметричного шифрования можно отнести к потоковой обработке массива данных. Для таких ситуаций в Эльбрусе есть механизм асинхронной подкачки данных из памяти APB (Array Prefetch Buffer). Использование этого механизма позволяет вовремя подгружать данные из памяти, не теряя время на кэш-промахи.

Выбор реализаций

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

Правда, о производительности ГОСТ алгоритмов обычно говорят только в контексте семейства x86-64, другие архитектуры мало кого интересуют. Но это не беда: мне показалось, что при знании команд ассемблера x86-64 ознакомиться с набором целочисленных и логических инструкций Эльбруса проще, чем, скажем, с ARM-овым. То есть прослеживаются определённые параллели, особенно, в области SIMD инструкций, и даже прямые аналоги. В остальном, конечно, у них нет ничего общего.

Итак, для Магмы известна эффективная реализация режимов, допускающих параллельную обработку блоков, то есть когда несколько блоков могут шифроваться независимо друг от друга. Это, например, режимы ECB, CTR, MGM. При этом скорость конкурирует с AES, для которого на x86-64 есть аппаратная поддержка. Реализация заточена именно под параллельную обработку, в случае последовательной (режимы с зацеплением) используются другие подходы. Мне интересно добиться максимальной скорости, поэтому я ограничился только случаем параллельной обработки.

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

Тестовые машины

То же самое в текстовом виде

Процессор

Версия арх-ры

Кол-во ядер

Тактовая частота

L1d

L1i

L2

L3

Эльбрус-4С

E2Kv3

4

0.75 ГГц

4 x 64 КБ

4 x 128 КБ

4 x 2 МБ

Нет

Эльбрус-1С+

E2Kv4

1

0.985 ГГц

1 x 64 КБ

1 x 128 КБ

1 x 2 МБ

Нет

Эльбрус-8С

E2Kv4

8

1.2 ГГц

8 x 64 КБ

8 x 128 КБ

8 x 512 КБ

16 МБ

Эльбрус-8СВ

E2Kv5

8

1.55 ГГц

8 x 64 КБ

8 x 128 КБ

8 x 512 КБ

16 МБ

Эльбрус-2С3

E2Kv6

2

2 ГГц

2 x 64 КБ

2 x 128 КБ

2 x 2 МБ

Нет

Эльбрус-16С

E2Kv6

16

2 ГГц

16 x 64 КБ

16 x 128 КБ

8 x 1 МБ

32 МБ

Магма

В случае x86-64 быстрая реализация Магмы опирается на использование расширений AVX и AVX2. При этом учитывается наличие в процессоре нескольких АЛУ и возможность параллельного исполнения до 3 векторных инструкций за один такт. Естественно, планирование параллельного исполнения остаётся на откуп процессора.

В случае же Эльбруса есть возможность явно распланировать параллельное исполнение. Опуская некоторые детали, можно считать, что на 3 и 4 поколении возможно исполнить 6 целочисленных векторных операций над 64-битными регистрами, а начиная с 5 поколения 4 векторных операции уже над 128-битными регистрами.

Для Эльбруса я написал собственную реализацию Магмы. Она использует те же идеи, что и исходная под x86-64, но при этом адаптирована под другой набор инструкций. Рассматривал перспективу написания на ассемблере и даже пробовал, но довольно быстро осознал, что ассемблер у Эльбруса достаточно сложный в плане программирования на нём (например, есть много нюансов по размерам задержек и зависимостям инструкций, которые тяжело учесть вручную). При этом оптимизирующий компилятор делает свою работу действительно хорошо: переставляет инструкции в рамках большого окна и при подборе опций компиляции выдаёт плотность кода, которая не отличается от теоретических оценок на количество инструкций и тактов. Так что я остановился на реализации на языке Си с использованием intrinsic функций для доступа к некоторым инструкциям процессора.

Для измерения скорости был выбран режим ECB. Обычно именно он (или даже его упрощения) используется при сравнении производительности, а скорость других режимов можно оценить на базе полученных результатов, отличия несущественны. Речь идёт о реализации базового алгоритма шифрования, поэтому накладные расходы от смены ключа также не учитываются. Объём данных для замера порядка 1 ГБ. Естественно, шифрование на одном ядре. Для многоядерной машины можно умножить результат на количество ядер и получить близкую к реальности оценку скорости. По крайней мере, во всех сравнениях я видел именно такую зависимость. Полученные результаты в таблице ниже:

То же самое в текстовом виде

Процессор

Скорость на невыровненных данных

Скорость на выровненных данных

Производительность

Эльбрус-4С

116 МБ/с

137 МБ/с

5.2 такт/байт

Эльбрус-1С+

151 МБ/с

179 МБ/с

5.2 такт/байт

Эльбрус-8С

185 МБ/с

220 МБ/с

5.2 такт/байт

Эльбрус-8СВ

402 МБ/с

520 МБ/с

2.8 такт/байт

Эльбрус-2С3

669 МБ/с

670 МБ/с

2.8 такт/байт

Эльбрус-16С

671 МБ/с

672 МБ/с

2.8 такт/байт

Здесь под выровненными данными подразумевается выравнивание по границе 8 байтов для E2Kv3/E2Kv4 и 16 байтов для E2Kv5/E2Kv6. При наличии такого выравнивания (на версиях до 6) работает механизм APB и данные для шифрования эффективно подкачиваются из памяти. При этом с версии 6 APB уже не требует выравнивания данных, поэтому при любом расположении данных достигается максимальная скорость. Для невыровненных данных на предыдущих версиях архитектуры я не провёл достаточно исследований, так что значения в этом столбце таблицы можно считать нижней границей.

Для сравнения приведу результаты из статьи с описанием базовой реализации на Intel Core i3-7100 @ 3.9 ГГц. При использовании AVX 458 МБ/с, 8.1 такт/байт; AVX2 1030 МБ/с, 3.6 такт/байт. Так что по абсолютной скорости Эльбрус достаточно близок к современным процессорам Intel (это при значительной разнице в тактовой частоте!) и превосходит x86-64 с AVX в тактах более чем в 1.5 раза (для 3 и 4 поколения), а x86-64 с AVX2 в 1.3 раза (для 5 поколения).

Кузнечик

По сравнению с Магмой, структура Кузнечика является более сложной. Несмотря на то, что удалось декомпозировать нелинейное преобразование S, техники реализации, основанные на широком использовании SIMD-инструкций, пока что отстают от "классической" реализации со склеенным LS (линейным и нелинейным) преобразованием и таблицей предвычислений размером 64 КБ (упоминается в статье под именами с LS или более простое описание на Хабре).

В случае x86-64 Кузнечик эффективнее всего реализуется с использованием AVX-инструкций (удобно работать со 128-битными регистрами, так как длина блока и размер значений в таблице равны в точности 128 битам). При этом для вычислений адресов в таблице не удаётся воспользоваться эффективной адресацией Scale-Index-Base-Displacement (именование из статьи), так как в качестве Scale нужно значение 16, а максимально возможное 8. На Эльбрусе можно ожидать конкурирующих результатов за счёт большого кэша L1d (64 КБ) и наличия 4 АЛУ, обеспечивающих произвольный доступ к памяти (насколько мне известно, у абсолютного большинства процессоров x86-64 2 порта для загрузки данных).

Как и в случае с Магмой, для Кузнечика я написал отдельную реализацию на Си под Эльбрус, чтобы добиться максимальных результатов. Начиная с 5 версии архитектуры я явным образом использовал тип __v2di (см. e2kintrin.h в составе компилятора), чтобы быть уверенным, что получится использовать регистры как 128-битные.

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

Итак, в случае строго последовательной обработки данных:

То же самое в текстовом виде

Процессор

Скорость на невыровненных данных

Скорость на выровненных данных

Производительность

Эльбрус-4С

52 МБ/с

69 МБ/с

10.4 такт/байт

Эльбрус-1С+

63 МБ/с

90 МБ/с

10.4 такт/байт

Эльбрус-8С

80 МБ/с

110 МБ/с

10.4 такт/байт

Эльбрус-8СВ

95 МБ/с

150 МБ/с

9.9 такт/байт

Эльбрус-2С3

170 МБ/с

171 МБ/с

11 такт/байт

Эльбрус-16С

171 МБ/с

172 МБ/с

11 такт/байт

Для сравнения результаты из статьи (лучшие из опубликованных) на Intel Core i7-6700 @ 4 ГГц 170МБ/с, 22.4 такт/байт. В отличие от Магмы, можно говорить о сопоставимой абсолютной скорости и преимуществе в тактах более чем в 2 раза.

В таблице заметен интересный момент: результаты ощутимо колеблются среди последних 3 версий Эльбруса. Такое поведение я заметил буквально недавно и начал обсуждение с коллегами из МЦСТ, так что есть надежда, что результаты удастся немного улучшить при доработке компилятора.

С параллельной обработкой ситуация намного интереснее:

То же самое в текстовом виде

Процессор

Скорость на невыровненных данных

Скорость на выровненных данных

Производительность

Эльбрус-4С

78 МБ/с

83 МБ/с

8.6 такт/байт

Эльбрус-1С+

102 МБ/с

108 МБ/с

8.7 такт/байт

Эльбрус-8С

126 МБ/с

133 МБ/с

8.6 такт/байт

Эльбрус-8СВ

248 МБ/с

291 МБ/с

5.1 такт/байт

Эльбрус-2С3

453 МБ/с

454 МБ/с

4.2 такт/байт

Эльбрус-16С

454 МБ/с

455 МБ/с

4.2 такт/байт

И традиционное сравнение с Intel Core i7-6700 @ 4 ГГц: на нём достигается 360 МБ/с, 10.6 такт/байт. В отличие от случая последовательной обработки, у E2Kv3 и E2Kv4 преимущество Эльбруса не такое большое, предположительно из-за того, что реализация обработки нескольких блоков вместе обладает более высокой степенью параллельности и планировщику на x86-64 легче справиться с выявлением независимых операций. А вот появление у 5 поколения Эльбруса 128-битных регистров и загрузок из памяти позволяет ему сохранить преимущество в тактах более чем в 2 раза.

Сравнивать E2Kv6 с i7-6700 оказалось несолидно, поэтому я взял ассемблерную реализацию режима ECB и провёл собственный замер. В статье с описанием результатов на i7-6700 данные шифруются на месте, без работы с памятью, поэтому у честного режима ECB результат чуточку хуже: на самом мощном из доступных мне процессоров Intel Core i7-9700K @ 4.7 ГГц вышло 411 МБ/с, 10.9 такт/байт. Эльбрус оказался быстрее, обеспечивая преимущество в тактах в 2.5 раза.

Заключение

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

За время изучения архитектуры Эльбруса у меня сложилось впечатление, что многие полезные инструкции исторически добавлялись для обеспечения работы двоичного транслятора, но ситуация изменилась с 5 версии: Эльбрус начал больше развиваться собственным путём. Эту положительную динамику невозможно не отметить.

С другой стороны, сложившаяся похожесть ряда инструкций упрощает разработку и оптимизацию под Эльбрус. Можно сказать, что эта статья предлагает простой способ портирования и оптимизации алгоритмов под Эльбрус: достаточно взять хорошо зарекомендовавший себя на Intel/AMD алгоритм и немного адаптировать его под Эльбрус. Я искренне верю, что в результате практически любой алгоритм должен работать по крайней мере не хуже, чем в разницу тактовых частот.

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

P.S.

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

Несмотря на то, что для получения описанных результатов мне удалось разобраться с Эльбрусом на основании только открытой информации и документации к компилятору, я хочу выразить благодарность сотрудникам МЦСТ, в особенности, Александру Трушу, за ответы на периодически возникавшие у меня вопросы и, конечно, за предоставление удалённого доступа к новым процессорам.

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru