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.](https://shkspr.mobi/blog/wp-content/uploads/2024/07/Figure_1-fs8.png)
HOLY SHIT! CONSPIRACY CONFIRMED! WTAF?!?!?
Don't believe me? Here's the code:
Python 3
import 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.](https://shkspr.mobi/blog/wp-content/uploads/2024/07/Figure_100-fs8.png)
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.](https://shkspr.mobi/blog/wp-content/uploads/2024/07/Figure_10000-fs8.png)
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.](https://shkspr.mobi/blog/wp-content/uploads/2024/07/Figure_1000000-fs8.png)
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.
still can't not read it as Top of the Pops
@Edent Nice little writeup. What about an analysis of how frequently each digit appears in each of the six possible positions? I would like to think that's also just as random, at least with a large enough sample.
How random are TOTP codes? – Terence Eden’s Blog - lazysoci.al
@Edent Aye- runs in a random pool is somthing that one needs to learn to expect. There are, of course, other methods for defeating that sort of statistical analysis. One simple example being the so-called "lucky log” die.
How random are TOTP codes? | Hacker News
More comments on Mastodon.