{-# 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
newtype Key = Key (Block Word16)
data Q = Q {-# UNPACK #-} !Word16 {-# UNPACK #-} !Word16
{-# UNPACK #-} !Word16 {-# UNPACK #-} !Word16
decomp64 :: Word64 -> Q
decomp64 :: Word64 -> Q
decomp64 Word64
x =
let d :: Word16
d = Word64 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
x Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` Int
48)
c :: Word16
c = Word64 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
x Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` Int
32)
b :: Word16
b = Word64 -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64
x Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` Int
16)
a :: Word16
a = Word64 -> Word16
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) =
(Word16 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
d Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
48) Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|.
(Word16 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
c Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
32) Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|.
(Word16 -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
b Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
16) Word64 -> Word64 -> Word64
forall a. Bits a => a -> a -> a
.|.
Word16 -> Word64
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 Word8 -> Word8 -> Word8
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 Word8 -> Word8 -> Word8
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 Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
3 of
Word8
0 -> (Word16 -> Int -> Word16) -> Int -> Word16 -> Word16
forall a b c. (a -> b -> c) -> b -> a -> c
flip Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
rotateL Int
1
Word8
1 -> (Word16 -> Int -> Word16) -> Int -> Word16 -> Word16
forall a b c. (a -> b -> c) -> b -> a -> c
flip Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
rotateL Int
2
Word8
2 -> (Word16 -> Int -> Word16) -> Int -> Word16 -> Word16
forall a b c. (a -> b -> c) -> b -> a -> c
flip Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
rotateL Int
3
Word8
_ -> (Word16 -> Int -> Word16) -> Int -> Word16 -> Word16
forall a b c. (a -> b -> c) -> b -> a -> c
flip Word16 -> Int -> Word16
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 Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
3 of
Word8
0 -> (Word16 -> Int -> Word16) -> Int -> Word16 -> Word16
forall a b c. (a -> b -> c) -> b -> a -> c
flip Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
rotateR Int
1
Word8
1 -> (Word16 -> Int -> Word16) -> Int -> Word16 -> Word16
forall a b c. (a -> b -> c) -> b -> a -> c
flip Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
rotateR Int
2
Word8
2 -> (Word16 -> Int -> Word16) -> Int -> Word16 -> Word16
forall a b c. (a -> b -> c) -> b -> a -> c
flip Word16 -> Int -> Word16
forall a. Bits a => a -> Int -> a
rotateR Int
3
Word8
_ -> (Word16 -> Int -> Word16) -> Int -> Word16 -> Word16
forall a b c. (a -> b -> c) -> b -> a -> c
flip Word16 -> Int -> Word16
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 (a -> a) -> (a -> a) -> a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
f (a -> a) -> (a -> a) -> a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
f (a -> a) -> (a -> a) -> a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
f (a -> a) -> (a -> a) -> a -> a
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 (a -> a) -> (a -> a) -> a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
f (a -> a) -> (a -> a) -> a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
f (a -> a) -> (a -> a) -> a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
f (a -> a) -> (a -> a) -> a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
f (a -> a) -> (a -> a) -> a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
f
encrypt :: Key -> Word64 -> Word64
encrypt :: Key -> Word64 -> Word64
encrypt Key
k = Q -> Word64
comp64 (Q -> Word64) -> (Word64 -> Q) -> Word64 -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Q -> Q
enc Key
k (Q -> Q) -> (Word64 -> Q) -> Word64 -> Q
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 =
(Q, Int) -> Q
forall a b. (a, b) -> a
fst ((Q, Int) -> Q) -> (Q, Int) -> Q
forall a b. (a -> b) -> a -> b
$ ((Q, Int) -> (Q, Int)) -> (Q, Int) -> (Q, Int)
forall a. (a -> a) -> a -> a
f5 (Key -> (Q, Int) -> (Q, Int)
mixingRound Key
k) ((Q, Int) -> (Q, Int)) -> (Q, Int) -> (Q, Int)
forall a b. (a -> b) -> a -> b
$ Key -> (Q, Int) -> (Q, Int)
mashingRound Key
k
((Q, Int) -> (Q, Int)) -> (Q, Int) -> (Q, Int)
forall a b. (a -> b) -> a -> b
$ ((Q, Int) -> (Q, Int)) -> (Q, Int) -> (Q, Int)
forall a. (a -> a) -> a -> a
f6 (Key -> (Q, Int) -> (Q, Int)
mixingRound Key
k) ((Q, Int) -> (Q, Int)) -> (Q, Int) -> (Q, Int)
forall a b. (a -> b) -> a -> b
$ Key -> (Q, Int) -> (Q, Int)
mashingRound Key
k
((Q, Int) -> (Q, Int)) -> (Q, Int) -> (Q, Int)
forall a b. (a -> b) -> a -> b
$ ((Q, Int) -> (Q, Int)) -> (Q, Int) -> (Q, Int)
forall a. (a -> a) -> a -> a
f5 (Key -> (Q, Int) -> (Q, Int)
mixingRound Key
k) (Q
r, Int
0)
decrypt :: Key -> Word64 -> Word64
decrypt :: Key -> Word64 -> Word64
decrypt Key
k = Q -> Word64
comp64 (Q -> Word64) -> (Word64 -> Q) -> Word64 -> Word64
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Q -> Q
dec Key
k (Q -> Q) -> (Word64 -> Q) -> Word64 -> Q
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 =
(Q, Int) -> Q
forall a b. (a, b) -> a
fst ((Q, Int) -> Q) -> (Q, Int) -> Q
forall a b. (a -> b) -> a -> b
$ ((Q, Int) -> (Q, Int)) -> (Q, Int) -> (Q, Int)
forall a. (a -> a) -> a -> a
f5 (Key -> (Q, Int) -> (Q, Int)
rmixingRound Key
k) ((Q, Int) -> (Q, Int)) -> (Q, Int) -> (Q, Int)
forall a b. (a -> b) -> a -> b
$ Key -> (Q, Int) -> (Q, Int)
rmashingRound Key
k
((Q, Int) -> (Q, Int)) -> (Q, Int) -> (Q, Int)
forall a b. (a -> b) -> a -> b
$ ((Q, Int) -> (Q, Int)) -> (Q, Int) -> (Q, Int)
forall a. (a -> a) -> a -> a
f6 (Key -> (Q, Int) -> (Q, Int)
rmixingRound Key
k) ((Q, Int) -> (Q, Int)) -> (Q, Int) -> (Q, Int)
forall a b. (a -> b) -> a -> b
$ Key -> (Q, Int) -> (Q, Int)
rmashingRound Key
k
((Q, Int) -> (Q, Int)) -> (Q, Int) -> (Q, Int)
forall a b. (a -> b) -> a -> b
$ ((Q, Int) -> (Q, Int)) -> (Q, Int) -> (Q, Int)
forall a. (a -> a) -> a -> a
f5 (Key -> (Q, Int) -> (Q, Int)
rmixingRound Key
k) (Q
r, Int
63)
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) = Q -> (Q, Int) -> (Q, Int)
forall a b. a -> b -> b
seq Q
r' ((Q, Int) -> (Q, Int)) -> (Q, Int) -> (Q, Int)
forall a b. (a -> b) -> a -> b
$ Int -> (Q, Int) -> (Q, Int)
forall a b. a -> b -> b
seq Int
j' (Q
r', Int
j')
where j' :: Int
j' = Int
j Int -> Int -> Int
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 Word16 -> Word16 -> Word16
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 ((Q, Int) -> (Q, Int))
-> ((Q, Int) -> (Q, Int)) -> (Q, Int) -> (Q, Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Word8 -> (Q, Int) -> (Q, Int)
mixUp Key
k Word8
2 ((Q, Int) -> (Q, Int))
-> ((Q, Int) -> (Q, Int)) -> (Q, Int) -> (Q, Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Word8 -> (Q, Int) -> (Q, Int)
mixUp Key
k Word8
1 ((Q, Int) -> (Q, Int))
-> ((Q, Int) -> (Q, Int)) -> (Q, Int) -> (Q, Int)
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 Word16 -> Word16 -> Word16
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 ((Q, Int) -> (Q, Int))
-> ((Q, Int) -> (Q, Int)) -> (Q, Int) -> (Q, Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Word8 -> (Q, Int) -> (Q, Int)
mash Key
k Word8
2 ((Q, Int) -> (Q, Int))
-> ((Q, Int) -> (Q, Int)) -> (Q, Int) -> (Q, Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Word8 -> (Q, Int) -> (Q, Int)
mash Key
k Word8
1 ((Q, Int) -> (Q, Int))
-> ((Q, Int) -> (Q, Int)) -> (Q, Int) -> (Q, Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Word8 -> (Q, Int) -> (Q, Int)
mash Key
k Word8
0
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) = Q -> (Q, Int) -> (Q, Int)
forall a b. a -> b -> b
seq Q
r' ((Q, Int) -> (Q, Int)) -> (Q, Int) -> (Q, Int)
forall a b. (a -> b) -> a -> b
$ Int -> (Q, Int) -> (Q, Int)
forall a b. a -> b -> b
seq Int
j' (Q
r', Int
j')
where j' :: Int
j' = Int
j Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
r' :: Q
r' = Q -> Word8 -> Word16 -> Q
setR Q
r Word8
i (Word16
ri Word16 -> Word16 -> Word16
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 ((Q, Int) -> (Q, Int))
-> ((Q, Int) -> (Q, Int)) -> (Q, Int) -> (Q, Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Word8 -> (Q, Int) -> (Q, Int)
rmixUp Key
k Word8
1 ((Q, Int) -> (Q, Int))
-> ((Q, Int) -> (Q, Int)) -> (Q, Int) -> (Q, Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Word8 -> (Q, Int) -> (Q, Int)
rmixUp Key
k Word8
2 ((Q, Int) -> (Q, Int))
-> ((Q, Int) -> (Q, Int)) -> (Q, Int) -> (Q, Int)
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 ((Q, Int) -> (Q, Int))
-> ((Q, Int) -> (Q, Int)) -> (Q, Int) -> (Q, Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Word8 -> (Q, Int) -> (Q, Int)
rmash Key
k Word8
1 ((Q, Int) -> (Q, Int))
-> ((Q, Int) -> (Q, Int)) -> (Q, Int) -> (Q, Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Word8 -> (Q, Int) -> (Q, Int)
rmash Key
k Word8
2 ((Q, Int) -> (Q, Int))
-> ((Q, Int) -> (Q, Int)) -> (Q, Int) -> (Q, Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Key -> Word8 -> (Q, Int) -> (Q, Int)
rmash Key
k Word8
3
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 Word16 -> Word16 -> Word16
forall a. Num a => a -> a -> a
+ (Word16
ri1 Word16 -> Word16 -> Word16
forall a. Bits a => a -> a -> a
.&. Word16
ri2) Word16 -> Word16 -> Word16
forall a. Num a => a -> a -> a
+ (Word16 -> Word16
forall a. Bits a => a -> a
complement Word16
ri1 Word16 -> Word16 -> Word16
forall a. Bits a => a -> a -> a
.&. Word16
ri3)
where ri1 :: Word16
ri1 = Q -> Word8 -> Word16
getR Q
r (Word8
i Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
- Word8
1)
ri2 :: Word16
ri2 = Q -> Word8 -> Word16
getR Q
r (Word8
i Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
- Word8
2)
ri3 :: Word16
ri3 = Q -> Word8 -> Word16
getR Q
r (Word8
i Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
- Word8
3)
kj :: Word16
kj = Block Word16 -> Offset Word16 -> Word16
forall ty. PrimType ty => Block ty -> Offset ty -> ty
unsafeIndex Block Word16
k (Int -> Offset Word16
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) = Q -> (Q, Int) -> (Q, Int)
forall a b. a -> b -> b
seq Q
r' ((Q, Int) -> (Q, Int)) -> (Q, Int) -> (Q, Int)
forall a b. (a -> b) -> a -> b
$ Int -> (Q, Int) -> (Q, Int)
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 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
- Word8
1)
kp :: Word16
kp = Block Word16 -> Offset Word16 -> Word16
forall ty. PrimType ty => Block ty -> Offset ty -> ty
unsafeIndex Block Word16
k (Offset Word16 -> Word16) -> Offset Word16 -> Word16
forall a b. (a -> b) -> a -> b
$ Int -> Offset Word16
forall ty. Int -> Offset ty
Offset (Word16 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
ri1 Int -> Int -> Int
forall a. Bits a => a -> a -> a
.&. Int
63)
{-# INLINE gmash #-}
buildKey :: ByteArrayAccess key
=> Int
-> key
-> Key
buildKey :: forall key. ByteArrayAccess key => Int -> key -> Key
buildKey Int
t1 key
key = Block Word16 -> Key
Key (Block Word16 -> Key) -> Block Word16 -> Key
forall a b. (a -> b) -> a -> b
$ Block Word8 -> Block Word16
doCast (Block Word8 -> Block Word16) -> Block Word8 -> Block Word16
forall a b. (a -> b) -> a -> b
$ Int -> (Ptr Word8 -> IO ()) -> Block Word8
forall a p. ByteArray a => Int -> (Ptr p -> IO ()) -> a
B.allocAndFreeze Int
128 ((Ptr Word8 -> IO ()) -> Block Word8)
-> (Ptr Word8 -> IO ()) -> Block Word8
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
p -> do
key -> Ptr Word8 -> IO ()
forall p. key -> Ptr p -> IO ()
forall ba p. ByteArrayAccess ba => ba -> Ptr p -> IO ()
B.copyByteArrayToPtr key
key Ptr Word8
p
[Int] -> (Int -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Int
t .. Int
127] ((Int -> IO ()) -> IO ()) -> (Int -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Int
i -> do
Word8
pos <- Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
(+) (Word8 -> Word8 -> Word8) -> IO Word8 -> IO (Word8 -> Word8)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr Word8 -> Int -> IO Word8
forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr Word8
p (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) IO (Word8 -> Word8) -> IO Word8 -> IO Word8
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Ptr Word8 -> Int -> IO Word8
forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr Word8
p (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
t)
let b :: Word8
b = Block Word8 -> Offset Word8 -> Word8
forall ty. PrimType ty => Block ty -> Offset ty -> ty
unsafeIndex Block Word8
piTable (Word8 -> Offset Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
pos)
Ptr Word8 -> Int -> Word8 -> IO ()
forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff Ptr Word8
p Int
i Word8
b
Word8
pos' <- (Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
tm) (Word8 -> Word8) -> IO Word8 -> IO Word8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr Word8 -> Int -> IO Word8
forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr Word8
p (Int
128 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
t8)
let b' :: Word8
b' = Block Word8 -> Offset Word8 -> Word8
forall ty. PrimType ty => Block ty -> Offset ty -> ty
unsafeIndex Block Word8
piTable (Word8 -> Offset Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
pos')
Ptr Word8 -> Int -> Word8 -> IO ()
forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff Ptr Word8
p (Int
128 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
t8) Word8
b'
[Int] -> (Int -> IO ()) -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ ([Int] -> [Int]
forall a. [a] -> [a]
Prelude.reverse [Int
0 .. Int
127 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
t8]) ((Int -> IO ()) -> IO ()) -> (Int -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Int
i -> do
Word8
pos <- Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
xor (Word8 -> Word8 -> Word8) -> IO Word8 -> IO (Word8 -> Word8)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr Word8 -> Int -> IO Word8
forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr Word8
p (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) IO (Word8 -> Word8) -> IO Word8 -> IO Word8
forall a b. IO (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Ptr Word8 -> Int -> IO Word8
forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr Word8
p (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
t8)
let b :: Word8
b = Block Word8 -> Offset Word8 -> Word8
forall ty. PrimType ty => Block ty -> Offset ty -> ty
unsafeIndex Block Word8
piTable (Word8 -> Offset Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
pos)
Ptr Word8 -> Int -> Word8 -> IO ()
forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff Ptr Word8
p Int
i Word8
b
where t :: Int
t = key -> Int
forall ba. ByteArrayAccess ba => ba -> Int
B.length key
key
t8 :: Int
t8 = (Int
t1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
7) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
8
tm :: Word8
tm | Int
t1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
8 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
t8 = Word8
255
| Bool
otherwise = Word8
255 Word8 -> Word8 -> Word8
forall a. Integral a => a -> a -> a
`mod` Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
shiftL Word8
1 (Int
8 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
t1 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
8 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
t8)
doCast :: Block Word8 -> Block Word16
doCast :: Block Word8 -> Block Word16
doCast = (LE Word16 -> Word16) -> Block (LE Word16) -> Block Word16
forall a b.
(PrimType a, PrimType b) =>
(a -> b) -> Block a -> Block b
Basement.Block.map LE Word16 -> Word16
forall a. ByteSwap a => LE a -> a
fromLE (Block (LE Word16) -> Block Word16)
-> (Block Word8 -> Block (LE Word16))
-> Block Word8
-> Block Word16
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Block Word8 -> Block (LE Word16)
forall a b. (PrimType a, PrimType b) => Block a -> Block b
cast
piTable :: Block Word8
piTable :: Block Word8
piTable = [Item (Block Word8)] -> Block Word8
forall l. IsList l => [Item l] -> l
fromList
[ Word8
Item (Block Word8)
0xd9, Word8
Item (Block Word8)
0x78, Word8
Item (Block Word8)
0xf9, Word8
Item (Block Word8)
0xc4, Word8
Item (Block Word8)
0x19, Word8
Item (Block Word8)
0xdd, Word8
Item (Block Word8)
0xb5, Word8
Item (Block Word8)
0xed, Word8
Item (Block Word8)
0x28, Word8
Item (Block Word8)
0xe9, Word8
Item (Block Word8)
0xfd, Word8
Item (Block Word8)
0x79, Word8
Item (Block Word8)
0x4a, Word8
Item (Block Word8)
0xa0, Word8
Item (Block Word8)
0xd8, Word8
Item (Block Word8)
0x9d
, Word8
Item (Block Word8)
0xc6, Word8
Item (Block Word8)
0x7e, Word8
Item (Block Word8)
0x37, Word8
Item (Block Word8)
0x83, Word8
Item (Block Word8)
0x2b, Word8
Item (Block Word8)
0x76, Word8
Item (Block Word8)
0x53, Word8
Item (Block Word8)
0x8e, Word8
Item (Block Word8)
0x62, Word8
Item (Block Word8)
0x4c, Word8
Item (Block Word8)
0x64, Word8
Item (Block Word8)
0x88, Word8
Item (Block Word8)
0x44, Word8
Item (Block Word8)
0x8b, Word8
Item (Block Word8)
0xfb, Word8
Item (Block Word8)
0xa2
, Word8
Item (Block Word8)
0x17, Word8
Item (Block Word8)
0x9a, Word8
Item (Block Word8)
0x59, Word8
Item (Block Word8)
0xf5, Word8
Item (Block Word8)
0x87, Word8
Item (Block Word8)
0xb3, Word8
Item (Block Word8)
0x4f, Word8
Item (Block Word8)
0x13, Word8
Item (Block Word8)
0x61, Word8
Item (Block Word8)
0x45, Word8
Item (Block Word8)
0x6d, Word8
Item (Block Word8)
0x8d, Word8
Item (Block Word8)
0x09, Word8
Item (Block Word8)
0x81, Word8
Item (Block Word8)
0x7d, Word8
Item (Block Word8)
0x32
, Word8
Item (Block Word8)
0xbd, Word8
Item (Block Word8)
0x8f, Word8
Item (Block Word8)
0x40, Word8
Item (Block Word8)
0xeb, Word8
Item (Block Word8)
0x86, Word8
Item (Block Word8)
0xb7, Word8
Item (Block Word8)
0x7b, Word8
Item (Block Word8)
0x0b, Word8
Item (Block Word8)
0xf0, Word8
Item (Block Word8)
0x95, Word8
Item (Block Word8)
0x21, Word8
Item (Block Word8)
0x22, Word8
Item (Block Word8)
0x5c, Word8
Item (Block Word8)
0x6b, Word8
Item (Block Word8)
0x4e, Word8
Item (Block Word8)
0x82
, Word8
Item (Block Word8)
0x54, Word8
Item (Block Word8)
0xd6, Word8
Item (Block Word8)
0x65, Word8
Item (Block Word8)
0x93, Word8
Item (Block Word8)
0xce, Word8
Item (Block Word8)
0x60, Word8
Item (Block Word8)
0xb2, Word8
Item (Block Word8)
0x1c, Word8
Item (Block Word8)
0x73, Word8
Item (Block Word8)
0x56, Word8
Item (Block Word8)
0xc0, Word8
Item (Block Word8)
0x14, Word8
Item (Block Word8)
0xa7, Word8
Item (Block Word8)
0x8c, Word8
Item (Block Word8)
0xf1, Word8
Item (Block Word8)
0xdc
, Word8
Item (Block Word8)
0x12, Word8
Item (Block Word8)
0x75, Word8
Item (Block Word8)
0xca, Word8
Item (Block Word8)
0x1f, Word8
Item (Block Word8)
0x3b, Word8
Item (Block Word8)
0xbe, Word8
Item (Block Word8)
0xe4, Word8
Item (Block Word8)
0xd1, Word8
Item (Block Word8)
0x42, Word8
Item (Block Word8)
0x3d, Word8
Item (Block Word8)
0xd4, Word8
Item (Block Word8)
0x30, Word8
Item (Block Word8)
0xa3, Word8
Item (Block Word8)
0x3c, Word8
Item (Block Word8)
0xb6, Word8
Item (Block Word8)
0x26
, Word8
Item (Block Word8)
0x6f, Word8
Item (Block Word8)
0xbf, Word8
Item (Block Word8)
0x0e, Word8
Item (Block Word8)
0xda, Word8
Item (Block Word8)
0x46, Word8
Item (Block Word8)
0x69, Word8
Item (Block Word8)
0x07, Word8
Item (Block Word8)
0x57, Word8
Item (Block Word8)
0x27, Word8
Item (Block Word8)
0xf2, Word8
Item (Block Word8)
0x1d, Word8
Item (Block Word8)
0x9b, Word8
Item (Block Word8)
0xbc, Word8
Item (Block Word8)
0x94, Word8
Item (Block Word8)
0x43, Word8
Item (Block Word8)
0x03
, Word8
Item (Block Word8)
0xf8, Word8
Item (Block Word8)
0x11, Word8
Item (Block Word8)
0xc7, Word8
Item (Block Word8)
0xf6, Word8
Item (Block Word8)
0x90, Word8
Item (Block Word8)
0xef, Word8
Item (Block Word8)
0x3e, Word8
Item (Block Word8)
0xe7, Word8
Item (Block Word8)
0x06, Word8
Item (Block Word8)
0xc3, Word8
Item (Block Word8)
0xd5, Word8
Item (Block Word8)
0x2f, Word8
Item (Block Word8)
0xc8, Word8
Item (Block Word8)
0x66, Word8
Item (Block Word8)
0x1e, Word8
Item (Block Word8)
0xd7
, Word8
Item (Block Word8)
0x08, Word8
Item (Block Word8)
0xe8, Word8
Item (Block Word8)
0xea, Word8
Item (Block Word8)
0xde, Word8
Item (Block Word8)
0x80, Word8
Item (Block Word8)
0x52, Word8
Item (Block Word8)
0xee, Word8
Item (Block Word8)
0xf7, Word8
Item (Block Word8)
0x84, Word8
Item (Block Word8)
0xaa, Word8
Item (Block Word8)
0x72, Word8
Item (Block Word8)
0xac, Word8
Item (Block Word8)
0x35, Word8
Item (Block Word8)
0x4d, Word8
Item (Block Word8)
0x6a, Word8
Item (Block Word8)
0x2a
, Word8
Item (Block Word8)
0x96, Word8
Item (Block Word8)
0x1a, Word8
Item (Block Word8)
0xd2, Word8
Item (Block Word8)
0x71, Word8
Item (Block Word8)
0x5a, Word8
Item (Block Word8)
0x15, Word8
Item (Block Word8)
0x49, Word8
Item (Block Word8)
0x74, Word8
Item (Block Word8)
0x4b, Word8
Item (Block Word8)
0x9f, Word8
Item (Block Word8)
0xd0, Word8
Item (Block Word8)
0x5e, Word8
Item (Block Word8)
0x04, Word8
Item (Block Word8)
0x18, Word8
Item (Block Word8)
0xa4, Word8
Item (Block Word8)
0xec
, Word8
Item (Block Word8)
0xc2, Word8
Item (Block Word8)
0xe0, Word8
Item (Block Word8)
0x41, Word8
Item (Block Word8)
0x6e, Word8
Item (Block Word8)
0x0f, Word8
Item (Block Word8)
0x51, Word8
Item (Block Word8)
0xcb, Word8
Item (Block Word8)
0xcc, Word8
Item (Block Word8)
0x24, Word8
Item (Block Word8)
0x91, Word8
Item (Block Word8)
0xaf, Word8
Item (Block Word8)
0x50, Word8
Item (Block Word8)
0xa1, Word8
Item (Block Word8)
0xf4, Word8
Item (Block Word8)
0x70, Word8
Item (Block Word8)
0x39
, Word8
Item (Block Word8)
0x99, Word8
Item (Block Word8)
0x7c, Word8
Item (Block Word8)
0x3a, Word8
Item (Block Word8)
0x85, Word8
Item (Block Word8)
0x23, Word8
Item (Block Word8)
0xb8, Word8
Item (Block Word8)
0xb4, Word8
Item (Block Word8)
0x7a, Word8
Item (Block Word8)
0xfc, Word8
Item (Block Word8)
0x02, Word8
Item (Block Word8)
0x36, Word8
Item (Block Word8)
0x5b, Word8
Item (Block Word8)
0x25, Word8
Item (Block Word8)
0x55, Word8
Item (Block Word8)
0x97, Word8
Item (Block Word8)
0x31
, Word8
Item (Block Word8)
0x2d, Word8
Item (Block Word8)
0x5d, Word8
Item (Block Word8)
0xfa, Word8
Item (Block Word8)
0x98, Word8
Item (Block Word8)
0xe3, Word8
Item (Block Word8)
0x8a, Word8
Item (Block Word8)
0x92, Word8
Item (Block Word8)
0xae, Word8
Item (Block Word8)
0x05, Word8
Item (Block Word8)
0xdf, Word8
Item (Block Word8)
0x29, Word8
Item (Block Word8)
0x10, Word8
Item (Block Word8)
0x67, Word8
Item (Block Word8)
0x6c, Word8
Item (Block Word8)
0xba, Word8
Item (Block Word8)
0xc9
, Word8
Item (Block Word8)
0xd3, Word8
Item (Block Word8)
0x00, Word8
Item (Block Word8)
0xe6, Word8
Item (Block Word8)
0xcf, Word8
Item (Block Word8)
0xe1, Word8
Item (Block Word8)
0x9e, Word8
Item (Block Word8)
0xa8, Word8
Item (Block Word8)
0x2c, Word8
Item (Block Word8)
0x63, Word8
Item (Block Word8)
0x16, Word8
Item (Block Word8)
0x01, Word8
Item (Block Word8)
0x3f, Word8
Item (Block Word8)
0x58, Word8
Item (Block Word8)
0xe2, Word8
Item (Block Word8)
0x89, Word8
Item (Block Word8)
0xa9
, Word8
Item (Block Word8)
0x0d, Word8
Item (Block Word8)
0x38, Word8
Item (Block Word8)
0x34, Word8
Item (Block Word8)
0x1b, Word8
Item (Block Word8)
0xab, Word8
Item (Block Word8)
0x33, Word8
Item (Block Word8)
0xff, Word8
Item (Block Word8)
0xb0, Word8
Item (Block Word8)
0xbb, Word8
Item (Block Word8)
0x48, Word8
Item (Block Word8)
0x0c, Word8
Item (Block Word8)
0x5f, Word8
Item (Block Word8)
0xb9, Word8
Item (Block Word8)
0xb1, Word8
Item (Block Word8)
0xcd, Word8
Item (Block Word8)
0x2e
, Word8
Item (Block Word8)
0xc5, Word8
Item (Block Word8)
0xf3, Word8
Item (Block Word8)
0xdb, Word8
Item (Block Word8)
0x47, Word8
Item (Block Word8)
0xe5, Word8
Item (Block Word8)
0xa5, Word8
Item (Block Word8)
0x9c, Word8
Item (Block Word8)
0x77, Word8
Item (Block Word8)
0x0a, Word8
Item (Block Word8)
0xa6, Word8
Item (Block Word8)
0x20, Word8
Item (Block Word8)
0x68, Word8
Item (Block Word8)
0xfe, Word8
Item (Block Word8)
0x7f, Word8
Item (Block Word8)
0xc1, Word8
Item (Block Word8)
0xad
]