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