← Teacher guide

Prove it with a challenge

Students build a challenge-and-response lock so that a heard answer cannot be used again, then add a lockout after three wrong answers.

Secret messages · Trust · about 50 minutes · Open the student lesson

Classroom resources

Load these into Waypoints Prepare: choose Load URL and paste the copied address, or download the file and import it. In Prepare, the worksheet's Teacher edition shows the answers; the student copy hides them.

Students will be able to

Timing

Predict and Run 10 min · Investigate 10 min · Modify 8 min · Make 18 min

Before class

The idea: to prove you know a secret without saying it, the other side sets a random question, the challenge, and you answer it using the secret. A fresh challenge each time means an old answer fits only the old challenge.

Everyday picture: a bank clerk who asks for a random character of your password each time. Where it breaks: if the same question comes up, the answer works again; the challenge must be random and not repeat.

Honest limits: the answer function here, (n × key + 3) mod 100, is a toy: someone who collects enough challenges and answers can work out the key, and with only 90 possible challenges they repeat soon. Real systems use a hash function (a one-way mix) and huge challenges. Tell students the toy is for learning the shape of the idea.

Same program on both micro:bits: the simulator runs two copies. The one where A is pressed acts as the key; the other acts as the lock.

Running the lesson

  1. Predict: ask for the working before the options.
  2. Investigate: ask what a listener has after hearing one full exchange (a challenge and its answer), and whether it helps with the next one.

The hard part (on purpose)

Why a fixed password fails once heard, and a fresh challenge doesn't. Ask what a listener could reuse, and whether the answer ever repeats.

When students get stuck

What you will seeA question to askThe fix
The lock always shows a cross.Do both micro:bits have the same secretKey? Is the answer function the same?Use the same secretKey and answer function on both.
The tick appears on the wrong micro:bit.Which micro:bit checks the answer?The micro:bit that picked the challenge also checks the answer; the knocker only answers.

Answers to the checks

  1. Predict: The key micro:bit knocks. The lock picks the challenge 50. The answer is (n × 7 + 3) remainder 100. What answer goes through the air?
    53. 50 × 7 + 3 = 353, and the remainder after dividing by 100 is 53.
  2. Working out an answer: The lock picks the challenge 20. What answer opens the lock? (n × 7 + 3, remainder after dividing by 100.)
    43
    20 × 7 + 3 = 143, and the remainder after dividing by 100 is 43.
  3. An answer heard before: Yesterday the lock's challenge was 50 and the answer 53. Today the lock picks a new challenge. Why is 53 unlikely to open it today?
    The new challenge is almost certainly different, so its answer is different
    The answer depends on the challenge. A new challenge gives a new answer, so an old answer fits only the old challenge.
  4. What crosses the air: For each item, does it cross the air in the challenge-and-response?
    The knock → Crosses the air; The challenge → Crosses the air; The answer → Crosses the air; The secret key → Never crosses the air

Solutions

One possible solution for each task. Other correct programs are fine.

Modify

The program as blocks
Show as code
let secretKey = 7
let challenge = 0
let opened = 0
function answer(n: number): number {
    return (n * secretKey + 3) % 100
}
radio.setGroup(5)
input.onButtonPressed(Button.A, function () {
    radio.sendString("KNOCK")
})
input.onButtonPressed(Button.B, function () {
    basic.showNumber(opened)
})
radio.onReceivedString(function (receivedString) {
    if (receivedString == "KNOCK") {
        challenge = randint(10, 99)
        radio.sendValue("chall", challenge)
    }
})
radio.onReceivedValue(function (name, value) {
    if (name == "chall") {
        radio.sendValue("answer", answer(value))
    } else if (name == "answer") {
        if (value == answer(challenge)) {
            opened += 1
            basic.showIcon(IconNames.Yes)
        } else {
            basic.showIcon(IconNames.No)
        }
    }
})

Make

The program as blocks
Show as code
let secretKey = 7
let challenge = 0
let wrong = 0
function answer(n: number): number {
    return (n * secretKey + 3) % 100
}
radio.setGroup(5)
input.onButtonPressed(Button.A, function () {
    radio.sendString("KNOCK")
})
radio.onReceivedString(function (receivedString) {
    if (receivedString == "KNOCK") {
        if (wrong >= 3) {
            basic.showIcon(IconNames.Skull)
            basic.pause(5000)
            wrong = 0
        } else {
            challenge = randint(10, 99)
            radio.sendValue("chall", challenge)
        }
    }
})
radio.onReceivedValue(function (name, value) {
    if (name == "chall") {
        radio.sendValue("answer", answer(value))
    } else if (name == "answer") {
        if (value == answer(challenge)) {
            wrong = 0
            basic.showIcon(IconNames.Yes)
        } else {
            wrong += 1
            basic.showIcon(IconNames.No)
        }
    }
})

Stretch and support

Stretch: Make the challenge 3 digits and store it as a number. Why does a longer challenge repeat less often?

Support: Give the lockout in outline: students fill in the conditions.

Exit ticket

Why does a challenge and response protect a lock better than a fixed password?

The answer depends on a fresh challenge, so an answer that was heard before no longer fits.

What each step is for

Where it leads

Next: capture-the-flag puzzles, then defend a whole system.