Introduction: Enigma Z30 Machine Simulator for Kim UNO, an Arduino Based KIM 1 Simulator

About: Get your own enigma machine simulator or use the enigma engine source code provided to create your own.

A numbers only Enigma Z30 Machine program is created for the Kim-Uno programmable calculator. The Kim Uno is a very basic development platform. It it capable of displaying 6 hexadecimal numbers. It also has a 24 button hexadecimal keyboard with some additional control keys. The Enigma Z30 is a very rare encryption device. Not many articles describing this machine exists.

To make your own:

  1. Make or buy a KIM Uno
  2. Follow the instructions on the image listed above to enter the program into your KIM Uno.

Step 1: Background Information

The Kim Uno was feeling lonely when all of a sudden a new Hackaday.IO challenge came out, create a program in less than 1kB of code. Most of the enigma machine simulators out there use LED displays and buttons mounted in a PCB. I wanted to create my own without rolling out a custom PCB. Thus the idea was born to write a program to simulate an Enigma Machine in 6502 assembly language.

The Kim Uno has a hexadecimal keyboard and 8 control keys. On top, it has a cluster of 7 segment displays where 6 numbers can be displayed, 4 on the left and 2 on the right. This is not enough for a regular enigma machine which encrypts letters A through Z. Fortunately, a very rare numbers only model, called the Enigma Z30 exists.

Enough information was published by Anders Wik to make this reconstruction attempt possible.

"Enigma Z30 retrieved", Anders Wik, Cryptologia Vol. 40 , Iss. 3,2016

The Z30 machine has 4 settable rotors that show the numbers 0 thru 9 one at a time through a window, a keyboard with 10 keys numbered 0..9 and 10 lamps above the keys.

When a key is pushed, the rotors are first advanced, then electricity is sent through the rotor maze and it comes out to illuminate a lamp. The keys are wired to a stationary set of contacts on the right which send electricity in through the right contacts of the rotor and out through its left side contacts into the next rotor.

The leftmost rotor is a reflector, it receives a signal on the right and returns it through another pin on the right. This sends electricity back through a different path through the rotors and out to the lamps.

Each rotor, including the reflector has a ring setting that controls the stepping position for that rotor. When set at 1, a rotor at the 9 position will increment the rotor to its left when the next key is pressed. The rotor on the right always moves one step. This results in the sequences: 0088 0089 0090 0101 0102 and 8888 8889 8890 8901 9002 9003 and is known as the double stepping anomaly.

A key will never encrypt to itself. To decrypt the numbers, the machine is re-set to the same starting position and the encrypted sequence typed. The decrypted numbers will be illuminated in the lamp field.

To use the Kim Uno Enigma Z30 machine, enter and execute the program. The rotors will be shown on the left and 00 on the right. Since 0 can never encrypt to 0, this was chosen to represent the machine is ready to encrypt. To encrypt a number, press a 0..9 key. The rotors will be advanced and the key encrypted. The key and its encrypted result will be shown for 1 second on the right two digits and the screen will then return to 00. On a normal enigma machine, the lamps will be lit for as long as the key is pressed. I did not find a way to read that the key is still pressed, so the result is cleared after one second or if another key is pressed.

The top row of keys start and stop a running program. Those cannot be read within a running program.

The next two rows below that have 4 keys each and are used to move the rotors up and down one step.

The remaining keys, 0..9 when pressed, are encrypted. Keys [A] [B] and [GO] are not used.

The default machine settings, Rotor Types 1,2,3, Ring settings 1,1,1,1 and Starting position 4,3,2,1 are copied to memory location 0050 where they can be examined and changed to encrypt. The left rotor is always a reflector, so its type cannot be set.

The basic program uses 460 bytes of code including the rotor substitution and default value tables. It uses the KIM 1 GETKEY and SCANS routines at $1F6A and $1F1F. Those routines and their dependencies add 150 bytes of code for a total of 610 bytes of our own code and dependencies as per the contest rules. The KIM-1 monitor is an unavoidable bootloader that is necessary to enter the program and get it running.

