8215643: Microbenchmarks for KeyAgreement and Cipher
authorapetcher
Wed, 02 Jan 2019 13:06:04 -0500
changeset 53124 a22e41395bfa
parent 53123 96ce82319e82
child 53125 dee9426ef417
8215643: Microbenchmarks for KeyAgreement and Cipher Summary: adding some missing microbenchmarks for crypto algorithms Reviewed-by: jnimeh
test/micro/org/openjdk/bench/javax/crypto/full/CipherBench.java
test/micro/org/openjdk/bench/javax/crypto/full/KeyAgreementBench.java
test/micro/org/openjdk/bench/javax/crypto/small/CipherBench.java
test/micro/org/openjdk/bench/javax/crypto/small/KeyAgreementBench.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/javax/crypto/full/CipherBench.java	Wed Jan 02 13:06:04 2019 -0500
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.javax.crypto.full;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Setup;
+
+import javax.crypto.*;
+import javax.crypto.spec.*;
+import java.security.*;
+import java.security.spec.*;
+
+
+public abstract class CipherBench extends CryptoBase {
+
+    @Param({})
+    private String permutation;
+
+    @Param({})
+    private String mode;
+
+    @Param({})
+    private String padding;
+
+    @Param({})
+    private int keyLength;
+
+    @Param({})
+    private int dataSize;
+
+    private int decryptCount = 0;
+    private byte[] data;
+    private byte[][] encryptedData = new byte[2][];
+    private byte[] outBuffer;
+    private Cipher[] encryptCipher = new Cipher[2];
+    private Cipher decryptCipher;
+    protected SecretKeySpec ks;
+    protected byte[] iv;
+
+    protected abstract int ivLength();
+    protected abstract AlgorithmParameterSpec makeParameterSpec();
+
+    protected void init(Cipher c, int mode, SecretKeySpec ks)
+        throws GeneralSecurityException {
+
+        if (iv == null) {
+            iv = fillSecureRandom(new byte[ivLength()]);
+        }
+
+        // toggle some bits in the IV to get around IV reuse defenses
+        iv[0] ^= 0xFF;
+        AlgorithmParameterSpec paramSpec = makeParameterSpec();
+
+        c.init(mode, ks, paramSpec);
+    }
+
+    protected void init(Cipher c, int mode, SecretKeySpec ks, Cipher fromCipher)
+        throws GeneralSecurityException {
+
+        AlgorithmParameters params = fromCipher.getParameters();
+        c.init(mode, ks, fromCipher.getParameters());
+    }
+
+    @Setup
+    public void setup() throws GeneralSecurityException {
+        setupProvider();
+
+        String transform = permutation + "/" + mode + "/" + padding;
+        byte[] keystring = fillSecureRandom(new byte[keyLength / 8]);
+        ks = new SecretKeySpec(keystring, permutation);
+        data = fillRandom(new byte[dataSize]);
+        for (int i = 0; i < 2; i++) {
+            encryptCipher[i] = makeCipher(prov, transform);
+            init(encryptCipher[i], Cipher.ENCRYPT_MODE, ks);
+            encryptedData[i] = encryptCipher[i].doFinal(data);
+        }
+        outBuffer = new byte[dataSize + 128]; // extra space for tag, etc
+        decryptCipher = makeCipher(prov, transform);
+    }
+
+    @Benchmark
+    public void encrypt() throws GeneralSecurityException {
+        init(encryptCipher[1], Cipher.ENCRYPT_MODE, ks);
+        encryptCipher[1].doFinal(data, 0, data.length, outBuffer);
+    }
+
+    @Benchmark
+    public void decrypt() throws GeneralSecurityException {
+        init(decryptCipher, Cipher.DECRYPT_MODE, ks,
+            encryptCipher[decryptCount]);
+        decryptCipher.doFinal(encryptedData[decryptCount], 0,
+            encryptedData[decryptCount].length, outBuffer);
+        decryptCount = (decryptCount + 1) % 2;
+    }
+
+    public static class GCM extends CipherBench {
+
+        @Param({"AES"})
+        private String permutation;
+
+        @Param({"GCM"})
+        private String mode;
+
+        @Param({"NoPadding", "PKCS5Padding"})
+        private String padding;
+
+        @Param({"128", "256"})
+        private int keyLength;
+
+        @Param({"1024", "" + 16 * 1024})
+        private int dataSize;
+
+        protected int ivLength() {
+            return 32;
+        }
+        protected AlgorithmParameterSpec makeParameterSpec() {
+            return new GCMParameterSpec(96, iv, 0, 16);
+        }
+
+        private byte[] aad;
+
+        protected void init(Cipher c, int mode, SecretKeySpec ks)
+            throws GeneralSecurityException {
+
+            if (aad == null) {
+                aad = fillSecureRandom(new byte[5]);
+            }
+
+            super.init(c, mode, ks);
+            c.updateAAD(aad);
+        }
+
+        protected void init(Cipher c, int mode, SecretKeySpec ks,
+            Cipher fromCipher) throws GeneralSecurityException {
+
+            super.init(c, mode, ks, fromCipher);
+            c.updateAAD(aad);
+        }
+    }
+
+    public static class CTR extends CipherBench {
+
+        @Param({"AES"})
+        private String permutation;
+
+        @Param({"CTR"})
+        private String mode;
+
+        @Param({"NoPadding"})
+        private String padding;
+
+        @Param({"128", "256"})
+        private int keyLength;
+
+        @Param({"1024", "" + 16 * 1024})
+        private int dataSize;
+
+        protected int ivLength() {
+            return 16;
+        }
+        protected AlgorithmParameterSpec makeParameterSpec() {
+            return new IvParameterSpec(iv);
+        }
+    }
+
+    public static class ChaCha20Poly1305 extends CipherBench {
+
+        @Param({"ChaCha20-Poly1305"})
+        private String permutation;
+
+        @Param({"None"})
+        private String mode;
+
+        @Param({"NoPadding"})
+        private String padding;
+
+        @Param({"256"})
+        private int keyLength;
+
+        @Param({"1024", "" + 16 * 1024})
+        private int dataSize;
+
+        protected int ivLength() {
+            return 12;
+        }
+        protected AlgorithmParameterSpec makeParameterSpec() {
+            return new IvParameterSpec(iv);
+        }
+    }
+
+    public static class ChaCha20 extends CipherBench {
+
+        @Param({"ChaCha20"})
+        private String permutation;
+
+        @Param({"None"})
+        private String mode;
+
+        @Param({"NoPadding"})
+        private String padding;
+
+        @Param({"256"})
+        private int keyLength;
+
+        @Param({"1024", "" + 16 * 1024})
+        private int dataSize;
+
+        protected int ivLength() {
+            return 12;
+        }
+        protected AlgorithmParameterSpec makeParameterSpec() {
+            return new ChaCha20ParameterSpec(iv, 0);
+        }
+
+        protected void init(Cipher c, int mode, SecretKeySpec ks,
+            Cipher fromCipher) throws GeneralSecurityException {
+
+            AlgorithmParameterSpec paramSpec =
+                new ChaCha20ParameterSpec(fromCipher.getIV(), 0);
+            c.init(mode, ks, paramSpec);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/javax/crypto/full/KeyAgreementBench.java	Wed Jan 02 13:06:04 2019 -0500
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.javax.crypto.full;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Setup;
+
+import java.security.*;
+import javax.crypto.KeyAgreement;
+
+public abstract class KeyAgreementBench extends CryptoBase {
+
+    @Param({})
+    private String kpgAlgorithm;
+
+    @Param({})
+    private String algorithm;
+
+    @Param({})
+    private int keyLength;
+
+
+    private KeyAgreement keyAgreement;
+    private PrivateKey privKey;
+    private PublicKey pubKey;
+
+    @Setup
+    public void setup() throws NoSuchAlgorithmException {
+        setupProvider();
+        KeyPairGenerator generator = (prov == null) ?
+            KeyPairGenerator.getInstance(kpgAlgorithm) :
+            KeyPairGenerator.getInstance(kpgAlgorithm, prov);
+        generator.initialize(keyLength);
+        KeyPair kpA = generator.generateKeyPair();
+        privKey = kpA.getPrivate();
+        KeyPair kpB = generator.generateKeyPair();
+        pubKey = kpB.getPublic();
+
+        keyAgreement = (prov == null) ?
+            KeyAgreement.getInstance(algorithm) :
+            KeyAgreement.getInstance(algorithm, prov);
+    }
+
+    @Benchmark
+    public byte[] generateSecret() throws InvalidKeyException {
+        keyAgreement.init(privKey);
+        keyAgreement.doPhase(pubKey, true);
+        return keyAgreement.generateSecret();
+    }
+
+    public static class DiffieHellman extends KeyAgreementBench {
+
+        @Param({"DiffieHellman"})
+        private String kpgAlgorithm;
+
+        @Param({"DiffieHellman"})
+        private String algorithm;
+
+        @Param({"2048"})
+        private int keyLength;
+
+    }
+
+    public static class EC extends KeyAgreementBench {
+
+        @Param({"EC"})
+        private String kpgAlgorithm;
+
+        @Param({"ECDH"})
+        private String algorithm;
+
+        @Param({"224", "256", "384", "521"})
+        private int keyLength;
+
+    }
+
+    public static class XDH extends KeyAgreementBench {
+
+        @Param({"XDH"})
+        private String kpgAlgorithm;
+
+        @Param({"XDH"})
+        private String algorithm;
+
+        @Param({"255", "448"})
+        private int keyLength;
+
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/javax/crypto/small/CipherBench.java	Wed Jan 02 13:06:04 2019 -0500
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.javax.crypto.small;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Setup;
+
+import javax.crypto.*;
+import javax.crypto.spec.*;
+import java.security.*;
+import java.security.spec.*;
+
+
+public abstract class CipherBench extends
+    org.openjdk.bench.javax.crypto.full.CipherBench {
+
+    public static class GCM extends
+        org.openjdk.bench.javax.crypto.full.CipherBench.GCM {
+
+        @Param({"AES"})
+        private String permutation;
+
+        @Param({"GCM"})
+        private String mode;
+
+        @Param({"NoPadding"})
+        private String padding;
+
+        @Param({"128"})
+        private int keyLength;
+
+        @Param({"" + 16 * 1024})
+        private int dataSize;
+    }
+
+    public static class ChaCha20Poly1305 extends
+        org.openjdk.bench.javax.crypto.full.CipherBench.ChaCha20Poly1305 {
+
+        @Param({"ChaCha20-Poly1305"})
+        private String permutation;
+
+        @Param({"None"})
+        private String mode;
+
+        @Param({"NoPadding"})
+        private String padding;
+
+        @Param({"256"})
+        private int keyLength;
+
+        @Param({"" + 16 * 1024})
+        private int dataSize;
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/javax/crypto/small/KeyAgreementBench.java	Wed Jan 02 13:06:04 2019 -0500
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.javax.crypto.small;
+
+import org.openjdk.jmh.annotations.Param;
+
+public abstract class KeyAgreementBench extends
+    org.openjdk.bench.javax.crypto.full.KeyAgreementBench {
+
+    public static class EC extends
+        org.openjdk.bench.javax.crypto.full.KeyAgreementBench.EC {
+
+        @Param({"EC"})
+        private String kpgAlgorithm;
+
+        @Param({"ECDH"})
+        private String algorithm;
+
+        @Param({"256"})
+        private int keyLength;
+
+    }
+
+    public static class XDH extends
+        org.openjdk.bench.javax.crypto.full.KeyAgreementBench.XDH {
+
+        @Param({"XDH"})
+        private String kpgAlgorithm;
+
+        @Param({"XDH"})
+        private String algorithm;
+
+        @Param({"255"})
+        private int keyLength;
+
+    }
+}
+