/rust/registry/src/index.crates.io-1949cf8c6b5b557f/sha2-0.11.0/src/block_api.rs
Line | Count | Source |
1 | | use crate::consts; |
2 | | use core::fmt; |
3 | | use digest::{ |
4 | | HashMarker, InvalidOutputSize, Output, |
5 | | array::Array, |
6 | | block_api::{ |
7 | | AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, Eager, OutputSizeUser, |
8 | | TruncSide, UpdateCore, VariableOutputCore, |
9 | | }, |
10 | | common::hazmat::{DeserializeStateError, SerializableState, SerializedState}, |
11 | | typenum::{U32, U40, U64, U80, U128, Unsigned}, |
12 | | }; |
13 | | |
14 | | pub use crate::{sha256::compress256, sha512::compress512}; |
15 | | |
16 | | /// Core block-level SHA-256 hasher with variable output size. |
17 | | /// |
18 | | /// Supports initialization only for 28 and 32 byte output sizes, |
19 | | /// i.e. 224 and 256 bits respectively. |
20 | | #[derive(Clone)] |
21 | | pub struct Sha256VarCore { |
22 | | state: consts::State256, |
23 | | block_len: u64, |
24 | | } |
25 | | |
26 | | impl HashMarker for Sha256VarCore {} |
27 | | |
28 | | impl BlockSizeUser for Sha256VarCore { |
29 | | type BlockSize = U64; |
30 | | } |
31 | | |
32 | | impl BufferKindUser for Sha256VarCore { |
33 | | type BufferKind = Eager; |
34 | | } |
35 | | |
36 | | impl UpdateCore for Sha256VarCore { |
37 | | #[inline] |
38 | 0 | fn update_blocks(&mut self, blocks: &[Block<Self>]) { |
39 | 0 | self.block_len += blocks.len() as u64; |
40 | 0 | let blocks = Array::cast_slice_to_core(blocks); |
41 | 0 | compress256(&mut self.state, blocks); |
42 | 0 | } Unexecuted instantiation: <sha2::block_api::Sha256VarCore as digest::block_api::UpdateCore>::update_blocks Unexecuted instantiation: <sha2::block_api::Sha256VarCore as digest::block_api::UpdateCore>::update_blocks |
43 | | } |
44 | | |
45 | | impl OutputSizeUser for Sha256VarCore { |
46 | | type OutputSize = U32; |
47 | | } |
48 | | |
49 | | impl VariableOutputCore for Sha256VarCore { |
50 | | const TRUNC_SIDE: TruncSide = TruncSide::Left; |
51 | | |
52 | | #[inline] |
53 | 0 | fn new(output_size: usize) -> Result<Self, InvalidOutputSize> { |
54 | 0 | let state = match output_size { |
55 | 0 | 28 => consts::H256_224, |
56 | 0 | 32 => consts::H256_256, |
57 | 0 | _ => return Err(InvalidOutputSize), |
58 | | }; |
59 | 0 | let block_len = 0; |
60 | 0 | Ok(Self { state, block_len }) |
61 | 0 | } Unexecuted instantiation: <sha2::block_api::Sha256VarCore as digest::block_api::VariableOutputCore>::new Unexecuted instantiation: <sha2::block_api::Sha256VarCore as digest::block_api::VariableOutputCore>::new |
62 | | |
63 | | #[inline] |
64 | 0 | fn finalize_variable_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>) { |
65 | 0 | let bs = Self::BlockSize::U64; |
66 | 0 | let bit_len = 8 * (buffer.get_pos() as u64 + bs * self.block_len); |
67 | 0 | buffer.len64_padding_be(bit_len, |b| compress256(&mut self.state, &[b.0])); Unexecuted instantiation: <sha2::block_api::Sha256VarCore as digest::block_api::VariableOutputCore>::finalize_variable_core::{closure#0}Unexecuted instantiation: <sha2::block_api::Sha256VarCore as digest::block_api::VariableOutputCore>::finalize_variable_core::{closure#0} |
68 | | |
69 | 0 | for (chunk, v) in out.chunks_exact_mut(4).zip(self.state.iter()) { |
70 | 0 | chunk.copy_from_slice(&v.to_be_bytes()); |
71 | 0 | } |
72 | 0 | } Unexecuted instantiation: <sha2::block_api::Sha256VarCore as digest::block_api::VariableOutputCore>::finalize_variable_core Unexecuted instantiation: <sha2::block_api::Sha256VarCore as digest::block_api::VariableOutputCore>::finalize_variable_core |
73 | | } |
74 | | |
75 | | impl AlgorithmName for Sha256VarCore { |
76 | | #[inline] |
77 | 0 | fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { |
78 | 0 | f.write_str("Sha256") |
79 | 0 | } |
80 | | } |
81 | | |
82 | | impl fmt::Debug for Sha256VarCore { |
83 | | #[inline] |
84 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
85 | 0 | f.write_str("Sha256VarCore { ... }") |
86 | 0 | } |
87 | | } |
88 | | |
89 | | impl Drop for Sha256VarCore { |
90 | 0 | fn drop(&mut self) { |
91 | | #[cfg(feature = "zeroize")] |
92 | | { |
93 | | use digest::zeroize::Zeroize; |
94 | | self.state.zeroize(); |
95 | | self.block_len.zeroize(); |
96 | | } |
97 | 0 | } |
98 | | } |
99 | | |
100 | | #[cfg(feature = "zeroize")] |
101 | | impl digest::zeroize::ZeroizeOnDrop for Sha256VarCore {} |
102 | | |
103 | | impl SerializableState for Sha256VarCore { |
104 | | type SerializedStateSize = U40; |
105 | | |
106 | 0 | fn serialize(&self) -> SerializedState<Self> { |
107 | 0 | let mut serialized_state = SerializedState::<Self>::default(); |
108 | | |
109 | 0 | for (val, chunk) in self.state.iter().zip(serialized_state.chunks_exact_mut(4)) { |
110 | 0 | chunk.copy_from_slice(&val.to_le_bytes()); |
111 | 0 | } |
112 | | |
113 | 0 | serialized_state[32..].copy_from_slice(&self.block_len.to_le_bytes()); |
114 | 0 | serialized_state |
115 | 0 | } |
116 | | |
117 | 0 | fn deserialize( |
118 | 0 | serialized_state: &SerializedState<Self>, |
119 | 0 | ) -> Result<Self, DeserializeStateError> { |
120 | 0 | let (serialized_state, serialized_block_len) = serialized_state.split::<U32>(); |
121 | | |
122 | 0 | let mut state = consts::State256::default(); |
123 | 0 | for (val, chunk) in state.iter_mut().zip(serialized_state.chunks_exact(4)) { |
124 | 0 | *val = u32::from_le_bytes(chunk.try_into().unwrap()); |
125 | 0 | } |
126 | | |
127 | 0 | let block_len = u64::from_le_bytes(*serialized_block_len.as_ref()); |
128 | | |
129 | 0 | Ok(Self { state, block_len }) |
130 | 0 | } |
131 | | } |
132 | | |
133 | | /// Core block-level SHA-512 hasher with variable output size. |
134 | | /// |
135 | | /// Supports initialization only for 28, 32, 48, and 64 byte output sizes, |
136 | | /// i.e. 224, 256, 384, and 512 bits respectively. |
137 | | #[derive(Clone)] |
138 | | pub struct Sha512VarCore { |
139 | | state: consts::State512, |
140 | | block_len: u128, |
141 | | } |
142 | | |
143 | | impl HashMarker for Sha512VarCore {} |
144 | | |
145 | | impl BlockSizeUser for Sha512VarCore { |
146 | | type BlockSize = U128; |
147 | | } |
148 | | |
149 | | impl BufferKindUser for Sha512VarCore { |
150 | | type BufferKind = Eager; |
151 | | } |
152 | | |
153 | | impl UpdateCore for Sha512VarCore { |
154 | | #[inline] |
155 | 0 | fn update_blocks(&mut self, blocks: &[Block<Self>]) { |
156 | 0 | self.block_len += blocks.len() as u128; |
157 | 0 | let blocks = Array::cast_slice_to_core(blocks); |
158 | 0 | compress512(&mut self.state, blocks); |
159 | 0 | } |
160 | | } |
161 | | |
162 | | impl OutputSizeUser for Sha512VarCore { |
163 | | type OutputSize = U64; |
164 | | } |
165 | | |
166 | | impl VariableOutputCore for Sha512VarCore { |
167 | | const TRUNC_SIDE: TruncSide = TruncSide::Left; |
168 | | |
169 | | #[inline] |
170 | 0 | fn new(output_size: usize) -> Result<Self, InvalidOutputSize> { |
171 | 0 | let state = match output_size { |
172 | 0 | 28 => consts::H512_224, |
173 | 0 | 32 => consts::H512_256, |
174 | 0 | 48 => consts::H512_384, |
175 | 0 | 64 => consts::H512_512, |
176 | 0 | _ => return Err(InvalidOutputSize), |
177 | | }; |
178 | 0 | let block_len = 0; |
179 | 0 | Ok(Self { state, block_len }) |
180 | 0 | } |
181 | | |
182 | | #[inline] |
183 | 0 | fn finalize_variable_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>) { |
184 | 0 | let bs = Self::BlockSize::U64 as u128; |
185 | 0 | let bit_len = 8 * (buffer.get_pos() as u128 + bs * self.block_len); |
186 | 0 | buffer.len128_padding_be(bit_len, |b| compress512(&mut self.state, &[b.0])); |
187 | | |
188 | 0 | for (chunk, v) in out.chunks_exact_mut(8).zip(self.state.iter()) { |
189 | 0 | chunk.copy_from_slice(&v.to_be_bytes()); |
190 | 0 | } |
191 | 0 | } |
192 | | } |
193 | | |
194 | | impl AlgorithmName for Sha512VarCore { |
195 | | #[inline] |
196 | 0 | fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { |
197 | 0 | f.write_str("Sha512") |
198 | 0 | } |
199 | | } |
200 | | |
201 | | impl fmt::Debug for Sha512VarCore { |
202 | | #[inline] |
203 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
204 | 0 | f.write_str("Sha512VarCore { ... }") |
205 | 0 | } |
206 | | } |
207 | | |
208 | | impl Drop for Sha512VarCore { |
209 | 0 | fn drop(&mut self) { |
210 | | #[cfg(feature = "zeroize")] |
211 | | { |
212 | | use digest::zeroize::Zeroize; |
213 | | self.state.zeroize(); |
214 | | self.block_len.zeroize(); |
215 | | } |
216 | 0 | } |
217 | | } |
218 | | #[cfg(feature = "zeroize")] |
219 | | impl digest::zeroize::ZeroizeOnDrop for Sha512VarCore {} |
220 | | |
221 | | impl SerializableState for Sha512VarCore { |
222 | | type SerializedStateSize = U80; |
223 | | |
224 | 0 | fn serialize(&self) -> SerializedState<Self> { |
225 | 0 | let mut serialized_state = SerializedState::<Self>::default(); |
226 | | |
227 | 0 | for (val, chunk) in self.state.iter().zip(serialized_state.chunks_exact_mut(8)) { |
228 | 0 | chunk.copy_from_slice(&val.to_le_bytes()); |
229 | 0 | } |
230 | | |
231 | 0 | serialized_state[64..].copy_from_slice(&self.block_len.to_le_bytes()); |
232 | | |
233 | 0 | serialized_state |
234 | 0 | } |
235 | | |
236 | 0 | fn deserialize( |
237 | 0 | serialized_state: &SerializedState<Self>, |
238 | 0 | ) -> Result<Self, DeserializeStateError> { |
239 | 0 | let (serialized_state, serialized_block_len) = serialized_state.split::<U64>(); |
240 | | |
241 | 0 | let mut state = consts::State512::default(); |
242 | 0 | for (val, chunk) in state.iter_mut().zip(serialized_state.chunks_exact(8)) { |
243 | 0 | *val = u64::from_le_bytes(chunk.try_into().unwrap()); |
244 | 0 | } |
245 | | |
246 | 0 | let block_len = u128::from_le_bytes(*serialized_block_len.as_ref()); |
247 | | |
248 | 0 | Ok(Self { state, block_len }) |
249 | 0 | } |
250 | | } |