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 + -
显示快捷键?