Тема 0

Подготовка: карта курса, математика и инструменты

Подготовка: карта курса, математика и инструменты

Курс начинается не с шифров, а с вопроса, на который шифры отвечают: от чего именно защищаемся, какими свойствами описывается защита и какими механизмами эти свойства достигаются. Пропустить этот шаг соблазнительно — кажется, что достаточно выучить AES и RSA, — но тогда любая задача сводится к «применим проверенный алгоритм», а ошибки возникают именно на стыках: свойство выбрано не то, примитив применён вне модели стойкости, ключ хранится неправильно. Тема собирает эти стыки в одну линию и даёт минимальный аппарат, на котором держится остальной курс.

Вторая задача темы — выровнять подготовку. Читателю нужны вероятность на уровне «что такое условная вероятность», логарифмы, представление о группах и кольцах, уверенное обращение с байтами в Python и командной строкой. Всё это обычно изучалось, но по частям и без привязки к криптографии; здесь оно повторяется в том объёме и с той точки зрения, в какой понадобится в темах 2–16. Математических доказательств нет — только определения, примеры и правила чтения оценок сложности.

Третья задача — договориться об обозначениях. В криптографической литературе одну и ту же величину записывают по-разному, и расхождения в формулах стойкости приводят к путанице: «преимущество 1/2» в одной книге и «преимущество 1» в другой описывают одно и то же. Курс фиксирует единые конвенции один раз, и дальше все темы им следуют.

Паспорт темы. Нужно знать: программирование на Python, школьную математику, базовую командную строку Linux. Освоите: читать карту курса и определять, какая тема нужна для задачи; оценивать сложность перебора в степенях двойки и переводить её в реальные ресурсы; свободно переходить между строками, байтами и целыми числами; проверять версии инструментов и настраивать изолированную среду; пользоваться едиными обозначениями курса. Проверяет: ЛР 0.

Карта курса

От угрозы к реализации

Любая криптографическая подсистема строится сверху вниз, и каждый уровень отвечает на свой вопрос. Схема ниже показывает эту линию; дальше она разбирается по шагам.

Линия проектирования криптографической подсистемы
Каждый уровень опирается на предыдущий: свойство нельзя достичь примитивом, который его не обеспечивает, а примитив бесполезен при неправильном управлении ключами

Первый уровень — модель угрозы: кто противник, что у него есть, к чему он имеет доступ. Противник, читающий только сетевой трафик, и противник, выполняющий код на той же машине, — это разные задачи с разными решениями. Модель угрозы фиксируется до выбора алгоритмов, иначе выбор нечем обосновать.

Второй уровень — свойство безопасности: конфиденциальность, целостность, аутентичность, неотрекаемость, свежесть, защита метаданных. Свойства формулируются отдельно от механизмов: «никто, кроме получателя, не может прочитать содержимое» — это свойство, а AES-GCM — один из способов его достичь. Тема 2 даёт формальные определения, включая то, что означает «не может» при ограниченных ресурсах противника.

Третий уровень — примитив: блочный шифр, хеш-функция, код аутентификации сообщений, функция выработки ключей, схема с открытым ключом. У примитива есть своё свойство стойкости (псевдослучайная перестановка, стойкость к коллизиям, стойкость к подделке), и оно не совпадает со свойством системы. AES-128 как псевдослучайная перестановка стоек; AES-128 в режиме ECB в системе с повторяющимися блоками — нет. Это различие между свойством примитива и свойством протокола — одна из главных идей курса.

Четвёртый уровень — режим или протокол: как примитив применяется к данным и как стороны договариваются о ключах. Режим задаёт требования к одноразовому числу, протокол — к порядку сообщений и аутентификации сторон. Ошибки этого уровня встречаются в реальных системах чаще всего 5: повтор nonce, отсутствие проверки целостности до расшифрования, понижение версии протокола.

Пятый уровень — реализация: библиотека, вызов API, обработка ошибок, время выполнения. Схема, стойкая в модели, может утекать ключ через время сравнения тегов (тема 9) или через ветвление в зависимости от секрета (тема 6). Реализация — не «последняя миля», а полноценный уровень, на котором ломаются корректные конструкции.

