511 lines
22 KiB
C#
511 lines
22 KiB
C#
using System;
|
|
using Org.BouncyCastle.Crypto.Parameters;
|
|
using Org.BouncyCastle.Crypto.Utilities;
|
|
using Org.BouncyCastle.Utilities;
|
|
|
|
namespace Org.BouncyCastle.Crypto.Engines;
|
|
|
|
public class AesEngine : IBlockCipher
|
|
{
|
|
private const uint m1 = 2155905152u;
|
|
|
|
private const uint m2 = 2139062143u;
|
|
|
|
private const uint m3 = 27u;
|
|
|
|
private const uint m4 = 3233857728u;
|
|
|
|
private const uint m5 = 1061109567u;
|
|
|
|
private const int BLOCK_SIZE = 16;
|
|
|
|
private static readonly byte[] S = new byte[256]
|
|
{
|
|
99, 124, 119, 123, 242, 107, 111, 197, 48, 1,
|
|
103, 43, 254, 215, 171, 118, 202, 130, 201, 125,
|
|
250, 89, 71, 240, 173, 212, 162, 175, 156, 164,
|
|
114, 192, 183, 253, 147, 38, 54, 63, 247, 204,
|
|
52, 165, 229, 241, 113, 216, 49, 21, 4, 199,
|
|
35, 195, 24, 150, 5, 154, 7, 18, 128, 226,
|
|
235, 39, 178, 117, 9, 131, 44, 26, 27, 110,
|
|
90, 160, 82, 59, 214, 179, 41, 227, 47, 132,
|
|
83, 209, 0, 237, 32, 252, 177, 91, 106, 203,
|
|
190, 57, 74, 76, 88, 207, 208, 239, 170, 251,
|
|
67, 77, 51, 133, 69, 249, 2, 127, 80, 60,
|
|
159, 168, 81, 163, 64, 143, 146, 157, 56, 245,
|
|
188, 182, 218, 33, 16, 255, 243, 210, 205, 12,
|
|
19, 236, 95, 151, 68, 23, 196, 167, 126, 61,
|
|
100, 93, 25, 115, 96, 129, 79, 220, 34, 42,
|
|
144, 136, 70, 238, 184, 20, 222, 94, 11, 219,
|
|
224, 50, 58, 10, 73, 6, 36, 92, 194, 211,
|
|
172, 98, 145, 149, 228, 121, 231, 200, 55, 109,
|
|
141, 213, 78, 169, 108, 86, 244, 234, 101, 122,
|
|
174, 8, 186, 120, 37, 46, 28, 166, 180, 198,
|
|
232, 221, 116, 31, 75, 189, 139, 138, 112, 62,
|
|
181, 102, 72, 3, 246, 14, 97, 53, 87, 185,
|
|
134, 193, 29, 158, 225, 248, 152, 17, 105, 217,
|
|
142, 148, 155, 30, 135, 233, 206, 85, 40, 223,
|
|
140, 161, 137, 13, 191, 230, 66, 104, 65, 153,
|
|
45, 15, 176, 84, 187, 22
|
|
};
|
|
|
|
private static readonly byte[] Si = new byte[256]
|
|
{
|
|
82, 9, 106, 213, 48, 54, 165, 56, 191, 64,
|
|
163, 158, 129, 243, 215, 251, 124, 227, 57, 130,
|
|
155, 47, 255, 135, 52, 142, 67, 68, 196, 222,
|
|
233, 203, 84, 123, 148, 50, 166, 194, 35, 61,
|
|
238, 76, 149, 11, 66, 250, 195, 78, 8, 46,
|
|
161, 102, 40, 217, 36, 178, 118, 91, 162, 73,
|
|
109, 139, 209, 37, 114, 248, 246, 100, 134, 104,
|
|
152, 22, 212, 164, 92, 204, 93, 101, 182, 146,
|
|
108, 112, 72, 80, 253, 237, 185, 218, 94, 21,
|
|
70, 87, 167, 141, 157, 132, 144, 216, 171, 0,
|
|
140, 188, 211, 10, 247, 228, 88, 5, 184, 179,
|
|
69, 6, 208, 44, 30, 143, 202, 63, 15, 2,
|
|
193, 175, 189, 3, 1, 19, 138, 107, 58, 145,
|
|
17, 65, 79, 103, 220, 234, 151, 242, 207, 206,
|
|
240, 180, 230, 115, 150, 172, 116, 34, 231, 173,
|
|
53, 133, 226, 249, 55, 232, 28, 117, 223, 110,
|
|
71, 241, 26, 113, 29, 41, 197, 137, 111, 183,
|
|
98, 14, 170, 24, 190, 27, 252, 86, 62, 75,
|
|
198, 210, 121, 32, 154, 219, 192, 254, 120, 205,
|
|
90, 244, 31, 221, 168, 51, 136, 7, 199, 49,
|
|
177, 18, 16, 89, 39, 128, 236, 95, 96, 81,
|
|
127, 169, 25, 181, 74, 13, 45, 229, 122, 159,
|
|
147, 201, 156, 239, 160, 224, 59, 77, 174, 42,
|
|
245, 176, 200, 235, 187, 60, 131, 83, 153, 97,
|
|
23, 43, 4, 126, 186, 119, 214, 38, 225, 105,
|
|
20, 99, 85, 33, 12, 125
|
|
};
|
|
|
|
private static readonly byte[] rcon = new byte[30]
|
|
{
|
|
1, 2, 4, 8, 16, 32, 64, 128, 27, 54,
|
|
108, 216, 171, 77, 154, 47, 94, 188, 99, 198,
|
|
151, 53, 106, 212, 179, 125, 250, 239, 197, 145
|
|
};
|
|
|
|
private static readonly uint[] T0 = new uint[256]
|
|
{
|
|
2774754246u, 2222750968u, 2574743534u, 2373680118u, 234025727u, 3177933782u, 2976870366u, 1422247313u, 1345335392u, 50397442u,
|
|
2842126286u, 2099981142u, 436141799u, 1658312629u, 3870010189u, 2591454956u, 1170918031u, 2642575903u, 1086966153u, 2273148410u,
|
|
368769775u, 3948501426u, 3376891790u, 200339707u, 3970805057u, 1742001331u, 4255294047u, 3937382213u, 3214711843u, 4154762323u,
|
|
2524082916u, 1539358875u, 3266819957u, 486407649u, 2928907069u, 1780885068u, 1513502316u, 1094664062u, 49805301u, 1338821763u,
|
|
1546925160u, 4104496465u, 887481809u, 150073849u, 2473685474u, 1943591083u, 1395732834u, 1058346282u, 201589768u, 1388824469u,
|
|
1696801606u, 1589887901u, 672667696u, 2711000631u, 251987210u, 3046808111u, 151455502u, 907153956u, 2608889883u, 1038279391u,
|
|
652995533u, 1764173646u, 3451040383u, 2675275242u, 453576978u, 2659418909u, 1949051992u, 773462580u, 756751158u, 2993581788u,
|
|
3998898868u, 4221608027u, 4132590244u, 1295727478u, 1641469623u, 3467883389u, 2066295122u, 1055122397u, 1898917726u, 2542044179u,
|
|
4115878822u, 1758581177u, 0u, 753790401u, 1612718144u, 536673507u, 3367088505u, 3982187446u, 3194645204u, 1187761037u,
|
|
3653156455u, 1262041458u, 3729410708u, 3561770136u, 3898103984u, 1255133061u, 1808847035u, 720367557u, 3853167183u, 385612781u,
|
|
3309519750u, 3612167578u, 1429418854u, 2491778321u, 3477423498u, 284817897u, 100794884u, 2172616702u, 4031795360u, 1144798328u,
|
|
3131023141u, 3819481163u, 4082192802u, 4272137053u, 3225436288u, 2324664069u, 2912064063u, 3164445985u, 1211644016u, 83228145u,
|
|
3753688163u, 3249976951u, 1977277103u, 1663115586u, 806359072u, 452984805u, 250868733u, 1842533055u, 1288555905u, 336333848u,
|
|
890442534u, 804056259u, 3781124030u, 2727843637u, 3427026056u, 957814574u, 1472513171u, 4071073621u, 2189328124u, 1195195770u,
|
|
2892260552u, 3881655738u, 723065138u, 2507371494u, 2690670784u, 2558624025u, 3511635870u, 2145180835u, 1713513028u, 2116692564u,
|
|
2878378043u, 2206763019u, 3393603212u, 703524551u, 3552098411u, 1007948840u, 2044649127u, 3797835452u, 487262998u, 1994120109u,
|
|
1004593371u, 1446130276u, 1312438900u, 503974420u, 3679013266u, 168166924u, 1814307912u, 3831258296u, 1573044895u, 1859376061u,
|
|
4021070915u, 2791465668u, 2828112185u, 2761266481u, 937747667u, 2339994098u, 854058965u, 1137232011u, 1496790894u, 3077402074u,
|
|
2358086913u, 1691735473u, 3528347292u, 3769215305u, 3027004632u, 4199962284u, 133494003u, 636152527u, 2942657994u, 2390391540u,
|
|
3920539207u, 403179536u, 3585784431u, 2289596656u, 1864705354u, 1915629148u, 605822008u, 4054230615u, 3350508659u, 1371981463u,
|
|
602466507u, 2094914977u, 2624877800u, 555687742u, 3712699286u, 3703422305u, 2257292045u, 2240449039u, 2423288032u, 1111375484u,
|
|
3300242801u, 2858837708u, 3628615824u, 84083462u, 32962295u, 302911004u, 2741068226u, 1597322602u, 4183250862u, 3501832553u,
|
|
2441512471u, 1489093017u, 656219450u, 3114180135u, 954327513u, 335083755u, 3013122091u, 856756514u, 3144247762u, 1893325225u,
|
|
2307821063u, 2811532339u, 3063651117u, 572399164u, 2458355477u, 552200649u, 1238290055u, 4283782570u, 2015897680u, 2061492133u,
|
|
2408352771u, 4171342169u, 2156497161u, 386731290u, 3669999461u, 837215959u, 3326231172u, 3093850320u, 3275833730u, 2962856233u,
|
|
1999449434u, 286199582u, 3417354363u, 4233385128u, 3602627437u, 974525996u
|
|
};
|
|
|
|
private static readonly uint[] Tinv0 = new uint[256]
|
|
{
|
|
1353184337u, 1399144830u, 3282310938u, 2522752826u, 3412831035u, 4047871263u, 2874735276u, 2466505547u, 1442459680u, 4134368941u,
|
|
2440481928u, 625738485u, 4242007375u, 3620416197u, 2151953702u, 2409849525u, 1230680542u, 1729870373u, 2551114309u, 3787521629u,
|
|
41234371u, 317738113u, 2744600205u, 3338261355u, 3881799427u, 2510066197u, 3950669247u, 3663286933u, 763608788u, 3542185048u,
|
|
694804553u, 1154009486u, 1787413109u, 2021232372u, 1799248025u, 3715217703u, 3058688446u, 397248752u, 1722556617u, 3023752829u,
|
|
407560035u, 2184256229u, 1613975959u, 1165972322u, 3765920945u, 2226023355u, 480281086u, 2485848313u, 1483229296u, 436028815u,
|
|
2272059028u, 3086515026u, 601060267u, 3791801202u, 1468997603u, 715871590u, 120122290u, 63092015u, 2591802758u, 2768779219u,
|
|
4068943920u, 2997206819u, 3127509762u, 1552029421u, 723308426u, 2461301159u, 4042393587u, 2715969870u, 3455375973u, 3586000134u,
|
|
526529745u, 2331944644u, 2639474228u, 2689987490u, 853641733u, 1978398372u, 971801355u, 2867814464u, 111112542u, 1360031421u,
|
|
4186579262u, 1023860118u, 2919579357u, 1186850381u, 3045938321u, 90031217u, 1876166148u, 4279586912u, 620468249u, 2548678102u,
|
|
3426959497u, 2006899047u, 3175278768u, 2290845959u, 945494503u, 3689859193u, 1191869601u, 3910091388u, 3374220536u, 0u,
|
|
2206629897u, 1223502642u, 2893025566u, 1316117100u, 4227796733u, 1446544655u, 517320253u, 658058550u, 1691946762u, 564550760u,
|
|
3511966619u, 976107044u, 2976320012u, 266819475u, 3533106868u, 2660342555u, 1338359936u, 2720062561u, 1766553434u, 370807324u,
|
|
179999714u, 3844776128u, 1138762300u, 488053522u, 185403662u, 2915535858u, 3114841645u, 3366526484u, 2233069911u, 1275557295u,
|
|
3151862254u, 4250959779u, 2670068215u, 3170202204u, 3309004356u, 880737115u, 1982415755u, 3703972811u, 1761406390u, 1676797112u,
|
|
3403428311u, 277177154u, 1076008723u, 538035844u, 2099530373u, 4164795346u, 288553390u, 1839278535u, 1261411869u, 4080055004u,
|
|
3964831245u, 3504587127u, 1813426987u, 2579067049u, 4199060497u, 577038663u, 3297574056u, 440397984u, 3626794326u, 4019204898u,
|
|
3343796615u, 3251714265u, 4272081548u, 906744984u, 3481400742u, 685669029u, 646887386u, 2764025151u, 3835509292u, 227702864u,
|
|
2613862250u, 1648787028u, 3256061430u, 3904428176u, 1593260334u, 4121936770u, 3196083615u, 2090061929u, 2838353263u, 3004310991u,
|
|
999926984u, 2809993232u, 1852021992u, 2075868123u, 158869197u, 4095236462u, 28809964u, 2828685187u, 1701746150u, 2129067946u,
|
|
147831841u, 3873969647u, 3650873274u, 3459673930u, 3557400554u, 3598495785u, 2947720241u, 824393514u, 815048134u, 3227951669u,
|
|
935087732u, 2798289660u, 2966458592u, 366520115u, 1251476721u, 4158319681u, 240176511u, 804688151u, 2379631990u, 1303441219u,
|
|
1414376140u, 3741619940u, 3820343710u, 461924940u, 3089050817u, 2136040774u, 82468509u, 1563790337u, 1937016826u, 776014843u,
|
|
1511876531u, 1389550482u, 861278441u, 323475053u, 2355222426u, 2047648055u, 2383738969u, 2302415851u, 3995576782u, 902390199u,
|
|
3991215329u, 1018251130u, 1507840668u, 1064563285u, 2043548696u, 3208103795u, 3939366739u, 1537932639u, 342834655u, 2262516856u,
|
|
2180231114u, 1053059257u, 741614648u, 1598071746u, 1925389590u, 203809468u, 2336832552u, 1100287487u, 1895934009u, 3736275976u,
|
|
2632234200u, 2428589668u, 1636092795u, 1890988757u, 1952214088u, 1113045200u
|
|
};
|
|
|
|
private int ROUNDS;
|
|
|
|
private uint[][] WorkingKey;
|
|
|
|
private uint C0;
|
|
|
|
private uint C1;
|
|
|
|
private uint C2;
|
|
|
|
private uint C3;
|
|
|
|
private bool forEncryption;
|
|
|
|
private byte[] s;
|
|
|
|
public virtual string AlgorithmName => "AES";
|
|
|
|
public virtual bool IsPartialBlockOkay => false;
|
|
|
|
private static uint Shift(uint r, int shift)
|
|
{
|
|
return (r >> shift) | (r << 32 - shift);
|
|
}
|
|
|
|
private static uint FFmulX(uint x)
|
|
{
|
|
return ((x & 0x7F7F7F7F) << 1) ^ (((x & 0x80808080u) >> 7) * 27);
|
|
}
|
|
|
|
private static uint FFmulX2(uint x)
|
|
{
|
|
uint num = (x & 0x3F3F3F3F) << 2;
|
|
uint num2 = x & 0xC0C0C0C0u;
|
|
num2 ^= num2 >> 1;
|
|
return num ^ (num2 >> 2) ^ (num2 >> 5);
|
|
}
|
|
|
|
private static uint Inv_Mcol(uint x)
|
|
{
|
|
uint num = x;
|
|
uint num2 = num ^ Shift(num, 8);
|
|
num ^= FFmulX(num2);
|
|
num2 ^= FFmulX2(num);
|
|
return num ^ (num2 ^ Shift(num2, 16));
|
|
}
|
|
|
|
private static uint SubWord(uint x)
|
|
{
|
|
return (uint)(S[x & 0xFF] | (S[(x >> 8) & 0xFF] << 8) | (S[(x >> 16) & 0xFF] << 16) | (S[(x >> 24) & 0xFF] << 24));
|
|
}
|
|
|
|
private uint[][] GenerateWorkingKey(byte[] key, bool forEncryption)
|
|
{
|
|
int num = key.Length;
|
|
if (num < 16 || num > 32 || (num & 7) != 0)
|
|
{
|
|
throw new ArgumentException("Key length not 128/192/256 bits.");
|
|
}
|
|
int num2 = num >> 2;
|
|
ROUNDS = num2 + 6;
|
|
uint[][] array = new uint[ROUNDS + 1][];
|
|
for (int i = 0; i <= ROUNDS; i++)
|
|
{
|
|
array[i] = new uint[4];
|
|
}
|
|
switch (num2)
|
|
{
|
|
case 4:
|
|
{
|
|
uint num21 = Pack.LE_To_UInt32(key, 0);
|
|
array[0][0] = num21;
|
|
uint num22 = Pack.LE_To_UInt32(key, 4);
|
|
array[0][1] = num22;
|
|
uint num23 = Pack.LE_To_UInt32(key, 8);
|
|
array[0][2] = num23;
|
|
uint num24 = Pack.LE_To_UInt32(key, 12);
|
|
array[0][3] = num24;
|
|
for (int l = 1; l <= 10; l++)
|
|
{
|
|
uint num25 = SubWord(Shift(num24, 8)) ^ rcon[l - 1];
|
|
num21 ^= num25;
|
|
array[l][0] = num21;
|
|
num22 ^= num21;
|
|
array[l][1] = num22;
|
|
num23 ^= num22;
|
|
array[l][2] = num23;
|
|
num24 ^= num23;
|
|
array[l][3] = num24;
|
|
}
|
|
break;
|
|
}
|
|
case 6:
|
|
{
|
|
uint num13 = Pack.LE_To_UInt32(key, 0);
|
|
array[0][0] = num13;
|
|
uint num14 = Pack.LE_To_UInt32(key, 4);
|
|
array[0][1] = num14;
|
|
uint num15 = Pack.LE_To_UInt32(key, 8);
|
|
array[0][2] = num15;
|
|
uint num16 = Pack.LE_To_UInt32(key, 12);
|
|
array[0][3] = num16;
|
|
uint num17 = Pack.LE_To_UInt32(key, 16);
|
|
array[1][0] = num17;
|
|
uint num18 = Pack.LE_To_UInt32(key, 20);
|
|
array[1][1] = num18;
|
|
uint num19 = 1u;
|
|
uint num20 = SubWord(Shift(num18, 8)) ^ num19;
|
|
num19 <<= 1;
|
|
num13 ^= num20;
|
|
array[1][2] = num13;
|
|
num14 ^= num13;
|
|
array[1][3] = num14;
|
|
num15 ^= num14;
|
|
array[2][0] = num15;
|
|
num16 ^= num15;
|
|
array[2][1] = num16;
|
|
num17 ^= num16;
|
|
array[2][2] = num17;
|
|
num18 ^= num17;
|
|
array[2][3] = num18;
|
|
for (int k = 3; k < 12; k += 3)
|
|
{
|
|
num20 = SubWord(Shift(num18, 8)) ^ num19;
|
|
num19 <<= 1;
|
|
num13 ^= num20;
|
|
array[k][0] = num13;
|
|
num14 ^= num13;
|
|
array[k][1] = num14;
|
|
num15 ^= num14;
|
|
array[k][2] = num15;
|
|
num16 ^= num15;
|
|
array[k][3] = num16;
|
|
num17 ^= num16;
|
|
array[k + 1][0] = num17;
|
|
num18 ^= num17;
|
|
array[k + 1][1] = num18;
|
|
num20 = SubWord(Shift(num18, 8)) ^ num19;
|
|
num19 <<= 1;
|
|
num13 ^= num20;
|
|
array[k + 1][2] = num13;
|
|
num14 ^= num13;
|
|
array[k + 1][3] = num14;
|
|
num15 ^= num14;
|
|
array[k + 2][0] = num15;
|
|
num16 ^= num15;
|
|
array[k + 2][1] = num16;
|
|
num17 ^= num16;
|
|
array[k + 2][2] = num17;
|
|
num18 ^= num17;
|
|
array[k + 2][3] = num18;
|
|
}
|
|
num20 = SubWord(Shift(num18, 8)) ^ num19;
|
|
num13 ^= num20;
|
|
array[12][0] = num13;
|
|
num14 ^= num13;
|
|
array[12][1] = num14;
|
|
num15 ^= num14;
|
|
array[12][2] = num15;
|
|
num16 ^= num15;
|
|
array[12][3] = num16;
|
|
break;
|
|
}
|
|
case 8:
|
|
{
|
|
uint num3 = Pack.LE_To_UInt32(key, 0);
|
|
array[0][0] = num3;
|
|
uint num4 = Pack.LE_To_UInt32(key, 4);
|
|
array[0][1] = num4;
|
|
uint num5 = Pack.LE_To_UInt32(key, 8);
|
|
array[0][2] = num5;
|
|
uint num6 = Pack.LE_To_UInt32(key, 12);
|
|
array[0][3] = num6;
|
|
uint num7 = Pack.LE_To_UInt32(key, 16);
|
|
array[1][0] = num7;
|
|
uint num8 = Pack.LE_To_UInt32(key, 20);
|
|
array[1][1] = num8;
|
|
uint num9 = Pack.LE_To_UInt32(key, 24);
|
|
array[1][2] = num9;
|
|
uint num10 = Pack.LE_To_UInt32(key, 28);
|
|
array[1][3] = num10;
|
|
uint num11 = 1u;
|
|
uint num12;
|
|
for (int j = 2; j < 14; j += 2)
|
|
{
|
|
num12 = SubWord(Shift(num10, 8)) ^ num11;
|
|
num11 <<= 1;
|
|
num3 ^= num12;
|
|
array[j][0] = num3;
|
|
num4 ^= num3;
|
|
array[j][1] = num4;
|
|
num5 ^= num4;
|
|
array[j][2] = num5;
|
|
num6 ^= num5;
|
|
array[j][3] = num6;
|
|
num12 = SubWord(num6);
|
|
num7 ^= num12;
|
|
array[j + 1][0] = num7;
|
|
num8 ^= num7;
|
|
array[j + 1][1] = num8;
|
|
num9 ^= num8;
|
|
array[j + 1][2] = num9;
|
|
num10 ^= num9;
|
|
array[j + 1][3] = num10;
|
|
}
|
|
num12 = SubWord(Shift(num10, 8)) ^ num11;
|
|
num3 ^= num12;
|
|
array[14][0] = num3;
|
|
num4 ^= num3;
|
|
array[14][1] = num4;
|
|
num5 ^= num4;
|
|
array[14][2] = num5;
|
|
num6 ^= num5;
|
|
array[14][3] = num6;
|
|
break;
|
|
}
|
|
default:
|
|
throw new InvalidOperationException("Should never get here");
|
|
}
|
|
if (!forEncryption)
|
|
{
|
|
for (int m = 1; m < ROUNDS; m++)
|
|
{
|
|
uint[] array2 = array[m];
|
|
for (int n = 0; n < 4; n++)
|
|
{
|
|
array2[n] = Inv_Mcol(array2[n]);
|
|
}
|
|
}
|
|
}
|
|
return array;
|
|
}
|
|
|
|
public virtual void Init(bool forEncryption, ICipherParameters parameters)
|
|
{
|
|
if (!(parameters is KeyParameter keyParameter))
|
|
{
|
|
throw new ArgumentException("invalid parameter passed to AES init - " + Platform.GetTypeName(parameters));
|
|
}
|
|
WorkingKey = GenerateWorkingKey(keyParameter.GetKey(), forEncryption);
|
|
this.forEncryption = forEncryption;
|
|
s = Arrays.Clone(forEncryption ? S : Si);
|
|
}
|
|
|
|
public virtual int GetBlockSize()
|
|
{
|
|
return 16;
|
|
}
|
|
|
|
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
|
|
{
|
|
if (WorkingKey == null)
|
|
{
|
|
throw new InvalidOperationException("AES engine not initialised");
|
|
}
|
|
Check.DataLength(input, inOff, 16, "input buffer too short");
|
|
Check.OutputLength(output, outOff, 16, "output buffer too short");
|
|
UnPackBlock(input, inOff);
|
|
if (forEncryption)
|
|
{
|
|
EncryptBlock(WorkingKey);
|
|
}
|
|
else
|
|
{
|
|
DecryptBlock(WorkingKey);
|
|
}
|
|
PackBlock(output, outOff);
|
|
return 16;
|
|
}
|
|
|
|
public virtual void Reset()
|
|
{
|
|
}
|
|
|
|
private void UnPackBlock(byte[] bytes, int off)
|
|
{
|
|
C0 = Pack.LE_To_UInt32(bytes, off);
|
|
C1 = Pack.LE_To_UInt32(bytes, off + 4);
|
|
C2 = Pack.LE_To_UInt32(bytes, off + 8);
|
|
C3 = Pack.LE_To_UInt32(bytes, off + 12);
|
|
}
|
|
|
|
private void PackBlock(byte[] bytes, int off)
|
|
{
|
|
Pack.UInt32_To_LE(C0, bytes, off);
|
|
Pack.UInt32_To_LE(C1, bytes, off + 4);
|
|
Pack.UInt32_To_LE(C2, bytes, off + 8);
|
|
Pack.UInt32_To_LE(C3, bytes, off + 12);
|
|
}
|
|
|
|
private void EncryptBlock(uint[][] KW)
|
|
{
|
|
uint[] array = KW[0];
|
|
uint num = C0 ^ array[0];
|
|
uint num2 = C1 ^ array[1];
|
|
uint num3 = C2 ^ array[2];
|
|
uint num4 = C3 ^ array[3];
|
|
int num5 = 1;
|
|
uint num6;
|
|
uint num7;
|
|
uint num8;
|
|
while (num5 < ROUNDS - 1)
|
|
{
|
|
array = KW[num5++];
|
|
num6 = T0[num & 0xFF] ^ Shift(T0[(num2 >> 8) & 0xFF], 24) ^ Shift(T0[(num3 >> 16) & 0xFF], 16) ^ Shift(T0[(num4 >> 24) & 0xFF], 8) ^ array[0];
|
|
num7 = T0[num2 & 0xFF] ^ Shift(T0[(num3 >> 8) & 0xFF], 24) ^ Shift(T0[(num4 >> 16) & 0xFF], 16) ^ Shift(T0[(num >> 24) & 0xFF], 8) ^ array[1];
|
|
num8 = T0[num3 & 0xFF] ^ Shift(T0[(num4 >> 8) & 0xFF], 24) ^ Shift(T0[(num >> 16) & 0xFF], 16) ^ Shift(T0[(num2 >> 24) & 0xFF], 8) ^ array[2];
|
|
num4 = T0[num4 & 0xFF] ^ Shift(T0[(num >> 8) & 0xFF], 24) ^ Shift(T0[(num2 >> 16) & 0xFF], 16) ^ Shift(T0[(num3 >> 24) & 0xFF], 8) ^ array[3];
|
|
array = KW[num5++];
|
|
num = T0[num6 & 0xFF] ^ Shift(T0[(num7 >> 8) & 0xFF], 24) ^ Shift(T0[(num8 >> 16) & 0xFF], 16) ^ Shift(T0[(num4 >> 24) & 0xFF], 8) ^ array[0];
|
|
num2 = T0[num7 & 0xFF] ^ Shift(T0[(num8 >> 8) & 0xFF], 24) ^ Shift(T0[(num4 >> 16) & 0xFF], 16) ^ Shift(T0[(num6 >> 24) & 0xFF], 8) ^ array[1];
|
|
num3 = T0[num8 & 0xFF] ^ Shift(T0[(num4 >> 8) & 0xFF], 24) ^ Shift(T0[(num6 >> 16) & 0xFF], 16) ^ Shift(T0[(num7 >> 24) & 0xFF], 8) ^ array[2];
|
|
num4 = T0[num4 & 0xFF] ^ Shift(T0[(num6 >> 8) & 0xFF], 24) ^ Shift(T0[(num7 >> 16) & 0xFF], 16) ^ Shift(T0[(num8 >> 24) & 0xFF], 8) ^ array[3];
|
|
}
|
|
array = KW[num5++];
|
|
num6 = T0[num & 0xFF] ^ Shift(T0[(num2 >> 8) & 0xFF], 24) ^ Shift(T0[(num3 >> 16) & 0xFF], 16) ^ Shift(T0[(num4 >> 24) & 0xFF], 8) ^ array[0];
|
|
num7 = T0[num2 & 0xFF] ^ Shift(T0[(num3 >> 8) & 0xFF], 24) ^ Shift(T0[(num4 >> 16) & 0xFF], 16) ^ Shift(T0[(num >> 24) & 0xFF], 8) ^ array[1];
|
|
num8 = T0[num3 & 0xFF] ^ Shift(T0[(num4 >> 8) & 0xFF], 24) ^ Shift(T0[(num >> 16) & 0xFF], 16) ^ Shift(T0[(num2 >> 24) & 0xFF], 8) ^ array[2];
|
|
num4 = T0[num4 & 0xFF] ^ Shift(T0[(num >> 8) & 0xFF], 24) ^ Shift(T0[(num2 >> 16) & 0xFF], 16) ^ Shift(T0[(num3 >> 24) & 0xFF], 8) ^ array[3];
|
|
array = KW[num5];
|
|
C0 = (uint)(S[num6 & 0xFF] ^ (S[(num7 >> 8) & 0xFF] << 8) ^ (s[(num8 >> 16) & 0xFF] << 16) ^ (s[(num4 >> 24) & 0xFF] << 24)) ^ array[0];
|
|
C1 = (uint)(s[num7 & 0xFF] ^ (S[(num8 >> 8) & 0xFF] << 8) ^ (S[(num4 >> 16) & 0xFF] << 16) ^ (s[(num6 >> 24) & 0xFF] << 24)) ^ array[1];
|
|
C2 = (uint)(s[num8 & 0xFF] ^ (S[(num4 >> 8) & 0xFF] << 8) ^ (S[(num6 >> 16) & 0xFF] << 16) ^ (S[(num7 >> 24) & 0xFF] << 24)) ^ array[2];
|
|
C3 = (uint)(s[num4 & 0xFF] ^ (s[(num6 >> 8) & 0xFF] << 8) ^ (s[(num7 >> 16) & 0xFF] << 16) ^ (S[(num8 >> 24) & 0xFF] << 24)) ^ array[3];
|
|
}
|
|
|
|
private void DecryptBlock(uint[][] KW)
|
|
{
|
|
uint[] array = KW[ROUNDS];
|
|
uint num = C0 ^ array[0];
|
|
uint num2 = C1 ^ array[1];
|
|
uint num3 = C2 ^ array[2];
|
|
uint num4 = C3 ^ array[3];
|
|
int num5 = ROUNDS - 1;
|
|
uint num6;
|
|
uint num7;
|
|
uint num8;
|
|
while (num5 > 1)
|
|
{
|
|
array = KW[num5--];
|
|
num6 = Tinv0[num & 0xFF] ^ Shift(Tinv0[(num4 >> 8) & 0xFF], 24) ^ Shift(Tinv0[(num3 >> 16) & 0xFF], 16) ^ Shift(Tinv0[(num2 >> 24) & 0xFF], 8) ^ array[0];
|
|
num7 = Tinv0[num2 & 0xFF] ^ Shift(Tinv0[(num >> 8) & 0xFF], 24) ^ Shift(Tinv0[(num4 >> 16) & 0xFF], 16) ^ Shift(Tinv0[(num3 >> 24) & 0xFF], 8) ^ array[1];
|
|
num8 = Tinv0[num3 & 0xFF] ^ Shift(Tinv0[(num2 >> 8) & 0xFF], 24) ^ Shift(Tinv0[(num >> 16) & 0xFF], 16) ^ Shift(Tinv0[(num4 >> 24) & 0xFF], 8) ^ array[2];
|
|
num4 = Tinv0[num4 & 0xFF] ^ Shift(Tinv0[(num3 >> 8) & 0xFF], 24) ^ Shift(Tinv0[(num2 >> 16) & 0xFF], 16) ^ Shift(Tinv0[(num >> 24) & 0xFF], 8) ^ array[3];
|
|
array = KW[num5--];
|
|
num = Tinv0[num6 & 0xFF] ^ Shift(Tinv0[(num4 >> 8) & 0xFF], 24) ^ Shift(Tinv0[(num8 >> 16) & 0xFF], 16) ^ Shift(Tinv0[(num7 >> 24) & 0xFF], 8) ^ array[0];
|
|
num2 = Tinv0[num7 & 0xFF] ^ Shift(Tinv0[(num6 >> 8) & 0xFF], 24) ^ Shift(Tinv0[(num4 >> 16) & 0xFF], 16) ^ Shift(Tinv0[(num8 >> 24) & 0xFF], 8) ^ array[1];
|
|
num3 = Tinv0[num8 & 0xFF] ^ Shift(Tinv0[(num7 >> 8) & 0xFF], 24) ^ Shift(Tinv0[(num6 >> 16) & 0xFF], 16) ^ Shift(Tinv0[(num4 >> 24) & 0xFF], 8) ^ array[2];
|
|
num4 = Tinv0[num4 & 0xFF] ^ Shift(Tinv0[(num8 >> 8) & 0xFF], 24) ^ Shift(Tinv0[(num7 >> 16) & 0xFF], 16) ^ Shift(Tinv0[(num6 >> 24) & 0xFF], 8) ^ array[3];
|
|
}
|
|
array = KW[1];
|
|
num6 = Tinv0[num & 0xFF] ^ Shift(Tinv0[(num4 >> 8) & 0xFF], 24) ^ Shift(Tinv0[(num3 >> 16) & 0xFF], 16) ^ Shift(Tinv0[(num2 >> 24) & 0xFF], 8) ^ array[0];
|
|
num7 = Tinv0[num2 & 0xFF] ^ Shift(Tinv0[(num >> 8) & 0xFF], 24) ^ Shift(Tinv0[(num4 >> 16) & 0xFF], 16) ^ Shift(Tinv0[(num3 >> 24) & 0xFF], 8) ^ array[1];
|
|
num8 = Tinv0[num3 & 0xFF] ^ Shift(Tinv0[(num2 >> 8) & 0xFF], 24) ^ Shift(Tinv0[(num >> 16) & 0xFF], 16) ^ Shift(Tinv0[(num4 >> 24) & 0xFF], 8) ^ array[2];
|
|
num4 = Tinv0[num4 & 0xFF] ^ Shift(Tinv0[(num3 >> 8) & 0xFF], 24) ^ Shift(Tinv0[(num2 >> 16) & 0xFF], 16) ^ Shift(Tinv0[(num >> 24) & 0xFF], 8) ^ array[3];
|
|
array = KW[0];
|
|
C0 = (uint)(Si[num6 & 0xFF] ^ (s[(num4 >> 8) & 0xFF] << 8) ^ (s[(num8 >> 16) & 0xFF] << 16) ^ (Si[(num7 >> 24) & 0xFF] << 24)) ^ array[0];
|
|
C1 = (uint)(s[num7 & 0xFF] ^ (s[(num6 >> 8) & 0xFF] << 8) ^ (Si[(num4 >> 16) & 0xFF] << 16) ^ (s[(num8 >> 24) & 0xFF] << 24)) ^ array[1];
|
|
C2 = (uint)(s[num8 & 0xFF] ^ (Si[(num7 >> 8) & 0xFF] << 8) ^ (Si[(num6 >> 16) & 0xFF] << 16) ^ (s[(num4 >> 24) & 0xFF] << 24)) ^ array[2];
|
|
C3 = (uint)(Si[num4 & 0xFF] ^ (s[(num8 >> 8) & 0xFF] << 8) ^ (s[(num7 >> 16) & 0xFF] << 16) ^ (s[(num6 >> 24) & 0xFF] << 24)) ^ array[3];
|
|
}
|
|
}
|