為什麼 Crypto++ 庫的 AES 定義如此之快
我正在嘗試比較兩種加密算法所需的 CPU 週期。一種算法是 AES,另一種算法是 B(代號)。我實現了算法 B 並且比 AES 具有更少和更簡單的操作,並且預計每次加密花費的時間/CPU 週期比 AES 少得多
我正在使用帶有 4MB 記憶體的 Intel i3,第 10 代處理器。我分別執行這兩種算法(使用隨機 16 字節輸入) $ 2^{20} $ 次並獲取所需的最小和最大 CPU 週期。
我看到算法 B 的 CPU 週期是
minimum=2707866
和maximum=4767402
。但是,對於 AES 的 crypto++ 定義,CPU 週期是minimum=2724
和maximum=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 倍的加速。