モジュール詳細:忘れられしアンフェア暗号

結局、忘れ去られることになった暗号もある。そもそも「本当にアンフェア」だったのだろうか?

上部のディスプレーには暗号化されたメッセージが表示される。ディスプレーの下には丸いLEDのストリップがあり、処理担当者が開いているページに応じて点灯する。

この状態では、真ん中のボタンをいつでも選択することができ、ページ間を循環表示させたり、単語送信モードとページ閲覧モードを切り替えることができる。

このマニュアルにあるアルファベットにまつわる暗号は、すべて英語のアルファベット「ABCDEFGHIJKLMNOPQRSTUVWXYZ」に対応している。このマニュアルにおける「アルファベット位置」とは、特に断りのない限り、A=1,Z=26としたアルファベット上の位置の数字である。

1ページ目の右側のディスプレーは、常にミスカウンターが赤、モジュールIDが白で表示される。

モジュールが送信モードでない状態におけるボタンの機能は以下の通りである。方向ボタンは中央の四角(内心)と外側の四角(外心)の間のボタンを表す。

  • 左:モジュールの1ページ目に移動する。
  • 上:モジュールの2ページ目に移動する。
  • 右:モジュールの3ページ目に移動する。
  • 下: モジュールの4ページ目に移動する。
  • 外心:送信ページと閲覧ページを切り替える。
  • 内心:長押しすると、3ページと4ページに表示されている色の名前を表示する。これは、ユーザーがこのモジュールの色覚モードを無効にしている場合でも使用できる。
  • 右画面:右と上に表示される内容を入れ替える。

復号 - ステップ1:バイナリコードの取得とキー文字列の完成

2ページ目では、上と右に長い文字列が表示される。以下の手順でバイナリ文字列を取得する。

  1. 2ページ目の上のディスプレーと右のディスプレーに表示されているテキストを順に連結する。これを1つの完全な文字列として扱う。
  2. 以下の表を使用して二進数に変換し、置換された数字を獲得する。バイナリ文字列を得るためには、複数の置換が必要なことに注意すること。
変換後の文字元の文字変換後の文字元の文字変換後の文字元の文字
0A1BAAC
BADABEBBF
CAGCBHDAI
DBJEAKEBL
FAMFBNAGO
BGPAHQBHR
AISBITAJU
BJVAKWBKX
ALYBLZ
  1. 3ページ目では、両ディスプレーとも最大9つのキーワードがあり、各キーワードを連結して最初に出現した英字のみを考慮すると、キー文字列になり、これは作成したハフマンツリーを使用した復号に使用される。
    • 連結は、読み順でキーワードを得た順で行い、一番上のディスプレーから始め、次に右のディスプレーに進む。
    • 連結の際に、キーワードがそれまでに使用された英字をすべて含んでいる場合、代わりにそのキーワードを破棄する。

復号 - ステップ2:赤色ハフマン暗号

そもそも、どうやってグリフィンドールがここに来たんだ?ハッフルパフのゲームに何かあったのだろうか?

取得したバイナリ文字列を使用し、10個の葉を取得するまで、以下の手順を繰り返す。葉とは、ハフマン木の末端にある節のことである。各桁は左から右に一度だけ読み取られ、戻ることはない。

  1. 「0」と「1」の葉から開始する。
  2. バイナリの桁を、バイナリ文字列内の先頭にある一つの節に出会うまで読み続ける。
  3. その情報を部分的なバイナリ文字列として分離させ、バイナリ文字列から始まりそれぞれ「0」と「1」で終わるような2つの項目に変更する。分割の際、葉の順序は維持すること。
  4. 上記の2ステップを繰り返す。

ハフマン木の一部を獲得後、バイナリ文字列を使ってある数字を得なければならない。この数字は、3×3ヒル暗号に使われる。ハフマン木を構築し続ける前に、この方法で18桁を取得する必要がある。

  1. 0から始まる葉を優先して、それぞれの葉に0~9の数字を順に割り当てる。
  2. バイナリの桁を、いずれかの葉に出会うまで読み続ける。その桁をメモして取り除き、再び先頭からやり直す。
  3. この状態で十分な桁数が得られるまで、前のステップを繰り返す。

18桁を取得したら、さらに16の葉が構築されるまで、ハフマン木の構築を再開する。この時点までに26の葉を作成する必要がある。0から始まる葉を優先して、それぞれの葉にキー文字列の各英字を割り当てる。

バイナリ文字列をもう1回読み、割り当てた英字に応じて4~8文字の単語を取得する。これが次のステップのキーワードとなる。残りのバイナリ文字列はまったく同じ英字になるはずであり、これは捨ててもよい。

