GolfScript, 60 Zeichen
{[[0 1{.283{1$2*.255>@*^}:r~^}255*].@?~)={257r}4*99]{^}*}:S;
Dieser Code definiert eine benannte Funktion S
, die ein Byte einnimmt und die Rijndael S-Box darauf anwendet. (Es wird auch eine interne Hilfsfunktion verwendet r
, um ein paar Zeichen zu speichern.)
Diese Implementierung verwendet eine Logarithmentabelle, um die GF (2 8 ) -Inversen zu berechnen , wie von Thomas Pornin vorgeschlagen . Um einige Zeichen zu sparen, wird die gesamte Logarithmentabelle für jedes Eingangsbyte neu berechnet. Trotzdem, und obwohl GolfScript im Allgemeinen eine sehr langsame Sprache ist, benötigt dieser Code nur etwa 10 ms, um ein Byte auf meinem alten Laptop zu verarbeiten. Durch Vorberechnung der Logarithmentabelle (as L
) wird eine Geschwindigkeit von bis zu 0,5 ms pro Byte erreicht, und dies zu moderaten Kosten von drei weiteren Zeichen:
[0 1{.283{1$2*.255>@*^}:r~^}255*]:L;{[L?~)L={257r}4*99]{^}*}:S;
Der Einfachheit halber hier ein einfaches Testkabel, das S
die oben definierte Funktion zum Berechnen und Ausdrucken der gesamten S-Box in hexadezimaler Form wie bei Wikipedia aufruft :
"0123456789abcdef"1/:h; 256, {S .16/h= \16%h= " "++ }% 16/ n*
Versuchen Sie diesen Code online.
(Die Online-Demo berechnet die Logarithmus-Tabelle vorab, um zu vermeiden, dass zu viel Zeit benötigt wird. Trotzdem kann es vorkommen, dass die Online-GolfScript-Site eine willkürliche Zeitüberschreitung aufweist. Dies ist ein bekanntes Problem, das in der Regel durch ein erneutes Laden behoben wird.)
Erläuterung:
Beginnen wir mit der Berechnung der Logarithmentabelle und speziell mit der Hilfsfunktion r
:
{1$2*.255>@*^}:r
Diese Funktion belegt zwei Eingänge im Stack: ein Byte und eine Reduktionsbitmaske (eine Konstante zwischen 256 und 511). Es dupliziert das Eingangsbyte, multipliziert die Kopie mit 2 und wenn das Ergebnis 255 überschreitet, wird es mit der Bitmaske XOR-verknüpft, um es wieder unter 256 zu bringen.
Innerhalb des Protokolltabellen-Erzeugungscodes wird die Funktion r
mit der Reduktionsbitmaske 283 = 0x11b (die dem Rijndael GF (2 8 ) -Reduktionspolynom x 8 + x 4 + x 3 + x + 1 entspricht) aufgerufen, und das Ergebnis ist XOR-verknüpft Multiplizieren Sie das ursprüngliche Byte mit 3 (= x + 1, als Polynom) im endlichen Rijndael-Feld. Diese Multiplikation wird ab Byte 1 255-mal wiederholt, und die Ergebnisse (plus ein anfängliches Null-Byte) werden in einem Array mit 257 Elementen gesammelt L
, das wie folgt aussieht (mittlerer Teil weggelassen):
[0 1 3 5 15 17 51 85 255 26 46 ... 180 199 82 246 1]
Der Grund, warum es 257 Elemente gibt, ist, dass wir mit der vorangestellten 0 und 1, die zweimal vorkommen, die modulare Inverse jedes gegebenen Bytes finden können, indem wir einfach seinen (nullbasierten) Index in diesem Array nachschlagen, ihn negieren und suchen up das Byte am negierten Index im gleichen Array. (In GolfScript, wie in vielen anderen Programmiersprachen, werden negative Array-Indizes vom Ende des Arrays an rückwärts gezählt.) In der Tat ist dies genau das, was der Code L?~)L=
am Anfang der Funktion S
tut.
Der Rest des Codes ruft die Hilfsfunktion r
viermal mit der Reduzierungsbitmaske 257 = 2 8 + 1 auf, um vier bitgedrehte Kopien des invertierten Eingangsbytes zu erstellen. Diese werden zusammen mit der Konstanten 99 = 0x63 zu einem Array zusammengefasst und zusammen mit XOR-Verknüpfungen versehen, um die endgültige Ausgabe zu erhalten.