commit 4716cd5b4e673e9cb66e4e5e427e5464a7c10977
parent 9bbe66af958ce48c8087108eaaf209d8faa055fc
Author: Jared Tobin <jared@jtobin.io>
Date: Sat, 10 Jan 2026 11:01:29 +0400
release: v0.3.0
Diffstat:
4 files changed, 34 insertions(+), 30 deletions(-)
diff --git a/CHANGELOG b/CHANGELOG
@@ -1,5 +1,10 @@
# Changelog
+- 0.3.0 (2026-01-10)
+ * The HMAC functions now produce a value of type MAC, which is a
+ newtype over a ByteString. The 'Eq' instance for MAC compares values
+ in constant time.
+
- 0.2.5 (2026-01-08)
* We now check if the ARM cryptographic extensions are available, and,
if so, use them to calculate hashes. If they're unavailable we
diff --git a/bench/Main.hs b/bench/Main.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE OverloadedStrings #-}
module Main where
@@ -14,30 +15,30 @@ main = defaultMain [
]
suite :: Benchmark
-suite = env setup $ \ ~(bs, bl, mac0, mac1, macl0, macl1) ->
- bgroup "ppad-sha256" [
- bgroup "SHA256 (32B input)" [
- bench "hash" $ whnf SHA256.hash bs
- , bench "hash_lazy" $ whnf SHA256.hash_lazy bl
- , bench "SHA.sha256" $ whnf SHA.sha256 bl
+suite =
+ let !bs = BS.replicate 32 0
+ !bl = BL.fromStrict bs
+ !mac0 = SHA256.hmac "key" "foo"
+ !mac1 = SHA256.hmac "key" "bar"
+ !mac2 = SHA256.hmac "key" "foo"
+ !macl0 = SHA256.hmac_lazy "key" "foo"
+ !macl1 = SHA256.hmac_lazy "key" "bar"
+ !macl2 = SHA256.hmac_lazy "key" "foo"
+ in bgroup "ppad-sha256" [
+ bgroup "SHA256 (32B input)" [
+ bench "hash" $ whnf SHA256.hash bs
+ , bench "hash_lazy" $ whnf SHA256.hash_lazy bl
+ , bench "SHA.sha256" $ whnf SHA.sha256 bl
+ ]
+ , bgroup "HMAC-SHA256 (32B input)" [
+ bench "hmac" $ whnf (SHA256.hmac "key") bs
+ , bench "hmac_lazy" $ whnf (SHA256.hmac_lazy "key") bl
+ , bench "SHA.hmacSha256" $ whnf (SHA.hmacSha256 "key") bl
+ ]
+ , bgroup "MAC comparison" [
+ bench "hmac, unequal" $ whnf (mac0 ==) mac1
+ , bench "hmac, equal" $ whnf (mac0 ==) mac2
+ , bench "hmac_lazy, unequal" $ whnf (macl0 ==) macl1
+ , bench "hmac_lazy, equal" $ whnf (macl0 ==) macl2
+ ]
]
- , bgroup "HMAC-SHA256 (32B input)" [
- bench "hmac" $ whnf (SHA256.hmac "key") bs
- , bench "hmac_lazy" $ whnf (SHA256.hmac_lazy "key") bl
- , bench "SHA.hmacSha256" $ whnf (SHA.hmacSha256 "key") bl
- ]
- , bgroup "MAC comparison" [
- bench "hmac" $ nf (mac0 ==) mac1
- , bench "hmac_lazy" $ nf (macl0 ==) macl1
- ]
- ]
- where
- setup = do
- let bs_32B = BS.replicate 32 0
- bl_32B = BL.fromStrict bs_32B
- mac0 = SHA256.hmac "key" "foo"
- mac1 = SHA256.hmac "key" "bar"
- macl0 = SHA256.hmac_lazy "key" "foo"
- macl1 = SHA256.hmac_lazy "key" "bar"
- pure (bs_32B, bl_32B, mac0, mac1, macl0, macl1)
-
diff --git a/lib/Crypto/Hash/SHA256/Internal.hs b/lib/Crypto/Hash/SHA256/Internal.hs
@@ -33,7 +33,6 @@ module Crypto.Hash.SHA256.Internal (
, unsafe_padding
) where
-import Control.DeepSeq (NFData(..))
import qualified Data.Bits as B
import qualified Data.ByteString as BS
import qualified Data.ByteString.Internal as BI
@@ -59,7 +58,7 @@ import qualified GHC.Word (Word8(..))
-- >>> bs0 == bs1 -- don't do this
-- False
newtype MAC = MAC BS.ByteString
- deriving newtype (Show, NFData)
+ deriving newtype Show
instance Eq MAC where
-- | A constant-time equality check for message authentication codes.
diff --git a/ppad-sha256.cabal b/ppad-sha256.cabal
@@ -1,6 +1,6 @@
cabal-version: 3.0
name: ppad-sha256
-version: 0.2.5
+version: 0.3.0
synopsis: The SHA-256 and HMAC-SHA256 algorithms
license: MIT
license-file: LICENSE
@@ -38,7 +38,6 @@ library
build-depends:
base >= 4.9 && < 5
, bytestring >= 0.9 && < 0.13
- , deepseq >= 1.4 && < 1.6
c-sources:
cbits/sha256_arm.c
if arch(aarch64)