-- |
-- 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)