commit 3060645abfec415f8dae8c08a613f7c51cc9c36c
parent c832ff090cd2f301d18c8f04886a2124d392a75f
Author: Jared Tobin <jared@jtobin.io>
Date: Sun, 1 Feb 2026 14:26:34 +0400
lib: export list and noinline pragma
The NOINLINE pragma is required with the explicit export list to stop
GHC from mis-optimizing the unsaf efunctions.
Diffstat:
2 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/README.md b/README.md
@@ -64,11 +64,10 @@ benchmark suite):
```
benchmarking ppad-sha256/SHA256 (32B input)/hash
- time 67.70 ns (66.08 ns .. 71.11 ns)
- 0.992 R² (0.979 R² .. 1.000 R²)
- mean 66.55 ns (65.91 ns .. 68.79 ns)
- std dev 3.919 ns (720.2 ps .. 8.253 ns)
- variance introduced by outliers: 78% (severely inflated)
+ time 65.85 ns (65.76 ns .. 65.95 ns)
+ 1.000 R² (1.000 R² .. 1.000 R²)
+ mean 65.90 ns (65.80 ns .. 65.99 ns)
+ std dev 307.5 ps (256.0 ps .. 392.9 ps)
benchmarking ppad-sha256/HMAC-SHA256 (32B input)/hmac
time 135.7 ns (135.2 ns .. 136.1 ns)
diff --git a/lib/Crypto/Hash/SHA256/Arm.hs b/lib/Crypto/Hash/SHA256/Arm.hs
@@ -46,6 +46,7 @@ fi :: (Integral a, Num b) => a -> b
fi = fromIntegral
{-# INLINE fi #-}
+
peek_registers
:: Ptr Word32
-> Registers
@@ -174,7 +175,7 @@ _hmac rp bp k m = do
poke_registers rp (iv ())
update rp bp (xor k (Exts.wordToWord32# 0x5C5C5C5C##))
update rp bp block
-{-# INLINABLE _hmac #-}
+{-# NOINLINE _hmac #-}
_hmac_rr
:: Ptr Word32 -- ^ register state
@@ -204,6 +205,8 @@ _hmac_bb rp bp k m = do
update rp bp inner
{-# INLINABLE _hmac_bb #-}
+-- | HMAC(key, v || sep || data) using ARM crypto extensions.
+-- Writes result to destination pointer.
_hmac_rsb
:: Ptr Word32 -- ^ destination (8 Word32s)
-> Ptr Word32 -- ^ scratch block buffer (16 Word32s)
@@ -223,6 +226,8 @@ _hmac_rsb rp bp k v sep dat = do
update rp bp inner
{-# INLINABLE _hmac_rsb #-}
+-- | Hash (v || sep || dat) with ARM crypto extensions.
+-- Assumes register state already initialized at rp.
_hash_vsb
:: Ptr Word32 -- ^ register state
-> Ptr Word32 -- ^ block buffer
@@ -236,9 +241,11 @@ _hash_vsb rp bp el v sep dat@(BI.PS _ _ l)
-- first block is complete: v || sep || dat[0:31]
let !b0 = parse_vsb v sep dat
update rp bp b0
+ -- hash remaining complete blocks from dat[31:]
let !rest = BU.unsafeDrop 31 dat
!restLen = l - 31
hash_blocks rp bp rest
+ -- handle final padding
let !finLen = restLen `rem` 64
!fin = BU.unsafeDrop (restLen - finLen) rest
!total = el + 33 + fi l