hashes 0.2.0.0 → 0.2.1.0
raw patch · 8 files changed
+154/−14 lines, 8 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Data.Hash.Internal.OpenSSL: Keccak512 :: ShortByteString -> Keccak512
+ Data.Hash.Internal.OpenSSL: instance Data.Hash.Class.Mutable.Hash Data.Hash.Internal.OpenSSL.Keccak512
+ Data.Hash.Internal.OpenSSL: instance Data.Hash.Class.Mutable.Internal.IncrementalHash Data.Hash.Internal.OpenSSL.Keccak512
+ Data.Hash.Internal.OpenSSL: instance GHC.Classes.Eq Data.Hash.Internal.OpenSSL.Keccak512
+ Data.Hash.Internal.OpenSSL: instance GHC.Classes.Ord Data.Hash.Internal.OpenSSL.Keccak512
+ Data.Hash.Internal.OpenSSL: instance GHC.Show.Show Data.Hash.Internal.OpenSSL.Keccak512
+ Data.Hash.Internal.OpenSSL: newtype Keccak512
+ Data.Hash.Keccak: Keccak512 :: ShortByteString -> Keccak512
+ Data.Hash.Keccak: newtype Keccak512
Files
- CHANGELOG.md +4/−0
- README.md +5/−1
- cbits/keccak.c +78/−12
- cbits/keccak.h +10/−0
- hashes.cabal +1/−1
- src/Data/Hash/Internal/OpenSSL.hs +54/−0
- src/Data/Hash/Keccak.hs +1/−0
- test/Cryptonite.hs +1/−0
CHANGELOG.md view
@@ -1,5 +1,9 @@ # Revision history for the hashes package +## 0.2.1.0 -- 2021-10-22++* Add OpenSSL based implementation of Keccak-512.+ ## 0.2.0.0 -- 2021-10-20 Breaking changes:
README.md view
@@ -37,5 +37,9 @@ * BLAKE2 * BLAKE2s256 * BLAKE2b512-* KECCAK-256 (cf. comment in [Data.Hash.Keccak](https://github.com/larskuhtz/hs-hashes/blob/main/src/Data/Hash/Keccak.hs))+* KECCAK+ * KECCAK-256+ * KECCAK-512+ See comment in [Data.Hash.Keccak](https://github.com/larskuhtz/hs-hashes/blob/main/src/Data/Hash/Keccak.hs) before using these Keccak implementations.+
cbits/keccak.c view
@@ -35,16 +35,13 @@ /* *************************************************************************** */ /* KECCAK-256 for OpenSSL 3.0 */ -typedef struct keccak1600_ctx_st KECCAK1600_CTX;-typedef KECCAK1600_CTX KECCAK256_CTX;- 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(int fn_id) {- const OSSL_DISPATCH *fns = ossl_sha3_256_functions;+VoidFunPtr dispatch(const OSSL_DISPATCH *fns, int fn_id) { for (; fns->function_id != 0; fns++) { if (fns->function_id == fn_id) { return fns->function;@@ -53,35 +50,72 @@ 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 *) dispatch(OSSL_FUNC_DIGEST_NEWCTX))(NULL);+ 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 *) dispatch(OSSL_FUNC_DIGEST_INIT))(ctx, NULL);+ 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 *) dispatch(OSSL_FUNC_DIGEST_UPDATE))(ctx, p, 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 *) dispatch(OSSL_FUNC_DIGEST_FINAL))(ctx, md, &l, 32);+ 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 *) dispatch(OSSL_FUNC_DIGEST_FREECTX))(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 */@@ -105,13 +139,16 @@ // unsigned char pad; // }; -typedef EVP_MD_CTX KECCAK256_CTX;- KECCAK256_CTX *keccak256_newctx() { return EVP_MD_CTX_new(); } +KECCAK512_CTX *keccak512_newctx()+{+ return EVP_MD_CTX_new();+}+ int keccak256_init(KECCAK256_CTX *ctx) { int ok = 1; const EVP_MD *md = NULL;@@ -125,18 +162,47 @@ return ok; } +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(EVP_DigestInit(ctx, md));++ // MAGIC (set padding char to 0x1)+ ((uint8_t *) EVP_MD_CTX_md_data(ctx))[padByteOffset] = 0x01;+finally:+ return ok;+}+ int keccak256_update(KECCAK256_CTX *ctx, const void *p, size_t l) { return EVP_DigestUpdate(ctx, p, l); } +int keccak512_update(KECCAK512_CTX *ctx, const void *p, size_t l)+{+ return EVP_DigestUpdate(ctx, p, l);+}+ int keccak256_final(KECCAK256_CTX *ctx, unsigned char *md) { unsigned int l; return EVP_DigestFinal(ctx, md, &l); } +int keccak512_final(KECCAK512_CTX *ctx, unsigned char *md)+{+ unsigned int l;+ return EVP_DigestFinal(ctx, md, &l);+}+ void keccak256_freectx(KECCAK256_CTX *ctx)+{+ return EVP_MD_CTX_free(ctx);+}++void keccak512_freectx(KECCAK512_CTX *ctx) { return EVP_MD_CTX_free(ctx); }
cbits/keccak.h view
@@ -16,15 +16,25 @@ #elif OPENSSL_VERSION_NUMBER >= 0x30000000L typedef struct keccak1600_ctx_st KECCAK1600_CTX; typedef KECCAK1600_CTX KECCAK256_CTX;+typedef KECCAK1600_CTX KECCAK512_CTX; #elif OPENSSL_VERSION_NUMBER >= 0x10100000L typedef EVP_MD_CTX KECCAK256_CTX;+typedef EVP_MD_CTX KECCAK512_CTX; #endif +// KECCAK-256 KECCAK256_CTX *keccak256_newctx(); int keccak256_init(KECCAK256_CTX *ctx); int keccak256_update(KECCAK256_CTX *ctx, const void *p, size_t l); int keccak256_final(KECCAK256_CTX *ctx, unsigned char *md); void keccak256_freectx(KECCAK256_CTX *ctx);++// KECCAK-512+KECCAK512_CTX *keccak512_newctx();+int keccak512_init(KECCAK512_CTX *ctx);+int keccak512_update(KECCAK512_CTX *ctx, const void *p, size_t l);+int keccak512_final(KECCAK512_CTX *ctx, unsigned char *md);+void keccak512_freectx(KECCAK512_CTX *ctx);
hashes.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: hashes-version: 0.2.0.0+version: 0.2.1.0 synopsis: Hash functions Description: Efficient implementations of hash functions homepage: https://github.com/larskuhtz/hs-hashes
src/Data/Hash/Internal/OpenSSL.hs view
@@ -65,6 +65,7 @@ -- $keccak , Keccak256(..)+, Keccak512(..) -- ** Blake2 --@@ -365,6 +366,8 @@ -- -- For details see the file cbits/keccak.c. +-- KECCAK-256+ newtype Keccak256 = Keccak256 BS.ShortByteString deriving (Eq, Ord) deriving (Show) via B16ShortByteString@@ -410,6 +413,57 @@ Ctx ctx <- newKeccak256Ctx r <- withForeignPtr ctx $ \ptr -> c_keccak256_init ptr+ unless r $ throw $ OpenSslException "digest initialization failed"+ return $ Ctx ctx+ {-# INLINE initialize #-}++-- KECCAK-512++newtype Keccak512 = Keccak512 BS.ShortByteString+ deriving (Eq, Ord)+ deriving (Show) via B16ShortByteString++foreign import ccall unsafe "keccak.h keccak512_newctx"+ c_keccak512_newctx :: IO (Ptr ctx)++foreign import ccall unsafe "keccak.h keccak512_init"+ c_keccak512_init :: Ptr ctx -> IO Bool++foreign import ccall unsafe "keccak.h keccak512_update"+ c_keccak512_update :: Ptr ctx -> Ptr Word8 -> Int -> IO Bool++foreign import ccall unsafe "keccak.h keccak512_final"+ c_keccak512_final :: Ptr ctx -> Ptr Word8 -> IO Bool++foreign import ccall unsafe "keccak.h &keccak512_freectx"+ c_keccak512_freectx_ptr :: FunPtr (Ptr ctx -> IO ())++instance IncrementalHash Keccak512 where+ type Context Keccak512 = Ctx Keccak512+ update (Ctx ctx) ptr n = withForeignPtr ctx $ \cptr -> do+ r <- c_keccak512_update cptr ptr n+ unless r $ throw $ OpenSslException "digest update failed"+ finalize (Ctx ctx) = withForeignPtr ctx $ \cptr -> do+ allocaBytes 64 $ \dptr -> do+ r <- c_keccak512_final cptr dptr+ unless r $ throw $ OpenSslException "digest finalization failed"+ Keccak512 <$> BS.packCStringLen (castPtr dptr, 64)+ {-# INLINE update #-}+ {-# INLINE finalize #-}+++newKeccak512Ctx :: IO (Ctx Keccak512)+newKeccak512Ctx = fmap Ctx $ mask_ $ do+ ptr <- c_keccak512_newctx+ when (ptr == nullPtr) $ throw $ OpenSslException "failed to initialize context"+ newForeignPtr c_keccak512_freectx_ptr ptr+{-# INLINE newKeccak512Ctx #-}++instance Hash Keccak512 where+ initialize = do+ Ctx ctx <- newKeccak512Ctx+ r <- withForeignPtr ctx $ \ptr ->+ c_keccak512_init ptr unless r $ throw $ OpenSslException "digest initialization failed" return $ Ctx ctx {-# INLINE initialize #-}
src/Data/Hash/Keccak.hs view
@@ -31,6 +31,7 @@ -- This version of Keccak-256 is used by the Ethereum project. Keccak256(..)+, Keccak512(..) , module Data.Hash.Class.Mutable ) where
test/Cryptonite.hs view
@@ -161,6 +161,7 @@ , ("Blake2s256", property $ prop_eq @Blake2s256 @C.Blake2s_256) , ("Blake2b512", property $ prop_eq @Blake2b512 @C.Blake2b_512) , ("Keccak256", property $ prop_eq @Keccak256 @C.Keccak_256)+ , ("Keccak512", property $ prop_eq @Keccak512 @C.Keccak_512) #endif ]