1#![no_std]
2#![doc = include_str!("../README.md")]
3#![doc(
4 html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
5 html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
6)]
7#![forbid(unsafe_code)]
8#![warn(missing_docs, unreachable_pub)]
9
10#[cfg(feature = "alloc")]
11extern crate alloc;
12
13pub use digest;
14
15pub mod block_api;
17
18use core::fmt;
19
20use digest::block_api::{
21 AlgorithmName,
22 BlockSizeUser,
23 ExtendableOutputCore,
24 UpdateCore,
25 XofReaderCore,
26};
27use digest::block_buffer::{
28 BlockBuffer,
29 Eager,
30 ReadBuffer,
31};
32use digest::consts::{
33 U16,
34 U32,
35 U128,
36 U136,
37 U168,
38};
39use digest::{
40 CollisionResistance,
41 ExtendableOutput,
42 HashMarker,
43 Reset,
44 Update,
45 XofReader,
46};
47
48macro_rules! impl_k12 {
49 (
50 $name:ident, $reader_name:ident, $core_name:ident, $reader_core_name:ident, $rate:ty,
51 $alg_name:literal,
52 ) => {
53 #[doc = $alg_name]
54 #[doc = " hasher."]
55 #[derive(Default, Clone)]
56 pub struct $name<'cs> {
57 core: block_api::$core_name<'cs>,
58 buffer: BlockBuffer<U128, Eager>,
59 }
60
61 impl<'cs> $name<'cs> {
62 #[doc = "Creates a new"]
63 #[doc = $alg_name]
64 #[doc = " instance with the given customization string."]
65 pub fn new(customization: &'cs [u8]) -> Self {
66 Self {
67 core: block_api::$core_name::new(customization),
68 buffer: Default::default(),
69 }
70 }
71 }
72
73 impl fmt::Debug for $name<'_> {
74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
75 f.write_str(concat!(stringify!($name), " { .. }"))
76 }
77 }
78
79 impl AlgorithmName for $name<'_> {
80 fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
81 f.write_str($alg_name)
82 }
83 }
84
85 impl HashMarker for $name<'_> {}
86
87 impl BlockSizeUser for $name<'_> {
88 type BlockSize = U128;
89 }
90
91 impl Update for $name<'_> {
92 fn update(&mut self, data: &[u8]) {
93 let Self { core, buffer } = self;
94 buffer.digest_blocks(data, |blocks| core.update_blocks(blocks));
95 }
96 }
97
98 impl Reset for $name<'_> {
99 fn reset(&mut self) {
100 self.core.reset();
101 self.buffer.reset();
102 }
103 }
104
105 impl ExtendableOutput for $name<'_> {
106 type Reader = $reader_name;
107
108 #[inline]
109 fn finalize_xof(mut self) -> Self::Reader {
110 Self::Reader {
111 core: self.core.finalize_xof_core(&mut self.buffer),
112 buffer: Default::default(),
113 }
114 }
115 }
116
117 #[cfg(feature = "zeroize")]
118 impl digest::zeroize::ZeroizeOnDrop for $name<'_> {}
119
120 #[doc = $alg_name]
121 #[doc = " XOF reader."]
122 pub struct $reader_name {
123 core: block_api::$reader_core_name,
124 buffer: ReadBuffer<$rate>,
125 }
126
127 impl fmt::Debug for $reader_name {
128 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
129 f.write_str(concat!(stringify!($reader_name), " { .. }"))
130 }
131 }
132
133 impl XofReader for $reader_name {
134 #[inline]
135 fn read(&mut self, buffer: &mut [u8]) {
136 let Self { core, buffer: buf } = self;
137 buf.read(buffer, |block| *block = core.read_block());
138 }
139 }
140
141 #[cfg(feature = "zeroize")]
142 impl digest::zeroize::ZeroizeOnDrop for $reader_name {}
143 };
144}
145
146impl_k12!(
147 Kt128,
148 Kt128Reader,
149 Kt128Core,
150 Kt128ReaderCore,
151 U168,
152 "KT128",
153);
154impl_k12!(
155 Kt256,
156 Kt256Reader,
157 Kt256Core,
158 Kt256ReaderCore,
159 U136,
160 "KT256",
161);
162
163impl CollisionResistance for Kt128<'_> {
171 type CollisionResistance = U16;
172}
173
174impl CollisionResistance for Kt256<'_> {
183 type CollisionResistance = U32;
184}