Таблица 6. Значения обратного S-блока
82 | 9 | 106 | 213 | 48 | 54 | 165 | 56 | 191 | 64 | 163 | 158 | 129 | 243 | 215 | 251 |
124 | 227 | 57 | 130 | 155 | 47 | 255 | 135 | 52 | 142 | 67 | 68 | 196 | 222 | 233 | 203 |
84 | 123 | 148 | 50 | 166 | 194 | 35 | 61 | 238 | 76 | 149 | 11 | 66 | 250 | 195 | 78 |
8 | 46 | 161 | 102 | 40 | 217 | 36 | 178 | 118 | 91 | 162 | 73 | 109 | 139 | 209 | 37 |
114 | 248 | 246 | 100 | 134 | 104 | 152 | 22 | 212 | 164 | 92 | 204 | 93 | 101 | 182 | 146 |
108 | 112 | 72 | 80 | 253 | 237 | 185 | 218 | 94 | 21 | 70 | 87 | 167 | 141 | 157 | 132 |
144 | 216 | 171 | 0 | 140 | 188 | 211 | 10 | 247 | 228 | 88 | 5 | 184 | 179 | 69 | 6 |
208 | 44 | 30 | 143 | 202 | 63 | 15 | 2 | 193 | 175 | 189 | 3 | 1 | 19 | 138 | 107 |
58 | 145 | 17 | 65 | 79 | 103 | 220 | 234 | 151 | 242 | 207 | 206 | 240 | 180 | 230 | 115 |
150 | 172 | 116 | 34 | 231 | 173 | 53 | 133 | 226 | 249 | 55 | 232 | 28 | 117 | 223 | 110 |
71 | 241 | 26 | 113 | 29 | 41 | 197 | 137 | 111 | 183 | 98 | 14 | 170 | 24 | 190 | 27 |
252 | 86 | 62 | 75 | 198 | 210 | 121 | 32 | 154 | 219 | 192 | 254 | 120 | 205 | 90 | 244 |
31 | 221 | 168 | 51 | 136 | 7 | 199 | 49 | 177 | 18 | 16 | 89 | 39 | 128 | 236 | 95 |
96 | 81 | 127 | 169 | 25 | 181 | 74 | 13 | 45 | 229 | 122 | 159 | 147 | 201 | 156 | 239 |
160 | 224 | 59 | 77 | 174 | 42 | 245 | 176 | 200 | 235 | 187 | 60 | 131 | 83 | 153 | 97 |
23 | 43 | 4 | 126 | 186 | 119 | 214 | 38 | 225 | 105 | 20 | 99 | 85 | 33 | 12 | 125 |
Следующий шаг раунда - перестановка байтов в блоке. Порядок байтов меняется в строке (bi,0, bi,1,bi,2,...,bi,Lb-1) структуры В в соответствии с таблицами 7-9.
Операция ShiftRow для блоков длины 128 бит (Lb = 4)
После операции ShiftRow | |||
0 | 4 | 8 | 12 |
5 | 9 | 13 | 1 |
10 | 14 | 2 | 6 |
15 | 3 | 7 | 11 |
После операции ShiftRow | |||||
0 | 4 | 8 | 12 | 16 | 20 |
5 | 9 | 13 | 17 | 21 | 1 |
10 | 14 | 18 | 22 | 2 | 6 |
15 | 19 | 23 | 3 | 7 | 11 |
После операции ShiftRow | |||||||
0 | 4 | 8 | 12 | 16 | 20 | 24 | 28 |
5 | 9 | 13 | 17 | 21 | 25 | 29 | 1 |
14 | 18 | 22 | 26 | 30 | 2 | 6 | 10 |
19 | 23 | 27 | 31 | 3 | 7 | 11 | 15 |
Lb | cLb,1 | cLb,2 | cLb,3 |
4 | 1 | 2 | 3 |
6 | 1 | 2 | 3 |
8 | 1 | 3 | 4 |
При обратном преобразовании позиция с номером j в строках i = 1,2,3 сдвигается на позицию с номером j + cLb, imodLb.
После того как выполнена последняя построчная перестановка, на следующем шаге каждый столбец (bi,j) блока текста, где i = 0,...,3, j = 0,...,Lb,представляется в виде полинома над полем F28 и умножается на фиксированный полином a (x) = а3x3 + а2x2 + а1x + a0скоэффициентами a0 (x) =x, a1 (x) = 1, a2 (x) = 1, a3 (x) = х + 1. Затем вычисляется остаток от деления полученного произведения на модуль М (х) = х4 + 1. Таким образом, каждый байт столбца взаимодействует со всеми остальными байтами столбца. При построковом преобразовании ShiftRow на каждом раунде байты взаимодействуют друг с другом в других комбинациях. То есть эти две операции дают сильное перемешивание.
Этот шаг можно свести к умножению на матрицу:
Умножение на '02' (соответственно на х) мы уже реализовали в виде функции xtime (см. таблицу 3). Умножение на '03' (соответственно на х + 1) тоже сделано по аналогии.
Для обращения преобразования MixColumn умножаем каждый столбец (bi,j) блока текста на полином г (х) = r3х3 + r2х2 + r1х + r0 с коэффициентами r0 (х) =х3 + х2 + х, r1 (х) = х3 + 1, r2 (х) = х3 + х2 + 1, r3 (х) = х3 + х + 1 и приводим результат по модулю М (х) = х4 + 1. Соответствующая матрица имеет вид:
На последнем шаге цикла раундовый ключ складывается по модулю 2 с блоком текста:
Зашифрование по алгоритму Rijndael реализуется в виде следующего псевдокода. Аргументы обрабатываются как указатели на поля байтов или четырехбайтовых слов. Интерпретация полей, переменных и функций дана в таблицах 11-13.
Таблица 11
Интерпретация переменных
Переменные | Интерпретация |
Nk | Длина Lk секретного ключа пользователя в четырехбайтовых словах |
Nb | Длина Lb блока в четырехбайтовых словах |
Nr | Число раундов Lrв соответствии с таблицами выше |
Таблица 12
Интерпретация полей
Переменные | Размер в байтах | Интерпретация |
CipherKey | 4*Nk | Секретный ключ пользователя |
ExpandedKey | 4*Nb* (Nr+1) | Поле четырехбайтовых слов под развертку ключа |
Rcon | é4*Nb* (Nr+1) /Nkù | Поле четырехбайтовых слов под константы c (j) = (rc (j), 0, 0, 0) |
State | 4*Nb | Поле ввода открытого текста и вывода зашифрованного текста |
RoundKey | 4*Nb | Раундовый ключ, фрагмент ExpandedKey |
Таблица 13
Интерпретация функций
Функция | Интерпретация |
KeyExpansion | Генерация раундового ключа |
RotByte | Сдвиг четырехбайтового слова влево на 1 байт: (abcd) ® (bcda) |
ByteSub | Подстановка в S-блоке всех байтов поля |
Round | Обычный раунд |
FinalRound | Последний раунд без преобразования MixColumn |
ShiftRow | Преобразование ShiftRow |
MixColumn | Преобразование MixColumn |
AddRoundKey | Сложение с ключом раунда |
Генерация ключа при Lk < 8:
KeyExpansion (byte CipherKey, word ExpandedKey)
{
for (i = 0; i < Nk; i++)
ExpandedKey [i] = (CipherKey [4*i], CipherKey [4*i + 1], CipherKey [4*i + 2], CipherKey [4*i + 3]);
for (i = Nk; i<Nb* (Nr+1); i++)
{
temp = ExpandedKey [i - 1] ; if (i% Nk == 0)
temp = ByteSub (RotByte (temp)) ^Rcon [i/Nk] ; ExpandedKeyp] = ExpandedKey [i - Nk] ^temp;
}
}
ГенерацияключаприLk = 8:
KeyExpansion (byte CipherKey, word ExpandedKey)
{
for (i = 0; i < Nk; i++)
ExpandedKey [i] = (CipherKey [4*i], CipherKey [4*i + 1], CipherKey [4*i + 2], CipherKey [4*i + 3]);
for (i = Nk; i < Nb * (Nr + 1); i++)
{
temp = ExpandedKey [i - 1] ; if (i% Nk == 0)
temp = ByteSub (RotByte (temp)) ^Rcon [i/Nk] ; else if (i% Nk == 4)
temp = ByteSub (temp); ExpandedKey [i] = ExpandedKey [i - Nk] ^temp;
}
}
Раундовыефункции:
Round (word State, word RoundKey)
{
ByteSub (State);
ShiftRow (State); MixColumn (State); AddRoundKey (State, RoundKey)
FinalRound (word State, word RoundKey) {
ByteSub (State);
ShiftRow (State);
AddRoundKey (State, RoundKey)
}
Полная процедура зашифрования блока текста: