twonly-app-dependencies/pointycastle/lib/block/des_base.dart
2025-12-07 16:10:41 +01:00

860 lines
15 KiB
Dart

import 'dart:typed_data';
import 'package:pointycastle/src/ufixnum.dart';
class DesBase {
static final BLOCK_SIZE = 8;
//static final List<int> bytebit = [128, 64, 32, 16, 8, 4, 2, 1];
static final List<int> bytebit = [0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1];
static final List<int> bigbyte = [
0x800000,
0x400000,
0x200000,
0x100000,
0x80000,
0x40000,
0x20000,
0x10000,
0x8000,
0x4000,
0x2000,
0x1000,
0x800,
0x400,
0x200,
0x100,
0x80,
0x40,
0x20,
0x10,
0x8,
0x4,
0x2,
0x1
];
/*
* Use the key schedule specified in the Standard (ANSI X3.92-1981).
*/
static final Uint8List pc1 = Uint8List.fromList([
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
]);
static final Uint8List totrot = Uint8List.fromList(
[1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28]);
static final Uint8List pc2 = Uint8List.fromList([
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
]);
static final List<int> 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
];
static final List<int> 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
];
static final List<int> 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
];
static final List<int> 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
];
static final List<int> 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
];
static final List<int> 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
];
static final List<int> 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
];
static final List<int> 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
];
List<int> generateWorkingKey(bool encrypting, Uint8List key) {
var newKey = List<int>.generate(32, (index) => 0);
var pc1m = List<bool>.generate(56, (index) => false);
var pcr = List<bool>.generate(56, (index) => false);
for (var j = 0; j < 56; j++) {
var l = pc1[j];
pc1m[j] = ((key[shiftr32(l, 3)] & bytebit[l & 07]) != 0);
}
for (var i = 0; i < 16; i++) {
int l, m, n;
if (encrypting) {
m = shiftl32(i, 1);
} else {
m = shiftl32(15 - i, 1);
}
n = m + 1;
newKey[m] = newKey[n] = 0;
for (var j = 0; j < 28; j++) {
l = j + totrot[i];
if (l < 28) {
pcr[j] = pc1m[l];
} else {
pcr[j] = pc1m[l - 28];
}
}
for (var j = 28; j < 56; j++) {
l = j + totrot[i];
if (l < 56) {
pcr[j] = pc1m[l];
} else {
pcr[j] = pc1m[l - 28];
}
}
for (var j = 0; j < 24; j++) {
if (pcr[pc2[j]]) {
newKey[m] |= bigbyte[j];
}
if (pcr[pc2[j + 24]]) {
newKey[n] |= bigbyte[j];
}
}
}
//
// store the processed key
//
for (var i = 0; i != 32; i += 2) {
int i1, i2;
i1 = newKey[i];
i2 = newKey[i + 1];
newKey[i] = (shiftl32(i1 & 0x00fc0000, 6)) |
(shiftl32(i1 & 0x00000fc0, 10)) |
(shiftr32(i2 & 0x00fc0000, 10)) |
(shiftr32(i2 & 0x00000fc0, 6));
newKey[i + 1] = (shiftl32(i1 & 0x0003f000, 12)) |
(shiftl32(i1 & 0x0000003f, 16)) |
(shiftr32(i2 & 0x0003f000, 4)) |
(i2 & 0x0000003f);
}
return newKey;
}
void desFunc(
List<int> wKey,
Uint8List inp,
int inOff,
Uint8List out,
int outOff,
) {
int work, right, left;
left = _bigEndianToInt(inp, inOff);
right = _bigEndianToInt(inp, inOff + 4);
work = ((shiftr32(left, 4)) ^ right) & 0x0f0f0f0f;
right ^= work;
left ^= shiftl32(work, 4);
work = ((shiftr32(left, 16)) ^ right) & 0x0000ffff;
right ^= work;
left ^= shiftl32(work, 16);
work = ((shiftr32(right, 2)) ^ left) & 0x33333333;
left ^= work;
right ^= shiftl32(work, 2);
work = ((shiftr32(right, 8)) ^ left) & 0x00ff00ff;
left ^= work;
right ^= shiftl32(work, 8);
right = (shiftl32(right, 1)) | (shiftr32(right, 31));
work = (left ^ right) & 0xaaaaaaaa;
left ^= work;
right ^= work;
left = (shiftl32(left, 1)) | (shiftr32(left, 31));
for (var round = 0; round < 8; round++) {
int fval;
work = (shiftl32(right, 28)) | (shiftr32(right, 4));
work ^= wKey[round * 4 + 0];
fval = SP7[work & 0x3f];
fval |= SP5[(shiftr32(work, 8)) & 0x3f];
fval |= SP3[(shiftr32(work, 16)) & 0x3f];
fval |= SP1[(shiftr32(work, 24)) & 0x3f];
work = right ^ wKey[round * 4 + 1];
fval |= SP8[work & 0x3f];
fval |= SP6[(shiftr32(work, 8)) & 0x3f];
fval |= SP4[(shiftr32(work, 16)) & 0x3f];
fval |= SP2[(shiftr32(work, 24)) & 0x3f];
left ^= fval;
work = (shiftl32(left, 28)) | (shiftr32(left, 4));
work ^= wKey[round * 4 + 2];
fval = SP7[work & 0x3f];
fval |= SP5[(shiftr32(work, 8)) & 0x3f];
fval |= SP3[(shiftr32(work, 16)) & 0x3f];
fval |= SP1[(shiftr32(work, 24)) & 0x3f];
work = left ^ wKey[round * 4 + 3];
fval |= SP8[work & 0x3f];
fval |= SP6[(shiftr32(work, 8)) & 0x3f];
fval |= SP4[(shiftr32(work, 16)) & 0x3f];
fval |= SP2[(shiftr32(work, 24)) & 0x3f];
right ^= fval;
}
right = (shiftl32(right, 31)) | (shiftr32(right, 1));
work = (left ^ right) & 0xaaaaaaaa;
left ^= work;
right ^= work;
left = (shiftl32(left, 31)) | (shiftr32(left, 1));
work = ((shiftr32(left, 8)) ^ right) & 0x00ff00ff;
right ^= work;
left ^= shiftl32(work, 8);
work = ((shiftr32(left, 2)) ^ right) & 0x33333333;
right ^= work;
left ^= shiftl32(work, 2);
work = ((shiftr32(right, 16)) ^ left) & 0x0000ffff;
left ^= work;
right ^= shiftl32(work, 16);
work = ((shiftr32(right, 4)) ^ left) & 0x0f0f0f0f;
left ^= work;
right ^= shiftl32(work, 4);
_intToBigEndian(right, out, outOff);
_intToBigEndian(left, out, outOff + 4);
}
void _intToBigEndian(int n, Uint8List bs, int off) {
bs[off] = shiftr32(n, 24);
bs[++off] = shiftr32(n, 16);
bs[++off] = shiftr32(n, 8);
bs[++off] = n;
}
int _bigEndianToInt(Uint8List bs, int off) {
var n = shiftl32(bs[off], 24);
n |= shiftl32(bs[++off] & 0xff, 16);
n |= shiftl32(bs[++off] & 0xff, 8);
n |= bs[++off] & 0xff;
return n;
}
}