学研の4ビットマイコン GMC-4 でエニグマのようなものを作ってみた。
エニグマ
エニグマは、変換する文字をキーボードで打ち込むと変換結果の文字のランプが光る、換字式暗号の暗号化および復号を行う装置である。
同じ設定を用いて平文を変換すると暗号文になり、暗号文を変換すると平文になる。
エニグマは、以下の順番に変換を行う。
- プラグボード
- ローター1 (正方向)
- ローター2 (正方向)
- ローター3 (正方向)
- リフレクター
- ローター3 (逆方向)
- ローター2 (逆方向)
- ローター1 (逆方向)
- プラグボード
それぞれのパーツは電気的な配線により変換を行い、以下の性質を持つ。
- プラグボードは、設定された2個の文字を入れ替える。(例えば、「AとB」のペアを設定したら、AをBに、BをAに変換する)
- ローターは、逆方向の変換が正方向の変換の逆変換になっている。(例えば、正方向でAがBに変換される場合、逆方向ではBがAに変換される)
- リフレクターは、入力の文字を必ず別の文字に変換する。
ローター1は、1文字変換するごとに1文字分回転し、変換の仕方が変わる。
ローター2は、ローター1の回転が一周すると1文字分回転する。
ローター3は、ローター2の回転が一周すると1文字分回転する。
これにより、文字の位置によって様々な変換が行われる。
今回の仕様
プラグボードは省略し、データメモリで表現するローター1枚だけを用いたエニグマもどきによる暗号処理を行う。
キーにより文字を入力すると、7セグメントLEDに変換結果の文字が出力される。
本来のエニグマはアルファベット26文字を対象とするが、今回は0~Fの16文字を対象とする。
プログラム
以下のプログラムは、MikeAssembler でアセンブルできる。
target gmc4
org 0x00
main_loop:
CAL RSTO
; キー読み込み
key_wait:
KA
JUMP key_wait
; ローター (順方向)
CY
MA
; リフレクター
CAL CMPL
; ローター (逆方向)
TIY 0
JUMP reverse_search_initial
reverse_search:
M-
AIY 1
reverse_search_initial:
M-
CIA 0
JUMP reverse_search
CY
; 暗号化/復号結果を出力
AO
; ローターを回転させる
TIY 0
MA
CH
TIY 1
rotate_loop:
MA
AIY -1
AM
AIY 2
JUMP rotate_loop_end
JUMP rotate_loop
rotate_loop_end:
CH
TIY 0xF
AM
; キーが離されるのを待つ
key_release_wait:
KA
JUMP main_loop
JUMP key_release_wait
; ローターの設定
org 0x50
datan 0x8, 0x6, 0xd, 0x9, 0x1, 0x4, 0xe, 0x7
datan 0xf, 0x2, 0x3, 0x0, 0xc, 0xa, 0xb, 0x5
以下は、このプログラムの機械語表現である。
| 0 1 2 3 4 5 6 7 8 9 A B C D E F
--+-----------------------------------
0 | E 0 0 F 0 2 3 5 E 4 A 0 F 1 2 7
1 | B 1 7 C 0 F 0 F 3 1 A 0 5 2 A 1
2 | 5 B F 4 B 2 F 2 C F 2 0 2 A F 4
3 | 0 F 0 0 F 3 0
さらに、データメモリを0~Fの順列 (0~Fをそれぞれちょうど1回ずつ使った列)で初期化しておく。
この列がローター (変換表および回転位置) を表す。
データメモリの内容が0~Fの順列でない状態でプログラムを実行した場合、結果は保証しない。(変換時に無限ループとなる可能性がある)
| 0 1 2 3 4 5 6 7 8 9 A B C D E F
--+-----------------------------------
5 | 8 6 D 9 1 4 E 7 F 2 3 0 C A B 5
実行結果
上記のローターの設定を用いて「DEADBEEF01234567」を暗号化すると、「FC849C0D330ABC85」となった。
本来は暗号化/復号を開始する際にローターの再設定が必要であるが、動画では16文字変換するとローターが一周して元に戻ることを利用し、再設定を省略した。