README.md (5022B)
1 # hmac-drbg 2 3 [](https://hackage.haskell.org/package/ppad-hmac-drbg) 4  5 [](https://docs.ppad.tech/hmac-drbg) 6 7 A pure Haskell implementation of the HMAC-DRBG cryptographically-secure PRNG, 8 as specified by [NIST SP 800-90A][sp800]. 9 10 ## Usage 11 12 A sample GHCi session: 13 14 ``` 15 > -- extensions/b16 import just for illustration here; not required for use 16 > :set -XOverloadedStrings 17 > :set -XRankNTypes 18 > import qualified Data.ByteString.Base16 as B16 19 > 20 > -- import qualified 21 > import qualified Crypto.DRBG.HMAC.SHA256 as DRBG 22 > 23 > -- instantiate a DRBG 24 > let entropy = "very random" 25 > let nonce = "very unused" 26 > let personalization_string = "very personal" 27 > 28 > drbg <- DRBG.new entropy nonce personalization_string 29 > 30 > -- use it to generate some bytes 31 > 32 > fmap B16.encode <$> DRBG.gen drbg mempty 32 33 Right "e4d17210810c4b343f6eae2c19e3d82395b555294b1b16a85f91dbea67e5f277" 34 > 35 > -- reuse the generator to get more; the state is updated automatically 36 > 37 > fmap B16.encode <$> DRBG.gen drbg mempty 16 38 Right "5d867730d99eb5335f16b1d622f03023" 39 > 40 > -- this DRBG was instantiated in the IO monad: 41 > 42 > :t drbg 43 drbg :: DRBG.DRBG ghc-prim:GHC.Prim.RealWorld 44 > 45 > -- but you can also use ST to keep things pure: 46 > 47 > import Control.Monad.ST 48 > 49 > :{ 50 ghci| let drbg_pure = DRBG.new mempty mempty mempty :: 51 ghci| forall s. ST s (DRBG.DRBG s) 52 ghci| :} 53 > 54 > :t drbg_pure 55 drbg_pure :: ST s (DRBG.DRBG s) 56 > 57 > runST $ drbg_pure >>= fmap (fmap B16.encode) . (\d -> DRBG.gen d mempty 16) 58 Right "b44299907e4e42aa4fded5d6153e8bac" 59 ``` 60 61 ## Documentation 62 63 Haddocks (API documentation, etc.) are hosted at 64 [docs.ppad.tech/hmac-drbg][hadoc]. 65 66 ## Performance 67 68 The aim is best-in-class performance for pure, highly-auditable Haskell 69 code. 70 71 Current benchmark figures on an M4 Silicon MacBook Air look like (use 72 `cabal bench` to run the benchmark suite): 73 74 ``` 75 benchmarking ppad-hmac-drbg/HMAC-SHA256/new 76 time 225.2 ns (224.3 ns .. 226.4 ns) 77 0.999 R² (0.998 R² .. 1.000 R²) 78 mean 233.4 ns (227.9 ns .. 241.8 ns) 79 std dev 23.42 ns (12.58 ns .. 34.87 ns) 80 variance introduced by outliers: 90% (severely inflated) 81 82 benchmarking ppad-hmac-drbg/HMAC-SHA256/reseed 83 time 211.3 ns (210.6 ns .. 211.9 ns) 84 1.000 R² (1.000 R² .. 1.000 R²) 85 mean 210.7 ns (210.3 ns .. 211.1 ns) 86 std dev 1.381 ns (1.133 ns .. 1.766 ns) 87 88 benchmarking ppad-hmac-drbg/HMAC-SHA256/gen (32B) 89 time 367.3 ns (366.4 ns .. 368.3 ns) 90 0.999 R² (0.999 R² .. 1.000 R²) 91 mean 375.9 ns (370.3 ns .. 388.7 ns) 92 std dev 28.42 ns (13.66 ns .. 55.18 ns) 93 variance introduced by outliers: 83% (severely inflated) 94 95 benchmarking ppad-hmac-drbg/HMAC-SHA256/gen (256B) 96 time 1.472 μs (1.468 μs .. 1.476 μs) 97 1.000 R² (1.000 R² .. 1.000 R²) 98 mean 1.470 μs (1.465 μs .. 1.474 μs) 99 std dev 15.77 ns (12.15 ns .. 21.36 ns) 100 ``` 101 102 You should compile with the 'llvm' flag for maximum performance. 103 104 ## Security 105 106 This library aims at the maximum security achievable in a 107 garbage-collected language under an optimizing compiler such as GHC, in 108 which strict constant-timeness can be [challenging to achieve][const]. 109 110 The HMAC-DRBG implementation within has been tested against the 111 NIST DRBGVS vectors available for SHA-256 and SHA-512. 112 113 DRBG internal state, which must be kept secret, is kept in a single, 114 pinned, heap-allocated mutable buffer. It is never copied, is guaranteed 115 never to be moved around by the garbage collector, and its components 116 are never allocated anywhere else on the heap. You should zero out the 117 DRBG state via the 'wipe' function when you've finished using it. 118 119 (The security properties of this library have been 120 examined and defended in more detail in a 121 [security analysis](https://ppad.tech/security-analysis-hmac-drbg) at 122 [ppad.tech](https://ppad.tech).) 123 124 If you discover any vulnerabilities, please disclose them via 125 security@ppad.tech. 126 127 ## Development 128 129 You'll require [Nix][nixos] with [flake][flake] support enabled. Enter a 130 development shell with: 131 132 ``` 133 $ nix develop 134 ``` 135 136 Then do e.g.: 137 138 ``` 139 $ cabal repl ppad-hmac-drbg 140 ``` 141 142 to get a REPL for the main library. 143 144 [sp800]: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf 145 [nixos]: https://nixos.org/ 146 [flake]: https://nixos.org/manual/nix/unstable/command-ref/new-cli/nix3-flake.html 147 [hadoc]: https://docs.ppad.tech/hmac-drbg 148 [sh256]: https://git.ppad.tech/sha256 149 [sh512]: https://git.ppad.tech/sha512 150 [const]: https://www.chosenplaintext.ca/articles/beginners-guide-constant-time-cryptography.html