pub struct Fixed<T>(/* private fields */);Expand description
Stack-allocated secure secret wrapper.
This is a zero-cost wrapper for fixed-size secrets like byte arrays or primitives. The inner field is private, forcing all access through explicit methods.
Security invariants:
- No
DereforAsRef— prevents silent access or borrowing. - No implicit
Copy— even for[u8; N], duplication must be explicit via.clone(). Debugis always redacted.
§Examples
Basic usage:
use secure_gate::Fixed;
let secret = Fixed::new(42u32);
assert_eq!(*secret.expose_secret(), 42);For byte arrays (most common):
use secure_gate::{Fixed, fixed_alias};
fixed_alias!(Aes256Key, 32);
let key_bytes = [0x42u8; 32];
let key: Aes256Key = Fixed::from(key_bytes);
assert_eq!(key.len(), 32);
assert_eq!(key.expose_secret()[0], 0x42);With zeroize feature (automatic wipe on drop):
use secure_gate::Fixed;
let mut secret = Fixed::new([1u8, 2, 3]);
drop(secret); // memory wiped automaticallyImplementations§
Source§impl<T> Fixed<T>
impl<T> Fixed<T>
Sourcepub const fn new(value: T) -> Self
pub const fn new(value: T) -> Self
Wrap a value in a Fixed secret.
This is zero-cost and const-friendly.
§Example
use secure_gate::Fixed;
const SECRET: Fixed<u32> = Fixed::new(42);Sourcepub const fn expose_secret(&self) -> &T
pub const fn expose_secret(&self) -> &T
Expose the inner value for read-only access.
This is the only way to read the secret — loud and auditable.
§Example
use secure_gate::Fixed;
let secret = Fixed::new("hunter2");
assert_eq!(secret.expose_secret(), &"hunter2");Sourcepub fn expose_secret_mut(&mut self) -> &mut T
pub fn expose_secret_mut(&mut self) -> &mut T
Expose the inner value for mutable access.
This is the only way to mutate the secret — loud and auditable.
§Example
use secure_gate::Fixed;
let mut secret = Fixed::new([1u8, 2, 3]);
secret.expose_secret_mut()[0] = 42;
assert_eq!(secret.expose_secret()[0], 42);Source§impl<const N: usize> Fixed<[u8; N]>
impl<const N: usize> Fixed<[u8; N]>
Sourcepub const fn len(&self) -> usize
pub const fn len(&self) -> usize
Returns the fixed length in bytes.
This is safe public metadata — does not expose the secret.
Sourcepub const fn is_empty(&self) -> bool
pub const fn is_empty(&self) -> bool
Returns true if the fixed secret is empty (zero-length).
This is safe public metadata — does not expose the secret.
Sourcepub fn from_slice(bytes: &[u8]) -> Self
pub fn from_slice(bytes: &[u8]) -> Self
Create from a byte slice of exactly N bytes.
Panics if the slice length does not match N.
For fallible construction, use TryFrom<&[u8]> instead.
§Example
use secure_gate::Fixed;
let bytes: &[u8] = &[1, 2, 3];
let secret = Fixed::<[u8; 3]>::from_slice(bytes);
assert_eq!(secret.expose_secret(), &[1, 2, 3]);Source§impl<const N: usize> Fixed<[u8; N]>
impl<const N: usize> Fixed<[u8; N]>
Sourcepub fn ct_eq(&self, other: &Self) -> bool
pub fn ct_eq(&self, other: &Self) -> bool
Constant-time equality comparison.
This is the only safe way to compare two fixed-size secrets.
Available only when the ct-eq feature is enabled.
§Example
use secure_gate::Fixed;
let a = Fixed::new([1u8; 32]);
let b = Fixed::new([1u8; 32]);
assert!(a.ct_eq(&b));Source§impl<const N: usize> Fixed<[u8; N]>
impl<const N: usize> Fixed<[u8; N]>
Sourcepub fn generate_random() -> Self
pub fn generate_random() -> Self
Generate fresh random bytes using the OS RNG.
This is a convenience method that generates random bytes directly
without going through FixedRng. Equivalent to:
FixedRng::<N>::generate().into_inner()
§Example
use secure_gate::Fixed;
let key: Fixed<[u8; 32]> = Fixed::generate_random();Sourcepub fn try_generate_random() -> Result<Self, OsError>
pub fn try_generate_random() -> Result<Self, OsError>
Try to generate random bytes for Fixed.
Returns an error if the RNG fails.
§Example
use secure_gate::Fixed;
let key: Result<Fixed<[u8; 32]>, rand::rand_core::OsError> = Fixed::try_generate_random();
assert!(key.is_ok());Source§impl<const N: usize> Fixed<CloneableArrayInner<N>>
impl<const N: usize> Fixed<CloneableArrayInner<N>>
Sourcepub const fn expose_inner(&self) -> &[u8; N]
pub const fn expose_inner(&self) -> &[u8; N]
Returns a reference to the inner array without cloning.
This method provides direct access to the wrapped [u8; N] array.
The reference is valid for the lifetime of the CloneableArray.
Sourcepub fn expose_inner_mut(&mut self) -> &mut [u8; N]
pub fn expose_inner_mut(&mut self) -> &mut [u8; N]
Returns a mutable reference to the inner array.
This method provides direct mutable access to the wrapped [u8; N] array.
Use this when you need to modify the array contents in-place.
Sourcepub fn init_with<F>(constructor: F) -> Self
pub fn init_with<F>(constructor: F) -> Self
Construct a cloneable array secret by building it in a closure.
Same stack-minimization benefits as CloneableString::init_with.
§Example
use secure_gate::CloneableArray;
let key = CloneableArray::<32>::init_with(|| {
let mut arr = [0u8; 32];
// Fill from some source...
arr
});Sourcepub fn try_init_with<F, E>(constructor: F) -> Result<Self, E>
pub fn try_init_with<F, E>(constructor: F) -> Result<Self, E>
Fallible version of init_with.
Same stack-minimization benefits as init_with, but allows for construction
that may fail with an error. Useful when reading secrets from fallible sources
like files or network connections.
Trait Implementations§
Source§impl<T: CloneableSecretMarker> Clone for Fixed<T>
Available on crate feature zeroize only.
impl<T: CloneableSecretMarker> Clone for Fixed<T>
zeroize only.Source§impl<const N: usize> From<FixedRng<N>> for Fixed<[u8; N]>
impl<const N: usize> From<FixedRng<N>> for Fixed<[u8; N]>
Source§fn from(rng: FixedRng<N>) -> Self
fn from(rng: FixedRng<N>) -> Self
Convert a FixedRng to Fixed, transferring ownership.
This preserves all security guarantees. The FixedRng type
ensures the value came from secure RNG, and this conversion
transfers that value to Fixed without exposing bytes.
§Example
use secure_gate::{Fixed, random::FixedRng};
let key: Fixed<[u8; 32]> = FixedRng::<32>::generate().into();impl<T: Zeroize> ZeroizeOnDrop for Fixed<T>
zeroize only.