README.md (4028B)
1 # ppad-ripemd160 2 3 A pure Haskell implementation of [RIPEMD-160][ripem] and HMAC-RIPEMD160 4 on strict and lazy ByteStrings. 5 6 ## Usage 7 8 A sample GHCi session: 9 10 ``` 11 > :set -XOverloadedStrings 12 > 13 > -- import qualified 14 > import qualified Crypto.Hash.RIPEMD160 as RIPEMD160 15 > 16 > -- 'hash' and 'hmac' operate on strict bytestrings 17 > 18 > let hash_s = RIPEMD160.hash "strict bytestring input" 19 > let hmac_s = RIPEMD160.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 = RIPEMD160.hash_lazy "lazy bytestring input" 25 > let hmac_l = RIPEMD160.hmac_lazy "strict secret" "lazy bytestring input" 26 > 27 > -- results are always unformatted 160-bit (20-byte) strict bytestrings 28 > 29 > import qualified Data.ByteString as BS 30 > 31 > BS.take 10 hash_s 32 "=\211\211\197]\NULJ\223n\223" 33 > BS.take 10 hmac_l 34 "\154\248\145[\196\ETX\f\ESC\NULs" 35 > 36 > -- you can use third-party libraries for rendering if needed 37 > -- e.g., using base16-bytestring: 38 > 39 > import qualified Data.ByteString.Base16 as B16 40 > 41 > B16.encode hash_s 42 "3dd3d3c55d004adf6edf9e11cb01f9ac9c56441f" 43 > B16.encode hmac_l 44 "9af8915bc4030c1b007323c8531b3129d82f50bd" 45 ``` 46 47 ## Documentation 48 49 Haddocks (API documentation, etc.) are hosted at 50 [docs.ppad.tech/ripemd160][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-ripemd160/RIPEMD160 (32B input)/hash 62 time 1.115 μs (1.109 μs .. 1.122 μs) 63 1.000 R² (1.000 R² .. 1.000 R²) 64 mean 1.123 μs (1.117 μs .. 1.130 μs) 65 std dev 19.84 ns (16.75 ns .. 23.55 ns) 66 variance introduced by outliers: 19% (moderately inflated) 67 68 benchmarking ppad-ripemd160/RIPEMD160 (32B input)/hash_lazy 69 time 1.072 μs (1.060 μs .. 1.085 μs) 70 0.999 R² (0.999 R² .. 1.000 R²) 71 mean 1.073 μs (1.066 μs .. 1.082 μs) 72 std dev 27.29 ns (23.35 ns .. 31.28 ns) 73 variance introduced by outliers: 33% (moderately inflated) 74 75 benchmarking ppad-ripemd160/HMAC-RIPEMD160 (32B input)/hmac 76 time 3.941 μs (3.919 μs .. 3.963 μs) 77 1.000 R² (0.999 R² .. 1.000 R²) 78 mean 3.997 μs (3.972 μs .. 4.037 μs) 79 std dev 111.0 ns (71.80 ns .. 191.1 ns) 80 variance introduced by outliers: 34% (moderately inflated) 81 82 benchmarking ppad-ripemd160/HMAC-RIPEMD160 (32B input)/hmac_lazy 83 time 3.944 μs (3.912 μs .. 3.991 μs) 84 0.999 R² (0.999 R² .. 1.000 R²) 85 mean 3.982 μs (3.955 μs .. 4.012 μs) 86 std dev 96.66 ns (83.81 ns .. 117.3 ns) 87 variance introduced by outliers: 28% (moderately inflated) 88 ``` 89 90 ## Security 91 92 This library aims at the maximum security achievable in a 93 garbage-collected language under an optimizing compiler such as GHC, in 94 which strict constant-timeness can be challenging to achieve. 95 96 The RIPEMD-160 functions pass the vectors present in the [official 97 spec][ripem], and the HMAC-RIPEMD160 functions pass all vectors found 98 contained in [RFC2286][rfc22]. 99 100 If you discover any vulnerabilities, please disclose them via 101 security@ppad.tech. 102 103 ## Development 104 105 You'll require [Nix][nixos] with [flake][flake] support enabled. Enter a 106 development shell with: 107 108 ``` 109 $ nix develop 110 ``` 111 112 Then do e.g.: 113 114 ``` 115 $ cabal repl ppad-ripemd160 116 ``` 117 118 to get a REPL for the main library. 119 120 [nixos]: https://nixos.org/ 121 [flake]: https://nixos.org/manual/nix/unstable/command-ref/new-cli/nix3-flake.html 122 [hadoc]: https://docs.ppad.tech/ripemd160 123 [ripem]: https://homes.esat.kuleuven.be/~bosselae/ripemd160/pdf/AB-9601/AB-9601.pdf 124 [rfc22]: https://www.rfc-editor.org/rfc/rfc2286.html#section-2