packages feed

hashes 0.2.1.1 → 0.2.2.0

raw patch · 8 files changed

+185/−142 lines, 8 filesdep +sha-validationdep +vectorPVP ok

version bump matches the API change (PVP)

Dependencies added: sha-validation, vector

API changes (from Hackage documentation)

Files

CHANGELOG.md view
@@ -1,5 +1,10 @@ # Revision history for the hashes package +## 0.2.2.0 -- 2022-08-20++*   Test suite for SHA hash functions+*   Fix openssl-3.0 support+ ## 0.2.1.1 -- 2021-10-23  *   Fixes for building with GHC-9.2
cbits/keccak.c view
@@ -26,119 +26,77 @@     printf("expected         : %s\n", expected);  finally:-    if (ctx) keccak256_freectx(ctx);+    if (ctx) EVP_MD_CTX_free(ctx);     return ! ok; } */ -#if OPENSSL_VERSION_NUMBER >= 0x30000000L /* *************************************************************************** */-/* KECCAK-256 for OpenSSL 3.0 */--extern const OSSL_DISPATCH ossl_sha3_256_functions[];-extern const OSSL_DISPATCH ossl_sha3_512_functions[];-extern int ossl_sha3_init(KECCAK1600_CTX *ctx, unsigned char pad, size_t bitlen);--typedef void (*VoidFunPtr) (void);--VoidFunPtr dispatch(const OSSL_DISPATCH *fns, int fn_id) {-    for (; fns->function_id != 0; fns++) {-        if (fns->function_id == fn_id) {-            return fns->function;-        }-    }-    return NULL;-}--VoidFunPtr dispatch256(int fn_id) {-    return dispatch(ossl_sha3_256_functions, fn_id);-}--VoidFunPtr dispatch512(int fn_id) {-    return dispatch(ossl_sha3_512_functions, fn_id);-}--KECCAK256_CTX *keccak256_newctx()-{-    KECCAK256_CTX * ctx = ((OSSL_FUNC_digest_newctx_fn *) dispatch256(OSSL_FUNC_DIGEST_NEWCTX))(NULL);--    // this has already be called once by the dispatch function. Here we update the pad character-    if (ctx) ossl_sha3_init(ctx, '\x01', 256);-    return ctx;-}--KECCAK512_CTX *keccak512_newctx()-{-    KECCAK512_CTX * ctx = ((OSSL_FUNC_digest_newctx_fn *) dispatch512(OSSL_FUNC_DIGEST_NEWCTX))(NULL);--    // this has already be called once by the dispatch function. Here we update the pad character-    if (ctx) ossl_sha3_init(ctx, '\x01', 512);-    return ctx;-}--int keccak256_init(KECCAK256_CTX *ctx) {-    return ((OSSL_FUNC_digest_init_fn *) dispatch256(OSSL_FUNC_DIGEST_INIT))(ctx, NULL);-}--int keccak512_init(KECCAK256_CTX *ctx) {-    return ((OSSL_FUNC_digest_init_fn *) dispatch512(OSSL_FUNC_DIGEST_INIT))(ctx, NULL);-}--int keccak256_update(KECCAK256_CTX *ctx, const void *p, size_t l)-{-    return ((OSSL_FUNC_digest_update_fn *) dispatch256(OSSL_FUNC_DIGEST_UPDATE))(ctx, p, l);-}--int keccak512_update(KECCAK512_CTX *ctx, const void *p, size_t l)-{-    return ((OSSL_FUNC_digest_update_fn *) dispatch512(OSSL_FUNC_DIGEST_UPDATE))(ctx, p, l);-}--int keccak256_final(KECCAK256_CTX *ctx, unsigned char *md)-{-    size_t l;-    return ((OSSL_FUNC_digest_final_fn *) dispatch256(OSSL_FUNC_DIGEST_FINAL))(ctx, md, &l, 32);-}--int keccak512_final(KECCAK512_CTX *ctx, unsigned char *md)-{-    size_t l;-    return ((OSSL_FUNC_digest_final_fn *) dispatch512(OSSL_FUNC_DIGEST_FINAL))(ctx, md, &l, 64);-}--void keccak256_freectx(KECCAK256_CTX *ctx)-{-    return ((OSSL_FUNC_digest_freectx_fn *) dispatch256(OSSL_FUNC_DIGEST_FREECTX))(ctx);-}--void keccak512_freectx(KECCAK512_CTX *ctx)-{-    return ((OSSL_FUNC_digest_freectx_fn *) dispatch512(OSSL_FUNC_DIGEST_FREECTX))(ctx);-}--#elif OPENSSL_VERSION_NUMBER >= 0x10100000L-/* *************************************************************************** */-/* OpenSSL 1.1 */+/* OpenSSL 1.1 and OpenSSL 3.0 */  /* The computation of the magic offset is base on the keccak_st structure in- * OpenSSL-1.1.+ * OpenSSL-1.1 and OpenSSL-3.0  *  * Assuming conventional alignment, the bytes offset is  *- * sizeof(uint64_t) * 40 + size_of(size_t) * 3 + (1600 / 8 - 32)+ * sizeof(uint64_t) * 25 + size_of(size_t) * 3 + (1600 / 8 - 32)  *  * On a 64bit platform this number is 392+ *+ * // struct keccak_st {+ * //     uint64_t A[5][5];+ * //     size_t block_size;+ * //     size_t md_size;+ * //     size_t bufsz;+ * //     unsigned char buf[KECCAK1600_WIDTH / 8 - 32];+ * //     unsigned char pad;+ * // };+ *+ * For OpenSSL 1.1 this context is stored in EVP_MD_CTX as data and is accessed+ * via EVP_CTX_MD_md_data().+ *+ * For OpenSSL 3.0 it is stored in EVP_MD_CTX in the algctx field. The structure+ * is a field of pointers and algctx is the 8th pointer.+ *+ * // struct evp_md_ctx_st {+ * //   const EVP_MD *reqdigest;+ * //   const EVP_MD *digest;+ * //   ENGINE *engine;+ * //   unsigned long flags;+ * //   void *md_data;+ * //   EVP_PKEY_CTX *pctx;+ * //   int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count);+ * //+ * //   // Opaque ctx returned from a providers digest algorithm implementation+ * //   // OSSL_FUNC_digest_newctx()+ * //   //+ * //   void *algctx;+ * //   EVP_MD *fetched_digest;+ * // }  */ -// struct keccak_st {-//     uint64_t A[5][5];-//     size_t block_size;          /* cached ctx->digest->block_size */-//     size_t md_size;             /* output length, variable in XOF */-//     size_t bufsz;               /* used bytes in below buffer */-//     unsigned char buf[KECCAK1600_WIDTH / 8 - 32];-//     unsigned char pad;-// };+#define PAD_BYTE_OFFSET (25 * sizeof(uint64_t) + 3 * sizeof(size_t) + 1600/8 - 32) +/* OPENSSL 3.1 */+#if OPENSSL_VERSION_NUMBER >= 0x31000000L+#define SET_PAD_BYTE ++/* OPENSSL 3.0 */+#elif OPENSSL_VERSION_NUMBER >= 0x30000000L+#define GET_CTX(ctx) (*(((uint8_t **) ctx) + 7))+#define SET_PAD_BYTE (((uint8_t *) GET_CTX(ctx))[PAD_BYTE_OFFSET] = 0x01)++/* OPENSSL 1.1 */+#elif OPENSSL_VERSION_NUMBER >= 0x10100000L+#define GET_CTX(ctx) ((uint8_t *) EVP_MD_CTX_md_data(ctx))+#define SET_PAD_BYTE (GET_CTX(ctx)[PAD_BYTE_OFFSET] = 0x01)++#endif++/* *************************************************************************** */+/* Implementation */++ KECCAK256_CTX *keccak256_newctx() {     return EVP_MD_CTX_new();@@ -152,12 +110,9 @@ int keccak256_init(KECCAK256_CTX *ctx) {     int ok = 1;     const EVP_MD *md = NULL;-    int padByteOffset = 25 * sizeof(uint64_t) + 3 * sizeof(size_t) + 1600/8 - 32;-    CHECKED(md = EVP_sha3_256());+    CHECKED(md = EVP_get_digestbyname("SHA3-256"));     CHECKED(EVP_DigestInit(ctx, md));--    // MAGIC (set padding char to 0x1)-    ((uint8_t *) EVP_MD_CTX_md_data(ctx))[padByteOffset] = 0x01;+    SET_PAD_BYTE; finally:     return ok; }@@ -165,12 +120,9 @@ int keccak512_init(KECCAK512_CTX *ctx) {     int ok = 1;     const EVP_MD *md = NULL;-    int padByteOffset = 25 * sizeof(uint64_t) + 3 * sizeof(size_t) + 1600/8 - 32;-    CHECKED(md = EVP_sha3_512());+    CHECKED(md = EVP_get_digestbyname("SHA3-512"));     CHECKED(EVP_DigestInit(ctx, md));--    // MAGIC (set padding char to 0x1)-    ((uint8_t *) EVP_MD_CTX_md_data(ctx))[padByteOffset] = 0x01;+    SET_PAD_BYTE; finally:     return ok; }@@ -206,6 +158,4 @@ {     return EVP_MD_CTX_free(ctx); }--#endif 
cbits/keccak.h view
@@ -9,20 +9,10 @@     }  /* *************************************************************************** */-/* Keccak-256 */--#if OPENSSL_VERSION_NUMBER >= 0x31000000L--#elif OPENSSL_VERSION_NUMBER >= 0x30000000L-typedef struct keccak1600_ctx_st KECCAK1600_CTX;-typedef KECCAK1600_CTX KECCAK256_CTX;-typedef KECCAK1600_CTX KECCAK512_CTX;+/* Keccak */ -#elif OPENSSL_VERSION_NUMBER >= 0x10100000L typedef EVP_MD_CTX KECCAK256_CTX; typedef EVP_MD_CTX KECCAK512_CTX;--#endif  // KECCAK-256 KECCAK256_CTX *keccak256_newctx();
hashes.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: hashes-version: 0.2.1.1+version: 0.2.2.0 synopsis: Hash functions Description: Efficient implementations of hash functions homepage: https://github.com/larskuhtz/hs-hashes@@ -12,9 +12,9 @@ copyright: Copyright (c) 2019-2021 Lars Kuhtz <lakuhtz@gmail.com> category: Data tested-with:+    GHC==9.2     GHC==9.0.1     GHC==8.10.7-    GHC==8.8.4 extra-source-files:     README.md     CHANGELOG.md@@ -51,13 +51,13 @@ common openssl-common     if flag(with-openssl)         c-sources:-            cbits/keccak.h             cbits/keccak.c         cpp-options: -DWITH_OPENSSL=1         if flag(openssl-use-pkg-config)             pkgconfig-depends: libcrypto         else-            extra-Libraries: crypto+            extra-libraries: crypto+        include-dirs: cbits  library     import: openssl-common@@ -110,6 +110,13 @@         , base >=4.11 && <5         , bytestring >=0.10         , sydtest >=0.4+        , vector >=0.12++    if flag(with-openssl)+        build-depends:+            , sha-validation >=0.1+        other-modules:+            Test.Data.Hash.SHA3      if flag(test-cryptonite)         build-depends:
src/Data/Hash/Class/Mutable.hs view
@@ -64,36 +64,36 @@  hashByteString :: forall a . Hash a => B.ByteString -> a hashByteString b = unsafeDupablePerformIO $ do-        ctx <- initialize @a-        updateByteString @a ctx b-        finalize ctx+    ctx <- initialize @a+    updateByteString @a ctx b+    finalize ctx {-# INLINE hashByteString #-}  hashByteStringLazy :: forall a . Hash a => BL.ByteString -> a hashByteStringLazy b = unsafeDupablePerformIO $ do-        ctx <- initialize @a-        updateByteStringLazy @a ctx b-        finalize ctx+    ctx <- initialize @a+    updateByteStringLazy @a ctx b+    finalize ctx {-# INLINE hashByteStringLazy #-}  hashShortByteString :: forall a . Hash a => BS.ShortByteString -> IO a hashShortByteString b = do-        ctx <- initialize @a-        updateShortByteString @a ctx b-        finalize ctx+    ctx <- initialize @a+    updateShortByteString @a ctx b+    finalize ctx {-# INLINE hashShortByteString #-}  hashStorable :: forall a b . Hash a => Storable b => b -> IO a hashStorable b = do-        ctx <- initialize @a-        updateStorable @a ctx b-        finalize ctx+    ctx <- initialize @a+    updateStorable @a ctx b+    finalize ctx {-# INLINE hashStorable #-}  hashByteArray :: forall a . Hash a => ByteArray# -> IO a hashByteArray b = do-        ctx <- initialize @a-        updateByteArray @a ctx b-        finalize ctx+    ctx <- initialize @a+    updateByteArray @a ctx b+    finalize ctx {-# INLINE hashByteArray #-} 
test/Main.hs view
@@ -15,6 +15,10 @@ import qualified Test.Data.Hash.SipHash import qualified Test.Data.Hash.Class.Pure +#if defined(WITH_OPENSSL)+import qualified Test.Data.Hash.SHA3+#endif+ #if defined(TEST_CRYPTONITE) import qualified Cryptonite #endif@@ -29,6 +33,10 @@     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++#if defined(WITH_OPENSSL)+    describe "Test.Data.Hash.SHA3" Test.Data.Hash.SHA3.tests+#endif  #if defined(TEST_CRYPTONITE)     describe "Cryptonite" Cryptonite.tests
test/Test/Data/Hash/FNV1.hs view
@@ -1,6 +1,4 @@ {-# LANGUAGE CPP #-}-{-# LANGUAGE LambdaCase #-}-{-# LANGUAGE MagicHash #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeApplications #-}
+ test/Test/Data/Hash/SHA3.hs view
@@ -0,0 +1,85 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}++-- |+-- Module: Test.Data.Hash.SHA3+-- Copyright: Copyright © 2022 Kadena LLC.+-- License: MIT+-- Maintainer: Lars Kuhtz <lars@kadena.io>+-- Stability: experimental+--+-- TODO+--+module Test.Data.Hash.SHA3+( tests+) where++import qualified Data.ByteString.Short as BS+import Data.Coerce++import Test.Syd+import Test.Hash.SHA3++-- internal modules++import Data.Hash.SHA3++-- -------------------------------------------------------------------------- --+--++tests :: Spec+tests = describe "SHA3 Test Vectors" $ do+    shortMsgTests+    longMsgTests+    monteTests++-- -------------------------------------------------------------------------- --+-- Msg Tests++shortMsgTests :: Spec+shortMsgTests = describe "ShortMsg" $ do+    describe "224" $ runMsgTest @Sha3_224 sha3_224ShortMsg+    describe "256" $ runMsgTest @Sha3_256 sha3_256ShortMsg+    describe "384" $ runMsgTest @Sha3_384 sha3_384ShortMsg+    describe "512" $ runMsgTest @Sha3_512 sha3_512ShortMsg++longMsgTests :: Spec+longMsgTests = describe "LongMsg" $ do+    describe "224" $ runMsgTest @Sha3_224 sha3_224LongMsg+    describe "256" $ runMsgTest @Sha3_256 sha3_256LongMsg+    describe "384" $ runMsgTest @Sha3_384 sha3_384LongMsg+    describe "512" $ runMsgTest @Sha3_512 sha3_512LongMsg++runMsgTest+    :: forall a+    . Hash a+    => Coercible a BS.ShortByteString+    => MsgFile+    -> Spec+runMsgTest = msgAssert+    (\l a b -> it l (a == b))+    (BS.fromShort . coerce . hashByteString @a)++-- -------------------------------------------------------------------------- --+-- Monte Tests++monteTests :: Spec+monteTests = describe "Monte" $ do+    describe "224" $ runMonteTest @Sha3_224 sha3_224Monte+    describe "256" $ runMonteTest @Sha3_256 sha3_256Monte+    describe "384" $ runMonteTest @Sha3_384 sha3_384Monte+    describe "512" $ runMonteTest @Sha3_512 sha3_512Monte++runMonteTest+    :: forall a+    . Hash a+    => Coercible a BS.ShortByteString+    => MonteFile+    -> Spec+runMonteTest = monteAssert+    (\l a b -> it l (a == b))+    (BS.fromShort . coerce . hashByteString @a)+