📄 rijndael.java
字号:
// Decompiled by Jad v1.5.7. Copyright 1997-99 Pavel Kouznetsov.
// Jad home page: http://www.geocities.com/SiliconValley/Bridge/8617/jad.html
// Decompiler options: packimports(3)
// Source File Name: Rijndael.java
package cn.ac.ict.crypto.provider.Rijndael;
import cn.ac.ict.crypto.provider.BlockCipher;
import java.security.InvalidKeyException;
import java.security.Key;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
// Referenced classes of package cn.ac.ict.crypto.provider.Rijndael:
// RijndaelKey
public class Rijndael extends BlockCipher
{
public Rijndael()
{
}
protected int engineGetBlockSize()
{
return blockSize();
}
protected int decryptBlock(byte in[], int inOff, int len, byte out[], int outOff)
throws BadPaddingException
{
if(len != 16)
{
throw new BadPaddingException("Datasize less than block size.");
}
else
{
byte pt[] = blockDecrypt(in, inOff, rijndaelKey, 16);
System.arraycopy(pt, 0, out, outOff, 16);
return 16;
}
}
protected int encryptBlock(byte in[], int inOff, int len, byte out[], int outOff)
throws IllegalBlockSizeException
{
if(len != 16)
{
throw new IllegalBlockSizeException("Datasize less than block size.");
}
else
{
byte ct[] = blockEncrypt(in, inOff, rijndaelKey, 16);
System.arraycopy(ct, 0, out, outOff, 16);
return 16;
}
}
protected void setKey(Key key)
throws InvalidKeyException
{
if(!(key instanceof RijndaelKey))
{
throw new InvalidKeyException("not a Rijndael Key");
}
else
{
rijndaelKey = makeKey(key.getEncoded(), 16);
return;
}
}
static final int mul(int a, int b)
{
return a == 0 || b == 0 ? 0 : alog[(log[a & 0xff] + log[b & 0xff]) % 255];
}
static final int mul4(int a, byte b[])
{
if(a == 0)
{
return 0;
}
else
{
a = log[a & 0xff];
int a0 = b[0] == 0 ? 0 : alog[(a + log[b[0] & 0xff]) % 255] & 0xff;
int a1 = b[1] == 0 ? 0 : alog[(a + log[b[1] & 0xff]) % 255] & 0xff;
int a2 = b[2] == 0 ? 0 : alog[(a + log[b[2] & 0xff]) % 255] & 0xff;
int a3 = b[3] == 0 ? 0 : alog[(a + log[b[3] & 0xff]) % 255] & 0xff;
return a0 << 24 | a1 << 16 | a2 << 8 | a3;
}
}
public static Object makeKey(byte k[])
throws InvalidKeyException
{
return makeKey(k, 16);
}
public static byte[] blockEncrypt(byte in[], int inOffset, Object sessionKey)
{
int Ke[][] = (int[][])((Object[])sessionKey)[0];
int ROUNDS = Ke.length - 1;
int Ker[] = Ke[0];
int t0 = ((in[inOffset++] & 0xff) << 24 | (in[inOffset++] & 0xff) << 16 | (in[inOffset++] & 0xff) << 8 | in[inOffset++] & 0xff) ^ Ker[0];
int t1 = ((in[inOffset++] & 0xff) << 24 | (in[inOffset++] & 0xff) << 16 | (in[inOffset++] & 0xff) << 8 | in[inOffset++] & 0xff) ^ Ker[1];
int t2 = ((in[inOffset++] & 0xff) << 24 | (in[inOffset++] & 0xff) << 16 | (in[inOffset++] & 0xff) << 8 | in[inOffset++] & 0xff) ^ Ker[2];
int t3 = ((in[inOffset++] & 0xff) << 24 | (in[inOffset++] & 0xff) << 16 | (in[inOffset++] & 0xff) << 8 | in[inOffset++] & 0xff) ^ Ker[3];
for(int r = 1; r < ROUNDS; r++)
{
Ker = Ke[r];
int a0 = T1[t0 >>> 24 & 0xff] ^ T2[t1 >>> 16 & 0xff] ^ T3[t2 >>> 8 & 0xff] ^ T4[t3 & 0xff] ^ Ker[0];
int a1 = T1[t1 >>> 24 & 0xff] ^ T2[t2 >>> 16 & 0xff] ^ T3[t3 >>> 8 & 0xff] ^ T4[t0 & 0xff] ^ Ker[1];
int a2 = T1[t2 >>> 24 & 0xff] ^ T2[t3 >>> 16 & 0xff] ^ T3[t0 >>> 8 & 0xff] ^ T4[t1 & 0xff] ^ Ker[2];
int a3 = T1[t3 >>> 24 & 0xff] ^ T2[t0 >>> 16 & 0xff] ^ T3[t1 >>> 8 & 0xff] ^ T4[t2 & 0xff] ^ Ker[3];
t0 = a0;
t1 = a1;
t2 = a2;
t3 = a3;
}
byte result[] = new byte[16];
Ker = Ke[ROUNDS];
int tt = Ker[0];
result[0] = (byte)(S[t0 >>> 24 & 0xff] ^ tt >>> 24);
result[1] = (byte)(S[t1 >>> 16 & 0xff] ^ tt >>> 16);
result[2] = (byte)(S[t2 >>> 8 & 0xff] ^ tt >>> 8);
result[3] = (byte)(S[t3 & 0xff] ^ tt);
tt = Ker[1];
result[4] = (byte)(S[t1 >>> 24 & 0xff] ^ tt >>> 24);
result[5] = (byte)(S[t2 >>> 16 & 0xff] ^ tt >>> 16);
result[6] = (byte)(S[t3 >>> 8 & 0xff] ^ tt >>> 8);
result[7] = (byte)(S[t0 & 0xff] ^ tt);
tt = Ker[2];
result[8] = (byte)(S[t2 >>> 24 & 0xff] ^ tt >>> 24);
result[9] = (byte)(S[t3 >>> 16 & 0xff] ^ tt >>> 16);
result[10] = (byte)(S[t0 >>> 8 & 0xff] ^ tt >>> 8);
result[11] = (byte)(S[t1 & 0xff] ^ tt);
tt = Ker[3];
result[12] = (byte)(S[t3 >>> 24 & 0xff] ^ tt >>> 24);
result[13] = (byte)(S[t0 >>> 16 & 0xff] ^ tt >>> 16);
result[14] = (byte)(S[t1 >>> 8 & 0xff] ^ tt >>> 8);
result[15] = (byte)(S[t2 & 0xff] ^ tt);
return result;
}
public static byte[] blockDecrypt(byte in[], int inOffset, Object sessionKey)
{
int Kd[][] = (int[][])((Object[])sessionKey)[1];
int ROUNDS = Kd.length - 1;
int Kdr[] = Kd[0];
int t0 = ((in[inOffset++] & 0xff) << 24 | (in[inOffset++] & 0xff) << 16 | (in[inOffset++] & 0xff) << 8 | in[inOffset++] & 0xff) ^ Kdr[0];
int t1 = ((in[inOffset++] & 0xff) << 24 | (in[inOffset++] & 0xff) << 16 | (in[inOffset++] & 0xff) << 8 | in[inOffset++] & 0xff) ^ Kdr[1];
int t2 = ((in[inOffset++] & 0xff) << 24 | (in[inOffset++] & 0xff) << 16 | (in[inOffset++] & 0xff) << 8 | in[inOffset++] & 0xff) ^ Kdr[2];
int t3 = ((in[inOffset++] & 0xff) << 24 | (in[inOffset++] & 0xff) << 16 | (in[inOffset++] & 0xff) << 8 | in[inOffset++] & 0xff) ^ Kdr[3];
for(int r = 1; r < ROUNDS; r++)
{
Kdr = Kd[r];
int a0 = T5[t0 >>> 24 & 0xff] ^ T6[t3 >>> 16 & 0xff] ^ T7[t2 >>> 8 & 0xff] ^ T8[t1 & 0xff] ^ Kdr[0];
int a1 = T5[t1 >>> 24 & 0xff] ^ T6[t0 >>> 16 & 0xff] ^ T7[t3 >>> 8 & 0xff] ^ T8[t2 & 0xff] ^ Kdr[1];
int a2 = T5[t2 >>> 24 & 0xff] ^ T6[t1 >>> 16 & 0xff] ^ T7[t0 >>> 8 & 0xff] ^ T8[t3 & 0xff] ^ Kdr[2];
int a3 = T5[t3 >>> 24 & 0xff] ^ T6[t2 >>> 16 & 0xff] ^ T7[t1 >>> 8 & 0xff] ^ T8[t0 & 0xff] ^ Kdr[3];
t0 = a0;
t1 = a1;
t2 = a2;
t3 = a3;
}
byte result[] = new byte[16];
Kdr = Kd[ROUNDS];
int tt = Kdr[0];
result[0] = (byte)(Si[t0 >>> 24 & 0xff] ^ tt >>> 24);
result[1] = (byte)(Si[t3 >>> 16 & 0xff] ^ tt >>> 16);
result[2] = (byte)(Si[t2 >>> 8 & 0xff] ^ tt >>> 8);
result[3] = (byte)(Si[t1 & 0xff] ^ tt);
tt = Kdr[1];
result[4] = (byte)(Si[t1 >>> 24 & 0xff] ^ tt >>> 24);
result[5] = (byte)(Si[t0 >>> 16 & 0xff] ^ tt >>> 16);
result[6] = (byte)(Si[t3 >>> 8 & 0xff] ^ tt >>> 8);
result[7] = (byte)(Si[t2 & 0xff] ^ tt);
tt = Kdr[2];
result[8] = (byte)(Si[t2 >>> 24 & 0xff] ^ tt >>> 24);
result[9] = (byte)(Si[t1 >>> 16 & 0xff] ^ tt >>> 16);
result[10] = (byte)(Si[t0 >>> 8 & 0xff] ^ tt >>> 8);
result[11] = (byte)(Si[t3 & 0xff] ^ tt);
tt = Kdr[3];
result[12] = (byte)(Si[t3 >>> 24 & 0xff] ^ tt >>> 24);
result[13] = (byte)(Si[t2 >>> 16 & 0xff] ^ tt >>> 16);
result[14] = (byte)(Si[t1 >>> 8 & 0xff] ^ tt >>> 8);
result[15] = (byte)(Si[t0 & 0xff] ^ tt);
return result;
}
public static int blockSize()
{
return 16;
}
public static synchronized Object makeKey(byte k[], int blockSize)
throws InvalidKeyException
{
if(k == null)
throw new InvalidKeyException("Empty key");
if(k.length != 16 && k.length != 24 && k.length != 32)
throw new InvalidKeyException("Incorrect key length");
int ROUNDS = getRounds(k.length, blockSize);
int BC = blockSize / 4;
int Ke[][] = new int[ROUNDS + 1][BC];
int Kd[][] = new int[ROUNDS + 1][BC];
int ROUND_KEY_COUNT = (ROUNDS + 1) * BC;
int KC = k.length / 4;
int tk[] = new int[KC];
int i = 0;
int j = 0;
while(i < KC)
tk[i++] = (k[j++] & 0xff) << 24 | (k[j++] & 0xff) << 16 | (k[j++] & 0xff) << 8 | k[j++] & 0xff;
int t = 0;
for(j = 0; j < KC && t < ROUND_KEY_COUNT; t++)
{
Ke[t / BC][t % BC] = tk[j];
Kd[ROUNDS - t / BC][t % BC] = tk[j];
j++;
}
int rconpointer = 0;
while(t < ROUND_KEY_COUNT)
{
int tt = tk[KC - 1];
tk[0] ^= (S[tt >>> 16 & 0xff] & 0xff) << 24 ^ (S[tt >>> 8 & 0xff] & 0xff) << 16 ^ (S[tt & 0xff] & 0xff) << 8 ^ S[tt >>> 24 & 0xff] & 0xff ^ (rcon[rconpointer++] & 0xff) << 24;
if(KC != 8)
{
i = 1;
j = 0;
while(i < KC)
tk[i++] ^= tk[j++];
}
else
{
i = 1;
j = 0;
while(i < KC / 2)
tk[i++] ^= tk[j++];
tt = tk[KC / 2 - 1];
tk[KC / 2] ^= S[tt & 0xff] & 0xff ^ (S[tt >>> 8 & 0xff] & 0xff) << 8 ^ (S[tt >>> 16 & 0xff] & 0xff) << 16 ^ (S[tt >>> 24 & 0xff] & 0xff) << 24;
j = KC / 2;
for(i = j + 1; i < KC;)
tk[i++] ^= tk[j++];
}
j = 0;
while(j < KC && t < ROUND_KEY_COUNT)
{
Ke[t / BC][t % BC] = tk[j];
Kd[ROUNDS - t / BC][t % BC] = tk[j];
j++;
t++;
}
}
for(int r = 1; r < ROUNDS; r++)
for(j = 0; j < BC; j++)
{
int tt = Kd[r][j];
Kd[r][j] = U1[tt >>> 24 & 0xff] ^ U2[tt >>> 16 & 0xff] ^ U3[tt >>> 8 & 0xff] ^ U4[tt & 0xff];
}
Object sessionKey[] = {
Ke, Kd
};
return ((Object) (sessionKey));
}
public static byte[] blockEncrypt(byte in[], int inOffset, Object sessionKey, int blockSize)
{
if(blockSize == 16)
return blockEncrypt(in, inOffset, sessionKey);
Object sKey[] = (Object[])sessionKey;
int Ke[][] = (int[][])sKey[0];
int BC = blockSize / 4;
int ROUNDS = Ke.length - 1;
int SC = BC != 4 ? ((int) (BC != 6 ? 2 : 1)) : 0;
int s1 = shifts[SC][1][0];
int s2 = shifts[SC][2][0];
int s3 = shifts[SC][3][0];
int a[] = new int[BC];
int t[] = new int[BC];
byte result[] = new byte[blockSize];
int j = 0;
for(int i = 0; i < BC; i++)
t[i] = ((in[inOffset++] & 0xff) << 24 | (in[inOffset++] & 0xff) << 16 | (in[inOffset++] & 0xff) << 8 | in[inOffset++] & 0xff) ^ Ke[0][i];
for(int r = 1; r < ROUNDS; r++)
{
for(int i = 0; i < BC; i++)
a[i] = T1[t[i] >>> 24 & 0xff] ^ T2[t[(i + s1) % BC] >>> 16 & 0xff] ^ T3[t[(i + s2) % BC] >>> 8 & 0xff] ^ T4[t[(i + s3) % BC] & 0xff] ^ Ke[r][i];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -