Students lock and unlock numbers with XOR and a shared key, and meet the weakness of sending the same locked message every time.
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 8 min · Investigate 10 min · Modify 8 min · Make 15 min
The idea: XOR gives a 1 where two bits differ and a 0 where they match. Doing it twice with the same key returns the original, so one key and one operation work in both directions. This is a shared-key (symmetric) cipher.
Bits: the lesson text shows 7 ^ 5 in bits. If students have not met binary, treat the working as a table to read, not something to learn: the check answers can be found by following the pattern.
Two honest limits: (1) XOR with a short key repeated is breakable; real systems use long keys and better methods. (2) The same message gives the same locked number every time, which the last Make task shows. Both are why the next lessons matter.
XOR undoes itself with the same key, and a wrong key gives a wrong answer, not an error. Ask them to compare the keys on both micro:bits first.
| What you will see | A question to ask | The fix |
|---|---|---|
| The receiver shows a different number. | Are the keys the same on both micro:bits? | Make both keys equal; check B was pressed the same number of times on each. |
| ^ looks odd in the blocks. | Which block is it? | The ^ block is in Math (Advanced), with the other bit operations. |
One possible solution for each task. Other correct programs are fine.

let key = 5
radio.setGroup(5)
input.onButtonPressed(Button.A, function () {
radio.sendNumber(7 ^ key)
})
input.onButtonPressed(Button.B, function () {
key += 1
if (key > 15) {
key = 1
}
basic.showNumber(key)
})
radio.onReceivedNumber(function (receivedNumber) {
basic.showNumber(receivedNumber ^ key)
})

let key = 12
let pin = 4271
radio.setGroup(5)
input.onButtonPressed(Button.A, function () {
radio.sendNumber(pin ^ key)
})
radio.onReceivedNumber(function (receivedNumber) {
basic.showNumber(receivedNumber ^ key)
})
Open task: any program that does what the step asks.
Stretch: Lock each digit of the PIN separately, using a different key digit for each.
Support: Give the sending half complete.
Why does the receiver use the same key and the same operation as the sender?
XOR with the same key undoes itself: (message ^ key) ^ key = message.
Next: both ends need the same key. How do they agree it without sending it?