The Enigma Machine consisted of a wooden cabinet enclosing a typewriter keyboard and a set of 26 lamps (one for each letter of the alphabet). At the top of the machine was a slot into which three wheels or rotors could be fitted onto a shaft.
The rotors were furnished with electrical contacts and buried inside were wires that connected the contacts on one side to those on the other in a scrambled order. The cabinet contained a battery, and when a key was pressed, electric current would flow from the keyboard through each of the three rotors in turn, through a reflector, then back through the rotors, and finally through one of the lamps making it light up.
A number of different rotors were available (8 in this case) and the operator would choose which rotors to use and the order in which to use them. The operator could also select which reflector to use (2 were available).
The rotors had adjustable rings which could be turned with respect to the inner core. The ring for each rotor could be set by the operator in any one of 26 possible positions (A to Z).
The initial positions of the rotors could also be set by the operator according to which letters on their rims showed through a window in the machine.
On the front of the cabinet was the plug board which consisted of a set of 26 sockets into which wires with plugs at both ends could be inserted. Its effect was an additional swapping of pairs of letters and hence added a further level of scrambling to the encryption process.
The cumulative effect of rotating rotors, rings, reflector and plugs meant that the number of possible different configurations of the machine was absolutely enormous. It was considered therefore to be a very secure method of encrypting messages (it was thought unbreakable in fact though this proved not to be the case).
As each key on the keyboard was pressed one of the lamps would light up (obviously not the same letter that had been pressed). It was the operator's job to write down which lamps lit up.
As keys were pressed the rotors would also rotate. This meant that the same letter of the alphabet would be encoded to a different letter each time it was used in a message. (If this weren't the case it would have been almost trivial to crack an Enigma message.) Effectively each letter in a message was encoded using its own unique code. It was this fact that made the Enigma so difficult to defeat. It took some of the best mathematical brains in Europe to beat it and doing so was the spur that led to the development of modern electronic computers.
The reciprocal nature of the design meant that if the letter A were encoded into, for example, a B at some point in a message, then a B would be encoded into an A at the same point. Consequently encoding and decoding were the same process, they were reversible. If encoded 'ciphertext' were passed through the machine again the result would be the original message or 'plaintext' (provided of course that the machine was set up in the same way).
One further consequence of the design was that a letter would never encode to itself. This proved to be the Enigma's Achilles' Heel.
The design
This is a re-working of an earlier design that used a 5x7 dot matrix display to show the encrypted and decrypted letters. That design employed a PS/2 keyboard for character entry. At the time PS/2 keyboards were still quite common with most PC owners having one at the back of a cupboard. Nowadays they are rare having been universally replaced by USB keyboards. So it was time for an upgrade.
The PS/2 keyboard protocol is much simpler than the USB keyboard protocol and can easily be handled by an 8-bit microcontroller in software. USB however really needs hardware support.
Technology moves on and small LCD displays are now very affordable (especially when ordered from AliExpress). The particular display used had a resolution of 240 x 240 pixels with 16-bit colour and an SPI interface.
For choice of processor a RP2040 was settled on in the form of a Raspberry Pi Pico. Picos are cheap, widely available with well-documented and comprehensive libraries. The RP2040 supports USB in hardware, both host and device. This application requires USB host which is thankfully supported by the TinyUSB library in the Pico SDK.
The other reason for using a Pico was its memory capacity, specifically 2MB of on-board quad SPI flash. That’s plenty of room for graphical assets. At a resolution of 240 x 240 pixels and 16 bits per pixel an image needs about 120kB so there is enough for 16 images in flash. That’s not enough for a full alphabet if each letter has its own image file, but storing images at 120 x 120 instead quadruples the number of images that can be stored with only a small loss of quality (with a very small display).
Enough flash memory remained for a splash screen and the Enigma logo.
Importing the graphical assets required a little additional work in writing a small program to load and parse a BMP file then export it as a C-style array of literals. The BMP file format is simple to parse as it contains uncompressed pixel data and most graphical programs support the format. The resulting C file is then simply included in the CMakeLists.txt input to the Make system.
A font was needed for the menus and text prompts. The font used was 8 x 8 pixels but a character at that size on a 1” x 1” display was too small to be easily legible. Firmware routines were written to draw characters at double and treble width which were far more readable.
The RP2040 contains a pair of Cortex M0+ Arm cores. That’s far more processing power than is needed to implement the Enigma coding algorithms. The first generation of this design, as mentioned earlier, used an 8-bit processor and that was perfectly adequate to execute the algorithms.
The RP2040 is clocked at 133MHz which allowed the SPI for the display to be run fast.
The Raspberry Pi Pico has a USB socket but it’s a micro USB socket and most USB keyboards have a Type A plug. Micro to full-size adapter cables are available but that wouldn’t be an elegant solution. The USB pins on the RP2040 aren’t fed to the castellated pads on the Pico but they are fed to test pads on the underside of the PCB. They can be flow soldered if the Pico is used as a surface mount component but that makes hand assembly hard as the alignment has to be perfect. The USB pads are not visible once the Pico is soldered to a carrier board so it can’t be visually verified that a good connection has been made. The solution arrived at was to position plated-through holes in the carrier PCB that aligned with the USB pads on the Pico. That approach still required accurate alignment but that was facilitated with guide holes in the carrier PCB that matched the holes in the castellated pads on the Pico. Four individual header pins could be used temporarily to align the two boards while the corners were soldered. Finally the through-plated holes that aligned with the USB pads were flooded with solder to make the connections between the two boards.
The RP2040 contains a pair of hardware SPI blocks one of which would have been perfectly adequate to drive the LCD display. The LCD has a D/C pin which differentiates between control and data bytes and a typical stream to the display interleaves control and data bytes. Using the hard SPI with its FIFO then creates a synchronisation problem with control bytes possibly interpreted as data bytes and vice versa without careful handling. The obvious way of solving this was to set the D/C pin appropriately, write a single byte to SPI and wait for its transmission to complete, then setting D/C for the next byte and sending that, and so on. That’s not as efficient as it could be since it introduces a software overhead.
The RP2040 has a number of programmable state machines called PIOs and it’s easy to write a small piece of code that emulates an SPI port. The PIOs also have FIFOs and they are 32 bits wide. The LCD stream is byte wide so there are unused bits available. A 9th bit can be co-opted to differentiate between control and data bytes. The PIO can examine that extra bit and set or reset D/C as appropriate and the synchronisation will be perfect. The PIO instruction set is flexible enough to accommodate the extra functionality.
Ideally the LCD would update as fast as possible with no visible ‘wipe’ as the screen was redrawn. The firmware was now optimal using a PIO and the other factor affecting the refresh rate was the SPI clock frequency. By trial and error a frequency of 48MHz was found to be reliable and led to near instantaneous screen updates.
A menu system was built with separate pages to set the rotors, rings, initial positions and plugs. An undo feature was added that reversed the previous key press. Options to save and load settings from flash were also included.
The PCB was shaped like a gear in the Enigma machine in a desire to make it more interesting than a green rectangle. The Raspberry Pi Pico is neatly hidden on the underside of the PCB with the regulator, display and USB connector on the top. The regulator supplied 5V from the battery to the USB keyboard and also fed the Pico. The Pico has its own 3.3V regulator and a 3.3V output from the Pico powered the LCD display.