-- | Advanced Encryption System (specification can be found in FIPS-197)
module Codec.Encryption.AESAux(
        aes128Encrypt,
        aes192Encrypt,
        aes256Encrypt,
        aes128Decrypt,
        aes192Decrypt,
        aes256Decrypt,
) where

import Data.Bits
import Data.Int(Int)
import Data.Word(Word32)

import Codec.Utils(Octet)

aes128Encrypt :: [Octet] -- ^ key (16 octets)
              -> [Octet] -- ^ msg (16 octets)
              -> [Octet] -- ^ enciphered msg (16 octets)
aes128Encrypt :: [Octet] -> [Octet] -> [Octet]
aes128Encrypt = Int -> Int -> [Octet] -> [Octet] -> [Octet]
aesEncrypt Int
10 Int
4

aes192Encrypt :: [Octet] -- ^ key (24 octets)
              -> [Octet] -- ^ msg (16 octets)
              -> [Octet] -- ^ enciphered msg (16 octets)
aes192Encrypt :: [Octet] -> [Octet] -> [Octet]
aes192Encrypt = Int -> Int -> [Octet] -> [Octet] -> [Octet]
aesEncrypt Int
12 Int
6

aes256Encrypt :: [Octet] -- ^ key (32 octets)
              -> [Octet] -- ^ msg (16 octets)
              -> [Octet] -- ^ enciphered msg (16 octets)
aes256Encrypt :: [Octet] -> [Octet] -> [Octet]
aes256Encrypt = Int -> Int -> [Octet] -> [Octet] -> [Octet]
aesEncrypt Int
14 Int
8

aes128Decrypt :: [Octet] -- ^ key (16 octets)
              -> [Octet] -- ^ enciphered msg (16 octets)
              -> [Octet] -- ^ deciphered msg (16 octets)
aes128Decrypt :: [Octet] -> [Octet] -> [Octet]
aes128Decrypt = Int -> Int -> [Octet] -> [Octet] -> [Octet]
aesDecrypt Int
10 Int
4

aes192Decrypt :: [Octet] -- ^ key (24 octets)
              -> [Octet] -- ^ enciphered msg (16 octets)
              -> [Octet] -- ^ deciphered msg (16 octets)
aes192Decrypt :: [Octet] -> [Octet] -> [Octet]
aes192Decrypt = Int -> Int -> [Octet] -> [Octet] -> [Octet]
aesDecrypt Int
12 Int
6

aes256Decrypt :: [Octet] -- ^ key (32 octets)
              -> [Octet] -- ^ enciphered msg (16 octets)
              -> [Octet] -- ^ deciphered msg (16 octets)
aes256Decrypt :: [Octet] -> [Octet] -> [Octet]
aes256Decrypt = Int -> Int -> [Octet] -> [Octet] -> [Octet]
aesDecrypt Int
14 Int
8

aesEncrypt :: Int     -- ^ nr
           -> Int     -- ^ nk
           -> [Octet] -- ^ key
           -> [Octet] -- ^ msg
           -> [Octet] -- ^ enciphered msg