A full featured user interface was written that allows the user to change the machine settings on the fly without exiting to the KIM-1 monitor. While on the main screen (00 on the right 2 digits), push the [B] button and the 2 right digits change to F1. The values shown on the rotors are now the rotor types. The usual up/down keys can be used to change them. The reflector cannot be changed and is shown as 0. To accept the rotor type settings, push [B] again. If the rotor types do not use the values 1,2,3 in any order exactly once, EE is shown on the 2 right digits. Once the rotors are correctly set, pushing [B] changes the 2 right digits to F2. The ring settings can now be changed. There are no restriction on the ring settings, repeats are fine. Pushing [B] again exits to the main screen and the machine is ready to encrypt with the current settings. While in F1 or F2 mode, pushing the numeric keys has no effect. If the [GO] key is pushed in any of the three screens, the current settings are zeroized back to the default values (1,2,3,1,1,1,1,4,3,2,1). The use of the [GO] key can be enabled/disabled in each of the screens independently by changing the jump address. For example, it can be disabled in the main screen, but enabled in the F1 or F2 screen in order to prevent accidental activation. The [A] button is still unused, it can be easily be changed to jump to F2 directly. If this is changed, the setup code can also be changed to return to the main screen after F1.

If the code to change the machine settings is added, the program grows to 703 bytes. Adding 150 bytes for the Kim-1 ROM keyboard and display routines brings the total to 853 bytes. We are still well below the 1kB limit and we can now change the machine settings at any time without exiting to the KIM-1 monitor.

Step 2: User Interface Design

The KIM Uno is capable of displaying 4 hexadecimal digits on the left and two hexadecimal digits on the right. Below it has a hexadecimal keyboard as well as 8 control keys.

This got me thinking. The four digits can represent rotors in an encrypting machine and the two digits on the right can represent the input number and the encrypted version.

The keys below the display can be used to move the rotors. The first row of keys [GO] [ST] [RS] [SST] cannot be used because the ST and RS keys stop a running program and resets the CPU respectively.

The [AD] [DA] [PC] [+] keys have no effect on a running program and can be read. The same situation applies to the row below [C] [D] [E] [F}.

So, we will use [AD]/[C] to increment/decrement the leftmost rotor value. [DA]/[D], [PC]/[E] and [+]/[F] to alter the remaining rotors. Pressing a 0..9 key will encrypt it and [A] and [B] will be unused for the moment.

Step 3: Reading Keys / Entering a Program on the KIM Uno.

Let's start by describing how to enter and run a program in the KIM Uno. When you first turn it on, the KIM monitor will run and it will display 0000 00. The monitor will let you examine memory, enter values into memory, run a program and single step a program. The contents of CPU registers and flags can be viewed by accessing special memory locations.

Upon power up, the group of 4 digits on the left is the memory location, the group of 2 digits on the right is the value stored at that address. A key pressed will be interpreted as an address or a value depending on which mode the Kim monitor is on. On power up, reset and stop, the monitor goes into Address mode and keys pressed change the memory location field. To change to data mode, press the [DA] key. A value keyed in will be written to memory. To go back to address mode, press the [AD] key.

An address is entered by keying it with the 0..9 and A..F keys. The address will be shifted left one digit at a time and the memory content field will be updated in real time. To see memory location 200, type 0200. Once all four numbers are keyed, you should see A5 on the right. If you forget to key in the first zero, and another address is shown, just type 0200 again.

If you have my clock program, type [AD]0400 and F8 will appear. Some other values will appear on the right as you type 0400.

The listing below shows a program that will read a key and display its value. The first line specifies the starting memory location. The middle column includes labels and program instructions. The numbers on the right are the opcodes for the program.

This program will call the routines at $1F1F, which displays the values of memory locations $FB $FA on the left 4 digits and $F9 on the right two digits. If the program writes 12 34 56 to $FB, $FA, $F9, the display will show 1234 56.

