/**
* Definition of Data Encryption Standard (DES) taken from:
* http://www.itl.nist.gov/fipspubs/fip46-2.htm
*/
(function() {
var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
// Shortcuts
var util = C.util, charenc = C.charenc, UTF8 = charenc.UTF8;
/***************************************************************************
*
* DES Key Schedule.
*
* The Key consists of 16 sub-keys of 48 bits each. As each sub-key is
* applied to an expanded 32-bit value where each 4 bits of input is
* expanded into 6 bits of output the sub-key can be broken down into 8
* 32-bit values which allows the key to be used without expansion.
*
* To create the 16 sub-keys, 56 bits are selected from the input 64 bit key
* according to <i>PC1</i>. Each sub-key is generated by left rotating the
* bits a different amount and then selecting 48 bits according to <i>PC2</i>.
*
**************************************************************************/
var KeySchedule;
/**
* Representation of a DES key schedule.
*
* @param {Array
* of 8 bytes} key The cipher key
*
* @constructor
*/
KeySchedule = function(key) {
/**
* The schedule of 16 keys
*/
this.keys = new Array(16);
this._initialiseKeys(key);
};
/**
* Permuted Choice 1 (PC1) byte offsets into the key. Each of the 56 entries
* selects one bit of DES's 56 bit key.
* <p>
*
* <pre>
* The PC1 is defined as:
*
* 57, 49, 41, 33, 25, 17, 9,
* 1, 58, 50, 42, 34, 26, 18,
* 10, 2, 59, 51, 43, 35, 27,
* 19, 11, 3, 60, 52, 44, 36,
* 63, 55, 47, 39, 31, 23, 15,
* 7, 62, 54, 46, 38, 30, 22,
* 14, 6, 61, 53, 45, 37, 29,
* 21, 13, 5, 28, 20, 12, 4
* </pre>
*
* We represent this as an offset into an 8-byte array and a bit mask upon
* that byte. For example 57=(7*8)+1 so is the first (MSB) of the 7th byte.
*
* @constant
*/
KeySchedule.PC1_offsets = [ 7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0,
7, 6, 5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 7, 6, 5, 4, 3, 2, 1, 0, 7, 6,
5, 4, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0, 3, 2, 1, 0 ];
/**
* Permuted Choice 1 (PC1) bit masks. Each of the 56 entries selects one bit
* of DES's 56 bit key.
*
* @constant
*/
KeySchedule.PC1_masks = [ 128, 128, 128, 128, 128, 128, 128, 128, 64, 64,
64, 64, 64, 64, 64, 64, 32, 32, 32, 32, 32, 32, 32, 32, 16, 16, 16,
16, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8,
8, 8, 8, 16, 16, 16, 16 ];
/**
* Permuted Choice 2 (PC2) selects the active 48 bits from the 56 bits of
* the key.
* <p>
*
* <pre>
* The PC2 is defined as:
*
* 14, 17, 11, 24, 1, 5,
* 3, 28, 15, 6, 21, 10,
* 23, 19, 12, 4, 26, 8,
* 16, 7, 27, 20, 13, 2,
* 41, 52, 31, 37, 47, 55,
* 30, 40, 51, 45, 33, 48,
* 44, 49, 39, 56, 34, 53,
* 46, 42, 50, 36, 29, 32
* </pre>
*
* We invert the choice to specify what each bit adds to each 6-bit value of
* the key. For example, bit 1 is the 5th bit selected so this add 2 to the
* first 6-bit value.
*
* @constant
*/
KeySchedule.PC2_offsets1 = [ 0, 3, 1, 2, 0, 1, 3, 2, 0, 1, 0, 2, 3, 0, 1,
3, 0, 0, 2, 3, 1, 0, 2, 0, 0, 2, 3, 1 ];
/**
* PC2 offsets for 2nd block.
*
* @constant
*/
KeySchedule.PC2_offsets2 = [ 7, 5, 4, 7, 5, 6, 0, 7, 4, 0, 6, 5, 4, 7, 0,
6, 5, 7, 4, 5, 6, 7, 5, 4, 6, 0, 4, 6 ];
/**
* Permuted Choice 2 (PC2) masks for 1st block.
*
* @constant
*/
KeySchedule.PC2_masks1 = [ 2, 1, 32, 4, 1, 4, 16, 1, 0, 1, 8, 8, 2, 32, 8,
32, 16, 0, 16, 4, 2, 0, 32, 4, 0, 2, 8, 16 ];
/**
* PC2 masks for 2nd block.
*
* @constant
*/
KeySchedule.PC2_masks2 = [ 2, 32, 8, 1, 2, 2, 0, 4, 4, 0, 8, 16, 32, 16, 0,
32, 4, 32, 2, 1, 16, 8, 8, 16, 1, 0, 1, 4 ];
/**
* Cumulative key shifts.
*
* @constant
*/
KeySchedule.keyShifts = [ 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23,
25, 27, 28 ];
KeySchedule.prototype._initialiseKeys = function(key) {
var i;
// extract 56 key bits in order determined by PC1
var bits = new Array(56);
for (i = 0; i < 56; i++) {
bits[i] = (key[KeySchedule.PC1_offsets[i]] & KeySchedule.PC1_masks[i]) != 0;
}
// split 56 bits into two 28-bit chunks
var bits1 = bits.slice(0, 28);
var bits2 = bits.slice(28, 56);
// duplicate each half to allow for easy bit shifts
bits1 = bits1.concat(bits1);
bits2 = bits2.concat(bits2);
// assemble the 16 keys
for (i = 0; i < 16; i++) {
var k = [ 0, 0, 0, 0, 0, 0, 0, 0 ];
// select the bits of the key according to PC2
var s = KeySchedule.keyShifts[i];
for ( var j = 0; j < 28; j++) {
if (bits1[j + s]) {
k[KeySchedule.PC2_offsets1[j]] += KeySchedule.PC2_masks1[j];
}
if (bits2[j + s]) {
k[KeySchedule.PC2_offsets2[j]] += KeySchedule.PC2_masks2[j];
}
}
// Scale each of the 8 blocks to a 32-bit mask.
k[0] = ((k[0] & 0x1f) << 27) + ((k[0] & 0x20) >> 5);
for ( var j = 1; j <= 6; j++) {
k[j] = k[j] << (27 - 4 * j);
}
k[7] = ((k[7] & 0x3e) >> 1) + ((k[7] & 0x1) << 31);
this.keys[i] = k;
}
};
/**
* Retrieve the key for a specified round
*
* @param i
* the round
* @returns the key
*/
KeySchedule.prototype.getKey = function(i) {
return this.keys[i];
};
/***************************************************************************
*
* DES Engine State
*
**************************************************************************/
var State;
/**
* The algorithm's state. DES operates on two sets of 32-bits, with each
* block of 32-bits treated as a single number.
*
* @class
*/
State = function() {
/** The LHS of the Feistel scheme */
this.lhs = 0;
/** The RHS of the Feistel scheme */
this.rhs = 0;
};
/**
* The masks that select the SBOX input. Each SBOX accepts 6 bits from the
* input.
*
* @constant
*/
State.SBOX_MASK = [ 0xf8000001, 0x1f800000, 0x01f80000, 0x001f8000,
0x0001f800, 0x00001f80, 0x000001f8, 0x8000001f ];
/**
* The SBOXes. The 8 SBOXes each map 6 bit masked bit of the input to 4 bits
* of output. These SBOXes include the post SBOX permutation and benefit
* from JavaScript's sparse arrays to make specifying the input match
* simple.
*
* @constant
*/
State.SBOX = new Array(8);
var SBOX = State.SBOX;
SBOX[0] = new Array();
SBOX[0][0] = 0x808200; // 0 (0, 0) = 14
SBOX[0][268435456] = 0x8000; // 10000000 (0, 1) = 4
SBOX[0][536870912] = 0x808002; // 20000000 (0, 2) = 13
SBOX[0][805306368] = 0x2; // 30000000 (0, 3) = 1
SBOX[0][1073741824] = 0x200; // 40000000 (0, 4) = 2
SBOX[0][1342177280] =