twofish.java

来自「linux下建立JAVA虚拟机的源码KAFFE」· Java 代码 · 共 909 行 · 第 1/3 页

JAVA
909
字号
                                   + ", ");                }              System.out.println();            }          System.out.println();          System.out.println("MDS[3][]:");          for (i = 0; i < 64; i++)            {              for (j = 0; j < 4; j++)                {                  System.out.print("0x" + Util.toString(MDS[3][i * 4 + j])                                   + ", ");                }              System.out.println();            }          System.out.println();          System.out.println("Total initialization time: " + time + " ms.");          System.out.println();        }    }  private static final int LFSR1(int x)  {    return (x >> 1) ^ ((x & 0x01) != 0 ? GF256_FDBK_2 : 0);  }  private static final int LFSR2(int x)  {    return (x >> 2) ^ ((x & 0x02) != 0 ? GF256_FDBK_2 : 0)           ^ ((x & 0x01) != 0 ? GF256_FDBK_4 : 0);  }  //   private static final int Mx_1(int x) {  //      return x;  //   }  private static final int Mx_X(int x)  { // 5B    return x ^ LFSR2(x);  }  private static final int Mx_Y(int x)  { // EF    return x ^ LFSR1(x) ^ LFSR2(x);  }  // Constructor(s)  // -------------------------------------------------------------------------  /** Trivial 0-arguments constructor. */  public Twofish()  {    super(Registry.TWOFISH_CIPHER, DEFAULT_BLOCK_SIZE, DEFAULT_KEY_SIZE);  }  // Class methods  // -------------------------------------------------------------------------  private static final int b0(int x)  {    return x & 0xFF;  }  private static final int b1(int x)  {    return (x >>> 8) & 0xFF;  }  private static final int b2(int x)  {    return (x >>> 16) & 0xFF;  }  private static final int b3(int x)  {    return (x >>> 24) & 0xFF;  }  /**   * Use (12, 8) Reed-Solomon code over GF(256) to produce a key S-box 32-bit   * entity from two key material 32-bit entities.   *   * @param k0 1st 32-bit entity.   * @param k1 2nd 32-bit entity.   * @return remainder polynomial generated using RS code   */  private static final int RS_MDS_Encode(int k0, int k1)  {    int r = k1;    int i;    for (i = 0; i < 4; i++)      { // shift 1 byte at a time        r = RS_rem(r);      }    r ^= k0;    for (i = 0; i < 4; i++)      {        r = RS_rem(r);      }    return r;  }  /**   * Reed-Solomon code parameters: (12, 8) reversible code:<p>   * <pre>   *   g(x) = x**4 + (a + 1/a) x**3 + a x**2 + (a + 1/a) x + 1   * </pre>   * where a = primitive root of field generator 0x14D   */  private static final int RS_rem(int x)  {    int b = (x >>> 24) & 0xFF;    int g2 = ((b << 1) ^ ((b & 0x80) != 0 ? RS_GF_FDBK : 0)) & 0xFF;    int g3 = (b >>> 1) ^ ((b & 0x01) != 0 ? (RS_GF_FDBK >>> 1) : 0) ^ g2;    int result = (x << 8) ^ (g3 << 24) ^ (g2 << 16) ^ (g3 << 8) ^ b;    return result;  }  private static final int F32(int k64Cnt, int x, int[] k32)  {    int b0 = b0(x);    int b1 = b1(x);    int b2 = b2(x);    int b3 = b3(x);    int k0 = k32[0];    int k1 = k32[1];    int k2 = k32[2];    int k3 = k32[3];    int result = 0;    switch (k64Cnt & 3)      {      case 1:        result = MDS[0][(P[P_01][b0] & 0xFF) ^ b0(k0)]                 ^ MDS[1][(P[P_11][b1] & 0xFF) ^ b1(k0)]                 ^ MDS[2][(P[P_21][b2] & 0xFF) ^ b2(k0)]                 ^ MDS[3][(P[P_31][b3] & 0xFF) ^ b3(k0)];        break;      case 0: // same as 4        b0 = (P[P_04][b0] & 0xFF) ^ b0(k3);        b1 = (P[P_14][b1] & 0xFF) ^ b1(k3);        b2 = (P[P_24][b2] & 0xFF) ^ b2(k3);        b3 = (P[P_34][b3] & 0xFF) ^ b3(k3);      case 3:        b0 = (P[P_03][b0] & 0xFF) ^ b0(k2);        b1 = (P[P_13][b1] & 0xFF) ^ b1(k2);        b2 = (P[P_23][b2] & 0xFF) ^ b2(k2);        b3 = (P[P_33][b3] & 0xFF) ^ b3(k2);      case 2: // 128-bit keys (optimize for this case)        result = MDS[0][(P[P_01][(P[P_02][b0] & 0xFF) ^ b0(k1)] & 0xFF)                        ^ b0(k0)]                 ^ MDS[1][(P[P_11][(P[P_12][b1] & 0xFF) ^ b1(k1)] & 0xFF)                          ^ b1(k0)]                 ^ MDS[2][(P[P_21][(P[P_22][b2] & 0xFF) ^ b2(k1)] & 0xFF)                          ^ b2(k0)]                 ^ MDS[3][(P[P_31][(P[P_32][b3] & 0xFF) ^ b3(k1)] & 0xFF)                          ^ b3(k0)];        break;      }    return result;  }  private static final int Fe32(int[] sBox, int x, int R)  {    return sBox[2 * _b(x, R)] ^ sBox[2 * _b(x, R + 1) + 1]           ^ sBox[0x200 + 2 * _b(x, R + 2)]           ^ sBox[0x200 + 2 * _b(x, R + 3) + 1];  }  private static final int _b(int x, int N)  {    //      int result = 0;    //      switch (N%4) {    //      case 0: result = b0(x); break;    //      case 1: result = b1(x); break;    //      case 2: result = b2(x); break;    //      case 3: result = b3(x); break;    //      }    //      return result;    // profiling shows that the code spends too long in this method.    // following constructs seem to improve, albeit marginally, performance    switch (N % 4)      {      case 0:        return x & 0xFF;      case 1:        return (x >>> 8) & 0xFF;      case 2:        return (x >>> 16) & 0xFF;      default:        return x >>> 24;      }  }  // Instance methods  // -------------------------------------------------------------------------  // java.lang.Cloneable interface implementation ----------------------------  public Object clone()  {    Twofish result = new Twofish();    result.currentBlockSize = this.currentBlockSize;    return result;  }  // IBlockCipherSpi interface implementation --------------------------------  public Iterator blockSizes()  {    ArrayList al = new ArrayList();    al.add(new Integer(DEFAULT_BLOCK_SIZE));    return Collections.unmodifiableList(al).iterator();  }  public Iterator keySizes()  {    ArrayList al = new ArrayList();    al.add(new Integer(8)); //   64-bit    al.add(new Integer(16)); // 128-bit    al.add(new Integer(24)); // 192-bit    al.add(new Integer(32)); // 256-bit    return Collections.unmodifiableList(al).iterator();  }  /**   * <p>Expands a user-supplied key material into a session key for a designated   * <i>block size</i>.</p>   *   * @param k the 64/128/192/256-bit user-key to use.   * @param bs the desired block size in bytes.   * @return an Object encapsulating the session key.   * @exception IllegalArgumentException if the block size is not 16 (128-bit).   * @exception InvalidKeyException if the key data is invalid.   */  public Object makeKey(byte[] k, int bs) throws InvalidKeyException  {    if (bs != DEFAULT_BLOCK_SIZE)      {        throw new IllegalArgumentException();      }    if (k == null)      {        throw new InvalidKeyException("Empty key");      }    int length = k.length;    if (!(length == 8 || length == 16 || length == 24 || length == 32))      {        throw new InvalidKeyException("Incorrect key length");      }    int k64Cnt = length / 8;    int subkeyCnt = ROUND_SUBKEYS + 2 * ROUNDS;    int[] k32e = new int[4]; // even 32-bit entities    int[] k32o = new int[4]; // odd 32-bit entities    int[] sBoxKey = new int[4];    //    // split user key material into even and odd 32-bit entities and    // compute S-box keys using (12, 8) Reed-Solomon code over GF(256)    //    int i, j, offset = 0;    for (i = 0, j = k64Cnt - 1; i < 4 && offset < length; i++, j--)      {        k32e[i] = (k[offset++] & 0xFF) | (k[offset++] & 0xFF) << 8                  | (k[offset++] & 0xFF) << 16 | (k[offset++] & 0xFF) << 24;        k32o[i] = (k[offset++] & 0xFF) | (k[offset++] & 0xFF) << 8                  | (k[offset++] & 0xFF) << 16 | (k[offset++] & 0xFF) << 24;        sBoxKey[j] = RS_MDS_Encode(k32e[i], k32o[i]); // reverse order      }    // compute the round decryption subkeys for PHT. these same subkeys    // will be used in encryption but will be applied in reverse order.    int q, A, B;    int[] subKeys = new int[subkeyCnt];    for (i = q = 0; i < subkeyCnt / 2; i++, q += SK_STEP)      {        A = F32(k64Cnt, q, k32e); // A uses even key entities        B = F32(k64Cnt, q + SK_BUMP, k32o); // B uses odd  key entities        B = B << 8 | B >>> 24;        A += B;        subKeys[2 * i] = A; // combine with a PHT        A += B;        subKeys[2 * i + 1] = A << SK_ROTL | A >>> (32 - SK_ROTL);      }    // fully expand the table for speed    int k0 = sBoxKey[0];    int k1 = sBoxKey[1];    int k2 = sBoxKey[2];    int k3 = sBoxKey[3];    int b0, b1, b2, b3;    int[] sBox = new int[4 * 256];    for (i = 0; i < 256; i++)      {        b0 = b1 = b2 = b3 = i;        switch (k64Cnt & 3)          {          case 1:            sBox[2 * i] = MDS[0][(P[P_01][b0] & 0xFF) ^ b0(k0)];

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?