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