{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE Rank2Types #-}
module Crypto.Cipher.Types.Block
    (
    
      BlockCipher(..)
    , BlockCipher128(..)
    
    , IV(..)
    , makeIV
    , nullIV
    , ivAdd
    
    , XTS
    
    , AEAD(..)
    
    , AEADModeImpl(..)
    , aeadAppendHeader
    , aeadEncrypt
    , aeadDecrypt
    , aeadFinalize
    
    
    
    ) where
import           Data.Word
import           Crypto.Error
import           Crypto.Cipher.Types.Base
import           Crypto.Cipher.Types.GF
import           Crypto.Cipher.Types.AEAD
import           Crypto.Cipher.Types.Utils
import           Crypto.Internal.ByteArray (ByteArrayAccess, ByteArray, withByteArray, Bytes)
import qualified Crypto.Internal.ByteArray as B
import           Foreign.Ptr
import           Foreign.Storable
data IV c = forall byteArray . ByteArray byteArray => IV !byteArray
instance BlockCipher c => ByteArrayAccess (IV c) where
    withByteArray :: forall p a. IV c -> (Ptr p -> IO a) -> IO a
withByteArray (IV byteArray
z) Ptr p -> IO a
f = byteArray -> (Ptr p -> IO a) -> IO a
forall ba p a. ByteArrayAccess ba => ba -> (Ptr p -> IO a) -> IO a
forall p a. byteArray -> (Ptr p -> IO a) -> IO a
withByteArray byteArray
z Ptr p -> IO a
f
    length :: IV c -> Int
length (IV byteArray
z) = byteArray -> Int
forall ba. ByteArrayAccess ba => ba -> Int
B.length byteArray
z
instance Eq (IV c) where
    (IV byteArray
a) == :: IV c -> IV c -> Bool
== (IV byteArray
b) = byteArray -> byteArray -> Bool
forall bs1 bs2.
(ByteArrayAccess bs1, ByteArrayAccess bs2) =>
bs1 -> bs2 -> Bool
B.eq byteArray
a byteArray
b
type XTS ba cipher = (cipher, cipher)
                  -> IV cipher        
                  -> DataUnitOffset   
                  -> ba               
                  -> ba               
class Cipher cipher => BlockCipher cipher where
    
    blockSize    :: cipher -> Int
    
    
    
    ecbEncrypt :: ByteArray ba => cipher -> ba -> ba
    
    
    
    ecbDecrypt :: ByteArray ba => cipher -> ba -> ba
    
    
    
    cbcEncrypt :: ByteArray ba => cipher -> IV cipher -> ba -> ba
    cbcEncrypt = cipher -> IV cipher -> ba -> ba
forall ba cipher.
(ByteArray ba, BlockCipher cipher) =>
cipher -> IV cipher -> ba -> ba
cbcEncryptGeneric
    
    
    
    cbcDecrypt :: ByteArray ba => cipher -> IV cipher -> ba -> ba
    cbcDecrypt = cipher -> IV cipher -> ba -> ba
forall ba cipher.
(ByteArray ba, BlockCipher cipher) =>
cipher -> IV cipher -> ba -> ba
cbcDecryptGeneric
    
    
    
    cfbEncrypt :: ByteArray ba => cipher -> IV cipher -> ba -> ba
    cfbEncrypt = cipher -> IV cipher -> ba -> ba
forall ba cipher.
(ByteArray ba, BlockCipher cipher) =>
cipher -> IV cipher -> ba -> ba
cfbEncryptGeneric
    
    
    
    cfbDecrypt :: ByteArray ba => cipher -> IV cipher -> ba -> ba
    cfbDecrypt = cipher -> IV cipher -> ba -> ba
forall ba cipher.
(ByteArray ba, BlockCipher cipher) =>
cipher -> IV cipher -> ba -> ba
cfbDecryptGeneric
    
    
    
    
    
    
    
    
    ctrCombine :: ByteArray ba => cipher -> IV cipher -> ba -> ba
    ctrCombine = cipher -> IV cipher -> ba -> ba
forall ba cipher.
(ByteArray ba, BlockCipher cipher) =>
cipher -> IV cipher -> ba -> ba
ctrCombineGeneric
    
    
    
    aeadInit :: ByteArrayAccess iv => AEADMode -> cipher -> iv -> CryptoFailable (AEAD cipher)
    aeadInit AEADMode
_ cipher
_ iv
_ = CryptoError -> CryptoFailable (AEAD cipher)
forall a. CryptoError -> CryptoFailable a
CryptoFailed CryptoError
CryptoError_AEADModeNotSupported
class BlockCipher cipher => BlockCipher128 cipher where
    
    
    
    
    xtsEncrypt :: ByteArray ba
               => (cipher, cipher)
               -> IV cipher        
               -> DataUnitOffset   
               -> ba               
               -> ba               
    xtsEncrypt = XTS ba cipher
forall ba cipher.
(ByteArray ba, BlockCipher128 cipher) =>
XTS ba cipher
xtsEncryptGeneric
    
    
    
    
    xtsDecrypt :: ByteArray ba
               => (cipher, cipher)
               -> IV cipher        
               -> DataUnitOffset   
               -> ba               
               -> ba               
    xtsDecrypt = XTS ba cipher
forall ba cipher.
(ByteArray ba, BlockCipher128 cipher) =>
XTS ba cipher
xtsDecryptGeneric
makeIV :: (ByteArrayAccess b, BlockCipher c) => b -> Maybe (IV c)
makeIV :: forall b c. (ByteArrayAccess b, BlockCipher c) => b -> Maybe (IV c)
makeIV b
b = c -> Maybe (IV c)
forall c. BlockCipher c => c -> Maybe (IV c)
toIV c
forall a. HasCallStack => a
undefined
  where toIV :: BlockCipher c => c -> Maybe (IV c)
        toIV :: forall c. BlockCipher c => c -> Maybe (IV c)
toIV c
cipher
          | b -> Int
forall ba. ByteArrayAccess ba => ba -> Int
B.length b
b Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
sz = IV c -> Maybe (IV c)
forall a. a -> Maybe a
Just (IV c -> Maybe (IV c)) -> IV c -> Maybe (IV c)
forall a b. (a -> b) -> a -> b
$ Bytes -> IV c
forall c byteArray. ByteArray byteArray => byteArray -> IV c
IV (b -> Bytes
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert b
b :: Bytes)
          | Bool
otherwise        = Maybe (IV c)
forall a. Maybe a
Nothing
          where sz :: Int
sz = c -> Int
forall cipher. BlockCipher cipher => cipher -> Int
blockSize c
cipher
nullIV :: BlockCipher c => IV c
nullIV :: forall c. BlockCipher c => IV c
nullIV = c -> IV c
forall c. BlockCipher c => c -> IV c
toIV c
forall a. HasCallStack => a
undefined
  where toIV :: BlockCipher c => c -> IV c
        toIV :: forall c. BlockCipher c => c -> IV c
toIV c
cipher = Bytes -> IV c
forall c byteArray. ByteArray byteArray => byteArray -> IV c
IV (Int -> Bytes
forall ba. ByteArray ba => Int -> ba
B.zero (c -> Int
forall cipher. BlockCipher cipher => cipher -> Int
blockSize c
cipher) :: Bytes)
ivAdd :: IV c -> Int -> IV c
ivAdd :: forall c. IV c -> Int -> IV c
ivAdd (IV byteArray
b) Int
i = byteArray -> IV c
forall c byteArray. ByteArray byteArray => byteArray -> IV c
IV (byteArray -> IV c) -> byteArray -> IV c
forall a b. (a -> b) -> a -> b
$ byteArray -> byteArray
forall bs. ByteArray bs => bs -> bs
copy byteArray
b
  where copy :: ByteArray bs => bs -> bs
        copy :: forall bs. ByteArray bs => bs -> bs
copy bs
bs = bs -> (Ptr Word8 -> IO ()) -> bs
forall bs1 bs2 p.
(ByteArrayAccess bs1, ByteArray bs2) =>
bs1 -> (Ptr p -> IO ()) -> bs2
B.copyAndFreeze bs
bs ((Ptr Word8 -> IO ()) -> bs) -> (Ptr Word8 -> IO ()) -> bs
forall a b. (a -> b) -> a -> b
$ Int -> Int -> Ptr Word8 -> IO ()
loop Int
i (bs -> Int
forall ba. ByteArrayAccess ba => ba -> Int
B.length bs
bs Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
        loop :: Int -> Int -> Ptr Word8 -> IO ()
        loop :: Int -> Int -> Ptr Word8 -> IO ()
loop Int
acc Int
ofs Ptr Word8
p
            | Int
ofs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0   = () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
            | Bool
otherwise = do
                Word8
v <- Ptr Word8 -> IO Word8
forall a. Storable a => Ptr a -> IO a
peek (Ptr Word8
p Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
ofs) :: IO Word8
                let accv :: Int
accv    = Int
acc Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
v
                    (Int
hi,Int
lo) = Int
accv Int -> Int -> (Int, Int)
forall a. Integral a => a -> a -> (a, a)
`divMod` Int
256
                Ptr Word8 -> Word8 -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke (Ptr Word8
p Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
ofs) (Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
lo :: Word8)
                Int -> Int -> Ptr Word8 -> IO ()
loop Int
hi (Int
ofs Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) Ptr Word8
p
cbcEncryptGeneric :: (ByteArray ba, BlockCipher cipher) => cipher -> IV cipher -> ba -> ba
cbcEncryptGeneric :: forall ba cipher.
(ByteArray ba, BlockCipher cipher) =>
cipher -> IV cipher -> ba -> ba
cbcEncryptGeneric cipher
cipher IV cipher
ivini ba
input = [ba] -> ba
forall a. Monoid a => [a] -> a
mconcat ([ba] -> ba) -> [ba] -> ba
forall a b. (a -> b) -> a -> b
$ IV cipher -> [ba] -> [ba]
forall {byteArray} {c} {a}.
(ByteArray byteArray, BlockCipher c, ByteArrayAccess a) =>
IV c -> [a] -> [byteArray]
doEnc IV cipher
ivini ([ba] -> [ba]) -> [ba] -> [ba]
forall a b. (a -> b) -> a -> b
$ Int -> ba -> [ba]
forall b. ByteArray b => Int -> b -> [b]
chunk (cipher -> Int
forall cipher. BlockCipher cipher => cipher -> Int
blockSize cipher
cipher) ba
input
  where doEnc :: IV c -> [a] -> [byteArray]
doEnc IV c
_  []     = []
        doEnc IV c
iv (a
i:[a]
is) =
            let o :: byteArray
o = cipher -> byteArray -> byteArray
forall ba. ByteArray ba => cipher -> ba -> ba
forall cipher ba.
(BlockCipher cipher, ByteArray ba) =>
cipher -> ba -> ba
ecbEncrypt cipher
cipher (byteArray -> byteArray) -> byteArray -> byteArray
forall a b. (a -> b) -> a -> b
$ IV c -> a -> byteArray
forall a b c.
(ByteArrayAccess a, ByteArrayAccess b, ByteArray c) =>
a -> b -> c
B.xor IV c
iv a
i
             in byteArray
o byteArray -> [byteArray] -> [byteArray]
forall a. a -> [a] -> [a]
: IV c -> [a] -> [byteArray]
doEnc (byteArray -> IV c
forall c byteArray. ByteArray byteArray => byteArray -> IV c
IV byteArray
o) [a]
is
cbcDecryptGeneric :: (ByteArray ba, BlockCipher cipher) => cipher -> IV cipher -> ba -> ba
cbcDecryptGeneric :: forall ba cipher.
(ByteArray ba, BlockCipher cipher) =>
cipher -> IV cipher -> ba -> ba
cbcDecryptGeneric cipher
cipher IV cipher
ivini ba
input = [ba] -> ba
forall a. Monoid a => [a] -> a
mconcat ([ba] -> ba) -> [ba] -> ba
forall a b. (a -> b) -> a -> b
$ IV cipher -> [ba] -> [ba]
forall {a} {byteArray} {c}.
(ByteArray a, ByteArray byteArray, BlockCipher c) =>
IV c -> [byteArray] -> [a]
doDec IV cipher
ivini ([ba] -> [ba]) -> [ba] -> [ba]
forall a b. (a -> b) -> a -> b
$ Int -> ba -> [ba]
forall b. ByteArray b => Int -> b -> [b]
chunk (cipher -> Int
forall cipher. BlockCipher cipher => cipher -> Int
blockSize cipher
cipher) ba
input
  where
        doDec :: IV c -> [byteArray] -> [a]
doDec IV c
_  []     = []
        doDec IV c
iv (byteArray
i:[byteArray]
is) =
            let o :: a
o = IV c -> byteArray -> a
forall a b c.
(ByteArrayAccess a, ByteArrayAccess b, ByteArray c) =>
a -> b -> c
B.xor IV c
iv (byteArray -> a) -> byteArray -> a
forall a b. (a -> b) -> a -> b
$ cipher -> byteArray -> byteArray
forall ba. ByteArray ba => cipher -> ba -> ba
forall cipher ba.
(BlockCipher cipher, ByteArray ba) =>
cipher -> ba -> ba
ecbDecrypt cipher
cipher byteArray
i
             in a
o a -> [a] -> [a]
forall a. a -> [a] -> [a]
: IV c -> [byteArray] -> [a]
doDec (byteArray -> IV c
forall c byteArray. ByteArray byteArray => byteArray -> IV c
IV byteArray
i) [byteArray]
is
cfbEncryptGeneric :: (ByteArray ba, BlockCipher cipher) => cipher -> IV cipher -> ba -> ba
cfbEncryptGeneric :: forall ba cipher.
(ByteArray ba, BlockCipher cipher) =>
cipher -> IV cipher -> ba -> ba
cfbEncryptGeneric cipher
cipher IV cipher
ivini ba
input = [ba] -> ba
forall a. Monoid a => [a] -> a
mconcat ([ba] -> ba) -> [ba] -> ba
forall a b. (a -> b) -> a -> b
$ IV cipher -> [ba] -> [ba]
forall {a} {a} {c}.
(ByteArray a, ByteArrayAccess a) =>
IV c -> [a] -> [a]
doEnc IV cipher
ivini ([ba] -> [ba]) -> [ba] -> [ba]
forall a b. (a -> b) -> a -> b
$ Int -> ba -> [ba]
forall b. ByteArray b => Int -> b -> [b]
chunk (cipher -> Int
forall cipher. BlockCipher cipher => cipher -> Int
blockSize cipher
cipher) ba
input
  where
        doEnc :: IV c -> [a] -> [a]
doEnc IV c
_  []     = []
        doEnc (IV byteArray
iv) (a
i:[a]
is) =
            let o :: a
o = a -> byteArray -> a
forall a b c.
(ByteArrayAccess a, ByteArrayAccess b, ByteArray c) =>
a -> b -> c
B.xor a
i (byteArray -> a) -> byteArray -> a
forall a b. (a -> b) -> a -> b
$ cipher -> byteArray -> byteArray
forall ba. ByteArray ba => cipher -> ba -> ba
forall cipher ba.
(BlockCipher cipher, ByteArray ba) =>
cipher -> ba -> ba
ecbEncrypt cipher
cipher byteArray
iv
             in a
o a -> [a] -> [a]
forall a. a -> [a] -> [a]
: IV c -> [a] -> [a]
doEnc (a -> IV c
forall c byteArray. ByteArray byteArray => byteArray -> IV c
IV a
o) [a]
is
cfbDecryptGeneric :: (ByteArray ba, BlockCipher cipher) => cipher -> IV cipher -> ba -> ba
cfbDecryptGeneric :: forall ba cipher.
(ByteArray ba, BlockCipher cipher) =>
cipher -> IV cipher -> ba -> ba
cfbDecryptGeneric cipher
cipher IV cipher
ivini ba
input = [ba] -> ba
forall a. Monoid a => [a] -> a
mconcat ([ba] -> ba) -> [ba] -> ba
forall a b. (a -> b) -> a -> b
$ IV cipher -> [ba] -> [ba]
forall {a} {a} {c}.
(ByteArray a, ByteArray a) =>
IV c -> [a] -> [a]
doDec IV cipher
ivini ([ba] -> [ba]) -> [ba] -> [ba]
forall a b. (a -> b) -> a -> b
$ Int -> ba -> [ba]
forall b. ByteArray b => Int -> b -> [b]
chunk (cipher -> Int
forall cipher. BlockCipher cipher => cipher -> Int
blockSize cipher
cipher) ba
input
  where
        doDec :: IV c -> [a] -> [a]
doDec IV c
_  []     = []
        doDec (IV byteArray
iv) (a
i:[a]
is) =
            let o :: a
o = a -> byteArray -> a
forall a b c.
(ByteArrayAccess a, ByteArrayAccess b, ByteArray c) =>
a -> b -> c
B.xor a
i (byteArray -> a) -> byteArray -> a
forall a b. (a -> b) -> a -> b
$ cipher -> byteArray -> byteArray
forall ba. ByteArray ba => cipher -> ba -> ba
forall cipher ba.
(BlockCipher cipher, ByteArray ba) =>
cipher -> ba -> ba
ecbEncrypt cipher
cipher byteArray
iv
             in a
o a -> [a] -> [a]
forall a. a -> [a] -> [a]
: IV c -> [a] -> [a]
doDec (a -> IV c
forall c byteArray. ByteArray byteArray => byteArray -> IV c
IV a
i) [a]
is
ctrCombineGeneric :: (ByteArray ba, BlockCipher cipher) => cipher -> IV cipher -> ba -> ba
ctrCombineGeneric :: forall ba cipher.
(ByteArray ba, BlockCipher cipher) =>
cipher -> IV cipher -> ba -> ba
ctrCombineGeneric cipher
cipher IV cipher
ivini ba
input = [ba] -> ba
forall a. Monoid a => [a] -> a
mconcat ([ba] -> ba) -> [ba] -> ba
forall a b. (a -> b) -> a -> b
$ IV cipher -> [ba] -> [ba]
forall {a} {a} {c}.
(ByteArray a, ByteArrayAccess a) =>
IV c -> [a] -> [a]
doCnt IV cipher
ivini ([ba] -> [ba]) -> [ba] -> [ba]
forall a b. (a -> b) -> a -> b
$ Int -> ba -> [ba]
forall b. ByteArray b => Int -> b -> [b]
chunk (cipher -> Int
forall cipher. BlockCipher cipher => cipher -> Int
blockSize cipher
cipher) ba
input
  where doCnt :: IV c -> [a] -> [a]
doCnt IV c
_  [] = []
        doCnt iv :: IV c
iv@(IV byteArray
ivd) (a
i:[a]
is) =
            let ivEnc :: byteArray
ivEnc = cipher -> byteArray -> byteArray
forall ba. ByteArray ba => cipher -> ba -> ba
forall cipher ba.
(BlockCipher cipher, ByteArray ba) =>
cipher -> ba -> ba
ecbEncrypt cipher
cipher byteArray
ivd
             in a -> byteArray -> a
forall a b c.
(ByteArrayAccess a, ByteArrayAccess b, ByteArray c) =>
a -> b -> c
B.xor a
i byteArray
ivEnc a -> [a] -> [a]
forall a. a -> [a] -> [a]
: IV c -> [a] -> [a]
doCnt (IV c -> Int -> IV c
forall c. IV c -> Int -> IV c
ivAdd IV c
iv Int
1) [a]
is
xtsEncryptGeneric :: (ByteArray ba, BlockCipher128 cipher) => XTS ba cipher
xtsEncryptGeneric :: forall ba cipher.
(ByteArray ba, BlockCipher128 cipher) =>
XTS ba cipher
xtsEncryptGeneric = (cipher -> ba -> ba)
-> (cipher, cipher) -> IV cipher -> DataUnitOffset -> ba -> ba
forall ba cipher.
(ByteArray ba, BlockCipher128 cipher) =>
(cipher -> ba -> ba)
-> (cipher, cipher) -> IV cipher -> DataUnitOffset -> ba -> ba
xtsGeneric cipher -> ba -> ba
forall ba. ByteArray ba => cipher -> ba -> ba
forall cipher ba.
(BlockCipher cipher, ByteArray ba) =>
cipher -> ba -> ba
ecbEncrypt
xtsDecryptGeneric :: (ByteArray ba, BlockCipher128 cipher) => XTS ba cipher
xtsDecryptGeneric :: forall ba cipher.
(ByteArray ba, BlockCipher128 cipher) =>
XTS ba cipher
xtsDecryptGeneric = (cipher -> ba -> ba)
-> (cipher, cipher) -> IV cipher -> DataUnitOffset -> ba -> ba
forall ba cipher.
(ByteArray ba, BlockCipher128 cipher) =>
(cipher -> ba -> ba)
-> (cipher, cipher) -> IV cipher -> DataUnitOffset -> ba -> ba
xtsGeneric cipher -> ba -> ba
forall ba. ByteArray ba => cipher -> ba -> ba
forall cipher ba.
(BlockCipher cipher, ByteArray ba) =>
cipher -> ba -> ba
ecbDecrypt
xtsGeneric :: (ByteArray ba, BlockCipher128 cipher)
           => (cipher -> ba -> ba)
           -> (cipher, cipher)
           -> IV cipher
           -> DataUnitOffset
           -> ba
           -> ba
xtsGeneric :: forall ba cipher.
(ByteArray ba, BlockCipher128 cipher) =>
(cipher -> ba -> ba)
-> (cipher, cipher) -> IV cipher -> DataUnitOffset -> ba -> ba
xtsGeneric cipher -> ba -> ba
f (cipher
cipher, cipher
tweakCipher) (IV byteArray
iv) DataUnitOffset
sPoint ba
input =
    [ba] -> ba
forall a. Monoid a => [a] -> a
mconcat ([ba] -> ba) -> [ba] -> ba
forall a b. (a -> b) -> a -> b
$ byteArray -> [ba] -> [ba]
forall {t} {a} {a}.
(ByteArray t, ByteArray a, ByteArrayAccess a) =>
t -> [a] -> [a]
doXts byteArray
iniTweak ([ba] -> [ba]) -> [ba] -> [ba]
forall a b. (a -> b) -> a -> b
$ Int -> ba -> [ba]
forall b. ByteArray b => Int -> b -> [b]
chunk (cipher -> Int
forall cipher. BlockCipher cipher => cipher -> Int
blockSize cipher
cipher) ba
input
  where encTweak :: byteArray
encTweak = cipher -> byteArray -> byteArray
forall ba. ByteArray ba => cipher -> ba -> ba
forall cipher ba.
(BlockCipher cipher, ByteArray ba) =>
cipher -> ba -> ba
ecbEncrypt cipher
tweakCipher byteArray
iv
        iniTweak :: byteArray
iniTweak = (byteArray -> byteArray) -> byteArray -> [byteArray]
forall a. (a -> a) -> a -> [a]
iterate byteArray -> byteArray
forall bs. ByteArray bs => bs -> bs
xtsGFMul byteArray
encTweak [byteArray] -> Int -> byteArray
forall a. HasCallStack => [a] -> Int -> a
!! DataUnitOffset -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral DataUnitOffset
sPoint
        doXts :: t -> [a] -> [a]
doXts t
_     []     = []
        doXts t
tweak (a
i:[a]
is) =
            let o :: a
o = ba -> t -> a
forall a b c.
(ByteArrayAccess a, ByteArrayAccess b, ByteArray c) =>
a -> b -> c
B.xor (cipher -> ba -> ba
f cipher
cipher (ba -> ba) -> ba -> ba
forall a b. (a -> b) -> a -> b
$ a -> t -> ba
forall a b c.
(ByteArrayAccess a, ByteArrayAccess b, ByteArray c) =>
a -> b -> c
B.xor a
i t
tweak) t
tweak
             in a
o a -> [a] -> [a]
forall a. a -> [a] -> [a]
: t -> [a] -> [a]
doXts (t -> t
forall bs. ByteArray bs => bs -> bs
xtsGFMul t
tweak) [a]
is