S-box Rijndaela jest często stosowaną operacją w szyfrowaniu i deszyfrowaniu AES . Zwykle jest implementowany jako 256-bajtowa tabela odnośników. Jest to szybkie, ale oznacza, że musisz wyliczyć 256-bajtową tabelę wyszukiwania w kodzie. Założę się, że ktoś w tym tłumie mógłby to zrobić z mniejszym kodem, biorąc pod uwagę podstawową strukturę matematyczną.
Napisz funkcję w swoim ulubionym języku, która implementuje S-box Rijndaela. Najkrótszy kod wygrywa.
code-golf
math
cryptography
Keith Randall
źródło
źródło
Odpowiedzi:
Ruby, 161 znaków
Aby sprawdzić wynik, możesz użyć następującego kodu, aby wydrukować go w formie tabeli:
źródło
GolfScript, 60 znaków
Ten kod definiuje nazwaną funkcję,
S
która pobiera bajt i stosuje do niego S-box Rijndael. (Używa także wewnętrznej funkcji pomocnika o nazwie,r
aby zapisać kilka znaków).Ta implementacja wykorzystuje tabelę logarytmiczną do obliczania odwrotności GF ( 28 ), jak zasugerował Thomas Pornin . Aby zapisać kilka znaków, cała tabela logarytmiczna jest ponownie obliczana dla każdego bajtu wejściowego; mimo to i mimo że GolfScript jest ogólnie bardzo wolnym językiem, ten kod zajmuje tylko około 10 ms na przetworzenie bajtu na moim starym laptopie. Wstępne obliczenie tabeli logarytmicznej (as
L
) przyspiesza ją do około 0,5 ms na bajt, przy skromnym koszcie jeszcze trzech znaków:Dla wygody oto prosta uprząż testowa, która wywołuje funkcję
S
, jak zdefiniowano powyżej, w celu obliczenia i wydrukowania całego S-boxa szesnastkowo jak na Wikipedii :Wypróbuj ten kod online.
(Wersja demonstracyjna online wstępnie oblicza tabelę logarytmiczną, aby uniknąć zbyt długiego czasu. Mimo to strona internetowa GolfScript może czasami losowo upłynąć limit czasu; jest to znany problem z witryną, a przeładowanie zwykle ją rozwiązuje).
Wyjaśnienie:
Zacznijmy od obliczenia tabeli logarytmicznej, a konkretnie od funkcji pomocniczej
r
:Ta funkcja przyjmuje na wejściu dwa wejścia: bajt i maskę bitów redukcyjnych (stała między 256 a 511). Duplikuje bajt wejściowy, mnoży kopię przez 2, a jeśli wynik przekracza 255, XORs ją z maską bitową, aby sprowadzić ją z powrotem poniżej 256.
W kodzie generującym tablicę logów funkcja
r
jest wywoływana z maską bitową redukcji 283 = 0x11b (co odpowiada wielomianowi redukcyjnemu Rijndael GF ( 28 ) x 8 + x 4 + x 3 + x + 1), a wynik jest XORed z oryginalnym bajtem, skutecznie mnożąc go przez 3 (= x + 1, jako wielomian) w skończonym polu Rijndaela. To zwielokrotnienie powtarza się 255 razy, zaczynając od bajtu 1, a wyniki (plus początkowy bajt zerowy) są gromadzone w 257-elementowej tablicy,L
która wygląda następująco (pominięta część środkowa):Powodem, dla którego istnieje 257 elementów, jest to, że przy wstawionym 0 i 1 występującym dwukrotnie, możemy znaleźć modułową odwrotność dowolnego danego bajtu, po prostu patrząc na jego (zerowy) indeks w tej tablicy, negując go i patrząc w górę bajtu przy zanegowanym indeksie w tej samej tablicy. (W GolfScript, podobnie jak w wielu innych językach programowania, ujemne indeksy tablic liczą się wstecz od końca tablicy.) Rzeczywiście, dokładnie to robi kod
L?~)L=
na początku funkcjiS
.Reszta kodu wywołuje funkcję pomocniczą
r
cztery razy z redukcyjną maską bitową 257 = 2 8 + 1, aby utworzyć cztery obrócone bity kopie odwróconego bajtu wejściowego. Wszystkie są zebrane w tablicę wraz ze stałą 99 = 0x63 i razem XOR, aby uzyskać końcowy wynik.źródło
x86-64 Kod maszynowy -
23 22 2019 bajtówKorzysta z zestawu instrukcji AES-NI
Używając konwencji wywoływania systemu Windows, pobiera bajt i wysyła bajt. Nie ma potrzeby odwracania,
ShiftRows
ponieważ nie wpływa to na pierwszy bajt.źródło
Tabelę można wygenerować bez obliczania odwrotności w polu skończonym GF (256), używając logarytmów. Wyglądałoby to tak (kod Java, używany w
int
celu uniknięcia problemów z podpisanymbyte
typem):Chodzi o to, że 3 jest multiplikatywnym generatorem GF (256) *. Tabela
t[]
jest taka, żet[x]
jest równa 3 x ; ponieważ 3 255 = 1, otrzymujemy to 1 / (3 x ) = 3 255-x .źródło
0x1B
(jeden 1 w literale szesnastkowym) zamiast0x11B
int
Javie jest to 32-bit; Muszę anulować wyższy bit.GolfScript (82 znaków)
Wykorzystuje zmienne globalne
A
iB
i tworzy funkcję jako zmienną globalnąS
.Inwersja Galois to brutalna siła; Eksperymentowałem z osobną
mul
funkcją, która mogłaby zostać ponownie wykorzystana do transformacji afinicznej po inwersji, ale okazało się, że była droższa z powodu różnych zachowań przepełnienia.Jest to zbyt wolne jak na demo online - przekroczyłoby limit czasu nawet w pierwszych dwóch rzędach tabeli.
źródło
Python, 176 znaków
Ta odpowiedź dotyczy pytania komentującego Paŭlo Ebermanna o ustawieniu funkcji na stały czas. Ten kod pasuje do rachunku.
źródło
re
to może wygenerować tablicę odnośników w czasie kompilacji, mógłbym trochę zaoszczędzić, zmieniając ubyte w ogólny parametr
edit kierować
ubyte
sięubyte
bez wyszukiwań tablicy, bez rozgałęzień i całkowicie unrollable pętleedit2 użył algo @Thomas do stworzenia tabeli odnośników
źródło
Stax , 53 bajty
Uruchom i debuguj
Nie mam szczególnego zrozumienia S-boxów. Jest to konwersja rozwiązania Thomasa Pornina (8 lat!) .
źródło