Arithmetic

加法模數究竟是什麼2322322^{32}在密碼學中?

  • October 21, 2012

編輯:我一直對此感到困惑。我一直想說的是加法模 $ 2^{32} $ 不像問題最初所說的那樣加模32。感謝您指出這一點。


我找不到這方面的任何資訊,我真的很想知道。我們在類數論中討論過,在對除法算法做了一些證明之後,我們做了一些模運算。我的理解是加法模的定義 $ 2^{32} $ 是: $ a +_n b = (a + b) \bmod (n) $ .

因此,如果我將例如 27 添加到 8 模 32,我會得到類似 $ (27 + 8) \bmod (32) = (35) \bmod (32) = 3 $ .

這是正確的嗎?提到加法模時,這是否與雜湊算法相同 $ 2^{32} $ ? 為什麼我在任何地方都找不到這個?

為什麼沒有關於加法模數的詳細資訊的 Wikipedia 文章 $ 2^{32} $ 這是關於密碼學的討論?

我問這是否與談論的雜湊算法相同,因為據我所知,這裡的答案說在Java中加法模 $ 2^{32} $ 與簡單地寫“+”相同,但我認為簡單的總和不可能相同。我完全迷路了。

在密碼學中,加法模 $ n $ (在哪裡 $ n $ 是一個正整數,也許 $ n=32 $ 就像原來的問題一樣,或者 $ n=2^{32} $ 如在修改後的問題中)通常被理解為來自的應用程序 $ \mathbb Z\times \mathbb Z $ 到 $ \mathbb Z $ , $ (a,b)\mapsto c $ 和 $ c $ 這樣 $ 0\le c<n $ 和 $ (a+b-c) $ 是的倍數 $ n $ . 這也是數學中的常識,儘管結果可能是 $ \mathbb Z/n\mathbb Z $ (記起 $ \mathbb Z $ 是有符號整數的集合,而 $ \mathbb Z/n\mathbb Z $ 是關係的等價類的集合:等於模 $ n $ ).

我們可以寫 $ (a+b)\bmod n=c $ 使用\bmod在 $ \TeX $ . 這暗示 $ a+b\equiv c\pmod n $ 使用\pmod在 $ \TeX $ , 但只有前者限制 $ c $ 在範圍內 $ [0\dots n-1] $ .

當模數 $ n $ 是個 $ k $ - 次方 $ 2 $ ( $ n=2^k $ ), 加法模 $ n $ 也被稱為 $ k $ 位加法。因此,加法模 $ 32 $ 是相同的 $ 5 $ -位加法和加法模 $ 2^{32} $ 是相同的 $ 32 $ 位加法。

通常,在密碼學中,我們將數字同化為位串,然後輸出 $ c $ 運算符的不是數字,而是表示的位串 $ c $ 在基地 $ 2 $ (正好結束 $ \lceil \log_2n\rceil $ 位和最高有效位在前,除非另有說明)。

因此加法模的結果 $ 32 $ 的 $ 27 $ 和 $ 8 $ 是整數 $ 3 $ ,或 bitstring 00011,取決於上下文。和加法模的結果 $ 2^{32} $ 的 $ 2000000000 $ ( 0x77359400) 和 $ 3000000000 $ ( 0xB2D05E00) 是 $ 705032704 $ ( 0x2A05F200) 或比特環00101010000001011111001000000000,因為 $ 5000000000-705032704=2^{32} $ .

有時輸入 $ a $ 或者 $ b $ 的運算符被限制為非負數,或/和小於 $ n $ , 或/和位串,可能是固定的或有限的大小。有時輸出範圍為 $ c $ 是 $ -n/2\le c<n/2 $ 而不是 $ 0\le c<n $ (例如,在缺少無符號 32 位類型的上下文中實現 32 位加法,見下文)。YMMV。

有一個關於模組化算術的維基百科條目,這是對該主題的更好介紹,但缺乏對加密和位串討論的專業化。


下面的討論完全是關於 Java 的(除了一些 Java Card 中的語言限制,它可能不支持 typelong甚至int),因此這裡有點離題,但是很好。

當使用類型的變數時long(also int, short, byte)(a+b)&0xffffffffLab模的總和 $ 2^{32} $ 在密碼學意義上,類型為long. 該&0xffffffffL技術適用於運營商+ - * & | ^ ~(但不是% /)。它可以擴展到任何模數 $ n=2^k $ 和 $ 0\le k\le63 $ 通過調整常數,即 $ n-1 $ . 此外,當 $ 0\le k\le31 $ 我們可以刪除L, 如果兩者ab都是類型int,short或者byte,結果將是類型int

對變數進行操作的運算符+ - * & | ^ ~(但不是% /)的定義int是這樣的,您可以假設這些運算符以模數工作 $ 2^{32} $ 如密碼學中所定義,但范圍內的數字除外 $ [2^{31}\dots 2^{32}-1] $ int在 Java中表示為否定。這使程式碼更清晰、更簡單、更快,並且(對於數組)節省了記憶體。使用該技術是因為在 Java 7 之前,Java 中沒有無符號類型。

對於範圍內n的類型int $ [1\dots2^{31}-1] $ 和操作數a和範圍內b的類型int $ [0\dots2^{30}-1] $ ,(a+b)%n是密碼學意義上的a和和b模數,類型為。這不適用於所有輸入操作數,原因有兩個:n``int

  • 當運算符的左操作數%為負數且不是右操作數的倍數時,結果為負數;
  • (a+b)被定義為整數 $ c $ 和 $ -2^{31}\le c<2^{31} $ 和 $ c\equiv a+b\pmod{2^{32}} $ , 從中可以推斷出某個時候 $ (\mathtt{(a+b)%n})\not\equiv (a+b)\pmod n $ (儘管第二個問題在 $ n $ 是二的冪,包括 $ n=32 $ ).

請注意,除了教育/測試目的之外,在 Java 中實現加密原語很少是一個好主意:在生產中,應該使用從 Java 呼叫的更有效的原語。

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