Шестой уровень — управление ключами: генерация, хранение, ротация, уничтожение, разделение по назначению. Ключ, лежащий в репозитории, обнуляет стойкость всех шести предыдущих уровней 3. Тема 10 посвящена этой части целиком, но упоминания о ней встречаются во всех темах, где появляется ключ.

Обратное движение по этой линии — диагностика. Если система сломалась, вопрос задаётся в обратном порядке: не «какой алгоритм виноват», а «какое свойство не выполнялось, в какой модели, на каком уровне».

Свойства и примитивы

Таблица связывает свойства безопасности с примитивами, которые их обеспечивают, и с темами, где они разбираются. Это не меню: одно свойство обычно требует нескольких механизмов, а один механизм редко даёт больше одного свойства.

СвойствоЧто означаетОсновные механизмыТемы
КонфиденциальностьПротивник не узнаёт содержимоеШифры, режимы, AEAD5–7, 11–13
ЦелостностьИзменение данных обнаруживаетсяХеши, MAC, AEAD, подписи8, 9, 12–14
Аутентичность источникаДанные создал владелец ключаMAC, AEAD, подписи9, 12–15
НеотрекаемостьАвтор не может отказатьсяЦифровая подпись, PKI, метки времени14
СвежестьСтарое сообщение не выдаётся за новоеNonce, счётчики, метки времени, протокол7, 9, 15
Защита метаданныхСкрыты не только данные, но и факт обменаСпециальные протоколы, заполнение трафика15

Практический вывод, который стоит запомнить до темы 9: конфиденциальность без целостности почти всегда обесценивается. Шифр, не обнаруживающий изменений, позволяет противнику управлять расшифрованием, а ошибки расшифрования превращаются в оракул. Поэтому в новых системах выбирают аутентифицированное шифрование, а не «шифр плюс отдельный MAC, собранные вручную» 4.

Зависимости тем

Порядок тем не произвольный: каждая опирается на предыдущие. Схема ниже — карта зависимостей; сплошная стрелка означает «без этой темы текст не читается», пунктирная — «понадобится пример или обозначение».

Карта зависимостей тем курса
Основы (1–4) обслуживают всю симметричную часть; математика темы 4 нужна для 11–13; протоколы 15 собирают всё предыдущее

Из карты видны две вещи. Во-первых, тема 4 (математика) — единственная, которая нужна далеко вперёд: без неё не читаются темы 11–13, но она не нужна для 5–10. Во-вторых, тема 9 (MAC и AEAD) — узел, через который проходят и симметричная часть, и протоколы: TLS 1.3 в теме 15 целиком построен на AEAD и HKDF.

Минимальная траектория, дающая цельную картину без углубления в асимметричную математику: темы 0, 1, 2, 3, 6, 7, 8, 9, 10, 15. Она пропускает поточные шифры, RSA, эллиптические кривые и PKI — то есть всё, что нужно для понимания TLS изнутри, но достаточно, чтобы правильно применять библиотеки и читать стандарты.

Вероятность, логарифмы и сложность

События и условная вероятность

Вероятностное пространство — это множество исходов Ω, семейство событий и функция P, сопоставляющая событию число от 0 до 1. В криптографии исходы почти всегда дискретны: монета экспериментатора, случайный ключ, случайный nonce. Равномерное распределение на множестве из N элементов даёт каждому исходу вероятность 1/N.

Условная вероятность P(A | B) — доля исходов A среди исходов B:

P(A | B) = P(A ∩ B) / P(B),   P(B) > 0

Из неё выводится формула Байеса, которой в криптоанализе пользуются постоянно: она показывает, как наблюдение меняет уверенность в гипотезе:

P(M = m \mid C = c) = \frac{P(C = c \mid M = m) \cdot P(M = m)}{P(C = c)}

Совершенная секретность (тема 2) — это в точности утверждение, что P(M = m \mid C = c) = P(M = m): наблюдение шифртекста не меняет апостериорных вероятностей. События A и B независимы, если P(A \cap B) = P(A) \cdot P(B); для криптографии важно, что детерминированное шифрование делает шифртекст зависимым от открытого текста, а хорошая рандомизация — нет.

Отдельно понадобится парадокс дней рождения. Если выбирать случайные значения из N равновероятных, то первое совпадение ожидается примерно после 1,18 · √N выборок, а не после N/2. Для N = 2^128 это ≈ 2^64 — отсюда оценки стойкости хеш-функций к коллизиям вдвое ниже длины дайджеста (тема 8). Вывод формулы — в дополнительных материалах темы; здесь важен сам порядок величины.

