totp-lite

A minimal, RFC 6238-compliant TOTP library for Rust with pluggable SHA-1, SHA-256, and SHA-512 hashing.

Library
Cargo
v2.0.1
33stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
36/100Needs Attention
Development Activity28
Maintenance24
Community20
Maturity60
Momentum12

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
76/100Good
Architecture78
Code Quality78
Innovation82
Learning Curve65

totp-lite is a small, focused Rust crate that implements Time-based One-Time Password generation per RFC 6238. It exposes two functions — totp for the common case (30-second step, 8-digit output) and totp_custom for full control over step and digit count — parameterized by hash algorithm (SHA-1, SHA-256, SHA-512) via generic type parameters backed by the RustCrypto digest/hmac crate ecosystem.

At roughly 140 lines of source and a small, well-known dependency chain (digest, hmac, sha1, sha2), it’s designed to be embedded directly into authentication flows — two-factor auth, API key rotation, or Google-Authenticator-compatible clients — without pulling in a heavier crypto or auth framework.

What You Get

  • RFC 6238-compliant TOTP generation via the totp and totp_custom functions
  • Support for SHA-1, SHA-256, and SHA-512 as the underlying HMAC hash algorithm, selected via a generic type parameter
  • Configurable time step and output digit count through totp_custom
  • A working example (examples/ga.rs) showing a Google Authenticator-compatible flow with base32 secret decoding
  • A tiny dependency surface built entirely on the RustCrypto digest/hmac crate family

Common Use Cases

  • Two-factor authentication for a web app - a backend generates and verifies 6-8 digit TOTP codes during login to add a second authentication factor.
  • Google Authenticator-compatible client - a CLI or mobile app decodes a base32 secret and produces codes matching what Authenticator apps display, as shown in examples/ga.rs.
  • API key rotation - a service issues short-lived, time-boxed tokens instead of static API keys, using totp_custom to tune the digit count and step interval.
  • Embedded auth in an existing RustCrypto stack - projects that already depend on digest/hmac/sha2 add TOTP support without introducing a new hashing implementation.

Under The Hood

Architecture The crate is a single file (src/lib.rs, ~140 lines) exposing two public functions, totp and totp_custom, plus a private to_bytes helper — there are no modules, layers, or state to speak of. totp delegates to totp_custom with RFC-default constants (DEFAULT_STEP = 30, DEFAULT_DIGITS = 8), making totp_custom the sole implementation of the RFC 6238 algorithm: it computes an HMAC over the big-endian time-step counter using a generic hash type constrained by digest’s CoreProxy/FixedOutputCore traits, then applies RFC dynamic truncation — using the last hash byte as an offset into the digest to extract a 31-bit integer, mod-reduced to the requested digit count. The generic trait bounds exist purely to satisfy Hmac<H>’s requirements across SHA-1/256/512’s differing block sizes, giving compile-time hash-algorithm polymorphism rather than runtime dispatch.

Tech Stack A Rust 2018 edition crate with a deliberately small dependency set drawn entirely from RustCrypto: digest 0.10 for hash trait definitions, hmac 0.12 for the HMAC construction, and sha1/sha2 0.10 for the concrete hash implementations re-exported as Sha1, Sha256, and Sha512. Dev-dependencies are version-sync 0.9, which keeps the doc(html_root_url) attribute in sync with the crate version via tests/version-numbers.rs, and koibumi-base32, used only by the examples/ga.rs demo. There’s no build script, FFI, or async runtime — this is a pure computation library, published to crates.io and built with cargo test --all-targets on GitHub Actions CI.

Code Quality Tests live inline in src/lib.rs under #[cfg(test)] mod tests, encoding the official RFC 6238 Appendix B test vectors for SHA-1, SHA-256, and SHA-512 — strong evidence of correctness against the spec rather than just internal consistency. Error handling is minimal by design: Hmac::new_from_slice is unwrapped rather than propagated as a Result, acceptable since HMAC in this crate family accepts keys of any length, but a latent panic surface if that ever changes upstream. Naming is clear and idiomatic, and hash-algorithm selection is encoded in the type system via generics rather than a string or enum, making misuse a compile error rather than a runtime one. No lint configuration is checked in, but CI runs the full test suite including doctests, and version-sync guards documentation drift.

API Design The public surface is exactly two functions, both generic over hash algorithm — about as low-boilerplate as an auth-code library gets: totp::<Sha512>(secret, seconds) returns a String directly, with no builder, config struct, or initialization step. Every public function’s doc comment includes a runnable, RFC-verified doctest, so the documented examples can’t silently drift from actual behavior. The one friction point is for callers who want to be generic over hash type themselves — the where H: Update + FixedOutput + CoreProxy, ... bound is copied from digest’s internals and isn’t trivial to satisfy for a custom hash type — but for the common case of using the three re-exported hash types, callers never see this.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search