commit 47b445a1684f93a6822f416f02aba19c3d229cc7
parent 3c329bb29be708da78c8c3940bf4ef19e7e1747a
Author: Jared Tobin <jared@jtobin.io>
Date: Sat, 10 Jan 2026 16:12:26 +0400
lib: handle new MAC types
.. that, for ergonomic reasons, I'm sort of regretting.
Diffstat:
4 files changed, 38 insertions(+), 20 deletions(-)
diff --git a/bench/Main.hs b/bench/Main.hs
@@ -8,11 +8,20 @@ import Criterion.Main
import qualified Crypto.DRBG.HMAC as DRBG
import qualified Crypto.Hash.SHA256 as SHA256
import qualified Crypto.Hash.SHA512 as SHA512
+import qualified Data.ByteString as BS
+
+hmac_sha256 :: BS.ByteString -> BS.ByteString -> BS.ByteString
+hmac_sha256 k b = case SHA256.hmac k b of
+ SHA256.MAC m -> m
+
+hmac_sha512 :: BS.ByteString -> BS.ByteString -> BS.ByteString
+hmac_sha512 k b = case SHA512.hmac k b of
+ SHA512.MAC m -> m
main :: IO ()
main = do
- !drbg256 <- DRBG.new SHA256.hmac mempty mempty mempty -- no NFData
- !drbg512 <- DRBG.new SHA512.hmac mempty mempty mempty -- no NFData
+ !drbg256 <- DRBG.new hmac_sha256 mempty mempty mempty -- no NFData
+ !drbg512 <- DRBG.new hmac_sha512 mempty mempty mempty -- no NFData
defaultMain [
suite drbg256 drbg512
]
@@ -20,13 +29,13 @@ main = do
suite drbg256 drbg512 =
bgroup "ppad-hmac-drbg" [
bgroup "HMAC-SHA256" [
- bench "new" $ whnfAppIO (DRBG.new SHA256.hmac mempty mempty) mempty
+ bench "new" $ whnfAppIO (DRBG.new hmac_sha256 mempty mempty) mempty
, bench "reseed" $ whnfAppIO (DRBG.reseed mempty mempty) drbg256
, bench "gen (32B)" $ whnfAppIO (DRBG.gen mempty 32) drbg256
, bench "gen (256B)" $ whnfAppIO (DRBG.gen mempty 256) drbg256
]
, bgroup "HMAC-SHA512" [
- bench "new" $ whnfAppIO (DRBG.new SHA512.hmac mempty mempty) mempty
+ bench "new" $ whnfAppIO (DRBG.new hmac_sha512 mempty mempty) mempty
, bench "reseed" $ whnfAppIO (DRBG.reseed mempty mempty) drbg512
, bench "gen (32B)" $ whnfAppIO (DRBG.gen mempty 32) drbg512
, bench "gen (256B)" $ whnfAppIO (DRBG.gen mempty 256) drbg512
diff --git a/flake.lock b/flake.lock
@@ -105,11 +105,11 @@
]
},
"locked": {
- "lastModified": 1767897559,
- "narHash": "sha256-UabcPqE4O+h1HHv02LjanjuorRS91OODqk0ek55VrmQ=",
+ "lastModified": 1768045644,
+ "narHash": "sha256-8+jLaYRN8iX6NmyotE7DvjfjUIT8I0KOchgcP7uq7Vo=",
"ref": "master",
- "rev": "528d9cf07ca756fb5422cab174849fe0708620d0",
- "revCount": 111,
+ "rev": "4716cd5b4e673e9cb66e4e5e427e5464a7c10977",
+ "revCount": 116,
"type": "git",
"url": "git://git.ppad.tech/sha256.git"
},
@@ -139,11 +139,11 @@
]
},
"locked": {
- "lastModified": 1767897585,
- "narHash": "sha256-QxLlHu8+tGKZ9aOKFnVOqNwEn+LCuNF27kY2dxOCYxo=",
+ "lastModified": 1768045869,
+ "narHash": "sha256-ySqv5fQRz+/9X54yXCuck2QnGyuIqRLpRzanh+Ehl88=",
"ref": "master",
- "rev": "428e2e09c345a0cb255d9aab432606308872c014",
- "revCount": 38,
+ "rev": "0fbaba3c091692622744d30016e36ca6b726a819",
+ "revCount": 42,
"type": "git",
"url": "git://git.ppad.tech/sha512.git"
},
diff --git a/lib/Crypto/DRBG/HMAC.hs b/lib/Crypto/DRBG/HMAC.hs
@@ -69,8 +69,7 @@ _RESEED_COUNTER = (2 :: Word64) ^ (48 :: Word64)
-- Create a DRBG with 'new', and then use and reuse it to generate
-- bytes as needed.
--
--- >>> import qualified Crypto.Hash.SHA256 as SHA256
--- >>> drbg <- new SHA256.hmac entropy nonce personalization_string
+-- >>> drbg <- new hmac entropy nonce personalization_string
-- >>> bytes0 <- gen addl_bytes 16 drbg
-- >>> bytes1 <- gen addl_bytes 16 drbg
-- >>> drbg
@@ -94,8 +93,9 @@ data DRBGState = DRBGState
-- value as the second, producing a MAC digest.
--
-- >>> import qualified Crypto.Hash.SHA256 as SHA256
--- >>> :t SHA256.hmac
--- SHA256.hmac :: BS.ByteString -> BS.ByteString -> BS.ByteString
+-- >>> let hmac k b = let SHA256.MAC m = SHA256.hmac k b in m
+-- >>> :t hmac
+-- hmac :: BS.ByteString -> BS.ByteString -> BS.ByteString
type HMAC = BS.ByteString -> BS.ByteString -> BS.ByteString
-- HMAC function and its associated outlength
@@ -133,7 +133,8 @@ _read_k (DRBG mut) = do
-- The DRBG is returned in any 'PrimMonad', e.g. 'ST' or 'IO'.
--
-- >>> import qualified Crypto.Hash.SHA256 as SHA256
--- >>> new SHA256.hmac entropy nonce personalization_string
+-- >>> let hmac k b = let SHA256.MAC m = SHA256.hmac k b in m
+-- >>> new hmac entropy nonce personalization_string
-- "<drbg>"
new
:: PrimMonad m
@@ -155,7 +156,7 @@ new hmac entropy nonce ps = do
-- 'MaxBytesExceeded'.
--
-- >>> import qualified Data.ByteString.Base16 as B16
--- >>> drbg <- new SHA256.hmac entropy nonce personalization_string
+-- >>> drbg <- new hmac entropy nonce personalization_string
-- >>> Right bytes0 <- gen addl_bytes 16 drbg
-- >>> Right bytes1 <- gen addl_bytes 16 drbg
-- >>> B16.encode bytes0
diff --git a/test/Main.hs b/test/Main.hs
@@ -37,10 +37,18 @@ main = do
defaultMain (cavp_14_3 sha256_cases sha512_cases)
+hmac_sha256 :: BS.ByteString -> BS.ByteString -> BS.ByteString
+hmac_sha256 k b = case SHA256.hmac k b of
+ SHA256.MAC m -> m
+
+hmac_sha512 :: BS.ByteString -> BS.ByteString -> BS.ByteString
+hmac_sha512 k b = case SHA512.hmac k b of
+ SHA512.MAC m -> m
+
cavp_14_3 :: [CaseBlock] -> [CaseBlock] -> TestTree
cavp_14_3 cs ds = testGroup "CAVP 14.3" [
- testGroup "HMAC-SHA256" (fmap (execute_caseblock SHA256.hmac) cs)
- , testGroup "HMAC-SHA512" (fmap (execute_caseblock SHA512.hmac) ds)
+ testGroup "HMAC-SHA256" (fmap (execute_caseblock hmac_sha256) cs)
+ , testGroup "HMAC-SHA512" (fmap (execute_caseblock hmac_sha512) ds)
]
data CaseBlock = CaseBlock {