Skip to main content

Hotp

Struct Hotp 

Source
pub struct Hotp { /* private fields */ }

Implementations§

Source§

impl Hotp

Source

pub fn new( alg: Algorithm, issuer: String, label: String, digits: u8, counter: u64, secret: Secret, ) -> Self

Creates a new Hotp instance with the specified configuration.

§Arguments
  • alg - The hashing algorithm to use (e.g., Algorithm::SHA1, Algorithm::SHA256, or Algorithm::SHA512).
  • issuer - The name of the service or provider (e.g., "GitHub" or "example.com").
  • label - An identifier for the user account (e.g., "alice@example.com").
  • digits - Number of digits in the generated OTP (typically 6 or 8).
  • counter - Initial counter value for HOTP generation.
  • secret - The shared secret key used to generate the HMAC.
§Returns

Returns a new instance of Hotp configured with the provided parameters.

§Example
use otp::{Hotp, Algorithm, Secret};

let hotp = Hotp::new(
    Algorithm::SHA1,
    "example".into(),
    "alice@example.com".into(),
    6,
    0,
    Secret::from_bytes(b"supersecret"),
);
Source

pub fn generate(&mut self) -> u32

Generates the next OTP value and increments the internal counter.

This method uses the current counter value, produces a new HOTP code, then advances the internal counter by one.

Internally uses generate_at and follows the HOTP Algorithm specified in RFC 4226.

§Returns

A numeric HOTP code as a u32.

§Example
let mut hotp = otp::Hotp::default();
let otp = hotp.generate();
println!("OTP: {}", otp);
Source

pub fn generate_at(&self, counter: u64) -> u32

Generates an OTP value at a specific counter value, without modifying internal state.

This method is useful for verifying or regenerating a known HOTP value at a given counter.

It uses HMAC with the configured algorithm (SHA-1, SHA-256, etc.), then applies dynamic truncation as described in [RFC 4226].

§Arguments
  • counter - The counter value at which to generate the OTP
§Returns

A numeric OTP code as a u32.

§Example
let hotp = otp::Hotp::default();
let otp = hotp.generate_at(1234);
§References
Source

pub fn verify(&self, otp: u32, counter: u64, window: u64) -> bool

Verifies a provided OTP code against a given counter value, allowing for a window of flexibility.

This method compares the given otp with the expected values generated at counter - window to counter + window. This accounts for clock drift or synchronization delays.

§Arguments
  • otp - The OTP code to verify
  • counter - The current known counter (typically stored server-side)
  • window - How many counter steps before and after to check
§Returns

true if a match is found within the window range, false otherwise.

§Example
let hotp = otp::Hotp::default();
let otp = hotp.generate_at(5);
assert!(hotp.verify(otp, 5, 1)); // exact match
assert!(hotp.verify(otp, 6, 1)); // match in past window
assert!(!hotp.verify(otp, 10, 2)); // out of range
§References
Source

pub fn to_uri(&self) -> String

Generates a Key URI string in the format compatible with Google Authenticator and other TOTP/HOTP apps.

This URI can be encoded as a QR code and scanned by authenticator apps (e.g., Google Authenticator, Authy) to configure the OTP settings automatically.

The URI format follows the Key URI Format specification:

otpauth://TYPE/LABEL?PARAMETERS

For example, a TOTP URI might look like:

otpauth://totp/Example%3Aalice%40example.com?secret=JBSWY3DPEHPK3PXP&issuer=Example&algorithm=SHA1&digits=6&period=30
§Format Details
  • TYPE: Either totp or hotp
  • LABEL: Usually issuer:account, URL-encoded
  • secret: Base32-encoded secret key
  • issuer: The provider or service name (optional, but recommended)
  • algorithm: Hash function used (e.g., SHA1, SHA256, SHA512)
  • digits: Number of digits in the OTP (typically 6 or 8)
  • period (TOTP only): Time step in seconds (e.g., 30)
  • counter (HOTP only): Current counter value
§Returns

A String containing the otpauth:// URI.

§Example
use otp::{Totp, Algorithm, Secret};

let totp = Totp::new(
    Algorithm::SHA256,
    "Example".into(),
    "alice@example.com".into(),
    6,
    30,
    Secret::from_bytes(b"supersecretkey")
);

let uri = totp.to_uri();
assert!(uri.starts_with("otpauth://totp/"));
Source

pub fn alg(&self) -> Algorithm

Source

pub fn issuer(&self) -> &str

Source

pub fn label(&self) -> &str

Source

pub fn digits(&self) -> u8

Source

pub fn counter(&self) -> u64

Source

pub fn secret(&self) -> &Secret

Source

pub fn from_uri(uri: &str) -> Result<Self, ParseUriError>

Parses a HOTP configuration from a URI string in the Key URI Format.

This function supports URIs of the form: otpauth://hotp/{label}?secret={secret}&issuer={issuer}&algorithm={algorithm}&digits={digits}&counter={counter}

§Arguments
  • uri - A string slice containing the HOTP URI.
§Returns

Returns Ok(Hotp) if the URI is valid and can be parsed. Otherwise returns Err(Error) indicating the reason for failure.

§Errors

This method returns an error in the following cases:

  • URI does not start with the otpauth://hotp/ scheme.
  • Missing or empty label in the URI.
  • Missing or invalid query parameters (e.g., secret, counter).
  • Unsupported or invalid algorithm name.
  • Base32 decoding of the secret fails.
  • Convert string errors (e.g., counter, digits).
  • Invalid percent-encoding in the label or issuer.
§Examples
use otp::Hotp;

let uri = "otpauth://hotp/example:alice@example.com?secret=JBSWY3DPEHPK3PXP&issuer=example&algorithm=SHA1&digits=6&counter=1";
let hotp = Hotp::from_uri(uri).unwrap();
assert_eq!(hotp.issuer(), "example");
assert_eq!(hotp.label(), "alice@example.com");

Trait Implementations§

Source§

impl Default for Hotp

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl Freeze for Hotp

§

impl RefUnwindSafe for Hotp

§

impl Send for Hotp

§

impl Sync for Hotp

§

impl Unpin for Hotp

§

impl UnsafeUnpin for Hotp

§

impl UnwindSafe for Hotp

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> 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, 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.