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