README.md (4618B)
1 # hmac-drbg 2 3 [](https://hackage.haskell.org/package/ppad-hmac-drbg) 4  5 6 A pure Haskell implementation of the HMAC-DRBG cryptographically-secure PRNG, 7 as specified by [NIST SP 800-90A][sp800]. 8 9 ## Usage 10 11 A sample GHCi session: 12 13 ``` 14 > -- extensions/b16 import just for illustration here; not required for use 15 > :set -XOverloadedStrings 16 > :set -XRankNTypes 17 > import qualified Data.ByteString.Base16 as B16 18 > 19 > -- import qualified 20 > import qualified Crypto.DRBG.HMAC as DRBG 21 > 22 > -- supply your own HMAC function 23 > import qualified Crypto.Hash.SHA256 as SHA256 24 > 25 > -- instantiate a DRBG 26 > let entropy = "very random" 27 > let nonce = "very unused" 28 > let personalization_string = "very personal" 29 > 30 > drbg <- DRBG.new SHA256.hmac entropy nonce personalization_string 31 > 32 > -- use it to generate some bytes 33 > 34 > fmap B16.encode (DRBG.gen mempty 32 drbg) 35 "e4d17210810c4b343f6eae2c19e3d82395b555294b1b16a85f91dbea67e5f277" 36 > 37 > -- reuse the generator to get more; the state is updated automatically 38 > 39 > fmap B16.encode (DRBG.gen mempty 16 drbg) 40 "5d867730d99eb5335f16b1d622f03023" 41 > 42 > -- this DRBG was instantiated in the IO monad: 43 > 44 > :t drbg 45 drbg :: DRBG.DRBG ghc-prim:GHC.Prim.RealWorld 46 > 47 > -- but you can also use use ST to keep things pure: 48 > 49 > import Control.Monad.ST 50 > 51 > :{ 52 ghci| let drbg_pure = DRBG.new SHA256.hmac mempty mempty mempty :: 53 ghci| forall s. ST s (DRBG.DRBG s) 54 ghci| :} 55 > 56 > :t drbg_pure 57 drbg_pure :: ST s (DRBG.DRBG s) 58 > 59 > runST $ drbg_pure >>= fmap B16.encode . DRBG.gen mempty 16 60 "b44299907e4e42aa4fded5d6153e8bac" 61 ``` 62 63 ## Documentation 64 65 Haddocks (API documentation, etc.) are hosted at 66 [docs.ppad.tech/hmac-drbg][hadoc]. 67 68 ## Performance 69 70 The aim is best-in-class performance for pure, highly-auditable Haskell 71 code. 72 73 Current benchmark figures on my mid-2020 MacBook Air look like (use 74 `cabal bench` to run the benchmark suite): 75 76 ``` 77 benchmarking ppad-hmac-drbg/HMAC-SHA256/new 78 time 20.86 μs (20.78 μs .. 20.94 μs) 79 1.000 R² (1.000 R² .. 1.000 R²) 80 mean 20.82 μs (20.72 μs .. 20.93 μs) 81 std dev 370.6 ns (299.3 ns .. 456.6 ns) 82 variance introduced by outliers: 15% (moderately inflated) 83 84 benchmarking ppad-hmac-drbg/HMAC-SHA256/reseed 85 time 13.98 μs (13.83 μs .. 14.18 μs) 86 0.999 R² (0.998 R² .. 1.000 R²) 87 mean 13.89 μs (13.79 μs .. 14.03 μs) 88 std dev 398.9 ns (296.7 ns .. 580.8 ns) 89 variance introduced by outliers: 32% (moderately inflated) 90 91 benchmarking ppad-hmac-drbg/HMAC-SHA256/gen (32B) 92 time 21.10 μs (20.95 μs .. 21.25 μs) 93 1.000 R² (0.999 R² .. 1.000 R²) 94 mean 21.19 μs (21.06 μs .. 21.36 μs) 95 std dev 509.2 ns (390.7 ns .. 812.2 ns) 96 variance introduced by outliers: 24% (moderately inflated) 97 98 benchmarking ppad-hmac-drbg/HMAC-SHA256/gen (256B) 99 time 68.17 μs (67.62 μs .. 68.82 μs) 100 1.000 R² (0.999 R² .. 1.000 R²) 101 mean 68.74 μs (68.42 μs .. 69.09 μs) 102 std dev 1.172 μs (1.022 μs .. 1.410 μs) 103 variance introduced by outliers: 12% (moderately inflated) 104 ``` 105 106 ## Security 107 108 This library aims at the maximum security achievable in a 109 garbage-collected language under an optimizing compiler such as GHC, in 110 which strict constant-timeness can be [challenging to achieve][const]. 111 112 The HMAC-DRBG implementation within has been tested against the 113 NIST DRBGVS vectors available for SHA-256 and SHA-512, using the 114 HMAC functions from [ppad-sha256][sh256] and [ppad-sha512][sh512] 115 respectively. 116 117 If you discover any vulnerabilities, please disclose them via 118 security@ppad.tech. 119 120 ## Development 121 122 You'll require [Nix][nixos] with [flake][flake] support enabled. Enter a 123 development shell with: 124 125 ``` 126 $ nix develop 127 ``` 128 129 Then do e.g.: 130 131 ``` 132 $ cabal repl ppad-hmac-drbg 133 ``` 134 135 to get a REPL for the main library. 136 137 [sp800]: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf 138 [nixos]: https://nixos.org/ 139 [flake]: https://nixos.org/manual/nix/unstable/command-ref/new-cli/nix3-flake.html 140 [hadoc]: https://docs.ppad.tech/hmac-drbg 141 [sh256]: https://git.ppad.tech/sha256 142 [sh512]: https://git.ppad.tech/sha512 143 [const]: https://www.chosenplaintext.ca/articles/beginners-guide-constant-time-cryptography.html