add template for hash generation and the little program associated with it
This commit is contained in:
parent
70e2321d95
commit
4652fd99a7
68
gen/Gen.hs
Normal file
68
gen/Gen.hs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
module Main where
|
||||||
|
|
||||||
|
import System.FilePath
|
||||||
|
import System.Directory
|
||||||
|
import Control.Applicative
|
||||||
|
import Control.Monad
|
||||||
|
import Template
|
||||||
|
|
||||||
|
readTemplate templateFile = parseTemplate <$> readFile templateFile
|
||||||
|
writeTemplate file vars template = writeFile file (renderTemplate template vars)
|
||||||
|
|
||||||
|
data GenHashModule = GenHashModule
|
||||||
|
{ ghmModuleName :: String
|
||||||
|
, ghmHeaderFile :: String
|
||||||
|
, ghmHashName :: String
|
||||||
|
, ghmContextSize :: Int
|
||||||
|
, ghmDigestSize :: Int
|
||||||
|
, ghmBlockLength :: Int
|
||||||
|
, ghmCustomizable :: Bool
|
||||||
|
} deriving (Show,Eq)
|
||||||
|
|
||||||
|
hashModules =
|
||||||
|
[ GenHashModule "MD2" "md2.h" "md2" 96 16 16 False
|
||||||
|
, GenHashModule "MD4" "md4.h" "md4" 96 16 64 False
|
||||||
|
, GenHashModule "MD5" "md5.h" "md5" 96 16 64 False
|
||||||
|
, GenHashModule "SHA1" "sha1.h" "sha1" 96 20 64 False
|
||||||
|
, GenHashModule "SHA224" "sha256.h" "sha224" 192 28 64 False
|
||||||
|
, GenHashModule "SHA256" "sha256.h" "sha256" 192 32 64 False
|
||||||
|
, GenHashModule "SHA384" "sha512.h" "sha384" 256 48 128 False
|
||||||
|
, GenHashModule "SHA512" "sha512.h" "sha512" 256 64 128 False
|
||||||
|
, GenHashModule "Kekkak" "kekkak.h" "kekkak" 360 64 64 True
|
||||||
|
, GenHashModule "SHA3" "sha3.h" "sha3" 360 64 64 True
|
||||||
|
, GenHashModule "RIPEMD160" "ripemd.h" "ripemd160" 128 20 64 False
|
||||||
|
, GenHashModule "Skein256" "skein256.h" "skein256" 96 32 32 True
|
||||||
|
, GenHashModule "Skein512" "skein512.h" "skein512" 160 64 64 True
|
||||||
|
, GenHashModule "Tiger" "tiger.h" "tiger" 96 24 64 False
|
||||||
|
, GenHashModule "Whirlpool" "whirlpool.h" "whirlpool" 168 64 64 False
|
||||||
|
]
|
||||||
|
|
||||||
|
renderHashModules genOpts = do
|
||||||
|
hashTemplate <- readTemplate "template/hash.hs"
|
||||||
|
hashInternalTemplate <- readTemplate "template/hash-internal.hs"
|
||||||
|
hashLenTemplate <- readTemplate "template/hash-len.hs"
|
||||||
|
hashLenInternalTemplate <- readTemplate "template/hash-internal-len.hs"
|
||||||
|
forM_ hashModules $ \ghm -> do
|
||||||
|
let vars = [ ("MODULENAME", ghmModuleName ghm)
|
||||||
|
, ("HEADER_FILE", ghmHeaderFile ghm)
|
||||||
|
, ("HASHNAME", ghmHashName ghm)
|
||||||
|
, ("SIZECTX", show (ghmContextSize ghm))
|
||||||
|
, ("DIGESTSIZE", show (ghmDigestSize ghm))
|
||||||
|
, ("SIZECTX8", show (ghmContextSize ghm `div` 8))
|
||||||
|
, ("BLOCKLEN", show (ghmBlockLength ghm))
|
||||||
|
]
|
||||||
|
let mainDir = "Crypto/Hash"
|
||||||
|
internalDir = "Crypto/Hash/Internal"
|
||||||
|
mainName = mainDir </> (ghmModuleName ghm ++ ".hs")
|
||||||
|
internalName = internalDir </> (ghmModuleName ghm ++ ".hs")
|
||||||
|
|
||||||
|
createDirectoryIfMissing True mainDir
|
||||||
|
createDirectoryIfMissing True internalDir
|
||||||
|
if ghmCustomizable ghm
|
||||||
|
then do writeTemplate mainName vars hashLenTemplate
|
||||||
|
writeTemplate internalName vars hashLenInternalTemplate
|
||||||
|
else do writeTemplate mainName vars hashTemplate
|
||||||
|
writeTemplate internalName vars hashInternalTemplate
|
||||||
|
|
||||||
|
main = do
|
||||||
|
renderHashModules ()
|
||||||
65
gen/Template.hs
Normal file
65
gen/Template.hs
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
-- |
|
||||||
|
-- Module : Template
|
||||||
|
-- License : BSD-style
|
||||||
|
-- Maintainer : Vincent Hanquez <vincent@snarc.org>
|
||||||
|
-- Stability : experimental
|
||||||
|
-- Portability : portable
|
||||||
|
--
|
||||||
|
-- A very simple template engine
|
||||||
|
--
|
||||||
|
module Template
|
||||||
|
( Template
|
||||||
|
, parseTemplate
|
||||||
|
, renderTemplate
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Data.Char (isDigit, isAlpha)
|
||||||
|
import Data.List (isPrefixOf)
|
||||||
|
|
||||||
|
data TAtom = Text String | Var String deriving (Show)
|
||||||
|
type Template = [TAtom]
|
||||||
|
|
||||||
|
renderTemplate :: Template -> [(String,String)] -> String
|
||||||
|
renderTemplate template attrs =
|
||||||
|
concat $ map renderAtom template
|
||||||
|
where
|
||||||
|
renderAtom :: TAtom -> String
|
||||||
|
renderAtom (Text b) = b
|
||||||
|
renderAtom (Var s) = maybe "" id $ lookup s attrs
|
||||||
|
|
||||||
|
parseTemplate :: String -> Template
|
||||||
|
parseTemplate content
|
||||||
|
| null content = []
|
||||||
|
| isPrefixOf "%%" content = parseVar $ tailMarker content
|
||||||
|
| otherwise = parseText content
|
||||||
|
where
|
||||||
|
parseText :: String -> Template
|
||||||
|
parseText s
|
||||||
|
| null s = []
|
||||||
|
| otherwise = Text b : (parseVar $ tailMarker a)
|
||||||
|
where
|
||||||
|
(b, a) = grabUntilMarker s
|
||||||
|
|
||||||
|
parseVar :: String -> Template
|
||||||
|
parseVar s
|
||||||
|
| null s = []
|
||||||
|
| otherwise =
|
||||||
|
let (b, a) = grabUntilMarker s in
|
||||||
|
if isVariable b
|
||||||
|
then Var b : (parseText $ tailMarker a)
|
||||||
|
else Text b : (parseVar $ tailMarker a)
|
||||||
|
|
||||||
|
isVariable :: String -> Bool
|
||||||
|
isVariable = and . map isVariableChar
|
||||||
|
where isVariableChar :: Char -> Bool
|
||||||
|
isVariableChar c = isAlpha c || isDigit c || c == '_'
|
||||||
|
|
||||||
|
tailMarker ('%':'%':xs) = xs
|
||||||
|
tailMarker s = s
|
||||||
|
|
||||||
|
grabUntilMarker = loop
|
||||||
|
where loop [] = ([], [])
|
||||||
|
loop l@('%':'%':xs) = ([], l)
|
||||||
|
loop (x:xs) =
|
||||||
|
let (l1,l2) = loop xs
|
||||||
|
in (x:l1,l2)
|
||||||
104
gen/template/hash-internal-len.hs
Normal file
104
gen/template/hash-internal-len.hs
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
{-# LANGUAGE ForeignFunctionInterface, CPP, MultiParamTypeClasses #-}
|
||||||
|
|
||||||
|
-- |
|
||||||
|
-- Module : Crypto.Hash.Internal.%%MODULENAME%%
|
||||||
|
-- License : BSD-style
|
||||||
|
-- Maintainer : Vincent Hanquez <vincent@snarc.org>
|
||||||
|
-- Stability : experimental
|
||||||
|
-- Portability : unknown
|
||||||
|
--
|
||||||
|
-- A module containing %%MODULENAME%% bindings
|
||||||
|
--
|
||||||
|
module Crypto.Hash.Internal.%%MODULENAME%%
|
||||||
|
( Ctx(..)
|
||||||
|
-- * Internal values
|
||||||
|
, sizeCtx
|
||||||
|
-- * Internal IO hash functions
|
||||||
|
, internalInit
|
||||||
|
, internalInitAt
|
||||||
|
, internalUpdate
|
||||||
|
, internalFinalize
|
||||||
|
-- * Context copy and creation
|
||||||
|
, withCtxCopy
|
||||||
|
, withCtxNewThrow
|
||||||
|
, withCtxThrow
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Prelude hiding (init)
|
||||||
|
import Foreign.Ptr
|
||||||
|
import Foreign.ForeignPtr (withForeignPtr)
|
||||||
|
import Foreign.Storable
|
||||||
|
import Foreign.Marshal.Alloc
|
||||||
|
import Data.ByteString (ByteString)
|
||||||
|
import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
|
||||||
|
import Data.ByteString.Internal (create, toForeignPtr)
|
||||||
|
import Data.Word
|
||||||
|
|
||||||
|
newtype Ctx = Ctx ByteString
|
||||||
|
|
||||||
|
{- return the number of bytes of output for the digest -}
|
||||||
|
peekHashlen :: Ptr Ctx -> IO Int
|
||||||
|
peekHashlen ptr = peek iptr >>= \v -> return $! fromIntegral v
|
||||||
|
where iptr :: Ptr Word32
|
||||||
|
iptr = castPtr ptr
|
||||||
|
|
||||||
|
{-# INLINE sizeCtx #-}
|
||||||
|
sizeCtx :: Int
|
||||||
|
sizeCtx = %%SIZECTX%%
|
||||||
|
|
||||||
|
{-# INLINE withByteStringPtr #-}
|
||||||
|
withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a
|
||||||
|
withByteStringPtr b f =
|
||||||
|
withForeignPtr fptr $ \ptr -> f (ptr `plusPtr` off)
|
||||||
|
where (fptr, off, _) = toForeignPtr b
|
||||||
|
|
||||||
|
{-# INLINE memcopy64 #-}
|
||||||
|
memcopy64 :: Ptr Word64 -> Ptr Word64 -> IO ()
|
||||||
|
memcopy64 dst src = mapM_ peekAndPoke [0..(%%SIZECTX8%%-1)]
|
||||||
|
where peekAndPoke i = peekElemOff src i >>= pokeElemOff dst i
|
||||||
|
|
||||||
|
withCtxCopy :: Ctx -> (Ptr Ctx -> IO ()) -> IO Ctx
|
||||||
|
withCtxCopy (Ctx ctxB) f = Ctx `fmap` createCtx
|
||||||
|
where createCtx = create sizeCtx $ \dstPtr ->
|
||||||
|
withByteStringPtr ctxB $ \srcPtr -> do
|
||||||
|
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
|
||||||
|
f (castPtr dstPtr)
|
||||||
|
|
||||||
|
withCtxThrow :: Ctx -> (Ptr Ctx -> IO a) -> IO a
|
||||||
|
withCtxThrow (Ctx ctxB) f =
|
||||||
|
allocaBytes sizeCtx $ \dstPtr ->
|
||||||
|
withByteStringPtr ctxB $ \srcPtr -> do
|
||||||
|
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
|
||||||
|
f (castPtr dstPtr)
|
||||||
|
|
||||||
|
withCtxNew :: (Ptr Ctx -> IO ()) -> IO Ctx
|
||||||
|
withCtxNew f = Ctx `fmap` create sizeCtx (f . castPtr)
|
||||||
|
|
||||||
|
withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a
|
||||||
|
withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr)
|
||||||
|
|
||||||
|
foreign import ccall unsafe "cryptonite_%%HEADER_FILE%% cryptonite_%%HASHNAME%%_init"
|
||||||
|
c_%%HASHNAME%%_init :: Ptr Ctx -> Word32 -> IO ()
|
||||||
|
|
||||||
|
foreign import ccall "cryptonite_%%HEADER_FILE%% cryptonite_%%HASHNAME%%_update"
|
||||||
|
c_%%HASHNAME%%_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO ()
|
||||||
|
|
||||||
|
foreign import ccall unsafe "cryptonite_%%HEADER_FILE%% cryptonite_%%HASHNAME%%_finalize"
|
||||||
|
c_%%HASHNAME%%_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
|
||||||
|
|
||||||
|
internalInitAt :: Int -> Ptr Ctx -> IO ()
|
||||||
|
internalInitAt hashlen ptr = c_%%HASHNAME%%_init ptr (fromIntegral hashlen)
|
||||||
|
|
||||||
|
-- | init a context
|
||||||
|
internalInit :: Int -> IO Ctx
|
||||||
|
internalInit hashlen = withCtxNew (internalInitAt hashlen)
|
||||||
|
|
||||||
|
-- | Update a context in place
|
||||||
|
internalUpdate :: Ptr Ctx -> ByteString -> IO ()
|
||||||
|
internalUpdate ptr d =
|
||||||
|
unsafeUseAsCStringLen d (\(cs, len) -> c_%%HASHNAME%%_update ptr (castPtr cs) (fromIntegral len))
|
||||||
|
|
||||||
|
-- | Finalize a context in place
|
||||||
|
internalFinalize :: Ptr Ctx -> IO ByteString
|
||||||
|
internalFinalize ptr =
|
||||||
|
peekHashlen ptr >>= \digestSize -> create digestSize (c_%%HASHNAME%%_finalize ptr)
|
||||||
101
gen/template/hash-internal.hs
Normal file
101
gen/template/hash-internal.hs
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
{-# LANGUAGE ForeignFunctionInterface, CPP, MultiParamTypeClasses #-}
|
||||||
|
|
||||||
|
-- |
|
||||||
|
-- Module : Crypto.Hash.Internal.%%MODULENAME%%
|
||||||
|
-- License : BSD-style
|
||||||
|
-- Maintainer : Vincent Hanquez <vincent@snarc.org>
|
||||||
|
-- Stability : experimental
|
||||||
|
-- Portability : unknown
|
||||||
|
--
|
||||||
|
-- A module containing %%MODULENAME%% bindings
|
||||||
|
--
|
||||||
|
module Crypto.Hash.Internal.%%MODULENAME%%
|
||||||
|
( Ctx(..)
|
||||||
|
-- * Internal values
|
||||||
|
, digestSize
|
||||||
|
, sizeCtx
|
||||||
|
-- * Internal IO hash functions
|
||||||
|
, internalInit
|
||||||
|
, internalInitAt
|
||||||
|
, internalUpdate
|
||||||
|
, internalFinalize
|
||||||
|
-- * Context copy and creation
|
||||||
|
, withCtxCopy
|
||||||
|
, withCtxNewThrow
|
||||||
|
, withCtxThrow
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Foreign.Ptr
|
||||||
|
import Foreign.ForeignPtr (withForeignPtr)
|
||||||
|
import Foreign.Storable
|
||||||
|
import Foreign.Marshal.Alloc
|
||||||
|
import Data.ByteString (ByteString)
|
||||||
|
import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
|
||||||
|
import Data.ByteString.Internal (create, toForeignPtr)
|
||||||
|
import Data.Word
|
||||||
|
|
||||||
|
newtype Ctx = Ctx ByteString
|
||||||
|
|
||||||
|
{-# INLINE digestSize #-}
|
||||||
|
digestSize :: Int
|
||||||
|
digestSize = %%DIGESTSIZE%%
|
||||||
|
|
||||||
|
{-# INLINE sizeCtx #-}
|
||||||
|
sizeCtx :: Int
|
||||||
|
sizeCtx = %%SIZECTX%%
|
||||||
|
|
||||||
|
{-# INLINE withByteStringPtr #-}
|
||||||
|
withByteStringPtr :: ByteString -> (Ptr Word8 -> IO a) -> IO a
|
||||||
|
withByteStringPtr b f =
|
||||||
|
withForeignPtr fptr $ \ptr -> f (ptr `plusPtr` off)
|
||||||
|
where (fptr, off, _) = toForeignPtr b
|
||||||
|
|
||||||
|
{-# INLINE memcopy64 #-}
|
||||||
|
memcopy64 :: Ptr Word64 -> Ptr Word64 -> IO ()
|
||||||
|
memcopy64 dst src = mapM_ peekAndPoke [0..(%%SIZECTX8%%-1)]
|
||||||
|
where peekAndPoke i = peekElemOff src i >>= pokeElemOff dst i
|
||||||
|
|
||||||
|
withCtxCopy :: Ctx -> (Ptr Ctx -> IO ()) -> IO Ctx
|
||||||
|
withCtxCopy (Ctx ctxB) f = Ctx `fmap` createCtx
|
||||||
|
where createCtx = create sizeCtx $ \dstPtr ->
|
||||||
|
withByteStringPtr ctxB $ \srcPtr -> do
|
||||||
|
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
|
||||||
|
f (castPtr dstPtr)
|
||||||
|
|
||||||
|
withCtxThrow :: Ctx -> (Ptr Ctx -> IO a) -> IO a
|
||||||
|
withCtxThrow (Ctx ctxB) f =
|
||||||
|
allocaBytes sizeCtx $ \dstPtr ->
|
||||||
|
withByteStringPtr ctxB $ \srcPtr -> do
|
||||||
|
memcopy64 (castPtr dstPtr) (castPtr srcPtr)
|
||||||
|
f (castPtr dstPtr)
|
||||||
|
|
||||||
|
withCtxNew :: (Ptr Ctx -> IO ()) -> IO Ctx
|
||||||
|
withCtxNew f = Ctx `fmap` create sizeCtx (f . castPtr)
|
||||||
|
|
||||||
|
withCtxNewThrow :: (Ptr Ctx -> IO a) -> IO a
|
||||||
|
withCtxNewThrow f = allocaBytes sizeCtx (f . castPtr)
|
||||||
|
|
||||||
|
foreign import ccall unsafe "cryptonite_%%HEADER_FILE%% cryptonite_%%HASHNAME%%_init"
|
||||||
|
c_%%HASHNAME%%_init :: Ptr Ctx -> IO ()
|
||||||
|
|
||||||
|
foreign import ccall "cryptonite_%%HEADER_FILE%% cryptonite_%%HASHNAME%%_update"
|
||||||
|
c_%%HASHNAME%%_update :: Ptr Ctx -> Ptr Word8 -> Word32 -> IO ()
|
||||||
|
|
||||||
|
foreign import ccall unsafe "cryptonite_%%HEADER_FILE%% cryptonite_%%HASHNAME%%_finalize"
|
||||||
|
c_%%HASHNAME%%_finalize :: Ptr Ctx -> Ptr Word8 -> IO ()
|
||||||
|
|
||||||
|
internalInitAt :: Ptr Ctx -> IO ()
|
||||||
|
internalInitAt = c_%%HASHNAME%%_init
|
||||||
|
|
||||||
|
-- | init a context
|
||||||
|
internalInit :: IO Ctx
|
||||||
|
internalInit = withCtxNew internalInitAt
|
||||||
|
|
||||||
|
-- | Update a context in place
|
||||||
|
internalUpdate :: Ptr Ctx -> ByteString -> IO ()
|
||||||
|
internalUpdate ptr d =
|
||||||
|
unsafeUseAsCStringLen d (\(cs, len) -> c_%%HASHNAME%%_update ptr (castPtr cs) (fromIntegral len))
|
||||||
|
|
||||||
|
-- | Finalize a context in place
|
||||||
|
internalFinalize :: Ptr Ctx -> IO ByteString
|
||||||
|
internalFinalize ptr = create digestSize (c_%%HASHNAME%%_finalize ptr)
|
||||||
74
gen/template/hash-len.hs
Normal file
74
gen/template/hash-len.hs
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
{-# LANGUAGE ForeignFunctionInterface #-}
|
||||||
|
|
||||||
|
-- |
|
||||||
|
-- Module : Crypto.Hash.%%MODULENAME%%
|
||||||
|
-- License : BSD-style
|
||||||
|
-- Maintainer : Vincent Hanquez <vincent@snarc.org>
|
||||||
|
-- Stability : experimental
|
||||||
|
-- Portability : unknown
|
||||||
|
--
|
||||||
|
-- module containing the pure functions to work with the
|
||||||
|
-- %%MODULENAME%% cryptographic hash.
|
||||||
|
--
|
||||||
|
-- it is recommended to import this module qualified.
|
||||||
|
--
|
||||||
|
module Crypto.Hash.%%MODULENAME%%
|
||||||
|
( Ctx(..)
|
||||||
|
|
||||||
|
-- * Incremental hashing Functions
|
||||||
|
, init -- :: Int -> Ctx
|
||||||
|
, update -- :: Ctx -> ByteString -> Ctx
|
||||||
|
, updates -- :: Ctx -> [ByteString] -> Ctx
|
||||||
|
, finalize -- :: Ctx -> ByteString
|
||||||
|
|
||||||
|
-- * Single Pass hashing
|
||||||
|
, hash -- :: Int -> ByteString -> ByteString
|
||||||
|
, hashlazy -- :: Int -> ByteString -> ByteString
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Prelude hiding (init)
|
||||||
|
import qualified Data.ByteString.Lazy as L
|
||||||
|
import Data.ByteString (ByteString)
|
||||||
|
import Crypto.Hash.Internal (unsafeDoIO)
|
||||||
|
import Crypto.Hash.Internal.%%MODULENAME%%
|
||||||
|
|
||||||
|
{-# NOINLINE init #-}
|
||||||
|
-- | init a context where
|
||||||
|
init :: Int -- ^ algorithm hash size in bits
|
||||||
|
-> Ctx
|
||||||
|
init hashlen = unsafeDoIO (internalInit hashlen)
|
||||||
|
|
||||||
|
{-# NOINLINE update #-}
|
||||||
|
-- | update a context with a bytestring returning the new updated context
|
||||||
|
update :: Ctx -- ^ the context to update
|
||||||
|
-> ByteString -- ^ the data to update with
|
||||||
|
-> Ctx -- ^ the updated context
|
||||||
|
update ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> internalUpdate ptr d
|
||||||
|
|
||||||
|
{-# NOINLINE updates #-}
|
||||||
|
-- | updates a context with multiples bytestring returning the new updated context
|
||||||
|
updates :: Ctx -- ^ the context to update
|
||||||
|
-> [ByteString] -- ^ a list of data bytestring to update with
|
||||||
|
-> Ctx -- ^ the updated context
|
||||||
|
updates ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> mapM_ (internalUpdate ptr) d
|
||||||
|
|
||||||
|
{-# NOINLINE finalize #-}
|
||||||
|
-- | finalize the context into a digest bytestring
|
||||||
|
finalize :: Ctx -> ByteString
|
||||||
|
finalize ctx = unsafeDoIO $ withCtxThrow ctx internalFinalize
|
||||||
|
|
||||||
|
{-# NOINLINE hash #-}
|
||||||
|
-- | hash a strict bytestring into a digest bytestring
|
||||||
|
hash :: Int -- ^ algorithm hash size in bits
|
||||||
|
-> ByteString -- ^ the data to hash
|
||||||
|
-> ByteString -- ^ the digest output
|
||||||
|
hash hashlen d = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
|
||||||
|
internalInitAt hashlen ptr >> internalUpdate ptr d >> internalFinalize ptr
|
||||||
|
|
||||||
|
{-# NOINLINE hashlazy #-}
|
||||||
|
-- | hash a lazy bytestring into a digest bytestring
|
||||||
|
hashlazy :: Int -- ^ algorithm hash size in bits
|
||||||
|
-> L.ByteString -- ^ the data to hash as a lazy bytestring
|
||||||
|
-> ByteString -- ^ the digest output
|
||||||
|
hashlazy hashlen l = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
|
||||||
|
internalInitAt hashlen ptr >> mapM_ (internalUpdate ptr) (L.toChunks l) >> internalFinalize ptr
|
||||||
74
gen/template/hash.hs
Normal file
74
gen/template/hash.hs
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
{-# LANGUAGE ForeignFunctionInterface #-}
|
||||||
|
|
||||||
|
-- |
|
||||||
|
-- Module : Crypto.Hash.%%MODULENAME%%
|
||||||
|
-- License : BSD-style
|
||||||
|
-- Maintainer : Vincent Hanquez <vincent@snarc.org>
|
||||||
|
-- Stability : experimental
|
||||||
|
-- Portability : unknown
|
||||||
|
--
|
||||||
|
-- module containing the pure functions to work with the
|
||||||
|
-- %%MODULENAME%% cryptographic hash.
|
||||||
|
--
|
||||||
|
-- it is recommended to import this module qualified.
|
||||||
|
--
|
||||||
|
module Crypto.Hash.%%MODULENAME%%
|
||||||
|
( Ctx(..)
|
||||||
|
|
||||||
|
-- * Incremental hashing Functions
|
||||||
|
, init -- :: Ctx
|
||||||
|
, update -- :: Ctx -> ByteString -> Ctx
|
||||||
|
, updates -- :: Ctx -> [ByteString] -> Ctx
|
||||||
|
, finalize -- :: Ctx -> ByteString
|
||||||
|
|
||||||
|
-- * Single Pass hashing
|
||||||
|
, hash -- :: ByteString -> ByteString
|
||||||
|
, hashlazy -- :: ByteString -> ByteString
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Prelude hiding (init)
|
||||||
|
import qualified Data.ByteString.Lazy as L
|
||||||
|
import Data.ByteString (ByteString)
|
||||||
|
import Crypto.Hash.Internal (unsafeDoIO)
|
||||||
|
import Crypto.Hash.Internal.%%MODULENAME%%
|
||||||
|
|
||||||
|
{-# RULES "hash" forall b. finalize (update init b) = hash b #-}
|
||||||
|
{-# RULES "hash.list1" forall b. finalize (updates init [b]) = hash b #-}
|
||||||
|
{-# RULES "hashmany" forall b. finalize (foldl update init b) = hashlazy (L.fromChunks b) #-}
|
||||||
|
{-# RULES "hashlazy" forall b. finalize (foldl update init $ L.toChunks b) = hashlazy b #-}
|
||||||
|
|
||||||
|
{-# NOINLINE init #-}
|
||||||
|
-- | init a context
|
||||||
|
init :: Ctx
|
||||||
|
init = unsafeDoIO internalInit
|
||||||
|
|
||||||
|
{-# NOINLINE update #-}
|
||||||
|
-- | update a context with a bytestring returning the new updated context
|
||||||
|
update :: Ctx -- ^ the context to update
|
||||||
|
-> ByteString -- ^ the data to update with
|
||||||
|
-> Ctx -- ^ the updated context
|
||||||
|
update ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> internalUpdate ptr d
|
||||||
|
|
||||||
|
{-# NOINLINE updates #-}
|
||||||
|
-- | updates a context with multiples bytestring returning the new updated context
|
||||||
|
updates :: Ctx -- ^ the context to update
|
||||||
|
-> [ByteString] -- ^ a list of data bytestring to update with
|
||||||
|
-> Ctx -- ^ the updated context
|
||||||
|
updates ctx d = unsafeDoIO $ withCtxCopy ctx $ \ptr -> mapM_ (internalUpdate ptr) d
|
||||||
|
|
||||||
|
{-# NOINLINE finalize #-}
|
||||||
|
-- | finalize the context into a digest bytestring
|
||||||
|
finalize :: Ctx -> ByteString
|
||||||
|
finalize ctx = unsafeDoIO $ withCtxThrow ctx internalFinalize
|
||||||
|
|
||||||
|
{-# NOINLINE hash #-}
|
||||||
|
-- | hash a strict bytestring into a digest bytestring
|
||||||
|
hash :: ByteString -> ByteString
|
||||||
|
hash d = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
|
||||||
|
internalInitAt ptr >> internalUpdate ptr d >> internalFinalize ptr
|
||||||
|
|
||||||
|
{-# NOINLINE hashlazy #-}
|
||||||
|
-- | hash a lazy bytestring into a digest bytestring
|
||||||
|
hashlazy :: L.ByteString -> ByteString
|
||||||
|
hashlazy l = unsafeDoIO $ withCtxNewThrow $ \ptr -> do
|
||||||
|
internalInitAt ptr >> mapM_ (internalUpdate ptr) (L.toChunks l) >> internalFinalize ptr
|
||||||
Loading…
Reference in New Issue
Block a user