Making and Breaking Ciphers with Python, er, a Commodore- Part 1: The Reverse Cipher
By Michael Doornbos
- 4 minutes read - 831 wordsSometime during my weeklong exploration of SHA-256 on a Commodore realized that there was a whole world of exploration that could be explored. Just because a Computer system is old, doesn’t mean it’s not interesting or useful.
I had expected it to take months to figure out the SHA-256 implementation, but it only took me a week or so. This was pretty surprising to me and is an excellent demonstration of what might be possible on a Commodore 64
Ciphers are interesting to implement in any programming language and I’ve already tackled some of them on the Commodore. This is the first in a multi part series where I’ll be implementing many ciphers in Commodore Assembly Language. Where appropriate, I’ll intermix some Python code to help visualize things.
My environment for this series
I like developing on vintage hardware, so I’ll be using Turbo Macro Pro on one of my Commodore 64s or my Commodore 128. I have a “The C64” as well and can highly recommend one if you’d like to go that route. Its full-size keyboard gives you the real Commodore experience while having a nice USB and HDMI interface set to make using it a snap. Its video output is nearly perfect so I’ll often use it for screen captures
If you want to get started with Turbo Macro Pro, Robin’s videos are the place to start.
Other Assemblers and Emulators
Turbo Macro Pro has a very simple syntax, so my code should be trivial to port to ACME, KickAssembler, TMPx, or others.
There are several modern emulators that very accurately mimic a Commodore 64. All of what I’m going to present in this series will work just fine in an emulator.
Case
You’ll notice that I use Uppercase letters for these examples. The Commodore 64 can do both uppercase and lowercase, but to keep out a few details on how characters work in Assembly Language I’m going to stick to Uppercase for now. I’ll be switching the Python examples to uppercase strings where relevant as well so that we’re comparing Apples to Apples as much as possible.
The reverse cipher
Finally! After all of that series setup, we’re at the fun part.
Chapter 4 of “Cracking Codes with Python” has our first Cipher and it’s a nice easy one get started with (Like VERY easy).
We’re going to take a string and flip it around backwards. Let’s use:
message = 'ARE YOU KEEPING UP'
The book does a quick loop from back to front to print the result.
translated = ''
i = len(message) - 1
while i >=0:
translated = translated + message[i]
i = i-1
print(translated)
>>> PU GNIPEEK UOY ERA
I like this method for Cipher functions because a lot of what we’re going to be doing is flipping and shifting bits and positions. You could do this same thing with the reverse function or a slice.
"ARE YOU KEEPING UP"[::-1]
>>> PU GNIPEEK UOY ERA
The first method is closest to how we’ll have to implement this on a Commodore, so let’s stick with that example.
Minor Tangent: Why do you keep using that phrase?
You may have noted that I will be using the phrase “ARE YOU KEEPING UP”.
This comes from a pretty silly 80s ad by Commodore. The jingle is “Are you keeping up with the Commodore, because the Commodore is keeping up with you.”
I’m using it because it just makes me happy. Happy is nice.
Commodore Assembly Version
There are several problems with reversing a string in Assembly Language. First is that there are no data types at all in the machine language we’re really using. The Assembler understands rudimentary strings, so that’s a start. We’ll have to use the ASCII representation of this string in a sequence and work on the bytes one at a time. Secondly, there is no built in length function, so we’ll have to make one of those as well.
Hard coded
Later we’ll work on accepting user input to take a string(message) and so work with it, but to follow the book closely we’ll hard code the string in this one.
I added a single byte o to the “beginning” of this string so that we can check for it to be done.
message .byte 0
.text "ARE YOU KEEPING UP"
Skipping the setup section, we just do the same thing we did in the python program.
ldx #18
loop lda message,x
jsr $ffd2 ;prints character
dex
bne loop
Extra Credit
- Write a routine that checks for the length of a string and output it as a hex value. I’ll provide the answer in the next article in the series as it’s something we’ll use often. I use both string length and checksum in my SHA-256 on a Commodore implementation.
- If you’re not an Assembly programmer, can you figure out how to print this in the correct order?
Next week: We tackle the Caesar Cipher
Hint: Many books are available on Archive.org