1 /*
   2  * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 package org.openjdk.bench.javax.crypto;
  24 
  25 import java.security.InvalidKeyException;
  26 import java.security.NoSuchAlgorithmException;
  27 import java.util.Random;
  28 import java.util.concurrent.TimeUnit;
  29 import javax.crypto.BadPaddingException;
  30 import javax.crypto.Cipher;
  31 import javax.crypto.IllegalBlockSizeException;
  32 import javax.crypto.KeyGenerator;
  33 import javax.crypto.NoSuchPaddingException;
  34 import javax.crypto.spec.SecretKeySpec;
  35 import org.openjdk.jmh.annotations.Benchmark;
  36 import org.openjdk.jmh.annotations.Fork;
  37 import org.openjdk.jmh.annotations.Measurement;
  38 import org.openjdk.jmh.annotations.OutputTimeUnit;
  39 import org.openjdk.jmh.annotations.Param;
  40 import org.openjdk.jmh.annotations.Scope;
  41 import org.openjdk.jmh.annotations.Setup;
  42 import org.openjdk.jmh.annotations.State;
  43 import org.openjdk.jmh.annotations.Warmup;
  44 
  45 /**
  46  * Tests various encryption algorithms with the JCE framework. Sets Fork
  47  * parameters as these tests are rather allocation intensive. Reduced numbers of
  48  * forks and iteration as benchmarks are stable.
  49  */
  50 @State(Scope.Thread)
  51 @OutputTimeUnit(TimeUnit.MILLISECONDS)
  52 @Warmup(iterations = 5)
  53 @Measurement(iterations = 10)
  54 @Fork(jvmArgsAppend = {"-Xms1024m", "-Xmx1024m", "-Xmn768m", "-XX:+UseParallelGC"}, value = 5)
  55 public class Crypto {
  56 
  57     @Param({"64", "1024", "16384"})
  58     private int length;
  59 
  60     @Param({"AES", "Blowfish", "DES", "DESede"})
  61     private String cipherName;
  62 
  63     private SecretKeySpec secretKey;
  64     private Cipher encryptCipher;
  65     private Cipher decryptCipher;
  66     private byte[] plainBytes;
  67     private byte[] encryptedBytes;
  68 
  69     @Setup
  70     public void setupSubclass() throws NoSuchAlgorithmException, NoSuchPaddingException,
  71             InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
  72 
  73         // Setup ciphers for encrypt/decrypt
  74         byte[] encodedKey = KeyGenerator.getInstance(cipherName).generateKey().getEncoded();
  75         secretKey = new SecretKeySpec(encodedKey, cipherName);
  76 
  77         encryptCipher = Cipher.getInstance(cipherName);
  78         encryptCipher.init(Cipher.ENCRYPT_MODE, secretKey);
  79 
  80         decryptCipher = Cipher.getInstance(cipherName);
  81         decryptCipher.init(Cipher.DECRYPT_MODE, secretKey);
  82 
  83         // Generate data to encrypt/decrypt
  84         plainBytes = new byte[length];
  85         new Random(1234567890).nextBytes(plainBytes);
  86         encryptedBytes = encryptCipher.doFinal(plainBytes);
  87     }
  88 
  89     /**
  90      * Encrypt byte array
  91      *
  92      * @return encrypted byte array
  93      * @throws javax.crypto.IllegalBlockSizeException
  94      * @throws javax.crypto.BadPaddingException
  95      */
  96     @Benchmark
  97     public byte[] encrypt() throws IllegalBlockSizeException, BadPaddingException {
  98         return encryptCipher.doFinal(plainBytes);
  99     }
 100 
 101     /**
 102      * Decrypt byte array
 103      *
 104      * @return decrypted byte array
 105      * @throws javax.crypto.IllegalBlockSizeException
 106      * @throws javax.crypto.BadPaddingException
 107      */
 108     @Benchmark
 109     public byte[] decrypt() throws IllegalBlockSizeException, BadPaddingException {
 110         return decryptCipher.doFinal(encryptedBytes);
 111     }
 112 }