-- |
-- Module      : Crypto.Store.Cipher.RC2.Primitive
-- License     : BSD-style
-- Maintainer  : Olivier Chéron <olivier.cheron@gmail.com>
-- Stability   : stable
-- Portability : good
--
{-# LANGUAGE Rank2Types #-}
module Crypto.Store.Cipher.RC2.Primitive
    ( Key
    , buildKey
    , encrypt
    , decrypt
    ) where

import Basement.Block
import Basement.Compat.IsList
import Basement.Endianness
import Basement.Types.OffsetSize

import Control.Monad (forM_)

import           Data.Bits
import           Data.ByteArray (ByteArrayAccess)
import qualified Data.ByteArray as B
import           Data.Word

import Foreign.Storable


-- | Expanded RC2 key
newtype Key = Key (Block Word16) -- [ K[0], K[1], ..., K[63] ]

data Q = Q {-# UNPACK #-} !Word16 {-# UNPACK #-} !Word16
           {-# UNPACK #-} !Word16 {-# UNPACK #-} !Word16


-- Utilities

decomp64 :: Word64 -> Q
decomp64 :: Word64 -> Q
decomp64 Word64
x =
    let d :: Word16
d = forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
x forall a. Bits a => a -> Int -> a
`shiftR` Int
48)
        c :: Word16
c = forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
x forall a. Bits a => a -> Int -> a
`shiftR` Int
32)
        b :: Word16
b = forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
x forall a. Bits a => a -> Int -> a
`shiftR` Int
16)
        a :: Word16
a = forall a b. (Integral a, Num b) => a -> b
fromIntegral  Word64
x
    in Word16 -> Word16 -> Word16 -> Word16 -> Q
Q Word16
a Word16
b Word16
c Word16
d

