cast5.java

来自「jpeg2000编解码」· Java 代码 · 共 1,317 行 · 第 1/5 页

JAVA
1,317
字号
        z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE] ^ S7[x8];        b = unscramble(z0z1z2z3); z0 = b[0]; z1 = b[1]; z2 = b[2]; z3 = b[3];        z4z5z6z7 = x8x9xAxB ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3] ^ S8[xA];        b = unscramble(z4z5z6z7); z4 = b[0]; z5 = b[1]; z6 = b[2]; z7 = b[3];        z8z9zAzB = xCxDxExF ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4] ^ S5[x9];        b = unscramble(z8z9zAzB); z8 = b[0]; z9 = b[1]; zA = b[2]; zB = b[3];        zCzDzEzF = x4x5x6x7 ^ S5[zA] ^ S6[z9] ^ S7[zB] ^ S8[z8] ^ S6[xB];        b = unscramble(zCzDzEzF); zC = b[0]; zD = b[1]; zE = b[2]; zF = b[3];        Km8 =  S5[z3] ^ S6[z2] ^ S7[zC] ^ S8[zD] ^ S5[z9];        Km9 =  S5[z1] ^ S6[z0] ^ S7[zE] ^ S8[zF] ^ S6[zC];        Km10 = S5[z7] ^ S6[z6] ^ S7[z8] ^ S8[z9] ^ S7[z2];        Km11 = S5[z5] ^ S6[z4] ^ S7[zA] ^ S8[zB] ^ S8[z6];        x0x1x2x3 = z8z9zAzB ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6] ^ S7[z0];        b = unscramble(x0x1x2x3); x0 = b[0]; x1 = b[1]; x2 = b[2]; x3 = b[3];        x4x5x6x7 = z0z1z2z3 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3] ^ S8[z2];        b = unscramble(x4x5x6x7); x4 = b[0]; x5 = b[1]; x6 = b[2]; x7 = b[3];        x8x9xAxB = z4z5z6z7 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4] ^ S5[z1];        b = unscramble(x8x9xAxB); x8 = b[0]; x9 = b[1]; xA = b[2]; xB = b[3];        xCxDxExF = zCzDzEzF ^ S5[xA] ^ S6[x9] ^ S7[xB] ^ S8[x8] ^ S6[z3];        b = unscramble(xCxDxExF); xC = b[0]; xD = b[1]; xE = b[2]; xF = b[3];        Km12 = S5[x8] ^ S6[x9] ^ S7[x7] ^ S8[x6] ^ S5[x3];        Km13 = S5[xA] ^ S6[xB] ^ S7[x5] ^ S8[x4] ^ S6[x7];        Km14 = S5[xC] ^ S6[xD] ^ S7[x3] ^ S8[x2] ^ S7[x8];        Km15 = S5[xE] ^ S6[xF] ^ S7[x1] ^ S8[x0] ^ S8[xD];        // The remaining half is identical to what is given above, carrying        // on from the last created x0..xF to generate keys K17 - K32. These        // keys will be used as the 'rotation' keys and as such only the five        // least significant bits are to be considered.        z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE] ^ S7[x8];        b = unscramble(z0z1z2z3); z0 = b[0]; z1 = b[1]; z2 = b[2]; z3 = b[3];        z4z5z6z7 = x8x9xAxB ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3] ^ S8[xA];        b = unscramble(z4z5z6z7); z4 = b[0]; z5 = b[1]; z6 = b[2]; z7 = b[3];        z8z9zAzB = xCxDxExF ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4] ^ S5[x9];        b = unscramble(z8z9zAzB); z8 = b[0]; z9 = b[1]; zA = b[2]; zB = b[3];        zCzDzEzF = x4x5x6x7 ^ S5[zA] ^ S6[z9] ^ S7[zB] ^ S8[z8] ^ S6[xB];        b = unscramble(zCzDzEzF); zC = b[0]; zD = b[1]; zE = b[2]; zF = b[3];        Kr0 = (S5[z8] ^ S6[z9] ^ S7[z7] ^ S8[z6] ^ S5[z2]) & 0x1F;        Kr1 = (S5[zA] ^ S6[zB] ^ S7[z5] ^ S8[z4] ^ S6[z6]) & 0x1F;        Kr2 = (S5[zC] ^ S6[zD] ^ S7[z3] ^ S8[z2] ^ S7[z9]) & 0x1F;        Kr3 = (S5[zE] ^ S6[zF] ^ S7[z1] ^ S8[z0] ^ S8[zC]) & 0x1F;        x0x1x2x3 = z8z9zAzB ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6] ^ S7[z0];        b = unscramble(x0x1x2x3); x0 = b[0]; x1 = b[1]; x2 = b[2]; x3 = b[3];        x4x5x6x7 = z0z1z2z3 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3] ^ S8[z2];        b = unscramble(x4x5x6x7); x4 = b[0]; x5 = b[1]; x6 = b[2]; x7 = b[3];        x8x9xAxB = z4z5z6z7 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4] ^ S5[z1];        b = unscramble(x8x9xAxB); x8 = b[0]; x9 = b[1]; xA = b[2]; xB = b[3];        xCxDxExF = zCzDzEzF ^ S5[xA] ^ S6[x9] ^ S7[xB] ^ S8[x8] ^ S6[z3];        b = unscramble(xCxDxExF); xC = b[0]; xD = b[1]; xE = b[2]; xF = b[3];        Kr4 = (S5[x3] ^ S6[x2] ^ S7[xC] ^ S8[xD] ^ S5[x8]) & 0x1F;        Kr5 = (S5[x1] ^ S6[x0] ^ S7[xE] ^ S8[xF] ^ S6[xD]) & 0x1F;        Kr6 = (S5[x7] ^ S6[x6] ^ S7[x8] ^ S8[x9] ^ S7[x3]) & 0x1F;        Kr7 = (S5[x5] ^ S6[x4] ^ S7[xA] ^ S8[xB] ^ S8[x7]) & 0x1F;        z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE] ^ S7[x8];        b = unscramble(z0z1z2z3); z0 = b[0]; z1 = b[1]; z2 = b[2]; z3 = b[3];        z4z5z6z7 = x8x9xAxB ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3] ^ S8[xA];        b = unscramble(z4z5z6z7); z4 = b[0]; z5 = b[1]; z6 = b[2]; z7 = b[3];        z8z9zAzB = xCxDxExF ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4] ^ S5[x9];        b = unscramble(z8z9zAzB); z8 = b[0]; z9 = b[1]; zA = b[2]; zB = b[3];        zCzDzEzF = x4x5x6x7 ^ S5[zA] ^ S6[z9] ^ S7[zB] ^ S8[z8] ^ S6[xB];        b = unscramble(zCzDzEzF); zC = b[0]; zD = b[1]; zE = b[2]; zF = b[3];        Kr8 =  (S5[z3] ^ S6[z2] ^ S7[zC] ^ S8[zD] ^ S5[z9]) & 0x1F;        Kr9 =  (S5[z1] ^ S6[z0] ^ S7[zE] ^ S8[zF] ^ S6[zC]) & 0x1F;        Kr10 = (S5[z7] ^ S6[z6] ^ S7[z8] ^ S8[z9] ^ S7[z2]) & 0x1F;        Kr11 = (S5[z5] ^ S6[z4] ^ S7[zA] ^ S8[zB] ^ S8[z6]) & 0x1F;                x0x1x2x3 = z8z9zAzB ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6] ^ S7[z0];        b = unscramble(x0x1x2x3); x0 = b[0]; x1 = b[1]; x2 = b[2]; x3 = b[3];        x4x5x6x7 = z0z1z2z3 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3] ^ S8[z2];        b = unscramble(x4x5x6x7); x4 = b[0]; x5 = b[1]; x6 = b[2]; x7 = b[3];        x8x9xAxB = z4z5z6z7 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4] ^ S5[z1];        b = unscramble(x8x9xAxB); x8 = b[0]; x9 = b[1]; xA = b[2]; xB = b[3];        xCxDxExF = zCzDzEzF ^ S5[xA] ^ S6[x9] ^ S7[xB] ^ S8[x8] ^ S6[z3];        b = unscramble(xCxDxExF); xC = b[0]; xD = b[1]; xE = b[2]; xF = b[3];        Kr12 = (S5[x8] ^ S6[x9] ^ S7[x7] ^ S8[x6] ^ S5[x3]) & 0x1F;        Kr13 = (S5[xA] ^ S6[xB] ^ S7[x5] ^ S8[x4] ^ S6[x7]) & 0x1F;        Kr14 = (S5[xC] ^ S6[xD] ^ S7[x3] ^ S8[x2] ^ S7[x8]) & 0x1F;        Kr15 = (S5[xE] ^ S6[xF] ^ S7[x1] ^ S8[x0] ^ S8[xD]) & 0x1F;    }    /**     * Assuming the input is a 32-bit block organised as: b31b30b29...b0,     * returns an array of 4 Java ints, containing from position 0 onward     * the values: {b31b30b29b28, b27b26b25b24, ... , b3b2b1b0}.     *     * @param  x    a 32-bit block     * @return an array of 4 ints, each being the contents of an 8-bit     *         block from the input.     */    private static final int[] unscramble (int x) {        return new int[]            { (x >>> 24) & 0xFF, (x >>> 16) & 0xFF, (x >>> 8) & 0xFF, x & 0xFF };    }    /**     * The full encryption algorithm is given in the following four steps.     * <p>     * INPUT:  plaintext m1...m64; key K = k1...k128.<br>     * OUTPUT: ciphertext c1...c64.     * <ol>     *   <li> (key schedule) Compute 16 pairs of subkeys {Kmi, Kri}     *        from a user key (see makeKey() method).     *   <li> (L0,R0) <-- (m1...m64).  (Split the plaintext into left     *        and right 32-bit halves L0 = m1...m32 and R0 = m33...m64.).     *   <li> (16 rounds) for i from 1 to 16, compute Li and Ri as     *        follows:     *     <ul>     *       <li> Li = Ri-1;     *       <li> Ri = Li-1 ^ F(Ri-1,Kmi,Kri), where F is defined in     *            method F() --f is of Type 1, Type 2, or Type 3, depending     *            on i, and ^ being the bitwise XOR function.     *     </ul>     *   <li> c1...c64 <-- (R16,L16). (Exchange final blocks L16, R16     *        and concatenate to form the ciphertext.)     * </ol>     * <p>     * Decryption is identical to the encryption algorithm given     * above, except that the rounds (and therefore the subkey pairs)     * are used in reverse order to compute (L0,R0) from (R16,L16).     * <p>     * Looking at the iterations/rounds in pairs we have:     * <pre>     * (1a)    Li = Ri-1;     * (1b)    Ri = Li-1 ^ Fi(Ri-1);     * (2a)    Li+1 = Ri;     * (2b)    Ri+1 = Li ^ Fi+1(Ri);     * </pre>     * which by substituting (2a) in (2b) becomes     * <pre>     * (2c)    Ri+1 = Li ^ Fi+1(Li+1);     * </pre>     * by substituting (1b) in (2a) and (1a) in (2c), we get:     * <pre>     * (3a)    Li+1 = Li-1 ^ Fi(Ri-1);     * (3b)    Ri+1 = Ri-1 ^ Fi+1(Li+1);     * </pre>     * Using only one couple of variables L and R, initialised to L0 and     * R0 respectively, the assignments for each pair of rounds become:     * <pre>     * (4a)    L ^= Fi(R);     * (4b)    R ^= Fi+1(L);     * </pre>     *     * @param  in      contains the plain-text 64-bit block.     * @param  off     start index within input where data is considered.     * @param  out     will contain the cipher-text block.     * @param  outOff  index in out where cipher-text starts.     */    private void blockEncrypt (byte[] in, int off, byte[] out, int outOff) {        int L = (in[off++] & 0xFF) << 24 |                (in[off++] & 0xFF) << 16 |                (in[off++] & 0xFF) <<  8 |                (in[off++] & 0xFF),            R = (in[off++] & 0xFF) << 24 |                (in[off++] & 0xFF) << 16 |                (in[off++] & 0xFF) <<  8 |                (in[off  ] & 0xFF);        L ^= f1(R, Km0,  Kr0);        R ^= f2(L, Km1,  Kr1);      // round 2        L ^= f3(R, Km2,  Kr2);        R ^= f1(L, Km3,  Kr3);      // round 4        L ^= f2(R, Km4,  Kr4);        R ^= f3(L, Km5,  Kr5);      // round 6        L ^= f1(R, Km6,  Kr6);        R ^= f2(L, Km7,  Kr7);      // round 8        L ^= f3(R, Km8,  Kr8);        R ^= f1(L, Km9,  Kr9);      // round 10        L ^= f2(R, Km10, Kr10);        R ^= f3(L, Km11, Kr11);     // round 12        if (rounds == MAX_NOF_ROUNDS) {            L ^= f1(R, Km12, Kr12);            R ^= f2(L, Km13, Kr13); // round 14            L ^= f3(R, Km14, Kr14);            R ^= f1(L, Km15, Kr15); // round 16        }        out[outOff++] = (byte)(R >>> 24);        out[outOff++] = (byte)(R >>> 16);        out[outOff++] = (byte)(R >>>  8);        out[outOff++] = (byte) R;        out[outOff++] = (byte)(L >>> 24);        out[outOff++] = (byte)(L >>> 16);        out[outOff++] = (byte)(L >>>  8);        out[outOff  ] = (byte) L;    }    /**     * Decrypts a 64-bit block by applying the formulae and sub-keys     * in reverse order to that of the encryption.     *     * @param  input   contains the cipher-text 64-bit block.     * @param  offset  start index within input where data is considered.     * @param  out     will contain the plain-text block.     * @param  outOff  index in out where plain-text starts.     */    private void blockDecrypt (byte[] in, int off, byte[] out, int outOff) {        int L = (in[off    ] & 0xFF) << 24 |                (in[off + 1] & 0xFF) << 16 |                (in[off + 2] & 0xFF) <<  8 |                (in[off + 3] & 0xFF),            R = (in[off + 4] & 0xFF) << 24 |                (in[off + 5] & 0xFF) << 16 |                (in[off + 6] & 0xFF) <<  8 |                (in[off + 7] & 0xFF);        if (rounds == MAX_NOF_ROUNDS) {            L ^= f1(R, Km15, Kr15);            R ^= f3(L, Km14, Kr14);            L ^= f2(R, Km13, Kr13);            R ^= f1(L, Km12, Kr12);        }        L ^= f3(R, Km11, Kr11);        R ^= f2(L, Km10, Kr10);        L ^= f1(R, Km9,  Kr9);        R ^= f3(L, Km8,  Kr8);        L ^= f2(R, Km7,  Kr7);        R ^= f1(L, Km6,  Kr6);        L ^= f3(R, Km5,  Kr5);        R ^= f2(L, Km4,  Kr4);        L ^= f1(R, Km3,  Kr3);        R ^= f3(L, Km2,  Kr2);        L ^= f2(R, Km1,  Kr1);        R ^= f1(L, Km0,  Kr0);        out[outOff++] = (byte)(R >>> 24);        out[outOff++] = (byte)(R >>> 16);        out[outOff++] = (byte)(R >>>  8);        out[outOff++] = (byte) R;        out[outOff++] = (byte)(L >>> 24);        out[outOff++] = (byte)(L >>> 16);        out[outOff++] = (byte)(L >>>  8);        out[outOff  ] = (byte) L;    }    private final int f1 (int I, int m, int r) {        I = m + I;        I = I << r | I >>> (32 - r);        return (((S1[(I >>> 24) & 0xFF]) ^ S2[(I >>> 16) & 0xFF]) - S3[(I >>>  8) & 0xFF]) + S4[I & 0xFF];    }    private final int f2 (int I, int m, int r) {        I = m ^ I;        I = I << r | I >>> (32 - r);        return (((S1[(I >>> 24) & 0xFF]) - S2[(I >>> 16) & 0xFF]) + S3[(I >>>  8) & 0xFF]) ^ S4[I & 0xFF];    }    private final int f3 (int I, int m, int r) {        I = m - I;        I = I << r | I >>> (32 - r);        return (((S1[(I >>> 24) & 0xFF]) + S2[(I >>> 16) & 0xFF]) ^ S3[(I >>>  8) & 0xFF]) - S4[I & 0xFF];    }}

⌨️ 快捷键说明

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