{-# LINE 1 "src/Data/Digest/GOST34112012/Hash.hsc" #-}
module Data.Digest.GOST34112012.Hash
( GOST34112012HashContext, hashGOST34112012, getGOST34112012HashBufSize,
  initGOST34112012Hash, updateGOST34112012Hash, finishGOST34112012Hash ) where
import Foreign hiding (newForeignPtr)
import Foreign.Concurrent (newForeignPtr)
import Foreign.C (newCString, CString, CInt(..), CUInt(..), CSize(..))
import Data.ByteString (ByteString, useAsCStringLen, packCStringLen)



type GOST34112012HashContext = ForeignPtr GOST34112012HashCtx

data GOST34112012HashCtx = GOST34112012HashCtx {
  GOST34112012HashCtx -> CSize
cGOST34112012HashBufSize    :: CSize,
  GOST34112012HashCtx -> CUInt
cGOST34112012HashDigestSize :: CUInt
} deriving (GOST34112012HashCtx -> GOST34112012HashCtx -> Bool
(GOST34112012HashCtx -> GOST34112012HashCtx -> Bool)
-> (GOST34112012HashCtx -> GOST34112012HashCtx -> Bool)
-> Eq GOST34112012HashCtx
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: GOST34112012HashCtx -> GOST34112012HashCtx -> Bool
== :: GOST34112012HashCtx -> GOST34112012HashCtx -> Bool
$c/= :: GOST34112012HashCtx -> GOST34112012HashCtx -> Bool
/= :: GOST34112012HashCtx -> GOST34112012HashCtx -> Bool
Eq, Eq GOST34112012HashCtx
Eq GOST34112012HashCtx =>
(GOST34112012HashCtx -> GOST34112012HashCtx -> Ordering)
-> (GOST34112012HashCtx -> GOST34112012HashCtx -> Bool)
-> (GOST34112012HashCtx -> GOST34112012HashCtx -> Bool)
-> (GOST34112012HashCtx -> GOST34112012HashCtx -> Bool)
-> (GOST34112012HashCtx -> GOST34112012HashCtx -> Bool)
-> (GOST34112012HashCtx
    -> GOST34112012HashCtx -> GOST34112012HashCtx)
-> (GOST34112012HashCtx
    -> GOST34112012HashCtx -> GOST34112012HashCtx)
-> Ord GOST34112012HashCtx
GOST34112012HashCtx -> GOST34112012HashCtx -> Bool
GOST34112012HashCtx -> GOST34112012HashCtx -> Ordering
GOST34112012HashCtx -> GOST34112012HashCtx -> GOST34112012HashCtx
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: GOST34112012HashCtx -> GOST34112012HashCtx -> Ordering
compare :: GOST34112012HashCtx -> GOST34112012HashCtx -> Ordering
$c< :: GOST34112012HashCtx -> GOST34112012HashCtx -> Bool
< :: GOST34112012HashCtx -> GOST34112012HashCtx -> Bool
$c<= :: GOST34112012HashCtx -> GOST34112012HashCtx -> Bool
<= :: GOST34112012HashCtx -> GOST34112012HashCtx -> Bool
$c> :: GOST34112012HashCtx -> GOST34112012HashCtx -> Bool
> :: GOST34112012HashCtx -> GOST34112012HashCtx -> Bool
$c>= :: GOST34112012HashCtx -> GOST34112012HashCtx -> Bool
>= :: GOST34112012HashCtx -> GOST34112012HashCtx -> Bool
$cmax :: GOST34112012HashCtx -> GOST34112012HashCtx -> GOST34112012HashCtx
max :: GOST34112012HashCtx -> GOST34112012HashCtx -> GOST34112012HashCtx
$cmin :: GOST34112012HashCtx -> GOST34112012HashCtx -> GOST34112012HashCtx
min :: GOST34112012HashCtx -> GOST34112012HashCtx -> GOST34112012HashCtx
Ord, Int -> GOST34112012HashCtx -> ShowS
[GOST34112012HashCtx] -> ShowS
GOST34112012HashCtx -> String
(Int -> GOST34112012HashCtx -> ShowS)
-> (GOST34112012HashCtx -> String)
-> ([GOST34112012HashCtx] -> ShowS)
-> Show GOST34112012HashCtx
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> GOST34112012HashCtx -> ShowS
showsPrec :: Int -> GOST34112012HashCtx -> ShowS
$cshow :: GOST34112012HashCtx -> String
show :: GOST34112012HashCtx -> String
$cshowList :: [GOST34112012HashCtx] -> ShowS
showList :: [GOST34112012HashCtx] -> ShowS
Show)

instance Storable GOST34112012HashCtx where
  sizeOf :: GOST34112012HashCtx -> Int
sizeOf GOST34112012HashCtx
_    = ((Int
336))
{-# LINE 20 "src/Data/Digest/GOST34112012/Hash.hsc" #-}
  alignment _ = (16)
{-# LINE 21 "src/Data/Digest/GOST34112012/Hash.hsc" #-}
  peek ptr    = GOST34112012HashCtx
            <$> ((\hsc_ptr -> peekByteOff hsc_ptr 320)) ptr
{-# LINE 23 "src/Data/Digest/GOST34112012/Hash.hsc" #-}
            <*> ((\hsc_ptr -> peekByteOff hsc_ptr 328)) ptr
{-# LINE 24 "src/Data/Digest/GOST34112012/Hash.hsc" #-}
  poke _ _    = fail "GOST34112012HashCtx is read only"

hashGOST34112012 :: Int -> ByteString -> IO ByteString
hashGOST34112012 :: Int -> ByteString -> IO ByteString
hashGOST34112012 Int
dsize ByteString
bytes = Int -> IO GOST34112012HashContext
initGOST34112012Hash Int
dsize
                   IO GOST34112012HashContext
-> (GOST34112012HashContext -> IO ByteString) -> IO ByteString
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \GOST34112012HashContext
ctx -> GOST34112012HashContext -> ByteString -> IO ()
updateGOST34112012Hash GOST34112012HashContext
ctx ByteString
bytes
                            IO () -> IO ByteString -> IO ByteString
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> GOST34112012HashContext -> IO ByteString
finishGOST34112012Hash GOST34112012HashContext
ctx

initGOST34112012Hash :: Int -> IO GOST34112012HashContext
initGOST34112012Hash :: Int -> IO GOST34112012HashContext
initGOST34112012Hash Int
dsize = IO (Ptr GOST34112012HashCtx)
forall a. Storable a => IO (Ptr a)
malloc IO (Ptr GOST34112012HashCtx)
-> (Ptr GOST34112012HashCtx -> IO GOST34112012HashContext)
-> IO GOST34112012HashContext
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Ptr GOST34112012HashCtx
ctx -> do
  Ptr GOST34112012HashCtx -> CInt -> IO ()
cGOST34112012Init Ptr GOST34112012HashCtx
ctx (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
dsize)
  Ptr GOST34112012HashCtx -> IO () -> IO GOST34112012HashContext
forall a. Ptr a -> IO () -> IO (ForeignPtr a)
newForeignPtr Ptr GOST34112012HashCtx
ctx (Ptr GOST34112012HashCtx -> IO ()
cGOST34112012Cleanup Ptr GOST34112012HashCtx
ctx IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Ptr GOST34112012HashCtx -> IO ()
forall a. Ptr a -> IO ()
free Ptr GOST34112012HashCtx
ctx)

updateGOST34112012Hash :: GOST34112012HashContext -> ByteString -> IO ()
updateGOST34112012Hash :: GOST34112012HashContext -> ByteString -> IO ()
updateGOST34112012Hash GOST34112012HashContext
ctx ByteString
bytes = ByteString -> (CStringLen -> IO ()) -> IO ()
forall a. ByteString -> (CStringLen -> IO a) -> IO a
useAsCStringLen ByteString
bytes (\(Ptr CChar
str, Int
len) ->
  GOST34112012HashContext
-> (Ptr GOST34112012HashCtx -> IO ()) -> IO ()
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr GOST34112012HashContext
ctx (\Ptr GOST34112012HashCtx
ptr -> Ptr GOST34112012HashCtx -> Ptr CChar -> CSize -> IO ()
cGOST34112012Update Ptr GOST34112012HashCtx
ptr Ptr CChar
str (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)))

finishGOST34112012Hash :: GOST34112012HashContext -> IO ByteString
finishGOST34112012Hash :: GOST34112012HashContext -> IO ByteString
finishGOST34112012Hash GOST34112012HashContext
ctx = GOST34112012HashContext
-> (Ptr GOST34112012HashCtx -> IO ByteString) -> IO ByteString
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr GOST34112012HashContext
ctx (\Ptr GOST34112012HashCtx
ptr -> Ptr GOST34112012HashCtx -> IO GOST34112012HashCtx
forall a. Storable a => Ptr a -> IO a
peek Ptr GOST34112012HashCtx
ptr IO GOST34112012HashCtx
-> (GOST34112012HashCtx -> IO ByteString) -> IO ByteString
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \GOST34112012HashCtx
ct ->
  String -> IO (Ptr CChar)
newCString (Int -> Char -> String
forall a. Int -> a -> [a]
replicate (GOST34112012HashCtx -> Int
forall {a}. Num a => GOST34112012HashCtx -> a
hsize GOST34112012HashCtx
ct) Char
' ') IO (Ptr CChar) -> (Ptr CChar -> IO ByteString) -> IO ByteString
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Ptr CChar
str -> Ptr GOST34112012HashCtx -> Ptr CChar -> IO ()
cGOST34112012Final Ptr GOST34112012HashCtx
ptr Ptr CChar
str
    IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Ptr GOST34112012HashCtx -> IO ()
cGOST34112012Cleanup Ptr GOST34112012HashCtx
ptr IO () -> IO ByteString -> IO ByteString
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> CStringLen -> IO ByteString
packCStringLen (Ptr CChar
str, GOST34112012HashCtx -> Int
forall {a}. Num a => GOST34112012HashCtx -> a
hsize GOST34112012HashCtx
ct)) where
      hsize :: GOST34112012HashCtx -> a
hsize GOST34112012HashCtx
ct = if CUInt
256 CUInt -> CUInt -> Bool
forall a. Eq a => a -> a -> Bool
== GOST34112012HashCtx -> CUInt
cGOST34112012HashDigestSize GOST34112012HashCtx
ct then a
32 else a
64

getGOST34112012HashBufSize :: GOST34112012HashContext -> IO Int
getGOST34112012HashBufSize :: GOST34112012HashContext -> IO Int
getGOST34112012HashBufSize = (GOST34112012HashCtx -> Int) -> IO GOST34112012HashCtx -> IO Int
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CSize -> Int)
-> (GOST34112012HashCtx -> CSize) -> GOST34112012HashCtx -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GOST34112012HashCtx -> CSize
cGOST34112012HashBufSize)
                                (IO GOST34112012HashCtx -> IO Int)
-> (GOST34112012HashContext -> IO GOST34112012HashCtx)
-> GOST34112012HashContext
-> IO Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((GOST34112012HashContext
 -> (Ptr GOST34112012HashCtx -> IO GOST34112012HashCtx)
 -> IO GOST34112012HashCtx)
-> (Ptr GOST34112012HashCtx -> IO GOST34112012HashCtx)
-> GOST34112012HashContext
-> IO GOST34112012HashCtx
forall a b c. (a -> b -> c) -> b -> a -> c
flip GOST34112012HashContext
-> (Ptr GOST34112012HashCtx -> IO GOST34112012HashCtx)
-> IO GOST34112012HashCtx
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr Ptr GOST34112012HashCtx -> IO GOST34112012HashCtx
forall a. Storable a => Ptr a -> IO a
peek)

foreign import ccall "GOST34112012Init"
  cGOST34112012Init :: Ptr GOST34112012HashCtx -> CInt -> IO ()

foreign import ccall "GOST34112012Update"
  cGOST34112012Update :: Ptr GOST34112012HashCtx -> CString -> CSize -> IO ()

foreign import ccall "GOST34112012Final"
  cGOST34112012Final :: Ptr GOST34112012HashCtx -> CString -> IO ()

foreign import ccall "GOST34112012Cleanup"
  cGOST34112012Cleanup :: Ptr GOST34112012HashCtx -> IO ()