Students agree a key over an open channel with a Diffie–Hellman style exchange using small numbers, then use it as the key for XOR.
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.
Predict and Run 12 min · Investigate 12 min · Modify 10 min · Make 18 min
The idea: two ends agree a shared key while everyone listens. Each mixes a private number with public numbers, swaps the mixes, and mixes again with its private number. Both reach the same number, which was never sent. This is the Diffie–Hellman key exchange, the idea behind the padlock in a browser.
Everyday picture: paint. Everyone knows the common colour (yellow). Each person adds a private colour and shares the mixture. Each then adds their private colour to the other's mixture. Both end with the same colour, and nobody can un-mix the shared one to find the private colours. Where it breaks: with numbers there is no real un-mixing for big numbers, but for tiny numbers you can just try them all.
The maths: students need only the pattern "power, then remainder". The check numbers are small. The program does the working (modPow, a loop, as in micro:bit Foundations).
Honest limits: P = 23 can be broken by trying all private numbers (the third Investigate task says so). Also, a key exchange does not say who you are talking to: an unknown micro:bit could do the exchange too. That need, to prove who is who, is the next lessons' job.
Following a key exchange where the shared key never travels. Ask them to trace on paper what each micro:bit sends and what it keeps private.
| What you will see | A question to ask | The fix |
|---|---|---|
| The two micro:bits show different numbers. | Did you press A on both before looking? Does each hear the other's mix? | Both must send a mix and receive one. Use the same group. |
| The numbers are far too large or wrong. | Is modPow taking the remainder at every step? | result = (result × base) % prime inside the loop. |
One possible solution for each task. Other correct programs are fine.

let P = 23
let G = 5
let secret = randint(2, 20)
let shared = 0
function modPow(base: number, power: number, prime: number): number {
let result = 1
for (let i = 0; i < power; i++) {
result = (result * base) % prime
}
return result
}
radio.setGroup(5)
input.onButtonPressed(Button.A, function () {
radio.sendValue("mix", modPow(G, secret, P))
})
input.onButtonPressed(Button.B, function () {
radio.sendNumber(7 ^ shared)
})
radio.onReceivedValue(function (name, value) {
if (name == "mix") {
shared = modPow(value, secret, P)
basic.showNumber(shared)
}
})
radio.onReceivedNumber(function (receivedNumber) {
basic.showNumber(receivedNumber ^ shared)
})

let P = 23
let G = 5
let secret = randint(2, 20)
let shared = 0
let pin = 4271
function modPow(base: number, power: number, prime: number): number {
let result = 1
for (let i = 0; i < power; i++) {
result = (result * base) % prime
}
return result
}
radio.setGroup(5)
input.onButtonPressed(Button.A, function () {
radio.sendValue("mix", modPow(G, secret, P))
})
input.onButtonPressed(Button.B, function () {
radio.sendNumber(pin ^ shared)
})
radio.onReceivedValue(function (name, value) {
if (name == "mix") {
shared = modPow(value, secret, P)
basic.showIcon(IconNames.Yes)
}
})
radio.onReceivedNumber(function (receivedNumber) {
basic.showNumber(receivedNumber ^ shared)
})
Stretch: Change P and G. Which private numbers still give a match? (All of them do: the method works for any P and G.)
Support: Give the exchange complete and ask only for the locked PIN.
Which of the numbers go across the air in a key exchange?
P, G and the two mixes. The private numbers and the shared key never do.
Next: how does the receiver know a message was not changed on the way?