comp64 :: Q -> Word64
comp64 :: Q -> Word64
comp64 (Q Word16
a Word16
b Word16
c Word16
d) =
    (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
d forall a. Bits a => a -> Int -> a
`shiftL` Int
48) forall a. Bits a => a -> a -> a
.|.
    (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
c forall a. Bits a => a -> Int -> a
`shiftL` Int
32) forall a. Bits a => a -> a -> a
.|.
    (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
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 Word16
a

getR :: Q -> Word8 -> Word16
getR :: Q -> Word8 -> Word16
getR (Q Word16
a Word16
b Word16
c Word16
d) Word8
i =
    case Word8
i forall a. Bits a => a -> a -> a
.&. Word8
3 of
        Word8
0 -> Word16
a
        Word8
1 -> Word16
b
        Word8
2 -> Word16
c
        Word8
_ -> Word16
d
{-# INLINE getR #-}

setR :: Q -> Word8 -> Word16 -> Q
setR :: Q -> Word8 -> Word16 -> Q
setR (Q Word16
a Word16
b Word16
c Word16
d) Word8
i Word16
x =
    case Word8
i forall a. Bits a => a -> a -> a
.&. Word8
3 of
        Word8
0 -> Word16 -> Word16 -> Word16 -> Word16 -> Q
Q Word16
x Word16
b Word16
c Word16
d
        Word8
1 -> Word16 -> Word16 -> Word16 -> Word16 -> Q
Q Word16
a Word16
x Word16
c Word16
d
        Word8
2 -> Word16 -> Word16 -> Word16 -> Word16 -> Q
Q Word16
a Word16
b Word16
x Word16
d
        Word8
_ -> Word16 -> Word16 -> Word16 -> Word16 -> Q
Q Word16
a Word16
b Word16
c Word16
x
{-# INLINE setR #-}

rol :: Word8 -> Word16 -> Word16
rol :: Word8 -> Word16 -> Word16
rol Word8
i =
    case Word8
i forall a. Bits a => a -> a -> a
.&. Word8
3 of
        Word8
0 -> forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. Bits a => a -> Int -> a
rotateL Int
1
        Word8
1 -> forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. Bits a => a -> Int -> a
rotateL Int
2
        Word8
2 -> forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. Bits a => a -> Int -> a
rotateL Int
3
        Word8
_ -> forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. Bits a => a -> Int -> a
rotateL Int
5
{-# INLINE rol #-}

ror :: Word8 -> Word16 -> Word16
ror :: Word8 -> Word16 -> Word16
ror Word8
i =
    case Word8
i forall a. Bits a => a -> a -> a
.&. Word8
3 of
        Word8
0 -> forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. Bits a => a -> Int -> a
rotateR Int
1
        Word8
1 -> forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. Bits a => a -> Int -> a
rotateR Int
2
        Word8
2 -> forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. Bits a => a -> Int -> a
rotateR Int
3
        Word8
_ -> forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. Bits a => a -> Int -> a
rotateR Int
5
{-# INLINE ror #-}

f5 :: (a -> a) -> a -> a
f5 :: forall a. (a -> a) -> a -> a
f5 a -> a
f = a -> a
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
f

f6 :: (a -> a) -> a -> a
f6 :: forall a. (a -> a) -> a -> a
f6 a -> a
f = a -> a
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
f


-- Encryption

-- | Encrypts a block using the specified key
encrypt :: Key -> Word64 -> Word64
encrypt :: Key -> Word64 -> Word64
encrypt Key
k = Q -> Word64
comp64 forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Q -> Q
enc Key
k forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Q
decomp64

enc :: Key -> Q -> Q
enc :: Key -> Q -> Q
enc Key
k Q
r =
    forall a b. (a, b) -> a
fst forall a b. (a -> b) -> a -> b
$ forall a. (a -> a) -> a -> a
f5 (Key -> (Q, Int) -> (Q, Int)
mixingRound Key
k) forall a b. (a -> b) -> a -> b
$ Key -> (Q, Int) -> (Q, Int)
mashingRound Key
k
        forall a b. (a -> b) -> a -> b
$ forall a. (a -> a) -> a -> a
f6 (Key -> (Q, Int) -> (Q, Int)
mixingRound Key
k) forall a b. (a -> b) -> a -> b
$ Key -> (Q, Int) -> (Q, Int)
mashingRound Key
k
        forall a b. (a -> b) -> a -> b
$ forall a. (a -> a) -> a -> a
f5 (Key -> (Q, Int) -> (Q, Int)
mixingRound Key
k) (Q
r, Int
0)

-- Decryption

-- | Decrypts a block using the specified key
decrypt :: Key -> Word64 -> Word64
decrypt :: Key -> Word64 -> Word64
decrypt Key
k = Q -> Word64
comp64 forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Q -> Q
dec Key
k forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word64 -> Q
decomp64

dec :: Key -> Q -> Q
dec :: Key -> Q -> Q
dec Key
k Q
r =
    forall a b. (a, b) -> a
fst forall a b. (a -> b) -> a -> b
$ forall a. (a -> a) -> a -> a
f5 (Key -> (Q, Int) -> (Q, Int)
rmixingRound Key
k) forall a b. (a -> b) -> a -> b
$ Key -> (Q, Int) -> (Q, Int)
rmashingRound Key
k
        forall a b. (a -> b) -> a -> b
$ forall a. (a -> a) -> a -> a
f6 (Key -> (Q, Int) -> (Q, Int)
rmixingRound Key
k) forall a b. (a -> b) -> a -> b
$ Key -> (Q, Int) -> (Q, Int)
rmashingRound Key
k
        forall a b. (a -> b) -> a -> b
$ forall a. (a -> a) -> a -> a
f5 (Key -> (Q, Int) -> (Q, Int)
rmixingRound Key
k) (Q
r, Int
63)


-- Encryptiong rounds

mixUp :: Key -> Word8 -> (Q, Int) -> (Q, Int)
mixUp :: Key -> Word8 -> (Q, Int) -> (Q, Int)
mixUp Key
k Word8
i input :: (Q, Int)
input@(Q
r, Int
j) = seq :: forall a b. a -> b -> b
seq Q
r' forall a b. (a -> b) -> a -> b
$ seq :: forall a b. a -> b -> b
seq Int
j' (Q
r', Int
j')
  where j' :: Int
j' = Int
j forall a. Num a => a -> a -> a
+ Int
1
        r' :: Q
r' = Q -> Word8 -> Word16 -> Q
setR Q
r Word8
i (Word8 -> Word16 -> Word16
rol Word8
i (Word16
ri forall a. Num a => a -> a -> a
+ Key -> Word8 -> (Q, Int) -> Word16
gmix Key
k Word8
i (Q, Int)
input))
        ri :: Word16
ri = Q -> Word8 -> Word16
getR Q
r Word8
i
{-# INLINE mixUp #-}

mixingRound :: Key -> (Q, Int) -> (Q, Int)
mixingRound :: Key -> (Q, Int) -> (Q, Int)
mixingRound Key
k = Key -> Word8 -> (Q, Int) -> (Q, Int)
mixUp Key
k Word8
3 forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Word8 -> (Q, Int) -> (Q, Int)
mixUp Key
k Word8
2 forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Word8 -> (Q, Int) -> (Q, Int)
mixUp Key
k Word8
1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Word8 -> (Q, Int) -> (Q, Int)
mixUp Key
k Word8
0

mash :: Key -> Word8 -> (Q, Int) -> (Q, Int)
mash :: Key -> Word8 -> (Q, Int) -> (Q, Int)
mash = (Word16 -> Word16 -> Word16)
-> Key -> Word8 -> (Q, Int) -> (Q, Int)
gmash forall a. Num a => a -> a -> a
(+)
{-# INLINE mash #-}

mashingRound :: Key -> (Q, Int) -> (Q, Int)
mashingRound :: Key -> (Q, Int) -> (Q, Int)
mashingRound Key
k = Key -> Word8 -> (Q, Int) -> (Q, Int)
mash Key
k Word8
3 forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Word8 -> (Q, Int) -> (Q, Int)
mash Key
k Word8
2 forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Word8 -> (Q, Int) -> (Q, Int)
mash Key
k Word8
1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Word8 -> (Q, Int) -> (Q, Int)
mash Key
k Word8
0


-- Decryption rounds

rmixUp :: Key -> Word8 -> (Q, Int) -> (Q, Int)
rmixUp :: Key -> Word8 -> (Q, Int) -> (Q, Int)
rmixUp Key
k Word8
i input :: (Q, Int)
input@(Q
r, Int
j) = seq :: forall a b. a -> b -> b
seq Q
r' forall a b. (a -> b) -> a -> b
$ seq :: forall a b. a -> b -> b
seq Int
j' (Q
r', Int
j')
  where j' :: Int
j' = Int
j forall a. Num a => a -> a -> a
- Int
1
        r' :: Q
r' = Q -> Word8 -> Word16 -> Q
setR Q
r Word8
i (Word16
ri forall a. Num a => a -> a -> a
- Key -> Word8 -> (Q, Int) -> Word16
gmix Key
k Word8
i (Q, Int)
input)
        ri :: Word16
ri = Word8 -> Word16 -> Word16
ror Word8
i (Q -> Word8 -> Word16
getR Q
r Word8
i)
{-# INLINE rmixUp #-}

rmixingRound :: Key -> (Q, Int) -> (Q, Int)
rmixingRound :: Key -> (Q, Int) -> (Q, Int)
rmixingRound Key
k = Key -> Word8 -> (Q, Int) -> (Q, Int)
rmixUp Key
k Word8
0 forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Word8 -> (Q, Int) -> (Q, Int)
rmixUp Key
k Word8
1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Word8 -> (Q, Int) -> (Q, Int)
rmixUp Key
k Word8
2 forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Word8 -> (Q, Int) -> (Q, Int)
rmixUp Key
k Word8
3

rmash :: Key -> Word8 -> (Q, Int) -> (Q, Int)
rmash :: Key -> Word8 -> (Q, Int) -> (Q, Int)
rmash = (Word16 -> Word16 -> Word16)
-> Key -> Word8 -> (Q, Int) -> (Q, Int)
gmash (-)
{-# INLINE rmash #-}

rmashingRound :: Key -> (Q, Int) -> (Q, Int)
rmashingRound :: Key -> (Q, Int) -> (Q, Int)
rmashingRound Key
k = Key -> Word8 -> (Q, Int) -> (Q, Int)
rmash Key
k Word8
0 forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Word8 -> (Q, Int) -> (Q, Int)
rmash Key
k Word8
1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Word8 -> (Q, Int) -> (Q, Int)
rmash Key
k Word8
2 forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Word8 -> (Q, Int) -> (Q, Int)
rmash Key
k Word8
3


-- Generic rounds

gmix :: Key -> Word8 -> (Q, Int) -> Word16
gmix :: Key -> Word8 -> (Q, Int) -> Word16
gmix (Key Block Word16
k) Word8
i (Q
r, Int
j) = Word16
kj forall a. Num a => a -> a -> a
+ (Word16
ri1 forall a. Bits a => a -> a -> a
.&. Word16
ri2) forall a. Num a => a -> a -> a
+ (forall a. Bits a => a -> a
complement Word16
ri1 forall a. Bits a => a -> a -> a
.&. Word16
ri3)
  where ri1 :: Word16
ri1 = Q -> Word8 -> Word16
getR Q
r (Word8
i forall a. Num a => a -> a -> a
- Word8
1)
        ri2 :: Word16
ri2 = Q -> Word8 -> Word16
getR Q
r (Word8
i forall a. Num a => a -> a -> a
- Word8
2)
        ri3 :: Word16
ri3 = Q -> Word8 -> Word16
getR Q
r (Word8
i forall a. Num a => a -> a -> a
- Word8
3)
        kj :: Word16
kj  = forall ty. PrimType ty => Block ty -> Offset ty -> ty
unsafeIndex Block Word16
k (forall ty. Int -> Offset ty
Offset Int
j)
{-# INLINE gmix #-}

gmash :: (Word16 -> Word16 -> Word16)
      -> Key -> Word8 -> (Q, Int) -> (Q, Int)
gmash :: (Word16 -> Word16 -> Word16)
-> Key -> Word8 -> (Q, Int) -> (Q, Int)
gmash Word16 -> Word16 -> Word16
op (Key Block Word16
k) Word8
i (Q
r, Int
j) = seq :: forall a b. a -> b -> b
seq Q
r' forall a b. (a -> b) -> a -> b
$ seq :: forall a b. a -> b -> b
seq Int
j (Q
r', Int
j)
  where r' :: Q
r'  = Q -> Word8 -> Word16 -> Q
setR Q
r Word8
i (Word16
ri Word16 -> Word16 -> Word16
`op` Word16
kp)
        ri :: Word16
ri  = Q -> Word8 -> Word16
getR Q
r Word8
i
        ri1 :: Word16
ri1 = Q -> Word8 -> Word16
getR Q
r (Word8
i forall a. Num a => a -> a -> a
- Word8
1)
        kp :: Word16
kp  = forall ty. PrimType ty => Block ty -> Offset ty -> ty
unsafeIndex Block Word16
k forall a b. (a -> b) -> a -> b
$ forall ty. Int -> Offset ty
Offset (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
ri1 forall a. Bits a => a -> a -> a
.&. Int
63)
{-# INLINE gmash #-}


-- Key expansion

-- | Perform key expansion
buildKey :: ByteArrayAccess key
         => Int    -- ^ Effective key length in bits
         -> key    -- ^ Input key between 1 and 128 bytes
         -> Key    -- ^ Expanded key
buildKey :: forall key. ByteArrayAccess key => Int -> key -> Key
buildKey Int
t1 key
key = Block Word16 -> Key
Key forall a b. (a -> b) -> a -> b
$ Block Word8 -> Block Word16
doCast forall a b. (a -> b) -> a -> b
$ forall a p. ByteArray a => Int -> (Ptr p -> IO ()) -> a
B.allocAndFreeze Int
128 forall a b. (a -> b) -> a -> b
$ \Ptr Word8
p -> do
    forall ba p. ByteArrayAccess ba => ba -> Ptr p -> IO ()
B.copyByteArrayToPtr key
key Ptr Word8
p

    forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Int
t .. Int
127] forall a b. (a -> b) -> a -> b
$ \Int
i -> do
        Word8
pos <- forall a. Num a => a -> a -> a
(+) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr Word8
p (Int
i forall a. Num a => a -> a -> a
- Int
1) forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr Word8
p (Int
i forall a. Num a => a -> a -> a
- Int
t)
        let b :: Word8
b = forall ty. PrimType ty => Block ty -> Offset ty -> ty
unsafeIndex Block Word8
piTable (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
pos)
        forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff Ptr Word8
p Int
i Word8
b

    Word8
pos' <- (forall a. Bits a => a -> a -> a
.&. Word8
tm) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr Word8
p (Int
128 forall a. Num a => a -> a -> a
- Int
t8)
    let b' :: Word8
b' = forall ty. PrimType ty => Block ty -> Offset ty -> ty
unsafeIndex Block Word8
piTable (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
pos')
    forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff Ptr Word8
p (Int
128 forall a. Num a => a -> a -> a
- Int
t8) Word8
b'

    forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ (forall a. [a] -> [a]
Prelude.reverse [Int
0 .. Int
127 forall a. Num a => a -> a -> a
- Int
t8]) forall a b. (a -> b) -> a -> b
$ \Int
i -> do
        Word8
pos <- forall a. Bits a => a -> a -> a
xor forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr Word8
p (Int
i forall a. Num a => a -> a -> a
+ Int
1) forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr Word8
p (Int
i forall a. Num a => a -> a -> a
+ Int
t8)
        let b :: Word8
b = forall ty. PrimType ty => Block ty -> Offset ty -> ty
unsafeIndex Block Word8
piTable (forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
pos)
        forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff Ptr Word8
p Int
i Word8
b

  where t :: Int
t  = forall ba. ByteArrayAccess ba => ba -> Int
B.length key
key
        t8 :: Int
t8 = (Int
t1 forall a. Num a => a -> a -> a
+ Int
7) forall a. Integral a => a -> a -> a
`div` Int
8
        tm :: Word8
tm | Int
t1 forall a. Eq a => a -> a -> Bool
== Int
8 forall a. Num a => a -> a -> a
* Int
t8 = Word8
255
           | Bool
otherwise    = Word8
255 forall a. Integral a => a -> a -> a
`mod` forall a. Bits a => a -> Int -> a
shiftL Word8
1 (Int
8 forall a. Num a => a -> a -> a
+ Int
t1 forall a. Num a => a -> a -> a
- Int
8 forall a. Num a => a -> a -> a
* Int
t8)

        doCast :: Block Word8 -> Block Word16
        doCast :: Block Word8 -> Block Word16
doCast = forall a b.
(PrimType a, PrimType b) =>
(a -> b) -> Block a -> Block b
Basement.Block.map forall a. ByteSwap a => LE a -> a
fromLE forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (PrimType a, PrimType b) => Block a -> Block b
cast


-- PITABLE

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