The next routine called is $1F6A, which reads a key and returns it in the A register. If A is 15 or greater, no key was read. The program stays in a loop defined by the label start, $1F1F is called repeatedly to keep the display alive, otherwise it will be turned off and no digits will be shown at all.

To enter the following program, we will go into address mode and select the starting location, then switch over to data mode and key in the program starting the 20, the first and second lines show the starting location and a symbol called THIRD, those do not result in opcodes, the first program line is JSR $1F1F, which is compiled to 20 1F 1F.

To accept one byte and move to the next, press the [+] key. If a mistake is made while entering a memory content, just retype it and press [+] when correct. For example, if we want to enter 20, but 21 was keyed in instead, just type 20 again and then press [+]

To enter the program below, key in [AD]100[DA]20+1F+1F+20+6A+1F+C9+ .... B0+F1+

To check your work, press [AD]0100 and repeatedly press the [+] key, The numbers on the right will show in order 20, 1F, 1F, 20 ...

You don't need to enter the whole program in one shot. You can stop at any time, change to address mode, examine memory locations with the [+] key and when you reach an empty memory location, press [DA] and continue entering the program. I like the listing view because it having the addresses on the left helps keep you on track as you enter the program, when entering the program for the first time, after 20+6A+1F, the Kim Uno will show 0106 on the left and you will know that it is the right place to keep typing C9+

* = $0100
0100 THIRD = 00F9
0100 START
0100 JSR $1F1F 20 1F 1F
0103 JSR $1F6A 20 6A 1F
0106 CMP #$15 C9 15
0108 BCS START B0 F6
010A STA *THIRD 85 F9
010C SEC 38

This program uses a small trick that allows it to run in any memory location. Conditional jumps like BCS are always relative. The last instruction at 010D to jump back to start is not a JMP START, which will compile to 4C 00 01 and specifies an absolute memory location of 0100 (represented backwards as 00 01). Instead, the jump used was a conditional jump BCS (branch if carry set), which uses a relative number of bytes to jump back. To force the jump to always happen, the carry is set with the SEC (set carry) instruction.

To execute this program, press [AD]0100[GO]

Start with the bottom row and press either 0, 1, 2 or 3.

The same value will be shown in the display.

This will continue until you read C,D,E and F. The AD, DA, PC, + row will also show values. On the top row, only [GO] reads a value of 13 (hexadecimal). If you press ST, RS, or SST, the program stops and the screen may blank out. To get a display back press [ST].

To go back into the program, type [AD]0100[GO] and try typing a number. If the number key changes the address field instead of being shown on the left, you are in Single Step mode, press the [SST] key once and the screen will blink. Then press [AD]0100[GO] again and try pressing a number key. It should be shown on the rightmost digits.

To stop the program and go back to monitor mode, press the [ST] key. This program was entered in RAM, powering off the KIM will delete it.

To have it permanently available, it must be entered in EEPROM, addresses 0400 thru 07FF. The clock program is stored from 0400 to 0434. You can use 0450 as a starting location for the test program above. To enter it in EEPROM, type [AD]0450[DA]. Blank EEPROM shows up as FF. You will notice that as you type 20, the display blinks and FF is unchanged. This is because read only mode is enabled.

To remove write protection from EEPROM, press and hold the [RS] key for about a second until the display blinks, then press [DA]20 and it will let you write 20 to EEPROM. Pressing the [RS] key drops you back yo address mode. If you do not press [DA] to go back to data mode, you will find yourself changing the memory address instead of the memory value. Simply press [AD]450[DA] to go back to the starting memory location for the program.

To restore the write protection, press and hold [RS] again for about a second until the display blinks again.

And that is a practical primer on using the KIM Uno monitor to examine, change memory and execute a program. Below are the key values returned when each key is pressed. The ST, RS and SST key cannot be read by code.

13 xx xx xx
10 11 14 12
0C 0D 0E 0F
08 09 0A 0B
04 05 06 07
00 01 02 03

For further reference, see:

The assembler I am using is:

Step 4: Encrypting a Message

