README.md (3800B)
1 # sha256 2 3 [](https://hackage.haskell.org/package/ppad-sha256) 4  5 [](https://docs.ppad.tech/sha256) 6 7 A pure Haskell implementation of SHA-256 and HMAC-SHA256 on strict and 8 lazy ByteStrings, as specified by RFC's [6234][r6234] and [2104][r2104]. 9 10 ## Usage 11 12 A sample GHCi session: 13 14 ``` 15 > :set -XOverloadedStrings 16 > 17 > -- import qualified 18 > import qualified Crypto.Hash.SHA256 as SHA256 19 > 20 > -- 'hash' and 'hmac' operate on strict bytestrings 21 > 22 > let hash_s = SHA256.hash "strict bytestring input" 23 > let hmac_s = SHA256.hmac "strict secret" "strict bytestring input" 24 > 25 > -- 'hash_lazy' and 'hmac_lazy' operate on lazy bytestrings 26 > -- but note that the key for HMAC is always strict 27 > 28 > let hash_l = SHA256.hash_lazy "lazy bytestring input" 29 > let hmac_l = SHA256.hmac_lazy "strict secret" "lazy bytestring input" 30 > 31 > -- results are always unformatted 256-bit (32-byte) strict bytestrings 32 > 33 > import qualified Data.ByteString as BS 34 > 35 > BS.take 10 hash_s 36 "1\223\152Ha\USB\171V\a" 37 > BS.take 10 hmac_l 38 "\DELSOk\180\242\182'v\187" 39 > 40 > -- you can use third-party libraries for rendering if needed 41 > -- e.g., using ppad-base16: 42 > 43 > import qualified Data.ByteString.Base16 as B16 44 > 45 > B16.encode hash_s 46 "31df9848611f42ab5607ea9e6de84b05d5259085abb30a7917d85efcda42b0e3" 47 > B16.encode hmac_l 48 "7f534f6bb4f2b62776bba3d6466e384505f2ff89c91f39800d7a0d4623a4711e" 49 ``` 50 51 ## Documentation 52 53 Haddocks (API documentation, etc.) are hosted at 54 [docs.ppad.tech/sha256][hadoc]. 55 56 ## Performance 57 58 The aim is best-in-class performance for pure Haskell code. 59 60 Current benchmark figures on an M4 Silicon MacBook Air look like (use 61 `cabal bench` to run the benchmark suite): 62 63 ``` 64 benchmarking ppad-sha256/SHA256 (32B input)/hash 65 time 265.9 ns (265.7 ns .. 266.1 ns) 66 1.000 R² (1.000 R² .. 1.000 R²) 67 mean 266.3 ns (266.1 ns .. 266.5 ns) 68 std dev 645.1 ps (524.2 ps .. 829.3 ps) 69 70 benchmarking ppad-sha256/HMAC-SHA256 (32B input)/hmac 71 time 877.7 ns (872.1 ns .. 886.0 ns) 72 1.000 R² (0.999 R² .. 1.000 R²) 73 mean 873.3 ns (871.5 ns .. 877.5 ns) 74 std dev 8.491 ns (4.940 ns .. 15.65 ns) 75 ``` 76 77 You should compile with the 'llvm' flag for maximum performance. 78 79 ## Security 80 81 This library aims at the maximum security achievable in a 82 garbage-collected language under an optimizing compiler such as GHC, in 83 which strict constant-timeness can be challenging to achieve. 84 85 The HMAC-SHA256 functions within pass all [Wycheproof vectors][wyche], 86 as well as various other useful unit test vectors found around the 87 internet. 88 89 If you discover any vulnerabilities, please disclose them via 90 security@ppad.tech. 91 92 ## Development 93 94 You'll require [Nix][nixos] with [flake][flake] support enabled. Enter a 95 development shell with: 96 97 ``` 98 $ nix develop 99 ``` 100 101 Then do e.g.: 102 103 ``` 104 $ cabal repl ppad-sha256 105 ``` 106 107 to get a REPL for the main library. 108 109 ## Attribution 110 111 This implementation has benefitted immensely from the [SHA][hacka] 112 package available on Hackage, which was used as a reference during 113 development. Many parts wound up being direct translations. 114 115 [nixos]: https://nixos.org/ 116 [flake]: https://nixos.org/manual/nix/unstable/command-ref/new-cli/nix3-flake.html 117 [hadoc]: https://docs.ppad.tech/sha256 118 [hacka]: https://hackage.haskell.org/package/SHA 119 [r6234]: https://datatracker.ietf.org/doc/html/rfc6234 120 [r2104]: https://datatracker.ietf.org/doc/html/rfc2104 121 [noble]: https://github.com/paulmillr/noble-hashes 122 [wyche]: https://github.com/C2SP/wycheproof