Barrier.hs (1116B)
1 {-# OPTIONS_HADDOCK hide #-} 2 3 -- | 4 -- Module: Data.Barrier 5 -- Copyright: (c) 2025 Jared Tobin 6 -- License: MIT 7 -- Maintainer: Jared Tobin <jared@ppad.tech> 8 -- 9 -- An optimisation barrier for constant-time code. 10 11 module Data.Barrier ( 12 barrier 13 ) where 14 15 import Data.Word (Word8) 16 17 -- | Identity on 'Word8', but opaque to the optimiser. A constant-time 18 -- accumulate-then-compare (e.g. an OR-fold of bytewise XORs, tested 19 -- against zero) routes its accumulator through this before the 20 -- zero-test, so the compiler cannot recognise it as an array-equality 21 -- test and lower it to a short-circuiting byte comparison (which would 22 -- leak the mismatch position). 23 -- 24 -- Both properties are required and must not be \"tidied\" away: 25 -- 26 -- * @NOINLINE@ -- if GHC inlines it, the LLVM backend regains the 27 -- accumulator's definition and short-circuits again. 28 -- * a /separate/ module -- a caller then compiles @barrier@ to an 29 -- external call it cannot see through. Inline it into the caller 30 -- and the barrier is gone. 31 barrier :: Word8 -> Word8 32 barrier x = x 33 {-# NOINLINE barrier #-}