pub struct Fixed<T: Zeroize> { /* private fields */ }Expand description
Stack-allocated secret wrapper with explicit access and automatic zeroization on drop.
Fixed-size secrets (keys, nonces, tokens). Inner type must implement Zeroize.
Always available — works without alloc. Prefer new_with over
new when minimizing stack residue matters.
See Dynamic<T> for the heap-allocated alternative.
use secure_gate::{Fixed, RevealSecret};
let key = Fixed::new([0xABu8; 32]);
key.with_secret(|b| assert_eq!(b[0], 0xAB));
assert_eq!(format!("{:?}", key), "[REDACTED]");Zero-cost stack-allocated wrapper for fixed-size secrets.
Fixed<T> stores a T: Zeroize value inline and unconditionally zeroizes it
on drop. There is no Deref, AsRef, or Copy — every access is explicit
through RevealSecret or RevealSecretMut.
§Examples
use secure_gate::{Fixed, RevealSecret};
// Create a secret key.
let key = Fixed::new([0xABu8; 32]);
// Scoped access — the borrow cannot escape the closure.
let first = key.with_secret(|k| k[0]);
assert_eq!(first, 0xAB);
// Debug is always redacted.
assert_eq!(format!("{:?}", key), "[REDACTED]");§Constructors
| Constructor | Feature | Notes |
|---|---|---|
new(value) | — | const fn, ergonomic default |
new_with(f) | — | Scoped; preferred for stack-residue minimization |
From<[u8; N]> | — | Equivalent to new |
TryFrom<&[u8]> | — | Length-checked slice conversion |
try_from_hex | encoding-hex | Constant-time hex decoding |
try_from_base32 | encoding-base32 | Constant-time Base32 decoding |
try_from_base64url | encoding-base64 | Constant-time Base64url decoding |
try_from_bech32 | encoding-bech32 | HRP-validated Bech32 decoding |
try_from_bech32_unchecked | encoding-bech32 | Bech32 without HRP check |
try_from_bech32m | encoding-bech32m | HRP-validated Bech32m decoding |
try_from_bech32m_unchecked | encoding-bech32m | Bech32m without HRP check |
from_random() | rand | System RNG |
from_rng(rng) | rand | Custom RNG |
§RustCrypto integration
RustCrypto’s BlockEncrypt/BlockDecrypt take &mut GenericArray<u8, U16>, and
GenericArray::from_mut_slice borrows its argument instead of copying it. That
is what lets a block cipher run inside the wrapper, so the plaintext never
materializes in memory nothing is obliged to wipe:
use aes::cipher::{generic_array::GenericArray, BlockDecrypt, KeyInit};
use aes::Aes128;
use secure_gate::{Fixed, RevealSecretMut};
let cipher = Aes128::new(GenericArray::from_slice(&[0x42u8; 16]));
let mut block: Fixed<[u8; 16]> = Fixed::new([0u8; 16]);
// `from_mut_slice` reborrows the wrapper's own storage, so zeroize-on-drop still
// covers every path out of this scope — early returns and panics included.
block.with_secret_mut(|b| cipher.decrypt_block(GenericArray::from_mut_slice(b)));The shape type inference nudges you toward is the footgun. It compiles, it is the easy thing to reach for, and it defeats the wrapper:
// Copies the secret OUT. `copy` is an ordinary stack value: no zeroization on
// drop, and it holds plaintext-equivalent bytes for the rest of the scope.
let mut copy = block.with_secret(|b| aes::Block::from(*b));
cipher.decrypt_block(&mut copy);The same reasoning applies to Dynamic<Vec<u8>> through
with_secret_mut, and to the
slice-at-a-time APIs (decrypt_blocks, apply_keystream), which take
&mut [Block] and &mut [u8] and so borrow just as well.
§See also
RevealSecret/RevealSecretMut— the 3-tier access traits.new_with— scoped constructor preferred overnew.
§Note
const fn new compiles in static position, but must not be used there
because Drop does not run on statics, which means zeroization is skipped.
Implementations§
Source§impl<T: Zeroize> Fixed<T>
impl<T: Zeroize> Fixed<T>
Sourcepub const fn new(value: T) -> Self
pub const fn new(value: T) -> Self
Creates a new Fixed<T> by wrapping a value.
This is a const fn, so it can be evaluated at compile time. However,
do not use it to initialize static items — Drop does not run on
statics, so zeroization would be skipped.
For Fixed<[u8; N]>, prefer new_with when minimizing
stack residue matters, as new may leave an intermediate copy of value
on the caller’s stack frame.
§Examples
use secure_gate::{Fixed, RevealSecret, SecretLen};
let secret = Fixed::new([0u8; 32]);
assert_eq!(secret.len(), 32);Source§impl<const N: usize> Fixed<[u8; N]>
Construction and ergonomic encoding helpers for Fixed<[u8; N]>.
impl<const N: usize> Fixed<[u8; N]>
Construction and ergonomic encoding helpers for Fixed<[u8; N]>.
Sourcepub fn new_with<F>(f: F) -> Self
pub fn new_with<F>(f: F) -> Self
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).
§Security rationale
With Fixed::new(value), the caller first builds value on
its own stack frame, then moves it into the wrapper. The compiler may
elide the copy, but this is not guaranteed — leaving a plaintext residue
on the stack. new_with avoids this by giving the closure a mutable
reference to the wrapper’s own storage, so the secret is never placed
anywhere else.
§Examples
use secure_gate::{Fixed, RevealSecret};
// Fill from a closure — no intermediate stack copy.
let secret = Fixed::<[u8; 4]>::new_with(|arr| arr.fill(0xAB));
assert_eq!(secret.expose_secret(), &[0xAB; 4]);
// Copy from an existing slice.
let src = [1u8, 2, 3, 4];
let secret = Fixed::<[u8; 4]>::new_with(|arr| arr.copy_from_slice(&src));§See also
Dynamic::new_with— the heap-allocated equivalent (requiresalloc).
If the secret will outlive the current function, prefer
Dynamic<T> over moving Fixed<T> around — each
move-by-value leaves residue in the previous stack slot.
Source§impl<const N: usize> Fixed<[u8; N]>
Hex encoding and decoding for Fixed<[u8; N]>.
impl<const N: usize> Fixed<[u8; N]>
Hex encoding and decoding for Fixed<[u8; N]>.
Encoding uses a constant-time backend (base16ct). Decoding works with or without
the alloc feature — on no-alloc targets the bytes are decoded directly into a
Zeroizing<[u8; N]> stack buffer.
Sourcepub fn try_from_hex(hex: &str) -> Result<Self, HexError>
pub fn try_from_hex(hex: &str) -> Result<Self, HexError>
Decodes a hex string (lowercase, uppercase, or mixed) into Fixed<[u8; N]>.
Uses a constant-time backend (base16ct) for both paths.
- With
alloc: decodes into aZeroizing<Vec<u8>>then copies onto the stack. The temporary heap buffer is zeroed on drop even if an error occurs. - Without
alloc: decodes directly into aZeroizing<[u8; N]>stack buffer. No heap allocation occurs.
§Errors
- [
HexError::InvalidHex] — non-hex characters or odd-length input. - [
HexError::InvalidLength] — decoded byte count does not equalN.
§Examples
use secure_gate::{Fixed, RevealSecret, ToHex};
// Round-trip: encode then decode.
let original = Fixed::new([0xDE, 0xAD, 0xBE, 0xEF]);
let hex_str = original.to_hex();
let decoded = Fixed::<[u8; 4]>::try_from_hex(&hex_str).unwrap();
assert_eq!(decoded.expose_secret(), &[0xDE, 0xAD, 0xBE, 0xEF]);
// Wrong length fails.
assert!(Fixed::<[u8; 2]>::try_from_hex("deadbeef").is_err());Source§impl<const N: usize> Fixed<[u8; N]>
Base32 encoding and decoding for Fixed<[u8; N]> (RFC 4648 §6, uppercase, unpadded).
impl<const N: usize> Fixed<[u8; N]>
Base32 encoding and decoding for Fixed<[u8; N]> (RFC 4648 §6, uppercase, unpadded).
Encoding uses a constant-time backend (base32ct). Decoding works with or without
the alloc feature — on no-alloc targets the bytes are decoded directly into a
Zeroizing<[u8; N]> stack buffer.
Sourcepub fn try_from_base32(s: &str) -> Result<Self, Base32Error>
pub fn try_from_base32(s: &str) -> Result<Self, Base32Error>
Decodes an uppercase, unpadded Base32 string (RFC 4648 §6 alphabet) into
Fixed<[u8; N]>.
Uses a constant-time backend (base32ct) on both paths.
- With
alloc: decodes into aZeroizing<Vec<u8>>then copies onto the stack. - Without
alloc: decodes directly into aZeroizing<[u8; N]>stack buffer.
Decoding is strict about the alphabet, case, padding and length, but lenient
about non-canonical trailing bits: unused bits in the final group are ignored
rather than rejected, so "MZ" and "MY" both decode to [0x66]. Decoding is
therefore not injective — two distinct strings can yield the same bytes, and
only encoder-produced strings are canonical. Do not use the decoded value to
decide that two encoded strings were equal.
§Errors
Base32Error::InvalidBase32— wrong alphabet or case,=padding, or a length that is impossible for unpadded Base32. Withoutallocan input that decodes to more thanNbytes also lands here rather than inInvalidLength, because the fixed stack buffer cannot hold the overflow to measure it.Base32Error::InvalidLength— decoded byte count does not equalN.
§Examples
use secure_gate::{Fixed, RevealSecret, ToBase32};
// Round-trip.
let original = Fixed::new([0xDE, 0xAD, 0xBE, 0xEF]);
let encoded = original.to_base32();
assert_eq!(encoded, "32W353Y");
let decoded = Fixed::<[u8; 4]>::try_from_base32(&encoded).unwrap();
assert_eq!(decoded.expose_secret(), &[0xDE, 0xAD, 0xBE, 0xEF]);Source§impl<const N: usize> Fixed<[u8; N]>
Base64url encoding and decoding for Fixed<[u8; N]>.
impl<const N: usize> Fixed<[u8; N]>
Base64url encoding and decoding for Fixed<[u8; N]>.
Encoding uses a constant-time backend (base64ct). Decoding works with or without
the alloc feature — on no-alloc targets the bytes are decoded directly into a
Zeroizing<[u8; N]> stack buffer.
Sourcepub fn try_from_base64url(s: &str) -> Result<Self, Base64Error>
pub fn try_from_base64url(s: &str) -> Result<Self, Base64Error>
Decodes an unpadded Base64url string (RFC 4648, URL-safe alphabet) into
Fixed<[u8; N]>.
Uses a constant-time backend (base64ct) on both paths.
- With
alloc: decodes into aZeroizing<Vec<u8>>then copies onto the stack. - Without
alloc: decodes directly into aZeroizing<[u8; N]>stack buffer.
§Errors
- [
Base64Error::InvalidBase64] — non-base64 characters or invalid padding. - [
Base64Error::InvalidLength] — decoded byte count does not equalN.
§Examples
use secure_gate::{Fixed, RevealSecret, ToBase64Url};
// Round-trip.
let original = Fixed::new([0xDE, 0xAD, 0xBE, 0xEF]);
let encoded = original.to_base64url();
let decoded = Fixed::<[u8; 4]>::try_from_base64url(&encoded).unwrap();
assert_eq!(decoded.expose_secret(), &[0xDE, 0xAD, 0xBE, 0xEF]);Source§impl<const N: usize> Fixed<[u8; N]>
Bech32 (BIP-173) encoding and decoding for Fixed<[u8; N]>.
impl<const N: usize> Fixed<[u8; N]>
Bech32 (BIP-173) encoding and decoding for Fixed<[u8; N]>.
Uses the extended Bech32Large checksum variant (~5 KB payload limit) rather than
the 90-character standard limit. For Bitcoin address formats use ToBech32m.
Sourcepub fn try_from_bech32(s: &str, expected_hrp: &str) -> Result<Self, Bech32Error>
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).
HRP comparison is non-constant-time — this is intentional, as the HRP is public
metadata, not secret material. Timing leaks on HRP mismatch are acceptable because
the HRP is not secret. Prefer this over
try_from_bech32_unchecked to prevent
cross-protocol confusion attacks.
Works without alloc — decodes into a stack-allocated Zeroizing<[u8; N]> buffer.
Sourcepub fn try_from_bech32_unchecked(s: &str) -> Result<Self, Bech32Error>
pub fn try_from_bech32_unchecked(s: &str) -> Result<Self, Bech32Error>
Decodes a Bech32 (BIP-173) string into Fixed<[u8; N]> without validating the HRP.
Any valid HRP is accepted as long as the checksum is valid and the payload length
equals N. Use try_from_bech32 in security-critical code
to prevent cross-protocol confusion attacks.
Works without alloc — decodes into a stack-allocated Zeroizing<[u8; N]> buffer.
Source§impl<const N: usize> Fixed<[u8; N]>
Bech32m (BIP-350) encoding and decoding for Fixed<[u8; N]>.
impl<const N: usize> Fixed<[u8; N]>
Bech32m (BIP-350) encoding and decoding for Fixed<[u8; N]>.
Uses the standard BIP-350 payload limit (~90 bytes). For large secrets
(ciphertexts, recipients) use ToBech32 / Bech32Large instead.
Sourcepub fn try_from_bech32m(
s: &str,
expected_hrp: &str,
) -> Result<Self, Bech32Error>
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).
HRP comparison is non-constant-time — this is intentional, as the HRP is public
metadata, not secret material. Timing leaks on HRP mismatch are acceptable because
the HRP is not secret. Prefer this over
try_from_bech32m_unchecked to prevent
cross-protocol confusion attacks.
Works without alloc — decodes into a stack-allocated Zeroizing<[u8; N]> buffer.
Sourcepub fn try_from_bech32m_unchecked(s: &str) -> Result<Self, Bech32Error>
pub fn try_from_bech32m_unchecked(s: &str) -> Result<Self, Bech32Error>
Decodes a Bech32m (BIP-350) string into Fixed<[u8; N]> without validating the HRP.
Any valid HRP is accepted as long as the checksum is valid and the payload length
equals N. Use try_from_bech32m in security-critical
code to prevent cross-protocol confusion attacks.
Works without alloc — decodes into a stack-allocated Zeroizing<[u8; N]> buffer.
Source§impl<const N: usize> Fixed<[u8; N]>
impl<const N: usize> Fixed<[u8; N]>
Sourcepub fn from_random() -> Self
pub fn from_random() -> Self
Fills a new [u8; N] with cryptographically secure random bytes and wraps it.
Uses the system RNG (SysRng). Requires the rand feature.
Heap-free and works in no_std / no_alloc builds.
§Panics
Panics if the system RNG fails to provide bytes (TryRng::try_fill_bytes
returns Err). This is treated as a fatal environment error.
§Examples
use secure_gate::{Fixed, RevealSecret, SecretLen};
let key: Fixed<[u8; 32]> = Fixed::from_random();
assert_eq!(key.len(), 32);Sourcepub fn from_rng<R: TryRng + TryCryptoRng>(rng: &mut R) -> Result<Self, R::Error>
pub fn from_rng<R: TryRng + TryCryptoRng>(rng: &mut R) -> Result<Self, R::Error>
Fills a new [u8; N] from rng and wraps it.
Accepts any TryCryptoRng + TryRng — for example,
a seeded StdRng for deterministic tests. Requires the rand
feature. Heap-free.
§Errors
Returns R::Error if try_fill_bytes fails.
§Examples
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");Trait Implementations§
Source§impl<T: Zeroize + CloneableSecret> Clone for Fixed<T>
Available on crate feature cloneable only.Opt-in cloning — requires cloneable feature and CloneableSecret
marker on the inner type. Each clone is independently zeroized on drop, but cloning
increases the in-memory exposure surface. Use sparingly.
impl<T: Zeroize + CloneableSecret> Clone for Fixed<T>
cloneable only.Opt-in cloning — requires cloneable feature and CloneableSecret
marker on the inner type. Each clone is independently zeroized on drop, but cloning
increases the in-memory exposure surface. Use sparingly.
Source§impl<T> ConstantTimeEq for Fixed<T>
Available on crate feature ct-eq only.Constant-time equality for Fixed<T> — routes through expose_secret().
impl<T> ConstantTimeEq for Fixed<T>
ct-eq only.Constant-time equality for Fixed<T> — routes through expose_secret().
== is deliberately not implemented on Fixed. Always use ct_eq.
use secure_gate::{Fixed, ConstantTimeEq};
let a = Fixed::new([1u8; 4]);
let b = Fixed::new([1u8; 4]);
let c = Fixed::new([2u8; 4]);
assert!(a.ct_eq(&b));
assert!(!a.ct_eq(&c));Source§impl<T: Zeroize> Debug for Fixed<T>
Always prints [REDACTED] — secrets never appear in debug output.
impl<T: Zeroize> Debug for Fixed<T>
Always prints [REDACTED] — secrets never appear in debug output.
use secure_gate::Fixed;
let key = Fixed::new([0xABu8; 32]);
assert_eq!(format!("{:?}", key), "[REDACTED]");Source§impl<'de, const N: usize> Deserialize<'de> for Fixed<[u8; N]>
Available on crate feature serde-deserialize only.Deserialization uses Zeroizing-wrapped temporary buffers — zeroized even on rejection.
impl<'de, const N: usize> Deserialize<'de> for Fixed<[u8; N]>
serde-deserialize only.Deserialization uses Zeroizing-wrapped temporary buffers — zeroized even on rejection.
The sequence buffer is pre-allocated to exactly N bytes and never grows: an
input sequence longer than N is rejected before the element that would trigger a
reallocation is stored. This matters because a Vec reallocation frees the old
buffer — which would already hold N secret bytes — without zeroizing it.
The entry point is deserialize_seq (unchanged wire format for non-self-describing
formats such as postcard), but the visitor also accepts byte strings via
visit_bytes / visit_byte_buf, so self-describing formats that encode byte
arrays as byte strings (e.g. CBOR) round-trip too. Owned buffers handed over
through visit_byte_buf are zeroized after the copy.
Source§fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
Source§impl<T: Zeroize> Drop for Fixed<T>
Unconditionally zeroizes the inner value when the wrapper is dropped.
impl<T: Zeroize> Drop for Fixed<T>
Unconditionally zeroizes the inner value when the wrapper is dropped.
Warning: Drop does not run for static items or under panic = "abort".
Source§impl<const N: usize> From<[u8; N]> for Fixed<[u8; N]>
Converts a byte array into a Fixed wrapper (equivalent to Fixed::new).
impl<const N: usize> From<[u8; N]> for Fixed<[u8; N]>
Converts a byte array into a Fixed wrapper (equivalent to Fixed::new).
§Examples
use secure_gate::Fixed;
let secret: Fixed<[u8; 4]> = [1u8, 2, 3, 4].into();Source§impl<T: Zeroize> RevealSecret for Fixed<T>
Explicit access to immutable [Fixed<[T; N]>] contents.
impl<T: Zeroize> RevealSecret for Fixed<T>
Explicit access to immutable [Fixed<[T; N]>] contents.
Source§fn into_inner(self) -> InnerSecret<T>
fn into_inner(self) -> InnerSecret<T>
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] via crate::SentinelValue (already zeroed for u8),
so Fixed::drop zeroizes an already-zero array — a harmless no-op.
Works for any array length N (not limited to 32 like Default).
See RevealSecret::into_inner for full documentation including the
SentinelValue bound rationale and redacted Debug behavior.
Source§fn with_secret<F, R>(&self, f: F) -> R
fn with_secret<F, R>(&self, f: F) -> R
Source§fn expose_secret(&self) -> &T
fn expose_secret(&self) -> &T
Source§impl<T: Zeroize> RevealSecretMut for Fixed<T>
Explicit access to mutable [Fixed<[T; N]>] contents.
impl<T: Zeroize> RevealSecretMut for Fixed<T>
Explicit access to mutable [Fixed<[T; N]>] contents.
Source§impl<const N: usize, T: Zeroize> SecretLen for Fixed<[T; N]>
Length is only meaningful for array-shaped secrets.
impl<const N: usize, T: Zeroize> SecretLen for Fixed<[T; N]>
Length is only meaningful for array-shaped secrets.
Source§impl<T: Zeroize + SerializableSecret> Serialize for Fixed<T>
Available on crate feature serde-serialize only.Opt-in serialization — requires serde-serialize feature and
SerializableSecret marker on the inner type.
Serialization exposes the full secret — audit every impl.
impl<T: Zeroize + SerializableSecret> Serialize for Fixed<T>
serde-serialize only.Opt-in serialization — requires serde-serialize feature and
SerializableSecret marker on the inner type.
Serialization exposes the full secret — audit every impl.
Source§impl<const N: usize> ToBase32 for Fixed<[u8; N]>
Available on crate features alloc and encoding-base32 only.Base32 encoding for Fixed<[u8; N]>; delegates via with_secret.
impl<const N: usize> ToBase32 for Fixed<[u8; N]>
alloc and encoding-base32 only.Base32 encoding for Fixed<[u8; N]>; delegates via with_secret.
Bring the trait into scope to call these: use secure_gate::ToBase32;.
use secure_gate::{Fixed, ToBase32};
let key = Fixed::new([0xABu8; 4]);
assert_eq!(key.to_base32(), "VOV2XKY");Source§fn to_base32(&self) -> String
fn to_base32(&self) -> String
Source§fn to_base32_zeroizing(&self) -> EncodedSecret
fn to_base32_zeroizing(&self) -> EncodedSecret
crate::EncodedSecret.Source§impl<const N: usize> ToBase64Url for Fixed<[u8; N]>
Available on crate features alloc and encoding-base64 only.Base64url encoding for Fixed<[u8; N]>; delegates via with_secret.
impl<const N: usize> ToBase64Url for Fixed<[u8; N]>
alloc and encoding-base64 only.Base64url encoding for Fixed<[u8; N]>; delegates via with_secret.
Bring the trait into scope to call these: use secure_gate::ToBase64Url;.
use secure_gate::{Fixed, ToBase64Url};
let key = Fixed::new([0xABu8; 4]);
assert_eq!(key.to_base64url(), "q6urqw");Source§fn to_base64url(&self) -> String
fn to_base64url(&self) -> String
Source§fn to_base64url_zeroizing(&self) -> EncodedSecret
fn to_base64url_zeroizing(&self) -> EncodedSecret
crate::EncodedSecret.Source§impl<const N: usize> ToBech32 for Fixed<[u8; N]>
Available on crate features alloc and encoding-bech32 only.Bech32 encoding for Fixed<[u8; N]>; delegates via with_secret.
impl<const N: usize> ToBech32 for Fixed<[u8; N]>
alloc and encoding-bech32 only.Bech32 encoding for Fixed<[u8; N]>; delegates via with_secret.
Bring the trait into scope to call these: use secure_gate::ToBech32;.
Source§fn try_to_bech32(&self, hrp: &str) -> Result<String, Bech32Error>
fn try_to_bech32(&self, hrp: &str) -> Result<String, Bech32Error>
Source§fn try_to_bech32_zeroizing(
&self,
hrp: &str,
) -> Result<EncodedSecret, Bech32Error>
fn try_to_bech32_zeroizing( &self, hrp: &str, ) -> Result<EncodedSecret, Bech32Error>
crate::EncodedSecret.Source§impl<const N: usize> ToBech32m for Fixed<[u8; N]>
Available on crate features alloc and encoding-bech32m only.Bech32m encoding for Fixed<[u8; N]>; delegates via with_secret.
impl<const N: usize> ToBech32m for Fixed<[u8; N]>
alloc and encoding-bech32m only.Bech32m encoding for Fixed<[u8; N]>; delegates via with_secret.
Bring the trait into scope to call these: use secure_gate::ToBech32m;.
Source§fn try_to_bech32m(&self, hrp: &str) -> Result<String, Bech32Error>
fn try_to_bech32m(&self, hrp: &str) -> Result<String, Bech32Error>
Source§fn try_to_bech32m_zeroizing(
&self,
hrp: &str,
) -> Result<EncodedSecret, Bech32Error>
fn try_to_bech32m_zeroizing( &self, hrp: &str, ) -> Result<EncodedSecret, Bech32Error>
crate::EncodedSecret.Source§impl<const N: usize> ToHex for Fixed<[u8; N]>
Available on crate features alloc and encoding-hex only.Hex encoding for Fixed<[u8; N]> — same constant-time backend as the
ToHex blanket impl on the inner bytes; delegates via with_secret.
impl<const N: usize> ToHex for Fixed<[u8; N]>
alloc and encoding-hex only.Hex encoding for Fixed<[u8; N]> — same constant-time backend as the
ToHex blanket impl on the inner bytes; delegates via with_secret.
Bring the trait into scope to call these: use secure_gate::ToHex;.
use secure_gate::{Fixed, ToHex};
let key = Fixed::new([0xABu8; 4]);
assert_eq!(key.to_hex(), "abababab");
assert_eq!(key.to_hex_upper(), "ABABABAB");
// Zeroizing variant — encoded form wipes itself on drop:
assert_eq!(&*key.to_hex_zeroizing(), "abababab");Source§fn to_hex_upper(&self) -> String
fn to_hex_upper(&self) -> String
Source§fn to_hex_zeroizing(&self) -> EncodedSecret
fn to_hex_zeroizing(&self) -> EncodedSecret
crate::EncodedSecret.Source§fn to_hex_upper_zeroizing(&self) -> EncodedSecret
fn to_hex_upper_zeroizing(&self) -> EncodedSecret
crate::EncodedSecret.Source§impl<const N: usize> TryFrom<&[u8]> for Fixed<[u8; N]>
Converts a byte slice into Fixed<[u8; N]>, failing if the length does not
match N.
impl<const N: usize> TryFrom<&[u8]> for Fixed<[u8; N]>
Converts a byte slice into Fixed<[u8; N]>, failing if the length does not
match N.
Internally uses Fixed::new_with so the secret is written directly into
the wrapper’s storage.
§Errors
Returns FromSliceError::InvalidLength when
slice.len() != N.
§Examples
use secure_gate::{Fixed, RevealSecret};
// Success — exact length.
let data = [0xFFu8; 4];
let secret = Fixed::<[u8; 4]>::try_from(data.as_slice()).unwrap();
assert_eq!(secret.expose_secret()[0], 0xFF);
// Failure — wrong length.
let short = [0u8; 2];
assert!(Fixed::<[u8; 4]>::try_from(short.as_slice()).is_err());Source§impl<T: Zeroize> Zeroize for Fixed<T>
Zeroizes the inner value. Called automatically by Drop.
impl<T: Zeroize> Zeroize for Fixed<T>
Zeroizes the inner value. Called automatically by Drop.
Warning: zeroization does not run for static items or under panic = "abort".
impl<T: Zeroize> ZeroizeOnDrop for Fixed<T>
Marker confirming that Fixed<T> always zeroizes on drop.