HORIZON HASKELLDocslts/ghc-10.0.x8174fa42026-10-11Search names, modules, packages, or :: a typeCtrl K

GHC 10.0.0.20260917 · lts/ghc-10.0.x · 8174fa4 · 2026-10-11

Modulecrypton-2.1.7Haskell2010

Crypto.OTP

One-time password implementation as defined by the HOTP and TOTP specifications.

Both implementations use a shared key between the client and the server. HOTP passwords are based on a synchronized counter. TOTP passwords use the same approach but calculate the counter as a number of time steps from the Unix epoch to the current time, thus requiring that both client and server have synchronized clocks.

Probably the best-known use of TOTP is in Google's 2-factor authentication.

The TOTP API doesn't depend on any particular time package, so the user needs to supply the current OTPTime value, based on the system time. For example, using the hourglass package, you could create a getOTPTime function:

Example4 expressions
import Time.Systemimport Time.Typeslet getOTPTime = timeCurrent >>= \(Elapsed t) -> return (fromIntegral t :: OTPTime)

Or if you prefer, the time package could be used:

Example3 expressions
import Data.Time.Clock.POSIXlet getOTPTime = getPOSIXTime >>= \t -> return (floor t :: OTPTime)
  • 5 types
  • 7 values
  • Packagecrypton-2.1.7
  • Exports12
  • LanguageHaskell2010
  • LicenceBSD-3-Clause AND MIT AND ISC
  • SourceOTP.hs
typetype OTP = Word32
#

A one-time password which is a sequence of 4 to 9 digits.

valueminimumDigestSize :: Int
#

The smallest hash digest hotp can be used with, in bytes.

RFC 4226 section 5.3 defines dynamic truncation over the 20-byte HMAC-SHA-1 output: the offset is the low four bits of the last byte, so it selects any of the first 16 bytes, and four bytes are then read starting there. The highest byte that can be reached is therefore byte 18, and a shorter digest would make that read run off the end of the MAC.

valuehotp
  1. :: (HashAlgorithm hash, ByteArrayAccess key)
  2. => hash
  3. -> OTPDigits

    Number of digits in the HOTP value extracted from the calculated HMAC

  4. -> key

    Shared secret between the client and server

  5. -> Word64

    Counter value synchronized between the client and server

  6. -> OTP

    The HOTP value

#

Calculate an HOTP value as defined by RFC 4226.

The hash must produce a digest of at least minimumDigestSize bytes, which is what the dynamic truncation step is defined over; error is raised otherwise.

valueresynchronize
  1. :: (HashAlgorithm hash, ByteArrayAccess key)
  2. => hash
  3. -> OTPDigits
  4. -> Word16

    The look-ahead window parameter. Up to this many values will be calculated and checked against the value(s) submitted by the client

  5. -> key

    The shared secret

  6. -> Word64

    The current server counter value

  7. -> (OTP, [OTP])

    The first OTP submitted by the client and a list of additional sequential OTPs (which may be empty)

  8. -> Maybe Word64

    The new counter value, synchronized with the client's current counter or Nothing if the submitted OTP values didn't match anywhere within the window

#

Attempt to resynchronize the server's counter value with the client, given a sequence of HOTP values.

Every counter in the window is tried and every submitted value is compared, whatever matches, so the time taken does not depend on where in the window the client's counter was found, nor on how many of the submitted values were right. The cost of a call is therefore one HMAC per counter in the window plus one per extra value, every time.

valuetotp
  1. :: (HashAlgorithm hash, ByteArrayAccess key)
  2. => TOTPParams hash
  3. -> key

    The shared secret

  4. -> OTPTime

    The time for which the OTP should be calculated. This is usually the current time as returned by Data.Time.Clock.POSIX.getPOSIXTime

  5. -> OTP
#

Calculate a totp value for the given time.

valuemkTOTPParams
  1. :: HashAlgorithm hash
  2. => hash
  3. -> OTPTime

    The T0 parameter in seconds. This is the Unix time from which to start counting steps (default 0). Must be before the current time.

  4. -> Word16

    The time step parameter X in seconds (default 30, maximum allowed 300)

  5. -> OTPDigits

    Number of required digits in the OTP (default 6)

  6. -> ClockSkew

    The number of time steps to check either side of the current value to allow for clock skew between client and server and or delay in submitting the value. The default is two time steps.

  7. -> Either String (TOTPParams hash)
#

Create a TOTP configuration with customized parameters.