Степени двойки и логарифмы

Сложность криптографических атак измеряется числом операций и записывается степенью двойки: 2^80, 2^128, 2^256. Такая запись удобна, потому что каждое прибавление единицы к показателю удваивает работу. Логарифм по основанию два — обратная операция: log₂(2^80) = 80. Отсюда два правила перевода, которые нужны постоянно:

  • число операций 2^b при производительности S операций в секунду выполняется за 2^b / S секунд;
  • при удвоении производительности срок уменьшается вдвое, то есть выигрывается ровно один бит стойкости.

Полезные приближения: 2^10 ≈ 10^3, 2^20 ≈ 10^6, 2^30 ≈ 10^9, 2^40 ≈ 10^12, 2^50 ≈ 10^15. Год — примерно 3,15 · 10^7 секунд, то есть 2^25 секунд. Значит, 2^64 операций при 10^9 операций в секунду — это 2^64 / 2^30 = 2^34 секунд, около 584 лет.

Проверим на числах и заодно обсудим, чего такие оценки стоят. Пусть перебор ключа идёт со скоростью 10^9 проверок в секунду на одном ядре — это порядок, достигаемый специализированным оборудованием для симметричных ключей и недостижимый для честной программной проверки пароля. Тогда:

КлючОперацийВремя при 10^9/сВремя при 10^15/с
40 бит2^40≈ 18 минут≈ 1 секунда
56 бит2^56≈ 2,3 года≈ 20 часов
64 бита2^64≈ 584 года≈ 213 дней
80 бит2^80≈ 3,8 · 10^7 лет≈ 38 000 лет
128 бит2^128≈ 10^22 лет≈ 10^19 лет

Оценки в таблице — арифметика, а не прогноз: они предполагают, что каждая операция стоит одинаково, что противник использует только перебор и что оборудование не меняется. Для реальной оценки нужны дата, источник и модель оборудования, поэтому в курсе количественные утверждения всегда сопровождаются этими тремя элементами, а формулировка «оценка» означает именно оценку, а не гарантию. Возраст Вселенной — около 1,4 · 10^10 лет, и уже 2^80 при такой модели выходит за него с большим запасом; именно поэтому 80-битная стойкость считается недостаточной для долгоживущих секретов (тема 2) 7.

Асимптотика и пренебрежимо малые величины

В теоретической криптографии стойкость формулируется асимптотически: есть параметр безопасности λ (обычно длина ключа), и противник считается эффективным, если его время работы ограничено многочленом от λ. Функция μ(λ) пренебрежимо мала 1, если она убывает быстрее любой обратной степени многочлена: для любого многочлена p и всех достаточно больших λ выполнено μ(λ) < 1/p(λ). Например, 2^(-λ) пренебрежимо мала, а 1/λ^10 — нет, хотя при λ = 128 второе число астрономически мало.

Практика и асимптотика расходятся, и это нужно держать в голове. «Стойкость доказана» в статье обычно означает: если задача X трудна, то схема стойка, причём сведение даёт конкретную оценку потерь. Сведение может быть корректным, но настолько слабым, что для реальных параметров ничего не говорит: типичная формулировка «преимущество противника не превосходит преимущества в решении задачи X, умноженного на q², где q — число запросов» при миллионе запросов даёт множитель 10^12. Поэтому в курсе различаются три утверждения: «атака известна», «атака практически применима при таких-то параметрах» и «схема стойка в модели при таком-то предположении». Первое не означает второго, второе не опровергает третьего.

Полиномиальные алгоритмы — те, чьё время растёт как O(n^k); экспоненциальные — как O(2^(c·n)). Разница принципиальна: удвоение входа у полиномиального алгоритма увеличивает время в константу раз, у экспоненциального — возводит сложность в квадрат. Отсюда смысл «уровня стойкости в битах»: это b в записи 2^b, а не длина ключа. Для AES-128 уровень стойкости 128 бит; для RSA-3072 — около 128 бит, хотя ключ в 24 раза длиннее; для ECDSA на P-256 — около 128 бит при ключе 256 бит. Таблица соответствий — в теме 2, а причины расхождения — в темах 12 и 13.

Множества, отображения и алгебраические структуры

