Skip to main content

Command Palette

Search for a command to run...

The Way Mathematics Automatically Built Modern Authentication

Published
4 min read

Story of passwords to Time-Based Cryptography

Imagine it’s 1995.

You create a profile in a web site.

You type:

dragon123

And that’s it.

Probably the password was a match to one that was available in the server, in which case you were in.

No encryption awareness.

No cryptography.

No second factor.

Just trust.

And that was enough.

Until math was studied by the attackers.

Chapter 1: The Age of Basic Passwords

It was not that difficult to authenticate before:

User → Type password → Server checks → Authorized

Diagram: Early Model

User
  |
  v
[ Password Input ]
  |
  v
Checking of passwords kept in the store.
  |
  v
Login Success

This, however, had a weakness in it:

  • Database leakages were influenced on passwords.

  • Users reused passwords.

  • The brute force attack was irrelevant.

It was in this manner as these we defended our first mathematical defence.

Chapter 2: Hashing — The First Mathematical Shield

We do not store passwords but a hash in plaintexts.

A hash function:

  • Is deterministic

  • Is one-way

  • Produces non-variable output

Example using Node.js

import crypto from "crypto";

function hashPassword(password) {
  return crypto
    .createHash("sha256")
    .update(password)
    .digest("hex");
}

const savedHash = hashPassword("dragon123");

Now authentication becomes:

if (hashPassword(inputPassword) === savedHash) {
  console.log("Login success");
}

Hash Based Authentication: Diagram

User Password
      |
      v
   SHA256
      |
      v
Compare with stored hash

Math made passwords safer.

But not safe enough.

The failure of authentication recurs in the event of the attackers offline breaking the hash.

We needed a second dimension.

Chapter 3: The Introduction of a Second Factor

The idea was simple:

What happens in case an access password is not enough?

We add:

  • Something you know — password

  • Something you have — phone

And here time-based mathematics is brought in.

Apps like:

  • Google Authenticator

  • Microsoft Authenticator

is a system that is called TOTP (Time-Based One-Time Password).

Chapter 4: When Time Became a Member of Identity

TOTP also relies on pure mathematics as compared to the SMS system (requires networks, and can be intercepted).

Both your phone and your server are separately computing a 6-digit code.

No interaction between them.

Just math.


The TOTP Formula

Let’s see this in real code.


JavaScript Implementation of TOTP

Using otpauth:

import * as OTPAuth from "otpauth";

// Step 1: Generate Secret
const secret = new OTPAuth.Secret({ size: 20 });

// Step 2: Create TOTP instance
const totp = new OTPAuth.TOTP({
  issuer: "SecureAuthDemo",
  label: "yaman",
  algorithm: "SHA1",
  digits: 6,
  period: 30,
  secret: secret,
});

// Generate current OTP
const otp = totp.generate();

console.log("Current OTP:", otp);

And background to this is this:

timeCounter = Math.floor(Date.now() / 1000 / 30);
hmac = HMACSHA1(secret, timeCounter);
binaryCode = dynamicTruncate(hmac);
otp = binaryCode % 1000000;

That’s it.

The Rationale of the Two Devices Receiving the Same OTP

Because:

  • Same Secret (K)

  • Same Time Counter (T)

  • Same HMAC-SHA1

  • Same Truncation

  • Same Modulo

Mathematically:

If K₁ = K₂ and T₁ = T₂

Then HMAC(K₁, T₁) = HMAC(K₂, T₂)

Therefore: OTP₁ = OTP₂

This is determinism.

There is no post-installation probability.


Diagram: Modern 2FA Flow

           Shared Secret (K)
                 |
      -----------------------------
      |                           |
      v                           v
Phone                         Server
Time → floor(t/30)            Time → floor(t/30)
      |                           |
HMAC(K, T)                    HMAC(K, T)
      |                           |
Truncate + mod 1e6            Truncate + mod 1e6
      |                           |
   OTP = 349182               OTP = 349182

The phone does not have a touch with Google.

The server never has any contact with Google.

Everything happens locally.

Verifying OTP on Backend

function verifyOTP(secretBase32, token) {
  const totp = new OTPAuth.TOTP({
    issuer: "SecureAuthDemo",
    label: "yaman",
    algorithm: "SHA1",
    digits: 6,
    period: 30,
    secret: OTPAuth.Secret.fromBase32(secretBase32),
  });

  const delta = totp.validate({
    token,
    window: 1, // allows +-30 seconds drift
  });

  return delta !== null;
}

It allows the toleration of small clock disparities yet, it is safe.

History of Authentication

The history of authentication can be traced back to ancient times.

[ Plain Password ]
        ↓
[ Hashed Password ]
        ↓
[ Password + SMS ]
        ↓
[ Password + TOTP (HMAC + Time) ]
        ↓
[ Public key cryptography (WebAuthn) ]

Every step took him further to be near the human weakness

and still closer to mathematical guarantees.


Why Mathematics Changed Everything

Authentication evolved out of:

“Do I believe this person?”

To:

Do they have the ability to compute a cryptographic function that can only be computed by the real user?

Behind every 6-digit OTP lies:

  • Modular arithmetic

  • HMAC

  • SHA1

  • Bitwise truncation

  • Deterministic functions

All that happens within milliseconds.


Final Reflection

Here you are now in your true authenticator app and you see:

349182

It is not a simple number you are looking at.

You’re seeing:

  • Time was divided into time intervals.

  • Cryptography converted a secret that was a secret common to all.

  • It is moulded into 6 digits by a modulo operation.

  • 25-years of secrecy research in cryptography.

Authentication is no more trust.

It is mathematics.

And mathematics does not lie.