twofish.java

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

JAVA
909
字号
            sBox[2 * i + 1] = MDS[1][(P[P_11][b1] & 0xFF) ^ b1(k0)];            sBox[0x200 + 2 * i] = MDS[2][(P[P_21][b2] & 0xFF) ^ b2(k0)];            sBox[0x200 + 2 * i + 1] = 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            sBox[2 * i] = MDS[0][(P[P_01][(P[P_02][b0] & 0xFF) ^ b0(k1)] & 0xFF)                                 ^ b0(k0)];            sBox[2 * i + 1] = MDS[1][(P[P_11][(P[P_12][b1] & 0xFF) ^ b1(k1)] & 0xFF)                                     ^ b1(k0)];            sBox[0x200 + 2 * i] = MDS[2][(P[P_21][(P[P_22][b2] & 0xFF) ^ b2(k1)] & 0xFF)                                         ^ b2(k0)];            sBox[0x200 + 2 * i + 1] = MDS[3][(P[P_31][(P[P_32][b3] & 0xFF)                                                      ^ b3(k1)] & 0xFF)                                             ^ b3(k0)];          }      }    if (DEBUG && debuglevel > 7)      {        System.out.println("S-box[]:");        for (i = 0; i < 64; i++)          {            for (j = 0; j < 4; j++)              {                System.out.print("0x" + Util.toString(sBox[i * 4 + j]) + ", ");              }            System.out.println();          }        System.out.println();        for (i = 0; i < 64; i++)          {            for (j = 0; j < 4; j++)              {                System.out.print("0x" + Util.toString(sBox[256 + i * 4 + j])                                 + ", ");              }            System.out.println();          }        System.out.println();        for (i = 0; i < 64; i++)          {            for (j = 0; j < 4; j++)              {                System.out.print("0x" + Util.toString(sBox[512 + i * 4 + j])                                 + ", ");              }            System.out.println();          }        System.out.println();        for (i = 0; i < 64; i++)          {            for (j = 0; j < 4; j++)              {                System.out.print("0x" + Util.toString(sBox[768 + i * 4 + j])                                 + ", ");              }            System.out.println();          }        System.out.println();        System.out.println("User (odd, even) keys  --> S-Box keys:");        for (i = 0; i < k64Cnt; i++)          {            System.out.println("0x" + Util.toString(k32o[i]) + "  0x"                               + Util.toString(k32e[i]) + " --> 0x"                               + Util.toString(sBoxKey[k64Cnt - 1 - i]));          }        System.out.println();        System.out.println("Round keys:");        for (i = 0; i < ROUND_SUBKEYS + 2 * ROUNDS; i += 2)          {            System.out.println("0x" + Util.toString(subKeys[i]) + "  0x"                               + Util.toString(subKeys[i + 1]));          }        System.out.println();      }    return new Object[] { sBox, subKeys };  }  public void encrypt(byte[] in, int inOffset, byte[] out, int outOffset,                      Object sessionKey, int bs)  {    if (bs != DEFAULT_BLOCK_SIZE)      {        throw new IllegalArgumentException();      }    Object[] sk = (Object[]) sessionKey; // extract S-box and session key    int[] sBox = (int[]) sk[0];    int[] sKey = (int[]) sk[1];    if (DEBUG && debuglevel > 6)      {        System.out.println("PT=" + Util.toString(in, inOffset, bs));      }    int x0 = (in[inOffset++] & 0xFF) | (in[inOffset++] & 0xFF) << 8             | (in[inOffset++] & 0xFF) << 16 | (in[inOffset++] & 0xFF) << 24;    int x1 = (in[inOffset++] & 0xFF) | (in[inOffset++] & 0xFF) << 8             | (in[inOffset++] & 0xFF) << 16 | (in[inOffset++] & 0xFF) << 24;    int x2 = (in[inOffset++] & 0xFF) | (in[inOffset++] & 0xFF) << 8             | (in[inOffset++] & 0xFF) << 16 | (in[inOffset++] & 0xFF) << 24;    int x3 = (in[inOffset++] & 0xFF) | (in[inOffset++] & 0xFF) << 8             | (in[inOffset++] & 0xFF) << 16 | (in[inOffset++] & 0xFF) << 24;    x0 ^= sKey[INPUT_WHITEN];    x1 ^= sKey[INPUT_WHITEN + 1];    x2 ^= sKey[INPUT_WHITEN + 2];    x3 ^= sKey[INPUT_WHITEN + 3];    if (DEBUG && debuglevel > 6)      {        System.out.println("PTw=" + Util.toString(x0) + Util.toString(x1)                           + Util.toString(x2) + Util.toString(x3));      }    int t0, t1;    int k = ROUND_SUBKEYS;    for (int R = 0; R < ROUNDS; R += 2)      {        t0 = Fe32(sBox, x0, 0);        t1 = Fe32(sBox, x1, 3);        x2 ^= t0 + t1 + sKey[k++];        x2 = x2 >>> 1 | x2 << 31;        x3 = x3 << 1 | x3 >>> 31;        x3 ^= t0 + 2 * t1 + sKey[k++];        if (DEBUG && debuglevel > 6)          {            System.out.println("CT" + (R) + "=" + Util.toString(x0)                               + Util.toString(x1) + Util.toString(x2)                               + Util.toString(x3));          }        t0 = Fe32(sBox, x2, 0);        t1 = Fe32(sBox, x3, 3);        x0 ^= t0 + t1 + sKey[k++];        x0 = x0 >>> 1 | x0 << 31;        x1 = x1 << 1 | x1 >>> 31;        x1 ^= t0 + 2 * t1 + sKey[k++];        if (DEBUG && debuglevel > 6)          {            System.out.println("CT" + (R + 1) + "=" + Util.toString(x0)                               + Util.toString(x1) + Util.toString(x2)                               + Util.toString(x3));          }      }    x2 ^= sKey[OUTPUT_WHITEN];    x3 ^= sKey[OUTPUT_WHITEN + 1];    x0 ^= sKey[OUTPUT_WHITEN + 2];    x1 ^= sKey[OUTPUT_WHITEN + 3];    if (DEBUG && debuglevel > 6)      {        System.out.println("CTw=" + Util.toString(x0) + Util.toString(x1)                           + Util.toString(x2) + Util.toString(x3));      }    out[outOffset++] = (byte) x2;    out[outOffset++] = (byte) (x2 >>> 8);    out[outOffset++] = (byte) (x2 >>> 16);    out[outOffset++] = (byte) (x2 >>> 24);    out[outOffset++] = (byte) x3;    out[outOffset++] = (byte) (x3 >>> 8);    out[outOffset++] = (byte) (x3 >>> 16);    out[outOffset++] = (byte) (x3 >>> 24);    out[outOffset++] = (byte) x0;    out[outOffset++] = (byte) (x0 >>> 8);    out[outOffset++] = (byte) (x0 >>> 16);    out[outOffset++] = (byte) (x0 >>> 24);    out[outOffset++] = (byte) x1;    out[outOffset++] = (byte) (x1 >>> 8);    out[outOffset++] = (byte) (x1 >>> 16);    out[outOffset] = (byte) (x1 >>> 24);    if (DEBUG && debuglevel > 6)      {        System.out.println("CT=" + Util.toString(out, outOffset - 15, 16));        System.out.println();      }  }  public void decrypt(byte[] in, int inOffset, byte[] out, int outOffset,                      Object sessionKey, int bs)  {    if (bs != DEFAULT_BLOCK_SIZE)      {        throw new IllegalArgumentException();      }    Object[] sk = (Object[]) sessionKey; // extract S-box and session key    int[] sBox = (int[]) sk[0];    int[] sKey = (int[]) sk[1];    if (DEBUG && debuglevel > 6)      {        System.out.println("CT=" + Util.toString(in, inOffset, bs));      }    int x2 = (in[inOffset++] & 0xFF) | (in[inOffset++] & 0xFF) << 8             | (in[inOffset++] & 0xFF) << 16 | (in[inOffset++] & 0xFF) << 24;    int x3 = (in[inOffset++] & 0xFF) | (in[inOffset++] & 0xFF) << 8             | (in[inOffset++] & 0xFF) << 16 | (in[inOffset++] & 0xFF) << 24;    int x0 = (in[inOffset++] & 0xFF) | (in[inOffset++] & 0xFF) << 8             | (in[inOffset++] & 0xFF) << 16 | (in[inOffset++] & 0xFF) << 24;    int x1 = (in[inOffset++] & 0xFF) | (in[inOffset++] & 0xFF) << 8             | (in[inOffset++] & 0xFF) << 16 | (in[inOffset++] & 0xFF) << 24;    x2 ^= sKey[OUTPUT_WHITEN];    x3 ^= sKey[OUTPUT_WHITEN + 1];    x0 ^= sKey[OUTPUT_WHITEN + 2];    x1 ^= sKey[OUTPUT_WHITEN + 3];    if (DEBUG && debuglevel > 6)      {        System.out.println("CTw=" + Util.toString(x2) + Util.toString(x3)                           + Util.toString(x0) + Util.toString(x1));      }    int k = ROUND_SUBKEYS + 2 * ROUNDS - 1;    int t0, t1;    for (int R = 0; R < ROUNDS; R += 2)      {        t0 = Fe32(sBox, x2, 0);        t1 = Fe32(sBox, x3, 3);        x1 ^= t0 + 2 * t1 + sKey[k--];        x1 = x1 >>> 1 | x1 << 31;        x0 = x0 << 1 | x0 >>> 31;        x0 ^= t0 + t1 + sKey[k--];        if (DEBUG && debuglevel > 6)          {            System.out.println("PT" + (ROUNDS - R) + "=" + Util.toString(x2)                               + Util.toString(x3) + Util.toString(x0)                               + Util.toString(x1));          }        t0 = Fe32(sBox, x0, 0);        t1 = Fe32(sBox, x1, 3);        x3 ^= t0 + 2 * t1 + sKey[k--];        x3 = x3 >>> 1 | x3 << 31;        x2 = x2 << 1 | x2 >>> 31;        x2 ^= t0 + t1 + sKey[k--];        if (DEBUG && debuglevel > 6)          {            System.out.println("PT" + (ROUNDS - R - 1) + "="                               + Util.toString(x2) + Util.toString(x3)                               + Util.toString(x0) + Util.toString(x1));          }      }    x0 ^= sKey[INPUT_WHITEN];    x1 ^= sKey[INPUT_WHITEN + 1];    x2 ^= sKey[INPUT_WHITEN + 2];    x3 ^= sKey[INPUT_WHITEN + 3];    if (DEBUG && debuglevel > 6)      {        System.out.println("PTw=" + Util.toString(x2) + Util.toString(x3)                           + Util.toString(x0) + Util.toString(x1));      }    out[outOffset++] = (byte) x0;    out[outOffset++] = (byte) (x0 >>> 8);    out[outOffset++] = (byte) (x0 >>> 16);    out[outOffset++] = (byte) (x0 >>> 24);    out[outOffset++] = (byte) x1;    out[outOffset++] = (byte) (x1 >>> 8);    out[outOffset++] = (byte) (x1 >>> 16);    out[outOffset++] = (byte) (x1 >>> 24);    out[outOffset++] = (byte) x2;    out[outOffset++] = (byte) (x2 >>> 8);    out[outOffset++] = (byte) (x2 >>> 16);    out[outOffset++] = (byte) (x2 >>> 24);    out[outOffset++] = (byte) x3;    out[outOffset++] = (byte) (x3 >>> 8);    out[outOffset++] = (byte) (x3 >>> 16);    out[outOffset] = (byte) (x3 >>> 24);    if (DEBUG && debuglevel > 6)      {        System.out.println("PT=" + Util.toString(out, outOffset - 15, 16));        System.out.println();      }  }  public boolean selfTest()  {    if (valid == null)      {        boolean result = super.selfTest(); // do symmetry tests        if (result)          {            result = testKat(KAT_KEY, KAT_CT);          }        valid = new Boolean(result);      }    return valid.booleanValue();  }}

⌨️ 快捷键说明

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