例 — 赤色ハフマン暗号の構築

先頭8桁のみを示す。
初期バイナリ文字列: 0111100000110101

[0][1]

1回目の分離後のバイナリ文字列: 111100000110101

[00][01][1]

2回目の分離後のバイナリ文字列: 11100000110101

[00][01][10][11]

3回目の分離後のバイナリ文字列: 100000110101

[00][01][10][110][111]

4回目の分離後のバイナリ文字列: 0000110101

[00][01][100][101][110][111]

5回目の分離後のバイナリ文字列: 00110101

[000][001][01][100][101][110][111]

6回目の分離後のバイナリ文字列: 10101

[000][0010][0011][01][100][101][110][111]

7回目の分離後のバイナリ文字列: 01

[000][0010][0011][01][100][1010][1011][110][111]

8回目の分離後の葉:

[000][0010][0011][010][011][100][1010][1011][110][111]

例 — 赤色ハフマン暗号バイナリの読み取り

この例では6桁だけ行う。

初期の残ったバイナリ文字列:0001011001100110010111

[000][0010][0011][010][011][100][1010][1011][110][111]
0123456789

「000」, 0

1文字目読み取り後のバイナリ文字列:1011001100110010111

[000][0010][0011][010][011][100][1010][1011][110][111]
0123456789

「1011」, 7

2文字目読み取り後のバイナリ文字列:001100110010111

[000][0010][0011][010][011][100][1010][1011][110][111]
0123456789

「0011」, 2

3文字目読み取り後のバイナリ文字列:00110010111

[000][0010][0011][010][011][100][1010][1011][110][111]
0123456789

「0011」, 2

4文字目読み取り後のバイナリ文字列:0010111

[000][0010][0011][010][011][100][1010][1011][110][111]
0123456789

「0010」, 1

5文字目読み取り後のバイナリ文字列:111

[000][0010][0011][010][011][100][1010][1011][110][111]
0123456789

「111」, 9

取得した数字:072219

復号 — ステップ3:RGBA分解暗号

上記の図は、このモジュールに表示されうる27色をすべて示している。モジュールの3ページにある6つのLEDは、各英字と演算子で使用する際に、同じ位置にある復号された英字に対応する。

ステップ2で得られたキーワードを使用し、重複する英字をすべて削除し、それぞれの最初に出現する英字は保持する。アルファベットを作成し、キーワードから文字を除外する。

1ページ目の右のディスプレーについて、モジュールIDに「MODULE ID:」が存在する場合、アルファベットをキーワードの末尾に置く(FORGETABCDHIJKLMNPQSUVWXYZ)。そうでなければ、アルファベットをキーワードの先頭に置く(ABCDHIJKLMNPQSUVWXYZFORGET)

4ページでは、3つのLEDが赤、緑、青の異なる色合いで表示される。ただし、この順番で表示されるとは限らない。3つのLEDに対応するRGBチャネルは、「-」(消灯)、「0」(暗い)、「+」(明るい)の3つの値のいずれかを持っている。各LEDごとに、他2つのチャネルと異なる値を持つ。LEDを左から右に見ると、これらの固有値を持つチャネルは、英字を配置する順番を構成している。英字を配置する順序は、上記の図に従って、-から始まり+で終わる。また、この値をRGB順に並べ替えると、先ほど作成したキー文字列を配置するときにスキップすべき色に対応する。

  • そのLEDに使われている値のいずれかに0がある場合、そのチャネルは0以外の値で表される。(例: 0+0では、0以外の値は+)
  • そうでなければ、そのチャネルは0として表される。

復号 - ステップ3: RGBA分解暗号(続き)

ページ1の上のディスプレーから英字を色に変換し、それぞれ R, G, Bを表す3文字の文字列を6個生成する。基本メッセージから形成された6個の文字列を、各チャネルに対応する3つ別々の直角三角形になるように読み順で並べる。三角形の底辺と高さは、3文字分である。ページ4には、各チャネルの変換を示す3つの文字列がある。上のディスプレーに表示されている3つの文字列は、上から下へ、ポートの個数だけ右にシフトしたRGBの順(R -> G -> B)となり、Bの場合はRにループしている。チャネルが「NONE」の場合、そのチャネルには変換は適用されない。変換後の文字列と表示された色を組み合わせると、6組の文字列ができるはずである。

  • 「TL」:そのチャネルの各段を水平方向に反転させる。
  • 「TR」:そのチャネルの各列を垂直方向に反転させる。
  • 「BL」:そのチャネルの段と列を入れ替える(B1 <-> A2)。
  • 「BR」:そのチャネルを反転する。つまり、- -> +やその逆を行う。0は反転させてはいけない。

