# Time and Hmac based One Time Passwords OTP implementations based on [RFC 4226](https://www.rfc-editor.org/rfc/rfc4226) for Hmac-based OTPs and [RFC 6238](https://www.rfc-editor.org/rfc/rfc6238) for Time-based OTPs. **By default all features are enabled**, if you wish only to use the default functionality (no `encoding`, `custom` or `qr` modules), use the flag `default-features = false` This module by itself allows you to generate and verify TOTPs and HOTPs using the default algorithm SHA-1, the default digit length of 6 and the default time step of 30 for TOTPs. *The following applies only if you set `default-features = false`, by default they are included*: If you need finer controls over password generation and verification use the `custom_otp` feature flag to gain access to the [custom](https://docs.rs/thotp/0.1.0/thotp/custom/index.html) module. The `encoding` feature flag gives access to the [encoding](https://docs.rs/thotp/0.1.0/thotp/encoding/index.html) module which provides 2 basic functions to encode and decode the generated keys to an encoding of choice avilable from the [data_encoding](https://docs.rs/data-encoding/latest/data_encoding/index.html) crate. The `qr` feature flag gives access to the [qr](https://docs.rs/thotp/0.1.0/thotp/qr/index.html) module and enables QR code generation of the generated secret keys ready to be used by authenticator apps. ## Example usage ```rust use thotp::{ otp, verify_totp, generate_secret, encoding::{encode, decode}, qr::generate_code, }; use std::time::{SystemTime, UNIX_EPOCH}; // The default time step used by this module internally const TIME_STEP: u8 = 30; // Generate an encoded secret let secret = generate_secret(80); // The data_encoding crate is re-exported for convenience let encoded = encode(&secret, data_encoding::BASE32); // Store the secret somewhere safe let qr_code = generate_code( // Type of otp "totp", // The encoded secret &encoded, // Your big corp title "Big Corp:john.doe@email.com", // Your big corp issuer "Big Corp", // The qr code width (None defaults to 200) None, // The qr code height (None defaults to 200) None, // Correction level, M is the default qrcode::EcLevel::M ) .expect("uh oh"); // Scan qr with some authenticator app // Verify a password provided from the client, assume this is what they calculated // When generating an OTP we have to calculate the current time slice let time_step_now = SystemTime::now() .duration_since(UNIX_EPOCH) .unwrap() .as_secs() / TIME_STEP as u64; let pw = otp(&secret, time_step_now).unwrap(); // The verify function does this internally let (result, discrepancy) = verify_totp(&pw, &secret, 0).unwrap(); assert_eq!((true, 0),(result, discrepancy)); ``` There are 3 constants used by this module internally; The `DIGITS_DEFAULT` constant is the default password length generated by the `otp` function as well as when verifying and is equal to 6. The `TIME_STEP` is the default and RFC recommended time step used to divide the duration in seconds from now until the unix epoch and is equal to 30. When TOTPs are generated, there is a chance they will be generated at the end of a time step and by the time they reach the server the password would be invalid because it would fall in the previous time step. This is mitigated by allowing passwords from `ALLOWED_DRIFT` time steps prior and subsequent to the current to be valid. The value of this is the RFC recommended amount 1, meaning the passwords from the time slice prior and subsequent to the current one are considered valid. The same drift can happen with HOTPs with the counter, and a lookahead parameter can be used to adjust how many passwords will be considered valid from the current counter.