GolfScript, 60 caratteri
{[[0 1{.283{1$2*.255>@*^}:r~^}255*].@?~)={257r}4*99]{^}*}:S;
Questo codice definisce una funzione denominata Sche accetta un byte e ad esso applica la S-box Rijndael. (Utilizza anche una funzione di supporto interna denominata rper salvare alcuni caratteri.)
Questa implementazione utilizza una tabella di logaritmi per calcolare le inversioni di GF (2 8 ), come suggerito da Thomas Pornin . Per salvare alcuni caratteri, l'intera tabella del logaritmo viene ricalcolata per ogni byte di input; anche così, e nonostante GolfScript sia un linguaggio molto lento in generale, questo codice impiega solo circa 10 ms per elaborare un byte sul mio vecchio laptop. Il pre-calcolo della tabella del logaritmo (as L) lo accelera fino a circa 0,5 ms per byte, al costo modesto di altri tre caratteri:
[0 1{.283{1$2*.255>@*^}:r~^}255*]:L;{[L?~)L={257r}4*99]{^}*}:S;
Per comodità, ecco un semplice cablaggio di prova che chiama la funzione S, come definita sopra, per calcolare e stampare l'intera S-box in esadecimale come su Wikipedia :
"0123456789abcdef"1/:h; 256, {S .16/h= \16%h= " "++ }% 16/ n*
Prova questo codice online.
(La demo online precalcola la tabella dei logaritmi per evitare di impiegare troppo tempo. Anche così, il sito GolfScript online a volte può andare in timeout in modo casuale; questo è un problema noto con il sito e una ricarica di solito lo risolve.)
Spiegazione:
Cominciamo con il calcolo della tabella dei logaritmi, e in particolare con la funzione helper r:
{1$2*.255>@*^}:r
Questa funzione accetta due input nello stack: un byte e una maschera di bit di riduzione (una costante tra 256 e 511). Duplica il byte di input, moltiplica la copia per 2 e, se il risultato supera 255, XORs con la maschera di bit per riportarlo sotto 256.
All'interno del codice di generazione della tabella di registro, la funzione rviene chiamata con la maschera di bit di riduzione 283 = 0x11b (che corrisponde al polinomio di riduzione Rijndael GF (2 8 ) x 8 + x 4 + x 3 + x + 1) e il risultato è XORed con il byte originale, moltiplicandolo efficacemente per 3 (= x + 1, come polinomio) nel campo finito di Rijndael. Questa moltiplicazione viene ripetuta 255 volte, a partire dal byte 1, e i risultati (più un byte zero iniziale) vengono raccolti in un array di 257 elementi Lche assomiglia a questo (parte centrale omessa):
[0 1 3 5 15 17 51 85 255 26 46 ... 180 199 82 246 1]
Il motivo per cui ci sono 257 elementi è che, con lo 0 anteposto e con 1 che si verificano due volte, possiamo trovare l'inverso modulare di un dato byte semplicemente osservando il suo indice (a base zero) in questo array, negandolo e osservando il byte nell'indice negato nello stesso array. (In GolfScript, come in molti altri linguaggi di programmazione, gli indici di array negativi contano all'indietro dalla fine dell'array.) In effetti, questo è esattamente ciò che fa il codice L?~)L=all'inizio della funzione S.
Il resto del codice chiama la funzione helper rquattro volte con la maschera di bit di riduzione 257 = 2 8 + 1 per creare quattro copie a rotazione di bit del byte di input invertito. Questi sono tutti raccolti in un array, insieme alla costante 99 = 0x63 e XORed insieme per produrre l'output finale.