2020-03-30 16:08:16 +02:00
|
|
|
# <a href="#"><img src="media/BLAKE3.svg" alt="BLAKE3" height=50></a>
|
2019-12-04 18:57:05 +01:00
|
|
|
|
2020-01-09 00:27:04 +01:00
|
|
|
BLAKE3 is a cryptographic hash function that is:
|
2019-12-04 18:57:05 +01:00
|
|
|
|
2020-01-09 00:41:53 +01:00
|
|
|
- **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.
|
2020-01-06 02:42:20 +01:00
|
|
|
|
2020-02-04 15:38:31 +01:00
|
|
|
The [chart below](https://github.com/BLAKE3-team/BLAKE3-specs/blob/master/benchmarks/bar_chart.py)
|
|
|
|
shows BLAKE3's performance on modern server hardware, an Intel Cascade
|
|
|
|
Lake-SP 8275CL processor:
|
2020-01-08 15:29:04 +01:00
|
|
|
|
|
|
|
<p align="center">
|
|
|
|
<img src="media/speed.svg" alt="performance graph">
|
|
|
|
</p>
|
|
|
|
|
2020-01-09 00:27:04 +01:00
|
|
|
BLAKE3 is based on an optimized instance of the established hash
|
2020-01-13 18:00:56 +01:00
|
|
|
function [BLAKE2](https://blake2.net) and on the [original Bao tree
|
2020-01-09 00:27:04 +01:00
|
|
|
mode](https://github.com/oconnor663/bao/blob/master/docs/spec_0.9.1.md).
|
2020-01-13 18:00:56 +01:00
|
|
|
The specifications and design rationale are available in the [BLAKE3
|
2020-01-09 21:40:22 +01:00
|
|
|
paper](https://github.com/BLAKE3-team/BLAKE3-specs/blob/master/blake3.pdf).
|
2020-01-13 18:00:56 +01:00
|
|
|
The default output size is 256 bits. The current version of
|
|
|
|
[Bao](https://github.com/oconnor663/bao) implements verified streaming
|
|
|
|
with BLAKE3.
|
2020-01-08 15:29:04 +01:00
|
|
|
|
2020-01-27 19:02:00 +01:00
|
|
|
This repository is the official implementation of BLAKE3. It includes:
|
2020-01-08 15:29:04 +01:00
|
|
|
|
|
|
|
* The [`blake3`](https://crates.io/crates/blake3) Rust crate, which
|
2020-09-01 15:47:24 +02:00
|
|
|
includes optimized implementations for SSE2, SSE4.1, AVX2, AVX-512,
|
|
|
|
and NEON, with automatic runtime CPU feature detection on x86. The
|
2020-09-01 15:52:36 +02:00
|
|
|
`rayon` feature provides multithreading.
|
2020-01-08 15:29:04 +01:00
|
|
|
|
2020-01-27 19:02:00 +01:00
|
|
|
* The [`b3sum`](https://crates.io/crates/b3sum) Rust crate, which
|
2020-09-01 15:52:36 +02:00
|
|
|
provides a command line interface. It uses multithreading by default,
|
2020-03-28 22:27:31 +01:00
|
|
|
making it an order of magnitude faster than e.g. `sha256sum` on
|
|
|
|
typical desktop hardware.
|
2020-01-08 15:29:04 +01:00
|
|
|
|
2020-01-27 19:02:00 +01:00
|
|
|
* The [C implementation](c), which like the Rust implementation includes
|
2020-03-28 22:27:31 +01:00
|
|
|
SIMD code and runtime CPU feature detection on x86. Unlike the Rust
|
2020-09-01 15:52:36 +02:00
|
|
|
implementation, it's not currently multithreaded. See
|
2020-03-28 22:27:31 +01:00
|
|
|
[`c/README.md`](c/README.md).
|
2020-01-08 15:29:04 +01:00
|
|
|
|
2020-01-27 19:02:00 +01:00
|
|
|
* 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
|
2020-09-01 15:52:36 +02:00
|
|
|
port that doesn't need multithreading or SIMD optimizations, start
|
2020-01-27 19:02:00 +01:00
|
|
|
here.
|
|
|
|
|
2020-05-15 19:19:59 +02:00
|
|
|
* 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.
|
|
|
|
|
2020-03-30 16:08:16 +02:00
|
|
|
* [![Actions Status](https://github.com/BLAKE3-team/BLAKE3/workflows/tests/badge.svg)](https://github.com/BLAKE3-team/BLAKE3/actions)
|
|
|
|
|
2019-12-04 18:57:05 +01:00
|
|
|
BLAKE3 was designed by:
|
|
|
|
|
2020-01-07 21:21:00 +01:00
|
|
|
* [@oconnor663 ](https://github.com/oconnor663) (Jack O'Connor)
|
2019-12-04 18:57:05 +01:00
|
|
|
* [@sneves](https://github.com/sneves) (Samuel Neves)
|
|
|
|
* [@veorq](https://github.com/veorq) (Jean-Philippe Aumasson)
|
2019-12-09 21:51:58 +01:00
|
|
|
* [@zookozcash](https://github.com/zookozcash) (Zooko)
|
2019-12-04 18:57:05 +01:00
|
|
|
|
2020-01-06 04:56:26 +01:00
|
|
|
The development of BLAKE3 was sponsored by
|
2020-01-07 00:25:53 +01:00
|
|
|
[Teserakt](https://teserakt.io) and [Electric Coin Company](https://electriccoin.co).
|
2020-01-06 04:56:26 +01:00
|
|
|
|
2020-01-08 17:16:24 +01:00
|
|
|
*NOTE: BLAKE3 is not a password hashing algorithm, because it's
|
2020-01-06 05:28:20 +01:00
|
|
|
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,
|
2020-01-08 17:16:24 +01:00
|
|
|
we recommend [Argon2](https://github.com/P-H-C/phc-winner-argon2).*
|
2019-12-04 18:57:05 +01:00
|
|
|
|
|
|
|
## Usage
|
|
|
|
|
2020-01-13 19:21:06 +01:00
|
|
|
### The `b3sum` utility
|
2020-01-08 15:29:04 +01:00
|
|
|
|
2020-04-28 03:30:54 +02:00
|
|
|
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
|
2020-01-07 23:39:26 +01:00
|
|
|
Cargo](https://doc.rust-lang.org/cargo/getting-started/installation.html),
|
2020-04-28 03:30:54 +02:00
|
|
|
you can also build `b3sum` yourself with:
|
2020-01-07 23:39:26 +01:00
|
|
|
|
|
|
|
```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
|
2020-04-28 03:30:54 +02:00
|
|
|
hashing it, for example:
|
2020-01-07 23:39:26 +01:00
|
|
|
|
|
|
|
```bash
|
|
|
|
# Create a 1 GB file.
|
|
|
|
head -c 1000000000 /dev/zero > /tmp/bigfile
|
|
|
|
# Hash it with SHA-256.
|
2020-01-07 23:57:50 +01:00
|
|
|
time openssl sha256 /tmp/bigfile
|
2020-01-07 23:39:26 +01:00
|
|
|
# Hash it with BLAKE3.
|
|
|
|
time b3sum /tmp/bigfile
|
|
|
|
```
|
|
|
|
|
2020-01-08 15:29:04 +01:00
|
|
|
### The `blake3` crate
|
|
|
|
|
2020-01-07 23:39:26 +01:00
|
|
|
To use BLAKE3 from Rust code, add a dependency on the `blake3` crate to
|
2020-03-31 18:36:41 +02:00
|
|
|
your `Cargo.toml`. Here's an example of hashing some input bytes:
|
2020-01-07 23:39:26 +01:00
|
|
|
|
|
|
|
```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());
|
2020-08-14 12:00:13 +02:00
|
|
|
|
2020-08-14 17:30:46 +02:00
|
|
|
// Print a hash as hex.
|
|
|
|
println!("{}", hash1.to_hex());
|
2020-01-07 23:39:26 +01:00
|
|
|
```
|
|
|
|
|
|
|
|
Besides `hash`, BLAKE3 provides two other modes, `keyed_hash` and
|
|
|
|
`derive_key`. The `keyed_hash` mode takes a 256-bit key:
|
|
|
|
|
|
|
|
```rust
|
2020-01-08 00:04:02 +01:00
|
|
|
// MAC an input all at once.
|
2020-01-07 23:39:26 +01:00
|
|
|
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 context string of any length and key
|
|
|
|
material of any length, and it outputs a derived key of any length. The
|
|
|
|
context string should be hardcoded, globally unique, and
|
|
|
|
application-specific. A good default format for the context string is
|
|
|
|
`"[application] [commit timestamp] [purpose]"`:
|
|
|
|
|
|
|
|
```rust
|
|
|
|
// Derive a couple of subkeys for different purposes.
|
|
|
|
const EMAIL_CONTEXT: &str = "BLAKE3 example 2020-01-07 17:10:44 email key";
|
|
|
|
const API_CONTEXT: &str = "BLAKE3 example 2020-01-07 17:11:21 API key";
|
|
|
|
let input_key = b"some very secret key material (>'-')> <('-'<) ^('-')^";
|
|
|
|
let mut email_key = [0; 32];
|
|
|
|
blake3::derive_key(EMAIL_CONTEXT, input_key, &mut email_key);
|
|
|
|
let mut api_key = [0; 32];
|
|
|
|
blake3::derive_key(API_CONTEXT, input_key, &mut api_key);
|
|
|
|
assert!(email_key != api_key);
|
|
|
|
```
|
2019-12-04 18:57:05 +01:00
|
|
|
|
2020-03-16 22:38:08 +01:00
|
|
|
### The C implementation
|
|
|
|
|
|
|
|
See [`c/README.md`](c/README.md).
|
|
|
|
|
|
|
|
### Other implementations
|
|
|
|
|
2020-03-17 19:25:57 +01:00
|
|
|
We post links to third-party bindings and implementations on the
|
2020-03-16 22:38:08 +01:00
|
|
|
[@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), and [binary
|
|
|
|
wheels for Python](https://github.com/oconnor663/blake3-py).
|
|
|
|
|
2019-12-04 18:57:05 +01:00
|
|
|
## Contributing
|
|
|
|
|
2020-01-08 15:29:04 +01:00
|
|
|
Please see [CONTRIBUTING.md](CONTRIBUTING.md).
|
2019-12-04 18:57:05 +01:00
|
|
|
|
2020-01-05 21:49:57 +01:00
|
|
|
## Intellectual property
|
|
|
|
|
2020-08-19 16:50:18 +02:00
|
|
|
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.
|
2019-12-04 18:57:05 +01:00
|
|
|
|
2020-01-08 00:04:02 +01:00
|
|
|
This work is released into the public domain with CC0 1.0.
|
|
|
|
Alternatively, it is licensed under the Apache License 2.0.
|