module Crypto.Random.DRBG.HashDF where

import qualified Data.ByteString as B
import qualified Data.ByteString.Lazy as L
import Crypto.Classes
import Data.Serialize (encode)
import Data.Serialize.Put (runPut, putWord32be)
import Data.Word (Word8, Word32)
import Crypto.Random.DRBG.Types

-- Section 10.4.1, pg 65
hash_df :: Hash c d => (L.ByteString -> d) -> B.ByteString -> BitLen -> B.ByteString
hash_df hashF str reqBits = B.take reqBytes $ getT B.empty (1 :: Word8)
  where
  reqBytes = reqBits `div` 8 
  outlen = outputLength  .::. (hashF undefined)
  hash = encode . hashF . L.fromChunks . \x -> [x]
  getT tmp cnt
        | B.length tmp >= reqBytes = tmp
        | otherwise = let new = hash (B.concat [B.singleton cnt, reqBitsBS, str]) in getT (B.append tmp new) (cnt + 1)
  len = (if reqBits `rem` outlen == 0 then reqBits `div` outlen else (reqBits + outlen) `div` outlen)
  reqBitsBS = runPut $ putWord32be (fromIntegral reqBits :: Word32)