Added bouncycastle AES-GCM performance benchmark
This commit is contained in:
parent
752a28f4b7
commit
ed89b3fd6d
156
Dorkbox-Util/test/dorkbox/util/crypto/PerformanceTest.java
Normal file
156
Dorkbox-Util/test/dorkbox/util/crypto/PerformanceTest.java
Normal 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");
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user