Skip to main content

Fixed

Struct Fixed 

Source
pub struct Fixed<T: Zeroize> { /* private fields */ }
Expand description

Stack-allocated secret wrapper with explicit access and automatic zeroization on drop.

Always available. Inner type must implement Zeroize. Zero-cost stack-allocated wrapper for fixed-size secrets.

Always available. Inner type must implement Zeroize for automatic zeroization on drop.

No Deref, AsRef, or Copy by default — all access requires expose_secret() or with_secret() (scoped, preferred). For construction of Fixed<[u8; N]>, new_with is the matching scoped constructor — it writes directly into the wrapper’s storage and avoids any intermediate stack copy. new(value) remains available as the ergonomic default. Debug always prints [REDACTED]. Performance indistinguishable from raw arrays.

Implementations§

Source§

impl<T: Zeroize> Fixed<T>

Source

pub const fn new(value: T) -> Self

Creates a new Fixed<T> by wrapping a value.

Source§

impl<const N: usize> Fixed<[u8; N]>

Construction and ergonomic encoding helpers for Fixed<[u8; N]>.

Source

pub fn new_with<F>(f: F) -> Self
where F: FnOnce(&mut [u8; N]),

Writes directly into the wrapper’s storage via a user-supplied closure, eliminating the intermediate stack copy that new may produce.

The array is zero-initialized before the closure runs. Prefer this over new(value) when minimizing stack residue matters (long-lived keys, high-assurance environments).

§Examples
use secure_gate::Fixed;

let secret = Fixed::<[u8; 4]>::new_with(|arr| arr.fill(0xAB));
Source

pub fn to_hex(&self) -> String

Encodes the secret bytes as a lowercase hex string.

Delegates to ToHex::to_hex on the inner [u8; N]. Requires the encoding-hex feature.

Source

pub fn to_hex_upper(&self) -> String

Encodes the secret bytes as an uppercase hex string.

Delegates to ToHex::to_hex_upper on the inner [u8; N]. Requires the encoding-hex feature.

Source

pub fn to_base64url(&self) -> String

Encodes the secret bytes as an unpadded Base64url string.

Delegates to ToBase64Url::to_base64url on the inner [u8; N]. Requires the encoding-base64 feature.

Source§

impl<const N: usize> Fixed<[u8; N]>

Source

pub fn from_random() -> Self

Fills a new [u8; N] with cryptographically secure random bytes and wraps it.

Uses the system RNG (OsRng) via TryRngCore::try_fill_bytes. In rand 0.9, OsRng is a zero-sized handle to the OS generator (not user-seedable). Requires the rand feature. Heap-free and works in no_std / no_alloc builds.

§Panics

Panics if the system RNG fails to provide bytes (TryRngCore::try_fill_bytes returns Err). This is treated as a fatal environment error.

§Examples
use secure_gate::{Fixed, RevealSecret};

let key: Fixed<[u8; 32]> = Fixed::from_random();
assert_eq!(key.len(), 32);
Source

pub fn from_rng<R: TryRngCore + TryCryptoRng>( rng: &mut R, ) -> Result<Self, R::Error>

Fills a new [u8; N] from rng and wraps it.

Accepts any TryCryptoRng + TryRngCore. Pass OsRng for the same system entropy as from_random with a fallible interface. Do not use OsRng for deterministic tests — in rand 0.9 it is a unit struct backed by the OS and is not seedable; use a seedable PRNG such as StdRng with SeedableRng instead. Requires the rand feature. Heap-free.

§Errors

Returns R::Error if try_fill_bytes fails.

§Examples

System RNG (same source as from_random, Result-based):

use rand::rngs::OsRng;
use secure_gate::Fixed;

let key: Fixed<[u8; 16]> = Fixed::from_rng(&mut OsRng).expect("rng fill");

Deterministic fill (tests) with a seedable generator:

use rand::rngs::StdRng;
use rand::SeedableRng;
use secure_gate::Fixed;