Отображения и перестановки

Отображение (функция) f: X → Y сопоставляет каждому элементу X элемент Y. Оно инъективно, если разные входы дают разные выходы; сюръективно, если каждый элемент Y достигается; биективно, если выполнено и то и другое. Биекция на конечном множестве — это перестановка: взаимно однозначное соответствие множества с самим собой.

Понятие перестановки — не абстракция, а рабочий инструмент. Блочный шифр с блоком n бит при фиксированном ключе задаёт перестановку на множестве из 2^n строк: каждому открытому блоку соответствует ровно один шифртекст, и обратно. Стойкость блочного шифра формулируется как неотличимость этой перестановки от случайной (тема 6). Атака, находящая два блока с одинаковым шифртекстом в режиме ECB, эксплуатирует как раз то, что перестановка детерминирована.

Мощность множества |X| — число элементов. Для криптографии она равна числу возможных ключей, и именно она стоит в показателе стойкости: ключ длиной k бит даёт |K| = 2^k, а полный перебор требует порядка 2^k попыток. Оценка «порядка», а не «ровно», важна: среднее число попыток равно половине пространства, а константа не влияет на битовую оценку.

Операции и структуры

Бинарная операция на множестве G — правило, сопоставляющее двум элементам третий. Операция замкнута, если результат всегда лежит в G; ассоциативна, если (a·b)·c = a·(b·c); коммутативна, если a·b = b·a. Нейтральный элемент e не меняет ничего: a·e = e·a = a. Обратный к a — такой a⁻¹, что a·a⁻¹ = e.

Из этих свойств складываются структуры 6, и различать их нужно потому, что разные криптографические задачи живут в разных структурах.

СтруктураТребованияПримерГде в курсе
ГруппаЗамкнутость, ассоциативность, нейтральный, обратныйZ_n по сложению; Z_p* по умножению; точки эллиптической кривой4, 11–13
Абелева группаГруппа с коммутативностьюZ_p*, группа точек кривой11–13
КольцоАбелева группа по сложению, замкнутое ассоциативное умножение, дистрибутивностьZ_n, многочлены4, 6
ПолеКольцо, где каждый ненулевой элемент обратимGF(p), GF(2^8)4, 6, 13

Z_n — целые числа по модулю n; Z_p* — ненулевые остатки по простому модулю p, они образуют группу по умножению. В GF(2^8), на котором построен AES, сложение — побитовый XOR, а умножение определено по модулю неприводимого многочлена; это поле, а не кольцо, потому что каждый ненулевой байт имеет обратный. Точки эллиптической кривой образуют группу, но не кольцо: умножать точку на точку в схеме не нужно и не определено.

Порядок группы — число её элементов; порядок элемента g — наименьшее k, при котором g^k = e. Теорема Лагранжа утверждает, что порядок элемента делит порядок группы; отсюда следует малая теорема Ферма a^(p−1) ≡ 1 (mod p) для простого p и теорема Эйлера для составного модуля (тема 4). Если порядок элемента равен порядку группы, элемент называется образующим, а группа — циклической. Проверим на Z_7*:

Z_7* = {1, 2, 3, 4, 5, 6},  |Z_7*| = 6
ord(2) = 3:  2, 4, 1
ord(3) = 6:  3, 2, 6, 4, 5, 1   → 3 — образующий
ord(6) = 2:  6, 1

Порядки 3, 6 и 2 делят 6 — как и обещает теорема Лагранжа. Цикличность Z_p* при простом p — фундаментальный факт, на котором держится Диффи — Хеллман: образующий элемент позволяет записать любой ненулевой остаток как степень, и задача дискретного логарифма состоит в обратном восстановлении показателя (тема 11).

Python: байты, кодировки и числа

Строки и байты — разные типы

В Python 3 строка (str) — последовательность символов Unicode, а bytes — последовательность байтов 11. Криптография работает только с байтами: ключ, nonce, шифртекст, тег — всё это последовательности октетов. Смешение типов — источник половины ошибок в учебном коде: len("ёж") равно 2, а len("ёж".encode("utf-8")) — 4, потому что каждая буква занимает два байта (RFC 3629) 8.

text = "ёж"
raw = text.encode("utf-8")
print(len(text), len(raw), raw.hex())      # 2 4 d191d0b6
print(raw.decode("utf-8"))                 # ёж
print(b"\xd1\x91".decode("utf-8"))         # ё

