    -----------------------------------------------------------------------------
    -- |
    -- Module    : Cryptol.AES
    -- Copyright : (c) Levent Erkok
    -- License   : BSD3
    -- Maintainer: erkokl@gmail.com
    -- Stability : experimental
    --
    -- A TBox-based implementation of AES primitives, based on
    -- the AES example code from SBV.  Here we've stripped out
    -- everything except the basic primitives needed, which
    -- essentially boil down to table table lookups in most cases.
    -----------------------------------------------------------------------------
    {-# LANGUAGE ParallelListComp #-}
    module Cryptol.AES
      ( State
      , Key
      , keyExpansionWords
      , invMixColumns
      , aesRound
      , aesFinalRound
      , aesInvRound
      , aesInvFinalRound
      ) where

    import Data.Bits
    import Data.List (transpose, genericDrop, genericTake)
    import Data.Word (Word8, Word32)

    -- | An element of the Galois Field 2^8, which are essentially polynomials with
    -- maximum degree 7. They are conveniently represented as values between 0 and 255.
    type GF28 = Word8

    -----------------------------------------------------------------------------
    -- ** Types and basic operations
    -----------------------------------------------------------------------------
    -- | AES state. The state consists of four 32-bit words, each of which is in turn treated
    -- as four GF28's, i.e., 4 bytes. The T-Box implementation keeps the four-bytes together
    -- for efficient representation.
    type State = [Word32]

    -- | The key, which can be 128, 192, or 256 bits. Represented as a sequence of 32-bit words.
    type Key = [Word32]

    -- | Rotating a state row by a fixed amount to the right.
    rotR :: [GF28] -> Int -> [GF28]
    rotR :: [GF28] -> Int -> [GF28]
    rotR [GF28
    a, GF28
    b, GF28
    c, GF28
    d] Int
    1 = [GF28
    d, GF28
    a, GF28
    b, GF28
    c]
    rotR [GF28
    a, GF28
    b, GF28
    c, GF28
    d] Int
    2 = [GF28
    c, GF28
    d, GF28
    a, GF28
    b]
    rotR [GF28
    a, GF28
    b, GF28
    c, GF28
    d] Int
    3 = [GF28
    b, GF28
    c, GF28
    d, GF28
    a]
    rotR [GF28]
    xs           Int
    i = [Char] -> [GF28]
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> [GF28]) -> [Char] -> [GF28]
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "rotR: Unexpected input: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ ([GF28], Int) -> [Char]
    forall a. Show a => a -> [Char]
    show ([GF28]
    xs, Int
    i)

    toBytes :: Word32 -> [Word8]
    toBytes :: Word32 -> [GF28]
    toBytes Word32
    w = [GF28
    b0,GF28
    b1,GF28
    b2,GF28
    b3]
      where
      b0 :: GF28
    b0 = Word32 -> GF28
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Word32
    w Word32 -> Int -> Word32
    forall a. Bits a => a -> Int -> a
    `shiftR` Int
    24)
      b1 :: GF28
    b1 = Word32 -> GF28
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Word32
    w Word32 -> Int -> Word32
    forall a. Bits a => a -> Int -> a
    `shiftR` Int
    16)
      b2 :: GF28
    b2 = Word32 -> GF28
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Word32
    w Word32 -> Int -> Word32
    forall a. Bits a => a -> Int -> a
    `shiftR`  Int
    8)
      b3 :: GF28
    b3 = Word32 -> GF28
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral  Word32
    w

    fromBytes :: [Word8] -> Word32
    fromBytes :: [GF28] -> Word32
    fromBytes [GF28
    b0,GF28
    b1,GF28
    b2,GF28
    b3] = Word32
    w
      where
      w :: Word32
    w = ((GF28 -> Word32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral GF28
    b0) Word32 -> Int -> Word32
    forall a. Bits a => a -> Int -> a
    `shiftL` Int
    24) Word32 -> Word32 -> Word32
    forall a. Bits a => a -> a -> a
    .|.
          ((GF28 -> Word32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral GF28
    b1) Word32 -> Int -> Word32
    forall a. Bits a => a -> Int -> a
    `shiftL` Int
    16) Word32 -> Word32 -> Word32
    forall a. Bits a => a -> a -> a
    .|.
          ((GF28 -> Word32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral GF28
    b2) Word32 -> Int -> Word32
    forall a. Bits a => a -> Int -> a
    `shiftL`  Int
    8) Word32 -> Word32 -> Word32
    forall a. Bits a => a -> a -> a
    .|.
           (GF28 -> Word32
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral GF28
    b3)
    fromBytes [GF28]
    bs = [Char] -> Word32
    forall a. HasCallStack => [Char] -> a
    error ([Char]
    "Unexpected list length in fromBytes: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Int -> [Char]
    forall a. Show a => a -> [Char]
    show ([GF28] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [GF28]
    bs))

    -----------------------------------------------------------------------------
    -- ** GF28 multiplication tables
    -----------------------------------------------------------------------------

    -- GF(2^8) multiplication by 0x0e
    mETable :: [GF28]
    mETable :: [GF28]
    mETable =
      [GF28
    0x00, GF28
    0x0e, GF28
    0x1c, GF28
    0x12, GF28
    0x38, GF28
    0x36, GF28
    0x24, GF28
    0x2a, GF28
    0x70, GF28
    0x7e, GF28
    0x6c,
       GF28
    0x62, GF28
    0x48, GF28
    0x46, GF28
    0x54, GF28
    0x5a, GF28
    0xe0, GF28
    0xee, GF28
    0xfc, GF28
    0xf2, GF28
    0xd8, GF28
    0xd6,
       GF28
    0xc4, GF28
    0xca, GF28
    0x90, GF28
    0x9e, GF28
    0x8c, GF28
    0x82, GF28
    0xa8, GF28
    0xa6, GF28
    0xb4, GF28
    0xba, GF28
    0xdb,
       GF28
    0xd5, GF28
    0xc7, GF28
    0xc9, GF28
    0xe3, GF28
    0xed, GF28
    0xff, GF28
    0xf1, GF28
    0xab, GF28
    0xa5, GF28
    0xb7, GF28
    0xb9,
       GF28
    0x93, GF28
    0x9d, GF28
    0x8f, GF28
    0x81, GF28
    0x3b, GF28
    0x35, GF28
    0x27, GF28
    0x29, GF28
    0x03, GF28
    0x0d, GF28
    0x1f,
       GF28
    0x11, GF28
    0x4b, GF28
    0x45, GF28
    0x57, GF28
    0x59, GF28
    0x73, GF28
    0x7d, GF28
    0x6f, GF28
    0x61, GF28
    0xad, GF28
    0xa3,
       GF28
    0xb1, GF28
    0xbf, GF28
    0x95, GF28
    0x9b, GF28
    0x89, GF28
    0x87, GF28
    0xdd, GF28
    0xd3, GF28
    0xc1, GF28
    0xcf, GF28
    0xe5,
       GF28
    0xeb, GF28
    0xf9, GF28
    0xf7, GF28
    0x4d, GF28
    0x43, GF28
    0x51, GF28
    0x5f, GF28
    0x75, GF28
    0x7b, GF28
    0x69, GF28
    0x67,
       GF28
    0x3d, GF28
    0x33, GF28
    0x21, GF28
    0x2f, GF28
    0x05, GF28
    0x0b, GF28
    0x19, GF28
    0x17, GF28
    0x76, GF28
    0x78, GF28
    0x6a,
       GF28
    0x64, GF28
    0x4e, GF28
    0x40, GF28
    0x52, GF28
    0x5c, GF28
    0x06, GF28
    0x08, GF28
    0x1a, GF28
    0x14, GF28
    0x3e, GF28
    0x30,
       GF28
    0x22, GF28
    0x2c, GF28
    0x96, GF28
    0x98, GF28
    0x8a, GF28
    0x84, GF28
    0xae, GF28
    0xa0, GF28
    0xb2, GF28
    0xbc, GF28
    0xe6,
       GF28
    0xe8, GF28
    0xfa, GF28
    0xf4, GF28
    0xde, GF28
    0xd0, GF28
    0xc2, GF28
    0xcc, GF28
    0x41, GF28
    0x4f, GF28
    0x5d, GF28
    0x53,
       GF28
    0x79, GF28
    0x77, GF28
    0x65, GF28
    0x6b, GF28
    0x31, GF28
    0x3f, GF28
    0x2d, GF28
    0x23, GF28
    0x09, GF28
    0x07, GF28
    0x15,
       GF28
    0x1b, GF28
    0xa1, GF28
    0xaf, GF28
    0xbd, GF28
    0xb3, GF28
    0x99, GF28
    0x97, GF28
    0x85, GF28
    0x8b, GF28
    0xd1, GF28
    0xdf,
       GF28
    0xcd, GF28
    0xc3, GF28
    0xe9, GF28
    0xe7, GF28
    0xf5, GF28
    0xfb, GF28
    0x9a, GF28
    0x94, GF28
    0x86, GF28
    0x88, GF28
    0xa2,
       GF28
    0xac, GF28
    0xbe, GF28
    0xb0, GF28
    0xea, GF28
    0xe4, GF28
    0xf6, GF28
    0xf8, GF28
    0xd2, GF28
    0xdc, GF28
    0xce, GF28
    0xc0,
       GF28
    0x7a, GF28
    0x74, GF28
    0x66, GF28
    0x68, GF28
    0x42, GF28
    0x4c, GF28
    0x5e, GF28
    0x50, GF28
    0x0a, GF28
    0x04, GF28
    0x16,
       GF28
    0x18, GF28
    0x32, GF28
    0x3c, GF28
    0x2e, GF28
    0x20, GF28
    0xec, GF28
    0xe2, GF28
    0xf0, GF28
    0xfe, GF28
    0xd4, GF28
    0xda,
       GF28
    0xc8, GF28
    0xc6, GF28
    0x9c, GF28
    0x92, GF28
    0x80, GF28
    0x8e, GF28
    0xa4, GF28
    0xaa, GF28
    0xb8, GF28
    0xb6, GF28
    0x0c,
       GF28
    0x02, GF28
    0x10, GF28
    0x1e, GF28
    0x34, GF28
    0x3a, GF28
    0x28, GF28
    0x26, GF28
    0x7c, GF28
    0x72, GF28
    0x60, GF28
    0x6e,
       GF28
    0x44, GF28
    0x4a, GF28
    0x58, GF28
    0x56, GF28
    0x37, GF28
    0x39, GF28
    0x2b, GF28
    0x25, GF28
    0x0f, GF28
    0x01, GF28
    0x13,
       GF28
    0x1d, GF28
    0x47, GF28
    0x49, GF28
    0x5b, GF28
    0x55, GF28
    0x7f, GF28
    0x71, GF28
    0x63, GF28
    0x6d, GF28
    0xd7, GF28
    0xd9,
       GF28
    0xcb, GF28
    0xc5, GF28
    0xef, GF28
    0xe1, GF28
    0xf3, GF28
    0xfd, GF28
    0xa7, GF28
    0xa9, GF28
    0xbb, GF28
    0xb5, GF28
    0x9f,
       GF28
    0x91, GF28
    0x83, GF28
    0x8d]

    -- GF(2^8) multiplication by 0x0b
    mBTable :: [GF28]
    mBTable :: [GF28]
    mBTable =
      [GF28
    0x00, GF28
    0x0b, GF28
    0x16, GF28
    0x1d, GF28
    0x2c, GF28
    0x27, GF28
    0x3a, GF28
    0x31, GF28
    0x58, GF28
    0x53, GF28
    0x4e,
       GF28
    0x45, GF28
    0x74, GF28
    0x7f, GF28
    0x62, GF28
    0x69, GF28
    0xb0, GF28
    0xbb, GF28
    0xa6, GF28
    0xad, GF28
    0x9c, GF28
    0x97,
       GF28
    0x8a, GF28
    0x81, GF28
    0xe8, GF28
    0xe3, GF28
    0xfe, GF28
    0xf5, GF28
    0xc4, GF28
    0xcf, GF28
    0xd2, GF28
    0xd9, GF28
    0x7b,
       GF28
    0x70, GF28
    0x6d, GF28
    0x66, GF28
    0x57, GF28
    0x5c, GF28
    0x41, GF28
    0x4a, GF28
    0x23, GF28
    0x28, GF28
    0x35, GF28
    0x3e,
       GF28
    0x0f, GF28
    0x04, GF28
    0x19, GF28
    0x12, GF28
    0xcb, GF28
    0xc0, GF28
    0xdd, GF28
    0xd6, GF28
    0xe7, GF28
    0xec, GF28
    0xf1,
       GF28
    0xfa, GF28
    0x93, GF28
    0x98, GF28
    0x85, GF28
    0x8e, GF28
    0xbf, GF28
    0xb4, GF28
    0xa9, GF28
    0xa2, GF28
    0xf6, GF28
    0xfd,
       GF28
    0xe0, GF28
    0xeb, GF28
    0xda, GF28
    0xd1, GF28
    0xcc, GF28
    0xc7, GF28
    0xae, GF28
    0xa5, GF28
    0xb8, GF28
    0xb3, GF28
    0x82,
       GF28
    0x89, GF28
    0x94, GF28
    0x9f, GF28
    0x46, GF28
    0x4d, GF28
    0x50, GF28
    0x5b, GF28
    0x6a, GF28
    0x61, GF28
    0x7c, GF28
    0x77,
       GF28
    0x1e, GF28
    0x15, GF28
    0x08, GF28
    0x03, GF28
    0x32, GF28
    0x39, GF28
    0x24, GF28
    0x2f, GF28
    0x8d, GF28
    0x86, GF28
    0x9b,
       GF28
    0x90, GF28
    0xa1, GF28
    0xaa, GF28
    0xb7, GF28
    0xbc, GF28
    0xd5, GF28
    0xde, GF28
    0xc3, GF28
    0xc8, GF28
    0xf9, GF28
    0xf2,
       GF28
    0xef, GF28
    0xe4, GF28
    0x3d, GF28
    0x36, GF28
    0x2b, GF28
    0x20, GF28
    0x11, GF28
    0x1a, GF28
    0x07, GF28
    0x0c, GF28
    0x65,
       GF28
    0x6e, GF28
    0x73, GF28
    0x78, GF28
    0x49, GF28
    0x42, GF28
    0x5f, GF28
    0x54, GF28
    0xf7, GF28
    0xfc, GF28
    0xe1, GF28
    0xea,
       GF28
    0xdb, GF28
    0xd0, GF28
    0xcd, GF28
    0xc6, GF28
    0xaf, GF28
    0xa4, GF28
    0xb9, GF28
    0xb2, GF28
    0x83, GF28
    0x88, GF28
    0x95,
       GF28
    0x9e, GF28
    0x47, GF28
    0x4c, GF28
    0x51, GF28
    0x5a, GF28
    0x6b, GF28
    0x60, GF28
    0x7d, GF28
    0x76, GF28
    0x1f, GF28
    0x14,
       GF28
    0x09, GF28
    0x02, GF28
    0x33, GF28
    0x38, GF28
    0x25, GF28
    0x2e, GF28
    0x8c, GF28
    0x87, GF28
    0x9a, GF28
    0x91, GF28
    0xa0,
       GF28
    0xab, GF28
    0xb6, GF28
    0xbd, GF28
    0xd4, GF28
    0xdf, GF28
    0xc2, GF28
    0xc9, GF28
    0xf8, GF28
    0xf3, GF28
    0xee, GF28
    0xe5,
       GF28
    0x3c, GF28
    0x37, GF28
    0x2a, GF28
    0x21, GF28
    0x10, GF28
    0x1b, GF28
    0x06, GF28
    0x0d, GF28
    0x64, GF28
    0x6f, GF28
    0x72,
       GF28
    0x79, GF28
    0x48, GF28
    0x43, GF28
    0x5e, GF28
    0x55, GF28
    0x01, GF28
    0x0a, GF28
    0x17, GF28
    0x1c, GF28
    0x2d, GF28
    0x26,
       GF28
    0x3b, GF28
    0x30, GF28
    0x59, GF28
    0x52, GF28
    0x4f, GF28
    0x44, GF28
    0x75, GF28
    0x7e, GF28
    0x63, GF28
    0x68, GF28
    0xb1,
       GF28
    0xba, GF28
    0xa7, GF28
    0xac, GF28
    0x9d, GF28
    0x96, GF28
    0x8b, GF28
    0x80, GF28
    0xe9, GF28
    0xe2, GF28
    0xff, GF28
    0xf4,
       GF28
    0xc5, GF28
    0xce, GF28
    0xd3, GF28
    0xd8, GF28
    0x7a, GF28
    0x71, GF28
    0x6c, GF28
    0x67, GF28
    0x56, GF28
    0x5d, GF28
    0x40,
       GF28
    0x4b, GF28
    0x22, GF28
    0x29, GF28
    0x34, GF28
    0x3f, GF28
    0x0e, GF28
    0x05, GF28
    0x18, GF28
    0x13, GF28
    0xca, GF28
    0xc1,
       GF28
    0xdc, GF28
    0xd7, GF28
    0xe6, GF28
    0xed, GF28
    0xf0, GF28
    0xfb, GF28
    0x92, GF28
    0x99, GF28
    0x84, GF28
    0x8f, GF28
    0xbe,
       GF28
    0xb5, GF28
    0xa8, GF28
    0xa3]

    -- GF(2^8) multiplication by 0x0d
    mDTable :: [GF28]
    mDTable :: [GF28]
    mDTable =
      [GF28
    0x00, GF28
    0x0d, GF28
    0x1a, GF28
    0x17, GF28
    0x34, GF28
    0x39, GF28
    0x2e, GF28
    0x23, GF28
    0x68, GF28
    0x65, GF28
    0x72,
       GF28
    0x7f, GF28
    0x5c, GF28
    0x51, GF28
    0x46, GF28
    0x4b, GF28
    0xd0, GF28
    0xdd, GF28
    0xca, GF28
    0xc7, GF28
    0xe4, GF28
    0xe9,
       GF28
    0xfe, GF28
    0xf3, GF28
    0xb8, GF28
    0xb5, GF28
    0xa2, GF28
    0xaf, GF28
    0x8c, GF28
    0x81, GF28
    0x96, GF28
    0x9b, GF28
    0xbb,
       GF28
    0xb6, GF28
    0xa1, GF28
    0xac, GF28
    0x8f, GF28
    0x82, GF28
    0x95, GF28
    0x98, GF28
    0xd3, GF28
    0xde, GF28
    0xc9, GF28
    0xc4,
       GF28
    0xe7, GF28
    0xea, GF28
    0xfd, GF28
    0xf0, GF28
    0x6b, GF28
    0x66, GF28
    0x71, GF28
    0x7c, GF28
    0x5f, GF28
    0x52, GF28
    0x45,
       GF28
    0x48, GF28
    0x03, GF28
    0x0e, GF28
    0x19, GF28
    0x14, GF28
    0x37, GF28
    0x3a, GF28
    0x2d, GF28
    0x20, GF28
    0x6d, GF28
    0x60,
       GF28
    0x77, GF28
    0x7a, GF28
    0x59, GF28
    0x54, GF28
    0x43, GF28
    0x4e, GF28
    0x05, GF28
    0x08, GF28
    0x1f, GF28
    0x12, GF28
    0x31,
       GF28
    0x3c, GF28
    0x2b, GF28
    0x26, GF28
    0xbd, GF28
    0xb0, GF28
    0xa7, GF28
    0xaa, GF28
    0x89, GF28
    0x84, GF28
    0x93, GF28
    0x9e,
       GF28
    0xd5, GF28
    0xd8, GF28
    0xcf, GF28
    0xc2, GF28
    0xe1, GF28
    0xec, GF28
    0xfb, GF28
    0xf6, GF28
    0xd6, GF28
    0xdb, GF28
    0xcc,
       GF28
    0xc1, GF28
    0xe2, GF28
    0xef, GF28
    0xf8, GF28
    0xf5, GF28
    0xbe, GF28
    0xb3, GF28
    0xa4, GF28
    0xa9, GF28
    0x8a, GF28
    0x87,
       GF28
    0x90, GF28
    0x9d, GF28
    0x06, GF28
    0x0b, GF28
    0x1c, GF28
    0x11, GF28
    0x32, GF28
    0x3f, GF28
    0x28, GF28
    0x25, GF28
    0x6e,
       GF28
    0x63, GF28
    0x74, GF28
    0x79, GF28
    0x5a, GF28
    0x57, GF28
    0x40, GF28
    0x4d, GF28
    0xda, GF28
    0xd7, GF28
    0xc0, GF28
    0xcd,
       GF28
    0xee, GF28
    0xe3, GF28
    0xf4, GF28
    0xf9, GF28
    0xb2, GF28
    0xbf, GF28
    0xa8, GF28
    0xa5, GF28
    0x86, GF28
    0x8b, GF28
    0x9c,
       GF28
    0x91, GF28
    0x0a, GF28
    0x07, GF28
    0x10, GF28
    0x1d, GF28
    0x3e, GF28
    0x33, GF28
    0x24, GF28
    0x29, GF28
    0x62, GF28
    0x6f,
       GF28
    0x78, GF28
    0x75, GF28
    0x56, GF28
    0x5b, GF28
    0x4c, GF28
    0x41, GF28
    0x61, GF28
    0x6c, GF28
    0x7b, GF28
    0x76, GF28
    0x55,
       GF28
    0x58, GF28
    0x4f, GF28
    0x42, GF28
    0x09, GF28
    0x04, GF28
    0x13, GF28
    0x1e, GF28
    0x3d, GF28
    0x30, GF28
    0x27, GF28
    0x2a,
       GF28
    0xb1, GF28
    0xbc, GF28
    0xab, GF28
    0xa6, GF28
    0x85, GF28
    0x88, GF28
    0x9f, GF28
    0x92, GF28
    0xd9, GF28
    0xd4, GF28
    0xc3,
       GF28
    0xce, GF28
    0xed, GF28
    0xe0, GF28
    0xf7, GF28
    0xfa, GF28
    0xb7, GF28
    0xba, GF28
    0xad, GF28
    0xa0, GF28
    0x83, GF28
    0x8e,
       GF28
    0x99, GF28
    0x94, GF28
    0xdf, GF28
    0xd2, GF28
    0xc5, GF28
    0xc8, GF28
    0xeb, GF28
    0xe6, GF28
    0xf1, GF28
    0xfc, GF28
    0x67,
       GF28
    0x6a, GF28
    0x7d, GF28
    0x70, GF28
    0x53, GF28
    0x5e, GF28
    0x49, GF28
    0x44, GF28
    0x0f, GF28
    0x02, GF28
    0x15, GF28
    0x18,
       GF28
    0x3b, GF28
    0x36, GF28
    0x21, GF28
    0x2c, GF28
    0x0c, GF28
    0x01, GF28
    0x16, GF28
    0x1b, GF28
    0x38, GF28
    0x35, GF28
    0x22,
       GF28
    0x2f, GF28
    0x64, GF28
    0x69, GF28
    0x7e, GF28
    0x73, GF28
    0x50, GF28
    0x5d, GF28
    0x4a, GF28
    0x47, GF28
    0xdc, GF28
    0xd1,
       GF28
    0xc6, GF28
    0xcb, GF28
    0xe8, GF28
    0xe5, GF28
    0xf2, GF28
    0xff, GF28
    0xb4, GF28
    0xb9, GF28
    0xae, GF28
    0xa3, GF28
    0x80,
       GF28
    0x8d, GF28
    0x9a, GF28
    0x97]

    -- GF(2^8) multiplication by 0x09
    m9Table :: [GF28]
    m9Table :: [GF28]
    m9Table =
      [GF28
    0x00, GF28
    0x09, GF28
    0x12, GF28
    0x1b, GF28
    0x24, GF28
    0x2d, GF28
    0x36, GF28
    0x3f, GF28
    0x48, GF28
    0x41, GF28
    0x5a,
       GF28
    0x53, GF28
    0x6c, GF28
    0x65, GF28
    0x7e, GF28
    0x77, GF28
    0x90, GF28
    0x99, GF28
    0x82, GF28
    0x8b, GF28
    0xb4, GF28
    0xbd,
       GF28
    0xa6, GF28
    0xaf, GF28
    0xd8, GF28
    0xd1, GF28
    0xca, GF28
    0xc3, GF28
    0xfc, GF28
    0xf5, GF28
    0xee, GF28
    0xe7, GF28
    0x3b,
       GF28
    0x32, GF28
    0x29, GF28
    0x20, GF28
    0x1f, GF28
    0x16, GF28
    0x0d, GF28
    0x04, GF28
    0x73, GF28
    0x7a, GF28
    0x61, GF28
    0x68,
       GF28
    0x57, GF28
    0x5e, GF28
    0x45, GF28
    0x4c, GF28
    0xab, GF28
    0xa2, GF28
    0xb9, GF28
    0xb0, GF28
    0x8f, GF28
    0x86, GF28
    0x9d,
       GF28
    0x94, GF28
    0xe3, GF28
    0xea, GF28
    0xf1, GF28
    0xf8, GF28
    0xc7, GF28
    0xce, GF28
    0xd5, GF28
    0xdc, GF28
    0x76, GF28
    0x7f,
       GF28
    0x64, GF28
    0x6d, GF28
    0x52, GF28
    0x5b, GF28
    0x40, GF28
    0x49, GF28
    0x3e, GF28
    0x37, GF28
    0x2c, GF28
    0x25, GF28
    0x1a,
       GF28
    0x13, GF28
    0x08, GF28
    0x01, GF28
    0xe6, GF28
    0xef, GF28
    0xf4, GF28
    0xfd, GF28
    0xc2, GF28
    0xcb, GF28
    0xd0, GF28
    0xd9,
       GF28
    0xae, GF28
    0xa7, GF28
    0xbc, GF28
    0xb5, GF28
    0x8a, GF28
    0x83, GF28
    0x98, GF28
    0x91, GF28
    0x4d, GF28
    0x44, GF28
    0x5f,
       GF28
    0x56, GF28
    0x69, GF28
    0x60, GF28
    0x7b, GF28
    0x72, GF28
    0x05, GF28
    0x0c, GF28
    0x17, GF28
    0x1e, GF28
    0x21, GF28
    0x28,
       GF28
    0x33, GF28
    0x3a, GF28
    0xdd, GF28
    0xd4, GF28
    0xcf, GF28
    0xc6, GF28
    0xf9, GF28
    0xf0, GF28
    0xeb, GF28
    0xe2, GF28
    0x95,
       GF28
    0x9c, GF28
    0x87, GF28
    0x8e, GF28
    0xb1, GF28
    0xb8, GF28
    0xa3, GF28
    0xaa, GF28
    0xec, GF28
    0xe5, GF28
    0xfe, GF28
    0xf7,
       GF28
    0xc8, GF28
    0xc1, GF28
    0xda, GF28
    0xd3, GF28
    0xa4, GF28
    0xad, GF28
    0xb6, GF28
    0xbf, GF28
    0x80, GF28
    0x89, GF28
    0x92,
       GF28
    0x9b, GF28
    0x7c, GF28
    0x75, GF28
    0x6e, GF28
    0x67, GF28
    0x58, GF28
    0x51, GF28
    0x4a, GF28
    0x43, GF28
    0x34, GF28
    0x3d,
       GF28
    0x26, GF28
    0x2f, GF28
    0x10, GF28
    0x19, GF28
    0x02, GF28
    0x0b, GF28
    0xd7, GF28
    0xde, GF28
    0xc5, GF28
    0xcc, GF28
    0xf3,
       GF28
    0xfa, GF28
    0xe1, GF28
    0xe8, GF28
    0x9f, GF28
    0x96, GF28
    0x8d, GF28
    0x84, GF28
    0xbb, GF28
    0xb2, GF28
    0xa9, GF28
    0xa0,
       GF28
    0x47, GF28
    0x4e, GF28
    0x55, GF28
    0x5c, GF28
    0x63, GF28
    0x6a, GF28
    0x71, GF28
    0x78, GF28
    0x0f, GF28
    0x06, GF28
    0x1d,
       GF28
    0x14, GF28
    0x2b, GF28
    0x22, GF28
    0x39, GF28
    0x30, GF28
    0x9a, GF28
    0x93, GF28
    0x88, GF28
    0x81, GF28
    0xbe, GF28
    0xb7,
       GF28
    0xac, GF28
    0xa5, GF28
    0xd2, GF28
    0xdb, GF28
    0xc0, GF28
    0xc9, GF28
    0xf6, GF28
    0xff, GF28
    0xe4, GF28
    0xed, GF28
    0x0a,
       GF28
    0x03, GF28
    0x18, GF28
    0x11, GF28
    0x2e, GF28
    0x27, GF28
    0x3c, GF28
    0x35, GF28
    0x42, GF28
    0x4b, GF28
    0x50, GF28
    0x59,
       GF28
    0x66, GF28
    0x6f, GF28
    0x74, GF28
    0x7d, GF28
    0xa1, GF28
    0xa8, GF28
    0xb3, GF28
    0xba, GF28
    0x85, GF28
    0x8c, GF28
    0x97,
       GF28
    0x9e, GF28
    0xe9, GF28
    0xe0, GF28
    0xfb, GF28
    0xf2, GF28
    0xcd, GF28
    0xc4, GF28
    0xdf, GF28
    0xd6, GF28
    0x31, GF28
    0x38,
       GF28
    0x23, GF28
    0x2a, GF28
    0x15, GF28
    0x1c, GF28
    0x07, GF28
    0x0e, GF28
    0x79, GF28
    0x70, GF28
    0x6b, GF28
    0x62, GF28
    0x5d,
       GF28
    0x54, GF28
    0x4f, GF28
    0x46]

    -- GF(2^8) multiplication by 0x02
    m2Table :: [GF28]
    m2Table :: [GF28]
    m2Table =
      [GF28
    0x00, GF28
    0x02, GF28
    0x04, GF28
    0x06, GF28
    0x08, GF28
    0x0a, GF28
    0x0c, GF28
    0x0e, GF28
    0x10, GF28
    0x12, GF28
    0x14,
       GF28
    0x16, GF28
    0x18, GF28
    0x1a, GF28
    0x1c, GF28
    0x1e, GF28
    0x20, GF28
    0x22, GF28
    0x24, GF28
    0x26, GF28
    0x28, GF28
    0x2a,
       GF28
    0x2c, GF28
    0x2e, GF28
    0x30, GF28
    0x32, GF28
    0x34, GF28
    0x36, GF28
    0x38, GF28
    0x3a, GF28
    0x3c, GF28
    0x3e, GF28
    0x40,
       GF28
    0x42, GF28
    0x44, GF28
    0x46, GF28
    0x48, GF28
    0x4a, GF28
    0x4c, GF28
    0x4e, GF28
    0x50, GF28
    0x52, GF28
    0x54, GF28
    0x56,
       GF28
    0x58, GF28
    0x5a, GF28
    0x5c, GF28
    0x5e, GF28
    0x60, GF28
    0x62, GF28
    0x64, GF28
    0x66, GF28
    0x68, GF28
    0x6a, GF28
    0x6c,
       GF28
    0x6e, GF28
    0x70, GF28
    0x72, GF28
    0x74, GF28
    0x76, GF28
    0x78, GF28
    0x7a, GF28
    0x7c, GF28
    0x7e, GF28
    0x80, GF28
    0x82,
       GF28
    0x84, GF28
    0x86, GF28
    0x88, GF28
    0x8a, GF28
    0x8c, GF28
    0x8e, GF28
    0x90, GF28
    0x92, GF28
    0x94, GF28
    0x96, GF28
    0x98,
       GF28
    0x9a, GF28
    0x9c, GF28
    0x9e, GF28
    0xa0, GF28
    0xa2, GF28
    0xa4, GF28
    0xa6, GF28
    0xa8, GF28
    0xaa, GF28
    0xac, GF28
    0xae,
       GF28
    0xb0, GF28
    0xb2, GF28
    0xb4, GF28
    0xb6, GF28
    0xb8, GF28
    0xba, GF28
    0xbc, GF28
    0xbe, GF28
    0xc0, GF28
    0xc2, GF28
    0xc4,
       GF28
    0xc6, GF28
    0xc8, GF28
    0xca, GF28
    0xcc, GF28
    0xce, GF28
    0xd0, GF28
    0xd2, GF28
    0xd4, GF28
    0xd6, GF28
    0xd8, GF28
    0xda,
       GF28
    0xdc, GF28
    0xde, GF28
    0xe0, GF28
    0xe2, GF28
    0xe4, GF28
    0xe6, GF28
    0xe8, GF28
    0xea, GF28
    0xec, GF28
    0xee, GF28
    0xf0,
       GF28
    0xf2, GF28
    0xf4, GF28
    0xf6, GF28
    0xf8, GF28
    0xfa, GF28
    0xfc, GF28
    0xfe, GF28
    0x1b, GF28
    0x19, GF28
    0x1f, GF28
    0x1d,
       GF28
    0x13, GF28
    0x11, GF28
    0x17, GF28
    0x15, GF28
    0x0b, GF28
    0x09, GF28
    0x0f, GF28
    0x0d, GF28
    0x03, GF28
    0x01, GF28
    0x07,
       GF28
    0x05, GF28
    0x3b, GF28
    0x39, GF28
    0x3f, GF28
    0x3d, GF28
    0x33, GF28
    0x31, GF28
    0x37, GF28
    0x35, GF28
    0x2b, GF28
    0x29,
       GF28
    0x2f, GF28
    0x2d, GF28
    0x23, GF28
    0x21, GF28
    0x27, GF28
    0x25, GF28
    0x5b, GF28
    0x59, GF28
    0x5f, GF28
    0x5d, GF28
    0x53,
       GF28
    0x51, GF28
    0x57, GF28
    0x55, GF28
    0x4b, GF28
    0x49, GF28
    0x4f, GF28
    0x4d, GF28
    0x43, GF28
    0x41, GF28
    0x47, GF28
    0x45,
       GF28
    0x7b, GF28
    0x79, GF28
    0x7f, GF28
    0x7d, GF28
    0x73, GF28
    0x71, GF28
    0x77, GF28
    0x75, GF28
    0x6b, GF28
    0x69, GF28
    0x6f,
       GF28
    0x6d, GF28
    0x63, GF28
    0x61, GF28
    0x67, GF28
    0x65, GF28
    0x9b, GF28
    0x99, GF28
    0x9f, GF28
    0x9d, GF28
    0x93, GF28
    0x91,
       GF28
    0x97, GF28
    0x95, GF28
    0x8b, GF28
    0x89, GF28
    0x8f, GF28
    0x8d, GF28
    0x83, GF28
    0x81, GF28
    0x87, GF28
    0x85, GF28
    0xbb,
       GF28
    0xb9, GF28
    0xbf, GF28
    0xbd, GF28
    0xb3, GF28
    0xb1, GF28
    0xb7, GF28
    0xb5, GF28
    0xab, GF28
    0xa9, GF28
    0xaf, GF28
    0xad,
       GF28
    0xa3, GF28
    0xa1, GF28
    0xa7, GF28
    0xa5, GF28
    0xdb, GF28
    0xd9, GF28
    0xdf, GF28
    0xdd, GF28
    0xd3, GF28
    0xd1, GF28
    0xd7,
       GF28
    0xd5, GF28
    0xcb, GF28
    0xc9, GF28
    0xcf, GF28
    0xcd, GF28
    0xc3, GF28
    0xc1, GF28
    0xc7, GF28
    0xc5, GF28
    0xfb, GF28
    0xf9,
       GF28
    0xff, GF28
    0xfd, GF28
    0xf3, GF28
    0xf1, GF28
    0xf7, GF28
    0xf5, GF28
    0xeb, GF28
    0xe9, GF28
    0xef, GF28
    0xed, GF28
    0xe3,
       GF28
    0xe1, GF28
    0xe7, GF28
    0xe5]

    -- GF(2^8) multiplication by 0x03
    m3Table :: [GF28]
    m3Table :: [GF28]
    m3Table =
      [GF28
    0x00, GF28
    0x03, GF28
    0x06, GF28
    0x05, GF28
    0x0c, GF28
    0x0f, GF28
    0x0a, GF28
    0x09, GF28
    0x18, GF28
    0x1b, GF28
    0x1e,
       GF28
    0x1d, GF28
    0x14, GF28
    0x17, GF28
    0x12, GF28
    0x11, GF28
    0x30, GF28
    0x33, GF28
    0x36, GF28
    0x35, GF28
    0x3c, GF28
    0x3f,
       GF28
    0x3a, GF28
    0x39, GF28
    0x28, GF28
    0x2b, GF28
    0x2e, GF28
    0x2d, GF28
    0x24, GF28
    0x27, GF28
    0x22, GF28
    0x21, GF28
    0x60,
       GF28
    0x63, GF28
    0x66, GF28
    0x65, GF28
    0x6c, GF28
    0x6f, GF28
    0x6a, GF28
    0x69, GF28
    0x78, GF28
    0x7b, GF28
    0x7e, GF28
    0x7d,
       GF28
    0x74, GF28
    0x77, GF28
    0x72, GF28
    0x71, GF28
    0x50, GF28
    0x53, GF28
    0x56, GF28
    0x55, GF28
    0x5c, GF28
    0x5f, GF28
    0x5a,
       GF28
    0x59, GF28
    0x48, GF28
    0x4b, GF28
    0x4e, GF28
    0x4d, GF28
    0x44, GF28
    0x47, GF28
    0x42, GF28
    0x41, GF28
    0xc0, GF28
    0xc3,
       GF28
    0xc6, GF28
    0xc5, GF28
    0xcc, GF28
    0xcf, GF28
    0xca, GF28
    0xc9, GF28
    0xd8, GF28
    0xdb, GF28
    0xde, GF28
    0xdd, GF28
    0xd4,
       GF28
    0xd7, GF28
    0xd2, GF28
    0xd1, GF28
    0xf0, GF28
    0xf3, GF28
    0xf6, GF28
    0xf5, GF28
    0xfc, GF28
    0xff, GF28
    0xfa, GF28
    0xf9,
       GF28
    0xe8, GF28
    0xeb, GF28
    0xee, GF28
    0xed, GF28
    0xe4, GF28
    0xe7, GF28
    0xe2, GF28
    0xe1, GF28
    0xa0, GF28
    0xa3, GF28
    0xa6,
       GF28
    0xa5, GF28
    0xac, GF28
    0xaf, GF28
    0xaa, GF28
    0xa9, GF28
    0xb8, GF28
    0xbb, GF28
    0xbe, GF28
    0xbd, GF28
    0xb4, GF28
    0xb7,
       GF28
    0xb2, GF28
    0xb1, GF28
    0x90, GF28
    0x93, GF28
    0x96, GF28
    0x95, GF28
    0x9c, GF28
    0x9f, GF28
    0x9a, GF28
    0x99, GF28
    0x88,
       GF28
    0x8b, GF28
    0x8e, GF28
    0x8d, GF28
    0x84, GF28
    0x87, GF28
    0x82, GF28
    0x81, GF28
    0x9b, GF28
    0x98, GF28
    0x9d, GF28
    0x9e,
       GF28
    0x97, GF28
    0x94, GF28
    0x91, GF28
    0x92, GF28
    0x83, GF28
    0x80, GF28
    0x85, GF28
    0x86, GF28
    0x8f, GF28
    0x8c, GF28
    0x89,
       GF28
    0x8a, GF28
    0xab, GF28
    0xa8, GF28
    0xad, GF28
    0xae, GF28
    0xa7, GF28
    0xa4, GF28
    0xa1, GF28
    0xa2, GF28
    0xb3, GF28
    0xb0,
       GF28
    0xb5, GF28
    0xb6, GF28
    0xbf, GF28
    0xbc, GF28
    0xb9, GF28
    0xba, GF28
    0xfb, GF28
    0xf8, GF28
    0xfd, GF28
    0xfe, GF28
    0xf7,
       GF28
    0xf4, GF28
    0xf1, GF28
    0xf2, GF28
    0xe3, GF28
    0xe0, GF28
    0xe5, GF28
    0xe6, GF28
    0xef, GF28
    0xec, GF28
    0xe9, GF28
    0xea,
       GF28
    0xcb, GF28
    0xc8, GF28
    0xcd, GF28
    0xce, GF28
    0xc7, GF28
    0xc4, GF28
    0xc1, GF28
    0xc2, GF28
    0xd3, GF28
    0xd0, GF28
    0xd5,
       GF28
    0xd6, GF28
    0xdf, GF28
    0xdc, GF28
    0xd9, GF28
    0xda, GF28
    0x5b, GF28
    0x58, GF28
    0x5d, GF28
    0x5e, GF28
    0x57, GF28
    0x54,
       GF28
    0x51, GF28
    0x52, GF28
    0x43, GF28
    0x40, GF28
    0x45, GF28
    0x46, GF28
    0x4f, GF28
    0x4c, GF28
    0x49, GF28
    0x4a, GF28
    0x6b,
       GF28
    0x68, GF28
    0x6d, GF28
    0x6e, GF28
    0x67, GF28
    0x64, GF28
    0x61, GF28
    0x62, GF28
    0x73, GF28
    0x70, GF28
    0x75, GF28
    0x76,
       GF28
    0x7f, GF28
    0x7c, GF28
    0x79, GF28
    0x7a, GF28
    0x3b, GF28
    0x38, GF28
    0x3d, GF28
    0x3e, GF28
    0x37, GF28
    0x34, GF28
    0x31,
       GF28
    0x32, GF28
    0x23, GF28
    0x20, GF28
    0x25, GF28
    0x26, GF28
    0x2f, GF28
    0x2c, GF28
    0x29, GF28
    0x2a, GF28
    0x0b, GF28
    0x08,
       GF28
    0x0d, GF28
    0x0e, GF28
    0x07, GF28
    0x04, GF28
    0x01, GF28
    0x02, GF28
    0x13, GF28
    0x10, GF28
    0x15, GF28
    0x16, GF28
    0x1f,
       GF28
    0x1c, GF28
    0x19, GF28
    0x1a]

    -- table-lookup versions of gf28Mult with the constants used in invMixColumns
    -- and TBox construction

    m2 :: GF28 -> GF28
    m2 :: GF28 -> GF28
    m2 GF28
    i = [GF28]
    m2Table [GF28] -> Int -> GF28
    forall a. HasCallStack => [a] -> Int -> a
    !! GF28 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral GF28
    i

    m3 :: GF28 -> GF28
    m3 :: GF28 -> GF28
    m3 GF28
    i = [GF28]
    m3Table [GF28] -> Int -> GF28
    forall a. HasCallStack => [a] -> Int -> a
    !! GF28 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral GF28
    i

    mE :: GF28 -> GF28
    mE :: GF28 -> GF28
    mE GF28
    i = [GF28]
    mETable [GF28] -> Int -> GF28
    forall a. HasCallStack => [a] -> Int -> a
    !! GF28 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral GF28
    i

    mB :: GF28 -> GF28
    mB :: GF28 -> GF28
    mB GF28
    i = [GF28]
    mBTable [GF28] -> Int -> GF28
    forall a. HasCallStack => [a] -> Int -> a
    !! GF28 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral GF28
    i

    mD :: GF28 -> GF28
    mD :: GF28 -> GF28
    mD GF28
    i = [GF28]
    mDTable [GF28] -> Int -> GF28
    forall a. HasCallStack => [a] -> Int -> a
    !! GF28 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral GF28
    i

    m9 :: GF28 -> GF28
    m9 :: GF28 -> GF28
    m9 GF28
    i = [GF28]
    m9Table [GF28] -> Int -> GF28
    forall a. HasCallStack => [a] -> Int -> a
    !! GF28 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral GF28
    i

    -----------------------------------------------------------------------------
    -- ** The key schedule
    -----------------------------------------------------------------------------

    -- | The @InvMixColumns@ transformation, as described in Section 5.3.3 of the standard. Note
    -- that this transformation is only used explicitly during key-expansion in the T-Box implementation
    -- of AES.
    invMixColumns :: State -> State
    invMixColumns :: State -> State
    invMixColumns State
    state = ([GF28] -> Word32) -> [[GF28]] -> State
    forall a b. (a -> b) -> [a] -> [b]
    map [GF28] -> Word32
    fromBytes ([[GF28]] -> State) -> [[GF28]] -> State
    forall a b. (a -> b) -> a -> b
    $ [[GF28]] -> [[GF28]]
    forall a. [[a]] -> [[a]]
    transpose ([[GF28]] -> [[GF28]]) -> [[GF28]] -> [[GF28]]
    forall a b. (a -> b) -> a -> b
    $ [[GF28]] -> [[GF28]]
    mmult ((Word32 -> [GF28]) -> State -> [[GF28]]
    forall a b. (a -> b) -> [a] -> [b]
    map Word32 -> [GF28]
    toBytes State
    state)
     where dot :: [b -> c] -> [b] -> c
    dot [b -> c]
    f   = (c -> c -> c) -> [c] -> c
    forall a. (a -> a -> a) -> [a] -> a
    forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
    foldr1 c -> c -> c
    forall a. Bits a => a -> a -> a
    xor ([c] -> c) -> ([b] -> [c]) -> [b] -> c
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ((b -> c) -> b -> c) -> [b -> c] -> [b] -> [c]
    forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
    zipWith (b -> c) -> b -> c
    forall a b. (a -> b) -> a -> b
    ($) [b -> c]
    f
           mmult :: [[Word8]] -> [[Word8]]
           mmult :: [[GF28]] -> [[GF28]]
    mmult [[GF28]]
    n = [([GF28] -> GF28) -> [[GF28]] -> [GF28]
    forall a b. (a -> b) -> [a] -> [b]
    map ([GF28 -> GF28] -> [GF28] -> GF28
    forall {c} {b}. Bits c => [b -> c] -> [b] -> c
    dot [GF28 -> GF28]
    r) [[GF28]]
    n | [GF28 -> GF28]
    r <- [ [GF28 -> GF28
    mE, GF28 -> GF28
    mB, GF28 -> GF28
    mD, GF28 -> GF28
    m9]
                                           , [GF28 -> GF28
    m9, GF28 -> GF28
    mE, GF28 -> GF28
    mB, GF28 -> GF28
    mD]
                                           , [GF28 -> GF28
    mD, GF28 -> GF28
    m9, GF28 -> GF28
    mE, GF28 -> GF28
    mB]
                                           , [GF28 -> GF28
    mB, GF28 -> GF28
    mD, GF28 -> GF28
    m9, GF28 -> GF28
    mE]
                                           ]]

    keyExpansionWords :: Integer -> Key -> [Word32]
    keyExpansionWords :: Integer -> State -> State
    keyExpansionWords Integer
    nk State
    key = Integer -> State -> State
    forall i a. Integral i => i -> [a] -> [a]
    genericTake (Integer
    4Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    *(Integer
    nkInteger -> Integer -> Integer
    forall a. Num a => a -> a -> a
    +Integer
    7)) State
    keys
       where keys :: [Word32]
             keys :: State
    keys = State
    key State -> State -> State
    forall a. [a] -> [a] -> [a]
    ++ [Integer -> Word32 -> Word32 -> Word32
    nextWord Integer
    i Word32
    prev Word32
    old | Integer
    i <- [Integer
    nk ..] | Word32
    prev <- Integer -> State -> State
    forall i a. Integral i => i -> [a] -> [a]
    genericDrop (Integer
    nkInteger -> Integer -> Integer
    forall a. Num a => a -> a -> a
    -Integer
    1) State
    keys | Word32
    old <- State
    keys]

             nextWord :: Integer -> Word32 -> Word32 -> Word32
             nextWord :: Integer -> Word32 -> Word32 -> Word32
    nextWord Integer
    i Word32
    prev Word32
    old
               | Integer
    i Integer -> Integer -> Integer
    forall a. Integral a => a -> a -> a
    `mod` Integer
    nk Integer -> Integer -> Bool
    forall a. Eq a => a -> a -> Bool
    == Integer
    0           = Word32
    old Word32 -> Word32 -> Word32
    forall a. Bits a => a -> a -> a
    `xor` Word32 -> GF28 -> Word32
    subWordRcon (Word32
    prev Word32 -> Int -> Word32
    forall a. Bits a => a -> Int -> a
    `rotateL` Int
    8) ([GF28]
    roundConstants [GF28] -> Int -> GF28
    forall a. HasCallStack => [a] -> Int -> a
    !! Integer -> Int
    forall a. Num a => Integer -> a
    fromInteger (Integer
    i Integer -> Integer -> Integer
    forall a. Integral a => a -> a -> a
    `div` Integer
    nk))
               | Integer
    i Integer -> Integer -> Integer
    forall a. Integral a => a -> a -> a
    `mod` Integer
    nk Integer -> Integer -> Bool
    forall a. Eq a => a -> a -> Bool
    == Integer
    4 Bool -> Bool -> Bool
    && Integer
    nk Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    > Integer
    6 = Word32
    old Word32 -> Word32 -> Word32
    forall a. Bits a => a -> a -> a
    `xor` Word32 -> GF28 -> Word32
    subWordRcon Word32
    prev GF28
    0
               | Bool
    True                      = Word32
    old Word32 -> Word32 -> Word32
    forall a. Bits a => a -> a -> a
    `xor` Word32
    prev

             subWordRcon :: Word32 -> GF28 -> Word32
             subWordRcon :: Word32 -> GF28 -> Word32
    subWordRcon Word32
    w GF28
    rc = [GF28] -> Word32
    fromBytes [GF28
    a GF28 -> GF28 -> GF28
    forall a. Bits a => a -> a -> a
    `xor` GF28
    rc, GF28
    b, GF28
    c, GF28
    d]
                where (GF28
    a, GF28
    b, GF28
    c, GF28
    d) =
                        case (GF28 -> GF28) -> [GF28] -> [GF28]
    forall a b. (a -> b) -> [a] -> [b]
    map GF28 -> GF28
    sbox ([GF28] -> [GF28]) -> [GF28] -> [GF28]
    forall a b. (a -> b) -> a -> b
    $ Word32 -> [GF28]
    toBytes Word32
    w of
                          [GF28
    a', GF28
    b', GF28
    c', GF28
    d'] -> (GF28
    a', GF28
    b', GF28
    c', GF28
    d')
                          [GF28]
    bs -> [Char] -> (GF28, GF28, GF28, GF28)
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> (GF28, GF28, GF28, GF28))
    -> [Char] -> (GF28, GF28, GF28, GF28)
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Unexpected list length in keyExpansionWords: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Int -> [Char]
    forall a. Show a => a -> [Char]
    show ([GF28] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [GF28]
    bs)

    -- | Definition of round-constants, as specified in Section 5.2 of the AES standard.
    --   We only need up to the 11th value for AES-128, and fewer than that for AES-192
    --   and AES-256.
    roundConstants :: [GF28]
    roundConstants :: [GF28]
    roundConstants = [GF28
    0,GF28
    1,GF28
    2,GF28
    4,GF28
    8,GF28
    16,GF28
    32,GF28
    64,GF28
    128,GF28
    27,GF28
    54]

    -----------------------------------------------------------------------------
    -- ** The S-box transformation
    -----------------------------------------------------------------------------

    sboxTable :: [GF28]
    sboxTable :: [GF28]
    sboxTable =
      [GF28
    0x63, GF28
    0x7c, GF28
    0x77, GF28
    0x7b, GF28
    0xf2, GF28
    0x6b, GF28
    0x6f, GF28
    0xc5, GF28
    0x30, GF28
    0x01, GF28
    0x67,
       GF28
    0x2b, GF28
    0xfe, GF28
    0xd7, GF28
    0xab, GF28
    0x76, GF28
    0xca, GF28
    0x82, GF28
    0xc9, GF28
    0x7d, GF28
    0xfa, GF28
    0x59,
       GF28
    0x47, GF28
    0xf0, GF28
    0xad, GF28
    0xd4, GF28
    0xa2, GF28
    0xaf, GF28
    0x9c, GF28
    0xa4, GF28
    0x72, GF28
    0xc0, GF28
    0xb7,
       GF28
    0xfd, GF28
    0x93, GF28
    0x26, GF28
    0x36, GF28
    0x3f, GF28
    0xf7, GF28
    0xcc, GF28
    0x34, GF28
    0xa5, GF28
    0xe5, GF28
    0xf1,
       GF28
    0x71, GF28
    0xd8, GF28
    0x31, GF28
    0x15, GF28
    0x04, GF28
    0xc7, GF28
    0x23, GF28
    0xc3, GF28
    0x18, GF28
    0x96, GF28
    0x05,
       GF28
    0x9a, GF28
    0x07, GF28
    0x12, GF28
    0x80, GF28
    0xe2, GF28
    0xeb, GF28
    0x27, GF28
    0xb2, GF28
    0x75, GF28
    0x09, GF28
    0x83,
       GF28
    0x2c, GF28
    0x1a, GF28
    0x1b, GF28
    0x6e, GF28
    0x5a, GF28
    0xa0, GF28
    0x52, GF28
    0x3b, GF28
    0xd6, GF28
    0xb3, GF28
    0x29,
       GF28
    0xe3, GF28
    0x2f, GF28
    0x84, GF28
    0x53, GF28
    0xd1, GF28
    0x00, GF28
    0xed, GF28
    0x20, GF28
    0xfc, GF28
    0xb1, GF28
    0x5b,
       GF28
    0x6a, GF28
    0xcb, GF28
    0xbe, GF28
    0x39, GF28
    0x4a, GF28
    0x4c, GF28
    0x58, GF28
    0xcf, GF28
    0xd0, GF28
    0xef, GF28
    0xaa,
       GF28
    0xfb, GF28
    0x43, GF28
    0x4d, GF28
    0x33, GF28
    0x85, GF28
    0x45, GF28
    0xf9, GF28
    0x02, GF28
    0x7f, GF28
    0x50, GF28
    0x3c,
       GF28
    0x9f, GF28
    0xa8, GF28
    0x51, GF28
    0xa3, GF28
    0x40, GF28
    0x8f, GF28
    0x92, GF28
    0x9d, GF28
    0x38, GF28
    0xf5, GF28
    0xbc,
       GF28
    0xb6, GF28
    0xda, GF28
    0x21, GF28
    0x10, GF28
    0xff, GF28
    0xf3, GF28
    0xd2, GF28
    0xcd, GF28
    0x0c, GF28
    0x13, GF28
    0xec,
       GF28
    0x5f, GF28
    0x97, GF28
    0x44, GF28
    0x17, GF28
    0xc4, GF28
    0xa7, GF28
    0x7e, GF28
    0x3d, GF28
    0x64, GF28
    0x5d, GF28
    0x19,
       GF28
    0x73, GF28
    0x60, GF28
    0x81, GF28
    0x4f, GF28
    0xdc, GF28
    0x22, GF28
    0x2a, GF28
    0x90, GF28
    0x88, GF28
    0x46, GF28
    0xee,
       GF28
    0xb8, GF28
    0x14, GF28
    0xde, GF28
    0x5e, GF28
    0x0b, GF28
    0xdb, GF28
    0xe0, GF28
    0x32, GF28
    0x3a, GF28
    0x0a, GF28
    0x49,
       GF28
    0x06, GF28
    0x24, GF28
    0x5c, GF28
    0xc2, GF28
    0xd3, GF28
    0xac, GF28
    0x62, GF28
    0x91, GF28
    0x95, GF28
    0xe4, GF28
    0x79,
       GF28
    0xe7, GF28
    0xc8, GF28
    0x37, GF28
    0x6d, GF28
    0x8d, GF28
    0xd5, GF28
    0x4e, GF28
    0xa9, GF28
    0x6c, GF28
    0x56, GF28
    0xf4,
       GF28
    0xea, GF28
    0x65, GF28
    0x7a, GF28
    0xae, GF28
    0x08, GF28
    0xba, GF28
    0x78, GF28
    0x25, GF28
    0x2e, GF28
    0x1c, GF28
    0xa6,
       GF28
    0xb4, GF28
    0xc6, GF28
    0xe8, GF28
    0xdd, GF28
    0x74, GF28
    0x1f, GF28
    0x4b, GF28
    0xbd, GF28
    0x8b, GF28
    0x8a, GF28
    0x70,
       GF28
    0x3e, GF28
    0xb5, GF28
    0x66, GF28
    0x48, GF28
    0x03, GF28
    0xf6, GF28
    0x0e, GF28
    0x61, GF28
    0x35, GF28
    0x57, GF28
    0xb9,
       GF28
    0x86, GF28
    0xc1, GF28
    0x1d, GF28
    0x9e, GF28
    0xe1, GF28
    0xf8, GF28
    0x98, GF28
    0x11, GF28
    0x69, GF28
    0xd9, GF28
    0x8e,
       GF28
    0x94, GF28
    0x9b, GF28
    0x1e, GF28
    0x87, GF28
    0xe9, GF28
    0xce, GF28
    0x55, GF28
    0x28, GF28
    0xdf, GF28
    0x8c, GF28
    0xa1,
       GF28
    0x89, GF28
    0x0d, GF28
    0xbf, GF28
    0xe6, GF28
    0x42, GF28
    0x68, GF28
    0x41, GF28
    0x99, GF28
    0x2d, GF28
    0x0f, GF28
    0xb0,
       GF28
    0x54, GF28
    0xbb, GF28
    0x16]

    -- | The AES sbox transformation
    sbox :: GF28 -> GF28
    sbox :: GF28 -> GF28
    sbox GF28
    i = [GF28]
    sboxTable [GF28] -> Int -> GF28
    forall a. HasCallStack => [a] -> Int -> a
    !! GF28 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral GF28
    i

    -----------------------------------------------------------------------------
    -- ** The inverse S-box transformation
    -----------------------------------------------------------------------------

    unSBoxTable :: [GF28]
    unSBoxTable :: [GF28]
    unSBoxTable =
      [GF28
    0x52, GF28
    0x09, GF28
    0x6a, GF28
    0xd5, GF28
    0x30, GF28
    0x36, GF28
    0xa5, GF28
    0x38, GF28
    0xbf, GF28
    0x40, GF28
    0xa3,
       GF28
    0x9e, GF28
    0x81, GF28
    0xf3, GF28
    0xd7, GF28
    0xfb, GF28
    0x7c, GF28
    0xe3, GF28
    0x39, GF28
    0x82, GF28
    0x9b, GF28
    0x2f,
       GF28
    0xff, GF28
    0x87, GF28
    0x34, GF28
    0x8e, GF28
    0x43, GF28
    0x44, GF28
    0xc4, GF28
    0xde, GF28
    0xe9, GF28
    0xcb, GF28
    0x54,
       GF28
    0x7b, GF28
    0x94, GF28
    0x32, GF28
    0xa6, GF28
    0xc2, GF28
    0x23, GF28
    0x3d, GF28
    0xee, GF28
    0x4c, GF28
    0x95, GF28
    0x0b,
       GF28
    0x42, GF28
    0xfa, GF28
    0xc3, GF28
    0x4e, GF28
    0x08, GF28
    0x2e, GF28
    0xa1, GF28
    0x66, GF28
    0x28, GF28
    0xd9, GF28
    0x24,
       GF28
    0xb2, GF28
    0x76, GF28
    0x5b, GF28
    0xa2, GF28
    0x49, GF28
    0x6d, GF28
    0x8b, GF28
    0xd1, GF28
    0x25, GF28
    0x72, GF28
    0xf8,
       GF28
    0xf6, GF28
    0x64, GF28
    0x86, GF28
    0x68, GF28
    0x98, GF28
    0x16, GF28
    0xd4, GF28
    0xa4, GF28
    0x5c, GF28
    0xcc, GF28
    0x5d,
       GF28
    0x65, GF28
    0xb6, GF28
    0x92, GF28
    0x6c, GF28
    0x70, GF28
    0x48, GF28
    0x50, GF28
    0xfd, GF28
    0xed, GF28
    0xb9, GF28
    0xda,
       GF28
    0x5e, GF28
    0x15, GF28
    0x46, GF28
    0x57, GF28
    0xa7, GF28
    0x8d, GF28
    0x9d, GF28
    0x84, GF28
    0x90, GF28
    0xd8, GF28
    0xab,
       GF28
    0x00, GF28
    0x8c, GF28
    0xbc, GF28
    0xd3, GF28
    0x0a, GF28
    0xf7, GF28
    0xe4, GF28
    0x58, GF28
    0x05, GF28
    0xb8, GF28
    0xb3,
       GF28
    0x45, GF28
    0x06, GF28
    0xd0, GF28
    0x2c, GF28
    0x1e, GF28
    0x8f, GF28
    0xca, GF28
    0x3f, GF28
    0x0f, GF28
    0x02, GF28
    0xc1,
       GF28
    0xaf, GF28
    0xbd, GF28
    0x03, GF28
    0x01, GF28
    0x13, GF28
    0x8a, GF28
    0x6b, GF28
    0x3a, GF28
    0x91, GF28
    0x11, GF28
    0x41,
       GF28
    0x4f, GF28
    0x67, GF28
    0xdc, GF28
    0xea, GF28
    0x97, GF28
    0xf2, GF28
    0xcf, GF28
    0xce, GF28
    0xf0, GF28
    0xb4, GF28
    0xe6,
       GF28
    0x73, GF28
    0x96, GF28
    0xac, GF28
    0x74, GF28
    0x22, GF28
    0xe7, GF28
    0xad, GF28
    0x35, GF28
    0x85, GF28
    0xe2, GF28
    0xf9,
       GF28
    0x37, GF28
    0xe8, GF28
    0x1c, GF28
    0x75, GF28
    0xdf, GF28
    0x6e, GF28
    0x47, GF28
    0xf1, GF28
    0x1a, GF28
    0x71, GF28
    0x1d,
       GF28
    0x29, GF28
    0xc5, GF28
    0x89, GF28
    0x6f, GF28
    0xb7, GF28
    0x62, GF28
    0x0e, GF28
    0xaa, GF28
    0x18, GF28
    0xbe, GF28
    0x1b,
       GF28
    0xfc, GF28
    0x56, GF28
    0x3e, GF28
    0x4b, GF28
    0xc6, GF28
    0xd2, GF28
    0x79, GF28
    0x20, GF28
    0x9a, GF28
    0xdb, GF28
    0xc0,
       GF28
    0xfe, GF28
    0x78, GF28
    0xcd, GF28
    0x5a, GF28
    0xf4, GF28
    0x1f, GF28
    0xdd, GF28
    0xa8, GF28
    0x33, GF28
    0x88, GF28
    0x07,
       GF28
    0xc7, GF28
    0x31, GF28
    0xb1, GF28
    0x12, GF28
    0x10, GF28
    0x59, GF28
    0x27, GF28
    0x80, GF28
    0xec, GF28
    0x5f, GF28
    0x60,
       GF28
    0x51, GF28
    0x7f, GF28
    0xa9, GF28
    0x19, GF28
    0xb5, GF28
    0x4a, GF28
    0x0d, GF28
    0x2d, GF28
    0xe5, GF28
    0x7a, GF28
    0x9f,
       GF28
    0x93, GF28
    0xc9, GF28
    0x9c, GF28
    0xef, GF28
    0xa0, GF28
    0xe0, GF28
    0x3b, GF28
    0x4d, GF28
    0xae, GF28
    0x2a, GF28
    0xf5,
       GF28
    0xb0, GF28
    0xc8, GF28
    0xeb, GF28
    0xbb, GF28
    0x3c, GF28
    0x83, GF28
    0x53, GF28
    0x99, GF28
    0x61, GF28
    0x17, GF28
    0x2b,
       GF28
    0x04, GF28
    0x7e, GF28
    0xba, GF28
    0x77, GF28
    0xd6, GF28
    0x26, GF28
    0xe1, GF28
    0x69, GF28
    0x14, GF28
    0x63, GF28
    0x55,
       GF28
    0x21, GF28
    0x0c, GF28
    0x7d]

    -- | The inverse s-box transformation.
    unSBox :: GF28 -> GF28
    unSBox :: GF28 -> GF28
    unSBox GF28
    i = [GF28]
    unSBoxTable [GF28] -> Int -> GF28
    forall a. HasCallStack => [a] -> Int -> a
    !! GF28 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral GF28
    i

    -----------------------------------------------------------------------------
    -- ** Tables for T-Box encryption
    -----------------------------------------------------------------------------

    -- | T-box table generation function for encryption
    t0Func :: GF28 -> [GF28]
    t0Func :: GF28 -> [GF28]
    t0Func GF28
    a = [ GF28 -> GF28
    m2 GF28
    s, GF28
    s, GF28
    s, GF28 -> GF28
    m3 GF28
    s]
      where s :: GF28
    s = GF28 -> GF28
    sbox GF28
    a

    -- | First look-up table used in encryption
    t0 :: GF28 -> Word32
    t0 :: GF28 -> Word32
    t0 GF28
    i = State
    t0Table State -> Int -> Word32
    forall a. HasCallStack => [a] -> Int -> a
    !! GF28 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral GF28
    i

    t0Table :: [Word32]
    t0Table :: State
    t0Table = [[GF28] -> Word32
    fromBytes (GF28 -> [GF28]
    t0Func GF28
    a)          | GF28
    a <- [GF28
    0..GF28
    255]]

    -- | Second look-up table used in encryption
    t1 :: GF28 -> Word32
    t1 :: GF28 -> Word32
    t1 GF28
    i = State
    t1Table State -> Int -> Word32
    forall a. HasCallStack => [a] -> Int -> a
    !! GF28 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral GF28
    i

    t1Table :: [Word32]
    t1Table :: State
    t1Table = [[GF28] -> Word32
    fromBytes (GF28 -> [GF28]
    t0Func GF28
    a [GF28] -> Int -> [GF28]
    `rotR` Int
    1) | GF28
    a <- [GF28
    0..GF28
    255]]

    -- | Third look-up table used in encryption
    t2 :: GF28 -> Word32
    t2 :: GF28 -> Word32
    t2 GF28
    i = State
    t2Table State -> Int -> Word32
    forall a. HasCallStack => [a] -> Int -> a
    !! GF28 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral GF28
    i

    t2Table :: [Word32]
    t2Table :: State
    t2Table = [[GF28] -> Word32
    fromBytes (GF28 -> [GF28]
    t0Func GF28
    a [GF28] -> Int -> [GF28]
    `rotR` Int
    2) | GF28
    a <- [GF28
    0..GF28
    255]]

    -- | Fourth look-up table used in encryption
    t3 :: GF28 -> Word32
    t3 :: GF28 -> Word32
    t3 GF28
    i = State
    t3Table State -> Int -> Word32
    forall a. HasCallStack => [a] -> Int -> a
    !! GF28 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral GF28
    i

    t3Table :: [Word32]
    t3Table :: State
    t3Table = [[GF28] -> Word32
    fromBytes (GF28 -> [GF28]
    t0Func GF28
    a [GF28] -> Int -> [GF28]
    `rotR` Int
    3) | GF28
    a <- [GF28
    0..GF28
    255]]

    -----------------------------------------------------------------------------
    -- ** Tables for T-Box decryption
    -----------------------------------------------------------------------------

    -- | T-box table generating function for decryption
    u0Func :: GF28 -> [GF28]
    u0Func :: GF28 -> [GF28]
    u0Func GF28
    a = [ GF28 -> GF28
    mE GF28
    s, GF28 -> GF28
    m9 GF28
    s, GF28 -> GF28
    mD GF28
    s, GF28 -> GF28
    mB GF28
    s ]
     where s :: GF28
    s = GF28 -> GF28
    unSBox GF28
    a

    -- | First look-up table used in decryption
    u0 :: GF28 -> Word32
    u0 :: GF28 -> Word32
    u0 GF28
    i = State
    u0Table State -> Int -> Word32
    forall a. HasCallStack => [a] -> Int -> a
    !! GF28 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral GF28
    i

    u0Table :: [Word32]
    u0Table :: State
    u0Table = [[GF28] -> Word32
    fromBytes (GF28 -> [GF28]
    u0Func GF28
    a)          | GF28
    a <- [GF28
    0..GF28
    255]]

    -- | Second look-up table used in decryption
    u1 :: GF28 -> Word32
    u1 :: GF28 -> Word32
    u1 GF28
    i = State
    u1Table State -> Int -> Word32
    forall a. HasCallStack => [a] -> Int -> a
    !! GF28 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral GF28
    i

    u1Table :: [Word32]
    u1Table :: State
    u1Table = [[GF28] -> Word32
    fromBytes (GF28 -> [GF28]
    u0Func GF28
    a [GF28] -> Int -> [GF28]
    `rotR` Int
    1) | GF28
    a <- [GF28
    0..GF28
    255]]

    -- | Third look-up table used in decryption
    u2 :: GF28 -> Word32
    u2 :: GF28 -> Word32
    u2 GF28
    i = State
    u2Table State -> Int -> Word32
    forall a. HasCallStack => [a] -> Int -> a
    !! GF28 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral GF28
    i

    u2Table :: [Word32]
    u2Table :: State
    u2Table = [[GF28] -> Word32
    fromBytes (GF28 -> [GF28]
    u0Func GF28
    a [GF28] -> Int -> [GF28]
    `rotR` Int
    2) | GF28
    a <- [GF28
    0..GF28
    255]]

    -- | Fourth look-up table used in decryption
    u3 :: GF28 -> Word32
    u3 :: GF28 -> Word32
    u3 GF28
    i = State
    u3Table State -> Int -> Word32
    forall a. HasCallStack => [a] -> Int -> a
    !! GF28 -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral GF28
    i

    u3Table :: [Word32]
    u3Table :: State
    u3Table = [[GF28] -> Word32
    fromBytes (GF28 -> [GF28]
    u0Func GF28
    a [GF28] -> Int -> [GF28]
    `rotR` Int
    3) | GF28
    a <- [GF28
    0..GF28
    255]]

    -----------------------------------------------------------------------------
    -- ** AES rounds
    -----------------------------------------------------------------------------

    aesRound :: State -> State
    aesRound :: State -> State
    aesRound State
    s = State
    d
      where d :: State
    d = (Int -> Word32) -> [Int] -> State
    forall a b. (a -> b) -> [a] -> [b]
    map Int -> Word32
    f [Int
    0..Int
    3]
            a :: [[GF28]]
    a = (Word32 -> [GF28]) -> State -> [[GF28]]
    forall a b. (a -> b) -> [a] -> [b]
    map Word32 -> [GF28]
    toBytes State
    s
            f :: Int -> Word32
    f Int
    j = Word32
    e0 Word32 -> Word32 -> Word32
    forall a. Bits a => a -> a -> a
    `xor` Word32
    e1 Word32 -> Word32 -> Word32
    forall a. Bits a => a -> a -> a
    `xor` Word32
    e2 Word32 -> Word32 -> Word32
    forall a. Bits a => a -> a -> a
    `xor` Word32
    e3
                  where e0 :: Word32
    e0 = GF28 -> Word32
    t0 ([[GF28]]
    a [[GF28]] -> Int -> [GF28]
    forall a. HasCallStack => [a] -> Int -> a
    !! ((Int
    jInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    0) Int -> Int -> Int
    forall a. Integral a => a -> a -> a
    `mod` Int
    4) [GF28] -> Int -> GF28
    forall a. HasCallStack => [a] -> Int -> a
    !! Int
    0)
                        e1 :: Word32
    e1 = GF28 -> Word32
    t1 ([[GF28]]
    a [[GF28]] -> Int -> [GF28]
    forall a. HasCallStack => [a] -> Int -> a
    !! ((Int
    jInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    1) Int -> Int -> Int
    forall a. Integral a => a -> a -> a
    `mod` Int
    4) [GF28] -> Int -> GF28
    forall a. HasCallStack => [a] -> Int -> a
    !! Int
    1)
                        e2 :: Word32
    e2 = GF28 -> Word32
    t2 ([[GF28]]
    a [[GF28]] -> Int -> [GF28]
    forall a. HasCallStack => [a] -> Int -> a
    !! ((Int
    jInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    2) Int -> Int -> Int
    forall a. Integral a => a -> a -> a
    `mod` Int
    4) [GF28] -> Int -> GF28
    forall a. HasCallStack => [a] -> Int -> a
    !! Int
    2)
                        e3 :: Word32
    e3 = GF28 -> Word32
    t3 ([[GF28]]
    a [[GF28]] -> Int -> [GF28]
    forall a. HasCallStack => [a] -> Int -> a
    !! ((Int
    jInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    3) Int -> Int -> Int
    forall a. Integral a => a -> a -> a
    `mod` Int
    4) [GF28] -> Int -> GF28
    forall a. HasCallStack => [a] -> Int -> a
    !! Int
    3)

    aesFinalRound :: State -> State
    aesFinalRound :: State -> State
    aesFinalRound State
    s = State
    d
      where d :: State
    d = (Int -> Word32) -> [Int] -> State
    forall a b. (a -> b) -> [a] -> [b]
    map Int -> Word32
    f [Int
    0..Int
    3]
            a :: [[GF28]]
    a = (Word32 -> [GF28]) -> State -> [[GF28]]
    forall a b. (a -> b) -> [a] -> [b]
    map Word32 -> [GF28]
    toBytes State
    s
            f :: Int -> Word32
    f Int
    j = [GF28] -> Word32
    fromBytes [ GF28 -> GF28
    sbox ([[GF28]]
    a [[GF28]] -> Int -> [GF28]
    forall a. HasCallStack => [a] -> Int -> a
    !! ((Int
    jInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    0) Int -> Int -> Int
    forall a. Integral a => a -> a -> a
    `mod` Int
    4) [GF28] -> Int -> GF28
    forall a. HasCallStack => [a] -> Int -> a
    !! Int
    0)
                            , GF28 -> GF28
    sbox ([[GF28]]
    a [[GF28]] -> Int -> [GF28]
    forall a. HasCallStack => [a] -> Int -> a
    !! ((Int
    jInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    1) Int -> Int -> Int
    forall a. Integral a => a -> a -> a
    `mod` Int
    4) [GF28] -> Int -> GF28
    forall a. HasCallStack => [a] -> Int -> a
    !! Int
    1)
                            , GF28 -> GF28
    sbox ([[GF28]]
    a [[GF28]] -> Int -> [GF28]
    forall a. HasCallStack => [a] -> Int -> a
    !! ((Int
    jInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    2) Int -> Int -> Int
    forall a. Integral a => a -> a -> a
    `mod` Int
    4) [GF28] -> Int -> GF28
    forall a. HasCallStack => [a] -> Int -> a
    !! Int
    2)
                            , GF28 -> GF28
    sbox ([[GF28]]
    a [[GF28]] -> Int -> [GF28]
    forall a. HasCallStack => [a] -> Int -> a
    !! ((Int
    jInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    3) Int -> Int -> Int
    forall a. Integral a => a -> a -> a
    `mod` Int
    4) [GF28] -> Int -> GF28
    forall a. HasCallStack => [a] -> Int -> a
    !! Int
    3)
                            ]

    aesInvRound :: State -> State
    aesInvRound :: State -> State
    aesInvRound State
    s = State
    d
      where d :: State
    d = (Int -> Word32) -> [Int] -> State
    forall a b. (a -> b) -> [a] -> [b]
    map Int -> Word32
    f [Int
    0..Int
    3]
            a :: [[GF28]]
    a = (Word32 -> [GF28]) -> State -> [[GF28]]
    forall a b. (a -> b) -> [a] -> [b]
    map Word32 -> [GF28]
    toBytes State
    s
            f :: Int -> Word32
    f Int
    j = Word32
    e0 Word32 -> Word32 -> Word32
    forall a. Bits a => a -> a -> a
    `xor` Word32
    e1 Word32 -> Word32 -> Word32
    forall a. Bits a => a -> a -> a
    `xor` Word32
    e2 Word32 -> Word32 -> Word32
    forall a. Bits a => a -> a -> a
    `xor` Word32
    e3
                  where e0 :: Word32
    e0 = GF28 -> Word32
    u0 ([[GF28]]
    a [[GF28]] -> Int -> [GF28]
    forall a. HasCallStack => [a] -> Int -> a
    !! ((Int
    jInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    0) Int -> Int -> Int
    forall a. Integral a => a -> a -> a
    `mod` Int
    4) [GF28] -> Int -> GF28
    forall a. HasCallStack => [a] -> Int -> a
    !! Int
    0)
                        e1 :: Word32
    e1 = GF28 -> Word32
    u1 ([[GF28]]
    a [[GF28]] -> Int -> [GF28]
    forall a. HasCallStack => [a] -> Int -> a
    !! ((Int
    jInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    3) Int -> Int -> Int
    forall a. Integral a => a -> a -> a
    `mod` Int
    4) [GF28] -> Int -> GF28
    forall a. HasCallStack => [a] -> Int -> a
    !! Int
    1)
                        e2 :: Word32
    e2 = GF28 -> Word32
    u2 ([[GF28]]
    a [[GF28]] -> Int -> [GF28]
    forall a. HasCallStack => [a] -> Int -> a
    !! ((Int
    jInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    2) Int -> Int -> Int
    forall a. Integral a => a -> a -> a
    `mod` Int
    4) [GF28] -> Int -> GF28
    forall a. HasCallStack => [a] -> Int -> a
    !! Int
    2)
                        e3 :: Word32
    e3 = GF28 -> Word32
    u3 ([[GF28]]
    a [[GF28]] -> Int -> [GF28]
    forall a. HasCallStack => [a] -> Int -> a
    !! ((Int
    jInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    1) Int -> Int -> Int
    forall a. Integral a => a -> a -> a
    `mod` Int
    4) [GF28] -> Int -> GF28
    forall a. HasCallStack => [a] -> Int -> a
    !! Int
    3)

    aesInvFinalRound :: State -> State
    aesInvFinalRound :: State -> State
    aesInvFinalRound State
    s = State
    d
      where d :: State
    d = (Int -> Word32) -> [Int] -> State
    forall a b. (a -> b) -> [a] -> [b]
    map Int -> Word32
    f [Int
    0..Int
    3]
            a :: [[GF28]]
    a = (Word32 -> [GF28]) -> State -> [[GF28]]
    forall a b. (a -> b) -> [a] -> [b]
    map Word32 -> [GF28]
    toBytes State
    s
            f :: Int -> Word32
    f Int
    j = [GF28] -> Word32
    fromBytes [ GF28 -> GF28
    unSBox ([[GF28]]
    a [[GF28]] -> Int -> [GF28]
    forall a. HasCallStack => [a] -> Int -> a
    !! ((Int
    jInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    0) Int -> Int -> Int
    forall a. Integral a => a -> a -> a
    `mod` Int
    4) [GF28] -> Int -> GF28
    forall a. HasCallStack => [a] -> Int -> a
    !! Int
    0)
                            , GF28 -> GF28
    unSBox ([[GF28]]
    a [[GF28]] -> Int -> [GF28]
    forall a. HasCallStack => [a] -> Int -> a
    !! ((Int
    jInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    3) Int -> Int -> Int
    forall a. Integral a => a -> a -> a
    `mod` Int
    4) [GF28] -> Int -> GF28
    forall a. HasCallStack => [a] -> Int -> a
    !! Int
    1)
                            , GF28 -> GF28
    unSBox ([[GF28]]
    a [[GF28]] -> Int -> [GF28]
    forall a. HasCallStack => [a] -> Int -> a
    !! ((Int
    jInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    2) Int -> Int -> Int
    forall a. Integral a => a -> a -> a
    `mod` Int
    4) [GF28] -> Int -> GF28
    forall a. HasCallStack => [a] -> Int -> a
    !! Int
    2)
                            , GF28 -> GF28
    unSBox ([[GF28]]
    a [[GF28]] -> Int -> [GF28]
    forall a. HasCallStack => [a] -> Int -> a
    !! ((Int
    jInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    1) Int -> Int -> Int
    forall a. Integral a => a -> a -> a
    `mod` Int
    4) [GF28] -> Int -> GF28
    forall a. HasCallStack => [a] -> Int -> a
    !! Int
    3)
                            ]