From 5e4b126fc5eee42aea65b3db4dfb57256b6e2880 Mon Sep 17 00:00:00 2001 From: Kei Hibino Date: Sun, 3 Apr 2016 05:51:07 +0900 Subject: [PATCH] Add implementation of MiyaguchiPreneel. --- Crypto/ConstructHash/MiyaguchiPreneel.hs | 56 ++++++++++++++++++++++++ cryptonite.cabal | 1 + 2 files changed, 57 insertions(+) create mode 100644 Crypto/ConstructHash/MiyaguchiPreneel.hs diff --git a/Crypto/ConstructHash/MiyaguchiPreneel.hs b/Crypto/ConstructHash/MiyaguchiPreneel.hs new file mode 100644 index 0000000..585b4f9 --- /dev/null +++ b/Crypto/ConstructHash/MiyaguchiPreneel.hs @@ -0,0 +1,56 @@ +-- | +-- Module : Crypto.ConstructHash.MiyaguchiPreneel +-- License : BSD-style +-- Maintainer : Kei Hibino +-- Stability : experimental +-- Portability : unknown +-- +-- provide the hash function construction method from block cipher +-- +-- +module Crypto.ConstructHash.MiyaguchiPreneel ( mp, cipherInit' ) where + +import Data.List (foldl') + +import Crypto.Cipher.Types +import Crypto.Error (eitherCryptoError) +import Crypto.Internal.ByteArray (ByteArrayAccess, ByteArray) +import qualified Crypto.Internal.ByteArray as B + + +-- | Compute Miyaguchi-Preneel one way compress using the supplied block cipher. +-- Simple usage /mp (cipherInit' :: ByteString -> AES128) msg/ +mp :: (ByteArrayAccess bin, ByteArray bout, ByteArray ba, BlockCipher cipher) + => (ba -> cipher) -- ^ key build function to compute Miyaguchi-Preneel + -> bin -- ^ input message + -> bout -- ^ output tag +mp g = B.convert . foldl' (step g) (B.replicate bsz 0) . chunks . B.convert + where + bsz = blockSize ( g B.empty {- dummy to get block size -} ) + chunks msg + | B.null tl = [hd] + | otherwise = hd : chunks tl + where + (hd, tl) = B.splitAt bsz msg + +-- | Simple key build function, which may raise size error. +cipherInit' :: (ByteArray ba, Cipher k) => ba -> k +cipherInit' = either (error . show) id . eitherCryptoError . cipherInit + +-- | computation step of Miyaguchi-Preneel +step :: (ByteArray ba, BlockCipher k) + => (ba -> k) + -> ba + -> ba + -> ba +step g iv msg = + ecbEncrypt k pmsg `bxor` iv `bxor` pmsg + where + k = g iv + pmsg = pad0 k msg + +pad0 :: (ByteArray ba, BlockCipher k) => k -> ba -> ba +pad0 k s = s `B.append` B.replicate (blockSize k - B.length s) 0 + +bxor :: ByteArray ba => ba -> ba -> ba +bxor = B.xor diff --git a/cryptonite.cabal b/cryptonite.cabal index d3da4ed..4359503 100644 --- a/cryptonite.cabal +++ b/cryptonite.cabal @@ -97,6 +97,7 @@ Library Crypto.Cipher.Salsa Crypto.Cipher.TripleDES Crypto.Cipher.Types + Crypto.ConstructHash.MiyaguchiPreneel Crypto.Data.AFIS Crypto.Data.Padding Crypto.Error