bouncycastle_sha3/
sha3.rs1use bouncycastle_core_interface::errors::{HashError, KDFError};
2use bouncycastle_core_interface::key_material::{KeyMaterialInternal, KeyType};
3use bouncycastle_core_interface::traits::{Hash, KeyMaterial, SecurityStrength, KDF};
4use bouncycastle_utils::{max, min};
5use crate::keccak::KeccakDigest;
6use crate::SHA3Params;
7
8#[derive(Clone)]
9pub struct SHA3<PARAMS: SHA3Params> {
10 _params: std::marker::PhantomData<PARAMS>,
11 keccak: KeccakDigest,
12 kdf_key_type: KeyType,
13 kdf_security_strength: SecurityStrength,
14 kdf_entropy: usize,
15}
16
17impl<PARAMS: SHA3Params> SHA3<PARAMS> {
20 pub fn new() -> Self {
21 Self {
22 _params: std::marker::PhantomData,
23 keccak: KeccakDigest::new(PARAMS::SIZE),
24 kdf_key_type: KeyType::Zeroized,
25 kdf_security_strength: SecurityStrength::None,
26 kdf_entropy: 0,
27 }
28 }
29
30 fn hash_internal(mut self, data: &[u8], output: &mut [u8]) -> usize {
32 self.do_update(data);
33 self.do_final_out(output)
34 }
35
36 fn mix_key_internal(&mut self, key: &impl KeyMaterial) {
37 self.kdf_key_type = *max(&self.kdf_key_type, &key.key_type());
39
40 if key.is_full_entropy() {
42 self.kdf_entropy += key.key_len();
43 self.kdf_security_strength =
44 max(&self.kdf_security_strength, &key.security_strength()).clone();
45 self.kdf_security_strength = min(
46 &self.kdf_security_strength,
47 &SecurityStrength::from_bits(PARAMS::OUTPUT_LEN * 8 / 2),
48 )
49 .clone();
50 }
51
52 self.do_update(key.ref_to_bytes())
53 }
54
55 fn derive_key_final_internal(
56 self,
57 additional_input: &[u8],
58 ) -> Result<Box<dyn KeyMaterial>, KDFError> {
59 let mut output_key = KeyMaterialInternal::<64>::new();
60 self.derive_key_out_final_internal(additional_input, &mut output_key)?;
61
62 Ok(Box::new(output_key))
63 }
64
65 fn derive_key_out_final_internal(
66 mut self,
67 additional_input: &[u8],
68 output_key: &mut impl KeyMaterial,
69 ) -> Result<usize, KDFError> {
70 if self.kdf_entropy < PARAMS::OUTPUT_LEN {
74 self.kdf_key_type = min(&self.kdf_key_type, &KeyType::BytesLowEntropy).clone();
75 self.kdf_security_strength = SecurityStrength::None; }
77
78 self.do_update(additional_input);
79
80 let mut key_type = self.kdf_key_type.clone();
81 let output_security_strength = self.kdf_security_strength.clone();
82 output_key.allow_hazardous_operations();
83 let bytes_written = self.do_final_out(output_key.mut_ref_to_bytes()?);
84 output_key.set_key_len(bytes_written)?;
85
86 if key_type == KeyType::Zeroized {
88 key_type = KeyType::BytesLowEntropy;
89 }
90 output_key.set_key_type(key_type)?;
91 output_key.set_security_strength(
92 min(&output_security_strength, &SecurityStrength::from_bits(bytes_written * 8)).clone(),
93 )?;
94 output_key.drop_hazardous_operations();
95 output_key.truncate(min(&output_key.key_len(), &PARAMS::OUTPUT_LEN).clone())?;
96 Ok(bytes_written)
97 }
98}
99
100impl<PARAMS: SHA3Params> Default for SHA3<PARAMS> {
101 fn default() -> Self {
102 Self::new()
103 }
104}
105
106impl<PARAMS: SHA3Params> Hash for SHA3<PARAMS> {
107 fn block_bitlen(&self) -> usize {
110 PARAMS::BLOCK_LEN * 8
111 }
112
113 fn output_len(&self) -> usize {
114 PARAMS::OUTPUT_LEN
115 }
116
117 fn hash(self, data: &[u8]) -> Vec<u8> {
118 let mut output: Vec<u8> = vec![0u8; PARAMS::OUTPUT_LEN];
119 _ = self.hash_internal(data, &mut output[..]);
120 output
121 }
122
123 fn hash_out(self, data: &[u8], mut output: &mut [u8]) -> usize {
124 self.hash_internal(data, &mut output)
125 }
126
127 fn do_update(&mut self, data: &[u8]) {
128 self.keccak.absorb(data)
129 }
130
131 fn do_final(self) -> Vec<u8> {
132 let dbg_rslt_len = self.output_len();
133 let mut output: Vec<u8> = vec![0u8; self.output_len()];
134 let bytes_written = self.do_final_out(output.as_mut_slice());
135 debug_assert_eq!(bytes_written, dbg_rslt_len);
136
137 output
138 }
139
140 fn do_final_out(mut self, output: &mut [u8]) -> usize {
141 self.keccak.absorb_bits(0x02, 2).expect("do_final_out: keccak.absorb_bits failed."); let bytes_written = if output.len() <= self.output_len() {
144 self.keccak.squeeze(output)
145 } else {
146 let min =
147 if output.len() >= self.output_len() { self.output_len() } else { output.len() };
148 self.keccak.squeeze(&mut output[..min])
149 };
150 bytes_written
151 }
152
153 fn do_final_partial_bits(
154 self,
155 partial_byte: u8,
156 num_partial_bits: usize,
157 ) -> Result<Vec<u8>, HashError> {
158 let dbg_rslt_len = self.output_len();
159 let mut output: Vec<u8> = vec![0u8; self.output_len()];
160 let bytes_written =
161 self.do_final_partial_bits_out(partial_byte, num_partial_bits, output.as_mut_slice())?;
162 debug_assert_eq!(bytes_written, dbg_rslt_len);
163
164 Ok(output)
165 }
166
167 fn do_final_partial_bits_out(
168 mut self,
169 partial_byte: u8,
170 num_partial_bits: usize,
171 output: &mut [u8],
172 ) -> Result<usize, HashError> {
173 let mut final_input: u16 =
175 ((partial_byte as u16) & ((1 << num_partial_bits) - 1)) | (0x02 << num_partial_bits);
176 let mut final_bits = num_partial_bits + 2;
177
178 if final_bits >= 8 {
179 self.keccak.absorb(&[final_input as u8]);
180 final_bits -= 8;
181 final_input >>= 8;
182 }
183
184 self.keccak.absorb_bits(final_input as u8, final_bits)?;
185
186 let min = if output.len() >= self.output_len() { self.output_len() } else { output.len() };
187 Ok(self.keccak.squeeze(&mut output[..min]))
188 }
189
190 fn max_security_strength(&self) -> SecurityStrength {
191 SecurityStrength::from_bytes(PARAMS::OUTPUT_LEN / 2)
192 }
193}
194
195impl<PARAMS: SHA3Params> KDF for SHA3<PARAMS> {
197 fn derive_key(
201 mut self,
202 key: &impl KeyMaterial,
203 additional_input: &[u8],
204 ) -> Result<Box<dyn KeyMaterial>, KDFError> {
205 self.mix_key_internal(key);
206 self.derive_key_final_internal(additional_input)
207 }
208
209 fn derive_key_out(
210 mut self,
211 key: &impl KeyMaterial,
212 additional_input: &[u8],
213 output_key: &mut impl KeyMaterial,
214 ) -> Result<usize, KDFError> {
215 self.mix_key_internal(key);
217 self.derive_key_out_final_internal(additional_input, output_key)
218 }
219
220 fn derive_key_from_multiple(
221 mut self,
222 keys: &[&impl KeyMaterial],
223 additional_input: &[u8],
224 ) -> Result<Box<dyn KeyMaterial>, KDFError> {
225 for key in keys {
226 self.mix_key_internal(*key);
227 }
228 self.derive_key_final_internal(additional_input)
229 }
230
231 fn derive_key_from_multiple_out(
232 mut self,
233 keys: &[&impl KeyMaterial],
234 additional_input: &[u8],
235 output_key: &mut impl KeyMaterial,
236 ) -> Result<usize, KDFError> {
237 for key in keys {
239 self.mix_key_internal(*key);
240 }
241 self.derive_key_out_final_internal(additional_input, output_key)
242 }
243
244 fn max_security_strength(&self) -> SecurityStrength {
245 SecurityStrength::from_bytes(PARAMS::OUTPUT_LEN / 2)
246 }
247}