| Copyright | (c) 2026 Jared Tobin |
|---|---|
| License | MIT |
| Maintainer | Jared Tobin <jared@ppad.tech> |
| Safe Haskell | None |
| Language | Haskell2010 |
Censor.FFI
Description
Testing foreign-function targets.
A FFIHypothesis works in one pinned workspace, allocated once
outside the timed region and reused for every pair. The samplers
fill it in place and the target reads (and may write) it, at
offsets of the caller's choosing.
Only ffiTarget is timed, so keep it to a single ccall unsafe
FFI call: marshalling or allocation inside it lands in the timed
region, and a safe call adds the RTS's thread suspend/resume.
Example
-- C side: void ct_mul(const uint8_t *a, const uint8_t *b,
-- uint8_t *out); -- 32-byte operands.
foreign import ccall unsafe "ct_mul"
c_mul :: Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> IO ()
mulHyp :: Rng -> FFIHypothesis
mulHyp g = FFIHypothesis
{ ffiWorkspaceBytes = 96
, ffiPrepare = pure ()
, ffiSampleA = \p -> do
fillRandom g (p `plusPtr` 0) 32 -- draw and discard,
fillBytes (p `plusPtr` 0) 0 32 -- then fix: input a
fillRandom g (p `plusPtr` 32) 32 -- input b: random
, ffiSampleB = \p -> do
fillRandom g (p `plusPtr` 0) 32
fillRandom g (p `plusPtr` 32) 32
, ffiTarget = \p ->
c_mul p (p `plusPtr` 32) (p `plusPtr` 64)
}
result <- withFFIHypothesis (mulHyp g) $ \h ->
runCT wallClock defaultConfig hfillBytes is fillBytes. The discarded
fillRandom in ffiSampleA keeps the two samplers' generator work
symmetric before the fixed operand overwrites it.
Synopsis
- data FFIHypothesis = FFIHypothesis {
- ffiWorkspaceBytes :: !Int
- ffiPrepare :: !(IO ())
- ffiSampleA :: !(Ptr Word8 -> IO ())
- ffiSampleB :: !(Ptr Word8 -> IO ())
- ffiTarget :: !(Ptr Word8 -> IO ())
- withFFIHypothesis :: FFIHypothesis -> (Hypothesis (Ptr Word8) -> IO a) -> IO a
- fillRandom :: Rng -> Ptr Word8 -> Int -> IO ()
Foreign hypothesis
data FFIHypothesis Source #
A foreign-function constant-time hypothesis over a pinned
workspace of ffiWorkspaceBytes bytes.
Constructors
| FFIHypothesis | |
Fields
| |
Bridging to runCT
withFFIHypothesis :: FFIHypothesis -> (Hypothesis (Ptr Word8) -> IO a) -> IO a Source #
Acquire the workspace, present a regular Hypothesis that the
sequential driver (runCT) can consume, and release the
workspace when the continuation returns.
The same workspace pointer is handed to every sample/measure pair; samplers should establish the buffer state for their class each call rather than relying on residual contents.