使用演算子はページ4の右のディスプレーに表示される。これらの演算子は、形成された文字列のペアへ順に適用され、最後の演算子を使ったら最初の演算子にループする、記号は正しく表示されないものがあるため、モジュールはそれぞれの記号を言葉で説明している。各説明は、ちょうど1つの演算子記号にのみ対応しなければならない。

使用する表示された演算子は、復号に使用する表に対応する。これらの表は文字列の各ペアに適用され、ペアのどちらが段/列に対応するかは関係ない。

+-0+
---0
0-0+
+0++
×-0+
-+0-
0000
+-0+
-0+
--+0
0+0-
+0-+
m-0+
----
0-00
+-0+
M-0+
--0+
000+
++++
-0+
-0-+
0-0-
++-0
+Add Symbol / Plus Sign / Plus Symbol / Symbol For Adding
×Multiply Symbol / x, literally / Times Symbol / Multiply Sign
Circle / o, literally / Unfilled Circle / Lowercase O
mLowercase M / M but Lowercase / Lowercase Mike
MUppercase M / M but Uppercase / Uppercase Mike
Slashed Circle / / through O / Empty Set Symbol / O and /

最後に、先程作成したキー文字列を用いて各文字列を英字に変換すると、復号された文字列が得られるはずだ。

例 — RGBA分解暗号

ページ1の上のディスプレー:AEIPAZ

キーワード:AMBITION

ページ3の6つのLED:Mint, Plum, Indigo, Forest, Rose, Magenta

ページ4の3つのLED:Mint(0+0), Red(+--), Indigo(--0)

固有値(G: +, R: 0, B: -) = 順番はGRB

表示された変換:「TL, BR」; 「BR, TR」; 「BR, BL」

ポートの個数を3で割った余り:1

演算子:+, ○ (Plus Symbol, Circle)

「Module ID」 は表示されている

3つのLEDから求めた色:5行目をRGBの順に並べて、0+- (Lime)

G-0+-0+-0+-0+- 0+-0+-0+-0+-0+
R---000+++---0 00+++---000+++
B---------0000 00000+++++++++
AMBIT!ONCDEF GHJKLPQRSUVWXYZ

RGBの順に並び替える:

R---000+++---0 00+++---000+++
G-0+-0+-0+-0+- 0+-0+-0+-0+-0+
B---------0000 00000+++++++++
AMBIT!ONCDEF GHJKLPQRSUVWXYZ

AEIPAZ = ---, -00, 0--, ++0, ---, +++ (RGB)

Rチャネルの転置
--0
+-
+
BR
++0
-+
-
BL
+--
++
0
Gチャネルの転置
-0-
+-
+
TL
-0-
-+
+
BR
+0+
+-
-
Bチャネルの転置
-0-
0-
+
BR
+0+
0+
-
TR
-++
00
+

順番通りに取得:++-, -0+, -++, ++0, +-0, 0-+

6つのLEDを変換:0+0, 0-0, --0, -0-, +-0, +-+

演算適用後の結果:++-, ++-, -0+, 0-+, +-0, --+

復号後:++-, ++-, -0+, 0-+, +-0, --+ = CCRUKQ

復号 — ステップ4:3×3ヒル暗号

やっぱり現れた。みんな今、それを復号するためにとんでもないツールを使おうとしている!なんてことをしているんだ!?

ステップ2で得られた18桁の数値は、読み順に3×3行列の一部となる2桁の数値セットを9つ形成する。本マニュアルでは、これらをa~iと表記する。復号するには、

3×3行列の行列式Xを、以下の式で求める:

3×3 Matrix Determinant

先ほど求めた行列式の逆数Yを求める。XをY倍し、アルファベットの長さP(26)で割った余りがすべて1に等しくなるような数を見つければよい。どのような方法を用いたとしても、以下の式は真となるはずである。

Multiplicative Inverse

復号 — ステップ4:3×3ヒル暗号(続き)

元の行列の余因子行列は、3×3行列の余因子を求め、左上から右下の対角線に対して転置させることで求められる。

3×3 Matrix Adjugate

復号 — ステップ4:3×3ヒル暗号(続き)

余因子行列にYを掛け、3×3行列内の2×2行列の行列式を計算すると逆行列が得られる。

3×3 Matrix Inverse

逆行列を使うには、ステップ3で復号した文字を3文字ずつにグループ分けし、それぞれのアルファベット位置を求める。Zは0とする。これを1×3行列として扱い、1×3行列に3×3逆行列を右から掛ける。1×3行列の最初の値は3×3行列の最初の列に掛け、1×3行列の2番目と3番目の値も同様に行う。積を行ごとに合計し、3つの別々の値を獲得する。その値をアルファベットの長さで割った余りを求め、アルファベットの位置を使ってそれぞれの英字に変換する。0はZとする。

