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