Рейтинг:0

Обобщение циклических сдвигов s-box AES в больших GF

флаг tf
Tom

Согласно википедии:

https://en.wikipedia.org/wiki/Rijndael_S-box

AES делает интересную вещь (где $<<<$ круговой сдвиг):

$s = b \oplus (b \lll 1) \oplus (b \lll 2) \oplus (b \lll 3) \oplus (b \lll 4)$

а это равно ($\раз$ это умножение в $GF(2^8)$):

$s = b \times 31 \mod 257$

На мой взгляд, это обеспечивает отличное смешивание. Допустим у меня 128 бит $х$ и $у$ и я хочу вычислить что-то подобное:

$x = y \oplus (y \lll 1) \oplus (y \lll 2) \oplus (y \lll 3) \oplus ... \oplus (y \lll 64)$

Могу ли я сделать это быстрее, используя умножение в $GF(2^{128}) \mod 2^{128}+1$? Я не знаю теории, стоящей за этим, поэтому у меня есть два типа множителей для этого:

$2^{125}-1$

и

$2^{65}-1$

Я думаю, что этот второй может работать таким же образом в $GF(2^{128})$, это правило.Так есть ли аналогичный номер, который я могу использовать? Что это за число?

РЕДАКТИРОВАТЬ: похоже, что в статье есть ошибка, и круговой сдвиг может быть в другом направлении:

$s = b \oplus (b \ggg 1) \oplus (b \ggg 2) \oplus (b \ggg 3) \oplus (b \ggg 4)$

В любом случае, можем ли мы обобщить это? В этом документе ничего не говорится о равенстве умножению на GF этого шага:

https://csrc.nist.gov/csrc/media/publications/fips/197/final/documents/fips-197.pdf

Рейтинг:3
флаг sa

ОК, проблема сдвига влево или вправо связана с тем, представлена ​​ли переменная соглашением «с прямым порядком байтов» или «с прямым порядком байтов», т. е. с наименьшим значащим битом слева или справа.

Операция:

$$s = b \oplus (b \lll 1) \oplus (b \lll 2) \oplus (b \lll 3) \oplus (b \lll 4)$$

эквивалентно умножению (где сдвиг равен $\раз х$ ниже)

$$ s(x)=b(x)(1+x+x^2+x^3+x^4)=b(x)\frac{x^5-1}{x-1} $$ но так как сдвиг влево тоже удваивается, пусть $х=2,$ получить $s(x)=(2^5-1)b(x).$ В любом случае циклический сдвиг эквивалентен рабочему $\pмод х^n-1$ куда $n$ длина слова в битах.

Ваша вторая операция действительно эквивалентна умножению на $2^{65}-1.$

Поскольку вы кажетесь достаточно математически способным, я бы предложил:

Прочтите полностью документ «Предложение AES» от Daemen и Rijmen, чтобы ознакомиться с этими типами операций и представлений. Так же есть книга Дизайн Rijndael тех же авторов. Вы изучаете взаимодействие между Полями Галуа характеристики 2, $GF(2^n)$ и целочисленные кольца $\mathbb{Z}_{2^n-1}$ которые также можно «разложить» на $\mathbb{Z}_{2^{n/2}-1} \times \mathbb{Z}_{2^{n/2}+1},$ когда $n$ даже.Еще одно место, где можно посмотреть, — это документация по дизайну SAFER-64 Джима Мэсси. В более общем плане теоретико-числовые преобразования (NTT), которые обобщают быстрое преобразование Фурье.

Если у вас есть рекурсивные декомпозиции того типа, о котором я упоминал выше, у вас есть быстрые реализации. Простейшим таким преобразованием является матрица Сильвестра Адамара, используемая в быстрых преобразованиях Уолша-Адамара, где $n$ Кронекеровские произведения той же матрицы $H_2$ используется: $$ H_n =H_2 \otimes H_2 \otimes \cdots \otimes H_2 $$ с $$ H_2=\left[\begin{array}{cc} +1 & +1 \ +1 & -1 \end{array} \right]. $$ Так как это в Преобразование Фурье для бинарного векторного пространства $GF(2)^n=\{0,1\}^n$ эквивалентно, строки приведенной выше матрицы Адамара являются групповыми характерами аддитивной группы $(\mathbb{GF(2)^n},\oplus)$ все это имеет смысл.

В любом случае, приятного чтения.

Tom avatar
флаг tf
Tom
У меня второй вопрос по поводу числа 99. Я подозреваю, что это какая-то проблема балансировки старших битов (если я прав, это даже может быть проблемой), которые всегда равны 1 в каждом числе. Но я не могу сделать эквивалент этого числа для моего примера. Вы знаете, откуда взялось число 99? Что может быть в GF(2^128)?
Tom avatar
флаг tf
Tom
Я пытаюсь проверить это вручную, и это не работает для меня. Есть ли сокращение на какой-то полином или x 31 просто умножение без переноса? В обоих случаях это, кажется, не работает. Возьмем b = 10000001. b
Tom avatar
флаг tf
Tom
Я уменьшил его на многочлен x^9+1. И, наконец, это работает.
Рейтинг:1
флаг tf
Tom

