/rust/registry/src/github.com-1ecc6299db9ec823/md-5-0.9.1/src/lib.rs
Line | Count | Source (jump to first uncovered line) |
1 | | //! An implementation of the [MD5][1] cryptographic hash algorithm. |
2 | | //! |
3 | | //! # Usage |
4 | | //! |
5 | | //! ```rust |
6 | | //! use md5::{Md5, Digest}; |
7 | | //! use hex_literal::hex; |
8 | | //! |
9 | | //! // create a Md5 hasher instance |
10 | | //! let mut hasher = Md5::new(); |
11 | | //! |
12 | | //! // process input message |
13 | | //! hasher.update(b"hello world"); |
14 | | //! |
15 | | //! // acquire hash digest in the form of GenericArray, |
16 | | //! // which in this case is equivalent to [u8; 16] |
17 | | //! let result = hasher.finalize(); |
18 | | //! assert_eq!(result[..], hex!("5eb63bbbe01eeed093cb22bb8f5acdc3")); |
19 | | //! ``` |
20 | | //! |
21 | | //! Also see [RustCrypto/hashes][2] readme. |
22 | | //! |
23 | | //! [1]: https://en.wikipedia.org/wiki/MD5 |
24 | | //! [2]: https://github.com/RustCrypto/hashes |
25 | | |
26 | | #![no_std] |
27 | | #![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] |
28 | | #![deny(unsafe_code)] |
29 | | #![warn(missing_docs, rust_2018_idioms)] |
30 | | |
31 | | #[cfg(feature = "asm")] |
32 | | extern crate md5_asm as utils; |
33 | | |
34 | | #[cfg(feature = "std")] |
35 | | extern crate std; |
36 | | |
37 | | #[cfg(not(feature = "asm"))] |
38 | | mod utils; |
39 | | |
40 | | pub use digest::{self, Digest}; |
41 | | |
42 | | use crate::utils::compress; |
43 | | |
44 | | use block_buffer::BlockBuffer; |
45 | | use digest::generic_array::typenum::{U16, U64}; |
46 | | use digest::generic_array::GenericArray; |
47 | | use digest::{BlockInput, FixedOutputDirty, Reset, Update}; |
48 | | |
49 | | mod consts; |
50 | | |
51 | | /// The MD5 hasher |
52 | 0 | #[derive(Clone)] |
53 | | pub struct Md5 { |
54 | | length_bytes: u64, |
55 | | buffer: BlockBuffer<U64>, |
56 | | state: [u32; 4], |
57 | | } |
58 | | |
59 | | impl Default for Md5 { |
60 | 2.04M | fn default() -> Self { |
61 | 2.04M | Md5 { |
62 | 2.04M | length_bytes: 0, |
63 | 2.04M | buffer: Default::default(), |
64 | 2.04M | state: consts::S0, |
65 | 2.04M | } |
66 | 2.04M | } |
67 | | } |
68 | | |
69 | | #[inline(always)] |
70 | 12.4M | fn convert(d: &GenericArray<u8, U64>) -> &[u8; 64] { |
71 | 12.4M | #[allow(unsafe_code)] |
72 | 12.4M | unsafe { |
73 | 12.4M | &*(d.as_ptr() as *const [u8; 64]) |
74 | 12.4M | } |
75 | 12.4M | } |
76 | | |
77 | | impl Md5 { |
78 | | #[inline] |
79 | 186k | fn finalize_inner(&mut self) { |
80 | 186k | let s = &mut self.state; |
81 | 186k | let l = (self.length_bytes << 3) as u64; |
82 | 191k | self.buffer.len64_padding_le(l, |d| compress(s, convert(d))); <md5::Md5>::finalize_inner::{closure#0} Line | Count | Source | 82 | 191k | self.buffer.len64_padding_le(l, |d| compress(s, convert(d))); |
Unexecuted instantiation: <md5::Md5>::finalize_inner::{closure#0} |
83 | 186k | } |
84 | | } |
85 | | |
86 | | impl BlockInput for Md5 { |
87 | | type BlockSize = U64; |
88 | | } |
89 | | |
90 | | impl Update for Md5 { |
91 | | #[inline] |
92 | 935k | fn update(&mut self, input: impl AsRef<[u8]>) { |
93 | 935k | let input = input.as_ref(); |
94 | 935k | // Unlike Sha1 and Sha2, the length value in MD5 is defined as |
95 | 935k | // the length of the message mod 2^64 - ie: integer overflow is OK. |
96 | 935k | self.length_bytes = self.length_bytes.wrapping_add(input.len() as u64); |
97 | 935k | let s = &mut self.state; |
98 | 12.2M | self.buffer.input_block(input, |d| compress(s, convert(d))); <md5::Md5 as digest::Update>::update::<&[u8]>::{closure#0} Line | Count | Source | 98 | 11.2M | self.buffer.input_block(input, |d| compress(s, convert(d))); |
<md5::Md5 as digest::Update>::update::<&&mut alloc::vec::Vec<u8>>::{closure#0} Line | Count | Source | 98 | 1.03M | self.buffer.input_block(input, |d| compress(s, convert(d))); |
Unexecuted instantiation: <md5::Md5 as digest::Update>::update::<&[u8]>::{closure#0} |
99 | 935k | } <md5::Md5 as digest::Update>::update::<&&mut alloc::vec::Vec<u8>> Line | Count | Source | 92 | 18.8k | fn update(&mut self, input: impl AsRef<[u8]>) { | 93 | 18.8k | let input = input.as_ref(); | 94 | 18.8k | // Unlike Sha1 and Sha2, the length value in MD5 is defined as | 95 | 18.8k | // the length of the message mod 2^64 - ie: integer overflow is OK. | 96 | 18.8k | self.length_bytes = self.length_bytes.wrapping_add(input.len() as u64); | 97 | 18.8k | let s = &mut self.state; | 98 | 18.8k | self.buffer.input_block(input, |d| compress(s, convert(d))); | 99 | 18.8k | } |
<md5::Md5 as digest::Update>::update::<&[u8]> Line | Count | Source | 92 | 916k | fn update(&mut self, input: impl AsRef<[u8]>) { | 93 | 916k | let input = input.as_ref(); | 94 | 916k | // Unlike Sha1 and Sha2, the length value in MD5 is defined as | 95 | 916k | // the length of the message mod 2^64 - ie: integer overflow is OK. | 96 | 916k | self.length_bytes = self.length_bytes.wrapping_add(input.len() as u64); | 97 | 916k | let s = &mut self.state; | 98 | 916k | self.buffer.input_block(input, |d| compress(s, convert(d))); | 99 | 916k | } |
Unexecuted instantiation: <md5::Md5 as digest::Update>::update::<&[u8]> |
100 | | } |
101 | | |
102 | | impl FixedOutputDirty for Md5 { |
103 | | type OutputSize = U16; |
104 | | |
105 | | #[inline] |
106 | 186k | fn finalize_into_dirty(&mut self, out: &mut GenericArray<u8, U16>) { |
107 | 186k | self.finalize_inner(); |
108 | 744k | for (chunk, v) in out.chunks_exact_mut(4).zip(self.state.iter()) { |
109 | 744k | chunk.copy_from_slice(&v.to_le_bytes()); |
110 | 744k | } |
111 | 186k | } |
112 | | } |
113 | | |
114 | | impl Reset for Md5 { |
115 | 0 | fn reset(&mut self) { |
116 | 0 | self.state = consts::S0; |
117 | 0 | self.length_bytes = 0; |
118 | 0 | self.buffer.reset(); |
119 | 0 | } |
120 | | } |
121 | | |
122 | | opaque_debug::implement!(Md5); |
123 | | digest::impl_write!(Md5); |