diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,10 @@
 # Changelog
 
+- 0.3.3 (2026-07-17)
+  * Uses a different algorithm for constant-time MAC comparison.
+    This version seems to produce less microarchitectural variance on
+    aarch64/darwin.
+
 - 0.3.2 (2026-05-16)
   * Bumps the poly1305 dependency to a version that returns its MAC in a
     custom type having a constant-time Eq instance.
diff --git a/lib/Crypto/AEAD/ChaCha20Poly1305.hs b/lib/Crypto/AEAD/ChaCha20Poly1305.hs
--- a/lib/Crypto/AEAD/ChaCha20Poly1305.hs
+++ b/lib/Crypto/AEAD/ChaCha20Poly1305.hs
@@ -31,17 +31,30 @@
 import qualified Data.Bits as B
 import qualified Data.ByteString as BS
 import qualified Data.ByteString.Internal as BI
-import Data.Word (Word64)
+import qualified Data.ByteString.Unsafe as BU
+import Data.Word (Word8, Word64)
 
 fi :: (Integral a, Num b) => a -> b
 fi = fromIntegral
 {-# INLINE fi #-}
 
--- constant-time equality comparison on bytestrings
+-- constant-time equality comparison on bytestrings. fused fold: OR
+-- the bytewise XORs into an accumulator directly, rather than via
+-- packZipWith, so no intermediate ByteString holding the
+-- (secret-derived) difference bytes is ever materialised on the
+-- heap.
 ct_eq :: BS.ByteString -> BS.ByteString -> Bool
 ct_eq a@(BI.PS _ _ la) b@(BI.PS _ _ lb)
-  | la /= lb = False
-  | otherwise = BS.foldl' (B..|.) 0 (BS.packZipWith B.xor a b) == 0
+    | la /= lb  = False
+    | otherwise = go 0 0
+  where
+    go :: Word8 -> Int -> Bool
+    go !acc !i
+      | i == la   = acc == 0
+      | otherwise =
+          let !x = BU.unsafeIndex a i
+              !y = BU.unsafeIndex b i
+          in  go (acc B..|. B.xor x y) (i + 1)
 {-# INLINE ct_eq #-}
 
 -- little-endian bytestring encoding
diff --git a/ppad-aead.cabal b/ppad-aead.cabal
--- a/ppad-aead.cabal
+++ b/ppad-aead.cabal
@@ -1,6 +1,6 @@
 cabal-version:      3.0
 name:               ppad-aead
-version:            0.3.2
+version:            0.3.3
 synopsis:           A pure AEAD-ChaCha20-Poly1305 construction
 license:            MIT
 license-file:       LICENSE
@@ -36,8 +36,8 @@
   build-depends:
       base >= 4.9 && < 5
     , bytestring >= 0.9 && < 0.13
-    , ppad-chacha >= 0.2.1 && < 0.3
-    , ppad-poly1305 >= 0.4.1 && < 0.5
+    , ppad-chacha >= 0.2.2 && < 0.3
+    , ppad-poly1305 >= 0.4.4 && < 0.5
 
 test-suite aead-tests
   type:                exitcode-stdio-1.0
