S-box от Rijndael - это часто используемая операция шифрования и дешифрования AES . Обычно он реализован в виде 256-байтовой таблицы поиска. Это быстро, но означает, что вам нужно перечислить 256-байтовую таблицу поиска в вашем коде. Бьюсь об заклад, кто-то из этой толпы может сделать это с меньшим количеством кода, учитывая основную математическую структуру.
Напишите функцию на вашем любимом языке, которая реализует S-блок Rijndael. Самый короткий код выигрывает.
code-golf
math
cryptography
Кит Рэндалл
источник
источник
Ответы:
Рубин, 161 символов
Чтобы проверить вывод, вы можете использовать следующий код для печати в табличной форме:
источник
GolfScript, 60 символов
Этот код определяет именованную функцию,
S
которая принимает байт и применяет к ней S-блок Rijndael. (Он также использует внутреннюю вспомогательную функцию с именем,r
чтобы сохранить несколько символов.)Эта реализация использует таблицу логарифма для вычисления GF (2 8 ) обратно, так как предложенный Томасом Pornin . Чтобы сохранить несколько символов, вся логарифмическая таблица пересчитывается для каждого входного байта; несмотря на это, несмотря на то, что GolfScript является очень медленным языком в целом, этот код занимает всего около 10 мс для обработки байта на моем старом ноутбуке. Предварительный расчет таблицы логарифмов (as
L
) ускоряет ее примерно до 0,5 мс на байт при скромной стоимости еще трех символов:Для удобства вот простой тестовый набор, который вызывает функцию
S
, как определено выше, для вычисления и распечатки всего S-блока в шестнадцатеричном виде, как в Википедии :Попробуйте этот код онлайн.
(Демонстрация в режиме онлайн предварительно вычисляет таблицу логарифмов, чтобы не занимать слишком много времени. Несмотря на это, онлайн-сайт GolfScript иногда может случайно зависнуть; это известная проблема с сайтом, и перезагрузка обычно исправляет ее.)
Объяснение:
Начнем с вычисления логарифмической таблицы, а именно с вспомогательной функции
r
:Эта функция принимает два входа в стек: битовую маску и битовую маску сокращения (константа между 256 и 511). Он дублирует входной байт, умножает копию на 2 и, если результат превышает 255, XOR с помощью битовой маски возвращает значение ниже 256.
В коде генерации таблицы журнала функция
r
вызывается с битовой маской редукции 283 = 0x11b (что соответствует многочлену редукции Rijndael GF (2 8 ) x 8 + x 4 + x 3 + x + 1), и результатом является XORed с исходным байтом, эффективно умножая его на 3 (= x + 1, как многочлен) в конечном поле Рейндаля. Это умножение повторяется 255 раз, начиная с байта 1, и результаты (плюс начальный нулевой байт) собираются в массив из 257 элементов,L
который выглядит следующим образом (средняя часть опущена):Причина, по которой существует 257 элементов, состоит в том, что с добавленным 0 и 1, встречающимся дважды, мы можем найти модульную инверсию любого данного байта, просто посмотрев его (основанный на нуле) индекс в этом массиве, отрицая его и посмотрев до байта в отрицательном индексе в том же массиве. (В GolfScript, как и во многих других языках программирования, отрицательные индексы массива считаются в обратном направлении от конца массива.) Действительно, это именно то, что делает код
L?~)L=
в начале функцииS
.Остальная часть коды вызывает вспомогательную функцию в
r
четыре раза с уменьшением битовой маской 257 = 2 8 +-для создания четыре битовых-повернутой копии перевернутого входного байта. Все они собраны в массив вместе с константой 99 = 0x63, и XORed вместе для получения окончательного результата.источник
x86-64 Машинный код -
23 22 2019 байтовИспользует набор инструкций AES-NI
Используя соглашения о вызовах Windows, принимает байт и выводит байт. Нет необходимости менять направление,
ShiftRows
поскольку это не влияет на первый байт.источник
Таблица может быть сгенерирована без вычисления обратных значений в конечном поле GF (256) с использованием логарифмов. Это выглядело бы так (код Java, использующий,
int
чтобы избежать проблем со подписаннымbyte
типом):Идея состоит в том, что 3 является мультипликативным генератором GF (256) *. Таблица
t[]
такова, чтоt[x]
равна 3 х ; так как 3 255 = 1, мы получаем, что 1 / (3 x ) = 3 255-x .источник
0x1B
(один 1 в шестнадцатеричном литерале) вместо0x11B
int
Тип 32-бит в Java; Я должен отменить старший бит.GolfScript (82 символа)
Использует глобальные переменные
A
иB
, и создает функцию в качестве глобальной переменнойS
.Инверсия Галуа - это грубая сила; Я экспериментировал с наличием отдельной
mul
функции, которую можно было бы повторно использовать для аффинного преобразования после инверсии, но это оказалось более дорогим из-за разного поведения переполнения.Это слишком медленно для онлайн-демонстрации - время ожидания даже в первых двух строках таблицы.
источник
Питон, 176 символов
Этот ответ предназначен для комментария-вопроса Пауло Эбермана о том, чтобы сделать функцию постоянной по времени. Этот код отвечает всем требованиям.
источник
d
это может генерировать таблицу поиска во время компиляции, я мог бы сохранить некоторые, сделав ubyte универсальным параметром
редактировать не направлять
ubyte
наubyte
без поиска в массиве, не ветвления и полностью unrollable петлиedit2 использовал алгоритм @Thomas для создания таблицы поиска
источник
Stax , 53 байта
Запустите и отладьте его
У меня нет особого понимания S-блоков. Это преобразование решения Томаса Порнина (8 лет!) .
источник