FileDocCategorySizeDatePackage
DES_ECB.javaAPI DocphoneME MR2 API (J2ME)15179Wed May 02 18:00:00 BST 2007com.sun.midp.crypto

DES_ECB

public class DES_ECB extends BlockCipherBase
DES cipher implementation.

Fields Summary
private boolean
tripleDes
True, if this class is being used for triple DES (EDE).
protected String
keyAlgorithm
Algorithm of the key.
protected static final int
BLOCK_SIZE
DES ciphers encrypt/decrypt in block size of 8 bytes.
private static final int[]
s0p
s0p.
private static final int[]
s1p
s1p.
private static final int[]
s2p
s2p.
private static final int[]
s3p
s3p.
private static final int[]
s4p
s4p.
private static final int[]
s5p
s5p.
private static final int[]
s6p
s6p.
private static final int[]
s7p
s7p.
private static int[]
initPermRight
initPermRight.
private static int[]
initPermLeft
initPermLeft.
private static int[]
perm
perm.
private static byte[]
expandData
Data used for key expansion.
private byte[]
dkey
DES key data.
Constructors Summary
public DES_ECB(boolean useTripleDes)
Constructor.

param
useTripleDes true if the class is being used for triple DES

    
                      
       
        super(BLOCK_SIZE);
        tripleDes = useTripleDes;

        if (useTripleDes) {
            keyAlgorithm = "DESEDE";
        } else {
            keyAlgorithm = "DES";
        }
    
Methods Summary
private voidcipherBlock(int keyIndex, boolean encryptMode)
Performs the encryption/decryption of data.

param
keyIndex index of the the key
param
encryptMode indicates if its encryption or decryption


        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.

param
key An 8 byte array containing the key data
param
keyOffset offset into the key byte array
return
the result of operation


        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 voidinit(int mode, Key key, CryptoParameter params)
Initializes this cipher with a key and a set of algorithm parameters.

param
mode the operation mode of this cipher
param
key the encryption key
param
params the algorithm parameters
exception
java.security.InvalidKeyException if the given key is inappropriate for initializing this cipher
exception
java.security.InvalidAlgorithmParameterException if the given algorithm parameters are inappropriate for this cipher

        doInit(mode, keyAlgorithm, key, false, null);
    
protected voidinitKey(byte[] data, int mode)
Initializes key.

param
data key data
param
mode cipher mode
exception
InvalidKeyException if the given key is inappropriate for this cipher


        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.

param
value seed value
param
period perion for value modification
param
divisor divisor of value
param
offset initial offset in the table
param
deltas1 packed offsets for elements 0 - 15
param
deltas2 packed offsets for elements 16 - 31
return
initialized data


        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.

param
bitmask mask of bits used in this table
param
l1 order of words 0 - 15
param
l2 order of words 16 - 31
param
l3 order of words 32 - 47
param
l4 order of words 48 - 63
return
the table


        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 voidprocessBlock(byte[] out, int offset)
Depending on the mode, either encrypts or decrypts the data in the queue.

param
out will contain the result of encryption or decryption operation
param
offset is the offset in out


        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 voidsetChainingModeAndPadding(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.

param
mode the mode parsed from the transformation parameter of getInstance and upper cased
param
padding the paddinge parsed from the transformation parameter of getInstance and upper cased

        // Note: The chaining mode is implicitly set by using this class.

        setPadding(padding);