1use alloc::vec;
21use alloc::vec::Vec;
22use core::fmt;
23
24use digest::block_api::{
25 AlgorithmName,
26 Block,
27 BlockSizeUser,
28 BufferKindUser,
29 Eager,
30 UpdateCore,
31};
32use digest::common::hazmat::{
33 DeserializeStateError,
34 SerializableState,
35 SerializedState,
36};
37use digest::consts::{
38 U16,
39 U32,
40 U136,
41 U168,
42 U400,
43};
44use digest::{
45 CollisionResistance,
46 ExtendableOutput,
47 HashMarker,
48 Reset,
49 Update,
50 XofReader,
51};
52use subtle::{
53 Choice,
54 ConstantTimeEq,
55};
56use zeroize::Zeroize;
57
58use crate::cshake::{
59 CShake128,
60 CShake128Reader,
61 CShake256,
62 CShake256Reader,
63};
64use crate::utils::{
65 MAX_SP800185_FIXED_OUTPUT_BYTES,
66 left_encode,
67 right_encode,
68};
69
70#[derive(Clone)]
72pub struct Kmac128 {
73 inner: CShake128,
74}
75
76#[derive(Clone)]
78pub struct Kmac256 {
79 inner: CShake256,
80}
81
82#[derive(Clone)]
84pub struct Kmac128Reader {
85 inner: CShake128Reader,
86}
87
88#[derive(Clone)]
90pub struct Kmac256Reader {
91 inner: CShake256Reader,
92}
93
94macro_rules! impl_kmac {
95 (
96 $name:ident, $inner_type:ident, $reader_name:ident, $inner_reader_type:ident, $rate:ident, $rate_expr:expr, $alg_name:expr
97 ) => {
98 impl $name {
99 pub fn new(key: &[u8], custom: &[u8]) -> Self {
101 let mut kmac = Self {
102 inner: $inner_type::new_with_function_name(b"KMAC", custom),
103 };
104 kmac.init(key, $rate_expr);
105 kmac
106 }
107
108 fn init(&mut self, key: &[u8], rate: usize) {
109 let mut enc_buf = [0u8; 9];
113 let mut total = 0usize;
114
115 let le = left_encode(rate as u64, &mut enc_buf);
117 Update::update(&mut self.inner, le);
118 total += le.len();
119
120 let le = left_encode((key.len() * 8) as u64, &mut enc_buf);
122 Update::update(&mut self.inner, le);
123 total += le.len();
124
125 Update::update(&mut self.inner, key);
126 total += key.len();
127
128 let padding = (rate - (total % rate)) % rate;
130 if padding > 0 {
131 const ZEROS: [u8; 168] = [0u8; 168];
132 Update::update(&mut self.inner, &ZEROS[..padding]);
133 }
134 }
135
136 pub fn update(&mut self, data: &[u8]) {
138 Update::update(&mut self.inner, data);
139 }
140
141 pub fn finalize(mut self, output: &mut [u8]) -> Option<()> {
149 if output.len() > MAX_SP800185_FIXED_OUTPUT_BYTES {
150 return None;
151 }
152 self.with_bitlength((output.len() * 8) as u64);
153 ExtendableOutput::finalize_xof_into(self.inner, output);
154 Some(())
155 }
156
157 pub fn verify(mut self, expected: &[u8]) -> Choice {
170 if expected.len() > MAX_SP800185_FIXED_OUTPUT_BYTES {
171 return Choice::from(0u8);
172 }
173 let mut mac = vec![0u8; expected.len()];
174 self.with_bitlength((mac.len() * 8) as u64);
175 ExtendableOutput::finalize_xof_into(self.inner, &mut mac);
176 let ok = mac.ct_eq(expected);
177 mac.zeroize();
178 ok
179 }
180
181 pub fn finalize_with_length(mut self, output_len: usize) -> Option<Vec<u8>> {
186 if output_len > MAX_SP800185_FIXED_OUTPUT_BYTES {
187 return None;
188 }
189 let mut output = vec![0u8; output_len];
190 self.with_bitlength((output_len * 8) as u64);
191 ExtendableOutput::finalize_xof_into(self.inner, &mut output);
192 Some(output)
193 }
194
195 pub fn xof(mut self) -> $reader_name {
203 self.with_bitlength(0);
204 $reader_name {
205 inner: ExtendableOutput::finalize_xof(self.inner),
206 }
207 }
208
209 fn with_bitlength(&mut self, bitlength: u64) {
210 let mut enc_buf = [0u8; 9];
211 let length_encoded = right_encode(bitlength, &mut enc_buf);
212 Update::update(&mut self.inner, length_encoded);
213 }
214 }
215
216 impl BlockSizeUser for $name {
218 type BlockSize = $rate;
219 }
220
221 impl BufferKindUser for $name {
222 type BufferKind = Eager;
223 }
224
225 impl HashMarker for $name {}
226
227 impl Update for $name {
228 #[inline]
229 fn update(&mut self, data: &[u8]) {
230 Update::update(&mut self.inner, data);
231 }
232 }
233
234 impl UpdateCore for $name {
235 #[inline]
236 fn update_blocks(&mut self, blocks: &[Block<Self>]) {
237 for block in blocks {
238 self.inner.update(block);
239 }
240 }
241 }
242
243 impl Reset for $name {
244 #[inline]
245 fn reset(&mut self) {
246 self.inner.reset();
247 }
248 }
249
250 impl AlgorithmName for $name {
251 fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
252 f.write_str($alg_name)
253 }
254 }
255
256 impl fmt::Debug for $name {
257 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
258 f.write_str(concat!(stringify!($name), " { ... }"))
259 }
260 }
261
262 #[cfg(feature = "zeroize")]
263 impl digest::zeroize::ZeroizeOnDrop for $name {}
264
265 impl Default for $name {
267 fn default() -> Self {
268 Self::new(b"", b"")
269 }
270 }
271
272 impl XofReader for $reader_name {
274 fn read(&mut self, buf: &mut [u8]) {
275 self.inner.read(buf);
276 }
277 }
278
279 impl fmt::Debug for $reader_name {
280 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
281 f.write_str(concat!(stringify!($reader_name), " { ... }"))
282 }
283 }
284 };
285}
286
287impl_kmac!(
288 Kmac128,
289 CShake128,
290 Kmac128Reader,
291 CShake128Reader,
292 U168,
293 168usize,
294 "KMAC128"
295);
296impl_kmac!(
297 Kmac256,
298 CShake256,
299 Kmac256Reader,
300 CShake256Reader,
301 U136,
302 136usize,
303 "KMAC256"
304);
305
306impl CollisionResistance for Kmac128 {
307 type CollisionResistance = U16;
308}
309
310impl CollisionResistance for Kmac256 {
311 type CollisionResistance = U32;
312}
313
314impl SerializableState for Kmac128 {
316 type SerializedStateSize = U400;
317
318 fn serialize(&self) -> SerializedState<Self> {
319 self.inner.serialize()
320 }
321
322 fn deserialize(
323 serialized_state: &SerializedState<Self>,
324 ) -> Result<Self, DeserializeStateError> {
325 let inner = CShake128::deserialize(serialized_state)?;
326 Ok(Self { inner })
327 }
328}
329
330impl SerializableState for Kmac256 {
331 type SerializedStateSize = U400;
332
333 fn serialize(&self) -> SerializedState<Self> {
334 self.inner.serialize()
335 }
336
337 fn deserialize(
338 serialized_state: &SerializedState<Self>,
339 ) -> Result<Self, DeserializeStateError> {
340 let inner = CShake256::deserialize(serialized_state)?;
341 Ok(Self { inner })
342 }
343}
344
345#[cfg(test)]
346mod tests {
347 use hex_literal::hex;
348
349 use super::*;
350
351 fn nist_kmac_key() -> [u8; 32] {
352 let mut key = [0u8; 32];
353 for (idx, b) in key.iter_mut().enumerate() {
354 *b = 0x40 + (idx as u8);
355 }
356 key
357 }
358
359 fn nist_kmac_short_data() -> [u8; 4] {
360 [0x00, 0x01, 0x02, 0x03]
361 }
362
363 fn nist_kmac_long_data() -> Vec<u8> {
364 (0x00..=0xC7).collect()
365 }
366
367 fn kmac128_reference(key: &[u8], custom: &[u8], data: &[u8], out_len: usize) -> Vec<u8> {
368 let mut inner = CShake128::new_with_function_name(b"KMAC", custom);
369 let mut enc_buf = [0u8; 9];
370 let mut total = 0usize;
371
372 let le = left_encode(168, &mut enc_buf);
373 inner.update(le);
374 total += le.len();
375
376 let le = left_encode((key.len() * 8) as u64, &mut enc_buf);
377 inner.update(le);
378 total += le.len();
379
380 inner.update(key);
381 total += key.len();
382
383 let padding = (168 - (total % 168)) % 168;
384 if padding > 0 {
385 const ZEROS: [u8; 168] = [0u8; 168];
386 inner.update(&ZEROS[..padding]);
387 }
388
389 inner.update(data);
390 inner.update(right_encode((out_len * 8) as u64, &mut enc_buf));
391
392 let mut out = vec![0u8; out_len];
393 inner.finalize_xof_into(&mut out);
394 out
395 }
396
397 fn kmac256_reference(key: &[u8], custom: &[u8], data: &[u8], out_len: usize) -> Vec<u8> {
398 let mut inner = CShake256::new_with_function_name(b"KMAC", custom);
399 let mut enc_buf = [0u8; 9];
400 let mut total = 0usize;
401
402 let le = left_encode(136, &mut enc_buf);
403 inner.update(le);
404 total += le.len();
405
406 let le = left_encode((key.len() * 8) as u64, &mut enc_buf);
407 inner.update(le);
408 total += le.len();
409
410 inner.update(key);
411 total += key.len();
412
413 let padding = (136 - (total % 136)) % 136;
414 if padding > 0 {
415 const ZEROS: [u8; 136] = [0u8; 136];
416 inner.update(&ZEROS[..padding]);
417 }
418
419 inner.update(data);
420 inner.update(right_encode((out_len * 8) as u64, &mut enc_buf));
421
422 let mut out = vec![0u8; out_len];
423 inner.finalize_xof_into(&mut out);
424 out
425 }
426
427 #[test]
428 fn test_kmac128_basic() {
429 let key = b"key";
430 let custom = b"custom";
431 let data = b"test data";
432
433 let mut kmac = Kmac128::new(key, custom);
434 kmac.update(data);
435
436 let mut output = [0u8; 32];
437 kmac.finalize(&mut output).unwrap();
438 assert_ne!(output, [0u8; 32]);
439 }
440
441 #[test]
442 fn test_kmac256_basic() {
443 let key = b"key";
444 let custom = b"custom";
445 let data = b"test data";
446
447 let mut kmac = Kmac256::new(key, custom);
448 kmac.update(data);
449
450 let mut output = [0u8; 64];
451 kmac.finalize(&mut output).unwrap();
452 assert_ne!(output, [0u8; 64]);
453 }
454
455 #[test]
456 fn test_kmac_xof() {
457 let key = b"key";
458 let custom = b"custom";
459 let data = b"test data";
460
461 let mut kmac = Kmac128::new(key, custom);
462 kmac.update(data);
463
464 let mut reader = kmac.xof();
465 let mut output = [0u8; 100];
466 reader.read(&mut output);
467 assert_ne!(output, [0u8; 100]);
468 }
469
470 #[test]
471 fn test_kmac_different_keys() {
472 let custom = b"custom";
473 let data = b"test data";
474
475 let mut kmac1 = Kmac128::new(b"key1", custom);
476 kmac1.update(data);
477 let mut output1 = [0u8; 32];
478 kmac1.finalize(&mut output1).unwrap();
479
480 let mut kmac2 = Kmac128::new(b"key2", custom);
481 kmac2.update(data);
482 let mut output2 = [0u8; 32];
483 kmac2.finalize(&mut output2).unwrap();
484
485 assert_ne!(output1, output2);
486 }
487
488 #[test]
489 fn test_kmac_different_customs() {
490 let key = b"key";
491 let data = b"test data";
492
493 let mut kmac1 = Kmac128::new(key, b"custom1");
494 kmac1.update(data);
495 let mut output1 = [0u8; 32];
496 kmac1.finalize(&mut output1).unwrap();
497
498 let mut kmac2 = Kmac128::new(key, b"custom2");
499 kmac2.update(data);
500 let mut output2 = [0u8; 32];
501 kmac2.finalize(&mut output2).unwrap();
502
503 assert_ne!(output1, output2);
504 }
505
506 #[test]
507 fn test_kmac_reset() {
508 let key = b"key";
509 let custom = b"custom";
510 let data = b"test data";
511
512 let mut kmac = Kmac128::new(key, custom);
513 kmac.update(data);
514
515 kmac.reset();
517 kmac.update(data);
518
519 let mut output = [0u8; 32];
520 kmac.finalize(&mut output).unwrap();
521 assert_ne!(output, [0u8; 32]);
522 }
523
524 #[test]
525 fn test_kmac_default() {
526 let kmac = Kmac128::default();
527 let data = b"test data";
528
529 let mut hasher = kmac;
530 hasher.update(data);
531 let result = hasher.finalize_with_length(32).unwrap();
532 assert_eq!(result.len(), 32);
533 }
534
535 #[test]
536 fn test_kmac_serialization() {
537 let key = b"key";
538 let custom = b"custom";
539 let data = b"test data";
540
541 let mut kmac = Kmac128::new(key, custom);
542 kmac.update(data);
543
544 let serialized = kmac.serialize();
546
547 let mut kmac2 = Kmac128::deserialize(&serialized).unwrap();
549 kmac2.update(b"more data");
550
551 let mut output = [0u8; 32];
552 kmac2.finalize(&mut output).unwrap();
553 assert_ne!(output, [0u8; 32]);
554 }
555
556 #[test]
557 fn test_kmac128_matches_reference_construction() {
558 let key = b"auditor-sensitive-key-material";
559 let custom = b"lib-q kmac reference";
560 let data = b"input message for kmac128";
561
562 let mut kmac = Kmac128::new(key, custom);
563 kmac.update(data);
564 let mut got = [0u8; 32];
565 kmac.finalize(&mut got).unwrap();
566
567 let expected = kmac128_reference(key, custom, data, 32);
568 assert_eq!(got.as_slice(), expected.as_slice());
569 }
570
571 #[test]
572 fn test_kmac256_matches_reference_construction() {
573 let key = b"auditor-sensitive-key-material";
574 let custom = b"lib-q kmac reference";
575 let data = b"input message for kmac256";
576
577 let mut kmac = Kmac256::new(key, custom);
578 kmac.update(data);
579 let mut got = [0u8; 64];
580 kmac.finalize(&mut got).unwrap();
581
582 let expected = kmac256_reference(key, custom, data, 64);
583 assert_eq!(got.as_slice(), expected.as_slice());
584 }
585
586 #[test]
587 fn test_kmac128_nist_sample_1() {
588 let key = nist_kmac_key();
589 let data = nist_kmac_short_data();
590 let custom = b"";
591 let expected = hex!(
592 "E5780B0D3EA6F7D3A429C5706AA43A00
593 FADBD7D49628839E3187243F456EE14E"
594 );
595
596 let mut kmac = Kmac128::new(&key, custom);
597 kmac.update(&data);
598 let mut out = [0u8; 32];
599 kmac.finalize(&mut out).unwrap();
600 assert_eq!(out, expected);
601 }
602
603 #[test]
604 fn test_kmac128_nist_sample_2() {
605 let key = nist_kmac_key();
606 let data = nist_kmac_short_data();
607 let custom = b"My Tagged Application";
608 let expected = hex!(
609 "3B1FBA963CD8B0B59E8C1A6D71888B71
610 43651AF8BA0A7070C0979E2811324AA5"
611 );
612
613 let mut kmac = Kmac128::new(&key, custom);
614 kmac.update(&data);
615 let mut out = [0u8; 32];
616 kmac.finalize(&mut out).unwrap();
617 assert_eq!(out, expected);
618 }
619
620 #[test]
621 fn test_kmac128_nist_sample_3() {
622 let key = nist_kmac_key();
623 let data = nist_kmac_long_data();
624 let custom = b"My Tagged Application";
625 let expected = hex!(
626 "1F5B4E6CCA02209E0DCB5CA635B89A15
627 E271ECC760071DFD805FAA38F9729230"
628 );
629
630 let mut kmac = Kmac128::new(&key, custom);
631 kmac.update(&data);
632 let mut out = [0u8; 32];
633 kmac.finalize(&mut out).unwrap();
634 assert_eq!(out, expected);
635 }
636
637 #[test]
638 fn test_kmac256_nist_sample_4() {
639 let key = nist_kmac_key();
640 let data = nist_kmac_short_data();
641 let custom = b"My Tagged Application";
642 let expected = hex!(
643 "20C570C31346F703C9AC36C61C03CB64
644 C3970D0CFC787E9B79599D273A68D2F7
645 F69D4CC3DE9D104A351689F27CF6F595
646 1F0103F33F4F24871024D9C27773A8DD"
647 );
648
649 let mut kmac = Kmac256::new(&key, custom);
650 kmac.update(&data);
651 let mut out = [0u8; 64];
652 kmac.finalize(&mut out).unwrap();
653 assert_eq!(out, expected);
654 }
655
656 #[test]
657 fn test_kmac256_nist_sample_5() {
658 let key = nist_kmac_key();
659 let data = nist_kmac_long_data();
660 let custom = b"";
661 let expected = hex!(
662 "75358CF39E41494E949707927CEE0AF2
663 0A3FF553904C86B08F21CC414BCFD691
664 589D27CF5E15369CBBFF8B9A4C2EB178
665 00855D0235FF635DA82533EC6B759B69"
666 );
667
668 let mut kmac = Kmac256::new(&key, custom);
669 kmac.update(&data);
670 let mut out = [0u8; 64];
671 kmac.finalize(&mut out).unwrap();
672 assert_eq!(out, expected);
673 }
674
675 #[test]
676 fn test_kmac256_nist_sample_6() {
677 let key = nist_kmac_key();
678 let data = nist_kmac_long_data();
679 let custom = b"My Tagged Application";
680 let expected = hex!(
681 "B58618F71F92E1D56C1B8C55DDD7CD18
682 8B97B4CA4D99831EB2699A837DA2E4D9
683 70FBACFDE50033AEA585F1A2708510C3
684 2D07880801BD182898FE476876FC8965"
685 );
686
687 let mut kmac = Kmac256::new(&key, custom);
688 kmac.update(&data);
689 let mut out = [0u8; 64];
690 kmac.finalize(&mut out).unwrap();
691 assert_eq!(out, expected);
692 }
693
694 #[test]
695 fn test_kmac128_verify_matches_finalize() {
696 let key = nist_kmac_key();
697 let data = nist_kmac_short_data();
698 let custom = b"My Tagged Application";
699 let expected = hex!(
700 "3B1FBA963CD8B0B59E8C1A6D71888B71
701 43651AF8BA0A7070C0979E2811324AA5"
702 );
703
704 let mut kmac = Kmac128::new(&key, custom);
705 kmac.update(&data);
706 let mut finalized = [0u8; 32];
707 kmac.finalize(&mut finalized).unwrap();
708 assert_eq!(finalized.as_slice(), expected.as_slice());
709
710 let mut kmac2 = Kmac128::new(&key, custom);
711 kmac2.update(&data);
712 assert!(bool::from(kmac2.verify(&expected)));
713
714 let mut wrong = expected;
715 wrong[0] ^= 0x01;
716 let mut kmac3 = Kmac128::new(&key, custom);
717 kmac3.update(&data);
718 assert!(!bool::from(kmac3.verify(&wrong)));
719 }
720
721 #[test]
722 fn test_kmac256_verify_nist() {
723 let key = nist_kmac_key();
724 let data = nist_kmac_short_data();
725 let custom = b"My Tagged Application";
726 let expected = hex!(
727 "20C570C31346F703C9AC36C61C03CB64
728 C3970D0CFC787E9B79599D273A68D2F7
729 F69D4CC3DE9D104A351689F27CF6F595
730 1F0103F33F4F24871024D9C27773A8DD"
731 );
732
733 let mut kmac = Kmac256::new(&key, custom);
734 kmac.update(&data);
735 assert!(bool::from(kmac.verify(&expected)));
736
737 let mut wrong = expected;
738 wrong[31] ^= 0x80;
739 let mut kmac2 = Kmac256::new(&key, custom);
740 kmac2.update(&data);
741 assert!(!bool::from(kmac2.verify(&wrong)));
742 }
743
744 #[test]
745 fn test_kmac_verify_rejects_oversized_expected_without_large_alloc() {
746 let key = b"k";
747 let data = b"d";
748 let oversized = vec![0u8; MAX_SP800185_FIXED_OUTPUT_BYTES + 1];
749 let mut kmac = Kmac128::new(key, b"");
750 kmac.update(data);
751 assert!(!bool::from(kmac.verify(&oversized)));
752 }
753
754 #[test]
755 fn test_kmac_finalize_with_length_rejects_over_cap() {
756 let mut kmac = Kmac128::new(b"k", b"");
757 kmac.update(b"x");
758 assert!(
759 kmac.finalize_with_length(MAX_SP800185_FIXED_OUTPUT_BYTES + 1)
760 .is_none()
761 );
762 }
763
764 #[test]
765 fn test_kmac_finalize_rejects_over_cap_output_buffer() {
766 let mut kmac = Kmac128::new(b"k", b"");
767 kmac.update(b"x");
768 let mut out = vec![0u8; MAX_SP800185_FIXED_OUTPUT_BYTES + 1];
769 assert!(kmac.finalize(&mut out).is_none());
770 }
771
772 #[test]
779 fn test_kmac128_verify_rejects_mismatch_at_every_byte_position() {
780 let key = b"key";
781 let data = b"data";
782 let mut kmac = Kmac128::new(key, b"custom");
783 kmac.update(data);
784 let mut good = [0u8; 32];
785 kmac.finalize(&mut good).unwrap();
786
787 for i in 0..good.len() {
788 let mut bad = good;
789 bad[i] ^= 0x01;
790 let mut kmac2 = Kmac128::new(key, b"custom");
791 kmac2.update(data);
792 assert!(
793 !bool::from(kmac2.verify(&bad)),
794 "mismatch at byte {i} was not rejected"
795 );
796 }
797 }
798
799 #[test]
802 fn test_kmac128_verify_rejects_wrong_length_expected() {
803 let key = b"key";
804 let data = b"data";
805 let mut kmac = Kmac128::new(key, b"custom");
806 kmac.update(data);
807 let mut good = [0u8; 32];
808 kmac.finalize(&mut good).unwrap();
809
810 let mut kmac2 = Kmac128::new(key, b"custom");
811 kmac2.update(data);
812 assert!(!bool::from(kmac2.verify(&good[..16])));
813
814 let mut over_long = good.to_vec();
815 over_long.push(0);
816 let mut kmac3 = Kmac128::new(key, b"custom");
817 kmac3.update(data);
818 assert!(!bool::from(kmac3.verify(&over_long)));
819 }
820}