Skip to content

Latest commit

 

History

History
233 lines (171 loc) · 12.3 KB

README.md

File metadata and controls

233 lines (171 loc) · 12.3 KB

RustCrypto: hashes Project Chat dependency status

Collection of cryptographic hash functions written in pure Rust.

All algorithms reside in the separate crates and implemented using traits from digest crate. Additionally all crates do not require the standard library (i.e. no_std capable) and can be easily used for bare-metal or WebAssembly programming.

Supported algorithms

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.

Algorithm Crate Crates.io Documentation MSRV Security
BLAKE2 blake2 crates.io Documentation Minimum Supported Rust Version 💚
FSB fsb crates.io Documentation Minimum Supported Rust Version 💚
GOST R 34.11-94 gost94 crates.io Documentation Minimum Supported Rust Version 💛
Grøstl (Groestl) groestl crates.io Documentation Minimum Supported Rust Version 💚
KangarooTwelve k12 crates.io Documentation Minimum Supported Rust Version 💚
MD2 md2 crates.io Documentation Minimum Supported Rust Version 💔
MD4 md4 crates.io Documentation Minimum Supported Rust Version 💔
MD5 md-5 crates.io Documentation Minimum Supported Rust Version 💔
RIPEMD ripemd crates.io Documentation Minimum Supported Rust Version 💚
SHA-1 sha-1 crates.io Documentation Minimum Supported Rust Version 💔
SHA-2 sha2 crates.io Documentation Minimum Supported Rust Version 💚
SHA-3 (Keccak) sha3 crates.io Documentation Minimum Supported Rust Version 💚
SHABAL shabal crates.io Documentation Minimum Supported Rust Version 💚
SM3 (OSCCA GM/T 0004-2012) sm3 crates.io Documentation Minimum Supported Rust Version 💚
Streebog (GOST R 34.11-2012) streebog crates.io Documentation Minimum Supported Rust Version 💛
Tiger tiger crates.io Documentation Minimum Supported Rust Version 💚
Whirlpool whirlpool crates.io Documentation Minimum Supported Rust Version 💚

NOTE: the BLAKE3 crate implements the digest traits used by the rest of the hashes in this repository, but is maintained by the BLAKE3 team.

Crate names

Whenever possible crates are published under the the same name as the crate folder. Owners of md5 and sha1 crates declined (1, 2) to participate in this project Those crates do not implement the [digest] traits, so they are not interoperable with the RustCrypto ecosystem. This is why crates marked by ❗ are published under md-5 and sha-1 names respectively.

Security Level Legend

The following describes the security level ratings associated with each hash function (i.e. algorithms, not the specific implementation):

Heart Description
💚 No known successful attacks
💛 Theoretical break: security lower than claimed
💔 Attack demonstrated in practice: avoid if at all possible

See the Security page on Wikipedia for more information.

Minimum Supported Rust Version (MSRV) Policy

MSRV bumps are considered breaking changes and will be performed only with minor version bump.

Usage

Let us demonstrate how to use crates in this repository using SHA-2 as an example.

First add sha2 crate to your Cargo.toml:

[dependencies]
sha2 = "0.10"

Note that all crates in this repository have an enabled by default std feature. So if you plan to use the crate in no_std environments, don't forget to disable it:

[dependencies]
sha2 = { version = "0.10", default-features = false }

sha2 and other crates re-export the digest crate and the Digest trait for convenience, so you don't have to add digest crate as an explicit dependency.

Now you can write the following code:

use sha2::{Sha256, Digest};

let mut hasher = Sha256::new();
let data = b"Hello world!";
hasher.update(data);
// `update` can be called repeatedly and is generic over `AsRef<[u8]>`
hasher.update("String data");
// Note that calling `finalize()` consumes hasher
let hash = hasher.finalize();
println!("Result: {:x}", hash);

In this example hash has type GenericArray<u8, U32>, which is a generic alternative to [u8; 32] defined in the generic-array crate.

Alternatively, you can use chained approach, which is equivalent to the previous example:

use sha2::{Sha256, Digest};

let hash = Sha256::new()
    .chain(b"Hello world!")
    .chain("String data")
    .finalize();
println!("Result: {:x}", hash);

If a complete message is available, then you also can use the convenience digest method:

use sha2::{Sha256, Digest};

let hash = Sha256::digest(b"my message");
println!("Result: {:x}", hash);

Hashing Readable objects

If you want to hash data from a type which imlements the Read trait, you can rely on implementation of the Write trait (requires enabled-by-default std feature):

use sha2::{Sha256, Digest};
use std::{fs, io};

let mut file = fs::File::open(&path)?;
let mut hasher = Sha256::new();
let n = io::copy(&mut file, &mut hasher)?;
let hash = hasher.finalize();

println!("Bytes processed: {}", n);
println!("Hash value: {:x}", hash);

Hash-based Message Authentication Code (HMAC)

If you want to calculate Hash-based Message Authentication Code (HMAC), you can use the generic implementation from hmac crate, which is a part of the RustCrypto/MACs repository.

Generic code

You can write generic code over the Digest trait (or other traits from the digest crate) which will work over different hash functions:

use sha2::{Sha256, Sha512, Digest};

// Toy example, do not use it in practice!
// Instead use crates from: https://github.com/RustCrypto/password-hashing
fn hash_password<D: Digest>(password: &str, salt: &str, output: &mut [u8]) {
    let mut hasher = D::new();
    hasher.update(password.as_bytes());
    hasher.update(b"$");
    hasher.update(salt.as_bytes());
    output.copy_from_slice(&hasher.finalize())
}

let mut buf1 = [0u8; 32];
hash_password::<Sha256>("my_password", "abcd", &mut buf1);

let mut buf2 = [0u8; 64];
hash_password::<Sha512>("my_password", "abcd", &mut buf2);

If you want to use hash functions with trait objects, you can use the DynDigest trait:

use sha2::{Sha256, Sha512, digest::DynDigest};

fn dyn_hash(hasher: &mut dyn DynDigest, data: &[u8]) -> Box<[u8]> {
    hasher.update(data);
    hasher.finalize_reset()
}

let mut sha256_hasher = Sha256::default();
let mut sha512_hasher = Sha512::default();

let res1 = dyn_hash(&mut sha256_hasher, b"foo");
let res2 = dyn_hash(&mut sha256_hasher, b"bar");
let res3 = dyn_hash(&mut sha512_hasher, b"foo");
let res4 = dyn_hash(&mut sha512_hasher, b"bar");

License

All crates licensed under either of

at your option.

Contribution

Unless 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.