private byte[] computeW(final byte[] iv, final byte[] key)
      throws GeneralSecurityException {
    // Checks the parameter sizes for which W is defined.
    // Note, that the caller ensures stricter limits.
    if (key.length <= 8 || key.length > Integer.MAX_VALUE - 16 || iv.length != 8) {
      throw new GeneralSecurityException("computeW called with invalid parameters");
    }
    byte[] data = new byte[wrappingSize(key.length)];
    System.arraycopy(iv, 0, data, 0, iv.length);
    System.arraycopy(key, 0, data, 8, key.length); 
    int blocks = data.length / 8 - 1;
    Cipher aes = EngineFactory.CIPHER.getInstance("AES/ECB/NoPadding");
    aes.init(Cipher.ENCRYPT_MODE, aesKey);
    byte[] block = new byte[16];
    System.arraycopy(data, 0, block, 0, 8);
    for (int i = 0; i < ROUNDS; i++) {
      for (int j = 0; j < blocks; j++) {
        System.arraycopy(data, 8 * (j + 1), block, 8, 8);
        int length = aes.doFinal(block, 0, 16, block);
        assert length == 16;
        // xor the round constant in bigendian order to the left half of block. 
        int roundConst = i * blocks + j + 1;
        for (int b = 0; b < 4; b++) {
          block[7 - b] ^= (byte) (roundConst & 0xff);
          roundConst >>>= 8;
        }
        System.arraycopy(block, 8, data, 8 * (j + 1), 8);
      }
    }
    System.arraycopy(block, 0, data, 0, 8);
    return data;
  }
Computes the pseudorandom permutation W over the IV
concatenated with zero padded key material.
@param iv an IV of size 8.
@param key the key to wrap.
           The pseudorandom permutation W is only defined for
           inputs with a size that is a multiple of 8 bytes and
           that is at least 24 bytes long. Hence computeW is undefined
           for keys of size 8 bytes or shorter.
java_src/src/main/java/com/google/crypto/tink/subtle/Kwp.java