{"id":15036957,"url":"https://github.com/rustcrypto/hashes","last_synced_at":"2025-05-13T20:06:41.903Z","repository":{"id":37772481,"uuid":"74106774","full_name":"RustCrypto/hashes","owner":"RustCrypto","description":"Collection of cryptographic hash functions written in pure Rust","archived":false,"fork":false,"pushed_at":"2025-05-06T16:51:37.000Z","size":4334,"stargazers_count":2012,"open_issues_count":26,"forks_count":271,"subscribers_count":28,"default_branch":"master","last_synced_at":"2025-05-06T19:52:17.360Z","etag":null,"topics":["blake2","cryptographic-hash-functions","cryptography","digest","gost","groestl","hash","k12","md2","md4","md5","ripemd","rust","sha1","sha2","sha3","sm3","streebog","whirlpool"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RustCrypto.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-11-18T07:40:17.000Z","updated_at":"2025-05-04T17:02:08.000Z","dependencies_parsed_at":"2024-02-07T21:43:15.064Z","dependency_job_id":"dd200ebb-3e2b-4e85-8dcc-3bfd915bc8eb","html_url":"https://github.com/RustCrypto/hashes","commit_stats":{"total_commits":515,"total_committers":72,"mean_commits":7.152777777777778,"dds":0.5592233009708738,"last_synced_commit":"2795b4fc666dd1e7c4afc1b32250cc4640ca0cdd"},"previous_names":[],"tags_count":211,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RustCrypto%2Fhashes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RustCrypto%2Fhashes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RustCrypto%2Fhashes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RustCrypto%2Fhashes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RustCrypto","download_url":"https://codeload.github.com/RustCrypto/hashes/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254020481,"owners_count":22000750,"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":["blake2","cryptographic-hash-functions","cryptography","digest","gost","groestl","hash","k12","md2","md4","md5","ripemd","rust","sha1","sha2","sha3","sm3","streebog","whirlpool"],"created_at":"2024-09-24T20:32:51.707Z","updated_at":"2025-05-13T20:06:41.865Z","avatar_url":"https://github.com/RustCrypto.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# RustCrypto: Hashes\n\n[![Project Chat][chat-image]][chat-link] [![dependency status][deps-image]][deps-link] ![Apache2/MIT licensed][license-image]\n\nCollection of [cryptographic hash functions][1] written in pure Rust.\n\nAll algorithms reside in separate crates and are implemented using traits from [`digest`] crate.\nAdditionally all crates do not require the standard library (i.e. `no_std` capable) and can be easily used for bare-metal or WebAssembly programming.\n\n## Supported Algorithms\n\n**Note:** For new applications, or where compatibility with other existing standards is not a primary concern, we strongly recommend to use either BLAKE2, SHA-2 or SHA-3.\n\n| Algorithm | Crate | Crates.io | Documentation | MSRV | [Security] |\n|-----------|-------|:---------:|:-------------:|:----:|:----------:|\n| [Ascon] hash | [`ascon‑hash`] | [![crates.io](https://img.shields.io/crates/v/ascon-hash.svg)](https://crates.io/crates/ascon-hash) | [![Documentation](https://docs.rs/ascon-hash/badge.svg)](https://docs.rs/ascon-hash) | 1.85 | :green_heart: |\n| [BelT] hash | [`belt‑hash`] | [![crates.io](https://img.shields.io/crates/v/belt-hash.svg)](https://crates.io/crates/belt-hash) | [![Documentation](https://docs.rs/belt-hash/badge.svg)](https://docs.rs/belt-hash) | 1.85 | :green_heart: |\n| [BLAKE2] | [`blake2`] | [![crates.io](https://img.shields.io/crates/v/blake2.svg)](https://crates.io/crates/blake2) | [![Documentation](https://docs.rs/blake2/badge.svg)](https://docs.rs/blake2) | 1.85 | :green_heart: |\n| [FSB] | [`fsb`] | [![crates.io](https://img.shields.io/crates/v/fsb.svg)](https://crates.io/crates/fsb) | [![Documentation](https://docs.rs/fsb/badge.svg)](https://docs.rs/fsb) | 1.85 | :green_heart: |\n| [GOST R 34.11-94][GOST94] | [`gost94`] | [![crates.io](https://img.shields.io/crates/v/gost94.svg)](https://crates.io/crates/gost94) | [![Documentation](https://docs.rs/gost94/badge.svg)](https://docs.rs/gost94) | 1.85 | :yellow_heart: |\n| [Grøstl] (Groestl) | [`groestl`] | [![crates.io](https://img.shields.io/crates/v/groestl.svg)](https://crates.io/crates/groestl) | [![Documentation](https://docs.rs/groestl/badge.svg)](https://docs.rs/groestl) | 1.85 | :green_heart: |\n| [JH] | [`jh`] | [![crates.io](https://img.shields.io/crates/v/jh.svg)](https://crates.io/crates/jh) | [![Documentation](https://docs.rs/jh/badge.svg)](https://docs.rs/jh) | 1.85 | :green_heart: |\n| [KangarooTwelve] | [`k12`] | [![crates.io](https://img.shields.io/crates/v/k12.svg)](https://crates.io/crates/k12) | [![Documentation](https://docs.rs/k12/badge.svg)](https://docs.rs/k12) | 1.85 | :green_heart: |\n| [Kupyna] | [`kupyna`] | [![crates.io](https://img.shields.io/crates/v/kupyna.svg)](https://crates.io/crates/kupyna) | [![Documentation](https://docs.rs/kupyna/badge.svg)](https://docs.rs/kupyna) | 1.85 | :green_heart: |\n| [MD2] | [`md2`] | [![crates.io](https://img.shields.io/crates/v/md2.svg)](https://crates.io/crates/md2) | [![Documentation](https://docs.rs/md2/badge.svg)](https://docs.rs/md2) | 1.85 | :broken_heart: |\n| [MD4] | [`md4`] | [![crates.io](https://img.shields.io/crates/v/md4.svg)](https://crates.io/crates/md4) | [![Documentation](https://docs.rs/md4/badge.svg)](https://docs.rs/md4) | 1.85 | :broken_heart: |\n| [MD5] | [`md5`] [:exclamation:] | [![crates.io](https://img.shields.io/crates/v/md-5.svg)](https://crates.io/crates/md-5) | [![Documentation](https://docs.rs/md-5/badge.svg)](https://docs.rs/md-5) | 1.85 | :broken_heart: |\n| [RIPEMD] | [`ripemd`] | [![crates.io](https://img.shields.io/crates/v/ripemd.svg)](https://crates.io/crates/ripemd) | [![Documentation](https://docs.rs/ripemd/badge.svg)](https://docs.rs/ripemd) | 1.85 | :green_heart: |\n| [SHA-1] | [`sha1`] | [![crates.io](https://img.shields.io/crates/v/sha1.svg)](https://crates.io/crates/sha1) | [![Documentation](https://docs.rs/sha1/badge.svg)](https://docs.rs/sha1) | 1.85 | :broken_heart: |\n| [SHA-1 Checked] | [`sha1-checked`] | [![crates.io](https://img.shields.io/crates/v/sha1-checked.svg)](https://crates.io/crates/sha1-checked) | [![Documentation](https://docs.rs/sha1-checked/badge.svg)](https://docs.rs/sha1-checked) | 1.85 | :yellow_heart: |\n| [SHA-2] | [`sha2`] | [![crates.io](https://img.shields.io/crates/v/sha2.svg)](https://crates.io/crates/sha2) | [![Documentation](https://docs.rs/sha2/badge.svg)](https://docs.rs/sha2) | 1.85 | :green_heart: |\n| [SHA-3] (Keccak) | [`sha3`] | [![crates.io](https://img.shields.io/crates/v/sha3.svg)](https://crates.io/crates/sha3) | [![Documentation](https://docs.rs/sha3/badge.svg)](https://docs.rs/sha3) | 1.85 | :green_heart: |\n| [SHABAL] | [`shabal`] | [![crates.io](https://img.shields.io/crates/v/shabal.svg)](https://crates.io/crates/shabal) | [![Documentation](https://docs.rs/shabal/badge.svg)](https://docs.rs/shabal) | 1.85 | :green_heart: |\n| [Skein] | [`skein`] | [![crates.io](https://img.shields.io/crates/v/skein.svg)](https://crates.io/crates/skein) | [![Documentation](https://docs.rs/skein/badge.svg)](https://docs.rs/skein) | 1.85 | :green_heart: |\n| [SM3] (OSCCA GM/T 0004-2012) | [`sm3`] | [![crates.io](https://img.shields.io/crates/v/sm3.svg)](https://crates.io/crates/sm3) | [![Documentation](https://docs.rs/sm3/badge.svg)](https://docs.rs/sm3) | 1.85 | :green_heart: |\n| [Streebog] (GOST R 34.11-2012) | [`streebog`] | [![crates.io](https://img.shields.io/crates/v/streebog.svg)](https://crates.io/crates/streebog) | [![Documentation](https://docs.rs/streebog/badge.svg)](https://docs.rs/streebog) | 1.85 | :yellow_heart: |\n| [Tiger] | [`tiger`] | [![crates.io](https://img.shields.io/crates/v/tiger.svg)](https://crates.io/crates/tiger) | [![Documentation](https://docs.rs/tiger/badge.svg)](https://docs.rs/tiger) | 1.85 | :green_heart: |\n| [Whirlpool] | [`whirlpool`] | [![crates.io](https://img.shields.io/crates/v/whirlpool.svg)](https://crates.io/crates/whirlpool) | [![Documentation](https://docs.rs/whirlpool/badge.svg)](https://docs.rs/whirlpool) | 1.85 | :green_heart: |\n\nNOTE: the [`blake3`] crate implements the `digest` traits used by the rest of the hashes in this repository, but is maintained by the BLAKE3 team.\n\n[Security]: https://en.wikipedia.org/wiki/Hash_function_security_summary\n[:exclamation:]: #crate-names\n\n### Security Level Legend\n\nThe following describes the security level ratings associated with each hash function (i.e. algorithms, not the specific implementation):\n\n| Heart          | Description |\n|:--------------:|-------------|\n| :green_heart:  | No known successful attacks |\n| :yellow_heart: | Theoretical break: security lower than claimed |\n| :broken_heart: | Attack demonstrated in practice: avoid if at all possible |\n\nSee the [Security] page on Wikipedia for more information.\n\n### Crate Names\n\nWhenever possible crates are published under the same name as the crate folder.\nOwners of `md5` [declined](https://github.com/stainless-steel/md5/pull/) to participate in this project.\nThis crate does not implement the [`digest`] traits, so it is not interoperable with the RustCrypto ecosystem.\nThis is why we publish our MD5 implementation as `md-5` and mark it with the :exclamation: mark.\nNote that the library itself is named as `md5`, i.e. inside `use` statements you should use `md5`, not `md_5`.\n\nThe SHA-1 implementation was previously published as `sha-1`, but migrated to `sha1` since v0.10.0.\n`sha-1` will continue to receive v0.10.x patch updates, but will be deprecated after `sha1` v0.11 release.\n\n## Examples\n\nLet us demonstrate how to use crates in this repository using SHA-2 as an example.\n\nFirst add [`sha2`](https://docs.rs/sha2) crate to your `Cargo.toml`:\n\n```toml\n[dependencies]\nsha2 = \"0.10\"\n```\n\nNote that all crates in this repository have an enabled by default `std` feature.\nSo if you plan to use the crate in `no_std` environments, don't forget to disable it:\n\n```toml\n[dependencies]\nsha2 = { version = \"0.10\", default-features = false }\n```\n\n[`sha2`](https://docs.rs/sha2) and the other hash implementation crates re-export the [`digest`] crate and the [`Digest`] trait for convenience, so you don't have to include it in your `Cargo.toml` it as an explicit dependency.\n\nNow you can write the following code:\n\n```rust\nuse sha2::{Sha256, Digest};\n\nlet mut hasher = Sha256::new();\nlet data = b\"Hello world!\";\nhasher.update(data);\n// `update` can be called repeatedly and is generic over `AsRef\u003c[u8]\u003e`\nhasher.update(\"String data\");\n// Note that calling `finalize()` consumes hasher\nlet hash = hasher.finalize();\nprintln!(\"Binary hash: {:?}\", hash);\n```\n\nIn this example `hash` has type `GenericArray\u003cu8, U32\u003e`, which is a generic alternative to `[u8; 32]` defined in the [`generic-array`] crate.\nIf you need to serialize hash value into string, you can use crates like [`base16ct`] and [`base64ct`]:\n```rust\nuse base64ct::{Base64, Encoding};\n\nlet base64_hash = Base64::encode_string(\u0026hash);\nprintln!(\"Base64-encoded hash: {}\", base64_hash);\n\nlet hex_hash = base16ct::lower::encode_string(\u0026hash);\nprintln!(\"Hex-encoded hash: {}\", hex_hash);\n```\n\nInstead of calling `update`, you also can use a chained approach:\n\n```rust\nuse sha2::{Sha256, Digest};\n\nlet hash = Sha256::new()\n    .chain_update(b\"Hello world!\")\n    .chain_update(\"String data\")\n    .finalize();\n```\n\nIf a complete message is available, then you can use the convenience [`Digest::digest`] method:\n\n```rust\nuse sha2::{Sha256, Digest};\n\nlet hash = Sha256::digest(b\"my message\");\n```\n\n### Hashing `Read`able Objects\n\nIf you want to hash data from a type which implements the [`Read`] trait, you can rely on implementation of the [`Write`] trait (requires enabled-by-default `std` feature):\n\n```rust\nuse sha2::{Sha256, Digest};\nuse std::{fs, io};\n\nlet mut file = fs::File::open(\u0026path)?;\nlet mut hasher = Sha256::new();\nlet n = io::copy(\u0026mut file, \u0026mut hasher)?;\nlet hash = hasher.finalize();\n```\n\n### Hash-based Message Authentication Code (HMAC)\n\nIf you want to calculate [Hash-based Message Authentication Code][HMAC] (HMAC), you can use the generic implementation from [`hmac`] crate, which is a part of the [RustCrypto/MACs] repository.\n\n### Generic Code\n\nYou can write generic code over the [`Digest`] trait (or other traits from the [`digest`] crate) which will work over different hash functions:\n\n```rust\nuse sha2::{Sha256, Sha512, Digest};\n\n// Toy example, do not use it in practice!\n// Instead use crates from: https://github.com/RustCrypto/password-hashing\nfn hash_password\u003cD: Digest\u003e(password: \u0026str, salt: \u0026str, output: \u0026mut [u8]) {\n    let mut hasher = D::new();\n    hasher.update(password.as_bytes());\n    hasher.update(b\"$\");\n    hasher.update(salt.as_bytes());\n    output.copy_from_slice(\u0026hasher.finalize())\n}\n\nlet mut buf1 = [0u8; 32];\nhash_password::\u003cSha256\u003e(\"my_password\", \"abcd\", \u0026mut buf1);\n\nlet mut buf2 = [0u8; 64];\nhash_password::\u003cSha512\u003e(\"my_password\", \"abcd\", \u0026mut buf2);\n```\n\nIf you want to use hash functions with trait objects, you can use the [`DynDigest`] trait:\n\n```rust\nuse digest::DynDigest;\n\n// Dynamic hash function\nfn use_hasher(hasher: \u0026mut dyn DynDigest, data: \u0026[u8]) -\u003e Box\u003c[u8]\u003e {\n    hasher.update(data);\n    hasher.finalize_reset()\n}\n\n// You can use something like this when parsing user input, CLI arguments, etc.\n// DynDigest needs to be boxed here, since function return should be sized.\nfn select_hasher(s: \u0026str) -\u003e Box\u003cdyn DynDigest\u003e {\n    match s {\n        \"md5\" =\u003e Box::new(md5::Md5::default()),\n        \"sha1\" =\u003e Box::new(sha1::Sha1::default()),\n        \"sha224\" =\u003e Box::new(sha2::Sha224::default()),\n        \"sha256\" =\u003e Box::new(sha2::Sha256::default()),\n        \"sha384\" =\u003e Box::new(sha2::Sha384::default()),\n        \"sha512\" =\u003e Box::new(sha2::Sha512::default()),\n        _ =\u003e unimplemented!(\"unsupported digest: {}\", s),\n    }\n}\n\nlet mut hasher1 = select_hasher(\"md5\");\nlet mut hasher2 = select_hasher(\"sha512\");\n\n// the `\u0026mut *hasher` is to DerefMut the value out of the Box\n// this is equivalent to `DerefMut::deref_mut(\u0026mut hasher)`\n\n// can be reused due to `finalize_reset()`\nlet hash1_1 = use_hasher(\u0026mut *hasher1, b\"foo\");\nlet hash1_2 = use_hasher(\u0026mut *hasher1, b\"bar\");\nlet hash2_1 = use_hasher(\u0026mut *hasher2, b\"foo\");\n```\n\n## License\n\nAll crates in this repository are licensed under either of\n\n* [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)\n* [MIT license](http://opensource.org/licenses/MIT)\n\nat your option.\n\n### Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.\n\n[//]: # (badges)\n\n[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg\n[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260041-hashes\n[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg\n[deps-image]: https://deps.rs/repo/github/RustCrypto/hashes/status.svg\n[deps-link]: https://deps.rs/repo/github/RustCrypto/hashes\n\n[//]: # (crates)\n\n[`ascon‑hash`]: ./ascon-hash\n[`belt‑hash`]: ./belt-hash\n[`blake2`]: ./blake2\n[`fsb`]: ./fsb\n[`gost94`]: ./gost94\n[`groestl`]: ./groestl\n[`jh`]: ./jh\n[`k12`]: ./k12\n[`kupyna`]: ./kupyna\n[`md2`]: ./md2\n[`md4`]: ./md4\n[`md5`]: ./md5\n[`ripemd`]: ./ripemd\n[`sha1`]: ./sha1\n[`sha1-checked`]: ./sha1-checked\n[`sha2`]: ./sha2\n[`sha3`]: ./sha3\n[`shabal`]: ./shabal\n[`skein`]: ./skein\n[`sm3`]: ./sm3\n[`streebog`]: ./streebog\n[`tiger`]: ./tiger\n[`whirlpool`]: ./whirlpool\n\n[//]: # (footnotes)\n\n[1]: https://en.wikipedia.org/wiki/Cryptographic_hash_function\n[`blake3`]: https://github.com/BLAKE3-team/BLAKE3\n[`base16ct`]: https://docs.rs/base16ct\n[`base64ct`]: https://docs.rs/base64ct\n[`digest`]: https://docs.rs/digest\n[`Digest`]: https://docs.rs/digest/0.10.0/digest/trait.Digest.html\n[`Digest::digest`]: https://docs.rs/digest/0.10.0/digest/trait.Digest.html#tymethod.digest\n[`DynDigest`]: https://docs.rs/digest/0.10.0/digest/trait.DynDigest.html\n[`generic-array`]: https://docs.rs/generic-array\n[HMAC]: https://en.wikipedia.org/wiki/Hash-based_message_authentication_code\n[`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html\n[`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html\n[`hmac`]: https://docs.rs/hmac\n[RustCrypto/MACs]: https://github.com/RustCrypto/MACs\n\n[//]: # (algorithms)\n\n[Ascon]: https://ascon.iaik.tugraz.at\n[BelT]: https://ru.wikipedia.org/wiki/BelT\n[BLAKE2]: https://en.wikipedia.org/wiki/BLAKE_(hash_function)#BLAKE2\n[FSB]: https://en.wikipedia.org/wiki/Fast_syndrome-based_hash\n[GOST94]: https://en.wikipedia.org/wiki/GOST_(hash_function)\n[Grøstl]: https://en.wikipedia.org/wiki/Grøstl\n[JH]: https://www3.ntu.edu.sg/home/wuhj/research/jh\n[KangarooTwelve]: https://keccak.team/kangarootwelve.html\n[Kupyna]: https://eprint.iacr.org/2015/885.pdf\n[MD2]: https://en.wikipedia.org/wiki/MD2_(cryptography)\n[MD4]: https://en.wikipedia.org/wiki/MD4\n[MD5]: https://en.wikipedia.org/wiki/MD5\n[RIPEMD]: https://en.wikipedia.org/wiki/RIPEMD\n[SHA-1]: https://en.wikipedia.org/wiki/SHA-1\n[SHA-1 Checked]: https://github.com/cr-marcstevens/sha1collisiondetection\n[SHA-2]: https://en.wikipedia.org/wiki/SHA-2\n[SHA-3]: https://en.wikipedia.org/wiki/SHA-3\n[SHABAL]: https://www.cs.rit.edu/~ark/20090927/Round2Candidates/Shabal.pdf\n[Skein]: https://schneier.com/academic/skein\n[SM3]: https://en.wikipedia.org/wiki/SM3_(hash_function)\n[Streebog]: https://en.wikipedia.org/wiki/Streebog\n[Whirlpool]: https://en.wikipedia.org/wiki/Whirlpool_(cryptography)\n[Tiger]: http://www.cs.technion.ac.il/~biham/Reports/Tiger/tiger/tiger.html\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frustcrypto%2Fhashes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frustcrypto%2Fhashes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frustcrypto%2Fhashes/lists"}