Схема ниже показывает, как одно и то же содержимое выглядит на четырёх уровнях: символы, кодовая точка, байты UTF-8 и текстовое представление в hex или base64.

Уровни представления данных
Кодировка — правило перевода кодовых точек в байты; hex и base64 — способы записать байты текстом, они не меняют данные

Три правила, которые снимают большинство проблем. Первое: граница между текстом и байтами проходит на входе и выходе, внутри всё в байтах. Второе: кодировка указывается явно, encode("utf-8"), а не по умолчанию, — иначе поведение зависит от локали. Третье: нельзя резать многобайтовую последовательность по произвольному индексу; разрезанный UTF-8 даёт ошибку декодирования, а не «почти правильный» текст.

Отдельный сюжет — нормализация Unicode. Символ «ё» можно записать одной кодовой точкой или как «е» плюс комбинирующее двоеточие; визуально строки совпадают, побайтово — нет. Для криптографии это значит, что два пароля, которые человек считает одинаковыми, дают разные хеши. Поэтому при работе с паролями и именами применяют нормализацию (NFC или NFKC) до хеширования — и фиксируют это в спецификации (тема 10).

Целые числа, hex и base64

Целые в Python не ограничены разрядностью: 2**256 — обычное число, и это делает язык удобным для учебных реализаций RSA и эллиптических кривых. Перевод между байтами и числом задаётся явно:

n = int.from_bytes(bytes.fromhex("00ff10"), "big")   # 65296
n.to_bytes(4, "big").hex()                            # 0000ff10
(2**256 - 1).bit_length()                             # 256

Порядок байтов (big или little) — часть формата, а не деталь реализации: несовпадение даёт «работающий» код, который обменивается мусором с другой системой. В криптографических стандартах порядок всегда указан; в учебном коде его фиксируют константой и не меняют по ходу.

Hex и base64 — кодировки «байты в текст», нужные для печати, конфигураций и JSON. Hex представляет каждый байт двумя символами; base64 упаковывает три байта в четыре символа (RFC 4648) 9. Ни та, ни другая не являются шифрованием: обратное преобразование выполняет любой, у кого есть таблица. Строка U2VjcmV0 — это «Secret» в base64, а не секрет.

Хеширование как инструмент разработчика

hashlib даёт доступ к криптографическим хеш-функциям. В подготовительной теме он нужен в трёх ролях: посчитать контрольную сумму файла, получить короткий идентификатор данных, сравнить две последовательности без утечки по времени.

import hashlib
digest = hashlib.sha256(b"example").hexdigest()
print(len(digest), digest[:16])     # 64 50ed8a3c...

Хеш — не шифрование: из дайджеста нельзя восстановить вход, но и секрета в нём нет, если вход известен или подбирается. Свойства хеш-функций, атаки на них и различие между «хеш для целостности» и «MAC для аутентичности» разбираются в темах 8 и 9; в подготовке достаточно запомнить, что sha256 возвращает 32 байта, а hexdigest — их текстовое представление в 64 символа.

Linux, OpenSSL и рабочая среда

Командная строка и обращение с файлами

Лабораторные работы выполняются в терминале Linux. Минимальный набор, который понадобится: переходы по каталогам, просмотр файлов, перенаправление вывода, конвейеры и права доступа. Последнее важнее, чем кажется: файл с закрытым ключом должен быть доступен только владельцу.

umask 077                                  # новые файлы — только для владельца
openssl genpkey -algorithm ED25519 -out key.pem
ls -l key.pem                              # -rw------- 1 user user
chmod 600 key.pem
xxd -l 32 key.pem                          # первые байты: PEM-заголовок

umask 077 снимает права группы и остальных с создаваемых файлов; chmod 600 делает то же для существующего. xxd показывает байты — полезно, когда нужно убедиться, что файл действительно бинарный или, наоборот, текстовый PEM.

OpenSSL: что чем является

OpenSSL — одновременно библиотека, набор утилит и провайдер алгоритмов 10. В курсе он используется как инструмент командной строки и как эталон для сверки учебных реализаций. Полезно с первого дня различать подкоманды по назначению.

openssl version -a
openssl list -digest-algorithms | head
openssl list -cipher-algorithms | head
openssl rand -hex 16
openssl dgst -sha256 file.bin

