Java での AES-NI の効力とか性能とか

Java って AES-NI 効いてるの?』って17歳女子高生の素朴な疑問から。

結果: 128KB のバイト配列を食わせた結果

AES-NI あり 663,478 ns
AES-NI なし 1,880,994 ns

2.8 倍ぐらいはやい。

OpenSSLを使ったベンチ のことを思うと振るわないけど効果はあるのね。

環境

データ処理方法

次のテストコードを回して出力された12回分の結果から、最低値と最高値を除いた10回分を平均。
JIT の影響があるので、最初に100回空回りさせておく。

public class AESTest {
    public static void main(String[] args) {
        byte[] src = new byte[128*1024];
        byte[] key = "foobar".getBytes();

        try {
            SecureRandom random = new SecureRandom(key);
            byte buff[] = new byte[256 >> 3];
            random.nextBytes(buff);
            for (int i=0; i < 100 + 12; i++) {
                Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
                cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(buff, "AES"));
                long now = System.nanoTime();
                cipher.doFinal(src);
                long diff = System.nanoTime() - now;
                if (100 <= i)
                    System.out.println("takes " + diff);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

ほぼ生データ

AES-NI 有効

> java -XX:+UseAES -XX:+UseAESIntrinsics test.AESTest
takes 581978
takes 786868
takes 589961
takes 540164
takes 540924
takes 813097
takes 813097
takes 699819
takes 640519
takes 677771
takes 724527
takes 579317

AES-NI 無効

> java -XX:-UseAES -XX:-UseAESIntrinsics test.AESTest
takes 1518997
takes 2549908
takes 1784708
takes 2340077
takes 1783947
takes 1794591
takes 1791931
takes 1792690
takes 1759999
takes 2638858
takes 1624673
takes 1587420

参考ページ

感想:適当なバイト列から各暗号アルゴリズム用に適切な鍵を作ってくれるユーティリティクラスが欲しいよね。56bitとか128bitとか256bitとか用意するの面倒('A`)