Кодирование и шифрование информации в системах связи
..pdf511
где ki – i-ый бит ключевого потока, производимого генератором; n – длина LFSR;
uij – состояние j-ой ячейки LFSR.
Для того чтобы получить ключевую последовательность, обладающую хорошими статистическими свойствами, необходимо чтобы обратные связи в LFSR были сформированы в соответствии с примитивными многочленами, а комбинирующая и фильтрующая функции формировали равномерно распределенные последовательности.
Параметры LFSR и комбинирующей и фильтрующей функций обычно общеизвестны,
секретными являются начальный состояния LFSR, зависящие от ключа. Поэтому целью большинства атак на комбинирующие и фильтрующие генераторы является восстановление начальных состояний всех LFSR.
Фильтрующий генератор можно рассматривать как частный случай комбинирующего генератора, у которого все LFSR одинаковы, а начальное состояние LFSR-i совпадает с состоянием LFSR-1 на i-ом такте работы. Но, поскольку криптоанализ этих схем несколько различается, принято рассматривать эти схемы как два различных типа генераторов ключевого потока.
Примерами комбинирующего генератора являются: генератор Геффе и генератор Дженнингса. Примером фильтрующего генератора является алгоритм Nanoteq.
Регистры сдвига с нелинейной обратной связью
Как уже говорилось выше, регистр сдвига с обратной связью состоит из двух частей:
регистра сдвига и функции обратной связи. В качестве функции обратной связи выступает любая булева функция f от n переменных. В случае, когда функция обратной связи f линейна,
регистр сдвига называется регистром сдвига с линейной обратной связью (LFSR), в
противном случае – регистром сдвига с нелинейной обратной связью (non-linear feedback shift register, NLFSR).
Регистры сдвига с обратной связью по переносу
Регистр сдвига с обратной связью по переносу (feedback with carry shift register, FCSR)
напоминает LFSR [4]. В обоих используется регистр сдвига и функция обратной связи, но в
FCSR дополнительно предусмотрен еще и регистр переноса (рисунок 8).
512
m |
div 2 |
mod 2 |
bn–1 |
|
|
bn–2 |
|
|
|
|
b1 |
|
|
b0 |
|||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
… |
|
|
|
|
|||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
c1 |
|
|
c2 |
|
|
|
|
cn–1 |
|
|
cn |
||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Рисунок 7.24. Регистр сдвига FCSR
На рисунке 2.24 знак означает целочисленное сложение. Содержимое регистра сдвига состоит из n бит, обозначенных bn–1, bn–2, …, b1, b0.
Работа FCSR описывается следующим образом [6]:
n
1.Вычисляется сумма n ck bn k m .
k1
2.Содержимое регистра сдвигается на одну позицию вправо. Содержимое крайней правой ячейки FCSR b0 поступает на выход.
3.Рассчитывается новое содержимое крайней левой ячейки bn–1 = n (mod
2).
4. |
В регистр переноса записывается новое значение |
m |
|
|
a |
|
|
|
|
|
n |
|
n |
|
n |
. |
|||
|
|
|
|
|
2 |
|
2 |
|
Регистром переноса служит число, а не бит. Размер регистра переноса должен быть не менее log2t, где t – количество отводов. Например, если отвода два, то регистр переноса однобитовый, а если отводов четыре, то регистр переноса должен состоять из 2 бит.
Максимальный период последовательности, генерируемой FCSR, равен (c – 1), где c –
число обратной связи (connection integer) FCSR. Число c определяется отводами обратной связи:
c = cn2n + cn–12n–1 + … + c121 – 1.
Последовательность максимального периода, генерируемая FCSR, называется l-
последовательностью. l-последовательность генерируется FCSR с числом обратной связи c,
для которого 2 является корнем примитивным.
513
Поточные шифры
Обозначения
Ниже используются следующие обозначения:
+: (x + y) означает x + y (mod 232), где 0 x < 232 и 0 y < 232.
: поразрядное исключающее ИЛИ (XOR).
: поразрядное И (AND).
&: логическое И.
||: конкатенация.
>>: оператор сдвига вправо. x >> n означает, что x сдвигается вправо на
n бит.
<<: оператор сдвига влево. x << n означает, что x сдвигается влево на n
бит.
>>>: оператор циклического сдвига вправо. x >>> n означает ((x >> n)
(x << (32 – n)), где 0 n < 32, 0 x <232.
<<<: оператор циклического сдвига влево. x <<< n означает ((x << n)
(x >> (32 – n)), где 0 n < 32, 0 x <232.
: (x y) означает x – y (mod 512).
A[g..h] обозначает биты с g по h переменной A.
Поточный шифр HC-128
Поточный шифр HC-128 [6] – упрощенная версия поточного шифра HC-256 для 128-
битового уровня безопасности. HC-128 – простой и свободно доступный шифр,
ориентированный на программную реализацию. Поточный шифр HC-128 использует 128
битовые ключ и вектор инициализации IV.
HC-128 состоит из двух секретных таблиц, каждая из которых содержит 512 32-
разрядных элемента. На каждом шаге один элемент таблицы обновляется с помощью нелинейной функции обратной связи. Все элементы этих двух таблиц обновляются каждые
1024 шага. На каждом шаге, нелинейной функцией фильтрации выхода генерируется один
32-разрядный выходной блок.
Инициализация
Процесс инициализации HC-128 состоит в расширении ключа и вектора инициализации в таблицы P и Q (подобно SHA-256) и выполнении цикла шифрования (1024 раза), без генерации выходной последовательности (выходные последовательности используются для обновления P и Q).
|
|
|
|
|
|
|
|
|
514 |
В процессе инициализации выполняются следующие шаги: |
|||||||||
1. Пусть K = K0||K1||K2||K3 |
и IV = IV0||IV1||IV2||IV3, где Ki and IVi обозначают 32-битовые |
||||||||
числа. Ключ и IV расширяются в массив Wi (0 i 1279): |
|||||||||
|
|
|
|
Ki |
|
|
|
|
0 i 7 |
|
|
|
|
IVi 8 |
|
|
|
8 i 15 |
|
Wi |
|
|
|
|
|
|
|||
f |
2 |
W |
W |
f |
W |
W |
i |
16 i 1279 |
|
|
i 2 |
i 7 |
1 |
|
i 15 |
i 16 |
|
|
где функции f1(x) и f2(x) при x = x3||x2||x1||x0, (x – 32-битное слово, x0, x1, x2, и x3 – четыре байта. x3 и x0 обозначают соответственно самый старший байт и самый младший байт величины x) определяются как
f1(x) = (x >>> 7) (x >>> 18) (x >> 3), f2(x) = (x >>> 17) (x >>> 19) (x >> 10).
2. Обновить таблицы P и Q массивом W.
P[i] = Wi+256, для 0 ≤ i ≤ 511, Q[i] = Wi+768, для 0 ≤ i ≤ 511.
3. Выполнить цикл шифрования 1024 раза и использовать выходные последовательности для замены элементов таблицы следующим образом:
for i = 0 to 511 do
P[i] = (P[i] + g1(P[i 3], P[i 10], P[i 511])) h1(P[i 12]);
for i = 0 to 511 do
Q[i] = (Q[i] + g2(Q[i 3], Q[i 10], Q[i 511])) h2(Q[i 12]);
где функции g1(x), g2(x), h1(x) и h2(x) при x = x3||x2||x1||x0 определяются как g1(x, y, z) = ((x >>> 10) (z >>> 23)) + (y >>> 8),
g2(x, y, z) = ((x <<< 10) (z <<< 23)) + (y <<< 8), h1(x) = Q[x0] + Q[256 + x2],
h2(x) = P[x0] + P[256 + x2].
Для функции h1(x) таблица Q используется как S-блок. Для функции h2(x), таблица P
используется как S-блок.
Процесс инициализации завершен, и шифр готов к генерации ключевой последовательности.
Генерация ключевого потока
На каждом шаге, обновляется один элемент таблицы, и генерируется один 32-битовый блок выходной последовательности. S-блок используется для генерации только 512
выходных последовательностей, затем он обновляется за следующие 512 шага. Процесс
515
генерации ключевой последовательности HC-128 описывается следующим псевдокодом
(рисунок 1).
i = 0; repeat {
j = i mod 512;
if (i mod 1024) < 512{
P[j] = P[j] + g1(P[j 3], P[j 10], P[j 511]);
si = h1(P[j 12]) P[j];
}
else {
Q[j] = Q[j] + g2(Q[j 3], Q[j 10], Q[j 511]);
si = h2(Q[j 12]) Q[j];
}
i = i + 1;
}
Рисунок 1. Псевдокод генерации ключевой последовательности
si – 32-битовый выходной блок на i-м шаге процесса генерации ключевой последовательности.
Поточный шифр Rabbit
Алгоритм Rabbit в качестве входных данных использует 128-битовый секретный ключ и,
если необходимо, 64-битовый вектор IV [6]. За одну итерацию генерирует блок 128
псевдослучайных бит. Шифрование/расшифрование производится путем сложения по модулю 2 (XOR) сгенерированной псевдослучайной последовательности с открытым/зашифрованным текстом. Размер внутреннего состояния – 513 бит, поделенных между восьмью 32-разрядными переменными состояния, восьмью 32-разрядными счетчиками и одним битом переноса. Эти восемь переменных состояния обновляются посредством восьми парных нелинейных функций. Счетчики гарантируют нижнюю границу на длине периода для переменных состояния.
Внутреннее состояние поточного шифра состоит из 513 битов. 512 битов разделены между восьмью 32-разрядными переменными состояния xj,i и восьмью 32-разрядными переменными счетчика cj,i, где xj,i – переменная состояния j-ой подсистемы в i-ой итерации, а cj,i обозначает соответствующую переменную счетчика. Также есть один бит счетчика по переносу 7,i, который должен сохраняться/накапливаться между итерациями. Этот бит счетчика по переносу инициализируется путем обнуления. Восемь переменных состояния и восемь счетчиков формируются из ключа при инициализации.
Инициализация
Алгоритм инициализируется разворачиванием 128-битового ключа в восемь переменных состояния и восемь счетчиков так, что есть взаимно однозначное соответствие между ключом и переменными начального состояния xj,i и начальными значениями счетчиков cj,i.
516
Ключ K[127.. 0] разделен на восемь 16-битовых подключей:
k0 = K[15..0], k1 = K[31..16], …, k7 = K[127..112].
Переменные состояния и счетчика инициализируются из подключей следующим
образом:
x j ,0 |
k |
j 1mod 8 |
|| k j , |
|
для четных j |
|
|
|
|
|
|| k j 4 mod 8 |
, |
|
|
|
|
k j 5 mod 8 |
|
для нечетных j |
|
|||
и |
|
|
|
|
|
|
|
x j ,0 |
k |
j 4 mod 8 |
|| k j 5 mod 8 |
, |
для четных j |
|
|
|
|
|
|
|
|
. |
|
|
k j || k j 1mod 8 , |
|
для нечетных j |
|
Чтобы уменьшить корреляцию между битами ключа и битами переменных внутреннего состояния система повторяется четыре раза, в соответствии с функцией следующего состояния, определенной ранее. Наконец, переменные счетчика повторно инициализируются согласно выражению:
cj,4 = cj,4 x(j+4 mod 8),4
для всех j, чтобы предотвратить восстановление ключа обратным преобразованием системы счетчика.
Обозначим внутреннее состояние после применения схемы установки ключа как основное состояние. Пусть копия этого основного состояния будет изменена в соответствии со схемой установки IV. Схема установки IV изменяет состояние счетчика как функция IV. Это реализуется путем применения операции XOR к 64-битовым IV и
всеми 256 битами состояния счетчика. 64 бита IV обозначаются IV[63..0]. Счетчики изменяются следующим образом:
c0,4 = c0,4 |
IV[31..0], |
|
c1,4 = c1,4 |
(IV[63..48] || IV[31..16]), |
|
c2,4 = c2,4 |
IV[63..32], |
|
c3,4 = c3,4 |
(IV[47..32] || IV[15..0]), |
|
c4,4 |
= c4,4 |
IV[31..0], |
c5,4 |
= c5,4 |
(IV[63..48] || IV[31..16]), |
c6,4 |
= c6,4 |
IV[63..32], |
c7,4 |
= c7,4 |
(IV[47..32] || IV[15..0]). |
517
Чтобы сделать все биты состояния нелинейно зависящими от всех битов IV система повторяется четыре раза. Модификация счетчика с помощью IV гарантирует, что все 264
различные вектора IV приведут к уникальным ключевым последовательностям.
Генерация ключевого потока
Ядром алгоритма Rabbit является повторение функции выработки следующего состояния, определенной уравнениями:
x0,i+1 = g0,i + (g7,i <<< 16) + (g6,i <<< 16),
x1,i+1 = g1,i + (g0,i <<< 8) + g7,i,
x2,i+1 = g2,i + (g1,i <<< 16) + (g0,i <<< 16),
x3,i+1 = g3,i + (g2,i <<< 8) + g1,i,
x4,i+1 = g4,i + (g3,i <<< 16) + (g2,i <<< 16),
x5,i+1 = g5,i + (g4,i <<< 8) + g3,i,
x6,i+1 = g6,i + (g5,i <<< 16) + (g4,i <<< 16),
x7,i+1 = g7,i + (g6,i <<< 8) + g5,i,
gj,i = ((xj,i + cj,i+1)2 ((xj,i + cj,i+1)2 >> 32)) mod 232,
где все операции сложения приводятся по модулю 232. Эта двойная система приведена на рисунке 2.25. Перед каждой итерацией счетчики увеличиваются в соответствии с описанным ниже правилом.
Рис. 2.25. Графическое представление системы Работа счетчиков определяется следующим образом:
c0,i+1 = c0,i + a0 + 7,i mod 232, c1,i+1 = c1,i + a0 + 0,i+1 mod 232,
518
c2,i+1 = c2,i + a0 + 1,i+1 mod 232,
c3,i+1 = c3,i + a0 + 2,i+1 mod 232,
c4,i+1 = c4,i + a0 + 3,i+1 mod 232,
c5,i+1 = c5,i + a0 + 4,i+1 mod 232,
c6,i+1 = c6,i + a0 + 5,i+1 mod 232,
c7,i+1 = c7,i + a0 + 6,i+1 mod 232,
где бит счетчика по переносу j,i+1 задан выражением
|
1 |
åñëè c |
a |
0 |
|
7,i |
232 |
j 0 |
||
|
|
0,i |
|
|
|
|
|
|
||
j ,i 1 |
åñëè c j ,i |
a j |
j 1,i 1 |
2 |
32 |
j 0 |
||||
1 |
|
|||||||||
|
|
|
|
|
|
|
|
|
|
|
|
0 |
во всех остальных |
случаях |
Кроме того, константы aj определены как: a0 = 0x4D34D34D, a1 = 0xD34D34D3,
a2 = 0x34D34D34, a3 = 0x4D34D34D, a4 = 0xD34D34D3, a5 = 0x34D34D34, a6 = 0x4D34D34D, a7 = 0xD34D34D3.
После каждой итерации результат извлекается следующим образом:
s |
15..0 x 15..0 x 31..16 , |
|
s |
31..16 |
x 31..16 |
x 15..0 , |
|
|||
|
i |
0,i |
5,i |
|
|
i |
|
0,i |
3,i |
|
s |
47..32 |
x 15..0 |
x 31..16 |
, |
s |
63..48 x 31..16 x 15..0 |
, |
|||
|
i |
2,i |
7,i |
|
|
|
i |
2,i |
5,i |
|
s |
79..64 |
x 15..0 |
x 31..16 |
, |
s |
95..80 x 31..16 x 15..0 |
, |
|||
|
i |
4,i |
1,i |
|
|
|
i |
4,i |
7,i |
|
s |
111..96 x 15..0 x 31..16 |
, |
s 127..112 x 31..16 x 15..0 . |
|||||||
|
i |
6,i |
3,i |
|
|
|
i |
6,i |
1,i |
|
Поточный шифр Salsa20
Ядром шифра Salsa20 является хеш-функция с 64-байтовым входом и 64-байтовым выходом [6]. Хеш-функция в режиме счетчика используется как поточный шифр: Salsa20
шифрует 64-байтовый блок открытого текста хешированием ключа, в данном случае, и
номера блока, складывая результат по модулю 2 (XOR) с открытым текстом.
Хеш-функция Salsa20
Хеш-функция Salsa20(x) определяется следующим выражением:
Salsa20(x) = x + doubleround10(x),
где каждая 4-байтовая последовательность x рассматривается как слово в форме littleendian.