|
@@ -1,13 +1,67 @@
|
|
|
/*
|
|
|
- * From: http://www.tero.co.uk/des/
|
|
|
- * Paul Tero, July 2001
|
|
|
+ * Ported from Flashlight VNC ActionScript implementation:
|
|
|
+ * http://www.wizhelp.com/flashlight-vnc/
|
|
|
*
|
|
|
- * Derived from Eric Young's OpenSSL C implementation (BSD-style license)
|
|
|
+ * Full attribution follows:
|
|
|
+ *
|
|
|
+ * -------------------------------------------------------------------------
|
|
|
+ *
|
|
|
+ * This DES class has been extracted from package Acme.Crypto for use in VNC.
|
|
|
+ * The bytebit[] array has been reversed so that the most significant bit
|
|
|
+ * in each byte of the key is ignored, not the least significant. Also the
|
|
|
+ * unnecessary odd parity code has been removed.
|
|
|
+ *
|
|
|
+ * These changes are:
|
|
|
+ * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
|
|
|
+ *
|
|
|
+ * This software is distributed in the hope that it will be useful,
|
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
+ *
|
|
|
+
|
|
|
+ * DesCipher - the DES encryption method
|
|
|
+ *
|
|
|
+ * The meat of this code is by Dave Zimmerman <dzimm@widget.com>, and is:
|
|
|
+ *
|
|
|
+ * Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved.
|
|
|
+ *
|
|
|
+ * Permission to use, copy, modify, and distribute this software
|
|
|
+ * and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and
|
|
|
+ * without fee is hereby granted, provided that this copyright notice is kept
|
|
|
+ * intact.
|
|
|
*
|
|
|
- * Optimised for performance with large blocks by Michael Hayworth, November 2001
|
|
|
- * http://www.netdealing.com
|
|
|
+ * WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY
|
|
|
+ * OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
|
|
+ * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
|
|
+ * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE LIABLE
|
|
|
+ * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
|
|
|
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
|
|
|
*
|
|
|
- * THIS SOFTWARE IS PROVIDED "AS IS" AND
|
|
|
+ * THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE
|
|
|
+ * CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
|
|
|
+ * PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
|
|
|
+ * NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
|
|
|
+ * SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
|
|
|
+ * SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE
|
|
|
+ * PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). WIDGET WORKSHOP
|
|
|
+ * SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR
|
|
|
+ * HIGH RISK ACTIVITIES.
|
|
|
+ *
|
|
|
+ *
|
|
|
+ * The rest is:
|
|
|
+ *
|
|
|
+ * Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
|
|
|
+ *
|
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
|
+ * modification, are permitted provided that the following conditions
|
|
|
+ * are met:
|
|
|
+ * 1. Redistributions of source code must retain the above copyright
|
|
|
+ * notice, this list of conditions and the following disclaimer.
|
|
|
+ * 2. Redistributions in binary form must reproduce the above copyright
|
|
|
+ * notice, this list of conditions and the following disclaimer in the
|
|
|
+ * documentation and/or other materials provided with the distribution.
|
|
|
+ *
|
|
|
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
@@ -18,210 +72,361 @@
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
* SUCH DAMAGE.
|
|
|
+ *
|
|
|
+ * Visit the ACME Labs Java page for up-to-date versions of this and other
|
|
|
+ * fine Java utilities: http://www.acme.com/java/
|
|
|
*/
|
|
|
|
|
|
+DES = {
|
|
|
|
|
|
-//des
|
|
|
-//this takes the key (byte array), the message (byte array), and whether to encrypt or decrypt
|
|
|
-function des (key, message, encrypt, mode, iv, padding) {
|
|
|
- //declaring this locally speeds things up a bit
|
|
|
- var spfunction1 = new Array (0x1010400,0,0x10000,0x1010404,0x1010004,0x10404,0x4,0x10000,0x400,0x1010400,0x1010404,0x400,0x1000404,0x1010004,0x1000000,0x4,0x404,0x1000400,0x1000400,0x10400,0x10400,0x1010000,0x1010000,0x1000404,0x10004,0x1000004,0x1000004,0x10004,0,0x404,0x10404,0x1000000,0x10000,0x1010404,0x4,0x1010000,0x1010400,0x1000000,0x1000000,0x400,0x1010004,0x10000,0x10400,0x1000004,0x400,0x4,0x1000404,0x10404,0x1010404,0x10004,0x1010000,0x1000404,0x1000004,0x404,0x10404,0x1010400,0x404,0x1000400,0x1000400,0,0x10004,0x10400,0,0x1010004);
|
|
|
- var spfunction2 = new Array (-0x7fef7fe0,-0x7fff8000,0x8000,0x108020,0x100000,0x20,-0x7fefffe0,-0x7fff7fe0,-0x7fffffe0,-0x7fef7fe0,-0x7fef8000,-0x80000000,-0x7fff8000,0x100000,0x20,-0x7fefffe0,0x108000,0x100020,-0x7fff7fe0,0,-0x80000000,0x8000,0x108020,-0x7ff00000,0x100020,-0x7fffffe0,0,0x108000,0x8020,-0x7fef8000,-0x7ff00000,0x8020,0,0x108020,-0x7fefffe0,0x100000,-0x7fff7fe0,-0x7ff00000,-0x7fef8000,0x8000,-0x7ff00000,-0x7fff8000,0x20,-0x7fef7fe0,0x108020,0x20,0x8000,-0x80000000,0x8020,-0x7fef8000,0x100000,-0x7fffffe0,0x100020,-0x7fff7fe0,-0x7fffffe0,0x100020,0x108000,0,-0x7fff8000,0x8020,-0x80000000,-0x7fefffe0,-0x7fef7fe0,0x108000);
|
|
|
- var spfunction3 = new Array (0x208,0x8020200,0,0x8020008,0x8000200,0,0x20208,0x8000200,0x20008,0x8000008,0x8000008,0x20000,0x8020208,0x20008,0x8020000,0x208,0x8000000,0x8,0x8020200,0x200,0x20200,0x8020000,0x8020008,0x20208,0x8000208,0x20200,0x20000,0x8000208,0x8,0x8020208,0x200,0x8000000,0x8020200,0x8000000,0x20008,0x208,0x20000,0x8020200,0x8000200,0,0x200,0x20008,0x8020208,0x8000200,0x8000008,0x200,0,0x8020008,0x8000208,0x20000,0x8000000,0x8020208,0x8,0x20208,0x20200,0x8000008,0x8020000,0x8000208,0x208,0x8020000,0x20208,0x8,0x8020008,0x20200);
|
|
|
- var spfunction4 = new Array (0x802001,0x2081,0x2081,0x80,0x802080,0x800081,0x800001,0x2001,0,0x802000,0x802000,0x802081,0x81,0,0x800080,0x800001,0x1,0x2000,0x800000,0x802001,0x80,0x800000,0x2001,0x2080,0x800081,0x1,0x2080,0x800080,0x2000,0x802080,0x802081,0x81,0x800080,0x800001,0x802000,0x802081,0x81,0,0,0x802000,0x2080,0x800080,0x800081,0x1,0x802001,0x2081,0x2081,0x80,0x802081,0x81,0x1,0x2000,0x800001,0x2001,0x802080,0x800081,0x2001,0x2080,0x800000,0x802001,0x80,0x800000,0x2000,0x802080);
|
|
|
- var spfunction5 = new Array (0x100,0x2080100,0x2080000,0x42000100,0x80000,0x100,0x40000000,0x2080000,0x40080100,0x80000,0x2000100,0x40080100,0x42000100,0x42080000,0x80100,0x40000000,0x2000000,0x40080000,0x40080000,0,0x40000100,0x42080100,0x42080100,0x2000100,0x42080000,0x40000100,0,0x42000000,0x2080100,0x2000000,0x42000000,0x80100,0x80000,0x42000100,0x100,0x2000000,0x40000000,0x2080000,0x42000100,0x40080100,0x2000100,0x40000000,0x42080000,0x2080100,0x40080100,0x100,0x2000000,0x42080000,0x42080100,0x80100,0x42000000,0x42080100,0x2080000,0,0x40080000,0x42000000,0x80100,0x2000100,0x40000100,0x80000,0,0x40080000,0x2080100,0x40000100);
|
|
|
- var spfunction6 = new Array (0x20000010,0x20400000,0x4000,0x20404010,0x20400000,0x10,0x20404010,0x400000,0x20004000,0x404010,0x400000,0x20000010,0x400010,0x20004000,0x20000000,0x4010,0,0x400010,0x20004010,0x4000,0x404000,0x20004010,0x10,0x20400010,0x20400010,0,0x404010,0x20404000,0x4010,0x404000,0x20404000,0x20000000,0x20004000,0x10,0x20400010,0x404000,0x20404010,0x400000,0x4010,0x20000010,0x400000,0x20004000,0x20000000,0x4010,0x20000010,0x20404010,0x404000,0x20400000,0x404010,0x20404000,0,0x20400010,0x10,0x4000,0x20400000,0x404010,0x4000,0x400010,0x20004010,0,0x20404000,0x20000000,0x400010,0x20004010);
|
|
|
- var spfunction7 = new Array (0x200000,0x4200002,0x4000802,0,0x800,0x4000802,0x200802,0x4200800,0x4200802,0x200000,0,0x4000002,0x2,0x4000000,0x4200002,0x802,0x4000800,0x200802,0x200002,0x4000800,0x4000002,0x4200000,0x4200800,0x200002,0x4200000,0x800,0x802,0x4200802,0x200800,0x2,0x4000000,0x200800,0x4000000,0x200800,0x200000,0x4000802,0x4000802,0x4200002,0x4200002,0x2,0x200002,0x4000000,0x4000800,0x200000,0x4200800,0x802,0x200802,0x4200800,0x802,0x4000002,0x4200802,0x4200000,0x200800,0,0x2,0x4200802,0,0x200802,0x4200000,0x800,0x4000002,0x4000800,0x800,0x200002);
|
|
|
- var spfunction8 = new Array (0x10001040,0x1000,0x40000,0x10041040,0x10000000,0x10001040,0x40,0x10000000,0x40040,0x10040000,0x10041040,0x41000,0x10041000,0x41040,0x1000,0x40,0x10040000,0x10000040,0x10001000,0x1040,0x41000,0x40040,0x10040040,0x10041000,0x1040,0,0,0x10040040,0x10000040,0x10001000,0x41040,0x40000,0x41040,0x40000,0x10041000,0x1000,0x40,0x10040040,0x1000,0x41040,0x10001000,0x40,0x10000040,0x10040000,0x10040040,0x10000000,0x40000,0x10001040,0,0x10041040,0x40040,0x10000040,0x10040000,0x10001000,0x10001040,0,0x10041040,0x41000,0x41000,0x1040,0x1040,0x40040,0x10000000,0x10041000);
|
|
|
-
|
|
|
- //create the 16 or 48 subkeys we will need
|
|
|
- var keys = des_createKeys (key);
|
|
|
- var m=0, i, j, temp, temp2, right1, right2, left, right, looping;
|
|
|
- var cbcleft, cbcleft2, cbcright, cbcright2
|
|
|
- var endloop, loopinc;
|
|
|
- var len = message.length;
|
|
|
- var chunk = 0;
|
|
|
- //set up the loops for single and triple des
|
|
|
- var iterations = keys.length == 32 ? 3 : 9; //single or triple des
|
|
|
- if (iterations == 3) {looping = encrypt ? new Array (0, 32, 2) : new Array (30, -2, -2);}
|
|
|
- else {looping = encrypt ? new Array (0, 32, 2, 62, 30, -2, 64, 96, 2) : new Array (94, 62, -2, 32, 64, 2, 30, -2, -2);}
|
|
|
-
|
|
|
- //pad the message depending on the padding parameter
|
|
|
- if (padding == 2) {
|
|
|
- for (var i=0; i<8; i++) { message.push(" "); } //pad the message with spaces
|
|
|
- } else if (padding == 1) {
|
|
|
- temp = 8-(len%8);
|
|
|
- for (var i=0; i<8; i++) { message.push(temp); };
|
|
|
- if (temp==8) len+=8; //PKCS7 padding
|
|
|
- } else if (!padding) {
|
|
|
- for (var i=0; i<8; i++) { message.push(0); } //pad the message out with null bytes
|
|
|
- }
|
|
|
-
|
|
|
- //store the result here
|
|
|
- result = [];
|
|
|
- tempresult = [];
|
|
|
-
|
|
|
- if (mode == 1) { //CBC mode
|
|
|
- cbcleft = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++);
|
|
|
- cbcright = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++);
|
|
|
- m=0;
|
|
|
- }
|
|
|
-
|
|
|
- //loop through each 64 bit chunk of the message
|
|
|
- while (m < len) {
|
|
|
- left = (message[m++] << 24) | (message[m++] << 16) | (message[m++] << 8) | message[m++];
|
|
|
- right = (message[m++] << 24) | (message[m++] << 16) | (message[m++] << 8) | message[m++];
|
|
|
-
|
|
|
- //for Cipher Block Chaining mode, xor the message with the previous result
|
|
|
- if (mode == 1) {if (encrypt) {left ^= cbcleft; right ^= cbcright;} else {cbcleft2 = cbcleft; cbcright2 = cbcright; cbcleft = left; cbcright = right;}}
|
|
|
-
|
|
|
- //first each 64 but chunk of the message must be permuted according to IP
|
|
|
- temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4);
|
|
|
- temp = ((left >>> 16) ^ right) & 0x0000ffff; right ^= temp; left ^= (temp << 16);
|
|
|
- temp = ((right >>> 2) ^ left) & 0x33333333; left ^= temp; right ^= (temp << 2);
|
|
|
- temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8);
|
|
|
- temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1);
|
|
|
-
|
|
|
- left = ((left << 1) | (left >>> 31));
|
|
|
- right = ((right << 1) | (right >>> 31));
|
|
|
-
|
|
|
- //do this either 1 or 3 times for each chunk of the message
|
|
|
- for (j=0; j<iterations; j+=3) {
|
|
|
- endloop = looping[j+1];
|
|
|
- loopinc = looping[j+2];
|
|
|
- //now go through and perform the encryption or decryption
|
|
|
- for (i=looping[j]; i!=endloop; i+=loopinc) { //for efficiency
|
|
|
- right1 = right ^ keys[i];
|
|
|
- right2 = ((right >>> 4) | (right << 28)) ^ keys[i+1];
|
|
|
- //the result is attained by passing these bytes through the S selection functions
|
|
|
- temp = left;
|
|
|
- left = right;
|
|
|
- right = temp ^ (spfunction2[(right1 >>> 24) & 0x3f] | spfunction4[(right1 >>> 16) & 0x3f]
|
|
|
- | spfunction6[(right1 >>> 8) & 0x3f] | spfunction8[right1 & 0x3f]
|
|
|
- | spfunction1[(right2 >>> 24) & 0x3f] | spfunction3[(right2 >>> 16) & 0x3f]
|
|
|
- | spfunction5[(right2 >>> 8) & 0x3f] | spfunction7[right2 & 0x3f]);
|
|
|
- }
|
|
|
- temp = left; left = right; right = temp; //unreverse left and right
|
|
|
- } //for either 1 or 3 iterations
|
|
|
-
|
|
|
- //move then each one bit to the right
|
|
|
- left = ((left >>> 1) | (left << 31));
|
|
|
- right = ((right >>> 1) | (right << 31));
|
|
|
-
|
|
|
- //now perform IP-1, which is IP in the opposite direction
|
|
|
- temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1);
|
|
|
- temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8);
|
|
|
- temp = ((right >>> 2) ^ left) & 0x33333333; left ^= temp; right ^= (temp << 2);
|
|
|
- temp = ((left >>> 16) ^ right) & 0x0000ffff; right ^= temp; left ^= (temp << 16);
|
|
|
- temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4);
|
|
|
-
|
|
|
- //for Cipher Block Chaining mode, xor the message with the previous result
|
|
|
- if (mode == 1) {if (encrypt) {cbcleft = left; cbcright = right;} else {left ^= cbcleft2; right ^= cbcright2;}}
|
|
|
- tempresult = tempresult.concat([(left>>>24), ((left>>>16) & 0xff), ((left>>>8) & 0xff), (left & 0xff), (right>>>24), ((right>>>16) & 0xff), ((right>>>8) & 0xff), (right & 0xff)]);
|
|
|
-
|
|
|
- chunk += 8;
|
|
|
- if (chunk == 512) {result = result.concat(tempresult); tempresult = []; chunk = 0;}
|
|
|
- } //for every 8 characters, or 64 bits in the message
|
|
|
-
|
|
|
- //return the result as an array
|
|
|
- return result.concat(tempresult);
|
|
|
-} //end of des
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-//des_createKeys
|
|
|
-//this takes as input a 64 bit key (even though only 56 bits are used)
|
|
|
-//as an array of 2 integers, and returns 16 48 bit keys
|
|
|
-function des_createKeys (key) {
|
|
|
- //declaring this locally speeds things up a bit
|
|
|
- pc2bytes0 = new Array (0,0x4,0x20000000,0x20000004,0x10000,0x10004,0x20010000,0x20010004,0x200,0x204,0x20000200,0x20000204,0x10200,0x10204,0x20010200,0x20010204);
|
|
|
- pc2bytes1 = new Array (0,0x1,0x100000,0x100001,0x4000000,0x4000001,0x4100000,0x4100001,0x100,0x101,0x100100,0x100101,0x4000100,0x4000101,0x4100100,0x4100101);
|
|
|
- pc2bytes2 = new Array (0,0x8,0x800,0x808,0x1000000,0x1000008,0x1000800,0x1000808,0,0x8,0x800,0x808,0x1000000,0x1000008,0x1000800,0x1000808);
|
|
|
- pc2bytes3 = new Array (0,0x200000,0x8000000,0x8200000,0x2000,0x202000,0x8002000,0x8202000,0x20000,0x220000,0x8020000,0x8220000,0x22000,0x222000,0x8022000,0x8222000);
|
|
|
- pc2bytes4 = new Array (0,0x40000,0x10,0x40010,0,0x40000,0x10,0x40010,0x1000,0x41000,0x1010,0x41010,0x1000,0x41000,0x1010,0x41010);
|
|
|
- pc2bytes5 = new Array (0,0x400,0x20,0x420,0,0x400,0x20,0x420,0x2000000,0x2000400,0x2000020,0x2000420,0x2000000,0x2000400,0x2000020,0x2000420);
|
|
|
- pc2bytes6 = new Array (0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002,0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002);
|
|
|
- pc2bytes7 = new Array (0,0x10000,0x800,0x10800,0x20000000,0x20010000,0x20000800,0x20010800,0x20000,0x30000,0x20800,0x30800,0x20020000,0x20030000,0x20020800,0x20030800);
|
|
|
- pc2bytes8 = new Array (0,0x40000,0,0x40000,0x2,0x40002,0x2,0x40002,0x2000000,0x2040000,0x2000000,0x2040000,0x2000002,0x2040002,0x2000002,0x2040002);
|
|
|
- pc2bytes9 = new Array (0,0x10000000,0x8,0x10000008,0,0x10000000,0x8,0x10000008,0x400,0x10000400,0x408,0x10000408,0x400,0x10000400,0x408,0x10000408);
|
|
|
- pc2bytes10 = new Array (0,0x20,0,0x20,0x100000,0x100020,0x100000,0x100020,0x2000,0x2020,0x2000,0x2020,0x102000,0x102020,0x102000,0x102020);
|
|
|
- pc2bytes11 = new Array (0,0x1000000,0x200,0x1000200,0x200000,0x1200000,0x200200,0x1200200,0x4000000,0x5000000,0x4000200,0x5000200,0x4200000,0x5200000,0x4200200,0x5200200);
|
|
|
- pc2bytes12 = new Array (0,0x1000,0x8000000,0x8001000,0x80000,0x81000,0x8080000,0x8081000,0x10,0x1010,0x8000010,0x8001010,0x80010,0x81010,0x8080010,0x8081010);
|
|
|
- pc2bytes13 = new Array (0,0x4,0x100,0x104,0,0x4,0x100,0x104,0x1,0x5,0x101,0x105,0x1,0x5,0x101,0x105);
|
|
|
-
|
|
|
- //how many iterations (1 for des, 3 for triple des)
|
|
|
- var iterations = key.length > 8 ? 3 : 1; //changed by Paul 16/6/2007 to use Triple DES for 9+ byte keys
|
|
|
- //stores the return keys
|
|
|
- var keys = new Array (32 * iterations);
|
|
|
- //now define the left shifts which need to be done
|
|
|
- var shifts = new Array (0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0);
|
|
|
- //other variables
|
|
|
- var lefttemp, righttemp, m=0, n=0, temp;
|
|
|
-
|
|
|
- for (var j=0; j<iterations; j++) { //either 1 or 3 iterations
|
|
|
- left = (key[m++] << 24) | (key[m++] << 16) | (key[m++] << 8) | key[m++];
|
|
|
- right = (key[m++] << 24) | (key[m++] << 16) | (key[m++] << 8) | key[m++];
|
|
|
-
|
|
|
- temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4);
|
|
|
- temp = ((right >>> -16) ^ left) & 0x0000ffff; left ^= temp; right ^= (temp << -16);
|
|
|
- temp = ((left >>> 2) ^ right) & 0x33333333; right ^= temp; left ^= (temp << 2);
|
|
|
- temp = ((right >>> -16) ^ left) & 0x0000ffff; left ^= temp; right ^= (temp << -16);
|
|
|
- temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1);
|
|
|
- temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8);
|
|
|
- temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1);
|
|
|
-
|
|
|
- //the right side needs to be shifted and to get the last four bits of the left side
|
|
|
- temp = (left << 8) | ((right >>> 20) & 0x000000f0);
|
|
|
- //left needs to be put upside down
|
|
|
- left = (right << 24) | ((right << 8) & 0xff0000) | ((right >>> 8) & 0xff00) | ((right >>> 24) & 0xf0);
|
|
|
- right = temp;
|
|
|
-
|
|
|
- //now go through and perform these shifts on the left and right keys
|
|
|
- for (var i=0; i < shifts.length; i++) {
|
|
|
- //shift the keys either one or two bits to the left
|
|
|
- if (shifts[i]) {left = (left << 2) | (left >>> 26); right = (right << 2) | (right >>> 26);}
|
|
|
- else {left = (left << 1) | (left >>> 27); right = (right << 1) | (right >>> 27);}
|
|
|
- left &= -0xf; right &= -0xf;
|
|
|
-
|
|
|
- //now apply PC-2, in such a way that E is easier when encrypting or decrypting
|
|
|
- //this conversion will look like PC-2 except only the last 6 bits of each byte are used
|
|
|
- //rather than 48 consecutive bits and the order of lines will be according to
|
|
|
- //how the S selection functions will be applied: S2, S4, S6, S8, S1, S3, S5, S7
|
|
|
- lefttemp = pc2bytes0[left >>> 28] | pc2bytes1[(left >>> 24) & 0xf]
|
|
|
- | pc2bytes2[(left >>> 20) & 0xf] | pc2bytes3[(left >>> 16) & 0xf]
|
|
|
- | pc2bytes4[(left >>> 12) & 0xf] | pc2bytes5[(left >>> 8) & 0xf]
|
|
|
- | pc2bytes6[(left >>> 4) & 0xf];
|
|
|
- righttemp = pc2bytes7[right >>> 28] | pc2bytes8[(right >>> 24) & 0xf]
|
|
|
- | pc2bytes9[(right >>> 20) & 0xf] | pc2bytes10[(right >>> 16) & 0xf]
|
|
|
- | pc2bytes11[(right >>> 12) & 0xf] | pc2bytes12[(right >>> 8) & 0xf]
|
|
|
- | pc2bytes13[(right >>> 4) & 0xf];
|
|
|
- temp = ((righttemp >>> 16) ^ lefttemp) & 0x0000ffff;
|
|
|
- keys[n++] = lefttemp ^ temp; keys[n++] = righttemp ^ (temp << 16);
|
|
|
- }
|
|
|
- } //for each iterations
|
|
|
- //return the keys we've created
|
|
|
- return keys;
|
|
|
-} //end of des_createKeys
|
|
|
+ // Tables, permutations, S-boxes, etc.
|
|
|
|
|
|
+ bytebit : [0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80],
|
|
|
+ bigbyte : [ 0x800000, 0x400000, 0x200000, 0x100000,
|
|
|
+ 0x080000, 0x040000, 0x020000, 0x010000, 0x008000, 0x004000,
|
|
|
+ 0x002000, 0x001000, 0x000800, 0x000400, 0x000200, 0x000100,
|
|
|
+ 0x000080, 0x000040, 0x000020, 0x000010, 0x000008, 0x000004,
|
|
|
+ 0x000002, 0x000001],
|
|
|
+ pc1 : [ 56, 48, 40, 32,
|
|
|
+ 24, 16, 8, 0, 57, 49,
|
|
|
+ 41, 33, 25, 17, 9, 1,
|
|
|
+ 58, 50, 42, 34, 26, 18,
|
|
|
+ 10, 2, 59, 51, 43, 35,
|
|
|
+ 62, 54, 46, 38, 30, 22,
|
|
|
+ 14, 6, 61, 53, 45, 37,
|
|
|
+ 29, 21, 13, 5, 60, 52,
|
|
|
+ 44, 36, 28, 20, 12, 4,
|
|
|
+ 27, 19, 11, 3 ],
|
|
|
+ totrot : [ 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21,
|
|
|
+ 23, 25, 27, 28],
|
|
|
+ pc2 : [ 13, 16, 10, 23,
|
|
|
+ 0, 4, 2, 27, 14, 5,
|
|
|
+ 20, 9, 22, 18, 11, 3,
|
|
|
+ 25, 7, 15, 6, 26, 19,
|
|
|
+ 12, 1, 40, 51, 30, 36,
|
|
|
+ 46, 54, 29, 39, 50, 44,
|
|
|
+ 32, 47, 43, 48, 38, 55,
|
|
|
+ 33, 52, 45, 41, 49, 35,
|
|
|
+ 28, 31, ],
|
|
|
+ SP1 : [ 0x01010400, 0x00000000, 0x00010000,
|
|
|
+ 0x01010404, 0x01010004, 0x00010404, 0x00000004, 0x00010000,
|
|
|
+ 0x00000400, 0x01010400, 0x01010404, 0x00000400, 0x01000404,
|
|
|
+ 0x01010004, 0x01000000, 0x00000004, 0x00000404, 0x01000400,
|
|
|
+ 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000,
|
|
|
+ 0x01000404, 0x00010004, 0x01000004, 0x01000004, 0x00010004,
|
|
|
+ 0x00000000, 0x00000404, 0x00010404, 0x01000000, 0x00010000,
|
|
|
+ 0x01010404, 0x00000004, 0x01010000, 0x01010400, 0x01000000,
|
|
|
+ 0x01000000, 0x00000400, 0x01010004, 0x00010000, 0x00010400,
|
|
|
+ 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404,
|
|
|
+ 0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004,
|
|
|
+ 0x00000404, 0x00010404, 0x01010400, 0x00000404, 0x01000400,
|
|
|
+ 0x01000400, 0x00000000, 0x00010004, 0x00010400, 0x00000000,
|
|
|
+ 0x01010004],
|
|
|
+ SP2 : [ 0x80108020, 0x80008000, 0x00008000,
|
|
|
+ 0x00108020, 0x00100000, 0x00000020, 0x80100020, 0x80008020,
|
|
|
+ 0x80000020, 0x80108020, 0x80108000, 0x80000000, 0x80008000,
|
|
|
+ 0x00100000, 0x00000020, 0x80100020, 0x00108000, 0x00100020,
|
|
|
+ 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020,
|
|
|
+ 0x80100000, 0x00100020, 0x80000020, 0x00000000, 0x00108000,
|
|
|
+ 0x00008020, 0x80108000, 0x80100000, 0x00008020, 0x00000000,
|
|
|
+ 0x00108020, 0x80100020, 0x00100000, 0x80008020, 0x80100000,
|
|
|
+ 0x80108000, 0x00008000, 0x80100000, 0x80008000, 0x00000020,
|
|
|
+ 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000,
|
|
|
+ 0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020,
|
|
|
+ 0x80008020, 0x80000020, 0x00100020, 0x00108000, 0x00000000,
|
|
|
+ 0x80008000, 0x00008020, 0x80000000, 0x80100020, 0x80108020,
|
|
|
+ 0x00108000],
|
|
|
+ SP3 : [ 0x00000208, 0x08020200, 0x00000000,
|
|
|
+ 0x08020008, 0x08000200, 0x00000000, 0x00020208, 0x08000200,
|
|
|
+ 0x00020008, 0x08000008, 0x08000008, 0x00020000, 0x08020208,
|
|
|
+ 0x00020008, 0x08020000, 0x00000208, 0x08000000, 0x00000008,
|
|
|
+ 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008,
|
|
|
+ 0x00020208, 0x08000208, 0x00020200, 0x00020000, 0x08000208,
|
|
|
+ 0x00000008, 0x08020208, 0x00000200, 0x08000000, 0x08020200,
|
|
|
+ 0x08000000, 0x00020008, 0x00000208, 0x00020000, 0x08020200,
|
|
|
+ 0x08000200, 0x00000000, 0x00000200, 0x00020008, 0x08020208,
|
|
|
+ 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008,
|
|
|
+ 0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008,
|
|
|
+ 0x00020208, 0x00020200, 0x08000008, 0x08020000, 0x08000208,
|
|
|
+ 0x00000208, 0x08020000, 0x00020208, 0x00000008, 0x08020008,
|
|
|
+ 0x00020200],
|
|
|
+ SP4 : [ 0x00802001, 0x00002081, 0x00002081,
|
|
|
+ 0x00000080, 0x00802080, 0x00800081, 0x00800001, 0x00002001,
|
|
|
+ 0x00000000, 0x00802000, 0x00802000, 0x00802081, 0x00000081,
|
|
|
+ 0x00000000, 0x00800080, 0x00800001, 0x00000001, 0x00002000,
|
|
|
+ 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001,
|
|
|
+ 0x00002080, 0x00800081, 0x00000001, 0x00002080, 0x00800080,
|
|
|
+ 0x00002000, 0x00802080, 0x00802081, 0x00000081, 0x00800080,
|
|
|
+ 0x00800001, 0x00802000, 0x00802081, 0x00000081, 0x00000000,
|
|
|
+ 0x00000000, 0x00802000, 0x00002080, 0x00800080, 0x00800081,
|
|
|
+ 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080,
|
|
|
+ 0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001,
|
|
|
+ 0x00002001, 0x00802080, 0x00800081, 0x00002001, 0x00002080,
|
|
|
+ 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002000,
|
|
|
+ 0x00802080],
|
|
|
+ SP5 : [ 0x00000100, 0x02080100, 0x02080000,
|
|
|
+ 0x42000100, 0x00080000, 0x00000100, 0x40000000, 0x02080000,
|
|
|
+ 0x40080100, 0x00080000, 0x02000100, 0x40080100, 0x42000100,
|
|
|
+ 0x42080000, 0x00080100, 0x40000000, 0x02000000, 0x40080000,
|
|
|
+ 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100,
|
|
|
+ 0x02000100, 0x42080000, 0x40000100, 0x00000000, 0x42000000,
|
|
|
+ 0x02080100, 0x02000000, 0x42000000, 0x00080100, 0x00080000,
|
|
|
+ 0x42000100, 0x00000100, 0x02000000, 0x40000000, 0x02080000,
|
|
|
+ 0x42000100, 0x40080100, 0x02000100, 0x40000000, 0x42080000,
|
|
|
+ 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000,
|
|
|
+ 0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000,
|
|
|
+ 0x00000000, 0x40080000, 0x42000000, 0x00080100, 0x02000100,
|
|
|
+ 0x40000100, 0x00080000, 0x00000000, 0x40080000, 0x02080100,
|
|
|
+ 0x40000100],
|
|
|
+ SP6 : [ 0x20000010, 0x20400000, 0x00004000,
|
|
|
+ 0x20404010, 0x20400000, 0x00000010, 0x20404010, 0x00400000,
|
|
|
+ 0x20004000, 0x00404010, 0x00400000, 0x20000010, 0x00400010,
|
|
|
+ 0x20004000, 0x20000000, 0x00004010, 0x00000000, 0x00400010,
|
|
|
+ 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010,
|
|
|
+ 0x20400010, 0x20400010, 0x00000000, 0x00404010, 0x20404000,
|
|
|
+ 0x00004010, 0x00404000, 0x20404000, 0x20000000, 0x20004000,
|
|
|
+ 0x00000010, 0x20400010, 0x00404000, 0x20404010, 0x00400000,
|
|
|
+ 0x00004010, 0x20000010, 0x00400000, 0x20004000, 0x20000000,
|
|
|
+ 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000,
|
|
|
+ 0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010,
|
|
|
+ 0x00004000, 0x20400000, 0x00404010, 0x00004000, 0x00400010,
|
|
|
+ 0x20004010, 0x00000000, 0x20404000, 0x20000000, 0x00400010,
|
|
|
+ 0x20004010],
|
|
|
+ SP7 : [ 0x00200000, 0x04200002, 0x04000802,
|
|
|
+ 0x00000000, 0x00000800, 0x04000802, 0x00200802, 0x04200800,
|
|
|
+ 0x04200802, 0x00200000, 0x00000000, 0x04000002, 0x00000002,
|
|
|
+ 0x04000000, 0x04200002, 0x00000802, 0x04000800, 0x00200802,
|
|
|
+ 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800,
|
|
|
+ 0x00200002, 0x04200000, 0x00000800, 0x00000802, 0x04200802,
|
|
|
+ 0x00200800, 0x00000002, 0x04000000, 0x00200800, 0x04000000,
|
|
|
+ 0x00200800, 0x00200000, 0x04000802, 0x04000802, 0x04200002,
|
|
|
+ 0x04200002, 0x00000002, 0x00200002, 0x04000000, 0x04000800,
|
|
|
+ 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800,
|
|
|
+ 0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800,
|
|
|
+ 0x00000000, 0x00000002, 0x04200802, 0x00000000, 0x00200802,
|
|
|
+ 0x04200000, 0x00000800, 0x04000002, 0x04000800, 0x00000800,
|
|
|
+ 0x00200002],
|
|
|
+ SP8 : [ 0x10001040, 0x00001000, 0x00040000,
|
|
|
+ 0x10041040, 0x10000000, 0x10001040, 0x00000040, 0x10000000,
|
|
|
+ 0x00040040, 0x10040000, 0x10041040, 0x00041000, 0x10041000,
|
|
|
+ 0x00041040, 0x00001000, 0x00000040, 0x10040000, 0x10000040,
|
|
|
+ 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040,
|
|
|
+ 0x10041000, 0x00001040, 0x00000000, 0x00000000, 0x10040040,
|
|
|
+ 0x10000040, 0x10001000, 0x00041040, 0x00040000, 0x00041040,
|
|
|
+ 0x00040000, 0x10041000, 0x00001000, 0x00000040, 0x10040040,
|
|
|
+ 0x00001000, 0x00041040, 0x10001000, 0x00000040, 0x10000040,
|
|
|
+ 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040,
|
|
|
+ 0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000,
|
|
|
+ 0x10001000, 0x10001040, 0x00000000, 0x10041040, 0x00041000,
|
|
|
+ 0x00041000, 0x00001040, 0x00001040, 0x00040040, 0x10000000,
|
|
|
+ 0x10041000],
|
|
|
|
|
|
+ // Key routines.
|
|
|
|
|
|
-////////////////////////////// TEST //////////////////////////////
|
|
|
-function stringToHex (s) {
|
|
|
- var r = "0x";
|
|
|
- var hexes = new Array ("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f");
|
|
|
- for (var i=0; i<s.length; i++) {r += hexes [s.charCodeAt(i) >> 4] + hexes [s.charCodeAt(i) & 0xf];}
|
|
|
- return r;
|
|
|
-}
|
|
|
+ encryptKeys : [],
|
|
|
+ decryptKeys : [],
|
|
|
|
|
|
-function hexToString (h) {
|
|
|
- var r = "";
|
|
|
- for (var i= (h.substr(0, 2)=="0x")?2:0; i<h.length; i+=2) {r += String.fromCharCode (parseInt (h.substr (i, 2), 16));}
|
|
|
- return r;
|
|
|
-}
|
|
|
+ // / Set the key.
|
|
|
+ setKeys : function(key) {
|
|
|
+ DES.encryptKeys = new Array(32);
|
|
|
+ DES.decryptKeys = new Array(32);
|
|
|
+
|
|
|
+ DES.deskey(key, true, DES.encryptKeys);
|
|
|
+ DES.deskey(key, false, DES.decryptKeys);
|
|
|
+ console.log("DES.encryptKeys: " + DES.encryptKeys);
|
|
|
+ },
|
|
|
|
|
|
-/*
|
|
|
-var key = "this is a 24 byte key !!";
|
|
|
-var message = "This is a test message";
|
|
|
-var ciphertext = des (key, message, 1, 0);
|
|
|
-document.writeln ("DES Test: " + stringToHex (ciphertext));
|
|
|
-*/
|
|
|
+ // Turn an 8-byte key into internal keys.
|
|
|
+ deskey : function(keyBlock, encrypting, KnL) {
|
|
|
+ var i, j, l, m, n;
|
|
|
+ var pc1m = new Array(56);
|
|
|
+ var pcr = new Array(56);
|
|
|
+ var kn = new Array(32);
|
|
|
+
|
|
|
+ for (j = 0; j < 56; ++j) {
|
|
|
+ l = DES.pc1[j];
|
|
|
+ m = l & 07;
|
|
|
+ pc1m[j] = ((keyBlock[l >>> 3] & DES.bytebit[m]) != 0) ? 1: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (i = 0; i < 16; ++i) {
|
|
|
+ if (encrypting)
|
|
|
+ m = i << 1;
|
|
|
+ else
|
|
|
+ m = (15- i) << 1;
|
|
|
+ n = m + 1;
|
|
|
+ kn[m] = kn[n] = 0;
|
|
|
+ for (j = 0; j < 28; ++j) {
|
|
|
+ l = j + DES.totrot[i];
|
|
|
+ if (l < 28)
|
|
|
+ pcr[j] = pc1m[l];
|
|
|
+ else
|
|
|
+ pcr[j] = pc1m[l - 28];
|
|
|
+ }
|
|
|
+ for (j = 28; j < 56; ++j) {
|
|
|
+ l = j + DES.totrot[i];
|
|
|
+ if (l < 56)
|
|
|
+ pcr[j] = pc1m[l];
|
|
|
+ else
|
|
|
+ pcr[j] = pc1m[l - 28];
|
|
|
+ }
|
|
|
+ for (j = 0; j < 24; ++j) {
|
|
|
+ if (pcr[DES.pc2[j]] != 0)
|
|
|
+ kn[m] |= DES.bigbyte[j];
|
|
|
+ if (pcr[DES.pc2[j + 24]] != 0)
|
|
|
+ kn[n] |= DES.bigbyte[j];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ DES.cookey(kn, KnL);
|
|
|
+ },
|
|
|
+
|
|
|
+ cookey: function(raw, KnL) {
|
|
|
+ var raw0, raw1;
|
|
|
+ var rawi, KnLi;
|
|
|
+ var i;
|
|
|
+
|
|
|
+ for (i = 0, rawi = 0, KnLi = 0; i < 16; ++i) {
|
|
|
+ raw0 = raw[rawi++];
|
|
|
+ raw1 = raw[rawi++];
|
|
|
+ KnL[KnLi] = (raw0 & 0x00fc0000) << 6;
|
|
|
+ KnL[KnLi] |= (raw0 & 0x00000fc0) << 10;
|
|
|
+ KnL[KnLi] |= (raw1 & 0x00fc0000) >>> 10;
|
|
|
+ KnL[KnLi] |= (raw1 & 0x00000fc0) >>> 6;
|
|
|
+ ++KnLi;
|
|
|
+ KnL[KnLi] = (raw0 & 0x0003f000) << 12;
|
|
|
+ KnL[KnLi] |= (raw0 & 0x0000003f) << 16;
|
|
|
+ KnL[KnLi] |= (raw1 & 0x0003f000) >>> 4;
|
|
|
+ KnL[KnLi] |= (raw1 & 0x0000003f);
|
|
|
+ ++KnLi;
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // Block encryption routines.
|
|
|
+
|
|
|
+ // / Encrypt a block of eight bytes.
|
|
|
+ encrypt: function(clearText, clearOff, cipherText, cipherOff) {
|
|
|
+ var tempInts = new Array(12);
|
|
|
+ DES.squashBytesToInts(clearText, clearOff, tempInts, 0, 2);
|
|
|
+ DES.des(tempInts, tempInts, DES.encryptKeys);
|
|
|
+ DES.spreadIntsToBytes(tempInts, 0, cipherText, cipherOff, 2);
|
|
|
+ },
|
|
|
+
|
|
|
+ // / Decrypt a block of eight bytes.
|
|
|
+ decrypt: function(cipherText, cipherOff, clearText, clearOff) {
|
|
|
+ var tempInts = new Array(12);
|
|
|
+ DES.squashBytesToInts(cipherText, cipherOff, tempInts, 0, 2);
|
|
|
+ DES.des(tempInts, tempInts, DES.decryptKeys);
|
|
|
+ DES.spreadIntsToBytes(tempInts, 0, clearText, clearOff, 2);
|
|
|
+ },
|
|
|
+
|
|
|
+ // The DES function.
|
|
|
+ des: function(inInts, outInts, keys) {
|
|
|
+ var fval, work, right, leftt;
|
|
|
+ var round;
|
|
|
+ var keysi = 0;
|
|
|
+
|
|
|
+ leftt = inInts[0];
|
|
|
+ right = inInts[1];
|
|
|
+
|
|
|
+ work = ((leftt >>> 4) ^ right) & 0x0f0f0f0f;
|
|
|
+ right ^= work;
|
|
|
+ leftt ^= (work << 4);
|
|
|
+
|
|
|
+ work = ((leftt >>> 16) ^ right) & 0x0000ffff;
|
|
|
+ right ^= work;
|
|
|
+ leftt ^= (work << 16);
|
|
|
+
|
|
|
+ work = ((right >>> 2) ^ leftt) & 0x33333333;
|
|
|
+ leftt ^= work;
|
|
|
+ right ^= (work << 2);
|
|
|
+
|
|
|
+ work = ((right >>> 8) ^ leftt) & 0x00ff00ff;
|
|
|
+ leftt ^= work;
|
|
|
+ right ^= (work << 8);
|
|
|
+ right = (right << 1) | ((right >>> 31) & 1);
|
|
|
+
|
|
|
+ work = (leftt ^ right) & 0xaaaaaaaa;
|
|
|
+ leftt ^= work;
|
|
|
+ right ^= work;
|
|
|
+ leftt = (leftt << 1) | ((leftt >>> 31) & 1);
|
|
|
+
|
|
|
+ for (round = 0; round < 8; ++round) {
|
|
|
+ work = (right << 28) | (right >>> 4);
|
|
|
+ work ^= keys[keysi++];
|
|
|
+ fval = DES.SP7[work & 0x0000003f];
|
|
|
+ fval |= DES.SP5[(work >>> 8) & 0x0000003f];
|
|
|
+ fval |= DES.SP3[(work >>> 16) & 0x0000003f];
|
|
|
+ fval |= DES.SP1[(work >>> 24) & 0x0000003f];
|
|
|
+ work = right ^ keys[keysi++];
|
|
|
+ fval |= DES.SP8[work & 0x0000003f];
|
|
|
+ fval |= DES.SP6[(work >>> 8) & 0x0000003f];
|
|
|
+ fval |= DES.SP4[(work >>> 16) & 0x0000003f];
|
|
|
+ fval |= DES.SP2[(work >>> 24) & 0x0000003f];
|
|
|
+ leftt ^= fval;
|
|
|
+ work = (leftt << 28) | (leftt >>> 4);
|
|
|
+ work ^= keys[keysi++];
|
|
|
+ fval = DES.SP7[work & 0x0000003f];
|
|
|
+ fval |= DES.SP5[(work >>> 8) & 0x0000003f];
|
|
|
+ fval |= DES.SP3[(work >>> 16) & 0x0000003f];
|
|
|
+ fval |= DES.SP1[(work >>> 24) & 0x0000003f];
|
|
|
+ work = leftt ^ keys[keysi++];
|
|
|
+ fval |= DES.SP8[work & 0x0000003f];
|
|
|
+ fval |= DES.SP6[(work >>> 8) & 0x0000003f];
|
|
|
+ fval |= DES.SP4[(work >>> 16) & 0x0000003f];
|
|
|
+ fval |= DES.SP2[(work >>> 24) & 0x0000003f];
|
|
|
+ right ^= fval;
|
|
|
+ }
|
|
|
+
|
|
|
+ right = (right << 31) | (right >>> 1);
|
|
|
+ work = (leftt ^ right) & 0xaaaaaaaa;
|
|
|
+ leftt ^= work;
|
|
|
+ right ^= work;
|
|
|
+ leftt = (leftt << 31) | (leftt >>> 1);
|
|
|
+ work = ((leftt >>> 8) ^ right) & 0x00ff00ff;
|
|
|
+ right ^= work;
|
|
|
+ leftt ^= (work << 8);
|
|
|
+ work = ((leftt >>> 2) ^ right) & 0x33333333;
|
|
|
+ right ^= work;
|
|
|
+ leftt ^= (work << 2);
|
|
|
+ work = ((right >>> 16) ^ leftt) & 0x0000ffff;
|
|
|
+ leftt ^= work;
|
|
|
+ right ^= (work << 16);
|
|
|
+ work = ((right >>> 4) ^ leftt) & 0x0f0f0f0f;
|
|
|
+ leftt ^= work;
|
|
|
+ right ^= (work << 4);
|
|
|
+ outInts[0] = right;
|
|
|
+ outInts[1] = leftt;
|
|
|
+ },
|
|
|
+
|
|
|
+ // Routines taken from other parts of the Acme utilities.
|
|
|
+
|
|
|
+ // / Squash bytes down to ints.
|
|
|
+ squashBytesToInts: function (inBytes, inOff, outInts, outOff, intLen) {
|
|
|
+ for (var i = 0; i < intLen; ++i)
|
|
|
+ outInts[outOff + i] = ((inBytes[inOff + i * 4] & 0xff) << 24)
|
|
|
+ | ((inBytes[inOff + i * 4+ 1] & 0xff) << 16)
|
|
|
+ | ((inBytes[inOff + i * 4+ 2] & 0xff) << 8)
|
|
|
+ | (inBytes[inOff + i * 4+ 3] & 0xff);
|
|
|
+ },
|
|
|
+
|
|
|
+ // / Spread ints into unsigned bytes.
|
|
|
+ spreadIntsToBytes: function (inInts, inOff, outBytes, outOff, intLen) {
|
|
|
+ for (var i = 0; i < intLen; ++i) {
|
|
|
+ outBytes[outOff + i * 4] = (inInts[inOff + i] >>> 24) % 256;
|
|
|
+ outBytes[outOff + i * 4+ 1] = (inInts[inOff + i] >>> 16) % 256;
|
|
|
+ outBytes[outOff + i * 4+ 2] = (inInts[inOff + i] >>> 8) % 256;
|
|
|
+ outBytes[outOff + i * 4+ 3] = (inInts[inOff + i]) % 256;
|
|
|
+ }
|
|
|
+ /* Make unsigned */
|
|
|
+ var idx;
|
|
|
+ for (var i = 0; i < intLen; ++i) {
|
|
|
+ for (var j = 0; j < 4; j++) {
|
|
|
+ idx = outOff + i * 4 + j;
|
|
|
+ if (outBytes[idx] < 0) {
|
|
|
+ outBytes[idx] += 256;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|