0

I am testing a case where a 32 bytes data is encrypted multiple times with different public keys using RSA. Here is my code:

    List<Long> colDurSetup = new ArrayList();
    List<Long> colDurEnc = new ArrayList();
    List<Long> colDurDec = new ArrayList();
    List<PublicKey> pubKeys = new ArrayList();
    List<PrivateKey> privKeys = new ArrayList();

    for(int i=0; i<10;i++) {
        long timeStart = System.currentTimeMillis();
        KeyPair kp = buildKeyPair();
        long timeEnd = System.currentTimeMillis();
        long dur = timeEnd-timeStart;
        colDurSetup.add(dur);
        pubKeys.add(kp.getPublic());
        System.out.println(kp.getPublic().getEncoded().length);
        privKeys.add(kp.getPrivate());
        System.out.println(kp.getPrivate().getEncoded().length);
    }

    SecureRandom r = new SecureRandom();
    byte[] data = new byte[32];
    r.nextBytes(data);
    System.err.println(Arrays.toString(data));

    System.out.println("data length "+data.length);

    for(int i=0;i<10;i++) {
        long timeStart = System.nanoTime();
        byte[] ciphertext = encrypt(pubKeys.get(i), data);
        long timeEnd = System.nanoTime();
        long dur = timeEnd-timeStart;
        System.out.println("enc duration "+dur);
        colDurEnc.add(dur);
        System.out.println(timeStart);
        System.out.println(timeEnd);

        System.out.println("ciphertext length "+ciphertext.length);
        System.err.println("cip "+Arrays.toString(ciphertext));

        long timeStart2 = System.nanoTime();
        byte[] decrypted = decrypt(privKeys.get(i), ciphertext);
        long timeEnd2 = System.nanoTime();

        long dur2 = timeEnd2-timeStart2;
        colDurDec.add(dur2);
        System.err.println("dec "+Arrays.toString(decrypted));
        System.out.println("dec duration "+dur2);
    }

public static KeyPair buildKeyPair() throws NoSuchAlgorithmException {
    final int keySize = 2048;
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
    keyPairGenerator.initialize(keySize, random);      
    return keyPairGenerator.genKeyPair();
}

public static byte[] encrypt(PublicKey publicKey, byte[] message) throws Exception {
    Cipher cipher = Cipher.getInstance("RSA");  
    cipher.init(Cipher.ENCRYPT_MODE, publicKey, random);  
    return cipher.doFinal(message);  
}

public static byte[] decrypt(PrivateKey privateKey, byte [] encrypted) throws Exception {
    Cipher cipher = Cipher.getInstance("RSA");  
    cipher.init(Cipher.DECRYPT_MODE, privateKey);
    return cipher.doFinal(encrypted);
}

When I run it, I noticed that the first iteration requires more time to encrypt and decrypt than the rest of iterations and I'm not sure why. Here is the result:

enc duration 231
dec duration 4
enc duration 0
dec duration 4
enc duration 0
dec duration 4
enc duration 0
dec duration 4
enc duration 0
dec duration 4
enc duration 1
dec duration 3
enc duration 0
dec duration 4
enc duration 0
dec duration 4
enc duration 0
dec duration 4
enc duration 0
dec duration 4

I assumme because it runs the same then all iteration should give the same duration but turns out I was wrong. Is there anything wrong in the code?

Ihsan Haikal
  • 1,085
  • 4
  • 16
  • 42
  • 5
    Ask google for "java JIT".... – piet.t Mar 21 '19 at 13:08
  • @piet.t so I assume it is normal because of JIT and compiler work? – Ihsan Haikal Mar 21 '19 at 13:10
  • what is the time output? https://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java – luk2302 Mar 21 '19 at 13:11
  • @luk2302 editing it now in the question – Ihsan Haikal Mar 21 '19 at 13:12
  • I doubt its a JIT effect after just one iteration. It's probably some one time work in one of the classes, possibly initializing a default SecureRandom instance. – President James K. Polk Mar 21 '19 at 13:38
  • 2
    It would be easier to tell if you actually included the encrypt() methode you are measuring. Anyway, you need to do an warm-up run where you eliminate all lazy processing time, like load of crypto providers, initialization of random generators etc ... – Ebbe M. Pedersen Mar 21 '19 at 13:53
  • @EbbeM.Pedersen i've already added the other methods. Could you tell me how do I eliminate the lazy processing time? – Ihsan Haikal Mar 21 '19 at 13:59
  • 1
    If you want qualified answer to why a metode takes some time, you should provide the code for that specific metode... as for the lazy processing you properbly just have to live with it. Classes needs to be loaded, Crypto providers needs to be started etc .. You properly only see the spike on the first call. – Ebbe M. Pedersen Mar 21 '19 at 15:08
  • I'd bet that JIT is not related to your issues. Check this https://stackoverflow.com/questions/137212/how-to-solve-slow-java-securerandom – Vasilii Ruzov Mar 21 '19 at 15:37

0 Answers0