Encryption

使用明文轉換使密碼不可延展?

  • May 14, 2022

注意:通過延展性/不可延展性,我的意思是能夠/或不更改密文的字節/塊並讓它僅更改明文的那個字節/塊。

我了解我們使用身份驗證(通過 HMAC/UMAC/等)來驗證完整性。但是,在無法進行身份驗證的情況下(可能在儲存/CPU 能力非常有限的情況下),我們可以在加密之前轉換明文嗎?

使用幾個“輪”的移動到前面的變換,在每次迭代後反轉明文就可以做到這一點。一旦明文超過 1kb(左右),您只需要幾輪。這會產生一種雪崩效應,因此任何地方的篡改都會​​影響大量明文。

我的 MTF 轉換使用可能字節 (0-255) 的索引。每個“輪”由一個 MTF 變換、重置索引、反轉明文和另一個 MTF 變換組成。

執行一些測試表明,對於隨機 256 字節輸入的兩輪 MTF,翻轉任何位平均會改變超過 50% 的解碼位。對於 512 字節的輸入,平均值為 53%。對於(幾乎未測試的)1024 字節輸入,任何翻轉位的平均(和最低)位更改數超過 50%。

對於足夠小的輸入,異常值(更改的最小位數)是線性的。對於 512 字節(或更少)的輸入,總是通過翻轉第一個輸入字節的第一位(更右邊)來實現最少的更改位數。此外,在小輸入結束時翻轉任何位總是會導致大於 50% 的變化,但不是在開始時。這些不良影響似乎隨著 1024 字節的輸入而消失,儘管測試這需要我太長時間(每個輸入大約 2 分鐘!)來做出任何有用的陳述。

這種方法的主要問題是耗時太長。我正在使用帶有 Intel Atom CPU Z3735 @ 1.33GHz 的小型筆記型電腦。1 KB 編碼大約需要 0.034 秒。使用 ChaCha 加密一個 KB 大約需要一半的時間。

注意:變換函式是完全已知的(根據 Kerckhoff 原理)。它完全依賴於明文。除了向明文和密文添加不可延展性外,該函式絕對沒有任何作用。它在任何密碼之前都有效,而不是與。

更新:我更新了轉換函式,更改了用於轉換輪次的索引,將輪次減少到 2,並將數據輸入的執行總和添加到程序中。它現在比 ChaCha 更快,並且在 512 字節的輸入下實現了不可延展性,沒有任何偏差(在我的測試範圍內)。它在編碼時添加了一個隨機數,在解碼時會刪除該隨機數。如果有人想看看,程式碼就在這裡。

我知道我可以使程式碼更快,但我仍然認為必須有一些標準方法來解決整體問題。我發現的唯一一個現代的、類似的東西與全有或全無的變換有關,Rivest 在這裡討論了這個變換。這個想法(假設 Rivest 關於增加安全性是正確的)並沒有真正流行起來,這似乎很奇怪。

我的問題:

  1. 是否有任何現有的方法可以做類似的事情?基本上是某種現代版的俄羅斯交配
  2. 有誰知道一種可能更快的方法來轉換明文(完全獨立於密碼)並使其(可能)不可延展?
  1. 是否有任何現有的方法可以做類似的事情?基本上是某種現代版的俄羅斯交配

目前在一些 RSA 實現中使用了一個現有的想法,可以稍微調整以適應俄羅斯交配的要求。我將在下面簡要描述,然後提到這種“轉換”的潛在額外好處。

OAEP

最佳非對稱加密填充(OAEP) 是一種填充方案,通常與 RSA 加密一起使用。

該算法採用 Feistel 網路的形式,該網路使用一對隨機預言機 $ G $ 和 $ H $ 在非對稱加密之前處理明文。與任何安全活板門單向排列組合時 $ f $ ,在隨機預言機模型中證明了這種處理產生了一種組合方案,該方案在選擇明文攻擊下是語義安全的

OAEP 佈局

由於將 OAEP 用作全有或全無的轉換將需要在塊中進行處理(帶有填充),並且可能需要一些額外的調整來設計它以實現非延展性。


最後,使用這種變換函式不一定只提供不可延展性的好處。根據 Ron Rivest 的論文All-or-nothing encryption and the package transform

我們提出了一種新的分組密碼加密模式,我們稱之為全有或全無加密。這種模式具有一個有趣的定義屬性,即必須先解密整個密文,然後才能確定一個消息塊。這意味著針對全有或全無加密的蠻力搜尋會減慢等於密文中塊數的因子。我們給出了一種使用“包變換≓”作為普通加密模式的預處理步驟來實現全有或全無加密的特定方法。包變換後跟普通碼本加密還有一個有趣的特性,那就是它可以非常有效地並行實現。全有或全無加密還可以提供針對選擇明文和相關消息攻擊的保護。


