1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
//! Hashing that *mitigates* a detected collision attack instead of reporting
//! the colliding digest.
//!
//! This is the special mode. Prefer [`crate::Hasher`]. A mitigated digest
//! matches no other SHA-1 implementation, so you cannot use it as a shared
//! identifier.
//!
//! Use this mode when you must produce a usable digest during an attack and
//! no external system must agree with the value. Examples are a private
//! content-addressed store, a cache key, and a pipeline with no error path.
use fmt;
use crate::;
/// A collision attack was detected, and mitigated.
///
/// [`Hasher::finalize`] returns this. You can use the digest as an
/// identity, because no message is known to give the same value. But it
/// matches no other SHA-1 implementation, and an attacker made the input.
/// SHA-1 hasher that mitigates a detected collision attack.
///
/// A message that is not part of an attack gives plain SHA-1. A message that
/// is part of one gets a *mitigated* digest, so the two colliding messages
/// give different values and the collision has no effect. Finalization still
/// reports the attack, because the digest is then non-standard and an attacker
/// made the input.
///
/// # Examples
///
/// ```
/// use sha1dc::mitigate;
///
/// let mut hasher = mitigate::Hasher::new();
/// hasher.update(b"hello world");
///
/// match hasher.finalize() {
/// Ok(digest) => println!("{digest}"),
/// // You can use this digest, but it is non-standard and an attacker made
/// // the input.
/// Err(mitigated) => println!("attack detected, hashed as {}", mitigated.digest()),
/// }
/// ```
Inner);
hasher_common!;
/// Hashes `data`, mitigating a detected collision attack.
///
/// This is the one-shot form of [`Hasher`]. For the usual non-mitigating form,
/// see [`crate::digest`].
///
/// # Examples
///
/// ```
/// let digest = sha1dc::mitigate::digest(b"hello world").expect("no collision");
/// assert_eq!(digest.to_string(), "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed");
/// ```