‘Blakingly’ Fast Hashing in Rust

We have Jean-Philippe Aumasson coming along on 10 Feb 2023 to speak to our students [here]. And, as the co-creator of SipHash and the BLAKE…

‘Blakingly’ Fast Hashing in Rust

We have Jean-Philippe Aumasson coming along on 10 Feb 2023 to speak to our students [here]. And, as the co-creator of SipHash and the BLAKE hashing method, we hope we will get an insight into the wonderful world of cryptographic hashing … especially in how to make them super fast.

BLAKE 3

Ask someone into cybersecurity about hashing methods, and they will probably identify MD5, SHA-1, SHA-256 (SHA-2) and SHA-3. So while NIST standardized the Keccak method for SHA-3, it is BLAKE 3 that is now being adopted in many systems. Why? Because it is now around six times faster than SHA-1:

So let’s do a bit of secure coding of Blake hashes such Rust. As we are using Rust, it will be so much faster than Python and Node.js.

BLAKE3 and Rust

BLAKE, BLAKE2 and BLAKE3 are hash functions based on the ChaCha stream cipher, and which was one of the finalists in the NIST competition for SHA-3. We will now implement these hashing methods, alongside other popular ones.

First we create the with:

cargo new blake

We then go into the blake folder, and add the following to the cargo.toml file:

[package]
name = "blake"
version = "1.0.0"
authors = ["Bill"]

[dependencies]
blake2 = "0.8"
blake3="0.1"
sha2 = "0.8"
sha3 = "0.8"
digest = "0.8"
sha1="0.6"

TThis will import the Blake2, Blake3, SHA2, SHA3, and SHA1 crates. Next we go into the src folder, and edit the main.rs file with [here]:

extern crate blake2;
extern crate digest;
extern crate sha2;
extern crate sha1;
extern crate sha3;

use blake2::{Blake2b, Blake2s, Digest};
use sha2::Sha256;
use sha3::{Sha3_224,Sha3_256,Sha3_384,Sha3_512};
use std::env;

fn main() {
let mut string = String::from("Hello world!");
let args: Vec = env::args().collect();
if args.len() >1 {
string = args[1].clone();
}
println!("Data: {}",string);
let data = string.as_bytes();

let hash = Blake2b::digest(data);
println!("\nBlake 2b Hash: {:x}", hash);

let hash = Blake2s::digest(data);
println!("\nBlake 2s Hash: {:x}", hash);

let hash1 = blake3::hash(data).to_hex();
println!("\nBlake3 Hash: {}", hash1);

let mut m = sha1::Sha1::new();
m.update(data);
println!("\nSHA-1 Hash: {}", m.digest().to_string());
let hash = Sha256::digest(data);
println!("SHA-256 Hash: {:x}", hash);
let hash = Sha3_224::digest(data);
println!("SHA3-244 Hash: {:x}", hash);

let hash = Sha3_256::digest(data);
println!("SHA3-256 Hash: {:x}", hash);

let hash = Sha3_384::digest(data);
println!("SHA3-384 Hash: {:x}", hash);

let hash = Sha3_512::digest(data);
println!("SHA3-512 Hash: {:x}", hash);
}

Finally we simply build with:

cargo build

A sample run is [here]:

Data: The quick brown fox jumps over the lazy dog
Blake 2b Hash: a8add4bdddfd93e4877d2746e62817b116364a1fa7bc148d95090bc7333b3673f82401cf7aa2e4cb1ecd90296e3f14cb5413f8ed77be73045b13914cdcd6a918
Blake 2s Hash: 606beeec743ccbeff6cbcdf5d5302aa855c256c29b88c8ed331ea1a6bf3c8812
Blake3 Hash: 2f1514181aadccd913abd94cfa592701a5686ab23f8df1dff1b74710febc6d4a
SHA-1 Hash: 2fd4e1c67a2d28fced849ee1bb76e7391b93eb12
SHA-256 Hash: d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592
SHA3-244 Hash: d15dadceaa4d5d7bb3b48f446421d542e08ad8887305e28d58335795
SHA3-256 Hash: 69070dda01975c8c120c3aada1b282394e7f032fa9cf32f4cb2259a0897dfc04
SHA3-384 Hash: 7063465e08a93bce31cd89d2e3ca8f602498696e253592ed26f07bf7e703cf328581e1471a7ba7ab119b1a9ebdf8be41
SHA3-512 Hash: 01dedd5de4ef14642445ba5f5b97c15e47b9ad931326e4b0727cd94cefc44fff23f07bf543139939b49128caf436dc1bdee54fcb24023a08d9403f9b4bf0d450

Here is the running code:

https://asecuritysite.com/rust/rust_blake

Conclusions

So, just because you don’t win a NIST competition for standardization, doesn’t mean that the method will never take off. With AES, we now have ChaCha20, and with SHA-3, we now have BLAKE-3. If you want to learn more about the BLAKE hash, try here:

https://asecuritysite.com/blake/