下面我將舉例說明我們如何使用 OAEP 作為靈感。它顯然可以改進(我可能會使用 ChaCha QR 的變體)。我的程式碼在這裡,可能比我在下面的解釋更容易閱讀。

這可以一次性完成,並且比我之前查找/切片/重新排列數組並逐字節處理的函式要快得多。

首先,我採用了一個不平衡的 Feistel 密碼並設置了它(有 10 個雙輪)。它由 8 個 32 位的塊組成。

這些塊與其他塊的固定圓形旋轉進行異或,並在每個雙輪後移動位置。在每個雙輪中,大多數塊都會以某種方式受到大多數其他塊的影響。例如,塊 0(在一個雙輪中)受塊 1、2、4、5 和 7 的影響。奇數塊受少一個影響,例如。區塊 1 受區塊 2、3、4 和 5 的影響。

在 10 次雙輪之後,這在輸出塊 0、3、5 和 6 中實現了良好(超過 50%)的擴散。在其他“壞”塊中,擴散率約為 56%。

我們將以 128 位塊處理輸入數據,使用 Feistel 的“好”塊和 Feistel 的“壞”塊將是狀態/容量,它使用隨機數據初始化並使用最終編碼保存。因此允許我們解碼(向後),並且初始隨機性提供隨機數。

最後,我們在 Feistel 中添加了一個 128 位的“計數器”。這會保持所有已處理數據塊的異或(並從 0 開始)。這不需要保存,但確實需要更多的解碼計算,因為我們需要在開始解碼過程之前“計算”所有塊。

當我們反向解碼時,很明顯最後一個數據塊會影響任何先前的數據塊(由於保存狀態)。並且由於先前數據塊的“計數”會影響最後一個數據塊,因此所有位都會影響所有位。

它需要填充輸入,但速度非常快。在我的垃圾機上處理 1KB 的時間 <0.003 秒。對於我的垃圾測試來說,這實際上太快了,而且經常以較低的數量註冊 0。

我可以看到的問題是它會根據輸入的大小產生不同的擴散水平。如果輸入為 128 位,則翻轉的任何位的平均更改位數約為 75%。對於 1024,它約為 57%。對於 3072,它約為 53%。對於 4096,它仍然在 52.5% 左右。在 1KB 時,它約為 52%

我還沒有發現一個可以翻轉的位不會導致超過 50% 的位針對任何輸入大小發生變化。

也許我沒有得到什麼。雪崩效應,已知狀態,沒有添加加密安全,如果一個位被翻轉,則翻轉 50% 位,比 ChaCha20 更簡單,更快……看起來你正在描述一個偽隨機數生成器,一個簡單的。為什麼不使用它?它符合您的所有要求。

請參閱此處,(尤其是第 18 和 23 頁,還有更遠的地方),它在圖片中顯示了完全相同的要求。這是最快的PRNG算法,雪崩效果好,週期長。

您的機器可以在每個字(32 位、64 位)上進行大約 10 次操作,這與需要在單個字節上進行數十甚至數百次操作的正確密碼學不同。

用每一步的數據重新播種 PRNG,以將更改傳播到一個塊之外。使用兩次傳球,一次向前傳一次向後傳球,以使每一位影響其他每一位,在其自身的左側和右側。

例如,初始種子為 42(公開),明文中的第一個數據塊為“D”。PCG 使用種子 42,輸出 948。然後進行 948 XOR “D” 以獲得第一個密文塊。使用來自最後一個數據明文塊“D”和 PCG 最後狀態 948 的數據重新設置 PCG 的種子,而不僅僅是 42。要解碼,請重複該過程,因為 XOR 會取消。將42作為PCG種子,得到948作為輸出,做948異或密文(948異或“D”),得到初始數據塊“D”,現在你可以製作下一個種子來解碼第二個符號,從D和948 . 當你進行反向傳遞時,你還需要一個公共種子,否則你將不知道如何解碼,因為第二遍將覆蓋第一個。使用兩個公共種子(它們可以相同),您可以將每個傳遞視為一個單獨的過程。

以前的 PCG 狀態和數據可以與加法、異或或其他功能混合。避免乘法,以免在 PCG 狀態中引入過多的零。也就是說,PCG 種子等於 PCG 舊輸出(+ 或 XOR)目前明文塊。

此頁面提供了一些 PCG 的程式碼範例:

您可以將任何 PRNG 用於此角色,但請查看說明為什麼您不應該使用其他每個可用 PRNG 的論文。特別是緩慢的雪崩時間和模式。

引用自:https://crypto.stackexchange.com/questions/86228