let mut rng = StdRng::from_seed([1u8; 32]);
let key: Fixed<[u8; 16]> = Fixed::from_rng(&mut rng).expect("rng fill");
Source§

impl<const N: usize> Fixed<[u8; N]>

Source

pub fn try_from_hex(hex: &str) -> Result<Self, HexError>

Decodes a lowercase hex string into Fixed<[u8; N]>.

The decoded bytes are held in a Zeroizing<Vec<u8>> until copied onto the stack array, so the temporary heap buffer is zeroed even if a panic occurs mid-flight.

§Errors

Returns HexError::InvalidLength if the decoded length does not equal N, or a parse error if the input is not valid hex.

§Note

Unlike Dynamic::try_from_hex, the secret lives on the stack inside a [u8; N]. Stack residue behaviour after the Fixed is dropped and zeroized is discussed in SECURITY.md.

Source§

impl<const N: usize> Fixed<[u8; N]>

Source

pub fn try_from_base64url(s: &str) -> Result<Self, Base64Error>

Decodes an unpadded Base64url string into Fixed<[u8; N]>.

The decoded bytes are held in a Zeroizing<Vec<u8>> until copied onto the stack array, so the temporary heap buffer is zeroed even if a panic occurs mid-flight.

§Errors

Returns Base64Error::InvalidLength if the decoded length does not equal N, or a parse error if the input is not valid Base64url.

§Note

Unlike Dynamic::try_from_base64url, the secret lives on the stack inside a [u8; N]. Stack residue behaviour after the Fixed is dropped and zeroized is discussed in SECURITY.md.

Source§

impl<const N: usize> Fixed<[u8; N]>

Source

pub fn try_from_bech32_unchecked(s: &str) -> Result<Self, Bech32Error>

Decodes a Bech32 (BIP-173) string into Fixed<[u8; N]>.

§Warning

The HRP is not validated — any HRP will be accepted as long as the checksum is valid and the payload length equals N. For security-critical code where cross-protocol confusion must be prevented, use try_from_bech32.

Source

pub fn try_from_bech32(s: &str, expected_hrp: &str) -> Result<Self, Bech32Error>

Decodes a Bech32 (BIP-173) string into Fixed<[u8; N]>, validating that the HRP matches expected_hrp (case-insensitive).

Prefer this over try_from_bech32_unchecked in security-critical code to prevent cross-protocol confusion attacks.

Source§

impl<const N: usize> Fixed<[u8; N]>

Source

pub fn try_from_bech32m_unchecked(s: &str) -> Result<Self, Bech32Error>

Decodes a Bech32m (BIP-350) string into Fixed<[u8; N]>.

§Warning

The HRP is not validated — any HRP will be accepted as long as the checksum is valid and the payload length equals N. For security-critical code where cross-protocol confusion must be prevented, use try_from_bech32m.

Source

pub fn try_from_bech32m( s: &str, expected_hrp: &str, ) -> Result<Self, Bech32Error>

Decodes a Bech32m (BIP-350) string into Fixed<[u8; N]>, validating that the HRP matches expected_hrp (case-insensitive).

Prefer this over try_from_bech32m_unchecked in security-critical code to prevent cross-protocol confusion attacks.

Trait Implementations§

Source§

impl<T: Zeroize + CloneableSecret> Clone for Fixed<T>

Available on crate feature cloneable only.
Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T> ConstantTimeEq for Fixed<T>

Available on crate feature ct-eq only.
Source§

fn ct_eq(&self, other: &Self) -> bool

Performs equality comparison in constant time. Read more
Source§

impl<T: Zeroize> Debug for Fixed<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de, const N: usize> Deserialize<'de> for Fixed<[u8; N]>

Available on crate feature serde-deserialize only.
Source§

fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl<T: Zeroize> Drop for Fixed<T>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl<const N: usize, T: Zeroize> ExposeSecret<[T; N]> for Fixed<[T; N]>

Source§

fn expose_secret(&self) -> &[T; N]

Returns a shared reference to the inner secret.
Source§

