DESEnginepublic class DESEngine extends Object implements org.bouncycastle.crypto.BlockCiphera class that provides a basic DES engine. |
Fields Summary |
---|
protected static final int | BLOCK_SIZE | private int[] | workingKey | static short[] | Df_Keywhat follows is mainly taken from "Applied Cryptography", by
Bruce Schneier, however it also bears great resemblance to Richard
Outerbridge's D3DES... | static short[] | bytebit | static int[] | bigbyte | static byte[] | pc1 | static byte[] | totrot | static byte[] | pc2 | static int[] | SP1 | static int[] | SP2 | static int[] | SP3 | static int[] | SP4 | static int[] | SP5 | static int[] | SP6 | static int[] | SP7 | static int[] | SP8 |
Constructors Summary |
---|
public DESEngine()standard constructor.
|
Methods Summary |
---|
protected void | desFunc(int[] wKey, byte[] in, int inOff, byte[] out, int outOff)the DES engine.
int work, right, left;
left = (in[inOff + 0] & 0xff) << 24;
left |= (in[inOff + 1] & 0xff) << 16;
left |= (in[inOff + 2] & 0xff) << 8;
left |= (in[inOff + 3] & 0xff);
right = (in[inOff + 4] & 0xff) << 24;
right |= (in[inOff + 5] & 0xff) << 16;
right |= (in[inOff + 6] & 0xff) << 8;
right |= (in[inOff + 7] & 0xff);
work = ((left >>> 4) ^ right) & 0x0f0f0f0f;
right ^= work;
left ^= (work << 4);
work = ((left >>> 16) ^ right) & 0x0000ffff;
right ^= work;
left ^= (work << 16);
work = ((right >>> 2) ^ left) & 0x33333333;
left ^= work;
right ^= (work << 2);
work = ((right >>> 8) ^ left) & 0x00ff00ff;
left ^= work;
right ^= (work << 8);
right = ((right << 1) | ((right >>> 31) & 1)) & 0xffffffff;
work = (left ^ right) & 0xaaaaaaaa;
left ^= work;
right ^= work;
left = ((left << 1) | ((left >>> 31) & 1)) & 0xffffffff;
for (int round = 0; round < 8; round++)
{
int fval;
work = (right << 28) | (right >>> 4);
work ^= wKey[round * 4 + 0];
fval = SP7[ work & 0x3f];
fval |= SP5[(work >>> 8) & 0x3f];
fval |= SP3[(work >>> 16) & 0x3f];
fval |= SP1[(work >>> 24) & 0x3f];
work = right ^ wKey[round * 4 + 1];
fval |= SP8[ work & 0x3f];
fval |= SP6[(work >>> 8) & 0x3f];
fval |= SP4[(work >>> 16) & 0x3f];
fval |= SP2[(work >>> 24) & 0x3f];
left ^= fval;
work = (left << 28) | (left >>> 4);
work ^= wKey[round * 4 + 2];
fval = SP7[ work & 0x3f];
fval |= SP5[(work >>> 8) & 0x3f];
fval |= SP3[(work >>> 16) & 0x3f];
fval |= SP1[(work >>> 24) & 0x3f];
work = left ^ wKey[round * 4 + 3];
fval |= SP8[ work & 0x3f];
fval |= SP6[(work >>> 8) & 0x3f];
fval |= SP4[(work >>> 16) & 0x3f];
fval |= SP2[(work >>> 24) & 0x3f];
right ^= fval;
}
right = (right << 31) | (right >>> 1);
work = (left ^ right) & 0xaaaaaaaa;
left ^= work;
right ^= work;
left = (left << 31) | (left >>> 1);
work = ((left >>> 8) ^ right) & 0x00ff00ff;
right ^= work;
left ^= (work << 8);
work = ((left >>> 2) ^ right) & 0x33333333;
right ^= work;
left ^= (work << 2);
work = ((right >>> 16) ^ left) & 0x0000ffff;
left ^= work;
right ^= (work << 16);
work = ((right >>> 4) ^ left) & 0x0f0f0f0f;
left ^= work;
right ^= (work << 4);
out[outOff + 0] = (byte)((right >>> 24) & 0xff);
out[outOff + 1] = (byte)((right >>> 16) & 0xff);
out[outOff + 2] = (byte)((right >>> 8) & 0xff);
out[outOff + 3] = (byte)(right & 0xff);
out[outOff + 4] = (byte)((left >>> 24) & 0xff);
out[outOff + 5] = (byte)((left >>> 16) & 0xff);
out[outOff + 6] = (byte)((left >>> 8) & 0xff);
out[outOff + 7] = (byte)(left & 0xff);
| protected int[] | generateWorkingKey(boolean encrypting, byte[] key)generate an integer based working key based on our secret key
and what we processing we are planning to do.
Acknowledgements for this routine go to James Gillogly & Phil Karn.
(whoever, and wherever they are!).
int[] newKey = new int[32];
boolean[] pc1m = new boolean[56],
pcr = new boolean[56];
for (int j = 0; j < 56; j++)
{
int l = pc1[j];
pc1m[j] = ((key[l >>> 3] & bytebit[l & 07]) != 0);
}
for (int i = 0; i < 16; i++)
{
int l, m, n;
if (encrypting)
{
m = i << 1;
}
else
{
m = (15 - i) << 1;
}
n = m + 1;
newKey[m] = newKey[n] = 0;
for (int j = 0; j < 28; j++)
{
l = j + totrot[i];
if (l < 28)
{
pcr[j] = pc1m[l];
}
else
{
pcr[j] = pc1m[l - 28];
}
}
for (int j = 28; j < 56; j++)
{
l = j + totrot[i];
if (l < 56)
{
pcr[j] = pc1m[l];
}
else
{
pcr[j] = pc1m[l - 28];
}
}
for (int j = 0; j < 24; j++)
{
if (pcr[pc2[j]])
{
newKey[m] |= bigbyte[j];
}
if (pcr[pc2[j + 24]])
{
newKey[n] |= bigbyte[j];
}
}
}
//
// store the processed key
//
for (int i = 0; i != 32; i += 2)
{
int i1, i2;
i1 = newKey[i];
i2 = newKey[i + 1];
newKey[i] = ((i1 & 0x00fc0000) << 6) | ((i1 & 0x00000fc0) << 10)
| ((i2 & 0x00fc0000) >>> 10) | ((i2 & 0x00000fc0) >>> 6);
newKey[i + 1] = ((i1 & 0x0003f000) << 12) | ((i1 & 0x0000003f) << 16)
| ((i2 & 0x0003f000) >>> 4) | (i2 & 0x0000003f);
}
return newKey;
| public java.lang.String | getAlgorithmName()
return "DES";
| public int | getBlockSize()
return BLOCK_SIZE;
| public void | init(boolean encrypting, org.bouncycastle.crypto.CipherParameters params)initialise a DES cipher.
if (params instanceof KeyParameter)
{
if (((KeyParameter)params).getKey().length > 8)
{
throw new IllegalArgumentException("DES key too long - should be 8 bytes");
}
workingKey = generateWorkingKey(encrypting,
((KeyParameter)params).getKey());
return;
}
throw new IllegalArgumentException("invalid parameter passed to DES init - " + params.getClass().getName());
| public int | processBlock(byte[] in, int inOff, byte[] out, int outOff)
if (workingKey == null)
{
throw new IllegalStateException("DES engine not initialised");
}
if ((inOff + BLOCK_SIZE) > in.length)
{
throw new DataLengthException("input buffer too short");
}
if ((outOff + BLOCK_SIZE) > out.length)
{
throw new DataLengthException("output buffer too short");
}
desFunc(workingKey, in, inOff, out, outOff);
return BLOCK_SIZE;
| public void | reset()
|
|