SHA-1 is cryptographically broken, because chosen-prefix collisions against it
are practical. However, there are still cases where it is needed for
compatibility, such as in git's object identifiers.
This security issue can be mitigated by detecting those manufactured collisions. This crate follows the method of Marc Stevens and Dan Shumow, which finds the message blocks that a collision attack produces and reports them (paper).
To implement filtering for known disturbance vectors, it follows a code
generation approach. Each condition for an attack is a linear equation over two
bits of the expanded message. A solver searches the space they span for a set of
equations that suits the target instruction set, and emits code for it. Current
targets are neon, sse2 and avx2, as well as a scalar baseline.
Where available, the implementation also uses SHA-1 hardware instructions on
x86_64 and aarch64. Detection still does more work per block than plain
SHA-1, and costs 14% to 23% of throughput, depending on the machine.
let digest = sha1dc::digest(b"hello world")?;
assert_eq!(digest.to_string(), "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed");Two modes are provided, as two separate Hasher structs. Hasher keeps the
standard digest, with output equivalent to a non-detecting SHA-1
implementation. mitigate::Hasher computes an alternative digest instead. Both
report a detected attack as an error. The documentation covers both.
These figures compare the crate against two others: sha1, which does no
detection at all, and sha1-checked, which detects the same collisions and
is a direct translation of the original C code to Rust. Each is at the best it
can do on the machine. The machines are an Apple M4 laptop, an EC2 c7i.xlarge
and an EC2 c8g.xlarge. Throughput is in MiB/s, and as a fraction of the sha1
row.
| implementation | Apple M4 | Xeon Platinum 8488C | Graviton4 |
|---|---|---|---|
sha1 0.11.0 |
2948 (100%) | 1872 (100%) | 1616 (100%) |
sha1dc (this crate) |
2404 (82%) | 1446 (77%) | 1394 (86%) |
sha1-checked 0.11.0-rc.0 |
852 (29%) | 528 (28%) | 456 (28%) |
sha1 and sha1dc both take the SHA-1 instructions of the machine,
SHA-NI on the Xeon and the ARMv8 ones on the M4 and the Graviton4, and
differ in whether they detect. The sha1dc shortfall from 100% is therefore
what detection costs: 14% to 23%, depending on the machine.
std(default): Enables run-time CPU feature detection for hardware acceleration andstd::io::Writesupport for the hasher.
Licensed under either of Apache License, Version 2.0 or MIT license at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this project by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.