Encryption

為什麼 Crypto++ 庫的 AES 定義如此之快

  • December 31, 2020

我正在嘗試比較兩種加密算法所需的 CPU 週期。一種算法是 AES,另一種算法是 B(代號)。我實現了算法 B 並且比 AES 具有更少和更簡單的操作,並且預計每次加密花費的時間/CPU 週期比 AES 少得多

我正在使用帶有 4MB 記憶體的 Intel i3,第 10 代處理器。我分別執行這兩種算法(使用隨機 16 字節輸入) $ 2^{20} $ 次並獲取所需的最小和最大 CPU 週期。

我看到算法 B 的 CPU 週期是minimum=2707866maximum=4767402。但是,對於 AES 的 crypto++ 定義,CPU 週期是minimum=2724maximum=29978194。我已經進行了多次測試,結果幾乎相似。很明顯,AES 所需的最長時間比算法 B 高得多(7 倍),但 AES 的最短時間要少得多。

然後我記錄了所有需要的 CPU 週期 $ 2^{20} $ AES 加密。我發現第一次加密佔用了最大29978194周期approx 3000(對於算法 B,每次加密都佔用幾乎相同的 CPU 週期。

我不明白 AES 加密(加密 ++ 庫)的 CPU 週期急劇減少(10000 次)。AES-NI有巫毒嗎?有人可以告訴那裡正在進行什麼樣的優化嗎?

實際上,您的數字似乎驚人地高,一個區塊有 2724 個週期 - 即使使用關鍵時間表。

Crypto++ 使用標準 AES-NI 來加密塊和生成密鑰,他們為 SBox 使用 AESKEYGENASSIST(不幸的是)。

理想情況下,預期的性能將是(對於它們的實現,而不是具有優化的動態密鑰擴展的性能):

  • 約 783 個密鑰調度週期(由 llvm-mca 估計
  • 密鑰的初始 XOR 的 1x 1 個週期
  • AESENC/AESENCLAST 10x 4 個週期

所以總共不到1000個週期。

即使我們在這裡假設 AES-256,實際操作的周期也不應超過 1500 個。2700 與此相差甚遠,表明提供 AES 數據的效率低下。

另請注意,這種測試對 AES-NI 硬體非常不公平,因為它只有在你給它 4 個或更多獨立的 AES 操作以並行計算時才會真正發光(由於每輪指令有 4 個週期的延遲,但吞吐量為 1每條指令周期)。此外請注意,Crypto++ 的密鑰調度實現是……相當乏味,優化的實現在不到 20 個週期內計算一個輪密鑰,因此整個密碼總共不到 200 個。

您可以在此處找到翻譯後的密鑰擴展程式碼。您可以在英特爾網站Agner Fog 的表格中查看指令的性能。


更公平的比較可能會採用最佳的非 AES-NI 實現、AES 的 AES-NI 實現和密碼的優化實現,並將它們在以下類別中相互對比:

  • 長消息的 CBC 加密 - 測量密碼延遲和長消息“隱藏”密鑰調度成本
  • 長消息的 CTR 加密 - 測量最大吞吐量
  • (可選)使用一種加密(大致是您測量的)的獨立密鑰調度計算 - 具有針對快速密鑰調度優化的實現(也不是目前的 Crypto++)

AES 具有高度優化的實現,包括為專門用於 AES 的英特爾 CPU 添加特殊指令。但即使沒有它,在算法的實現中可以進行多少優化也是令人驚訝的,這也是一門藝術。

我對您的測量也有疑問,最大值可能只是來自上下文切換等的雜訊。

AES 可以在現代 CPU 上以每秒數百 MB 的速度非常快地實現。即使算法從根本上更有效,你實現的東西也很難被擊敗


OpenSSL 上的軟體 AES-256-CBC 性能

openssl speed aes-256-cbc
Doing aes-256 cbc for 3s on 16 size blocks: 34522867 aes-256 cbc's in 3.00s
Doing aes-256 cbc for 3s on 64 size blocks: 8989219 aes-256 cbc's in 3.00s
Doing aes-256 cbc for 3s on 256 size blocks: 2263537 aes-256 cbc's in 3.00s
Doing aes-256 cbc for 3s on 1024 size blocks: 536651 aes-256 cbc's in 3.00s
Doing aes-256 cbc for 3s on 8192 size blocks: 68886 aes-256 cbc's in 3.00s
Doing aes-256 cbc for 3s on 16384 size blocks: 34381 aes-256 cbc's in 3.00s

OpenSSL 上的 AES-NI AES-256-CBC 性能(可通過 evp 獲得)

openssl speed -evp aes-256-cbc
Doing aes-256-cbc for 3s on 16 size blocks: 128709647 aes-256-cbc's in 3.00s
Doing aes-256-cbc for 3s on 64 size blocks: 46266772 aes-256-cbc's in 3.00s
Doing aes-256-cbc for 3s on 256 size blocks: 11740574 aes-256-cbc's in 3.00s
Doing aes-256-cbc for 3s on 1024 size blocks: 2953460 aes-256-cbc's in 3.00s
Doing aes-256-cbc for 3s on 8192 size blocks: 368469 aes-256-cbc's in 3.00s
Doing aes-256-cbc for 3s on 16384 size blocks: 181790 aes-256-cbc's in 3.00s

大約 5 倍的加速。

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