secure_gate/lib.rs
1// uncomment for doctest runs
2// #![doc = include_str!("../EXAMPLES.md")]
3// #![doc = include_str!("../README.md")]
4// Forbid unsafe code unconditionally
5#![forbid(unsafe_code)]
6
7//! Zero-cost secure wrappers for secrets — [`Dynamic<T>`] for heap-allocated variable-length data,
8//! [`Fixed<T>`] for stack-allocated fixed-size data.
9//!
10//! This crate provides explicit, guarded wrappers for sensitive values (e.g. keys, tokens, ciphertexts)
11//! with controlled exposure via `.expose_secret()` / `.expose_secret_mut()`. No accidental leaks via
12//! `Deref`, `AsRef`, or implicit conversions.
13//!
14//! See [README.md](../README.md) for usage examples, feature overview, and macros for custom aliases.
15//!
16//! ## Equality Options
17//!
18//!
19//! [`ConstantTimeEq`] (via `ct-eq` feature): Direct byte-by-byte constant-time comparison using `subtle`.
20//! Best for small/fixed-size secrets (< ~256–512 bytes) where speed matters most.
21//!
22//! [`ConstantTimeEqExt`] (via `ct-eq-hash` feature): BLAKE3 hash -> constant-time compare on fixed 32-byte digest.
23//! Faster for large/variable secrets (e.g. ML-KEM ciphertexts ~1–1.5 KiB, ML-DSA signatures ~2–4 KiB),
24//! with length hiding and optional keyed mode (`rand` for per-process random key).
25//!
26//! See the ConstantTimeEqExt trait documentation for performance numbers, security properties (probabilistic, timing-safe), and guidance on when to choose each (or hybrid).
27
28// Note: Enabling both 'alloc' and 'no-alloc' allows 'alloc' to take precedence.
29// This is permitted for docs.rs compatibility (--all-features) but should be avoided in normal builds.
30// Prefer using 'no-alloc' alone for true no-heap builds.
31
32#[cfg(feature = "alloc")]
33extern crate alloc;
34
35/// Dynamic secret wrapper types - available with `alloc` feature.
36/// These provide fundamental secure storage abstractions for dynamic data.
37#[cfg(feature = "alloc")]
38mod dynamic;
39
40/// Fixed-size secret wrapper types - always available with zero dependencies.
41/// These provide fundamental secure storage abstractions for fixed-size data.
42mod fixed;
43
44/// Centralized error types - always available.
45mod error;
46
47/// Core traits for wrapper polymorphism - always available.
48mod traits;
49
50#[cfg(feature = "alloc")]
51/// Re-export of the [`Dynamic`] type.
52pub use dynamic::Dynamic;
53/// Re-export of the [`Fixed`] type.
54pub use fixed::Fixed;
55
56#[cfg(feature = "cloneable")]
57pub use traits::CloneableType;
58/// Re-export of the traits.
59#[cfg(feature = "ct-eq")]
60pub use traits::ConstantTimeEq;
61#[cfg(feature = "ct-eq-hash")]
62pub use traits::ConstantTimeEqExt;
63#[cfg(feature = "serde-serialize")]
64pub use traits::SerializableType;
65pub use traits::{ExposeSecret, ExposeSecretMut};
66
67// Type alias macros (always available).
68// Convenient macros for creating custom secret wrapper types.
69mod macros;
70
71#[cfg(feature = "encoding-base64")]
72pub use traits::FromBase64UrlStr;
73#[cfg(feature = "encoding-bech32")]
74pub use traits::FromBech32Str;
75#[cfg(any(feature = "encoding-bech32", feature = "encoding-bech32m"))]
76pub use traits::FromBech32mStr;
77#[cfg(feature = "encoding-hex")]
78pub use traits::FromHexStr;
79
80#[cfg(feature = "encoding-base64")]
81pub use traits::ToBase64Url;
82#[cfg(feature = "encoding-bech32")]
83pub use traits::ToBech32;
84#[cfg(any(feature = "encoding-bech32", feature = "encoding-bech32m"))]
85pub use traits::ToBech32m;
86#[cfg(feature = "encoding-hex")]
87pub use traits::ToHex;
88
89#[cfg(any(
90 feature = "encoding-hex",
91 feature = "encoding-base64",
92 feature = "encoding-bech32",
93 feature = "encoding-bech32m"
94))]
95pub use traits::{SecureDecoding, SecureEncoding};
96
97/// Re-export of [`Bech32Error`] for convenience when using bech32 encoding/decoding.
98#[cfg(feature = "encoding-bech32")]
99pub use error::Bech32Error;
100
101/// Re-export of [`Base64Error`] for convenience when using base64 decoding.
102#[cfg(feature = "encoding-base64")]
103pub use error::Base64Error;
104
105/// Re-export of [`HexError`] for convenience when using hex decoding.
106#[cfg(feature = "encoding-hex")]
107pub use error::HexError;
108
109/// Re-export of [`DecodingError`] for convenience in decoding operations.
110pub use error::DecodingError;