1use core::fmt;
2use digest::{
3 CollisionResistance, ExtendableOutput, ExtendableOutputReset, HashMarker, Reset, Update,
4 common::AlgorithmName,
5 consts::{U16, U32},
6};
7
8use crate::{Kt, KtReader, utils::length_encode};
9
10#[derive(Clone)]
12pub struct CustomRefKt<'a, const RATE: usize> {
13 customization: &'a [u8],
14 inner: Kt<RATE>,
15}
16
17impl<'a, const RATE: usize> CustomRefKt<'a, RATE> {
18 #[inline]
23 #[must_use]
24 pub fn new_customized(customization: &'a [u8]) -> Self {
25 Self {
26 customization,
27 inner: Default::default(),
28 }
29 }
30}
31
32impl<const RATE: usize> Default for CustomRefKt<'static, RATE> {
33 #[inline]
34 fn default() -> Self {
35 Self::new_customized(&[])
36 }
37}
38
39impl<const RATE: usize> fmt::Debug for CustomRefKt<'_, RATE> {
40 #[inline]
41 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
42 write!(f, "CustomKt{} {{ ... }}", 4 * (200 - RATE))
43 }
44}
45
46impl<const RATE: usize> AlgorithmName for CustomRefKt<'_, RATE> {
47 #[inline]
48 fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
49 Kt::<RATE>::write_alg_name(f)
50 }
51}
52
53impl<const RATE: usize> HashMarker for CustomRefKt<'_, RATE> {}
54
55impl<const RATE: usize> Update for CustomRefKt<'_, RATE> {
56 #[inline]
57 fn update(&mut self, data: &[u8]) {
58 self.inner.update(data);
59 }
60}
61
62impl<const RATE: usize> Reset for CustomRefKt<'_, RATE> {
63 #[inline]
64 fn reset(&mut self) {
65 self.inner.reset();
66 }
67}
68
69impl<const RATE: usize> CustomRefKt<'_, RATE> {
70 fn absorb_customization(&mut self) {
71 self.inner.update(self.customization);
72 let len = u64::try_from(self.customization.len()).expect("length always fits into `u64`");
73 length_encode(len, |enc_len| self.inner.update(enc_len));
74 }
75}
76
77impl<const RATE: usize> ExtendableOutput for CustomRefKt<'_, RATE> {
78 type Reader = KtReader<RATE>;
79
80 #[inline]
81 fn finalize_xof(mut self) -> Self::Reader {
82 self.absorb_customization();
83 self.inner.raw_finalize()
84 }
85}
86
87impl<const RATE: usize> ExtendableOutputReset for CustomRefKt<'_, RATE> {
88 #[inline]
89 fn finalize_xof_reset(&mut self) -> Self::Reader {
90 self.absorb_customization();
91 let reader = self.inner.raw_finalize();
92 self.inner.reset();
93 reader
94 }
95}
96
97#[cfg(feature = "zeroize")]
99impl<const RATE: usize> digest::zeroize::ZeroizeOnDrop for CustomRefKt<'_, RATE> {}
100
101pub type CustomRefKt128<'a> = CustomRefKt<'a, 168>;
103pub type CustomRefKt256<'a> = CustomRefKt<'a, 136>;
105
106impl CollisionResistance for CustomRefKt128<'_> {
107 type CollisionResistance = U16;
108}
109
110impl CollisionResistance for CustomRefKt256<'_> {
111 type CollisionResistance = U32;
112}