version показывает версию и сборку; list — доступные алгоритмы, и это первый запрос при любой ошибке «algorithm not found». rand выдаёт случайные байты из CSPRNG системы (тема 3), dgst считает хеш. Отдельно стоит запомнить, что openssl enc — учебная команда с паролем и слабым наследованием параметров; в новых системах её не применяют, а для аутентифицированного шифрования используют openssl enc -aes-256-gcm с явными параметрами или библиотеку cryptography (темы 7 и 9).

Схема ниже показывает уровни инструментов: приложение вызывает библиотеку, библиотека — провайдер, провайдер — инструкции процессора или программную реализацию. Когда «AES медленный», вопрос обычно не в алгоритме, а в том, используется ли аппаратное ускорение.

Уровни инструментов и место OpenSSL
Один и тот же вызов библиотеки может попасть в разные реализации; отсюда расхождения в скорости и в поддерживаемых алгоритмах

Изолированная среда

Лабораторные работы включают атаки, поэтому среда должна быть отделена от рабочих данных. Достаточно виртуальной машины со снимком: перед экспериментом снимок делается, после — откатывается. Сетевые учебные сервисы слушают только 127.0.0.1, то есть недоступны снаружи машины. Внешняя сеть нужна лишь для установки пакетов и для необязательных частей отдельных работ.

Правовая рамка упоминается один раз, в этой теме: несанкционированный доступ к чужой информации и вредоносные программы преследуются по закону (статьи 272–274 УК РФ). Все задания курса выполняются против учебных объектов из окружений — собственных программ, локальных серверов и заранее сгенерированных данных. Это не ограничение учебной ценности: атака на собственную реализацию демонстрирует ровно тот механизм, который встретится в чужом коде.

Версии инструментов фиксируются, потому что поведение зависит от них: в Ubuntu 24.04 стоит OpenSSL 3.0, в котором нет ML-KEM и гибридных групп, а в cryptography до версии 44 нет Argon2id. В курсе такие места помечаются явно: «на OpenSSL 3.5 и новее», «в cryptography 44 и новее». Проверка версии — первая команда в лабораторной работе.

python3 -c "import sys, cryptography; print(sys.version); print(cryptography.__version__)"
openssl version

Обозначения и конвенции

Запись формул

Курс использует единую систему математических обозначений во всех темах. Противник обозначается A, схема — \Pi, оракул — \mathcal{O}, параметр безопасности — \lambda, вероятность — P, преимущество — \text{Adv}. Ключи и сообщения — строчные буквы (k, m, c), пространства — каллиграфическими или заглавными (\mathcal{K}, \mathcal{M}, \mathcal{C}). Математические формулы верстаются средствами LaTeX:

c = \text{Enc}(k, m), \qquad m = \text{Dec}(k, c)

\Pr[\text{Exp}(\Pi, A, \lambda) = 1] = \frac{1}{2} + \varepsilon

Запись \text{Enc}(k, m) означает шифрование сообщения m ключом k; \text{Enc} и \text{Dec} — алгоритмы схемы, а не конкретный шифр. Такая нотация позволяет говорить о схеме вообще, не привязываясь к AES или RSA.

Преимущество противника

В играх неразличимости противник угадывает бит b, выбранный экспериментатором. Если бы он угадывал случайно, вероятность успеха была бы 1/2. Преимущество измеряет, насколько он лучше случайного угадывания:

\text{Adv} = \big|2 \cdot P(\text{успех}) - 1\big|

Множитель два выбран намеренно: при таком определении \text{Adv} лежит в отрезке от 0 до 1, а величина \text{Adv} = 1 означает, что противник угадывает всегда. Ту же величину можно записать через вероятности ответов в двух экспериментах: \text{Adv} = |P(A \to 1 \mid b = 1) - P(A \to 1 \mid b = 0)| — оба выражения равны 12. В литературе встречается запись без множителя, |P(\text{успех}) - 1/2|; это та же величина, делённая на два, и путать их нельзя, иначе «преимущество 1/2» будет означать разные вещи в разных книгах. Курс везде использует форму с множителем.

