現狀 9 已解 · 3 部分 · 10 未解
清單條目應寫作“22條電報,9條已解密,3條部分解密,10條未解”,而 Lasry 在評論帖中復原的那把金鑰應與已公佈的十四把並列。Norbert 2017年的方法——針對已知金鑰做兩處至多五個字母的塊編輯——在此用一個德語語言模型重新實現,在不提供任何明文線索的情況下重新推出了已解的各頁。對十條未解電報,它用十五把金鑰中的任何一把都一無所獲;而在這樣的長度下,不依賴金鑰的攻擊即便在人為植入的對照上也無法復原換位。這十條未解電報需要 Childs 的原件,或者一把從未出現在語料中的金鑰。
01 這份清單是什麼
James Rives Childs 是1918年派駐法軍的美國密碼分析員,他儲存了一份在東線截獲的德軍 ADFGVX 通訊的抄本。2017年,George Lasry、Ingo Niebel、Nils Kopal 和 Arno Wacker 用針對換位的爬山法攻破了這批語料,在1918年9月至12月的十四把三日金鑰下復原了618份密碼電報。隨後 Lasry 把在這些金鑰下都無法解密的電報列成清單交給 Klaus Schmeh,Schmeh 以“Unsolved ADFGVX messages from World War I”為題發表,附上了金鑰,後來又將其列為他的五十強第46號。
Lasry 在那個頁面上的附註點明瞭問題所在:這些金鑰“most certainly all the keys used during the period”,所以“the challenge is to understand how the cryptograms were mutilated”。ADFGVX 對長度毫不寬容。列換位按金鑰長度切分字母流,所以丟失或多出一個字母,就會讓其後的每個列邊界都移位,把電報的其餘部分變成噪聲。一條有兩處亂碼的電報,即使金鑰已知,也無法再用該金鑰解密。
2017年2月至9月間,該帖下的評論區完成了大部分工作。Norbert Biermann、Armin、Thomas、Max Baertl 和 Lasry 本人一條接一條地解密了電報。Schmeh 宣佈要寫一篇彙總文章,卻始終沒寫,所以這些解密結果只零散地存在於評論中,無論印本還是網上都找不到結果彙總表。本報告做的第一件事就是釋出這張表。
02 金鑰,轉成機器可讀格式
Lasry 的清單把每把金鑰給成一個換位排列和一個36字元的替換方陣,各單元按 A D F G V X 的行序排列。十四個方陣中有三個含有成串的連字元,表示從未復原的單元,而 PDF 的文字層把這些連字串壓縮成了短破折號和長破折號,使方陣只剩34或35個字元。把每個破折號還原成能湊足36個字元的連字串長度,三個方陣就都修復了。全部十四把都在 keys.json.
金鑰數字有兩種解釋。要麼 perm[i] 是第 i 個輸出的列,要麼是第 i 列被輸出的位置。兩種解釋都能自洽地往返,所以加密–解密測試無法區分它們。解密一條真實電報則可以。答案是第二種。
不在清單上的金鑰
2017年5月3日,Lasry 在評論帖中報告:一條分成兩部分的電報——11月13日的 FFVXV 密碼電報及其後續的 AFAFF 殘片——在一把不屬於十四個時段中任何一個的金鑰下合併解密成功:換位詞 CMBLAKOHIDENFJGP,長度16。他給出了合併後的明文,共173個字母,並指出他的程式需要全部356個密文字母才能復原一把長度為16的金鑰。替換方陣沒有公佈。這裡把兩份密碼電報中未換位的雙字母組與他的明文(已採用 Norbert 的修正)對齊,重建了方陣:36個單元中復原了24個,數字和字母 M、Q、Y 未能復原,因為這條電報從未用到它們。它是以下檔案中的第十五個條目: keys.json 倉庫的筆記稱之為 CHI 金鑰,名稱取自它所加密的那條電報的報頭。
03 2017年的成果匯成一表
評論帖的全部70條評論都逐一看過。頁碼是 Schmeh 所印的 Childs 抄本頁碼;清單上有兩條電報沒有頁碼。字母數是收到的密文字母數,印本轉錄中標出的缺口另行計數。每項解密都歸功於最先貼出它的人。
| Childs 頁碼 | 字母數 | 狀態 | 金鑰 | 讀解 |
|---|---|---|---|---|
| 73 | 176 + 2處缺口 | 未解 | 無一相符 | — |
| 100 | 122 | 已解 | 11月1–3日 | KEINE STOERUNG DURCH FEIND X MITTAGS 2 FEINDL X DIV X IM MARSCH AUF BELGRAD X(Armin) |
| 105 | 290 | 已解 | 11月1–3日 | GERMANIA ETAPPE KONSTANTINOPEL XX FUER MITTELMEER DIVISION ZU X TEL X NR X 62 X DIV X TELEGR X NR X 58 X ERSTELLT … VOM X 4 X NOVEMBER ERLEDIGT X ADMIRALSTAB(Norbert) |
| 109 | 258 | 已解 | 11月1–3日 | O X K X M X ABENDMELDUNG … UNTERBRINGUNG LETZTER TEILE BEENDET X 1 WEITERER DU X DIV 5 IM MARSCH AUF BELGRADER KAVV X 2 X SONST KEINE EREIGNISSE(Norbert) |
| 132 | 153 + 缺口 | 已解 | 11月4–6日 | FUER EILVESE X WIEDERHOLE TELEGR X VON VIERTER PERIODE IN FUENFTER X GEBETSORDER 5 MIN X VVV。加密者把 VV 寫成了 VVV,因此長度是奇數(Norbert) |
| 146 | 244 | 已解 | 11月4–6日 | FUNKSTELLE KERTSCH ER HAT BETRIEB X 1F X RUFNAMEN RICHARD EMIL KARL X FUNKSTELLEN DORTIGEN BEREICHS BENACHRICHTIGEN X NACHRICHTENCHEF 4B X 7834 X(Norbert) |
| 152 | 104 | 未解 | 無一相符 | — |
| 153(VFVAX) | 132 | 未解 | 無一相符,包括 CHI 金鑰 | — |
| 153(AXVAA) | 93 + 15處缺口 | 未解 | 無一相符,包括 CHI 金鑰 | — |
| 158 | 240 + 2處缺口 | 未解 | 無一相符 | — |
| 164 (F-G-X) | 158 + 44處缺口 | 部分 | 11月7–9日 | … X 9 X 11 X TEMESVAR X … DIE VON X MIRCO NACH WESTEN UND SUEDEN WEG X LEIDER WEGE VOM GEGNER BESETZT X(Norbert) |
| 164(VFGAG) | 136 + 44處缺口 | 部分 | 11月7–9日 | EL X DIE HOEHE X 828 X O X H X L X MIRCO X SONST KEINE EREIGNISSE VON BEDEUTUNG XX(Norbert) |
| 170 | 106 | 未解 | 無一相符 | — |
| 171 | 310 + 4處缺口 | 已解 | 11月7–9日 | IN UKRAINE UND POLEN RUBELKURSE STARK STEIGEND INFOLGE BRUCHES ZWISCHEN DEUTSCHLAND UND SOWJETREGIERUNG UND ERWARTUNG DER WIEDERHERSTELLUNG RUSSLANDS DURCH DEUTSCHLAND UND ENTENTE(Norbert) |
| 176(“缺10個字母”) | 214 | 已解 | 11月10–12日 | DURCHBRUCH VORBEREITET X DURCHBRUCHSRICHTUNG NACH NORDEN ODER NORDOSTEN ERFOLGEN WIRD X KANN JETZT NOCH NICHT BEURTEILT WERDEN X(Norbert) |
| 176(GGDAA) | 220 | 未解 | 無一相符 | — |
| 無頁碼(VGADA;Childs p. 215,11月22日) | 237 + 11處缺口 | 部分 | 11月22–24日 | ABS X MIDIV 5 X EILMELDG … ARMADA KERTSCH X BRINGT ENTENTE FLOTTE ZWO DIVISIONEN X NEUSEELAENDER X ENGL X U X FRANZO X MIT X … OHL X KORPS …(Norbert、Baertl) |
| 187(FFVXV;Childs p. 191,11月13日,第1部分) | 212 | 已解 | CHI,11月13日 | RUSSISCHEN UND POLN HEERESVERKEHR VOLL ERFASSEN X WICHTIGES BESONDERS AUS POLN VERKEHR UEBER OHL STATION VERZIFFERT FUNKEN(Lasry、Norbert) |
| 無頁碼(AFAFF;第2部分) | 142 | 已解 | CHI,11月13日 | SOWEIT FERNSCHREIBERVERBDG NICHT ARBEITET X REST SCHRIFTLICH X NACH CHEF(Lasry、Norbert) |
| 189 | 84 + 6處缺口 | 未解 | 無一相符 | — |
| 198 | 165 | 未解 | 無一相符 | — |
| 217 | 170 | 未解 | 無一相符 | — |
九條已解密,三條部分解密,十條在任何地方都找不到解密結果。另有一頁抄本,即印本中的187(SELLV…,“Stellv. Gen. Kom. 9 AK Breslau”),是卡塞爾團隊早已解出的電報,不應列入清單;Lasry 在評論帖中已指出這一點。兩條 CHI 電報被列為在已公佈金鑰下無法解密,這沒錯;它們是在 Lasry 復原了一把未公佈的金鑰之後才解密的。
04 重新實現 Norbert 的方法
Norbert 用一句話說明了他的方法:在兩個不同位置新增或刪除至多五個字元,窮舉搜尋,用 n 元組評價函式為結果排序。 blocks.py 做的正是這件事。對十五把金鑰中的每一把,以及每一種至多兩處、每處一到五個字母的塊編輯(在抄本的五字母組邊界處插入或刪除),它都進行解密,並用一個德語四元組模型為結果打分;該模型由 Gutenberg 德語文字中的360萬個字母構建(lm_de.py)。含有數字或未復原單元的視窗記最低分;跨越 X 分隔符的視窗,代價低於亂碼、高於正文。在這個模型上,德語散文每個視窗的得分約為 −3.3 nats,隨機字母約為 −7。
在不提供任何明文線索的情況下,搜尋重新推出了第105、109、146、171頁,第176頁那條“缺10個字母”的電報,以及兩條 CHI 電報。在第146頁上,Norbert 在第10組之前插入的那個五字母塊得出為 (45, 5)。在第176頁的電報上,兩個五字母塊得出為 (10, 5), (130, 5)。第100頁用同樣的搜尋、只插入一個雙字母塊就解開了。搜尋還找到了無頁碼的 VGADA 電報在11月22–24日金鑰下的部分解。在印本轉錄標出缺口之處, gaps.py 把缺口還原到各自的組裡,再用模擬退火處理剩餘的單字母丟失;在第132頁上,它在沒有任何提示的情況下得出了 Norbert 的文字。
重新推出的各頁得分(取自執行日誌),與未解電報所能達到的最佳得分對比:
| 頁碼 | 金鑰長度 | 最佳得分,nats/視窗 | 搜尋返回的解密結果 |
|---|---|---|---|
| 187(CHI 第1部分) | 16 | −4.45 | RUSSISCHETUNDPOLNHEERESVERKEHRVOLLERFASSENXWICHTIGESBESONDERS… |
| 146 | 17 | −5.25 | FUNKSTELLEKERTSCHERHAE.TAB12X1.XRUFNAME.RICHARD.MILKARLX… |
| AFAFF(CHI 第2部分) | 16 | −5.28 | SOWEITFERNSCHREIBERVERBDGNITHTARBEICETXRESTSCHRIFTLICHXNACHCHEF… |
| 100 | 19 | −5.39 | KEI.ESTOERFNGDURCHFEINDXMITTAGS2FEINDLXDIVXIMMARSCHAUFBELGRAD. |
| 171 | 20 | −5.50 | INUKRAI.EUNDPOLEN.UBELKURSETARKSIEIGENDINFOLGEBRUCHEEZWISCHEN… |
| 105 | 19 | −6.02 | GERMANIAATAPPEKONSTANTINOPELX6FUERMITTJLMEERDIVISIVNZUXTELXNRX62… |
| 109 | 19 | −6.02 | OXFXMXABECDMELUNGXS4VCXUMBJRGABGLETZTEVTEILEBEEVUKTX1WEITEDE… |
| 最佳的未解電報(158,170) | 20, 19 | −6.89 | 噪聲 |
已解的各頁即便塊編輯不完全準確,也一眼就能認出是德語,剩下的亂碼是第二輪能修復的單字母丟失。第105頁和第109頁兩行得分比其他的低,因為兩塊搜尋只能近似其損壞情況;但兩段文字在原始輸出中都清晰可讀,也都與 Norbert 2017年的解密一致。
05 檢驗十條未解電報
兩處塊編輯,十五把金鑰
十條電報中的每一條都用全部十五把金鑰、至多兩處塊編輯跑過一遍。每條的最佳結果,取自 blocks_out.txt:
| 頁碼 | 字母數 | 最佳結果的金鑰長度 | 最佳得分 | 輸出 |
|---|---|---|---|---|
| 73 | 176 | 22 | −7.12 | DWR5C10WAXWBI.GWBXD1QGRA.R7OCW3Q… |
| 152 | 104 | 22 | −6.76 | YPVXKTHJ7EM46PGPQ3RONDSEEUHXKTAX… |
| 153(兩條) | 132, 93 | 20 | −6.99 | XWH2XBB3WATECOIFLUKTXMHK17SSY2ME… |
| 158 | 240 | 20 | −6.89 | ZF2B0GEKJXII32RXRCO4LRS2DXA2RBDO… |
| 170 | 106 | 19 | −6.89 | N5ADB08EKYND918UFEED92H3ELZEJ0UA… |
| 176(GGDAA) | 220 | 22 | −7.10 | RGXCXXPPUN6RAXZK2YD8PMRX4NVX4ZYT… |
| 189 | 84 | 22 | −7.08 | 1AA1SLUOXO.VGXWUXUWH6LXXNHLV.9WW… |
| 198 | 165 | 20 | −6.97 | LTDUUKWRA28KK61UITPUU31LEPXSIP42… |
| 217 | 170 | 18 | −7.04 | YBEIEU84543EOTXT45R8K6XXGCSF4PWI… |
沒有一條超過 −6.7。同一次執行中,已解電報的得分在 −4.4 到 −6.0 之間,隨機字母約為 −7.3。所以這十條中沒有一條是用十五把金鑰之一加密、且只有兩處或更少塊損壞的,這恰恰是2017年的讀者們到達並止步的邊界。輸出中數字很多,通常是金鑰不對的跡象:這裡的真實通訊大多是字母,錯誤的方陣會把雙字母組散佈到數字單元上。
用 CHI 金鑰試第153頁的兩條電報
2017年9月,Norbert 提出(但未測試)第153頁的兩條電報可能屬於 CHI 金鑰,因為它們出自同一時期。用奇偶修復直接解密,以及塊搜尋,對兩條電報返回的都是噪聲。原因要麼是還有另一把未列出的金鑰,要麼是損壞超過了兩塊。
不依賴金鑰的攻擊,以及它為何失敗
如果某些未解電報是用語料之外的金鑰加密的,那麼這把金鑰就只能僅憑密文來複原。 keyless.py 的做法是:在每個候選長度上,以逆換位產生的字母對的重合指數為目標,對列序做模擬退火(因為正確的逆換位會把單表替換的雙字母組配成對),然後用德語模型求解36符號的替換。在用於未解電報之前,先在一個人為植入的對照上執行:224個德語字母,用同樣設計的長度為19的金鑰加密。
| 候選長度 | 15 | 16 | 17 | 18 | 19(真實) | 20 | 21 | 22 | 23 |
|---|---|---|---|---|---|---|---|---|---|
| 退火後的字母對重合指數 | 0.055 | 0.048 | 0.060 | 0.053 | 0.064 | 0.058 | 0.066 | 0.063 | 0.073 |
真實長度並不突出:19處的峰值被21、22和23超過,替換階段在任何長度上都不收斂。對照沒有被複原。Lasry 專為此目的編寫的程式,需要356個字母才能復原一把長度為16的金鑰。十條未解電報的長度在84到240個字母之間。因此在這樣的長度下,不依賴金鑰的復原是做不到的,只有一個例外:兩條或更多共用同一把未知金鑰的未解電報可以合併求解,就像那兩條 CHI 電報一樣。密文中沒有任何東西表明哪些電報屬於這種情況;而最自然的候選——第153頁的兩條電報——放在一起試,也一無所獲。
06 現狀,以及什麼能改變它
九條電報已解密,三條部分解密,十條未解。這十條於2026年9月經過檢驗,在每一把已知金鑰、至多兩處塊編輯之下都失敗了。有三件事能改變這一點。
| 什麼 | 為何重要 |
|---|---|
| Childs 的原件 | 這十條中有幾條在印本轉錄中帶有明確的缺口標記,其中一條標著“缺10個字母”。Schmeh 印出的轉錄是抄本的抄本;截獲原件上可能保留著搜尋不得不去猜的那些字母。 |
| 另一把金鑰 | CHI 電報證明了公佈的清單並不完整。一把從其他來源、或從同一時期某條從未列入本清單的較長電報中復原的金鑰,幾秒鐘內就能對全部十條進行測試。 |
| 超過兩處編輯的搜尋 | 在十五把金鑰上做三處塊編輯,計算量是夠得著的,也是自然的下一步;這裡沒有執行,是因為兩處編輯這一標準已經解出了2017年讀者們解出的一切,而且得分沒有顯示任何未解電報接近解開。 |
在其中任何一項出現之前,有用的成果是:上面的表格,十五把機器可讀格式的金鑰(三個受損方陣已修復,CHI 方陣已重建),以及一個無需提供明文就能重現2017年解密結果的解碼器。
07 檔案
| 檔案 | 內容 |
|---|---|
targets/adfgvx/msgs.txt | Schmeh 所印的二十二份密碼電報,保留缺口標記 |
targets/adfgvx/keys.json | 十五把金鑰:Lasry 的十四把(三個受損方陣已修復),以及11月13日的 CHI 金鑰 |
targets/adfgvx/key16.py | 根據兩部分明文重建 CHI 替換方陣 |
targets/adfgvx/repair.py | 解碼器; validate 重現第100頁, solve 對所有電報執行插入搜尋 |
targets/adfgvx/blocks.py | Norbert 的兩處塊編輯搜尋,針對所有金鑰;輸出在 blocks_out.txt |
targets/adfgvx/gaps.py | 識別缺口的解析器,以及處理剩餘單字母丟失的退火程式 |
targets/adfgvx/lm_de.py | 德語四元組模型,Gutenberg 德語文字中的360萬個字母 |
targets/adfgvx/keyless.py | 不依賴金鑰的換位攻擊;對照輸出在 kl_control224.txt |
research/top50/arts/46_comments.txt | 2017年評論帖的70條評論,文字 |
targets/adfgvx/NOTES.md | 工作筆記,兩次會話 |