/// Random shared-secret generation.
///|
/// Generate `length` cryptographically random secret bytes.
pub fn generate_secret(length? : Int = 20) -> Bytes raise OtpError {
if length < 1 {
raise InvalidSecretLength(length)
}
match @env.rand(length) {
Some(bytes) if bytes.length() == length => bytes
_ => raise RandomUnavailable
}
}
///|
/// Generate a secret and return it as an unpadded RFC 4648 Base32 string,
/// the format used by Google Authenticator / most 2FA enrollment flows.
pub fn generate_secret_base32(length? : Int = 20) -> String raise OtpError {
let bytes = generate_secret(length~)
base32_encode_unpadded(bytes)
}