4
* An Actionscript 3 implementation of the Data Encryption Standard (DES)
5
* Copyright (c) 2007 Henri Torgemane
8
* The Bouncy Castle Crypto package,
9
* Copyright (c) 2000-2004 The Legion Of The Bouncy Castle
10
* (http://www.bouncycastle.org)
12
* See LICENSE.txt for full license information.
14
package com.hurlant.crypto.symmetric
16
import flash.utils.ByteArray;
17
import com.hurlant.util.Hex;
18
import com.hurlant.util.Memory;
20
public class DESKey implements ISymmetricKey
23
* what follows is mainly taken from "Applied Cryptography", by Bruce
24
* Schneier, however it also bears great resemblance to Richard
25
* Outerbridge's D3DES...
28
private static const Df_Key:Array = [ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32,
29
0x10, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67 ];
31
private static const bytebit:Array = [ 128, 64, 32, 16, 8, 4, 2, 1 ];
33
private static const bigbyte:Array = [ 0x800000, 0x400000, 0x200000, 0x100000, 0x80000, 0x40000, 0x20000, 0x10000, 0x8000,
34
0x4000, 0x2000, 0x1000, 0x800, 0x400, 0x200, 0x100, 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1 ];
37
* Use the key schedule specified in the Standard (ANSI X3.92-1981).
40
private static const pc1:Array = [ 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2,
41
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,
44
private static const totrot:Array = [ 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 ];
46
private static const pc2:Array = [ 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,
47
51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 ];
49
private static const SP1:Array = [ 0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404, 0x00000004,
50
0x00010000, 0x00000400, 0x01010400, 0x01010404, 0x00000400, 0x01000404, 0x01010004, 0x01000000, 0x00000004,
51
0x00000404, 0x01000400, 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404, 0x00010004,
52
0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404, 0x00010404, 0x01000000, 0x00010000, 0x01010404,
53
0x00000004, 0x01010000, 0x01010400, 0x01000000, 0x01000000, 0x00000400, 0x01010004, 0x00010000, 0x00010400,
54
0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404, 0x01010404, 0x00010004, 0x01010000, 0x01000404,
55
0x01000004, 0x00000404, 0x00010404, 0x01010400, 0x00000404, 0x01000400, 0x01000400, 0x00000000, 0x00010004,
56
0x00010400, 0x00000000, 0x01010004 ];
58
private static const SP2:Array = [ 0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020, 0x80100020,
59
0x80008020, 0x80000020, 0x80108020, 0x80108000, 0x80000000, 0x80008000, 0x00100000, 0x00000020, 0x80100020,
60
0x00108000, 0x00100020, 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000, 0x00100020,
61
0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000, 0x80100000, 0x00008020, 0x00000000, 0x00108020,
62
0x80100020, 0x00100000, 0x80008020, 0x80100000, 0x80108000, 0x00008000, 0x80100000, 0x80008000, 0x00000020,
63
0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000, 0x00008020, 0x80108000, 0x00100000, 0x80000020,
64
0x00100020, 0x80008020, 0x80000020, 0x00100020, 0x00108000, 0x00000000, 0x80008000, 0x00008020, 0x80000000,
65
0x80100020, 0x80108020, 0x00108000 ];
67
private static const SP3:Array = [ 0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000, 0x00020208,
68
0x08000200, 0x00020008, 0x08000008, 0x08000008, 0x00020000, 0x08020208, 0x00020008, 0x08020000, 0x00000208,
69
0x08000000, 0x00000008, 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208, 0x08000208,
70
0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208, 0x00000200, 0x08000000, 0x08020200, 0x08000000,
71
0x00020008, 0x00000208, 0x00020000, 0x08020200, 0x08000200, 0x00000000, 0x00000200, 0x00020008, 0x08020208,
72
0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008, 0x08000208, 0x00020000, 0x08000000, 0x08020208,
73
0x00000008, 0x00020208, 0x00020200, 0x08000008, 0x08020000, 0x08000208, 0x00000208, 0x08020000, 0x00020208,
74
0x00000008, 0x08020008, 0x00020200 ];
76
private static const SP4:Array = [ 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081, 0x00800001,
77
0x00002001, 0x00000000, 0x00802000, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00800080, 0x00800001,
78
0x00000001, 0x00002000, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080, 0x00800081,
79
0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080, 0x00802081, 0x00000081, 0x00800080, 0x00800001,
80
0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00000000, 0x00802000, 0x00002080, 0x00800080, 0x00800081,
81
0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802081, 0x00000081, 0x00000001, 0x00002000,
82
0x00800001, 0x00002001, 0x00802080, 0x00800081, 0x00002001, 0x00002080, 0x00800000, 0x00802001, 0x00000080,
83
0x00800000, 0x00002000, 0x00802080 ];
85
private static const SP5:Array = [ 0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100, 0x40000000,
86
0x02080000, 0x40080100, 0x00080000, 0x02000100, 0x40080100, 0x42000100, 0x42080000, 0x00080100, 0x40000000,
87
0x02000000, 0x40080000, 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100, 0x42080000,
88
0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000, 0x42000000, 0x00080100, 0x00080000, 0x42000100,
89
0x00000100, 0x02000000, 0x40000000, 0x02080000, 0x42000100, 0x40080100, 0x02000100, 0x40000000, 0x42080000,
90
0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000, 0x42080100, 0x00080100, 0x42000000, 0x42080100,
91
0x02080000, 0x00000000, 0x40080000, 0x42000000, 0x00080100, 0x02000100, 0x40000100, 0x00080000, 0x00000000,
92
0x40080000, 0x02080100, 0x40000100 ];
94
private static const SP6:Array = [ 0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010, 0x20404010,
95
0x00400000, 0x20004000, 0x00404010, 0x00400000, 0x20000010, 0x00400010, 0x20004000, 0x20000000, 0x00004010,
96
0x00000000, 0x00400010, 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010, 0x20400010,
97
0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000, 0x20404000, 0x20000000, 0x20004000, 0x00000010,
98
0x20400010, 0x00404000, 0x20404010, 0x00400000, 0x00004010, 0x20000010, 0x00400000, 0x20004000, 0x20000000,
99
0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000, 0x00404010, 0x20404000, 0x00000000, 0x20400010,
100
0x00000010, 0x00004000, 0x20400000, 0x00404010, 0x00004000, 0x00400010, 0x20004010, 0x00000000, 0x20404000,
101
0x20000000, 0x00400010, 0x20004010 ];
103
private static const SP7:Array = [ 0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802, 0x00200802,
104
0x04200800, 0x04200802, 0x00200000, 0x00000000, 0x04000002, 0x00000002, 0x04000000, 0x04200002, 0x00000802,
105
0x04000800, 0x00200802, 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002, 0x04200000,
106
0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002, 0x04000000, 0x00200800, 0x04000000, 0x00200800,
107
0x00200000, 0x04000802, 0x04000802, 0x04200002, 0x04200002, 0x00000002, 0x00200002, 0x04000000, 0x04000800,
108
0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800, 0x00000802, 0x04000002, 0x04200802, 0x04200000,
109
0x00200800, 0x00000000, 0x00000002, 0x04200802, 0x00000000, 0x00200802, 0x04200000, 0x00000800, 0x04000002,
110
0x04000800, 0x00000800, 0x00200002 ];
112
private static const SP8:Array = [ 0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040, 0x00000040,
113
0x10000000, 0x00040040, 0x10040000, 0x10041040, 0x00041000, 0x10041000, 0x00041040, 0x00001000, 0x00000040,
114
0x10040000, 0x10000040, 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000, 0x00001040,
115
0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000, 0x00041040, 0x00040000, 0x00041040, 0x00040000,
116
0x10041000, 0x00001000, 0x00000040, 0x10040040, 0x00001000, 0x00041040, 0x10001000, 0x00000040, 0x10000040,
117
0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040, 0x00000000, 0x10041040, 0x00040040, 0x10000040,
118
0x10040000, 0x10001000, 0x10001040, 0x00000000, 0x10041040, 0x00041000, 0x00041000, 0x00001040, 0x00001040,
119
0x00040040, 0x10000000, 0x10041000 ];
122
protected var key:ByteArray;
123
protected var encKey:Array;
124
protected var decKey:Array;
127
public function DESKey(key:ByteArray) {
129
this.encKey = generateWorkingKey(true, key, 0);
130
this.decKey = generateWorkingKey(false, key, 0);
133
public function getBlockSize():uint
138
public function decrypt(block:ByteArray, index:uint=0):void
140
desFunc(decKey, block, index, block, index);
143
public function dispose():void
146
for (i=0;i<encKey.length;i++) { encKey[i]=0; }
147
for (i=0;i<decKey.length;i++) { decKey[i]=0; }
150
for (i=0;i<key.length;i++) { key[i]=0; }
156
public function encrypt(block:ByteArray, index:uint=0):void
158
desFunc(encKey, block, index, block, index);
163
* generate an integer based working key based on our secret key and what we
164
* processing we are planning to do.
166
* Acknowledgements for this routine go to James Gillogly & Phil Karn.
168
protected function generateWorkingKey(encrypting:Boolean, key:ByteArray, off:uint):Array
170
//int[] newKey = new int[32];
171
var newKey:Array = [];
172
//boolean[] pc1m = new boolean[56], pcr = new boolean[56];
173
var pc1m:ByteArray = new ByteArray;
174
var pcr:ByteArray = new ByteArray;
178
for (var j:uint = 0; j < 56; j++)
182
pc1m[j] = ((key[off + (l >>> 3)] & bytebit[l & 07]) != 0);
185
for (var i:uint = 0; i < 16; i++)
200
newKey[m] = newKey[n] = 0;
202
for (j = 0; j < 28; j++)
211
pcr[j] = pc1m[l - 28];
215
for (j = 28; j < 56; j++)
224
pcr[j] = pc1m[l - 28];
228
for (j = 0; j < 24; j++)
232
newKey[m] |= bigbyte[j];
235
if (pcr[pc2[j + 24]])
237
newKey[n] |= bigbyte[j];
243
// store the processed key
245
for (i = 0; i != 32; i += 2)
253
newKey[i] = ((i1 & 0x00fc0000) << 6) | ((i1 & 0x00000fc0) << 10) | ((i2 & 0x00fc0000) >>> 10)
254
| ((i2 & 0x00000fc0) >>> 6);
256
newKey[i + 1] = ((i1 & 0x0003f000) << 12) | ((i1 & 0x0000003f) << 16) | ((i2 & 0x0003f000) >>> 4)
265
protected function desFunc(wKey:Array, inp:ByteArray, inOff:uint, out:ByteArray, outOff:uint):void
271
left = (inp[inOff + 0] & 0xff) << 24;
272
left |= (inp[inOff + 1] & 0xff) << 16;
273
left |= (inp[inOff + 2] & 0xff) << 8;
274
left |= (inp[inOff + 3] & 0xff);
276
right = (inp[inOff + 4] & 0xff) << 24;
277
right |= (inp[inOff + 5] & 0xff) << 16;
278
right |= (inp[inOff + 6] & 0xff) << 8;
279
right |= (inp[inOff + 7] & 0xff);
281
work = ((left >>> 4) ^ right) & 0x0f0f0f0f;
284
work = ((left >>> 16) ^ right) & 0x0000ffff;
286
left ^= (work << 16);
287
work = ((right >>> 2) ^ left) & 0x33333333;
289
right ^= (work << 2);
290
work = ((right >>> 8) ^ left) & 0x00ff00ff;
292
right ^= (work << 8);
293
right = ((right << 1) | ((right >>> 31) & 1)) & 0xffffffff;
294
work = (left ^ right) & 0xaaaaaaaa;
297
left = ((left << 1) | ((left >>> 31) & 1)) & 0xffffffff;
299
for (var round:uint = 0; round < 8; round++)
303
work = (right << 28) | (right >>> 4);
304
work ^= wKey[round * 4 + 0];
305
fval = SP7[work & 0x3f];
306
fval |= SP5[(work >>> 8) & 0x3f];
307
fval |= SP3[(work >>> 16) & 0x3f];
308
fval |= SP1[(work >>> 24) & 0x3f];
309
work = right ^ wKey[round * 4 + 1];
310
fval |= SP8[work & 0x3f];
311
fval |= SP6[(work >>> 8) & 0x3f];
312
fval |= SP4[(work >>> 16) & 0x3f];
313
fval |= SP2[(work >>> 24) & 0x3f];
315
work = (left << 28) | (left >>> 4);
316
work ^= wKey[round * 4 + 2];
317
fval = SP7[work & 0x3f];
318
fval |= SP5[(work >>> 8) & 0x3f];
319
fval |= SP3[(work >>> 16) & 0x3f];
320
fval |= SP1[(work >>> 24) & 0x3f];
321
work = left ^ wKey[round * 4 + 3];
322
fval |= SP8[work & 0x3f];
323
fval |= SP6[(work >>> 8) & 0x3f];
324
fval |= SP4[(work >>> 16) & 0x3f];
325
fval |= SP2[(work >>> 24) & 0x3f];
329
right = (right << 31) | (right >>> 1);
330
work = (left ^ right) & 0xaaaaaaaa;
333
left = (left << 31) | (left >>> 1);
334
work = ((left >>> 8) ^ right) & 0x00ff00ff;
337
work = ((left >>> 2) ^ right) & 0x33333333;
340
work = ((right >>> 16) ^ left) & 0x0000ffff;
342
right ^= (work << 16);
343
work = ((right >>> 4) ^ left) & 0x0f0f0f0f;
345
right ^= (work << 4);
347
out[outOff + 0] = ((right >>> 24) & 0xff);
348
out[outOff + 1] = ((right >>> 16) & 0xff);
349
out[outOff + 2] = ((right >>> 8) & 0xff);
350
out[outOff + 3] = (right & 0xff);
351
out[outOff + 4] = ((left >>> 24) & 0xff);
352
out[outOff + 5] = ((left >>> 16) & 0xff);
353
out[outOff + 6] = ((left >>> 8) & 0xff);
354
out[outOff + 7] = (left & 0xff);
358
public function toString():String {
b'\\ No newline at end of file'