GolfScript, 60 znaków
{[[0 1{.283{1$2*.255>@*^}:r~^}255*].@?~)={257r}4*99]{^}*}:S;
Ten kod definiuje nazwaną funkcję, Sktóra pobiera bajt i stosuje do niego S-box Rijndael. (Używa także wewnętrznej funkcji pomocnika o nazwie, raby 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:
[0 1{.283{1$2*.255>@*^}:r~^}255*]:L;{[L?~)L={257r}4*99]{^}*}:S;
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 :
"0123456789abcdef"1/:h; 256, {S .16/h= \16%h= " "++ }% 16/ n*
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:
{1$2*.255>@*^}: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 rjest 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, Lktóra wygląda następująco (pominięta część środkowa):
[0 1 3 5 15 17 51 85 255 26 46 ... 180 199 82 246 1]
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 funkcji S.
Reszta kodu wywołuje funkcję pomocniczą rcztery 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.