commit c4b5f63bcf084357cf1b9b958e58cf4b1165871d
parent de2e199b2f48e3e10fb804a89fabde63163bd12c
Author: Jared Tobin <jared@jtobin.io>
Date: Sun, 1 Feb 2026 15:53:09 +0400
meta: update readme
Diffstat:
| M | README.md | | | 37 | ++++++++++++++++++------------------- |
1 file changed, 18 insertions(+), 19 deletions(-)
diff --git a/README.md b/README.md
@@ -18,47 +18,44 @@ A sample GHCi session:
> import qualified Data.ByteString.Base16 as B16
>
> -- import qualified
- > import qualified Crypto.DRBG.HMAC as DRBG
- >
- > -- supply your own HMAC function
- > import qualified Crypto.Hash.SHA256 as SHA256
+ > import qualified Crypto.DRBG.HMAC.SHA256 as DRBG
>
> -- instantiate a DRBG
> let entropy = "very random"
> let nonce = "very unused"
> let personalization_string = "very personal"
>
- > drbg <- DRBG.new SHA256.hmac entropy nonce personalization_string
+ > drbg <- DRBG.new entropy nonce personalization_string
>
> -- use it to generate some bytes
>
- > fmap B16.encode (DRBG.gen mempty 32 drbg)
- "e4d17210810c4b343f6eae2c19e3d82395b555294b1b16a85f91dbea67e5f277"
+ > fmap B16.encode <$> DRBG.gen drbg mempty 32
+ Right "e4d17210810c4b343f6eae2c19e3d82395b555294b1b16a85f91dbea67e5f277"
>
> -- reuse the generator to get more; the state is updated automatically
>
- > fmap B16.encode (DRBG.gen mempty 16 drbg)
- "5d867730d99eb5335f16b1d622f03023"
+ > fmap B16.encode <$> DRBG.gen drbg mempty 16
+ Right "5d867730d99eb5335f16b1d622f03023"
>
> -- this DRBG was instantiated in the IO monad:
>
> :t drbg
drbg :: DRBG.DRBG ghc-prim:GHC.Prim.RealWorld
>
- > -- but you can also use use ST to keep things pure:
+ > -- but you can also use ST to keep things pure:
>
> import Control.Monad.ST
>
> :{
- ghci| let drbg_pure = DRBG.new SHA256.hmac mempty mempty mempty ::
+ ghci| let drbg_pure = DRBG.new mempty mempty mempty ::
ghci| forall s. ST s (DRBG.DRBG s)
ghci| :}
>
> :t drbg_pure
drbg_pure :: ST s (DRBG.DRBG s)
>
- > runST $ drbg_pure >>= fmap B16.encode . DRBG.gen mempty 16
- "b44299907e4e42aa4fded5d6153e8bac"
+ > runST $ drbg_pure >>= fmap (fmap B16.encode) . (\d -> DRBG.gen d mempty 16)
+ Right "b44299907e4e42aa4fded5d6153e8bac"
```
## Documentation
@@ -102,9 +99,7 @@ Current benchmark figures on an M4 Silicon MacBook Air look like (use
std dev 15.77 ns (12.15 ns .. 21.36 ns)
```
-You should compile with the 'llvm' flag (and ensure that
-[ppad-sha256][sh256] has been compiled with the 'llvm' flag) for
-maximum performance.
+You should compile with the 'llvm' flag for maximum performance.
## Security
@@ -113,9 +108,13 @@ garbage-collected language under an optimizing compiler such as GHC, in
which strict constant-timeness can be [challenging to achieve][const].
The HMAC-DRBG implementation within has been tested against the
-NIST DRBGVS vectors available for SHA-256 and SHA-512, using the
-HMAC functions from [ppad-sha256][sh256] and [ppad-sha512][sh512]
-respectively.
+NIST DRBGVS vectors available for SHA-256 and SHA-512.
+
+DRBG internal state, which must be kept secret, is kept in a single,
+pinned, heap-allocated mutable buffer. It is never copied, is guaranteed
+never to be moved around by the garbage collector, and its components
+are never allocated anywhere else on the heap. You should zero out the
+DRBG state via the 'wipe' function when you've finished using it.
If you discover any vulnerabilities, please disclose them via
security@ppad.tech.