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


      1 # sha512
      2 
      3 [![](https://img.shields.io/hackage/v/ppad-sha512?color=blue)](https://hackage.haskell.org/package/ppad-sha512)
      4 ![](https://img.shields.io/badge/license-MIT-brightgreen)
      5 
      6 A pure Haskell implementation of SHA-512 and HMAC-SHA512 on strict and
      7 lazy ByteStrings, as specified by RFC's [6234][r6234] and [2104][r2104].
      8 
      9 ## Usage
     10 
     11 A sample GHCi session:
     12 
     13 ```
     14   > :set -XOverloadedStrings
     15   >
     16   > -- import qualified
     17   > import qualified Crypto.Hash.SHA512 as SHA512
     18   >
     19   > -- 'hash' and 'hmac' operate on strict bytestrings
     20   >
     21   > let hash_s = SHA512.hash "strict bytestring input"
     22   > let hmac_s = SHA512.hmac "strict secret" "strict bytestring input"
     23   >
     24   > -- 'hash_lazy' and 'hmac_lazy' operate on lazy bytestrings
     25   > -- but note that the key for HMAC is always strict
     26   >
     27   > let hash_l = SHA512.hash_lazy "lazy bytestring input"
     28   > let hmac_l = SHA512.hmac_lazy "strict secret" "lazy bytestring input"
     29   >
     30   > -- results are always unformatted 512-bit (64-byte) strict bytestrings
     31   >
     32   > import qualified Data.ByteString as BS
     33   >
     34   > BS.take 10 hash_s
     35   "\189D*\v\166\245N\216\&1\243"
     36   > BS.take 10 hmac_l
     37   "#}9\185\179\233[&\246\205"
     38   >
     39   > -- you can use third-party libraries for rendering if needed
     40   > -- e.g., using base64-bytestring:
     41   >
     42   > import qualified Data.ByteString.Base64 as B64
     43   >
     44   > B64.encode (BS.take 16 hash_s)
     45   "vUQqC6b1Ttgx8+ydx4MmtQ=="
     46   > B64.encode (BS.take 16 hmac_l)
     47   "I305ubPpWyb2zUi4pwDkrw=="
     48 ```
     49 
     50 ## Documentation
     51 
     52 Haddocks (API documentation, etc.) are hosted at
     53 [docs.ppad.tech/sha512][hadoc].
     54 
     55 ## Performance
     56 
     57 The aim is best-in-class performance for pure, highly-auditable Haskell
     58 code.
     59 
     60 Current benchmark figures on my mid-2020 MacBook Air look like (use
     61 `cabal bench` to run the benchmark suite):
     62 
     63 ```
     64   benchmarking ppad-sha512/SHA512 (32B input)/hash
     65   time                 1.116 μs   (1.103 μs .. 1.130 μs)
     66                        0.999 R²   (0.999 R² .. 0.999 R²)
     67   mean                 1.142 μs   (1.132 μs .. 1.154 μs)
     68   std dev              37.35 ns   (30.15 ns .. 49.36 ns)
     69   variance introduced by outliers: 45% (moderately inflated)
     70 
     71   benchmarking ppad-sha512/HMAC-SHA512 (32B input)/hmac
     72   time                 4.943 μs   (4.823 μs .. 5.086 μs)
     73                        0.997 R²   (0.994 R² .. 1.000 R²)
     74   mean                 4.878 μs   (4.838 μs .. 4.946 μs)
     75   std dev              180.9 ns   (105.1 ns .. 337.4 ns)
     76   variance introduced by outliers: 48% (moderately inflated)
     77 ```
     78 
     79 Compare this to Hackage's famous SHA package:
     80 
     81 ```
     82   benchmarking ppad-sha512/SHA512 (32B input)/SHA.sha512
     83   time                 2.371 μs   (2.350 μs .. 2.401 μs)
     84                        0.999 R²   (0.999 R² .. 1.000 R²)
     85   mean                 2.422 μs   (2.403 μs .. 2.443 μs)
     86   std dev              69.84 ns   (51.04 ns .. 114.0 ns)
     87   variance introduced by outliers: 37% (moderately inflated)
     88 
     89   benchmarking ppad-sha512/HMAC-SHA512 (32B input)/SHA.hmacSha512
     90   time                 8.832 μs   (8.714 μs .. 8.976 μs)
     91                        0.999 R²   (0.998 R² .. 1.000 R²)
     92   mean                 8.911 μs   (8.834 μs .. 9.006 μs)
     93   std dev              278.9 ns   (215.8 ns .. 365.1 ns)
     94   variance introduced by outliers: 37% (moderately inflated)
     95 ```
     96 
     97 Or the relevant SHA-512-based functions from a library with similar
     98 aims, [noble-hashes][noble] (though with no HMAC-SHA512 benchmark
     99 available):
    100 
    101 ```
    102 SHA512 32B x 217,296 ops/sec @ 4μs/op ± 2.00% (min: 3μs, max: 20ms)
    103 ```
    104 
    105 ## Security
    106 
    107 This library aims at the maximum security achievable in a
    108 garbage-collected language under an optimizing compiler such as GHC, in
    109 which strict constant-timeness can be challenging to achieve.
    110 
    111 The HMAC-SHA512 functions within pass all [Wycheproof vectors][wyche],
    112 as well as various other useful unit test vectors found around the
    113 internet.
    114 
    115 If you discover any vulnerabilities, please disclose them via
    116 security@ppad.tech.
    117 
    118 ## Development
    119 
    120 You'll require [Nix][nixos] with [flake][flake] support enabled. Enter a
    121 development shell with:
    122 
    123 ```
    124 $ nix develop
    125 ```
    126 
    127 Then do e.g.:
    128 
    129 ```
    130 $ cabal repl ppad-sha512
    131 ```
    132 
    133 to get a REPL for the main library.
    134 
    135 ## Attribution
    136 
    137 This implementation has benefitted immensely from the [SHA][hacka]
    138 package available on Hackage, which was used as a reference during
    139 development. Many parts wound up being direct translations.
    140 
    141 [nixos]: https://nixos.org/
    142 [flake]: https://nixos.org/manual/nix/unstable/command-ref/new-cli/nix3-flake.html
    143 [hadoc]: https://docs.ppad.tech/sha512
    144 [hacka]: https://hackage.haskell.org/package/SHA
    145 [r6234]: https://datatracker.ietf.org/doc/html/rfc6234
    146 [r2104]: https://datatracker.ietf.org/doc/html/rfc2104
    147 [noble]: https://github.com/paulmillr/noble-hashes
    148 [wyche]: https://github.com/C2SP/wycheproof