1use core::{error, fmt};
2
3use generic_array::{typenum::Unsigned, ArrayLength, GenericArray};
4use sha3::{
5 digest::{
6 core_api::{Block, CoreProxy, UpdateCore},
7 crypto_common::{AlgorithmName, BlockSizeUser},
8 ExtendableOutput, Update, XofReader,
9 },
10 CShake128, CShake256,
11};
12use sha3_utils::{bytepad_blocks, encode_string, right_encode, right_encode_bytes};
13
14#[derive(Copy, Clone, Debug, Eq, PartialEq)]
16pub struct InvalidLength;
17
18impl fmt::Display for InvalidLength {
19 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20 write!(f, "invalid length")
21 }
22}
23
24impl error::Error for InvalidLength {}
25
26pub type Mac<N> = GenericArray<u8, N>;
28
29macro_rules! impl_kmac {
30 ($alg:literal, $name:ident, $cshake:ty, $security:literal) => {
31 #[doc = "`"]
32 #[doc = $alg]
33 #[doc = "`."]
34 #[derive(Clone, Debug)]
35 pub struct $name {
36 cshake: $cshake,
37 }
38
39 impl $name {
40 pub const MIN_KEY_SIZE: usize = $security / 8;
42
43 pub fn new(k: &[u8], s: &[u8]) -> Result<Self, InvalidLength> {
51 if k.len() < Self::MIN_KEY_SIZE {
52 return Err(InvalidLength);
53 }
54
55 let mut core = <$cshake as CoreProxy>::Core::new_with_function_name(b"KMAC", s);
56
57 const BLOCK_SIZE: usize = <$cshake as BlockSizeUser>::BlockSize::USIZE;
64 let (head, mid, tail) = bytepad_blocks::<BLOCK_SIZE>(encode_string(k));
65 core.update_blocks(&[*Block::<$cshake>::from_slice(&head)]);
66 if !mid.is_empty() {
67 core.update_blocks(
68 unsafe { &*(mid as *const [[u8; BLOCK_SIZE]] as *const [Block<$cshake>]) },
72 );
73 }
74 if let Some(tail) = tail {
75 core.update_blocks(&[*Block::<$cshake>::from_slice(&tail)]);
76 }
77
78 let cshake = <$cshake>::from_core(core);
79
80 Ok(Self { cshake })
81 }
82
83 #[inline]
85 pub fn update(&mut self, data: &[u8]) {
86 self.cshake.update(data);
87 }
88
89 pub fn finalize_into(mut self, out: &mut [u8]) {
91 self.cshake.update(right_encode_bytes(out.len()).as_bytes());
92 self.cshake.finalize_xof().read(out)
93 }
94
95 pub fn finalize<N: ArrayLength>(self) -> Mac<N> {
97 let mut out = Mac::default();
98 self.finalize_into(&mut out);
99 out
100 }
101 }
102
103 impl AlgorithmName for $name {
104 fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
105 write!(f, $alg)
106 }
107 }
108
109 impl Update for $name {
110 #[inline]
111 fn update(&mut self, data: &[u8]) {
112 self.update(data);
113 }
114 }
115 };
116}
117impl_kmac!("KMAC128", Kmac128, CShake128, 128);
118impl_kmac!("KMAC256", Kmac256, CShake256, 256);
119
120macro_rules! impl_kmac_xof {
121 ($alg:literal, $name:ident, $cshake:ty, $security:literal) => {
122 #[doc = "`"]
123 #[doc = $alg]
124 #[doc = "`."]
125 #[derive(Clone, Debug)]
126 pub struct $name {
127 cshake: $cshake,
128 }
129
130 impl $name {
131 pub const MIN_KEY_SIZE: usize = $security / 8;
133
134 pub fn new(k: &[u8], s: &[u8]) -> Result<Self, InvalidLength> {
142 if k.len() < Self::MIN_KEY_SIZE {
143 return Err(InvalidLength);
144 }
145
146 let mut core = <$cshake as CoreProxy>::Core::new_with_function_name(b"KMAC", s);
147
148 const BLOCK_SIZE: usize = <$cshake as BlockSizeUser>::BlockSize::USIZE;
155 let (head, mid, tail) = bytepad_blocks::<BLOCK_SIZE>(encode_string(k));
156 core.update_blocks(&[*Block::<$cshake>::from_slice(&head)]);
157 if !mid.is_empty() {
158 core.update_blocks(
159 unsafe { &*(mid as *const [[u8; BLOCK_SIZE]] as *const [Block<$cshake>]) },
163 );
164 }
165 if let Some(tail) = tail {
166 core.update_blocks(&[*Block::<$cshake>::from_slice(&tail)]);
167 }
168
169 let cshake = <$cshake>::from_core(core);
170
171 Ok(Self { cshake })
172 }
173
174 #[inline]
176 pub fn update(&mut self, data: &[u8]) {
177 self.cshake.update(data);
178 }
179
180 pub fn finalize_xof(mut self) -> <$cshake as ExtendableOutput>::Reader {
182 self.cshake.update(right_encode(0).as_bytes());
183 self.cshake.finalize_xof()
184 }
185 }
186
187 impl AlgorithmName for $name {
188 fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
189 write!(f, $alg)
190 }
191 }
192
193 impl ExtendableOutput for $name {
194 type Reader = <$cshake as ExtendableOutput>::Reader;
195
196 #[inline]
197 fn finalize_xof(self) -> Self::Reader {
198 self.finalize_xof()
199 }
200 }
201
202 impl Update for $name {
203 #[inline]
204 fn update(&mut self, data: &[u8]) {
205 self.update(data);
206 }
207 }
208 };
209}
210impl_kmac_xof!("KMACXOF128", KmacXof128, CShake128, 128);
211impl_kmac_xof!("KMACXOF256", KmacXof256, CShake256, 256);
212
213#[cfg(test)]
214#[allow(clippy::type_complexity, reason = "Tests")]
215mod tests {
216 use generic_array::typenum::{U32, U64};
217
218 use super::*;
219
220 #[test]
222 fn test_kmac128() {
223 let vectors: &[(&[u8], &[u8], &[u8], &[u8])] = &[
224 (
225 &[
226 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C,
227 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
228 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
229 ],
230 &[0x00, 0x01, 0x02, 0x03],
231 &[],
232 &[
233 0xE5, 0x78, 0x0B, 0x0D, 0x3E, 0xA6, 0xF7, 0xD3, 0xA4, 0x29, 0xC5, 0x70, 0x6A,
234 0xA4, 0x3A, 0x00, 0xFA, 0xDB, 0xD7, 0xD4, 0x96, 0x28, 0x83, 0x9E, 0x31, 0x87,
235 0x24, 0x3F, 0x45, 0x6E, 0xE1, 0x4E,
236 ],
237 ),
238 (
239 &[
240 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C,
241 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
242 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
243 ],
244 &[0x00, 0x01, 0x02, 0x03],
245 b"My Tagged Application",
246 &[
247 0x3B, 0x1F, 0xBA, 0x96, 0x3C, 0xD8, 0xB0, 0xB5, 0x9E, 0x8C, 0x1A, 0x6D, 0x71,
248 0x88, 0x8B, 0x71, 0x43, 0x65, 0x1A, 0xF8, 0xBA, 0x0A, 0x70, 0x70, 0xC0, 0x97,
249 0x9E, 0x28, 0x11, 0x32, 0x4A, 0xA5,
250 ],
251 ),
252 ];
253 for (i, &(k, data, s, want)) in vectors.iter().enumerate() {
254 let mut m = Kmac128::new(k, s).unwrap();
255 m.update(data);
256 let got = m.finalize::<U32>();
257 let want = Mac::<U32>::from_slice(want);
258 assert_eq!(&got, want, "#{i}");
259 }
260 }
261
262 #[test]
264 fn test_kmac256() {
265 let vectors: &[(&[u8], &[u8], &[u8], &[u8])] = &[
266 (
267 &[
268 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C,
269 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
270 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
271 ],
272 &[0x00, 0x01, 0x02, 0x03],
273 b"My Tagged Application",
274 &[
275 0x20, 0xC5, 0x70, 0xC3, 0x13, 0x46, 0xF7, 0x03, 0xC9, 0xAC, 0x36, 0xC6, 0x1C,
276 0x03, 0xCB, 0x64, 0xC3, 0x97, 0x0D, 0x0C, 0xFC, 0x78, 0x7E, 0x9B, 0x79, 0x59,
277 0x9D, 0x27, 0x3A, 0x68, 0xD2, 0xF7, 0xF6, 0x9D, 0x4C, 0xC3, 0xDE, 0x9D, 0x10,
278 0x4A, 0x35, 0x16, 0x89, 0xF2, 0x7C, 0xF6, 0xF5, 0x95, 0x1F, 0x01, 0x03, 0xF3,
279 0x3F, 0x4F, 0x24, 0x87, 0x10, 0x24, 0xD9, 0xC2, 0x77, 0x73, 0xA8, 0xDD,
280 ],
281 ),
282 (
283 &[
284 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C,
285 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
286 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
287 ],
288 &[
289 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
290 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
291 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
292 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33,
293 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40,
294 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D,
295 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A,
296 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
297 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74,
298 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81,
299 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E,
300 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B,
301 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
302 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5,
303 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2,
304 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
305 ],
306 &[],
307 &[
308 0x75, 0x35, 0x8C, 0xF3, 0x9E, 0x41, 0x49, 0x4E, 0x94, 0x97, 0x07, 0x92, 0x7C,
309 0xEE, 0x0A, 0xF2, 0x0A, 0x3F, 0xF5, 0x53, 0x90, 0x4C, 0x86, 0xB0, 0x8F, 0x21,
310 0xCC, 0x41, 0x4B, 0xCF, 0xD6, 0x91, 0x58, 0x9D, 0x27, 0xCF, 0x5E, 0x15, 0x36,
311 0x9C, 0xBB, 0xFF, 0x8B, 0x9A, 0x4C, 0x2E, 0xB1, 0x78, 0x00, 0x85, 0x5D, 0x02,
312 0x35, 0xFF, 0x63, 0x5D, 0xA8, 0x25, 0x33, 0xEC, 0x6B, 0x75, 0x9B, 0x69,
313 ],
314 ),
315 (
316 &[
317 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C,
318 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
319 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
320 ],
321 &[
322 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
323 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
324 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
325 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33,
326 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40,
327 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D,
328 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A,
329 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
330 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74,
331 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81,
332 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E,
333 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B,
334 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
335 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5,
336 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2,
337 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
338 ],
339 b"My Tagged Application",
340 &[
341 0xB5, 0x86, 0x18, 0xF7, 0x1F, 0x92, 0xE1, 0xD5, 0x6C, 0x1B, 0x8C, 0x55, 0xDD,
342 0xD7, 0xCD, 0x18, 0x8B, 0x97, 0xB4, 0xCA, 0x4D, 0x99, 0x83, 0x1E, 0xB2, 0x69,
343 0x9A, 0x83, 0x7D, 0xA2, 0xE4, 0xD9, 0x70, 0xFB, 0xAC, 0xFD, 0xE5, 0x00, 0x33,
344 0xAE, 0xA5, 0x85, 0xF1, 0xA2, 0x70, 0x85, 0x10, 0xC3, 0x2D, 0x07, 0x88, 0x08,
345 0x01, 0xBD, 0x18, 0x28, 0x98, 0xFE, 0x47, 0x68, 0x76, 0xFC, 0x89, 0x65,
346 ],
347 ),
348 ];
349 for (i, &(k, data, s, want)) in vectors.iter().enumerate() {
350 let mut m = Kmac256::new(k, s).unwrap();
351 m.update(data);
352 let got = m.finalize::<U64>();
353 let want = Mac::<U64>::from_slice(want);
354 assert_eq!(&got, want, "#{i}");
355 }
356 }
357
358 #[test]
360 fn test_kmacxof128() {
361 let vectors: &[(&[u8], &[u8], &[u8], &[u8])] = &[
362 (
363 &[
364 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C,
365 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
366 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
367 ],
368 &[0x00, 0x01, 0x02, 0x03],
369 &[],
370 &[
371 0xCD, 0x83, 0x74, 0x0B, 0xBD, 0x92, 0xCC, 0xC8, 0xCF, 0x03, 0x2B, 0x14, 0x81,
372 0xA0, 0xF4, 0x46, 0x0E, 0x7C, 0xA9, 0xDD, 0x12, 0xB0, 0x8A, 0x0C, 0x40, 0x31,
373 0x17, 0x8B, 0xAC, 0xD6, 0xEC, 0x35,
374 ],
375 ),
376 (
377 &[
378 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C,
379 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
380 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
381 ],
382 &[0x00, 0x01, 0x02, 0x03],
383 b"My Tagged Application",
384 &[
385 0x31, 0xA4, 0x45, 0x27, 0xB4, 0xED, 0x9F, 0x5C, 0x61, 0x01, 0xD1, 0x1D, 0xE6,
386 0xD2, 0x6F, 0x06, 0x20, 0xAA, 0x5C, 0x34, 0x1D, 0xEF, 0x41, 0x29, 0x96, 0x57,
387 0xFE, 0x9D, 0xF1, 0xA3, 0xB1, 0x6C,
388 ],
389 ),
390 ];
391 for (i, &(k, data, s, want)) in vectors.iter().enumerate() {
392 let mut m = KmacXof128::new(k, s).unwrap();
393 m.update(data);
394 let got = m.finalize_xof().read_boxed(32);
395 assert_eq!(&*got, want, "#{i}");
396 }
397 }
398
399 #[test]
401 fn test_kmacxof256() {
402 let vectors: &[(&[u8], &[u8], &[u8], &[u8])] = &[
403 (
404 &[
405 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C,
406 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
407 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
408 ],
409 &[0x00, 0x01, 0x02, 0x03],
410 b"My Tagged Application",
411 &[
412 0x17, 0x55, 0x13, 0x3F, 0x15, 0x34, 0x75, 0x2A, 0xAD, 0x07, 0x48, 0xF2, 0xC7,
413 0x06, 0xFB, 0x5C, 0x78, 0x45, 0x12, 0xCA, 0xB8, 0x35, 0xCD, 0x15, 0x67, 0x6B,
414 0x16, 0xC0, 0xC6, 0x64, 0x7F, 0xA9, 0x6F, 0xAA, 0x7A, 0xF6, 0x34, 0xA0, 0xBF,
415 0x8F, 0xF6, 0xDF, 0x39, 0x37, 0x4F, 0xA0, 0x0F, 0xAD, 0x9A, 0x39, 0xE3, 0x22,
416 0xA7, 0xC9, 0x20, 0x65, 0xA6, 0x4E, 0xB1, 0xFB, 0x08, 0x01, 0xEB, 0x2B,
417 ],
418 ),
419 (
420 &[
421 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C,
422 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
423 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
424 ],
425 &[
426 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
427 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
428 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
429 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33,
430 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40,
431 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D,
432 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A,
433 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
434 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74,
435 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81,
436 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E,
437 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B,
438 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
439 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5,
440 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2,
441 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
442 ],
443 &[],
444 &[
445 0xFF, 0x7B, 0x17, 0x1F, 0x1E, 0x8A, 0x2B, 0x24, 0x68, 0x3E, 0xED, 0x37, 0x83,
446 0x0E, 0xE7, 0x97, 0x53, 0x8B, 0xA8, 0xDC, 0x56, 0x3F, 0x6D, 0xA1, 0xE6, 0x67,
447 0x39, 0x1A, 0x75, 0xED, 0xC0, 0x2C, 0xA6, 0x33, 0x07, 0x9F, 0x81, 0xCE, 0x12,
448 0xA2, 0x5F, 0x45, 0x61, 0x5E, 0xC8, 0x99, 0x72, 0x03, 0x1D, 0x18, 0x33, 0x73,
449 0x31, 0xD2, 0x4C, 0xEB, 0x8F, 0x8C, 0xA8, 0xE6, 0xA1, 0x9F, 0xD9, 0x8B,
450 ],
451 ),
452 (
453 &[
454 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C,
455 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
456 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
457 ],
458 &[
459 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
460 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
461 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
462 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33,
463 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40,
464 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D,
465 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A,
466 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
467 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74,
468 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81,
469 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E,
470 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B,
471 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
472 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5,
473 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2,
474 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
475 ],
476 b"My Tagged Application",
477 &[
478 0xD5, 0xBE, 0x73, 0x1C, 0x95, 0x4E, 0xD7, 0x73, 0x28, 0x46, 0xBB, 0x59, 0xDB,
479 0xE3, 0xA8, 0xE3, 0x0F, 0x83, 0xE7, 0x7A, 0x4B, 0xFF, 0x44, 0x59, 0xF2, 0xF1,
480 0xC2, 0xB4, 0xEC, 0xEB, 0xB8, 0xCE, 0x67, 0xBA, 0x01, 0xC6, 0x2E, 0x8A, 0xB8,
481 0x57, 0x8D, 0x2D, 0x49, 0x9B, 0xD1, 0xBB, 0x27, 0x67, 0x68, 0x78, 0x11, 0x90,
482 0x02, 0x0A, 0x30, 0x6A, 0x97, 0xDE, 0x28, 0x1D, 0xCC, 0x30, 0x30, 0x5D,
483 ],
484 ),
485 ];
486 for (i, &(k, data, s, want)) in vectors.iter().enumerate() {
487 let mut m = KmacXof256::new(k, s).unwrap();
488 m.update(data);
489 let got = m.finalize_xof().read_boxed(64);
490 assert_eq!(&*got, want, "#{i}");
491 }
492 }
493}