Added bouncycastle AES-GCM performance benchmark

This commit is contained in:
nathan 2016-03-12 02:37:08 +01:00
parent 752a28f4b7
commit ed89b3fd6d

View File

@ -0,0 +1,156 @@
package dorkbox.util.crypto;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.engines.AESFastEngine;
import org.bouncycastle.crypto.modes.GCMBlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
import java.security.SecureRandom;
import java.util.Random;
// See: https://stackoverflow.com/questions/25992131/slow-aes-gcm-encryption-and-decryption-with-java-8u20
// java8 performance is 3 MB/s. BC is ~43 MB/s
public
class PerformanceTest {
private static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(PerformanceTest.class);
private static String entropySeed = "asdjhasdkljalksdfhlaks4356268909087s0dfgkjh255124515hasdg87";
public static
void main(String[] args) throws Exception {
final int max = 5;
for (int i = 0; i < max; i++) {
System.out.println("Warming up " + (i+1) + " of " + max);
new PerformanceTest(true);
}
new PerformanceTest(false);
}
PerformanceTest(boolean isWarmup) {
final byte[] bytes = new byte[64 * 1024];
byte[] encrypted = null;
final byte[] aesKey = new byte[32];
final byte[] aesIV = new byte[12];
final Random random = new SecureRandom(entropySeed.getBytes());
random.nextBytes(bytes);
random.nextBytes(aesKey);
random.nextBytes(aesIV);
int length = bytes.length;
if (!isWarmup) {
System.out.println("Benchmarking AES-256 GCM encryption");
}
long javaEncryptInputBytes = 0;
long javaEncryptStartTime = System.currentTimeMillis();
// convert to bouncycastle
GCMBlockCipher aesEngine = new GCMBlockCipher(new AESFastEngine());
CipherParameters aesIVAndKey = new ParametersWithIV(new KeyParameter(aesKey), aesIV);
long encryptInitTime = 0L;
long encryptUpdate1Time = 0L;
long encryptDoFinalTime = 0L;
while (System.currentTimeMillis() - javaEncryptStartTime < 10000) {
random.nextBytes(aesIV);
long n1 = System.nanoTime();
aesEngine.reset();
aesEngine.init(true, aesIVAndKey);
if (encrypted == null) {
int minSize = aesEngine.getOutputSize(length);
encrypted = new byte[minSize];
}
long n2 = System.nanoTime();
int actualLength = aesEngine.processBytes(bytes, 0, length, encrypted, 0);
long n3 = System.nanoTime();
try {
actualLength += aesEngine.doFinal(encrypted, actualLength);
} catch (Exception e) {
logger.error("Unable to perform AES cipher.", e);
}
if (encrypted.length != actualLength) {
byte[] result = new byte[actualLength];
System.arraycopy(encrypted, 0, result, 0, result.length);
encrypted = result;
}
long n4 = System.nanoTime();
javaEncryptInputBytes += actualLength;
encryptInitTime = n2 - n1;
encryptUpdate1Time = n3 - n2;
encryptDoFinalTime = n4 - n3;
}
long javaEncryptEndTime = System.currentTimeMillis();
if (!isWarmup) {
System.out.println("Time init (ns): " + encryptInitTime);
System.out.println("Time update (ns): " + encryptUpdate1Time);
System.out.println("Time do final (ns): " + encryptDoFinalTime);
System.out.println("Java calculated at " +
(javaEncryptInputBytes / 1024 / 1024 / ((javaEncryptEndTime - javaEncryptStartTime) / 1000)) + " MB/s");
System.out.println("Benchmarking AES-256 GCM decryption");
}
long javaDecryptInputBytes = 0;
long javaDecryptStartTime = System.currentTimeMillis();
length = encrypted.length;
long decryptInitTime = 0L;
long decryptUpdate1Time = 0L;
long decryptDoFinalTime = 0L;
while (System.currentTimeMillis() - javaDecryptStartTime < 10000) {
long n1 = System.nanoTime();
aesEngine.reset();
aesEngine.init(false, aesIVAndKey);
long n2 = System.nanoTime();
int actualLength = aesEngine.processBytes(encrypted, 0, length, bytes, 0);
long n3 = System.nanoTime();
try {
actualLength += aesEngine.doFinal(bytes, actualLength);
} catch (Exception e) {
logger.debug("Unable to perform AES cipher.", e);
}
long n4 = System.nanoTime();
javaDecryptInputBytes += actualLength;
decryptInitTime += n2 - n1;
decryptUpdate1Time += n3 - n2;
decryptDoFinalTime += n4 - n3;
}
long javaDecryptEndTime = System.currentTimeMillis();
if (!isWarmup) {
System.out.println("Time init (ns): " + decryptInitTime);
System.out.println("Time update 1 (ns): " + decryptUpdate1Time);
System.out.println("Time do final (ns): " + decryptDoFinalTime);
System.out.println("Total bytes processed: " + javaDecryptInputBytes);
System.out.println("Java calculated at " +
(javaDecryptInputBytes / 1024 / 1024 / ((javaDecryptEndTime - javaDecryptStartTime) / 1000)) + " MB/s");
}
}
}