> For the complete documentation index, see [llms.txt](https://www.csprinciples.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://www.csprinciples.com/25-26/session-25.md).

# Session 25

## authenticator.lua

```lua
-- ============================================================
-- Authenticator
-- ============================================================
-- In this lab you will play BOTH roles in a Multi-Factor
-- Authentication system: the phone that generates codes, and
-- the server that checks them.

-- ============================================================
-- HELPERS (already done for you).
-- ============================================================

-- Returns the current "time bucket" -- a number that changes
-- every 30 seconds.
function getCurrentBucket()
  return math.floor(os.time() / 30)
end

-- Returns a random 6-digit code as a string (e.g. "041938").
function randomCode()
  return string.format("%06d", math.random(0, 999999))
end

-- ============================================================
-- CHECKPOINT 1:  generateCode
-- Mixes a secret and a time bucket into a 6-digit code.
-- ============================================================
function generateCode(secret, timeBucket)

  -- TODO #1:
  -- Combine `secret` and `timeBucket` into ONE number, using
  -- multiplication and addition. Store the result in `code`.
  --
  -- Pick any formula you like, as long as it uses BOTH inputs.
  -- Examples:  secret + timeBucket
  --            secret * 100 + timeBucket
  --            secret * 31 + timeBucket * 17
  local code = 0   -- replace this line with your formula

  -- Done for you. Squishes the number into 6 digits.
  code = (code * code) % 1000000
  return string.format("%06d", code)

end

-- ============================================================
-- CHECKPOINT 2:  verifyCode
-- Returns true if submittedCode is the right code for userSecret
-- right now, and false otherwise.
-- ============================================================
function verifyCode(submittedCode, userSecret)

  -- TODO #2:  Write the body of this function.
  --
  -- Your function should:
  --   (1) Compute the code that SHOULD be valid right now.
  --       Call generateCode, passing in userSecret and the
  --       current time bucket from getCurrentBucket().
  --   (2) Compare that expected code to submittedCode using ==
  --   (3) Return true if they match, false if they don't.

end

-- ============================================================
-- CHECKPOINT 3 (CHALLENGE):  bruteForce
-- An attacker who DOESN'T know your secret tries to guess by
-- typing random 6-digit codes. How often does that work?
-- ============================================================
function bruteForce(numAttempts, userSecret)

  -- TODO #3:  Write the body of this function.
  --
  -- Your function should:
  --   (1) Use a loop that runs numAttempts times.
  --   (2) Each time, call randomCode() to get a random guess.
  --   (3) Call verifyCode to check if the guess works.
  --   (4) Count how many guesses were accepted.
  --   (5) Return the count.

end

-- ============================================================
-- TEST AREA -- this is your secret. Pick any number you like.
-- ============================================================

local mySecret = 000000 -- change

-- Test Checkpoint 1 (this runs as soon as you fill in TODO #1).
print("Your code right now:  " .. generateCode(mySecret, getCurrentBucket()))


-- Test Checkpoint 2 -- uncomment these lines after TODO #2.
--
-- local guess = "123456"
-- if verifyCode(guess, mySecret) then
--   print("Login with " .. guess .. ":  ACCESS GRANTED")
-- else
--   print("Login with " .. guess .. ":  access denied")
-- end


-- Test Checkpoint 3 -- uncomment these lines after TODO #3.
--
-- local hits = bruteForce(10000, mySecret)
-- print("Attacker tried 10,000 random guesses, succeeded " .. hits .. " times.")

```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.csprinciples.com/25-26/session-25.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