To create an actual encrypted message, start by reading the key table for today.

 |Tag |  Walzenlage  |   Ringstellung  |   Kenngruppen   |
 | 18 | 2    3    1  |  3   8   7   1  | 537 183 547 654 |

The first column is the day of the month. The second column sets the rotor types and order. The next column is the ring setting values. Finally on the last column there are some indicator values to embed in the message to indicate the key used. To set the machine with this values. Type [AD] 0050 [DA] 02+03+01+03+08+07+01

Then execute the enigma program by typing [AD] 0500 [GO] Select a random message starting position 8497 and select a random message key 8351. Set the wheels to 8497 and encrypt 8351

The random message key of 8351 encrypts to 7800. Set the Rotor Visible wheels to 7800. The use of a random starting position and random message key ensures messages with the same clear text encrypt to different cyphertexts. Encrypt the rest of the message

Now we put everything together. The random message starting position and the random message key are listed on the first line. The next line starts with a message indicator of 5475. The first three numbers must match any of the groups listed on the last column. This assures the recipient that the correct key is used. A random number was added to 547 to pad it to a group of 4 characters. Then, include the rest of the message.

8497 8351
5475 9451 6340 5542 2888 4592 

Before this sequence of numbers is given to the radio operator to send over the air, you may want to add a header indicating how many groups of 4 characters are in this message and a message sequence number.

To decrypt a received message. Confirm the correct key by matching the first group of numbers in the second row to one of the possible message indicators for the day. Set the machine rotor wheel types and ring settings. Move the rotors to the first group of numbers. Type the second group of numbers to get the message key. Move the rotors to the message key and start decrypting from the second group of numbers in the second row.

Now that you have the theory behind encrypting messages with the Enigma Z30 machine, head over to and give this message a go.

Step 5: Arduino Uno Implementation

Now that the Excel Paper Model and the KIM Uno version are working and producing the same results, here is a third implementation to make experimenting with this machine more accessible to everybody,

To use it, open a Serial Monitor. Send ! and and any combination of 1,2,3 to set the wheel type and their position.

Send @ and four numbers to set the ring settings

Send # and four numbers to set the visible wheel position.

The set commands can be concatenated to set the whole key at once. After !,@ or # receive the required digits, the current key will be shown.

Send a number and it will be encrypted with the current machine settings.

For example:

1111 encrypts it with the current machine settings

!312 sets the wheels to 3,1,2

@1111 sets the ring settings to 1111

#6789 sets the wheel positions to 6789

!312@1111#6789 sets the whole key.

1111 encrypts it with the key set on the step before.

$ prints the current key, will print 03+01+02+01+01+01+01+06+07+08+09 the sequence to enter in the KIM Uno at address 0050 to configure the machine

Step 6: Additional Code to Set the Key Without Using the KIM Monitor

Some new code was added to be able to change the machine settings without exiting to the KIM-1 monitor. From within the main screen (00 on the right two digits), push the [B] button and the screen will show 0123 F1. The numbers on the left are the rotor types. There is only one reflector type, so a 0 is shown in its place. The up/down buttons used to change the rotors in the normal view can be used to change the rotor types. To accept the new rotor types, push [B] again. If an invalid rotor combination is selected, EE is shown on the two right digit.

Once any combination of 1,2,3 is entered, pushing [B] again will take us to the ring setting screen. The screen will initially show 1111 F2. The numbers on the left are the ring settings for the reflector and the 3 rotors. Again, the up/down buttons can be used to change the settings to any value between 0000 and 9999. Pushing [B] again returns to the main screen (00) and the machine is now ready to encrypt numbers with the current settings.

While on the F1 or F2 screens, the machine will not accept a numeric input to encrypt. Pushing [GO] in any of the 3 screens will zeroise the encryption key to its default value of 1,2,3,1,1,1,1,4,3,2,1 This use of the [GO] button can be disabled in either screen independently by changing the location of a jump in the code.

