sha512

Pure Haskell SHA-512, HMAC-SHA512 (docs.ppad.tech/sha512).
git clone git://git.ppad.tech/sha512.git
Log | Files | Refs | README | LICENSE

README.md (5292B)


      1 # ppad-sha512
      2 
      3 A pure Haskell implementation of SHA-512 and HMAC-SHA512 on strict and
      4 lazy ByteStrings, as specified by RFC's [6234][r6234] and [2104][r2104].
      5 
      6 ## Usage
      7 
      8 A sample GHCi session:
      9 
     10 ```
     11   > :set -XOverloadedStrings
     12   >
     13   > -- import qualified
     14   > import qualified Crypto.Hash.SHA512 as SHA512
     15   >
     16   > -- 'hash' and 'hmac' operate on strict bytestrings
     17   >
     18   > let hash_s = SHA512.hash "strict bytestring input"
     19   > let hmac_s = SHA512.hmac "strict secret" "strict bytestring input"
     20   >
     21   > -- 'hash_lazy' and 'hmac_lazy' operate on lazy bytestrings
     22   > -- but note that the key for HMAC is always strict
     23   >
     24   > let hash_l = SHA512.hash_lazy "lazy bytestring input"
     25   > let hmac_l = SHA512.hmac_lazy "strict secret" "lazy bytestring input"
     26   >
     27   > -- results are always unformatted 512-bit (64-byte) strict bytestrings
     28   >
     29   > import qualified Data.ByteString as BS
     30   >
     31   > BS.take 10 hash_s
     32   "\189D*\v\166\245N\216\&1\243"
     33   > BS.take 10 hmac_l
     34   "#}9\185\179\233[&\246\205"
     35   >
     36   > -- you can use third-party libraries for rendering if needed
     37   > -- e.g., using base64-bytestring:
     38   >
     39   > import qualified Data.ByteString.Base64 as B64
     40   >
     41   > B64.encode (BS.take 16 hash_s)
     42   "vUQqC6b1Ttgx8+ydx4MmtQ=="
     43   > B64.encode (BS.take 16 hmac_l)
     44   "I305ubPpWyb2zUi4pwDkrw=="
     45 ```
     46 
     47 ## Documentation
     48 
     49 Haddocks (API documentation, etc.) are hosted at
     50 [docs.ppad.tech/sha512][hadoc].
     51 
     52 ## Performance
     53 
     54 The aim is best-in-class performance for pure, highly-auditable Haskell
     55 code.
     56 
     57 Current benchmark figures on my mid-2020 MacBook Air look like (use
     58 `cabal bench` to run the benchmark suite):
     59 
     60 ```
     61   benchmarking ppad-sha512/SHA512 (32B input)/hash
     62   time                 2.386 μs   (2.320 μs .. 2.445 μs)
     63                        0.995 R²   (0.993 R² .. 0.997 R²)
     64   mean                 2.370 μs   (2.319 μs .. 2.432 μs)
     65   std dev              193.0 ns   (160.0 ns .. 232.3 ns)
     66   variance introduced by outliers: 83% (severely inflated)
     67 
     68   benchmarking ppad-sha512/SHA512 (32B input)/hash_lazy
     69   time                 2.279 μs   (2.214 μs .. 2.349 μs)
     70                        0.994 R²   (0.992 R² .. 0.997 R²)
     71   mean                 2.292 μs   (2.238 μs .. 2.359 μs)
     72   std dev              196.1 ns   (165.2 ns .. 237.1 ns)
     73   variance introduced by outliers: 84% (severely inflated)
     74 
     75   benchmarking ppad-sha512/HMAC-SHA512 (32B input)/hmac
     76   time                 7.511 μs   (7.312 μs .. 7.726 μs)
     77                        0.995 R²   (0.993 R² .. 0.997 R²)
     78   mean                 7.494 μs   (7.341 μs .. 7.676 μs)
     79   std dev              579.6 ns   (477.5 ns .. 736.9 ns)
     80   variance introduced by outliers: 80% (severely inflated)
     81 
     82   benchmarking ppad-sha512/HMAC-SHA512 (32B input)/hmac_lazy
     83   time                 7.563 μs   (7.278 μs .. 7.867 μs)
     84                        0.993 R²   (0.989 R² .. 0.997 R²)
     85   mean                 7.374 μs   (7.226 μs .. 7.566 μs)
     86   std dev              551.8 ns   (464.4 ns .. 690.1 ns)
     87   variance introduced by outliers: 78% (severely inflated)
     88 ```
     89 
     90 Compare this to Hackage's famous SHA package:
     91 
     92 ```
     93   benchmarking ppad-sha512/SHA512 (32B input)/SHA.sha512
     94   time                 3.198 μs   (3.133 μs .. 3.262 μs)
     95                        0.996 R²   (0.993 R² .. 0.998 R²)
     96   mean                 3.212 μs   (3.149 μs .. 3.300 μs)
     97   std dev              247.6 ns   (192.3 ns .. 347.0 ns)
     98   variance introduced by outliers: 81% (severely inflated)
     99 
    100   benchmarking ppad-sha512/HMAC-SHA512 (32B input)/SHA.hmacSha512
    101   time                 11.71 μs   (11.35 μs .. 12.08 μs)
    102                        0.992 R²   (0.988 R² .. 0.995 R²)
    103   mean                 11.68 μs   (11.39 μs .. 12.06 μs)
    104   std dev              1.036 μs   (871.1 ns .. 1.224 μs)
    105   variance introduced by outliers: 83% (severely inflated)
    106 ```
    107 
    108 Or the relevant SHA-512-based functions from a library with similar
    109 aims, [noble-hashes][noble] (though with no HMAC-SHA512 benchmark
    110 available):
    111 
    112 ```
    113 SHA512 32B x 217,296 ops/sec @ 4μs/op ± 2.00% (min: 3μs, max: 20ms)
    114 ```
    115 
    116 ## Security
    117 
    118 This library aims at the maximum security achievable in a
    119 garbage-collected language under an optimizing compiler such as GHC, in
    120 which strict constant-timeness can be challenging to achieve.
    121 
    122 The HMAC-SHA512 functions within pass all [Wycheproof vectors][wyche],
    123 as well as various other useful unit test vectors found around the
    124 internet.
    125 
    126 If you discover any vulnerabilities, please disclose them via
    127 security@ppad.tech.
    128 
    129 ## Development
    130 
    131 You'll require [Nix][nixos] with [flake][flake] support enabled. Enter a
    132 development shell with:
    133 
    134 ```
    135 $ nix develop
    136 ```
    137 
    138 Then do e.g.:
    139 
    140 ```
    141 $ cabal repl ppad-sha512
    142 ```
    143 
    144 to get a REPL for the main library.
    145 
    146 ## Attribution
    147 
    148 This implementation has benefitted immensely from the [SHA][hacka]
    149 package available on Hackage, which was used as a reference during
    150 development. Many parts wound up being direct translations.
    151 
    152 [nixos]: https://nixos.org/
    153 [flake]: https://nixos.org/manual/nix/unstable/command-ref/new-cli/nix3-flake.html
    154 [hadoc]: https://docs.ppad.tech/sha512
    155 [hacka]: https://hackage.haskell.org/package/SHA
    156 [r6234]: https://datatracker.ietf.org/doc/html/rfc6234
    157 [r2104]: https://datatracker.ietf.org/doc/html/rfc2104
    158 [noble]: https://github.com/paulmillr/noble-hashes
    159 [wyche]: https://github.com/C2SP/wycheproof