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 (4587B)


      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                 1.116 μs   (1.103 μs .. 1.130 μs)
     63                        0.999 R²   (0.999 R² .. 0.999 R²)
     64   mean                 1.142 μs   (1.132 μs .. 1.154 μs)
     65   std dev              37.35 ns   (30.15 ns .. 49.36 ns)
     66   variance introduced by outliers: 45% (moderately inflated)
     67 
     68   benchmarking ppad-sha512/HMAC-SHA512 (32B input)/hmac
     69   time                 4.943 μs   (4.823 μs .. 5.086 μs)
     70                        0.997 R²   (0.994 R² .. 1.000 R²)
     71   mean                 4.878 μs   (4.838 μs .. 4.946 μs)
     72   std dev              180.9 ns   (105.1 ns .. 337.4 ns)
     73   variance introduced by outliers: 48% (moderately inflated)
     74 ```
     75 
     76 Compare this to Hackage's famous SHA package:
     77 
     78 ```
     79   benchmarking ppad-sha512/SHA512 (32B input)/SHA.sha512
     80   time                 2.371 μs   (2.350 μs .. 2.401 μs)
     81                        0.999 R²   (0.999 R² .. 1.000 R²)
     82   mean                 2.422 μs   (2.403 μs .. 2.443 μs)
     83   std dev              69.84 ns   (51.04 ns .. 114.0 ns)
     84   variance introduced by outliers: 37% (moderately inflated)
     85 
     86   benchmarking ppad-sha512/HMAC-SHA512 (32B input)/SHA.hmacSha512
     87   time                 8.832 μs   (8.714 μs .. 8.976 μs)
     88                        0.999 R²   (0.998 R² .. 1.000 R²)
     89   mean                 8.911 μs   (8.834 μs .. 9.006 μs)
     90   std dev              278.9 ns   (215.8 ns .. 365.1 ns)
     91   variance introduced by outliers: 37% (moderately inflated)
     92 ```
     93 
     94 Or the relevant SHA-512-based functions from a library with similar
     95 aims, [noble-hashes][noble] (though with no HMAC-SHA512 benchmark
     96 available):
     97 
     98 ```
     99 SHA512 32B x 217,296 ops/sec @ 4μs/op ± 2.00% (min: 3μs, max: 20ms)
    100 ```
    101 
    102 ## Security
    103 
    104 This library aims at the maximum security achievable in a
    105 garbage-collected language under an optimizing compiler such as GHC, in
    106 which strict constant-timeness can be challenging to achieve.
    107 
    108 The HMAC-SHA512 functions within pass all [Wycheproof vectors][wyche],
    109 as well as various other useful unit test vectors found around the
    110 internet.
    111 
    112 If you discover any vulnerabilities, please disclose them via
    113 security@ppad.tech.
    114 
    115 ## Development
    116 
    117 You'll require [Nix][nixos] with [flake][flake] support enabled. Enter a
    118 development shell with:
    119 
    120 ```
    121 $ nix develop
    122 ```
    123 
    124 Then do e.g.:
    125 
    126 ```
    127 $ cabal repl ppad-sha512
    128 ```
    129 
    130 to get a REPL for the main library.
    131 
    132 ## Attribution
    133 
    134 This implementation has benefitted immensely from the [SHA][hacka]
    135 package available on Hackage, which was used as a reference during
    136 development. Many parts wound up being direct translations.
    137 
    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/sha512
    141 [hacka]: https://hackage.haskell.org/package/SHA
    142 [r6234]: https://datatracker.ietf.org/doc/html/rfc6234
    143 [r2104]: https://datatracker.ietf.org/doc/html/rfc2104
    144 [noble]: https://github.com/paulmillr/noble-hashes
    145 [wyche]: https://github.com/C2SP/wycheproof