diff options
author | Robin Haberkorn <rhaberkorn@fmsbw.de> | 2025-10-06 00:48:48 +0300 |
---|---|---|
committer | Robin Haberkorn <rhaberkorn@fmsbw.de> | 2025-10-06 00:48:48 +0300 |
commit | ad9e7cd5117c965222aae708f660e56d537914fc (patch) | |
tree | 580006656ec76513500170e5646e92e7819c6c0b /aes.apl | |
download | snippets-ad9e7cd5117c965222aae708f660e56d537914fc.tar.gz |
imported all of my Github gists from https://gist.github.com/rhaberkorn
Diffstat (limited to 'aes.apl')
-rw-r--r-- | aes.apl | 69 |
1 files changed, 69 insertions, 0 deletions
@@ -0,0 +1,69 @@ +⍝ 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 |