📄 square.java
字号:
b = bb; c = cc; d = dd; } // last round (diffusion becomes only transposition) aa = ((S[(a >>> 24)]) << 24 | (S[(b >>> 24)] & 0xFF) << 16 | (S[(c >>> 24)] & 0xFF) << 8 | (S[(d >>> 24)] & 0xFF)) ^ K[r][0]; bb = ((S[(a >>> 16) & 0xFF]) << 24 | (S[(b >>> 16) & 0xFF] & 0xFF) << 16 | (S[(c >>> 16) & 0xFF] & 0xFF) << 8 | (S[(d >>> 16) & 0xFF] & 0xFF)) ^ K[r][1]; cc = ((S[(a >>> 8) & 0xFF]) << 24 | (S[(b >>> 8) & 0xFF] & 0xFF) << 16 | (S[(c >>> 8) & 0xFF] & 0xFF) << 8 | (S[(d >>> 8) & 0xFF] & 0xFF)) ^ K[r][2]; dd = ((S[a & 0xFF]) << 24 | (S[b & 0xFF] & 0xFF) << 16 | (S[c & 0xFF] & 0xFF) << 8 | (S[d & 0xFF] & 0xFF)) ^ K[r][3]; out[j++] = (byte) (aa >>> 24); out[j++] = (byte) (aa >>> 16); out[j++] = (byte) (aa >>> 8); out[j++] = (byte) aa; out[j++] = (byte) (bb >>> 24); out[j++] = (byte) (bb >>> 16); out[j++] = (byte) (bb >>> 8); out[j++] = (byte) bb; out[j++] = (byte) (cc >>> 24); out[j++] = (byte) (cc >>> 16); out[j++] = (byte) (cc >>> 8); out[j++] = (byte) cc; out[j++] = (byte) (dd >>> 24); out[j++] = (byte) (dd >>> 16); out[j++] = (byte) (dd >>> 8); out[j] = (byte) dd; } /** * <p>Applies the Theta function to an input <i>in</i> in order to produce in * <i>out</i> an internal session sub-key.</p> * * <p>Both <i>in</i> and <i>out</i> are arrays of four ints.</p> * * <p>Pseudo-code is:</p> * * <pre> * for (i = 0; i < 4; i++) { * out[i] = 0; * for (j = 0, n = 24; j < 4; j++, n -= 8) { * k = mul(in[i] >>> 24, G[0][j]) ^ * mul(in[i] >>> 16, G[1][j]) ^ * mul(in[i] >>> 8, G[2][j]) ^ * mul(in[i] , G[3][j]); * out[i] ^= k << n; * } * } * </pre> */ private static void transform(int[] in, int[] out) { int l3, l2, l1, l0, m; for (int i = 0; i < 4; i++) { l3 = in[i]; l2 = l3 >>> 8; l1 = l3 >>> 16; l0 = l3 >>> 24; m = ((mul(l0, 2) ^ mul(l1, 3) ^ l2 ^ l3) & 0xFF) << 24; m ^= ((l0 ^ mul(l1, 2) ^ mul(l2, 3) ^ l3) & 0xFF) << 16; m ^= ((l0 ^ l1 ^ mul(l2, 2) ^ mul(l3, 3)) & 0xFF) << 8; m ^= ((mul(l0, 3) ^ l1 ^ l2 ^ mul(l3, 2)) & 0xFF); out[i] = m; } } /** * <p>Left rotate a 32-bit chunk.</p> * * @param x the 32-bit data to rotate * @param s number of places to left-rotate by * @return the newly permutated value. */ private static int rot32L(int x, int s) { return x << s | x >>> (32 - s); } /** * <p>Right rotate a 32-bit chunk.</p> * * @param x the 32-bit data to rotate * @param s number of places to right-rotate by * @return the newly permutated value. */ private static int rot32R(int x, int s) { return x >>> s | x << (32 - s); } /** * <p>Returns the product of two binary numbers a and b, using the generator * ROOT as the modulus: p = (a * b) mod ROOT. ROOT Generates a suitable * Galois Field in GF(2**8).</p> * * <p>For best performance call it with abs(b) < abs(a).</p> * * @param a operand for multiply. * @param b operand for multiply. * @return the result of (a * b) % ROOT. */ private static final int mul(int a, int b) { if (a == 0) { return 0; } a &= 0xFF; b &= 0xFF; int result = 0; while (b != 0) { if ((b & 0x01) != 0) { result ^= a; } b >>>= 1; a <<= 1; if (a > 0xFF) { a ^= ROOT; } } return result & 0xFF; } // Instance methods // ------------------------------------------------------------------------- // java.lang.Cloneable interface implementation ---------------------------- public Object clone() { Square result = new Square(); 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(DEFAULT_KEY_SIZE)); return Collections.unmodifiableList(al).iterator(); } public Object makeKey(byte[] uk, int bs) throws InvalidKeyException { if (bs != DEFAULT_BLOCK_SIZE) { throw new IllegalArgumentException(); } if (uk == null) { throw new InvalidKeyException("Empty key"); } if (uk.length != DEFAULT_KEY_SIZE) { throw new InvalidKeyException("Key is not 128-bit."); } int[][] Ke = new int[ROUNDS + 1][4]; int[][] Kd = new int[ROUNDS + 1][4]; int[][] tK = new int[ROUNDS + 1][4]; int i = 0; Ke[0][0] = (uk[i++] & 0xFF) << 24 | (uk[i++] & 0xFF) << 16 | (uk[i++] & 0xFF) << 8 | (uk[i++] & 0xFF); tK[0][0] = Ke[0][0]; Ke[0][1] = (uk[i++] & 0xFF) << 24 | (uk[i++] & 0xFF) << 16 | (uk[i++] & 0xFF) << 8 | (uk[i++] & 0xFF); tK[0][1] = Ke[0][1]; Ke[0][2] = (uk[i++] & 0xFF) << 24 | (uk[i++] & 0xFF) << 16 | (uk[i++] & 0xFF) << 8 | (uk[i++] & 0xFF); tK[0][2] = Ke[0][2]; Ke[0][3] = (uk[i++] & 0xFF) << 24 | (uk[i++] & 0xFF) << 16 | (uk[i++] & 0xFF) << 8 | (uk[i] & 0xFF); tK[0][3] = Ke[0][3]; int j; for (i = 1, j = 0; i < ROUNDS + 1; i++, j++) { tK[i][0] = tK[j][0] ^ rot32L(tK[j][3], 8) ^ OFFSET[j]; tK[i][1] = tK[j][1] ^ tK[i][0]; tK[i][2] = tK[j][2] ^ tK[i][1]; tK[i][3] = tK[j][3] ^ tK[i][2]; System.arraycopy(tK[i], 0, Ke[i], 0, 4); transform(Ke[j], Ke[j]); } for (i = 0; i < ROUNDS; i++) { System.arraycopy(tK[ROUNDS - i], 0, Kd[i], 0, 4); } transform(tK[0], Kd[ROUNDS]); return new Object[] { Ke, Kd }; } public void encrypt(byte[] in, int i, byte[] out, int j, Object k, int bs) { if (bs != DEFAULT_BLOCK_SIZE) { throw new IllegalArgumentException(); } int[][] K = (int[][]) ((Object[]) k)[0]; square(in, i, out, j, K, Te, Se); } public void decrypt(byte[] in, int i, byte[] out, int j, Object k, int bs) { if (bs != DEFAULT_BLOCK_SIZE) { throw new IllegalArgumentException(); } int[][] K = (int[][]) ((Object[]) k)[1]; square(in, i, out, j, K, Td, Sd); } 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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -