Захист мережевого трафіку у віртуальних приватних мережах покладається на алгоритми автентифікованого симетричного шифрування (AEAD). Головне завдання цих шифрів полягає не лише у збереженні конфіденційності даних тунелю, а й у гарантуванні їхньої цілісності та автентичності відправника. Протягом тривалого часу золотим стандартом у протоколах IPsec та OpenVPN залишався алгоритм AES у режимі лічильника Галуа (AES-GCM). Проте масовий розвиток мобільних пристроїв та систем Інтернету речей (IoT) виявив серйозні обмеження та мікроархітектурні ризики, пов'язані з програмним виконанням AES.
Криптографічна комбінація ChaCha20-Poly1305, створена Деніелом Бернштейном та стандартизована IETF у специфікації RFC 8439, запропонувала принципово інший підхід. Протокол WireGuard обрав її як єдиний криптографічний механізм інкапсуляції пакетів, забезпечивши високу обчислювальну продуктивність та апаратний захист від атак через сторонні канали часу доступу до кешу (cache-timing attacks).
Проблема програмної реалізації AES та сторонні канали
Алгоритм AES, розроблений наприкінці 1990-х років, використовує нелінійні таблиці підстановок, відомі як S-бокси (S-boxes). На настільних та серверних процесорах із вбудованими інструкціями AES-NI або ARMv8 Crypto операції підстановки виконуються апаратно за фіксовану кількість тактів, що унеможливлює витік інформації.
Однак на недорогих маршрутизаторах, енергоефективних мікроконтролерах та бюджетних смартфонах без криптографічних інструкцій компілятори змушені застосовувати програмні таблиці підстановок у пам'яті (T-tables):
- Витік через кеш-пам'ять: Індекси таблиці підстановки безпосередньо обчислюються як результат операції XOR між фрагментами відкритого тексту та байтами секретного ключа. Коли процесор завантажує рядок кешу (cache line), час операції залежить від того, чи була адреса вже в кеші (cache hit), чи знадобилося звернення до повільної оперативної пам'яті (cache miss).
- Статистичний аналіз затримок: Сусідні процеси на тому самому процесорному ядрі можуть використовувати методики Flush+Reload або Prime+Probe для моніторингу доступу до ліній кешу, поетапно відновлюючи повний 128- або 256-бітний ключ AES.
- Складність автентифікації GHASH: Режим GCM вимагає обчислення полінома автентифікації над полем Галуа $\mathbb{F}_{2^{128}}$. Без апаратних блоків множення без переносу (CLMUL/PMULL) операція GHASH спирається на великі таблиці в пам'яті, які також створюють часові розбіжності та навантажують процесор.
Архітектура ARX: константний час виконання без таблиць у пам'яті
Шифр ChaCha20 повністю відмовляється від будь-яких таблиць пошуку в оперативній пам'яті. В його основі лежить концепція ARX (Addition, Rotation, XOR), що використовує лише три базові арифметико-логічні операції процесора:
- Додавання (Addition): Додавання 32-бітних слів за модулем $2^{32}$ ($a + b \pmod{2^{32}}$).
- Циклічний зсув (Rotation): Зсув бітів у слові ліворуч на константну кількість позицій ($a \lll n$).
- Побітове додавання за модулем 2 (XOR): Логічна операція $a \oplus b$.
Усі ці інструкції підтримуються на рівні арифметико-логічного пристрою (ALU) будь-якого сучасного процесора і виконуються строго за фіксовану кількість циклів, незалежно від значень оброблюваних даних чи їхніх адрес у пам'яті. Завдяки цьому виконання ChaCha20 є детермінованим за часом, що повністю блокує таймінгові атаки на кеш.
Матриця стану та функція чверть-раунду (Quarter-Round)
Внутрішній стан ChaCha20 складається з 512 бітів, організованих як 16 слів по 32 біти кожне у вигляді квадратної матриці 4×4:
| Стовпець 0 | Стовпець 1 | Стовпець 2 | Стовпець 3 |
|---|---|---|---|
| Константа c0 (0x61707865) | Константа c1 (0x3320646e) | Константа c2 (0x79622d32) | Константа c3 (0x6b206574) |
| Ключ k0 | Ключ k1 | Ключ k2 | Ключ k3 |
| Ключ k4 | Ключ k5 | Ключ k6 | Ключ k7 |
| Лічильник b0 | Нонс n0 | Нонс n1 | Нонс n2 |
Перші чотири слова містять стандартизовані константи ASCII, які формують рядок expand 32-byte k. Наступні вісім слів займає 256-бітний симетричний ключ. Останній рядок складається з одного слова лічильника блоків (Block Counter) та трьох слів унікального 96-бітного значення (Nonce за RFC 8439).
Базовим елементом перемішування є операція чверть-раунду QR(a, b, c, d), яка виконує послідовні перетворення:
$$a \leftarrow a + b; \quad d \leftarrow (d \oplus a) \lll 16;$$ $$c \leftarrow c + d; \quad b \leftarrow (b \oplus c) \lll 12;$$ $$a \leftarrow a + b; \quad d \leftarrow (d \oplus a) \lll 8;$$ $$c \leftarrow c + d; \quad b \leftarrow (b \oplus c) \lll 7;$$
Шифр виконує 20 таких раундів (10 раундів для стовпців по черзі з 10 раундами для діагоналей матриці), досягаючи високого ступеня дифузії та псевдовипадковості. Після завершення раундів фінальний стан покомпонентно додається до початкового стану. Отримані 64 байти гами (keystream) накладаються на відкритий текст операцією XOR.
Автентифікатор Poly1305 та неприпустимість повторного використання нонса
Для захисту від модифікації даних ChaCha20 поєднується з алгоритмом Poly1305, розробленим як поліноміальний автентифікатор класу Картера-Вегмана.
Обчислення у простому полі та закріплення бітів (Clamping)
Poly1305 розбиває повідомлення на 16-байтні блоки та обчислює значення полінома над простим полем $\mathbb{F}_{2^{130}-5}$. Вибір простого модуля $2^{130}-5$ зумовлений зручністю модульної редукції в двійковій системі числення, що не потребує повільної операції ділення процесора.
Для кожного блоку трафіку ChaCha20 за нульового значення лічильника генерує одноразовий 32-байтний ключ автентифікації. Він розбивається на ключ $r$ (коефіцієнт полінома) та $s$ (маскуючий доданок). Для гарантії безпеки до ключа $r$ застосовується процедура закріплення бітів (clamping):
- Обнулення верхніх 4 бітів у чотирьох байтах для запобігання переповненню розрядів.
- Обнулення двох молодших бітів у трьох байтах для стабільності редукції.
- Сумарно очищуються 22 фіксовані біти, що математично унеможливлює вихід проміжних сум за межі допустимого діапазону.
Захист від повторення нонса у WireGuard
Критичною вимогою безпеки AEAD є унікальність комбінації ключа та значення нонса (Key-Nonce pair):
- Повторне застосування нонса з однаковим ключем у ChaCha20 відкриває результат додавання двох відкритих текстів за правилом $C_1 \oplus C_2 = P_1 \oplus P_2$, що компрометує конфіденційність.
- Повтор нонса в Poly1305 створює систему лінійних рівнянь між тегами автентифікації, що дозволяє обчислити секретний коефіцієнт $r$ та підробляти автентифікаційні мітки майбутніх пакетів.
WireGuard усуває цей ризик завдяки строгій архітектурі:
- Односпрямований 64-бітний лічильник: Для кожного пакета даних нонс формується зі строго монотонного 64-бітного лічильника передавання транспортного рівня, виключаючи будь-яку випадковість чи циклічні збої генератора.
- Примусова зміна ключів (Rekeying): При досягненні значення лічильника $2^{60}$ пакетів або за лімітом часу протокол автоматично ініціює створення нової сесії та оновлення ключів за протоколом Noise. Після досягнення лічильником $2^{64}-1$ передавання повністю блокується.
Векторизація SIMD та багатопотокова обробка в RiceGuard
Матрична структура ChaCha20 ідеально піддається векторизації на сучасних процесорах. Використання векторних інструкцій ARM NEON, AVX2 та AVX-512 дозволяє паралельно обчислювати кілька чверть-раундів або генерувати кілька 64-байтних блоків гами за один процесорний такт, досягаючи пропускної здатності в десятки гігабіт на секунду.
У системі RiceGuard алгоритм інтегровано у високопродуктивний стек:
- Паралелізація через механізм padata: Розподіл завдань шифрування та перевірки автентичності між усіма доступними ядрами процесора зі збереженням первинного порядку проходження пакетів.
- Своєчасне очищення пам'яті (Zeroization): Після завершення обробки пакета всі проміжні стани та тимчасові ключі видаляються з оперативної пам'яті та регістрів за допомогою системних функцій
memzero_explicit, що запобігає видаленню інструкцій оптимізатором компілятора. - Порівняння тегів зі сталим часом: Перевірка автентичності 16-байтних тегів Poly1305 здійснюється через функцію
crypto_memneq, унеможливлюючи аналіз часових коливань під час перевірки валідності пакетів.
Завдяки поєднанню строгої математичної бази ARX, ефективного захисту від сторонніх каналів та оптимізації на рівні ядра, ChaCha20-Poly1305 залишається надійним фундаментом сучасних захищених з'єднань.