impl<const N: usize, T: Zeroize> ExposeSecretMut<[T; N]> for Fixed<[T; N]>

Source§

fn expose_secret_mut(&mut self) -> &mut [T; N]

Returns a mutable reference to the inner secret.
Source§

impl<const N: usize> From<[u8; N]> for Fixed<[u8; N]>

Source§

fn from(arr: [u8; N]) -> Self

Converts to this type from the input type.
Source§

impl<T: Clone + Zeroize, const N: usize> From<Fixed<[T; N]>> for Secret<[T; N]>

Converts a Fixed<[T; N]> into Secret<[T; N]>.

Source§

fn from(f: Fixed<[T; N]>) -> Self

Converts to this type from the input type.
Source§

impl<T: Clone + Zeroize, const N: usize> From<Secret<[T; N]>> for Fixed<[T; N]>

Converts Secret<[T; N]> into a Fixed<[T; N]>.

Source§

fn from(s: Secret<[T; N]>) -> Self

Converts to this type from the input type.
Source§

impl<const N: usize, T: Zeroize> RevealSecret for Fixed<[T; N]>

Explicit access to immutable [Fixed<[T; N]>] contents.

Source§

fn into_inner(self) -> InnerSecret<[T; N]>
where Self: Sized, Self::Inner: Sized + Default + Zeroize,

Consumes self and returns the inner [T; N] wrapped in crate::InnerSecret.

Zero cost — no allocation. The sentinel placed in self.inner is [T::default(); N] (already zeroed for u8), so Fixed::drop zeroizes an already-zero array — a harmless no-op.

See RevealSecret::into_inner for full documentation including the Default bound rationale and redacted Debug behavior.

Source§

type Inner = [T; N]

The inner secret type being revealed. Read more
Source§

fn with_secret<F, R>(&self, f: F) -> R
where F: FnOnce(&[T; N]) -> R,

Provides scoped (recommended) read-only access to the secret. Read more
Source§

fn expose_secret(&self) -> &[T; N]

Returns a direct (auditable) read-only reference to the secret. Read more
Source§

fn len(&self) -> usize

Returns the length of the secret in bytes. Read more
Source§

fn is_empty(&self) -> bool

Returns true if the secret is empty. Read more
Source§

impl<const N: usize, T: Zeroize> RevealSecretMut for Fixed<[T; N]>

Explicit access to mutable [Fixed<[T; N]>] contents.

Source§

fn with_secret_mut<F, R>(&mut self, f: F) -> R
where F: FnOnce(&mut [T; N]) -> R,

Provides scoped (recommended) mutable access to the secret. Read more
Source§

fn expose_secret_mut(&mut self) -> &mut [T; N]

Returns a direct (auditable) mutable reference to the secret. Read more
Source§

impl<T: Zeroize + SerializableSecret> Serialize for Fixed<T>

Available on crate feature serde-serialize only.
Source§

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl<const N: usize> TryFrom<&[u8]> for Fixed<[u8; N]>

Source§

type Error = FromSliceError

The type returned in the event of a conversion error.
Source§

fn try_from(slice: &[u8]) -> Result<Self, Self::Error>

Performs the conversion.
Source§

impl<T: Zeroize> Zeroize for Fixed<T>

Source§

fn zeroize(&mut self)

Zero out this object from memory using Rust intrinsics which ensure the zeroization operation is not “optimized away” by the compiler.
Source§

impl<T: Zeroize> ZeroizeOnDrop for Fixed<T>

Auto Trait Implementations§

§

impl<T> Freeze for Fixed<T>
where T: Freeze,

§

impl<T> RefUnwindSafe for Fixed<T>
where T: RefUnwindSafe,

§

impl<T> Send for Fixed<T>
where T: Send,

§

impl<T> Sync for Fixed<T>
where T: Sync,

§

impl<T> Unpin for Fixed<T>
where T: Unpin,

§

impl<T> UnsafeUnpin for Fixed<T>
where T: UnsafeUnpin,

§

impl<T> UnwindSafe for Fixed<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,