Podstawa wykładowa: Część 3 - slajdy 30, 31, 32, 33: architektura ARX (Addition, Rotation, XOR), funkcja ćwierćrundowa QR, stan 16 słów 32-bitowych (512
bitów), RFC 8439, stałe 'expand 32-byte k'.
Cel
Celem zadania jest zaimplementowanie w języku Python elementarnej funkcji Quarter Round (QR) szyfru ChaCha20, zbadanie mechanizmu dyfuzji w architekturze ARX
(Addition-Rotation-XOR) oraz zweryfikowanie poprawności działania na oficjalnych wektorach testowych ze standardu IETF RFC 8439.
Scenariusz – opis
Szyfr strumieniowy ChaCha20 opiera się na architekturze ARX, wykorzystującej wyłącznie trzy operacje na słowach 32-bitowych: dodawanie modulo 2^32, rotację bitową oraz XOR.
Fundamentem całego algorytmu jest funkcja ćwierćrundowa QR(a, b, c, d), która modyfikuje cztery słowa 32-bitowe w czterech krokach obliczeniowych. W każdym kroku następuje dodanie dwóch
słów, XOR wyniku z kolejnym słowem oraz cykliczna rotacja bitowa w lewo o specyficzną stałą (16, 12, 8 lub 7 bitów). Dzięki brakowi tablic S-box algorytm jest całkowicie odporny na ataki
czasowe na pamięć podręczną (ang. cache-timing attacks) i działa wysoce wydajnie na dowolnym procesorze. Pełna runda ChaCha20 składa się z czterech operacji QR na kolumnach macierzy
stanu oraz czterech na przekątnych (tzw. Double Round). W tym zadaniu zaimplementujesz funkcję QR oraz rundę podwójną w Pythonie w JSLinux i przetestujesz je na danych ze standardu RFC
8439.
Co ma wykonać student / grupa
W konsoli JSLinux tworzysz plik programu
chacha20_qr.py. Definiujesz pomocniczą funkcję rotacji bitowej w lewo dla liczb 32-bitowych: rol(v, c) = ((v << c) & 0xFFFFFFFF) | (v >>
(32 - c)). Implementujesz funkcję quarter_round(a, b, c, d) wykonującą cztery kroki transformacji ARX dokładnie według specyfikacji
RFC 8439. Krok 1: a = (a + b) mod
2^32; d = (d XOR a)<<< 16.
Krok 2: c = (c + d) mod 2^32; b = (b XOR c)<<< 12. Krok 3: a = (a + b) mod
2^32; d = (d XOR a)<<< 8. Krok 4: c = (c + d) mod 2^32; b = (b XOR c)<<<
7. Wprowadzasz oficjalny wektor testowy z rozdziału 2.1.1 dokumentu RFC 8439 (wejście: a = 0x11111111, b = 0x01020304, c =
0x9b8d6f43, d = 0x01234567).
Uruchamiasz funkcję i porównujesz wynik z wartościami oczekiwanymi z RFC 8439: a = 0xea2a92f4, b = 0xcb1cf8ce, c =
0x4581472e, d = 0x5881c4bb. Potwierdzasz stuprocentową zgodność obliczeń z oficjalną normą IETF.
Następnie budujesz macierz stanu 4x4 słów 32-bitowych i implementujesz rundę kolumnową (QR na kolumnach 0, 1, 2, 3) oraz przekątniową (QR na przekątnych). Badanie
rozszerzasz o analizę efektu lawinowego: zmieniasz 1 bit w słowie 'a' i mierzysz, ile bitów ulega zmianie po wykonaniu jednej funkcji QR. Sprawdzasz, że
już po pojedynczym wykonaniu QR zmiana jednego bitu rozprzestrzenia się na wszystkie cztery słowa stanu. Sporządzasz tabelę zestawień bitowych i analizujesz, dlaczego stałe rotacji
(16, 12, 8, 7) zostały dobrane optymalnie pod kątem szybkości dyfuzji.
Wykonujesz zrzuty ekranu z konsoli JSLinux dokumentujące walidację z RFC 8439. Przygotowujesz kompletne wnioski techniczne do raportu laboratoryjnego.
Przykładowe kroki do wykonania jako sugestia
- Uruchom emulator JSLinux Alpine.
- Utwórz plik programu:
nano chacha20_qr.py.
-
Zaimplementuj w Pythonie funkcję
32-bitowej rotacji bitowej w lewo
rol(x, n).
-
Zaimplementuj operację dodawania
32-bitowego z
obcięciem do maski 0xFFFFFFFF.
-
Zaimplementuj funkcję
quarter_round(a, b,
c, d) zgodnie z algorytmem RFC
8439.
-
Wprowadź oficjalne wektory testowe z sekcji
2.1.1 RFC 8439.
-
Wykonaj funkcję
QR i porównaj wyjściowe wartości szesnastkowe a,
b, c, d z normą.
- Wypisz w konsoli potwierdzenie poprawności testu jednostkowego (
PASS/FAIL).
- Zaimplementuj strukturę stanu 16 słów i funkcję
column_round( state).
- Zaimplementuj funkcję
diagonal_round( state) operującą na przekątnych macierzy.
- Złóż pełną rundę podwójną (
Double Round) składającą się z rundy kolumnowej i przekątniowej.
- Przeprowadź test efektu lawinowego: odwróć 1 bit w wejściowym słowie a i przelicz
QR.
- Oblicz liczbę zmienionych bitów we wszystkich czterech słowach wyjściowych.
- Zestaw wyniki pomiaru dyfuzji w tabeli sprawozdania.
-
Mini
-pomiar motywujący dyskusję o sprzęcie: zmierz w Pythonie czas 20 pełnych rund ChaCha20
(Double Round × 10) oraz 10 rund
AES z Zadania 3 na tym samym hoście i podaj krotność (nie
milisekundy); wyjaśnij, dlaczego na procesorze z AES-NI relacja się odwraca - to jest właściwy
wniosek inżynierski, nie same liczby.
- Wykonaj zrzuty ekranu kodu oraz wyjścia konsoli w JSLinux.
-
Sformułuj wnioski wyjaśniające,
w jaki sposób architektura
ARX eliminuje luki czasowe implementacji programowych w porównaniu z
AES.
Kontrola zaliczenia (checklist):
- Uruchomiono skrypt QR i zachowano log: wynik Quarter Round zgodny z RFC 8439 dla wektora testowego, z widocznymi krokami ARX.
- Dołączono kod (własne min. 20 linii): dodawanie mod 2³², rotacje, XOR, rundy kolumnowe/przekątniowe.
- Przeprowadzono test pozytywny (wektor RFC przechodzi) i negatywny (zła rotacja — rozjazd natychmiast wykryty).
- Opisano w 3–5 zdaniach: ARX jako dyfuzja bez tablic, stały czas vs cache-timing, kolumny+przekątne jako pełne mieszanie.
Wariant offline (fallback): Brak bibliotek: praca w pełni offline na wektorach ze startera w lokalnym Pythonie 3 (hashlib, struct); openssl speed zastąp pomiarem time w Pythonie; dołącz kod i log z konsoli.
Sugerowane wnioski i podsumowanie - co student ma osiągnąć
Sprawozdanie z realizacji zadania musi zawierać następujące kluczowe wnioski i osiągnięcia:
- W jaki sposób naprzemienne stosowanie dodawania arytmetycznego (nieliniowość) i XOR (liniowość) z rotacją generuje wysoką dyfuzję.
- Dlaczego brak odwołań do tablic pamięci (S-box) gwarantuje stały czas wykonania operacji i odporność na ataki cache-timing.
- Rola podziału na rundy kolumnowe i przekątniowe w zapewnieniu pełnego wymieszania wszystkich 16 słów macierzy stanu.
- Student potrafi poprawnie zaimplementować funkcję QR ChaCha20 w Pythonie i zweryfikować jej poprawność z oficjalnym dokumentem RFC 8439.