packages feed

ppad-aead 0.3.3 → 0.3.4

raw patch · 4 files changed

+50/−4 lines, 4 filesdep ~ppad-poly1305PVP ok

version bump matches the API change (PVP)

Dependency ranges changed: ppad-poly1305

API changes (from Hackage documentation)

Files

CHANGELOG view
@@ -1,5 +1,10 @@ # Changelog +- 0.3.4 (2026-07-17)+  * Adds an optimization-opaque barrier to MAC equality comparison+    to prevent LLVM from introducing variable-time instructions when+    compiling with the LLVM backend.+ - 0.3.3 (2026-07-17)   * Uses a different algorithm for constant-time MAC comparison.     This version seems to produce less microarchitectural variance on
lib/Crypto/AEAD/ChaCha20Poly1305.hs view
@@ -25,6 +25,7 @@   , _poly1305_key_gen   ) where +import Data.Barrier (barrier) import qualified Crypto.Cipher.ChaCha20 as ChaCha20 import qualified Crypto.MAC.Poly1305 as Poly1305 import Data.Bits ((.>>.))@@ -42,7 +43,9 @@ -- 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.+-- heap. The accumulator is routed through 'barrier' before the+-- zero-test so the LLVM backend cannot recover the array-equality+-- idiom and short-circuit on the first mismatch (see "Data.Barrier"). ct_eq :: BS.ByteString -> BS.ByteString -> Bool ct_eq a@(BI.PS _ _ la) b@(BI.PS _ _ lb)     | la /= lb  = False@@ -50,7 +53,7 @@   where     go :: Word8 -> Int -> Bool     go !acc !i-      | i == la   = acc == 0+      | i == la   = barrier acc == 0       | otherwise =           let !x = BU.unsafeIndex a i               !y = BU.unsafeIndex b i
+ lib/Data/Barrier.hs view
@@ -0,0 +1,36 @@+{-# OPTIONS_HADDOCK hide #-}++-- |+-- Module: Data.Barrier+-- Copyright: (c) 2025 Jared Tobin+-- License: MIT+-- Maintainer: Jared Tobin <jared@ppad.tech>+--+-- An optimisation barrier for constant-time code.++module Data.Barrier (+    barrier+  ) where++import Data.Word (Word8)++-- | Identity on 'Word8', but opaque to the optimiser. A constant-time+--   accumulate-then-compare (e.g. an OR-fold of bytewise XORs, tested+--   against zero) routes its accumulator through this before the+--   zero-test, so the compiler cannot recognise it as an array-equality+--   test and lower it to a short-circuiting byte comparison (which would+--   leak the mismatch position).+--+--   Both properties are required and must not be \"tidied\" away:+--+--     * @NOINLINE@ -- if GHC inlines it, the LLVM backend regains the+--       accumulator's definition and short-circuits again.+--     * a /separate/ module -- a caller then compiles @barrier@ to an+--       external call it cannot see through. Inline it into the caller+--       and the barrier is gone.+--+--   Guarded by the substratum + censor constant-time checks; weakening+--   either property re-introduces the timing leak.+barrier :: Word8 -> Word8+barrier x = x+{-# NOINLINE barrier #-}
ppad-aead.cabal view
@@ -1,6 +1,6 @@ cabal-version:      3.0 name:               ppad-aead-version:            0.3.3+version:            0.3.4 synopsis:           A pure AEAD-ChaCha20-Poly1305 construction license:            MIT license-file:       LICENSE@@ -33,11 +33,13 @@     ghc-options: -fllvm -O2   exposed-modules:       Crypto.AEAD.ChaCha20Poly1305+  other-modules:+      Data.Barrier   build-depends:       base >= 4.9 && < 5     , bytestring >= 0.9 && < 0.13     , ppad-chacha >= 0.2.2 && < 0.3-    , ppad-poly1305 >= 0.4.4 && < 0.5+    , ppad-poly1305 >= 0.4.5 && < 0.5  test-suite aead-tests   type:                exitcode-stdio-1.0