aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJack O'Connor <[email protected]>2022-03-02 17:21:24 -0500
committerJack O'Connor <[email protected]>2022-03-02 17:39:25 -0500
commitea3bc782d8128d7f52008d459ecd4df8b51979cf (patch)
tree4bcea03e001253f3a3d4e332cc4f7ae3c6facbf7 /src
parent4e84c8c7ae3da71d3aff5ba54d8ffa39a9b90fa0 (diff)
document the extended output security issue found by Aldo Gunsing
https://eprint.iacr.org/2022/283
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs41
1 files changed, 31 insertions, 10 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 8082dbf..1cd9fa0 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -667,7 +667,7 @@ fn compress_parents_parallel(
// As a special case when the SIMD degree is 1, this function will still return
// at least 2 outputs. This guarantees that this function doesn't perform the
// root compression. (If it did, it would use the wrong flags, and also we
-// wouldn't be able to implement exendable ouput.) Note that this function is
+// wouldn't be able to implement exendable output.) Note that this function is
// not used when the whole input is only 1 chunk long; that's a different
// codepath.
//
@@ -1340,16 +1340,37 @@ impl std::io::Write for Hasher {
/// An incremental reader for extended output, returned by
/// [`Hasher::finalize_xof`](struct.Hasher.html#method.finalize_xof).
///
-/// Outputs shorter than the default length of 32 bytes (256 bits)
-/// provide less security. An N-bit BLAKE3 output is intended to provide
-/// N bits of first and second preimage resistance and N/2 bits of
-/// collision resistance, for any N up to 256. Longer outputs don't
-/// provide any additional security.
+/// Shorter BLAKE3 outputs are prefixes of longer ones, and explicitly requesting a short output is
+/// equivalent to truncating the default-length output. Note that this is a difference between
+/// BLAKE2 and BLAKE3.
///
-/// Shorter BLAKE3 outputs are prefixes of longer ones. Explicitly
-/// requesting a short output is equivalent to truncating the
-/// default-length output. (Note that this is different between BLAKE2
-/// and BLAKE3.)
+/// # Security notes
+///
+/// Outputs shorter than the default length of 32 bytes (256 bits) provide less security. An N-bit
+/// BLAKE3 output is intended to provide N bits of first and second preimage resistance and N/2
+/// bits of collision resistance, for any N up to 256. Longer outputs don't provide any additional
+/// security.
+///
+/// [_Block-Cipher-Based Tree Hashing_ by Aldo Gunsing](https://eprint.iacr.org/2022/283) shows
+/// that an extended BLAKE3 output doesn't protect the secrecy of its offset — that is the number
+/// of output bytes that came before, or the argument to
+/// [`seek`](struct.OutputReader.html#method.seek) or
+/// [`position`](struct.OutputReader.html#method.position) — as well as it ideally could. Callers
+/// who rely on secret output lengths or offsets need to pay attention to this, but the vast
+/// majority of callers use constant and/or public lengths and offsets and aren't affected.
+///
+/// The underlying issue is that the BLAKE3 compression function is invertible if an attacker
+/// already knows the message and the key and also observes an extended output. In particular,
+/// inverting the compression function doesn't require knowing the internal `t` parameter that
+/// represents the offset. In other words, an output offset doesn't contribute any entropy towards
+/// protecting its own secrecy or the secrecy of other inputs. However, the offset does benefit
+/// from the entropy of the message and the key, so for example a caller using a 256-bit secret key
+/// is also not affected.
+///
+/// For comparison, AES-CTR has a similar property. If you know the key, you can decrypt a block
+/// from an unknown position in the output stream to recover its block index. However, the Salsa
+/// and ChaCha stream ciphers don't have this property, because they feed their offsets forward
+/// into their output.
#[derive(Clone)]
pub struct OutputReader {
inner: Output,