< prev index next >

test/jdk/jdk/incubator/vector/benchmark/src/main/java/benchmark/crypto/ChaChaBench.java

Print this page
rev 55894 : 8222897: [vector] Renaming of shift, rotate operations. Few other api changes.
Summary: Renaming of shift, rotate operations. Few other api changes.
Reviewed-by: jrose, briangoetz


  20  * or visit www.oracle.com if you need additional information or have
  21  * questions.
  22  */
  23   
  24 package benchmark.crypto;
  25 
  26 import org.openjdk.jmh.annotations.*;
  27 import jdk.incubator.vector.*;
  28 import java.util.Arrays;
  29 
  30 @State(Scope.Thread)
  31 @BenchmarkMode(Mode.Throughput)
  32 @Fork(value = 1, jvmArgsPrepend = {"--add-modules=jdk.incubator.vector"})
  33 @Warmup(iterations = 3, time = 3)
  34 @Measurement(iterations = 8, time = 2)
  35 public class ChaChaBench {
  36 
  37     @Param({"16384", "65536"})
  38     private int dataSize;
  39     
  40     private ChaChaVector cc20_S128 = makeCC20(Vector.Shape.S_128_BIT);
  41     private ChaChaVector cc20_S256 = makeCC20(Vector.Shape.S_256_BIT);
  42     private ChaChaVector cc20_S512 = makeCC20(Vector.Shape.S_512_BIT);
  43  
  44     private byte[] in;
  45     private byte[] out;
  46     
  47     private byte[] key = new byte[32];
  48     private byte[] nonce = new byte[12];
  49     private long counter = 0;
  50 
  51     private static ChaChaVector makeCC20(Vector.Shape shape) {
  52         ChaChaVector cc20 = new ChaChaVector(shape);
  53         runKAT(cc20);
  54         return cc20;
  55     }
  56 
  57     @Setup
  58     public void setup() {
  59         
  60         in = new byte[dataSize];
  61         out = new byte[dataSize];
  62     }
  63 
  64     @Benchmark
  65     public void encrypt128() {
  66         cc20_S128.chacha20(key, nonce, counter, in, out);
  67     }
  68 
  69     @Benchmark
  70     public void encrypt256() {
  71         cc20_S256.chacha20(key, nonce, counter, in, out);
  72     }
  73 
  74     @Benchmark
  75     public void encrypt512() {
  76         cc20_S512.chacha20(key, nonce, counter, in, out);
  77     }
  78 
  79     private static class ChaChaVector {
  80 
  81         private static final int[] STATE_CONSTANTS =
  82             new int[]{0x61707865, 0x3320646e, 0x79622d32, 0x6b206574};
  83 
  84         private final Vector.Species<Integer> intSpecies;
  85         private final int numBlocks;
  86 
  87         private final Vector.Shuffle<Integer> rot1;
  88         private final Vector.Shuffle<Integer> rot2;
  89         private final Vector.Shuffle<Integer> rot3;
  90 
  91         private final IntVector counterAdd;
  92 
  93         private final Vector.Shuffle<Integer> shuf0;
  94         private final Vector.Shuffle<Integer> shuf1;
  95         private final Vector.Shuffle<Integer> shuf2;
  96         private final Vector.Shuffle<Integer> shuf3;
  97 
  98         private final Vector.Mask<Integer> mask0;
  99         private final Vector.Mask<Integer> mask1;
 100         private final Vector.Mask<Integer> mask2;
 101         private final Vector.Mask<Integer> mask3;
 102 
 103         private final int[] state;
 104 
 105         public ChaChaVector(Vector.Shape shape) {
 106             this.intSpecies = Vector.Species.of(Integer.class, shape);
 107             this.numBlocks = intSpecies.length() / 4;
 108 
 109             this.rot1 = makeRotate(1);
 110             this.rot2 = makeRotate(2);
 111             this.rot3 = makeRotate(3);
 112 
 113             this.counterAdd = makeCounterAdd();
 114 
 115             this.shuf0 = makeRearrangeShuffle(0);
 116             this.shuf1 = makeRearrangeShuffle(1);
 117             this.shuf2 = makeRearrangeShuffle(2);
 118             this.shuf3 = makeRearrangeShuffle(3);
 119 
 120             this.mask0 = makeRearrangeMask(0);
 121             this.mask1 = makeRearrangeMask(1);
 122             this.mask2 = makeRearrangeMask(2);
 123             this.mask3 = makeRearrangeMask(3);
 124 
 125             this.state = new int[numBlocks * 16];
 126         }
 127 
 128         private Vector.Shuffle<Integer>  makeRotate(int amount) {
 129             int[] shuffleArr = new int[intSpecies.length()];
 130 
 131             for (int i = 0; i < intSpecies.length(); i ++) {
 132                 int offset = (i / 4) * 4;
 133                 shuffleArr[i] = offset + ((i + amount) % 4);
 134             }
 135 
 136             return IntVector.shuffleFromValues(intSpecies, shuffleArr);
 137         }
 138 
 139         private IntVector makeCounterAdd() {
 140             int[] addArr = new int[intSpecies.length()];
 141             for(int i = 0; i < numBlocks; i++) {
 142                 addArr[4 * i] = numBlocks;
 143             }
 144             return IntVector.fromArray(intSpecies, addArr, 0);
 145         }
 146 
 147         private Vector.Shuffle<Integer>  makeRearrangeShuffle(int order) {
 148             int[] shuffleArr = new int[intSpecies.length()];
 149             int start = order * 4;
 150             for (int i = 0; i < shuffleArr.length; i++) {
 151                 shuffleArr[i] = (i % 4) + start;
 152             }
 153             return IntVector.shuffleFromArray(intSpecies, shuffleArr, 0);
 154         }
 155 
 156         private Vector.Mask<Integer> makeRearrangeMask(int order) {
 157             boolean[] maskArr = new boolean[intSpecies.length()];
 158             int start = order * 4;
 159             if (start < maskArr.length) {
 160                 for (int i = 0; i < 4; i++) {
 161                     maskArr[i + start] = true;
 162                 }
 163             }
 164 
 165             return IntVector.maskFromValues(intSpecies, maskArr);
 166         }
 167 
 168         public void makeState(byte[] key, byte[] nonce, long counter,
 169             int[] out) {
 170 
 171             // first field is constants
 172             for (int i = 0; i < 4; i++) {
 173                 for (int j = 0; j < numBlocks; j++) {
 174                     out[4*j + i] = STATE_CONSTANTS[i];
 175                 }
 176             }
 177 
 178             // second field is first part of key
 179             int fieldStart = 4 * numBlocks;
 180             for (int i = 0; i < 4; i++) {
 181                 int keyInt = 0;
 182                 for (int j = 0; j < 4; j++) {
 183                     keyInt += (0xFF & key[4 * i + j]) << 8 * j;
 184                 }
 185                 for (int j = 0; j < numBlocks; j++) {


 226             int len = intSpecies.length();
 227 
 228             IntVector sa = IntVector.fromArray(intSpecies, state, 0);
 229             IntVector sb = IntVector.fromArray(intSpecies, state, len);
 230             IntVector sc = IntVector.fromArray(intSpecies, state, 2 * len);
 231             IntVector sd = IntVector.fromArray(intSpecies, state, 3 * len);
 232 
 233             int stateLenBytes = state.length * 4;
 234             int numStates = (in.length + stateLenBytes - 1) / stateLenBytes;
 235             for (int j = 0; j < numStates; j++){
 236 
 237                 IntVector a = sa;
 238                 IntVector b = sb;
 239                 IntVector c = sc;
 240                 IntVector d = sd;
 241 
 242                 for (int i = 0; i < 10; i++) {
 243                     // first round
 244                     a = a.add(b);
 245                     d = d.xor(a);
 246                     d = d.rotateL(16);
 247 
 248                     c = c.add(d);
 249                     b = b.xor(c);
 250                     b = b.rotateL(12);
 251 
 252                     a = a.add(b);
 253                     d = d.xor(a);
 254                     d = d.rotateL(8);
 255 
 256                     c = c.add(d);
 257                     b = b.xor(c);
 258                     b = b.rotateL(7);
 259 
 260                     // makeRotate
 261                     b = b.rearrange(rot1);
 262                     c = c.rearrange(rot2);
 263                     d = d.rearrange(rot3);
 264 
 265                     // second round
 266                     a = a.add(b);
 267                     d = d.xor(a);
 268                     d = d.rotateL(16);
 269 
 270                     c = c.add(d);
 271                     b = b.xor(c);
 272                     b = b.rotateL(12);
 273 
 274                     a = a.add(b);
 275                     d = d.xor(a);
 276                     d = d.rotateL(8);
 277 
 278                     c = c.add(d);
 279                     b = b.xor(c);
 280                     b = b.rotateL(7);
 281 
 282                     // makeRotate
 283                     b = b.rearrange(rot3);
 284                     c = c.rearrange(rot2);
 285                     d = d.rearrange(rot1);
 286                 }
 287 
 288                 a = a.add(sa);
 289                 b = b.add(sb);
 290                 c = c.add(sc);
 291                 d = d.add(sd);
 292 
 293                 // rearrange the vectors
 294                 if (intSpecies.length() == 4) {
 295                     // no rearrange needed
 296                 } else if (intSpecies.length() == 8) {
 297                     IntVector a_r = a.rearrange(b, shuf0, mask1);
 298                     IntVector b_r = c.rearrange(d, shuf0, mask1);
 299                     IntVector c_r = a.rearrange(b, shuf1, mask1);
 300                     IntVector d_r = c.rearrange(d, shuf1, mask1);




  20  * or visit www.oracle.com if you need additional information or have
  21  * questions.
  22  */
  23   
  24 package benchmark.crypto;
  25 
  26 import org.openjdk.jmh.annotations.*;
  27 import jdk.incubator.vector.*;
  28 import java.util.Arrays;
  29 
  30 @State(Scope.Thread)
  31 @BenchmarkMode(Mode.Throughput)
  32 @Fork(value = 1, jvmArgsPrepend = {"--add-modules=jdk.incubator.vector"})
  33 @Warmup(iterations = 3, time = 3)
  34 @Measurement(iterations = 8, time = 2)
  35 public class ChaChaBench {
  36 
  37     @Param({"16384", "65536"})
  38     private int dataSize;
  39     
  40     private ChaChaVector cc20_S128 = makeCC20(VectorShape.S_128_BIT);
  41     private ChaChaVector cc20_S256 = makeCC20(VectorShape.S_256_BIT);
  42     private ChaChaVector cc20_S512 = makeCC20(VectorShape.S_512_BIT);
  43  
  44     private byte[] in;
  45     private byte[] out;
  46     
  47     private byte[] key = new byte[32];
  48     private byte[] nonce = new byte[12];
  49     private long counter = 0;
  50 
  51     private static ChaChaVector makeCC20(VectorShape shape) {
  52         ChaChaVector cc20 = new ChaChaVector(shape);
  53         runKAT(cc20);
  54         return cc20;
  55     }
  56 
  57     @Setup
  58     public void setup() {
  59         
  60         in = new byte[dataSize];
  61         out = new byte[dataSize];
  62     }
  63 
  64     @Benchmark
  65     public void encrypt128() {
  66         cc20_S128.chacha20(key, nonce, counter, in, out);
  67     }
  68 
  69     @Benchmark
  70     public void encrypt256() {
  71         cc20_S256.chacha20(key, nonce, counter, in, out);
  72     }
  73 
  74     @Benchmark
  75     public void encrypt512() {
  76         cc20_S512.chacha20(key, nonce, counter, in, out);
  77     }
  78 
  79     private static class ChaChaVector {
  80 
  81         private static final int[] STATE_CONSTANTS =
  82             new int[]{0x61707865, 0x3320646e, 0x79622d32, 0x6b206574};
  83 
  84         private final VectorSpecies<Integer> intSpecies;
  85         private final int numBlocks;
  86 
  87         private final VectorShuffle<Integer> rot1;
  88         private final VectorShuffle<Integer> rot2;
  89         private final VectorShuffle<Integer> rot3;
  90 
  91         private final IntVector counterAdd;
  92 
  93         private final VectorShuffle<Integer> shuf0;
  94         private final VectorShuffle<Integer> shuf1;
  95         private final VectorShuffle<Integer> shuf2;
  96         private final VectorShuffle<Integer> shuf3;
  97 
  98         private final VectorMask<Integer> mask0;
  99         private final VectorMask<Integer> mask1;
 100         private final VectorMask<Integer> mask2;
 101         private final VectorMask<Integer> mask3;
 102 
 103         private final int[] state;
 104 
 105         public ChaChaVector(VectorShape shape) {
 106             this.intSpecies = VectorSpecies.of(Integer.class, shape);
 107             this.numBlocks = intSpecies.length() / 4;
 108 
 109             this.rot1 = makeRotate(1);
 110             this.rot2 = makeRotate(2);
 111             this.rot3 = makeRotate(3);
 112 
 113             this.counterAdd = makeCounterAdd();
 114 
 115             this.shuf0 = makeRearrangeShuffle(0);
 116             this.shuf1 = makeRearrangeShuffle(1);
 117             this.shuf2 = makeRearrangeShuffle(2);
 118             this.shuf3 = makeRearrangeShuffle(3);
 119 
 120             this.mask0 = makeRearrangeMask(0);
 121             this.mask1 = makeRearrangeMask(1);
 122             this.mask2 = makeRearrangeMask(2);
 123             this.mask3 = makeRearrangeMask(3);
 124 
 125             this.state = new int[numBlocks * 16];
 126         }
 127 
 128         private VectorShuffle<Integer>  makeRotate(int amount) {
 129             int[] shuffleArr = new int[intSpecies.length()];
 130 
 131             for (int i = 0; i < intSpecies.length(); i ++) {
 132                 int offset = (i / 4) * 4;
 133                 shuffleArr[i] = offset + ((i + amount) % 4);
 134             }
 135 
 136             return VectorShuffle.fromValues(intSpecies, shuffleArr);
 137         }
 138 
 139         private IntVector makeCounterAdd() {
 140             int[] addArr = new int[intSpecies.length()];
 141             for(int i = 0; i < numBlocks; i++) {
 142                 addArr[4 * i] = numBlocks;
 143             }
 144             return IntVector.fromArray(intSpecies, addArr, 0);
 145         }
 146 
 147         private VectorShuffle<Integer>  makeRearrangeShuffle(int order) {
 148             int[] shuffleArr = new int[intSpecies.length()];
 149             int start = order * 4;
 150             for (int i = 0; i < shuffleArr.length; i++) {
 151                 shuffleArr[i] = (i % 4) + start;
 152             }
 153             return VectorShuffle.fromArray(intSpecies, shuffleArr, 0);
 154         }
 155 
 156         private VectorMask<Integer> makeRearrangeMask(int order) {
 157             boolean[] maskArr = new boolean[intSpecies.length()];
 158             int start = order * 4;
 159             if (start < maskArr.length) {
 160                 for (int i = 0; i < 4; i++) {
 161                     maskArr[i + start] = true;
 162                 }
 163             }
 164 
 165             return VectorMask.fromValues(intSpecies, maskArr);
 166         }
 167 
 168         public void makeState(byte[] key, byte[] nonce, long counter,
 169             int[] out) {
 170 
 171             // first field is constants
 172             for (int i = 0; i < 4; i++) {
 173                 for (int j = 0; j < numBlocks; j++) {
 174                     out[4*j + i] = STATE_CONSTANTS[i];
 175                 }
 176             }
 177 
 178             // second field is first part of key
 179             int fieldStart = 4 * numBlocks;
 180             for (int i = 0; i < 4; i++) {
 181                 int keyInt = 0;
 182                 for (int j = 0; j < 4; j++) {
 183                     keyInt += (0xFF & key[4 * i + j]) << 8 * j;
 184                 }
 185                 for (int j = 0; j < numBlocks; j++) {


 226             int len = intSpecies.length();
 227 
 228             IntVector sa = IntVector.fromArray(intSpecies, state, 0);
 229             IntVector sb = IntVector.fromArray(intSpecies, state, len);
 230             IntVector sc = IntVector.fromArray(intSpecies, state, 2 * len);
 231             IntVector sd = IntVector.fromArray(intSpecies, state, 3 * len);
 232 
 233             int stateLenBytes = state.length * 4;
 234             int numStates = (in.length + stateLenBytes - 1) / stateLenBytes;
 235             for (int j = 0; j < numStates; j++){
 236 
 237                 IntVector a = sa;
 238                 IntVector b = sb;
 239                 IntVector c = sc;
 240                 IntVector d = sd;
 241 
 242                 for (int i = 0; i < 10; i++) {
 243                     // first round
 244                     a = a.add(b);
 245                     d = d.xor(a);
 246                     d = d.rotateLeft(16);
 247 
 248                     c = c.add(d);
 249                     b = b.xor(c);
 250                     b = b.rotateLeft(12);
 251 
 252                     a = a.add(b);
 253                     d = d.xor(a);
 254                     d = d.rotateLeft(8);
 255 
 256                     c = c.add(d);
 257                     b = b.xor(c);
 258                     b = b.rotateLeft(7);
 259 
 260                     // makeRotate
 261                     b = b.rearrange(rot1);
 262                     c = c.rearrange(rot2);
 263                     d = d.rearrange(rot3);
 264 
 265                     // second round
 266                     a = a.add(b);
 267                     d = d.xor(a);
 268                     d = d.rotateLeft(16);
 269 
 270                     c = c.add(d);
 271                     b = b.xor(c);
 272                     b = b.rotateLeft(12);
 273 
 274                     a = a.add(b);
 275                     d = d.xor(a);
 276                     d = d.rotateLeft(8);
 277 
 278                     c = c.add(d);
 279                     b = b.xor(c);
 280                     b = b.rotateLeft(7);
 281 
 282                     // makeRotate
 283                     b = b.rearrange(rot3);
 284                     c = c.rearrange(rot2);
 285                     d = d.rearrange(rot1);
 286                 }
 287 
 288                 a = a.add(sa);
 289                 b = b.add(sb);
 290                 c = c.add(sc);
 291                 d = d.add(sd);
 292 
 293                 // rearrange the vectors
 294                 if (intSpecies.length() == 4) {
 295                     // no rearrange needed
 296                 } else if (intSpecies.length() == 8) {
 297                     IntVector a_r = a.rearrange(b, shuf0, mask1);
 298                     IntVector b_r = c.rearrange(d, shuf0, mask1);
 299                     IntVector c_r = a.rearrange(b, shuf1, mask1);
 300                     IntVector d_r = c.rearrange(d, shuf1, mask1);


< prev index next >