aesEncrypt :: Int -> Int -> [Octet] -> [Octet] -> [Octet]
aesEncrypt Int
nr Int
nk [Octet]
key
                [Octet
i00, Octet
i10, Octet
i20, Octet
i30,
                 Octet
i01, Octet
i11, Octet
i21, Octet
i31,
                 Octet
i02, Octet
i12, Octet
i22, Octet
i32,
                 Octet
i03, Octet
i13, Octet
i23, Octet
i33] =
                [Word32 -> Octet
fo Word32
o00, Word32 -> Octet
fo Word32
o10, Word32 -> Octet
fo Word32
o20, Word32 -> Octet
fo Word32
o30,
                 Word32 -> Octet
fo Word32
o01, Word32 -> Octet
fo Word32
o11, Word32 -> Octet
fo Word32
o21, Word32 -> Octet
fo Word32
o31,
                 Word32 -> Octet
fo Word32
o02, Word32 -> Octet
fo Word32
o12, Word32 -> Octet
fo Word32
o22, Word32 -> Octet
fo Word32
o32,
                 Word32 -> Octet
fo Word32
o03, Word32 -> Octet
fo Word32
o13, Word32 -> Octet
fo Word32
o23, Word32 -> Octet
fo Word32
o33]
        where State (Word32
o00, Word32
o01, Word32
o02, Word32
o03)
                    (Word32
o10, Word32
o11, Word32
o12, Word32
o13)
                    (Word32
o20, Word32
o21, Word32
o22, Word32
o23)
                    (Word32
o30, Word32
o31, Word32
o32, Word32
o33) = State -> State
transform (
                        (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
-> State
State(Octet -> Word32
fi Octet
i00, Octet -> Word32
fi Octet
i01, Octet -> Word32
fi Octet
i02, Octet -> Word32
fi Octet
i03)
                             (Octet -> Word32
fi Octet
i10, Octet -> Word32
fi Octet
i11, Octet -> Word32
fi Octet
i12, Octet -> Word32
fi Octet
i13)
                             (Octet -> Word32
fi Octet
i20, Octet -> Word32
fi Octet
i21, Octet -> Word32
fi Octet
i22, Octet -> Word32
fi Octet
i23)
                             (Octet -> Word32
fi Octet
i30, Octet -> Word32
fi Octet
i31, Octet -> Word32
fi Octet
i32, Octet -> Word32
fi Octet
i33))
              fi :: Octet -> Word32
fi = (forall a b. (Integral a, Num b) => a -> b
fromIntegral :: Octet -> Word32)
              fo :: Word32 -> Octet
fo = (forall a b. (Integral a, Num b) => a -> b
fromIntegral :: Word32 -> Octet)
              (State -> State
kt0:[State -> State]
kts) = [Word32] -> [State -> State]
genAddRoundKey (Int -> Int -> [Octet] -> [Word32]
generateKeys Int
nr Int
nk [Octet]
key)
              transform :: State -> State
transform = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr forall b c a. (b -> c) -> (a -> b) -> a -> c
(.) State -> State
kt0 (forall a. [a] -> [a]
reverse [State -> State]
rest)
              mss :: [State -> State]
mss = forall a. Int -> a -> [a]
replicate (Int
nr forall a. Num a => a -> a -> a
- Int
1) (State -> State
mixColumns forall b c a. (b -> c) -> (a -> b) -> a -> c
. State -> State
shiftRows forall b c a. (b -> c) -> (a -> b) -> a -> c
. State -> State
subBytes)
              rest :: [State -> State]
rest = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall b c a. (b -> c) -> (a -> b) -> a -> c
(.) [State -> State]
kts ([State -> State]
mss forall a. [a] -> [a] -> [a]
++ [State -> State
shiftRows forall b c a. (b -> c) -> (a -> b) -> a -> c
. State -> State
subBytes ])


aesDecrypt :: Int     -- ^ nr
           -> Int     -- ^ nk
           -> [Octet] -- ^ key
           -> [Octet] -- ^ enciphered msg
           -> [Octet] -- ^ deciphered msg
aesDecrypt :: Int -> Int -> [Octet] -> [Octet] -> [Octet]
aesDecrypt Int
nr Int
nk [Octet]
key
                [Octet
i00, Octet
i10, Octet
i20, Octet
i30,
                 Octet
i01, Octet
i11, Octet
i21, Octet
i31,
                 Octet
i02, Octet
i12, Octet
i22, Octet
i32,
                 Octet
i03, Octet
i13, Octet
i23, Octet
i33] =
                [Word32 -> Octet
fo Word32
o00, Word32 -> Octet
fo Word32
o10, Word32 -> Octet
fo Word32
o20, Word32 -> Octet
fo Word32
o30,
                 Word32 -> Octet
fo Word32
o01, Word32 -> Octet
fo Word32
o11, Word32 -> Octet
fo Word32
o21, Word32 -> Octet
fo Word32
o31,
                 Word32 -> Octet
fo Word32
o02, Word32 -> Octet
fo Word32
o12, Word32 -> Octet
fo Word32
o22, Word32 -> Octet
fo Word32
o32,
                 Word32 -> Octet
fo Word32
o03, Word32 -> Octet
fo Word32
o13, Word32 -> Octet
fo Word32
o23, Word32 -> Octet
fo Word32
o33]
        where State (Word32
o00, Word32
o01, Word32
o02, Word32
o03)
                    (Word32
o10, Word32
o11, Word32
o12, Word32
o13)
                    (Word32
o20, Word32
o21, Word32
o22, Word32
o23)
                    (Word32
o30, Word32
o31, Word32
o32, Word32
o33) = State -> State
transform (
                        (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
-> State
State(Octet -> Word32
fi Octet
i00, Octet -> Word32
fi Octet
i01, Octet -> Word32
fi Octet
i02, Octet -> Word32
fi Octet
i03)
                             (Octet -> Word32
fi Octet
i10, Octet -> Word32
fi Octet
i11, Octet -> Word32
fi Octet
i12, Octet -> Word32
fi Octet
i13)
                             (Octet -> Word32
fi Octet
i20, Octet -> Word32
fi Octet
i21, Octet -> Word32
fi Octet
i22, Octet -> Word32
fi Octet
i23)
                             (Octet -> Word32
fi Octet
i30, Octet -> Word32
fi Octet
i31, Octet -> Word32
fi Octet
i32, Octet -> Word32
fi Octet
i33))
              fi :: Octet -> Word32
fi = (forall a b. (Integral a, Num b) => a -> b
fromIntegral :: Octet -> Word32)
              fo :: Word32 -> Octet
fo = (forall a b. (Integral a, Num b) => a -> b
fromIntegral :: Word32 -> Octet)
              (State -> State
kt0:[State -> State]
kts) = forall a. [a] -> [a]
reverse ([Word32] -> [State -> State]
genAddRoundKey (Int -> Int -> [Octet] -> [Word32]
generateKeys Int
nr Int
nk [Octet]
key))
              transform :: State -> State
transform = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr forall b c a. (b -> c) -> (a -> b) -> a -> c
(.) State -> State
kt0 (forall a. [a] -> [a]
reverse [State -> State]
rest)
              ssm :: [State -> State]
ssm = forall a. Int -> a -> [a]
replicate (Int
nr forall a. Num a => a -> a -> a
- Int
1)
                                (State -> State
subBytesRev forall b c a. (b -> c) -> (a -> b) -> a -> c
. State -> State
shiftRowsRev forall b c a. (b -> c) -> (a -> b) -> a -> c
. State -> State
mixColumnsRev)
              rest :: [State -> State]
rest = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall b c a. (b -> c) -> (a -> b) -> a -> c
(.) [State -> State]
kts ([State -> State
subBytesRev forall b c a. (b -> c) -> (a -> b) -> a -> c
. State -> State
shiftRowsRev] forall a. [a] -> [a] -> [a]
++ [State -> State]
ssm)



data State =  State !(Word32, Word32, Word32, Word32)
                    !(Word32, Word32, Word32, Word32)
                    !(Word32, Word32, Word32, Word32)
                    !(Word32, Word32, Word32, Word32)

sbox :: Word32 -> Word32
sboxRev :: Word32 -> Word32

sbox :: Word32 -> Word32
sbox Word32
0x00 = Word32
0x63
sbox Word32
0x01 = Word32
0x7C
sbox Word32
0x02 = Word32
0x77
sbox Word32
0x03 = Word32
0x7B
sbox Word32
0x04 = Word32
0xF2
sbox Word32
0x05 = Word32
0x6B
sbox Word32
0x06 = Word32
0x6F
sbox Word32
0x07 = Word32
0xC5

sbox Word32
0x08 = Word32
0x30
sbox Word32
0x09 = Word32
0x01
sbox Word32
0x0a = Word32
0x67
sbox Word32
0x0b = Word32
0x2B
sbox Word32
0x0c = Word32
0xFE
sbox Word32
0x0d = Word32
0xD7
sbox Word32
0x0e = Word32
0xAB
sbox Word32
0x0f = Word32
0x76

sbox Word32
0x10 = Word32
0xCA
sbox Word32
0x11 = Word32
0x82
sbox Word32
0x12 = Word32
0xC9
sbox Word32
0x13 = Word32
0x7D
sbox Word32
0x14 = Word32
0xFA
sbox Word32
0x15 = Word32
0x59
sbox Word32
0x16 = Word32
0x47
sbox Word32
0x17 = Word32
0xF0

sbox Word32
0x18 = Word32
0xAD
sbox Word32
0x19 = Word32
0xD4
sbox Word32
0x1a = Word32
0xA2
sbox Word32
0x1b = Word32
0xAF
sbox Word32
0x1c = Word32
0x9C
sbox Word32
0x1d = Word32
0xA4
sbox Word32
0x1e = Word32
0x72
sbox Word32
0x1f = Word32
0xC0

sbox Word32
0x20 = Word32
0xB7
sbox Word32
0x21 = Word32
0xFD
sbox Word32
0x22 = Word32
0x93
sbox Word32
0x23 = Word32
0x26
sbox Word32
0x24 = Word32
0x36
sbox Word32
0x25 = Word32
0x3F
sbox Word32
0x26 = Word32
0xF7
sbox Word32
0x27 = Word32
0xCC

sbox Word32
0x28 = Word32
0x34
sbox Word32
0x29 = Word32
0xA5
sbox Word32
0x2a = Word32
0xE5
sbox Word32
0x2b = Word32
0xF1
sbox Word32
0x2c = Word32
0x71
sbox Word32
0x2d = Word32
0xD8
sbox Word32
0x2e = Word32
0x31
sbox Word32
0x2f = Word32
0x15

sbox Word32
0x30 = Word32
0x04
sbox Word32
0x31 = Word32
0xC7
sbox Word32
0x32 = Word32
0x23
sbox Word32
0x33 = Word32
0xC3
sbox Word32
0x34 = Word32
0x18
sbox Word32
0x35 = Word32
0x96
sbox Word32
0x36 = Word32
0x05
sbox Word32
0x37 = Word32
0x9A

sbox Word32
0x38 = Word32
0x07
sbox Word32
0x39 = Word32
0x12
sbox Word32
0x3a = Word32
0x80
sbox Word32
0x3b = Word32
0xE2
sbox Word32
0x3c = Word32
0xEB
sbox Word32
0x3d = Word32
0x27
sbox Word32
0x3e = Word32
0xB2
sbox Word32
0x3f = Word32
0x75

sbox Word32
0x40 = Word32
0x09
sbox Word32
0x41 = Word32
0x83
sbox Word32
0x42 = Word32
0x2C
sbox Word32
0x43 = Word32
0x1A
sbox Word32
0x44 = Word32
0x1B
sbox Word32
0x45 = Word32
0x6E
sbox Word32
0x46 = Word32
0x5A
sbox Word32
0x47 = Word32
0xA0

sbox Word32
0x48 = Word32
0x52
sbox Word32
0x49 = Word32
0x3B
sbox Word32
0x4a = Word32
0xD6
sbox Word32
0x4b = Word32
0xB3
sbox Word32
0x4c = Word32
0x29
sbox Word32
0x4d = Word32
0xE3
sbox Word32
0x4e = Word32
0x2F
sbox Word32
0x4f = Word32
0x84

sbox Word32
0x50 = Word32
0x53
sbox Word32
0x51 = Word32
0xD1
sbox Word32
0x52 = Word32
0x00
sbox Word32
0x53 = Word32
0xED
sbox Word32
0x54 = Word32
0x20
sbox Word32
0x55 = Word32
0xFC
sbox Word32
0x56 = Word32
0xB1
sbox Word32
0x57 = Word32
0x5B

sbox Word32
0x58 = Word32
0x6A
sbox Word32
0x59 = Word32
0xCB
sbox Word32
0x5a = Word32
0xBE
sbox Word32
0x5b = Word32
0x39
sbox Word32
0x5c = Word32
0x4A
sbox Word32
0x5d = Word32
0x4C
sbox Word32
0x5e = Word32
0x58
sbox Word32
0x5f = Word32
0xCF

sbox Word32
0x60 = Word32
0xD0
sbox Word32
0x61 = Word32
0xEF
sbox Word32
0x62 = Word32
0xAA
sbox Word32
0x63 = Word32
0xFB
sbox Word32
0x64 = Word32
0x43
sbox Word32
0x65 = Word32
0x4D
sbox Word32
0x66 = Word32
0x33
sbox Word32
0x67 = Word32
0x85

sbox Word32
0x68 = Word32
0x45
sbox Word32
0x69 = Word32
0xF9
sbox Word32
0x6a = Word32
0x02
sbox Word32
0x6b = Word32
0x7F
sbox Word32
0x6c = Word32
0x50
sbox Word32
0x6d = Word32
0x3C
sbox Word32
0x6e = Word32
0x9F
sbox Word32
0x6f = Word32
0xA8

sbox Word32
0x70 = Word32
0x51
sbox Word32
0x71 = Word32
0xA3
sbox Word32
0x72 = Word32
0x40
sbox Word32
0x73 = Word32
0x8F
sbox Word32
0x74 = Word32
0x92
sbox Word32
0x75 = Word32
0x9D
sbox Word32
0x76 = Word32
0x38
sbox Word32
0x77 = Word32
0xF5

sbox Word32
0x78 = Word32
0xBC
sbox Word32
0x79 = Word32
0xB6
sbox Word32
0x7a = Word32
0xDA
sbox Word32
0x7b = Word32
0x21
sbox Word32
0x7c = Word32
0x10
sbox Word32
0x7d = Word32
0xFF
sbox Word32
0x7e = Word32
0xF3
sbox Word32
0x7f = Word32
0xD2

sbox Word32
0x80 = Word32
0xCD
sbox Word32
0x81 = Word32
0x0C
sbox Word32
0x82 = Word32
0x13
sbox Word32
0x83 = Word32
0xEC
sbox Word32
0x84 = Word32
0x5F
sbox Word32
0x85 = Word32
0x97
sbox Word32
0x86 = Word32
0x44
sbox Word32
0x87 = Word32
0x17

sbox Word32
0x88 = Word32
0xC4
sbox Word32
0x89 = Word32
0xA7
sbox Word32
0x8a = Word32
0x7E
sbox Word32
0x8b = Word32
0x3D
sbox Word32
0x8c = Word32
0x64
sbox Word32
0x8d = Word32
0x5D
sbox Word32
0x8e = Word32
0x19
sbox Word32
0x8f = Word32
0x73

sbox Word32
0x90 = Word32
0x60
sbox Word32
0x91 = Word32
0x81
sbox Word32
0x92 = Word32
0x4F
sbox Word32
0x93 = Word32
0xDC
sbox Word32
0x94 = Word32
0x22
sbox Word32
0x95 = Word32
0x2A
sbox Word32
0x96 = Word32
0x90
sbox Word32
0x97 = Word32
0x88

sbox Word32
0x98 = Word32
0x46
sbox Word32
0x99 = Word32
0xEE
sbox Word32
0x9a = Word32
0xB8
sbox Word32
0x9b = Word32
0x14
sbox Word32
0x9c = Word32
0xDE
sbox Word32
0x9d = Word32
0x5E
sbox Word32
0x9e = Word32
0x0B
sbox Word32
0x9f = Word32
0xDB

sbox Word32
0xa0 = Word32
0xE0
sbox Word32
0xa1 = Word32
0x32
sbox Word32
0xa2 = Word32
0x3A
sbox Word32
0xa3 = Word32
0x0A
sbox Word32
0xa4 = Word32
0x49
sbox Word32
0xa5 = Word32
0x06
sbox Word32
0xa6 = Word32
0x24
sbox Word32
0xa7 = Word32
0x5C

sbox Word32
0xa8 = Word32
0xC2
sbox Word32
0xa9 = Word32
0xD3
sbox Word32
0xaa = Word32
0xAC
sbox Word32
0xab = Word32
0x62
sbox Word32
0xac = Word32
0x91
sbox Word32
0xad = Word32
0x95
sbox Word32
0xae = Word32
0xE4
sbox Word32
0xaf = Word32
0x79

sbox Word32
0xb0 = Word32
0xE7
sbox Word32
0xb1 = Word32
0xC8
sbox Word32
0xb2 = Word32
0x37
sbox Word32
0xb3 = Word32
0x6D
sbox Word32
0xb4 = Word32
0x8D
sbox Word32
0xb5 = Word32
0xD5
sbox Word32
0xb6 = Word32
0x4E
sbox Word32
0xb7 = Word32
0xA9

sbox Word32
0xb8 = Word32
0x6C
sbox Word32
0xb9 = Word32
0x56
sbox Word32
0xba = Word32
0xF4
sbox Word32
0xbb = Word32
0xEA
sbox Word32
0xbc = Word32
0x65
sbox Word32
0xbd = Word32
0x7A
sbox Word32
0xbe = Word32
0xAE
sbox Word32
0xbf = Word32
0x08

sbox Word32
0xc0 = Word32
0xBA
sbox Word32
0xc1 = Word32
0x78
sbox Word32
0xc2 = Word32
0x25
sbox Word32
0xc3 = Word32
0x2E
sbox Word32
0xc4 = Word32
0x1C
sbox Word32
0xc5 = Word32
0xA6
sbox Word32
0xc6 = Word32
0xB4
sbox Word32
0xc7 = Word32
0xC6

sbox Word32
0xc8 = Word32
0xE8
sbox Word32
0xc9 = Word32
0xDD
sbox Word32
0xca = Word32
0x74
sbox Word32
0xcb = Word32
0x1F
sbox Word32
0xcc = Word32
0x4B
sbox Word32
0xcd = Word32
0xBD
sbox Word32
0xce = Word32
0x8B
sbox Word32
0xcf = Word32
0x8A

sbox Word32
0xd0 = Word32
0x70
sbox Word32
0xd1 = Word32
0x3E
sbox Word32
0xd2 = Word32
0xB5
sbox Word32
0xd3 = Word32
0x66
sbox Word32
0xd4 = Word32
0x48
sbox Word32
0xd5 = Word32
0x03
sbox Word32
0xd6 = Word32
0xF6
sbox Word32
0xd7 = Word32
0x0E

sbox Word32
0xd8 = Word32
0x61
sbox Word32
0xd9 = Word32
0x35
sbox Word32
0xda = Word32
0x57
sbox Word32
0xdb = Word32
0xB9
sbox Word32
0xdc = Word32
0x86
sbox Word32
0xdd = Word32
0xC1
sbox Word32
0xde = Word32
0x1D
sbox Word32
0xdf = Word32
0x9E

sbox Word32
0xe0 = Word32
0xE1
sbox Word32
0xe1 = Word32
0xF8
sbox Word32
0xe2 = Word32
0x98
sbox Word32
0xe3 = Word32
0x11
sbox Word32
0xe4 = Word32
0x69
sbox Word32
0xe5 = Word32
0xD9
sbox Word32
0xe6 = Word32
0x8E
sbox Word32
0xe7 = Word32
0x94

sbox Word32
0xe8 = Word32
0x9B
sbox Word32
0xe9 = Word32
0x1E
sbox Word32
0xea = Word32
0x87
sbox Word32
0xeb = Word32
0xE9
sbox Word32
0xec = Word32
0xCE
sbox Word32
0xed = Word32
0x55
sbox Word32
0xee = Word32
0x28
sbox Word32
0xef = Word32
0xDF

sbox Word32
0xf0 = Word32
0x8C
sbox Word32
0xf1 = Word32
0xA1
sbox Word32
0xf2 = Word32
0x89
sbox Word32
0xf3 = Word32
0x0D
sbox Word32
0xf4 = Word32
0xBF
sbox Word32
0xf5 = Word32
0xE6
sbox Word32
0xf6 = Word32
0x42
sbox Word32
0xf7 = Word32
0x68

sbox Word32
0xf8 = Word32
0x41
sbox Word32
0xf9 = Word32
0x99
sbox Word32
0xfa = Word32
0x2D
sbox Word32
0xfb = Word32
0x0F
sbox Word32
0xfc = Word32
0xB0
sbox Word32
0xfd = Word32
0x54
sbox Word32
0xfe = Word32
0xBB
sbox Word32
0xff = Word32
0x16

{----}

sboxRev :: Word32 -> Word32
sboxRev Word32
0x63 = Word32
0x00
sboxRev Word32
0x7C = Word32
0x01
sboxRev Word32
0x77 = Word32
0x02
sboxRev Word32
0x7B = Word32
0x03
sboxRev Word32
0xF2 = Word32
0x04
sboxRev Word32
0x6B = Word32
0x05
sboxRev Word32
0x6F = Word32
0x06
sboxRev Word32
0xC5 = Word32
0x07

sboxRev Word32
0x30 = Word32
0x08
sboxRev Word32
0x01 = Word32
0x09
sboxRev Word32
0x67 = Word32
0x0a
sboxRev Word32
0x2B = Word32
0x0b
sboxRev Word32
0xFE = Word32
0x0c
sboxRev Word32
0xD7 = Word32
0x0d
sboxRev Word32
0xAB = Word32
0x0e
sboxRev Word32
0x76 = Word32
0x0f

sboxRev Word32
0xCA = Word32
0x10
sboxRev Word32
0x82 = Word32
0x11
sboxRev Word32
0xC9 = Word32
0x12
sboxRev Word32
0x7D = Word32
0x13
sboxRev Word32
0xFA = Word32
0x14
sboxRev Word32
0x59 = Word32
0x15
sboxRev Word32
0x47 = Word32
0x16
sboxRev Word32
0xF0 = Word32
0x17

sboxRev Word32
0xAD = Word32
0x18
sboxRev Word32
0xD4 = Word32
0x19
sboxRev Word32
0xA2 = Word32
0x1a
sboxRev Word32
0xAF = Word32
0x1b
sboxRev Word32
0x9C = Word32
0x1c
sboxRev Word32
0xA4 = Word32
0x1d
sboxRev Word32
0x72 = Word32
0x1e
sboxRev Word32
0xC0 = Word32
0x1f

sboxRev Word32
0xB7 = Word32
0x20
sboxRev Word32
0xFD = Word32
0x21
sboxRev Word32
0x93 = Word32
0x22
sboxRev Word32
0x26 = Word32
0x23
sboxRev Word32
0x36 = Word32
0x24
sboxRev Word32
0x3F = Word32
0x25
sboxRev Word32
0xF7 = Word32
0x26
sboxRev Word32
0xCC = Word32
0x27

sboxRev Word32
0x34 = Word32
0x28
sboxRev Word32
0xA5 = Word32
0x29
sboxRev Word32
0xE5 = Word32
0x2a
sboxRev Word32
0xF1 = Word32
0x2b
sboxRev Word32
0x71 = Word32
0x2c
sboxRev Word32
0xD8 = Word32
0x2d
sboxRev Word32
0x31 = Word32
0x2e
sboxRev Word32
0x15 = Word32
0x2f

sboxRev Word32
0x04 = Word32
0x30
sboxRev Word32
0xC7 = Word32
0x31
sboxRev Word32
0x23 = Word32
0x32
sboxRev Word32
0xC3 = Word32
0x33
sboxRev Word32
0x18 = Word32
0x34
sboxRev Word32
0x96 = Word32
0x35
sboxRev Word32
0x05 = Word32
0x36
sboxRev Word32
0x9A = Word32
0x37

sboxRev Word32
0x07 = Word32
0x38
sboxRev Word32
0x12 = Word32
0x39
sboxRev Word32
0x80 = Word32
0x3a
sboxRev Word32
0xE2 = Word32
0x3b
sboxRev Word32
0xEB = Word32
0x3c
sboxRev Word32
0x27 = Word32
0x3d
sboxRev Word32
0xB2 = Word32
0x3e
sboxRev Word32
0x75 = Word32
0x3f

sboxRev Word32
0x09 = Word32
0x40
sboxRev Word32
0x83 = Word32
0x41
sboxRev Word32
0x2C = Word32
0x42
sboxRev Word32
0x1A = Word32
0x43
sboxRev Word32
0x1B = Word32
0x44
sboxRev Word32
0x6E = Word32
0x45
sboxRev Word32
0x5A = Word32
0x46
sboxRev Word32
0xA0 = Word32
0x47

sboxRev Word32
0x52 = Word32
0x48
sboxRev Word32
0x3B = Word32
0x49
sboxRev Word32
0xD6 = Word32
0x4a
sboxRev Word32
0xB3 = Word32
0x4b
sboxRev Word32
0x29 = Word32
0x4c
sboxRev Word32
0xE3 = Word32
0x4d
sboxRev Word32
0x2F = Word32
0x4e
sboxRev Word32
0x84 = Word32
0x4f

sboxRev Word32
0x53 = Word32
0x50
sboxRev Word32
0xD1 = Word32
0x51
sboxRev Word32
0x00 = Word32
0x52
sboxRev Word32
0xED = Word32
0x53
sboxRev Word32
0x20 = Word32
0x54
sboxRev Word32
0xFC = Word32
0x55
sboxRev Word32
0xB1 = Word32
0x56
sboxRev Word32
0x5B = Word32
0x57

sboxRev Word32
0x6A = Word32
0x58
sboxRev Word32
0xCB = Word32
0x59
sboxRev Word32
0xBE = Word32
0x5a
sboxRev Word32
0x39 = Word32
0x5b
sboxRev Word32
0x4A = Word32
0x5c
sboxRev Word32
0x4C = Word32
0x5d
sboxRev Word32
0x58 = Word32
0x5e
sboxRev Word32
0xCF = Word32
0x5f

sboxRev Word32
0xD0 = Word32
0x60
sboxRev Word32
0xEF = Word32
0x61
sboxRev Word32
0xAA = Word32
0x62
sboxRev Word32
0xFB = Word32
0x63
sboxRev Word32
0x43 = Word32
0x64
sboxRev Word32
0x4D = Word32
0x65
sboxRev Word32
0x33 = Word32
0x66
sboxRev Word32
0x85 = Word32
0x67

sboxRev Word32
0x45 = Word32
0x68
sboxRev Word32
0xF9 = Word32
0x69
sboxRev Word32
0x02 = Word32
0x6a
sboxRev Word32
0x7F = Word32
0x6b
sboxRev Word32
0x50 = Word32
0x6c
sboxRev Word32
0x3C = Word32
0x6d
sboxRev Word32
0x9F = Word32
0x6e
sboxRev Word32
0xA8 = Word32
0x6f

sboxRev Word32
0x51 = Word32
0x70
sboxRev Word32
0xA3 = Word32
0x71
sboxRev Word32
0x40 = Word32
0x72
sboxRev Word32
0x8F = Word32
0x73
sboxRev Word32
0x92 = Word32
0x74
sboxRev Word32
0x9D = Word32
0x75
sboxRev Word32
0x38 = Word32
0x76
sboxRev Word32
0xF5 = Word32
0x77

sboxRev Word32
0xBC = Word32
0x78
sboxRev Word32
0xB6 = Word32
0x79
sboxRev Word32
0xDA = Word32
0x7a
sboxRev Word32
0x21 = Word32
0x7b
sboxRev Word32
0x10 = Word32
0x7c
sboxRev Word32
0xFF = Word32
0x7d
sboxRev Word32
0xF3 = Word32
0x7e
sboxRev Word32
0xD2 = Word32
0x7f

sboxRev Word32
0xCD = Word32
0x80
sboxRev Word32
0x0C = Word32
0x81
sboxRev Word32
0x13 = Word32
0x82
sboxRev Word32
0xEC = Word32
0x83
sboxRev Word32
0x5F = Word32
0x84
sboxRev Word32
0x97 = Word32
0x85
sboxRev Word32
0x44 = Word32
0x86
sboxRev Word32
0x17 = Word32
0x87

sboxRev Word32
0xC4 = Word32
0x88
sboxRev Word32
0xA7 = Word32
0x89
sboxRev Word32
0x7E = Word32
0x8a
sboxRev Word32
0x3D = Word32
0x8b
sboxRev Word32
0x64 = Word32
0x8c
sboxRev Word32
0x5D = Word32
0x8d
sboxRev Word32
0x19 = Word32
0x8e
sboxRev Word32
0x73 = Word32
0x8f

sboxRev Word32
0x60 = Word32
0x90
sboxRev Word32
0x81 = Word32
0x91
sboxRev Word32
0x4F = Word32
0x92
sboxRev Word32
0xDC = Word32
0x93
sboxRev Word32
0x22 = Word32
0x94
sboxRev Word32
0x2A = Word32
0x95
sboxRev Word32
0x90 = Word32
0x96
sboxRev Word32
0x88 = Word32
0x97

sboxRev Word32
0x46 = Word32
0x98
sboxRev Word32
0xEE = Word32
0x99
sboxRev Word32
0xB8 = Word32
0x9a
sboxRev Word32
0x14 = Word32
0x9b
sboxRev Word32
0xDE = Word32
0x9c
sboxRev Word32
0x5E = Word32
0x9d
sboxRev Word32
0x0B = Word32
0x9e
sboxRev Word32
0xDB = Word32
0x9f

sboxRev Word32
0xE0 = Word32
0xa0
sboxRev Word32
0x32 = Word32
0xa1
sboxRev Word32
0x3A = Word32
0xa2
sboxRev Word32
0x0A = Word32
0xa3
sboxRev Word32
0x49 = Word32
0xa4
sboxRev Word32
0x06 = Word32
0xa5
sboxRev Word32
0x24 = Word32
0xa6
sboxRev Word32
0x5C = Word32
0xa7

sboxRev Word32
0xC2 = Word32
0xa8
sboxRev Word32
0xD3 = Word32
0xa9
sboxRev Word32
0xAC = Word32
0xaa
sboxRev Word32
0x62 = Word32
0xab
sboxRev Word32
0x91 = Word32
0xac
sboxRev Word32
0x95 = Word32
0xad
sboxRev Word32
0xE4 = Word32
0xae
sboxRev Word32
0x79 = Word32
0xaf

sboxRev Word32
0xE7 = Word32
0xb0
sboxRev Word32
0xC8 = Word32
0xb1
sboxRev Word32
0x37 = Word32
0xb2
sboxRev Word32
0x6D = Word32
0xb3
sboxRev Word32
0x8D = Word32
0xb4
sboxRev Word32
0xD5 = Word32
0xb5
sboxRev Word32
0x4E = Word32
0xb6
sboxRev Word32
0xA9 = Word32
0xb7

sboxRev Word32
0x6C = Word32
0xb8
sboxRev Word32
0x56 = Word32
0xb9
sboxRev Word32
0xF4 = Word32
0xba
sboxRev Word32
0xEA = Word32
0xbb
sboxRev Word32
0x65 = Word32
0xbc
sboxRev Word32
0x7A = Word32
0xbd
sboxRev Word32
0xAE = Word32
0xbe
sboxRev Word32
0x08 = Word32
0xbf

sboxRev Word32
0xBA = Word32
0xc0
sboxRev Word32
0x78 = Word32
0xc1
sboxRev Word32
0x25 = Word32
0xc2
sboxRev Word32
0x2E = Word32
0xc3
sboxRev Word32
0x1C = Word32
0xc4
sboxRev Word32
0xA6 = Word32
0xc5
sboxRev Word32
0xB4 = Word32
0xc6
sboxRev Word32
0xC6 = Word32
0xc7

sboxRev Word32
0xE8 = Word32
0xc8
sboxRev Word32
0xDD = Word32
0xc9
sboxRev Word32
0x74 = Word32
0xca
sboxRev Word32
0x1F = Word32
0xcb
sboxRev Word32
0x4B = Word32
0xcc
sboxRev Word32
0xBD = Word32
0xcd
sboxRev Word32
0x8B = Word32
0xce
sboxRev Word32
0x8A = Word32
0xcf

sboxRev Word32
0x70 = Word32
0xd0
sboxRev Word32
0x3E = Word32
0xd1
sboxRev Word32
0xB5 = Word32
0xd2
sboxRev Word32
0x66 = Word32
0xd3
sboxRev Word32
0x48 = Word32
0xd4
sboxRev Word32
0x03 = Word32
0xd5
sboxRev Word32
0xF6 = Word32
0xd6
sboxRev Word32
0x0E = Word32
0xd7

sboxRev Word32
0x61 = Word32
0xd8
sboxRev Word32
0x35 = Word32
0xd9
sboxRev Word32
0x57 = Word32
0xda
sboxRev Word32
0xB9 = Word32
0xdb
sboxRev Word32
0x86 = Word32
0xdc
sboxRev Word32
0xC1 = Word32
0xdd
sboxRev Word32
0x1D = Word32
0xde
sboxRev Word32
0x9E = Word32
0xdf

sboxRev Word32
0xE1 = Word32
0xe0
sboxRev Word32
0xF8 = Word32
0xe1
sboxRev Word32
0x98 = Word32
0xe2
sboxRev Word32
0x11 = Word32
0xe3
sboxRev Word32
0x69 = Word32
0xe4
sboxRev Word32
0xD9 = Word32
0xe5
sboxRev Word32
0x8E = Word32
0xe6
sboxRev Word32
0x94 = Word32
0xe7

sboxRev Word32
0x9B = Word32
0xe8
sboxRev Word32
0x1E = Word32
0xe9
sboxRev Word32
0x87 = Word32
0xea
sboxRev Word32
0xE9 = Word32
0xeb
sboxRev Word32
0xCE = Word32
0xec
sboxRev Word32
0x55 = Word32
0xed
sboxRev Word32
0x28 = Word32
0xee
sboxRev Word32
0xDF = Word32
0xef

sboxRev Word32
0x8C = Word32
0xf0
sboxRev Word32
0xA1 = Word32
0xf1
sboxRev Word32
0x89 = Word32
0xf2
sboxRev Word32
0x0D = Word32
0xf3
sboxRev Word32
0xBF = Word32
0xf4
sboxRev Word32
0xE6 = Word32
0xf5
sboxRev Word32
0x42 = Word32
0xf6
sboxRev Word32
0x68 = Word32
0xf7

sboxRev Word32
0x41 = Word32
0xf8
sboxRev Word32
0x99 = Word32
0xf9
sboxRev Word32
0x2D = Word32
0xfa
sboxRev Word32
0x0F = Word32
0xfb
sboxRev Word32
0xB0 = Word32
0xfc
sboxRev Word32
0x54 = Word32
0xfd
sboxRev Word32
0xBB = Word32
0xfe
sboxRev Word32
0x16 = Word32
0xff

xtime :: Word32 -> Word32
xtime :: Word32 -> Word32
xtime Word32
x = Word32
b
        where   a :: Word32
a = Word32
x forall a. Bits a => a -> Int -> a
`shiftL` Int
1
                b :: Word32
b = if Word32
a forall a. Bits a => a -> a -> a
.&. (Word32
0x0100) forall a. Eq a => a -> a -> Bool
== Word32
0 then Word32
a else Word32
a forall a. Bits a => a -> a -> a
`xor` Word32
0x11b

xtimeX2 :: Word32 -> Word32
--xtimeX2 = xtime . xtime
xtimeX2 :: Word32 -> Word32
xtimeX2 Word32
x = Word32
c
        where   a :: Word32
a = Word32
x forall a. Bits a => a -> Int -> a
`shiftL` Int
2
                b :: Word32
b = if Word32
a forall a. Bits a => a -> a -> a
.&. (Word32
0x0200) forall a. Eq a => a -> a -> Bool
== Word32
0 then Word32
a else Word32
a forall a. Bits a => a -> a -> a
`xor` Word32
0x236
                c :: Word32
c = if Word32
b forall a. Bits a => a -> a -> a
.&. (Word32
0x0100) forall a. Eq a => a -> a -> Bool
== Word32
0 then Word32
b else Word32
b forall a. Bits a => a -> a -> a
`xor` Word32
0x11b

xtimeX3 :: Word32 -> Word32
--xtimeX3 = xtime . xtime . xtime
xtimeX3 :: Word32 -> Word32
xtimeX3 Word32
x = Word32
d
        where   a :: Word32
a = Word32
x forall a. Bits a => a -> Int -> a
`shiftL` Int
3
                b :: Word32
b = if Word32
a forall a. Bits a => a -> a -> a
.&. (Word32
0x0400) forall a. Eq a => a -> a -> Bool
== Word32
0 then Word32
a else Word32
a forall a. Bits a => a -> a -> a
`xor` Word32
0x46c
                c :: Word32
c = if Word32
b forall a. Bits a => a -> a -> a
.&. (Word32
0x0200) forall a. Eq a => a -> a -> Bool
== Word32
0 then Word32
b else Word32
b forall a. Bits a => a -> a -> a
`xor` Word32
0x236
                d :: Word32
d = if Word32
c forall a. Bits a => a -> a -> a
.&. (Word32
0x0100) forall a. Eq a => a -> a -> Bool
== Word32
0 then Word32
c else Word32
c forall a. Bits a => a -> a -> a
`xor` Word32
0x11b

xtime03 :: Word32 -> Word32
xtime03 :: Word32 -> Word32
xtime03 Word32
x = Word32
x forall a. Bits a => a -> a -> a
`xor` (Word32 -> Word32
xtime Word32
x)

xtime0e :: Word32 -> Word32
xtime0e :: Word32 -> Word32
xtime0e Word32
x = Word32 -> Word32
xtime (Word32
x forall a. Bits a => a -> a -> a
`xor` (Word32 -> Word32
xtime (Word32
x forall a. Bits a => a -> a -> a
`xor` (Word32 -> Word32
xtime Word32
x))))

xtime09 :: Word32 -> Word32
xtime09 :: Word32 -> Word32
xtime09 Word32
x = Word32
x forall a. Bits a => a -> a -> a
`xor` (Word32 -> Word32
xtimeX3 Word32
x)

xtime0d :: Word32 -> Word32
xtime0d :: Word32 -> Word32
xtime0d Word32
x = Word32
x forall a. Bits a => a -> a -> a
`xor` (Word32 -> Word32
xtimeX2 (Word32
x forall a. Bits a => a -> a -> a
`xor` (Word32 -> Word32
xtime Word32
x)))

xtime0b :: Word32 -> Word32
xtime0b :: Word32 -> Word32
xtime0b Word32
x = Word32
x forall a. Bits a => a -> a -> a
`xor` (Word32 -> Word32
xtime (Word32
x forall a. Bits a => a -> a -> a
`xor` (Word32 -> Word32
xtimeX2 Word32
x)))

generateKey :: Int -> Int -> Word32 -> Word32 -> Word32
generateKey :: Int -> Int -> Word32 -> Word32 -> Word32
generateKey Int
nk Int
i Word32
wIminus1 Word32
wIminusNk =
                (Word32
temp' forall a. Bits a => a -> a -> a
`xor` Word32
wIminusNk)
        where temp' :: Word32
temp' =
                if (Int
i forall a. Integral a => a -> a -> a
`mod` Int
nk) forall a. Eq a => a -> a -> Bool
== Int
0 then (Word32 -> Word32
subword(Word32 -> Word32
rotword Word32
temp)) forall a. Bits a => a -> a -> a
`xor` Word32
rcon
                else if (Int
nk forall a. Ord a => a -> a -> Bool
> Int
6) Bool -> Bool -> Bool
&& ((Int
i forall a. Integral a => a -> a -> a
`mod` Int
nk) forall a. Eq a => a -> a -> Bool
== Int
4) then Word32 -> Word32
subword Word32
temp
                else Word32
temp
              temp :: Word32
temp = Word32
wIminus1
              subword :: Word32 -> Word32
              subword :: Word32 -> Word32
subword Word32
w = (Word32
a forall a. Bits a => a -> Int -> a
`shiftL` Int
24) forall a. Bits a => a -> a -> a
.|. (Word32
b forall a. Bits a => a -> Int -> a
`shiftL` Int
16) forall a. Bits a => a -> a -> a
.|.
                          (Word32
c forall a. Bits a => a -> Int -> a
`shiftL` Int
8) forall a. Bits a => a -> a -> a
.|. Word32
d
                          where a :: Word32
a = Word32 -> Word32
sbox ((Word32
w forall a. Bits a => a -> Int -> a
`shiftR` Int
24) forall a. Bits a => a -> a -> a
.&. Word32
0xff)
                                b :: Word32
b = Word32 -> Word32
sbox ((Word32
w forall a. Bits a => a -> Int -> a
`shiftR` Int
16) forall a. Bits a => a -> a -> a
.&. Word32
0xff)
                                c :: Word32
c = Word32 -> Word32
sbox ((Word32
w forall a. Bits a => a -> Int -> a
`shiftR`  Int
8) forall a. Bits a => a -> a -> a
.&. Word32
0xff)
                                d :: Word32
d = Word32 -> Word32
sbox ( Word32
w             forall a. Bits a => a -> a -> a
.&. Word32
0xff)
              rotword :: Word32 -> Word32
              rotword :: Word32 -> Word32
rotword Word32
w = Word32
w forall a. Bits a => a -> Int -> a
`rotateL` Int
8
              rcon :: Word32
              rcon :: Word32
rcon = ((forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
rconMSB)::Word32) forall a. Bits a => a -> Int -> a
`shiftL` Int
24
              rconMSB :: Word32
rconMSB = (forall a. (a -> a) -> a -> [a]
iterate Word32 -> Word32
xtime Word32
0x01) forall a. [a] -> Int -> a
!! ((Int
i forall a. Integral a => a -> a -> a
`div` Int
nk) forall a. Num a => a -> a -> a
- Int
1)

wordify :: [Octet] -> [Word32]
wordify :: [Octet] -> [Word32]
wordify [] = []
wordify [Octet]
octets = Word32
firstWordforall a. a -> [a] -> [a]
:[Word32]
otherWords
        where
                (Word32
firstWord, [Octet]
otherOctets) = [Octet] -> (Word32, [Octet])
getWord32 [Octet]
octets
                otherWords :: [Word32]
otherWords = [Octet] -> [Word32]
wordify [Octet]
otherOctets

generateKeys :: Int -> Int -> [Octet] -> [Word32]
generateKeys :: Int -> Int -> [Octet] -> [Word32]
generateKeys Int
nr Int
nk [Octet]
mainKey =
                -- assert ((nk * 4) == length mainKey) $
                (forall a. Int -> [a] -> [a]
take (Int
4 forall a. Num a => a -> a -> a
* (Int
nr forall a. Num a => a -> a -> a
+ Int
1)) [Word32]
xs)
        where
                xs :: [Word32]
xs = ([Octet] -> [Word32]
wordify [Octet]
mainKey) forall a. [a] -> [a] -> [a]
++ (forall a b c d. (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
zipWith3 (Int -> Int -> Word32 -> Word32 -> Word32
generateKey Int
nk)
                                                (forall a. Int -> [a] -> [a]
drop Int
nk [Int
0,Int
1..])
                                                (forall a. Int -> [a] -> [a]
drop (Int
nk forall a. Num a => a -> a -> a
- Int
1) [Word32]
xs)
                                                [Word32]
xs
                                        )

subBytes :: State -> State
subBytes :: State -> State
subBytes (State (Word32
s00, Word32
s01, Word32
s02, Word32
s03)
                (Word32
s10, Word32
s11, Word32
s12, Word32
s13)
                (Word32
s20, Word32
s21, Word32
s22, Word32
s23)
                (Word32
s30, Word32
s31, Word32
s32, Word32
s33)) =
          (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
-> State
State (Word32 -> Word32
sbox Word32
s00, Word32 -> Word32
sbox Word32
s01, Word32 -> Word32
sbox Word32
s02, Word32 -> Word32
sbox Word32
s03)
                (Word32 -> Word32
sbox Word32
s10, Word32 -> Word32
sbox Word32
s11, Word32 -> Word32
sbox Word32
s12, Word32 -> Word32
sbox Word32
s13)
                (Word32 -> Word32
sbox Word32
s20, Word32 -> Word32
sbox Word32
s21, Word32 -> Word32
sbox Word32
s22, Word32 -> Word32
sbox Word32
s23)
                (Word32 -> Word32
sbox Word32
s30, Word32 -> Word32
sbox Word32
s31, Word32 -> Word32
sbox Word32
s32, Word32 -> Word32
sbox Word32
s33)

subBytesRev :: State -> State
subBytesRev :: State -> State
subBytesRev (State (Word32
s00, Word32
s01, Word32
s02, Word32
s03)
                   (Word32
s10, Word32
s11, Word32
s12, Word32
s13)
                   (Word32
s20, Word32
s21, Word32
s22, Word32
s23)
                   (Word32
s30, Word32
s31, Word32
s32, Word32
s33)) =
          (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
-> State
State (Word32 -> Word32
sboxRev Word32
s00, Word32 -> Word32
sboxRev Word32
s01, Word32 -> Word32
sboxRev Word32
s02, Word32 -> Word32
sboxRev Word32
s03)
                (Word32 -> Word32
sboxRev Word32
s10, Word32 -> Word32
sboxRev Word32
s11, Word32 -> Word32
sboxRev Word32
s12, Word32 -> Word32
sboxRev Word32
s13)
                (Word32 -> Word32
sboxRev Word32
s20, Word32 -> Word32
sboxRev Word32
s21, Word32 -> Word32
sboxRev Word32
s22, Word32 -> Word32
sboxRev Word32
s23)
                (Word32 -> Word32
sboxRev Word32
s30, Word32 -> Word32
sboxRev Word32
s31, Word32 -> Word32
sboxRev Word32
s32, Word32 -> Word32
sboxRev Word32
s33)

shiftRows :: State -> State
shiftRows :: State -> State
shiftRows (State (Word32
s00, Word32
s01, Word32
s02, Word32
s03)
                 (Word32
s10, Word32
s11, Word32
s12, Word32
s13)
                 (Word32
s20, Word32
s21, Word32
s22, Word32
s23)
                 (Word32
s30, Word32
s31, Word32
s32, Word32
s33)) =
          (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
-> State
State (Word32
s00, Word32
s01, Word32
s02, Word32
s03)
                (Word32
s11, Word32
s12, Word32
s13, Word32
s10)
                (Word32
s22, Word32
s23, Word32
s20, Word32
s21)
                (Word32
s33, Word32
s30, Word32
s31, Word32
s32)

shiftRowsRev :: State -> State
shiftRowsRev :: State -> State
shiftRowsRev (State (Word32
s00, Word32
s01, Word32
s02, Word32
s03)
                    (Word32
s10, Word32
s11, Word32
s12, Word32
s13)
                    (Word32
s20, Word32
s21, Word32
s22, Word32
s23)
                    (Word32
s30, Word32
s31, Word32
s32, Word32
s33)) =
          (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
-> State
State (Word32
s00, Word32
s01, Word32
s02, Word32
s03)
                (Word32
s13, Word32
s10, Word32
s11, Word32
s12)
                (Word32
s22, Word32
s23, Word32
s20, Word32
s21)
                (Word32
s31, Word32
s32, Word32
s33, Word32
s30)

mixColumn:: (Word32, Word32, Word32, Word32) -> (Word32, Word32, Word32, Word32)
mixColumn :: (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
mixColumn (Word32
s0,Word32
s1,Word32
s2,Word32
s3) =
        ((Word32 -> Word32
xtime   Word32
s0) forall a. Bits a => a -> a -> a
`xor` (Word32 -> Word32
xtime03 Word32
s1) forall a. Bits a => a -> a -> a
`xor`          Word32
s2  forall a. Bits a => a -> a -> a
`xor`          Word32
s3 ,
                  Word32
s0  forall a. Bits a => a -> a -> a
`xor` (Word32 -> Word32
xtime   Word32
s1) forall a. Bits a => a -> a -> a
`xor` (Word32 -> Word32
xtime03 Word32
s2) forall a. Bits a => a -> a -> a
`xor`          Word32
s3 ,
                  Word32
s0  forall a. Bits a => a -> a -> a
`xor`          Word32
s1  forall a. Bits a => a -> a -> a
`xor` (Word32 -> Word32
xtime   Word32
s2) forall a. Bits a => a -> a -> a
`xor` (Word32 -> Word32
xtime03 Word32
s3),
         (Word32 -> Word32
xtime03 Word32
s0) forall a. Bits a => a -> a -> a
`xor`          Word32
s1  forall a. Bits a => a -> a -> a
`xor`          Word32
s2  forall a. Bits a => a -> a -> a
`xor` (Word32 -> Word32
xtime   Word32
s3))

mixColumns :: State -> State
mixColumns :: State -> State
mixColumns (State (Word32
s00, Word32
s01, Word32
s02, Word32
s03)
                  (Word32
s10, Word32
s11, Word32
s12, Word32
s13)
                  (Word32
s20, Word32
s21, Word32
s22, Word32
s23)
                  (Word32
s30, Word32
s31, Word32
s32, Word32
s33)) =
          (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
-> State
State (Word32
r00, Word32
r01, Word32
r02, Word32
r03)
                (Word32
r10, Word32
r11, Word32
r12, Word32
r13)
                (Word32
r20, Word32
r21, Word32
r22, Word32
r23)
                (Word32
r30, Word32
r31, Word32
r32, Word32
r33)
        where (Word32
r00, Word32
r10, Word32
r20, Word32
r30) = (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
mixColumn (Word32
s00, Word32
s10, Word32
s20, Word32
s30)
              (Word32
r01, Word32
r11, Word32
r21, Word32
r31) = (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
mixColumn (Word32
s01, Word32
s11, Word32
s21, Word32
s31)
              (Word32
r02, Word32
r12, Word32
r22, Word32
r32) = (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
mixColumn (Word32
s02, Word32
s12, Word32
s22, Word32
s32)
              (Word32
r03, Word32
r13, Word32
r23, Word32
r33) = (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
mixColumn (Word32
s03, Word32
s13, Word32
s23, Word32
s33)

mixColumnRev :: (Word32, Word32, Word32, Word32)
                -> (Word32, Word32, Word32, Word32)
mixColumnRev :: (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
mixColumnRev (Word32
s0,Word32
s1,Word32
s2,Word32
s3) =
        ((Word32 -> Word32
xtime0e Word32
s0) forall a. Bits a => a -> a -> a
`xor` (Word32 -> Word32
xtime0b Word32
s1) forall a. Bits a => a -> a -> a
`xor` (Word32 -> Word32
xtime0d Word32
s2) forall a. Bits a => a -> a -> a
`xor` (Word32 -> Word32
xtime09 Word32
s3),
         (Word32 -> Word32
xtime09 Word32
s0) forall a. Bits a => a -> a -> a
`xor` (Word32 -> Word32
xtime0e Word32
s1) forall a. Bits a => a -> a -> a
`xor` (Word32 -> Word32
xtime0b Word32
s2) forall a. Bits a => a -> a -> a
`xor` (Word32 -> Word32
xtime0d Word32
s3),
         (Word32 -> Word32
xtime0d Word32
s0) forall a. Bits a => a -> a -> a
`xor` (Word32 -> Word32
xtime09 Word32
s1) forall a. Bits a => a -> a -> a
`xor` (Word32 -> Word32
xtime0e Word32
s2) forall a. Bits a => a -> a -> a
`xor` (Word32 -> Word32
xtime0b Word32
s3),
         (Word32 -> Word32
xtime0b Word32
s0) forall a. Bits a => a -> a -> a
`xor` (Word32 -> Word32
xtime0d Word32
s1) forall a. Bits a => a -> a -> a
`xor` (Word32 -> Word32
xtime09 Word32
s2) forall a. Bits a => a -> a -> a
`xor` (Word32 -> Word32
xtime0e Word32
s3))

mixColumnsRev :: State -> State
mixColumnsRev :: State -> State
mixColumnsRev (State (Word32
s00, Word32
s01, Word32
s02, Word32
s03)
                  (Word32
s10, Word32
s11, Word32
s12, Word32
s13)
                  (Word32
s20, Word32
s21, Word32
s22, Word32
s23)
                  (Word32
s30, Word32
s31, Word32
s32, Word32
s33)) =
          (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
-> State
State (Word32
r00, Word32
r01, Word32
r02, Word32
r03)
                (Word32
r10, Word32
r11, Word32
r12, Word32
r13)
                (Word32
r20, Word32
r21, Word32
r22, Word32
r23)
                (Word32
r30, Word32
r31, Word32
r32, Word32
r33)
        where (Word32
r00, Word32
r10, Word32
r20, Word32
r30) = (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
mixColumnRev (Word32
s00, Word32
s10, Word32
s20, Word32
s30)
              (Word32
r01, Word32
r11, Word32
r21, Word32
r31) = (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
mixColumnRev (Word32
s01, Word32
s11, Word32
s21, Word32
s31)
              (Word32
r02, Word32
r12, Word32
r22, Word32
r32) = (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
mixColumnRev (Word32
s02, Word32
s12, Word32
s22, Word32
s32)
              (Word32
r03, Word32
r13, Word32
r23, Word32
r33) = (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
mixColumnRev (Word32
s03, Word32
s13, Word32
s23, Word32
s33)

addRoundKey :: State -> State -> State
addRoundKey :: State -> State -> State
addRoundKey (State (Word32
k00, Word32
k01, Word32
k02, Word32
k03)
                   (Word32
k10, Word32
k11, Word32
k12, Word32
k13)
                   (Word32
k20, Word32
k21, Word32
k22, Word32
k23)
                   (Word32
k30, Word32
k31, Word32
k32, Word32
k33))
            (State (Word32
s00, Word32
s01, Word32
s02, Word32
s03)
                   (Word32
s10, Word32
s11, Word32
s12, Word32
s13)
                   (Word32
s20, Word32
s21, Word32
s22, Word32
s23)
                   (Word32
s30, Word32
s31, Word32
s32, Word32
s33)) =
          (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
-> State
State (Word32
s00 forall a. Bits a => a -> a -> a
`xor` Word32
k00, Word32
s01 forall a. Bits a => a -> a -> a
`xor` Word32
k01, Word32
s02 forall a. Bits a => a -> a -> a
`xor` Word32
k02, Word32
s03 forall a. Bits a => a -> a -> a
`xor` Word32
k03)
                (Word32
s10 forall a. Bits a => a -> a -> a
`xor` Word32
k10, Word32
s11 forall a. Bits a => a -> a -> a
`xor` Word32
k11, Word32
s12 forall a. Bits a => a -> a -> a
`xor` Word32
k12, Word32
s13 forall a. Bits a => a -> a -> a
`xor` Word32
k13)
                (Word32
s20 forall a. Bits a => a -> a -> a
`xor` Word32
k20, Word32
s21 forall a. Bits a => a -> a -> a
`xor` Word32
k21, Word32
s22 forall a. Bits a => a -> a -> a
`xor` Word32
k22, Word32
s23 forall a. Bits a => a -> a -> a
`xor` Word32
k23)
                (Word32
s30 forall a. Bits a => a -> a -> a
`xor` Word32
k30, Word32
s31 forall a. Bits a => a -> a -> a
`xor` Word32
k31, Word32
s32 forall a. Bits a => a -> a -> a
`xor` Word32
k32, Word32
s33 forall a. Bits a => a -> a -> a
`xor` Word32
k33)

genAddRoundKey :: [Word32] -> [State -> State]
genAddRoundKey :: [Word32] -> [State -> State]
genAddRoundKey [] = []
genAddRoundKey (Word32
a:Word32
b:Word32
c:Word32
d:[Word32]
ks) = (State -> State -> State
addRoundKey State
k)forall a. a -> [a] -> [a]
:([Word32] -> [State -> State]
genAddRoundKey [Word32]
ks)
        where k :: State
k = (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
-> (Word32, Word32, Word32, Word32)
-> State
State (forall a b. (Integral a, Num b) => a -> b
fromIntegral Octet
s00, forall a b. (Integral a, Num b) => a -> b
fromIntegral Octet
s01,
                         forall a b. (Integral a, Num b) => a -> b
fromIntegral Octet
s02, forall a b. (Integral a, Num b) => a -> b
fromIntegral Octet
s03)
                        (forall a b. (Integral a, Num b) => a -> b
fromIntegral Octet
s10, forall a b. (Integral a, Num b) => a -> b
fromIntegral Octet
s11,
                         forall a b. (Integral a, Num b) => a -> b
fromIntegral Octet
s12, forall a b. (Integral a, Num b) => a -> b
fromIntegral Octet
s13)
                        (forall a b. (Integral a, Num b) => a -> b
fromIntegral Octet
s20, forall a b. (Integral a, Num b) => a -> b
fromIntegral Octet
s21,
                         forall a b. (Integral a, Num b) => a -> b
fromIntegral Octet
s22, forall a b. (Integral a, Num b) => a -> b
fromIntegral Octet
s23)
                        (forall a b. (Integral a, Num b) => a -> b
fromIntegral Octet
s30, forall a b. (Integral a, Num b) => a -> b
fromIntegral Octet
s31,
                         forall a b. (Integral a, Num b) => a -> b
fromIntegral Octet
s32, forall a b. (Integral a, Num b) => a -> b
fromIntegral Octet
s33)
              [Octet
s00, Octet
s10, Octet
s20, Octet
s30] = Word32 -> [Octet]
putWord32 Word32
a
              [Octet
s01, Octet
s11, Octet
s21, Octet
s31] = Word32 -> [Octet]
putWord32 Word32
b
              [Octet
s02, Octet
s12, Octet
s22, Octet
s32] = Word32 -> [Octet]
putWord32 Word32
c
              [Octet
s03, Octet
s13, Octet
s23, Octet
s33] = Word32 -> [Octet]
putWord32 Word32
d

getWord32 :: [Octet] -> (Word32, [Octet])
getWord32 :: [Octet] -> (Word32, [Octet])
getWord32 (Octet
a:Octet
b:Octet
c:Octet
d:[Octet]
xs) = (Word32
x, [Octet]
xs)
        where
                x :: Word32
x = ((forall a b. (Integral a, Num b) => a -> b
fromIntegral Octet
a) forall a. Bits a => a -> Int -> a
`shiftL` Int
24) forall a. Bits a => a -> a -> a
.|.
                    ((forall a b. (Integral a, Num b) => a -> b
fromIntegral Octet
b) forall a. Bits a => a -> Int -> a
`shiftL` Int
16) forall a. Bits a => a -> a -> a
.|.
                    ((forall a b. (Integral a, Num b) => a -> b
fromIntegral Octet
c) forall a. Bits a => a -> Int -> a
`shiftL`  Int
8) forall a. Bits a => a -> a -> a
.|.
                    ((forall a b. (Integral a, Num b) => a -> b
fromIntegral Octet
d)            )

putWord32 :: Word32 -> [Octet]
--a bit slower putWord32 x = map fromIntegral [a,b,c,d]
putWord32 :: Word32 -> [Octet]
putWord32 Word32
x = [forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
a, forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
b, forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
c, forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
d]
        where
                a :: Word32
a = (Word32
x forall a. Bits a => a -> Int -> a
`shiftR` Int
24)
                b :: Word32
b = (Word32
x forall a. Bits a => a -> Int -> a
`shiftR` Int
16) forall a. Bits a => a -> a -> a
.&. Word32
255
                c :: Word32
c = (Word32
x forall a. Bits a => a -> Int -> a
`shiftR`  Int
8) forall a. Bits a => a -> a -> a
.&. Word32
255
                d :: Word32
d = (Word32
x            ) forall a. Bits a => a -> a -> a
.&. Word32
255

{-
testGenerateKeys128 :: Test
testGenerateKeys128 =
        let key = [0x2b, 0x7e, 0x15, 0x16,
                   0x28, 0xae, 0xd2, 0xa6,
                   0xab, 0xf7, 0x15, 0x88,
                   0x09, 0xcf, 0x4f, 0x3c]
            expected = [0x2b7e1516, 0x28aed2a6, 0xabf71588, 0x09cf4f3c,
                        0xa0fafe17, 0x88542cb1, 0x23a33939, 0x2a6c7605,
                        0xf2c295f2, 0x7a96b943, 0x5935807a, 0x7359f67f,
                        0x3d80477d, 0x4716fe3e, 0x1e237e44, 0x6d7a883b,
                        0xef44a541, 0xa8525b7f, 0xb671253b, 0xdb0bad00,
                        0xd4d1c6f8, 0x7c839d87, 0xcaf2b8bc, 0x11f915bc,
                        0x6d88a37a, 0x110b3efd, 0xdbf98641, 0xca0093fd,
                        0x4e54f70e, 0x5f5fc9f3, 0x84a64fb2, 0x4ea6dc4f,
                        0xead27321, 0xb58dbad2, 0x312bf560, 0x7f8d292f,
                        0xac7766f3, 0x19fadc21, 0x28d12941, 0x575c006e,
                        0xd014f9a8, 0xc9ee2589, 0xe13f0cc8, 0xb6630ca6
                        ]
        in TestCase (do
                assertEqual "" expected (generateKeys 10 4 key)
        )


testGenerateKeys192 :: Test
testGenerateKeys192 =
        let key = [0x8e, 0x73, 0xb0, 0xf7,
                   0xda, 0x0e, 0x64, 0x52,
                   0xc8, 0x10, 0xf3, 0x2b,
                   0x80, 0x90, 0x79, 0xe5,
                   0x62, 0xf8, 0xea, 0xd2,
                   0x52, 0x2c, 0x6b, 0x7b]
            expected = [0x8e73b0f7, 0xda0e6452, 0xc810f32b, 0x809079e5,
                        0x62f8ead2, 0x522c6b7b, 0xfe0c91f7, 0x2402f5a5,
                        0xec12068e, 0x6c827f6b, 0x0e7a95b9, 0x5c56fec2,
                        0x4db7b4bd, 0x69b54118, 0x85a74796, 0xe92538fd,
                        0xe75fad44, 0xbb095386, 0x485af057, 0x21efb14f
                        ]
        in TestCase (do
                assertEqual "" expected
                        (take (length expected) (generateKeys 12 6 key))
        )

testGenerateKeys256 :: Test
testGenerateKeys256 =
        let key = [0x60, 0x3d, 0xeb, 0x10,
                   0x15, 0xca, 0x71, 0xbe,
                   0x2b, 0x73, 0xae, 0xf0,
                   0x85, 0x7d, 0x77, 0x81,
                   0x1f, 0x35, 0x2c, 0x07,
                   0x3b, 0x61, 0x08, 0xd7,
                   0x2d, 0x98, 0x10, 0xa3,
                   0x09, 0x14, 0xdf, 0xf4]
            expected = [0x603deb10, 0x15ca71be, 0x2b73aef0, 0x857d7781,
                        0x1f352c07, 0x3b6108d7, 0x2d9810a3, 0x0914dff4,
                        0x9ba35411, 0x8e6925af, 0xa51a8b5f, 0x2067fcde,
                        0xa8b09c1a, 0x93d194cd, 0xbe49846e, 0xb75d5b9a,
                        0xd59aecb8, 0x5bf3c917, 0xfee94248, 0xde8ebe96
                        ]
        in TestCase (do
                assertEqual "" expected
                        (take (length expected) (generateKeys 14 8 key))
        )

testAes128 :: Test
testAes128 =
        let key = [0x2b, 0x7e, 0x15, 0x16,
                   0x28, 0xae, 0xd2, 0xa6,
                   0xab, 0xf7, 0x15, 0x88,
                   0x09, 0xcf, 0x4f, 0x3c]
            input = [0x32, 0x43, 0xf6, 0xa8,
                     0x88, 0x5a, 0x30, 0x8d,
                     0x31, 0x31, 0x98, 0xa2,
                     0xe0, 0x37, 0x07, 0x34]
            output = [0x39, 0x25, 0x84, 0x1d,
                      0x02, 0xdc, 0x09, 0xfb,
                      0xdc, 0x11, 0x85, 0x97,
                      0x19, 0x6a, 0x0b, 0x32]
        in TestCase (do
                assertEqual "encrypt test" output (aes128Encrypt key input)
                assertEqual "encrypt/decrypt test" input
                                (aes128Decrypt key (aes128Encrypt key input))
        )

testAesRandom :: Test
testAesRandom =
        TestCase (do
                key128 <- getRandomOctets 16
                key192 <- getRandomOctets 24
                key256 <- getRandomOctets 32
                msg <- getRandomOctets 16
                assertEqual "aes128" msg
                        (aes128Decrypt key128 (aes128Encrypt key128 msg))
                assertEqual "aes192" msg
                        (aes192Decrypt key192 (aes192Encrypt key192 msg))
                assertEqual "aes256" msg
                        (aes256Decrypt key256 (aes256Encrypt key256 msg))
        )

-- | HUnit tests
tests :: Test
tests = TestList [
                TestLabel "testGenerateKeys128" testGenerateKeys128,
                TestLabel "testGenerateKeys192" testGenerateKeys192,
                TestLabel "testGenerateKeys256" testGenerateKeys256,
                TestLabel "testAes128" testAes128,
                TestLabel "testAesRandom" testAesRandom
        ]
-}