secure_gate/traits/mod.rs
1//! Traits for polymorphic secret handling.
2//!
3//! > **Note:** All traits in this module are re-exported at the crate root
4//! > (`secure_gate::RevealSecret`, not `secure_gate::traits::RevealSecret`).
5//! > You should never need to import from `secure_gate::traits::*` directly.
6//!
7//! This module defines the core traits that enable generic, zero-cost, and secure
8//! operations across different secret wrapper types (`Fixed<T>`, `Dynamic<T>`, etc.).
9//! These traits allow writing polymorphic code that preserves strong security invariants:
10//! explicit access, controlled mutability, timing safety, and opt-in risk features.
11//!
12//! # Core Traits
13//!
14//! | Trait | Purpose | Requires Feature | Notes |
15//! |------------------------|----------------------------------------------|--------------------------|-----------------------------------------------------------------------|
16//! | [`RevealSecret`] | Read-only scoped / direct access + metadata | Always available | Preferred: `with_secret` (scoped); escape hatch: `expose_secret` |
17//! | [`RevealSecretMut`] | Mutable scoped / direct access | Always available | Same preference: `with_secret_mut` over `expose_secret_mut` |
18//! | [`ConstantTimeEq`] | Deterministic constant-time equality | `ct-eq` | Timing-attack resistant byte comparison |
19//! | [`CloneableSecret`] | Opt-in marker for safe cloning | `cloneable` | Requires explicit impl on inner type; zeroize preserved. See [`SECURITY.md`](https://github.com/Slurp9187/secure-gate/blob/main/SECURITY.md) for opt-in risk details. |
20//! | [`SerializableSecret`] | Opt-in marker for Serde serialization | `serde-serialize` | Serialization exposes secret — use with extreme caution. See [`SECURITY.md`](https://github.com/Slurp9187/secure-gate/blob/main/SECURITY.md) for opt-in risk details. |
21//! | [`SecureEncoding`] | Marker + blanket impl for encoding traits | Any `encoding-*` | Enables `ToHex`, `ToBase64Url`, `ToBech32`, `ToBech32m` |
22//! | [`SecureDecoding`] | Marker + blanket impl for decoding traits | Any `encoding-*` | Enables `FromHexStr`, `FromBase64UrlStr`, `FromBech32Str`, etc. |
23//!
24//! # Security Guarantees
25//!
26//! - **No implicit access** — All secret data access requires explicit trait methods
27//! - **Scoped preference** — `with_secret` / `with_secret_mut` limit borrow lifetime
28//! - **Zero-cost** — All methods use `#[inline(always)]` where possible
29//! - **Timing safety** — `ConstantTimeEq` provides constant-time equality
30//! - **Opt-in risk** — Cloning and serialization require deliberate marker impls
31//! - **Read-only enforcement** — Encoding wrappers and random types only expose immutable access
32//!
33//! # Feature Gates
34//!
35//! Some traits are only available when their corresponding Cargo features are enabled:
36//!
37//! - `ct-eq` → [`ConstantTimeEq`]
38//! - `cloneable` → [`CloneableSecret`]
39//! - `serde-serialize`→ [`SerializableSecret`]
40//! - `encoding-*` → [`SecureEncoding`], [`SecureDecoding`], and per-format traits
41//!
42//! The encoding traits (`ToHex`, `FromHexStr`, etc.) are re-exported from submodules for convenience.
43//!
44//! See individual trait docs for detailed usage and examples.
45
46pub mod revealed_secrets;
47pub use revealed_secrets::InnerSecret;
48
49#[cfg(feature = "alloc")]
50pub use revealed_secrets::EncodedSecret;
51
52pub mod reveal_secret;
53pub use reveal_secret::RevealSecret;
54
55pub mod reveal_secret_mut;
56pub use reveal_secret_mut::RevealSecretMut;
57
58#[cfg(feature = "ct-eq")]
59pub mod constant_time_eq;
60#[cfg(feature = "ct-eq")]
61pub use constant_time_eq::ConstantTimeEq;
62
63pub mod decoding;
64pub mod encoding;
65
66// Re-export per-format decoding traits (feature-gated; blanket impls return Vec<u8> — alloc required)
67#[cfg(all(feature = "encoding-base64", feature = "alloc"))]
68pub use decoding::FromBase64UrlStr;
69
70#[cfg(all(feature = "encoding-bech32", feature = "alloc"))]
71pub use decoding::FromBech32Str;
72
73#[cfg(all(feature = "encoding-bech32m", feature = "alloc"))]
74pub use decoding::FromBech32mStr;
75
76#[cfg(all(feature = "encoding-hex", feature = "alloc"))]
77pub use decoding::FromHexStr;
78
79// Re-export per-format encoding traits (feature-gated)
80// Note: blanket impls of ToBase64Url, ToBech32, ToBech32m require alloc (String output).
81// The traits themselves are exported unconditionally so inherent methods on Fixed/Dynamic
82// can call them; the blanket impls gate the alloc dependency.
83#[cfg(all(feature = "encoding-base64", feature = "alloc"))]
84pub use encoding::ToBase64Url;
85
86#[cfg(all(feature = "encoding-bech32", feature = "alloc"))]
87pub use encoding::ToBech32;
88
89#[cfg(all(feature = "encoding-bech32m", feature = "alloc"))]
90pub use encoding::ToBech32m;
91
92#[cfg(all(feature = "encoding-hex", feature = "alloc"))]
93pub use encoding::ToHex;
94
95/// Marker trait for types that support secure encoding operations.
96///
97/// Automatically implemented for any type that implements `AsRef<[u8]>`,
98/// such as `&[u8]`, `Vec<u8>`, `[u8; N]`, etc. This enables blanket impls
99/// of the individual encoding traits (`ToHex`, `ToBase64Url`, `ToBech32`, etc.).
100///
101/// Since this is a marker trait (no methods), it exists only to allow trait
102/// bounds and extension methods to be available where appropriate.
103///
104/// Requires at least one `encoding-*` feature to be enabled.
105#[cfg(any(
106 feature = "encoding-hex",
107 feature = "encoding-base64",
108 feature = "encoding-bech32",
109 feature = "encoding-bech32m",
110))]
111pub trait SecureEncoding {}
112
113#[cfg(any(
114 feature = "encoding-hex",
115 feature = "encoding-base64",
116 feature = "encoding-bech32",
117 feature = "encoding-bech32m",
118))]
119impl<T: AsRef<[u8]> + ?Sized> SecureEncoding for T {}
120
121/// Marker trait for types that support secure decoding operations.
122///
123/// Automatically implemented for any type that implements `AsRef<str>`,
124/// such as `&str`, `String`, etc. This enables blanket impls of the
125/// individual decoding traits (`FromHexStr`, `FromBase64UrlStr`, etc.).
126///
127/// Like `SecureEncoding`, this is a marker trait with no methods — it exists
128/// to allow trait bounds and extension methods where relevant.
129///
130/// Requires at least one `encoding-*` feature to be enabled.
131#[cfg(any(
132 feature = "encoding-hex",
133 feature = "encoding-base64",
134 feature = "encoding-bech32",
135 feature = "encoding-bech32m",
136))]
137pub trait SecureDecoding {}
138
139#[cfg(any(
140 feature = "encoding-hex",
141 feature = "encoding-base64",
142 feature = "encoding-bech32",
143 feature = "encoding-bech32m",
144))]
145impl<T: AsRef<str> + ?Sized> SecureDecoding for T {}
146
147#[cfg(feature = "cloneable")]
148pub mod cloneable_secret;
149#[cfg(feature = "cloneable")]
150pub use cloneable_secret::CloneableSecret;
151
152#[cfg(feature = "serde-serialize")]
153pub mod serializable_secret;
154#[cfg(feature = "serde-serialize")]
155pub use serializable_secret::SerializableSecret;