例 — 3×3ヒル暗号における逆行列の取得

取得した行列:

7, 22, 19
21, 9, 15
11, 16, 22

行列式X: 7*9*22 + 22*15*11 + 19*21*16 - 7*15*16 - 22*21*22 - 19*9*11 = -2325

計算を簡略化するため、26で割った余りを使用 -2325 mod 26 = 15

15 * Y = 1 mod 26を満たすYは、 Y = 7

余因子行列:

9, 15
16, 22
-
22, 19
16, 22
22, 19
9, 15
-
21, 15
11, 22
7, 19
11, 22
-
7, 19
21, 15
21, 9
11, 16
-
7, 22
11, 16
7, 22
21, 9

逆行列:

7*(9*22-15*16) -7*(22*22-19*16) 7*(22*15-19*9)
-7*(21*22-11*15) 7*(7*22-19*11) -7*(7*15-19*21)
7*(21*16-9*11) -7*(7*16-22*11) 7*(7*9-22*21)

-294, -1260, 1113
-2079, -385, 2058
1659, 910, -2793

例 — 3×3ヒル暗号における行列の利用

取得した逆行列(26で割った余り):

18, 14, 21
1, 5, 4
21, 0, 15

暗号化された単語:CCRUKQ

暗号化された単語の英字をアルファベット位置に変換:3, 3, 18, 21, 11, 17

3*18 + 3*14 + 18*21 = 474, 474 mod 26 = 6, F

3*1 + 3*5 + 18*4 = 90, 90 mod 26 = 12, L

3*21 + 3*0 + 18*15 = 333, 333 mod 26 = 21, U

21*18 + 11*14 + 17*21 = 889, 889 mod 26 = 5, E

21*1 + 11*5 + 17*4 = 144, 144 mod 26 = 14, N

21*21 + 11*0 + 17*15 = 696, 696 mod 26 = 20, T

復号された単語:FLUENT

単語の送信

最後にもうひとつ。

外心を押して送信モードに入ると、内心と外心の間にある4つのボタンが異なる色合いに変化する。
外心を押すと送信モードを終了し、これはいつでも押すことができる。

送信モードはロックされているため、まず解除する必要がある。外心以外のいずれかのボタン(ディスプレーを除く)を押すと、送信モードが解禁されるが、正しいタイミングで押さないとミスが記録される。送信でミスが記録されても、送信モードは解禁されたままとなる。

  • シリアルナンバーの最後の数字から始め、モジュールIDを足す。
  • 点灯していないすべてのインジケーターに含まれている、Nを除いたNよりに前にアルファベットに現れる英字の個数を足す。
  • 現在の値に、もしページ1の2行目にあるミスカウンターが、数字の後ろに「STRIKE(S)」がある形式で現れていれば、点灯しているすべてのインジケーターに含まれている、Nを除いたNよりに前にアルファベットに現れる英字の個数を足す。そうでない場合、もしページ1の2行目にあるミスカウンターが、数字の前に「STRIKE(S):」がある形式で現れていれば、バッテリーの個数を足す。そうでない場合、バッテリーホルダーの個数とポートプレートの個数の和を加える。
  • 単語の一部または単語そのものとして、名前に「Fair」を含むモジュールの個数の3倍を引く。これは大文字小文字を区別しない
  • 3を足し、その結果を10で割った余りを求める。カウントダウンタイマーの秒の下一桁がその数字である場合、モジュール解禁時にミスが記録されない。

送信のロックが解除されると、右側のディスプレーには、どのボタンがモジュールのどの部分にアクセスできるかが表示される。

を押すと、それぞれ-、0、+が右のディスプレーに入力され、その文字が上のディスプレーに表示される。

を押すと、右のディスプレーに表示されている入力があればそれを削除し、なければ上ディスプレーの最後の文字を削除する。

内心を押すと、上のディスプレーの文字を送信する。

外心を押すと、すべての入力が消去され、送信モードが終了する。

送信された単語が正しければ、モジュールは解除される。そうでない場合、モジュールにはミスが記録され、最終的に送信モードが終了する。正しい単語は変化しない。

参考までに、右側に表示されている入力内容の最初の文字は、-、0、+を入力すると、それぞれアルファベットのA~I、J~R、S~Zのセクションに入る。2番目の入力は1番目の入力における3文字ごとのサブセクションの位置を示し、3番目の入力が英字を示す。「?」は無効な文字を表すのに使われる。