mirror of
https://github.com/BLAKE3-team/BLAKE3
synced 2025-01-21 15:50:01 +01:00
Apart from being pretty ambiguous in general, the term "context string" has the specific problem that it isn't clear whether it should be describing the input or the output. In fact, it's quite important that it describes the output, because the whole point is to domain-separate different outputs that derive from the *same* input. To make that clearer, rename the "context string" to the "purpose string" in documentation.
205 lines
7.8 KiB
Markdown
205 lines
7.8 KiB
Markdown
# <a href="#"><img src="media/BLAKE3.svg" alt="BLAKE3" height=50></a>
|
|
|
|
BLAKE3 is a cryptographic hash function that is:
|
|
|
|
- **Much faster** than MD5, SHA-1, SHA-2, SHA-3, and BLAKE2.
|
|
- **Secure**, unlike MD5 and SHA-1. And secure against length extension,
|
|
unlike SHA-2.
|
|
- **Highly parallelizable** across any number of threads and SIMD lanes,
|
|
because it's a Merkle tree on the inside.
|
|
- Capable of **verified streaming** and **incremental updates**, again
|
|
because it's a Merkle tree.
|
|
- A **PRF**, **MAC**, **KDF**, and **XOF**, as well as a regular hash.
|
|
- **One algorithm with no variants**, which is fast on x86-64 and also
|
|
on smaller architectures.
|
|
|
|
The [chart below](https://github.com/BLAKE3-team/BLAKE3-specs/blob/master/benchmarks/bar_chart.py)
|
|
is an example benchmark of 16 KiB inputs on modern server hardware (a Cascade
|
|
Lake-SP 8275CL processor). For more detailed benchmarks, see the
|
|
[BLAKE3 paper](https://github.com/BLAKE3-team/BLAKE3-specs/blob/master/blake3.pdf).
|
|
|
|
<p align="center">
|
|
<img src="media/speed.svg" alt="performance graph">
|
|
</p>
|
|
|
|
BLAKE3 is based on an optimized instance of the established hash
|
|
function [BLAKE2](https://blake2.net) and on the [original Bao tree
|
|
mode](https://github.com/oconnor663/bao/blob/master/docs/spec_0.9.1.md).
|
|
The specifications and design rationale are available in the [BLAKE3
|
|
paper](https://github.com/BLAKE3-team/BLAKE3-specs/blob/master/blake3.pdf).
|
|
The default output size is 256 bits. The current version of
|
|
[Bao](https://github.com/oconnor663/bao) implements verified streaming
|
|
with BLAKE3.
|
|
|
|
This repository is the official implementation of BLAKE3. It includes:
|
|
|
|
* The [`blake3`](https://crates.io/crates/blake3) Rust crate, which
|
|
includes optimized implementations for SSE2, SSE4.1, AVX2, AVX-512,
|
|
and NEON, with automatic runtime CPU feature detection on x86. The
|
|
`rayon` feature provides multithreading.
|
|
|
|
* The [`b3sum`](https://crates.io/crates/b3sum) Rust crate, which
|
|
provides a command line interface. It uses multithreading by default,
|
|
making it an order of magnitude faster than e.g. `sha256sum` on
|
|
typical desktop hardware.
|
|
|
|
* The [C implementation](c), which like the Rust implementation includes
|
|
SIMD code and runtime CPU feature detection on x86. Unlike the Rust
|
|
implementation, it's not currently multithreaded. See
|
|
[`c/README.md`](c/README.md).
|
|
|
|
* The [reference implementation](reference_impl/reference_impl.rs),
|
|
which is discussed in Section 5.1 of the [BLAKE3
|
|
paper](https://github.com/BLAKE3-team/BLAKE3-specs/blob/master/blake3.pdf).
|
|
This implementation is much smaller and simpler than the optimized
|
|
ones above. If you want to see how BLAKE3 works, or you're writing a
|
|
port that doesn't need multithreading or SIMD optimizations, start
|
|
here.
|
|
|
|
* A [set of test
|
|
vectors](https://github.com/BLAKE3-team/BLAKE3/blob/master/test_vectors/test_vectors.json)
|
|
that covers extended outputs, all three modes, and a variety of input
|
|
lengths.
|
|
|
|
* [](https://github.com/BLAKE3-team/BLAKE3/actions)
|
|
|
|
BLAKE3 was designed by:
|
|
|
|
* [@oconnor663 ](https://github.com/oconnor663) (Jack O'Connor)
|
|
* [@sneves](https://github.com/sneves) (Samuel Neves)
|
|
* [@veorq](https://github.com/veorq) (Jean-Philippe Aumasson)
|
|
* [@zookozcash](https://github.com/zookozcash) (Zooko)
|
|
|
|
The development of BLAKE3 was sponsored by
|
|
[Teserakt](https://teserakt.io) and [Electric Coin Company](https://electriccoin.co).
|
|
|
|
*NOTE: BLAKE3 is not a password hashing algorithm, because it's
|
|
designed to be fast, whereas password hashing should not be fast. If you
|
|
hash passwords to store the hashes or if you derive keys from passwords,
|
|
we recommend [Argon2](https://github.com/P-H-C/phc-winner-argon2).*
|
|
|
|
## Usage
|
|
|
|
### The `b3sum` utility
|
|
|
|
The `b3sum` command line utility prints the BLAKE3 hashes of files or of
|
|
standard input. Prebuilt binaries are available for Linux, Windows, and
|
|
macOS (requiring the [unidentified developer
|
|
workaround](https://support.apple.com/guide/mac-help/open-a-mac-app-from-an-unidentified-developer-mh40616/mac))
|
|
on the [releases page](https://github.com/BLAKE3-team/BLAKE3/releases).
|
|
If you've [installed Rust and
|
|
Cargo](https://doc.rust-lang.org/cargo/getting-started/installation.html),
|
|
you can also build `b3sum` yourself with:
|
|
|
|
```bash
|
|
cargo install b3sum
|
|
```
|
|
|
|
If `rustup` didn't configure your `PATH` for you, you might need to go
|
|
looking for the installed binary in e.g. `~/.cargo/bin`. You can test
|
|
out how fast BLAKE3 is on your machine by creating a big file and
|
|
hashing it, for example:
|
|
|
|
```bash
|
|
# Create a 1 GB file.
|
|
head -c 1000000000 /dev/zero > /tmp/bigfile
|
|
# Hash it with SHA-256.
|
|
time openssl sha256 /tmp/bigfile
|
|
# Hash it with BLAKE3.
|
|
time b3sum /tmp/bigfile
|
|
```
|
|
|
|
### The `blake3` crate [](https://docs.rs/blake3)
|
|
|
|
To use BLAKE3 from Rust code, add a dependency on the `blake3` crate to
|
|
your `Cargo.toml`. Here's an example of hashing some input bytes:
|
|
|
|
```rust
|
|
// Hash an input all at once.
|
|
let hash1 = blake3::hash(b"foobarbaz");
|
|
|
|
// Hash an input incrementally.
|
|
let mut hasher = blake3::Hasher::new();
|
|
hasher.update(b"foo");
|
|
hasher.update(b"bar");
|
|
hasher.update(b"baz");
|
|
let hash2 = hasher.finalize();
|
|
assert_eq!(hash1, hash2);
|
|
|
|
// Extended output. OutputReader also implements Read and Seek.
|
|
let mut output = [0; 1000];
|
|
let mut output_reader = hasher.finalize_xof();
|
|
output_reader.fill(&mut output);
|
|
assert_eq!(&output[..32], hash1.as_bytes());
|
|
|
|
// Print a hash as hex.
|
|
println!("{}", hash1.to_hex());
|
|
```
|
|
|
|
Besides `hash`, BLAKE3 provides two other modes, `keyed_hash` and
|
|
`derive_key`. The `keyed_hash` mode takes a 256-bit key:
|
|
|
|
```rust
|
|
// MAC an input all at once.
|
|
let example_key = [42u8; 32];
|
|
let mac1 = blake3::keyed_hash(&example_key, b"example input");
|
|
|
|
// MAC incrementally.
|
|
let mut hasher = blake3::Hasher::new_keyed(&example_key);
|
|
hasher.update(b"example input");
|
|
let mac2 = hasher.finalize();
|
|
assert_eq!(mac1, mac2);
|
|
```
|
|
|
|
The `derive_key` mode takes a purpose string of any length and key material of
|
|
any length (not a password), and it outputs a derived key of any length. The
|
|
purpose string should be hardcoded, globally unique, and application-specific.
|
|
A good default format for the purpose string is `"[application] [commit
|
|
timestamp] [purpose]"`:
|
|
|
|
```rust
|
|
// Derive a couple of subkeys for different purposes.
|
|
const EMAIL_PURPOSE: &str = "BLAKE3 example 2020-01-07 17:10:44 email key";
|
|
const API_PURPOSE: &str = "BLAKE3 example 2020-01-07 17:11:21 API key";
|
|
let input_key_material = b"usually at least 32 random bytes, not a password!";
|
|
let mut email_key = [0; 32];
|
|
blake3::derive_key(EMAIL_PURPOSE, input_key_material, &mut email_key);
|
|
let mut api_key = [0; 32];
|
|
blake3::derive_key(API_PURPOSE, input_key_material, &mut api_key);
|
|
assert!(email_key != api_key);
|
|
```
|
|
|
|
### The C implementation
|
|
|
|
See [`c/README.md`](c/README.md).
|
|
|
|
### Other implementations
|
|
|
|
We post links to third-party bindings and implementations on the
|
|
[@BLAKE3team Twitter account](https://twitter.com/BLAKE3team) whenever
|
|
we hear about them. Some highlights include [an optimized Go
|
|
implementation](https://github.com/zeebo/blake3), [Wasm bindings for
|
|
Node.js and browsers](https://github.com/connor4312/blake3), [binary
|
|
wheels for Python](https://github.com/oconnor663/blake3-py), [.NET
|
|
bindings](https://github.com/xoofx/Blake3.NET), and [JNI
|
|
bindings](https://github.com/sken77/BLAKE3jni).
|
|
|
|
## Contributing
|
|
|
|
Please see [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
|
|
## Intellectual property
|
|
|
|
The Rust code is copyright Jack O'Connor, 2019-2020. The C code is
|
|
copyright Samuel Neves and Jack O'Connor, 2019-2020. The assembly code
|
|
is copyright Samuel Neves, 2019-2020.
|
|
|
|
This work is released into the public domain with CC0 1.0.
|
|
Alternatively, it is licensed under the Apache License 2.0.
|
|
|
|
## Miscellany
|
|
|
|
- [@veorq](https://github.com/veorq) and
|
|
[@oconnor663](https://github.com/oconnor663) did [a podcast
|
|
interview](https://www.cryptography.fm/3) about designing BLAKE3.
|