Что-то вводит в заблуждение в статье Википедии. Они написали:

$s = b \oplus (b \lll 1) \oplus (b \lll 2) \oplus (b \lll 3) \oplus (b \lll 4)$

Равно:

$s = b \times 31 \mod 257$

куда $\раз$ является полиномиальным умножением $b$ и $31$ воспринимаются как битовые массивы. Но $\мод 257$ не является стандартной операцией по модулю, это мод в $GF(2^8)$ и $257$ на самом деле является полиномом вида $х^{9}+1$.

Легко видеть, что умножение без переноса $b \раз 31$ равно:

$s = b \oplus (b \ll 1) \oplus (b \ll 2) \oplus (b \ll 3) \oplus (b \ll 4)$

в битах $7,6,5,4$, куда $\ll$ это побитовый сдвиг, а не круговой сдвиг. Но в примере с Википедией и в AES есть круговой сдвиг. Так откуда берется циркуляр? Это происходит из редукции полиномом $х^9+1$. Вот как работает умножение с полиномиальной редукцией в $GF(2^8)$:

#include <cstdint>
#include <cstdio>
#include <битсет>
#include<iostream>


uint8_t умножить (uint a, uint b)
    {
        uint8_t р = 1;
        uint16_t L = 1;
        uint16_t с = 0;

        for (целое без знака i = 0; i < 8; ++i)
        {
            с ^ = а & (L << я) ? (uint16_t)b << i : 0;
        }

        for (целое без знака i = 8; i-- > 0; )
        {
            если (с & (L << (i + 8)))
            {
                с ^= L << (i + 8);
                с ^= (uint16_t)p << i;
            }
        }

        возврат (uint8_t)с;
    }

основной ()
{
    результат = 0;
    
    результат = умножить (131,31);
    std::cout << результат;
    
    вернуть 0;
}

Нам нужен многочлен степени $9$, но мы можем определить уменьшающий многочлен в практической реализации, взяв только его первый $8$ младшие биты, поэтому в нашем случае $р=1$. Теперь, если мы посмотрим, как работает умножение без переноса (первый цикл), мы увидим, что в $7,6,5,4$ бит мы бы получили тот же результат, что и со сдвигами:

$s = b \oplus (b \ll 1) \oplus (b \ll 2) \oplus (b \ll 3) \oplus (b \ll 4)$

Но вместо бит $11,10,9,8$ будут ровно биты сдвинуты (отменены) в процессе побитового сдвига. Это связано с тем, что умножение без переноса перемещает их влево на $1,2,3...$ позиции, а затем все xored. Как здесь:

введите описание изображения здесь

Так как мы умножаем на $31$ мы всегда получали $4$ дополнительные биты в старшей значащей половине нашего 16-битного результата. И они будут подвергнуты xoring, потому что именно так работает умножение без переноса. Итак, теперь у нас есть биты $7,6,5,4$ равно результату:

$s = b \oplus (b \ll 1) \oplus (b \ll 2) \oplus (b \ll 3) \oplus (b \ll 4)$

И биты $11,10,9,8$, который может быть вместо бит $3,2,1,0$. Чтобы сделать циклический сдвиг, нам нужно только выполнить операцию xor назад для этих битов. Это делается:

for (целое без знака i = 8; i-- > 0; )
        {
            если (с & (L << (i + 8)))
            {
                с ^= L << (i + 8);
                с ^= (uint16_t)p << i;
            }
        }

Если $р=1$. Мы видим, что этот код действительно проверяет, равен ли бит $1$ слева на позиции $я$ нашей верхней половины, и если это так, то это xor тот бит с битом $я$ на нашей низкой половине. И весь этот алгоритм равен xoring с круговым сдвигом $\lll$:

$s = b \oplus (b \lll 1) \oplus (b \lll 2) \oplus (b \lll 3) \oplus (b \lll 4)$

Зная это, становится ясно, что такого рода эквивалентность имеет место для любого $GF(2^k)$, если мы выбираем $р=1$ (по соглашению размещенного кода), так как наш многочлен и множитель равны $ 2 ^ {\ гидроразрыва {к} {2} +1} + 1 $.

kelalaka avatar
флаг in
В $\LaTeX$ есть `\ll \lll \gg` и `\ggg` для получения $\ll, \quad \lll, \quad \gg \quad \text{ и } \quad \ggg$

Ответить или комментировать

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