GolfScript, 60 znaków
{[[0 1{.283{1$2*.255>@*^}:r~^}255*].@?~)={257r}4*99]{^}*}:S;
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:
[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 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):
[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ą 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.