Skip to main content

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`](Digest::update) and [`Update::update`](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_api`]: 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`; the `doc_cfg`
20//! rustdoc feature marks APIs that require a Cargo feature. 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#![cfg_attr(docsrs, feature(doc_cfg))]
34#![forbid(unsafe_code)]
35#![warn(missing_docs, missing_debug_implementations)]
36
37pub use digest::{
38    self,
39    CollisionResistance,
40    CustomizedInit,
41    Digest,
42    ExtendableOutput,
43    ExtendableOutputReset,
44    Update,
45    XofReader,
46};
47
48/// Block-level types and Keccak cores for advanced composition (e.g. K12). Most callers should use the crate-root types.
49pub mod block_api;
50/// cSHAKE-128 and cSHAKE-256 (NIST SP 800-185). Types are re-exported at the crate root.
51pub mod cshake;
52/// TurboSHAKE-128 and TurboSHAKE-256. Types are re-exported at the crate root.
53pub mod turbo_shake;
54
55use block_api::{
56    SpongeHasherCore,
57    SpongeReaderCore,
58};
59#[doc(inline)]
60pub use cshake::{
61    CShake128,
62    CShake128Reader,
63    CShake256,
64    CShake256Reader,
65};
66use digest::consts::{
67    U0,
68    U16,
69    U28,
70    U32,
71    U48,
72    U64,
73    U72,
74    U104,
75    U136,
76    U144,
77    U168,
78};
79#[doc(inline)]
80pub use turbo_shake::{
81    TurboShake128,
82    TurboShake128Reader,
83    TurboShake256,
84    TurboShake256Reader,
85};
86
87/// One-shot **SHA3-256** (FIPS 202) over `data`.
88///
89/// Equivalent to [`Sha3_256`]`::`[`digest`](Digest::digest)`(data)` but may inline more aggressively. For incremental input or state serialization, use [`Sha3_256`] and [`Digest`].
90#[inline(always)]
91pub fn sha3_256(data: &[u8]) -> [u8; 32] {
92    let mut hasher = Sha3_256::new();
93    Digest::update(&mut hasher, data);
94    hasher.finalize().into()
95}
96
97// Paddings
98const SHA3_PAD: u8 = 0x06;
99const SHAKE_PAD: u8 = 0x1F;
100const CSHAKE_PAD: u8 = 0x04;
101
102const PLEN: usize = 25;
103const DEFAULT_ROUND_COUNT: usize = 24;
104
105digest::buffer_fixed!(
106    /// SHA-3-224 (FIPS 202).
107    pub struct Sha3_224(SpongeHasherCore<U144, U28, SHA3_PAD>);
108    oid: "2.16.840.1.101.3.4.2.7";
109    impl: FixedHashTraits;
110);
111digest::buffer_fixed!(
112    /// SHA-3-256 (FIPS 202).
113    pub struct Sha3_256(SpongeHasherCore<U136, U32, SHA3_PAD>);
114    oid: "2.16.840.1.101.3.4.2.8";
115    impl: FixedHashTraits;
116);
117digest::buffer_fixed!(
118    /// SHA-3-384 (FIPS 202).
119    pub struct Sha3_384(SpongeHasherCore<U104, U48, SHA3_PAD>);
120    oid: "2.16.840.1.101.3.4.2.9";
121    impl: FixedHashTraits;
122);
123digest::buffer_fixed!(
124    /// SHA-3-512 (FIPS 202).
125    pub struct Sha3_512(SpongeHasherCore<U72, U64, SHA3_PAD>);
126    oid: "2.16.840.1.101.3.4.2.10";
127    impl: FixedHashTraits;
128);
129digest::buffer_xof!(
130    /// SHAKE128 (FIPS 202, extendable output).
131    pub struct Shake128(SpongeHasherCore<U168, U0, SHAKE_PAD>);
132    oid: "2.16.840.1.101.3.4.2.11";
133    impl: XofHasherTraits;
134    /// SHAKE128 XOF output reader.
135    pub struct Shake128Reader(SpongeReaderCore<U168>);
136    impl: XofReaderTraits;
137);
138digest::buffer_xof!(
139    /// SHAKE256 (FIPS 202, extendable output).
140    pub struct Shake256(SpongeHasherCore<U136, U0, SHAKE_PAD>);
141    oid: "2.16.840.1.101.3.4.2.12";
142    impl: XofHasherTraits;
143    /// SHAKE256 XOF output reader.
144    pub struct Shake256Reader(SpongeReaderCore<U136>);
145    impl: XofReaderTraits;
146);
147
148impl CollisionResistance for Shake128 {
149    // https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf#page=31
150    type CollisionResistance = U16;
151}
152
153impl CollisionResistance for Shake256 {
154    // https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf#page=31
155    type CollisionResistance = U32;
156}