8215643: Microbenchmarks for KeyAgreement and Cipher

Adding some missing microbenchmarks for crypto algorithms

Reviewed-by: jnimeh
This commit is contained in:
Adam Petcher 2019-01-02 13:06:04 -05:00
parent 99bb6c77b3
commit df05de6ea7
4 changed files with 490 additions and 0 deletions

View File

@ -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);
}
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}