    -- |
    -- Module      : Crypto.PubKey.MaskGenFunction
    -- License     : BSD-style
    -- Maintainer  : Vincent Hanquez <vincent@snarc.org>
    -- Stability   : experimental
    -- Portability : Good
    --
    module Crypto.PubKey.MaskGenFunction
        ( MaskGenAlgorithm
        , mgf1
        ) where

    import Data.ByteString (ByteString)
    import qualified Data.ByteString as B
    import Crypto.PubKey.HashDescr
    import Crypto.Number.Serialize (i2ospOf_)

    -- | Represent a mask generation algorithm
    type MaskGenAlgorithm = HashFunction -- ^ hash function to use
                         -> ByteString   -- ^ seed
                         -> Int          -- ^ length to generate
                         -> ByteString

    -- | Mask generation algorithm MGF1
    mgf1 :: MaskGenAlgorithm
    mgf1 :: MaskGenAlgorithm
    mgf1 hashF :: HashFunction
    hashF seed :: ByteString
    seed len :: Int
    len = ByteString -> Integer -> ByteString
    loop ByteString
    B.empty 0
        where loop :: ByteString -> Integer -> ByteString
    loop t :: ByteString
    t counter :: Integer
    counter
                | ByteString -> Int
    B.length ByteString
    t Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int
    len = Int -> HashFunction
    B.take Int
    len ByteString
    t
                | Bool
    otherwise         = let counterBS :: ByteString
    counterBS = Int -> Integer -> ByteString
    i2ospOf_ 4 Integer
    counter
                                          newT :: ByteString
    newT = ByteString
    t ByteString -> HashFunction
    `B.append` HashFunction
    hashF (ByteString
    seed ByteString -> HashFunction
    `B.append` ByteString
    counterBS)
                                       in ByteString -> Integer -> ByteString
    loop ByteString
    newT (Integer
    counterInteger -> Integer -> Integer
    forall a. Num a => a -> a -> a
    +1)