Операция MixColumns, выполняемая Rijndael шифр, наряду с шагом ShiftRows, является основным источником распространение в Rijndael. Каждый столбец рассматривается как четырехчленный многочлен которые являются элементами в поле . Коэффициенты полиномов являются элементами в пределах простого подполе .
Каждый столбец умножается на фиксированный многочлен по модулю ; обратный к этому многочлену равен .
MixColumns
Операция заключается в модульном умножении двух четырехчленных многочленов, коэффициенты которых являются элементами . Модуль, используемый для этой операции, равен .
Первые четырехчленные полиномиальные коэффициенты определяются столбцом состояния , который содержит четыре байта. Каждый байт является коэффициентом четырехчленного, так что
Второй четырехчленный многочлен является постоянным многочленом . Его коэффициенты также являются элементами . Его обратное .
Нам нужно определить некоторые обозначения:
- обозначает умножение по модулю .
- обозначает сложение по .
- обозначает умножение (обычное умножение многочленов, когда между многочленами и умножение над для коэффициентов).
Сложение двух многочленов, коэффициенты которых являются элементами имеет следующее правило:
Демонстрация
Полином будет выражаться как .
Полиномиальное умножение
куда:
Модульное сокращение
Результат является семичленным многочленом, который должен быть уменьшен до четырехбайтового слова, что достигается умножением по модулю .
Если мы проделаем некоторые базовые полиномиальные модульные операции, мы увидим, что:
В целом можно сказать, что
Так
куда
Матричное представление
Коэффициент , , и можно также выразить следующим образом:
И когда мы заменим коэффициенты при с константами используемое в шифре, получаем следующее:
Это демонстрирует, что сама операция похожа на Шифр холма. Это можно сделать, умножив вектор координат из четырех номеров в Поле Галуа Риджндаля следующими циркулирующий Матрица МДС:
Пример реализации
В реальной реализации это можно несколько упростить, заменив умножение на 2 одним сдвигом и условным исключающим или, а также заменив умножение на 3 на умножение на 2 в сочетании с исключающим или. А C пример такой реализации:
1 пустота gmix_column(беззнаковый char *р) { 2 беззнаковый char а[4]; 3 беззнаковый char б[4]; 4 беззнаковый char c; 5 беззнаковый char час; 6 / * Массив 'a' - это просто копия входного массива 'r' 7 * Массив 'b' - это каждый элемент массива 'a', умноженный на 2 8 * в поле Галуа Риджндала 9 * a [n] ^ b [n] - это элемент n, умноженный на 3 в поле Галуа Риджндала * / 10 за (c = 0; c < 4; c++) {11 а[c] = р[c];12 / * h равно 0xff, если установлен старший бит r [c], в противном случае - 0 * /13 час = (беззнаковый char)((подписанный char)р[c] >> 7); / * арифметический сдвиг вправо, смещая, таким образом, либо нули, либо единицы * /14 б[c] = р[c] << 1; / * неявно удаляет старший бит, потому что b [c] является 8-битным символом, поэтому мы выполняем xor по 0x1b, а не 0x11b в следующей строке * /15 б[c] ^= 0x1B & час; / * Поле Галуа Риджндала * /16 }17 р[0] = б[0] ^ а[3] ^ а[2] ^ б[1] ^ а[1]; / * 2 * a0 + a3 + a2 + 3 * a1 * /18 р[1] = б[1] ^ а[0] ^ а[3] ^ б[2] ^ а[2]; / * 2 * a1 + a0 + a3 + 3 * a2 * /19 р[2] = б[2] ^ а[1] ^ а[0] ^ б[3] ^ а[3]; / * 2 * a2 + a1 + a0 + 3 * a3 * /20 р[3] = б[3] ^ а[2] ^ а[1] ^ б[0] ^ а[0]; / * 2 * a3 + a2 + a1 + 3 * a0 * /21 }
Пример C #
1 частный байт GMul(байт а, байт б) { // Поле Галуа (256) Умножение двух байтов 2 байт п = 0; 3 4 за (int прилавок = 0; прилавок < 8; прилавок++) { 5 если ((б & 1) != 0) { 6 п ^= а; 7 } 8 9 bool hi_bit_set = (а & 0x80) != 0;10 а <<= 1;11 если (hi_bit_set) {12 а ^= 0x1B; / * х ^ 8 + х ^ 4 + х ^ 3 + х + 1 * /13 }14 б >>= 1;15 }16 17 возвращаться п;18 }19 20 частный пустота MixColumns() { // 's' - это основная матрица состояний, 'ss' - это временная матрица тех же размеров, что и 's'.21 Множество.Прозрачный(SS, 0, SS.Длина);22 23 за (int c = 0; c < 4; c++) {24 SS[0, c] = (байт)(GMul(0x02, s[0, c]) ^ GMul(0x03, s[1, c]) ^ s[2, c] ^ s[3, c]);25 SS[1, c] = (байт)(s[0, c] ^ GMul(0x02, s[1, c]) ^ GMul(0x03, s[2, c]) ^ s[3,c]);26 SS[2, c] = (байт)(s[0, c] ^ s[1, c] ^ GMul(0x02, s[2, c]) ^ GMul(0x03, s[3, c]));27 SS[3, c] = (байт)(GMul(0x03, s[0,c]) ^ s[1, c] ^ s[2, c] ^ GMul(0x02, s[3, c]));28 }29 30 SS.Скопировать в(s, 0);31 }
Тестовые векторы для MixColumn ()
Шестнадцатеричный | Десятичный |
---|
Перед | После | Перед | После |
---|
дб 13 53 45 | 8e 4d a1 bc | 219 19 83 69 | 142 77 161 188 |
f2 0a 22 5c | 9f dc 58 9d | 242 10 34 92 | 159 220 88 157 |
01 01 01 01 | 01 01 01 01 | 1 1 1 1 | 1 1 1 1 |
c6 c6 c6 c6 | c6 c6 c6 c6 | 198 198 198 198 | 198 198 198 198 |
d4 d4 d4 d5 | d5 d5 d7 d6 | 212 212 212 213 | 213 213 215 214 |
2d 26 31 4c | 4d 7e bd f8 | 45 38 49 76 | 77 126 189 248 |
InverseMixColumns
Операция MixColumns имеет обратный (числа являются десятичными):
Или же:
Рекомендации
Смотрите также