The new program size is 703 bytes. Counting the bytes for the Kim-1 ROM keyboard and display routines adds 150 bytes for a total of 853 bytes. We can now fully configure the machine from within the program. The only time the KIM-1 monitor is needed is to launch the program by typing [AD] 0500 [GO]

Step 7: Demonstration Video

Enigma Z30 Machine Demo

Shows operating and setting the machine key with the built in setup mode. Assumes the program is already loaded. To start the program, from the KIM Uno monitor press [AD] 0500 [GO]

In the main screen, the rotor values are shown and can be changed with the up/down keys under each rotor. Pressing a key encrypts it. From the main screen pushing [B] goes into settings menu. The rotor types can now be set in option F1, if the rotors 1,2,3 are not used exactly once, pushing B to go to the next menu shows instead EE. The ring settings can be set in option F2. Pushing [GO] in any screen zeroises the settings to the default key.

The video shows:

The display changes to 4321, the default rotor values when the program starts. The two digits on the right show 00. When a key is pressed it will be shown on the left digit and the output on the right digit. This is an enigma machine, a number can never encrypt to itself, 00 which means the machine is ready to encode.

The rotors are then changed by pressing the up/down keys below each rotor. Pressing up on 9 changes the rotor to 0. Pressing down on 0, changes the rotor to 9. The rotors are set to 8888 to show how the 9 propagates all the way to the left due to the double stepping anomaly.

The number 6 is repeatedly encoded. The encrypted output is shown in the rightmost digit. Notice the display never shows 66. The last presed key and its encrypted output will be shown on the screen for 1 second and then cleared automatically. If a rotor is changed with the up/down buttons, it will be cleared as well.

Pushing the [A] button does nothing except to clear the last input key and encrypted output.

The [B] button enters the rotor setup routine. The mode indicator changes from 00 to F1 to F2 and back to 00. The left 4 digits change the last rotor values to 0123 on F1 and 1111 on F2. Those are the default rotor types and ring settings. Pushing [GO] in mode 00 clears the machine key to the default values. The rotors return to 4321

The [B] button is pushed again and the mode changes to F1. The rotor types are shown to be 0123. The 0 in the left is the reflector, which cannot be changed. Pressing the up/down keys below the rotors changes their type. To accept the new values, push the [B] button again. If any rotor is used twice (313), error EE is shown. When all rotors are used exactly once in any combination, pushing [B] changes the mode to F2.

The display changes to 1111 F2. Those are the default ring settings for the rotors. Those can be changed with the up/down buttons to any value from 0 to 9. Pushing [B] again returns to the main screen (mode 00). Pushing [B] again shows the current rotor types in the F1 screen and the ring settings on the F2 screen.

Pressing a [0]..[9] key in mode F1 or F2 has no effect. The machine will not encrypt until returned to the 00 screen.

The value 6666 is encrypted with a custom key, it encodes to 2152. The rotors advance with each key press and end in 4325.

The [B] button is pressed and the machine changes to F1. The rotor types are shown. Pressing [GO] in this screen zeroises the encryption key to its default value and returns the machine to the main screen, mode 00. Pressing [B] again shows that the rotor types and ring settings have been returned to their default values of 0123 and 1111 in the F1 and F2 screens.

The [B] button is pressed until the mode changes to F2. The up and down keys are used to change the ring settings. [B] is pushed repeatedly until we return to F2. Pushing [GO] in this mode also clears the key and returns to the 00 screen

The value 66 now encrypts to 79, instead of 21 as before. This shows the inner machine settings also affect the output. No key is pressed for a second and the output is automatically cleared back to 00.

#enigmamachine #enigma #Z30 #simulator #hackaday #hackadayio #1kBChallenge #Kim #UNO #Kim1 #KimUno #clone #Arduino #CPU #emulator #crypto #sigaba #fialka #setecastronomy #retro #retrocomputing #opensource #FOSS #mystery6502program #kimunoprogram #enigmaz #enigmaz30 #bletchleypark #miltonkeynes

Arduino Contest 2016

Participated in the
Arduino Contest 2016