hashes 0.3.0 → 0.3.0.1
raw patch · 13 files changed
+101/−53 lines, 13 filesdep +hspecdep −sydtestPVP ok
version bump matches the API change (PVP)
Dependencies added: hspec
Dependencies removed: sydtest
API changes (from Hackage documentation)
Files
- CHANGELOG.md +9/−0
- cbits/keccak.c +1/−1
- cbits/keccak.h +1/−1
- hashes.cabal +9/−4
- src/Data/Hash/Internal/OpenSSL.hs +66/−34
- test/Cryptonite.hs +2/−1
- test/Main.hs +3/−3
- test/Test/Data/Hash/Class/Pure.hs +2/−1
- test/Test/Data/Hash/FNV1.hs +1/−1
- test/Test/Data/Hash/Keccak.hs +3/−3
- test/Test/Data/Hash/SHA2.hs +1/−1
- test/Test/Data/Hash/SHA3.hs +2/−2
- test/Test/Data/Hash/SipHash.hs +1/−1
CHANGELOG.md view
@@ -1,5 +1,14 @@ # Revision history for the hashes package +## 0.3.0.1 -- 2024-08-20++* Fix building the package on Gentoo.++Internal Changes:++* Replace the Syd test framework by hspec.+* Modernize the FFI interface with OpenSSL.+ ## 0.3.0 -- 2024-07-12 Breaking Changes:
cbits/keccak.c view
@@ -100,7 +100,7 @@ /* Implementation */ #if OPENSSL_VERSION_NUMBER < 0x30200000L-int keccak_EVP_DigestInit_ex(EVP_MD_CTX *ctx, EVP_MD *md) {+int keccak_EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *md) { int ok = 1; CHECKED(EVP_DigestInit_ex(ctx, md, NULL)); SET_PAD_BYTE;
cbits/keccak.h view
@@ -22,5 +22,5 @@ */ #if OPENSSL_VERSION_NUMBER < 0x30200000L-int keccak_EVP_DigestInit_ex(EVP_MD_CTX *ctx, EVP_MD *md);+int keccak_EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *md); #endif
hashes.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: hashes-version: 0.3.0+version: 0.3.0.1 synopsis: Hash functions Description: Efficient implementations of hash functions homepage: https://github.com/larskuhtz/hs-hashes@@ -75,6 +75,12 @@ Data.Hash.FNV1.Salted Data.Hash.Internal.Utils Data.Hash.SipHash+ -- this allows us to #include <opensslv.h> on Gentoo+ -- from a Haskell file+ if arch(x86_64)+ cpp-options: -D__x86_64__+ if arch(aarch64)+ cpp-options: -D__aarch64__ if flag(with-openssl) exposed-modules: Data.Hash.Blake2@@ -107,10 +113,10 @@ -- internal , hashes -- external- , QuickCheck >= 2.13+ , QuickCheck >=2.13 , base >=4.11 && <5 , bytestring >=0.10- , sydtest >=0.4+ , hspec >=2.11 , vector >=0.12 if flag(with-openssl)@@ -155,4 +161,3 @@ , memory >=0.14 , cryptonite >=0.29 cpp-options: -DBENCHMARK_CRYPTONITE=1-
src/Data/Hash/Internal/OpenSSL.hs view
@@ -13,6 +13,10 @@ {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} +#if !MIN_VERSION_base(4,18,0)+{-# LANGUAGE PatternSynonyms #-}+#endif+ #include <openssl/opensslv.h> -- |@@ -98,7 +102,13 @@ import Data.Void import Data.Word -import Foreign.C.String (CString, withCString)+#if MIN_VERSION_base(4,18,0)+import Foreign.C.ConstPtr (ConstPtr(..))+import Foreign.C.String (withCString)+#else+import Foreign.C.String(CString, withCString)+#endif+import Foreign.C.Types import Foreign.ForeignPtr import Foreign.Marshal import Foreign.Ptr@@ -141,6 +151,28 @@ instance Exception OpenSslException -- -------------------------------------------------------------------------- --+-- Utils for ConstPtr++#if MIN_VERSION_base(4,18,0)+type ConstCString = ConstPtr CChar+#else+type ConstPtr a = Ptr a+type ConstCString = CString++pattern ConstPtr :: forall p. p -> p+pattern ConstPtr a = a+#endif++withConstCString :: String -> (ConstCString -> IO a) -> IO a+withConstCString str inner = withCString str $ \cstr -> inner (ConstPtr cstr)++constPtr :: Addr# -> ConstPtr a+constPtr a = ConstPtr (Ptr a)++nullConstPtr :: ConstPtr a+nullConstPtr = ConstPtr nullPtr++-- -------------------------------------------------------------------------- -- -- OpenSSL Message Digest Algorithms -- | An algorithm implementation from an OpenSSL algorithm provider.@@ -172,7 +204,7 @@ -- identifier, and the search criteria. -- foreign import ccall unsafe "openssl/evp.h EVP_MD_fetch"- c_evp_md_fetch :: Ptr Void {- nullPtr -} -> CString -> CString -> IO (Ptr a)+ c_evp_md_fetch :: Ptr Void {- nullPtr -} -> ConstCString -> ConstCString -> IO (Ptr a) foreign import ccall unsafe "openssl/evp.h &EVP_MD_free" c_evp_md_free :: FunPtr (Ptr a -> IO ())@@ -187,14 +219,14 @@ -- fetchAlgorithm :: String -> IO (Algorithm a) fetchAlgorithm name = do- withCString name $ \namePtr -> mask_ $ do- ptr <- c_evp_md_fetch nullPtr namePtr (Ptr "provider=default"#)+ withConstCString name $ \namePtr -> mask_ $ do+ ptr <- c_evp_md_fetch nullPtr namePtr (constPtr "provider=default"#) when (ptr == nullPtr) $ throw $ OpenSslException $ "fetching algorithm failed: " <> name Algorithm <$> newForeignPtr c_evp_md_free ptr #else foreign import ccall unsafe "openssl/evp.h EVP_get_digestbyname"- c_EVP_get_digestbyname :: CString -> IO (Ptr a)+ c_EVP_get_digestbyname :: ConstCString -> IO (ConstPtr a) -- | Look up the 'Algorithm' with given identifier. This is a less efficient -- legacy way to obtain algorithm implementations. The returned algorithms@@ -205,8 +237,8 @@ -- fetchAlgorithm :: String -> IO (Algorithm a) fetchAlgorithm name = do- withCString name $ \namePtr -> mask_ $ do- ptr <- c_EVP_get_digestbyname namePtr+ withConstCString name $ \namePtr -> mask_ $ do+ ConstPtr ptr <- c_EVP_get_digestbyname namePtr when (ptr == nullPtr) $ throw $ OpenSslException $ "fetching algorithm failed: " <> name Algorithm <$> newForeignPtr_ ptr #endif@@ -240,27 +272,27 @@ #else foreign import ccall unsafe "openssl/evp.h EVP_DigestInit_ex" #endif- c_evp_digest_init :: Ptr ctx -> Ptr alg -> Ptr Void {- nullPtr -} -> IO Bool+ c_evp_digest_init :: Ptr ctx -> ConstPtr alg -> Ptr Void {- nullPtr -} -> IO CInt foreign import ccall unsafe "openssl/evp.h EVP_DigestUpdate"- c_evp_digest_update :: Ptr ctx -> Ptr d -> Int -> IO Bool+ c_evp_digest_update :: Ptr ctx -> ConstPtr d -> CSize -> IO CInt foreign import ccall unsafe "openssl/evp.h EVP_DigestFinal_ex"- c_evp_digest_final :: Ptr ctx -> Ptr d -> Ptr Int -> IO Bool+ c_evp_digest_final :: Ptr ctx -> Ptr CUChar -> Ptr CUInt -> IO CInt #if OPENSSL_VERSION_NUMBER >= 0x30000000L foreign import ccall unsafe "openssl/evp.h EVP_MD_CTX_get0_md" #else foreign import ccall unsafe "openssl/evp.h EVP_MD_CTX_md" #endif- c_evp_md_ctx_get0_md :: Ptr ctx -> Ptr a+ c_evp_md_ctx_get0_md :: ConstPtr ctx -> ConstPtr a #if OPENSSL_VERSION_NUMBER >= 0x30000000L foreign import ccall unsafe "openssl/evp.h EVP_MD_get_size" #else foreign import ccall unsafe "openssl/evp.h EVP_MD_size" #endif- c_evp_md_get_size :: Ptr a -> Int+ c_evp_md_get_size :: ConstPtr a -> CInt newCtx :: IO (Ctx a) newCtx = mask_ $ do@@ -277,8 +309,8 @@ c@(Ctx ctx) <- newCtx r <- withForeignPtr ctx $ \ctxPtr -> withForeignPtr alg $ \algPtr ->- c_evp_digest_init ctxPtr algPtr nullPtr- unless r $ throw $ OpenSslException "digest initialization failed"+ c_evp_digest_init ctxPtr (ConstPtr algPtr) nullPtr+ when (r == 0) $ throw $ OpenSslException "digest initialization failed" return c {-# INLINE initCtx #-} @@ -287,27 +319,27 @@ resetCtx :: Ctx a -> IO () resetCtx (Ctx ctx) = do r <- withForeignPtr ctx $ \ptr ->- c_evp_digest_init ptr nullPtr nullPtr- unless r $ throw $ OpenSslException "digest re-initialization failed"+ c_evp_digest_init ptr nullConstPtr nullPtr+ when (r == 0) $ throw $ OpenSslException "digest re-initialization failed" {-# INLINE resetCtx #-} -- | Feed more data into an context. -- updateCtx :: Ctx a -> Ptr Word8 -> Int -> IO () updateCtx (Ctx ctx) d c = withForeignPtr ctx $ \ptr -> do- r <- c_evp_digest_update ptr d c- unless r $ throw $ OpenSslException "digest update failed"+ r <- c_evp_digest_update ptr (ConstPtr d) (fromIntegral c)+ when (r == 0) $ throw $ OpenSslException "digest update failed" {-# INLINE updateCtx #-} -- | Finalize a hash and return the digest. -- finalCtx :: Ctx a -> IO (Digest a) finalCtx (Ctx ctx) = withForeignPtr ctx $ \ptr -> do- let s = c_evp_md_get_size (c_evp_md_ctx_get0_md ptr)+ let s = fromIntegral $ c_evp_md_get_size (c_evp_md_ctx_get0_md (ConstPtr ptr)) allocaBytes s $ \dptr -> do r <- c_evp_digest_final ptr dptr nullPtr- unless r $ throw $ OpenSslException "digest finalization failed"- Digest <$> BS.packCStringLen (dptr, s)+ when (r == 0) $ throw $ OpenSslException "digest finalization failed"+ Digest <$> BS.packCStringLen (castPtr dptr, s) {-# INLINE finalCtx #-} -- -------------------------------------------------------------------------- --@@ -337,16 +369,16 @@ deriving (Show, IsString) via B16ShortByteString foreign import ccall unsafe "openssl/evp.h EVP_DigestFinalXOF"- c_EVP_DigestFinalXOF :: Ptr ctx -> Ptr d -> Int -> IO Bool+ c_EVP_DigestFinalXOF :: Ptr ctx -> Ptr CUChar -> CSize -> IO CInt -- | Finalize an XOF based hash and return the digest. -- xof_finalCtx :: forall n a . KnownNat n => Ctx a -> IO (XOF_Digest n a) xof_finalCtx (Ctx ctx) = withForeignPtr ctx $ \ptr -> do allocaBytes s $ \dptr -> do- r <- c_EVP_DigestFinalXOF ptr dptr s- unless r $ throw $ OpenSslException "digest finalization failed"- XOF_Digest <$> BS.packCStringLen (dptr, s)+ r <- c_EVP_DigestFinalXOF ptr dptr (fromIntegral s)+ when (r == 0) $ throw $ OpenSslException "digest finalization failed"+ XOF_Digest <$> BS.packCStringLen (castPtr dptr, s) where s = fromIntegral $ natVal' @n proxy# {-# INLINE xof_finalCtx #-}@@ -368,23 +400,23 @@ deriving (Show, IsString) via B16ShortByteString foreign import ccall unsafe "keccak.h keccak_EVP_DigestInit_ex"- c_keccak_EVP_DigestInit_ex :: Ptr ctx -> Ptr a -> IO Bool+ c_keccak_EVP_DigestInit_ex :: Ptr ctx -> ConstPtr a -> IO CInt legacyKeccak_initCtx :: Algorithm a -> IO (Ctx a) legacyKeccak_initCtx (Algorithm alg) = do c@(Ctx ctx) <- newCtx r <- withForeignPtr ctx $ \ctxPtr -> withForeignPtr alg $ \algPtr ->- c_keccak_EVP_DigestInit_ex ctxPtr algPtr- unless r $ throw $ OpenSslException "digest initialization failed"+ c_keccak_EVP_DigestInit_ex ctxPtr (ConstPtr algPtr)+ when (r == 0) $ throw $ OpenSslException "digest initialization failed" return c {-# INLINE legacyKeccak_initCtx #-} legacyKeccak_resetCtx :: Ctx a -> IO () legacyKeccak_resetCtx (Ctx ctx) = do r <- withForeignPtr ctx $ \ptr ->- c_keccak_EVP_DigestInit_ex ptr nullPtr- unless r $ throw $ OpenSslException "digest re-initialization failed"+ c_keccak_EVP_DigestInit_ex ptr nullConstPtr+ when (r == 0) $ throw $ OpenSslException "digest re-initialization failed" {-# INLINE legacyKeccak_resetCtx #-} instance OpenSslDigest a => Hash (LegacyKeccak_Digest a) where@@ -641,8 +673,8 @@ finalizeKeccak256Ptr :: Ctx Keccak256 -> Ptr Word8 -> IO () finalizeKeccak256Ptr (Ctx ctx) dptr = withForeignPtr ctx $ \cptr -> do- r <- c_evp_digest_final cptr dptr nullPtr- unless r $ throw $ OpenSslException "digest finalization failed"+ r <- c_evp_digest_final cptr (castPtr dptr) nullPtr+ when (r == 0) $ throw $ OpenSslException "digest finalization failed" {-# INLINE finalizeKeccak256Ptr #-} -- | Low-Level function that writes the final digest directly into the provided@@ -653,8 +685,8 @@ finalizeKeccak512Ptr :: Ctx Keccak512 -> Ptr Word8 -> IO () finalizeKeccak512Ptr (Ctx ctx) dptr = do withForeignPtr ctx $ \cptr -> do- r <- c_evp_digest_final cptr dptr nullPtr- unless r $ throw $ OpenSslException "digest finalization failed"+ r <- c_evp_digest_final cptr (castPtr dptr) nullPtr+ when (r == 0) $ throw $ OpenSslException "digest finalization failed" {-# INLINE finalizeKeccak512Ptr #-} -- -------------------------------------------------------------------------- --
test/Cryptonite.hs view
@@ -34,8 +34,9 @@ import qualified Data.ByteString as B import Data.Word +import Test.Hspec+import Test.Hspec.QuickCheck import Test.QuickCheck-import Test.Syd -- internal modules
test/Main.hs view
@@ -25,13 +25,13 @@ import qualified Cryptonite #endif -import Test.Syd+import Test.Hspec main :: IO ()-main = sydTest tests+main = hspec tests tests :: Spec-tests = do+tests = parallel $ do describe "Test.Data.Hash.FNV1.tests" Test.Data.Hash.FNV1.tests describe "Test.Data.Hash.SipHash.tests" Test.Data.Hash.SipHash.tests describe "Test.Data.Hash.Class.Pure" Test.Data.Hash.Class.Pure.tests
test/Test/Data/Hash/Class/Pure.hs view
@@ -32,8 +32,9 @@ import GHC.IO import GHC.Word +import Test.Hspec+import Test.Hspec.QuickCheck import Test.QuickCheck-import Test.Syd -- internal modules
test/Test/Data/Hash/FNV1.hs view
@@ -24,7 +24,7 @@ import System.IO.Unsafe -import Test.Syd+import Test.Hspec -- internal modules
test/Test/Data/Hash/Keccak.hs view
@@ -22,8 +22,8 @@ import Data.Coerce import Data.String +import Test.Hspec import Test.QuickCheck-import Test.Syd -- internal modules @@ -97,7 +97,7 @@ => Coercible a B16ShortByteString => B16ShortByteString -> a- -> TestDefM '[] () ()+ -> Spec succeed a b = do it (show a) $ shouldBe (hashShortByteString_ @a $ coerce a) b @@ -109,7 +109,7 @@ => Coercible a B16ShortByteString => B16ShortByteString -> a- -> TestDefM '[] () ()+ -> Spec failTest a b = do it (show a) $ shouldNotBe (hashShortByteString_ @a $ coerce a) b
test/Test/Data/Hash/SHA2.hs view
@@ -26,7 +26,7 @@ import qualified Data.ByteString.Short as BS import Data.Coerce -import Test.Syd+import Test.Hspec import Test.Hash.SHA -- internal modules
test/Test/Data/Hash/SHA3.hs view
@@ -27,7 +27,7 @@ import qualified Data.ByteString.Short as BS import Data.Coerce -import Test.Syd+import Test.Hspec import Test.Hash.SHA3 -- internal modules@@ -65,7 +65,7 @@ => Coercible a B16ShortByteString => String -> a- -> TestDefM '[] () ()+ -> Spec go l b = do it l $ shouldBe (hashShortByteString_ @a "") b
test/Test/Data/Hash/SipHash.hs view
@@ -22,7 +22,7 @@ import System.IO.Unsafe -import Test.Syd+import Test.Hspec -- internal modules