<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0</id>
	<title>Алговики - Вклад [ru]</title>
	<link rel="self" type="application/atom+xml" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0"/>
	<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/ru/%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0"/>
	<updated>2026-10-22T21:29:59Z</updated>
	<subtitle>Вклад</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0&amp;diff=20276</id>
		<title>Обсуждение участницы:Александра</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0&amp;diff=20276"/>
		<updated>2016-12-07T19:17:34Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Замечания */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Замечания к [[Участник:Александра/Метод_встречи_посередине]] ==&lt;br /&gt;
&lt;br /&gt;
1) отсутствует оценка объёма входных данных на врезке в начале статьи&lt;br /&gt;
&lt;br /&gt;
2) пункты 2.1 и 2.2 должны быть 2.4 и 2.7, согласно формату описания [[Структура_описания_свойств_алгоритмов]]&lt;br /&gt;
&lt;br /&gt;
== Замечания к пункту 2.4 от 16.11.2016 == &lt;br /&gt;
&lt;br /&gt;
* в чём измерялась произвоидтельность в пункте? требуется указать&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt; Добавила в пункт 2.4 пояснение того, как подсчитывалась производительность. Поскольку производительность в единицах арифметические операции/сек может быть разной в зависимости от используемого алгоритма шифрования, вместо арифметических операций я использовала операции опробования ключа.&lt;br /&gt;
&lt;br /&gt;
== Замечания ==&lt;br /&gt;
&lt;br /&gt;
* полное и качественное описание, развернутый анализ&lt;br /&gt;
* операции log и max лучше набирать прямым шрифтом: \log и \max&lt;br /&gt;
* п.2.4: &amp;quot;зависимость производительности от числа ядер визуально близка к линейной&amp;quot; - у вас ведь логарифмическая шкала по ядрам! лучше просто сказать, что она возрастает&lt;br /&gt;
&lt;br /&gt;
: &amp;gt;&amp;gt; Сделала правки по замечаниям [[Участник:Александра]] 7.12.2016&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0&amp;diff=20268</id>
		<title>Обсуждение участницы:Александра</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0&amp;diff=20268"/>
		<updated>2016-12-07T18:57:56Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Замечания */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Замечания к [[Участник:Александра/Метод_встречи_посередине]] ==&lt;br /&gt;
