📄 cast128.java
字号:
/****************************************************************************** * * Copyright (c) 1999-2003 AppGate Network Security AB. All Rights Reserved. * * This file contains Original Code and/or Modifications of Original Code as * defined in and that are subject to the MindTerm Public Source License, * Version 2.0, (the 'License'). You may not use this file except in compliance * with the License. * * You should have received a copy of the MindTerm Public Source License * along with this software; see the file LICENSE. If not, write to * AppGate Network Security AB, Otterhallegatan 2, SE-41118 Goteborg, SWEDEN * *****************************************************************************/package com.mindbright.security.cipher;import com.mindbright.jca.security.InvalidKeyException;public final class CAST128 extends BlockCipher { private final static int BLOCK_SIZE = 8; // bytes in a data-block protected int[] Km; protected int[] Kr; public CAST128() { Km = new int[16]; Kr = new int[16]; } public int getBlockSize() { return BLOCK_SIZE; } private static final int getIntMSBOSpec(int[] src, int srcOffset) { return (((src[srcOffset ]) << 24) | ((src[srcOffset + 1]) << 16) | ((src[srcOffset + 2]) << 8) | ( src[srcOffset + 3])); } protected static final void putIntMSBOSpec(int val, int[] dest, int destOffset) { dest[destOffset ] = ((val >>> 24) & 0xff); dest[destOffset + 1] = ((val >>> 16) & 0xff); dest[destOffset + 2] = ((val >>> 8 ) & 0xff); dest[destOffset + 3] = ( val & 0xff); } public synchronized void initializeKey(byte[] key) throws InvalidKeyException { int[] x = new int[16]; int[] z = new int[16]; int[] K = new int[32]; int v, i; // !!! TODO, right now we only support 128 bit key if(key.length != 16) { throw new InvalidKeyException("Invalid key size for CAST128"); } for(i = 0; i < key.length; i++) { x[i] = key[i] & 0xff; if(x[i] < 0) x[i] += 256; } for(i = 0; i < 4; i++) { /* * z0z1z2z3 = x0x1x2x3 ^ S5[xD] ^ S6[xF] ^ S7[xC] ^ S8[xE] ^ S7[x8] * z4z5z6z7 = x8x9xAxB ^ S5[z0] ^ S6[z2] ^ S7[z1] ^ S8[z3] ^ S8[xA] * z8z9zAzB = xCxDxExF ^ S5[z7] ^ S6[z6] ^ S7[z5] ^ S8[z4] ^ S5[x9] * zCzDzEzF = x4x5x6x7 ^ S5[zA] ^ S6[z9] ^ S7[zB] ^ S8[z8] ^ S6[xB] */ v = getIntMSBOSpec(x, 0) ^ S5[x[13]] ^ S6[x[15]] ^ S7[x[12]] ^ S8[x[14]] ^ S7[x[8]]; putIntMSBOSpec(v, z, 0); v = getIntMSBOSpec(x, 8) ^ S5[z[0]] ^ S6[z[2]] ^ S7[z[1]] ^ S8[z[3]] ^ S8[x[10]]; putIntMSBOSpec(v, z, 4); v = getIntMSBOSpec(x, 12) ^ S5[z[7]] ^ S6[z[6]] ^ S7[z[5]] ^ S8[z[4]] ^ S5[x[9]]; putIntMSBOSpec(v, z, 8); v = getIntMSBOSpec(x, 4) ^ S5[z[10]] ^ S6[z[9]] ^ S7[z[11]] ^ S8[z[8]] ^ S6[x[11]]; putIntMSBOSpec(v, z, 12); if((i % 2) == 0) { /* * K1/17 = S5[z8] ^ S6[z9] ^ S7[z7] ^ S8[z6] ^ S5[z2] * K2/18 = S5[zA] ^ S6[zB] ^ S7[z5] ^ S8[z4] ^ S6[z6] * K3/19 = S5[zC] ^ S6[zD] ^ S7[z3] ^ S8[z2] ^ S7[z9] * K4/20 = S5[zE] ^ S6[zF] ^ S7[z1] ^ S8[z0] ^ S8[zC] */ K[i * 8 + 0] = S5[z[8]] ^ S6[z[9]] ^ S7[z[7]] ^ S8[z[6]] ^ S5[z[2]]; K[i * 8 + 1] = S5[z[10]] ^ S6[z[11]] ^ S7[z[5]] ^ S8[z[4]] ^ S6[z[6]]; K[i * 8 + 2] = S5[z[12]] ^ S6[z[13]] ^ S7[z[3]] ^ S8[z[2]] ^ S7[z[9]]; K[i * 8 + 3] = S5[z[14]] ^ S6[z[15]] ^ S7[z[1]] ^ S8[z[0]] ^ S8[z[12]]; } else { /* * K9/25 = S5[z3] ^ S6[z2] ^ S7[zC] ^ S8[zD] ^ S5[z9] * K10/26 = S5[z1] ^ S6[z0] ^ S7[zE] ^ S8[zF] ^ S6[zC] * K11/27 = S5[z7] ^ S6[z6] ^ S7[z8] ^ S8[z9] ^ S7[z2] * K12/28 = S5[z5] ^ S6[z4] ^ S7[zA] ^ S8[zB] ^ S8[z6] */ K[i * 8 + 0] = S5[z[3]] ^ S6[z[2]] ^ S7[z[12]] ^ S8[z[13]] ^ S5[z[9]]; K[i * 8 + 1] = S5[z[1]] ^ S6[z[0]] ^ S7[z[14]] ^ S8[z[15]] ^ S6[z[12]]; K[i * 8 + 2] = S5[z[7]] ^ S6[z[6]] ^ S7[z[8]] ^ S8[z[9]] ^ S7[z[2]]; K[i * 8 + 3] = S5[z[5]] ^ S6[z[4]] ^ S7[z[10]] ^ S8[z[11]] ^ S8[z[6]]; } /* * x0x1x2x3 = z8z9zAzB ^ S5[z5] ^ S6[z7] ^ S7[z4] ^ S8[z6] ^ S7[z0] * x4x5x6x7 = z0z1z2z3 ^ S5[x0] ^ S6[x2] ^ S7[x1] ^ S8[x3] ^ S8[z2] * x8x9xAxB = z4z5z6z7 ^ S5[x7] ^ S6[x6] ^ S7[x5] ^ S8[x4] ^ S5[z1] * xCxDxExF = zCzDzEzF ^ S5[xA] ^ S6[x9] ^ S7[xB] ^ S8[x8] ^ S6[z3] */ v = getIntMSBOSpec(z, 8) ^ S5[z[5]] ^ S6[z[7]] ^ S7[z[4]] ^ S8[z[6]] ^ S7[z[0]]; putIntMSBOSpec(v, x, 0); v = getIntMSBOSpec(z, 0) ^ S5[x[0]] ^ S6[x[2]] ^ S7[x[1]] ^ S8[x[3]] ^ S8[z[2]]; putIntMSBOSpec(v, x, 4); v = getIntMSBOSpec(z, 4) ^ S5[x[7]] ^ S6[x[6]] ^ S7[x[5]] ^ S8[x[4]] ^ S5[z[1]]; putIntMSBOSpec(v, x, 8); v = getIntMSBOSpec(z, 12) ^ S5[x[10]] ^ S6[x[9]] ^ S7[x[11]] ^ S8[x[8]] ^ S6[z[3]]; putIntMSBOSpec(v, x, 12); if((i % 2) == 0) { /* * K5/21 = S5[x3] ^ S6[x2] ^ S7[xC] ^ S8[xD] ^ S5[x8] * K6/22 = S5[x1] ^ S6[x0] ^ S7[xE] ^ S8[xF] ^ S6[xD] * K7/23 = S5[x7] ^ S6[x6] ^ S7[x8] ^ S8[x9] ^ S7[x3] * K8/24 = S5[x5] ^ S6[x4] ^ S7[xA] ^ S8[xB] ^ S8[x7] */ K[i * 8 + 4] = S5[x[3]] ^ S6[x[2]] ^ S7[x[12]] ^ S8[x[13]] ^ S5[x[8]]; K[i * 8 + 5] = S5[x[1]] ^ S6[x[0]] ^ S7[x[14]] ^ S8[x[15]] ^ S6[x[13]]; K[i * 8 + 6] = S5[x[7]] ^ S6[x[6]] ^ S7[x[8]] ^ S8[x[9]] ^ S7[x[3]]; K[i * 8 + 7] = S5[x[5]] ^ S6[x[4]] ^ S7[x[10]] ^ S8[x[11]] ^ S8[x[7]]; } else { /* * K13/29 = S5[x8] ^ S6[x9] ^ S7[x7] ^ S8[x6] ^ S5[x3] * K14/30 = S5[xA] ^ S6[xB] ^ S7[x5] ^ S8[x4] ^ S6[x7] * K15/31 = S5[xC] ^ S6[xD] ^ S7[x3] ^ S8[x2] ^ S7[x8] * K16/32 = S5[xE] ^ S6[xF] ^ S7[x1] ^ S8[x0] ^ S8[xD] */ K[i * 8 + 4] = S5[x[8]] ^ S6[x[9]] ^ S7[x[7]] ^ S8[x[6]] ^ S5[x[3]]; K[i * 8 + 5] = S5[x[10]] ^ S6[x[11]] ^ S7[x[5]] ^ S8[x[4]] ^ S6[x[7]]; K[i * 8 + 6] = S5[x[12]] ^ S6[x[13]] ^ S7[x[3]] ^ S8[x[2]] ^ S7[x[8]]; K[i * 8 + 7] = S5[x[14]] ^ S6[x[15]] ^ S7[x[1]] ^ S8[x[0]] ^ S8[x[13]]; } } for(i = 0; i < 16; i++) { Km[i] = K[i]; Kr[i] = K[16 + i] & 0x1f; } } private static int rotateLeft (int x, int n) { return (x << n) | (x >>> (32 - n)); } private final static int f1(int D, int Kmi, int Kri) { int v = rotateLeft((Kmi + D), Kri); return ((S1[(v >>> 24) & 0xff] ^ S2[(v >>> 16) & 0xff]) - S3[(v >>> 8) & 0xff]) + S4[v & 0xff]; } private final static int f2(int D, int Kmi, int Kri) { int v = rotateLeft((Kmi ^ D), Kri); return ((S1[(v >>> 24) & 0xff] - S2[(v >>> 16) & 0xff]) + S3[(v >>> 8) & 0xff]) ^ S4[v & 0xff]; } private final static int f3(int D, int Kmi, int Kri) { int v = rotateLeft((Kmi - D), Kri); return ((S1[(v >>> 24) & 0xff] + S2[(v >>> 16) & 0xff]) ^ S3[(v >>> 8) & 0xff]) - S4[v & 0xff]; } public void blockEncrypt(byte[] in, int inOffset, byte[] out, int outOffset) { int L, R, T; L = getIntMSBO(in, inOffset); R = getIntMSBO(in, inOffset + 4); // !!! TODO, can optimize (i.e. unroll loop and eliminate temp var.) // is that faster? for(int i = 0; i < 5; i++) { int j = i * 3; T = L; L = R; R = T ^ f1(R, Km[j + 0], Kr[j + 0]); T = L; L = R; R = T ^ f2(R, Km[j + 1], Kr[j + 1]); T = L;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -