Rijndael MixКолонны - Rijndael MixColumns

Операция 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 458e 4d a1 bc219 19 83 69142 77 161 188
f2 0a 22 5c9f dc 58 9d242 10 34 92159 220 88 157
01 01 01 0101 01 01 011 1 1 11 1 1 1
c6 c6 c6 c6c6 c6 c6 c6198 198 198 198198 198 198 198
d4 d4 d4 d5d5 d5 d7 d6212 212 212 213213 213 215 214
2d 26 31 4c4d 7e bd f845 38 49 7677 126 189 248

InverseMixColumns

Операция MixColumns имеет обратный (числа являются десятичными):

Или же:

Рекомендации

Смотрите также