The New Year 2014/2015 #sophospuzzle is over.
Here’s a list of everyone who solved it in time, and those of the solvers who won prizes.
We’ve also explained how to solve it for those who weren’t able to take part.
The puzzle revisited
We showed you this image:
493D5105 51151081 B481213C 5C813505 39648109 25514CFD
And we said:
Just extract the question hidden in the data, and answer it.
Not an awful lot to go on, but the “tags” added to the article (those are the WordPress indexing notes we add to each item) offered a little hint:
Apparently, everyone agreed that eggs should be opened at the more convenient end, but which end was that to be?
The argument split the nation.
In computer science, the same dogmatism has applied over the years over how numbers should be stored in memory by a processor.
Should a 32-bit number like 0x12345678 be stored in memory as it is written, so that the lowest-numbered memory address holds the most significant byte?
Or should the bytes be reversed in memory so that the least significant byte is at the lowest-numbered address?
Worse still, should the processor include an “ecumenical bit” that can be set or cleared to switch from one style to another, so that anyone can be happy but everyone can be confused?
Solving the puzzle
So the endianity hint is suggesting that you pick one way to interpret the data supplied, and stick to it.
We have to start somewhere, so we’ll go for big-endian, and use the bytes in the order they’re written.
The mention of word length in the tags invites us to decide how many bits at a time we’ll process the data.
It’s written byte-by-byte, so we’ll assume that we need to use the bits conventionally, eight at a time; and it’s divided into 32-bit chunks, so we’ll guess at 32-bit words.
So, what can we make of the data broken up that way?
We know it’s a question, and we’ll guess it’s text, so it looks as though 0x81 just might be a space, and the final 0xFD just might be a question mark.
The “tags” are inviting us to try bit-twiddling, which could refer to things like ADDing and XORing, though that’s a bit more like arithmetic than twiddling.
Also, to convert 0x81 to space, we need 0x81 XOR 0xA1, while to convert 0xFD to 0x3F (question mark), we need 0xFD XOR 0xC2.
Yet the 0x81 bytes are at various offsets in each 32-bit word, as though any XOR key ought to be constant for each byte; in any case, we were invited to consider word length, as though the bit-twiddling would be affected by it.
Maybe we should try operations that work directly on the bits in a word together, like NOT or SHIFT or ROTATE?
Shifting is easy to do in your head because a left shift means multiplying by two and a right shift means dividing by two.
And if you’re thinking on your feet, you’ll notice, if you ignore the remainder when dividing, that 0xFD / 4 = 0x3F (question mark) and 0x81 / 4 = 0x20 (space).
Dividing all the 32-bit numbers by four (a right shift of two) gives:
We’re obviously onto something here, because bytes from 0x41 and 0x5A in the ASCII table represent the characters A to Z.
In fact, we have:
You’ll notice that in line three, where the rightmost byte in the original was 0x0C (a multiple of four), the topmost byte came out looking OK (0x2D, a dash) after the shift.
But where the rightmost bytes were odd, the topmost byte came out less than 0x20, which is in the unprintable part of the ASCII table, even though there are letters which would fit perfectly, e.g. an “I” in the last row to make the word BITS.
So those bottommost bits – the ones we simply dropped off when shifting right – are probably important after all.
Indeed, they are, as the hint we snuck into this week’s 60 Second Security video suggested:
If we rotate right by 2 bits instead of simply shifting, bringing the bottomost bits in each 32-bit word back in at the topmost end, we get:
To which the answer, quite simply, is, “Two.”
For what it’s worth we’d have accepted “Thirty”, because rotating an N-bit word 2 bits right is the same as rotating it (N-2) bits left, but no-one was willing to risk that answer.
Seventeen people solved the puzzle in time:
1. Tim Warriner 2. @alvinnieto 3. @rbaranyi 4. Nick Griffin 5. @kwanre 6. @vanjasvajcer 7. M Rusnak 8. Adremel Philip H. Redondo 9. Phil Rhea 10. Greg Edridge 11. Dave Anderson 12. Jorrit Kronjee 13. Adam Wagner 14. @hackery 15. Melissa R 16. Bob Wilson 17. Martin Lindhe
The fastest, Tim Warriner, wins the first of the five T-shirts outright.
Four of the remaining 16 solvers were chosen to win T-shirts with the help of /dev/random, and they are:
@alvinnieto Phil Rhea @hackery Bob Wilson
Well done to all who worked through to the end; congratulations to the winners; and thanks to everybody who took part.