Skip to main content

Module base32

Module base32 

Source
Expand description

Base32 decoding trait (RFC 4648 §6, uppercase, unpadded).

Import path: use secure_gate::FromBase32Str;

This trait provides secure, explicit decoding of Base32-encoded strings (RFC 4648 §6 alphabet, uppercase, no padding) to byte vectors. It is designed for handling untrusted input in cryptographic contexts, such as decoding otpauth:// TOTP/HOTP shared secrets or encoded keys.

Requires the encoding-base32 feature.

§Security Notes

  • Treat all input as untrusted: validate Base32 strings upstream before wrapping in secrets. Invalid input may indicate tampering or injection attempts.
  • Heap allocation: Returns Vec<u8> — wrap in Fixed or Dynamic to store as a secret.
  • Strict validation: uppercase RFC 4648 §6 alphabet (A–Z, 2–7) only, no = padding, no whitespace, no non-ASCII, and the length must be ≡ 0, 2, 4, 5 or 7 (mod 8) — the only lengths an unpadded Base32 string can have. Lowercase and mixed-case input is rejected; normalise upstream (to_ascii_uppercase(), ideally inside zeroize::Zeroizing, since it copies the encoded secret).
  • Lenient trailing bits: non-zero bits in the final partial group are ignored rather than rejected ("MZ" decodes to the same byte as "MY"). Decoding is therefore not injective: two distinct strings can yield the same bytes. Only encoder-produced strings are canonical, so round-tripping encode(decode(s)) == s holds only for canonical s.

§Example

use secure_gate::{FromBase32Str, Fixed};
{
// "NBSWY3DP" decodes to b"hello"
let bytes = "NBSWY3DP".try_from_base32().unwrap();
assert_eq!(bytes, b"hello");

// Wrap result in a secret immediately
let secret: Fixed<[u8; 4]> = Fixed::try_from_base32("32W353Y").unwrap();

// Error on invalid input
assert!("!!!!".try_from_base32().is_err());
}

Traits§

FromBase32Str
Extension trait for decoding uppercase, unpadded Base32 strings into byte vectors.