Схема стойка в данной модели, если для любого эффективного противника Adv пренебрежимо мало как функция λ. Слово «эффективный» отсылает к ограничению времени полиномом, слово «пренебрежимо» — к определению выше. Обе оговорки обязательны: без ограничения на время противник может перебрать всё пространство ключей, а без асимптотики нельзя говорить о стойкости «вообще», только о конкретных параметрах.

Единицы, версии, даты

Таблица фиксирует соглашения, которые дальше не оговариваются.

ЧтоКак записываетсяЧего избегать
Длина ключа«ключ 128 бит»«128-битный пароль»
Сложность2^128 операций«128-битная сложность»
Уровень стойкости«128 бит стойкости»отождествление с длиной ключа
Версия«на OpenSSL 3.5 и новее»«в OpenSSL»
Оценка«оценка 2024 года, модель X»число без источника
Вероятность1/2, 2^-64проценты в формулах

Последняя строка таблицы — про честность изложения. Числа в курсе стареют: скорости перебора, версии библиотек, редакции рекомендаций. Поэтому количественные оценки сопровождаются датой и источником, а сведения, зависящие от версии, отделяются от стабильных. Реестр таких уточнений ведётся отдельно и обновляется при каждой проверке.

Итоги темы

Криптографическая подсистема строится по линии «модель угрозы → свойство → примитив → режим или протокол → реализация → управление ключами», и каждый уровень может обесценить остальные. Свойство примитива и свойство системы — разные вещи: стойкий блочный шифр в неправильном режиме даёт нестойкую систему, а корректная схема с ключом в репозитории не защищает ничего. Дальнейшие темы проходят эту линию по частям: 2 формализует свойства, 5–10 собирают симметричные примитивы, 11–14 — асимметричные и инфраструктуру, 15 складывает всё в протоколы.

Математический минимум курса — вероятность (условная вероятность, формула Байеса, парадокс дней рождения), логарифмы и степени двойки для чтения оценок сложности, множества и отображения для понимания перестановок, группы, кольца и поля для понимания арифметики, на которой стоят схемы. Асимптотические определения — полиномиальный противник, пренебрежимо малая функция — нужны, чтобы правильно читать формулировки стойкости и не путать доказанную стойкость в модели с практической применимостью атаки.

Инструментальная часть — Python с его разделением строк и байтов, OpenSSL с его подкомандами, командная строка с правами доступа к файлам. Ошибка на этом уровне (кодировка, порядок байтов, права на ключ) выглядит как криптографическая, но ею не является, и её важно научиться отличать до того, как начнутся настоящие атаки.

Единые обозначения — не формальность. Формула преимущества, определения «эффективного» и «пренебрежимо малого», соглашения о длинах и версиях делают текст тем 2–16 сравнимым между собой и с литературой. Там, где конвенция курса расходится с источником, расхождение оговаривается явно.

Литература

  1. Katz J., Lindell Y. Introduction to Modern Cryptography. — 3rd ed. — CRC Press, 2020.
  2. Boneh D., Shoup V. A Graduate Course in Applied Cryptography. — 2023. https://crypto.stanford.edu/~dabo/cryptobook/
  3. Ferguson N., Schneier B., Kohno T. Cryptography Engineering: Design Principles and Practical Applications. — Wiley, 2010.
  4. Aumasson J.-P. Serious Cryptography: A Practical Introduction to Modern Encryption. — 2nd ed. — No Starch Press, 2024.
  5. Wong D. Real-World Cryptography. — Manning, 2021.
  6. Menezes A., van Oorschot P., Vanstone S. Handbook of Applied Cryptography. — CRC Press, 1996. https://cacr.uwaterloo.ca/hac/
  7. NIST. Recommendation for Key Management: Part 1 — General. — NIST Special Publication 800-57 Part 1 Rev. 5, 2020. https://doi.org/10.6028/NIST.SP.800-57pt1r5
  8. Yergeau F. UTF-8, a transformation format of ISO 10646. — RFC 3629, IETF, 2003. https://www.rfc-editor.org/rfc/rfc3629
  9. Josefsson S. The Base16, Base32, and Base64 Data Encodings. — RFC 4648, IETF, 2006. https://www.rfc-editor.org/rfc/rfc4648
  10. OpenSSL Documentation. — 2025. https://docs.openssl.org/
  11. Python Software Foundation. Built-in Types: Text Sequence Type str, Binary Sequence Types. — 2025. https://docs.python.org/3/library/stdtypes.html