lib_q_sha3/lib.rs
1//! SHA-3 family for lib-Q: fixed-output **SHA-3** (FIPS 202), **SHAKE** and **cSHAKE** XOFs, **TurboSHAKE**. Raw pre-FIPS **Keccak** digests are in [`lib_q_keccak_digest`](https://github.com/Enkom-Tech/libQ/tree/main/lib-q-keccak-digest).
2//!
3//! # Re-exports
4//!
5//! - [`digest`]: the `digest` crate (version unified with the workspace).
6//! - [`Digest`], [`Update`], [`ExtendableOutput`], [`ExtendableOutputReset`], [`XofReader`], [`CustomizedInit`], [`CollisionResistance`]: common [`digest`](https://docs.rs/digest) traits, re-exported at the root. For XOFs use [`Update`], [`ExtendableOutput`], and [`XofReader`]. If a module imports both [`Digest`] and [`Update`], disambiguate [`Digest::update`] and [`Update::update`] with explicit trait paths.
7//!
8//! # Modules
9//!
10//! - [`cshake`]: cSHAKE-128/256 (NIST SP 800-185).
11//! - [`turbo_shake`]: TurboSHAKE-128/256 (12-round Keccak; used by RFC 9861 KangarooTwelve in [`lib_q_k12`](https://github.com/Enkom-Tech/libQ/tree/main/lib-q-k12)).
12//! - [`block_core`]: low-level cores and Keccak state for composition (e.g. K12); not needed for typical hashing.
13//!
14//! The rest of the API is re-exported at the crate root for discoverability. See the crate **README** (front page of docs) for standards links, feature flags, and **security** considerations.
15//!
16//! # Crate features
17//!
18//! Optional Cargo features: `alloc`, `oid`, `zeroize`, `asm` (see the README *Feature flags* table).
19//! On [docs.rs](https://docs.rs/lib-q-sha3), this crate is built with `all-features`; rustdoc
20//! marks APIs that require a Cargo feature automatically. The `zeroize` feature enables
21//! [`ZeroizeOnDrop`](https://docs.rs/digest/latest/digest/trait.ZeroizeOnDrop.html) (from the `zeroize` feature) on supported types.
22//!
23//! # `sha3_256` vs `Sha3_256`
24//!
25//! [`sha3_256`](fn.sha3_256.html) is a small convenience for one-shot hashing. Prefer [`Sha3_256`] with the [`Digest`] trait when reusing a hasher or when you need serialization / OID features.
26
27#![no_std]
28#![doc = include_str!("../README.md")]
29#![doc(
30 html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
31 html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
32)]
33#![forbid(unsafe_code)]
34#![warn(missing_docs, missing_debug_implementations)]
35
36pub use digest::{
37 self,
38 CollisionResistance,
39 CustomizedInit,
40 Digest,
41 ExtendableOutput,
42 ExtendableOutputReset,
43 Update,
44 XofReader,
45};
46
47/// Block-level types and Keccak cores for advanced composition (e.g. K12). Most callers should use the crate-root types.
48pub mod block_core;
49/// cSHAKE-128 and cSHAKE-256 (NIST SP 800-185). Types are re-exported at the crate root.
50pub mod cshake;
51/// Four-way batched TurboSHAKE (AVX2-accelerated leaf hashing for KangarooTwelve).
52pub mod parallel;
53/// TurboSHAKE-128 and TurboSHAKE-256. Types are re-exported at the crate root.
54pub mod turbo_shake;
55
56use block_core::{
57 SpongeHasherCore,
58 SpongeReaderCore,
59};
60#[doc(inline)]
61pub use cshake::{
62 CShake128,
63 CShake128Reader,
64 CShake256,
65 CShake256Reader,
66};
67use digest::consts::{
68 U0,
69 U16,
70 U28,
71 U32,
72 U48,
73 U64,
74 U72,
75 U104,
76 U136,
77 U144,
78 U168,
79};
80#[doc(inline)]
81pub use turbo_shake::{
82 TurboShake128,
83 TurboShake128Reader,
84 TurboShake256,
85 TurboShake256Reader,
86};
87
88/// One-shot **SHA3-256** (FIPS 202) over `data`.
89///
90/// Equivalent to [`Sha3_256`]`::`[`digest`](Digest::digest)`(data)` but may inline more aggressively. For incremental input or state serialization, use [`Sha3_256`] and [`Digest`].
91#[inline(always)]
92pub fn sha3_256(data: &[u8]) -> [u8; 32] {
93 let mut hasher = Sha3_256::new();
94 Digest::update(&mut hasher, data);
95 hasher.finalize().into()
96}
97
98// Paddings
99const SHA3_PAD: u8 = 0x06;
100const SHAKE_PAD: u8 = 0x1F;
101const CSHAKE_PAD: u8 = 0x04;
102
103const PLEN: usize = 25;
104const DEFAULT_ROUND_COUNT: usize = 24;
105
106/// XOR a (partial) block into the Keccak state lanes (little-endian).
107///
108/// Shared Keccak-sponge helper used by both the block API and cSHAKE; lives at the crate root
109/// so neither module has to depend on the other.
110pub(crate) fn xor_block(state: &mut [u64; PLEN], block: &[u8]) {
111 assert!(block.len() < 8 * PLEN);
112
113 let (chunks, rem) = block.as_chunks::<8>();
114 for (s, chunk) in state.iter_mut().zip(chunks) {
115 *s ^= u64::from_le_bytes(*chunk);
116 }
117
118 if !rem.is_empty() {
119 let mut buf = [0u8; 8];
120 buf[..rem.len()].copy_from_slice(rem);
121 let n = block.len() / 8;
122 state[n] ^= u64::from_le_bytes(buf);
123 }
124}
125
126digest::buffer_fixed!(
127 /// SHA-3-224 (FIPS 202).
128 pub struct Sha3_224(SpongeHasherCore<U144, U28, SHA3_PAD>);
129 oid: "2.16.840.1.101.3.4.2.7";
130 impl: FixedHashTraits;
131);
132digest::buffer_fixed!(
133 /// SHA-3-256 (FIPS 202).
134 pub struct Sha3_256(SpongeHasherCore<U136, U32, SHA3_PAD>);
135 oid: "2.16.840.1.101.3.4.2.8";
136 impl: FixedHashTraits;
137);
138digest::buffer_fixed!(
139 /// SHA-3-384 (FIPS 202).
140 pub struct Sha3_384(SpongeHasherCore<U104, U48, SHA3_PAD>);
141 oid: "2.16.840.1.101.3.4.2.9";
142 impl: FixedHashTraits;
143);
144digest::buffer_fixed!(
145 /// SHA-3-512 (FIPS 202).
146 pub struct Sha3_512(SpongeHasherCore<U72, U64, SHA3_PAD>);
147 oid: "2.16.840.1.101.3.4.2.10";
148 impl: FixedHashTraits;
149);
150digest::buffer_xof!(
151 /// SHAKE128 (FIPS 202, extendable output).
152 pub struct Shake128(SpongeHasherCore<U168, U0, SHAKE_PAD>);
153 oid: "2.16.840.1.101.3.4.2.11";
154 impl: XofHasherTraits;
155 /// SHAKE128 XOF output reader.
156 pub struct Shake128Reader(SpongeReaderCore<U168>);
157 impl: XofReaderTraits;
158);
159digest::buffer_xof!(
160 /// SHAKE256 (FIPS 202, extendable output).
161 pub struct Shake256(SpongeHasherCore<U136, U0, SHAKE_PAD>);
162 oid: "2.16.840.1.101.3.4.2.12";
163 impl: XofHasherTraits;
164 /// SHAKE256 XOF output reader.
165 pub struct Shake256Reader(SpongeReaderCore<U136>);
166 impl: XofReaderTraits;
167);
168
169impl CollisionResistance for Shake128 {
170 // https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf#page=31
171 type CollisionResistance = U16;
172}
173
174impl CollisionResistance for Shake256 {
175 // https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf#page=31
176 type CollisionResistance = U32;
177}