*** HERE IS THE SOLUTION TO THE PUZZLE *** Let's start with the riddle:
The little end of thirty-two
Shall say where the Omega lies
The Alpha is important too
The message that you seek it hides
To find the path you must reveal
What has been hidden in plain sight
Apart the layers you must peel
And see them in a different light
The first step was to figure out that the alpha channel of the PNG image had data embedded in it, and how it was embedded. In this case, the data was encoded with 1 bit per pixel, subtracted from the normal alpha value. Since the image was otherwise wholly opaque, the alpha value of each pixel was 255 for 0-bits and 254 for 1-bits.
A bit of an issue arose here, because I was not aware that I had unintentionally encoded each byte in little-endian bit order. I used the .NET BitArray class to convert the bytes to bits and back again, not knowing that the methods the class uses for that also reverses the bit order. Because I used this both for encoding the data into the image, and extracting it from the image again, I never noticed that this was even happening until Alaric.us clued me in. This added an extra layer of complexity to the puzzle that I had not intended.
When extracting the data correctly from the PNG, the first 4 bytes were
BC 1A 00 00, followed by a lot of C64 BASIC code as ASCII characters, and ending with a whole bunch of 00 bytes (the unused part of the alpha channel). The 00 bytes are obviously not important. The first 4 bytes we'll get back to.
The C64 code looks like this (most of the data lines have been omitted):
10 rem this is c64 basic just so you know
20 rem make sure to use an emulator that lets you paste code into it
30 rem you really do not want to type all this in by hand
40 rem i used vice so this will work in that
50 s=1024:c=55296:print chr$(147):d=0
60 poke 53280,0:poke 53281,0
70 read a:a=a+d:d=a:if a=256 then goto 110
80 poke c,a:c=c+1
90 read a:a=a+d:d=a
100 poke s,a:s=s+1:goto 70
110 poke 214,20
2140 data 8,149,-151,99,-100,90,-86,181,-184,101,-105,35,-26,214,-214
2150 data 213,-215,159,-163,77,-80,42,-36,153,-149,236,-238,200,-201,156
... (lots and lots of data lines)
3030 data 89,-85,163,-163,178,-182,90,-85,184,-189,72,-71,100,-96,188
3040 data -192,101,-97,189,-193,94,-96,60,-52,223,21
1110 data 6,102,-102,109,-104,213,-222,44,-44,-2,6,108,-103,211
1120 data -212,192,-198,66,-59,215,-221,89,-85,177,-174,231,-235,118
... (lots and lots of data lines)
2120 data -168,103,-97,227,-235,54,-56,35,-25,224,-230,98,-102,34
2130 data -30,111,-109,110,-106,231,-232,220,-223,111,-113,105,145
The first 4 lines are simply code comments. I did not intend this puzzle to require intimate knowledge of C64 BASIC to solve, so I gave as much help up front as I could, to make executing the code as easy as possible.
Basically (pun unintended) what the code does is to draw a picture. It does this by alternating between setting the color of a location on the screen, and drawing a character to that same location, then moving on to the next location. The values of the colors and characters come from the data lines, and are arranged in such a way that adding the next data value to the current one gives the next color or character to be used. This was an (only partially successful) attempt to prevent people from solving the puzzle by analyzing the code rather than executing it.
Upon executing the code on a C64 (or an emulator), the attached image called noomega.png appears. This is an indicator that the user has not solved the first two lines of the riddle, and must do so in order to progress.
In order to get the No Omega image to display, I utilized the fact that in C64 BASIC, lines are numbered. As such, it does not matter which order lines are entered in, they will always be executed in the order they are numbered.
Looking at the middle quoted bit of the C64 code, you'll notice that the line numbers suddenly jump backwards. The data lines from 1110 to 2130 contain the data for the No Omega image. The data for the image containing the game code are in lines 2140 to 3040. The data is organized in such a way that the final data point of each section results in a value of 255, which causes the program to terminate. This means that even though the data for the real image is present in the code, it will never be executed because the program will stop after printing the No Omega image to the screen.
Unfortunately, this method also provided a way to bypass solving the first two lines of the riddle, if you noticed the jump in the line numbers, and simply removed lines 1110 to 2130 from the code.
The way I
intended this to be solved is as follows. Remember those 4 bytes that came before the C64 code in the embedded data? BC 1A 00 00? 4 bytes = 32 bits. It's a 32bit integer in little-endian byte order. "The little end of thirty-two". So, 1ABC = 6844. "Shall say where the Omega lies". The meaning of Alpha in the riddle is obviously the alpha channel, but when mentioning Alpha and Omega
together, they take on the meaning of "the beginning and the end". As such, in this context, the 6844 is supposed to tell you where the end of something is. If you take the first 6844 bytes of the C64 code, you will get everything up to and including line 3040, cutting off lines 1110 to 2130.
However you solve that bit, the new image you get looks like the attached image called finalscreen.png.
Two of the four 5-hex-digit groups are fairly obvious to spot. They are drawn using the special graphical characters in the PETSCII character set used on the C64. Indicentally, this also made solving the puzzle by analyzing the C64 code a difficult proposition, since the PETSCII character set does not exist on any other platforms.
The last two groups proved a lot more difficult for a lot of people than I had anticipated. They are color-coded as white into the image in the same parts as the drawn characters. They are very hard to discern precisely by the naked eye due to the randomness of the drawn characters, but map them out onto checkered paper, and they are very easy to recognize. I did try to make them easier to spot by removing the brightest of the C64 colors from the list of colors used to randomize the background, thus making the contrast to the white characters greater.
Having found all four groups of hex characters, all that remained was to determine the order they belonged in. Considering the drawn characters as the front layer (easiest to see), and the white characters as the back layer (hardest to see), the sequence is top-front, top-back, bottom-front, bottom-back.
The game code, and the final solution, is:
56265-F5EF7-5E45E-963E8 I hope you enjoyed this puzzle. I certainly enjoyed making it, and sharing it with you all :-)
Feel free to discuss it now.