DES_ECBpublic class DES_ECB extends BlockCipherBase DES cipher implementation. |
Fields Summary |
---|
private boolean | tripleDesTrue, if this class is being used for triple DES (EDE). | protected String | keyAlgorithmAlgorithm of the key. | protected static final int | BLOCK_SIZEDES ciphers encrypt/decrypt in block size of 8 bytes. | private static final int[] | s0ps0p. | private static final int[] | s1ps1p. | private static final int[] | s2ps2p. | private static final int[] | s3ps3p. | private static final int[] | s4ps4p. | private static final int[] | s5ps5p. | private static final int[] | s6ps6p. | private static final int[] | s7ps7p. | private static int[] | initPermRightinitPermRight. | private static int[] | initPermLeftinitPermLeft. | private static int[] | permperm. | private static byte[] | expandDataData used for key expansion. | private byte[] | dkeyDES key data. |
Constructors Summary |
---|
public DES_ECB(boolean useTripleDes)Constructor.
super(BLOCK_SIZE);
tripleDes = useTripleDes;
if (useTripleDes) {
keyAlgorithm = "DESEDE";
} else {
keyAlgorithm = "DES";
}
|
Methods Summary |
---|
private void | cipherBlock(int keyIndex, boolean encryptMode)Performs the encryption/decryption of data.
byte[] key = dkey[keyIndex];
byte[] data = holdData;
int j = encryptMode ? 0 : 128 - BLOCK_SIZE;
int offset = (encryptMode ? 0 : 16) - BLOCK_SIZE;
// initial permutations
int t, v;
int left = 0;
for (int i = 0; i < 8; i++) {
left |= initPermLeft[(v = i << 5) + 16 + ((t = data[i]) & 0xf)] |
initPermLeft[v + ((t >> 4) & 0xf)];
}
int right = 0;
for (int i = 0; i < 8; i++) {
right |= initPermRight[(v = i << 5) + 16 + ((t = data[i]) & 0xf)] |
initPermRight[v + ((t >> 4) & 0xf)];
}
int i = 0;
while (true) {
// making the first bit and last bit adjacent
// move the first bit to the last
int temp = (right << 1) | ((right >> 31) & 1);
// Mangler Function
// every 6 bit is fed into the sbox, which
// produces 4 bit output
left ^= s0p[(temp & 0x3f) ^ key[j]]
^ s1p[((temp >> 4) & 0x3f) ^ key[j + 1]]
^ s2p[((temp >> 8) & 0x3f) ^ key[j + 2]]
^ s3p[((temp >> 12) & 0x3f) ^ key[j + 3]]
^ s4p[((temp >> 16) & 0x3f) ^ key[j + 4]]
^ s5p[((temp >> 20) & 0x3f) ^ key[j + 5]]
^ s6p[((temp >> 24) & 0x3f) ^ key[j + 6]];
// making the last sbox input last bit from right[0]
temp = ((right & 1) << 5) | ((right >> 27) & 0x1f);
left ^= s7p[temp ^ key[j + 7]];
if (i++ == 15) {
break;
}
temp = left;
left = right;
right = temp;
j -= offset;
}
// permutations
int high = perm[left & 0xf] |
perm[32 + ((left >> 8) & 0xf)] |
perm[64 + ((left >> 16) & 0xf)] |
perm[96 + ((left >> 24) & 0xf)] |
perm[128 + (right & 0xf)] |
perm[160 + ((right >> 8) & 0xf)] |
perm[192 + ((right >> 16) & 0xf)] |
perm[224 + ((right >> 24) & 0xf)];
int low = perm[16 + ((left >> 4) & 0xf)] |
perm[48 + ((left >> 12) & 0xf)] |
perm[80 + ((left >> 20) & 0xf)] |
perm[112 + ((left >> 28) & 0xf)] |
perm[144 + ((right >> 4) & 0xf)] |
perm[176 + ((right >> 12) & 0xf)] |
perm[208 + ((right >> 20) & 0xf)] |
perm[240 + ((right >> 28) & 0xf)];
data[0] = (byte) low;
data[1] = (byte) (low >> 8);
data[2] = (byte) (low >> 16);
data[3] = (byte) (low >> 24);
data[4] = (byte) high;
data[5] = (byte) (high >> 8);
data[6] = (byte) (high >> 16);
data[7] = (byte) (high >> 24);
| private static byte[] | expandKey(byte[] key, int keyOffset)Implements part of the DES algorithm.
byte ek[] = new byte[128];
int pos = 0;
for (int i = 0; i < 8; i++) {
int octet = key[keyOffset++];
int len;
for (int j = 0; j < 7; j++) {
len = expandData[pos++];
int offset = 0;
if ((octet & (0x80 >> j)) != 0) {
while (len-- > 0) {
int v;
if ((v = expandData[pos++]) == 125) {
offset += 16;
} else {
ek[offset += (v >> 3)] |= (1 << (v & 0x7));
}
}
} else {
pos += len;
}
}
}
return ek;
| public void | init(int mode, Key key, CryptoParameter params)Initializes this cipher with a key and a set of algorithm
parameters.
doInit(mode, keyAlgorithm, key, false, null);
| protected void | initKey(byte[] data, int mode)Initializes key.
if (data.length != (tripleDes ? 24 : 8)) {
throw new InvalidKeyException();
}
int keyCount = data.length >> 3;
dkey = new byte[keyCount][];
for (int i = 0; i < keyCount; i++) {
dkey[i] = expandKey(data, i << 3);
}
| private static int[] | initPerm(int value, int period, int divisor, int offset, long deltas1, long deltas2)Initializes data for permutation.
int[] result = new int[256];
int count = 0;
while (true) {
offset += ((((count & 0x1f) < 16 ? deltas1 : deltas2) >>
((15 - count & 0xf) << 2)) & 0xf) + 1;
if (offset > 1023) {
return result;
}
count++;
if (count > 1 && count % period == 1) {
value = value == 1 ? 128 : (value / divisor);
}
result[offset >> 2] |= (value << ((3 - offset & 3) << 3));
}
| private static final int[] | initTable(int bitmask, long l1, long l2, long l3, long l4)Initializes static data used by DES.
int[] words = new int[16];
int count = 1;
for (int i = 0; i < 8; i++) {
int mask;
if ((mask = bitmask & (0xf << (i << 2))) == 0) {
continue;
}
for (int j = 0; j < count; j++) {
words[count + j] = words[j] | mask;
}
count += count;
}
int[] data = new int[64];
for (int i = 0; i < 64; i++) {
data[i] = words[((int) ((i < 32 ? (i < 16 ? l1 : l2) :
(i < 48 ? l3 : l4)) >>
((15 - (i & 0xf)) << 2))) & 0xf];
}
return data;
| protected void | processBlock(byte[] out, int offset)Depending on the mode, either encrypts
or decrypts the data in the queue.
if (dkey.length == 1) {
cipherBlock(0, mode == Cipher.ENCRYPT_MODE);
} else {
if (mode == Cipher.ENCRYPT_MODE) {
cipherBlock(0, true);
cipherBlock(1, false);
cipherBlock(2, true);
} else {
cipherBlock(2, false);
cipherBlock(1, true);
cipherBlock(0, false);
}
}
System.arraycopy(holdData, 0, out, offset, BLOCK_SIZE);
holdCount = 0;
| protected void | setChainingModeAndPadding(java.lang.String mode, java.lang.String padding)Called by the factory method to set the mode and padding parameters.
Need because Class.newInstance does not take args.
// Note: The chaining mode is implicitly set by using this class.
setPadding(padding);
|
|