⍝ AES in GNU APL ⍝ Left rotate ⍺ bit Rot8 ← {2⊥⍺⌽(8⍴2)⊤⍵} ⍝ Addition and subtraction in finite field GF(2) Add2 ← {⍺ ⊤≠ ⍵} ⍝ Multiplication in GF(2) [x]/(x8 + x4 + x3 + x + 1) Mul2 ← {⊤≠/({⍵,$FF ⊤∧ ($11B×$80≤¯1↑⍵) ⊤≠ 2ׯ1↑⍵}⍣7 ⍺) × ⌽(8⍴2)⊤⍵} ⍝ Multiplicative inverse, calculated by brute force Mul2Inv ← {$FF ⊤∧ 1⍳⍨⍵ Mul2¨⍳255} SBox ← {⊤≠/$63,(1-⍨⍳5) Rot8¨Mul2Inv ⍵}¨1-⍨⍳256 InvSBox ← {Mul2Inv ⊤≠/$5,(1 3 6) Rot8¨⍵}¨1-⍨⍳256 ⍝ ⎕ ← 16 16⍴6 ⎕CR¨SBox ⍝ ⎕ ← 16 16⍴6 ⎕CR¨InvSBox ⍝ Round constants (in rows) Rcon ← (10 1⍴$01 $02 $04 $08 $10 $20 $40 $80 $1B $36),10 3⍴0 RotWord ← {1⌽⍵} SubWord ← {SBox[⍵+1]} ⍝ See SubBytes ⍝ Round keys based on Key (array of 8-bit integers) ∇RoundKeys ← KeyExpansion Key; NK; NR; i NK ← 4÷⍨↑⍴Key ⍝ Rounds: 11 for AES-128, 13 for AES-192, 15 for AES-256 (see NIST p.18) NR ← NK+6+1 ⍝ We need one key more than rounds RoundKeys ← (NR×4) 4⍴Key i ← 1+NK Loop: RoundKeys[i;] ← {Rcon[⌊i÷NK;] ⊤≠ SubWord RotWord ⍵}⍣(0=NK|i-1) RoundKeys[i-1;] RoundKeys[i;] ← RoundKeys[i-NK;] ⊤≠ SubWord⍣((NK>6) ∧ 4=NK|i-1) RoundKeys[i;] i ← i+1 →(i≤NR×4)/Loop RoundKeys ← NR 4 4⍴RoundKeys ∇ AddRoundKey ← {⍵ ⊤≠ ⍉⍺} ⍝ This is also its inverse SubBytes ← {SBox[⍵+1]} InvSubBytes ← {InvSBox[⍵+1]} ShiftRows ← {⍵⌽⍨1-⍨⍳4} InvShiftRows ← {⍵⌽⍨1+-⍳4} MixColumns ← {⍵ ⊤≠.Mul2⍨ (-⍳4)⌽⍤(0 1) 3 1 1 2} InvMixColumns ← {⍵ ⊤≠.Mul2⍨ (-⍳4)⌽⍤(0 1) $b $d $9 $e} ∇CipherText←RoundKeys Cipher PlainText; State; Round State ← RoundKeys[Round←1;;] AddRoundKey ⍉4 4⍴PlainText State ← {RoundKeys[Round←Round+1;;] AddRoundKey MixColumns ShiftRows SubBytes ⍵}⍣(2-⍨↑⍴RoundKeys) State CipherText ← ∊⍉RoundKeys[Round+1;;] AddRoundKey ShiftRows SubBytes State ∇ Encrypt ← {(KeyExpansion ⍺) Cipher ⍵} ∇PlainText←RoundKeys InvCipher CipherText; State; Round State ← RoundKeys[Round←↑⍴RoundKeys;;] AddRoundKey ⍉4 4⍴CipherText State ← {InvMixColumns RoundKeys[Round←Round-1;;] AddRoundKey InvSubBytes InvShiftRows ⍵}⍣(2-⍨↑⍴RoundKeys) State PlainText ← ∊⍉RoundKeys[Round-1;;] AddRoundKey InvSubBytes InvShiftRows State ∇ Decrypt ← {(KeyExpansion ⍺) InvCipher ⍵} RoundKeys ← KeyExpansion ⎕UCS 13 ⎕CR '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4' ⍝ 5 ⎕CR RoundKeys CipherText ← RoundKeys Cipher ⎕UCS 'Hello world!!!!!' ⎕ ← 6 ⎕CR¨CipherText ⍝ To check the cipher text: ⍝ echo -en 'Hello world!!!!!' | openssl enc -aes-256-ecb -nosalt -nopad -K '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4' | hexdump -C PlainText ← ⎕UCS RoundKeys InvCipher CipherText ⎕ ← PlainText