AES-NIという加速装置のお話
今回は、暗号の話をしましょう。といっても、難しい数学の話をするわけではありませんよ。ただ、数個のコマンドをたたくだけです。
インターネットという開かれた空間の中であんまり収集されると困る情報をやりとりするのに暗号は重要です。弊社では広告配信のステータスをユーザのブラウザを介して送受信するので、そこで最も暗号化処理が活躍します。
私の勝手なイメージですが、ブロック暗号の中ではBlowfishが処理速度が速いと思っていました。他にも3DESやAESといったよく使われる暗号方式はありますが、それらはBlowfishと比べて暗号強度は強いが処理は遅いものだと思っていました。しかし、世の中にはAES-NIという加速装置があるではありませんか! この加速装置がどのくらいの性能であるのかみてみましょう。
AES-NIは、AES (Advanced Encryption Standard)専用のCPU命令群です。AESのために専用の回路がCPUの中にあるわけです。CPUに足し算やかけ算をさせるのと同じように、AES(の処理の1ステップ)をやれ、と命令できるわけです。さすが暗号標準と言われるだけありますね。すさまじい優遇措置です。
速度比較
opensslコマンドを使ってベンチマークをします。コマンドは次の通り。
openssl speed blowfish camellia-256-cbc des-ede3 aes-256-cbc
これで、Blowfish, Camellia, 3DES, AESのベンチマークができます。使用マシンのCPUは、AMD Opteron(R) 6276 2.3GHz。opensslのバージョンなどは結果を参照ください。
結果は次のようになりました。
OpenSSL 1.0.1i 6 Aug 2014 built on: Mon Aug 11 21:45:22 CEST 2014 options:bn(64,64) rc4(8x,int) des(idx,cisc,16,int) aes(partial) blowfish(idx) compiler: gcc -fPIC -DOPENSSL_PIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -m64 -DL_ENDIAN -DTERMIO -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -Wl,-z,relro -Wa,--noexecstack -Wall -DMD32_REG_T=int -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM The 'numbers' are in 1000s of bytes per second processed. type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes des ede3 20369.30k 20810.84k 20913.41k 20885.16k 20995.08k blowfish cbc 74977.91k 81826.65k 85267.20k 86458.48k 86436.52k aes-256 cbc 55840.73k 58654.36k 59740.07k 141040.98k 142798.34k camellia-256 cbc 82854.92k 104024.62k 111749.97k 114186.92k 114657.96k
3DESはやっぱり遅いですね。Blowfishの1∕4程度の速度しか出ていません。
そして、AESもBlowfishに比べれば遅……くもないですね。1KBを超えてから突如として性能が良くなっています。実は加速装置はまだ使っていないはずなんですが。AESのブロックサイズは16 Bytesですし、256 Bytesと1KBに隔たりがある理由はなんでしょう? 今後の考察対象になりますね。メモリの速度とかまで関係してくると最早わかりませんが。
また、試しに比較対象にしてみたCamelliaが意外に速かったです。これ、使えるかも。
本番
さて、AES-NIを使うためには次のようなコマンドを使わないとならないようです。
openssl speed -evp aes-256-cbc
ベンチマーク用の暗号化プログラムではなく、通常利用する(openssl enc
)ための暗号化プログラムを使うということでしょうか。時間があったらソースコードを見てみたいですね。
-evp
をつけた複数のアルゴリズムを同時に速度比較できないようなので、AESだけで実行します。結果は次のようになりました。
OpenSSL 1.0.1i 6 Aug 2014 built on: Mon Aug 11 21:45:22 CEST 2014 options:bn(64,64) rc4(8x,int) des(idx,cisc,16,int) aes(partial) blowfish(idx) compiler: gcc -fPIC -DOPENSSL_PIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -m64 -DL_ENDIAN -DTERMIO -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -Wl,-z,relro -Wa,--noexecstack -Wall -DMD32_REG_T=int -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM The 'numbers' are in 1000s of bytes per second processed. type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes aes-256-cbc 252170.02k 341556.71k 386134.44k 395323.59k 397369.34k
先ほどの結果と並べてみましょう。
des ede3 20369.30k 20810.84k 20913.41k 20885.16k 20995.08k blowfish cbc 74977.91k 81826.65k 85267.20k 86458.48k 86436.52k aes-256 cbc 55840.73k 58654.36k 59740.07k 141040.98k 142798.34k camellia-256 cbc 82854.92k 104024.62k 111749.97k 114186.92k 114657.96k
そして、併せてグラフ化しました。
圧倒的な速さ! Blowfishの3倍〜4.5倍くらいの速度が出ています! もとのAESとの比較では、256Bytesのときに6.4倍にもなっています。さすが、暗号標準は優遇されていますね。
Intelでは?
せっかくなので、IntelのCPUでも比較してみました。Intel(R) Xeon(R) CPU E5-2620 v2 @ 2.10GHzです。1コアあたりの公称周波数は上で使ったAMDのマシンよりちょっと劣りますね。
コマンドと
openssl speed blowfish camellia-256-cbc des-ede3 aes-256-cbc -evp aes-256-cbc
結果。
OpenSSL 1.0.1e 11 Feb 2013 built on: Wed Aug 6 18:48:11 UTC 2014 options:bn(64,64) rc4(16x,int) des(idx,cisc,16,int) aes(partial) blowfish(idx) compiler: gcc -fPIC -DOPENSSL_PIC -DZLIB -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -m64 -DL_ENDIAN -DTERMIO -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -Wl,-z,relro -Wa,--noexecstack -Wall -DMD32_REG_T=int -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM The 'numbers' are in 1000s of bytes per second processed. type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes des ede3 20447.94k 20658.20k 20828.21k 20768.77k 20788.57k blowfish cbc 92491.66k 97588.27k 98745.43k 99492.39k 99396.27k aes-256 cbc 70233.34k 73782.06k 75054.58k 75234.65k 75423.74k camellia-256 cbc 63901.00k 87021.12k 95395.67k 98536.54k 99046.74k aes-256-cbc 345117.58k 360506.67k 364538.03k 366619.06k 365707.26k
AMDと比較して、周波数が低いので全体的に遅くなるかなと思いきや、Blowfishだけなぜか速くなっています。SSEなどベクトル演算関係の命令の速さの違いとか、opensslのバージョンによる実装の違いとか、あるかもしれませんね。
AES-NIを使わない場合(aes-256 cbc
のほう)と使った場合(aes-256-cbc
のほう)を比較すると、どの平文のサイズでも安定して4.9倍くらいになっています。
まとめ
Blowfishと比べるとその他のアルゴリズムは遅いものと思っていましたが、完全に勝手な思い込みでした。3DESが3回暗号化している分3倍遅いくらいで、AESもチートハードウェアのアシストがなくてもそれなりのスピードでした。そして、今まで使おうとも思ったことがなかったCamelliaが、AMDのCPUではBlowfishを上回るスピードを出してくれたのも収穫でした。