code: private void enhancedKeySchedule(int[] P, int[] S, byte[] data, byte[] key) {
          int i;
          int[] koffp = {0}, doffp = {0};
          int[] lr = {0, 0};
          int plen = P.length, slen = S.length;
  
          for (i = 0; i < plen; i++) {
              P[i] = P[i] ^ streamToWord(key, koffp);
          }
  
          //noinspection Duplicates
          for (i = 0; i < plen; i += 2) {
              lr[0] ^= streamToWord(data, doffp);
              lr[1] ^= streamToWord(data, doffp);
              encipher(P, S, lr, 0);
              P[i] = lr[0];
              P[i + 1] = lr[1];
          }
  
          //noinspection Duplicates
          for (i = 0; i < slen; i += 2) {
              lr[0] ^= streamToWord(data, doffp);
              lr[1] ^= streamToWord(data, doffp);
              encipher(P, S, lr, 0);
              S[i] = lr[0];
              S[i + 1] = lr[1];
          }
      }
docs: Perform the "enhanced key schedule" step described by
  Provos and Mazieres in "A Future-Adaptable Password Scheme"
  http://www.openbsd.org/papers/bcrypt-paper.ps
  
  @param data salt information
  @param key  password information