Methods Summary |
---|
private int | FFmulX(int x)
return (((x & m2) << 1) ^ (((x & m1) >>> 7) * m3));
|
private final void | decryptBlock(int[][] KW)
int r, r0, r1, r2, r3;
C0 ^= KW[ROUNDS][0];
C1 ^= KW[ROUNDS][1];
C2 ^= KW[ROUNDS][2];
C3 ^= KW[ROUNDS][3];
for (r = ROUNDS-1; r>1;)
{
r0 = inv_mcol((Si[C0&255]&255) ^ ((Si[(C3>>8)&255]&255)<<8) ^ ((Si[(C2>>16)&255]&255)<<16) ^ (Si[(C1>>24)&255]<<24)) ^ KW[r][0];
r1 = inv_mcol((Si[C1&255]&255) ^ ((Si[(C0>>8)&255]&255)<<8) ^ ((Si[(C3>>16)&255]&255)<<16) ^ (Si[(C2>>24)&255]<<24)) ^ KW[r][1];
r2 = inv_mcol((Si[C2&255]&255) ^ ((Si[(C1>>8)&255]&255)<<8) ^ ((Si[(C0>>16)&255]&255)<<16) ^ (Si[(C3>>24)&255]<<24)) ^ KW[r][2];
r3 = inv_mcol((Si[C3&255]&255) ^ ((Si[(C2>>8)&255]&255)<<8) ^ ((Si[(C1>>16)&255]&255)<<16) ^ (Si[(C0>>24)&255]<<24)) ^ KW[r--][3];
C0 = inv_mcol((Si[r0&255]&255) ^ ((Si[(r3>>8)&255]&255)<<8) ^ ((Si[(r2>>16)&255]&255)<<16) ^ (Si[(r1>>24)&255]<<24)) ^ KW[r][0];
C1 = inv_mcol((Si[r1&255]&255) ^ ((Si[(r0>>8)&255]&255)<<8) ^ ((Si[(r3>>16)&255]&255)<<16) ^ (Si[(r2>>24)&255]<<24)) ^ KW[r][1];
C2 = inv_mcol((Si[r2&255]&255) ^ ((Si[(r1>>8)&255]&255)<<8) ^ ((Si[(r0>>16)&255]&255)<<16) ^ (Si[(r3>>24)&255]<<24)) ^ KW[r][2];
C3 = inv_mcol((Si[r3&255]&255) ^ ((Si[(r2>>8)&255]&255)<<8) ^ ((Si[(r1>>16)&255]&255)<<16) ^ (Si[(r0>>24)&255]<<24)) ^ KW[r--][3];
}
r0 = inv_mcol((Si[C0&255]&255) ^ ((Si[(C3>>8)&255]&255)<<8) ^ ((Si[(C2>>16)&255]&255)<<16) ^ (Si[(C1>>24)&255]<<24)) ^ KW[r][0];
r1 = inv_mcol((Si[C1&255]&255) ^ ((Si[(C0>>8)&255]&255)<<8) ^ ((Si[(C3>>16)&255]&255)<<16) ^ (Si[(C2>>24)&255]<<24)) ^ KW[r][1];
r2 = inv_mcol((Si[C2&255]&255) ^ ((Si[(C1>>8)&255]&255)<<8) ^ ((Si[(C0>>16)&255]&255)<<16) ^ (Si[(C3>>24)&255]<<24)) ^ KW[r][2];
r3 = inv_mcol((Si[C3&255]&255) ^ ((Si[(C2>>8)&255]&255)<<8) ^ ((Si[(C1>>16)&255]&255)<<16) ^ (Si[(C0>>24)&255]<<24)) ^ KW[r--][3];
// the final round's table is a simple function of Si
C0 = (Si[r0&255]&255) ^ ((Si[(r3>>8)&255]&255)<<8) ^ ((Si[(r2>>16)&255]&255)<<16) ^ (Si[(r1>>24)&255]<<24) ^ KW[0][0];
C1 = (Si[r1&255]&255) ^ ((Si[(r0>>8)&255]&255)<<8) ^ ((Si[(r3>>16)&255]&255)<<16) ^ (Si[(r2>>24)&255]<<24) ^ KW[0][1];
C2 = (Si[r2&255]&255) ^ ((Si[(r1>>8)&255]&255)<<8) ^ ((Si[(r0>>16)&255]&255)<<16) ^ (Si[(r3>>24)&255]<<24) ^ KW[0][2];
C3 = (Si[r3&255]&255) ^ ((Si[(r2>>8)&255]&255)<<8) ^ ((Si[(r1>>16)&255]&255)<<16) ^ (Si[(r0>>24)&255]<<24) ^ KW[0][3];
|
private void | encryptBlock(int[][] KW)
int r, r0, r1, r2, r3;
C0 ^= KW[0][0];
C1 ^= KW[0][1];
C2 ^= KW[0][2];
C3 ^= KW[0][3];
for (r = 1; r < ROUNDS - 1;)
{
r0 = mcol((S[C0&255]&255) ^ ((S[(C1>>8)&255]&255)<<8) ^ ((S[(C2>>16)&255]&255)<<16) ^ (S[(C3>>24)&255]<<24)) ^ KW[r][0];
r1 = mcol((S[C1&255]&255) ^ ((S[(C2>>8)&255]&255)<<8) ^ ((S[(C3>>16)&255]&255)<<16) ^ (S[(C0>>24)&255]<<24)) ^ KW[r][1];
r2 = mcol((S[C2&255]&255) ^ ((S[(C3>>8)&255]&255)<<8) ^ ((S[(C0>>16)&255]&255)<<16) ^ (S[(C1>>24)&255]<<24)) ^ KW[r][2];
r3 = mcol((S[C3&255]&255) ^ ((S[(C0>>8)&255]&255)<<8) ^ ((S[(C1>>16)&255]&255)<<16) ^ (S[(C2>>24)&255]<<24)) ^ KW[r++][3];
C0 = mcol((S[r0&255]&255) ^ ((S[(r1>>8)&255]&255)<<8) ^ ((S[(r2>>16)&255]&255)<<16) ^ (S[(r3>>24)&255]<<24)) ^ KW[r][0];
C1 = mcol((S[r1&255]&255) ^ ((S[(r2>>8)&255]&255)<<8) ^ ((S[(r3>>16)&255]&255)<<16) ^ (S[(r0>>24)&255]<<24)) ^ KW[r][1];
C2 = mcol((S[r2&255]&255) ^ ((S[(r3>>8)&255]&255)<<8) ^ ((S[(r0>>16)&255]&255)<<16) ^ (S[(r1>>24)&255]<<24)) ^ KW[r][2];
C3 = mcol((S[r3&255]&255) ^ ((S[(r0>>8)&255]&255)<<8) ^ ((S[(r1>>16)&255]&255)<<16) ^ (S[(r2>>24)&255]<<24)) ^ KW[r++][3];
}
r0 = mcol((S[C0&255]&255) ^ ((S[(C1>>8)&255]&255)<<8) ^ ((S[(C2>>16)&255]&255)<<16) ^ (S[(C3>>24)&255]<<24)) ^ KW[r][0];
r1 = mcol((S[C1&255]&255) ^ ((S[(C2>>8)&255]&255)<<8) ^ ((S[(C3>>16)&255]&255)<<16) ^ (S[(C0>>24)&255]<<24)) ^ KW[r][1];
r2 = mcol((S[C2&255]&255) ^ ((S[(C3>>8)&255]&255)<<8) ^ ((S[(C0>>16)&255]&255)<<16) ^ (S[(C1>>24)&255]<<24)) ^ KW[r][2];
r3 = mcol((S[C3&255]&255) ^ ((S[(C0>>8)&255]&255)<<8) ^ ((S[(C1>>16)&255]&255)<<16) ^ (S[(C2>>24)&255]<<24)) ^ KW[r++][3];
// the final round is a simple function of S
C0 = (S[r0&255]&255) ^ ((S[(r1>>8)&255]&255)<<8) ^ ((S[(r2>>16)&255]&255)<<16) ^ (S[(r3>>24)&255]<<24) ^ KW[r][0];
C1 = (S[r1&255]&255) ^ ((S[(r2>>8)&255]&255)<<8) ^ ((S[(r3>>16)&255]&255)<<16) ^ (S[(r0>>24)&255]<<24) ^ KW[r][1];
C2 = (S[r2&255]&255) ^ ((S[(r3>>8)&255]&255)<<8) ^ ((S[(r0>>16)&255]&255)<<16) ^ (S[(r1>>24)&255]<<24) ^ KW[r][2];
C3 = (S[r3&255]&255) ^ ((S[(r0>>8)&255]&255)<<8) ^ ((S[(r1>>16)&255]&255)<<16) ^ (S[(r2>>24)&255]<<24) ^ KW[r][3];
|
private int[][] | generateWorkingKey(byte[] key, boolean forEncryption)Calculate the necessary round keys
The number of calculations depends on key size and block size
AES specified a fixed block size of 128 bits and key sizes 128/192/256 bits
This code is written assuming those are the only possible values
int KC = key.length / 4; // key length in words
int t;
if (((KC != 4) && (KC != 6) && (KC != 8)) || ((KC * 4) != key.length))
{
throw new IllegalArgumentException("Key length not 128/192/256 bits.");
}
ROUNDS = KC + 6; // This is not always true for the generalized Rijndael that allows larger block sizes
int[][] W = new int[ROUNDS+1][4]; // 4 words in a block
//
// copy the key into the round key array
//
t = 0;
int i = 0;
while (i < key.length)
{
W[t >> 2][t & 3] = (key[i]&0xff) | ((key[i+1]&0xff) << 8) | ((key[i+2]&0xff) << 16) | (key[i+3] << 24);
i+=4;
t++;
}
//
// while not enough round key material calculated
// calculate new values
//
int k = (ROUNDS + 1) << 2;
for (i = KC; (i < k); i++)
{
int temp = W[(i-1)>>2][(i-1)&3];
if ((i % KC) == 0)
{
temp = subWord(shift(temp, 8)) ^ rcon[(i / KC)-1];
}
else if ((KC > 6) && ((i % KC) == 4))
{
temp = subWord(temp);
}
W[i>>2][i&3] = W[(i - KC)>>2][(i-KC)&3] ^ temp;
}
if (!forEncryption)
{
for (int j = 1; j < ROUNDS; j++)
{
for (i = 0; i < 4; i++)
{
W[j][i] = inv_mcol(W[j][i]);
}
}
}
return W;
|
public java.lang.String | getAlgorithmName()
return "AES";
|
public int | getBlockSize()
return BLOCK_SIZE;
|
public void | init(boolean forEncryption, org.bouncycastle.crypto.CipherParameters params)initialise an AES cipher.
if (params instanceof KeyParameter)
{
WorkingKey = generateWorkingKey(((KeyParameter)params).getKey(), forEncryption);
this.forEncryption = forEncryption;
return;
}
throw new IllegalArgumentException("invalid parameter passed to AES init - " + params.getClass().getName());
|
private int | inv_mcol(int x)
int f2 = FFmulX(x);
int f4 = FFmulX(f2);
int f8 = FFmulX(f4);
int f9 = x ^ f8;
return f2 ^ f4 ^ f8 ^ shift(f2 ^ f9, 8) ^ shift(f4 ^ f9, 16) ^ shift(f9, 24);
|
private int | mcol(int x)
int f2 = FFmulX(x);
return f2 ^ shift(x ^ f2, 8) ^ shift(x, 16) ^ shift(x, 24);
|
private final void | packBlock(byte[] bytes, int off)
int index = off;
bytes[index++] = (byte)C0;
bytes[index++] = (byte)(C0 >> 8);
bytes[index++] = (byte)(C0 >> 16);
bytes[index++] = (byte)(C0 >> 24);
bytes[index++] = (byte)C1;
bytes[index++] = (byte)(C1 >> 8);
bytes[index++] = (byte)(C1 >> 16);
bytes[index++] = (byte)(C1 >> 24);
bytes[index++] = (byte)C2;
bytes[index++] = (byte)(C2 >> 8);
bytes[index++] = (byte)(C2 >> 16);
bytes[index++] = (byte)(C2 >> 24);
bytes[index++] = (byte)C3;
bytes[index++] = (byte)(C3 >> 8);
bytes[index++] = (byte)(C3 >> 16);
bytes[index++] = (byte)(C3 >> 24);
|
public int | processBlock(byte[] in, int inOff, byte[] out, int outOff)
if (WorkingKey == null)
{
throw new IllegalStateException("AES engine not initialised");
}
if ((inOff + (32 / 2)) > in.length)
{
throw new DataLengthException("input buffer too short");
}
if ((outOff + (32 / 2)) > out.length)
{
throw new DataLengthException("output buffer too short");
}
if (forEncryption)
{
unpackBlock(in, inOff);
encryptBlock(WorkingKey);
packBlock(out, outOff);
}
else
{
unpackBlock(in, inOff);
decryptBlock(WorkingKey);
packBlock(out, outOff);
}
return BLOCK_SIZE;
|
public void | reset()
|
private int | shift(int r, int shift)
return (r >>> shift) | (r << -shift);
|
private int | subWord(int x)
return (S[x&255]&255 | ((S[(x>>8)&255]&255)<<8) | ((S[(x>>16)&255]&255)<<16) | S[(x>>24)&255]<<24);
|
private final void | unpackBlock(byte[] bytes, int off)
int index = off;
C0 = (bytes[index++] & 0xff);
C0 |= (bytes[index++] & 0xff) << 8;
C0 |= (bytes[index++] & 0xff) << 16;
C0 |= bytes[index++] << 24;
C1 = (bytes[index++] & 0xff);
C1 |= (bytes[index++] & 0xff) << 8;
C1 |= (bytes[index++] & 0xff) << 16;
C1 |= bytes[index++] << 24;
C2 = (bytes[index++] & 0xff);
C2 |= (bytes[index++] & 0xff) << 8;
C2 |= (bytes[index++] & 0xff) << 16;
C2 |= bytes[index++] << 24;
C3 = (bytes[index++] & 0xff);
C3 |= (bytes[index++] & 0xff) << 8;
C3 |= (bytes[index++] & 0xff) << 16;
C3 |= bytes[index++] << 24;
|