Coverage Report

Created: 2026-09-28 07:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/sha1-0.10.6/src/lib.rs
Line
Count
Source
1
//! Pure Rust implementation of the [SHA-1][1] cryptographic hash algorithm
2
//! with optional hardware-specific optimizations.
3
//!
4
//! # 🚨 Warning: Cryptographically Broken! 🚨
5
//!
6
//! The SHA-1 hash function should be considered cryptographically broken and
7
//! unsuitable for further use in any security critical capacity, as it is
8
//! [practically vulnerable to chosen-prefix collisions][2].
9
//!
10
//! We provide this crate for legacy interoperability purposes only.
11
//!
12
//! # Usage
13
//!
14
//! ```rust
15
//! use hex_literal::hex;
16
//! use sha1::{Sha1, Digest};
17
//!
18
//! // create a Sha1 object
19
//! let mut hasher = Sha1::new();
20
//!
21
//! // process input message
22
//! hasher.update(b"hello world");
23
//!
24
//! // acquire hash digest in the form of GenericArray,
25
//! // which in this case is equivalent to [u8; 20]
26
//! let result = hasher.finalize();
27
//! assert_eq!(result[..], hex!("2aae6c35c94fcfb415dbe95f408b9ce91ee846ed"));
28
//! ```
29
//!
30
//! Also see [RustCrypto/hashes][3] readme.
31
//!
32
//! # Note for users of `sha1 v0.6`
33
//!
34
//! This crate has been transferred to the RustCrypto organization and uses
35
//! implementation previously published as the `sha-1` crate. The previous
36
//! zero dependencies version is now published as the [`sha1_smol`] crate.
37
//!
38
//! [1]: https://en.wikipedia.org/wiki/SHA-1
39
//! [2]: https://sha-mbles.github.io/
40
//! [3]: https://github.com/RustCrypto/hashes
41
//! [`sha1_smol`]: https://github.com/mitsuhiko/sha1-smol/
42
43
#![no_std]
44
#![cfg_attr(docsrs, feature(doc_cfg))]
45
#![doc(
46
    html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
47
    html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
48
)]
49
#![warn(missing_docs, rust_2018_idioms)]
50
51
pub use digest::{self, Digest};
52
53
use core::{fmt, slice::from_ref};
54
#[cfg(feature = "oid")]
55
use digest::const_oid::{AssociatedOid, ObjectIdentifier};
56
use digest::{
57
    block_buffer::Eager,
58
    core_api::{
59
        AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreWrapper, FixedOutputCore,
60
        OutputSizeUser, Reset, UpdateCore,
61
    },
62
    typenum::{Unsigned, U20, U64},
63
    HashMarker, Output,
64
};
65
66
mod compress;
67
68
#[cfg(feature = "compress")]
69
pub use compress::compress;
70
#[cfg(not(feature = "compress"))]
71
use compress::compress;
72
73
const STATE_LEN: usize = 5;
74
75
/// Core SHA-1 hasher state.
76
#[derive(Clone)]
77
pub struct Sha1Core {
78
    h: [u32; STATE_LEN],
79
    block_len: u64,
80
}
81
82
impl HashMarker for Sha1Core {}
83
84
impl BlockSizeUser for Sha1Core {
85
    type BlockSize = U64;
86
}
87
88
impl BufferKindUser for Sha1Core {
89
    type BufferKind = Eager;
90
}
91
92
impl OutputSizeUser for Sha1Core {
93
    type OutputSize = U20;
94
}
95
96
impl UpdateCore for Sha1Core {
97
    #[inline]
98
1.85M
    fn update_blocks(&mut self, blocks: &[Block<Self>]) {
99
1.85M
        self.block_len += blocks.len() as u64;
100
1.85M
        compress(&mut self.h, blocks);
101
1.85M
    }
<sha1::Sha1Core as digest::core_api::UpdateCore>::update_blocks
Line
Count
Source
98
618k
    fn update_blocks(&mut self, blocks: &[Block<Self>]) {
99
618k
        self.block_len += blocks.len() as u64;
100
618k
        compress(&mut self.h, blocks);
101
618k
    }
<sha1::Sha1Core as digest::core_api::UpdateCore>::update_blocks
Line
Count
Source
98
1.23M
    fn update_blocks(&mut self, blocks: &[Block<Self>]) {
99
1.23M
        self.block_len += blocks.len() as u64;
100
1.23M
        compress(&mut self.h, blocks);
101
1.23M
    }
102
}
103
104
impl FixedOutputCore for Sha1Core {
105
    #[inline]
106
2.01M
    fn finalize_fixed_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>) {
107
2.01M
        let bs = Self::BlockSize::U64;
108
2.01M
        let bit_len = 8 * (buffer.get_pos() as u64 + bs * self.block_len);
109
110
2.01M
        let mut h = self.h;
111
2.03M
        buffer.len64_padding_be(bit_len, |b| compress(&mut h, from_ref(b)));
<sha1::Sha1Core as digest::core_api::FixedOutputCore>::finalize_fixed_core::{closure#0}
Line
Count
Source
111
919k
        buffer.len64_padding_be(bit_len, |b| compress(&mut h, from_ref(b)));
Unexecuted instantiation: <sha1::Sha1Core as digest::core_api::FixedOutputCore>::finalize_fixed_core::{closure#0}
<sha1::Sha1Core as digest::core_api::FixedOutputCore>::finalize_fixed_core::{closure#0}
Line
Count
Source
111
1.11M
        buffer.len64_padding_be(bit_len, |b| compress(&mut h, from_ref(b)));
Unexecuted instantiation: <sha1::Sha1Core as digest::core_api::FixedOutputCore>::finalize_fixed_core::{closure#0}
112
10.0M
        for (chunk, v) in out.chunks_exact_mut(4).zip(h.iter()) {
113
10.0M
            chunk.copy_from_slice(&v.to_be_bytes());
114
10.0M
        }
115
2.01M
    }
<sha1::Sha1Core as digest::core_api::FixedOutputCore>::finalize_fixed_core
Line
Count
Source
106
912k
    fn finalize_fixed_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>) {
107
912k
        let bs = Self::BlockSize::U64;
108
912k
        let bit_len = 8 * (buffer.get_pos() as u64 + bs * self.block_len);
109
110
912k
        let mut h = self.h;
111
912k
        buffer.len64_padding_be(bit_len, |b| compress(&mut h, from_ref(b)));
112
4.56M
        for (chunk, v) in out.chunks_exact_mut(4).zip(h.iter()) {
113
4.56M
            chunk.copy_from_slice(&v.to_be_bytes());
114
4.56M
        }
115
912k
    }
<sha1::Sha1Core as digest::core_api::FixedOutputCore>::finalize_fixed_core
Line
Count
Source
106
1.10M
    fn finalize_fixed_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>) {
107
1.10M
        let bs = Self::BlockSize::U64;
108
1.10M
        let bit_len = 8 * (buffer.get_pos() as u64 + bs * self.block_len);
109
110
1.10M
        let mut h = self.h;
111
1.10M
        buffer.len64_padding_be(bit_len, |b| compress(&mut h, from_ref(b)));
112
5.51M
        for (chunk, v) in out.chunks_exact_mut(4).zip(h.iter()) {
113
5.51M
            chunk.copy_from_slice(&v.to_be_bytes());
114
5.51M
        }
115
1.10M
    }
116
}
117
118
impl Default for Sha1Core {
119
    #[inline]
120
2.14M
    fn default() -> Self {
121
2.14M
        Self {
122
2.14M
            h: [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0],
123
2.14M
            block_len: 0,
124
2.14M
        }
125
2.14M
    }
<sha1::Sha1Core as core::default::Default>::default
Line
Count
Source
120
977k
    fn default() -> Self {
121
977k
        Self {
122
977k
            h: [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0],
123
977k
            block_len: 0,
124
977k
        }
125
977k
    }
<sha1::Sha1Core as core::default::Default>::default
Line
Count
Source
120
1.17M
    fn default() -> Self {
121
1.17M
        Self {
122
1.17M
            h: [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0],
123
1.17M
            block_len: 0,
124
1.17M
        }
125
1.17M
    }
126
}
127
128
impl Reset for Sha1Core {
129
    #[inline]
130
0
    fn reset(&mut self) {
131
0
        *self = Default::default();
132
0
    }
Unexecuted instantiation: <sha1::Sha1Core as crypto_common::Reset>::reset
Unexecuted instantiation: <sha1::Sha1Core as crypto_common::Reset>::reset
133
}
134
135
impl AlgorithmName for Sha1Core {
136
0
    fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
137
0
        f.write_str("Sha1")
138
0
    }
Unexecuted instantiation: <sha1::Sha1Core as crypto_common::AlgorithmName>::write_alg_name
Unexecuted instantiation: <sha1::Sha1Core as crypto_common::AlgorithmName>::write_alg_name
139
}
140
141
impl fmt::Debug for Sha1Core {
142
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
143
0
        f.write_str("Sha1Core { ... }")
144
0
    }
Unexecuted instantiation: <sha1::Sha1Core as core::fmt::Debug>::fmt
Unexecuted instantiation: <sha1::Sha1Core as core::fmt::Debug>::fmt
145
}
146
147
#[cfg(feature = "oid")]
148
#[cfg_attr(docsrs, doc(cfg(feature = "oid")))]
149
impl AssociatedOid for Sha1Core {
150
    const OID: ObjectIdentifier = ObjectIdentifier::new_unwrap("1.3.14.3.2.26");
151
}
152
153
/// SHA-1 hasher state.
154
pub type Sha1 = CoreWrapper<Sha1Core>;