How random are TOTP codes?


I'm pretty sure that the 2FA codes generated by my bank's TOTP app have a bias towards the number 8 - because eight is an auspicious number.

But is that just my stupid meaty brain noticing patterns where none exist?

The TOTP algorithm uses HMAC, which in turn uses SHA-1. My aforementioned brain is not clever enough to understand how that works. Although bigger, meatier brains have assured me it is fine.

What happens if I sample, say, the next 10 TOTP codes and plot how often digits appear?

Histogram of distributions. 8 is clearly higher than the rest.

HOLY SHIT! CONSPIRACY CONFIRMED! WTAF?!?!?

Don't believe me? Here's the code:

Python 3 Python 3import pyotp
import numpy as np
import matplotlib.pyplot as plt

totp = pyotp.TOTP('')

#   How many times to run this?
runs = 10

#   Initialize a NumPy array with shape to store the digits
digits_array = np.zeros( ( runs, 6), dtype=int)

#   Generate the digits
for i in range( runs ):
    number_str = totp.at( i * 30 )
    for j in range(6):
        digits_array[i, j] = int(number_str[j])

#   Analyse the entire array
all_digits = digits_array.flatten()

# Plot histogram for all digits
plt.figure()
plt.hist(all_digits, bins=np.arange(11) - 0.5, edgecolor='black', density=True)
plt.xticks(range(10))
plt.title('Digit Distribution for All Digits (' + f"{runs:,}" + ' runs)')
plt.xlabel('Digit')
plt.ylabel('Frequency')
plt.show()

OK, so maybe that's a coincidence. What happens if we check 100 generations?

Histogram of 100 runs. Still significant variation, although flattened.

Quite a lot of noise in there - but lucky number 8 isn't quite as prominent.

After 10,000 generations, the variation is all but gone.

Histogram showing almost no variation.

There are about 30 million seconds in a year. TOTP codes change every 30 seconds. Which means, in a year, you'll see about a million of them:

Histogram which is basically flat.

Is it possible that a TOTP code could be formed which shows a clear bias to a specific number? Probably not.

I love being able to check the source code - but sometimes it's just as reassuring to measure the output.


Share this post on…

  • Mastodon
  • Facebook
  • LinkedIn
  • BlueSky
  • Threads
  • Reddit
  • HackerNews
  • Lobsters
  • WhatsApp
  • Telegram

5 thoughts on “How random are TOTP codes?”

What are your reckons?

All comments are moderated and may not be published immediately. Your email address will not be published.

Allowed HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <p> <pre> <br> <img src="" alt="" title="" srcset="">