&lt;br /&gt;
1) отсутствует оценка объёма входных данных на врезке в начале статьи&lt;br /&gt;
&lt;br /&gt;
2) пункты 2.1 и 2.2 должны быть 2.4 и 2.7, согласно формату описания [[Структура_описания_свойств_алгоритмов]]&lt;br /&gt;
&lt;br /&gt;
== Замечания к пункту 2.4 от 16.11.2016 == &lt;br /&gt;
&lt;br /&gt;
* в чём измерялась произвоидтельность в пункте? требуется указать&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt; Добавила в пункт 2.4 пояснение того, как подсчитывалась производительность. Поскольку производительность в единицах арифметические операции/сек может быть разной в зависимости от используемого алгоритма шифрования, вместо арифметических операций я использовала операции опробования ключа.&lt;br /&gt;
&lt;br /&gt;
== Замечания ==&lt;br /&gt;
&lt;br /&gt;
* полное и качественное описание, развернутый анализ&lt;br /&gt;
* операции log и max лучше набирать прямым шрифтом: \log и \max&lt;br /&gt;
* п.2.4: &amp;quot;зависимость производительности от числа ядер визуально близка к линейной&amp;quot; - у вас ведь логарифмическая шкала по ядрам! лучше просто сказать, что она возрастает&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt; Сделала правки по замечаниям&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=20267</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=20267"/>
		<updated>2016-12-07T18:55:26Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Algoman}}&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;O(\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;\log(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
В случае использования хэш-таблицы достаточно большого размера основную сложность алгоритма составляет опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Одним из самых трудоёмких шагов также оказывается сортировка таблицы.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Всюду далее считаем, что алгоритм не прекращает работу при нахождении первого совпадения, а ищет все совпадения.&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(\log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(\max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем информационный граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифровывается (Dec) на ключах &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|900px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open — открытый текст, Close — шифртекст, Enc — операция зашифрования, Dec — операция расшифрования, Cmp — операция сравнения, Keys — вычисленные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки мощности &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt;, т.е. из каждой такой вершины выходит &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; дуг. Длинных дуг в алгоритме нет. В случае поиска всех пар ключей с совпадающими криптограммами алгоритм полностью детерминирован.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
Исследование масштабируемости реализации алгоритма проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Изменяемые параметры запуска:&lt;br /&gt;
* Размер ключа – от 8 до 20 бит с шагом 1&lt;br /&gt;
* Число ядер – от 1 до 8 (значения являются степенью числа 2)&lt;br /&gt;
Ниже представлен график зависимости [[Глоссарий#Производительность|производительности]] от числа ядер и размера ключа (размер задачи – экспоненциальная функция от размера ключа). Для измерения производительности в качестве базовой операции используется операция опробования ключа и время в секундах. Количество арифметических операций, содержащихся в операции опробования, может быть разным в зависимости от используемого алгоритма шифрования.&lt;br /&gt;
[[File:Масштабируемость.jpg|thumb|center|900px|Рисунок 2. Масштабируемость реализации алгоритма]]&lt;br /&gt;
&lt;br /&gt;
Как видно из графика, производительность почти не изменяется в зависимости от размера задачи и возрастает в зависимости от числа ядер. Росту производительности способствует то, что алгоритм содержит большое количество независимых операций опробования ключа, синхронизация между параллельно выполняющимися опробованиями не требуется.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/AlBatarina/Super2016/blob/master/meet_in_the_middle/meet.c Исследованная параллельная реализация на языке C]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=20266</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=20266"/>
		<updated>2016-12-07T18:50:11Z</updated>

		<summary type="html">&lt;p&gt;Александра: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Algoman}}&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;O(\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;\log(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
В случае использования хэш-таблицы достаточно большого размера основную сложность алгоритма составляет опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Одним из самых трудоёмких шагов также оказывается сортировка таблицы.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Всюду далее считаем, что алгоритм не прекращает работу при нахождении первого совпадения, а ищет все совпадения.&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(\log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(\max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем информационный граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифровывается (Dec) на ключах &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|900px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open — открытый текст, Close — шифртекст, Enc — операция зашифрования, Dec — операция расшифрования, Cmp — операция сравнения, Keys — вычисленные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки мощности &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt;, т.е. из каждой такой вершины выходит &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; дуг. Длинных дуг в алгоритме нет. В случае поиска всех пар ключей с совпадающими криптограммами алгоритм полностью детерминирован.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
Исследование масштабируемости реализации алгоритма проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Изменяемые параметры запуска:&lt;br /&gt;
* Размер ключа – от 8 до 20 бит с шагом 1&lt;br /&gt;
* Число ядер – от 1 до 8 (значения являются степенью числа 2)&lt;br /&gt;
Ниже представлен график зависимости [[Глоссарий#Производительность|производительности]] от числа ядер и размера ключа (размер задачи – экспоненциальная функция от размера ключа). Для измерения производительности в качестве базовой операции используется операция опробования ключа и время в секундах. Количество арифметических операций, содержащихся в операции опробования, может быть разным в зависимости от используемого алгоритма шифрования.&lt;br /&gt;
[[File:Масштабируемость.jpg|thumb|center|900px|Рисунок 2. Масштабируемость реализации алгоритма]]&lt;br /&gt;
&lt;br /&gt;
Как видно из графика, производительность почти не изменяется в зависимости от размера задачи, в то время как зависимость производительности от числа ядер визуально близка к линейной. Это связано с тем, что алгоритм содержит большое количество независимых операций опробования ключа, синхронизация между параллельно выполняющимися опробованиями не требуется.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/AlBatarina/Super2016/blob/master/meet_in_the_middle/meet.c Исследованная параллельная реализация на языке C]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=18870</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=18870"/>
		<updated>2016-11-21T19:43:38Z</updated>

		<summary type="html">&lt;p&gt;Александра: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;O(\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;\log(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
В случае использования хэш-таблицы достаточно большого размера основную сложность алгоритма составляет опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Одним из самых трудоёмких шагов также оказывается сортировка таблицы.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Всюду далее считаем, что алгоритм не прекращает работу при нахождении первого совпадения, а ищет все совпадения.&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем информационный граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифровывается (Dec) на ключах &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|900px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open — открытый текст, Close — шифртекст, Enc — операция зашифрования, Dec — операция расшифрования, Cmp — операция сравнения, Keys — вычисленные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки мощности &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt;, т.е. из каждой такой вершины выходит &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; дуг. Длинных дуг в алгоритме нет. В случае поиска всех пар ключей с совпадающими криптограммами алгоритм полностью детерминирован.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование масштабируемости реализации алгоритма проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Изменяемые параметры запуска:&lt;br /&gt;
* Размер ключа – от 8 до 20 бит с шагом 1&lt;br /&gt;
* Число ядер – от 1 до 8 (значения являются степенью числа 2)&lt;br /&gt;
Ниже представлен график зависимости [[Глоссарий#Производительность|производительности]] от числа ядер и размера ключа (размер задачи – экспоненциальная функция от размера ключа). Для измерения производительности в качестве базовой операции используется операция опробования ключа и время в секундах. Количество арифметических операций, содержащихся в операции опробования, может быть разным в зависимости от используемого алгоритма шифрования.&lt;br /&gt;
[[File:Масштабируемость.jpg|thumb|center|900px|Рисунок 2. Масштабируемость реализации алгоритма]]&lt;br /&gt;
&lt;br /&gt;
Как видно из графика, производительность почти не изменяется в зависимости от размера задачи, в то время как зависимость производительности от числа ядер визуально близка к линейной. Это связано с тем, что алгоритм содержит большое количество независимых операций опробования ключа, синхронизация между параллельно выполняющимися опробованиями не требуется.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/AlBatarina/Super2016/blob/master/meet_in_the_middle/meet.c Исследованная параллельная реализация на языке C]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0&amp;diff=18869</id>
		<title>Обсуждение участницы:Александра</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%9E%D0%B1%D1%81%D1%83%D0%B6%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D1%8B:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0&amp;diff=18869"/>
		<updated>2016-11-21T19:40:54Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Замечания к пункту 2.4 от 16.11.2016 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Замечания к [[Участник:Александра/Метод_встречи_посередине]] ==&lt;br /&gt;
&lt;br /&gt;
1) отсутствует оценка объёма входных данных на врезке в начале статьи&lt;br /&gt;
&lt;br /&gt;
2) пункты 2.1 и 2.2 должны быть 2.4 и 2.7, согласно формату описания [[Структура_описания_свойств_алгоритмов]]&lt;br /&gt;
&lt;br /&gt;
== Замечания к пункту 2.4 от 16.11.2016 == &lt;br /&gt;
&lt;br /&gt;
* в чём измерялась произвоидтельность в пункте? требуется указать&lt;br /&gt;
&lt;br /&gt;
&amp;gt;&amp;gt; Добавила в пункт 2.4 пояснение того, как подсчитывалась производительность. Поскольку производительность в единицах арифметические операции/сек может быть разной в зависимости от используемого алгоритма шифрования, вместо арифметических операций я использовала операции опробования ключа.&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=18864</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=18864"/>
		<updated>2016-11-21T19:33:45Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;O(\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;\log(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
В случае использования хэш-таблицы достаточно большого размера основную сложность алгоритма составляет опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Одним из самых трудоёмких шагов также оказывается сортировка таблицы.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Всюду далее считаем, что алгоритм не прекращает работу при нахождении первого совпадения, а ищет все совпадения.&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем информационный граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифровывается (Dec) на ключах &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|900px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open — открытый текст, Close — шифртекст, Enc — операция зашифрования, Dec — операция расшифрования, Cmp — операция сравнения, Keys — вычисленные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки мощности &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt;, т.е. из каждой такой вершины выходит &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; дуг. Длинных дуг в алгоритме нет. В случае поиска всех пар ключей с совпадающими криптограммами алгоритм полностью детерминирован.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование масштабируемости реализации алгоритма проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Изменяемые параметры запуска:&lt;br /&gt;
* Размер ключа – от 8 до 20 бит с шагом 1&lt;br /&gt;
* Число ядер – от 1 до 8 (значения являются степенью числа 2)&lt;br /&gt;
Ниже представлен график зависимости [[Глоссарий#Производительность|производительности]] от числа ядер и размера ключа (размер задачи – экспоненциальная функция от размера ключа). Для измерения производительности в качестве базовой операции используется операция опробования ключа и время в секундах. Количество арифметических операций, содержащихся в операции опробования, может быть разным в зависимости от используемого алгоритма шифрования.&lt;br /&gt;
[[File:Масштабируемость.jpg|thumb|center|900px|Рисунок 2. Масштабируемость реализации алгоритма]]&lt;br /&gt;
&lt;br /&gt;
Как видно из графика, производительность почти не изменяется в зависимости от размера задачи, в то время как зависимость производительности от числа ядер визуально близка к линейной. Это связано с тем, что алгоритм содержит большое количество независимых операций опробования ключа, синхронизация между параллельно выполняющимися опробованиями не требуется.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/AlBatarina/Super2016/blob/master/meet_in_the_middle/meet.c Исследованная параллельная реализация на языке C]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=18863</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=18863"/>
		<updated>2016-11-21T19:33:09Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;O(\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;\log(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
В случае использования хэш-таблицы достаточно большого размера основную сложность алгоритма составляет опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Одним из самых трудоёмких шагов также оказывается сортировка таблицы.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Всюду далее считаем, что алгоритм не прекращает работу при нахождении первого совпадения, а ищет все совпадения.&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем информационный граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифровывается (Dec) на ключах &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|900px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open — открытый текст, Close — шифртекст, Enc — операция зашифрования, Dec — операция расшифрования, Cmp — операция сравнения, Keys — вычисленные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки мощности &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt;, т.е. из каждой такой вершины выходит &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; дуг. Длинных дуг в алгоритме нет. В случае поиска всех пар ключей с совпадающими криптограммами алгоритм полностью детерминирован.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование масштабируемости реализации алгоритма проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Изменяемые параметры запуска:&lt;br /&gt;
* Размер ключа – от 8 до 20 бит с шагом 1&lt;br /&gt;
* Число ядер – от 1 до 8 (значения являются степенью числа 2)&lt;br /&gt;
Ниже представлен график зависимости [[Глоссарий#Производительность|производительности]] от числа ядер и размера ключа (размер задачи – экспоненциальная функция от размера ключа). Для измерения производительности качестве базовой операции используется операция опробования ключа и время в секундах. Количество арифметических операций, содержащихся в операции опробования, может быть разным в зависимости от используемого алгоритма шифрования.&lt;br /&gt;
[[File:Масштабируемость.jpg|thumb|center|900px|Рисунок 2. Масштабируемость реализации алгоритма]]&lt;br /&gt;
&lt;br /&gt;
Как видно из графика, производительность почти не изменяется в зависимости от размера задачи, в то время как зависимость производительности от числа ядер визуально близка к линейной. Это связано с тем, что алгоритм содержит большое количество независимых операций опробования ключа, синхронизация между параллельно выполняющимися опробованиями не требуется.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/AlBatarina/Super2016/blob/master/meet_in_the_middle/meet.c Исследованная параллельная реализация на языке C]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=15993</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=15993"/>
		<updated>2016-11-06T17:55:39Z</updated>

		<summary type="html">&lt;p&gt;Александра: Исправила опечатку&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Algoman}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;O(\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;\log(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
В случае использования хэш-таблицы достаточно большого размера основную сложность алгоритма составляет опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Одним из самых трудоёмких шагов также оказывается сортировка таблицы.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Всюду далее считаем, что алгоритм не прекращает работу при нахождении первого совпадения, а ищет все совпадения.&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем информационный граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифровывается (Dec) на ключах &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|900px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open — открытый текст, Close — шифртекст, Enc — операция зашифрования, Dec — операция расшифрования, Cmp — операция сравнения, Keys — вычисленные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки мощности &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt;, т.е. из каждой такой вершины выходит &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; дуг. Длинных дуг в алгоритме нет. В случае поиска всех пар ключей с совпадающими криптограммами алгоритм полностью детерминирован.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование масштабируемости реализации алгоритма проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Изменяемые параметры запуска:&lt;br /&gt;
* Размер ключа – от 8 до 20 бит с шагом 1&lt;br /&gt;
* Число ядер – от 1 до 8 (значения являются степенью числа 2)&lt;br /&gt;
Ниже представлен график зависимости [[Глоссарий#Производительность|производительности]] от числа ядер и размера ключа (размер задачи – экспоненциальная функция от размера ключа).&lt;br /&gt;
[[File:Масштабируемость.jpg|thumb|center|900px|Рисунок 2. Масштабируемость реализации алгоритма]]&lt;br /&gt;
&lt;br /&gt;
Как видно из графика, производительность почти не изменяется в зависимости от размера задачи, в то время как зависимость производительности от числа ядер визуально близка к линейной. Это связано с тем, что алгоритм содержит большое количество независимых операций опробования ключа, синхронизация между параллельно выполняющимися опробованиями не требуется.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/AlBatarina/Super2016/blob/master/meet_in_the_middle/meet.c Исследованная параллельная реализация на языке C]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=15992</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=15992"/>
		<updated>2016-11-06T17:50:22Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Algoman}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
В случае использования хэш-таблицы достаточно большого размера основную сложность алгоритма составляет опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Одним из самых трудоёмких шагов также оказывается сортировка таблицы.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Всюду далее считаем, что алгоритм не прекращает работу при нахождении первого совпадения, а ищет все совпадения.&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем информационный граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифровывается (Dec) на ключах &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|900px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open — открытый текст, Close — шифртекст, Enc — операция зашифрования, Dec — операция расшифрования, Cmp — операция сравнения, Keys — вычисленные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки мощности &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt;, т.е. из каждой такой вершины выходит &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; дуг. Длинных дуг в алгоритме нет. В случае поиска всех пар ключей с совпадающими криптограммами алгоритм полностью детерминирован.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование масштабируемости реализации алгоритма проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Изменяемые параметры запуска:&lt;br /&gt;
* Размер ключа – от 8 до 20 бит с шагом 1&lt;br /&gt;
* Число ядер – от 1 до 8 (значения являются степенью числа 2)&lt;br /&gt;
Ниже представлен график зависимости [[Глоссарий#Производительность|производительности]] от числа ядер и размера ключа (размер задачи – экспоненциальная функция от размера ключа).&lt;br /&gt;
[[File:Масштабируемость.jpg|thumb|center|900px|Рисунок 2. Масштабируемость реализации алгоритма]]&lt;br /&gt;
&lt;br /&gt;
Как видно из графика, производительность почти не изменяется в зависимости от размера задачи, в то время как зависимость производительности от числа ядер визуально близка к линейной. Это связано с тем, что алгоритм содержит большое количество независимых операций опробования ключа, синхронизация между параллельно выполняющимися опробованиями не требуется.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/AlBatarina/Super2016/blob/master/meet_in_the_middle/meet.c Исследованная параллельная реализация на языке C]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=15927</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=15927"/>
		<updated>2016-11-05T09:35:38Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Algoman}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
В случае использования хэш-таблицы достаточно большого размера основную сложность алгоритма составляет опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Одним из самых трудоёмких шагов также оказывается сортировка таблицы.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Всюду далее считаем, что алгоритм не прекращает работу при нахождении первого совпадения, а ищет все совпадения.&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем информационный граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифровывается (Dec) на ключах &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|900px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open — открытый текст, Close — шифртекст, Enc — операция зашифрования, Dec — операция расшифрования, Cmp — операция сравнения, Keys — вычисленные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки мощности &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt;, т.е. из каждой такой вершины выходит &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; дуг. Длинных дуг в алгоритме нет. В случае поиска всех пар ключей с совпадающими криптограммами алгоритм полностью детерминирован.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование масштабируемости реализации алгоритма проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Изменяемые параметры запуска:&lt;br /&gt;
* Размер ключа – от 8 до 20 бит с шагом 1&lt;br /&gt;
* Число ядер – от 1 до 8 (значения являются степенью числа 2)&lt;br /&gt;
Ниже представлен график зависимости [[Глоссарий#Производительность|производительности]] от числа ядер и размера ключа (размер задачи – экспоненциальная функция от размера ключа).&lt;br /&gt;
[[File:Масштабируемость.jpg|thumb|center|900px|Рисунок 2. Масштабируемость реализации алгоритма]]&lt;br /&gt;
&lt;br /&gt;
Как видно из графика, производительность почти не изменяется в зависимости от размера задачи, в то время как зависимость производительности от числа ядер практически линейна. Это связано с тем, что алгоритм содержит большое количество независимых операций опробования ключа, синхронизация между параллельно выполняющимися опробованиями не требуется.&lt;br /&gt;
&lt;br /&gt;
[https://github.com/AlBatarina/Super2016/blob/master/meet_in_the_middle/meet.c Исследованная параллельная реализация на языке C]&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=15925</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=15925"/>
		<updated>2016-11-04T19:17:37Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Algoman}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
В случае использования хэш-таблицы достаточно большого размера основную сложность алгоритма составляет опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Одним из самых трудоёмких шагов также оказывается сортировка таблицы.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Всюду далее считаем, что алгоритм не прекращает работу при нахождении первого совпадения, а ищет все совпадения.&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем информационный граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифровывается (Dec) на ключах &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|900px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open — открытый текст, Close — шифртекст, Enc — операция зашифрования, Dec — операция расшифрования, Cmp — операция сравнения, Keys — вычисленные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки мощности &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt;, т.е. из каждой такой вершины выходит &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; дуг. Длинных дуг в алгоритме нет. В случае поиска всех пар ключей с совпадающими криптограммами алгоритм полностью детерминирован.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование масштабируемости реализации алгоритма проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Изменяемые параметры запуска:&lt;br /&gt;
* Размер ключа – от 8 до 20 бит с шагом 1&lt;br /&gt;
* Число ядер – от 1 до 8 (значения являются степенью числа 2)&lt;br /&gt;
Ниже представлен график зависимости [[Глоссарий#Производительность|производительности]] от числа ядер и размера ключа (размер задачи – экспоненциальная функция от размера ключа).&lt;br /&gt;
[[File:Масштабируемость.jpg|thumb|center|900px|Рисунок 2. Масштабируемость реализации алгоритма]]&lt;br /&gt;
&lt;br /&gt;
Как видно из графика, производительность почти не изменяется в зависимости от размера задачи, в то время как зависимость производительности от числа ядер практически линейна. Это связано с тем, что алгоритм содержит большое количество независимых операций опробования ключа, синхронизация между параллельно выполняющимися опробованиями не требуется.&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=15924</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=15924"/>
		<updated>2016-11-04T19:16:01Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Информационный граф */ поменяла размер картинки&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Algoman}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
В случае использования хэш-таблицы достаточно большого размера основную сложность алгоритма составляет опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Одним из самых трудоёмких шагов также оказывается сортировка таблицы.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Всюду далее считаем, что алгоритм не прекращает работу при нахождении первого совпадения, а ищет все совпадения.&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем информационный граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифровывается (Dec) на ключах &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|900px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open — открытый текст, Close — шифртекст, Enc — операция зашифрования, Dec — операция расшифрования, Cmp — операция сравнения, Keys — вычисленные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки мощности &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt;, т.е. из каждой такой вершины выходит &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; дуг. Длинных дуг в алгоритме нет. В случае поиска всех пар ключей с совпадающими криптограммами алгоритм полностью детерминирован.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование масштабируемости реализации алгоритма проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Изменяемые параметры запуска:&lt;br /&gt;
* Размер ключа – от 8 до 20 бит с шагом 1&lt;br /&gt;
* Число ядер – от 1 до 8 (значения являются степенью числа 2)&lt;br /&gt;
Ниже представлен график зависимости [[Глоссарий#Производительность|производительности]] от числа ядер и размера ключа (размер задачи – экспоненциальная функция от размера ключа).&lt;br /&gt;
[[File:Масштабируемость.jpg|900px]]&lt;br /&gt;
&lt;br /&gt;
Как видно из графика, производительность почти не изменяется в зависимости от размера задачи, в то время как зависимость производительности от числа ядер практически линейна. Это связано с тем, что алгоритм содержит большое количество независимых операций опробования ключа, синхронизация между параллельно выполняющимися опробованиями не требуется.&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=15923</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=15923"/>
		<updated>2016-11-04T19:14:11Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Algoman}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
В случае использования хэш-таблицы достаточно большого размера основную сложность алгоритма составляет опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Одним из самых трудоёмких шагов также оказывается сортировка таблицы.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Всюду далее считаем, что алгоритм не прекращает работу при нахождении первого совпадения, а ищет все совпадения.&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем информационный граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифровывается (Dec) на ключах &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open — открытый текст, Close — шифртекст, Enc — операция зашифрования, Dec — операция расшифрования, Cmp — операция сравнения, Keys — вычисленные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки мощности &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt;, т.е. из каждой такой вершины выходит &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; дуг. Длинных дуг в алгоритме нет. В случае поиска всех пар ключей с совпадающими криптограммами алгоритм полностью детерминирован.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование масштабируемости реализации алгоритма проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Изменяемые параметры запуска:&lt;br /&gt;
* Размер ключа – от 8 до 20 бит с шагом 1&lt;br /&gt;
* Число ядер – от 1 до 8 (значения являются степенью числа 2)&lt;br /&gt;
Ниже представлен график зависимости [[Глоссарий#Производительность|производительности]] от числа ядер и размера ключа (размер задачи – экспоненциальная функция от размера ключа).&lt;br /&gt;
[[File:Масштабируемость.jpg|900px]]&lt;br /&gt;
&lt;br /&gt;
Как видно из графика, производительность почти не изменяется в зависимости от размера задачи, в то время как зависимость производительности от числа ядер практически линейна. Это связано с тем, что алгоритм содержит большое количество независимых операций опробования ключа, синхронизация между параллельно выполняющимися опробованиями не требуется.&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=15922</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=15922"/>
		<updated>2016-11-04T19:01:40Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Масштабируемость реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Algoman}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
В случае использования хэш-таблицы достаточно большого размера основную сложность алгоритма составляет опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Одним из самых трудоёмких шагов также оказывается сортировка таблицы.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Всюду далее считаем, что алгоритм не прекращает работу при нахождении первого совпадения, а ищет все совпадения.&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем информационный граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифровывается (Dec) на ключах &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open — открытый текст, Close — шифртекст, Enc — операция зашифрования, Dec — операция расшифрования, Cmp — операция сравнения, Keys — вычисленные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки мощности &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt;, т.е. из каждой такой вершины выходит &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; дуг. Длинных дуг в алгоритме нет. В случае поиска всех пар ключей с совпадающими криптограммами алгоритм полностью детерминирован.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование масштабируемости реализации алгоритма проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Изменяемые параметры запуска:&lt;br /&gt;
* Размер ключа – от 8 до 20 бит с шагом 1&lt;br /&gt;
* Число ядер – от 1 до 8 (значения являются степенью числа 2)&lt;br /&gt;
Ниже представлен график зависимости [[Глоссарий#Производительность|производительности]] от числа ядер и размера ключа (размер задачи – экспоненциальная функция от размера ключа).&lt;br /&gt;
[[File:Масштабируемость.jpg]]&lt;br /&gt;
Как видно из графика, производительность почти не изменяется в зависимости от размера задачи, в то время как зависимость производительности от числа ядер практически линейна. Это связано с тем, что алгоритм содержит большое количество независимых операций опробования ключа, синхронизация между параллельно выполняющимися опробованиями не требуется.&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=15921</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=15921"/>
		<updated>2016-11-04T18:51:52Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment|Algoman}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
В случае использования хэш-таблицы достаточно большого размера основную сложность алгоритма составляет опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Одним из самых трудоёмких шагов также оказывается сортировка таблицы.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Всюду далее считаем, что алгоритм не прекращает работу при нахождении первого совпадения, а ищет все совпадения.&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем информационный граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифровывается (Dec) на ключах &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open — открытый текст, Close — шифртекст, Enc — операция зашифрования, Dec — операция расшифрования, Cmp — операция сравнения, Keys — вычисленные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки мощности &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt;, т.е. из каждой такой вершины выходит &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; дуг. Длинных дуг в алгоритме нет. В случае поиска всех пар ключей с совпадающими криптограммами алгоритм полностью детерминирован.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
==== Масштабируемость алгоритма ====&lt;br /&gt;
==== Масштабируемость реализации алгоритма ====&lt;br /&gt;
Исследование масштабируемости проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета]. Изменяемые параметры запуска:&lt;br /&gt;
* Размер ключа - от 8 до 20 с шагом 1&lt;br /&gt;
* Число ядер - от 1 до 8 (значения являются степенью двойки)&lt;br /&gt;
Ниже представлен график зависимости [[Глоссарий#Производительность|производительности]] от числа ядер и размера ключа (размер ключа определяет размер задачи).&lt;br /&gt;
[[File:Масштабируемость.jpg]]&lt;br /&gt;
Как видно из графика, производительность почти не изменяется в зависимости от размера задачи, в то время как зависимость производительности от числа ядер практически линейна. Это связано с тем, что алгоритм содержит большое количество независимых операций опробования ключа, синхронизация между параллельно выполняющимися опробованиями не требуется.&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=14652</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=14652"/>
		<updated>2016-10-29T08:19:00Z</updated>

		<summary type="html">&lt;p&gt;Александра: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
В случае использования хэш-таблицы достаточно большого размера основную сложность алгоритма составляет опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Одним из самых трудоёмких шагов также оказывается сортировка таблицы.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Всюду далее считаем, что алгоритм не прекращает работу при нахождении первого совпадения, а ищет все совпадения.&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем информационный граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифровывается (Dec) на ключах &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open — открытый текст, Close — шифртекст, Enc — операция зашифрования, Dec — операция расшифрования, Cmp — операция сравнения, Keys — вычисленные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки мощности &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt;, т.е. из каждой такой вершины выходит &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; дуг. Длинных дуг в алгоритме нет. В случае поиска всех пар ключей с совпадающими криптограммами алгоритм полностью детерминирован.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=14651</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=14651"/>
		<updated>2016-10-29T08:14:34Z</updated>

		<summary type="html">&lt;p&gt;Александра: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| input_data        = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
В случае использования хэш-таблицы достаточно большого размера основную сложность алгоритма составляет опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Одним из самых трудоёмких шагов также оказывается сортировка таблицы.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Всюду далее считаем, что алгоритм не прекращает работу при нахождении первого совпадения, а ищет все совпадения.&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем информационный граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифровывается (Dec) на ключах &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open — открытый текст, Close — шифртекст, Enc — операция зашифрования, Dec — операция расшифрования, Cmp — операция сравнения, Keys — вычисленные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки мощности &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt;, т.е. из каждой такой вершины выходит &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; дуг. Длинных дуг в алгоритме нет. В случае поиска всех пар ключей с совпадающими криптограммами алгоритм полностью детерминирован.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=14650</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=14650"/>
		<updated>2016-10-29T08:13:36Z</updated>

		<summary type="html">&lt;p&gt;Александра: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
В случае использования хэш-таблицы достаточно большого размера основную сложность алгоритма составляет опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Одним из самых трудоёмких шагов также оказывается сортировка таблицы.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Всюду далее считаем, что алгоритм не прекращает работу при нахождении первого совпадения, а ищет все совпадения.&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем информационный граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифровывается (Dec) на ключах &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open — открытый текст, Close — шифртекст, Enc — операция зашифрования, Dec — операция расшифрования, Cmp — операция сравнения, Keys — вычисленные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки мощности &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt;, т.е. из каждой такой вершины выходит &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; дуг. Длинных дуг в алгоритме нет. В случае поиска всех пар ключей с совпадающими криптограммами алгоритм полностью детерминирован.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Локальность данных и вычислений ===&lt;br /&gt;
&lt;br /&gt;
=== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Динамические характеристики и эффективность реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
=== Выводы для классов архитектур ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=14649</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=14649"/>
		<updated>2016-10-29T08:09:47Z</updated>

		<summary type="html">&lt;p&gt;Александра: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
В случае использования хэш-таблицы достаточно большого размера основную сложность алгоритма составляет опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Одним из самых трудоёмких шагов также оказывается сортировка таблицы.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Всюду далее считаем, что алгоритм не прекращает работу при нахождении первого совпадения, а ищет все совпадения.&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем информационный граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифровывается (Dec) на ключах &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open — открытый текст, Close — шифртекст, Enc — операция зашифрования, Dec — операция расшифрования, Cmp — операция сравнения, Keys — вычисленные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки мощности &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt;, т.е. из каждой такой вершины выходит &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; дуг. Длинных дуг в алгоритме нет. В случае поиска всех пар ключей с совпадающими криптограммами алгоритм полностью детерминирован.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== ===&lt;br /&gt;
&lt;br /&gt;
=== ===&lt;br /&gt;
&lt;br /&gt;
=== ===&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
TBD&lt;br /&gt;
&lt;br /&gt;
=== ===&lt;br /&gt;
&lt;br /&gt;
=== ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10442</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10442"/>
		<updated>2016-10-15T16:11:49Z</updated>

		<summary type="html">&lt;p&gt;Александра: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Assignment}}&lt;br /&gt;
&lt;br /&gt;
{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
В случае использования хэш-таблицы достаточно большого размера основную сложность алгоритма составляет опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Одним из самых трудоёмких шагов также оказывается сортировка таблицы.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Всюду далее считаем, что алгоритм не прекращает работу при нахождении первого совпадения, а ищет все совпадения.&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем информационный граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифровывается (Dec) на ключах &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open — открытый текст, Close — шифртекст, Enc — операция зашифрования, Dec — операция расшифрования, Cmp — операция сравнения, Keys — вычисленные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки мощности &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt;, т.е. из каждой такой вершины выходит &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; дуг. Длинных дуг в алгоритме нет. В случае поиска всех пар ключей с совпадающими криптограммами алгоритм полностью детерминирован.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
TBD&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10396</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10396"/>
		<updated>2016-10-15T16:00:07Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Свойства алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
В случае использования хэш-таблицы достаточно большого размера основную сложность алгоритма составляет опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Одним из самых трудоёмких шагов также оказывается сортировка таблицы.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Всюду далее считаем, что алгоритм не прекращает работу при нахождении первого совпадения, а ищет все совпадения.&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем информационный граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифровывается (Dec) на ключах &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open — открытый текст, Close — шифртекст, Enc — операция зашифрования, Dec — операция расшифрования, Cmp — операция сравнения, Keys — вычисленные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки мощности &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt;, т.е. из каждой такой вершины выходит &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; дуг. Длинных дуг в алгоритме нет. В случае поиска всех пар ключей с совпадающими криптограммами алгоритм полностью детерминирован.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
TBD&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10341</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10341"/>
		<updated>2016-10-15T15:51:27Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
В случае использования хэш-таблицы достаточно большого размера основную сложность алгоритма составляет опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Одним из самых трудоёмких шагов также оказывается сортировка таблицы.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Всюду далее считаем, что алгоритм не прекращает работу при нахождении первого совпадения, а ищет все совпадения.&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем информационный граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифровывается (Dec) на ключах &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open — открытый текст, Close — шифртекст, Enc — операция зашифрования, Dec — операция расшифрования, Cmp — операция сравнения, Keys — вычисленные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки мощности &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt;, т.е. из каждой такой вершины выходит &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; дуг. Длинных дуг в алгоритме нет.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
TBD&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10335</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10335"/>
		<updated>2016-10-15T15:50:42Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Свойства алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
В случае использования хэш-таблицы достаточно большого размера основную сложность алгоритма составляет опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Одним из самых трудоёмких шагов также оказывается сортировка таблицы.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Всюду далее считаем, что алгоритм не прекращает работу при нахождении первого совпадения, а ищет все совпадения.&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем информационный граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифровывается (Dec) на ключах &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open — открытый текст, Close — шифртекст, Enc — операция зашифрования, Dec — операция расшифрования, Cmp — операция сравнения, Keys — вычисленные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки мощности &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt;, т.е. из каждой такой вершины выходит &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; дуг. Длинных дуг в алгоритме нет.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10323</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10323"/>
		<updated>2016-10-15T15:49:07Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Свойства алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
В случае использования хэш-таблицы достаточно большого размера основную сложность алгоритма составляет опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Одним из самых трудоёмких шагов также оказывается сортировка таблицы.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Всюду далее считаем, что алгоритм не прекращает работу при нахождении первого совпадения, а ищет все совпадения.&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем информационный граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифровывается (Dec) на ключах &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open — открытый текст, Close — шифртекст, Enc — операция зашифрования, Dec — операция расшифрования, Cmp — операция сравнения, Keys — вычисленные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки мощности &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt;, т.е. из каждой такой вершины выходит &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; дуг.&lt;br /&gt;
&lt;br /&gt;
В случае нахождения всех возможных пар ключей (алгоритм продолжает работу, даже если одна из возможных пар найдена). Длинных дуг в алгоритме нет.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10312</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10312"/>
		<updated>2016-10-15T15:47:53Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Свойства алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
В случае использования хэш-таблицы достаточно большого размера основную сложность алгоритма составляет опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Одним из самых трудоёмких шагов также оказывается сортировка таблицы.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Всюду далее считаем, что алгоритм не прекращает работу при нахождении первого совпадения, а ищет все совпадения.&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем информационный граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифровывается (Dec) на ключах &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open — открытый текст, Close — шифртекст, Enc — операция зашифрования, Dec — операция расшифрования, Cmp — операция сравнения, Keys — вычисленные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки линейной мощности, т.к. из каждой такой вершины выходит &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; дуг.&lt;br /&gt;
&lt;br /&gt;
В случае нахождения всех возможных пар ключей (алгоритм продолжает работу, даже если одна из возможных пар найдена). Длинных дуг в алгоритме нет.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10273</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10273"/>
		<updated>2016-10-15T15:40:06Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Вычислительное ядро алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
В случае использования хэш-таблицы достаточно большого размера основную сложность алгоритма составляет опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Одним из самых трудоёмких шагов также оказывается сортировка таблицы.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Всюду далее считаем, что алгоритм не прекращает работу при нахождении первого совпадения, а ищет все совпадения.&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем информационный граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифровывается (Dec) на ключах &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open — открытый текст, Close — шифртекст, Enc — операция зашифрования, Dec — операция расшифрования, Cmp — операция сравнения, Keys — вычисленные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки линейной мощности, т.к. из каждой такой вершины выходит &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; дуг.&lt;br /&gt;
&lt;br /&gt;
В случае нахождения всех возможных пар ключей (алгоритм продолжает работу, даже если одна из возможных пар найдена). Длинных дуг в алгоритме нет.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10261</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10261"/>
		<updated>2016-10-15T15:37:04Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
В случае использования хэш-таблицы достаточно большого размера основную сложность алгоритма составляет опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Достаточно трудоёмкой также оказывается сортировка таблицы.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Всюду далее считаем, что алгоритм не прекращает работу при нахождении первого совпадения, а ищет все совпадения.&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем информационный граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифровывается (Dec) на ключах &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open — открытый текст, Close — шифртекст, Enc — операция зашифрования, Dec — операция расшифрования, Cmp — операция сравнения, Keys — вычисленные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки линейной мощности, т.к. из каждой такой вершины выходит &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; дуг.&lt;br /&gt;
&lt;br /&gt;
В случае нахождения всех возможных пар ключей (алгоритм продолжает работу, даже если одна из возможных пар найдена). Длинных дуг в алгоритме нет.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10246</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10246"/>
		<updated>2016-10-15T15:32:13Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Последовательная сложность алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
В случае использования хэш-таблицы достаточно большого размера основную сложность алгоритма составляет опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Достаточно трудоёмкой также оказывается сортировка таблицы.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
Всюду далее считаем, что алгоритм не прекращает работу при нахождении первого совпадения, а ищет все совпадения.&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем информационный граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифровывается (Dec) на ключе &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open — открытый текст, Close — шифртекст, Enc — операция зашифрования, Dec — операция расшифрования, Cmp — операция сравнения, Keys — вычисленные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки линейной мощности, т.к. из каждой такой вершины выходит &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; дуг.&lt;br /&gt;
&lt;br /&gt;
В случае нахождения всех возможных пар ключей (алгоритм продолжает работу, даже если одна из возможных пар найдена). Длинных дуг в алгоритме нет.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10208</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10208"/>
		<updated>2016-10-15T15:22:27Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
В случае использования хэш-таблицы достаточно большого размера основную сложность алгоритма составляет опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Достаточно трудоёмкой также оказывается сортировка таблицы.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем информационный граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифровывается (Dec) на ключе &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open — открытый текст, Close — шифртекст, Enc — операция зашифрования, Dec — операция расшифрования, Cmp — операция сравнения, Keys — вычисленные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки линейной мощности, т.к. из каждой такой вершины выходит &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; дуг.&lt;br /&gt;
&lt;br /&gt;
В случае нахождения всех возможных пар ключей (алгоритм продолжает работу, даже если одна из возможных пар найдена). Длинных дуг в алгоритме нет.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10202</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10202"/>
		<updated>2016-10-15T15:21:19Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
В случае использования хэш-таблицы достаточно большого размера основную сложность алгоритма составляет опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Достаточно трудоёмкой также оказывается сортировка таблицы.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем информационный граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифровывается (Dec) на ключе &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open - открытый текст Close — шифртекст Enc — операция зашифрования Dec — операция расшифрования, Cmp — операция сравнения, Keys — полученные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки линейной мощности, т.к. из каждой такой вершины выходит &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; дуг.&lt;br /&gt;
&lt;br /&gt;
В случае нахождения всех возможных пар ключей (алгоритм продолжает работу, даже если одна из возможных пар найдена). Длинных дуг в алгоритме нет.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10199</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10199"/>
		<updated>2016-10-15T15:20:42Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
В случае использования хэш-таблицы достаточно большого размера основную сложность алгоритма составляет опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Достаточно трудоёмкой также оказывается сортировка таблицы.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем информационный граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифруется (Dec) на ключе &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open - открытый текст Close — шифртекст Enc — операция зашифрования Dec — операция расшифрования, Cmp — операция сравнения, Keys — полученные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки линейной мощности, т.к. из каждой такой вершины выходит &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; дуг.&lt;br /&gt;
&lt;br /&gt;
В случае нахождения всех возможных пар ключей (алгоритм продолжает работу, даже если одна из возможных пар найдена). Длинных дуг в алгоритме нет.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10184</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10184"/>
		<updated>2016-10-15T15:16:21Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Схема реализации последовательного алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
В случае использования хэш-таблицы достаточно большого размера основную сложность алгоритма составляет опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Достаточно трудоёмкой также оказывается сортировка таблицы.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифруется (Dec) на ключе &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open - открытый текст Close — шифртекст Enc — операция зашифрования Dec — операция расшифрования, Cmp — операция сравнения, Keys — полученные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки линейной мощности, т.к. из каждой такой вершины выходит &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; дуг.&lt;br /&gt;
&lt;br /&gt;
В случае нахождения всех возможных пар ключей (алгоритм продолжает работу, даже если одна из возможных пар найдена). Длинных дуг в алгоритме нет.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10175</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10175"/>
		<updated>2016-10-15T15:13:41Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Вычислительное ядро алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
В случае использования хэш-таблицы достаточно большого размера основную сложность алгоритма составляет опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
Достаточно трудоёмкой также оказывается сортировка таблицы.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифруется (Dec) на ключе &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open - открытый текст Close — шифртекст Enc — операция зашифрования Dec — операция расшифрования, Cmp — операция сравнения, Keys — полученные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки линейной мощности, т.к. из каждой такой вершины выходит &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; дуг.&lt;br /&gt;
&lt;br /&gt;
В случае нахождения всех возможных пар ключей (алгоритм продолжает работу, даже если одна из возможных пар найдена). Длинных дуг в алгоритме нет.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10138</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10138"/>
		<updated>2016-10-15T15:07:21Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1^i \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2^j \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Основную сложность алгоритма составляет сортировка таблицы, полученной в результате опробования ключей. В случае использования хэш-таблицы достаточно большого размера вместо сортировки основную сложность составит опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифруется (Dec) на ключе &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open - открытый текст Close — шифртекст Enc — операция зашифрования Dec — операция расшифрования, Cmp — операция сравнения, Keys — полученные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки линейной мощности, т.к. из каждой такой вершины выходит &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; дуг.&lt;br /&gt;
&lt;br /&gt;
В случае нахождения всех возможных пар ключей (алгоритм продолжает работу, даже если одна из возможных пар найдена). Длинных дуг в алгоритме нет.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10133</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10133"/>
		<updated>2016-10-15T15:06:32Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;, а в худшем случае &amp;lt;math&amp;gt;|K_1||K_2|&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Основную сложность алгоритма составляет сортировка таблицы, полученной в результате опробования ключей. В случае использования хэш-таблицы достаточно большого размера вместо сортировки основную сложность составит опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифруется (Dec) на ключе &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open - открытый текст Close — шифртекст Enc — операция зашифрования Dec — операция расшифрования, Cmp — операция сравнения, Keys — полученные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки линейной мощности, т.к. из каждой такой вершины выходит &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; дуг.&lt;br /&gt;
&lt;br /&gt;
В случае нахождения всех возможных пар ключей (алгоритм продолжает работу, даже если одна из возможных пар найдена). Длинных дуг в алгоритме нет.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10120</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10120"/>
		<updated>2016-10-15T15:05:19Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Исходные данные:&#039;&#039;&#039; открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вычисляемые данные:&#039;&#039;&#039; ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Основную сложность алгоритма составляет сортировка таблицы, полученной в результате опробования ключей. В случае использования хэш-таблицы достаточно большого размера вместо сортировки основную сложность составит опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифруется (Dec) на ключе &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open - открытый текст Close — шифртекст Enc — операция зашифрования Dec — операция расшифрования, Cmp — операция сравнения, Keys — полученные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки линейной мощности, т.к. из каждой такой вершины выходит &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; дуг.&lt;br /&gt;
&lt;br /&gt;
В случае нахождения всех возможных пар ключей (алгоритм продолжает работу, даже если одна из возможных пар найдена). Длинных дуг в алгоритме нет.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10118</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10118"/>
		<updated>2016-10-15T15:04:32Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Математическое описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные: открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;y=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Основную сложность алгоритма составляет сортировка таблицы, полученной в результате опробования ключей. В случае использования хэш-таблицы достаточно большого размера вместо сортировки основную сложность составит опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифруется (Dec) на ключе &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open - открытый текст Close — шифртекст Enc — операция зашифрования Dec — операция расшифрования, Cmp — операция сравнения, Keys — полученные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки линейной мощности, т.к. из каждой такой вершины выходит &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; дуг.&lt;br /&gt;
&lt;br /&gt;
В случае нахождения всех возможных пар ключей (алгоритм продолжает работу, даже если одна из возможных пар найдена). Длинных дуг в алгоритме нет.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10114</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=10114"/>
		<updated>2016-10-15T15:03:18Z</updated>

		<summary type="html">&lt;p&gt;Александра: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные: открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;x=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Основную сложность алгоритма составляет сортировка таблицы, полученной в результате опробования ключей. В случае использования хэш-таблицы достаточно большого размера вместо сортировки основную сложность составит опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифруется (Dec) на ключе &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open - открытый текст Close — шифртекст Enc — операция зашифрования Dec — операция расшифрования, Cmp — операция сравнения, Keys — полученные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки линейной мощности, т.к. из каждой такой вершины выходит &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; дуг.&lt;br /&gt;
&lt;br /&gt;
В случае нахождения всех возможных пар ключей (алгоритм продолжает работу, даже если одна из возможных пар найдена). Длинных дуг в алгоритме нет.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=9697</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=9697"/>
		<updated>2016-10-15T13:29:42Z</updated>

		<summary type="html">&lt;p&gt;Александра: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
==== Блочный шифр с ключевым расписанием ====&lt;br /&gt;
==== Усложнённые шифры ====&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные: открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;x=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Основную сложность алгоритма составляет сортировка таблицы, полученной в результате опробования ключей. В случае использования хэш-таблицы достаточно большого размера вместо сортировки основную сложность составит опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифруется (Dec) на ключе &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open - открытый текст Close — шифртекст Enc — операция зашифрования Dec — операция расшифрования, Cmp — операция сравнения, Keys — полученные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки линейной мощности, т.к. из каждой такой вершины выходит &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; дуг.&lt;br /&gt;
&lt;br /&gt;
В случае нахождения всех возможных пар ключей (алгоритм продолжает работу, даже если одна из возможных пар найдена). Длинных дуг в алгоритме нет.&lt;br /&gt;
&lt;br /&gt;
== Программная реализация алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма и его реализации ===&lt;br /&gt;
&lt;br /&gt;
=== Существующие реализации алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Одна из реализаций атаки &amp;quot;встреча посередине&amp;quot; с использованием хэш-таблицы представлена в свободном доступе по ссылке [https://gist.github.com/dchest/1062437 github]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=9613</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=9613"/>
		<updated>2016-10-15T13:10:03Z</updated>

		<summary type="html">&lt;p&gt;Александра: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O(n)&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
==== Блочный шифр с ключевым расписанием ====&lt;br /&gt;
==== Усложнённые шифры ====&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные: открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;x=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Основную сложность алгоритма составляет сортировка таблицы, полученной в результате опробования ключей. В случае использования хэш-таблицы достаточно большого размера вместо сортировки основную сложность составит опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифруется (Dec) на ключе &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open - открытый текст Close — шифртекст Enc — операция зашифрования Dec — операция расшифрования, Cmp — операция сравнения, Keys — полученные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Соотношением последовательной и параллельной сложности алгоритма является &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпадает с размером ключа (на практике это сравнимые величины), а сортировка слиянием делит массивы пополам. Тогда вычислительная мощность алгоритма — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Дуги информационного графа, исходящие из вершин зашифрования и расшифрования, образуют пучки линейной мощности, т.к. из каждой такой вершины выходит &amp;lt;math&amp;gt;\frac{n}{2}&amp;lt;/math&amp;gt; дуг.&lt;br /&gt;
&lt;br /&gt;
В случае нахождения всех возможных пар ключей (алгоритм продолжает работу, даже если одна из возможных пар найдена). Длинных дуг в алгоритме нет.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=9495</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=9495"/>
		<updated>2016-10-15T12:36:19Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Свойства алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O()&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O()&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
==== Блочный шифр с ключевым расписанием ====&lt;br /&gt;
==== Усложнённые шифры ====&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные: открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;x=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Основную сложность алгоритма составляет сортировка таблицы, полученной в результате опробования ключей. В случае использования хэш-таблицы достаточно большого размера вместо сортировки основную сложность составит опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифруется (Dec) на ключе &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open - открытый текст Close — шифртекст Enc — операция зашифрования Dec — операция расшифрования, Cmp — операция сравнения, Keys — полученные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Будем считать, что размер входных данных (открытый текст и шифртекст) совпдает с размером ключа (на практике это сравнимые величины). Тогда вычислительная мощность алгоритма —&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=9324</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=9324"/>
		<updated>2016-10-15T11:44:56Z</updated>

		<summary type="html">&lt;p&gt;Александра: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O()&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O()&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
==== Блочный шифр с ключевым расписанием ====&lt;br /&gt;
==== Усложнённые шифры ====&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные: открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;x=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Основную сложность алгоритма составляет сортировка таблицы, полученной в результате опробования ключей. В случае использования хэш-таблицы достаточно большого размера вместо сортировки основную сложность составит опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифруется (Dec) на ключе &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open - открытый текст Close — шифртекст Enc — операция зашифрования Dec — операция расшифрования, Cmp — операция сравнения, Keys — полученные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
=== Свойства алгоритма ===&lt;br /&gt;
Вычислительная мощность алгоритма — &lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=9298</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=9298"/>
		<updated>2016-10-15T11:37:51Z</updated>

		<summary type="html">&lt;p&gt;Александра: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O()&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O()&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
==== Блочный шифр с ключевым расписанием ====&lt;br /&gt;
==== Усложнённые шифры ====&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные: открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;x=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Вычислительное ядро алгоритма ===&lt;br /&gt;
Основную сложность алгоритма составляет сортировка таблицы, полученной в результате опробования ключей. В случае использования хэш-таблицы достаточно большого размера вместо сортировки основную сложность составит опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из описания, атака &amp;quot;встреча посередине&amp;quot; использует (или может использовать в качестве оптимизации) следующие алгоритмы:&lt;br /&gt;
&lt;br /&gt;
1. Алгоритм зашифрования/расшифрования&lt;br /&gt;
&lt;br /&gt;
2. Алгоритм сортировки&lt;br /&gt;
&lt;br /&gt;
3. Алгоритмы поиска, вставки в хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифруется (Dec) на ключе &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open - открытый текст Close — шифртекст Enc — операция зашифрования Dec — операция расшифрования, Cmp — операция сравнения, Keys — полученные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=9218</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=9218"/>
		<updated>2016-10-15T11:11:07Z</updated>

		<summary type="html">&lt;p&gt;Александра: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O()&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O()&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
==== Блочный шифр с ключевым расписанием ====&lt;br /&gt;
==== Усложнённые шифры ====&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные: открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;x=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
Если же пара открытый текст/шифртекст определяет ключ не единственном образом, то выходом алгоритма будет некоторое множество пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;, одна из которых является истинным ключом. Для выбора истинного ключа достаточно проверить ключи из полученного множества на других парах открытый текст/шифртекст.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную сложность алгоритма составляет сортировка таблицы, полученной в результате опробования ключей. В случае использования хэш-таблицы достаточно большого размера вместо сортировки основную сложность составит опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифруется (Dec) на ключе &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open - открытый текст Close — шифртекст Enc — операция зашифрования Dec — операция расшифрования, Cmp — операция сравнения, Keys — полученные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Входные и выходные данные алгоритма ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Вход:&#039;&#039;&#039;&lt;br /&gt;
На вход подаётся открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;, а также алгоритм зашифрования/расшифрования. В случае блочного шифра открытым текстом и шифртекстом является последовательность блоков. Для атаки &amp;quot;встреча посередине&amp;quot;, как правило, берётся один блок для максимального ускорения операций зашифрования и расшифрования.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выход:&#039;&#039;&#039;&lt;br /&gt;
Результатом работы алгоритма является множество пар &amp;lt;math&amp;gt;k_1^i,k_2^j&amp;lt;/math&amp;gt;, для которых нашлись совпадения. Только одна из пар является настоящим ключом. Чтобы отсеять лишние, необходимо проверить все пары на блоках открытого и шифрованного текста, которые в алгоритме не использовались.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=9165</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=9165"/>
		<updated>2016-10-15T10:54:20Z</updated>

		<summary type="html">&lt;p&gt;Александра: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O()&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O()&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
==== Блочный шифр с ключевым расписанием ====&lt;br /&gt;
==== Усложнённые шифры ====&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные: открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;x=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную сложность алгоритма составляет сортировка таблицы, полученной в результате опробования ключей. В случае использования хэш-таблицы достаточно большого размера вместо сортировки основную сложность составит опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифруется (Dec) на ключе &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open - открытый текст Close — шифртекст Enc — операция зашифрования Dec — операция расшифрования, Cmp — операция сравнения, Keys — полученные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются выполнение следующих двух ярусов (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;\sqrt n&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
Таким образом, высота ЯПФ составляет 2, ширина - &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=9126</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=9126"/>
		<updated>2016-10-15T10:45:18Z</updated>

		<summary type="html">&lt;p&gt;Александра: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O()&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O()&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
==== Блочный шифр с ключевым расписанием ====&lt;br /&gt;
==== Усложнённые шифры ====&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные: открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;x=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную сложность алгоритма составляет сортировка таблицы, полученной в результате опробования ключей. В случае использования хэш-таблицы достаточно большого размера вместо сортировки основную сложность составит опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключах &amp;lt;math&amp;gt;k_1^i&amp;lt;/math&amp;gt;, а зашифрованный расшифруется (Dec) на ключе &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open - открытый текст Close — шифртекст Enc — операция зашифрования Dec — операция расшифрования, Cmp — операция сравнения, Keys — полученные ключи]]&lt;br /&gt;
&lt;br /&gt;
=== Ресурс параллелизма алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Как видно из информационного графа, для реализации атаки &amp;quot;встреча посередине&amp;quot; в параллельном варианте потребуются следующие шаги (в предположении, что &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
1. &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt; зашифрований и столько же расшифрований&lt;br /&gt;
&lt;br /&gt;
2. &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; сравнений&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=9007</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=9007"/>
		<updated>2016-10-15T10:23:43Z</updated>

		<summary type="html">&lt;p&gt;Александра: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O()&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O()&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
==== Блочный шифр с ключевым расписанием ====&lt;br /&gt;
==== Усложнённые шифры ====&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные: открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;x=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную сложность алгоритма составляет сортировка таблицы, полученной в результате опробования ключей. В случае использования хэш-таблицы достаточно большого размера вместо сортировки основную сложность составит опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется (Enc) на ключе &amp;lt;math&amp;gt;k_1&amp;lt;/math&amp;gt;, а зашифрованный расшифруется (Dec) на ключе &amp;lt;math&amp;gt;k_2&amp;lt;/math&amp;gt;. Далее полученные криптограммы сравниваются (Cmp) и все ключи, на которых они совпали, являются выходом алгоритма.&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open - открытый текст Close — шифртекст Enc — операция зашифрования Dec — операция расшифрования, Cmp — операция сравнения, Keys — полученные ключи]]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=8993</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=8993"/>
		<updated>2016-10-15T10:19:48Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O()&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O()&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
==== Блочный шифр с ключевым расписанием ====&lt;br /&gt;
==== Усложнённые шифры ====&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные: открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;x=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную сложность алгоритма составляет сортировка таблицы, полученной в результате опробования ключей. В случае использования хэш-таблицы достаточно большого размера вместо сортировки основную сложность составит опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
Опишем граф алгоритма. На вход подаётся открытый (Open) и закрытый (Close), т.е. зашифрованный, текст. Далее открытый текст шифруется на &lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open - открытый текст Close — шифртекст Enc — операция зашифрования Dec — операция расшифрования, Cmp — операция сравнения, Keys — полученные ключи]]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=7986</id>
		<title>Участница:Александра/Метод встречи посередине</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D1%86%D0%B0:%D0%90%D0%BB%D0%B5%D0%BA%D1%81%D0%B0%D0%BD%D0%B4%D1%80%D0%B0/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D0%B2%D1%81%D1%82%D1%80%D0%B5%D1%87%D0%B8_%D0%BF%D0%BE%D1%81%D0%B5%D1%80%D0%B5%D0%B4%D0%B8%D0%BD%D0%B5&amp;diff=7986"/>
		<updated>2016-10-14T19:12:52Z</updated>

		<summary type="html">&lt;p&gt;Александра: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{algorithm&lt;br /&gt;
| name              = Метод встречи посередине&lt;br /&gt;
| serial_complexity = &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_height         = &amp;lt;math&amp;gt;O()&amp;lt;/math&amp;gt;&lt;br /&gt;
| pf_width          = &amp;lt;math&amp;gt;O()&amp;lt;/math&amp;gt;&lt;br /&gt;
| output_data       = &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Автор описания: [[Участник:Александра|А.В.Батарина]]&lt;br /&gt;
&lt;br /&gt;
== Свойства и структура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
=== Общее описание алгоритма ===&lt;br /&gt;
Метод &amp;quot;Встреча посередине&amp;quot; криптоанализа блочных шифров был впервые предложен в 1977 году Уитфилдом Диффи и Мартином Хеллманом &amp;lt;ref&amp;gt;(June 1977) «Exhaustive Cryptanalysis of the NBS Data Encryption Standard». Computer 10 (6): 74–84. DOI:10.1109/C-M.1977.217750&amp;lt;/ref&amp;gt;. Встреча посередине используется для ускорения перебора ключей шифра за счёт увеличения требуемой памяти. Метод применим в случае каскадного построения сложного шифра из нескольких простых, другими словами, в случае последовательного применения шифрующих преобразований на разных ключах к блокам открытого текста.&lt;br /&gt;
==== Блочный шифр с ключевым расписанием ====&lt;br /&gt;
==== Усложнённые шифры ====&lt;br /&gt;
В качестве примера шифра, поддающегося атаке &amp;quot;встреча посередине&amp;quot; можно привести криптоалгоритм 2DES, являющийся модификацией шифра DES. В 2DES открытый текст шифруется дважды алгоритмом DES на двух разных 56-битных ключах. Однако из-за атаки &amp;quot;встреча посередине&amp;quot; сложность перебора двойного ключа (112 бит) шифра 2DES составляет &amp;lt;math&amp;gt;2^{57}&amp;lt;/math&amp;gt; вместо ожидаемых &amp;lt;math&amp;gt;2^{112}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Математическое описание алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Исходные данные: открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt;, шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Алгоритм зашифрования — композиция двух преобразований &amp;lt;math&amp;gt;T_1(x,k_1)&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;T_2(x,k_2)&amp;lt;/math&amp;gt;, т.е. &amp;lt;math&amp;gt;y=T_2(T_1(x,k_1),k_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм расшифрования — &amp;lt;math&amp;gt;x=T_1^{-1}(T_2^{-1}(x,k_2),k_1)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: ключи шифрования &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;, где &amp;lt;math&amp;gt;K_1, K_2&amp;lt;/math&amp;gt; — множества возможных ключей.&lt;br /&gt;
&lt;br /&gt;
Трудоёмкость полного перебора всех возможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; составляет в среднем &amp;lt;math&amp;gt;\frac{|K_1||K_2|}{2}&amp;lt;/math&amp;gt;. Однако используя дополнительную память, можно сократить перебор.&lt;br /&gt;
&lt;br /&gt;
Предположим, что открытый текст &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; и шифртекст &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; однозначно определяют ключи &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;. Составим две таблицы:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
z_1 &amp;amp; =T_1(x,k_1^1) &amp;amp; z_1^&#039; &amp;amp;=T_2^{-1}(x,k_2^1)\\\\&lt;br /&gt;
z_2 &amp;amp; =T_1(x,k_1^2) &amp;amp; z_2^&#039; &amp;amp; =T_2^{-1}(x,k_2^2)\\&lt;br /&gt;
... &amp;amp; .................  &amp;amp; ... &amp;amp; .................... \\&lt;br /&gt;
z_{|K_1|} &amp;amp; =T_1(x,k_1^{|K_1|}) &amp;amp; z_{|K_1|}^&#039; &amp;amp; =T_2^{-1}(x,k_2^{|K_1|})&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для всех &amp;lt;math&amp;gt;k_1 \in K_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;k_2 \in K_2&amp;lt;/math&amp;gt;. Далее таблицы объединяются и сортируются по значениям &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt;. Индексы &amp;lt;math&amp;gt;i,j&amp;lt;/math&amp;gt;, при которых &amp;lt;math&amp;gt;z_i=z_j^&#039;&amp;lt;/math&amp;gt;, однозначно определяют искомую пару ключей &amp;lt;math&amp;gt;k_1=k_1^i,k_2=k_2^j&amp;lt;/math&amp;gt;. Для нахождения такой пары достаточно просмотреть отсортированную таблицу один раз.&lt;br /&gt;
&lt;br /&gt;
==== Оптимизации ====&lt;br /&gt;
&lt;br /&gt;
1. От генерации второй таблицы со значениями &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; можно отказаться, перебирая ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; до того момента, когда значение &amp;lt;math&amp;gt;z_j^&#039;&amp;lt;/math&amp;gt; совпадёт с одним из значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. В таком случае опробование ключей &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt; в среднем сократится вдвое. Также вдвое сократится объём используемой памяти. Для нахождения совпадающего значения в отсортированном массиве можно применить бинарный поиск.&lt;br /&gt;
&lt;br /&gt;
2. Вместо сортировки таблицы со значениями &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt; и последующего бинарного поиска можно использовать хэш-таблицу.&lt;br /&gt;
&lt;br /&gt;
=== Макроструктура алгоритма ===&lt;br /&gt;
Основную сложность алгоритма составляет сортировка таблицы, полученной в результате опробования ключей. В случае использования хэш-таблицы достаточно большого размера вместо сортировки основную сложность составит опробование ключей &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Схема реализации последовательного алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Далее приводится последовательность действий для варианта алгоритма с генерацией одной таблицы значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
1. Вычислить таблицу &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;, записывая значения в порядке вычисления или используя хэш-таблицу&lt;br /&gt;
&lt;br /&gt;
2. В случае записи значений в порядке вычисления отсортировать массив&lt;br /&gt;
&lt;br /&gt;
3. Опробовать ключи &amp;lt;math&amp;gt;k_2^j&amp;lt;/math&amp;gt;, ища совпадения с таблицей значений &amp;lt;math&amp;gt;z_i&amp;lt;/math&amp;gt;. Для нахождения совпадения использовать поиск по хэш-таблице (если она есть) или бинарный поиск&lt;br /&gt;
&lt;br /&gt;
=== Последовательная сложность алгоритма ===&lt;br /&gt;
&lt;br /&gt;
1. Сложность вычисления таблиц значений &amp;lt;math&amp;gt;z_i,z_j^&#039;&amp;lt;/math&amp;gt; составит &amp;lt;math&amp;gt;O(|K_1|+|K_2|)&amp;lt;/math&amp;gt; операций опробования &lt;br /&gt;
&lt;br /&gt;
2. Объединение таблиц и их сортировка будет иметь сложность &amp;lt;math&amp;gt;O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt; (например, при сортировке слиянием).&lt;br /&gt;
&lt;br /&gt;
3. Сложность бинарного поиска в отсортированном массиве — &amp;lt;math&amp;gt;O(log_2(|K_1|))&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
4. Сложность поиска в достаточно большой хэш-таблице составит &amp;lt;math&amp;gt;O(1)&amp;lt;/math&amp;gt; для каждого поиска&lt;br /&gt;
&lt;br /&gt;
Итого асимптотическая сложность алгоритма:&lt;br /&gt;
&lt;br /&gt;
1. С генерацией двух таблиц — &amp;lt;math&amp;gt;O(|K_1|+|K_2|) + O((|K_1|+|K_2|)\log(|K_1|+|K_2|)) + O(|K_1|+|K_2|)=O((|K_1|+|K_2|)\log(|K_1|+|K_2|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. C генерацией одной таблицы, сортировкой и бинарным поиском — &amp;lt;math&amp;gt;O(|K_1|) + O((|K_1|)\log(|K_1|)) + O(|K_2|\log_2(|K_1|))=O(max(|K_1|,|K_2|)\log(|K_1|))&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. C генерацией одной (достаточно большой) хэш-таблицы — &amp;lt;math&amp;gt;O(|K_1|) + O(|K_2|)=O(|K_1|+|K_2|)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Пусть n - количество всевозможных пар &amp;lt;math&amp;gt;k_1,k_2&amp;lt;/math&amp;gt; и пусть &amp;lt;math&amp;gt;|K_1|=|K_2|&amp;lt;/math&amp;gt;. В этом случае &amp;lt;math&amp;gt;|K_1|=|K_2|=\sqrt n&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
Тогда сложность алгоритма в первых двух пунктах составляет &amp;lt;math&amp;gt;O(\sqrt n\log(n))&amp;lt;/math&amp;gt;, в третьем — &amp;lt;math&amp;gt;O(\sqrt n)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Информационный граф ===&lt;br /&gt;
&lt;br /&gt;
[[file:meet.png|thumb|center|1040px|Рисунок 1. Граф алгоритма c отображением входных и выходных данных. Open - открытый текст Close - шифртекст Enc - операция зашифрования Dec - операция расшифрования, Cmp - операция сравнения, Keys - полученные ключи]]&lt;br /&gt;
&lt;br /&gt;
== Литература ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references \&amp;gt;&lt;/div&gt;</summary>
		<author><name>Александра</name></author>
	</entry>
</feed>