Skip to main content

k12/
lib.rs

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
13/// Block-level types
14pub 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    // https://www.rfc-editor.org/rfc/rfc9861.html#section-7-7
141    type CollisionResistance = U16;
142}
143
144impl CollisionResistance for Kt256<'_> {
145    // https://www.rfc-editor.org/rfc/rfc9861.html#section-7-8
146    type CollisionResistance = U32;
147}
148
149/// KT128 hasher.
150#[deprecated(since = "0.4.0-pre", note = "use `Kt128` instead")]
151pub type KangarooTwelve<'cs> = Kt128<'cs>;
152
153/// KT128 XOF reader.
154#[deprecated(since = "0.4.0-pre", note = "use `Kt128Reader` instead")]
155pub type KangarooTwelveReader = Kt128Reader;