Introduction: Kid's Game to Arduino Enigma Machine

The technology behind Enigma machines and the work done to crack them has influenced cryptography, cryptanalysis, and computer science in general.  If you're unfamiliar with Enigma machines, it's a device that was developed near the end of World War I, then used extensively by the Nazi regime in World War II, to encrypt messages.  The allies (the British in particular) worked tirelessly to break the code.  One of the father's of modern computer science Alan Turing (of Turing Machine fame) worked on the British team that worked break the code.  Some estimate that because the allies were able to crack the code the war ended two years earlier than it would have otherwise.

One thing to note, the Enigma's encryption algorithm is pretty good, but not perfect.  One weakness is that a letter can never be encrypted as itself which eliminates at least on character and can make it easier to crack.  Most of the issues the Nazi's had that made it crackable had to do with their processes as they used the machine.  Key exchange is hard in a system like this where you don't really have an out of band method to exchange keys.

If you want a detailed description of how Enigma machines work check out the Wikipedia article( http://en.wikipedia.org/wiki/Enigma_machine  ), or the many other articles on the internet, I'll just give a quick overview here.

The Enigma machine basically consisted of three or more rotors that had contacts on both sides.  The rotors are set to the encryption or decryption "key" then a button is pushed which goes through the wiring in the rotors, then lights up a lamp corresponding to the encrypted output (there's a lamp for every letter in the alphabet).  To decrypt you simply start with the same key that was used to encrypt the data and type in the cipher text.  One thing significant about the Enigma machine is that the rotors rotate as each key is pressed, so the encryption key essentially changes with each character.

I was in a thrift store recently and saw a game with a screen and a keyboard and I thought, that would make a good Enigma machine (I've always wanted one, but I know my wife would kill me if I bought a real one $$$).  In this instructable I'll show how I gutted an kids game and used an Arduino to hook up to the keypad and speaker.  The code's not too bad (so far).  This version is a simple three rotor Enigma machine.  You can switch the rotors around and change the letters for the rotors.  Future plans are to all for more rotors, allow changing out the reflector, allow for spinning the ring around a rotor, and a plug board implementation.  This Enigma machine will be able to encode and decode messages to and from the real, old Enigma machines used during Wold War II.



Note: The image for this page is from the Wikipedia article on Enigma Machines

Step 1: Parts and Tools

Parts
1. A kid's game with a keyboard and a screen (I chose the Fisher Price game in the picture, got it at a local thrift store)
2. An Arduino (I used an Arduino Pro from Sparkfun).
3. Maybe a screen (you may be able to patch into the screen that comes with the game).

Tools
1. Mulitmeter
2. Soldering Iron
3. Maybe a Dremel type tool if you're replacing the screen or doing other mods to the case



Step 2: Open It Up

First, grab the game, remove the screws and open it up.  After I did that I had to remove a few more screws to get to the keyboard.  I cut the wires that connected the keyboard to the other PCB inside the game.

Step 3: Figure Out the Keyboard

I pulled the rubber buttons off the keypad PCB so I could figure out how it was all wired up. To figure out how it's wired up a used a multimeter on the Ohm meter setting to test for continuity. I put one lead on the row of pins on the cable the came off the keyboard to the "brains" of the game, and the other on the bare metal on the button circuit board for each button. I just used a sheet of paper to keep track of what button went to what pins.



That's all there is to it

Step 4:

At this point it was apparent what pins on the cables coming out of the board were the columns and rows of the keyboard matrix. I used this keypad library http://www.arduino.cc/playground/Main/KeypadTutorial on my Arduino to control the keypad. In my case it was a 5x8 keypad, so I need 13 pins. I ended up using Digital pins 2 and 4-13 and Analog pins 0 and 1. I didn't use Digital pin 3 because I wanted that for driving the speaker in the game.

I kind of cheated when I mapped the key values. I basically just put bogus unique characters in the 2 dimensional array that defines the keys then I just started pushing buttons and had my Arduino output the keys pushed to serial. Then I could look at the output to set the 2 dimensional array for the library to the right values.

That seemed kind of confusing so I'll do an example. As part of the keypad library you define a 2 dimensional array so it knows what keys correspond to the values on the matrix. So basically it's something like this:

char keys[ROWS][COLS] = {
{'<','>','+',' ','5','4','3','2'},
{'^','*','%','#','6','1','Z','Y'},
{'X','W','V','U','T','S','R','Q'},
{'P','O','N','M','L','K','J','I'},
{'H','G','F','E','D','C','B','A'}
};

I'd then push a button on the keypad ('A' for example). Then I'd look at what came out on the serial console (say it was 'W', then I'd go and replace the 'W' in the matrix with an 'A'). After I went through all the keys then I had the keypad all mapped up.

Step 5: Modding the Case

My next step was modifying the case of the game.  I had to do a couple of things.  First I wanted to put a different screen in that was a little bigger, so I had to cut part of the case off.  There was also a handle in the back that made it hard to fit everything in.  I just traced out what I needed to cut and used a Dremel tool with a cutting disk to cut the case.

The pictures show the window before the mod, then with my new screen in it.  I used an I2C/Serial LCD from web4robot.

Step 6: Hooking Up the Keyboard and Screen to the Arduino

Now I needed to wire stuff up.  I used a female header on the Arduino and soldered wires right onto the pins.  You could also create a shield and solder onto that as well (in fact that's probably a better way to do it, but this works for me).  Solder HO!

After that I screwed the keypad back onto the case so it wouldn't fall off when I turned it over.

Step 7: The Code:Overview

The meat of the code is pretty simple.  I have an array for each rotor type, then I just needed to keep track of what rotor was in what slot, and what position the rotor was currently in.  Probably the easiest way to figure out what the code needs to do is to go through the example of this paper enigma machine.  http://mckoss.com/Crypto/Paper%20Enigma.pdf  .  Basically we need to take the input index, look at what letter is in that spot, then figure out what slot that should map to (it's basically the where the letter ends up in a char array of the alphabet and the offset of the rotor).

The code also needs to handle the rotors moving.  The right most rotor moves one spot every time a key is pushed.  The middle rotor moves when the right most rotor hits a certain value (so it will turn 1/26 of the times the right one turns).  The left rotor turns 1/26 of the times the center rotor turns.  To do this I have an int that keeps track of the current position of the rotor and I add one to it when they need to turn.  When they get to 26 I set them back to 0 (it went all the way around the rotor so we're starting again).

To swap out rotors I simply strncpy the rotor constants to the rotor in for the position.

You'll notice I used a lot of example code in my code to do things like play tones, get keypad values, and address the I2C LCD.  I'm a big fan of libraries and example code.

Step 8: The Code: Rotors

This is a more detailed description of the rotors in the program.  Basically I defined the rotors like this:

const char rI[26] = {'E',
'K',
'M',
'F',
'L',
'G',
'D',
'Q',
'V',
'Z',
'N',
'T',
'O',
'W',
'Y',
'H',
'X',
'U',
'S',
'P',
'A',
'I',
'B',
'R',
'C',
'J'};

const char rII[26] = {'A',
'J',
'D',
'K',
'S',
'I',
'R',
'U',
'X',
'B',
'L',
'H',
'W',
'T',
'M',
'C',
'Q',
'G',
'Z',
'N',
'P',
'Y',
'F',
'V',
'O',
'E'};

char rIII[26] = {'B',
'D',
'F',
'H',
'J',
'L',
'C',
'P',
'R',
'T',
'X',
'V',
'Z',
'N',
'Y',
'E',
'I',
'W',
'G',
'A',
'K',
'M',
'U',
'S',
'Q',
'O'};

You may ask "Why not just define them as a string, this seems like longhand".  In other words why not do it like this:

char rotI[26] = "'EKMFLGDQVZNTOWYHXUSPAIBRCJ"

I'll admit this makes for much longer code, but to me it makes more sense visually to see it down (I can't think of a time I've ever done this before, but with this one I think it works).  Basically since these are rotors (and I was copying the values off a paper Enigma machine) then that's the way I chose to do it.

In addition to defining the reflectors I defined what number each rotor should turn the next rotor on.  In other words, when RI is in position 17, then the rotor to the left should turn.

const int spinRI = 17;
const int spinRII = 5;
const int spinRIII = 22;

Because the rotors can be put in any of the three slots you see in the screen I copy the constant spin values into ints that change anytime a different rotor is put in a slot (r1 is the left most rotor, r2 is the center rotor, r3 is the right most rotor).

int spin_r1 = spinRI;
int spin_r2 = spinRII;
int spin_r3 = spinRIII;

The following variables keep track of what rotor is in what slot.  This is used so you know when you change rotors in a slot what rotor next one will be

int cur_r1 = 1;
int cur_r2 = 2;
int cur_r3 = 3;

I also define the reflector.  Basically what this is saying is if an input comes in at position 3, then it should go back out position 7 for example (since the value in position 3 is 7).  The reflector basically sends the signal back through the rotors in reverse order

int reflector[26] = {24,
17,
20,
7,
16,
18,
11,
3,
15,
23,
13,
6,
14,
10,
12,
8,
4,
1,
5,
25,
2,
22,
21,
9,
0,
19};

These are placeholders for the current rotor array in positions 1, 2, and 3 on the screen
char rotor1[26];
char rotor2[26];
char rotor3[26];

Note: The image in this step is from Wikipedia

Step 9: The Code: Encryption

The first thing we do is spin the right most rotor, and spin the others if we need to (depending on the spin values we defined earlier)

pos_rotor3 += 1;
if(pos_rotor3 > 25)
{
pos_rotor3 = 0;
}

if(pos_rotor3 == spin_r3)
{
pos_rotor2 += 1;
if(pos_rotor2 > 25)
{
pos_rotor2 = 0;
}
if(pos_rotor2 == spin_r2)
{
pos_rotor1 += 1;
if(pos_rotor1 > 25)
{
pos_rotor1 = 0;
}
}
}

This function is basically where all the magic happens.  A value is input in addition to the rotor values and the offset the rotor is currently on.  It ouputs the letter that would come out of that one rotor.

This is really not a lot more than a simple character subsitution.  A real Enigma machine did this with wires inside a rotor.  We do this multiple times, one for each rotor going forward, then we send it through the reflector, then back through the rotors.

int get_rotor_output(int index, char rot[], char rotIndex[], int pos_rot)
{

//first thing we need to do is add the rotor position to the index to figure
//out what letter we're really on
index += pos_rot;

//If the index is more than 25 then we've wrapped around the end of the array
//so we'll subtract 26 from it to get to the real character
if(index > 25)
{
index -= 26;
}

//now we figure out the index of the letter in the alphabet
// i.e. A = 0, B = 1, C = 2, etc.
//then we grab the letter in the same position in the rotor array
//this is how we do the character substitution
char tmp_letter = rot[find_index(rotIndex, alpha[index])];

//now we get the index of the letter that was ouput in the alphabet
//same idea as above  A= 0, B =1., etc
index = find_index(alpha, tmp_letter);

//Now we subtract the rotor position from the index that was output
index -= pos_rot;

//if the index is less than 0, then we've wrapped off the beginning
//of the array, so we'll add 26 to it to get back in the array
if(index < 0)
{
index += 26;
}

//now let's return the index
return index;
}

Note: The image in this step is from Wikipedia

Step 10: Use It!

To use it simply set the key, then type in a message.  To decrypt it set the key to the same thing you stared with and type in the cipher text and you'll get the clear text as output.  It's that easy.

References
http://startpad.googlecode.com/hg/labs/js/enigma/enigma-sim.html

http://mckoss.com/Crypto/Paper%20Enigma.pdf

http://en.wikipedia.org/wiki/Enigma_machine

Microcontroller Contest

Second Prize in the
Microcontroller Contest

3rd Epilog Challenge

Participated in the
3rd Epilog Challenge