{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Crypto.ConstructHash.MiyaguchiPreneel
( compute, compute'
, MiyaguchiPreneel
) where
import Data.List (foldl')
import Crypto.Data.Padding (pad, Format (ZERO))
import Crypto.Cipher.Types
import Crypto.Error (throwCryptoError)
import Crypto.Internal.ByteArray (ByteArrayAccess, ByteArray, Bytes)
import qualified Crypto.Internal.ByteArray as B
newtype MiyaguchiPreneel a = MP Bytes
deriving (MiyaguchiPreneel a -> Int
forall a. MiyaguchiPreneel a -> Int
forall p. MiyaguchiPreneel a -> Ptr p -> IO ()
forall ba.
(ba -> Int)
-> (forall p a. ba -> (Ptr p -> IO a) -> IO a)
-> (forall p. ba -> Ptr p -> IO ())
-> ByteArrayAccess ba
forall a p. MiyaguchiPreneel a -> Ptr p -> IO ()
forall p a. MiyaguchiPreneel a -> (Ptr p -> IO a) -> IO a
forall a p a. MiyaguchiPreneel a -> (Ptr p -> IO a) -> IO a
copyByteArrayToPtr :: forall p. MiyaguchiPreneel a -> Ptr p -> IO ()
$ccopyByteArrayToPtr :: forall a p. MiyaguchiPreneel a -> Ptr p -> IO ()
withByteArray :: forall p a. MiyaguchiPreneel a -> (Ptr p -> IO a) -> IO a
$cwithByteArray :: forall a p a. MiyaguchiPreneel a -> (Ptr p -> IO a) -> IO a
length :: MiyaguchiPreneel a -> Int
$clength :: forall a. MiyaguchiPreneel a -> Int
ByteArrayAccess)
instance Eq (MiyaguchiPreneel a) where
MP Bytes
b1 == :: MiyaguchiPreneel a -> MiyaguchiPreneel a -> Bool
== MP Bytes
b2 = forall bs1 bs2.
(ByteArrayAccess bs1, ByteArrayAccess bs2) =>
bs1 -> bs2 -> Bool
B.constEq Bytes
b1 Bytes
b2
compute' :: (ByteArrayAccess bin, BlockCipher cipher)
=> (Bytes -> cipher)
-> bin
-> MiyaguchiPreneel cipher
compute' :: forall bin cipher.
(ByteArrayAccess bin, BlockCipher cipher) =>
(Bytes -> cipher) -> bin -> MiyaguchiPreneel cipher
compute' Bytes -> cipher
g = forall a. Bytes -> MiyaguchiPreneel a
MP forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (forall ba k.
(ByteArray ba, BlockCipher k) =>
(ba -> k) -> ba -> ba -> ba
step forall a b. (a -> b) -> a -> b
$ Bytes -> cipher
g) (forall ba. ByteArray ba => Int -> Word8 -> ba
B.replicate Int
bsz Word8
0) forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bytes -> [Bytes]
chunks forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall byteArray.
ByteArray byteArray =>
Format -> byteArray -> byteArray
pad (Int -> Format
ZERO Int
bsz) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
B.convert
where
bsz :: Int
bsz = forall cipher. BlockCipher cipher => cipher -> Int
blockSize ( Bytes -> cipher
g forall a. ByteArray a => a
B.empty )
chunks :: Bytes -> [Bytes]
chunks Bytes
msg
| forall a. ByteArrayAccess a => a -> Bool
B.null Bytes
msg = []
| Bool
otherwise = (Bytes
hd :: Bytes) forall a. a -> [a] -> [a]
: Bytes -> [Bytes]
chunks Bytes
tl
where
(Bytes
hd, Bytes
tl) = forall bs. ByteArray bs => Int -> bs -> (bs, bs)
B.splitAt Int
bsz Bytes
msg
compute :: (ByteArrayAccess bin, BlockCipher cipher)
=> bin
-> MiyaguchiPreneel cipher
compute :: forall bin cipher.
(ByteArrayAccess bin, BlockCipher cipher) =>
bin -> MiyaguchiPreneel cipher
compute = forall bin cipher.
(ByteArrayAccess bin, BlockCipher cipher) =>
(Bytes -> cipher) -> bin -> MiyaguchiPreneel cipher
compute' forall a b. (a -> b) -> a -> b
$ forall a. CryptoFailable a -> a
throwCryptoError forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall cipher key.
(Cipher cipher, ByteArray key) =>
key -> CryptoFailable cipher
cipherInit
step :: (ByteArray ba, BlockCipher k)
=> (ba -> k)
-> ba
-> ba
-> ba
step :: forall ba k.
(ByteArray ba, BlockCipher k) =>
(ba -> k) -> ba -> ba -> ba
step ba -> k
g ba
iv ba
msg =
forall cipher ba.
(BlockCipher cipher, ByteArray ba) =>
cipher -> ba -> ba
ecbEncrypt k
k ba
msg forall ba. ByteArray ba => ba -> ba -> ba
`bxor` ba
iv forall ba. ByteArray ba => ba -> ba -> ba
`bxor` ba
msg
where
k :: k
k = ba -> k
g ba
iv
bxor :: ByteArray ba => ba -> ba -> ba
bxor :: forall ba. ByteArray ba => ba -> ba -> ba
bxor = forall a b c.
(ByteArrayAccess a, ByteArrayAccess b, ByteArray c) =>
a -> b -> c
B.xor