{-# LANGUAGE MagicHash #-}
{-# LANGUAGE BangPatterns #-}
module Crypto.Cipher.Twofish.Primitive
( Twofish
, initTwofish
, encrypt
, decrypt
) where
import Crypto.Error
import Crypto.Internal.ByteArray (ByteArray)
import qualified Crypto.Internal.ByteArray as B
import Crypto.Internal.WordArray
import Data.Word
import Data.Bits
import Data.List
blockSize :: Int
blockSize :: Int
blockSize = 16
mdsPolynomial, rsPolynomial :: Word32
mdsPolynomial :: Word32
mdsPolynomial = 0x169
rsPolynomial :: Word32
rsPolynomial = 0x14d
data Twofish = Twofish { Twofish -> (Array32, Array32, Array32, Array32)
s :: (Array32, Array32, Array32, Array32)
, Twofish -> Array32
k :: Array32 }
data ByteSize = Bytes16 | Bytes24 | Bytes32 deriving (ByteSize -> ByteSize -> Bool
(ByteSize -> ByteSize -> Bool)
-> (ByteSize -> ByteSize -> Bool) -> Eq ByteSize
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ByteSize -> ByteSize -> Bool
$c/= :: ByteSize -> ByteSize -> Bool
== :: ByteSize -> ByteSize -> Bool
$c== :: ByteSize -> ByteSize -> Bool
Eq)
data KeyPackage ba = KeyPackage { KeyPackage ba -> ba
rawKeyBytes :: ba
, KeyPackage ba -> ByteSize
byteSize :: ByteSize }
buildPackage :: ByteArray ba => ba -> Maybe (KeyPackage ba)
buildPackage :: ba -> Maybe (KeyPackage ba)
buildPackage key :: ba
key
| ba -> Int
forall ba. ByteArrayAccess ba => ba -> Int
B.length ba
key Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 16 = KeyPackage ba -> Maybe (KeyPackage ba)
forall (m :: * -> *) a. Monad m => a -> m a
return (KeyPackage ba -> Maybe (KeyPackage ba))
-> KeyPackage ba -> Maybe (KeyPackage ba)
forall a b. (a -> b) -> a -> b
$ ba -> ByteSize -> KeyPackage ba
forall ba. ba -> ByteSize -> KeyPackage ba
KeyPackage ba
key ByteSize
Bytes16
| ba -> Int
forall ba. ByteArrayAccess ba => ba -> Int
B.length ba
key Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 24 = KeyPackage ba -> Maybe (KeyPackage ba)
forall (m :: * -> *) a. Monad m => a -> m a
return (KeyPackage ba -> Maybe (KeyPackage ba))
-> KeyPackage ba -> Maybe (KeyPackage ba)
forall a b. (a -> b) -> a -> b
$ ba -> ByteSize -> KeyPackage ba
forall ba. ba -> ByteSize -> KeyPackage ba
KeyPackage ba
key ByteSize
Bytes24
| ba -> Int
forall ba. ByteArrayAccess ba => ba -> Int
B.length ba
key Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 32 = KeyPackage ba -> Maybe (KeyPackage ba)
forall (m :: * -> *) a. Monad m => a -> m a
return (KeyPackage ba -> Maybe (KeyPackage ba))
-> KeyPackage ba -> Maybe (KeyPackage ba)
forall a b. (a -> b) -> a -> b
$ ba -> ByteSize -> KeyPackage ba
forall ba. ba -> ByteSize -> KeyPackage ba
KeyPackage ba
key ByteSize
Bytes32
| Bool
otherwise = Maybe (KeyPackage ba)
forall a. Maybe a
Nothing
initTwofish :: ByteArray key
=> key
-> CryptoFailable Twofish
initTwofish :: key -> CryptoFailable Twofish
initTwofish key :: key
key =
case key -> Maybe (KeyPackage key)
forall ba. ByteArray ba => ba -> Maybe (KeyPackage ba)
buildPackage key
key of Nothing -> CryptoError -> CryptoFailable Twofish
forall a. CryptoError -> CryptoFailable a
CryptoFailed CryptoError
CryptoError_KeySizeInvalid
Just keyPackage :: KeyPackage key
keyPackage -> Twofish -> CryptoFailable Twofish
forall a. a -> CryptoFailable a
CryptoPassed Twofish :: (Array32, Array32, Array32, Array32) -> Array32 -> Twofish
Twofish { k :: Array32
k = Array32
generatedK, s :: (Array32, Array32, Array32, Array32)
s = (Array32, Array32, Array32, Array32)
generatedS }
where generatedK :: Array32
generatedK = Int -> [Word32] -> Array32
array32 40 ([Word32] -> Array32) -> [Word32] -> Array32
forall a b. (a -> b) -> a -> b
$ KeyPackage key -> [Word32]
forall ba. ByteArray ba => KeyPackage ba -> [Word32]
genK KeyPackage key
keyPackage
generatedS :: (Array32, Array32, Array32, Array32)
generatedS = KeyPackage key -> [Word8] -> (Array32, Array32, Array32, Array32)
forall ba.
KeyPackage ba -> [Word8] -> (Array32, Array32, Array32, Array32)
genSboxes KeyPackage key
keyPackage ([Word8] -> (Array32, Array32, Array32, Array32))
-> [Word8] -> (Array32, Array32, Array32, Array32)
forall a b. (a -> b) -> a -> b
$ key -> [Word8]
forall ba. ByteArray ba => ba -> [Word8]
sWords key
key
mapBlocks :: ByteArray ba => (ba -> ba) -> ba -> ba
mapBlocks :: (ba -> ba) -> ba -> ba
mapBlocks operation :: ba -> ba
operation input :: ba
input
| ba -> Bool
forall a. ByteArrayAccess a => a -> Bool
B.null ba
rest = ba
blockOutput
| Bool
otherwise = ba
blockOutput ba -> ba -> ba
forall bs. ByteArray bs => bs -> bs -> bs
`B.append` (ba -> ba) -> ba -> ba
forall ba. ByteArray ba => (ba -> ba) -> ba -> ba
mapBlocks ba -> ba
operation ba
rest
where (block :: ba
block, rest :: ba
rest) = Int -> ba -> (ba, ba)
forall bs. ByteArray bs => Int -> bs -> (bs, bs)
B.splitAt Int
blockSize ba
input
blockOutput :: ba
blockOutput = ba -> ba
operation ba
block
encrypt :: ByteArray ba
=> Twofish
-> ba
-> ba
encrypt :: Twofish -> ba -> ba
encrypt cipher :: Twofish
cipher = (ba -> ba) -> ba -> ba
forall ba. ByteArray ba => (ba -> ba) -> ba -> ba
mapBlocks (Twofish -> ba -> ba
forall ba. ByteArray ba => Twofish -> ba -> ba
encryptBlock Twofish
cipher)
encryptBlock :: ByteArray ba => Twofish -> ba -> ba
encryptBlock :: Twofish -> ba -> ba
encryptBlock Twofish { s :: Twofish -> (Array32, Array32, Array32, Array32)
s = (s1 :: Array32
s1, s2 :: Array32
s2, s3 :: Array32
s3, s4 :: Array32
s4), k :: Twofish -> Array32
k = Array32
ks } message :: ba
message = (Word32, Word32, Word32, Word32) -> ba
forall ba. ByteArray ba => (Word32, Word32, Word32, Word32) -> ba
store32ls (Word32, Word32, Word32, Word32)
ts
where (a :: Word32
a, b :: Word32
b, c :: Word32
c, d :: Word32
d) = ba -> (Word32, Word32, Word32, Word32)
forall ba. ByteArray ba => ba -> (Word32, Word32, Word32, Word32)
load32ls ba
message
a' :: Word32
a' = Word32
a Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Int -> Word32
arrayRead32 Array32
ks 0
b' :: Word32
b' = Word32
b Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Int -> Word32
arrayRead32 Array32
ks 1
c' :: Word32
c' = Word32
c Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Int -> Word32
arrayRead32 Array32
ks 2
d' :: Word32
d' = Word32
d Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Int -> Word32
arrayRead32 Array32
ks 3
(!Word32
a'', !Word32
b'', !Word32
c'', !Word32
d'') = ((Word32, Word32, Word32, Word32)
-> Int -> (Word32, Word32, Word32, Word32))
-> (Word32, Word32, Word32, Word32)
-> [Int]
-> (Word32, Word32, Word32, Word32)
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (Word32, Word32, Word32, Word32)
-> Int -> (Word32, Word32, Word32, Word32)
shuffle (Word32
a', Word32
b', Word32
c', Word32
d') [0..7]
ts :: (Word32, Word32, Word32, Word32)
ts = (Word32
c'' Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Int -> Word32
arrayRead32 Array32
ks 4, Word32
d'' Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Int -> Word32
arrayRead32 Array32
ks 5, Word32
a'' Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Int -> Word32
arrayRead32 Array32
ks 6, Word32
b'' Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Int -> Word32
arrayRead32 Array32
ks 7)
shuffle :: (Word32, Word32, Word32, Word32) -> Int -> (Word32, Word32, Word32, Word32)
shuffle :: (Word32, Word32, Word32, Word32)
-> Int -> (Word32, Word32, Word32, Word32)
shuffle (!Word32
retA, !Word32
retB, !Word32
retC, !Word32
retD) ind :: Int
ind = (Word32
retA', Word32
retB', Word32
retC', Word32
retD')
where [k0 :: Word32
k0, k1 :: Word32
k1, k2 :: Word32
k2, k3 :: Word32
k3] = (Int -> Word32) -> [Int] -> [Word32]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\offset :: Int
offset -> Array32 -> Int -> Word32
arrayRead32 Array32
ks (Int -> Word32) -> Int -> Word32
forall a b. (a -> b) -> a -> b
$ (8 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 4 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
ind) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
offset) [0..3]
t2 :: Word32
t2 = Array32 -> Word32 -> Word32
byteIndex Array32
s2 Word32
retB Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Word32 -> Word32
byteIndex Array32
s3 (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftR Word32
retB 8) Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Word32 -> Word32
byteIndex Array32
s4 (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftR Word32
retB 16) Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Word32 -> Word32
byteIndex Array32
s1 (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftR Word32
retB 24)
t1 :: Word32
t1 = (Array32 -> Word32 -> Word32
byteIndex Array32
s1 Word32
retA Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Word32 -> Word32
byteIndex Array32
s2 (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftR Word32
retA 8) Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Word32 -> Word32
byteIndex Array32
s3 (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftR Word32
retA 16) Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Word32 -> Word32
byteIndex Array32
s4 (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftR Word32
retA 24)) Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
t2
retC' :: Word32
retC' = Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
rotateR (Word32
retC Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` (Word32
t1 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
k0)) 1
retD' :: Word32
retD' = Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
rotateL Word32
retD 1 Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` (Word32
t1 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
t2 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
k1)
t2' :: Word32
t2' = Array32 -> Word32 -> Word32
byteIndex Array32
s2 Word32
retD' Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Word32 -> Word32
byteIndex Array32
s3 (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftR Word32
retD' 8) Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Word32 -> Word32
byteIndex Array32
s4 (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftR Word32
retD' 16) Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Word32 -> Word32
byteIndex Array32
s1 (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftR Word32
retD' 24)
t1' :: Word32
t1' = (Array32 -> Word32 -> Word32
byteIndex Array32
s1 Word32
retC' Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Word32 -> Word32
byteIndex Array32
s2 (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftR Word32
retC' 8) Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Word32 -> Word32
byteIndex Array32
s3 (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftR Word32
retC' 16) Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Word32 -> Word32
byteIndex Array32
s4 (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftR Word32
retC' 24)) Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
t2'
retA' :: Word32
retA' = Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
rotateR (Word32
retA Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` (Word32
t1' Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
k2)) 1
retB' :: Word32
retB' = Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
rotateL Word32
retB 1 Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` (Word32
t1' Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
t2' Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
k3)
byteIndex :: Array32 -> Word32 -> Word32
byteIndex :: Array32 -> Word32 -> Word32
byteIndex xs :: Array32
xs ind :: Word32
ind = Array32 -> Int -> Word32
arrayRead32 Array32
xs (Int -> Word32) -> Int -> Word32
forall a b. (a -> b) -> a -> b
$ Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
byte
where byte :: Word32
byte = Word32
ind Word32 -> Word32 -> Word32
forall a. Integral a => a -> a -> a
`mod` 256
decrypt :: ByteArray ba
=> Twofish
-> ba
-> ba
decrypt :: Twofish -> ba -> ba
decrypt cipher :: Twofish
cipher = (ba -> ba) -> ba -> ba
forall ba. ByteArray ba => (ba -> ba) -> ba -> ba
mapBlocks (Twofish -> ba -> ba
forall ba. ByteArray ba => Twofish -> ba -> ba
decryptBlock Twofish
cipher)
decryptBlock :: ByteArray ba => Twofish -> ba -> ba
decryptBlock :: Twofish -> ba -> ba
decryptBlock Twofish { s :: Twofish -> (Array32, Array32, Array32, Array32)
s = (s1 :: Array32
s1, s2 :: Array32
s2, s3 :: Array32
s3, s4 :: Array32
s4), k :: Twofish -> Array32
k = Array32
ks } message :: ba
message = (Word32, Word32, Word32, Word32) -> ba
forall ba. ByteArray ba => (Word32, Word32, Word32, Word32) -> ba
store32ls (Word32, Word32, Word32, Word32)
ixs
where (a :: Word32
a, b :: Word32
b, c :: Word32
c, d :: Word32
d) = ba -> (Word32, Word32, Word32, Word32)
forall ba. ByteArray ba => ba -> (Word32, Word32, Word32, Word32)
load32ls ba
message
a' :: Word32
a' = Word32
c Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Int -> Word32
arrayRead32 Array32
ks 6
b' :: Word32
b' = Word32
d Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Int -> Word32
arrayRead32 Array32
ks 7
c' :: Word32
c' = Word32
a Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Int -> Word32
arrayRead32 Array32
ks 4
d' :: Word32
d' = Word32
b Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Int -> Word32
arrayRead32 Array32
ks 5
(!Word32
a'', !Word32
b'', !Word32
c'', !Word32
d'') = ((Word32, Word32, Word32, Word32)
-> Int -> (Word32, Word32, Word32, Word32))
-> (Word32, Word32, Word32, Word32)
-> [Int]
-> (Word32, Word32, Word32, Word32)
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (Word32, Word32, Word32, Word32)
-> Int -> (Word32, Word32, Word32, Word32)
unshuffle (Word32
a', Word32
b', Word32
c', Word32
d') [8, 7..1]
ixs :: (Word32, Word32, Word32, Word32)
ixs = (Word32
a'' Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Int -> Word32
arrayRead32 Array32
ks 0, Word32
b'' Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Int -> Word32
arrayRead32 Array32
ks 1, Word32
c'' Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Int -> Word32
arrayRead32 Array32
ks 2, Word32
d'' Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Int -> Word32
arrayRead32 Array32
ks 3)
unshuffle :: (Word32, Word32, Word32, Word32) -> Int -> (Word32, Word32, Word32, Word32)
unshuffle :: (Word32, Word32, Word32, Word32)
-> Int -> (Word32, Word32, Word32, Word32)
unshuffle (!Word32
retA, !Word32
retB, !Word32
retC, !Word32
retD) ind :: Int
ind = (Word32
retA', Word32
retB', Word32
retC', Word32
retD')
where [k0 :: Word32
k0, k1 :: Word32
k1, k2 :: Word32
k2, k3 :: Word32
k3] = (Int -> Word32) -> [Int] -> [Word32]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\offset :: Int
offset -> Array32 -> Int -> Word32
arrayRead32 Array32
ks (Int -> Word32) -> Int -> Word32
forall a b. (a -> b) -> a -> b
$ (4 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 4 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
ind) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
offset) [0..3]
t2 :: Word32
t2 = Array32 -> Word32 -> Word32
byteIndex Array32
s2 Word32
retD Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Word32 -> Word32
byteIndex Array32
s3 (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftR Word32
retD 8) Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Word32 -> Word32
byteIndex Array32
s4 (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftR Word32
retD 16) Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Word32 -> Word32
byteIndex Array32
s1 (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftR Word32
retD 24)
t1 :: Word32
t1 = (Array32 -> Word32 -> Word32
byteIndex Array32
s1 Word32
retC Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Word32 -> Word32
byteIndex Array32
s2 (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftR Word32
retC 8) Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Word32 -> Word32
byteIndex Array32
s3 (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftR Word32
retC 16) Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Word32 -> Word32
byteIndex Array32
s4 (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftR Word32
retC 24)) Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
t2
retA' :: Word32
retA' = Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
rotateL Word32
retA 1 Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` (Word32
t1 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
k2)
retB' :: Word32
retB' = Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
rotateR (Word32
retB Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` (Word32
t2 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
t1 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
k3)) 1
t2' :: Word32
t2' = Array32 -> Word32 -> Word32
byteIndex Array32
s2 Word32
retB' Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Word32 -> Word32
byteIndex Array32
s3 (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftR Word32
retB' 8) Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Word32 -> Word32
byteIndex Array32
s4 (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftR Word32
retB' 16) Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Word32 -> Word32
byteIndex Array32
s1 (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftR Word32
retB' 24)
t1' :: Word32
t1' = (Array32 -> Word32 -> Word32
byteIndex Array32
s1 Word32
retA' Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Word32 -> Word32
byteIndex Array32
s2 (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftR Word32
retA' 8) Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Word32 -> Word32
byteIndex Array32
s3 (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftR Word32
retA' 16) Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Array32 -> Word32 -> Word32
byteIndex Array32
s4 (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftR Word32
retA' 24)) Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
t2'
retC' :: Word32
retC' = Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
rotateL Word32
retC 1 Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` (Word32
t1' Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
k0)
retD' :: Word32
retD' = Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
rotateR (Word32
retD Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` (Word32
t2' Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
t1' Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
k1)) 1
sbox0 :: Int -> Word8
sbox0 :: Int -> Word8
sbox0 = Array8 -> Int -> Word8
arrayRead8 Array8
t
where t :: Array8
t = Addr# -> Array8
array8
"\xa9\x67\xb3\xe8\x04\xfd\xa3\x76\x9a\x92\x80\x78\xe4\xdd\xd1\x38\
\\x0d\xc6\x35\x98\x18\xf7\xec\x6c\x43\x75\x37\x26\xfa\x13\x94\x48\
\\xf2\xd0\x8b\x30\x84\x54\xdf\x23\x19\x5b\x3d\x59\xf3\xae\xa2\x82\
\\x63\x01\x83\x2e\xd9\x51\x9b\x7c\xa6\xeb\xa5\xbe\x16\x0c\xe3\x61\
\\xc0\x8c\x3a\xf5\x73\x2c\x25\x0b\xbb\x4e\x89\x6b\x53\x6a\xb4\xf1\
\\xe1\xe6\xbd\x45\xe2\xf4\xb6\x66\xcc\x95\x03\x56\xd4\x1c\x1e\xd7\
\\xfb\xc3\x8e\xb5\xe9\xcf\xbf\xba\xea\x77\x39\xaf\x33\xc9\x62\x71\
\\x81\x79\x09\xad\x24\xcd\xf9\xd8\xe5\xc5\xb9\x4d\x44\x08\x86\xe7\
\\xa1\x1d\xaa\xed\x06\x70\xb2\xd2\x41\x7b\xa0\x11\x31\xc2\x27\x90\
\\x20\xf6\x60\xff\x96\x5c\xb1\xab\x9e\x9c\x52\x1b\x5f\x93\x0a\xef\
\\x91\x85\x49\xee\x2d\x4f\x8f\x3b\x47\x87\x6d\x46\xd6\x3e\x69\x64\
\\x2a\xce\xcb\x2f\xfc\x97\x05\x7a\xac\x7f\xd5\x1a\x4b\x0e\xa7\x5a\
\\x28\x14\x3f\x29\x88\x3c\x4c\x02\xb8\xda\xb0\x17\x55\x1f\x8a\x7d\
\\x57\xc7\x8d\x74\xb7\xc4\x9f\x72\x7e\x15\x22\x12\x58\x07\x99\x34\
\\x6e\x50\xde\x68\x65\xbc\xdb\xf8\xc8\xa8\x2b\x40\xdc\xfe\x32\xa4\
\\xca\x10\x21\xf0\xd3\x5d\x0f\x00\x6f\x9d\x36\x42\x4a\x5e\xc1\xe0"#
sbox1 :: Int -> Word8
sbox1 :: Int -> Word8
sbox1 = Array8 -> Int -> Word8
arrayRead8 Array8
t
where t :: Array8
t = Addr# -> Array8
array8
"\x75\xf3\xc6\xf4\xdb\x7b\xfb\xc8\x4a\xd3\xe6\x6b\x45\x7d\xe8\x4b\
\\xd6\x32\xd8\xfd\x37\x71\xf1\xe1\x30\x0f\xf8\x1b\x87\xfa\x06\x3f\
\\x5e\xba\xae\x5b\x8a\x00\xbc\x9d\x6d\xc1\xb1\x0e\x80\x5d\xd2\xd5\
\\xa0\x84\x07\x14\xb5\x90\x2c\xa3\xb2\x73\x4c\x54\x92\x74\x36\x51\
\\x38\xb0\xbd\x5a\xfc\x60\x62\x96\x6c\x42\xf7\x10\x7c\x28\x27\x8c\
\\x13\x95\x9c\xc7\x24\x46\x3b\x70\xca\xe3\x85\xcb\x11\xd0\x93\xb8\
\\xa6\x83\x20\xff\x9f\x77\xc3\xcc\x03\x6f\x08\xbf\x40\xe7\x2b\xe2\
\\x79\x0c\xaa\x82\x41\x3a\xea\xb9\xe4\x9a\xa4\x97\x7e\xda\x7a\x17\
\\x66\x94\xa1\x1d\x3d\xf0\xde\xb3\x0b\x72\xa7\x1c\xef\xd1\x53\x3e\
\\x8f\x33\x26\x5f\xec\x76\x2a\x49\x81\x88\xee\x21\xc4\x1a\xeb\xd9\
\\xc5\x39\x99\xcd\xad\x31\x8b\x01\x18\x23\xdd\x1f\x4e\x2d\xf9\x48\
\\x4f\xf2\x65\x8e\x78\x5c\x58\x19\x8d\xe5\x98\x57\x67\x7f\x05\x64\
\\xaf\x63\xb6\xfe\xf5\xb7\x3c\xa5\xce\xe9\x68\x44\xe0\x4d\x43\x69\
\\x29\x2e\xac\x15\x59\xa8\x0a\x9e\x6e\x47\xdf\x34\x35\x6a\xcf\xdc\
\\x22\xc9\xc0\x9b\x89\xd4\xed\xab\x12\xa2\x0d\x52\xbb\x02\x2f\xa9\
\\xd7\x61\x1e\xb4\x50\x04\xf6\xc2\x16\x25\x86\x56\x55\x09\xbe\x91"#
rs :: [[Word8]]
rs :: [[Word8]]
rs = [ [0x01, 0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E]
, [0xA4, 0x56, 0x82, 0xF3, 0x1E, 0xC6, 0x68, 0xE5]
, [0x02, 0xA1, 0xFC, 0xC1, 0x47, 0xAE, 0x3D, 0x19]
, [0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E, 0x03] ]
load32ls :: ByteArray ba => ba -> (Word32, Word32, Word32, Word32)
load32ls :: ba -> (Word32, Word32, Word32, Word32)
load32ls message :: ba
message = (ba -> Word32
forall ba. ByteArray ba => ba -> Word32
intify ba
q1, ba -> Word32
forall ba. ByteArray ba => ba -> Word32
intify ba
q2, ba -> Word32
forall ba. ByteArray ba => ba -> Word32
intify ba
q3, ba -> Word32
forall ba. ByteArray ba => ba -> Word32
intify ba
q4)
where (half1 :: ba
half1, half2 :: ba
half2) = Int -> ba -> (ba, ba)
forall bs. ByteArray bs => Int -> bs -> (bs, bs)
B.splitAt 8 ba
message
(q1 :: ba
q1, q2 :: ba
q2) = Int -> ba -> (ba, ba)
forall bs. ByteArray bs => Int -> bs -> (bs, bs)
B.splitAt 4 ba
half1
(q3 :: ba
q3, q4 :: ba
q4) = Int -> ba -> (ba, ba)
forall bs. ByteArray bs => Int -> bs -> (bs, bs)
B.splitAt 4 ba
half2
intify :: ByteArray ba => ba -> Word32
intify :: ba -> Word32
intify bytes :: ba
bytes = (Word32 -> (Word8, Int) -> Word32)
-> Word32 -> [(Word8, Int)] -> Word32
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\int :: Word32
int (!Word8
word, !Int
ind) -> Word32
int Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftL (Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
word) (Int
ind Int -> Int -> Int
forall a. Num a => a -> a -> a
* 8) ) 0 ([Word8] -> [Int] -> [(Word8, Int)]
forall a b. [a] -> [b] -> [(a, b)]
zip (ba -> [Word8]
forall a. ByteArrayAccess a => a -> [Word8]
B.unpack ba
bytes) [0..])
store32ls :: ByteArray ba => (Word32, Word32, Word32, Word32) -> ba
store32ls :: (Word32, Word32, Word32, Word32) -> ba
store32ls (a :: Word32
a, b :: Word32
b, c :: Word32
c, d :: Word32
d) = [Word8] -> ba
forall a. ByteArray a => [Word8] -> a
B.pack ([Word8] -> ba) -> [Word8] -> ba
forall a b. (a -> b) -> a -> b
$ (Word32 -> [Word8]) -> [Word32] -> [Word8]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Word32 -> [Word8]
splitWordl [Word32
a, Word32
b, Word32
c, Word32
d]
where splitWordl :: Word32 -> [Word8]
splitWordl :: Word32 -> [Word8]
splitWordl w :: Word32
w = (Int -> Word8) -> [Int] -> [Word8]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\ind :: Int
ind -> Word32 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Word8) -> Word32 -> Word8
forall a b. (a -> b) -> a -> b
$ Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftR Word32
w (8 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
ind)) [0..3]
sWords :: ByteArray ba => ba -> [Word8]
sWords :: ba -> [Word8]
sWords key :: ba
key = [Word8]
sWord
where word64Count :: Int
word64Count = ba -> Int
forall ba. ByteArrayAccess ba => ba -> Int
B.length ba
key Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` 2
sWord :: [Word8]
sWord = (Int -> [Word8]) -> [Int] -> [Word8]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\wordIndex :: Int
wordIndex ->
([Word8] -> Word8) -> [[Word8]] -> [Word8]
forall a b. (a -> b) -> [a] -> [b]
map (\rsRow :: [Word8]
rsRow ->
(Word8 -> (Word8, Int) -> Word8)
-> Word8 -> [(Word8, Int)] -> Word8
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\acc :: Word8
acc (!Word8
rsVal, !Int
colIndex) ->
Word8
acc Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word32 -> Word8 -> Word8 -> Word8
gfMult Word32
rsPolynomial (ba -> Int -> Word8
forall a. ByteArrayAccess a => a -> Int -> Word8
B.index ba
key (Int -> Word8) -> Int -> Word8
forall a b. (a -> b) -> a -> b
$ 8 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
wordIndex Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
colIndex) Word8
rsVal
) 0 ([Word8] -> [Int] -> [(Word8, Int)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Word8]
rsRow [0..])
) [[Word8]]
rs
) [0..Int
word64Count Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1]
data Column = Zero | One | Two | Three deriving (Int -> Column -> ShowS
[Column] -> ShowS
Column -> String
(Int -> Column -> ShowS)
-> (Column -> String) -> ([Column] -> ShowS) -> Show Column
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Column] -> ShowS
$cshowList :: [Column] -> ShowS
show :: Column -> String
$cshow :: Column -> String
showsPrec :: Int -> Column -> ShowS
$cshowsPrec :: Int -> Column -> ShowS
Show, Column -> Column -> Bool
(Column -> Column -> Bool)
-> (Column -> Column -> Bool) -> Eq Column
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Column -> Column -> Bool
$c/= :: Column -> Column -> Bool
== :: Column -> Column -> Bool
$c== :: Column -> Column -> Bool
Eq, Int -> Column
Column -> Int
Column -> [Column]
Column -> Column
Column -> Column -> [Column]
Column -> Column -> Column -> [Column]
(Column -> Column)
-> (Column -> Column)
-> (Int -> Column)
-> (Column -> Int)
-> (Column -> [Column])
-> (Column -> Column -> [Column])
-> (Column -> Column -> [Column])
-> (Column -> Column -> Column -> [Column])
-> Enum Column
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: Column -> Column -> Column -> [Column]
$cenumFromThenTo :: Column -> Column -> Column -> [Column]
enumFromTo :: Column -> Column -> [Column]
$cenumFromTo :: Column -> Column -> [Column]
enumFromThen :: Column -> Column -> [Column]
$cenumFromThen :: Column -> Column -> [Column]
enumFrom :: Column -> [Column]
$cenumFrom :: Column -> [Column]
fromEnum :: Column -> Int
$cfromEnum :: Column -> Int
toEnum :: Int -> Column
$ctoEnum :: Int -> Column
pred :: Column -> Column
$cpred :: Column -> Column
succ :: Column -> Column
$csucc :: Column -> Column
Enum, Column
Column -> Column -> Bounded Column
forall a. a -> a -> Bounded a
maxBound :: Column
$cmaxBound :: Column
minBound :: Column
$cminBound :: Column
Bounded)
genSboxes :: KeyPackage ba -> [Word8] -> (Array32, Array32, Array32, Array32)
genSboxes :: KeyPackage ba -> [Word8] -> (Array32, Array32, Array32, Array32)
genSboxes keyPackage :: KeyPackage ba
keyPackage ws :: [Word8]
ws = ([Word32] -> Array32
mkArray [Word32]
b0', [Word32] -> Array32
mkArray [Word32]
b1', [Word32] -> Array32
mkArray [Word32]
b2', [Word32] -> Array32
mkArray [Word32]
b3')
where range :: [Int]
range = [0..255]
mkArray :: [Word32] -> Array32
mkArray = Int -> [Word32] -> Array32
array32 256
[w0 :: Word8
w0, w1 :: Word8
w1, w2 :: Word8
w2, w3 :: Word8
w3, w4 :: Word8
w4, w5 :: Word8
w5, w6 :: Word8
w6, w7 :: Word8
w7, w8 :: Word8
w8, w9 :: Word8
w9, w10 :: Word8
w10, w11 :: Word8
w11, w12 :: Word8
w12, w13 :: Word8
w13, w14 :: Word8
w14, w15 :: Word8
w15] = Int -> [Word8] -> [Word8]
forall a. Int -> [a] -> [a]
take 16 [Word8]
ws
(b0' :: [Word32]
b0', b1' :: [Word32]
b1', b2' :: [Word32]
b2', b3' :: [Word32]
b3') = ByteSize -> ([Word32], [Word32], [Word32], [Word32])
sboxBySize (ByteSize -> ([Word32], [Word32], [Word32], [Word32]))
-> ByteSize -> ([Word32], [Word32], [Word32], [Word32])
forall a b. (a -> b) -> a -> b
$ KeyPackage ba -> ByteSize
forall ba. KeyPackage ba -> ByteSize
byteSize KeyPackage ba
keyPackage
sboxBySize :: ByteSize -> ([Word32], [Word32], [Word32], [Word32])
sboxBySize :: ByteSize -> ([Word32], [Word32], [Word32], [Word32])
sboxBySize Bytes16 = ([Word32]
b0, [Word32]
b1, [Word32]
b2, [Word32]
b3)
where !b0 :: [Word32]
b0 = (Int -> Word32) -> [Int] -> [Word32]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> Word32
mapper [Int]
range
where mapper :: Int -> Word32
mapper :: Int -> Word32
mapper byte :: Int
byte = Word8 -> Column -> Word32
mdsColumnMult ((Int -> Word8
sbox1 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) ((Int -> Word8
sbox0 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word8) -> Word8 -> Word8
forall a b. (a -> b) -> a -> b
$ Int -> Word8
sbox0 Int
byte Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w0) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w4)) Column
Zero
!b1 :: [Word32]
b1 = (Int -> Word32) -> [Int] -> [Word32]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> Word32
mapper [Int]
range
where mapper :: Int -> Word32
mapper byte :: Int
byte = Word8 -> Column -> Word32
mdsColumnMult ((Int -> Word8
sbox0 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) ((Int -> Word8
sbox0 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word8) -> Word8 -> Word8
forall a b. (a -> b) -> a -> b
$ Int -> Word8
sbox1 Int
byte Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w1) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w5)) Column
One
!b2 :: [Word32]
b2 = (Int -> Word32) -> [Int] -> [Word32]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> Word32
mapper [Int]
range
where mapper :: Int -> Word32
mapper byte :: Int
byte = Word8 -> Column -> Word32
mdsColumnMult ((Int -> Word8
sbox1 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) ((Int -> Word8
sbox1 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word8) -> Word8 -> Word8
forall a b. (a -> b) -> a -> b
$ Int -> Word8
sbox0 Int
byte Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w2) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w6)) Column
Two
!b3 :: [Word32]
b3 = (Int -> Word32) -> [Int] -> [Word32]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> Word32
mapper [Int]
range
where mapper :: Int -> Word32
mapper byte :: Int
byte = Word8 -> Column -> Word32
mdsColumnMult ((Int -> Word8
sbox0 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) ((Int -> Word8
sbox1 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word8) -> Word8 -> Word8
forall a b. (a -> b) -> a -> b
$ Int -> Word8
sbox1 Int
byte Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w3) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w7)) Column
Three
sboxBySize Bytes24 = ([Word32]
b0, [Word32]
b1, [Word32]
b2, [Word32]
b3)
where !b0 :: [Word32]
b0 = (Int -> Word32) -> [Int] -> [Word32]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> Word32
mapper [Int]
range
where mapper :: Int -> Word32
mapper byte :: Int
byte = Word8 -> Column -> Word32
mdsColumnMult ((Int -> Word8
sbox1 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) ((Int -> Word8
sbox0 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) ((Int -> Word8
sbox0 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word8) -> Word8 -> Word8
forall a b. (a -> b) -> a -> b
$ Int -> Word8
sbox1 Int
byte Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w0) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w4) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w8)) Column
Zero
!b1 :: [Word32]
b1 = (Int -> Word32) -> [Int] -> [Word32]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> Word32
mapper [Int]
range
where mapper :: Int -> Word32
mapper byte :: Int
byte = Word8 -> Column -> Word32
mdsColumnMult ((Int -> Word8
sbox0 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) ((Int -> Word8
sbox0 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) ((Int -> Word8
sbox1 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word8) -> Word8 -> Word8
forall a b. (a -> b) -> a -> b
$ Int -> Word8
sbox1 Int
byte Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w1) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w5) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w9)) Column
One
!b2 :: [Word32]
b2 = (Int -> Word32) -> [Int] -> [Word32]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> Word32
mapper [Int]
range
where mapper :: Int -> Word32
mapper byte :: Int
byte = Word8 -> Column -> Word32
mdsColumnMult ((Int -> Word8
sbox1 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) ((Int -> Word8
sbox1 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) ((Int -> Word8
sbox0 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word8) -> Word8 -> Word8
forall a b. (a -> b) -> a -> b
$ Int -> Word8
sbox0 Int
byte Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w2) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w6) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w10)) Column
Two
!b3 :: [Word32]
b3 = (Int -> Word32) -> [Int] -> [Word32]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> Word32
mapper [Int]
range
where mapper :: Int -> Word32
mapper byte :: Int
byte = Word8 -> Column -> Word32
mdsColumnMult ((Int -> Word8
sbox0 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) ((Int -> Word8
sbox1 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) ((Int -> Word8
sbox1 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word8) -> Word8 -> Word8
forall a b. (a -> b) -> a -> b
$ Int -> Word8
sbox0 Int
byte Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w3) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w7) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w11)) Column
Three
sboxBySize Bytes32 = ([Word32]
b0, [Word32]
b1, [Word32]
b2, [Word32]
b3)
where !b0 :: [Word32]
b0 = (Int -> Word32) -> [Int] -> [Word32]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> Word32
mapper [Int]
range
where mapper :: Int -> Word32
mapper byte :: Int
byte = Word8 -> Column -> Word32
mdsColumnMult ((Int -> Word8
sbox1 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) ((Int -> Word8
sbox0 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) ((Int -> Word8
sbox0 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) ((Int -> Word8
sbox1 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word8) -> Word8 -> Word8
forall a b. (a -> b) -> a -> b
$ Int -> Word8
sbox1 Int
byte Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w0) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w4) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w8) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w12)) Column
Zero
!b1 :: [Word32]
b1 = (Int -> Word32) -> [Int] -> [Word32]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> Word32
mapper [Int]
range
where mapper :: Int -> Word32
mapper byte :: Int
byte = Word8 -> Column -> Word32
mdsColumnMult ((Int -> Word8
sbox0 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) ((Int -> Word8
sbox0 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) ((Int -> Word8
sbox1 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) ((Int -> Word8
sbox1 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word8) -> Word8 -> Word8
forall a b. (a -> b) -> a -> b
$ Int -> Word8
sbox0 Int
byte Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w1) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w5) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w9) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w13)) Column
One
!b2 :: [Word32]
b2 = (Int -> Word32) -> [Int] -> [Word32]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> Word32
mapper [Int]
range
where mapper :: Int -> Word32
mapper byte :: Int
byte = Word8 -> Column -> Word32
mdsColumnMult ((Int -> Word8
sbox1 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) ((Int -> Word8
sbox1 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) ((Int -> Word8
sbox0 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) ((Int -> Word8
sbox0 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word8) -> Word8 -> Word8
forall a b. (a -> b) -> a -> b
$ Int -> Word8
sbox0 Int
byte Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w2) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w6) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w10) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w14)) Column
Two
!b3 :: [Word32]
b3 = (Int -> Word32) -> [Int] -> [Word32]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> Word32
mapper [Int]
range
where mapper :: Int -> Word32
mapper byte :: Int
byte = Word8 -> Column -> Word32
mdsColumnMult ((Int -> Word8
sbox0 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) ((Int -> Word8
sbox1 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) ((Int -> Word8
sbox1 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) ((Int -> Word8
sbox0 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word8) -> Word8 -> Word8
forall a b. (a -> b) -> a -> b
$ Int -> Word8
sbox1 Int
byte Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w3) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w7) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w11) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` Word8
w15)) Column
Three
genK :: (ByteArray ba) => KeyPackage ba -> [Word32]
genK :: KeyPackage ba -> [Word32]
genK keyPackage :: KeyPackage ba
keyPackage = (Word8 -> [Word32]) -> [Word8] -> [Word32]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Word8 -> [Word32]
makeTuple [0..19]
where makeTuple :: Word8 -> [Word32]
makeTuple :: Word8 -> [Word32]
makeTuple idx :: Word8
idx = [Word32
a Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
b', Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
rotateL (2 Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
* Word32
b' Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
a) 9]
where tmp1 :: [Word8]
tmp1 = Int -> Word8 -> [Word8]
forall a. Int -> a -> [a]
replicate 4 (Word8 -> [Word8]) -> Word8 -> [Word8]
forall a b. (a -> b) -> a -> b
$ 2 Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
* Word8
idx
tmp2 :: [Word8]
tmp2 = (Word8 -> Word8) -> [Word8] -> [Word8]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Word8 -> Word8 -> Word8
forall a. Num a => a -> a -> a
+1) [Word8]
tmp1
a :: Word32
a = [Word8] -> KeyPackage ba -> Int -> Word32
forall ba.
ByteArray ba =>
[Word8] -> KeyPackage ba -> Int -> Word32
h [Word8]
tmp1 KeyPackage ba
keyPackage 0
b :: Word32
b = [Word8] -> KeyPackage ba -> Int -> Word32
forall ba.
ByteArray ba =>
[Word8] -> KeyPackage ba -> Int -> Word32
h [Word8]
tmp2 KeyPackage ba
keyPackage 1
b' :: Word32
b' = Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
rotateL Word32
b 8
h :: (ByteArray ba) => [Word8] -> KeyPackage ba -> Int -> Word32
h :: [Word8] -> KeyPackage ba -> Int -> Word32
h input :: [Word8]
input keyPackage :: KeyPackage ba
keyPackage offset :: Int
offset = (Word32 -> (Word8, Column) -> Word32)
-> Word32 -> [(Word8, Column)] -> Word32
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Word32 -> (Word8, Column) -> Word32
xorMdsColMult 0 ([(Word8, Column)] -> Word32) -> [(Word8, Column)] -> Word32
forall a b. (a -> b) -> a -> b
$ [Word8] -> [Column] -> [(Word8, Column)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Word8
y0f, Word8
y1f, Word8
y2f, Word8
y3f] ([Column] -> [(Word8, Column)]) -> [Column] -> [(Word8, Column)]
forall a b. (a -> b) -> a -> b
$ Column -> [Column]
forall a. Enum a => a -> [a]
enumFrom Column
Zero
where key :: ba
key = KeyPackage ba -> ba
forall ba. KeyPackage ba -> ba
rawKeyBytes KeyPackage ba
keyPackage
[y0 :: Word8
y0, y1 :: Word8
y1, y2 :: Word8
y2, y3 :: Word8
y3] = Int -> [Word8] -> [Word8]
forall a. Int -> [a] -> [a]
take 4 [Word8]
input
(!Word8
y0f, !Word8
y1f, !Word8
y2f, !Word8
y3f) = (Word8, Word8, Word8, Word8)
-> ByteSize -> (Word8, Word8, Word8, Word8)
run (Word8
y0, Word8
y1, Word8
y2, Word8
y3) (ByteSize -> (Word8, Word8, Word8, Word8))
-> ByteSize -> (Word8, Word8, Word8, Word8)
forall a b. (a -> b) -> a -> b
$ KeyPackage ba -> ByteSize
forall ba. KeyPackage ba -> ByteSize
byteSize KeyPackage ba
keyPackage
run :: (Word8, Word8, Word8, Word8) -> ByteSize -> (Word8, Word8, Word8, Word8)
run :: (Word8, Word8, Word8, Word8)
-> ByteSize -> (Word8, Word8, Word8, Word8)
run (!Word8
y0'', !Word8
y1'', !Word8
y2'', !Word8
y3'') Bytes32 = (Word8, Word8, Word8, Word8)
-> ByteSize -> (Word8, Word8, Word8, Word8)
run (Word8
y0', Word8
y1', Word8
y2', Word8
y3') ByteSize
Bytes24
where y0' :: Word8
y0' = Int -> Word8
sbox1 (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
y0'') Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` ba -> Int -> Word8
forall a. ByteArrayAccess a => a -> Int -> Word8
B.index ba
key (4 Int -> Int -> Int
forall a. Num a => a -> a -> a
* (6 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
offset) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 0)
y1' :: Word8
y1' = Int -> Word8
sbox0 (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
y1'') Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` ba -> Int -> Word8
forall a. ByteArrayAccess a => a -> Int -> Word8
B.index ba
key (4 Int -> Int -> Int
forall a. Num a => a -> a -> a
* (6 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
offset) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1)
y2' :: Word8
y2' = Int -> Word8
sbox0 (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
y2'') Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` ba -> Int -> Word8
forall a. ByteArrayAccess a => a -> Int -> Word8
B.index ba
key (4 Int -> Int -> Int
forall a. Num a => a -> a -> a
* (6 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
offset) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 2)
y3' :: Word8
y3' = Int -> Word8
sbox1 (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
y3'') Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` ba -> Int -> Word8
forall a. ByteArrayAccess a => a -> Int -> Word8
B.index ba
key (4 Int -> Int -> Int
forall a. Num a => a -> a -> a
* (6 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
offset) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 3)
run (!Word8
y0'', !Word8
y1'', !Word8
y2'', !Word8
y3'') Bytes24 = (Word8, Word8, Word8, Word8)
-> ByteSize -> (Word8, Word8, Word8, Word8)
run (Word8
y0', Word8
y1', Word8
y2', Word8
y3') ByteSize
Bytes16
where y0' :: Word8
y0' = Int -> Word8
sbox1 (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
y0'') Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` ba -> Int -> Word8
forall a. ByteArrayAccess a => a -> Int -> Word8
B.index ba
key (4 Int -> Int -> Int
forall a. Num a => a -> a -> a
* (4 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
offset) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 0)
y1' :: Word8
y1' = Int -> Word8
sbox1 (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
y1'') Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` ba -> Int -> Word8
forall a. ByteArrayAccess a => a -> Int -> Word8
B.index ba
key (4 Int -> Int -> Int
forall a. Num a => a -> a -> a
* (4 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
offset) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1)
y2' :: Word8
y2' = Int -> Word8
sbox0 (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
y2'') Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` ba -> Int -> Word8
forall a. ByteArrayAccess a => a -> Int -> Word8
B.index ba
key (4 Int -> Int -> Int
forall a. Num a => a -> a -> a
* (4 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
offset) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 2)
y3' :: Word8
y3' = Int -> Word8
sbox0 (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
y3'') Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` ba -> Int -> Word8
forall a. ByteArrayAccess a => a -> Int -> Word8
B.index ba
key (4 Int -> Int -> Int
forall a. Num a => a -> a -> a
* (4 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
offset) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 3)
run (!Word8
y0'', !Word8
y1'', !Word8
y2'', !Word8
y3'') Bytes16 = (Word8
y0', Word8
y1', Word8
y2', Word8
y3')
where y0' :: Word8
y0' = Int -> Word8
sbox1 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word8) -> Word8 -> Word8
forall a b. (a -> b) -> a -> b
$ (Int -> Word8
sbox0 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word8) -> Word8 -> Word8
forall a b. (a -> b) -> a -> b
$ (Int -> Word8
sbox0 (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
y0'') Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` ba -> Int -> Word8
forall a. ByteArrayAccess a => a -> Int -> Word8
B.index ba
key (4 Int -> Int -> Int
forall a. Num a => a -> a -> a
* (2 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
offset) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 0))) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` ba -> Int -> Word8
forall a. ByteArrayAccess a => a -> Int -> Word8
B.index ba
key (4 Int -> Int -> Int
forall a. Num a => a -> a -> a
* (0 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
offset) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 0)
y1' :: Word8
y1' = Int -> Word8
sbox0 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word8) -> Word8 -> Word8
forall a b. (a -> b) -> a -> b
$ (Int -> Word8
sbox0 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word8) -> Word8 -> Word8
forall a b. (a -> b) -> a -> b
$ (Int -> Word8
sbox1 (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
y1'') Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` ba -> Int -> Word8
forall a. ByteArrayAccess a => a -> Int -> Word8
B.index ba
key (4 Int -> Int -> Int
forall a. Num a => a -> a -> a
* (2 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
offset) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1))) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` ba -> Int -> Word8
forall a. ByteArrayAccess a => a -> Int -> Word8
B.index ba
key (4 Int -> Int -> Int
forall a. Num a => a -> a -> a
* (0 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
offset) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1)
y2' :: Word8
y2' = Int -> Word8
sbox1 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word8) -> Word8 -> Word8
forall a b. (a -> b) -> a -> b
$ (Int -> Word8
sbox1 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word8) -> Word8 -> Word8
forall a b. (a -> b) -> a -> b
$ (Int -> Word8
sbox0 (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
y2'') Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` ba -> Int -> Word8
forall a. ByteArrayAccess a => a -> Int -> Word8
B.index ba
key (4 Int -> Int -> Int
forall a. Num a => a -> a -> a
* (2 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
offset) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 2))) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` ba -> Int -> Word8
forall a. ByteArrayAccess a => a -> Int -> Word8
B.index ba
key (4 Int -> Int -> Int
forall a. Num a => a -> a -> a
* (0 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
offset) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 2)
y3' :: Word8
y3' = Int -> Word8
sbox0 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word8) -> Word8 -> Word8
forall a b. (a -> b) -> a -> b
$ (Int -> Word8
sbox1 (Int -> Word8) -> (Word8 -> Int) -> Word8 -> Word8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word8) -> Word8 -> Word8
forall a b. (a -> b) -> a -> b
$ (Int -> Word8
sbox1 (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
y3'') Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` ba -> Int -> Word8
forall a. ByteArrayAccess a => a -> Int -> Word8
B.index ba
key (4 Int -> Int -> Int
forall a. Num a => a -> a -> a
* (2 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
offset) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 3))) Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
`xor` ba -> Int -> Word8
forall a. ByteArrayAccess a => a -> Int -> Word8
B.index ba
key (4 Int -> Int -> Int
forall a. Num a => a -> a -> a
* (0 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
offset) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 3)
xorMdsColMult :: Word32 -> (Word8, Column) -> Word32
xorMdsColMult :: Word32 -> (Word8, Column) -> Word32
xorMdsColMult acc :: Word32
acc wordAndIndex :: (Word8, Column)
wordAndIndex = Word32
acc Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` (Word8 -> Column -> Word32) -> (Word8, Column) -> Word32
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Word8 -> Column -> Word32
mdsColumnMult (Word8, Column)
wordAndIndex
mdsColumnMult :: Word8 -> Column -> Word32
mdsColumnMult :: Word8 -> Column -> Word32
mdsColumnMult !Word8
byte !Column
col =
case Column
col of Zero -> Word32
input Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
rotateL Word32
mul5B 8 Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
rotateL Word32
mulEF 16 Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
rotateL Word32
mulEF 24
One -> Word32
mulEF Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
rotateL Word32
mulEF 8 Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
rotateL Word32
mul5B 16 Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
rotateL Word32
input 24
Two -> Word32
mul5B Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
rotateL Word32
mulEF 8 Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
rotateL Word32
input 16 Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
rotateL Word32
mulEF 24
Three -> Word32
mul5B Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
rotateL Word32
input 8 Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
rotateL Word32
mulEF 16 Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.|. Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
rotateL Word32
mul5B 24
where input :: Word32
input = Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
byte
mul5B :: Word32
mul5B = Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word32) -> Word8 -> Word32
forall a b. (a -> b) -> a -> b
$ Word32 -> Word8 -> Word8 -> Word8
gfMult Word32
mdsPolynomial Word8
byte 0x5B
mulEF :: Word32
mulEF = Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word32) -> Word8 -> Word32
forall a b. (a -> b) -> a -> b
$ Word32 -> Word8 -> Word8 -> Word8
gfMult Word32
mdsPolynomial Word8
byte 0xEF
tupInd :: (Bits b) => b -> (a, a) -> a
tupInd :: b -> (a, a) -> a
tupInd b :: b
b
| b -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit b
b 0 = (a, a) -> a
forall a b. (a, b) -> b
snd
| Bool
otherwise = (a, a) -> a
forall a b. (a, b) -> a
fst
gfMult :: Word32 -> Word8 -> Word8 -> Word8
gfMult :: Word32 -> Word8 -> Word8 -> Word8
gfMult p :: Word32
p a :: Word8
a b :: Word8
b = Word32 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Word8) -> Word32 -> Word8
forall a b. (a -> b) -> a -> b
$ Word8
-> (Word32, Word32) -> (Word32, Word32) -> Word32 -> Int -> Word32
run Word8
a (Word32, Word32)
b' (Word32, Word32)
p' Word32
result 0
where b' :: (Word32, Word32)
b' = (0, Word8 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
b)
p' :: (Word32, Word32)
p' = (0, Word32
p)
result :: Word32
result = 0
run :: Word8 -> (Word32, Word32) -> (Word32, Word32) -> Word32 -> Int -> Word32
run :: Word8
-> (Word32, Word32) -> (Word32, Word32) -> Word32 -> Int -> Word32
run a' :: Word8
a' b'' :: (Word32, Word32)
b'' p'' :: (Word32, Word32)
p'' result' :: Word32
result' count :: Int
count =
if Int
count Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 7
then Word32
result''
else Word8
-> (Word32, Word32) -> (Word32, Word32) -> Word32 -> Int -> Word32
run Word8
a'' (Word32, Word32)
b''' (Word32, Word32)
p'' Word32
result'' (Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 1)
where result'' :: Word32
result'' = Word32
result' Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Word8 -> (Word32, Word32) -> Word32
forall b a. Bits b => b -> (a, a) -> a
tupInd (Word8
a' Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. 1) (Word32, Word32)
b''
a'' :: Word8
a'' = Word8 -> Int -> Word8
forall a. Bits a => a -> Int -> a
shiftR Word8
a' 1
b''' :: (Word32, Word32)
b''' = ((Word32, Word32) -> Word32
forall a b. (a, b) -> a
fst (Word32, Word32)
b'', Word32 -> (Word32, Word32) -> Word32
forall b a. Bits b => b -> (a, a) -> a
tupInd (Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftR ((Word32, Word32) -> Word32
forall a b. (a, b) -> b
snd (Word32, Word32)
b'') 7) (Word32, Word32)
p'' Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
`xor` Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
shiftL ((Word32, Word32) -> Word32
forall a b. (a, b) -> b
snd (Word32, Word32)
b'') 1)