{"id":26933545,"url":"https://github.com/ppad-tech/sha256","last_synced_at":"2025-07-03T01:38:07.920Z","repository":{"id":261559232,"uuid":"884222476","full_name":"ppad-tech/sha256","owner":"ppad-tech","description":"Pure Haskell SHA-256, HMAC-SHA256","archived":false,"fork":false,"pushed_at":"2025-06-22T09:12:24.000Z","size":115,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-22T10:21:39.502Z","etag":null,"topics":["cryptography","hashing","haskell","sha2","sha256"],"latest_commit_sha":null,"homepage":"","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ppad-tech.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-11-06T11:19:42.000Z","updated_at":"2025-06-22T09:12:27.000Z","dependencies_parsed_at":"2024-11-07T07:49:34.451Z","dependency_job_id":"86635bdf-37fc-4ff6-a802-35eab907f142","html_url":"https://github.com/ppad-tech/sha256","commit_stats":null,"previous_names":["ppad-tech/sha256"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/ppad-tech/sha256","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ppad-tech%2Fsha256","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ppad-tech%2Fsha256/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ppad-tech%2Fsha256/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ppad-tech%2Fsha256/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ppad-tech","download_url":"https://codeload.github.com/ppad-tech/sha256/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ppad-tech%2Fsha256/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263244729,"owners_count":23436478,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cryptography","hashing","haskell","sha2","sha256"],"created_at":"2025-04-02T09:19:32.664Z","updated_at":"2025-07-03T01:38:07.908Z","avatar_url":"https://github.com/ppad-tech.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# sha256\n\n[![](https://img.shields.io/hackage/v/ppad-sha256?color=blue)](https://hackage.haskell.org/package/ppad-sha256)\n![](https://img.shields.io/badge/license-MIT-brightgreen)\n[![](https://img.shields.io/badge/haddock-sha256-lightblue)](https://docs.ppad.tech/sha256)\n\nA pure Haskell implementation of SHA-256 and HMAC-SHA256 on strict and\nlazy ByteStrings, as specified by RFC's [6234][r6234] and [2104][r2104].\n\n## Usage\n\nA sample GHCi session:\n\n```\n  \u003e :set -XOverloadedStrings\n  \u003e\n  \u003e -- import qualified\n  \u003e import qualified Crypto.Hash.SHA256 as SHA256\n  \u003e\n  \u003e -- 'hash' and 'hmac' operate on strict bytestrings\n  \u003e\n  \u003e let hash_s = SHA256.hash \"strict bytestring input\"\n  \u003e let hmac_s = SHA256.hmac \"strict secret\" \"strict bytestring input\"\n  \u003e\n  \u003e -- 'hash_lazy' and 'hmac_lazy' operate on lazy bytestrings\n  \u003e -- but note that the key for HMAC is always strict\n  \u003e\n  \u003e let hash_l = SHA256.hash_lazy \"lazy bytestring input\"\n  \u003e let hmac_l = SHA256.hmac_lazy \"strict secret\" \"lazy bytestring input\"\n  \u003e\n  \u003e -- results are always unformatted 256-bit (32-byte) strict bytestrings\n  \u003e\n  \u003e import qualified Data.ByteString as BS\n  \u003e\n  \u003e BS.take 10 hash_s\n  \"1\\223\\152Ha\\USB\\171V\\a\"\n  \u003e BS.take 10 hmac_l\n  \"\\DELSOk\\180\\242\\182'v\\187\"\n  \u003e\n  \u003e -- you can use third-party libraries for rendering if needed\n  \u003e -- e.g., using ppad-base16:\n  \u003e\n  \u003e import qualified Data.ByteString.Base16 as B16\n  \u003e\n  \u003e B16.encode hash_s\n  \"31df9848611f42ab5607ea9e6de84b05d5259085abb30a7917d85efcda42b0e3\"\n  \u003e B16.encode hmac_l\n  \"7f534f6bb4f2b62776bba3d6466e384505f2ff89c91f39800d7a0d4623a4711e\"\n```\n\n## Documentation\n\nHaddocks (API documentation, etc.) are hosted at\n[docs.ppad.tech/sha256][hadoc].\n\n## Performance\n\nThe aim is best-in-class performance for pure, highly-auditable Haskell\ncode.\n\nCurrent benchmark figures on an M4 Silicon MacBook Air look like (use\n`cabal bench` to run the benchmark suite):\n\n```\n  benchmarking ppad-sha256/SHA256 (32B input)/hash\n  time                 879.7 ns   (879.5 ns .. 879.9 ns)\n                       1.000 R²   (1.000 R² .. 1.000 R²)\n  mean                 880.1 ns   (879.5 ns .. 882.1 ns)\n  std dev              3.504 ns   (994.6 ps .. 7.537 ns)\n\n  benchmarking ppad-sha256/HMAC-SHA256 (32B input)/hmac\n  time                 3.322 μs   (3.322 μs .. 3.322 μs)\n                       1.000 R²   (1.000 R² .. 1.000 R²)\n  mean                 3.321 μs   (3.317 μs .. 3.323 μs)\n  std dev              10.53 ns   (4.987 ns .. 19.12 ns)\n```\n\nCompare this to Hackage's venerable SHA package:\n\n```\n  benchmarking ppad-sha256/SHA256 (32B input)/SHA.sha256\n  time                 1.415 μs   (1.414 μs .. 1.415 μs)\n                       1.000 R²   (1.000 R² .. 1.000 R²)\n  mean                 1.415 μs   (1.415 μs .. 1.415 μs)\n  std dev              1.334 ns   (1.158 ns .. 1.576 ns)\n\n  benchmarking ppad-sha256/HMAC-SHA256 (32B input)/SHA.hmacSha256\n  time                 5.157 μs   (5.156 μs .. 5.158 μs)\n                       1.000 R²   (1.000 R² .. 1.000 R²)\n  mean                 5.158 μs   (5.157 μs .. 5.159 μs)\n  std dev              2.947 ns   (2.413 ns .. 3.606 ns)\n```\n\nOr the relevant SHA-256-based functions from a library with similar\naims, [noble-hashes][noble]:\n\n```\nSHA256 32B x 420,875 ops/sec @ 2μs/op ± 1.33% (min: 1μs, max: 3ms)\nHMAC-SHA256 32B x 97,304 ops/sec @ 10μs/op\n```\n\nWhen reading a 1GB input from disk and testing it with `hash_lazy`, we\nget statistics like the following:\n\n```\n   2,310,899,616 bytes allocated in the heap\n          93,800 bytes copied during GC\n          78,912 bytes maximum residency (2 sample(s))\n          35,776 bytes maximum slop\n              10 MiB total memory in use (0 MiB lost due to fragmentation)\n\n                                     Tot time (elapsed)  Avg pause  Max pause\n  Gen  0       295 colls,     0 par    0.007s   0.008s     0.0000s    0.0001s\n  Gen  1         2 colls,     0 par    0.000s   0.001s     0.0004s    0.0004s\n\n  INIT    time    0.003s  (  0.003s elapsed)\n  MUT     time   22.205s  ( 22.260s elapsed)\n  GC      time    0.007s  (  0.009s elapsed)\n  EXIT    time    0.000s  (  0.001s elapsed)\n  Total   time   22.216s  ( 22.273s elapsed)\n\n  %GC     time       0.0%  (0.0% elapsed)\n\n  Alloc rate    104,073,382 bytes per MUT second\n\n  Productivity 100.0% of total user, 99.9% of total elapsed\n```\n\nSHA.sha256 gets more like:\n\n```\n  74,403,596,936 bytes allocated in the heap\n      12,971,992 bytes copied during GC\n          79,176 bytes maximum residency (2 sample(s))\n          35,512 bytes maximum slop\n               6 MiB total memory in use (0 MiB lost due to fragmentation)\n\n                                     Tot time (elapsed)  Avg pause  Max pause\n  Gen  0     17883 colls,     0 par    0.103s   0.148s     0.0000s    0.0001s\n  Gen  1         2 colls,     0 par    0.000s   0.000s     0.0002s    0.0003s\n\n  INIT    time    0.006s  (  0.006s elapsed)\n  MUT     time   32.367s  ( 32.408s elapsed)\n  GC      time    0.104s  (  0.149s elapsed)\n  EXIT    time    0.000s  (  0.001s elapsed)\n  Total   time   32.477s  ( 32.563s elapsed)\n\n  %GC     time       0.0%  (0.0% elapsed)\n\n  Alloc rate    2,298,740,250 bytes per MUT second\n\n  Productivity  99.7% of total user, 99.5% of total elapsed\n```\n\n## Security\n\nThis library aims at the maximum security achievable in a\ngarbage-collected language under an optimizing compiler such as GHC, in\nwhich strict constant-timeness can be challenging to achieve.\n\nThe HMAC-SHA256 functions within pass all [Wycheproof vectors][wyche],\nas well as various other useful unit test vectors found around the\ninternet.\n\nIf you discover any vulnerabilities, please disclose them via\nsecurity@ppad.tech.\n\n## Development\n\nYou'll require [Nix][nixos] with [flake][flake] support enabled. Enter a\ndevelopment shell with:\n\n```\n$ nix develop\n```\n\nThen do e.g.:\n\n```\n$ cabal repl ppad-sha256\n```\n\nto get a REPL for the main library.\n\n## Attribution\n\nThis implementation has benefitted immensely from the [SHA][hacka]\npackage available on Hackage, which was used as a reference during\ndevelopment. Many parts wound up being direct translations.\n\n[nixos]: https://nixos.org/\n[flake]: https://nixos.org/manual/nix/unstable/command-ref/new-cli/nix3-flake.html\n[hadoc]: https://docs.ppad.tech/sha256\n[hacka]: https://hackage.haskell.org/package/SHA\n[r6234]: https://datatracker.ietf.org/doc/html/rfc6234\n[r2104]: https://datatracker.ietf.org/doc/html/rfc2104\n[noble]: https://github.com/paulmillr/noble-hashes\n[wyche]: https://github.com/C2SP/wycheproof\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fppad-tech%2Fsha256","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fppad-tech%2Fsha256","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fppad-tech%2Fsha256/lists"}