init commit

This commit is contained in:
2025-10-09 09:57:24 +09:00
commit 4d551bd74f
6636 changed files with 1218703 additions and 0 deletions

View File

@@ -0,0 +1,510 @@
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];
}
}

View File

@@ -0,0 +1,688 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Utilities;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
[Obsolete("Use AesEngine instead")]
public class AesFastEngine : 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[] T1 = new uint[256]
{
1667483301u, 2088564868u, 2004348569u, 2071721613u, 4076011277u, 1802229437u, 1869602481u, 3318059348u, 808476752u, 16843267u,
1734856361u, 724260477u, 4278118169u, 3621238114u, 2880130534u, 1987505306u, 3402272581u, 2189565853u, 3385428288u, 2105408135u,
4210749205u, 1499050731u, 1195871945u, 4042324747u, 2913812972u, 3570709351u, 2728550397u, 2947499498u, 2627478463u, 2762232823u,
1920132246u, 3233848155u, 3082253762u, 4261273884u, 2475900334u, 640044138u, 909536346u, 1061125697u, 4160222466u, 3435955023u,
875849820u, 2779075060u, 3857043764u, 4059166984u, 1903288979u, 3638078323u, 825320019u, 353708607u, 67373068u, 3351745874u,
589514341u, 3284376926u, 404238376u, 2526427041u, 84216335u, 2593796021u, 117902857u, 303178806u, 2155879323u, 3806519101u,
3958099238u, 656887401u, 2998042573u, 1970662047u, 151589403u, 2206408094u, 741103732u, 437924910u, 454768173u, 1852759218u,
1515893998u, 2694863867u, 1381147894u, 993752653u, 3604395873u, 3014884814u, 690573947u, 3823361342u, 791633521u, 2223248279u,
1397991157u, 3520182632u, 0u, 3991781676u, 538984544u, 4244431647u, 2981198280u, 1532737261u, 1785386174u, 3419114822u,
3200149465u, 960066123u, 1246401758u, 1280088276u, 1482207464u, 3486483786u, 3503340395u, 4025468202u, 2863288293u, 4227591446u,
1128498885u, 1296931543u, 859006549u, 2240090516u, 1162185423u, 4193904912u, 33686534u, 2139094657u, 1347461360u, 1010595908u,
2678007226u, 2829601763u, 1364304627u, 2745392638u, 1077969088u, 2408514954u, 2459058093u, 2644320700u, 943222856u, 4126535940u,
3166462943u, 3065411521u, 3671764853u, 555827811u, 269492272u, 4294960410u, 4092853518u, 3537026925u, 3452797260u, 202119188u,
320022069u, 3974939439u, 1600110305u, 2543269282u, 1145342156u, 387395129u, 3301217111u, 2812761586u, 2122251394u, 1027439175u,
1684326572u, 1566423783u, 421081643u, 1936975509u, 1616953504u, 2172721560u, 1330618065u, 3705447295u, 572671078u, 707417214u,
2425371563u, 2290617219u, 1179028682u, 4008625961u, 3099093971u, 336865340u, 3739133817u, 1583267042u, 185275933u, 3688607094u,
3772832571u, 842163286u, 976909390u, 168432670u, 1229558491u, 101059594u, 606357612u, 1549580516u, 3267534685u, 3553869166u,
2896970735u, 1650640038u, 2442213800u, 2509582756u, 3840201527u, 2038035083u, 3890730290u, 3368586051u, 926379609u, 1835915959u,
2374828428u, 3587551588u, 1313774802u, 2846444000u, 1819072692u, 1448520954u, 4109693703u, 3941256997u, 1701169839u, 2054878350u,
2930657257u, 134746136u, 3132780501u, 2021191816u, 623200879u, 774790258u, 471611428u, 2795919345u, 3031724999u, 3334903633u,
3907570467u, 3722289532u, 1953818780u, 522141217u, 1263245021u, 3183305180u, 2341145990u, 2324303749u, 1886445712u, 1044282434u,
3048567236u, 1718013098u, 1212715224u, 50529797u, 4143380225u, 235805714u, 1633796771u, 892693087u, 1465364217u, 3115936208u,
2256934801u, 3250690392u, 488454695u, 2661164985u, 3789674808u, 4177062675u, 2560109491u, 286335539u, 1768542907u, 3654920560u,
2391672713u, 2492740519u, 2610638262u, 505297954u, 2273777042u, 3924412704u, 3469641545u, 1431677695u, 673730680u, 3755976058u,
2357986191u, 2711706104u, 2307459456u, 218962455u, 3216991706u, 3873888049u, 1111655622u, 1751699640u, 1094812355u, 2576951728u,
757946999u, 252648977u, 2964356043u, 1414834428u, 3149622742u, 370551866u
};
private static readonly uint[] T2 = new uint[256]
{
1673962851u, 2096661628u, 2012125559u, 2079755643u, 4076801522u, 1809235307u, 1876865391u, 3314635973u, 811618352u, 16909057u,
1741597031u, 727088427u, 4276558334u, 3618988759u, 2874009259u, 1995217526u, 3398387146u, 2183110018u, 3381215433u, 2113570685u,
4209972730u, 1504897881u, 1200539975u, 4042984432u, 2906778797u, 3568527316u, 2724199842u, 2940594863u, 2619588508u, 2756966308u,
1927583346u, 3231407040u, 3077948087u, 4259388669u, 2470293139u, 642542118u, 913070646u, 1065238847u, 4160029431u, 3431157708u,
879254580u, 2773611685u, 3855693029u, 4059629809u, 1910674289u, 3635114968u, 828527409u, 355090197u, 67636228u, 3348452039u,
591815971u, 3281870531u, 405809176u, 2520228246u, 84545285u, 2586817946u, 118360327u, 304363026u, 2149292928u, 3806281186u,
3956090603u, 659450151u, 2994720178u, 1978310517u, 152181513u, 2199756419u, 743994412u, 439627290u, 456535323u, 1859957358u,
1521806938u, 2690382752u, 1386542674u, 997608763u, 3602342358u, 3011366579u, 693271337u, 3822927587u, 794718511u, 2215876484u,
1403450707u, 3518589137u, 0u, 3988860141u, 541089824u, 4242743292u, 2977548465u, 1538714971u, 1792327274u, 3415033547u,
3194476990u, 963791673u, 1251270218u, 1285084236u, 1487988824u, 3481619151u, 3501943760u, 4022676207u, 2857362858u, 4226619131u,
1132905795u, 1301993293u, 862344499u, 2232521861u, 1166724933u, 4192801017u, 33818114u, 2147385727u, 1352724560u, 1014514748u,
2670049951u, 2823545768u, 1369633617u, 2740846243u, 1082179648u, 2399505039u, 2453646738u, 2636233885u, 946882616u, 4126213365u,
3160661948u, 3061301686u, 3668932058u, 557998881u, 270544912u, 4293204735u, 4093447923u, 3535760850u, 3447803085u, 202904588u,
321271059u, 3972214764u, 1606345055u, 2536874647u, 1149815876u, 388905239u, 3297990596u, 2807427751u, 2130477694u, 1031423805u,
1690872932u, 1572530013u, 422718233u, 1944491379u, 1623236704u, 2165938305u, 1335808335u, 3701702620u, 574907938u, 710180394u,
2419829648u, 2282455944u, 1183631942u, 4006029806u, 3094074296u, 338181140u, 3735517662u, 1589437022u, 185998603u, 3685578459u,
3772464096u, 845436466u, 980700730u, 169090570u, 1234361161u, 101452294u, 608726052u, 1555620956u, 3265224130u, 3552407251u,
2890133420u, 1657054818u, 2436475025u, 2503058581u, 3839047652u, 2045938553u, 3889509095u, 3364570056u, 929978679u, 1843050349u,
2365688973u, 3585172693u, 1318900302u, 2840191145u, 1826141292u, 1454176854u, 4109567988u, 3939444202u, 1707781989u, 2062847610u,
2923948462u, 135272456u, 3127891386u, 2029029496u, 625635109u, 777810478u, 473441308u, 2790781350u, 3027486644u, 3331805638u,
3905627112u, 3718347997u, 1961401460u, 524165407u, 1268178251u, 3177307325u, 2332919435u, 2316273034u, 1893765232u, 1048330814u,
3044132021u, 1724688998u, 1217452104u, 50726147u, 4143383030u, 236720654u, 1640145761u, 896163637u, 1471084887u, 3110719673u,
2249691526u, 3248052417u, 490350365u, 2653403550u, 3789109473u, 4176155640u, 2553000856u, 287453969u, 1775418217u, 3651760345u,
2382858638u, 2486413204u, 2603464347u, 507257374u, 2266337927u, 3922272489u, 3464972750u, 1437269845u, 676362280u, 3752164063u,
2349043596u, 2707028129u, 2299101321u, 219813645u, 3211123391u, 3872862694u, 1115997762u, 1758509160u, 1099088705u, 2569646233u,
760903469u, 253628687u, 2960903088u, 1420360788u, 3144537787u, 371997206u
};
private static readonly uint[] T3 = new uint[256]
{
3332727651u, 4169432188u, 4003034999u, 4136467323u, 4279104242u, 3602738027u, 3736170351u, 2438251973u, 1615867952u, 33751297u,
3467208551u, 1451043627u, 3877240574u, 3043153879u, 1306962859u, 3969545846u, 2403715786u, 530416258u, 2302724553u, 4203183485u,
4011195130u, 3001768281u, 2395555655u, 4211863792u, 1106029997u, 3009926356u, 1610457762u, 1173008303u, 599760028u, 1408738468u,
3835064946u, 2606481600u, 1975695287u, 3776773629u, 1034851219u, 1282024998u, 1817851446u, 2118205247u, 4110612471u, 2203045068u,
1750873140u, 1374987685u, 3509904869u, 4178113009u, 3801313649u, 2876496088u, 1649619249u, 708777237u, 135005188u, 2505230279u,
1181033251u, 2640233411u, 807933976u, 933336726u, 168756485u, 800430746u, 235472647u, 607523346u, 463175808u, 3745374946u,
3441880043u, 1315514151u, 2144187058u, 3936318837u, 303761673u, 496927619u, 1484008492u, 875436570u, 908925723u, 3702681198u,
3035519578u, 1543217312u, 2767606354u, 1984772923u, 3076642518u, 2110698419u, 1383803177u, 3711886307u, 1584475951u, 328696964u,
2801095507u, 3110654417u, 0u, 3240947181u, 1080041504u, 3810524412u, 2043195825u, 3069008731u, 3569248874u, 2370227147u,
1742323390u, 1917532473u, 2497595978u, 2564049996u, 2968016984u, 2236272591u, 3144405200u, 3307925487u, 1340451498u, 3977706491u,
2261074755u, 2597801293u, 1716859699u, 294946181u, 2328839493u, 3910203897u, 67502594u, 4269899647u, 2700103760u, 2017737788u,
632987551u, 1273211048u, 2733855057u, 1576969123u, 2160083008u, 92966799u, 1068339858u, 566009245u, 1883781176u, 4043634165u,
1675607228u, 2009183926u, 2943736538u, 1113792801u, 540020752u, 3843751935u, 4245615603u, 3211645650u, 2169294285u, 403966988u,
641012499u, 3274697964u, 3202441055u, 899848087u, 2295088196u, 775493399u, 2472002756u, 1441965991u, 4236410494u, 2051489085u,
3366741092u, 3135724893u, 841685273u, 3868554099u, 3231735904u, 429425025u, 2664517455u, 2743065820u, 1147544098u, 1417554474u,
1001099408u, 193169544u, 2362066502u, 3341414126u, 1809037496u, 675025940u, 2809781982u, 3168951902u, 371002123u, 2910247899u,
3678134496u, 1683370546u, 1951283770u, 337512970u, 2463844681u, 201983494u, 1215046692u, 3101973596u, 2673722050u, 3178157011u,
1139780780u, 3299238498u, 967348625u, 832869781u, 3543655652u, 4069226873u, 3576883175u, 2336475336u, 1851340599u, 3669454189u,
25988493u, 2976175573u, 2631028302u, 1239460265u, 3635702892u, 2902087254u, 4077384948u, 3475368682u, 3400492389u, 4102978170u,
1206496942u, 270010376u, 1876277946u, 4035475576u, 1248797989u, 1550986798u, 941890588u, 1475454630u, 1942467764u, 2538718918u,
3408128232u, 2709315037u, 3902567540u, 1042358047u, 2531085131u, 1641856445u, 226921355u, 260409994u, 3767562352u, 2084716094u,
1908716981u, 3433719398u, 2430093384u, 100991747u, 4144101110u, 470945294u, 3265487201u, 1784624437u, 2935576407u, 1775286713u,
395413126u, 2572730817u, 975641885u, 666476190u, 3644383713u, 3943954680u, 733190296u, 573772049u, 3535497577u, 2842745305u,
126455438u, 866620564u, 766942107u, 1008868894u, 361924487u, 3374377449u, 2269761230u, 2868860245u, 1350051880u, 2776293343u,
59739276u, 1509466529u, 159418761u, 437718285u, 1708834751u, 3610371814u, 2227585602u, 3501746280u, 2193834305u, 699439513u,
1517759789u, 504434447u, 2076946608u, 2835108948u, 1842789307u, 742004246u
};
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 static readonly uint[] Tinv1 = new uint[256]
{
2817806672u, 1698790995u, 2752977603u, 1579629206u, 1806384075u, 1167925233u, 1492823211u, 65227667u, 4197458005u, 1836494326u,
1993115793u, 1275262245u, 3622129660u, 3408578007u, 1144333952u, 2741155215u, 1521606217u, 465184103u, 250234264u, 3237895649u,
1966064386u, 4031545618u, 2537983395u, 4191382470u, 1603208167u, 2626819477u, 2054012907u, 1498584538u, 2210321453u, 561273043u,
1776306473u, 3368652356u, 2311222634u, 2039411832u, 1045993835u, 1907959773u, 1340194486u, 2911432727u, 2887829862u, 986611124u,
1256153880u, 823846274u, 860985184u, 2136171077u, 2003087840u, 2926295940u, 2692873756u, 722008468u, 1749577816u, 4249194265u,
1826526343u, 4168831671u, 3547573027u, 38499042u, 2401231703u, 2874500650u, 686535175u, 3266653955u, 2076542618u, 137876389u,
2267558130u, 2780767154u, 1778582202u, 2182540636u, 483363371u, 3027871634u, 4060607472u, 3798552225u, 4107953613u, 3188000469u,
1647628575u, 4272342154u, 1395537053u, 1442030240u, 3783918898u, 3958809717u, 3968011065u, 4016062634u, 2675006982u, 275692881u,
2317434617u, 115185213u, 88006062u, 3185986886u, 2371129781u, 1573155077u, 3557164143u, 357589247u, 4221049124u, 3921532567u,
1128303052u, 2665047927u, 1122545853u, 2341013384u, 1528424248u, 4006115803u, 175939911u, 256015593u, 512030921u, 0u,
2256537987u, 3979031112u, 1880170156u, 1918528590u, 4279172603u, 948244310u, 3584965918u, 959264295u, 3641641572u, 2791073825u,
1415289809u, 775300154u, 1728711857u, 3881276175u, 2532226258u, 2442861470u, 3317727311u, 551313826u, 1266113129u, 437394454u,
3130253834u, 715178213u, 3760340035u, 387650077u, 218697227u, 3347837613u, 2830511545u, 2837320904u, 435246981u, 125153100u,
3717852859u, 1618977789u, 637663135u, 4117912764u, 996558021u, 2130402100u, 692292470u, 3324234716u, 4243437160u, 4058298467u,
3694254026u, 2237874704u, 580326208u, 298222624u, 608863613u, 1035719416u, 855223825u, 2703869805u, 798891339u, 817028339u,
1384517100u, 3821107152u, 380840812u, 3111168409u, 1217663482u, 1693009698u, 2365368516u, 1072734234u, 746411736u, 2419270383u,
1313441735u, 3510163905u, 2731183358u, 198481974u, 2180359887u, 3732579624u, 2394413606u, 3215802276u, 2637835492u, 2457358349u,
3428805275u, 1182684258u, 328070850u, 3101200616u, 4147719774u, 2948825845u, 2153619390u, 2479909244u, 768962473u, 304467891u,
2578237499u, 2098729127u, 1671227502u, 3141262203u, 2015808777u, 408514292u, 3080383489u, 2588902312u, 1855317605u, 3875515006u,
3485212936u, 3893751782u, 2615655129u, 913263310u, 161475284u, 2091919830u, 2997105071u, 591342129u, 2493892144u, 1721906624u,
3159258167u, 3397581990u, 3499155632u, 3634836245u, 2550460746u, 3672916471u, 1355644686u, 4136703791u, 3595400845u, 2968470349u,
1303039060u, 76997855u, 3050413795u, 2288667675u, 523026872u, 1365591679u, 3932069124u, 898367837u, 1955068531u, 1091304238u,
493335386u, 3537605202u, 1443948851u, 1205234963u, 1641519756u, 211892090u, 351820174u, 1007938441u, 665439982u, 3378624309u,
3843875309u, 2974251580u, 3755121753u, 1945261375u, 3457423481u, 935818175u, 3455538154u, 2868731739u, 1866325780u, 3678697606u,
4088384129u, 3295197502u, 874788908u, 1084473951u, 3273463410u, 635616268u, 1228679307u, 2500722497u, 27801969u, 3003910366u,
3837057180u, 3243664528u, 2227927905u, 3056784752u, 1550600308u, 1471729730u
};
private static readonly uint[] Tinv2 = new uint[256]
{
4098969767u, 1098797925u, 387629988u, 658151006u, 2872822635u, 2636116293u, 4205620056u, 3813380867u, 807425530u, 1991112301u,
3431502198u, 49620300u, 3847224535u, 717608907u, 891715652u, 1656065955u, 2984135002u, 3123013403u, 3930429454u, 4267565504u,
801309301u, 1283527408u, 1183687575u, 3547055865u, 2399397727u, 2450888092u, 1841294202u, 1385552473u, 3201576323u, 1951978273u,
3762891113u, 3381544136u, 3262474889u, 2398386297u, 1486449470u, 3106397553u, 3787372111u, 2297436077u, 550069932u, 3464344634u,
3747813450u, 451248689u, 1368875059u, 1398949247u, 1689378935u, 1807451310u, 2180914336u, 150574123u, 1215322216u, 1167006205u,
3734275948u, 2069018616u, 1940595667u, 1265820162u, 534992783u, 1432758955u, 3954313000u, 3039757250u, 3313932923u, 936617224u,
674296455u, 3206787749u, 50510442u, 384654466u, 3481938716u, 2041025204u, 133427442u, 1766760930u, 3664104948u, 84334014u,
886120290u, 2797898494u, 775200083u, 4087521365u, 2315596513u, 4137973227u, 2198551020u, 1614850799u, 1901987487u, 1857900816u,
557775242u, 3717610758u, 1054715397u, 3863824061u, 1418835341u, 3295741277u, 100954068u, 1348534037u, 2551784699u, 3184957417u,
1082772547u, 3647436702u, 3903896898u, 2298972299u, 434583643u, 3363429358u, 2090944266u, 1115482383u, 2230896926u, 0u,
2148107142u, 724715757u, 287222896u, 1517047410u, 251526143u, 2232374840u, 2923241173u, 758523705u, 252339417u, 1550328230u,
1536938324u, 908343854u, 168604007u, 1469255655u, 4004827798u, 2602278545u, 3229634501u, 3697386016u, 2002413899u, 303830554u,
2481064634u, 2696996138u, 574374880u, 454171927u, 151915277u, 2347937223u, 3056449960u, 504678569u, 4049044761u, 1974422535u,
2582559709u, 2141453664u, 33005350u, 1918680309u, 1715782971u, 4217058430u, 1133213225u, 600562886u, 3988154620u, 3837289457u,
836225756u, 1665273989u, 2534621218u, 3330547729u, 1250262308u, 3151165501u, 4188934450u, 700935585u, 2652719919u, 3000824624u,
2249059410u, 3245854947u, 3005967382u, 1890163129u, 2484206152u, 3913753188u, 4238918796u, 4037024319u, 2102843436u, 857927568u,
1233635150u, 953795025u, 3398237858u, 3566745099u, 4121350017u, 2057644254u, 3084527246u, 2906629311u, 976020637u, 2018512274u,
1600822220u, 2119459398u, 2381758995u, 3633375416u, 959340279u, 3280139695u, 1570750080u, 3496574099u, 3580864813u, 634368786u,
2898803609u, 403744637u, 2632478307u, 1004239803u, 650971512u, 1500443672u, 2599158199u, 1334028442u, 2514904430u, 4289363686u,
3156281551u, 368043752u, 3887782299u, 1867173430u, 2682967049u, 2955531900u, 2754719666u, 1059729699u, 2781229204u, 2721431654u,
1316239292u, 2197595850u, 2430644432u, 2805143000u, 82922136u, 3963746266u, 3447656016u, 2434215926u, 1299615190u, 4014165424u,
2865517645u, 2531581700u, 3516851125u, 1783372680u, 750893087u, 1699118929u, 1587348714u, 2348899637u, 2281337716u, 201010753u,
1739807261u, 3683799762u, 283718486u, 3597472583u, 3617229921u, 2704767500u, 4166618644u, 334203196u, 2848910887u, 1639396809u,
484568549u, 1199193265u, 3533461983u, 4065673075u, 337148366u, 3346251575u, 4149471949u, 4250885034u, 1038029935u, 1148749531u,
2949284339u, 1756970692u, 607661108u, 2747424576u, 488010435u, 3803974693u, 1009290057u, 234832277u, 2822336769u, 201907891u,
3034094820u, 1449431233u, 3413860740u, 852848822u, 1816687708u, 3100656215u
};
private static readonly uint[] Tinv3 = new uint[256]
{
1364240372u, 2119394625u, 449029143u, 982933031u, 1003187115u, 535905693u, 2896910586u, 1267925987u, 542505520u, 2918608246u,
2291234508u, 4112862210u, 1341970405u, 3319253802u, 645940277u, 3046089570u, 3729349297u, 627514298u, 1167593194u, 1575076094u,
3271718191u, 2165502028u, 2376308550u, 1808202195u, 65494927u, 362126482u, 3219880557u, 2514114898u, 3559752638u, 1490231668u,
1227450848u, 2386872521u, 1969916354u, 4101536142u, 2573942360u, 668823993u, 3199619041u, 4028083592u, 3378949152u, 2108963534u,
1662536415u, 3850514714u, 2539664209u, 1648721747u, 2984277860u, 3146034795u, 4263288961u, 4187237128u, 1884842056u, 2400845125u,
2491903198u, 1387788411u, 2871251827u, 1927414347u, 3814166303u, 1714072405u, 2986813675u, 788775605u, 2258271173u, 3550808119u,
821200680u, 598910399u, 45771267u, 3982262806u, 2318081231u, 2811409529u, 4092654087u, 1319232105u, 1707996378u, 114671109u,
3508494900u, 3297443494u, 882725678u, 2728416755u, 87220618u, 2759191542u, 188345475u, 1084944224u, 1577492337u, 3176206446u,
1056541217u, 2520581853u, 3719169342u, 1296481766u, 2444594516u, 1896177092u, 74437638u, 1627329872u, 421854104u, 3600279997u,
2311865152u, 1735892697u, 2965193448u, 126389129u, 3879230233u, 2044456648u, 2705787516u, 2095648578u, 4173930116u, 0u,
159614592u, 843640107u, 514617361u, 1817080410u, 4261150478u, 257308805u, 1025430958u, 908540205u, 174381327u, 1747035740u,
2614187099u, 607792694u, 212952842u, 2467293015u, 3033700078u, 463376795u, 2152711616u, 1638015196u, 1516850039u, 471210514u,
3792353939u, 3236244128u, 1011081250u, 303896347u, 235605257u, 4071475083u, 767142070u, 348694814u, 1468340721u, 2940995445u,
4005289369u, 2751291519u, 4154402305u, 1555887474u, 1153776486u, 1530167035u, 2339776835u, 3420243491u, 3060333805u, 3093557732u,
3620396081u, 1108378979u, 322970263u, 2216694214u, 2239571018u, 3539484091u, 2920362745u, 3345850665u, 491466654u, 3706925234u,
233591430u, 2010178497u, 728503987u, 2845423984u, 301615252u, 1193436393u, 2831453436u, 2686074864u, 1457007741u, 586125363u,
2277985865u, 3653357880u, 2365498058u, 2553678804u, 2798617077u, 2770919034u, 3659959991u, 1067761581u, 753179962u, 1343066744u,
1788595295u, 1415726718u, 4139914125u, 2431170776u, 777975609u, 2197139395u, 2680062045u, 1769771984u, 1873358293u, 3484619301u,
3359349164u, 279411992u, 3899548572u, 3682319163u, 3439949862u, 1861490777u, 3959535514u, 2208864847u, 3865407125u, 2860443391u,
554225596u, 4024887317u, 3134823399u, 1255028335u, 3939764639u, 701922480u, 833598116u, 707863359u, 3325072549u, 901801634u,
1949809742u, 4238789250u, 3769684112u, 857069735u, 4048197636u, 1106762476u, 2131644621u, 389019281u, 1989006925u, 1129165039u,
3428076970u, 3839820950u, 2665723345u, 1276872810u, 3250069292u, 1182749029u, 2634345054u, 22885772u, 4201870471u, 4214112523u,
3009027431u, 2454901467u, 3912455696u, 1829980118u, 2592891351u, 930745505u, 1502483704u, 3951639571u, 3471714217u, 3073755489u,
3790464284u, 2050797895u, 2623135698u, 1430221810u, 410635796u, 1941911495u, 1407897079u, 1599843069u, 3742658365u, 2022103876u,
3397514159u, 3107898472u, 942421028u, 3261022371u, 376619805u, 3154912738u, 680216892u, 4282488077u, 963707304u, 148812556u,
3634160820u, 1687208278u, 2069988555u, 3580933682u, 1215585388u, 3494008760u
};
private int ROUNDS;
private uint[][] WorkingKey;
private uint C0;
private uint C1;
private uint C2;
private uint C3;
private bool forEncryption;
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;
}
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] ^ T1[(num2 >> 8) & 0xFF] ^ T2[(num3 >> 16) & 0xFF] ^ T3[num4 >> 24] ^ array[0];
num7 = T0[num2 & 0xFF] ^ T1[(num3 >> 8) & 0xFF] ^ T2[(num4 >> 16) & 0xFF] ^ T3[num >> 24] ^ array[1];
num8 = T0[num3 & 0xFF] ^ T1[(num4 >> 8) & 0xFF] ^ T2[(num >> 16) & 0xFF] ^ T3[num2 >> 24] ^ array[2];
num4 = T0[num4 & 0xFF] ^ T1[(num >> 8) & 0xFF] ^ T2[(num2 >> 16) & 0xFF] ^ T3[num3 >> 24] ^ array[3];
array = KW[num5++];
num = T0[num6 & 0xFF] ^ T1[(num7 >> 8) & 0xFF] ^ T2[(num8 >> 16) & 0xFF] ^ T3[num4 >> 24] ^ array[0];
num2 = T0[num7 & 0xFF] ^ T1[(num8 >> 8) & 0xFF] ^ T2[(num4 >> 16) & 0xFF] ^ T3[num6 >> 24] ^ array[1];
num3 = T0[num8 & 0xFF] ^ T1[(num4 >> 8) & 0xFF] ^ T2[(num6 >> 16) & 0xFF] ^ T3[num7 >> 24] ^ array[2];
num4 = T0[num4 & 0xFF] ^ T1[(num6 >> 8) & 0xFF] ^ T2[(num7 >> 16) & 0xFF] ^ T3[num8 >> 24] ^ array[3];
}
array = KW[num5++];
num6 = T0[num & 0xFF] ^ T1[(num2 >> 8) & 0xFF] ^ T2[(num3 >> 16) & 0xFF] ^ T3[num4 >> 24] ^ array[0];
num7 = T0[num2 & 0xFF] ^ T1[(num3 >> 8) & 0xFF] ^ T2[(num4 >> 16) & 0xFF] ^ T3[num >> 24] ^ array[1];
num8 = T0[num3 & 0xFF] ^ T1[(num4 >> 8) & 0xFF] ^ T2[(num >> 16) & 0xFF] ^ T3[num2 >> 24] ^ array[2];
num4 = T0[num4 & 0xFF] ^ T1[(num >> 8) & 0xFF] ^ T2[(num2 >> 16) & 0xFF] ^ T3[num3 >> 24] ^ array[3];
array = KW[num5];
C0 = (uint)(S[num6 & 0xFF] ^ (S[(num7 >> 8) & 0xFF] << 8) ^ (S[(num8 >> 16) & 0xFF] << 16) ^ (S[num4 >> 24] << 24)) ^ array[0];
C1 = (uint)(S[num7 & 0xFF] ^ (S[(num8 >> 8) & 0xFF] << 8) ^ (S[(num4 >> 16) & 0xFF] << 16) ^ (S[num6 >> 24] << 24)) ^ array[1];
C2 = (uint)(S[num8 & 0xFF] ^ (S[(num4 >> 8) & 0xFF] << 8) ^ (S[(num6 >> 16) & 0xFF] << 16) ^ (S[num7 >> 24] << 24)) ^ array[2];
C3 = (uint)(S[num4 & 0xFF] ^ (S[(num6 >> 8) & 0xFF] << 8) ^ (S[(num7 >> 16) & 0xFF] << 16) ^ (S[num8 >> 24] << 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] ^ Tinv1[(num4 >> 8) & 0xFF] ^ Tinv2[(num3 >> 16) & 0xFF] ^ Tinv3[num2 >> 24] ^ array[0];
num7 = Tinv0[num2 & 0xFF] ^ Tinv1[(num >> 8) & 0xFF] ^ Tinv2[(num4 >> 16) & 0xFF] ^ Tinv3[num3 >> 24] ^ array[1];
num8 = Tinv0[num3 & 0xFF] ^ Tinv1[(num2 >> 8) & 0xFF] ^ Tinv2[(num >> 16) & 0xFF] ^ Tinv3[num4 >> 24] ^ array[2];
num4 = Tinv0[num4 & 0xFF] ^ Tinv1[(num3 >> 8) & 0xFF] ^ Tinv2[(num2 >> 16) & 0xFF] ^ Tinv3[num >> 24] ^ array[3];
array = KW[num5--];
num = Tinv0[num6 & 0xFF] ^ Tinv1[(num4 >> 8) & 0xFF] ^ Tinv2[(num8 >> 16) & 0xFF] ^ Tinv3[num7 >> 24] ^ array[0];
num2 = Tinv0[num7 & 0xFF] ^ Tinv1[(num6 >> 8) & 0xFF] ^ Tinv2[(num4 >> 16) & 0xFF] ^ Tinv3[num8 >> 24] ^ array[1];
num3 = Tinv0[num8 & 0xFF] ^ Tinv1[(num7 >> 8) & 0xFF] ^ Tinv2[(num6 >> 16) & 0xFF] ^ Tinv3[num4 >> 24] ^ array[2];
num4 = Tinv0[num4 & 0xFF] ^ Tinv1[(num8 >> 8) & 0xFF] ^ Tinv2[(num7 >> 16) & 0xFF] ^ Tinv3[num6 >> 24] ^ array[3];
}
array = KW[1];
num6 = Tinv0[num & 0xFF] ^ Tinv1[(num4 >> 8) & 0xFF] ^ Tinv2[(num3 >> 16) & 0xFF] ^ Tinv3[num2 >> 24] ^ array[0];
num7 = Tinv0[num2 & 0xFF] ^ Tinv1[(num >> 8) & 0xFF] ^ Tinv2[(num4 >> 16) & 0xFF] ^ Tinv3[num3 >> 24] ^ array[1];
num8 = Tinv0[num3 & 0xFF] ^ Tinv1[(num2 >> 8) & 0xFF] ^ Tinv2[(num >> 16) & 0xFF] ^ Tinv3[num4 >> 24] ^ array[2];
num4 = Tinv0[num4 & 0xFF] ^ Tinv1[(num3 >> 8) & 0xFF] ^ Tinv2[(num2 >> 16) & 0xFF] ^ Tinv3[num >> 24] ^ array[3];
array = KW[0];
C0 = (uint)(Si[num6 & 0xFF] ^ (Si[(num4 >> 8) & 0xFF] << 8) ^ (Si[(num8 >> 16) & 0xFF] << 16) ^ (Si[num7 >> 24] << 24)) ^ array[0];
C1 = (uint)(Si[num7 & 0xFF] ^ (Si[(num6 >> 8) & 0xFF] << 8) ^ (Si[(num4 >> 16) & 0xFF] << 16) ^ (Si[num8 >> 24] << 24)) ^ array[1];
C2 = (uint)(Si[num8 & 0xFF] ^ (Si[(num7 >> 8) & 0xFF] << 8) ^ (Si[(num6 >> 16) & 0xFF] << 16) ^ (Si[num4 >> 24] << 24)) ^ array[2];
C3 = (uint)(Si[num4 & 0xFF] ^ (Si[(num8 >> 8) & 0xFF] << 8) ^ (Si[(num7 >> 16) & 0xFF] << 16) ^ (Si[num6 >> 24] << 24)) ^ array[3];
}
}

View File

@@ -0,0 +1,454 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Utilities;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class AesLightEngine : 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 int ROUNDS;
private uint[][] WorkingKey;
private uint C0;
private uint C1;
private uint C2;
private uint C3;
private bool forEncryption;
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 Mcol(uint x)
{
uint num = Shift(x, 8);
uint num2 = x ^ num;
return Shift(num2, 16) ^ num ^ FFmulX(num2);
}
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;
}
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 = Mcol((uint)(S[num & 0xFF] ^ (S[(num2 >> 8) & 0xFF] << 8) ^ (S[(num3 >> 16) & 0xFF] << 16) ^ (S[(num4 >> 24) & 0xFF] << 24))) ^ array[0];
num7 = Mcol((uint)(S[num2 & 0xFF] ^ (S[(num3 >> 8) & 0xFF] << 8) ^ (S[(num4 >> 16) & 0xFF] << 16) ^ (S[(num >> 24) & 0xFF] << 24))) ^ array[1];
num8 = Mcol((uint)(S[num3 & 0xFF] ^ (S[(num4 >> 8) & 0xFF] << 8) ^ (S[(num >> 16) & 0xFF] << 16) ^ (S[(num2 >> 24) & 0xFF] << 24))) ^ array[2];
num4 = Mcol((uint)(S[num4 & 0xFF] ^ (S[(num >> 8) & 0xFF] << 8) ^ (S[(num2 >> 16) & 0xFF] << 16) ^ (S[(num3 >> 24) & 0xFF] << 24))) ^ array[3];
array = KW[num5++];
num = Mcol((uint)(S[num6 & 0xFF] ^ (S[(num7 >> 8) & 0xFF] << 8) ^ (S[(num8 >> 16) & 0xFF] << 16) ^ (S[(num4 >> 24) & 0xFF] << 24))) ^ array[0];
num2 = Mcol((uint)(S[num7 & 0xFF] ^ (S[(num8 >> 8) & 0xFF] << 8) ^ (S[(num4 >> 16) & 0xFF] << 16) ^ (S[(num6 >> 24) & 0xFF] << 24))) ^ array[1];
num3 = Mcol((uint)(S[num8 & 0xFF] ^ (S[(num4 >> 8) & 0xFF] << 8) ^ (S[(num6 >> 16) & 0xFF] << 16) ^ (S[(num7 >> 24) & 0xFF] << 24))) ^ array[2];
num4 = Mcol((uint)(S[num4 & 0xFF] ^ (S[(num6 >> 8) & 0xFF] << 8) ^ (S[(num7 >> 16) & 0xFF] << 16) ^ (S[(num8 >> 24) & 0xFF] << 24))) ^ array[3];
}
array = KW[num5++];
num6 = Mcol((uint)(S[num & 0xFF] ^ (S[(num2 >> 8) & 0xFF] << 8) ^ (S[(num3 >> 16) & 0xFF] << 16) ^ (S[(num4 >> 24) & 0xFF] << 24))) ^ array[0];
num7 = Mcol((uint)(S[num2 & 0xFF] ^ (S[(num3 >> 8) & 0xFF] << 8) ^ (S[(num4 >> 16) & 0xFF] << 16) ^ (S[(num >> 24) & 0xFF] << 24))) ^ array[1];
num8 = Mcol((uint)(S[num3 & 0xFF] ^ (S[(num4 >> 8) & 0xFF] << 8) ^ (S[(num >> 16) & 0xFF] << 16) ^ (S[(num2 >> 24) & 0xFF] << 24))) ^ array[2];
num4 = Mcol((uint)(S[num4 & 0xFF] ^ (S[(num >> 8) & 0xFF] << 8) ^ (S[(num2 >> 16) & 0xFF] << 16) ^ (S[(num3 >> 24) & 0xFF] << 24))) ^ 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 = Inv_Mcol((uint)(Si[num & 0xFF] ^ (Si[(num4 >> 8) & 0xFF] << 8) ^ (Si[(num3 >> 16) & 0xFF] << 16) ^ (Si[(num2 >> 24) & 0xFF] << 24))) ^ array[0];
num7 = Inv_Mcol((uint)(Si[num2 & 0xFF] ^ (Si[(num >> 8) & 0xFF] << 8) ^ (Si[(num4 >> 16) & 0xFF] << 16) ^ (Si[(num3 >> 24) & 0xFF] << 24))) ^ array[1];
num8 = Inv_Mcol((uint)(Si[num3 & 0xFF] ^ (Si[(num2 >> 8) & 0xFF] << 8) ^ (Si[(num >> 16) & 0xFF] << 16) ^ (Si[(num4 >> 24) & 0xFF] << 24))) ^ array[2];
num4 = Inv_Mcol((uint)(Si[num4 & 0xFF] ^ (Si[(num3 >> 8) & 0xFF] << 8) ^ (Si[(num2 >> 16) & 0xFF] << 16) ^ (Si[(num >> 24) & 0xFF] << 24))) ^ array[3];
array = KW[num5--];
num = Inv_Mcol((uint)(Si[num6 & 0xFF] ^ (Si[(num4 >> 8) & 0xFF] << 8) ^ (Si[(num8 >> 16) & 0xFF] << 16) ^ (Si[(num7 >> 24) & 0xFF] << 24))) ^ array[0];
num2 = Inv_Mcol((uint)(Si[num7 & 0xFF] ^ (Si[(num6 >> 8) & 0xFF] << 8) ^ (Si[(num4 >> 16) & 0xFF] << 16) ^ (Si[(num8 >> 24) & 0xFF] << 24))) ^ array[1];
num3 = Inv_Mcol((uint)(Si[num8 & 0xFF] ^ (Si[(num7 >> 8) & 0xFF] << 8) ^ (Si[(num6 >> 16) & 0xFF] << 16) ^ (Si[(num4 >> 24) & 0xFF] << 24))) ^ array[2];
num4 = Inv_Mcol((uint)(Si[num4 & 0xFF] ^ (Si[(num8 >> 8) & 0xFF] << 8) ^ (Si[(num7 >> 16) & 0xFF] << 16) ^ (Si[(num6 >> 24) & 0xFF] << 24))) ^ array[3];
}
array = KW[1];
num6 = Inv_Mcol((uint)(Si[num & 0xFF] ^ (Si[(num4 >> 8) & 0xFF] << 8) ^ (Si[(num3 >> 16) & 0xFF] << 16) ^ (Si[(num2 >> 24) & 0xFF] << 24))) ^ array[0];
num7 = Inv_Mcol((uint)(Si[num2 & 0xFF] ^ (Si[(num >> 8) & 0xFF] << 8) ^ (Si[(num4 >> 16) & 0xFF] << 16) ^ (Si[(num3 >> 24) & 0xFF] << 24))) ^ array[1];
num8 = Inv_Mcol((uint)(Si[num3 & 0xFF] ^ (Si[(num2 >> 8) & 0xFF] << 8) ^ (Si[(num >> 16) & 0xFF] << 16) ^ (Si[(num4 >> 24) & 0xFF] << 24))) ^ array[2];
num4 = Inv_Mcol((uint)(Si[num4 & 0xFF] ^ (Si[(num3 >> 8) & 0xFF] << 8) ^ (Si[(num2 >> 16) & 0xFF] << 16) ^ (Si[(num >> 24) & 0xFF] << 24))) ^ array[3];
array = KW[0];
C0 = (uint)(Si[num6 & 0xFF] ^ (Si[(num4 >> 8) & 0xFF] << 8) ^ (Si[(num8 >> 16) & 0xFF] << 16) ^ (Si[(num7 >> 24) & 0xFF] << 24)) ^ array[0];
C1 = (uint)(Si[num7 & 0xFF] ^ (Si[(num6 >> 8) & 0xFF] << 8) ^ (Si[(num4 >> 16) & 0xFF] << 16) ^ (Si[(num8 >> 24) & 0xFF] << 24)) ^ array[1];
C2 = (uint)(Si[num8 & 0xFF] ^ (Si[(num7 >> 8) & 0xFF] << 8) ^ (Si[(num6 >> 16) & 0xFF] << 16) ^ (Si[(num4 >> 24) & 0xFF] << 24)) ^ array[2];
C3 = (uint)(Si[num4 & 0xFF] ^ (Si[(num8 >> 8) & 0xFF] << 8) ^ (Si[(num7 >> 16) & 0xFF] << 16) ^ (Si[(num6 >> 24) & 0xFF] << 24)) ^ array[3];
}
}

View File

@@ -0,0 +1,9 @@
namespace Org.BouncyCastle.Crypto.Engines;
public class AesWrapEngine : Rfc3394WrapEngine
{
public AesWrapEngine()
: base(new AesEngine())
{
}
}

View File

@@ -0,0 +1,296 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Utilities;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public sealed class BlowfishEngine : IBlockCipher
{
private const int BLOCK_SIZE = 8;
private static readonly uint[] KP = new uint[18]
{
608135816u, 2242054355u, 320440878u, 57701188u, 2752067618u, 698298832u, 137296536u, 3964562569u, 1160258022u, 953160567u,
3193202383u, 887688300u, 3232508343u, 3380367581u, 1065670069u, 3041331479u, 2450970073u, 2306472731u
};
private static readonly uint[] KS0 = new uint[256]
{
3509652390u, 2564797868u, 805139163u, 3491422135u, 3101798381u, 1780907670u, 3128725573u, 4046225305u, 614570311u, 3012652279u,
134345442u, 2240740374u, 1667834072u, 1901547113u, 2757295779u, 4103290238u, 227898511u, 1921955416u, 1904987480u, 2182433518u,
2069144605u, 3260701109u, 2620446009u, 720527379u, 3318853667u, 677414384u, 3393288472u, 3101374703u, 2390351024u, 1614419982u,
1822297739u, 2954791486u, 3608508353u, 3174124327u, 2024746970u, 1432378464u, 3864339955u, 2857741204u, 1464375394u, 1676153920u,
1439316330u, 715854006u, 3033291828u, 289532110u, 2706671279u, 2087905683u, 3018724369u, 1668267050u, 732546397u, 1947742710u,
3462151702u, 2609353502u, 2950085171u, 1814351708u, 2050118529u, 680887927u, 999245976u, 1800124847u, 3300911131u, 1713906067u,
1641548236u, 4213287313u, 1216130144u, 1575780402u, 4018429277u, 3917837745u, 3693486850u, 3949271944u, 596196993u, 3549867205u,
258830323u, 2213823033u, 772490370u, 2760122372u, 1774776394u, 2652871518u, 566650946u, 4142492826u, 1728879713u, 2882767088u,
1783734482u, 3629395816u, 2517608232u, 2874225571u, 1861159788u, 326777828u, 3124490320u, 2130389656u, 2716951837u, 967770486u,
1724537150u, 2185432712u, 2364442137u, 1164943284u, 2105845187u, 998989502u, 3765401048u, 2244026483u, 1075463327u, 1455516326u,
1322494562u, 910128902u, 469688178u, 1117454909u, 936433444u, 3490320968u, 3675253459u, 1240580251u, 122909385u, 2157517691u,
634681816u, 4142456567u, 3825094682u, 3061402683u, 2540495037u, 79693498u, 3249098678u, 1084186820u, 1583128258u, 426386531u,
1761308591u, 1047286709u, 322548459u, 995290223u, 1845252383u, 2603652396u, 3431023940u, 2942221577u, 3202600964u, 3727903485u,
1712269319u, 422464435u, 3234572375u, 1170764815u, 3523960633u, 3117677531u, 1434042557u, 442511882u, 3600875718u, 1076654713u,
1738483198u, 4213154764u, 2393238008u, 3677496056u, 1014306527u, 4251020053u, 793779912u, 2902807211u, 842905082u, 4246964064u,
1395751752u, 1040244610u, 2656851899u, 3396308128u, 445077038u, 3742853595u, 3577915638u, 679411651u, 2892444358u, 2354009459u,
1767581616u, 3150600392u, 3791627101u, 3102740896u, 284835224u, 4246832056u, 1258075500u, 768725851u, 2589189241u, 3069724005u,
3532540348u, 1274779536u, 3789419226u, 2764799539u, 1660621633u, 3471099624u, 4011903706u, 913787905u, 3497959166u, 737222580u,
2514213453u, 2928710040u, 3937242737u, 1804850592u, 3499020752u, 2949064160u, 2386320175u, 2390070455u, 2415321851u, 4061277028u,
2290661394u, 2416832540u, 1336762016u, 1754252060u, 3520065937u, 3014181293u, 791618072u, 3188594551u, 3933548030u, 2332172193u,
3852520463u, 3043980520u, 413987798u, 3465142937u, 3030929376u, 4245938359u, 2093235073u, 3534596313u, 375366246u, 2157278981u,
2479649556u, 555357303u, 3870105701u, 2008414854u, 3344188149u, 4221384143u, 3956125452u, 2067696032u, 3594591187u, 2921233993u,
2428461u, 544322398u, 577241275u, 1471733935u, 610547355u, 4027169054u, 1432588573u, 1507829418u, 2025931657u, 3646575487u,
545086370u, 48609733u, 2200306550u, 1653985193u, 298326376u, 1316178497u, 3007786442u, 2064951626u, 458293330u, 2589141269u,
3591329599u, 3164325604u, 727753846u, 2179363840u, 146436021u, 1461446943u, 4069977195u, 705550613u, 3059967265u, 3887724982u,
4281599278u, 3313849956u, 1404054877u, 2845806497u, 146425753u, 1854211946u
};
private static readonly uint[] KS1 = new uint[256]
{
1266315497u, 3048417604u, 3681880366u, 3289982499u, 2909710000u, 1235738493u, 2632868024u, 2414719590u, 3970600049u, 1771706367u,
1449415276u, 3266420449u, 422970021u, 1963543593u, 2690192192u, 3826793022u, 1062508698u, 1531092325u, 1804592342u, 2583117782u,
2714934279u, 4024971509u, 1294809318u, 4028980673u, 1289560198u, 2221992742u, 1669523910u, 35572830u, 157838143u, 1052438473u,
1016535060u, 1802137761u, 1753167236u, 1386275462u, 3080475397u, 2857371447u, 1040679964u, 2145300060u, 2390574316u, 1461121720u,
2956646967u, 4031777805u, 4028374788u, 33600511u, 2920084762u, 1018524850u, 629373528u, 3691585981u, 3515945977u, 2091462646u,
2486323059u, 586499841u, 988145025u, 935516892u, 3367335476u, 2599673255u, 2839830854u, 265290510u, 3972581182u, 2759138881u,
3795373465u, 1005194799u, 847297441u, 406762289u, 1314163512u, 1332590856u, 1866599683u, 4127851711u, 750260880u, 613907577u,
1450815602u, 3165620655u, 3734664991u, 3650291728u, 3012275730u, 3704569646u, 1427272223u, 778793252u, 1343938022u, 2676280711u,
2052605720u, 1946737175u, 3164576444u, 3914038668u, 3967478842u, 3682934266u, 1661551462u, 3294938066u, 4011595847u, 840292616u,
3712170807u, 616741398u, 312560963u, 711312465u, 1351876610u, 322626781u, 1910503582u, 271666773u, 2175563734u, 1594956187u,
70604529u, 3617834859u, 1007753275u, 1495573769u, 4069517037u, 2549218298u, 2663038764u, 504708206u, 2263041392u, 3941167025u,
2249088522u, 1514023603u, 1998579484u, 1312622330u, 694541497u, 2582060303u, 2151582166u, 1382467621u, 776784248u, 2618340202u,
3323268794u, 2497899128u, 2784771155u, 503983604u, 4076293799u, 907881277u, 423175695u, 432175456u, 1378068232u, 4145222326u,
3954048622u, 3938656102u, 3820766613u, 2793130115u, 2977904593u, 26017576u, 3274890735u, 3194772133u, 1700274565u, 1756076034u,
4006520079u, 3677328699u, 720338349u, 1533947780u, 354530856u, 688349552u, 3973924725u, 1637815568u, 332179504u, 3949051286u,
53804574u, 2852348879u, 3044236432u, 1282449977u, 3583942155u, 3416972820u, 4006381244u, 1617046695u, 2628476075u, 3002303598u,
1686838959u, 431878346u, 2686675385u, 1700445008u, 1080580658u, 1009431731u, 832498133u, 3223435511u, 2605976345u, 2271191193u,
2516031870u, 1648197032u, 4164389018u, 2548247927u, 300782431u, 375919233u, 238389289u, 3353747414u, 2531188641u, 2019080857u,
1475708069u, 455242339u, 2609103871u, 448939670u, 3451063019u, 1395535956u, 2413381860u, 1841049896u, 1491858159u, 885456874u,
4264095073u, 4001119347u, 1565136089u, 3898914787u, 1108368660u, 540939232u, 1173283510u, 2745871338u, 3681308437u, 4207628240u,
3343053890u, 4016749493u, 1699691293u, 1103962373u, 3625875870u, 2256883143u, 3830138730u, 1031889488u, 3479347698u, 1535977030u,
4236805024u, 3251091107u, 2132092099u, 1774941330u, 1199868427u, 1452454533u, 157007616u, 2904115357u, 342012276u, 595725824u,
1480756522u, 206960106u, 497939518u, 591360097u, 863170706u, 2375253569u, 3596610801u, 1814182875u, 2094937945u, 3421402208u,
1082520231u, 3463918190u, 2785509508u, 435703966u, 3908032597u, 1641649973u, 2842273706u, 3305899714u, 1510255612u, 2148256476u,
2655287854u, 3276092548u, 4258621189u, 236887753u, 3681803219u, 274041037u, 1734335097u, 3815195456u, 3317970021u, 1899903192u,
1026095262u, 4050517792u, 356393447u, 2410691914u, 3873677099u, 3682840055u
};
private static readonly uint[] KS2 = new uint[256]
{
3913112168u, 2491498743u, 4132185628u, 2489919796u, 1091903735u, 1979897079u, 3170134830u, 3567386728u, 3557303409u, 857797738u,
1136121015u, 1342202287u, 507115054u, 2535736646u, 337727348u, 3213592640u, 1301675037u, 2528481711u, 1895095763u, 1721773893u,
3216771564u, 62756741u, 2142006736u, 835421444u, 2531993523u, 1442658625u, 3659876326u, 2882144922u, 676362277u, 1392781812u,
170690266u, 3921047035u, 1759253602u, 3611846912u, 1745797284u, 664899054u, 1329594018u, 3901205900u, 3045908486u, 2062866102u,
2865634940u, 3543621612u, 3464012697u, 1080764994u, 553557557u, 3656615353u, 3996768171u, 991055499u, 499776247u, 1265440854u,
648242737u, 3940784050u, 980351604u, 3713745714u, 1749149687u, 3396870395u, 4211799374u, 3640570775u, 1161844396u, 3125318951u,
1431517754u, 545492359u, 4268468663u, 3499529547u, 1437099964u, 2702547544u, 3433638243u, 2581715763u, 2787789398u, 1060185593u,
1593081372u, 2418618748u, 4260947970u, 69676912u, 2159744348u, 86519011u, 2512459080u, 3838209314u, 1220612927u, 3339683548u,
133810670u, 1090789135u, 1078426020u, 1569222167u, 845107691u, 3583754449u, 4072456591u, 1091646820u, 628848692u, 1613405280u,
3757631651u, 526609435u, 236106946u, 48312990u, 2942717905u, 3402727701u, 1797494240u, 859738849u, 992217954u, 4005476642u,
2243076622u, 3870952857u, 3732016268u, 765654824u, 3490871365u, 2511836413u, 1685915746u, 3888969200u, 1414112111u, 2273134842u,
3281911079u, 4080962846u, 172450625u, 2569994100u, 980381355u, 4109958455u, 2819808352u, 2716589560u, 2568741196u, 3681446669u,
3329971472u, 1835478071u, 660984891u, 3704678404u, 4045999559u, 3422617507u, 3040415634u, 1762651403u, 1719377915u, 3470491036u,
2693910283u, 3642056355u, 3138596744u, 1364962596u, 2073328063u, 1983633131u, 926494387u, 3423689081u, 2150032023u, 4096667949u,
1749200295u, 3328846651u, 309677260u, 2016342300u, 1779581495u, 3079819751u, 111262694u, 1274766160u, 443224088u, 298511866u,
1025883608u, 3806446537u, 1145181785u, 168956806u, 3641502830u, 3584813610u, 1689216846u, 3666258015u, 3200248200u, 1692713982u,
2646376535u, 4042768518u, 1618508792u, 1610833997u, 3523052358u, 4130873264u, 2001055236u, 3610705100u, 2202168115u, 4028541809u,
2961195399u, 1006657119u, 2006996926u, 3186142756u, 1430667929u, 3210227297u, 1314452623u, 4074634658u, 4101304120u, 2273951170u,
1399257539u, 3367210612u, 3027628629u, 1190975929u, 2062231137u, 2333990788u, 2221543033u, 2438960610u, 1181637006u, 548689776u,
2362791313u, 3372408396u, 3104550113u, 3145860560u, 296247880u, 1970579870u, 3078560182u, 3769228297u, 1714227617u, 3291629107u,
3898220290u, 166772364u, 1251581989u, 493813264u, 448347421u, 195405023u, 2709975567u, 677966185u, 3703036547u, 1463355134u,
2715995803u, 1338867538u, 1343315457u, 2802222074u, 2684532164u, 233230375u, 2599980071u, 2000651841u, 3277868038u, 1638401717u,
4028070440u, 3237316320u, 6314154u, 819756386u, 300326615u, 590932579u, 1405279636u, 3267499572u, 3150704214u, 2428286686u,
3959192993u, 3461946742u, 1862657033u, 1266418056u, 963775037u, 2089974820u, 2263052895u, 1917689273u, 448879540u, 3550394620u,
3981727096u, 150775221u, 3627908307u, 1303187396u, 508620638u, 2975983352u, 2726630617u, 1817252668u, 1876281319u, 1457606340u,
908771278u, 3720792119u, 3617206836u, 2455994898u, 1729034894u, 1080033504u
};
private static readonly uint[] KS3 = new uint[256]
{
976866871u, 3556439503u, 2881648439u, 1522871579u, 1555064734u, 1336096578u, 3548522304u, 2579274686u, 3574697629u, 3205460757u,
3593280638u, 3338716283u, 3079412587u, 564236357u, 2993598910u, 1781952180u, 1464380207u, 3163844217u, 3332601554u, 1699332808u,
1393555694u, 1183702653u, 3581086237u, 1288719814u, 691649499u, 2847557200u, 2895455976u, 3193889540u, 2717570544u, 1781354906u,
1676643554u, 2592534050u, 3230253752u, 1126444790u, 2770207658u, 2633158820u, 2210423226u, 2615765581u, 2414155088u, 3127139286u,
673620729u, 2805611233u, 1269405062u, 4015350505u, 3341807571u, 4149409754u, 1057255273u, 2012875353u, 2162469141u, 2276492801u,
2601117357u, 993977747u, 3918593370u, 2654263191u, 753973209u, 36408145u, 2530585658u, 25011837u, 3520020182u, 2088578344u,
530523599u, 2918365339u, 1524020338u, 1518925132u, 3760827505u, 3759777254u, 1202760957u, 3985898139u, 3906192525u, 674977740u,
4174734889u, 2031300136u, 2019492241u, 3983892565u, 4153806404u, 3822280332u, 352677332u, 2297720250u, 60907813u, 90501309u,
3286998549u, 1016092578u, 2535922412u, 2839152426u, 457141659u, 509813237u, 4120667899u, 652014361u, 1966332200u, 2975202805u,
55981186u, 2327461051u, 676427537u, 3255491064u, 2882294119u, 3433927263u, 1307055953u, 942726286u, 933058658u, 2468411793u,
3933900994u, 4215176142u, 1361170020u, 2001714738u, 2830558078u, 3274259782u, 1222529897u, 1679025792u, 2729314320u, 3714953764u,
1770335741u, 151462246u, 3013232138u, 1682292957u, 1483529935u, 471910574u, 1539241949u, 458788160u, 3436315007u, 1807016891u,
3718408830u, 978976581u, 1043663428u, 3165965781u, 1927990952u, 4200891579u, 2372276910u, 3208408903u, 3533431907u, 1412390302u,
2931980059u, 4132332400u, 1947078029u, 3881505623u, 4168226417u, 2941484381u, 1077988104u, 1320477388u, 886195818u, 18198404u,
3786409000u, 2509781533u, 112762804u, 3463356488u, 1866414978u, 891333506u, 18488651u, 661792760u, 1628790961u, 3885187036u,
3141171499u, 876946877u, 2693282273u, 1372485963u, 791857591u, 2686433993u, 3759982718u, 3167212022u, 3472953795u, 2716379847u,
445679433u, 3561995674u, 3504004811u, 3574258232u, 54117162u, 3331405415u, 2381918588u, 3769707343u, 4154350007u, 1140177722u,
4074052095u, 668550556u, 3214352940u, 367459370u, 261225585u, 2610173221u, 4209349473u, 3468074219u, 3265815641u, 314222801u,
3066103646u, 3808782860u, 282218597u, 3406013506u, 3773591054u, 379116347u, 1285071038u, 846784868u, 2669647154u, 3771962079u,
3550491691u, 2305946142u, 453669953u, 1268987020u, 3317592352u, 3279303384u, 3744833421u, 2610507566u, 3859509063u, 266596637u,
3847019092u, 517658769u, 3462560207u, 3443424879u, 370717030u, 4247526661u, 2224018117u, 4143653529u, 4112773975u, 2788324899u,
2477274417u, 1456262402u, 2901442914u, 1517677493u, 1846949527u, 2295493580u, 3734397586u, 2176403920u, 1280348187u, 1908823572u,
3871786941u, 846861322u, 1172426758u, 3287448474u, 3383383037u, 1655181056u, 3139813346u, 901632758u, 1897031941u, 2986607138u,
3066810236u, 3447102507u, 1393639104u, 373351379u, 950779232u, 625454576u, 3124240540u, 4148612726u, 2007998917u, 544563296u,
2244738638u, 2330496472u, 2058025392u, 1291430526u, 424198748u, 50039436u, 29584100u, 3605783033u, 2429876329u, 2791104160u,
1057563949u, 3255363231u, 3075367218u, 3463963227u, 1469046755u, 985887462u
};
private static readonly int ROUNDS = 16;
private static readonly int SBOX_SK = 256;
private static readonly int P_SZ = ROUNDS + 2;
private readonly uint[] S0;
private readonly uint[] S1;
private readonly uint[] S2;
private readonly uint[] S3;
private readonly uint[] P;
private bool encrypting;
private byte[] workingKey;
public string AlgorithmName => "Blowfish";
public bool IsPartialBlockOkay => false;
public BlowfishEngine()
{
S0 = new uint[SBOX_SK];
S1 = new uint[SBOX_SK];
S2 = new uint[SBOX_SK];
S3 = new uint[SBOX_SK];
P = new uint[P_SZ];
}
public void Init(bool forEncryption, ICipherParameters parameters)
{
if (!(parameters is KeyParameter))
{
throw new ArgumentException("invalid parameter passed to Blowfish init - " + Platform.GetTypeName(parameters));
}
encrypting = forEncryption;
workingKey = ((KeyParameter)parameters).GetKey();
SetKey(workingKey);
}
public int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
{
if (workingKey == null)
{
throw new InvalidOperationException("Blowfish not initialised");
}
Check.DataLength(input, inOff, 8, "input buffer too short");
Check.OutputLength(output, outOff, 8, "output buffer too short");
if (encrypting)
{
EncryptBlock(input, inOff, output, outOff);
}
else
{
DecryptBlock(input, inOff, output, outOff);
}
return 8;
}
public void Reset()
{
}
public int GetBlockSize()
{
return 8;
}
private uint F(uint x)
{
return ((S0[x >> 24] + S1[(x >> 16) & 0xFF]) ^ S2[(x >> 8) & 0xFF]) + S3[x & 0xFF];
}
private void ProcessTable(uint xl, uint xr, uint[] table)
{
int num = table.Length;
for (int i = 0; i < num; i += 2)
{
xl ^= P[0];
for (int j = 1; j < ROUNDS; j += 2)
{
xr ^= F(xl) ^ P[j];
xl ^= F(xr) ^ P[j + 1];
}
xr ^= P[ROUNDS + 1];
table[i] = xr;
table[i + 1] = xl;
xr = xl;
xl = table[i];
}
}
private void SetKey(byte[] key)
{
Array.Copy(KS0, 0, S0, 0, SBOX_SK);
Array.Copy(KS1, 0, S1, 0, SBOX_SK);
Array.Copy(KS2, 0, S2, 0, SBOX_SK);
Array.Copy(KS3, 0, S3, 0, SBOX_SK);
Array.Copy(KP, 0, P, 0, P_SZ);
int num = key.Length;
int num2 = 0;
for (int i = 0; i < P_SZ; i++)
{
uint num3 = 0u;
for (int j = 0; j < 4; j++)
{
num3 = (num3 << 8) | key[num2++];
if (num2 >= num)
{
num2 = 0;
}
}
uint[] p;
uint[] array = (p = P);
int num4 = i;
nint num5 = num4;
array[num4] = p[num5] ^ num3;
}
ProcessTable(0u, 0u, P);
ProcessTable(P[P_SZ - 2], P[P_SZ - 1], S0);
ProcessTable(S0[SBOX_SK - 2], S0[SBOX_SK - 1], S1);
ProcessTable(S1[SBOX_SK - 2], S1[SBOX_SK - 1], S2);
ProcessTable(S2[SBOX_SK - 2], S2[SBOX_SK - 1], S3);
}
private void EncryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex)
{
uint num = Pack.BE_To_UInt32(src, srcIndex);
uint num2 = Pack.BE_To_UInt32(src, srcIndex + 4);
num ^= P[0];
for (int i = 1; i < ROUNDS; i += 2)
{
num2 ^= F(num) ^ P[i];
num ^= F(num2) ^ P[i + 1];
}
num2 ^= P[ROUNDS + 1];
Pack.UInt32_To_BE(num2, dst, dstIndex);
Pack.UInt32_To_BE(num, dst, dstIndex + 4);
}
private void DecryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex)
{
uint num = Pack.BE_To_UInt32(src, srcIndex);
uint num2 = Pack.BE_To_UInt32(src, srcIndex + 4);
num ^= P[ROUNDS + 1];
for (int num3 = ROUNDS; num3 > 0; num3 -= 2)
{
num2 ^= F(num) ^ P[num3];
num ^= F(num2) ^ P[num3 - 1];
}
num2 ^= P[0];
Pack.UInt32_To_BE(num2, dst, dstIndex);
Pack.UInt32_To_BE(num, dst, dstIndex + 4);
}
}

View File

@@ -0,0 +1,548 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
namespace Org.BouncyCastle.Crypto.Engines;
public class CamelliaEngine : IBlockCipher
{
private const int BLOCK_SIZE = 16;
private bool initialised = false;
private bool _keyIs128;
private uint[] subkey = new uint[96];
private uint[] kw = new uint[8];
private uint[] ke = new uint[12];
private uint[] state = new uint[4];
private static readonly uint[] SIGMA = new uint[12]
{
2694735487u, 1003262091u, 3061508184u, 1286239154u, 3337565999u, 3914302142u, 1426019237u, 4057165596u, 283453434u, 3731369245u,
2958461122u, 3018244605u
};
private static readonly uint[] SBOX1_1110 = new uint[256]
{
1886416896u, 2189591040u, 741092352u, 3974949888u, 3014898432u, 656877312u, 3233857536u, 3857048832u, 3840205824u, 2240120064u,
1465341696u, 892679424u, 3941263872u, 202116096u, 2930683392u, 1094795520u, 589505280u, 4025478912u, 1802201856u, 2475922176u,
1162167552u, 421075200u, 2779096320u, 555819264u, 3991792896u, 235802112u, 1330597632u, 1313754624u, 488447232u, 1701143808u,
2459079168u, 3183328512u, 2256963072u, 3099113472u, 2947526400u, 2408550144u, 2088532992u, 3958106880u, 522133248u, 3469659648u,
1044266496u, 808464384u, 3705461760u, 1600085760u, 1583242752u, 3318072576u, 185273088u, 437918208u, 2795939328u, 3789676800u,
960051456u, 3402287616u, 3587560704u, 1195853568u, 1566399744u, 1027423488u, 3654932736u, 16843008u, 1515870720u, 3604403712u,
1364283648u, 1448498688u, 1819044864u, 1296911616u, 2341178112u, 218959104u, 2593823232u, 1717986816u, 4227595008u, 3435973632u,
2964369408u, 757935360u, 1953788928u, 303174144u, 724249344u, 538976256u, 4042321920u, 2981212416u, 2223277056u, 2576980224u,
3755990784u, 1280068608u, 3419130624u, 3267543552u, 875836416u, 2122219008u, 1987474944u, 84215040u, 1835887872u, 3082270464u,
2846468352u, 825307392u, 3520188672u, 387389184u, 67372032u, 3621246720u, 336860160u, 1482184704u, 976894464u, 1633771776u,
3739147776u, 454761216u, 286331136u, 471604224u, 842150400u, 252645120u, 2627509248u, 370546176u, 1397969664u, 404232192u,
4076007936u, 572662272u, 4278124032u, 1145324544u, 3486502656u, 2998055424u, 3284386560u, 3048584448u, 2054846976u, 2442236160u,
606348288u, 134744064u, 3907577856u, 2829625344u, 1616928768u, 4244438016u, 1768515840u, 1347440640u, 2863311360u, 3503345664u,
2694881280u, 2105376000u, 2711724288u, 2307492096u, 1650614784u, 2543294208u, 1414812672u, 1532713728u, 505290240u, 2509608192u,
3772833792u, 4294967040u, 1684300800u, 3537031680u, 269488128u, 3301229568u, 0u, 1212696576u, 2745410304u, 4160222976u,
1970631936u, 3688618752u, 2324335104u, 50529024u, 3873891840u, 3671775744u, 151587072u, 1061109504u, 3722304768u, 2492765184u,
2273806080u, 1549556736u, 2206434048u, 33686016u, 3452816640u, 1246382592u, 2425393152u, 858993408u, 1936945920u, 1734829824u,
4143379968u, 4092850944u, 2644352256u, 2139062016u, 3217014528u, 3806519808u, 1381126656u, 2610666240u, 3638089728u, 640034304u,
3368601600u, 926365440u, 3334915584u, 993737472u, 2172748032u, 2526451200u, 1869573888u, 1263225600u, 320017152u, 3200171520u,
1667457792u, 774778368u, 3924420864u, 2038003968u, 2812782336u, 2358021120u, 2678038272u, 1852730880u, 3166485504u, 2391707136u,
690563328u, 4126536960u, 4193908992u, 3065427456u, 791621376u, 4261281024u, 3031741440u, 1499027712u, 2021160960u, 2560137216u,
101058048u, 1785358848u, 3890734848u, 1179010560u, 1903259904u, 3132799488u, 3570717696u, 623191296u, 2880154368u, 1111638528u,
2290649088u, 2728567296u, 2374864128u, 4210752000u, 1920102912u, 117901056u, 3115956480u, 1431655680u, 4177065984u, 4008635904u,
2896997376u, 168430080u, 909522432u, 1229539584u, 707406336u, 1751672832u, 1010580480u, 943208448u, 4059164928u, 2762253312u,
1077952512u, 673720320u, 3553874688u, 2071689984u, 3149642496u, 3385444608u, 1128481536u, 3250700544u, 353703168u, 3823362816u,
2913840384u, 4109693952u, 2004317952u, 3351758592u, 2155905024u, 2661195264u
};
private static readonly uint[] SBOX4_4404 = new uint[256]
{
1886388336u, 741081132u, 3014852787u, 3233808576u, 3840147684u, 1465319511u, 3941204202u, 2930639022u, 589496355u, 1802174571u,
1162149957u, 2779054245u, 3991732461u, 1330577487u, 488439837u, 2459041938u, 2256928902u, 2947481775u, 2088501372u, 522125343u,
1044250686u, 3705405660u, 1583218782u, 185270283u, 2795896998u, 960036921u, 3587506389u, 1566376029u, 3654877401u, 1515847770u,
1364262993u, 1819017324u, 2341142667u, 2593783962u, 4227531003u, 2964324528u, 1953759348u, 724238379u, 4042260720u, 2223243396u,
3755933919u, 3419078859u, 875823156u, 1987444854u, 1835860077u, 2846425257u, 3520135377u, 67371012u, 336855060u, 976879674u,
3739091166u, 286326801u, 842137650u, 2627469468u, 1397948499u, 4075946226u, 4278059262u, 3486449871u, 3284336835u, 2054815866u,
606339108u, 3907518696u, 1616904288u, 1768489065u, 2863268010u, 2694840480u, 2711683233u, 1650589794u, 1414791252u, 505282590u,
3772776672u, 1684275300u, 269484048u, 0u, 2745368739u, 1970602101u, 2324299914u, 3873833190u, 151584777u, 3722248413u,
2273771655u, 2206400643u, 3452764365u, 2425356432u, 1936916595u, 4143317238u, 2644312221u, 3216965823u, 1381105746u, 3638034648u,
3368550600u, 3334865094u, 2172715137u, 1869545583u, 320012307u, 1667432547u, 3924361449u, 2812739751u, 2677997727u, 3166437564u,
690552873u, 4193845497u, 791609391u, 3031695540u, 2021130360u, 101056518u, 3890675943u, 1903231089u, 3570663636u, 2880110763u,
2290614408u, 2374828173u, 1920073842u, 3115909305u, 4177002744u, 2896953516u, 909508662u, 707395626u, 1010565180u, 4059103473u,
1077936192u, 3553820883u, 3149594811u, 1128464451u, 353697813u, 2913796269u, 2004287607u, 2155872384u, 2189557890u, 3974889708u,
656867367u, 3856990437u, 2240086149u, 892665909u, 202113036u, 1094778945u, 4025417967u, 2475884691u, 421068825u, 555810849u,
235798542u, 1313734734u, 1701118053u, 3183280317u, 3099066552u, 2408513679u, 3958046955u, 3469607118u, 808452144u, 1600061535u,
3318022341u, 437911578u, 3789619425u, 3402236106u, 1195835463u, 1027407933u, 16842753u, 3604349142u, 1448476758u, 1296891981u,
218955789u, 1717960806u, 3435921612u, 757923885u, 303169554u, 538968096u, 2981167281u, 2576941209u, 1280049228u, 3267494082u,
2122186878u, 84213765u, 3082223799u, 825294897u, 387383319u, 3621191895u, 1482162264u, 1633747041u, 454754331u, 471597084u,
252641295u, 370540566u, 404226072u, 572653602u, 1145307204u, 2998010034u, 3048538293u, 2442199185u, 134742024u, 2829582504u,
4244373756u, 1347420240u, 3503292624u, 2105344125u, 2307457161u, 2543255703u, 1532690523u, 2509570197u, 4294902015u, 3536978130u,
3301179588u, 1212678216u, 4160159991u, 3688562907u, 50528259u, 3671720154u, 1061093439u, 2492727444u, 1549533276u, 33685506u,
1246363722u, 858980403u, 1734803559u, 4092788979u, 2139029631u, 3806462178u, 2610626715u, 640024614u, 926351415u, 993722427u,
2526412950u, 1263206475u, 3200123070u, 774766638u, 2037973113u, 2357985420u, 1852702830u, 2391670926u, 4126474485u, 3065381046u,
4261216509u, 1499005017u, 2560098456u, 1785331818u, 1178992710u, 3132752058u, 623181861u, 1111621698u, 2728525986u, 4210688250u,
117899271u, 1431634005u, 4008575214u, 168427530u, 1229520969u, 1751646312u, 943194168u, 2762211492u, 673710120u, 2071658619u,
3385393353u, 3250651329u, 3823304931u, 4109631732u, 3351707847u, 2661154974u
};
private static readonly uint[] SBOX2_0222 = new uint[256]
{
14737632u, 328965u, 5789784u, 14277081u, 6776679u, 5131854u, 8487297u, 13355979u, 13224393u, 723723u,
11447982u, 6974058u, 14013909u, 1579032u, 6118749u, 8553090u, 4605510u, 14671839u, 14079702u, 2565927u,
9079434u, 3289650u, 4934475u, 4342338u, 14408667u, 1842204u, 10395294u, 10263708u, 3815994u, 13290186u,
2434341u, 8092539u, 855309u, 7434609u, 6250335u, 2039583u, 16316664u, 14145495u, 4079166u, 10329501u,
8158332u, 6316128u, 12171705u, 12500670u, 12369084u, 9145227u, 1447446u, 3421236u, 5066061u, 12829635u,
7500402u, 9803157u, 11250603u, 9342606u, 12237498u, 8026746u, 11776947u, 131586u, 11842740u, 11382189u,
10658466u, 11316396u, 14211288u, 10132122u, 1513239u, 1710618u, 3487029u, 13421772u, 16250871u, 10066329u,
6381921u, 5921370u, 15263976u, 2368548u, 5658198u, 4210752u, 14803425u, 6513507u, 592137u, 3355443u,
12566463u, 10000536u, 9934743u, 8750469u, 6842472u, 16579836u, 15527148u, 657930u, 14342874u, 7303023u,
5460819u, 6447714u, 10724259u, 3026478u, 526344u, 11513775u, 2631720u, 11579568u, 7631988u, 12763842u,
12434877u, 3552822u, 2236962u, 3684408u, 6579300u, 1973790u, 3750201u, 2894892u, 10921638u, 3158064u,
15066597u, 4473924u, 16645629u, 8947848u, 10461087u, 6645093u, 8882055u, 7039851u, 16053492u, 2302755u,
4737096u, 1052688u, 13750737u, 5329233u, 12632256u, 16382457u, 13816530u, 10526880u, 5592405u, 10592673u,
4276545u, 16448250u, 4408131u, 1250067u, 12895428u, 3092271u, 11053224u, 11974326u, 3947580u, 2829099u,
12698049u, 16777215u, 13158600u, 10855845u, 2105376u, 9013641u, 0u, 9474192u, 4671303u, 15724527u,
15395562u, 12040119u, 1381653u, 394758u, 13487565u, 11908533u, 1184274u, 8289918u, 12303291u, 2697513u,
986895u, 12105912u, 460551u, 263172u, 10197915u, 9737364u, 2171169u, 6710886u, 15132390u, 13553358u,
15592941u, 15198183u, 3881787u, 16711422u, 8355711u, 12961221u, 10790052u, 3618615u, 11645361u, 5000268u,
9539985u, 7237230u, 9276813u, 7763574u, 197379u, 2960685u, 14606046u, 9868950u, 2500134u, 8224125u,
13027014u, 6052956u, 13882323u, 15921906u, 5197647u, 1644825u, 4144959u, 14474460u, 7960953u, 1907997u,
5395026u, 15461355u, 15987699u, 7171437u, 6184542u, 16514043u, 6908265u, 11711154u, 15790320u, 3223857u,
789516u, 13948116u, 13619151u, 9211020u, 14869218u, 7697781u, 11119017u, 4868682u, 5723991u, 8684676u,
1118481u, 4539717u, 1776411u, 16119285u, 15000804u, 921102u, 7566195u, 11184810u, 15856113u, 14540253u,
5855577u, 1315860u, 7105644u, 9605778u, 5526612u, 13684944u, 7895160u, 7368816u, 14935011u, 4802889u,
8421504u, 5263440u, 10987431u, 16185078u, 7829367u, 9671571u, 8816262u, 8618883u, 2763306u, 13092807u,
5987163u, 15329769u, 15658734u, 9408399u, 65793u, 4013373u
};
private static readonly uint[] SBOX3_3033 = new uint[256]
{
939538488u, 1090535745u, 369104406u, 1979741814u, 3640711641u, 2466288531u, 1610637408u, 4060148466u, 1912631922u, 3254829762u,
2868947883u, 2583730842u, 1962964341u, 100664838u, 1459640151u, 2684395680u, 2432733585u, 4144035831u, 3036722613u, 3372272073u,
2717950626u, 2348846220u, 3523269330u, 2415956112u, 4127258358u, 117442311u, 2801837991u, 654321447u, 2382401166u, 2986390194u,
1224755529u, 3724599006u, 1124090691u, 1543527516u, 3607156695u, 3338717127u, 1040203326u, 4110480885u, 2399178639u, 1728079719u,
520101663u, 402659352u, 1845522030u, 2936057775u, 788541231u, 3791708898u, 2231403909u, 218107149u, 1392530259u, 4026593520u,
2617285788u, 1694524773u, 3925928682u, 2734728099u, 2919280302u, 2650840734u, 3959483628u, 2147516544u, 754986285u, 1795189611u,
2818615464u, 721431339u, 905983542u, 2785060518u, 3305162181u, 2248181382u, 1291865421u, 855651123u, 4244700669u, 1711302246u,
1476417624u, 2516620950u, 973093434u, 150997257u, 2499843477u, 268439568u, 2013296760u, 3623934168u, 1107313218u, 3422604492u,
4009816047u, 637543974u, 3842041317u, 1627414881u, 436214298u, 1056980799u, 989870907u, 2181071490u, 3053500086u, 3674266587u,
3556824276u, 2550175896u, 3892373736u, 2332068747u, 33554946u, 3942706155u, 167774730u, 738208812u, 486546717u, 2952835248u,
1862299503u, 2365623693u, 2281736328u, 234884622u, 419436825u, 2264958855u, 1308642894u, 184552203u, 2835392937u, 201329676u,
2030074233u, 285217041u, 2130739071u, 570434082u, 3875596263u, 1493195097u, 3774931425u, 3657489114u, 1023425853u, 3355494600u,
301994514u, 67109892u, 1946186868u, 1409307732u, 805318704u, 2113961598u, 3019945140u, 671098920u, 1426085205u, 1744857192u,
1342197840u, 3187719870u, 3489714384u, 3288384708u, 822096177u, 3405827019u, 704653866u, 2902502829u, 251662095u, 3389049546u,
1879076976u, 4278255615u, 838873650u, 1761634665u, 134219784u, 1644192354u, 0u, 603989028u, 3506491857u, 4211145723u,
3120609978u, 3976261101u, 1157645637u, 2164294017u, 1929409395u, 1828744557u, 2214626436u, 2667618207u, 3993038574u, 1241533002u,
3271607235u, 771763758u, 3238052289u, 16777473u, 3858818790u, 620766501u, 1207978056u, 2566953369u, 3103832505u, 3003167667u,
2063629179u, 4177590777u, 3456159438u, 3204497343u, 3741376479u, 1895854449u, 687876393u, 3439381965u, 1811967084u, 318771987u,
1677747300u, 2600508315u, 1660969827u, 2634063261u, 3221274816u, 1258310475u, 3070277559u, 2768283045u, 2298513801u, 1593859935u,
2969612721u, 385881879u, 4093703412u, 3154164924u, 3540046803u, 1174423110u, 3472936911u, 922761015u, 1577082462u, 1191200583u,
2483066004u, 4194368250u, 4227923196u, 1526750043u, 2533398423u, 4261478142u, 1509972570u, 2885725356u, 1006648380u, 1275087948u,
50332419u, 889206069u, 4076925939u, 587211555u, 3087055032u, 1560304989u, 1778412138u, 2449511058u, 3573601749u, 553656609u,
1140868164u, 1358975313u, 3321939654u, 2097184125u, 956315961u, 2197848963u, 3691044060u, 2852170410u, 2080406652u, 1996519287u,
1442862678u, 83887365u, 452991771u, 2751505572u, 352326933u, 872428596u, 503324190u, 469769244u, 4160813304u, 1375752786u,
536879136u, 335549460u, 3909151209u, 3170942397u, 3707821533u, 3825263844u, 2701173153u, 3758153952u, 2315291274u, 4043370993u,
3590379222u, 2046851706u, 3137387451u, 3808486371u, 1073758272u, 1325420367u
};
public virtual string AlgorithmName => "Camellia";
public virtual bool IsPartialBlockOkay => false;
private static uint rightRotate(uint x, int s)
{
return (x >> s) + (x << 32 - s);
}
private static uint leftRotate(uint x, int s)
{
return (x << s) + (x >> 32 - s);
}
private static void roldq(int rot, uint[] ki, int ioff, uint[] ko, int ooff)
{
ko[ooff] = (ki[ioff] << rot) | (ki[1 + ioff] >> 32 - rot);
ko[1 + ooff] = (ki[1 + ioff] << rot) | (ki[2 + ioff] >> 32 - rot);
ko[2 + ooff] = (ki[2 + ioff] << rot) | (ki[3 + ioff] >> 32 - rot);
ko[3 + ooff] = (ki[3 + ioff] << rot) | (ki[ioff] >> 32 - rot);
ki[ioff] = ko[ooff];
ki[1 + ioff] = ko[1 + ooff];
ki[2 + ioff] = ko[2 + ooff];
ki[3 + ioff] = ko[3 + ooff];
}
private static void decroldq(int rot, uint[] ki, int ioff, uint[] ko, int ooff)
{
ko[2 + ooff] = (ki[ioff] << rot) | (ki[1 + ioff] >> 32 - rot);
ko[3 + ooff] = (ki[1 + ioff] << rot) | (ki[2 + ioff] >> 32 - rot);
ko[ooff] = (ki[2 + ioff] << rot) | (ki[3 + ioff] >> 32 - rot);
ko[1 + ooff] = (ki[3 + ioff] << rot) | (ki[ioff] >> 32 - rot);
ki[ioff] = ko[2 + ooff];
ki[1 + ioff] = ko[3 + ooff];
ki[2 + ioff] = ko[ooff];
ki[3 + ioff] = ko[1 + ooff];
}
private static void roldqo32(int rot, uint[] ki, int ioff, uint[] ko, int ooff)
{
ko[ooff] = (ki[1 + ioff] << rot - 32) | (ki[2 + ioff] >> 64 - rot);
ko[1 + ooff] = (ki[2 + ioff] << rot - 32) | (ki[3 + ioff] >> 64 - rot);
ko[2 + ooff] = (ki[3 + ioff] << rot - 32) | (ki[ioff] >> 64 - rot);
ko[3 + ooff] = (ki[ioff] << rot - 32) | (ki[1 + ioff] >> 64 - rot);
ki[ioff] = ko[ooff];
ki[1 + ioff] = ko[1 + ooff];
ki[2 + ioff] = ko[2 + ooff];
ki[3 + ioff] = ko[3 + ooff];
}
private static void decroldqo32(int rot, uint[] ki, int ioff, uint[] ko, int ooff)
{
ko[2 + ooff] = (ki[1 + ioff] << rot - 32) | (ki[2 + ioff] >> 64 - rot);
ko[3 + ooff] = (ki[2 + ioff] << rot - 32) | (ki[3 + ioff] >> 64 - rot);
ko[ooff] = (ki[3 + ioff] << rot - 32) | (ki[ioff] >> 64 - rot);
ko[1 + ooff] = (ki[ioff] << rot - 32) | (ki[1 + ioff] >> 64 - rot);
ki[ioff] = ko[2 + ooff];
ki[1 + ioff] = ko[3 + ooff];
ki[2 + ioff] = ko[ooff];
ki[3 + ioff] = ko[1 + ooff];
}
private static uint bytes2uint(byte[] src, int offset)
{
uint num = 0u;
for (int i = 0; i < 4; i++)
{
num = (num << 8) + src[i + offset];
}
return num;
}
private static void uint2bytes(uint word, byte[] dst, int offset)
{
for (int i = 0; i < 4; i++)
{
dst[3 - i + offset] = (byte)word;
word >>= 8;
}
}
private static void camelliaF2(uint[] s, uint[] skey, int keyoff)
{
uint num = s[0] ^ skey[keyoff];
uint num2 = SBOX4_4404[(byte)num];
num2 ^= SBOX3_3033[(byte)(num >> 8)];
num2 ^= SBOX2_0222[(byte)(num >> 16)];
num2 ^= SBOX1_1110[(byte)(num >> 24)];
uint num3 = s[1] ^ skey[1 + keyoff];
uint num4 = SBOX1_1110[(byte)num3];
num4 ^= SBOX4_4404[(byte)(num3 >> 8)];
num4 ^= SBOX3_3033[(byte)(num3 >> 16)];
num4 ^= SBOX2_0222[(byte)(num3 >> 24)];
uint[] array;
(array = s)[2] = array[2] ^ (num2 ^ num4);
(array = s)[3] = array[3] ^ (num2 ^ num4 ^ rightRotate(num2, 8));
num = s[2] ^ skey[2 + keyoff];
num2 = SBOX4_4404[(byte)num];
num2 ^= SBOX3_3033[(byte)(num >> 8)];
num2 ^= SBOX2_0222[(byte)(num >> 16)];
num2 ^= SBOX1_1110[(byte)(num >> 24)];
num3 = s[3] ^ skey[3 + keyoff];
num4 = SBOX1_1110[(byte)num3];
num4 ^= SBOX4_4404[(byte)(num3 >> 8)];
num4 ^= SBOX3_3033[(byte)(num3 >> 16)];
num4 ^= SBOX2_0222[(byte)(num3 >> 24)];
(array = s)[0] = array[0] ^ (num2 ^ num4);
(array = s)[1] = array[1] ^ (num2 ^ num4 ^ rightRotate(num2, 8));
}
private static void camelliaFLs(uint[] s, uint[] fkey, int keyoff)
{
uint[] array;
(array = s)[1] = array[1] ^ leftRotate(s[0] & fkey[keyoff], 1);
(array = s)[0] = array[0] ^ (fkey[1 + keyoff] | s[1]);
(array = s)[2] = array[2] ^ (fkey[3 + keyoff] | s[3]);
(array = s)[3] = array[3] ^ leftRotate(fkey[2 + keyoff] & s[2], 1);
}
private void setKey(bool forEncryption, byte[] key)
{
uint[] array = new uint[8];
uint[] array2 = new uint[4];
uint[] array3 = new uint[4];
uint[] array4 = new uint[4];
switch (key.Length)
{
case 16:
_keyIs128 = true;
array[0] = bytes2uint(key, 0);
array[1] = bytes2uint(key, 4);
array[2] = bytes2uint(key, 8);
array[3] = bytes2uint(key, 12);
array[4] = (array[5] = (array[6] = (array[7] = 0u)));
break;
case 24:
array[0] = bytes2uint(key, 0);
array[1] = bytes2uint(key, 4);
array[2] = bytes2uint(key, 8);
array[3] = bytes2uint(key, 12);
array[4] = bytes2uint(key, 16);
array[5] = bytes2uint(key, 20);
array[6] = ~array[4];
array[7] = ~array[5];
_keyIs128 = false;
break;
case 32:
array[0] = bytes2uint(key, 0);
array[1] = bytes2uint(key, 4);
array[2] = bytes2uint(key, 8);
array[3] = bytes2uint(key, 12);
array[4] = bytes2uint(key, 16);
array[5] = bytes2uint(key, 20);
array[6] = bytes2uint(key, 24);
array[7] = bytes2uint(key, 28);
_keyIs128 = false;
break;
default:
throw new ArgumentException("key sizes are only 16/24/32 bytes.");
}
for (int i = 0; i < 4; i++)
{
array2[i] = array[i] ^ array[i + 4];
}
camelliaF2(array2, SIGMA, 0);
for (int j = 0; j < 4; j++)
{
uint[] array6;
uint[] array5 = (array6 = array2);
int num = j;
nint num2 = num;
array5[num] = array6[num2] ^ array[j];
}
camelliaF2(array2, SIGMA, 4);
if (_keyIs128)
{
if (forEncryption)
{
kw[0] = array[0];
kw[1] = array[1];
kw[2] = array[2];
kw[3] = array[3];
roldq(15, array, 0, subkey, 4);
roldq(30, array, 0, subkey, 12);
roldq(15, array, 0, array4, 0);
subkey[18] = array4[2];
subkey[19] = array4[3];
roldq(17, array, 0, ke, 4);
roldq(17, array, 0, subkey, 24);
roldq(17, array, 0, subkey, 32);
subkey[0] = array2[0];
subkey[1] = array2[1];
subkey[2] = array2[2];
subkey[3] = array2[3];
roldq(15, array2, 0, subkey, 8);
roldq(15, array2, 0, ke, 0);
roldq(15, array2, 0, array4, 0);
subkey[16] = array4[0];
subkey[17] = array4[1];
roldq(15, array2, 0, subkey, 20);
roldqo32(34, array2, 0, subkey, 28);
roldq(17, array2, 0, kw, 4);
}
else
{
kw[4] = array[0];
kw[5] = array[1];
kw[6] = array[2];
kw[7] = array[3];
decroldq(15, array, 0, subkey, 28);
decroldq(30, array, 0, subkey, 20);
decroldq(15, array, 0, array4, 0);
subkey[16] = array4[0];
subkey[17] = array4[1];
decroldq(17, array, 0, ke, 0);
decroldq(17, array, 0, subkey, 8);
decroldq(17, array, 0, subkey, 0);
subkey[34] = array2[0];
subkey[35] = array2[1];
subkey[32] = array2[2];
subkey[33] = array2[3];
decroldq(15, array2, 0, subkey, 24);
decroldq(15, array2, 0, ke, 4);
decroldq(15, array2, 0, array4, 0);
subkey[18] = array4[2];
subkey[19] = array4[3];
decroldq(15, array2, 0, subkey, 12);
decroldqo32(34, array2, 0, subkey, 4);
roldq(17, array2, 0, kw, 0);
}
return;
}
for (int k = 0; k < 4; k++)
{
array3[k] = array2[k] ^ array[k + 4];
}
camelliaF2(array3, SIGMA, 8);
if (forEncryption)
{
kw[0] = array[0];
kw[1] = array[1];
kw[2] = array[2];
kw[3] = array[3];
roldqo32(45, array, 0, subkey, 16);
roldq(15, array, 0, ke, 4);
roldq(17, array, 0, subkey, 32);
roldqo32(34, array, 0, subkey, 44);
roldq(15, array, 4, subkey, 4);
roldq(15, array, 4, ke, 0);
roldq(30, array, 4, subkey, 24);
roldqo32(34, array, 4, subkey, 36);
roldq(15, array2, 0, subkey, 8);
roldq(30, array2, 0, subkey, 20);
ke[8] = array2[1];
ke[9] = array2[2];
ke[10] = array2[3];
ke[11] = array2[0];
roldqo32(49, array2, 0, subkey, 40);
subkey[0] = array3[0];
subkey[1] = array3[1];
subkey[2] = array3[2];
subkey[3] = array3[3];
roldq(30, array3, 0, subkey, 12);
roldq(30, array3, 0, subkey, 28);
roldqo32(51, array3, 0, kw, 4);
}
else
{
kw[4] = array[0];
kw[5] = array[1];
kw[6] = array[2];
kw[7] = array[3];
decroldqo32(45, array, 0, subkey, 28);
decroldq(15, array, 0, ke, 4);
decroldq(17, array, 0, subkey, 12);
decroldqo32(34, array, 0, subkey, 0);
decroldq(15, array, 4, subkey, 40);
decroldq(15, array, 4, ke, 8);
decroldq(30, array, 4, subkey, 20);
decroldqo32(34, array, 4, subkey, 8);
decroldq(15, array2, 0, subkey, 36);
decroldq(30, array2, 0, subkey, 24);
ke[2] = array2[1];
ke[3] = array2[2];
ke[0] = array2[3];
ke[1] = array2[0];
decroldqo32(49, array2, 0, subkey, 4);
subkey[46] = array3[0];
subkey[47] = array3[1];
subkey[44] = array3[2];
subkey[45] = array3[3];
decroldq(30, array3, 0, subkey, 32);
decroldq(30, array3, 0, subkey, 16);
roldqo32(51, array3, 0, kw, 0);
}
}
private int processBlock128(byte[] input, int inOff, byte[] output, int outOff)
{
uint[] array2;
for (int i = 0; i < 4; i++)
{
state[i] = bytes2uint(input, inOff + i * 4);
uint[] array = (array2 = state);
int num = i;
nint num2 = num;
array[num] = array2[num2] ^ kw[i];
}
camelliaF2(state, subkey, 0);
camelliaF2(state, subkey, 4);
camelliaF2(state, subkey, 8);
camelliaFLs(state, ke, 0);
camelliaF2(state, subkey, 12);
camelliaF2(state, subkey, 16);
camelliaF2(state, subkey, 20);
camelliaFLs(state, ke, 4);
camelliaF2(state, subkey, 24);
camelliaF2(state, subkey, 28);
camelliaF2(state, subkey, 32);
(array2 = state)[2] = array2[2] ^ kw[4];
(array2 = state)[3] = array2[3] ^ kw[5];
(array2 = state)[0] = array2[0] ^ kw[6];
(array2 = state)[1] = array2[1] ^ kw[7];
uint2bytes(state[2], output, outOff);
uint2bytes(state[3], output, outOff + 4);
uint2bytes(state[0], output, outOff + 8);
uint2bytes(state[1], output, outOff + 12);
return 16;
}
private int processBlock192or256(byte[] input, int inOff, byte[] output, int outOff)
{
uint[] array2;
for (int i = 0; i < 4; i++)
{
state[i] = bytes2uint(input, inOff + i * 4);
uint[] array = (array2 = state);
int num = i;
nint num2 = num;
array[num] = array2[num2] ^ kw[i];
}
camelliaF2(state, subkey, 0);
camelliaF2(state, subkey, 4);
camelliaF2(state, subkey, 8);
camelliaFLs(state, ke, 0);
camelliaF2(state, subkey, 12);
camelliaF2(state, subkey, 16);
camelliaF2(state, subkey, 20);
camelliaFLs(state, ke, 4);
camelliaF2(state, subkey, 24);
camelliaF2(state, subkey, 28);
camelliaF2(state, subkey, 32);
camelliaFLs(state, ke, 8);
camelliaF2(state, subkey, 36);
camelliaF2(state, subkey, 40);
camelliaF2(state, subkey, 44);
(array2 = state)[2] = array2[2] ^ kw[4];
(array2 = state)[3] = array2[3] ^ kw[5];
(array2 = state)[0] = array2[0] ^ kw[6];
(array2 = state)[1] = array2[1] ^ kw[7];
uint2bytes(state[2], output, outOff);
uint2bytes(state[3], output, outOff + 4);
uint2bytes(state[0], output, outOff + 8);
uint2bytes(state[1], output, outOff + 12);
return 16;
}
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
if (!(parameters is KeyParameter))
{
throw new ArgumentException("only simple KeyParameter expected.");
}
setKey(forEncryption, ((KeyParameter)parameters).GetKey());
initialised = true;
}
public virtual int GetBlockSize()
{
return 16;
}
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
{
if (!initialised)
{
throw new InvalidOperationException("Camellia engine not initialised");
}
Check.DataLength(input, inOff, 16, "input buffer too short");
Check.OutputLength(output, outOff, 16, "output buffer too short");
if (_keyIs128)
{
return processBlock128(input, inOff, output, outOff);
}
return processBlock192or256(input, inOff, output, outOff);
}
public virtual void Reset()
{
}
}

View File

@@ -0,0 +1,491 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
namespace Org.BouncyCastle.Crypto.Engines;
public class CamelliaLightEngine : IBlockCipher
{
private const int BLOCK_SIZE = 16;
private bool initialised;
private bool _keyis128;
private uint[] subkey = new uint[96];
private uint[] kw = new uint[8];
private uint[] ke = new uint[12];
private uint[] state = new uint[4];
private static readonly uint[] SIGMA = new uint[12]
{
2694735487u, 1003262091u, 3061508184u, 1286239154u, 3337565999u, 3914302142u, 1426019237u, 4057165596u, 283453434u, 3731369245u,
2958461122u, 3018244605u
};
private static readonly byte[] SBOX1 = new byte[256]
{
112, 130, 44, 236, 179, 39, 192, 229, 228, 133,
87, 53, 234, 12, 174, 65, 35, 239, 107, 147,
69, 25, 165, 33, 237, 14, 79, 78, 29, 101,
146, 189, 134, 184, 175, 143, 124, 235, 31, 206,
62, 48, 220, 95, 94, 197, 11, 26, 166, 225,
57, 202, 213, 71, 93, 61, 217, 1, 90, 214,
81, 86, 108, 77, 139, 13, 154, 102, 251, 204,
176, 45, 116, 18, 43, 32, 240, 177, 132, 153,
223, 76, 203, 194, 52, 126, 118, 5, 109, 183,
169, 49, 209, 23, 4, 215, 20, 88, 58, 97,
222, 27, 17, 28, 50, 15, 156, 22, 83, 24,
242, 34, 254, 68, 207, 178, 195, 181, 122, 145,
36, 8, 232, 168, 96, 252, 105, 80, 170, 208,
160, 125, 161, 137, 98, 151, 84, 91, 30, 149,
224, 255, 100, 210, 16, 196, 0, 72, 163, 247,
117, 219, 138, 3, 230, 218, 9, 63, 221, 148,
135, 92, 131, 2, 205, 74, 144, 51, 115, 103,
246, 243, 157, 127, 191, 226, 82, 155, 216, 38,
200, 55, 198, 59, 129, 150, 111, 75, 19, 190,
99, 46, 233, 121, 167, 140, 159, 110, 188, 142,
41, 245, 249, 182, 47, 253, 180, 89, 120, 152,
6, 106, 231, 70, 113, 186, 212, 37, 171, 66,
136, 162, 141, 250, 114, 7, 185, 85, 248, 238,
172, 10, 54, 73, 42, 104, 60, 56, 241, 164,
64, 40, 211, 123, 187, 201, 67, 193, 21, 227,
173, 244, 119, 199, 128, 158
};
public virtual string AlgorithmName => "Camellia";
public virtual bool IsPartialBlockOkay => false;
private static uint rightRotate(uint x, int s)
{
return (x >> s) + (x << 32 - s);
}
private static uint leftRotate(uint x, int s)
{
return (x << s) + (x >> 32 - s);
}
private static void roldq(int rot, uint[] ki, int ioff, uint[] ko, int ooff)
{
ko[ooff] = (ki[ioff] << rot) | (ki[1 + ioff] >> 32 - rot);
ko[1 + ooff] = (ki[1 + ioff] << rot) | (ki[2 + ioff] >> 32 - rot);
ko[2 + ooff] = (ki[2 + ioff] << rot) | (ki[3 + ioff] >> 32 - rot);
ko[3 + ooff] = (ki[3 + ioff] << rot) | (ki[ioff] >> 32 - rot);
ki[ioff] = ko[ooff];
ki[1 + ioff] = ko[1 + ooff];
ki[2 + ioff] = ko[2 + ooff];
ki[3 + ioff] = ko[3 + ooff];
}
private static void decroldq(int rot, uint[] ki, int ioff, uint[] ko, int ooff)
{
ko[2 + ooff] = (ki[ioff] << rot) | (ki[1 + ioff] >> 32 - rot);
ko[3 + ooff] = (ki[1 + ioff] << rot) | (ki[2 + ioff] >> 32 - rot);
ko[ooff] = (ki[2 + ioff] << rot) | (ki[3 + ioff] >> 32 - rot);
ko[1 + ooff] = (ki[3 + ioff] << rot) | (ki[ioff] >> 32 - rot);
ki[ioff] = ko[2 + ooff];
ki[1 + ioff] = ko[3 + ooff];
ki[2 + ioff] = ko[ooff];
ki[3 + ioff] = ko[1 + ooff];
}
private static void roldqo32(int rot, uint[] ki, int ioff, uint[] ko, int ooff)
{
ko[ooff] = (ki[1 + ioff] << rot - 32) | (ki[2 + ioff] >> 64 - rot);
ko[1 + ooff] = (ki[2 + ioff] << rot - 32) | (ki[3 + ioff] >> 64 - rot);
ko[2 + ooff] = (ki[3 + ioff] << rot - 32) | (ki[ioff] >> 64 - rot);
ko[3 + ooff] = (ki[ioff] << rot - 32) | (ki[1 + ioff] >> 64 - rot);
ki[ioff] = ko[ooff];
ki[1 + ioff] = ko[1 + ooff];
ki[2 + ioff] = ko[2 + ooff];
ki[3 + ioff] = ko[3 + ooff];
}
private static void decroldqo32(int rot, uint[] ki, int ioff, uint[] ko, int ooff)
{
ko[2 + ooff] = (ki[1 + ioff] << rot - 32) | (ki[2 + ioff] >> 64 - rot);
ko[3 + ooff] = (ki[2 + ioff] << rot - 32) | (ki[3 + ioff] >> 64 - rot);
ko[ooff] = (ki[3 + ioff] << rot - 32) | (ki[ioff] >> 64 - rot);
ko[1 + ooff] = (ki[ioff] << rot - 32) | (ki[1 + ioff] >> 64 - rot);
ki[ioff] = ko[2 + ooff];
ki[1 + ioff] = ko[3 + ooff];
ki[2 + ioff] = ko[ooff];
ki[3 + ioff] = ko[1 + ooff];
}
private static uint bytes2uint(byte[] src, int offset)
{
uint num = 0u;
for (int i = 0; i < 4; i++)
{
num = (num << 8) + src[i + offset];
}
return num;
}
private static void uint2bytes(uint word, byte[] dst, int offset)
{
for (int i = 0; i < 4; i++)
{
dst[3 - i + offset] = (byte)word;
word >>= 8;
}
}
private byte lRot8(byte v, int rot)
{
return (byte)((v << rot) | (v >>> 8 - rot));
}
private uint sbox2(int x)
{
return lRot8(SBOX1[x], 1);
}
private uint sbox3(int x)
{
return lRot8(SBOX1[x], 7);
}
private uint sbox4(int x)
{
return SBOX1[lRot8((byte)x, 1)];
}
private void camelliaF2(uint[] s, uint[] skey, int keyoff)
{
uint num = s[0] ^ skey[keyoff];
uint num2 = sbox4((byte)num);
num2 |= sbox3((byte)(num >> 8)) << 8;
num2 |= sbox2((byte)(num >> 16)) << 16;
num2 |= (uint)(SBOX1[(byte)(num >> 24)] << 24);
uint num3 = s[1] ^ skey[1 + keyoff];
uint num4 = SBOX1[(byte)num3];
num4 |= sbox4((byte)(num3 >> 8)) << 8;
num4 |= sbox3((byte)(num3 >> 16)) << 16;
num4 |= sbox2((byte)(num3 >> 24)) << 24;
num4 = leftRotate(num4, 8);
num2 ^= num4;
num4 = leftRotate(num4, 8) ^ num2;
num2 = rightRotate(num2, 8) ^ num4;
uint[] array;
(array = s)[2] = array[2] ^ (leftRotate(num4, 16) ^ num2);
(array = s)[3] = array[3] ^ leftRotate(num2, 8);
num = s[2] ^ skey[2 + keyoff];
num2 = sbox4((byte)num);
num2 |= sbox3((byte)(num >> 8)) << 8;
num2 |= sbox2((byte)(num >> 16)) << 16;
num2 |= (uint)(SBOX1[(byte)(num >> 24)] << 24);
num3 = s[3] ^ skey[3 + keyoff];
num4 = SBOX1[(byte)num3];
num4 |= sbox4((byte)(num3 >> 8)) << 8;
num4 |= sbox3((byte)(num3 >> 16)) << 16;
num4 |= sbox2((byte)(num3 >> 24)) << 24;
num4 = leftRotate(num4, 8);
num2 ^= num4;
num4 = leftRotate(num4, 8) ^ num2;
num2 = rightRotate(num2, 8) ^ num4;
(array = s)[0] = array[0] ^ (leftRotate(num4, 16) ^ num2);
(array = s)[1] = array[1] ^ leftRotate(num2, 8);
}
private void camelliaFLs(uint[] s, uint[] fkey, int keyoff)
{
uint[] array;
(array = s)[1] = array[1] ^ leftRotate(s[0] & fkey[keyoff], 1);
(array = s)[0] = array[0] ^ (fkey[1 + keyoff] | s[1]);
(array = s)[2] = array[2] ^ (fkey[3 + keyoff] | s[3]);
(array = s)[3] = array[3] ^ leftRotate(fkey[2 + keyoff] & s[2], 1);
}
private void setKey(bool forEncryption, byte[] key)
{
uint[] array = new uint[8];
uint[] array2 = new uint[4];
uint[] array3 = new uint[4];
uint[] array4 = new uint[4];
switch (key.Length)
{
case 16:
_keyis128 = true;
array[0] = bytes2uint(key, 0);
array[1] = bytes2uint(key, 4);
array[2] = bytes2uint(key, 8);
array[3] = bytes2uint(key, 12);
array[4] = (array[5] = (array[6] = (array[7] = 0u)));
break;
case 24:
array[0] = bytes2uint(key, 0);
array[1] = bytes2uint(key, 4);
array[2] = bytes2uint(key, 8);
array[3] = bytes2uint(key, 12);
array[4] = bytes2uint(key, 16);
array[5] = bytes2uint(key, 20);
array[6] = ~array[4];
array[7] = ~array[5];
_keyis128 = false;
break;
case 32:
array[0] = bytes2uint(key, 0);
array[1] = bytes2uint(key, 4);
array[2] = bytes2uint(key, 8);
array[3] = bytes2uint(key, 12);
array[4] = bytes2uint(key, 16);
array[5] = bytes2uint(key, 20);
array[6] = bytes2uint(key, 24);
array[7] = bytes2uint(key, 28);
_keyis128 = false;
break;
default:
throw new ArgumentException("key sizes are only 16/24/32 bytes.");
}
for (int i = 0; i < 4; i++)
{
array2[i] = array[i] ^ array[i + 4];
}
camelliaF2(array2, SIGMA, 0);
for (int j = 0; j < 4; j++)
{
uint[] array6;
uint[] array5 = (array6 = array2);
int num = j;
nint num2 = num;
array5[num] = array6[num2] ^ array[j];
}
camelliaF2(array2, SIGMA, 4);
if (_keyis128)
{
if (forEncryption)
{
kw[0] = array[0];
kw[1] = array[1];
kw[2] = array[2];
kw[3] = array[3];
roldq(15, array, 0, subkey, 4);
roldq(30, array, 0, subkey, 12);
roldq(15, array, 0, array4, 0);
subkey[18] = array4[2];
subkey[19] = array4[3];
roldq(17, array, 0, ke, 4);
roldq(17, array, 0, subkey, 24);
roldq(17, array, 0, subkey, 32);
subkey[0] = array2[0];
subkey[1] = array2[1];
subkey[2] = array2[2];
subkey[3] = array2[3];
roldq(15, array2, 0, subkey, 8);
roldq(15, array2, 0, ke, 0);
roldq(15, array2, 0, array4, 0);
subkey[16] = array4[0];
subkey[17] = array4[1];
roldq(15, array2, 0, subkey, 20);
roldqo32(34, array2, 0, subkey, 28);
roldq(17, array2, 0, kw, 4);
}
else
{
kw[4] = array[0];
kw[5] = array[1];
kw[6] = array[2];
kw[7] = array[3];
decroldq(15, array, 0, subkey, 28);
decroldq(30, array, 0, subkey, 20);
decroldq(15, array, 0, array4, 0);
subkey[16] = array4[0];
subkey[17] = array4[1];
decroldq(17, array, 0, ke, 0);
decroldq(17, array, 0, subkey, 8);
decroldq(17, array, 0, subkey, 0);
subkey[34] = array2[0];
subkey[35] = array2[1];
subkey[32] = array2[2];
subkey[33] = array2[3];
decroldq(15, array2, 0, subkey, 24);
decroldq(15, array2, 0, ke, 4);
decroldq(15, array2, 0, array4, 0);
subkey[18] = array4[2];
subkey[19] = array4[3];
decroldq(15, array2, 0, subkey, 12);
decroldqo32(34, array2, 0, subkey, 4);
roldq(17, array2, 0, kw, 0);
}
return;
}
for (int k = 0; k < 4; k++)
{
array3[k] = array2[k] ^ array[k + 4];
}
camelliaF2(array3, SIGMA, 8);
if (forEncryption)
{
kw[0] = array[0];
kw[1] = array[1];
kw[2] = array[2];
kw[3] = array[3];
roldqo32(45, array, 0, subkey, 16);
roldq(15, array, 0, ke, 4);
roldq(17, array, 0, subkey, 32);
roldqo32(34, array, 0, subkey, 44);
roldq(15, array, 4, subkey, 4);
roldq(15, array, 4, ke, 0);
roldq(30, array, 4, subkey, 24);
roldqo32(34, array, 4, subkey, 36);
roldq(15, array2, 0, subkey, 8);
roldq(30, array2, 0, subkey, 20);
ke[8] = array2[1];
ke[9] = array2[2];
ke[10] = array2[3];
ke[11] = array2[0];
roldqo32(49, array2, 0, subkey, 40);
subkey[0] = array3[0];
subkey[1] = array3[1];
subkey[2] = array3[2];
subkey[3] = array3[3];
roldq(30, array3, 0, subkey, 12);
roldq(30, array3, 0, subkey, 28);
roldqo32(51, array3, 0, kw, 4);
}
else
{
kw[4] = array[0];
kw[5] = array[1];
kw[6] = array[2];
kw[7] = array[3];
decroldqo32(45, array, 0, subkey, 28);
decroldq(15, array, 0, ke, 4);
decroldq(17, array, 0, subkey, 12);
decroldqo32(34, array, 0, subkey, 0);
decroldq(15, array, 4, subkey, 40);
decroldq(15, array, 4, ke, 8);
decroldq(30, array, 4, subkey, 20);
decroldqo32(34, array, 4, subkey, 8);
decroldq(15, array2, 0, subkey, 36);
decroldq(30, array2, 0, subkey, 24);
ke[2] = array2[1];
ke[3] = array2[2];
ke[0] = array2[3];
ke[1] = array2[0];
decroldqo32(49, array2, 0, subkey, 4);
subkey[46] = array3[0];
subkey[47] = array3[1];
subkey[44] = array3[2];
subkey[45] = array3[3];
decroldq(30, array3, 0, subkey, 32);
decroldq(30, array3, 0, subkey, 16);
roldqo32(51, array3, 0, kw, 0);
}
}
private int processBlock128(byte[] input, int inOff, byte[] output, int outOff)
{
uint[] array2;
for (int i = 0; i < 4; i++)
{
state[i] = bytes2uint(input, inOff + i * 4);
uint[] array = (array2 = state);
int num = i;
nint num2 = num;
array[num] = array2[num2] ^ kw[i];
}
camelliaF2(state, subkey, 0);
camelliaF2(state, subkey, 4);
camelliaF2(state, subkey, 8);
camelliaFLs(state, ke, 0);
camelliaF2(state, subkey, 12);
camelliaF2(state, subkey, 16);
camelliaF2(state, subkey, 20);
camelliaFLs(state, ke, 4);
camelliaF2(state, subkey, 24);
camelliaF2(state, subkey, 28);
camelliaF2(state, subkey, 32);
(array2 = state)[2] = array2[2] ^ kw[4];
(array2 = state)[3] = array2[3] ^ kw[5];
(array2 = state)[0] = array2[0] ^ kw[6];
(array2 = state)[1] = array2[1] ^ kw[7];
uint2bytes(state[2], output, outOff);
uint2bytes(state[3], output, outOff + 4);
uint2bytes(state[0], output, outOff + 8);
uint2bytes(state[1], output, outOff + 12);
return 16;
}
private int processBlock192or256(byte[] input, int inOff, byte[] output, int outOff)
{
uint[] array2;
for (int i = 0; i < 4; i++)
{
state[i] = bytes2uint(input, inOff + i * 4);
uint[] array = (array2 = state);
int num = i;
nint num2 = num;
array[num] = array2[num2] ^ kw[i];
}
camelliaF2(state, subkey, 0);
camelliaF2(state, subkey, 4);
camelliaF2(state, subkey, 8);
camelliaFLs(state, ke, 0);
camelliaF2(state, subkey, 12);
camelliaF2(state, subkey, 16);
camelliaF2(state, subkey, 20);
camelliaFLs(state, ke, 4);
camelliaF2(state, subkey, 24);
camelliaF2(state, subkey, 28);
camelliaF2(state, subkey, 32);
camelliaFLs(state, ke, 8);
camelliaF2(state, subkey, 36);
camelliaF2(state, subkey, 40);
camelliaF2(state, subkey, 44);
(array2 = state)[2] = array2[2] ^ kw[4];
(array2 = state)[3] = array2[3] ^ kw[5];
(array2 = state)[0] = array2[0] ^ kw[6];
(array2 = state)[1] = array2[1] ^ kw[7];
uint2bytes(state[2], output, outOff);
uint2bytes(state[3], output, outOff + 4);
uint2bytes(state[0], output, outOff + 8);
uint2bytes(state[1], output, outOff + 12);
return 16;
}
public CamelliaLightEngine()
{
initialised = false;
}
public virtual int GetBlockSize()
{
return 16;
}
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
if (!(parameters is KeyParameter))
{
throw new ArgumentException("only simple KeyParameter expected.");
}
setKey(forEncryption, ((KeyParameter)parameters).GetKey());
initialised = true;
}
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
{
if (!initialised)
{
throw new InvalidOperationException("Camellia engine not initialised");
}
Check.DataLength(input, inOff, 16, "input buffer too short");
Check.OutputLength(output, outOff, 16, "output buffer too short");
if (_keyis128)
{
return processBlock128(input, inOff, output, outOff);
}
return processBlock192or256(input, inOff, output, outOff);
}
public virtual void Reset()
{
}
}

View File

@@ -0,0 +1,9 @@
namespace Org.BouncyCastle.Crypto.Engines;
public class CamelliaWrapEngine : Rfc3394WrapEngine
{
public CamelliaWrapEngine()
: base(new CamelliaEngine())
{
}
}

View File

@@ -0,0 +1,585 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Utilities;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class Cast5Engine : IBlockCipher
{
private const int BLOCK_SIZE = 8;
private static readonly uint[] S1 = new uint[256]
{
821772500u, 2678128395u, 1810681135u, 1059425402u, 505495343u, 2617265619u, 1610868032u, 3483355465u, 3218386727u, 2294005173u,
3791863952u, 2563806837u, 1852023008u, 365126098u, 3269944861u, 584384398u, 677919599u, 3229601881u, 4280515016u, 2002735330u,
1136869587u, 3744433750u, 2289869850u, 2731719981u, 2714362070u, 879511577u, 1639411079u, 575934255u, 717107937u, 2857637483u,
576097850u, 2731753936u, 1725645000u, 2810460463u, 5111599u, 767152862u, 2543075244u, 1251459544u, 1383482551u, 3052681127u,
3089939183u, 3612463449u, 1878520045u, 1510570527u, 2189125840u, 2431448366u, 582008916u, 3163445557u, 1265446783u, 1354458274u,
3529918736u, 3202711853u, 3073581712u, 3912963487u, 3029263377u, 1275016285u, 4249207360u, 2905708351u, 3304509486u, 1442611557u,
3585198765u, 2712415662u, 2731849581u, 3248163920u, 2283946226u, 208555832u, 2766454743u, 1331405426u, 1447828783u, 3315356441u,
3108627284u, 2957404670u, 2981538698u, 3339933917u, 1669711173u, 286233437u, 1465092821u, 1782121619u, 3862771680u, 710211251u,
980974943u, 1651941557u, 430374111u, 2051154026u, 704238805u, 4128970897u, 3144820574u, 2857402727u, 948965521u, 3333752299u,
2227686284u, 718756367u, 2269778983u, 2731643755u, 718440111u, 2857816721u, 3616097120u, 1113355533u, 2478022182u, 410092745u,
1811985197u, 1944238868u, 2696854588u, 1415722873u, 1682284203u, 1060277122u, 1998114690u, 1503841958u, 82706478u, 2315155686u,
1068173648u, 845149890u, 2167947013u, 1768146376u, 1993038550u, 3566826697u, 3390574031u, 940016341u, 3355073782u, 2328040721u,
904371731u, 1205506512u, 4094660742u, 2816623006u, 825647681u, 85914773u, 2857843460u, 1249926541u, 1417871568u, 3287612u,
3211054559u, 3126306446u, 1975924523u, 1353700161u, 2814456437u, 2438597621u, 1800716203u, 722146342u, 2873936343u, 1151126914u,
4160483941u, 2877670899u, 458611604u, 2866078500u, 3483680063u, 770352098u, 2652916994u, 3367839148u, 3940505011u, 3585973912u,
3809620402u, 718646636u, 2504206814u, 2914927912u, 3631288169u, 2857486607u, 2860018678u, 575749918u, 2857478043u, 718488780u,
2069512688u, 3548183469u, 453416197u, 1106044049u, 3032691430u, 52586708u, 3378514636u, 3459808877u, 3211506028u, 1785789304u,
218356169u, 3571399134u, 3759170522u, 1194783844u, 1523787992u, 3007827094u, 1975193539u, 2555452411u, 1341901877u, 3045838698u,
3776907964u, 3217423946u, 2802510864u, 2889438986u, 1057244207u, 1636348243u, 3761863214u, 1462225785u, 2632663439u, 481089165u,
718503062u, 24497053u, 3332243209u, 3344655856u, 3655024856u, 3960371065u, 1195698900u, 2971415156u, 3710176158u, 2115785917u,
4027663609u, 3525578417u, 2524296189u, 2745972565u, 3564906415u, 1372086093u, 1452307862u, 2780501478u, 1476592880u, 3389271281u,
18495466u, 2378148571u, 901398090u, 891748256u, 3279637769u, 3157290713u, 2560960102u, 1447622437u, 4284372637u, 216884176u,
2086908623u, 1879786977u, 3588903153u, 2242455666u, 2938092967u, 3559082096u, 2810645491u, 758861177u, 1121993112u, 215018983u,
642190776u, 4169236812u, 1196255959u, 2081185372u, 3508738393u, 941322904u, 4124243163u, 2877523539u, 1848581667u, 2205260958u,
3180453958u, 2589345134u, 3694731276u, 550028657u, 2519456284u, 3789985535u, 2973870856u, 2093648313u, 443148163u, 46942275u,
2734146937u, 1117713533u, 1115362972u, 1523183689u, 3717140224u, 1551984063u
};
private static readonly uint[] S2 = new uint[256]
{
522195092u, 4010518363u, 1776537470u, 960447360u, 4267822970u, 4005896314u, 1435016340u, 1929119313u, 2913464185u, 1310552629u,
3579470798u, 3724818106u, 2579771631u, 1594623892u, 417127293u, 2715217907u, 2696228731u, 1508390405u, 3994398868u, 3925858569u,
3695444102u, 4019471449u, 3129199795u, 3770928635u, 3520741761u, 990456497u, 4187484609u, 2783367035u, 21106139u, 3840405339u,
631373633u, 3783325702u, 532942976u, 396095098u, 3548038825u, 4267192484u, 2564721535u, 2011709262u, 2039648873u, 620404603u,
3776170075u, 2898526339u, 3612357925u, 4159332703u, 1645490516u, 223693667u, 1567101217u, 3362177881u, 1029951347u, 3470931136u,
3570957959u, 1550265121u, 119497089u, 972513919u, 907948164u, 3840628539u, 1613718692u, 3594177948u, 465323573u, 2659255085u,
654439692u, 2575596212u, 2699288441u, 3127702412u, 277098644u, 624404830u, 4100943870u, 2717858591u, 546110314u, 2403699828u,
3655377447u, 1321679412u, 4236791657u, 1045293279u, 4010672264u, 895050893u, 2319792268u, 494945126u, 1914543101u, 2777056443u,
3894764339u, 2219737618u, 311263384u, 4275257268u, 3458730721u, 669096869u, 3584475730u, 3835122877u, 3319158237u, 3949359204u,
2005142349u, 2713102337u, 2228954793u, 3769984788u, 569394103u, 3855636576u, 1425027204u, 108000370u, 2736431443u, 3671869269u,
3043122623u, 1750473702u, 2211081108u, 762237499u, 3972989403u, 2798899386u, 3061857628u, 2943854345u, 867476300u, 964413654u,
1591880597u, 1594774276u, 2179821409u, 552026980u, 3026064248u, 3726140315u, 2283577634u, 3110545105u, 2152310760u, 582474363u,
1582640421u, 1383256631u, 2043843868u, 3322775884u, 1217180674u, 463797851u, 2763038571u, 480777679u, 2718707717u, 2289164131u,
3118346187u, 214354409u, 200212307u, 3810608407u, 3025414197u, 2674075964u, 3997296425u, 1847405948u, 1342460550u, 510035443u,
4080271814u, 815934613u, 833030224u, 1620250387u, 1945732119u, 2703661145u, 3966000196u, 1388869545u, 3456054182u, 2687178561u,
2092620194u, 562037615u, 1356438536u, 3409922145u, 3261847397u, 1688467115u, 2150901366u, 631725691u, 3840332284u, 549916902u,
3455104640u, 394546491u, 837744717u, 2114462948u, 751520235u, 2221554606u, 2415360136u, 3999097078u, 2063029875u, 803036379u,
2702586305u, 821456707u, 3019566164u, 360699898u, 4018502092u, 3511869016u, 3677355358u, 2402471449u, 812317050u, 49299192u,
2570164949u, 3259169295u, 2816732080u, 3331213574u, 3101303564u, 2156015656u, 3705598920u, 3546263921u, 143268808u, 3200304480u,
1638124008u, 3165189453u, 3341807610u, 578956953u, 2193977524u, 3638120073u, 2333881532u, 807278310u, 658237817u, 2969561766u,
1641658566u, 11683945u, 3086995007u, 148645947u, 1138423386u, 4158756760u, 1981396783u, 2401016740u, 3699783584u, 380097457u,
2680394679u, 2803068651u, 3334260286u, 441530178u, 4016580796u, 1375954390u, 761952171u, 891809099u, 2183123478u, 157052462u,
3683840763u, 1592404427u, 341349109u, 2438483839u, 1417898363u, 644327628u, 2233032776u, 2353769706u, 2201510100u, 220455161u,
1815641738u, 182899273u, 2995019788u, 3627381533u, 3702638151u, 2890684138u, 1052606899u, 588164016u, 1681439879u, 4038439418u,
2405343923u, 4229449282u, 167996282u, 1336969661u, 1688053129u, 2739224926u, 1543734051u, 1046297529u, 1138201970u, 2121126012u,
115334942u, 1819067631u, 1902159161u, 1941945968u, 2206692869u, 1159982321u
};
private static readonly uint[] S3 = new uint[256]
{
2381300288u, 637164959u, 3952098751u, 3893414151u, 1197506559u, 916448331u, 2350892612u, 2932787856u, 3199334847u, 4009478890u,
3905886544u, 1373570990u, 2450425862u, 4037870920u, 3778841987u, 2456817877u, 286293407u, 124026297u, 3001279700u, 1028597854u,
3115296800u, 4208886496u, 2691114635u, 2188540206u, 1430237888u, 1218109995u, 3572471700u, 308166588u, 570424558u, 2187009021u,
2455094765u, 307733056u, 1310360322u, 3135275007u, 1384269543u, 2388071438u, 863238079u, 2359263624u, 2801553128u, 3380786597u,
2831162807u, 1470087780u, 1728663345u, 4072488799u, 1090516929u, 532123132u, 2389430977u, 1132193179u, 2578464191u, 3051079243u,
1670234342u, 1434557849u, 2711078940u, 1241591150u, 3314043432u, 3435360113u, 3091448339u, 1812415473u, 2198440252u, 267246943u,
796911696u, 3619716990u, 38830015u, 1526438404u, 2806502096u, 374413614u, 2943401790u, 1489179520u, 1603809326u, 1920779204u,
168801282u, 260042626u, 2358705581u, 1563175598u, 2397674057u, 1356499128u, 2217211040u, 514611088u, 2037363785u, 2186468373u,
4022173083u, 2792511869u, 2913485016u, 1173701892u, 4200428547u, 3896427269u, 1334932762u, 2455136706u, 602925377u, 2835607854u,
1613172210u, 41346230u, 2499634548u, 2457437618u, 2188827595u, 41386358u, 4172255629u, 1313404830u, 2405527007u, 3801973774u,
2217704835u, 873260488u, 2528884354u, 2478092616u, 4012915883u, 2555359016u, 2006953883u, 2463913485u, 575479328u, 2218240648u,
2099895446u, 660001756u, 2341502190u, 3038761536u, 3888151779u, 3848713377u, 3286851934u, 1022894237u, 1620365795u, 3449594689u,
1551255054u, 15374395u, 3570825345u, 4249311020u, 4151111129u, 3181912732u, 310226346u, 1133119310u, 530038928u, 136043402u,
2476768958u, 3107506709u, 2544909567u, 1036173560u, 2367337196u, 1681395281u, 1758231547u, 3641649032u, 306774401u, 1575354324u,
3716085866u, 1990386196u, 3114533736u, 2455606671u, 1262092282u, 3124342505u, 2768229131u, 4210529083u, 1833535011u, 423410938u,
660763973u, 2187129978u, 1639812000u, 3508421329u, 3467445492u, 310289298u, 272797111u, 2188552562u, 2456863912u, 310240523u,
677093832u, 1013118031u, 901835429u, 3892695601u, 1116285435u, 3036471170u, 1337354835u, 243122523u, 520626091u, 277223598u,
4244441197u, 4194248841u, 1766575121u, 594173102u, 316590669u, 742362309u, 3536858622u, 4176435350u, 3838792410u, 2501204839u,
1229605004u, 3115755532u, 1552908988u, 2312334149u, 979407927u, 3959474601u, 1148277331u, 176638793u, 3614686272u, 2083809052u,
40992502u, 1340822838u, 2731552767u, 3535757508u, 3560899520u, 1354035053u, 122129617u, 7215240u, 2732932949u, 3118912700u,
2718203926u, 2539075635u, 3609230695u, 3725561661u, 1928887091u, 2882293555u, 1988674909u, 2063640240u, 2491088897u, 1459647954u,
4189817080u, 2302804382u, 1113892351u, 2237858528u, 1927010603u, 4002880361u, 1856122846u, 1594404395u, 2944033133u, 3855189863u,
3474975698u, 1643104450u, 4054590833u, 3431086530u, 1730235576u, 2984608721u, 3084664418u, 2131803598u, 4178205752u, 267404349u,
1617849798u, 1616132681u, 1462223176u, 736725533u, 2327058232u, 551665188u, 2945899023u, 1749386277u, 2575514597u, 1611482493u,
674206544u, 2201269090u, 3642560800u, 728599968u, 1680547377u, 2620414464u, 1388111496u, 453204106u, 4156223445u, 1094905244u,
2754698257u, 2201108165u, 3757000246u, 2704524545u, 3922940700u, 3996465027u
};
private static readonly uint[] S4 = new uint[256]
{
2645754912u, 532081118u, 2814278639u, 3530793624u, 1246723035u, 1689095255u, 2236679235u, 4194438865u, 2116582143u, 3859789411u,
157234593u, 2045505824u, 4245003587u, 1687664561u, 4083425123u, 605965023u, 672431967u, 1336064205u, 3376611392u, 214114848u,
4258466608u, 3232053071u, 489488601u, 605322005u, 3998028058u, 264917351u, 1912574028u, 756637694u, 436560991u, 202637054u,
135989450u, 85393697u, 2152923392u, 3896401662u, 2895836408u, 2145855233u, 3535335007u, 115294817u, 3147733898u, 1922296357u,
3464822751u, 4117858305u, 1037454084u, 2725193275u, 2127856640u, 1417604070u, 1148013728u, 1827919605u, 642362335u, 2929772533u,
909348033u, 1346338451u, 3547799649u, 297154785u, 1917849091u, 4161712827u, 2883604526u, 3968694238u, 1469521537u, 3780077382u,
3375584256u, 1763717519u, 136166297u, 4290970789u, 1295325189u, 2134727907u, 2798151366u, 1566297257u, 3672928234u, 2677174161u,
2672173615u, 965822077u, 2780786062u, 289653839u, 1133871874u, 3491843819u, 35685304u, 1068898316u, 418943774u, 672553190u,
642281022u, 2346158704u, 1954014401u, 3037126780u, 4079815205u, 2030668546u, 3840588673u, 672283427u, 1776201016u, 359975446u,
3750173538u, 555499703u, 2769985273u, 1324923u, 69110472u, 152125443u, 3176785106u, 3822147285u, 1340634837u, 798073664u,
1434183902u, 15393959u, 216384236u, 1303690150u, 3881221631u, 3711134124u, 3960975413u, 106373927u, 2578434224u, 1455997841u,
1801814300u, 1578393881u, 1854262133u, 3188178946u, 3258078583u, 2302670060u, 1539295533u, 3505142565u, 3078625975u, 2372746020u,
549938159u, 3278284284u, 2620926080u, 181285381u, 2865321098u, 3970029511u, 68876850u, 488006234u, 1728155692u, 2608167508u,
836007927u, 2435231793u, 919367643u, 3339422534u, 3655756360u, 1457871481u, 40520939u, 1380155135u, 797931188u, 234455205u,
2255801827u, 3990488299u, 397000196u, 739833055u, 3077865373u, 2871719860u, 4022553888u, 772369276u, 390177364u, 3853951029u,
557662966u, 740064294u, 1640166671u, 1699928825u, 3535942136u, 622006121u, 3625353122u, 68743880u, 1742502u, 219489963u,
1664179233u, 1577743084u, 1236991741u, 410585305u, 2366487942u, 823226535u, 1050371084u, 3426619607u, 3586839478u, 212779912u,
4147118561u, 1819446015u, 1911218849u, 530248558u, 3486241071u, 3252585495u, 2886188651u, 3410272728u, 2342195030u, 20547779u,
2982490058u, 3032363469u, 3631753222u, 312714466u, 1870521650u, 1493008054u, 3491686656u, 615382978u, 4103671749u, 2534517445u,
1932181u, 2196105170u, 278426614u, 6369430u, 3274544417u, 2913018367u, 697336853u, 2143000447u, 2946413531u, 701099306u,
1558357093u, 2805003052u, 3500818408u, 2321334417u, 3567135975u, 216290473u, 3591032198u, 23009561u, 1996984579u, 3735042806u,
2024298078u, 3739440863u, 569400510u, 2339758983u, 3016033873u, 3097871343u, 3639523026u, 3844324983u, 3256173865u, 795471839u,
2951117563u, 4101031090u, 4091603803u, 3603732598u, 971261452u, 534414648u, 428311343u, 3389027175u, 2844869880u, 694888862u,
1227866773u, 2456207019u, 3043454569u, 2614353370u, 3749578031u, 3676663836u, 459166190u, 4132644070u, 1794958188u, 51825668u,
2252611902u, 3084671440u, 2036672799u, 3436641603u, 1099053433u, 2469121526u, 3059204941u, 1323291266u, 2061838604u, 1018778475u,
2233344254u, 2553501054u, 334295216u, 3556750194u, 1065731521u, 183467730u
};
private static readonly uint[] S5 = new uint[256]
{
2127105028u, 745436345u, 2601412319u, 2788391185u, 3093987327u, 500390133u, 1155374404u, 389092991u, 150729210u, 3891597772u,
3523549952u, 1935325696u, 716645080u, 946045387u, 2901812282u, 1774124410u, 3869435775u, 4039581901u, 3293136918u, 3438657920u,
948246080u, 363898952u, 3867875531u, 1286266623u, 1598556673u, 68334250u, 630723836u, 1104211938u, 1312863373u, 613332731u,
2377784574u, 1101634306u, 441780740u, 3129959883u, 1917973735u, 2510624549u, 3238456535u, 2544211978u, 3308894634u, 1299840618u,
4076074851u, 1756332096u, 3977027158u, 297047435u, 3790297736u, 2265573040u, 3621810518u, 1311375015u, 1667687725u, 47300608u,
3299642885u, 2474112369u, 201668394u, 1468347890u, 576830978u, 3594690761u, 3742605952u, 1958042578u, 1747032512u, 3558991340u,
1408974056u, 3366841779u, 682131401u, 1033214337u, 1545599232u, 4265137049u, 206503691u, 103024618u, 2855227313u, 1337551222u,
2428998917u, 2963842932u, 4015366655u, 3852247746u, 2796956967u, 3865723491u, 3747938335u, 247794022u, 3755824572u, 702416469u,
2434691994u, 397379957u, 851939612u, 2314769512u, 218229120u, 1380406772u, 62274761u, 214451378u, 3170103466u, 2276210409u,
3845813286u, 28563499u, 446592073u, 1693330814u, 3453727194u, 29968656u, 3093872512u, 220656637u, 2470637031u, 77972100u,
1667708854u, 1358280214u, 4064765667u, 2395616961u, 325977563u, 4277240721u, 4220025399u, 3605526484u, 3355147721u, 811859167u,
3069544926u, 3962126810u, 652502677u, 3075892249u, 4132761541u, 3498924215u, 1217549313u, 3250244479u, 3858715919u, 3053989961u,
1538642152u, 2279026266u, 2875879137u, 574252750u, 3324769229u, 2651358713u, 1758150215u, 141295887u, 2719868960u, 3515574750u,
4093007735u, 4194485238u, 1082055363u, 3417560400u, 395511885u, 2966884026u, 179534037u, 3646028556u, 3738688086u, 1092926436u,
2496269142u, 257381841u, 3772900718u, 1636087230u, 1477059743u, 2499234752u, 3811018894u, 2675660129u, 3285975680u, 90732309u,
1684827095u, 1150307763u, 1723134115u, 3237045386u, 1769919919u, 1240018934u, 815675215u, 750138730u, 2239792499u, 1234303040u,
1995484674u, 138143821u, 675421338u, 1145607174u, 1936608440u, 3238603024u, 2345230278u, 2105974004u, 323969391u, 779555213u,
3004902369u, 2861610098u, 1017501463u, 2098600890u, 2628620304u, 2940611490u, 2682542546u, 1171473753u, 3656571411u, 3687208071u,
4091869518u, 393037935u, 159126506u, 1662887367u, 1147106178u, 391545844u, 3452332695u, 1891500680u, 3016609650u, 1851642611u,
546529401u, 1167818917u, 3194020571u, 2848076033u, 3953471836u, 575554290u, 475796850u, 4134673196u, 450035699u, 2351251534u,
844027695u, 1080539133u, 86184846u, 1554234488u, 3692025454u, 1972511363u, 2018339607u, 1491841390u, 1141460869u, 1061690759u,
4244549243u, 2008416118u, 2351104703u, 2868147542u, 1598468138u, 722020353u, 1027143159u, 212344630u, 1387219594u, 1725294528u,
3745187956u, 2500153616u, 458938280u, 4129215917u, 1828119673u, 544571780u, 3503225445u, 2297937496u, 1241802790u, 267843827u,
2694610800u, 1397140384u, 1558801448u, 3782667683u, 1806446719u, 929573330u, 2234912681u, 400817706u, 616011623u, 4121520928u,
3603768725u, 1761550015u, 1968522284u, 4053731006u, 4192232858u, 4005120285u, 872482584u, 3140537016u, 3894607381u, 2287405443u,
1963876937u, 3663887957u, 1584857000u, 2975024454u, 1833426440u, 4025083860u
};
private static readonly uint[] S6 = new uint[256]
{
4143615901u, 749497569u, 1285769319u, 3795025788u, 2514159847u, 23610292u, 3974978748u, 844452780u, 3214870880u, 3751928557u,
2213566365u, 1676510905u, 448177848u, 3730751033u, 4086298418u, 2307502392u, 871450977u, 3222878141u, 4110862042u, 3831651966u,
2735270553u, 1310974780u, 2043402188u, 1218528103u, 2736035353u, 4274605013u, 2702448458u, 3936360550u, 2693061421u, 162023535u,
2827510090u, 687910808u, 23484817u, 3784910947u, 3371371616u, 779677500u, 3503626546u, 3473927188u, 4157212626u, 3500679282u,
4248902014u, 2466621104u, 3899384794u, 1958663117u, 925738300u, 1283408968u, 3669349440u, 1840910019u, 137959847u, 2679828185u,
1239142320u, 1315376211u, 1547541505u, 1690155329u, 739140458u, 3128809933u, 3933172616u, 3876308834u, 905091803u, 1548541325u,
4040461708u, 3095483362u, 144808038u, 451078856u, 676114313u, 2861728291u, 2469707347u, 993665471u, 373509091u, 2599041286u,
4025009006u, 4170239449u, 2149739950u, 3275793571u, 3749616649u, 2794760199u, 1534877388u, 572371878u, 2590613551u, 1753320020u,
3467782511u, 1405125690u, 4270405205u, 633333386u, 3026356924u, 3475123903u, 632057672u, 2846462855u, 1404951397u, 3882875879u,
3915906424u, 195638627u, 2385783745u, 3902872553u, 1233155085u, 3355999740u, 2380578713u, 2702246304u, 2144565621u, 3663341248u,
3894384975u, 2502479241u, 4248018925u, 3094885567u, 1594115437u, 572884632u, 3385116731u, 767645374u, 1331858858u, 1475698373u,
3793881790u, 3532746431u, 1321687957u, 619889600u, 1121017241u, 3440213920u, 2070816767u, 2833025776u, 1933951238u, 4095615791u,
890643334u, 3874130214u, 859025556u, 360630002u, 925594799u, 1764062180u, 3920222280u, 4078305929u, 979562269u, 2810700344u,
4087740022u, 1949714515u, 546639971u, 1165388173u, 3069891591u, 1495988560u, 922170659u, 1291546247u, 2107952832u, 1813327274u,
3406010024u, 3306028637u, 4241950635u, 153207855u, 2313154747u, 1608695416u, 1150242611u, 1967526857u, 721801357u, 1220138373u,
3691287617u, 3356069787u, 2112743302u, 3281662835u, 1111556101u, 1778980689u, 250857638u, 2298507990u, 673216130u, 2846488510u,
3207751581u, 3562756981u, 3008625920u, 3417367384u, 2198807050u, 529510932u, 3547516680u, 3426503187u, 2364944742u, 102533054u,
2294910856u, 1617093527u, 1204784762u, 3066581635u, 1019391227u, 1069574518u, 1317995090u, 1691889997u, 3661132003u, 510022745u,
3238594800u, 1362108837u, 1817929911u, 2184153760u, 805817662u, 1953603311u, 3699844737u, 120799444u, 2118332377u, 207536705u,
2282301548u, 4120041617u, 145305846u, 2508124933u, 3086745533u, 3261524335u, 1877257368u, 2977164480u, 3160454186u, 2503252186u,
4221677074u, 759945014u, 254147243u, 2767453419u, 3801518371u, 629083197u, 2471014217u, 907280572u, 3900796746u, 940896768u,
2751021123u, 2625262786u, 3161476951u, 3661752313u, 3260732218u, 1425318020u, 2977912069u, 1496677566u, 3988592072u, 2140652971u,
3126511541u, 3069632175u, 977771578u, 1392695845u, 1698528874u, 1411812681u, 1369733098u, 1343739227u, 3620887944u, 1142123638u,
67414216u, 3102056737u, 3088749194u, 1626167401u, 2546293654u, 3941374235u, 697522451u, 33404913u, 143560186u, 2595682037u,
994885535u, 1247667115u, 3859094837u, 2699155541u, 3547024625u, 4114935275u, 2968073508u, 3199963069u, 2732024527u, 1237921620u,
951448369u, 1898488916u, 1211705605u, 2790989240u, 2233243581u, 3598044975u
};
private static readonly uint[] S7 = new uint[256]
{
2246066201u, 858518887u, 1714274303u, 3485882003u, 713916271u, 2879113490u, 3730835617u, 539548191u, 36158695u, 1298409750u,
419087104u, 1358007170u, 749914897u, 2989680476u, 1261868530u, 2995193822u, 2690628854u, 3443622377u, 3780124940u, 3796824509u,
2976433025u, 4259637129u, 1551479000u, 512490819u, 1296650241u, 951993153u, 2436689437u, 2460458047u, 144139966u, 3136204276u,
310820559u, 3068840729u, 643875328u, 1969602020u, 1680088954u, 2185813161u, 3283332454u, 672358534u, 198762408u, 896343282u,
276269502u, 3014846926u, 84060815u, 197145886u, 376173866u, 3943890818u, 3813173521u, 3545068822u, 1316698879u, 1598252827u,
2633424951u, 1233235075u, 859989710u, 2358460855u, 3503838400u, 3409603720u, 1203513385u, 1193654839u, 2792018475u, 2060853022u,
207403770u, 1144516871u, 3068631394u, 1121114134u, 177607304u, 3785736302u, 326409831u, 1929119770u, 2983279095u, 4183308101u,
3474579288u, 3200513878u, 3228482096u, 119610148u, 1170376745u, 3378393471u, 3163473169u, 951863017u, 3337026068u, 3135789130u,
2907618374u, 1183797387u, 2015970143u, 4045674555u, 2182986399u, 2952138740u, 3928772205u, 384012900u, 2454997643u, 10178499u,
2879818989u, 2596892536u, 111523738u, 2995089006u, 451689641u, 3196290696u, 235406569u, 1441906262u, 3890558523u, 3013735005u,
4158569349u, 1644036924u, 376726067u, 1006849064u, 3664579700u, 2041234796u, 1021632941u, 1374734338u, 2566452058u, 371631263u,
4007144233u, 490221539u, 206551450u, 3140638584u, 1053219195u, 1853335209u, 3412429660u, 3562156231u, 735133835u, 1623211703u,
3104214392u, 2738312436u, 4096837757u, 3366392578u, 3110964274u, 3956598718u, 3196820781u, 2038037254u, 3877786376u, 2339753847u,
300912036u, 3766732888u, 2372630639u, 1516443558u, 4200396704u, 1574567987u, 4069441456u, 4122592016u, 2699739776u, 146372218u,
2748961456u, 2043888151u, 35287437u, 2596680554u, 655490400u, 1132482787u, 110692520u, 1031794116u, 2188192751u, 1324057718u,
1217253157u, 919197030u, 686247489u, 3261139658u, 1028237775u, 3135486431u, 3059715558u, 2460921700u, 986174950u, 2661811465u,
4062904701u, 2752986992u, 3709736643u, 367056889u, 1353824391u, 731860949u, 1650113154u, 1778481506u, 784341916u, 357075625u,
3608602432u, 1074092588u, 2480052770u, 3811426202u, 92751289u, 877911070u, 3600361838u, 1231880047u, 480201094u, 3756190983u,
3094495953u, 434011822u, 87971354u, 363687820u, 1717726236u, 1901380172u, 3926403882u, 2481662265u, 400339184u, 1490350766u,
2661455099u, 1389319756u, 2558787174u, 784598401u, 1983468483u, 30828846u, 3550527752u, 2716276238u, 3841122214u, 1765724805u,
1955612312u, 1277890269u, 1333098070u, 1564029816u, 2704417615u, 1026694237u, 3287671188u, 1260819201u, 3349086767u, 1016692350u,
1582273796u, 1073413053u, 1995943182u, 694588404u, 1025494639u, 3323872702u, 3551898420u, 4146854327u, 453260480u, 1316140391u,
1435673405u, 3038941953u, 3486689407u, 1622062951u, 403978347u, 817677117u, 950059133u, 4246079218u, 3278066075u, 1486738320u,
1417279718u, 481875527u, 2549965225u, 3933690356u, 760697757u, 1452955855u, 3897451437u, 1177426808u, 1702951038u, 4085348628u,
2447005172u, 1084371187u, 3516436277u, 3068336338u, 1073369276u, 1027665953u, 3284188590u, 1230553676u, 1368340146u, 2226246512u,
267243139u, 2274220762u, 4070734279u, 2497715176u, 2423353163u, 2504755875u
};
private static readonly uint[] S8 = new uint[256]
{
3793104909u, 3151888380u, 2817252029u, 895778965u, 2005530807u, 3871412763u, 237245952u, 86829237u, 296341424u, 3851759377u,
3974600970u, 2475086196u, 709006108u, 1994621201u, 2972577594u, 937287164u, 3734691505u, 168608556u, 3189338153u, 2225080640u,
3139713551u, 3033610191u, 3025041904u, 77524477u, 185966941u, 1208824168u, 2344345178u, 1721625922u, 3354191921u, 1066374631u,
1927223579u, 1971335949u, 2483503697u, 1551748602u, 2881383779u, 2856329572u, 3003241482u, 48746954u, 1398218158u, 2050065058u,
313056748u, 4255789917u, 393167848u, 1912293076u, 940740642u, 3465845460u, 3091687853u, 2522601570u, 2197016661u, 1727764327u,
364383054u, 492521376u, 1291706479u, 3264136376u, 1474851438u, 1685747964u, 2575719748u, 1619776915u, 1814040067u, 970743798u,
1561002147u, 2925768690u, 2123093554u, 1880132620u, 3151188041u, 697884420u, 2550985770u, 2607674513u, 2659114323u, 110200136u,
1489731079u, 997519150u, 1378877361u, 3527870668u, 478029773u, 2766872923u, 1022481122u, 431258168u, 1112503832u, 897933369u,
2635587303u, 669726182u, 3383752315u, 918222264u, 163866573u, 3246985393u, 3776823163u, 114105080u, 1903216136u, 761148244u,
3571337562u, 1690750982u, 3166750252u, 1037045171u, 1888456500u, 2010454850u, 642736655u, 616092351u, 365016990u, 1185228132u,
4174898510u, 1043824992u, 2023083429u, 2241598885u, 3863320456u, 3279669087u, 3674716684u, 108438443u, 2132974366u, 830746235u,
606445527u, 4173263986u, 2204105912u, 1844756978u, 2532684181u, 4245352700u, 2969441100u, 3796921661u, 1335562986u, 4061524517u,
2720232303u, 2679424040u, 634407289u, 885462008u, 3294724487u, 3933892248u, 2094100220u, 339117932u, 4048830727u, 3202280980u,
1458155303u, 2689246273u, 1022871705u, 2464987878u, 3714515309u, 353796843u, 2822958815u, 4256850100u, 4052777845u, 551748367u,
618185374u, 3778635579u, 4020649912u, 1904685140u, 3069366075u, 2670879810u, 3407193292u, 2954511620u, 4058283405u, 2219449317u,
3135758300u, 1120655984u, 3447565834u, 1474845562u, 3577699062u, 550456716u, 3466908712u, 2043752612u, 881257467u, 869518812u,
2005220179u, 938474677u, 3305539448u, 3850417126u, 1315485940u, 3318264702u, 226533026u, 965733244u, 321539988u, 1136104718u,
804158748u, 573969341u, 3708209826u, 937399083u, 3290727049u, 2901666755u, 1461057207u, 4013193437u, 4066861423u, 3242773476u,
2421326174u, 1581322155u, 3028952165u, 786071460u, 3900391652u, 3918438532u, 1485433313u, 4023619836u, 3708277595u, 3678951060u,
953673138u, 1467089153u, 1930354364u, 1533292819u, 2492563023u, 1346121658u, 1685000834u, 1965281866u, 3765933717u, 4190206607u,
2052792609u, 3515332758u, 690371149u, 3125873887u, 2180283551u, 2903598061u, 3933952357u, 436236910u, 289419410u, 14314871u,
1242357089u, 2904507907u, 1616633776u, 2666382180u, 585885352u, 3471299210u, 2699507360u, 1432659641u, 277164553u, 3354103607u,
770115018u, 2303809295u, 3741942315u, 3177781868u, 2853364978u, 2269453327u, 3774259834u, 987383833u, 1290892879u, 225909803u,
1741533526u, 890078084u, 1496906255u, 1111072499u, 916028167u, 243534141u, 1252605537u, 2204162171u, 531204876u, 290011180u,
3916834213u, 102027703u, 237315147u, 209093447u, 1486785922u, 220223953u, 2758195998u, 4175039106u, 82940208u, 3127791296u,
2569425252u, 518464269u, 1353887104u, 3941492737u, 2377294467u, 3935040926u
};
internal static readonly int MAX_ROUNDS = 16;
internal static readonly int RED_ROUNDS = 12;
private int[] _Kr = new int[17];
private uint[] _Km = new uint[17];
private bool _encrypting;
private byte[] _workingKey;
private int _rounds = MAX_ROUNDS;
public virtual string AlgorithmName => "CAST5";
public virtual bool IsPartialBlockOkay => false;
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
if (!(parameters is KeyParameter))
{
throw new ArgumentException("Invalid parameter passed to " + AlgorithmName + " init - " + Platform.GetTypeName(parameters));
}
_encrypting = forEncryption;
_workingKey = ((KeyParameter)parameters).GetKey();
SetKey(_workingKey);
}
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
{
int blockSize = GetBlockSize();
if (_workingKey == null)
{
throw new InvalidOperationException(AlgorithmName + " not initialised");
}
Check.DataLength(input, inOff, blockSize, "input buffer too short");
Check.OutputLength(output, outOff, blockSize, "output buffer too short");
if (_encrypting)
{
return EncryptBlock(input, inOff, output, outOff);
}
return DecryptBlock(input, inOff, output, outOff);
}
public virtual void Reset()
{
}
public virtual int GetBlockSize()
{
return 8;
}
internal virtual void SetKey(byte[] key)
{
if (key.Length < 11)
{
_rounds = RED_ROUNDS;
}
int[] array = new int[16];
int[] array2 = new int[16];
for (int i = 0; i < key.Length; i++)
{
array2[i] = key[i] & 0xFF;
}
uint num = IntsTo32bits(array2, 0);
uint num2 = IntsTo32bits(array2, 4);
uint num3 = IntsTo32bits(array2, 8);
uint num4 = IntsTo32bits(array2, 12);
uint inData = num ^ S5[array2[13]] ^ S6[array2[15]] ^ S7[array2[12]] ^ S8[array2[14]] ^ S7[array2[8]];
Bits32ToInts(inData, array, 0);
uint inData2 = num3 ^ S5[array[0]] ^ S6[array[2]] ^ S7[array[1]] ^ S8[array[3]] ^ S8[array2[10]];
Bits32ToInts(inData2, array, 4);
uint inData3 = num4 ^ S5[array[7]] ^ S6[array[6]] ^ S7[array[5]] ^ S8[array[4]] ^ S5[array2[9]];
Bits32ToInts(inData3, array, 8);
uint inData4 = num2 ^ S5[array[10]] ^ S6[array[9]] ^ S7[array[11]] ^ S8[array[8]] ^ S6[array2[11]];
Bits32ToInts(inData4, array, 12);
_Km[1] = S5[array[8]] ^ S6[array[9]] ^ S7[array[7]] ^ S8[array[6]] ^ S5[array[2]];
_Km[2] = S5[array[10]] ^ S6[array[11]] ^ S7[array[5]] ^ S8[array[4]] ^ S6[array[6]];
_Km[3] = S5[array[12]] ^ S6[array[13]] ^ S7[array[3]] ^ S8[array[2]] ^ S7[array[9]];
_Km[4] = S5[array[14]] ^ S6[array[15]] ^ S7[array[1]] ^ S8[array[0]] ^ S8[array[12]];
inData = IntsTo32bits(array, 0);
inData2 = IntsTo32bits(array, 4);
inData3 = IntsTo32bits(array, 8);
inData4 = IntsTo32bits(array, 12);
num = inData3 ^ S5[array[5]] ^ S6[array[7]] ^ S7[array[4]] ^ S8[array[6]] ^ S7[array[0]];
Bits32ToInts(num, array2, 0);
num2 = inData ^ S5[array2[0]] ^ S6[array2[2]] ^ S7[array2[1]] ^ S8[array2[3]] ^ S8[array[2]];
Bits32ToInts(num2, array2, 4);
num3 = inData2 ^ S5[array2[7]] ^ S6[array2[6]] ^ S7[array2[5]] ^ S8[array2[4]] ^ S5[array[1]];
Bits32ToInts(num3, array2, 8);
num4 = inData4 ^ S5[array2[10]] ^ S6[array2[9]] ^ S7[array2[11]] ^ S8[array2[8]] ^ S6[array[3]];
Bits32ToInts(num4, array2, 12);
_Km[5] = S5[array2[3]] ^ S6[array2[2]] ^ S7[array2[12]] ^ S8[array2[13]] ^ S5[array2[8]];
_Km[6] = S5[array2[1]] ^ S6[array2[0]] ^ S7[array2[14]] ^ S8[array2[15]] ^ S6[array2[13]];
_Km[7] = S5[array2[7]] ^ S6[array2[6]] ^ S7[array2[8]] ^ S8[array2[9]] ^ S7[array2[3]];
_Km[8] = S5[array2[5]] ^ S6[array2[4]] ^ S7[array2[10]] ^ S8[array2[11]] ^ S8[array2[7]];
num = IntsTo32bits(array2, 0);
num2 = IntsTo32bits(array2, 4);
num3 = IntsTo32bits(array2, 8);
num4 = IntsTo32bits(array2, 12);
inData = num ^ S5[array2[13]] ^ S6[array2[15]] ^ S7[array2[12]] ^ S8[array2[14]] ^ S7[array2[8]];
Bits32ToInts(inData, array, 0);
inData2 = num3 ^ S5[array[0]] ^ S6[array[2]] ^ S7[array[1]] ^ S8[array[3]] ^ S8[array2[10]];
Bits32ToInts(inData2, array, 4);
inData3 = num4 ^ S5[array[7]] ^ S6[array[6]] ^ S7[array[5]] ^ S8[array[4]] ^ S5[array2[9]];
Bits32ToInts(inData3, array, 8);
inData4 = num2 ^ S5[array[10]] ^ S6[array[9]] ^ S7[array[11]] ^ S8[array[8]] ^ S6[array2[11]];
Bits32ToInts(inData4, array, 12);
_Km[9] = S5[array[3]] ^ S6[array[2]] ^ S7[array[12]] ^ S8[array[13]] ^ S5[array[9]];
_Km[10] = S5[array[1]] ^ S6[array[0]] ^ S7[array[14]] ^ S8[array[15]] ^ S6[array[12]];
_Km[11] = S5[array[7]] ^ S6[array[6]] ^ S7[array[8]] ^ S8[array[9]] ^ S7[array[2]];
_Km[12] = S5[array[5]] ^ S6[array[4]] ^ S7[array[10]] ^ S8[array[11]] ^ S8[array[6]];
inData = IntsTo32bits(array, 0);
inData2 = IntsTo32bits(array, 4);
inData3 = IntsTo32bits(array, 8);
inData4 = IntsTo32bits(array, 12);
num = inData3 ^ S5[array[5]] ^ S6[array[7]] ^ S7[array[4]] ^ S8[array[6]] ^ S7[array[0]];
Bits32ToInts(num, array2, 0);
num2 = inData ^ S5[array2[0]] ^ S6[array2[2]] ^ S7[array2[1]] ^ S8[array2[3]] ^ S8[array[2]];
Bits32ToInts(num2, array2, 4);
num3 = inData2 ^ S5[array2[7]] ^ S6[array2[6]] ^ S7[array2[5]] ^ S8[array2[4]] ^ S5[array[1]];
Bits32ToInts(num3, array2, 8);
num4 = inData4 ^ S5[array2[10]] ^ S6[array2[9]] ^ S7[array2[11]] ^ S8[array2[8]] ^ S6[array[3]];
Bits32ToInts(num4, array2, 12);
_Km[13] = S5[array2[8]] ^ S6[array2[9]] ^ S7[array2[7]] ^ S8[array2[6]] ^ S5[array2[3]];
_Km[14] = S5[array2[10]] ^ S6[array2[11]] ^ S7[array2[5]] ^ S8[array2[4]] ^ S6[array2[7]];
_Km[15] = S5[array2[12]] ^ S6[array2[13]] ^ S7[array2[3]] ^ S8[array2[2]] ^ S7[array2[8]];
_Km[16] = S5[array2[14]] ^ S6[array2[15]] ^ S7[array2[1]] ^ S8[array2[0]] ^ S8[array2[13]];
num = IntsTo32bits(array2, 0);
num2 = IntsTo32bits(array2, 4);
num3 = IntsTo32bits(array2, 8);
num4 = IntsTo32bits(array2, 12);
inData = num ^ S5[array2[13]] ^ S6[array2[15]] ^ S7[array2[12]] ^ S8[array2[14]] ^ S7[array2[8]];
Bits32ToInts(inData, array, 0);
inData2 = num3 ^ S5[array[0]] ^ S6[array[2]] ^ S7[array[1]] ^ S8[array[3]] ^ S8[array2[10]];
Bits32ToInts(inData2, array, 4);
inData3 = num4 ^ S5[array[7]] ^ S6[array[6]] ^ S7[array[5]] ^ S8[array[4]] ^ S5[array2[9]];
Bits32ToInts(inData3, array, 8);
inData4 = num2 ^ S5[array[10]] ^ S6[array[9]] ^ S7[array[11]] ^ S8[array[8]] ^ S6[array2[11]];
Bits32ToInts(inData4, array, 12);
_Kr[1] = (int)((S5[array[8]] ^ S6[array[9]] ^ S7[array[7]] ^ S8[array[6]] ^ S5[array[2]]) & 0x1F);
_Kr[2] = (int)((S5[array[10]] ^ S6[array[11]] ^ S7[array[5]] ^ S8[array[4]] ^ S6[array[6]]) & 0x1F);
_Kr[3] = (int)((S5[array[12]] ^ S6[array[13]] ^ S7[array[3]] ^ S8[array[2]] ^ S7[array[9]]) & 0x1F);
_Kr[4] = (int)((S5[array[14]] ^ S6[array[15]] ^ S7[array[1]] ^ S8[array[0]] ^ S8[array[12]]) & 0x1F);
inData = IntsTo32bits(array, 0);
inData2 = IntsTo32bits(array, 4);
inData3 = IntsTo32bits(array, 8);
inData4 = IntsTo32bits(array, 12);
num = inData3 ^ S5[array[5]] ^ S6[array[7]] ^ S7[array[4]] ^ S8[array[6]] ^ S7[array[0]];
Bits32ToInts(num, array2, 0);
num2 = inData ^ S5[array2[0]] ^ S6[array2[2]] ^ S7[array2[1]] ^ S8[array2[3]] ^ S8[array[2]];
Bits32ToInts(num2, array2, 4);
num3 = inData2 ^ S5[array2[7]] ^ S6[array2[6]] ^ S7[array2[5]] ^ S8[array2[4]] ^ S5[array[1]];
Bits32ToInts(num3, array2, 8);
num4 = inData4 ^ S5[array2[10]] ^ S6[array2[9]] ^ S7[array2[11]] ^ S8[array2[8]] ^ S6[array[3]];
Bits32ToInts(num4, array2, 12);
_Kr[5] = (int)((S5[array2[3]] ^ S6[array2[2]] ^ S7[array2[12]] ^ S8[array2[13]] ^ S5[array2[8]]) & 0x1F);
_Kr[6] = (int)((S5[array2[1]] ^ S6[array2[0]] ^ S7[array2[14]] ^ S8[array2[15]] ^ S6[array2[13]]) & 0x1F);
_Kr[7] = (int)((S5[array2[7]] ^ S6[array2[6]] ^ S7[array2[8]] ^ S8[array2[9]] ^ S7[array2[3]]) & 0x1F);
_Kr[8] = (int)((S5[array2[5]] ^ S6[array2[4]] ^ S7[array2[10]] ^ S8[array2[11]] ^ S8[array2[7]]) & 0x1F);
num = IntsTo32bits(array2, 0);
num2 = IntsTo32bits(array2, 4);
num3 = IntsTo32bits(array2, 8);
num4 = IntsTo32bits(array2, 12);
inData = num ^ S5[array2[13]] ^ S6[array2[15]] ^ S7[array2[12]] ^ S8[array2[14]] ^ S7[array2[8]];
Bits32ToInts(inData, array, 0);
inData2 = num3 ^ S5[array[0]] ^ S6[array[2]] ^ S7[array[1]] ^ S8[array[3]] ^ S8[array2[10]];
Bits32ToInts(inData2, array, 4);
inData3 = num4 ^ S5[array[7]] ^ S6[array[6]] ^ S7[array[5]] ^ S8[array[4]] ^ S5[array2[9]];
Bits32ToInts(inData3, array, 8);
inData4 = num2 ^ S5[array[10]] ^ S6[array[9]] ^ S7[array[11]] ^ S8[array[8]] ^ S6[array2[11]];
Bits32ToInts(inData4, array, 12);
_Kr[9] = (int)((S5[array[3]] ^ S6[array[2]] ^ S7[array[12]] ^ S8[array[13]] ^ S5[array[9]]) & 0x1F);
_Kr[10] = (int)((S5[array[1]] ^ S6[array[0]] ^ S7[array[14]] ^ S8[array[15]] ^ S6[array[12]]) & 0x1F);
_Kr[11] = (int)((S5[array[7]] ^ S6[array[6]] ^ S7[array[8]] ^ S8[array[9]] ^ S7[array[2]]) & 0x1F);
_Kr[12] = (int)((S5[array[5]] ^ S6[array[4]] ^ S7[array[10]] ^ S8[array[11]] ^ S8[array[6]]) & 0x1F);
inData = IntsTo32bits(array, 0);
inData2 = IntsTo32bits(array, 4);
inData3 = IntsTo32bits(array, 8);
inData4 = IntsTo32bits(array, 12);
num = inData3 ^ S5[array[5]] ^ S6[array[7]] ^ S7[array[4]] ^ S8[array[6]] ^ S7[array[0]];
Bits32ToInts(num, array2, 0);
num2 = inData ^ S5[array2[0]] ^ S6[array2[2]] ^ S7[array2[1]] ^ S8[array2[3]] ^ S8[array[2]];
Bits32ToInts(num2, array2, 4);
num3 = inData2 ^ S5[array2[7]] ^ S6[array2[6]] ^ S7[array2[5]] ^ S8[array2[4]] ^ S5[array[1]];
Bits32ToInts(num3, array2, 8);
num4 = inData4 ^ S5[array2[10]] ^ S6[array2[9]] ^ S7[array2[11]] ^ S8[array2[8]] ^ S6[array[3]];
Bits32ToInts(num4, array2, 12);
_Kr[13] = (int)((S5[array2[8]] ^ S6[array2[9]] ^ S7[array2[7]] ^ S8[array2[6]] ^ S5[array2[3]]) & 0x1F);
_Kr[14] = (int)((S5[array2[10]] ^ S6[array2[11]] ^ S7[array2[5]] ^ S8[array2[4]] ^ S6[array2[7]]) & 0x1F);
_Kr[15] = (int)((S5[array2[12]] ^ S6[array2[13]] ^ S7[array2[3]] ^ S8[array2[2]] ^ S7[array2[8]]) & 0x1F);
_Kr[16] = (int)((S5[array2[14]] ^ S6[array2[15]] ^ S7[array2[1]] ^ S8[array2[0]] ^ S8[array2[13]]) & 0x1F);
}
internal virtual int EncryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex)
{
uint l = Pack.BE_To_UInt32(src, srcIndex);
uint r = Pack.BE_To_UInt32(src, srcIndex + 4);
uint[] array = new uint[2];
CAST_Encipher(l, r, array);
Pack.UInt32_To_BE(array[0], dst, dstIndex);
Pack.UInt32_To_BE(array[1], dst, dstIndex + 4);
return 8;
}
internal virtual int DecryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex)
{
uint l = Pack.BE_To_UInt32(src, srcIndex);
uint r = Pack.BE_To_UInt32(src, srcIndex + 4);
uint[] array = new uint[2];
CAST_Decipher(l, r, array);
Pack.UInt32_To_BE(array[0], dst, dstIndex);
Pack.UInt32_To_BE(array[1], dst, dstIndex + 4);
return 8;
}
internal static uint F1(uint D, uint Kmi, int Kri)
{
uint num = Kmi + D;
num = (num << Kri) | (num >> 32 - Kri);
return (S1[(num >> 24) & 0xFF] ^ S2[(num >> 16) & 0xFF]) - S3[(num >> 8) & 0xFF] + S4[num & 0xFF];
}
internal static uint F2(uint D, uint Kmi, int Kri)
{
uint num = Kmi ^ D;
num = (num << Kri) | (num >> 32 - Kri);
return (S1[(num >> 24) & 0xFF] - S2[(num >> 16) & 0xFF] + S3[(num >> 8) & 0xFF]) ^ S4[num & 0xFF];
}
internal static uint F3(uint D, uint Kmi, int Kri)
{
uint num = Kmi - D;
num = (num << Kri) | (num >> 32 - Kri);
return ((S1[(num >> 24) & 0xFF] + S2[(num >> 16) & 0xFF]) ^ S3[(num >> 8) & 0xFF]) - S4[num & 0xFF];
}
internal void CAST_Encipher(uint L0, uint R0, uint[] result)
{
uint num = L0;
uint num2 = R0;
uint num3 = L0;
uint num4 = R0;
for (int i = 1; i <= _rounds; i++)
{
num = num3;
num2 = num4;
num3 = num2;
switch (i)
{
case 1:
case 4:
case 7:
case 10:
case 13:
case 16:
num4 = num ^ F1(num2, _Km[i], _Kr[i]);
break;
case 2:
case 5:
case 8:
case 11:
case 14:
num4 = num ^ F2(num2, _Km[i], _Kr[i]);
break;
case 3:
case 6:
case 9:
case 12:
case 15:
num4 = num ^ F3(num2, _Km[i], _Kr[i]);
break;
}
}
result[0] = num4;
result[1] = num3;
}
internal void CAST_Decipher(uint L16, uint R16, uint[] result)
{
uint num = L16;
uint num2 = R16;
uint num3 = L16;
uint num4 = R16;
for (int num5 = _rounds; num5 > 0; num5--)
{
num = num3;
num2 = num4;
num3 = num2;
switch (num5)
{
case 1:
case 4:
case 7:
case 10:
case 13:
case 16:
num4 = num ^ F1(num2, _Km[num5], _Kr[num5]);
break;
case 2:
case 5:
case 8:
case 11:
case 14:
num4 = num ^ F2(num2, _Km[num5], _Kr[num5]);
break;
case 3:
case 6:
case 9:
case 12:
case 15:
num4 = num ^ F3(num2, _Km[num5], _Kr[num5]);
break;
}
}
result[0] = num4;
result[1] = num3;
}
internal static void Bits32ToInts(uint inData, int[] b, int offset)
{
b[offset + 3] = (int)(inData & 0xFF);
b[offset + 2] = (int)((inData >> 8) & 0xFF);
b[offset + 1] = (int)((inData >> 16) & 0xFF);
b[offset] = (int)((inData >> 24) & 0xFF);
}
internal static uint IntsTo32bits(int[] b, int i)
{
return (uint)(((b[i] & 0xFF) << 24) | ((b[i + 1] & 0xFF) << 16) | ((b[i + 2] & 0xFF) << 8) | (b[i + 3] & 0xFF));
}
}

View File

@@ -0,0 +1,163 @@
using Org.BouncyCastle.Crypto.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public sealed class Cast6Engine : Cast5Engine
{
private const int ROUNDS = 12;
private const int BLOCK_SIZE = 16;
private int[] _Kr = new int[48];
private uint[] _Km = new uint[48];
private int[] _Tr = new int[192];
private uint[] _Tm = new uint[192];
private uint[] _workingKey = new uint[8];
public override string AlgorithmName => "CAST6";
public override void Reset()
{
}
public override int GetBlockSize()
{
return 16;
}
internal override void SetKey(byte[] key)
{
uint num = 1518500249u;
uint num2 = 1859775393u;
int num3 = 19;
int num4 = 17;
for (int i = 0; i < 24; i++)
{
for (int j = 0; j < 8; j++)
{
_Tm[i * 8 + j] = num;
num += num2;
_Tr[i * 8 + j] = num3;
num3 = (num3 + num4) & 0x1F;
}
}
byte[] array = new byte[64];
key.CopyTo(array, 0);
for (int k = 0; k < 8; k++)
{
_workingKey[k] = Pack.BE_To_UInt32(array, k * 4);
}
for (int l = 0; l < 12; l++)
{
int num5 = l * 2 * 8;
uint[] workingKey;
(workingKey = _workingKey)[6] = workingKey[6] ^ Cast5Engine.F1(_workingKey[7], _Tm[num5], _Tr[num5]);
(workingKey = _workingKey)[5] = workingKey[5] ^ Cast5Engine.F2(_workingKey[6], _Tm[num5 + 1], _Tr[num5 + 1]);
(workingKey = _workingKey)[4] = workingKey[4] ^ Cast5Engine.F3(_workingKey[5], _Tm[num5 + 2], _Tr[num5 + 2]);
(workingKey = _workingKey)[3] = workingKey[3] ^ Cast5Engine.F1(_workingKey[4], _Tm[num5 + 3], _Tr[num5 + 3]);
(workingKey = _workingKey)[2] = workingKey[2] ^ Cast5Engine.F2(_workingKey[3], _Tm[num5 + 4], _Tr[num5 + 4]);
(workingKey = _workingKey)[1] = workingKey[1] ^ Cast5Engine.F3(_workingKey[2], _Tm[num5 + 5], _Tr[num5 + 5]);
(workingKey = _workingKey)[0] = workingKey[0] ^ Cast5Engine.F1(_workingKey[1], _Tm[num5 + 6], _Tr[num5 + 6]);
(workingKey = _workingKey)[7] = workingKey[7] ^ Cast5Engine.F2(_workingKey[0], _Tm[num5 + 7], _Tr[num5 + 7]);
num5 = (l * 2 + 1) * 8;
(workingKey = _workingKey)[6] = workingKey[6] ^ Cast5Engine.F1(_workingKey[7], _Tm[num5], _Tr[num5]);
(workingKey = _workingKey)[5] = workingKey[5] ^ Cast5Engine.F2(_workingKey[6], _Tm[num5 + 1], _Tr[num5 + 1]);
(workingKey = _workingKey)[4] = workingKey[4] ^ Cast5Engine.F3(_workingKey[5], _Tm[num5 + 2], _Tr[num5 + 2]);
(workingKey = _workingKey)[3] = workingKey[3] ^ Cast5Engine.F1(_workingKey[4], _Tm[num5 + 3], _Tr[num5 + 3]);
(workingKey = _workingKey)[2] = workingKey[2] ^ Cast5Engine.F2(_workingKey[3], _Tm[num5 + 4], _Tr[num5 + 4]);
(workingKey = _workingKey)[1] = workingKey[1] ^ Cast5Engine.F3(_workingKey[2], _Tm[num5 + 5], _Tr[num5 + 5]);
(workingKey = _workingKey)[0] = workingKey[0] ^ Cast5Engine.F1(_workingKey[1], _Tm[num5 + 6], _Tr[num5 + 6]);
(workingKey = _workingKey)[7] = workingKey[7] ^ Cast5Engine.F2(_workingKey[0], _Tm[num5 + 7], _Tr[num5 + 7]);
_Kr[l * 4] = (int)(_workingKey[0] & 0x1F);
_Kr[l * 4 + 1] = (int)(_workingKey[2] & 0x1F);
_Kr[l * 4 + 2] = (int)(_workingKey[4] & 0x1F);
_Kr[l * 4 + 3] = (int)(_workingKey[6] & 0x1F);
_Km[l * 4] = _workingKey[7];
_Km[l * 4 + 1] = _workingKey[5];
_Km[l * 4 + 2] = _workingKey[3];
_Km[l * 4 + 3] = _workingKey[1];
}
}
internal override int EncryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex)
{
uint a = Pack.BE_To_UInt32(src, srcIndex);
uint b = Pack.BE_To_UInt32(src, srcIndex + 4);
uint c = Pack.BE_To_UInt32(src, srcIndex + 8);
uint d = Pack.BE_To_UInt32(src, srcIndex + 12);
uint[] array = new uint[4];
CAST_Encipher(a, b, c, d, array);
Pack.UInt32_To_BE(array[0], dst, dstIndex);
Pack.UInt32_To_BE(array[1], dst, dstIndex + 4);
Pack.UInt32_To_BE(array[2], dst, dstIndex + 8);
Pack.UInt32_To_BE(array[3], dst, dstIndex + 12);
return 16;
}
internal override int DecryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex)
{
uint a = Pack.BE_To_UInt32(src, srcIndex);
uint b = Pack.BE_To_UInt32(src, srcIndex + 4);
uint c = Pack.BE_To_UInt32(src, srcIndex + 8);
uint d = Pack.BE_To_UInt32(src, srcIndex + 12);
uint[] array = new uint[4];
CAST_Decipher(a, b, c, d, array);
Pack.UInt32_To_BE(array[0], dst, dstIndex);
Pack.UInt32_To_BE(array[1], dst, dstIndex + 4);
Pack.UInt32_To_BE(array[2], dst, dstIndex + 8);
Pack.UInt32_To_BE(array[3], dst, dstIndex + 12);
return 16;
}
private void CAST_Encipher(uint A, uint B, uint C, uint D, uint[] result)
{
for (int i = 0; i < 6; i++)
{
int num = i * 4;
C ^= Cast5Engine.F1(D, _Km[num], _Kr[num]);
B ^= Cast5Engine.F2(C, _Km[num + 1], _Kr[num + 1]);
A ^= Cast5Engine.F3(B, _Km[num + 2], _Kr[num + 2]);
D ^= Cast5Engine.F1(A, _Km[num + 3], _Kr[num + 3]);
}
for (int j = 6; j < 12; j++)
{
int num2 = j * 4;
D ^= Cast5Engine.F1(A, _Km[num2 + 3], _Kr[num2 + 3]);
A ^= Cast5Engine.F3(B, _Km[num2 + 2], _Kr[num2 + 2]);
B ^= Cast5Engine.F2(C, _Km[num2 + 1], _Kr[num2 + 1]);
C ^= Cast5Engine.F1(D, _Km[num2], _Kr[num2]);
}
result[0] = A;
result[1] = B;
result[2] = C;
result[3] = D;
}
private void CAST_Decipher(uint A, uint B, uint C, uint D, uint[] result)
{
for (int i = 0; i < 6; i++)
{
int num = (11 - i) * 4;
C ^= Cast5Engine.F1(D, _Km[num], _Kr[num]);
B ^= Cast5Engine.F2(C, _Km[num + 1], _Kr[num + 1]);
A ^= Cast5Engine.F3(B, _Km[num + 2], _Kr[num + 2]);
D ^= Cast5Engine.F1(A, _Km[num + 3], _Kr[num + 3]);
}
for (int j = 6; j < 12; j++)
{
int num2 = (11 - j) * 4;
D ^= Cast5Engine.F1(A, _Km[num2 + 3], _Kr[num2 + 3]);
A ^= Cast5Engine.F3(B, _Km[num2 + 2], _Kr[num2 + 2]);
B ^= Cast5Engine.F2(C, _Km[num2 + 1], _Kr[num2 + 1]);
C ^= Cast5Engine.F1(D, _Km[num2], _Kr[num2]);
}
result[0] = A;
result[1] = B;
result[2] = C;
result[3] = D;
}
}

View File

@@ -0,0 +1,45 @@
using System;
using Org.BouncyCastle.Crypto.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class ChaCha7539Engine : Salsa20Engine
{
public override string AlgorithmName => "ChaCha7539" + rounds;
protected override int NonceSize => 12;
protected override void AdvanceCounter()
{
uint[] array;
if (((array = engineState)[12] = array[12] + 1) == 0)
{
throw new InvalidOperationException("attempt to increase counter past 2^32.");
}
}
protected override void ResetCounter()
{
engineState[12] = 0u;
}
protected override void SetKey(byte[] keyBytes, byte[] ivBytes)
{
if (keyBytes != null)
{
if (keyBytes.Length != 32)
{
throw new ArgumentException(AlgorithmName + " requires 256 bit key");
}
PackTauOrSigma(keyBytes.Length, engineState, 0);
Pack.LE_To_UInt32(keyBytes, 0, engineState, 4, 8);
}
Pack.LE_To_UInt32(ivBytes, 0, engineState, 13, 3);
}
protected override void GenerateKeyStream(byte[] output)
{
ChaChaEngine.ChachaCore(rounds, engineState, x);
Pack.UInt32_To_LE(x, output, 0);
}
}

View File

@@ -0,0 +1,168 @@
using System;
using Org.BouncyCastle.Crypto.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class ChaChaEngine : Salsa20Engine
{
public override string AlgorithmName => "ChaCha" + rounds;
public ChaChaEngine()
{
}
public ChaChaEngine(int rounds)
: base(rounds)
{
}
protected override void AdvanceCounter()
{
uint[] array;
if (((array = engineState)[12] = array[12] + 1) == 0)
{
(array = engineState)[13] = array[13] + 1;
}
}
protected override void ResetCounter()
{
engineState[12] = (engineState[13] = 0u);
}
protected override void SetKey(byte[] keyBytes, byte[] ivBytes)
{
if (keyBytes != null)
{
if (keyBytes.Length != 16 && keyBytes.Length != 32)
{
throw new ArgumentException(AlgorithmName + " requires 128 bit or 256 bit key");
}
PackTauOrSigma(keyBytes.Length, engineState, 0);
Pack.LE_To_UInt32(keyBytes, 0, engineState, 4, 4);
Pack.LE_To_UInt32(keyBytes, keyBytes.Length - 16, engineState, 8, 4);
}
Pack.LE_To_UInt32(ivBytes, 0, engineState, 14, 2);
}
protected override void GenerateKeyStream(byte[] output)
{
ChachaCore(rounds, engineState, x);
Pack.UInt32_To_LE(x, output, 0);
}
internal static void ChachaCore(int rounds, uint[] input, uint[] x)
{
if (input.Length != 16)
{
throw new ArgumentException();
}
if (x.Length != 16)
{
throw new ArgumentException();
}
if (rounds % 2 != 0)
{
throw new ArgumentException("Number of rounds must be even");
}
uint num = input[0];
uint num2 = input[1];
uint num3 = input[2];
uint num4 = input[3];
uint num5 = input[4];
uint num6 = input[5];
uint num7 = input[6];
uint num8 = input[7];
uint num9 = input[8];
uint num10 = input[9];
uint num11 = input[10];
uint num12 = input[11];
uint num13 = input[12];
uint num14 = input[13];
uint num15 = input[14];
uint num16 = input[15];
for (int num17 = rounds; num17 > 0; num17 -= 2)
{
num += num5;
num13 = Salsa20Engine.R(num13 ^ num, 16);
num9 += num13;
num5 = Salsa20Engine.R(num5 ^ num9, 12);
num += num5;
num13 = Salsa20Engine.R(num13 ^ num, 8);
num9 += num13;
num5 = Salsa20Engine.R(num5 ^ num9, 7);
num2 += num6;
num14 = Salsa20Engine.R(num14 ^ num2, 16);
num10 += num14;
num6 = Salsa20Engine.R(num6 ^ num10, 12);
num2 += num6;
num14 = Salsa20Engine.R(num14 ^ num2, 8);
num10 += num14;
num6 = Salsa20Engine.R(num6 ^ num10, 7);
num3 += num7;
num15 = Salsa20Engine.R(num15 ^ num3, 16);
num11 += num15;
num7 = Salsa20Engine.R(num7 ^ num11, 12);
num3 += num7;
num15 = Salsa20Engine.R(num15 ^ num3, 8);
num11 += num15;
num7 = Salsa20Engine.R(num7 ^ num11, 7);
num4 += num8;
num16 = Salsa20Engine.R(num16 ^ num4, 16);
num12 += num16;
num8 = Salsa20Engine.R(num8 ^ num12, 12);
num4 += num8;
num16 = Salsa20Engine.R(num16 ^ num4, 8);
num12 += num16;
num8 = Salsa20Engine.R(num8 ^ num12, 7);
num += num6;
num16 = Salsa20Engine.R(num16 ^ num, 16);
num11 += num16;
num6 = Salsa20Engine.R(num6 ^ num11, 12);
num += num6;
num16 = Salsa20Engine.R(num16 ^ num, 8);
num11 += num16;
num6 = Salsa20Engine.R(num6 ^ num11, 7);
num2 += num7;
num13 = Salsa20Engine.R(num13 ^ num2, 16);
num12 += num13;
num7 = Salsa20Engine.R(num7 ^ num12, 12);
num2 += num7;
num13 = Salsa20Engine.R(num13 ^ num2, 8);
num12 += num13;
num7 = Salsa20Engine.R(num7 ^ num12, 7);
num3 += num8;
num14 = Salsa20Engine.R(num14 ^ num3, 16);
num9 += num14;
num8 = Salsa20Engine.R(num8 ^ num9, 12);
num3 += num8;
num14 = Salsa20Engine.R(num14 ^ num3, 8);
num9 += num14;
num8 = Salsa20Engine.R(num8 ^ num9, 7);
num4 += num5;
num15 = Salsa20Engine.R(num15 ^ num4, 16);
num10 += num15;
num5 = Salsa20Engine.R(num5 ^ num10, 12);
num4 += num5;
num15 = Salsa20Engine.R(num15 ^ num4, 8);
num10 += num15;
num5 = Salsa20Engine.R(num5 ^ num10, 7);
}
x[0] = num + input[0];
x[1] = num2 + input[1];
x[2] = num3 + input[2];
x[3] = num4 + input[3];
x[4] = num5 + input[4];
x[5] = num6 + input[5];
x[6] = num7 + input[6];
x[7] = num8 + input[7];
x[8] = num9 + input[8];
x[9] = num10 + input[9];
x[10] = num11 + input[10];
x[11] = num12 + input[11];
x[12] = num13 + input[12];
x[13] = num14 + input[13];
x[14] = num15 + input[14];
x[15] = num16 + input[15];
}
}

View File

@@ -0,0 +1,81 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class DesEdeEngine : DesEngine
{
private int[] workingKey1;
private int[] workingKey2;
private int[] workingKey3;
private bool forEncryption;
public override string AlgorithmName => "DESede";
public override void Init(bool forEncryption, ICipherParameters parameters)
{
if (!(parameters is KeyParameter))
{
throw new ArgumentException("invalid parameter passed to DESede init - " + Platform.GetTypeName(parameters));
}
byte[] key = ((KeyParameter)parameters).GetKey();
if (key.Length != 24 && key.Length != 16)
{
throw new ArgumentException("key size must be 16 or 24 bytes.");
}
this.forEncryption = forEncryption;
byte[] array = new byte[8];
Array.Copy(key, 0, array, 0, array.Length);
workingKey1 = DesEngine.GenerateWorkingKey(forEncryption, array);
byte[] array2 = new byte[8];
Array.Copy(key, 8, array2, 0, array2.Length);
workingKey2 = DesEngine.GenerateWorkingKey(!forEncryption, array2);
if (key.Length == 24)
{
byte[] array3 = new byte[8];
Array.Copy(key, 16, array3, 0, array3.Length);
workingKey3 = DesEngine.GenerateWorkingKey(forEncryption, array3);
}
else
{
workingKey3 = workingKey1;
}
}
public override int GetBlockSize()
{
return 8;
}
public override int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
{
if (workingKey1 == null)
{
throw new InvalidOperationException("DESede engine not initialised");
}
Check.DataLength(input, inOff, 8, "input buffer too short");
Check.OutputLength(output, outOff, 8, "output buffer too short");
byte[] array = new byte[8];
if (forEncryption)
{
DesEngine.DesFunc(workingKey1, input, inOff, array, 0);
DesEngine.DesFunc(workingKey2, array, 0, array, 0);
DesEngine.DesFunc(workingKey3, array, 0, output, outOff);
}
else
{
DesEngine.DesFunc(workingKey3, input, inOff, array, 0);
DesEngine.DesFunc(workingKey2, array, 0, array, 0);
DesEngine.DesFunc(workingKey1, array, 0, output, outOff);
}
return 8;
}
public override void Reset()
{
}
}

View File

@@ -0,0 +1,175 @@
using System;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class DesEdeWrapEngine : IWrapper
{
private CbcBlockCipher engine;
private KeyParameter param;
private ParametersWithIV paramPlusIV;
private byte[] iv;
private bool forWrapping;
private static readonly byte[] IV2 = new byte[8] { 74, 221, 162, 44, 121, 232, 33, 5 };
private readonly IDigest sha1 = new Sha1Digest();
private readonly byte[] digest = new byte[20];
public virtual string AlgorithmName => "DESede";
public virtual void Init(bool forWrapping, ICipherParameters parameters)
{
this.forWrapping = forWrapping;
engine = new CbcBlockCipher(new DesEdeEngine());
SecureRandom secureRandom;
if (parameters is ParametersWithRandom)
{
ParametersWithRandom parametersWithRandom = (ParametersWithRandom)parameters;
parameters = parametersWithRandom.Parameters;
secureRandom = parametersWithRandom.Random;
}
else
{
secureRandom = new SecureRandom();
}
if (parameters is KeyParameter)
{
param = (KeyParameter)parameters;
if (this.forWrapping)
{
iv = new byte[8];
secureRandom.NextBytes(iv);
paramPlusIV = new ParametersWithIV(param, iv);
}
}
else if (parameters is ParametersWithIV)
{
if (!forWrapping)
{
throw new ArgumentException("You should not supply an IV for unwrapping");
}
paramPlusIV = (ParametersWithIV)parameters;
iv = paramPlusIV.GetIV();
param = (KeyParameter)paramPlusIV.Parameters;
if (iv.Length != 8)
{
throw new ArgumentException("IV is not 8 octets", "parameters");
}
}
}
public virtual byte[] Wrap(byte[] input, int inOff, int length)
{
if (!forWrapping)
{
throw new InvalidOperationException("Not initialized for wrapping");
}
byte[] array = new byte[length];
Array.Copy(input, inOff, array, 0, length);
byte[] array2 = CalculateCmsKeyChecksum(array);
byte[] array3 = new byte[array.Length + array2.Length];
Array.Copy(array, 0, array3, 0, array.Length);
Array.Copy(array2, 0, array3, array.Length, array2.Length);
int blockSize = engine.GetBlockSize();
if (array3.Length % blockSize != 0)
{
throw new InvalidOperationException("Not multiple of block length");
}
engine.Init(forEncryption: true, paramPlusIV);
byte[] array4 = new byte[array3.Length];
for (int i = 0; i != array3.Length; i += blockSize)
{
engine.ProcessBlock(array3, i, array4, i);
}
byte[] array5 = new byte[iv.Length + array4.Length];
Array.Copy(iv, 0, array5, 0, iv.Length);
Array.Copy(array4, 0, array5, iv.Length, array4.Length);
byte[] array6 = reverse(array5);
ParametersWithIV parameters = new ParametersWithIV(param, IV2);
engine.Init(forEncryption: true, parameters);
for (int j = 0; j != array6.Length; j += blockSize)
{
engine.ProcessBlock(array6, j, array6, j);
}
return array6;
}
public virtual byte[] Unwrap(byte[] input, int inOff, int length)
{
if (forWrapping)
{
throw new InvalidOperationException("Not set for unwrapping");
}
if (input == null)
{
throw new InvalidCipherTextException("Null pointer as ciphertext");
}
int blockSize = engine.GetBlockSize();
if (length % blockSize != 0)
{
throw new InvalidCipherTextException("Ciphertext not multiple of " + blockSize);
}
ParametersWithIV parameters = new ParametersWithIV(param, IV2);
engine.Init(forEncryption: false, parameters);
byte[] array = new byte[length];
for (int i = 0; i != array.Length; i += blockSize)
{
engine.ProcessBlock(input, inOff + i, array, i);
}
byte[] array2 = reverse(array);
iv = new byte[8];
byte[] array3 = new byte[array2.Length - 8];
Array.Copy(array2, 0, iv, 0, 8);
Array.Copy(array2, 8, array3, 0, array2.Length - 8);
paramPlusIV = new ParametersWithIV(param, iv);
engine.Init(forEncryption: false, paramPlusIV);
byte[] array4 = new byte[array3.Length];
for (int j = 0; j != array4.Length; j += blockSize)
{
engine.ProcessBlock(array3, j, array4, j);
}
byte[] array5 = new byte[array4.Length - 8];
byte[] array6 = new byte[8];
Array.Copy(array4, 0, array5, 0, array4.Length - 8);
Array.Copy(array4, array4.Length - 8, array6, 0, 8);
if (!CheckCmsKeyChecksum(array5, array6))
{
throw new InvalidCipherTextException("Checksum inside ciphertext is corrupted");
}
return array5;
}
private byte[] CalculateCmsKeyChecksum(byte[] key)
{
sha1.BlockUpdate(key, 0, key.Length);
sha1.DoFinal(digest, 0);
byte[] array = new byte[8];
Array.Copy(digest, 0, array, 0, 8);
return array;
}
private bool CheckCmsKeyChecksum(byte[] key, byte[] checksum)
{
return Arrays.ConstantTimeAreEqual(CalculateCmsKeyChecksum(key), checksum);
}
private static byte[] reverse(byte[] bs)
{
byte[] array = new byte[bs.Length];
for (int i = 0; i < bs.Length; i++)
{
array[i] = bs[^(i + 1)];
}
return array;
}
}

View File

@@ -0,0 +1,310 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Utilities;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class DesEngine : IBlockCipher
{
internal const int BLOCK_SIZE = 8;
private int[] workingKey;
private static readonly short[] bytebit = new short[8] { 128, 64, 32, 16, 8, 4, 2, 1 };
private static readonly int[] bigbyte = new int[24]
{
8388608, 4194304, 2097152, 1048576, 524288, 262144, 131072, 65536, 32768, 16384,
8192, 4096, 2048, 1024, 512, 256, 128, 64, 32, 16,
8, 4, 2, 1
};
private static readonly byte[] pc1 = new byte[56]
{
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
};
private static readonly byte[] totrot = new byte[16]
{
1, 2, 4, 6, 8, 10, 12, 14, 15, 17,
19, 21, 23, 25, 27, 28
};
private static readonly byte[] pc2 = new byte[48]
{
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
};
private static readonly uint[] SP1 = new uint[64]
{
16843776u, 0u, 65536u, 16843780u, 16842756u, 66564u, 4u, 65536u, 1024u, 16843776u,
16843780u, 1024u, 16778244u, 16842756u, 16777216u, 4u, 1028u, 16778240u, 16778240u, 66560u,
66560u, 16842752u, 16842752u, 16778244u, 65540u, 16777220u, 16777220u, 65540u, 0u, 1028u,
66564u, 16777216u, 65536u, 16843780u, 4u, 16842752u, 16843776u, 16777216u, 16777216u, 1024u,
16842756u, 65536u, 66560u, 16777220u, 1024u, 4u, 16778244u, 66564u, 16843780u, 65540u,
16842752u, 16778244u, 16777220u, 1028u, 66564u, 16843776u, 1028u, 16778240u, 16778240u, 0u,
65540u, 66560u, 0u, 16842756u
};
private static readonly uint[] SP2 = new uint[64]
{
2148565024u, 2147516416u, 32768u, 1081376u, 1048576u, 32u, 2148532256u, 2147516448u, 2147483680u, 2148565024u,
2148564992u, 2147483648u, 2147516416u, 1048576u, 32u, 2148532256u, 1081344u, 1048608u, 2147516448u, 0u,
2147483648u, 32768u, 1081376u, 2148532224u, 1048608u, 2147483680u, 0u, 1081344u, 32800u, 2148564992u,
2148532224u, 32800u, 0u, 1081376u, 2148532256u, 1048576u, 2147516448u, 2148532224u, 2148564992u, 32768u,
2148532224u, 2147516416u, 32u, 2148565024u, 1081376u, 32u, 32768u, 2147483648u, 32800u, 2148564992u,
1048576u, 2147483680u, 1048608u, 2147516448u, 2147483680u, 1048608u, 1081344u, 0u, 2147516416u, 32800u,
2147483648u, 2148532256u, 2148565024u, 1081344u
};
private static readonly uint[] SP3 = new uint[64]
{
520u, 134349312u, 0u, 134348808u, 134218240u, 0u, 131592u, 134218240u, 131080u, 134217736u,
134217736u, 131072u, 134349320u, 131080u, 134348800u, 520u, 134217728u, 8u, 134349312u, 512u,
131584u, 134348800u, 134348808u, 131592u, 134218248u, 131584u, 131072u, 134218248u, 8u, 134349320u,
512u, 134217728u, 134349312u, 134217728u, 131080u, 520u, 131072u, 134349312u, 134218240u, 0u,
512u, 131080u, 134349320u, 134218240u, 134217736u, 512u, 0u, 134348808u, 134218248u, 131072u,
134217728u, 134349320u, 8u, 131592u, 131584u, 134217736u, 134348800u, 134218248u, 520u, 134348800u,
131592u, 8u, 134348808u, 131584u
};
private static readonly uint[] SP4 = new uint[64]
{
8396801u, 8321u, 8321u, 128u, 8396928u, 8388737u, 8388609u, 8193u, 0u, 8396800u,
8396800u, 8396929u, 129u, 0u, 8388736u, 8388609u, 1u, 8192u, 8388608u, 8396801u,
128u, 8388608u, 8193u, 8320u, 8388737u, 1u, 8320u, 8388736u, 8192u, 8396928u,
8396929u, 129u, 8388736u, 8388609u, 8396800u, 8396929u, 129u, 0u, 0u, 8396800u,
8320u, 8388736u, 8388737u, 1u, 8396801u, 8321u, 8321u, 128u, 8396929u, 129u,
1u, 8192u, 8388609u, 8193u, 8396928u, 8388737u, 8193u, 8320u, 8388608u, 8396801u,
128u, 8388608u, 8192u, 8396928u
};
private static readonly uint[] SP5 = new uint[64]
{
256u, 34078976u, 34078720u, 1107296512u, 524288u, 256u, 1073741824u, 34078720u, 1074266368u, 524288u,
33554688u, 1074266368u, 1107296512u, 1107820544u, 524544u, 1073741824u, 33554432u, 1074266112u, 1074266112u, 0u,
1073742080u, 1107820800u, 1107820800u, 33554688u, 1107820544u, 1073742080u, 0u, 1107296256u, 34078976u, 33554432u,
1107296256u, 524544u, 524288u, 1107296512u, 256u, 33554432u, 1073741824u, 34078720u, 1107296512u, 1074266368u,
33554688u, 1073741824u, 1107820544u, 34078976u, 1074266368u, 256u, 33554432u, 1107820544u, 1107820800u, 524544u,
1107296256u, 1107820800u, 34078720u, 0u, 1074266112u, 1107296256u, 524544u, 33554688u, 1073742080u, 524288u,
0u, 1074266112u, 34078976u, 1073742080u
};
private static readonly uint[] SP6 = new uint[64]
{
536870928u, 541065216u, 16384u, 541081616u, 541065216u, 16u, 541081616u, 4194304u, 536887296u, 4210704u,
4194304u, 536870928u, 4194320u, 536887296u, 536870912u, 16400u, 0u, 4194320u, 536887312u, 16384u,
4210688u, 536887312u, 16u, 541065232u, 541065232u, 0u, 4210704u, 541081600u, 16400u, 4210688u,
541081600u, 536870912u, 536887296u, 16u, 541065232u, 4210688u, 541081616u, 4194304u, 16400u, 536870928u,
4194304u, 536887296u, 536870912u, 16400u, 536870928u, 541081616u, 4210688u, 541065216u, 4210704u, 541081600u,
0u, 541065232u, 16u, 16384u, 541065216u, 4210704u, 16384u, 4194320u, 536887312u, 0u,
541081600u, 536870912u, 4194320u, 536887312u
};
private static readonly uint[] SP7 = new uint[64]
{
2097152u, 69206018u, 67110914u, 0u, 2048u, 67110914u, 2099202u, 69208064u, 69208066u, 2097152u,
0u, 67108866u, 2u, 67108864u, 69206018u, 2050u, 67110912u, 2099202u, 2097154u, 67110912u,
67108866u, 69206016u, 69208064u, 2097154u, 69206016u, 2048u, 2050u, 69208066u, 2099200u, 2u,
67108864u, 2099200u, 67108864u, 2099200u, 2097152u, 67110914u, 67110914u, 69206018u, 69206018u, 2u,
2097154u, 67108864u, 67110912u, 2097152u, 69208064u, 2050u, 2099202u, 69208064u, 2050u, 67108866u,
69208066u, 69206016u, 2099200u, 0u, 2u, 69208066u, 0u, 2099202u, 69206016u, 2048u,
67108866u, 67110912u, 2048u, 2097154u
};
private static readonly uint[] SP8 = new uint[64]
{
268439616u, 4096u, 262144u, 268701760u, 268435456u, 268439616u, 64u, 268435456u, 262208u, 268697600u,
268701760u, 266240u, 268701696u, 266304u, 4096u, 64u, 268697600u, 268435520u, 268439552u, 4160u,
266240u, 262208u, 268697664u, 268701696u, 4160u, 0u, 0u, 268697664u, 268435520u, 268439552u,
266304u, 262144u, 266304u, 262144u, 268701696u, 4096u, 64u, 268697664u, 4096u, 266304u,
268439552u, 64u, 268435520u, 268697600u, 268697664u, 268435456u, 262144u, 268439616u, 0u, 268701760u,
262208u, 268435520u, 268697600u, 268439552u, 268439616u, 0u, 268701760u, 266240u, 266240u, 4160u,
4160u, 262208u, 268435456u, 268701696u
};
public virtual string AlgorithmName => "DES";
public virtual bool IsPartialBlockOkay => false;
public virtual int[] GetWorkingKey()
{
return workingKey;
}
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
if (!(parameters is KeyParameter))
{
throw new ArgumentException("invalid parameter passed to DES init - " + Platform.GetTypeName(parameters));
}
workingKey = GenerateWorkingKey(forEncryption, ((KeyParameter)parameters).GetKey());
}
public virtual int GetBlockSize()
{
return 8;
}
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
{
if (workingKey == null)
{
throw new InvalidOperationException("DES engine not initialised");
}
Check.DataLength(input, inOff, 8, "input buffer too short");
Check.OutputLength(output, outOff, 8, "output buffer too short");
DesFunc(workingKey, input, inOff, output, outOff);
return 8;
}
public virtual void Reset()
{
}
protected static int[] GenerateWorkingKey(bool encrypting, byte[] key)
{
int[] array = new int[32];
bool[] array2 = new bool[56];
bool[] array3 = new bool[56];
for (int i = 0; i < 56; i++)
{
int num = pc1[i];
array2[i] = (key[num >>> 3] & bytebit[num & 7]) != 0;
}
for (int j = 0; j < 16; j++)
{
int num2 = ((!encrypting) ? (15 - j << 1) : (j << 1));
int num3 = num2 + 1;
array[num2] = (array[num3] = 0);
for (int k = 0; k < 28; k++)
{
int num4 = k + totrot[j];
if (num4 < 28)
{
array3[k] = array2[num4];
}
else
{
array3[k] = array2[num4 - 28];
}
}
for (int l = 28; l < 56; l++)
{
int num4 = l + totrot[j];
if (num4 < 56)
{
array3[l] = array2[num4];
}
else
{
array3[l] = array2[num4 - 28];
}
}
for (int m = 0; m < 24; m++)
{
if (array3[pc2[m]])
{
int[] array5;
int[] array4 = (array5 = array);
nint num5 = num2;
array4[num2] = array5[num5] | bigbyte[m];
}
if (array3[pc2[m + 24]])
{
int[] array5;
int[] array6 = (array5 = array);
nint num5 = num3;
array6[num3] = array5[num5] | bigbyte[m];
}
}
}
for (int n = 0; n != 32; n += 2)
{
int num6 = array[n];
int num7 = array[n + 1];
array[n] = ((num6 & 0xFC0000) << 6) | ((num6 & 0xFC0) << 10) | ((num7 & 0xFC0000) >>> 10) | ((num7 & 0xFC0) >>> 6);
array[n + 1] = ((num6 & 0x3F000) << 12) | ((num6 & 0x3F) << 16) | ((num7 & 0x3F000) >>> 4) | (num7 & 0x3F);
}
return array;
}
internal static void DesFunc(int[] wKey, byte[] input, int inOff, byte[] outBytes, int outOff)
{
uint num = Pack.BE_To_UInt32(input, inOff);
uint num2 = Pack.BE_To_UInt32(input, inOff + 4);
uint num3 = ((num >> 4) ^ num2) & 0xF0F0F0F;
num2 ^= num3;
num ^= num3 << 4;
num3 = ((num >> 16) ^ num2) & 0xFFFF;
num2 ^= num3;
num ^= num3 << 16;
num3 = ((num2 >> 2) ^ num) & 0x33333333;
num ^= num3;
num2 ^= num3 << 2;
num3 = ((num2 >> 8) ^ num) & 0xFF00FF;
num ^= num3;
num2 ^= num3 << 8;
num2 = (num2 << 1) | (num2 >> 31);
num3 = (num ^ num2) & 0xAAAAAAAAu;
num ^= num3;
num2 ^= num3;
num = (num << 1) | (num >> 31);
for (int i = 0; i < 8; i++)
{
num3 = (num2 << 28) | (num2 >> 4);
num3 ^= (uint)wKey[i * 4];
uint num4 = SP7[num3 & 0x3F];
num4 |= SP5[(num3 >> 8) & 0x3F];
num4 |= SP3[(num3 >> 16) & 0x3F];
num4 |= SP1[(num3 >> 24) & 0x3F];
num3 = num2 ^ (uint)wKey[i * 4 + 1];
num4 |= SP8[num3 & 0x3F];
num4 |= SP6[(num3 >> 8) & 0x3F];
num4 |= SP4[(num3 >> 16) & 0x3F];
num4 |= SP2[(num3 >> 24) & 0x3F];
num ^= num4;
num3 = (num << 28) | (num >> 4);
num3 ^= (uint)wKey[i * 4 + 2];
num4 = SP7[num3 & 0x3F];
num4 |= SP5[(num3 >> 8) & 0x3F];
num4 |= SP3[(num3 >> 16) & 0x3F];
num4 |= SP1[(num3 >> 24) & 0x3F];
num3 = num ^ (uint)wKey[i * 4 + 3];
num4 |= SP8[num3 & 0x3F];
num4 |= SP6[(num3 >> 8) & 0x3F];
num4 |= SP4[(num3 >> 16) & 0x3F];
num4 |= SP2[(num3 >> 24) & 0x3F];
num2 ^= num4;
}
num2 = (num2 << 31) | (num2 >> 1);
num3 = (num ^ num2) & 0xAAAAAAAAu;
num ^= num3;
num2 ^= num3;
num = (num << 31) | (num >> 1);
num3 = ((num >> 8) ^ num2) & 0xFF00FF;
num2 ^= num3;
num ^= num3 << 8;
num3 = ((num >> 2) ^ num2) & 0x33333333;
num2 ^= num3;
num ^= num3 << 2;
num3 = ((num2 >> 16) ^ num) & 0xFFFF;
num ^= num3;
num2 ^= num3 << 16;
num3 = ((num2 >> 4) ^ num) & 0xF0F0F0F;
num ^= num3;
num2 ^= num3 << 4;
Pack.UInt32_To_BE(num2, outBytes, outOff);
Pack.UInt32_To_BE(num, outBytes, outOff + 4);
}
}

View File

@@ -0,0 +1,164 @@
using System;
using System.Collections;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Utilities;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class Dstu7624WrapEngine : IWrapper
{
private KeyParameter param;
private Dstu7624Engine engine;
private bool forWrapping;
private int blockSize;
public string AlgorithmName => "Dstu7624WrapEngine";
public Dstu7624WrapEngine(int blockSizeBits)
{
engine = new Dstu7624Engine(blockSizeBits);
param = null;
blockSize = blockSizeBits / 8;
}
public void Init(bool forWrapping, ICipherParameters parameters)
{
this.forWrapping = forWrapping;
if (parameters is KeyParameter)
{
param = (KeyParameter)parameters;
engine.Init(forWrapping, param);
return;
}
throw new ArgumentException("Bad parameters passed to Dstu7624WrapEngine");
}
public byte[] Wrap(byte[] input, int inOff, int length)
{
if (!forWrapping)
{
throw new InvalidOperationException("Not set for wrapping");
}
if (length % blockSize != 0)
{
throw new ArgumentException("Padding not supported");
}
int num = 2 * (1 + length / blockSize);
int num2 = (num - 1) * 6;
byte[] array = new byte[length + blockSize];
Array.Copy(input, inOff, array, 0, length);
byte[] array2 = new byte[blockSize / 2];
Array.Copy(array, 0, array2, 0, blockSize / 2);
IList list = Platform.CreateArrayList();
int num3 = array.Length - blockSize / 2;
int num4 = blockSize / 2;
while (num3 != 0)
{
byte[] array3 = new byte[blockSize / 2];
Array.Copy(array, num4, array3, 0, blockSize / 2);
list.Add(array3);
num3 -= blockSize / 2;
num4 += blockSize / 2;
}
for (int i = 0; i < num2; i++)
{
Array.Copy(array2, 0, array, 0, blockSize / 2);
Array.Copy((byte[])list[0], 0, array, blockSize / 2, blockSize / 2);
engine.ProcessBlock(array, 0, array, 0);
byte[] array4 = Pack.UInt32_To_LE((uint)(i + 1));
for (int j = 0; j < array4.Length; j++)
{
byte[] array6;
byte[] array5 = (array6 = array);
int num5 = j + blockSize / 2;
nint num6 = num5;
array5[num5] = (byte)(array6[num6] ^ array4[j]);
}
Array.Copy(array, blockSize / 2, array2, 0, blockSize / 2);
for (int k = 2; k < num; k++)
{
Array.Copy((byte[])list[k - 1], 0, (byte[])list[k - 2], 0, blockSize / 2);
}
Array.Copy(array, 0, (byte[])list[num - 2], 0, blockSize / 2);
}
Array.Copy(array2, 0, array, 0, blockSize / 2);
num4 = blockSize / 2;
for (int l = 0; l < num - 1; l++)
{
Array.Copy((byte[])list[l], 0, array, num4, blockSize / 2);
num4 += blockSize / 2;
}
return array;
}
public byte[] Unwrap(byte[] input, int inOff, int length)
{
if (forWrapping)
{
throw new InvalidOperationException("not set for unwrapping");
}
if (length % blockSize != 0)
{
throw new ArgumentException("Padding not supported");
}
int num = 2 * length / blockSize;
int num2 = (num - 1) * 6;
byte[] array = new byte[length];
Array.Copy(input, inOff, array, 0, length);
byte[] array2 = new byte[blockSize / 2];
Array.Copy(array, 0, array2, 0, blockSize / 2);
IList list = Platform.CreateArrayList();
int num3 = array.Length - blockSize / 2;
int num4 = blockSize / 2;
while (num3 != 0)
{
byte[] array3 = new byte[blockSize / 2];
Array.Copy(array, num4, array3, 0, blockSize / 2);
list.Add(array3);
num3 -= blockSize / 2;
num4 += blockSize / 2;
}
for (int i = 0; i < num2; i++)
{
Array.Copy((byte[])list[num - 2], 0, array, 0, blockSize / 2);
Array.Copy(array2, 0, array, blockSize / 2, blockSize / 2);
byte[] array4 = Pack.UInt32_To_LE((uint)(num2 - i));
for (int j = 0; j < array4.Length; j++)
{
byte[] array6;
byte[] array5 = (array6 = array);
int num5 = j + blockSize / 2;
nint num6 = num5;
array5[num5] = (byte)(array6[num6] ^ array4[j]);
}
engine.ProcessBlock(array, 0, array, 0);
Array.Copy(array, 0, array2, 0, blockSize / 2);
for (int k = 2; k < num; k++)
{
Array.Copy((byte[])list[num - k - 1], 0, (byte[])list[num - k], 0, blockSize / 2);
}
Array.Copy(array, blockSize / 2, (byte[])list[0], 0, blockSize / 2);
}
Array.Copy(array2, 0, array, 0, blockSize / 2);
num4 = blockSize / 2;
for (int l = 0; l < num - 1; l++)
{
Array.Copy((byte[])list[l], 0, array, num4, blockSize / 2);
num4 += blockSize / 2;
}
byte b = 0;
for (int m = array.Length - blockSize; m < array.Length; m++)
{
b |= array[m];
}
if (b != 0)
{
throw new InvalidCipherTextException("checksum failed");
}
return Arrays.CopyOfRange(array, 0, array.Length - blockSize);
}
}

View File

@@ -0,0 +1,114 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Engines;
public class ElGamalEngine : IAsymmetricBlockCipher
{
private ElGamalKeyParameters key;
private SecureRandom random;
private bool forEncryption;
private int bitSize;
public virtual string AlgorithmName => "ElGamal";
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
if (parameters is ParametersWithRandom)
{
ParametersWithRandom parametersWithRandom = (ParametersWithRandom)parameters;
key = (ElGamalKeyParameters)parametersWithRandom.Parameters;
random = parametersWithRandom.Random;
}
else
{
key = (ElGamalKeyParameters)parameters;
random = new SecureRandom();
}
this.forEncryption = forEncryption;
bitSize = key.Parameters.P.BitLength;
if (forEncryption)
{
if (!(key is ElGamalPublicKeyParameters))
{
throw new ArgumentException("ElGamalPublicKeyParameters are required for encryption.");
}
}
else if (!(key is ElGamalPrivateKeyParameters))
{
throw new ArgumentException("ElGamalPrivateKeyParameters are required for decryption.");
}
}
public virtual int GetInputBlockSize()
{
if (forEncryption)
{
return (bitSize - 1) / 8;
}
return 2 * ((bitSize + 7) / 8);
}
public virtual int GetOutputBlockSize()
{
if (forEncryption)
{
return 2 * ((bitSize + 7) / 8);
}
return (bitSize - 1) / 8;
}
public virtual byte[] ProcessBlock(byte[] input, int inOff, int length)
{
if (key == null)
{
throw new InvalidOperationException("ElGamal engine not initialised");
}
int num = (forEncryption ? ((bitSize - 1 + 7) / 8) : GetInputBlockSize());
if (length > num)
{
throw new DataLengthException("input too large for ElGamal cipher.\n");
}
BigInteger p = key.Parameters.P;
byte[] array;
if (key is ElGamalPrivateKeyParameters)
{
int num2 = length / 2;
BigInteger bigInteger = new BigInteger(1, input, inOff, num2);
BigInteger val = new BigInteger(1, input, inOff + num2, num2);
ElGamalPrivateKeyParameters elGamalPrivateKeyParameters = (ElGamalPrivateKeyParameters)key;
BigInteger bigInteger2 = bigInteger.ModPow(p.Subtract(BigInteger.One).Subtract(elGamalPrivateKeyParameters.X), p).Multiply(val).Mod(p);
array = bigInteger2.ToByteArrayUnsigned();
}
else
{
BigInteger bigInteger3 = new BigInteger(1, input, inOff, length);
if (bigInteger3.BitLength >= p.BitLength)
{
throw new DataLengthException("input too large for ElGamal cipher.\n");
}
ElGamalPublicKeyParameters elGamalPublicKeyParameters = (ElGamalPublicKeyParameters)key;
BigInteger value = p.Subtract(BigInteger.Two);
BigInteger bigInteger4;
do
{
bigInteger4 = new BigInteger(p.BitLength, random);
}
while (bigInteger4.SignValue == 0 || bigInteger4.CompareTo(value) > 0);
BigInteger g = key.Parameters.G;
BigInteger bigInteger5 = g.ModPow(bigInteger4, p);
BigInteger bigInteger6 = bigInteger3.Multiply(elGamalPublicKeyParameters.Y.ModPow(bigInteger4, p)).Mod(p);
array = new byte[GetOutputBlockSize()];
byte[] array2 = bigInteger5.ToByteArrayUnsigned();
byte[] array3 = bigInteger6.ToByteArrayUnsigned();
array2.CopyTo(array, array.Length / 2 - array2.Length);
array3.CopyTo(array, array.Length - array3.Length);
}
return array;
}
}

View File

@@ -0,0 +1,347 @@
using System;
using System.Collections;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class Gost28147Engine : IBlockCipher
{
private const int BlockSize = 8;
private int[] workingKey = null;
private bool forEncryption;
private byte[] S = Sbox_Default;
private static readonly byte[] Sbox_Default;
private static readonly byte[] ESbox_Test;
private static readonly byte[] ESbox_A;
private static readonly byte[] ESbox_B;
private static readonly byte[] ESbox_C;
private static readonly byte[] ESbox_D;
private static readonly byte[] DSbox_Test;
private static readonly byte[] DSbox_A;
private static readonly IDictionary sBoxes;
public virtual string AlgorithmName => "Gost28147";
public virtual bool IsPartialBlockOkay => false;
static Gost28147Engine()
{
Sbox_Default = new byte[128]
{
4, 10, 9, 2, 13, 8, 0, 14, 6, 11,
1, 12, 7, 15, 5, 3, 14, 11, 4, 12,
6, 13, 15, 10, 2, 3, 8, 1, 0, 7,
5, 9, 5, 8, 1, 13, 10, 3, 4, 2,
14, 15, 12, 7, 6, 0, 9, 11, 7, 13,
10, 1, 0, 8, 9, 15, 14, 4, 6, 12,
11, 2, 5, 3, 6, 12, 7, 1, 5, 15,
13, 8, 4, 10, 9, 14, 0, 3, 11, 2,
4, 11, 10, 0, 7, 2, 1, 13, 3, 6,
8, 5, 9, 12, 15, 14, 13, 11, 4, 1,
3, 15, 5, 9, 0, 10, 14, 7, 6, 8,
2, 12, 1, 15, 13, 0, 5, 7, 10, 4,
9, 2, 3, 14, 6, 11, 8, 12
};
ESbox_Test = new byte[128]
{
4, 2, 15, 5, 9, 1, 0, 8, 14, 3,
11, 12, 13, 7, 10, 6, 12, 9, 15, 14,
8, 1, 3, 10, 2, 7, 4, 13, 6, 0,
11, 5, 13, 8, 14, 12, 7, 3, 9, 10,
1, 5, 2, 4, 6, 15, 0, 11, 14, 9,
11, 2, 5, 15, 7, 1, 0, 13, 12, 6,
10, 4, 3, 8, 3, 14, 5, 9, 6, 8,
0, 13, 10, 11, 7, 12, 2, 1, 15, 4,
8, 15, 6, 11, 1, 9, 12, 5, 13, 3,
7, 10, 0, 14, 2, 4, 9, 11, 12, 0,
3, 6, 7, 5, 4, 8, 14, 15, 1, 10,
2, 13, 12, 6, 5, 2, 11, 0, 9, 13,
3, 14, 7, 10, 15, 4, 1, 8
};
ESbox_A = new byte[128]
{
9, 6, 3, 2, 8, 11, 1, 7, 10, 4,
14, 15, 12, 0, 13, 5, 3, 7, 14, 9,
8, 10, 15, 0, 5, 2, 6, 12, 11, 4,
13, 1, 14, 4, 6, 2, 11, 3, 13, 8,
12, 15, 5, 10, 0, 7, 1, 9, 14, 7,
10, 12, 13, 1, 3, 9, 0, 2, 11, 4,
15, 8, 5, 6, 11, 5, 1, 9, 8, 13,
15, 0, 14, 4, 2, 3, 12, 7, 10, 6,
3, 10, 13, 12, 1, 2, 0, 11, 7, 5,
9, 4, 8, 15, 14, 6, 1, 13, 2, 9,
7, 10, 6, 0, 8, 12, 4, 5, 15, 3,
11, 14, 11, 10, 15, 5, 0, 12, 14, 8,
6, 2, 3, 9, 1, 7, 13, 4
};
ESbox_B = new byte[128]
{
8, 4, 11, 1, 3, 5, 0, 9, 2, 14,
10, 12, 13, 6, 7, 15, 0, 1, 2, 10,
4, 13, 5, 12, 9, 7, 3, 15, 11, 8,
6, 14, 14, 12, 0, 10, 9, 2, 13, 11,
7, 5, 8, 15, 3, 6, 1, 4, 7, 5,
0, 13, 11, 6, 1, 2, 3, 10, 12, 15,
4, 14, 9, 8, 2, 7, 12, 15, 9, 5,
10, 11, 1, 4, 0, 13, 6, 8, 14, 3,
8, 3, 2, 6, 4, 13, 14, 11, 12, 1,
7, 15, 10, 0, 9, 5, 5, 2, 10, 11,
9, 1, 12, 3, 7, 4, 13, 0, 6, 15,
8, 14, 0, 4, 11, 14, 8, 3, 7, 1,
10, 2, 9, 6, 15, 13, 5, 12
};
ESbox_C = new byte[128]
{
1, 11, 12, 2, 9, 13, 0, 15, 4, 5,
8, 14, 10, 7, 6, 3, 0, 1, 7, 13,
11, 4, 5, 2, 8, 14, 15, 12, 9, 10,
6, 3, 8, 2, 5, 0, 4, 9, 15, 10,
3, 7, 12, 13, 6, 14, 1, 11, 3, 6,
0, 1, 5, 13, 10, 8, 11, 2, 9, 7,
14, 15, 12, 4, 8, 13, 11, 0, 4, 5,
1, 2, 9, 3, 12, 14, 6, 15, 10, 7,
12, 9, 11, 1, 8, 14, 2, 4, 7, 3,
6, 5, 10, 0, 15, 13, 10, 9, 6, 8,
13, 14, 2, 0, 15, 3, 5, 11, 4, 1,
12, 7, 7, 4, 0, 5, 10, 2, 15, 14,
12, 6, 1, 11, 13, 9, 3, 8
};
ESbox_D = new byte[128]
{
15, 12, 2, 10, 6, 4, 5, 0, 7, 9,
14, 13, 1, 11, 8, 3, 11, 6, 3, 4,
12, 15, 14, 2, 7, 13, 8, 0, 5, 10,
9, 1, 1, 12, 11, 0, 15, 14, 6, 5,
10, 13, 4, 8, 9, 3, 7, 2, 1, 5,
14, 12, 10, 7, 0, 13, 6, 2, 11, 4,
9, 3, 15, 8, 0, 12, 8, 9, 13, 2,
10, 11, 7, 3, 6, 5, 4, 14, 15, 1,
8, 0, 15, 3, 2, 5, 14, 11, 1, 10,
4, 7, 12, 9, 13, 6, 3, 0, 6, 15,
1, 14, 9, 2, 13, 8, 12, 4, 11, 10,
5, 7, 1, 10, 6, 8, 15, 11, 0, 4,
12, 3, 5, 9, 7, 13, 2, 14
};
DSbox_Test = new byte[128]
{
4, 10, 9, 2, 13, 8, 0, 14, 6, 11,
1, 12, 7, 15, 5, 3, 14, 11, 4, 12,
6, 13, 15, 10, 2, 3, 8, 1, 0, 7,
5, 9, 5, 8, 1, 13, 10, 3, 4, 2,
14, 15, 12, 7, 6, 0, 9, 11, 7, 13,
10, 1, 0, 8, 9, 15, 14, 4, 6, 12,
11, 2, 5, 3, 6, 12, 7, 1, 5, 15,
13, 8, 4, 10, 9, 14, 0, 3, 11, 2,
4, 11, 10, 0, 7, 2, 1, 13, 3, 6,
8, 5, 9, 12, 15, 14, 13, 11, 4, 1,
3, 15, 5, 9, 0, 10, 14, 7, 6, 8,
2, 12, 1, 15, 13, 0, 5, 7, 10, 4,
9, 2, 3, 14, 6, 11, 8, 12
};
DSbox_A = new byte[128]
{
10, 4, 5, 6, 8, 1, 3, 7, 13, 12,
14, 0, 9, 2, 11, 15, 5, 15, 4, 0,
2, 13, 11, 9, 1, 7, 6, 3, 12, 14,
10, 8, 7, 15, 12, 14, 9, 4, 1, 0,
3, 11, 5, 2, 6, 10, 8, 13, 4, 10,
7, 12, 0, 15, 2, 8, 14, 1, 6, 5,
13, 11, 9, 3, 7, 6, 4, 11, 9, 12,
2, 10, 1, 8, 0, 14, 15, 13, 3, 5,
7, 6, 2, 4, 13, 9, 15, 0, 10, 1,
5, 11, 8, 14, 12, 3, 13, 14, 4, 1,
7, 0, 5, 10, 3, 12, 8, 15, 6, 2,
9, 11, 1, 3, 10, 9, 5, 11, 4, 15,
8, 6, 7, 14, 13, 0, 2, 12
};
sBoxes = Platform.CreateHashtable();
AddSBox("Default", Sbox_Default);
AddSBox("E-TEST", ESbox_Test);
AddSBox("E-A", ESbox_A);
AddSBox("E-B", ESbox_B);
AddSBox("E-C", ESbox_C);
AddSBox("E-D", ESbox_D);
AddSBox("D-TEST", DSbox_Test);
AddSBox("D-A", DSbox_A);
}
private static void AddSBox(string sBoxName, byte[] sBox)
{
sBoxes.Add(Platform.ToUpperInvariant(sBoxName), sBox);
}
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
if (parameters is ParametersWithSBox)
{
ParametersWithSBox parametersWithSBox = (ParametersWithSBox)parameters;
byte[] sBox = parametersWithSBox.GetSBox();
if (sBox.Length != Sbox_Default.Length)
{
throw new ArgumentException("invalid S-box passed to GOST28147 init");
}
S = Arrays.Clone(sBox);
if (parametersWithSBox.Parameters != null)
{
workingKey = generateWorkingKey(forEncryption, ((KeyParameter)parametersWithSBox.Parameters).GetKey());
}
}
else if (parameters is KeyParameter)
{
workingKey = generateWorkingKey(forEncryption, ((KeyParameter)parameters).GetKey());
}
else if (parameters != null)
{
throw new ArgumentException("invalid parameter passed to Gost28147 init - " + Platform.GetTypeName(parameters));
}
}
public virtual int GetBlockSize()
{
return 8;
}
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
{
if (workingKey == null)
{
throw new InvalidOperationException("Gost28147 engine not initialised");
}
Check.DataLength(input, inOff, 8, "input buffer too short");
Check.OutputLength(output, outOff, 8, "output buffer too short");
Gost28147Func(workingKey, input, inOff, output, outOff);
return 8;
}
public virtual void Reset()
{
}
private int[] generateWorkingKey(bool forEncryption, byte[] userKey)
{
this.forEncryption = forEncryption;
if (userKey.Length != 32)
{
throw new ArgumentException("Key length invalid. Key needs to be 32 byte - 256 bit!!!");
}
int[] array = new int[8];
for (int i = 0; i != 8; i++)
{
array[i] = bytesToint(userKey, i * 4);
}
return array;
}
private int Gost28147_mainStep(int n1, int key)
{
int num = key + n1;
int num2 = S[num & 0xF];
num2 += S[16 + ((num >> 4) & 0xF)] << 4;
num2 += S[32 + ((num >> 8) & 0xF)] << 8;
num2 += S[48 + ((num >> 12) & 0xF)] << 12;
num2 += S[64 + ((num >> 16) & 0xF)] << 16;
num2 += S[80 + ((num >> 20) & 0xF)] << 20;
num2 += S[96 + ((num >> 24) & 0xF)] << 24;
num2 += S[112 + ((num >> 28) & 0xF)] << 28;
int num3 = num2 << 11;
int num4 = num2 >>> 21;
return num3 | num4;
}
private void Gost28147Func(int[] workingKey, byte[] inBytes, int inOff, byte[] outBytes, int outOff)
{
int num = bytesToint(inBytes, inOff);
int num2 = bytesToint(inBytes, inOff + 4);
if (forEncryption)
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 8; j++)
{
int num3 = num;
int num4 = Gost28147_mainStep(num, workingKey[j]);
num = num2 ^ num4;
num2 = num3;
}
}
for (int num5 = 7; num5 > 0; num5--)
{
int num3 = num;
num = num2 ^ Gost28147_mainStep(num, workingKey[num5]);
num2 = num3;
}
}
else
{
for (int k = 0; k < 8; k++)
{
int num3 = num;
num = num2 ^ Gost28147_mainStep(num, workingKey[k]);
num2 = num3;
}
for (int l = 0; l < 3; l++)
{
int num6 = 7;
while (num6 >= 0 && (l != 2 || num6 != 0))
{
int num3 = num;
num = num2 ^ Gost28147_mainStep(num, workingKey[num6]);
num2 = num3;
num6--;
}
}
}
num2 ^= Gost28147_mainStep(num, workingKey[0]);
intTobytes(num, outBytes, outOff);
intTobytes(num2, outBytes, outOff + 4);
}
private static int bytesToint(byte[] inBytes, int inOff)
{
return (int)((inBytes[inOff + 3] << 24) & 0xFF000000u) + ((inBytes[inOff + 2] << 16) & 0xFF0000) + ((inBytes[inOff + 1] << 8) & 0xFF00) + (inBytes[inOff] & 0xFF);
}
private static void intTobytes(int num, byte[] outBytes, int outOff)
{
outBytes[outOff + 3] = (byte)(num >> 24);
outBytes[outOff + 2] = (byte)(num >> 16);
outBytes[outOff + 1] = (byte)(num >> 8);
outBytes[outOff] = (byte)num;
}
public static byte[] GetSBox(string sBoxName)
{
byte[] array = (byte[])sBoxes[Platform.ToUpperInvariant(sBoxName)];
if (array == null)
{
throw new ArgumentException("Unknown S-Box - possible types: \"Default\", \"E-Test\", \"E-A\", \"E-B\", \"E-C\", \"E-D\", \"D-Test\", \"D-A\".");
}
return Arrays.Clone(array);
}
public static string GetSBoxName(byte[] sBox)
{
foreach (string key in sBoxes.Keys)
{
byte[] a = (byte[])sBoxes[key];
if (Arrays.AreEqual(a, sBox))
{
return key;
}
}
throw new ArgumentException("SBOX provided did not map to a known one");
}
}

View File

@@ -0,0 +1,205 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Utilities;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class HC128Engine : IStreamCipher
{
private uint[] p = new uint[512];
private uint[] q = new uint[512];
private uint cnt = 0u;
private byte[] key;
private byte[] iv;
private bool initialised;
private byte[] buf = new byte[4];
private int idx = 0;
public virtual string AlgorithmName => "HC-128";
private static uint F1(uint x)
{
return RotateRight(x, 7) ^ RotateRight(x, 18) ^ (x >> 3);
}
private static uint F2(uint x)
{
return RotateRight(x, 17) ^ RotateRight(x, 19) ^ (x >> 10);
}
private uint G1(uint x, uint y, uint z)
{
return (RotateRight(x, 10) ^ RotateRight(z, 23)) + RotateRight(y, 8);
}
private uint G2(uint x, uint y, uint z)
{
return (RotateLeft(x, 10) ^ RotateLeft(z, 23)) + RotateLeft(y, 8);
}
private static uint RotateLeft(uint x, int bits)
{
return (x << bits) | (x >> -bits);
}
private static uint RotateRight(uint x, int bits)
{
return (x >> bits) | (x << -bits);
}
private uint H1(uint x)
{
return q[x & 0xFF] + q[((x >> 16) & 0xFF) + 256];
}
private uint H2(uint x)
{
return p[x & 0xFF] + p[((x >> 16) & 0xFF) + 256];
}
private static uint Mod1024(uint x)
{
return x & 0x3FF;
}
private static uint Mod512(uint x)
{
return x & 0x1FF;
}
private static uint Dim(uint x, uint y)
{
return Mod512(x - y);
}
private uint Step()
{
uint num = Mod512(cnt);
uint result;
if (cnt < 512)
{
uint[] array;
nint num2;
(array = p)[num2 = (nint)num] = array[num2] + G1(p[Dim(num, 3u)], p[Dim(num, 10u)], p[Dim(num, 511u)]);
result = H1(p[Dim(num, 12u)]) ^ p[num];
}
else
{
uint[] array;
nint num2;
(array = q)[num2 = (nint)num] = array[num2] + G2(q[Dim(num, 3u)], q[Dim(num, 10u)], q[Dim(num, 511u)]);
result = H2(q[Dim(num, 12u)]) ^ q[num];
}
cnt = Mod1024(cnt + 1);
return result;
}
private void Init()
{
if (key.Length != 16)
{
throw new ArgumentException("The key must be 128 bits long");
}
idx = 0;
cnt = 0u;
uint[] array = new uint[1280];
for (int i = 0; i < 16; i++)
{
uint[] array3;
uint[] array2 = (array3 = array);
int num = i >> 2;
nint num2 = num;
array2[num] = array3[num2] | (uint)(key[i] << 8 * (i & 3));
}
Array.Copy(array, 0, array, 4, 4);
for (int j = 0; j < iv.Length && j < 16; j++)
{
uint[] array3;
uint[] array4 = (array3 = array);
int num3 = (j >> 2) + 8;
nint num2 = num3;
array4[num3] = array3[num2] | (uint)(iv[j] << 8 * (j & 3));
}
Array.Copy(array, 8, array, 12, 4);
for (uint num4 = 16u; num4 < 1280; num4++)
{
array[num4] = F2(array[num4 - 2]) + array[num4 - 7] + F1(array[num4 - 15]) + array[num4 - 16] + num4;
}
Array.Copy(array, 256, p, 0, 512);
Array.Copy(array, 768, q, 0, 512);
for (int k = 0; k < 512; k++)
{
p[k] = Step();
}
for (int l = 0; l < 512; l++)
{
q[l] = Step();
}
cnt = 0u;
}
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
ICipherParameters cipherParameters = parameters;
if (parameters is ParametersWithIV)
{
iv = ((ParametersWithIV)parameters).GetIV();
cipherParameters = ((ParametersWithIV)parameters).Parameters;
}
else
{
iv = new byte[0];
}
if (cipherParameters is KeyParameter)
{
key = ((KeyParameter)cipherParameters).GetKey();
Init();
initialised = true;
return;
}
throw new ArgumentException("Invalid parameter passed to HC128 init - " + Platform.GetTypeName(parameters), "parameters");
}
private byte GetByte()
{
if (idx == 0)
{
Pack.UInt32_To_LE(Step(), buf);
}
byte result = buf[idx];
idx = (idx + 1) & 3;
return result;
}
public virtual void ProcessBytes(byte[] input, int inOff, int len, byte[] output, int outOff)
{
if (!initialised)
{
throw new InvalidOperationException(AlgorithmName + " not initialised");
}
Check.DataLength(input, inOff, len, "input buffer too short");
Check.OutputLength(output, outOff, len, "output buffer too short");
for (int i = 0; i < len; i++)
{
output[outOff + i] = (byte)(input[inOff + i] ^ GetByte());
}
}
public virtual void Reset()
{
Init();
}
public virtual byte ReturnByte(byte input)
{
return (byte)(input ^ GetByte());
}
}

View File

@@ -0,0 +1,175 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Utilities;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class HC256Engine : IStreamCipher
{
private uint[] p = new uint[1024];
private uint[] q = new uint[1024];
private uint cnt = 0u;
private byte[] key;
private byte[] iv;
private bool initialised;
private byte[] buf = new byte[4];
private int idx = 0;
public virtual string AlgorithmName => "HC-256";
private uint Step()
{
uint num = cnt & 0x3FF;
uint result;
if (cnt < 1024)
{
uint num2 = p[(num - 3) & 0x3FF];
uint num3 = p[(num - 1023) & 0x3FF];
uint[] array;
nint num4;
(array = p)[num4 = (nint)num] = array[num4] + (p[(num - 10) & 0x3FF] + (RotateRight(num2, 10) ^ RotateRight(num3, 23)) + q[(num2 ^ num3) & 0x3FF]);
num2 = p[(num - 12) & 0x3FF];
result = (q[num2 & 0xFF] + q[((num2 >> 8) & 0xFF) + 256] + q[((num2 >> 16) & 0xFF) + 512] + q[((num2 >> 24) & 0xFF) + 768]) ^ p[num];
}
else
{
uint num5 = q[(num - 3) & 0x3FF];
uint num6 = q[(num - 1023) & 0x3FF];
uint[] array;
nint num4;
(array = q)[num4 = (nint)num] = array[num4] + (q[(num - 10) & 0x3FF] + (RotateRight(num5, 10) ^ RotateRight(num6, 23)) + p[(num5 ^ num6) & 0x3FF]);
num5 = q[(num - 12) & 0x3FF];
result = (p[num5 & 0xFF] + p[((num5 >> 8) & 0xFF) + 256] + p[((num5 >> 16) & 0xFF) + 512] + p[((num5 >> 24) & 0xFF) + 768]) ^ q[num];
}
cnt = (cnt + 1) & 0x7FF;
return result;
}
private void Init()
{
if (key.Length != 32 && key.Length != 16)
{
throw new ArgumentException("The key must be 128/256 bits long");
}
if (iv.Length < 16)
{
throw new ArgumentException("The IV must be at least 128 bits long");
}
if (key.Length != 32)
{
byte[] destinationArray = new byte[32];
Array.Copy(key, 0, destinationArray, 0, key.Length);
Array.Copy(key, 0, destinationArray, 16, key.Length);
key = destinationArray;
}
if (iv.Length < 32)
{
byte[] array = new byte[32];
Array.Copy(iv, 0, array, 0, iv.Length);
Array.Copy(iv, 0, array, iv.Length, array.Length - iv.Length);
iv = array;
}
idx = 0;
cnt = 0u;
uint[] array2 = new uint[2560];
for (int i = 0; i < 32; i++)
{
uint[] array4;
uint[] array3 = (array4 = array2);
int num = i >> 2;
nint num2 = num;
array3[num] = array4[num2] | (uint)(key[i] << 8 * (i & 3));
}
for (int j = 0; j < 32; j++)
{
uint[] array4;
uint[] array5 = (array4 = array2);
int num3 = (j >> 2) + 8;
nint num2 = num3;
array5[num3] = array4[num2] | (uint)(iv[j] << 8 * (j & 3));
}
for (uint num4 = 16u; num4 < 2560; num4++)
{
uint num5 = array2[num4 - 2];
uint num6 = array2[num4 - 15];
array2[num4] = (RotateRight(num5, 17) ^ RotateRight(num5, 19) ^ (num5 >> 10)) + array2[num4 - 7] + (RotateRight(num6, 7) ^ RotateRight(num6, 18) ^ (num6 >> 3)) + array2[num4 - 16] + num4;
}
Array.Copy(array2, 512, p, 0, 1024);
Array.Copy(array2, 1536, q, 0, 1024);
for (int k = 0; k < 4096; k++)
{
Step();
}
cnt = 0u;
}
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
ICipherParameters cipherParameters = parameters;
if (parameters is ParametersWithIV)
{
iv = ((ParametersWithIV)parameters).GetIV();
cipherParameters = ((ParametersWithIV)parameters).Parameters;
}
else
{
iv = new byte[0];
}
if (cipherParameters is KeyParameter)
{
key = ((KeyParameter)cipherParameters).GetKey();
Init();
initialised = true;
return;
}
throw new ArgumentException("Invalid parameter passed to HC256 init - " + Platform.GetTypeName(parameters), "parameters");
}
private byte GetByte()
{
if (idx == 0)
{
Pack.UInt32_To_LE(Step(), buf);
}
byte result = buf[idx];
idx = (idx + 1) & 3;
return result;
}
public virtual void ProcessBytes(byte[] input, int inOff, int len, byte[] output, int outOff)
{
if (!initialised)
{
throw new InvalidOperationException(AlgorithmName + " not initialised");
}
Check.DataLength(input, inOff, len, "input buffer too short");
Check.OutputLength(output, outOff, len, "output buffer too short");
for (int i = 0; i < len; i++)
{
output[outOff + i] = (byte)(input[inOff + i] ^ GetByte());
}
}
public virtual void Reset()
{
Init();
}
public virtual byte ReturnByte(byte input)
{
return (byte)(input ^ GetByte());
}
private static uint RotateRight(uint x, int bits)
{
return (x >> bits) | (x << -bits);
}
}

View File

@@ -0,0 +1,230 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class IdeaEngine : IBlockCipher
{
private const int BLOCK_SIZE = 8;
private int[] workingKey;
private static readonly int MASK = 65535;
private static readonly int BASE = 65537;
public virtual string AlgorithmName => "IDEA";
public virtual bool IsPartialBlockOkay => false;
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
if (!(parameters is KeyParameter))
{
throw new ArgumentException("invalid parameter passed to IDEA init - " + Platform.GetTypeName(parameters));
}
workingKey = GenerateWorkingKey(forEncryption, ((KeyParameter)parameters).GetKey());
}
public virtual int GetBlockSize()
{
return 8;
}
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
{
if (workingKey == null)
{
throw new InvalidOperationException("IDEA engine not initialised");
}
Check.DataLength(input, inOff, 8, "input buffer too short");
Check.OutputLength(output, outOff, 8, "output buffer too short");
IdeaFunc(workingKey, input, inOff, output, outOff);
return 8;
}
public virtual void Reset()
{
}
private int BytesToWord(byte[] input, int inOff)
{
return ((input[inOff] << 8) & 0xFF00) + (input[inOff + 1] & 0xFF);
}
private void WordToBytes(int word, byte[] outBytes, int outOff)
{
outBytes[outOff] = (byte)((uint)word >> 8);
outBytes[outOff + 1] = (byte)word;
}
private int Mul(int x, int y)
{
if (x == 0)
{
x = BASE - y;
}
else if (y == 0)
{
x = BASE - x;
}
else
{
int num = x * y;
y = num & MASK;
x = num >>> 16;
x = y - x + ((y < x) ? 1 : 0);
}
return x & MASK;
}
private void IdeaFunc(int[] workingKey, byte[] input, int inOff, byte[] outBytes, int outOff)
{
int num = 0;
int x = BytesToWord(input, inOff);
int num2 = BytesToWord(input, inOff + 2);
int num3 = BytesToWord(input, inOff + 4);
int x2 = BytesToWord(input, inOff + 6);
for (int i = 0; i < 8; i++)
{
x = Mul(x, workingKey[num++]);
num2 += workingKey[num++];
num2 &= MASK;
num3 += workingKey[num++];
num3 &= MASK;
x2 = Mul(x2, workingKey[num++]);
int num4 = num2;
int num5 = num3;
num3 ^= x;
num2 ^= x2;
num3 = Mul(num3, workingKey[num++]);
num2 += num3;
num2 &= MASK;
num2 = Mul(num2, workingKey[num++]);
num3 += num2;
num3 &= MASK;
x ^= num2;
x2 ^= num3;
num2 ^= num5;
num3 ^= num4;
}
WordToBytes(Mul(x, workingKey[num++]), outBytes, outOff);
WordToBytes(num3 + workingKey[num++], outBytes, outOff + 2);
WordToBytes(num2 + workingKey[num++], outBytes, outOff + 4);
WordToBytes(Mul(x2, workingKey[num]), outBytes, outOff + 6);
}
private int[] ExpandKey(byte[] uKey)
{
int[] array = new int[52];
if (uKey.Length < 16)
{
byte[] array2 = new byte[16];
Array.Copy(uKey, 0, array2, array2.Length - uKey.Length, uKey.Length);
uKey = array2;
}
for (int i = 0; i < 8; i++)
{
array[i] = BytesToWord(uKey, i * 2);
}
for (int j = 8; j < 52; j++)
{
if ((j & 7) < 6)
{
array[j] = (((array[j - 7] & 0x7F) << 9) | (array[j - 6] >> 7)) & MASK;
}
else if ((j & 7) == 6)
{
array[j] = (((array[j - 7] & 0x7F) << 9) | (array[j - 14] >> 7)) & MASK;
}
else
{
array[j] = (((array[j - 15] & 0x7F) << 9) | (array[j - 14] >> 7)) & MASK;
}
}
return array;
}
private int MulInv(int x)
{
if (x < 2)
{
return x;
}
int num = 1;
int num2 = BASE / x;
int num3 = BASE % x;
while (num3 != 1)
{
int num4 = x / num3;
x %= num3;
num = (num + num2 * num4) & MASK;
if (x == 1)
{
return num;
}
num4 = num3 / x;
num3 %= x;
num2 = (num2 + num * num4) & MASK;
}
return (1 - num2) & MASK;
}
private int AddInv(int x)
{
return -x & MASK;
}
private int[] InvertKey(int[] inKey)
{
int num = 52;
int[] array = new int[52];
int num2 = 0;
int num3 = MulInv(inKey[num2++]);
int num4 = AddInv(inKey[num2++]);
int num5 = AddInv(inKey[num2++]);
int num6 = MulInv(inKey[num2++]);
array[--num] = num6;
array[--num] = num5;
array[--num] = num4;
array[--num] = num3;
for (int i = 1; i < 8; i++)
{
num3 = inKey[num2++];
num4 = inKey[num2++];
array[--num] = num4;
array[--num] = num3;
num3 = MulInv(inKey[num2++]);
num4 = AddInv(inKey[num2++]);
num5 = AddInv(inKey[num2++]);
num6 = MulInv(inKey[num2++]);
array[--num] = num6;
array[--num] = num4;
array[--num] = num5;
array[--num] = num3;
}
num3 = inKey[num2++];
num4 = inKey[num2++];
array[--num] = num4;
array[--num] = num3;
num3 = MulInv(inKey[num2++]);
num4 = AddInv(inKey[num2++]);
num5 = AddInv(inKey[num2++]);
num6 = MulInv(inKey[num2]);
array[--num] = num6;
array[--num] = num5;
array[--num] = num4;
array[--num] = num3;
return array;
}
private int[] GenerateWorkingKey(bool forEncryption, byte[] userKey)
{
if (forEncryption)
{
return ExpandKey(userKey);
}
return InvertKey(ExpandKey(userKey));
}
}

View File

@@ -0,0 +1,159 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class IesEngine
{
private readonly IBasicAgreement agree;
private readonly IDerivationFunction kdf;
private readonly IMac mac;
private readonly BufferedBlockCipher cipher;
private readonly byte[] macBuf;
private bool forEncryption;
private ICipherParameters privParam;
private ICipherParameters pubParam;
private IesParameters param;
public IesEngine(IBasicAgreement agree, IDerivationFunction kdf, IMac mac)
{
this.agree = agree;
this.kdf = kdf;
this.mac = mac;
macBuf = new byte[mac.GetMacSize()];
}
public IesEngine(IBasicAgreement agree, IDerivationFunction kdf, IMac mac, BufferedBlockCipher cipher)
{
this.agree = agree;
this.kdf = kdf;
this.mac = mac;
macBuf = new byte[mac.GetMacSize()];
this.cipher = cipher;
}
public virtual void Init(bool forEncryption, ICipherParameters privParameters, ICipherParameters pubParameters, ICipherParameters iesParameters)
{
this.forEncryption = forEncryption;
privParam = privParameters;
pubParam = pubParameters;
param = (IesParameters)iesParameters;
}
private byte[] DecryptBlock(byte[] in_enc, int inOff, int inLen, byte[] z)
{
byte[] array = null;
KeyParameter keyParameter = null;
KdfParameters kdfParameters = new KdfParameters(z, param.GetDerivationV());
int macKeySize = param.MacKeySize;
kdf.Init(kdfParameters);
if (inLen < mac.GetMacSize())
{
throw new InvalidCipherTextException("Length of input must be greater than the MAC");
}
inLen -= mac.GetMacSize();
if (cipher == null)
{
byte[] array2 = GenerateKdfBytes(kdfParameters, inLen + macKeySize / 8);
array = new byte[inLen];
for (int i = 0; i != inLen; i++)
{
array[i] = (byte)(in_enc[inOff + i] ^ array2[i]);
}
keyParameter = new KeyParameter(array2, inLen, macKeySize / 8);
}
else
{
int cipherKeySize = ((IesWithCipherParameters)param).CipherKeySize;
byte[] key = GenerateKdfBytes(kdfParameters, cipherKeySize / 8 + macKeySize / 8);
cipher.Init(forEncryption: false, new KeyParameter(key, 0, cipherKeySize / 8));
array = cipher.DoFinal(in_enc, inOff, inLen);
keyParameter = new KeyParameter(key, cipherKeySize / 8, macKeySize / 8);
}
byte[] encodingV = param.GetEncodingV();
mac.Init(keyParameter);
mac.BlockUpdate(in_enc, inOff, inLen);
mac.BlockUpdate(encodingV, 0, encodingV.Length);
mac.DoFinal(macBuf, 0);
inOff += inLen;
byte[] a = Arrays.CopyOfRange(in_enc, inOff, inOff + macBuf.Length);
if (!Arrays.ConstantTimeAreEqual(a, macBuf))
{
throw new InvalidCipherTextException("Invalid MAC.");
}
return array;
}
private byte[] EncryptBlock(byte[] input, int inOff, int inLen, byte[] z)
{
byte[] array = null;
KeyParameter keyParameter = null;
KdfParameters kParam = new KdfParameters(z, param.GetDerivationV());
int num = 0;
int macKeySize = param.MacKeySize;
if (cipher == null)
{
byte[] array2 = GenerateKdfBytes(kParam, inLen + macKeySize / 8);
array = new byte[inLen + mac.GetMacSize()];
num = inLen;
for (int i = 0; i != inLen; i++)
{
array[i] = (byte)(input[inOff + i] ^ array2[i]);
}
keyParameter = new KeyParameter(array2, inLen, macKeySize / 8);
}
else
{
int cipherKeySize = ((IesWithCipherParameters)param).CipherKeySize;
byte[] key = GenerateKdfBytes(kParam, cipherKeySize / 8 + macKeySize / 8);
cipher.Init(forEncryption: true, new KeyParameter(key, 0, cipherKeySize / 8));
num = cipher.GetOutputSize(inLen);
byte[] array3 = new byte[num];
int num2 = cipher.ProcessBytes(input, inOff, inLen, array3, 0);
num2 += cipher.DoFinal(array3, num2);
array = new byte[num2 + mac.GetMacSize()];
num = num2;
Array.Copy(array3, 0, array, 0, num2);
keyParameter = new KeyParameter(key, cipherKeySize / 8, macKeySize / 8);
}
byte[] encodingV = param.GetEncodingV();
mac.Init(keyParameter);
mac.BlockUpdate(array, 0, num);
mac.BlockUpdate(encodingV, 0, encodingV.Length);
mac.DoFinal(array, num);
return array;
}
private byte[] GenerateKdfBytes(KdfParameters kParam, int length)
{
byte[] array = new byte[length];
kdf.Init(kParam);
kdf.GenerateBytes(array, 0, array.Length);
return array;
}
public virtual byte[] ProcessBlock(byte[] input, int inOff, int inLen)
{
agree.Init(privParam);
BigInteger n = agree.CalculateAgreement(pubParam);
byte[] array = BigIntegers.AsUnsignedByteArray(agree.GetFieldSize(), n);
try
{
return forEncryption ? EncryptBlock(input, inOff, inLen, array) : DecryptBlock(input, inOff, inLen, array);
}
finally
{
Array.Clear(array, 0, array.Length);
}
}
}

View File

@@ -0,0 +1,191 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Utilities;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class IsaacEngine : IStreamCipher
{
private static readonly int sizeL = 8;
private static readonly int stateArraySize = sizeL << 5;
private uint[] engineState = null;
private uint[] results = null;
private uint a = 0u;
private uint b = 0u;
private uint c = 0u;
private int index = 0;
private byte[] keyStream = new byte[stateArraySize << 2];
private byte[] workingKey = null;
private bool initialised = false;
public virtual string AlgorithmName => "ISAAC";
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
if (!(parameters is KeyParameter))
{
throw new ArgumentException("invalid parameter passed to ISAAC Init - " + Platform.GetTypeName(parameters), "parameters");
}
KeyParameter keyParameter = (KeyParameter)parameters;
setKey(keyParameter.GetKey());
}
public virtual byte ReturnByte(byte input)
{
if (index == 0)
{
isaac();
keyStream = Pack.UInt32_To_BE(results);
}
byte result = (byte)(keyStream[index] ^ input);
index = (index + 1) & 0x3FF;
return result;
}
public virtual void ProcessBytes(byte[] input, int inOff, int len, byte[] output, int outOff)
{
if (!initialised)
{
throw new InvalidOperationException(AlgorithmName + " not initialised");
}
Check.DataLength(input, inOff, len, "input buffer too short");
Check.OutputLength(output, outOff, len, "output buffer too short");
for (int i = 0; i < len; i++)
{
if (index == 0)
{
isaac();
keyStream = Pack.UInt32_To_BE(results);
}
output[i + outOff] = (byte)(keyStream[index] ^ input[i + inOff]);
index = (index + 1) & 0x3FF;
}
}
public virtual void Reset()
{
setKey(workingKey);
}
private void setKey(byte[] keyBytes)
{
workingKey = keyBytes;
if (engineState == null)
{
engineState = new uint[stateArraySize];
}
if (results == null)
{
results = new uint[stateArraySize];
}
for (int i = 0; i < stateArraySize; i++)
{
engineState[i] = (results[i] = 0u);
}
a = (b = (c = 0u));
index = 0;
byte[] array = new byte[keyBytes.Length + (keyBytes.Length & 3)];
Array.Copy(keyBytes, 0, array, 0, keyBytes.Length);
for (int i = 0; i < array.Length; i += 4)
{
results[i >> 2] = Pack.LE_To_UInt32(array, i);
}
uint[] array2 = new uint[sizeL];
for (int i = 0; i < sizeL; i++)
{
array2[i] = 2654435769u;
}
for (int i = 0; i < 4; i++)
{
mix(array2);
}
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < stateArraySize; j += sizeL)
{
for (int k = 0; k < sizeL; k++)
{
uint[] array4;
uint[] array3 = (array4 = array2);
int num = k;
nint num2 = num;
array3[num] = array4[num2] + ((i < 1) ? results[j + k] : engineState[j + k]);
}
mix(array2);
for (int k = 0; k < sizeL; k++)
{
engineState[j + k] = array2[k];
}
}
}
isaac();
initialised = true;
}
private void isaac()
{
b += ++c;
for (int i = 0; i < stateArraySize; i++)
{
uint num = engineState[i];
switch (i & 3)
{
case 0:
a ^= a << 13;
break;
case 1:
a ^= a >> 6;
break;
case 2:
a ^= a << 2;
break;
case 3:
a ^= a >> 16;
break;
}
a += engineState[(i + 128) & 0xFF];
uint num2 = (engineState[i] = engineState[(num >> 2) & 0xFF] + a + b);
results[i] = (b = engineState[(num2 >> 10) & 0xFF] + num);
}
}
private void mix(uint[] x)
{
uint[] array;
(array = x)[0] = array[0] ^ (x[1] << 11);
(array = x)[3] = array[3] + x[0];
(array = x)[1] = array[1] + x[2];
(array = x)[1] = array[1] ^ (x[2] >> 2);
(array = x)[4] = array[4] + x[1];
(array = x)[2] = array[2] + x[3];
(array = x)[2] = array[2] ^ (x[3] << 8);
(array = x)[5] = array[5] + x[2];
(array = x)[3] = array[3] + x[4];
(array = x)[3] = array[3] ^ (x[4] >> 16);
(array = x)[6] = array[6] + x[3];
(array = x)[4] = array[4] + x[5];
(array = x)[4] = array[4] ^ (x[5] << 10);
(array = x)[7] = array[7] + x[4];
(array = x)[5] = array[5] + x[6];
(array = x)[5] = array[5] ^ (x[6] >> 4);
(array = x)[0] = array[0] + x[5];
(array = x)[6] = array[6] + x[7];
(array = x)[6] = array[6] ^ (x[7] << 8);
(array = x)[1] = array[1] + x[6];
(array = x)[7] = array[7] + x[0];
(array = x)[7] = array[7] ^ (x[0] >> 9);
(array = x)[2] = array[2] + x[7];
(array = x)[0] = array[0] + x[1];
}
}

View File

@@ -0,0 +1,204 @@
using System;
using System.Collections;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class NaccacheSternEngine : IAsymmetricBlockCipher
{
private bool forEncryption;
private NaccacheSternKeyParameters key;
private IList[] lookup = null;
public string AlgorithmName => "NaccacheStern";
[Obsolete("Remove: no longer used")]
public virtual bool Debug
{
set
{
}
}
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
this.forEncryption = forEncryption;
if (parameters is ParametersWithRandom)
{
parameters = ((ParametersWithRandom)parameters).Parameters;
}
key = (NaccacheSternKeyParameters)parameters;
if (this.forEncryption)
{
return;
}
NaccacheSternPrivateKeyParameters naccacheSternPrivateKeyParameters = (NaccacheSternPrivateKeyParameters)key;
IList smallPrimesList = naccacheSternPrivateKeyParameters.SmallPrimesList;
lookup = new IList[smallPrimesList.Count];
for (int i = 0; i < smallPrimesList.Count; i++)
{
BigInteger bigInteger = (BigInteger)smallPrimesList[i];
int intValue = bigInteger.IntValue;
lookup[i] = Platform.CreateArrayList(intValue);
lookup[i].Add(BigInteger.One);
BigInteger bigInteger2 = BigInteger.Zero;
for (int j = 1; j < intValue; j++)
{
bigInteger2 = bigInteger2.Add(naccacheSternPrivateKeyParameters.PhiN);
BigInteger e = bigInteger2.Divide(bigInteger);
lookup[i].Add(naccacheSternPrivateKeyParameters.G.ModPow(e, naccacheSternPrivateKeyParameters.Modulus));
}
}
}
public virtual int GetInputBlockSize()
{
if (forEncryption)
{
return (key.LowerSigmaBound + 7) / 8 - 1;
}
return key.Modulus.BitLength / 8 + 1;
}
public virtual int GetOutputBlockSize()
{
if (forEncryption)
{
return key.Modulus.BitLength / 8 + 1;
}
return (key.LowerSigmaBound + 7) / 8 - 1;
}
public virtual byte[] ProcessBlock(byte[] inBytes, int inOff, int length)
{
if (key == null)
{
throw new InvalidOperationException("NaccacheStern engine not initialised");
}
if (length > GetInputBlockSize() + 1)
{
throw new DataLengthException("input too large for Naccache-Stern cipher.\n");
}
if (!forEncryption && length < GetInputBlockSize())
{
throw new InvalidCipherTextException("BlockLength does not match modulus for Naccache-Stern cipher.\n");
}
BigInteger bigInteger = new BigInteger(1, inBytes, inOff, length);
if (forEncryption)
{
return Encrypt(bigInteger);
}
IList list = Platform.CreateArrayList();
NaccacheSternPrivateKeyParameters naccacheSternPrivateKeyParameters = (NaccacheSternPrivateKeyParameters)key;
IList smallPrimesList = naccacheSternPrivateKeyParameters.SmallPrimesList;
for (int i = 0; i < smallPrimesList.Count; i++)
{
BigInteger value = bigInteger.ModPow(naccacheSternPrivateKeyParameters.PhiN.Divide((BigInteger)smallPrimesList[i]), naccacheSternPrivateKeyParameters.Modulus);
IList list2 = lookup[i];
if (lookup[i].Count != ((BigInteger)smallPrimesList[i]).IntValue)
{
throw new InvalidCipherTextException("Error in lookup Array for " + ((BigInteger)smallPrimesList[i]).IntValue + ": Size mismatch. Expected ArrayList with length " + ((BigInteger)smallPrimesList[i]).IntValue + " but found ArrayList of length " + lookup[i].Count);
}
int num = list2.IndexOf(value);
if (num == -1)
{
throw new InvalidCipherTextException("Lookup failed");
}
list.Add(BigInteger.ValueOf(num));
}
BigInteger bigInteger2 = chineseRemainder(list, smallPrimesList);
return bigInteger2.ToByteArray();
}
public virtual byte[] Encrypt(BigInteger plain)
{
byte[] array = new byte[key.Modulus.BitLength / 8 + 1];
byte[] array2 = key.G.ModPow(plain, key.Modulus).ToByteArray();
Array.Copy(array2, 0, array, array.Length - array2.Length, array2.Length);
return array;
}
public virtual byte[] AddCryptedBlocks(byte[] block1, byte[] block2)
{
if (forEncryption)
{
if (block1.Length > GetOutputBlockSize() || block2.Length > GetOutputBlockSize())
{
throw new InvalidCipherTextException("BlockLength too large for simple addition.\n");
}
}
else if (block1.Length > GetInputBlockSize() || block2.Length > GetInputBlockSize())
{
throw new InvalidCipherTextException("BlockLength too large for simple addition.\n");
}
BigInteger bigInteger = new BigInteger(1, block1);
BigInteger val = new BigInteger(1, block2);
BigInteger bigInteger2 = bigInteger.Multiply(val);
bigInteger2 = bigInteger2.Mod(key.Modulus);
byte[] array = new byte[key.Modulus.BitLength / 8 + 1];
byte[] array2 = bigInteger2.ToByteArray();
Array.Copy(array2, 0, array, array.Length - array2.Length, array2.Length);
return array;
}
public virtual byte[] ProcessData(byte[] data)
{
if (data.Length > GetInputBlockSize())
{
int inputBlockSize = GetInputBlockSize();
int outputBlockSize = GetOutputBlockSize();
int num = 0;
int num2 = 0;
byte[] array = new byte[(data.Length / inputBlockSize + 1) * outputBlockSize];
while (num < data.Length)
{
byte[] array2;
if (num + inputBlockSize < data.Length)
{
array2 = ProcessBlock(data, num, inputBlockSize);
num += inputBlockSize;
}
else
{
array2 = ProcessBlock(data, num, data.Length - num);
num += data.Length - num;
}
if (array2 != null)
{
array2.CopyTo(array, num2);
num2 += array2.Length;
continue;
}
throw new InvalidCipherTextException("cipher returned null");
}
byte[] array3 = new byte[num2];
Array.Copy(array, 0, array3, 0, num2);
return array3;
}
return ProcessBlock(data, 0, data.Length);
}
private static BigInteger chineseRemainder(IList congruences, IList primes)
{
BigInteger bigInteger = BigInteger.Zero;
BigInteger bigInteger2 = BigInteger.One;
for (int i = 0; i < primes.Count; i++)
{
bigInteger2 = bigInteger2.Multiply((BigInteger)primes[i]);
}
for (int j = 0; j < primes.Count; j++)
{
BigInteger bigInteger3 = (BigInteger)primes[j];
BigInteger bigInteger4 = bigInteger2.Divide(bigInteger3);
BigInteger val = bigInteger4.ModInverse(bigInteger3);
BigInteger bigInteger5 = bigInteger4.Multiply(val);
bigInteger5 = bigInteger5.Multiply((BigInteger)congruences[j]);
bigInteger = bigInteger.Add(bigInteger5);
}
return bigInteger.Mod(bigInteger2);
}
}

View File

@@ -0,0 +1,193 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Utilities;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class NoekeonEngine : IBlockCipher
{
private const int GenericSize = 16;
private static readonly uint[] nullVector;
private static readonly uint[] roundConstants;
private uint[] state = new uint[4];
private uint[] subKeys = new uint[4];
private uint[] decryptKeys = new uint[4];
private bool _initialised;
private bool _forEncryption;
public virtual string AlgorithmName => "Noekeon";
public virtual bool IsPartialBlockOkay => false;
public NoekeonEngine()
{
_initialised = false;
}
public virtual int GetBlockSize()
{
return 16;
}
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
if (!(parameters is KeyParameter))
{
throw new ArgumentException("Invalid parameters passed to Noekeon init - " + Platform.GetTypeName(parameters), "parameters");
}
_forEncryption = forEncryption;
_initialised = true;
KeyParameter keyParameter = (KeyParameter)parameters;
setKey(keyParameter.GetKey());
}
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
{
if (!_initialised)
{
throw new InvalidOperationException(AlgorithmName + " not initialised");
}
Check.DataLength(input, inOff, 16, "input buffer too short");
Check.OutputLength(output, outOff, 16, "output buffer too short");
if (!_forEncryption)
{
return decryptBlock(input, inOff, output, outOff);
}
return encryptBlock(input, inOff, output, outOff);
}
public virtual void Reset()
{
}
private void setKey(byte[] key)
{
subKeys[0] = Pack.BE_To_UInt32(key, 0);
subKeys[1] = Pack.BE_To_UInt32(key, 4);
subKeys[2] = Pack.BE_To_UInt32(key, 8);
subKeys[3] = Pack.BE_To_UInt32(key, 12);
}
private int encryptBlock(byte[] input, int inOff, byte[] output, int outOff)
{
state[0] = Pack.BE_To_UInt32(input, inOff);
state[1] = Pack.BE_To_UInt32(input, inOff + 4);
state[2] = Pack.BE_To_UInt32(input, inOff + 8);
state[3] = Pack.BE_To_UInt32(input, inOff + 12);
int i;
uint[] array;
for (i = 0; i < 16; i++)
{
(array = state)[0] = array[0] ^ roundConstants[i];
theta(state, subKeys);
pi1(state);
gamma(state);
pi2(state);
}
(array = state)[0] = array[0] ^ roundConstants[i];
theta(state, subKeys);
Pack.UInt32_To_BE(state[0], output, outOff);
Pack.UInt32_To_BE(state[1], output, outOff + 4);
Pack.UInt32_To_BE(state[2], output, outOff + 8);
Pack.UInt32_To_BE(state[3], output, outOff + 12);
return 16;
}
private int decryptBlock(byte[] input, int inOff, byte[] output, int outOff)
{
state[0] = Pack.BE_To_UInt32(input, inOff);
state[1] = Pack.BE_To_UInt32(input, inOff + 4);
state[2] = Pack.BE_To_UInt32(input, inOff + 8);
state[3] = Pack.BE_To_UInt32(input, inOff + 12);
Array.Copy(subKeys, 0, decryptKeys, 0, subKeys.Length);
theta(decryptKeys, nullVector);
int num;
uint[] array;
for (num = 16; num > 0; num--)
{
theta(state, decryptKeys);
(array = state)[0] = array[0] ^ roundConstants[num];
pi1(state);
gamma(state);
pi2(state);
}
theta(state, decryptKeys);
(array = state)[0] = array[0] ^ roundConstants[num];
Pack.UInt32_To_BE(state[0], output, outOff);
Pack.UInt32_To_BE(state[1], output, outOff + 4);
Pack.UInt32_To_BE(state[2], output, outOff + 8);
Pack.UInt32_To_BE(state[3], output, outOff + 12);
return 16;
}
private void gamma(uint[] a)
{
uint[] array;
(array = a)[1] = array[1] ^ (~a[3] & ~a[2]);
(array = a)[0] = array[0] ^ (a[2] & a[1]);
uint num = a[3];
a[3] = a[0];
a[0] = num;
(array = a)[2] = array[2] ^ (a[0] ^ a[1] ^ a[3]);
(array = a)[1] = array[1] ^ (~a[3] & ~a[2]);
(array = a)[0] = array[0] ^ (a[2] & a[1]);
}
private void theta(uint[] a, uint[] k)
{
uint num = a[0] ^ a[2];
num ^= rotl(num, 8) ^ rotl(num, 24);
uint[] array;
(array = a)[1] = array[1] ^ num;
(array = a)[3] = array[3] ^ num;
for (int i = 0; i < 4; i++)
{
uint[] array2 = (array = a);
int num2 = i;
nint num3 = num2;
array2[num2] = array[num3] ^ k[i];
}
num = a[1] ^ a[3];
num ^= rotl(num, 8) ^ rotl(num, 24);
(array = a)[0] = array[0] ^ num;
(array = a)[2] = array[2] ^ num;
}
private void pi1(uint[] a)
{
a[1] = rotl(a[1], 1);
a[2] = rotl(a[2], 5);
a[3] = rotl(a[3], 2);
}
private void pi2(uint[] a)
{
a[1] = rotl(a[1], 31);
a[2] = rotl(a[2], 27);
a[3] = rotl(a[3], 30);
}
private uint rotl(uint x, int y)
{
return (x << y) | (x >> 32 - y);
}
static NoekeonEngine()
{
uint[] array = new uint[4];
nullVector = array;
roundConstants = new uint[17]
{
128u, 27u, 54u, 108u, 216u, 171u, 77u, 154u, 47u, 94u,
188u, 99u, 198u, 151u, 53u, 106u, 212u
};
}
}

View File

@@ -0,0 +1,43 @@
using System;
namespace Org.BouncyCastle.Crypto.Engines;
public class NullEngine : IBlockCipher
{
private const int BlockSize = 1;
private bool initialised;
public virtual string AlgorithmName => "Null";
public virtual bool IsPartialBlockOkay => true;
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
initialised = true;
}
public virtual int GetBlockSize()
{
return 1;
}
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
{
if (!initialised)
{
throw new InvalidOperationException("Null engine not initialised");
}
Check.DataLength(input, inOff, 1, "input buffer too short");
Check.OutputLength(output, outOff, 1, "output buffer too short");
for (int i = 0; i < 1; i++)
{
output[outOff + i] = input[inOff + i];
}
return 1;
}
public virtual void Reset()
{
}
}

View File

@@ -0,0 +1,225 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class RC2Engine : IBlockCipher
{
private const int BLOCK_SIZE = 8;
private static readonly byte[] piTable = new byte[256]
{
217, 120, 249, 196, 25, 221, 181, 237, 40, 233,
253, 121, 74, 160, 216, 157, 198, 126, 55, 131,
43, 118, 83, 142, 98, 76, 100, 136, 68, 139,
251, 162, 23, 154, 89, 245, 135, 179, 79, 19,
97, 69, 109, 141, 9, 129, 125, 50, 189, 143,
64, 235, 134, 183, 123, 11, 240, 149, 33, 34,
92, 107, 78, 130, 84, 214, 101, 147, 206, 96,
178, 28, 115, 86, 192, 20, 167, 140, 241, 220,
18, 117, 202, 31, 59, 190, 228, 209, 66, 61,
212, 48, 163, 60, 182, 38, 111, 191, 14, 218,
70, 105, 7, 87, 39, 242, 29, 155, 188, 148,
67, 3, 248, 17, 199, 246, 144, 239, 62, 231,
6, 195, 213, 47, 200, 102, 30, 215, 8, 232,
234, 222, 128, 82, 238, 247, 132, 170, 114, 172,
53, 77, 106, 42, 150, 26, 210, 113, 90, 21,
73, 116, 75, 159, 208, 94, 4, 24, 164, 236,
194, 224, 65, 110, 15, 81, 203, 204, 36, 145,
175, 80, 161, 244, 112, 57, 153, 124, 58, 133,
35, 184, 180, 122, 252, 2, 54, 91, 37, 85,
151, 49, 45, 93, 250, 152, 227, 138, 146, 174,
5, 223, 41, 16, 103, 108, 186, 201, 211, 0,
230, 207, 225, 158, 168, 44, 99, 22, 1, 63,
88, 226, 137, 169, 13, 56, 52, 27, 171, 51,
255, 176, 187, 72, 12, 95, 185, 177, 205, 46,
197, 243, 219, 71, 229, 165, 156, 119, 10, 166,
32, 104, 254, 127, 193, 173
};
private int[] workingKey;
private bool encrypting;
public virtual string AlgorithmName => "RC2";
public virtual bool IsPartialBlockOkay => false;
private int[] GenerateWorkingKey(byte[] key, int bits)
{
int[] array = new int[128];
for (int i = 0; i != key.Length; i++)
{
array[i] = key[i] & 0xFF;
}
int num = key.Length;
int num3;
if (num < 128)
{
int num2 = 0;
num3 = array[num - 1];
do
{
num3 = piTable[(num3 + array[num2++]) & 0xFF] & 0xFF;
array[num++] = num3;
}
while (num < 128);
}
num = bits + 7 >> 3;
num3 = (array[128 - num] = piTable[array[128 - num] & (255 >> (7 & -bits))] & 0xFF);
for (int num4 = 128 - num - 1; num4 >= 0; num4--)
{
num3 = (array[num4] = piTable[num3 ^ array[num4 + num]] & 0xFF);
}
int[] array2 = new int[64];
for (int j = 0; j != array2.Length; j++)
{
array2[j] = array[2 * j] + (array[2 * j + 1] << 8);
}
return array2;
}
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
encrypting = forEncryption;
if (parameters is RC2Parameters)
{
RC2Parameters rC2Parameters = (RC2Parameters)parameters;
workingKey = GenerateWorkingKey(rC2Parameters.GetKey(), rC2Parameters.EffectiveKeyBits);
return;
}
if (parameters is KeyParameter)
{
KeyParameter keyParameter = (KeyParameter)parameters;
byte[] key = keyParameter.GetKey();
workingKey = GenerateWorkingKey(key, key.Length * 8);
return;
}
throw new ArgumentException("invalid parameter passed to RC2 init - " + Platform.GetTypeName(parameters));
}
public virtual void Reset()
{
}
public virtual int GetBlockSize()
{
return 8;
}
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
{
if (workingKey == null)
{
throw new InvalidOperationException("RC2 engine not initialised");
}
Check.DataLength(input, inOff, 8, "input buffer too short");
Check.OutputLength(output, outOff, 8, "output buffer too short");
if (encrypting)
{
EncryptBlock(input, inOff, output, outOff);
}
else
{
DecryptBlock(input, inOff, output, outOff);
}
return 8;
}
private int RotateWordLeft(int x, int y)
{
x &= 0xFFFF;
return (x << y) | (x >> 16 - y);
}
private void EncryptBlock(byte[] input, int inOff, byte[] outBytes, int outOff)
{
int num = ((input[inOff + 7] & 0xFF) << 8) + (input[inOff + 6] & 0xFF);
int num2 = ((input[inOff + 5] & 0xFF) << 8) + (input[inOff + 4] & 0xFF);
int num3 = ((input[inOff + 3] & 0xFF) << 8) + (input[inOff + 2] & 0xFF);
int num4 = ((input[inOff + 1] & 0xFF) << 8) + (input[inOff] & 0xFF);
for (int i = 0; i <= 16; i += 4)
{
num4 = RotateWordLeft(num4 + (num3 & ~num) + (num2 & num) + workingKey[i], 1);
num3 = RotateWordLeft(num3 + (num2 & ~num4) + (num & num4) + workingKey[i + 1], 2);
num2 = RotateWordLeft(num2 + (num & ~num3) + (num4 & num3) + workingKey[i + 2], 3);
num = RotateWordLeft(num + (num4 & ~num2) + (num3 & num2) + workingKey[i + 3], 5);
}
num4 += workingKey[num & 0x3F];
num3 += workingKey[num4 & 0x3F];
num2 += workingKey[num3 & 0x3F];
num += workingKey[num2 & 0x3F];
for (int j = 20; j <= 40; j += 4)
{
num4 = RotateWordLeft(num4 + (num3 & ~num) + (num2 & num) + workingKey[j], 1);
num3 = RotateWordLeft(num3 + (num2 & ~num4) + (num & num4) + workingKey[j + 1], 2);
num2 = RotateWordLeft(num2 + (num & ~num3) + (num4 & num3) + workingKey[j + 2], 3);
num = RotateWordLeft(num + (num4 & ~num2) + (num3 & num2) + workingKey[j + 3], 5);
}
num4 += workingKey[num & 0x3F];
num3 += workingKey[num4 & 0x3F];
num2 += workingKey[num3 & 0x3F];
num += workingKey[num2 & 0x3F];
for (int k = 44; k < 64; k += 4)
{
num4 = RotateWordLeft(num4 + (num3 & ~num) + (num2 & num) + workingKey[k], 1);
num3 = RotateWordLeft(num3 + (num2 & ~num4) + (num & num4) + workingKey[k + 1], 2);
num2 = RotateWordLeft(num2 + (num & ~num3) + (num4 & num3) + workingKey[k + 2], 3);
num = RotateWordLeft(num + (num4 & ~num2) + (num3 & num2) + workingKey[k + 3], 5);
}
outBytes[outOff] = (byte)num4;
outBytes[outOff + 1] = (byte)(num4 >> 8);
outBytes[outOff + 2] = (byte)num3;
outBytes[outOff + 3] = (byte)(num3 >> 8);
outBytes[outOff + 4] = (byte)num2;
outBytes[outOff + 5] = (byte)(num2 >> 8);
outBytes[outOff + 6] = (byte)num;
outBytes[outOff + 7] = (byte)(num >> 8);
}
private void DecryptBlock(byte[] input, int inOff, byte[] outBytes, int outOff)
{
int num = ((input[inOff + 7] & 0xFF) << 8) + (input[inOff + 6] & 0xFF);
int num2 = ((input[inOff + 5] & 0xFF) << 8) + (input[inOff + 4] & 0xFF);
int num3 = ((input[inOff + 3] & 0xFF) << 8) + (input[inOff + 2] & 0xFF);
int num4 = ((input[inOff + 1] & 0xFF) << 8) + (input[inOff] & 0xFF);
for (int num5 = 60; num5 >= 44; num5 -= 4)
{
num = RotateWordLeft(num, 11) - ((num4 & ~num2) + (num3 & num2) + workingKey[num5 + 3]);
num2 = RotateWordLeft(num2, 13) - ((num & ~num3) + (num4 & num3) + workingKey[num5 + 2]);
num3 = RotateWordLeft(num3, 14) - ((num2 & ~num4) + (num & num4) + workingKey[num5 + 1]);
num4 = RotateWordLeft(num4, 15) - ((num3 & ~num) + (num2 & num) + workingKey[num5]);
}
num -= workingKey[num2 & 0x3F];
num2 -= workingKey[num3 & 0x3F];
num3 -= workingKey[num4 & 0x3F];
num4 -= workingKey[num & 0x3F];
for (int num6 = 40; num6 >= 20; num6 -= 4)
{
num = RotateWordLeft(num, 11) - ((num4 & ~num2) + (num3 & num2) + workingKey[num6 + 3]);
num2 = RotateWordLeft(num2, 13) - ((num & ~num3) + (num4 & num3) + workingKey[num6 + 2]);
num3 = RotateWordLeft(num3, 14) - ((num2 & ~num4) + (num & num4) + workingKey[num6 + 1]);
num4 = RotateWordLeft(num4, 15) - ((num3 & ~num) + (num2 & num) + workingKey[num6]);
}
num -= workingKey[num2 & 0x3F];
num2 -= workingKey[num3 & 0x3F];
num3 -= workingKey[num4 & 0x3F];
num4 -= workingKey[num & 0x3F];
for (int num7 = 16; num7 >= 0; num7 -= 4)
{
num = RotateWordLeft(num, 11) - ((num4 & ~num2) + (num3 & num2) + workingKey[num7 + 3]);
num2 = RotateWordLeft(num2, 13) - ((num & ~num3) + (num4 & num3) + workingKey[num7 + 2]);
num3 = RotateWordLeft(num3, 14) - ((num2 & ~num4) + (num & num4) + workingKey[num7 + 1]);
num4 = RotateWordLeft(num4, 15) - ((num3 & ~num) + (num2 & num) + workingKey[num7]);
}
outBytes[outOff] = (byte)num4;
outBytes[outOff + 1] = (byte)(num4 >> 8);
outBytes[outOff + 2] = (byte)num3;
outBytes[outOff + 3] = (byte)(num3 >> 8);
outBytes[outOff + 4] = (byte)num2;
outBytes[outOff + 5] = (byte)(num2 >> 8);
outBytes[outOff + 6] = (byte)num;
outBytes[outOff + 7] = (byte)(num >> 8);
}
}

View File

@@ -0,0 +1,198 @@
using System;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class RC2WrapEngine : IWrapper
{
private CbcBlockCipher engine;
private ICipherParameters parameters;
private ParametersWithIV paramPlusIV;
private byte[] iv;
private bool forWrapping;
private SecureRandom sr;
private static readonly byte[] IV2 = new byte[8] { 74, 221, 162, 44, 121, 232, 33, 5 };
private IDigest sha1 = new Sha1Digest();
private byte[] digest = new byte[20];
public virtual string AlgorithmName => "RC2";
public virtual void Init(bool forWrapping, ICipherParameters parameters)
{
this.forWrapping = forWrapping;
engine = new CbcBlockCipher(new RC2Engine());
if (parameters is ParametersWithRandom)
{
ParametersWithRandom parametersWithRandom = (ParametersWithRandom)parameters;
sr = parametersWithRandom.Random;
parameters = parametersWithRandom.Parameters;
}
else
{
sr = new SecureRandom();
}
if (parameters is ParametersWithIV)
{
if (!forWrapping)
{
throw new ArgumentException("You should not supply an IV for unwrapping");
}
paramPlusIV = (ParametersWithIV)parameters;
iv = paramPlusIV.GetIV();
this.parameters = paramPlusIV.Parameters;
if (iv.Length != 8)
{
throw new ArgumentException("IV is not 8 octets");
}
}
else
{
this.parameters = parameters;
if (this.forWrapping)
{
iv = new byte[8];
sr.NextBytes(iv);
paramPlusIV = new ParametersWithIV(this.parameters, iv);
}
}
}
public virtual byte[] Wrap(byte[] input, int inOff, int length)
{
if (!forWrapping)
{
throw new InvalidOperationException("Not initialized for wrapping");
}
int num = length + 1;
if (num % 8 != 0)
{
num += 8 - num % 8;
}
byte[] array = new byte[num];
array[0] = (byte)length;
Array.Copy(input, inOff, array, 1, length);
byte[] array2 = new byte[array.Length - length - 1];
if (array2.Length > 0)
{
sr.NextBytes(array2);
Array.Copy(array2, 0, array, length + 1, array2.Length);
}
byte[] array3 = CalculateCmsKeyChecksum(array);
byte[] array4 = new byte[array.Length + array3.Length];
Array.Copy(array, 0, array4, 0, array.Length);
Array.Copy(array3, 0, array4, array.Length, array3.Length);
byte[] array5 = new byte[array4.Length];
Array.Copy(array4, 0, array5, 0, array4.Length);
int num2 = array4.Length / engine.GetBlockSize();
if (array4.Length % engine.GetBlockSize() != 0)
{
throw new InvalidOperationException("Not multiple of block length");
}
engine.Init(forEncryption: true, paramPlusIV);
for (int i = 0; i < num2; i++)
{
int num3 = i * engine.GetBlockSize();
engine.ProcessBlock(array5, num3, array5, num3);
}
byte[] array6 = new byte[iv.Length + array5.Length];
Array.Copy(iv, 0, array6, 0, iv.Length);
Array.Copy(array5, 0, array6, iv.Length, array5.Length);
byte[] array7 = new byte[array6.Length];
for (int j = 0; j < array6.Length; j++)
{
array7[j] = array6[^(j + 1)];
}
ParametersWithIV parametersWithIV = new ParametersWithIV(parameters, IV2);
engine.Init(forEncryption: true, parametersWithIV);
for (int k = 0; k < num2 + 1; k++)
{
int num4 = k * engine.GetBlockSize();
engine.ProcessBlock(array7, num4, array7, num4);
}
return array7;
}
public virtual byte[] Unwrap(byte[] input, int inOff, int length)
{
if (forWrapping)
{
throw new InvalidOperationException("Not set for unwrapping");
}
if (input == null)
{
throw new InvalidCipherTextException("Null pointer as ciphertext");
}
if (length % engine.GetBlockSize() != 0)
{
throw new InvalidCipherTextException("Ciphertext not multiple of " + engine.GetBlockSize());
}
ParametersWithIV parametersWithIV = new ParametersWithIV(parameters, IV2);
engine.Init(forEncryption: false, parametersWithIV);
byte[] array = new byte[length];
Array.Copy(input, inOff, array, 0, length);
for (int i = 0; i < array.Length / engine.GetBlockSize(); i++)
{
int num = i * engine.GetBlockSize();
engine.ProcessBlock(array, num, array, num);
}
byte[] array2 = new byte[array.Length];
for (int j = 0; j < array.Length; j++)
{
array2[j] = array[^(j + 1)];
}
iv = new byte[8];
byte[] array3 = new byte[array2.Length - 8];
Array.Copy(array2, 0, iv, 0, 8);
Array.Copy(array2, 8, array3, 0, array2.Length - 8);
paramPlusIV = new ParametersWithIV(parameters, iv);
engine.Init(forEncryption: false, paramPlusIV);
byte[] array4 = new byte[array3.Length];
Array.Copy(array3, 0, array4, 0, array3.Length);
for (int k = 0; k < array4.Length / engine.GetBlockSize(); k++)
{
int num2 = k * engine.GetBlockSize();
engine.ProcessBlock(array4, num2, array4, num2);
}
byte[] array5 = new byte[array4.Length - 8];
byte[] array6 = new byte[8];
Array.Copy(array4, 0, array5, 0, array4.Length - 8);
Array.Copy(array4, array4.Length - 8, array6, 0, 8);
if (!CheckCmsKeyChecksum(array5, array6))
{
throw new InvalidCipherTextException("Checksum inside ciphertext is corrupted");
}
if (array5.Length - ((array5[0] & 0xFF) + 1) > 7)
{
throw new InvalidCipherTextException("too many pad bytes (" + (array5.Length - ((array5[0] & 0xFF) + 1)) + ")");
}
byte[] array7 = new byte[array5[0]];
Array.Copy(array5, 1, array7, 0, array7.Length);
return array7;
}
private byte[] CalculateCmsKeyChecksum(byte[] key)
{
sha1.BlockUpdate(key, 0, key.Length);
sha1.DoFinal(digest, 0);
byte[] array = new byte[8];
Array.Copy(digest, 0, array, 0, 8);
return array;
}
private bool CheckCmsKeyChecksum(byte[] key, byte[] checksum)
{
return Arrays.ConstantTimeAreEqual(CalculateCmsKeyChecksum(key), checksum);
}
}

View File

@@ -0,0 +1,86 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class RC4Engine : IStreamCipher
{
private static readonly int STATE_LENGTH = 256;
private byte[] engineState;
private int x;
private int y;
private byte[] workingKey;
public virtual string AlgorithmName => "RC4";
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
if (parameters is KeyParameter)
{
workingKey = ((KeyParameter)parameters).GetKey();
SetKey(workingKey);
return;
}
throw new ArgumentException("invalid parameter passed to RC4 init - " + Platform.GetTypeName(parameters));
}
public virtual byte ReturnByte(byte input)
{
x = (x + 1) & 0xFF;
y = (engineState[x] + y) & 0xFF;
byte b = engineState[x];
engineState[x] = engineState[y];
engineState[y] = b;
return (byte)(input ^ engineState[(engineState[x] + engineState[y]) & 0xFF]);
}
public virtual void ProcessBytes(byte[] input, int inOff, int length, byte[] output, int outOff)
{
Check.DataLength(input, inOff, length, "input buffer too short");
Check.OutputLength(output, outOff, length, "output buffer too short");
for (int i = 0; i < length; i++)
{
x = (x + 1) & 0xFF;
y = (engineState[x] + y) & 0xFF;
byte b = engineState[x];
engineState[x] = engineState[y];
engineState[y] = b;
output[i + outOff] = (byte)(input[i + inOff] ^ engineState[(engineState[x] + engineState[y]) & 0xFF]);
}
}
public virtual void Reset()
{
SetKey(workingKey);
}
private void SetKey(byte[] keyBytes)
{
workingKey = keyBytes;
x = 0;
y = 0;
if (engineState == null)
{
engineState = new byte[STATE_LENGTH];
}
for (int i = 0; i < STATE_LENGTH; i++)
{
engineState[i] = (byte)i;
}
int num = 0;
int num2 = 0;
for (int j = 0; j < STATE_LENGTH; j++)
{
num2 = ((keyBytes[num] & 0xFF) + engineState[j] + num2) & 0xFF;
byte b = engineState[j];
engineState[j] = engineState[num2];
engineState[num2] = b;
num = (num + 1) % keyBytes.Length;
}
}
}

View File

@@ -0,0 +1,147 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class RC532Engine : IBlockCipher
{
private int _noRounds;
private int[] _S;
private static readonly int P32 = -1209970333;
private static readonly int Q32 = -1640531527;
private bool forEncryption;
public virtual string AlgorithmName => "RC5-32";
public virtual bool IsPartialBlockOkay => false;
public RC532Engine()
{
_noRounds = 12;
}
public virtual int GetBlockSize()
{
return 8;
}
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
if (typeof(RC5Parameters).IsInstanceOfType(parameters))
{
RC5Parameters rC5Parameters = (RC5Parameters)parameters;
_noRounds = rC5Parameters.Rounds;
SetKey(rC5Parameters.GetKey());
}
else
{
if (!typeof(KeyParameter).IsInstanceOfType(parameters))
{
throw new ArgumentException("invalid parameter passed to RC532 init - " + Platform.GetTypeName(parameters));
}
KeyParameter keyParameter = (KeyParameter)parameters;
SetKey(keyParameter.GetKey());
}
this.forEncryption = forEncryption;
}
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
{
if (!forEncryption)
{
return DecryptBlock(input, inOff, output, outOff);
}
return EncryptBlock(input, inOff, output, outOff);
}
public virtual void Reset()
{
}
private void SetKey(byte[] key)
{
int[] array = new int[(key.Length + 3) / 4];
for (int i = 0; i != key.Length; i++)
{
int[] array3;
int[] array2 = (array3 = array);
int num = i / 4;
nint num2 = num;
array2[num] = array3[num2] + ((key[i] & 0xFF) << 8 * (i % 4));
}
_S = new int[2 * (_noRounds + 1)];
_S[0] = P32;
for (int j = 1; j < _S.Length; j++)
{
_S[j] = _S[j - 1] + Q32;
}
int num3 = ((array.Length <= _S.Length) ? (3 * _S.Length) : (3 * array.Length));
int num4 = 0;
int num5 = 0;
int num6 = 0;
int num7 = 0;
for (int k = 0; k < num3; k++)
{
num4 = (_S[num6] = RotateLeft(_S[num6] + num4 + num5, 3));
num5 = (array[num7] = RotateLeft(array[num7] + num4 + num5, num4 + num5));
num6 = (num6 + 1) % _S.Length;
num7 = (num7 + 1) % array.Length;
}
}
private int EncryptBlock(byte[] input, int inOff, byte[] outBytes, int outOff)
{
int num = BytesToWord(input, inOff) + _S[0];
int num2 = BytesToWord(input, inOff + 4) + _S[1];
for (int i = 1; i <= _noRounds; i++)
{
num = RotateLeft(num ^ num2, num2) + _S[2 * i];
num2 = RotateLeft(num2 ^ num, num) + _S[2 * i + 1];
}
WordToBytes(num, outBytes, outOff);
WordToBytes(num2, outBytes, outOff + 4);
return 8;
}
private int DecryptBlock(byte[] input, int inOff, byte[] outBytes, int outOff)
{
int num = BytesToWord(input, inOff);
int num2 = BytesToWord(input, inOff + 4);
for (int num3 = _noRounds; num3 >= 1; num3--)
{
num2 = RotateRight(num2 - _S[2 * num3 + 1], num) ^ num;
num = RotateRight(num - _S[2 * num3], num2) ^ num2;
}
WordToBytes(num - _S[0], outBytes, outOff);
WordToBytes(num2 - _S[1], outBytes, outOff + 4);
return 8;
}
private int RotateLeft(int x, int y)
{
return (x << (y & 0x1F)) | (x >>> 32 - (y & 0x1F));
}
private int RotateRight(int x, int y)
{
return (x >>> (y & 0x1F)) | (x << 32 - (y & 0x1F));
}
private int BytesToWord(byte[] src, int srcOff)
{
return (src[srcOff] & 0xFF) | ((src[srcOff + 1] & 0xFF) << 8) | ((src[srcOff + 2] & 0xFF) << 16) | ((src[srcOff + 3] & 0xFF) << 24);
}
private void WordToBytes(int word, byte[] dst, int dstOff)
{
dst[dstOff] = (byte)word;
dst[dstOff + 1] = (byte)(word >> 8);
dst[dstOff + 2] = (byte)(word >> 16);
dst[dstOff + 3] = (byte)(word >> 24);
}
}

View File

@@ -0,0 +1,149 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class RC564Engine : IBlockCipher
{
private static readonly int wordSize = 64;
private static readonly int bytesPerWord = wordSize / 8;
private int _noRounds;
private long[] _S;
private static readonly long P64 = -5196783011329398165L;
private static readonly long Q64 = -7046029254386353131L;
private bool forEncryption;
public virtual string AlgorithmName => "RC5-64";
public virtual bool IsPartialBlockOkay => false;
public RC564Engine()
{
_noRounds = 12;
}
public virtual int GetBlockSize()
{
return 2 * bytesPerWord;
}
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
if (!typeof(RC5Parameters).IsInstanceOfType(parameters))
{
throw new ArgumentException("invalid parameter passed to RC564 init - " + Platform.GetTypeName(parameters));
}
RC5Parameters rC5Parameters = (RC5Parameters)parameters;
this.forEncryption = forEncryption;
_noRounds = rC5Parameters.Rounds;
SetKey(rC5Parameters.GetKey());
}
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
{
if (!forEncryption)
{
return DecryptBlock(input, inOff, output, outOff);
}
return EncryptBlock(input, inOff, output, outOff);
}
public virtual void Reset()
{
}
private void SetKey(byte[] key)
{
long[] array = new long[(key.Length + (bytesPerWord - 1)) / bytesPerWord];
for (int i = 0; i != key.Length; i++)
{
long[] array3;
long[] array2 = (array3 = array);
int num = i / bytesPerWord;
nint num2 = num;
array2[num] = array3[num2] + ((long)(key[i] & 0xFF) << 8 * (i % bytesPerWord));
}
_S = new long[2 * (_noRounds + 1)];
_S[0] = P64;
for (int j = 1; j < _S.Length; j++)
{
_S[j] = _S[j - 1] + Q64;
}
int num3 = ((array.Length <= _S.Length) ? (3 * _S.Length) : (3 * array.Length));
long num4 = 0L;
long num5 = 0L;
int num6 = 0;
int num7 = 0;
for (int k = 0; k < num3; k++)
{
num4 = (_S[num6] = RotateLeft(_S[num6] + num4 + num5, 3L));
num5 = (array[num7] = RotateLeft(array[num7] + num4 + num5, num4 + num5));
num6 = (num6 + 1) % _S.Length;
num7 = (num7 + 1) % array.Length;
}
}
private int EncryptBlock(byte[] input, int inOff, byte[] outBytes, int outOff)
{
long num = BytesToWord(input, inOff) + _S[0];
long num2 = BytesToWord(input, inOff + bytesPerWord) + _S[1];
for (int i = 1; i <= _noRounds; i++)
{
num = RotateLeft(num ^ num2, num2) + _S[2 * i];
num2 = RotateLeft(num2 ^ num, num) + _S[2 * i + 1];
}
WordToBytes(num, outBytes, outOff);
WordToBytes(num2, outBytes, outOff + bytesPerWord);
return 2 * bytesPerWord;
}
private int DecryptBlock(byte[] input, int inOff, byte[] outBytes, int outOff)
{
long num = BytesToWord(input, inOff);
long num2 = BytesToWord(input, inOff + bytesPerWord);
for (int num3 = _noRounds; num3 >= 1; num3--)
{
num2 = RotateRight(num2 - _S[2 * num3 + 1], num) ^ num;
num = RotateRight(num - _S[2 * num3], num2) ^ num2;
}
WordToBytes(num - _S[0], outBytes, outOff);
WordToBytes(num2 - _S[1], outBytes, outOff + bytesPerWord);
return 2 * bytesPerWord;
}
private long RotateLeft(long x, long y)
{
return (x << (int)(y & (wordSize - 1))) | (x >>> (int)(wordSize - (y & (wordSize - 1))));
}
private long RotateRight(long x, long y)
{
return (x >>> (int)(y & (wordSize - 1))) | (x << (int)(wordSize - (y & (wordSize - 1))));
}
private long BytesToWord(byte[] src, int srcOff)
{
long num = 0L;
for (int num2 = bytesPerWord - 1; num2 >= 0; num2--)
{
num = (num << 8) + (src[num2 + srcOff] & 0xFF);
}
return num;
}
private void WordToBytes(long word, byte[] dst, int dstOff)
{
for (int i = 0; i < bytesPerWord; i++)
{
dst[i + dstOff] = (byte)word;
word >>>= 8;
}
}
}

View File

@@ -0,0 +1,198 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class RC6Engine : IBlockCipher
{
private static readonly int wordSize = 32;
private static readonly int bytesPerWord = wordSize / 8;
private static readonly int _noRounds = 20;
private int[] _S;
private static readonly int P32 = -1209970333;
private static readonly int Q32 = -1640531527;
private static readonly int LGW = 5;
private bool forEncryption;
public virtual string AlgorithmName => "RC6";
public virtual bool IsPartialBlockOkay => false;
public virtual int GetBlockSize()
{
return 4 * bytesPerWord;
}
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
if (!(parameters is KeyParameter))
{
throw new ArgumentException("invalid parameter passed to RC6 init - " + Platform.GetTypeName(parameters));
}
this.forEncryption = forEncryption;
KeyParameter keyParameter = (KeyParameter)parameters;
SetKey(keyParameter.GetKey());
}
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
{
int blockSize = GetBlockSize();
if (_S == null)
{
throw new InvalidOperationException("RC6 engine not initialised");
}
Check.DataLength(input, inOff, blockSize, "input buffer too short");
Check.OutputLength(output, outOff, blockSize, "output buffer too short");
if (!forEncryption)
{
return DecryptBlock(input, inOff, output, outOff);
}
return EncryptBlock(input, inOff, output, outOff);
}
public virtual void Reset()
{
}
private void SetKey(byte[] key)
{
if ((key.Length + (bytesPerWord - 1)) / bytesPerWord == 0)
{
int num = 1;
}
int[] array = new int[(key.Length + bytesPerWord - 1) / bytesPerWord];
for (int num2 = key.Length - 1; num2 >= 0; num2--)
{
array[num2 / bytesPerWord] = (array[num2 / bytesPerWord] << 8) + (key[num2] & 0xFF);
}
_S = new int[2 + 2 * _noRounds + 2];
_S[0] = P32;
for (int i = 1; i < _S.Length; i++)
{
_S[i] = _S[i - 1] + Q32;
}
int num3 = ((array.Length <= _S.Length) ? (3 * _S.Length) : (3 * array.Length));
int num4 = 0;
int num5 = 0;
int num6 = 0;
int num7 = 0;
for (int j = 0; j < num3; j++)
{
num4 = (_S[num6] = RotateLeft(_S[num6] + num4 + num5, 3));
num5 = (array[num7] = RotateLeft(array[num7] + num4 + num5, num4 + num5));
num6 = (num6 + 1) % _S.Length;
num7 = (num7 + 1) % array.Length;
}
}
private int EncryptBlock(byte[] input, int inOff, byte[] outBytes, int outOff)
{
int num = BytesToWord(input, inOff);
int num2 = BytesToWord(input, inOff + bytesPerWord);
int num3 = BytesToWord(input, inOff + bytesPerWord * 2);
int num4 = BytesToWord(input, inOff + bytesPerWord * 3);
num2 += _S[0];
num4 += _S[1];
for (int i = 1; i <= _noRounds; i++)
{
int num5 = 0;
int num6 = 0;
num5 = num2 * (2 * num2 + 1);
num5 = RotateLeft(num5, 5);
num6 = num4 * (2 * num4 + 1);
num6 = RotateLeft(num6, 5);
num ^= num5;
num = RotateLeft(num, num6);
num += _S[2 * i];
num3 ^= num6;
num3 = RotateLeft(num3, num5);
num3 += _S[2 * i + 1];
int num7 = num;
num = num2;
num2 = num3;
num3 = num4;
num4 = num7;
}
num += _S[2 * _noRounds + 2];
num3 += _S[2 * _noRounds + 3];
WordToBytes(num, outBytes, outOff);
WordToBytes(num2, outBytes, outOff + bytesPerWord);
WordToBytes(num3, outBytes, outOff + bytesPerWord * 2);
WordToBytes(num4, outBytes, outOff + bytesPerWord * 3);
return 4 * bytesPerWord;
}
private int DecryptBlock(byte[] input, int inOff, byte[] outBytes, int outOff)
{
int num = BytesToWord(input, inOff);
int num2 = BytesToWord(input, inOff + bytesPerWord);
int num3 = BytesToWord(input, inOff + bytesPerWord * 2);
int num4 = BytesToWord(input, inOff + bytesPerWord * 3);
num3 -= _S[2 * _noRounds + 3];
num -= _S[2 * _noRounds + 2];
for (int num5 = _noRounds; num5 >= 1; num5--)
{
int num6 = 0;
int num7 = 0;
int num8 = num4;
num4 = num3;
num3 = num2;
num2 = num;
num = num8;
num6 = num2 * (2 * num2 + 1);
num6 = RotateLeft(num6, LGW);
num7 = num4 * (2 * num4 + 1);
num7 = RotateLeft(num7, LGW);
num3 -= _S[2 * num5 + 1];
num3 = RotateRight(num3, num6);
num3 ^= num7;
num -= _S[2 * num5];
num = RotateRight(num, num7);
num ^= num6;
}
num4 -= _S[1];
num2 -= _S[0];
WordToBytes(num, outBytes, outOff);
WordToBytes(num2, outBytes, outOff + bytesPerWord);
WordToBytes(num3, outBytes, outOff + bytesPerWord * 2);
WordToBytes(num4, outBytes, outOff + bytesPerWord * 3);
return 4 * bytesPerWord;
}
private int RotateLeft(int x, int y)
{
return (x << (y & (wordSize - 1))) | (x >>> wordSize - (y & (wordSize - 1)));
}
private int RotateRight(int x, int y)
{
return (x >>> (y & (wordSize - 1))) | (x << wordSize - (y & (wordSize - 1)));
}
private int BytesToWord(byte[] src, int srcOff)
{
int num = 0;
for (int num2 = bytesPerWord - 1; num2 >= 0; num2--)
{
num = (num << 8) + (src[num2 + srcOff] & 0xFF);
}
return num;
}
private void WordToBytes(int word, byte[] dst, int dstOff)
{
for (int i = 0; i < bytesPerWord; i++)
{
dst[i + dstOff] = (byte)word;
word >>>= 8;
}
}
}

View File

@@ -0,0 +1,122 @@
using System;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Engines;
public class Rfc3211WrapEngine : IWrapper
{
private CbcBlockCipher engine;
private ParametersWithIV param;
private bool forWrapping;
private SecureRandom rand;
public virtual string AlgorithmName => engine.GetUnderlyingCipher().AlgorithmName + "/RFC3211Wrap";
public Rfc3211WrapEngine(IBlockCipher engine)
{
this.engine = new CbcBlockCipher(engine);
}
public virtual void Init(bool forWrapping, ICipherParameters param)
{
this.forWrapping = forWrapping;
if (param is ParametersWithRandom)
{
ParametersWithRandom parametersWithRandom = (ParametersWithRandom)param;
rand = parametersWithRandom.Random;
this.param = parametersWithRandom.Parameters as ParametersWithIV;
}
else
{
if (forWrapping)
{
rand = new SecureRandom();
}
this.param = param as ParametersWithIV;
}
if (this.param == null)
{
throw new ArgumentException("RFC3211Wrap requires an IV", "param");
}
}
public virtual byte[] Wrap(byte[] inBytes, int inOff, int inLen)
{
if (!forWrapping)
{
throw new InvalidOperationException("not set for wrapping");
}
if (inLen > 255 || inLen < 0)
{
throw new ArgumentException("input must be from 0 to 255 bytes", "inLen");
}
engine.Init(forEncryption: true, param);
int blockSize = engine.GetBlockSize();
byte[] array = ((inLen + 4 >= blockSize * 2) ? new byte[((inLen + 4) % blockSize == 0) ? (inLen + 4) : (((inLen + 4) / blockSize + 1) * blockSize)] : new byte[blockSize * 2]);
array[0] = (byte)inLen;
Array.Copy(inBytes, inOff, array, 4, inLen);
rand.NextBytes(array, inLen + 4, array.Length - inLen - 4);
array[1] = (byte)(~array[4]);
array[2] = (byte)(~array[5]);
array[3] = (byte)(~array[6]);
for (int i = 0; i < array.Length; i += blockSize)
{
engine.ProcessBlock(array, i, array, i);
}
for (int j = 0; j < array.Length; j += blockSize)
{
engine.ProcessBlock(array, j, array, j);
}
return array;
}
public virtual byte[] Unwrap(byte[] inBytes, int inOff, int inLen)
{
if (forWrapping)
{
throw new InvalidOperationException("not set for unwrapping");
}
int blockSize = engine.GetBlockSize();
if (inLen < 2 * blockSize)
{
throw new InvalidCipherTextException("input too short");
}
byte[] array = new byte[inLen];
byte[] array2 = new byte[blockSize];
Array.Copy(inBytes, inOff, array, 0, inLen);
Array.Copy(inBytes, inOff, array2, 0, array2.Length);
engine.Init(forEncryption: false, new ParametersWithIV(param.Parameters, array2));
for (int i = blockSize; i < array.Length; i += blockSize)
{
engine.ProcessBlock(array, i, array, i);
}
Array.Copy(array, array.Length - array2.Length, array2, 0, array2.Length);
engine.Init(forEncryption: false, new ParametersWithIV(param.Parameters, array2));
engine.ProcessBlock(array, 0, array, 0);
engine.Init(forEncryption: false, param);
for (int j = 0; j < array.Length; j += blockSize)
{
engine.ProcessBlock(array, j, array, j);
}
bool flag = array[0] > array.Length - 4;
byte[] array3 = ((!flag) ? new byte[array[0]] : new byte[array.Length - 4]);
Array.Copy(array, 4, array3, 0, array3.Length);
int num = 0;
for (int k = 0; k != 3; k++)
{
byte b = (byte)(~array[1 + k]);
num |= b ^ array[4 + k];
}
Array.Clear(array, 0, array.Length);
if (num != 0 || flag)
{
throw new InvalidCipherTextException("wrapped key corrupted");
}
return array3;
}
}

View File

@@ -0,0 +1,139 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class Rfc3394WrapEngine : IWrapper
{
private readonly IBlockCipher engine;
private KeyParameter param;
private bool forWrapping;
private byte[] iv = new byte[8] { 166, 166, 166, 166, 166, 166, 166, 166 };
public virtual string AlgorithmName => engine.AlgorithmName;
public Rfc3394WrapEngine(IBlockCipher engine)
{
this.engine = engine;
}
public virtual void Init(bool forWrapping, ICipherParameters parameters)
{
this.forWrapping = forWrapping;
if (parameters is ParametersWithRandom)
{
parameters = ((ParametersWithRandom)parameters).Parameters;
}
if (parameters is KeyParameter)
{
param = (KeyParameter)parameters;
}
else if (parameters is ParametersWithIV)
{
ParametersWithIV parametersWithIV = (ParametersWithIV)parameters;
byte[] iV = parametersWithIV.GetIV();
if (iV.Length != 8)
{
throw new ArgumentException("IV length not equal to 8", "parameters");
}
iv = iV;
param = (KeyParameter)parametersWithIV.Parameters;
}
}
public virtual byte[] Wrap(byte[] input, int inOff, int inLen)
{
if (!forWrapping)
{
throw new InvalidOperationException("not set for wrapping");
}
int num = inLen / 8;
if (num * 8 != inLen)
{
throw new DataLengthException("wrap data must be a multiple of 8 bytes");
}
byte[] array = new byte[inLen + iv.Length];
byte[] array2 = new byte[8 + iv.Length];
Array.Copy(iv, 0, array, 0, iv.Length);
Array.Copy(input, inOff, array, iv.Length, inLen);
engine.Init(forEncryption: true, param);
for (int i = 0; i != 6; i++)
{
for (int j = 1; j <= num; j++)
{
Array.Copy(array, 0, array2, 0, iv.Length);
Array.Copy(array, 8 * j, array2, iv.Length, 8);
engine.ProcessBlock(array2, 0, array2, 0);
int num2 = num * i + j;
int num3 = 1;
while (num2 != 0)
{
byte b = (byte)num2;
byte[] array4;
byte[] array3 = (array4 = array2);
int num4 = iv.Length - num3;
nint num5 = num4;
array3[num4] = (byte)(array4[num5] ^ b);
num2 >>>= 8;
num3++;
}
Array.Copy(array2, 0, array, 0, 8);
Array.Copy(array2, 8, array, 8 * j, 8);
}
}
return array;
}
public virtual byte[] Unwrap(byte[] input, int inOff, int inLen)
{
if (forWrapping)
{
throw new InvalidOperationException("not set for unwrapping");
}
int num = inLen / 8;
if (num * 8 != inLen)
{
throw new InvalidCipherTextException("unwrap data must be a multiple of 8 bytes");
}
byte[] array = new byte[inLen - iv.Length];
byte[] array2 = new byte[iv.Length];
byte[] array3 = new byte[8 + iv.Length];
Array.Copy(input, inOff, array2, 0, iv.Length);
Array.Copy(input, inOff + iv.Length, array, 0, inLen - iv.Length);
engine.Init(forEncryption: false, param);
num--;
for (int num2 = 5; num2 >= 0; num2--)
{
for (int num3 = num; num3 >= 1; num3--)
{
Array.Copy(array2, 0, array3, 0, iv.Length);
Array.Copy(array, 8 * (num3 - 1), array3, iv.Length, 8);
int num4 = num * num2 + num3;
int num5 = 1;
while (num4 != 0)
{
byte b = (byte)num4;
byte[] array5;
byte[] array4 = (array5 = array3);
int num6 = iv.Length - num5;
nint num7 = num6;
array4[num6] = (byte)(array5[num7] ^ b);
num4 >>>= 8;
num5++;
}
engine.ProcessBlock(array3, 0, array3, 0);
Array.Copy(array3, 0, array2, 0, 8);
Array.Copy(array3, 8, array, 8 * (num3 - 1), 8);
}
}
if (!Arrays.ConstantTimeAreEqual(array2, iv))
{
throw new InvalidCipherTextException("checksum failed");
}
return array;
}
}

View File

@@ -0,0 +1,627 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class RijndaelEngine : IBlockCipher
{
private static readonly int MAXROUNDS = 14;
private static readonly int MAXKC = 64;
private static readonly byte[] Logtable = new byte[256]
{
0, 0, 25, 1, 50, 2, 26, 198, 75, 199,
27, 104, 51, 238, 223, 3, 100, 4, 224, 14,
52, 141, 129, 239, 76, 113, 8, 200, 248, 105,
28, 193, 125, 194, 29, 181, 249, 185, 39, 106,
77, 228, 166, 114, 154, 201, 9, 120, 101, 47,
138, 5, 33, 15, 225, 36, 18, 240, 130, 69,
53, 147, 218, 142, 150, 143, 219, 189, 54, 208,
206, 148, 19, 92, 210, 241, 64, 70, 131, 56,
102, 221, 253, 48, 191, 6, 139, 98, 179, 37,
226, 152, 34, 136, 145, 16, 126, 110, 72, 195,
163, 182, 30, 66, 58, 107, 40, 84, 250, 133,
61, 186, 43, 121, 10, 21, 155, 159, 94, 202,
78, 212, 172, 229, 243, 115, 167, 87, 175, 88,
168, 80, 244, 234, 214, 116, 79, 174, 233, 213,
231, 230, 173, 232, 44, 215, 117, 122, 235, 22,
11, 245, 89, 203, 95, 176, 156, 169, 81, 160,
127, 12, 246, 111, 23, 196, 73, 236, 216, 67,
31, 45, 164, 118, 123, 183, 204, 187, 62, 90,
251, 96, 177, 134, 59, 82, 161, 108, 170, 85,
41, 157, 151, 178, 135, 144, 97, 190, 220, 252,
188, 149, 207, 205, 55, 63, 91, 209, 83, 57,
132, 60, 65, 162, 109, 71, 20, 42, 158, 93,
86, 242, 211, 171, 68, 17, 146, 217, 35, 32,
46, 137, 180, 124, 184, 38, 119, 153, 227, 165,
103, 74, 237, 222, 197, 49, 254, 24, 13, 99,
140, 128, 192, 247, 112, 7
};
private static readonly byte[] Alogtable = new byte[511]
{
0, 3, 5, 15, 17, 51, 85, 255, 26, 46,
114, 150, 161, 248, 19, 53, 95, 225, 56, 72,
216, 115, 149, 164, 247, 2, 6, 10, 30, 34,
102, 170, 229, 52, 92, 228, 55, 89, 235, 38,
106, 190, 217, 112, 144, 171, 230, 49, 83, 245,
4, 12, 20, 60, 68, 204, 79, 209, 104, 184,
211, 110, 178, 205, 76, 212, 103, 169, 224, 59,
77, 215, 98, 166, 241, 8, 24, 40, 120, 136,
131, 158, 185, 208, 107, 189, 220, 127, 129, 152,
179, 206, 73, 219, 118, 154, 181, 196, 87, 249,
16, 48, 80, 240, 11, 29, 39, 105, 187, 214,
97, 163, 254, 25, 43, 125, 135, 146, 173, 236,
47, 113, 147, 174, 233, 32, 96, 160, 251, 22,
58, 78, 210, 109, 183, 194, 93, 231, 50, 86,
250, 21, 63, 65, 195, 94, 226, 61, 71, 201,
64, 192, 91, 237, 44, 116, 156, 191, 218, 117,
159, 186, 213, 100, 172, 239, 42, 126, 130, 157,
188, 223, 122, 142, 137, 128, 155, 182, 193, 88,
232, 35, 101, 175, 234, 37, 111, 177, 200, 67,
197, 84, 252, 31, 33, 99, 165, 244, 7, 9,
27, 45, 119, 153, 176, 203, 70, 202, 69, 207,
74, 222, 121, 139, 134, 145, 168, 227, 62, 66,
198, 81, 243, 14, 18, 54, 90, 238, 41, 123,
141, 140, 143, 138, 133, 148, 167, 242, 13, 23,
57, 75, 221, 124, 132, 151, 162, 253, 28, 36,
108, 180, 199, 82, 246, 1, 3, 5, 15, 17,
51, 85, 255, 26, 46, 114, 150, 161, 248, 19,
53, 95, 225, 56, 72, 216, 115, 149, 164, 247,
2, 6, 10, 30, 34, 102, 170, 229, 52, 92,
228, 55, 89, 235, 38, 106, 190, 217, 112, 144,
171, 230, 49, 83, 245, 4, 12, 20, 60, 68,
204, 79, 209, 104, 184, 211, 110, 178, 205, 76,
212, 103, 169, 224, 59, 77, 215, 98, 166, 241,
8, 24, 40, 120, 136, 131, 158, 185, 208, 107,
189, 220, 127, 129, 152, 179, 206, 73, 219, 118,
154, 181, 196, 87, 249, 16, 48, 80, 240, 11,
29, 39, 105, 187, 214, 97, 163, 254, 25, 43,
125, 135, 146, 173, 236, 47, 113, 147, 174, 233,
32, 96, 160, 251, 22, 58, 78, 210, 109, 183,
194, 93, 231, 50, 86, 250, 21, 63, 65, 195,
94, 226, 61, 71, 201, 64, 192, 91, 237, 44,
116, 156, 191, 218, 117, 159, 186, 213, 100, 172,
239, 42, 126, 130, 157, 188, 223, 122, 142, 137,
128, 155, 182, 193, 88, 232, 35, 101, 175, 234,
37, 111, 177, 200, 67, 197, 84, 252, 31, 33,
99, 165, 244, 7, 9, 27, 45, 119, 153, 176,
203, 70, 202, 69, 207, 74, 222, 121, 139, 134,
145, 168, 227, 62, 66, 198, 81, 243, 14, 18,
54, 90, 238, 41, 123, 141, 140, 143, 138, 133,
148, 167, 242, 13, 23, 57, 75, 221, 124, 132,
151, 162, 253, 28, 36, 108, 180, 199, 82, 246,
1
};
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 byte[][] shifts0 = new byte[5][]
{
new byte[4] { 0, 8, 16, 24 },
new byte[4] { 0, 8, 16, 24 },
new byte[4] { 0, 8, 16, 24 },
new byte[4] { 0, 8, 16, 32 },
new byte[4] { 0, 8, 24, 32 }
};
private static readonly byte[][] shifts1 = new byte[5][]
{
new byte[4] { 0, 24, 16, 8 },
new byte[4] { 0, 32, 24, 16 },
new byte[4] { 0, 40, 32, 24 },
new byte[4] { 0, 48, 40, 24 },
new byte[4] { 0, 56, 40, 32 }
};
private int BC;
private long BC_MASK;
private int ROUNDS;
private int blockBits;
private long[][] workingKey;
private long A0;
private long A1;
private long A2;
private long A3;
private bool forEncryption;
private byte[] shifts0SC;
private byte[] shifts1SC;
public virtual string AlgorithmName => "Rijndael";
public virtual bool IsPartialBlockOkay => false;
private byte Mul0x2(int b)
{
if (b != 0)
{
return Alogtable[25 + (Logtable[b] & 0xFF)];
}
return 0;
}
private byte Mul0x3(int b)
{
if (b != 0)
{
return Alogtable[1 + (Logtable[b] & 0xFF)];
}
return 0;
}
private byte Mul0x9(int b)
{
if (b >= 0)
{
return Alogtable[199 + b];
}
return 0;
}
private byte Mul0xb(int b)
{
if (b >= 0)
{
return Alogtable[104 + b];
}
return 0;
}
private byte Mul0xd(int b)
{
if (b >= 0)
{
return Alogtable[238 + b];
}
return 0;
}
private byte Mul0xe(int b)
{
if (b >= 0)
{
return Alogtable[223 + b];
}
return 0;
}
private void KeyAddition(long[] rk)
{
A0 ^= rk[0];
A1 ^= rk[1];
A2 ^= rk[2];
A3 ^= rk[3];
}
private long Shift(long r, int shift)
{
ulong num = (ulong)r >> shift;
if (shift > 31)
{
num &= 0xFFFFFFFFu;
}
return (long)(num | (ulong)(r << BC - shift)) & BC_MASK;
}
private void ShiftRow(byte[] shiftsSC)
{
A1 = Shift(A1, shiftsSC[1]);
A2 = Shift(A2, shiftsSC[2]);
A3 = Shift(A3, shiftsSC[3]);
}
private long ApplyS(long r, byte[] box)
{
long num = 0L;
for (int i = 0; i < BC; i += 8)
{
num |= (long)(box[(int)((r >> i) & 0xFF)] & 0xFF) << i;
}
return num;
}
private void Substitution(byte[] box)
{
A0 = ApplyS(A0, box);
A1 = ApplyS(A1, box);
A2 = ApplyS(A2, box);
A3 = ApplyS(A3, box);
}
private void MixColumn()
{
long num2;
long num3;
long num4;
long num = (num2 = (num3 = (num4 = 0L)));
for (int i = 0; i < BC; i += 8)
{
int num5 = (int)((A0 >> i) & 0xFF);
int num6 = (int)((A1 >> i) & 0xFF);
int num7 = (int)((A2 >> i) & 0xFF);
int num8 = (int)((A3 >> i) & 0xFF);
num |= (long)((Mul0x2(num5) ^ Mul0x3(num6) ^ num7 ^ num8) & 0xFF) << i;
num2 |= (long)((Mul0x2(num6) ^ Mul0x3(num7) ^ num8 ^ num5) & 0xFF) << i;
num3 |= (long)((Mul0x2(num7) ^ Mul0x3(num8) ^ num5 ^ num6) & 0xFF) << i;
num4 |= (long)((Mul0x2(num8) ^ Mul0x3(num5) ^ num6 ^ num7) & 0xFF) << i;
}
A0 = num;
A1 = num2;
A2 = num3;
A3 = num4;
}
private void InvMixColumn()
{
long num2;
long num3;
long num4;
long num = (num2 = (num3 = (num4 = 0L)));
for (int i = 0; i < BC; i += 8)
{
int num5 = (int)((A0 >> i) & 0xFF);
int num6 = (int)((A1 >> i) & 0xFF);
int num7 = (int)((A2 >> i) & 0xFF);
int num8 = (int)((A3 >> i) & 0xFF);
num5 = ((num5 != 0) ? (Logtable[num5 & 0xFF] & 0xFF) : (-1));
num6 = ((num6 != 0) ? (Logtable[num6 & 0xFF] & 0xFF) : (-1));
num7 = ((num7 != 0) ? (Logtable[num7 & 0xFF] & 0xFF) : (-1));
num8 = ((num8 != 0) ? (Logtable[num8 & 0xFF] & 0xFF) : (-1));
num |= (long)((Mul0xe(num5) ^ Mul0xb(num6) ^ Mul0xd(num7) ^ Mul0x9(num8)) & 0xFF) << i;
num2 |= (long)((Mul0xe(num6) ^ Mul0xb(num7) ^ Mul0xd(num8) ^ Mul0x9(num5)) & 0xFF) << i;
num3 |= (long)((Mul0xe(num7) ^ Mul0xb(num8) ^ Mul0xd(num5) ^ Mul0x9(num6)) & 0xFF) << i;
num4 |= (long)((Mul0xe(num8) ^ Mul0xb(num5) ^ Mul0xd(num6) ^ Mul0x9(num7)) & 0xFF) << i;
}
A0 = num;
A1 = num2;
A2 = num3;
A3 = num4;
}
private long[][] GenerateWorkingKey(byte[] key)
{
int num = 0;
int num2 = key.Length * 8;
byte[,] array = new byte[4, MAXKC];
long[][] array2 = new long[MAXROUNDS + 1][];
for (int i = 0; i < MAXROUNDS + 1; i++)
{
array2[i] = new long[4];
}
int num3 = num2 switch
{
128 => 4,
160 => 5,
192 => 6,
224 => 7,
256 => 8,
_ => throw new ArgumentException("Key length not 128/160/192/224/256 bits."),
};
if (num2 >= blockBits)
{
ROUNDS = num3 + 6;
}
else
{
ROUNDS = BC / 8 + 6;
}
int num4 = 0;
for (int j = 0; j < key.Length; j++)
{
array[j % 4, j / 4] = key[num4++];
}
int num5 = 0;
int num6 = 0;
while (num6 < num3 && num5 < (ROUNDS + 1) * (BC / 8))
{
for (int k = 0; k < 4; k++)
{
long[] array4;
long[] array3 = (array4 = array2[num5 / (BC / 8)]);
int num7 = k;
nint num8 = num7;
array3[num7] = array4[num8] | ((long)(array[k, num6] & 0xFF) << num5 * 8 % BC);
}
num6++;
num5++;
}
while (num5 < (ROUNDS + 1) * (BC / 8))
{
byte[,] array6;
for (int l = 0; l < 4; l++)
{
byte[,] array5 = (array6 = array);
int num9 = l;
nint num8 = num9;
array5[num9, 0] = (byte)(array6[(int)num8, 0] ^ S[array[(l + 1) % 4, num3 - 1] & 0xFF]);
}
(array6 = array)[0, 0] = (byte)(array6[0, 0] ^ rcon[num++]);
if (num3 <= 6)
{
for (int m = 1; m < num3; m++)
{
for (int n = 0; n < 4; n++)
{
byte[,] array7 = (array6 = array);
int num10 = n;
nint num8 = num10;
int num11 = m;
nint num12 = num11;
array7[num10, num11] = (byte)(array6[(int)num8, (int)num12] ^ array[n, m - 1]);
}
}
}
else
{
for (int num13 = 1; num13 < 4; num13++)
{
for (int num14 = 0; num14 < 4; num14++)
{
byte[,] array8 = (array6 = array);
int num15 = num14;
nint num8 = num15;
int num16 = num13;
nint num12 = num16;
array8[num15, num16] = (byte)(array6[(int)num8, (int)num12] ^ array[num14, num13 - 1]);
}
}
for (int num17 = 0; num17 < 4; num17++)
{
byte[,] array9 = (array6 = array);
int num18 = num17;
nint num8 = num18;
array9[num18, 4] = (byte)(array6[(int)num8, 4] ^ S[array[num17, 3] & 0xFF]);
}
for (int num19 = 5; num19 < num3; num19++)
{
for (int num20 = 0; num20 < 4; num20++)
{
byte[,] array10 = (array6 = array);
int num21 = num20;
nint num8 = num21;
int num22 = num19;
nint num12 = num22;
array10[num21, num22] = (byte)(array6[(int)num8, (int)num12] ^ array[num20, num19 - 1]);
}
}
}
int num23 = 0;
while (num23 < num3 && num5 < (ROUNDS + 1) * (BC / 8))
{
for (int num24 = 0; num24 < 4; num24++)
{
long[] array4;
long[] array11 = (array4 = array2[num5 / (BC / 8)]);
int num25 = num24;
nint num8 = num25;
array11[num25] = array4[num8] | ((long)(array[num24, num23] & 0xFF) << num5 * 8 % BC);
}
num23++;
num5++;
}
}
return array2;
}
public RijndaelEngine()
: this(128)
{
}
public RijndaelEngine(int blockBits)
{
switch (blockBits)
{
case 128:
BC = 32;
BC_MASK = 4294967295L;
shifts0SC = shifts0[0];
shifts1SC = shifts1[0];
break;
case 160:
BC = 40;
BC_MASK = 1099511627775L;
shifts0SC = shifts0[1];
shifts1SC = shifts1[1];
break;
case 192:
BC = 48;
BC_MASK = 281474976710655L;
shifts0SC = shifts0[2];
shifts1SC = shifts1[2];
break;
case 224:
BC = 56;
BC_MASK = 72057594037927935L;
shifts0SC = shifts0[3];
shifts1SC = shifts1[3];
break;
case 256:
BC = 64;
BC_MASK = -1L;
shifts0SC = shifts0[4];
shifts1SC = shifts1[4];
break;
default:
throw new ArgumentException("unknown blocksize to Rijndael");
}
this.blockBits = blockBits;
}
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
if (typeof(KeyParameter).IsInstanceOfType(parameters))
{
workingKey = GenerateWorkingKey(((KeyParameter)parameters).GetKey());
this.forEncryption = forEncryption;
return;
}
throw new ArgumentException("invalid parameter passed to Rijndael init - " + Platform.GetTypeName(parameters));
}
public virtual int GetBlockSize()
{
return BC / 2;
}
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
{
if (workingKey == null)
{
throw new InvalidOperationException("Rijndael engine not initialised");
}
Check.DataLength(input, inOff, BC / 2, "input buffer too short");
Check.OutputLength(output, outOff, BC / 2, "output buffer too short");
UnPackBlock(input, inOff);
if (forEncryption)
{
EncryptBlock(workingKey);
}
else
{
DecryptBlock(workingKey);
}
PackBlock(output, outOff);
return BC / 2;
}
public virtual void Reset()
{
}
private void UnPackBlock(byte[] bytes, int off)
{
int num = off;
A0 = bytes[num++] & 0xFF;
A1 = bytes[num++] & 0xFF;
A2 = bytes[num++] & 0xFF;
A3 = bytes[num++] & 0xFF;
for (int i = 8; i != BC; i += 8)
{
A0 |= (long)(bytes[num++] & 0xFF) << i;
A1 |= (long)(bytes[num++] & 0xFF) << i;
A2 |= (long)(bytes[num++] & 0xFF) << i;
A3 |= (long)(bytes[num++] & 0xFF) << i;
}
}
private void PackBlock(byte[] bytes, int off)
{
int num = off;
for (int i = 0; i != BC; i += 8)
{
bytes[num++] = (byte)(A0 >> i);
bytes[num++] = (byte)(A1 >> i);
bytes[num++] = (byte)(A2 >> i);
bytes[num++] = (byte)(A3 >> i);
}
}
private void EncryptBlock(long[][] rk)
{
KeyAddition(rk[0]);
for (int i = 1; i < ROUNDS; i++)
{
Substitution(S);
ShiftRow(shifts0SC);
MixColumn();
KeyAddition(rk[i]);
}
Substitution(S);
ShiftRow(shifts0SC);
KeyAddition(rk[ROUNDS]);
}
private void DecryptBlock(long[][] rk)
{
KeyAddition(rk[ROUNDS]);
Substitution(Si);
ShiftRow(shifts1SC);
for (int num = ROUNDS - 1; num > 0; num--)
{
KeyAddition(rk[num]);
InvMixColumn();
Substitution(Si);
ShiftRow(shifts1SC);
}
KeyAddition(rk[0]);
}
}

View File

@@ -0,0 +1,91 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class RsaBlindedEngine : IAsymmetricBlockCipher
{
private readonly IRsa core;
private RsaKeyParameters key;
private SecureRandom random;
public virtual string AlgorithmName => "RSA";
public RsaBlindedEngine()
: this(new RsaCoreEngine())
{
}
public RsaBlindedEngine(IRsa rsa)
{
core = rsa;
}
public virtual void Init(bool forEncryption, ICipherParameters param)
{
core.Init(forEncryption, param);
if (param is ParametersWithRandom)
{
ParametersWithRandom parametersWithRandom = (ParametersWithRandom)param;
key = (RsaKeyParameters)parametersWithRandom.Parameters;
random = parametersWithRandom.Random;
}
else
{
key = (RsaKeyParameters)param;
random = new SecureRandom();
}
}
public virtual int GetInputBlockSize()
{
return core.GetInputBlockSize();
}
public virtual int GetOutputBlockSize()
{
return core.GetOutputBlockSize();
}
public virtual byte[] ProcessBlock(byte[] inBuf, int inOff, int inLen)
{
if (key == null)
{
throw new InvalidOperationException("RSA engine not initialised");
}
BigInteger bigInteger = core.ConvertInput(inBuf, inOff, inLen);
BigInteger bigInteger4;
if (key is RsaPrivateCrtKeyParameters)
{
RsaPrivateCrtKeyParameters rsaPrivateCrtKeyParameters = (RsaPrivateCrtKeyParameters)key;
BigInteger publicExponent = rsaPrivateCrtKeyParameters.PublicExponent;
if (publicExponent != null)
{
BigInteger modulus = rsaPrivateCrtKeyParameters.Modulus;
BigInteger bigInteger2 = BigIntegers.CreateRandomInRange(BigInteger.One, modulus.Subtract(BigInteger.One), random);
BigInteger input = bigInteger2.ModPow(publicExponent, modulus).Multiply(bigInteger).Mod(modulus);
BigInteger bigInteger3 = core.ProcessBlock(input);
BigInteger val = bigInteger2.ModInverse(modulus);
bigInteger4 = bigInteger3.Multiply(val).Mod(modulus);
if (!bigInteger.Equals(bigInteger4.ModPow(publicExponent, modulus)))
{
throw new InvalidOperationException("RSA engine faulty decryption/signing detected");
}
}
else
{
bigInteger4 = core.ProcessBlock(bigInteger);
}
}
else
{
bigInteger4 = core.ProcessBlock(bigInteger);
}
return core.ConvertOutput(bigInteger4);
}
}

View File

@@ -0,0 +1,78 @@
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
namespace Org.BouncyCastle.Crypto.Engines;
public class RsaBlindingEngine : IAsymmetricBlockCipher
{
private readonly IRsa core;
private RsaKeyParameters key;
private BigInteger blindingFactor;
private bool forEncryption;
public virtual string AlgorithmName => "RSA";
public RsaBlindingEngine()
: this(new RsaCoreEngine())
{
}
public RsaBlindingEngine(IRsa rsa)
{
core = rsa;
}
public virtual void Init(bool forEncryption, ICipherParameters param)
{
RsaBlindingParameters rsaBlindingParameters;
if (param is ParametersWithRandom)
{
ParametersWithRandom parametersWithRandom = (ParametersWithRandom)param;
rsaBlindingParameters = (RsaBlindingParameters)parametersWithRandom.Parameters;
}
else
{
rsaBlindingParameters = (RsaBlindingParameters)param;
}
core.Init(forEncryption, rsaBlindingParameters.PublicKey);
this.forEncryption = forEncryption;
key = rsaBlindingParameters.PublicKey;
blindingFactor = rsaBlindingParameters.BlindingFactor;
}
public virtual int GetInputBlockSize()
{
return core.GetInputBlockSize();
}
public virtual int GetOutputBlockSize()
{
return core.GetOutputBlockSize();
}
public virtual byte[] ProcessBlock(byte[] inBuf, int inOff, int inLen)
{
BigInteger bigInteger = core.ConvertInput(inBuf, inOff, inLen);
bigInteger = ((!forEncryption) ? UnblindMessage(bigInteger) : BlindMessage(bigInteger));
return core.ConvertOutput(bigInteger);
}
private BigInteger BlindMessage(BigInteger msg)
{
BigInteger bigInteger = blindingFactor;
bigInteger = msg.Multiply(bigInteger.ModPow(key.Exponent, key.Modulus));
return bigInteger.Mod(key.Modulus);
}
private BigInteger UnblindMessage(BigInteger blindedMsg)
{
BigInteger modulus = key.Modulus;
BigInteger bigInteger = blindedMsg;
BigInteger val = blindingFactor.ModInverse(modulus);
bigInteger = bigInteger.Multiply(val);
return bigInteger.Mod(modulus);
}
}

View File

@@ -0,0 +1,113 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
namespace Org.BouncyCastle.Crypto.Engines;
public class RsaCoreEngine : IRsa
{
private RsaKeyParameters key;
private bool forEncryption;
private int bitSize;
private void CheckInitialised()
{
if (key == null)
{
throw new InvalidOperationException("RSA engine not initialised");
}
}
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
if (parameters is ParametersWithRandom)
{
parameters = ((ParametersWithRandom)parameters).Parameters;
}
if (!(parameters is RsaKeyParameters))
{
throw new InvalidKeyException("Not an RSA key");
}
key = (RsaKeyParameters)parameters;
this.forEncryption = forEncryption;
bitSize = key.Modulus.BitLength;
}
public virtual int GetInputBlockSize()
{
CheckInitialised();
if (forEncryption)
{
return (bitSize - 1) / 8;
}
return (bitSize + 7) / 8;
}
public virtual int GetOutputBlockSize()
{
CheckInitialised();
if (forEncryption)
{
return (bitSize + 7) / 8;
}
return (bitSize - 1) / 8;
}
public virtual BigInteger ConvertInput(byte[] inBuf, int inOff, int inLen)
{
CheckInitialised();
int num = (bitSize + 7) / 8;
if (inLen > num)
{
throw new DataLengthException("input too large for RSA cipher.");
}
BigInteger bigInteger = new BigInteger(1, inBuf, inOff, inLen);
if (bigInteger.CompareTo(key.Modulus) >= 0)
{
throw new DataLengthException("input too large for RSA cipher.");
}
return bigInteger;
}
public virtual byte[] ConvertOutput(BigInteger result)
{
CheckInitialised();
byte[] array = result.ToByteArrayUnsigned();
if (forEncryption)
{
int outputBlockSize = GetOutputBlockSize();
if (array.Length < outputBlockSize)
{
byte[] array2 = new byte[outputBlockSize];
array.CopyTo(array2, array2.Length - array.Length);
array = array2;
}
}
return array;
}
public virtual BigInteger ProcessBlock(BigInteger input)
{
CheckInitialised();
if (key is RsaPrivateCrtKeyParameters)
{
RsaPrivateCrtKeyParameters rsaPrivateCrtKeyParameters = (RsaPrivateCrtKeyParameters)key;
BigInteger p = rsaPrivateCrtKeyParameters.P;
BigInteger q = rsaPrivateCrtKeyParameters.Q;
BigInteger dP = rsaPrivateCrtKeyParameters.DP;
BigInteger dQ = rsaPrivateCrtKeyParameters.DQ;
BigInteger qInv = rsaPrivateCrtKeyParameters.QInv;
BigInteger bigInteger = input.Remainder(p).ModPow(dP, p);
BigInteger bigInteger2 = input.Remainder(q).ModPow(dQ, q);
BigInteger bigInteger3 = bigInteger.Subtract(bigInteger2);
bigInteger3 = bigInteger3.Multiply(qInv);
bigInteger3 = bigInteger3.Mod(p);
BigInteger bigInteger4 = bigInteger3.Multiply(q);
return bigInteger4.Add(bigInteger2);
}
return input.ModPow(key.Exponent, key.Modulus);
}
}

View File

@@ -0,0 +1,42 @@
using Org.BouncyCastle.Math;
namespace Org.BouncyCastle.Crypto.Engines;
public class RsaEngine : IAsymmetricBlockCipher
{
private readonly IRsa core;
public virtual string AlgorithmName => "RSA";
public RsaEngine()
: this(new RsaCoreEngine())
{
}
public RsaEngine(IRsa rsa)
{
core = rsa;
}
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
core.Init(forEncryption, parameters);
}
public virtual int GetInputBlockSize()
{
return core.GetInputBlockSize();
}
public virtual int GetOutputBlockSize()
{
return core.GetOutputBlockSize();
}
public virtual byte[] ProcessBlock(byte[] inBuf, int inOff, int inLen)
{
BigInteger input = core.ConvertInput(inBuf, inOff, inLen);
BigInteger result = core.ProcessBlock(input);
return core.ConvertOutput(result);
}
}

View File

@@ -0,0 +1,205 @@
using System;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Utilities;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;
using Org.BouncyCastle.Math.EC.Multiplier;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class SM2Engine
{
private readonly IDigest mDigest;
private bool mForEncryption;
private ECKeyParameters mECKey;
private ECDomainParameters mECParams;
private int mCurveLength;
private SecureRandom mRandom;
public SM2Engine()
: this(new SM3Digest())
{
}
public SM2Engine(IDigest digest)
{
mDigest = digest;
}
public virtual void Init(bool forEncryption, ICipherParameters param)
{
mForEncryption = forEncryption;
if (forEncryption)
{
ParametersWithRandom parametersWithRandom = (ParametersWithRandom)param;
mECKey = (ECKeyParameters)parametersWithRandom.Parameters;
mECParams = mECKey.Parameters;
ECPoint eCPoint = ((ECPublicKeyParameters)mECKey).Q.Multiply(mECParams.H);
if (eCPoint.IsInfinity)
{
throw new ArgumentException("invalid key: [h]Q at infinity");
}
mRandom = parametersWithRandom.Random;
}
else
{
mECKey = (ECKeyParameters)param;
mECParams = mECKey.Parameters;
}
mCurveLength = (mECParams.Curve.FieldSize + 7) / 8;
}
public virtual byte[] ProcessBlock(byte[] input, int inOff, int inLen)
{
if (mForEncryption)
{
return Encrypt(input, inOff, inLen);
}
return Decrypt(input, inOff, inLen);
}
protected virtual ECMultiplier CreateBasePointMultiplier()
{
return new FixedPointCombMultiplier();
}
private byte[] Encrypt(byte[] input, int inOff, int inLen)
{
byte[] array = new byte[inLen];
Array.Copy(input, inOff, array, 0, array.Length);
ECMultiplier eCMultiplier = CreateBasePointMultiplier();
byte[] encoded;
ECPoint eCPoint2;
do
{
BigInteger bigInteger = NextK();
ECPoint eCPoint = eCMultiplier.Multiply(mECParams.G, bigInteger).Normalize();
encoded = eCPoint.GetEncoded(compressed: false);
eCPoint2 = ((ECPublicKeyParameters)mECKey).Q.Multiply(bigInteger).Normalize();
Kdf(mDigest, eCPoint2, array);
}
while (NotEncrypted(array, input, inOff));
AddFieldElement(mDigest, eCPoint2.AffineXCoord);
mDigest.BlockUpdate(input, inOff, inLen);
AddFieldElement(mDigest, eCPoint2.AffineYCoord);
byte[] array2 = DigestUtilities.DoFinal(mDigest);
return Arrays.ConcatenateAll(encoded, array, array2);
}
private byte[] Decrypt(byte[] input, int inOff, int inLen)
{
byte[] array = new byte[mCurveLength * 2 + 1];
Array.Copy(input, inOff, array, 0, array.Length);
ECPoint eCPoint = mECParams.Curve.DecodePoint(array);
ECPoint eCPoint2 = eCPoint.Multiply(mECParams.H);
if (eCPoint2.IsInfinity)
{
throw new InvalidCipherTextException("[h]C1 at infinity");
}
eCPoint = eCPoint.Multiply(((ECPrivateKeyParameters)mECKey).D).Normalize();
byte[] array2 = new byte[inLen - array.Length - mDigest.GetDigestSize()];
Array.Copy(input, inOff + array.Length, array2, 0, array2.Length);
Kdf(mDigest, eCPoint, array2);
AddFieldElement(mDigest, eCPoint.AffineXCoord);
mDigest.BlockUpdate(array2, 0, array2.Length);
AddFieldElement(mDigest, eCPoint.AffineYCoord);
byte[] array3 = DigestUtilities.DoFinal(mDigest);
int num = 0;
for (int i = 0; i != array3.Length; i++)
{
num |= array3[i] ^ input[inOff + array.Length + array2.Length + i];
}
Arrays.Fill(array, 0);
Arrays.Fill(array3, 0);
if (num != 0)
{
Arrays.Fill(array2, 0);
throw new InvalidCipherTextException("invalid cipher text");
}
return array2;
}
private bool NotEncrypted(byte[] encData, byte[] input, int inOff)
{
for (int i = 0; i != encData.Length; i++)
{
if (encData[i] != input[inOff])
{
return false;
}
}
return true;
}
private void Kdf(IDigest digest, ECPoint c1, byte[] encData)
{
int digestSize = digest.GetDigestSize();
byte[] array = new byte[System.Math.Max(4, digestSize)];
int i = 0;
IMemoable memoable = digest as IMemoable;
IMemoable other = null;
if (memoable != null)
{
AddFieldElement(digest, c1.AffineXCoord);
AddFieldElement(digest, c1.AffineYCoord);
other = memoable.Copy();
}
uint num = 0u;
int num2;
for (; i < encData.Length; i += num2)
{
if (memoable != null)
{
memoable.Reset(other);
}
else
{
AddFieldElement(digest, c1.AffineXCoord);
AddFieldElement(digest, c1.AffineYCoord);
}
Pack.UInt32_To_BE(++num, array, 0);
digest.BlockUpdate(array, 0, 4);
digest.DoFinal(array, 0);
num2 = System.Math.Min(digestSize, encData.Length - i);
Xor(encData, array, i, num2);
}
}
private void Xor(byte[] data, byte[] kdfOut, int dOff, int dRemaining)
{
for (int i = 0; i != dRemaining; i++)
{
byte[] array2;
byte[] array = (array2 = data);
int num = dOff + i;
nint num2 = num;
array[num] = (byte)(array2[num2] ^ kdfOut[i]);
}
}
private BigInteger NextK()
{
int bitLength = mECParams.N.BitLength;
BigInteger bigInteger;
do
{
bigInteger = new BigInteger(bitLength, mRandom);
}
while (bigInteger.SignValue == 0 || bigInteger.CompareTo(mECParams.N) >= 0);
return bigInteger;
}
private void AddFieldElement(IDigest digest, ECFieldElement v)
{
byte[] encoded = v.GetEncoded();
digest.BlockUpdate(encoded, 0, encoded.Length);
}
}

View File

@@ -0,0 +1,167 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Utilities;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class SM4Engine : IBlockCipher
{
private const int BlockSize = 16;
private static readonly byte[] Sbox = new byte[256]
{
214, 144, 233, 254, 204, 225, 61, 183, 22, 182,
20, 194, 40, 251, 44, 5, 43, 103, 154, 118,
42, 190, 4, 195, 170, 68, 19, 38, 73, 134,
6, 153, 156, 66, 80, 244, 145, 239, 152, 122,
51, 84, 11, 67, 237, 207, 172, 98, 228, 179,
28, 169, 201, 8, 232, 149, 128, 223, 148, 250,
117, 143, 63, 166, 71, 7, 167, 252, 243, 115,
23, 186, 131, 89, 60, 25, 230, 133, 79, 168,
104, 107, 129, 178, 113, 100, 218, 139, 248, 235,
15, 75, 112, 86, 157, 53, 30, 36, 14, 94,
99, 88, 209, 162, 37, 34, 124, 59, 1, 33,
120, 135, 212, 0, 70, 87, 159, 211, 39, 82,
76, 54, 2, 231, 160, 196, 200, 158, 234, 191,
138, 210, 64, 199, 56, 181, 163, 247, 242, 206,
249, 97, 21, 161, 224, 174, 93, 164, 155, 52,
26, 85, 173, 147, 50, 48, 245, 140, 177, 227,
29, 246, 226, 46, 130, 102, 202, 96, 192, 41,
35, 171, 13, 83, 78, 111, 213, 219, 55, 69,
222, 253, 142, 47, 3, 255, 106, 114, 109, 108,
91, 81, 141, 27, 175, 146, 187, 221, 188, 127,
17, 217, 92, 65, 31, 16, 90, 216, 10, 193,
49, 136, 165, 205, 123, 189, 45, 116, 208, 18,
184, 229, 180, 176, 137, 105, 151, 74, 12, 150,
119, 126, 101, 185, 241, 9, 197, 110, 198, 132,
24, 240, 125, 236, 58, 220, 77, 32, 121, 238,
95, 62, 215, 203, 57, 72
};
private static readonly uint[] CK = new uint[32]
{
462357u, 472066609u, 943670861u, 1415275113u, 1886879365u, 2358483617u, 2830087869u, 3301692121u, 3773296373u, 4228057617u,
404694573u, 876298825u, 1347903077u, 1819507329u, 2291111581u, 2762715833u, 3234320085u, 3705924337u, 4177462797u, 337322537u,
808926789u, 1280531041u, 1752135293u, 2223739545u, 2695343797u, 3166948049u, 3638552301u, 4110090761u, 269950501u, 741554753u,
1213159005u, 1684763257u
};
private static readonly uint[] FK = new uint[4] { 2746333894u, 1453994832u, 1736282519u, 2993693404u };
private uint[] rk;
public virtual string AlgorithmName => "SM4";
public virtual bool IsPartialBlockOkay => false;
private static uint tau(uint A)
{
uint num = Sbox[A >> 24];
uint num2 = Sbox[(A >> 16) & 0xFF];
uint num3 = Sbox[(A >> 8) & 0xFF];
uint num4 = Sbox[A & 0xFF];
return (num << 24) | (num2 << 16) | (num3 << 8) | num4;
}
private static uint L_ap(uint B)
{
return B ^ Integers.RotateLeft(B, 13) ^ Integers.RotateLeft(B, 23);
}
private uint T_ap(uint Z)
{
return L_ap(tau(Z));
}
private void ExpandKey(bool forEncryption, byte[] key)
{
uint num = Pack.BE_To_UInt32(key, 0) ^ FK[0];
uint num2 = Pack.BE_To_UInt32(key, 4) ^ FK[1];
uint num3 = Pack.BE_To_UInt32(key, 8) ^ FK[2];
uint num4 = Pack.BE_To_UInt32(key, 12) ^ FK[3];
if (forEncryption)
{
rk[0] = num ^ T_ap(num2 ^ num3 ^ num4 ^ CK[0]);
rk[1] = num2 ^ T_ap(num3 ^ num4 ^ rk[0] ^ CK[1]);
rk[2] = num3 ^ T_ap(num4 ^ rk[0] ^ rk[1] ^ CK[2]);
rk[3] = num4 ^ T_ap(rk[0] ^ rk[1] ^ rk[2] ^ CK[3]);
for (int i = 4; i < 32; i++)
{
rk[i] = rk[i - 4] ^ T_ap(rk[i - 3] ^ rk[i - 2] ^ rk[i - 1] ^ CK[i]);
}
return;
}
rk[31] = num ^ T_ap(num2 ^ num3 ^ num4 ^ CK[0]);
rk[30] = num2 ^ T_ap(num3 ^ num4 ^ rk[31] ^ CK[1]);
rk[29] = num3 ^ T_ap(num4 ^ rk[31] ^ rk[30] ^ CK[2]);
rk[28] = num4 ^ T_ap(rk[31] ^ rk[30] ^ rk[29] ^ CK[3]);
for (int num5 = 27; num5 >= 0; num5--)
{
rk[num5] = rk[num5 + 4] ^ T_ap(rk[num5 + 3] ^ rk[num5 + 2] ^ rk[num5 + 1] ^ CK[31 - num5]);
}
}
private static uint L(uint B)
{
return B ^ Integers.RotateLeft(B, 2) ^ Integers.RotateLeft(B, 10) ^ Integers.RotateLeft(B, 18) ^ Integers.RotateLeft(B, 24);
}
private static uint T(uint Z)
{
return L(tau(Z));
}
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
if (!(parameters is KeyParameter keyParameter))
{
throw new ArgumentException("invalid parameter passed to SM4 init - " + Platform.GetTypeName(parameters), "parameters");
}
byte[] key = keyParameter.GetKey();
if (key.Length != 16)
{
throw new ArgumentException("SM4 requires a 128 bit key", "parameters");
}
if (rk == null)
{
rk = new uint[32];
}
ExpandKey(forEncryption, key);
}
public virtual int GetBlockSize()
{
return 16;
}
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
{
if (rk == null)
{
throw new InvalidOperationException("SM4 not initialised");
}
Check.DataLength(input, inOff, 16, "input buffer too short");
Check.OutputLength(output, outOff, 16, "output buffer too short");
uint num = Pack.BE_To_UInt32(input, inOff);
uint num2 = Pack.BE_To_UInt32(input, inOff + 4);
uint num3 = Pack.BE_To_UInt32(input, inOff + 8);
uint num4 = Pack.BE_To_UInt32(input, inOff + 12);
for (int i = 0; i < 32; i += 4)
{
num ^= T(num2 ^ num3 ^ num4 ^ rk[i]);
num2 ^= T(num3 ^ num4 ^ num ^ rk[i + 1]);
num3 ^= T(num4 ^ num ^ num2 ^ rk[i + 2]);
num4 ^= T(num ^ num2 ^ num3 ^ rk[i + 3]);
}
Pack.UInt32_To_BE(num4, output, outOff);
Pack.UInt32_To_BE(num3, output, outOff + 4);
Pack.UInt32_To_BE(num2, output, outOff + 8);
Pack.UInt32_To_BE(num, output, outOff + 12);
return 16;
}
public virtual void Reset()
{
}
}

View File

@@ -0,0 +1,310 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Utilities;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class Salsa20Engine : IStreamCipher
{
private const int StateSize = 16;
public static readonly int DEFAULT_ROUNDS = 20;
private static readonly uint[] TAU_SIGMA = Pack.LE_To_UInt32(Strings.ToAsciiByteArray("expand 16-byte kexpand 32-byte k"), 0, 8);
[Obsolete]
protected static readonly byte[] sigma = Strings.ToAsciiByteArray("expand 32-byte k");
[Obsolete]
protected static readonly byte[] tau = Strings.ToAsciiByteArray("expand 16-byte k");
protected int rounds;
private int index = 0;
internal uint[] engineState = new uint[16];
internal uint[] x = new uint[16];
private byte[] keyStream = new byte[64];
private bool initialised = false;
private uint cW0;
private uint cW1;
private uint cW2;
protected virtual int NonceSize => 8;
public virtual string AlgorithmName
{
get
{
string text = "Salsa20";
if (rounds != DEFAULT_ROUNDS)
{
text = text + "/" + rounds;
}
return text;
}
}
internal void PackTauOrSigma(int keyLength, uint[] state, int stateOffset)
{
int num = (keyLength - 16) / 4;
state[stateOffset] = TAU_SIGMA[num];
state[stateOffset + 1] = TAU_SIGMA[num + 1];
state[stateOffset + 2] = TAU_SIGMA[num + 2];
state[stateOffset + 3] = TAU_SIGMA[num + 3];
}
public Salsa20Engine()
: this(DEFAULT_ROUNDS)
{
}
public Salsa20Engine(int rounds)
{
if (rounds <= 0 || (rounds & 1) != 0)
{
throw new ArgumentException("'rounds' must be a positive, even number");
}
this.rounds = rounds;
}
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
if (!(parameters is ParametersWithIV parametersWithIV))
{
throw new ArgumentException(AlgorithmName + " Init requires an IV", "parameters");
}
byte[] iV = parametersWithIV.GetIV();
if (iV == null || iV.Length != NonceSize)
{
throw new ArgumentException(AlgorithmName + " requires exactly " + NonceSize + " bytes of IV");
}
ICipherParameters parameters2 = parametersWithIV.Parameters;
if (parameters2 == null)
{
if (!initialised)
{
throw new InvalidOperationException(AlgorithmName + " KeyParameter can not be null for first initialisation");
}
SetKey(null, iV);
}
else
{
if (!(parameters2 is KeyParameter))
{
throw new ArgumentException(AlgorithmName + " Init parameters must contain a KeyParameter (or null for re-init)");
}
SetKey(((KeyParameter)parameters2).GetKey(), iV);
}
Reset();
initialised = true;
}
public virtual byte ReturnByte(byte input)
{
if (LimitExceeded())
{
throw new MaxBytesExceededException("2^70 byte limit per IV; Change IV");
}
if (index == 0)
{
GenerateKeyStream(keyStream);
AdvanceCounter();
}
byte result = (byte)(keyStream[index] ^ input);
index = (index + 1) & 0x3F;
return result;
}
protected virtual void AdvanceCounter()
{
uint[] array;
if (((array = engineState)[8] = array[8] + 1) == 0)
{
(array = engineState)[9] = array[9] + 1;
}
}
public virtual void ProcessBytes(byte[] inBytes, int inOff, int len, byte[] outBytes, int outOff)
{
if (!initialised)
{
throw new InvalidOperationException(AlgorithmName + " not initialised");
}
Check.DataLength(inBytes, inOff, len, "input buffer too short");
Check.OutputLength(outBytes, outOff, len, "output buffer too short");
if (LimitExceeded((uint)len))
{
throw new MaxBytesExceededException("2^70 byte limit per IV would be exceeded; Change IV");
}
for (int i = 0; i < len; i++)
{
if (index == 0)
{
GenerateKeyStream(keyStream);
AdvanceCounter();
}
outBytes[i + outOff] = (byte)(keyStream[index] ^ inBytes[i + inOff]);
index = (index + 1) & 0x3F;
}
}
public virtual void Reset()
{
index = 0;
ResetLimitCounter();
ResetCounter();
}
protected virtual void ResetCounter()
{
engineState[8] = (engineState[9] = 0u);
}
protected virtual void SetKey(byte[] keyBytes, byte[] ivBytes)
{
if (keyBytes != null)
{
if (keyBytes.Length != 16 && keyBytes.Length != 32)
{
throw new ArgumentException(AlgorithmName + " requires 128 bit or 256 bit key");
}
int num = (keyBytes.Length - 16) / 4;
engineState[0] = TAU_SIGMA[num];
engineState[5] = TAU_SIGMA[num + 1];
engineState[10] = TAU_SIGMA[num + 2];
engineState[15] = TAU_SIGMA[num + 3];
Pack.LE_To_UInt32(keyBytes, 0, engineState, 1, 4);
Pack.LE_To_UInt32(keyBytes, keyBytes.Length - 16, engineState, 11, 4);
}
Pack.LE_To_UInt32(ivBytes, 0, engineState, 6, 2);
}
protected virtual void GenerateKeyStream(byte[] output)
{
SalsaCore(rounds, engineState, x);
Pack.UInt32_To_LE(x, output, 0);
}
internal static void SalsaCore(int rounds, uint[] input, uint[] x)
{
if (input.Length != 16)
{
throw new ArgumentException();
}
if (x.Length != 16)
{
throw new ArgumentException();
}
if (rounds % 2 != 0)
{
throw new ArgumentException("Number of rounds must be even");
}
uint num = input[0];
uint num2 = input[1];
uint num3 = input[2];
uint num4 = input[3];
uint num5 = input[4];
uint num6 = input[5];
uint num7 = input[6];
uint num8 = input[7];
uint num9 = input[8];
uint num10 = input[9];
uint num11 = input[10];
uint num12 = input[11];
uint num13 = input[12];
uint num14 = input[13];
uint num15 = input[14];
uint num16 = input[15];
for (int num17 = rounds; num17 > 0; num17 -= 2)
{
num5 ^= R(num + num13, 7);
num9 ^= R(num5 + num, 9);
num13 ^= R(num9 + num5, 13);
num ^= R(num13 + num9, 18);
num10 ^= R(num6 + num2, 7);
num14 ^= R(num10 + num6, 9);
num2 ^= R(num14 + num10, 13);
num6 ^= R(num2 + num14, 18);
num15 ^= R(num11 + num7, 7);
num3 ^= R(num15 + num11, 9);
num7 ^= R(num3 + num15, 13);
num11 ^= R(num7 + num3, 18);
num4 ^= R(num16 + num12, 7);
num8 ^= R(num4 + num16, 9);
num12 ^= R(num8 + num4, 13);
num16 ^= R(num12 + num8, 18);
num2 ^= R(num + num4, 7);
num3 ^= R(num2 + num, 9);
num4 ^= R(num3 + num2, 13);
num ^= R(num4 + num3, 18);
num7 ^= R(num6 + num5, 7);
num8 ^= R(num7 + num6, 9);
num5 ^= R(num8 + num7, 13);
num6 ^= R(num5 + num8, 18);
num12 ^= R(num11 + num10, 7);
num9 ^= R(num12 + num11, 9);
num10 ^= R(num9 + num12, 13);
num11 ^= R(num10 + num9, 18);
num13 ^= R(num16 + num15, 7);
num14 ^= R(num13 + num16, 9);
num15 ^= R(num14 + num13, 13);
num16 ^= R(num15 + num14, 18);
}
x[0] = num + input[0];
x[1] = num2 + input[1];
x[2] = num3 + input[2];
x[3] = num4 + input[3];
x[4] = num5 + input[4];
x[5] = num6 + input[5];
x[6] = num7 + input[6];
x[7] = num8 + input[7];
x[8] = num9 + input[8];
x[9] = num10 + input[9];
x[10] = num11 + input[10];
x[11] = num12 + input[11];
x[12] = num13 + input[12];
x[13] = num14 + input[13];
x[14] = num15 + input[14];
x[15] = num16 + input[15];
}
internal static uint R(uint x, int y)
{
return (x << y) | (x >> 32 - y);
}
private void ResetLimitCounter()
{
cW0 = 0u;
cW1 = 0u;
cW2 = 0u;
}
private bool LimitExceeded()
{
if (++cW0 == 0 && ++cW1 == 0)
{
return (++cW2 & 0x20) != 0;
}
return false;
}
private bool LimitExceeded(uint len)
{
uint num = cW0;
cW0 += len;
if (cW0 < num && ++cW1 == 0)
{
return (++cW2 & 0x20) != 0;
}
return false;
}
}

View File

@@ -0,0 +1,282 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
namespace Org.BouncyCastle.Crypto.Engines;
public class SeedEngine : IBlockCipher
{
private const int BlockSize = 16;
private static readonly uint[] SS0 = new uint[256]
{
696885672u, 92635524u, 382128852u, 331600848u, 340021332u, 487395612u, 747413676u, 621093156u, 491606364u, 54739776u,
403181592u, 504238620u, 289493328u, 1020063996u, 181060296u, 591618912u, 671621160u, 71581764u, 536879136u, 495817116u,
549511392u, 583197408u, 147374280u, 386339604u, 629514660u, 261063564u, 50529024u, 994800504u, 999011256u, 318968592u,
314757840u, 785310444u, 809529456u, 210534540u, 1057960764u, 680042664u, 839004720u, 500027868u, 919007988u, 876900468u,
751624428u, 361075092u, 185271048u, 390550356u, 474763356u, 457921368u, 1032696252u, 16843008u, 604250148u, 470552604u,
860058480u, 411603096u, 268439568u, 214745292u, 851636976u, 432656856u, 738992172u, 667411428u, 843215472u, 58950528u,
462132120u, 297914832u, 109478532u, 164217288u, 541089888u, 272650320u, 595829664u, 734782440u, 218956044u, 914797236u,
512660124u, 256852812u, 931640244u, 441078360u, 113689284u, 944271480u, 646357668u, 302125584u, 797942700u, 365285844u,
557932896u, 63161280u, 881111220u, 21053760u, 306336336u, 1028485500u, 227377548u, 134742024u, 521081628u, 428446104u,
0u, 420024600u, 67371012u, 323179344u, 935850996u, 566354400u, 1036907004u, 910586484u, 789521196u, 654779172u,
813740208u, 193692552u, 235799052u, 730571688u, 578986656u, 776888940u, 327390096u, 223166796u, 692674920u, 1011642492u,
151585032u, 168428040u, 1066382268u, 802153452u, 868479984u, 96846276u, 126321540u, 335810580u, 1053750012u, 608460900u,
516870876u, 772678188u, 189481800u, 436867608u, 101057028u, 553722144u, 726360936u, 642146916u, 33686016u, 902164980u,
310547088u, 176849544u, 202113036u, 864269232u, 1045328508u, 281071824u, 977957496u, 122110788u, 377918100u, 633725412u,
637936164u, 8421504u, 764256684u, 533713884u, 562143648u, 805318704u, 923218740u, 781099692u, 906375732u, 352653588u,
570565152u, 940060728u, 885321972u, 663200676u, 88424772u, 206323788u, 25264512u, 701096424u, 75792516u, 394761108u,
889532724u, 197903304u, 248431308u, 1007431740u, 826372464u, 285282576u, 130532292u, 160006536u, 893743476u, 1003222008u,
449499864u, 952692984u, 344232084u, 424235352u, 42107520u, 80003268u, 1070593020u, 155795784u, 956903736u, 658989924u,
12632256u, 265274316u, 398971860u, 948482232u, 252642060u, 244220556u, 37896768u, 587408160u, 293704080u, 743202924u,
466342872u, 612671652u, 872689716u, 834793968u, 138952776u, 46318272u, 793731948u, 1024274748u, 755835180u, 4210752u,
1049539260u, 1041117756u, 1015853244u, 29475264u, 713728680u, 982168248u, 240009804u, 356864340u, 990589752u, 483184860u,
675831912u, 1062171516u, 478974108u, 415813848u, 172638792u, 373707348u, 927429492u, 545300640u, 768467436u, 105267780u,
897954228u, 722150184u, 625303908u, 986379000u, 600040416u, 965325240u, 830583216u, 529503132u, 508449372u, 969535992u,
650568420u, 847426224u, 822161712u, 717939432u, 760045932u, 525292380u, 616882404u, 817950960u, 231588300u, 143163528u,
369496596u, 973746744u, 407392344u, 348442836u, 574775904u, 688464168u, 117900036u, 855847728u, 684253416u, 453710616u,
84214020u, 961114488u, 276861072u, 709517928u, 705307176u, 445289112u
};
private static readonly uint[] SS1 = new uint[256]
{
943196208u, 3894986976u, 741149985u, 2753988258u, 3423588291u, 3693006546u, 2956166067u, 3090712752u, 2888798115u, 1612726368u,
1410680145u, 3288844227u, 1141130304u, 1815039843u, 1747667811u, 1478183763u, 3221472195u, 1612857954u, 808649523u, 3023406513u,
673777953u, 2686484640u, 3760374498u, 2754054051u, 3490956243u, 2417066385u, 269549841u, 67503618u, 471600144u, 3158084784u,
875955762u, 1208699715u, 3962556387u, 2282260608u, 1814842464u, 2821228704u, 337053459u, 3288646848u, 336987666u, 4097098992u,
3221406402u, 1141196097u, 3760308705u, 3558262482u, 1010765619u, 1010634033u, 2349764226u, 2551744656u, 673712160u, 1276005954u,
4097230578u, 1010699826u, 2753922465u, 4164536817u, 202181889u, 3693072339u, 3625502928u, 673909539u, 1680229986u, 2017086066u,
606537507u, 741281571u, 4029792753u, 1882342002u, 1073889858u, 3558130896u, 1073824065u, 3221274816u, 1882407795u, 1680295779u,
2888600736u, 2282457987u, 4097296371u, 2888666529u, 2147516544u, 471797523u, 3356150466u, 741084192u, 2821360290u, 875824176u,
3490890450u, 134941443u, 3962490594u, 3895052769u, 1545424209u, 2484372624u, 404228112u, 4164471024u, 1410811731u, 2888732322u,
134744064u, 3288712641u, 269681427u, 3423456705u, 2215020162u, 3090778545u, 4232040435u, 2084392305u, 3221340609u, 808517937u,
4097164785u, 2282392194u, 1747602018u, 2956034481u, 3490824657u, 538968096u, 3558328275u, 131586u, 539099682u, 67372032u,
1747470432u, 1882276209u, 67569411u, 3625700307u, 2619182481u, 2551810449u, 1612792161u, 3158216370u, 3827746530u, 1478052177u,
3692940753u, 1343308113u, 2417000592u, 3692874960u, 2551876242u, 2686682019u, 2821426083u, 3490758864u, 2147582337u, 202313475u,
1141327683u, 404359698u, 3760440291u, 3962359008u, 2349698433u, 3158282163u, 2484504210u, 2017151859u, 1545358416u, 2686616226u,
2686550433u, 1612923747u, 539165475u, 1275940161u, 3356018880u, 2619248274u, 2619116688u, 943327794u, 202116096u, 741215778u,
3090844338u, 1814974050u, 2619314067u, 1478117970u, 4029858546u, 2417132178u, 4029924339u, 1208568129u, 2016954480u, 3423390912u,
336921873u, 4164668403u, 1882210416u, 1949648241u, 2084523891u, 875889969u, 269484048u, 197379u, 1680098400u, 1814908257u,
3288778434u, 1949582448u, 3558196689u, 3023340720u, 3895118562u, 134809857u, 1949714034u, 404293905u, 4231974642u, 1073758272u,
269615634u, 3760242912u, 3158150577u, 67437825u, 4164602610u, 65793u, 4029726960u, 673843746u, 1545490002u, 2821294497u,
1410745938u, 1073955651u, 2214954369u, 336856080u, 2282326401u, 2551942035u, 2955968688u, 3827680737u, 1208502336u, 2017020273u,
2484570003u, 4231843056u, 471731730u, 2147648130u, 539033889u, 2349632640u, 404425491u, 1545555795u, 1949779827u, 1410614352u,
2956100274u, 471665937u, 606405921u, 1276071747u, 0u, 1141261890u, 3962424801u, 1477986384u, 1343373906u, 3895184355u,
2084458098u, 3625634514u, 3356084673u, 4231908849u, 808452144u, 2484438417u, 1680164193u, 1010568240u, 3023472306u, 3827614944u,
3090910131u, 2084326512u, 202247682u, 1343242320u, 943262001u, 606471714u, 808583730u, 2214888576u, 1747536225u, 2417197971u,
876021555u, 3827812323u, 606340128u, 2753856672u, 3356216259u, 1343439699u, 134875650u, 2215085955u, 3625568721u, 1275874368u,
2147713923u, 2349830019u, 3423522498u, 943393587u, 1208633922u, 3023538099u
};
private static readonly uint[] SS2 = new uint[256]
{
2712152457u, 2172913029u, 3537114822u, 3553629123u, 1347687492u, 287055117u, 2695638156u, 556016901u, 1364991309u, 1128268611u,
270014472u, 303832590u, 1364201793u, 4043062476u, 3267889866u, 1667244867u, 539502600u, 1078199364u, 538976256u, 2442927501u,
3772784832u, 3806339778u, 3234334920u, 320083719u, 2711889285u, 2206994319u, 50332419u, 1937259339u, 3015195531u, 319820547u,
3536851650u, 3807129294u, 1886400576u, 2156661900u, 859586319u, 2695374984u, 842019330u, 3520863693u, 4076091078u, 1886663748u,
3773574348u, 2442401157u, 50858763u, 1398019911u, 1348213836u, 1398283083u, 2981903757u, 16777473u, 539239428u, 270277644u,
1936732995u, 2425886856u, 269488128u, 3234598092u, 4075827906u, 3520600521u, 539765772u, 3823380423u, 1919955522u, 2206204803u,
2476219275u, 3520074177u, 2189690502u, 3251112393u, 1616912448u, 1347424320u, 2745181059u, 3823643595u, 17566989u, 2998154886u,
2459704974u, 1129058127u, 3014932359u, 1381505610u, 3267626694u, 1886926920u, 2728666758u, 303043074u, 2745970575u, 3520337349u,
1633689921u, 3284140995u, 2964599940u, 1094713665u, 1380979266u, 1903967565u, 2173439373u, 526344u, 320610063u, 2442664329u,
0u, 286791945u, 263172u, 1397756739u, 4092868551u, 3789562305u, 4059839949u, 1920218694u, 590098191u, 589571847u,
2964336768u, 2206731147u, 34344462u, 2745707403u, 2728403586u, 1651256910u, 2475692931u, 1095503181u, 1634216265u, 1887190092u,
17303817u, 34081290u, 3015458703u, 3823906767u, 4092605379u, 3250849221u, 2206467975u, 269751300u, 4076617422u, 1617175620u,
3537641166u, 573320718u, 1128794955u, 303569418u, 33818118u, 555753729u, 1667771211u, 1650730566u, 33554946u, 4059313605u,
2458915458u, 2189953674u, 789516u, 3014669187u, 1920745038u, 3503296704u, 1920481866u, 1128531783u, 2459178630u, 3789825477u,
572794374u, 2155872384u, 2712415629u, 3554418639u, 2711626113u, 808464384u, 859059975u, 2729193102u, 842282502u, 286528773u,
572531202u, 808990728u, 4042536132u, 2745444231u, 1094976837u, 1078725708u, 2172649857u, 3790088649u, 2156135556u, 2475956103u,
825505029u, 3284667339u, 3268153038u, 809253900u, 1903178049u, 286265601u, 3284404167u, 2173176201u, 1903441221u, 4093131723u,
3537377994u, 4042799304u, 2425623684u, 1364728137u, 2189427330u, 3234071748u, 4093394895u, 1095240009u, 825768201u, 1667508039u,
3233808576u, 3284930511u, 3553892295u, 2964863112u, 51121935u, 2190216846u, 1111491138u, 589308675u, 2442137985u, 1617701964u,
3554155467u, 2695111812u, 808727556u, 4059050433u, 1078462536u, 3267363522u, 1668034383u, 826031373u, 556543245u, 1077936192u,
2998681230u, 842808846u, 2965126284u, 3250586049u, 2728929930u, 2998418058u, 1112280654u, 1364464965u, 859323147u, 3504086220u,
1617438792u, 1937522511u, 2426150028u, 3503823048u, 1112017482u, 1381242438u, 1936996167u, 2694848640u, 3790351821u, 1111754310u,
2981377413u, 589835019u, 1633953093u, 4076354250u, 3823117251u, 2981640585u, 2981114241u, 2476482447u, 1381768782u, 4059576777u,
3806602950u, 2997891714u, 825241857u, 3806866122u, 1634479437u, 1398546255u, 3773048004u, 4042272960u, 3251375565u, 2156398728u,
303306246u, 842545674u, 1347950664u, 3503559876u, 1650467394u, 556280073u, 50595591u, 858796803u, 3773311176u, 320346891u,
17040645u, 1903704393u, 2425360512u, 1650993738u, 573057546u, 2459441802u
};
private static readonly uint[] SS3 = new uint[256]
{
137377848u, 3370182696u, 220277805u, 2258805798u, 3485715471u, 3469925406u, 2209591347u, 2293282872u, 2409868335u, 1080057888u,
1162957845u, 3351495687u, 1145062404u, 1331915823u, 1264805931u, 1263753243u, 3284385795u, 1113743394u, 53686323u, 2243015733u,
153167913u, 2158010400u, 3269648418u, 2275648551u, 3285438483u, 2173800465u, 17895441u, 100795398u, 202382364u, 2360392764u,
103953462u, 1262700555u, 3487820847u, 2290124808u, 1281387564u, 2292230184u, 118690839u, 3300967428u, 101848086u, 3304125492u,
3267543042u, 1161905157u, 3252805665u, 3335705622u, 255015999u, 221330493u, 2390920206u, 2291177496u, 136325160u, 1312967694u,
3337810998u, 238173246u, 2241963045u, 3388078137u, 218172429u, 3486768159u, 3369130008u, 186853419u, 1180853286u, 1249015866u,
119743527u, 253963311u, 3253858353u, 1114796082u, 1111638018u, 3302020116u, 1094795265u, 3233857536u, 1131638835u, 1197696039u,
2359340076u, 2340653067u, 3354653751u, 2376182829u, 2155905024u, 252910623u, 3401762826u, 203435052u, 2325915690u, 70267956u,
3268595730u, 184748043u, 3470978094u, 3387025449u, 1297177629u, 2224067604u, 135272472u, 3371235384u, 1196643351u, 2393025582u,
134219784u, 3317810181u, 51580947u, 3452029965u, 2256700422u, 2310125625u, 3488873535u, 1299283005u, 3250700289u, 20000817u,
3320968245u, 2323810314u, 1247963178u, 2175905841u, 3251752977u, 2105376u, 3352548375u, 33685506u, 35790882u, 67109892u,
1214277672u, 1097953329u, 117638151u, 3419658267u, 2375130141u, 2308020249u, 1096900641u, 2394078270u, 3336758310u, 1230067737u,
3453082653u, 1095847953u, 2156957712u, 3436239900u, 2324863002u, 2208538659u, 2342758443u, 3234910224u, 2172747777u, 251857935u,
1195590663u, 168957978u, 3286491171u, 3437292588u, 2374077453u, 2410921023u, 2257753110u, 1265858619u, 1280334876u, 2191695906u,
2174853153u, 1130586147u, 52633635u, 1296124941u, 3368077320u, 2391972894u, 2358287388u, 171063354u, 201329676u, 237120558u,
2326968378u, 1315073070u, 2408815647u, 1246910490u, 3270701106u, 2190643218u, 3287543859u, 1229015049u, 1215330360u, 3435187212u,
85005333u, 3421763643u, 1081110576u, 1165063221u, 1332968511u, 87110709u, 1052688u, 50528259u, 1147167780u, 1298230317u,
3334652934u, 1148220468u, 3318862869u, 2226172980u, 3403868202u, 151062537u, 1181905974u, 152115225u, 3472030782u, 1077952512u,
34738194u, 3235962912u, 2377235517u, 83952645u, 3404920890u, 16842753u, 3237015600u, 170010666u, 1314020382u, 2309072937u,
1179800598u, 1128480771u, 2239857669u, 68162580u, 2306967561u, 2341705755u, 2159063088u, 3319915557u, 1212172296u, 1232173113u,
2274595863u, 3438345276u, 236067870u, 2189590530u, 18948129u, 2357234700u, 185800731u, 1330863135u, 1198748727u, 1146115092u,
2192748594u, 219225117u, 86058021u, 1329810447u, 0u, 1178747910u, 3454135341u, 1213224984u, 1112690706u, 3420710955u,
1316125758u, 3402815514u, 3384920073u, 3455188029u, 3158064u, 2240910357u, 1164010533u, 204487740u, 2259858486u, 3303072804u,
2343811131u, 1282440252u, 235015182u, 1079005200u, 154220601u, 102900774u, 36843570u, 2223014916u, 1231120425u, 2207485971u,
120796215u, 3353601063u, 69215268u, 2225120292u, 3418605579u, 1129533459u, 167905290u, 2273543175u, 3385972761u, 1279282188u,
2206433283u, 2407762959u, 3468872718u, 187906107u, 1245857802u, 2276701239u
};
private static readonly uint[] KC = new uint[16]
{
2654435769u, 1013904243u, 2027808486u, 4055616972u, 3816266649u, 3337566003u, 2380164711u, 465362127u, 930724254u, 1861448508u,
3722897016u, 3150826737u, 2006686179u, 4013372358u, 3731777421u, 3168587547u
};
private int[] wKey;
private bool forEncryption;
public virtual string AlgorithmName => "SEED";
public virtual bool IsPartialBlockOkay => false;
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
this.forEncryption = forEncryption;
wKey = createWorkingKey(((KeyParameter)parameters).GetKey());
}
public virtual int GetBlockSize()
{
return 16;
}
public virtual int ProcessBlock(byte[] inBuf, int inOff, byte[] outBuf, int outOff)
{
if (wKey == null)
{
throw new InvalidOperationException("SEED engine not initialised");
}
Check.DataLength(inBuf, inOff, 16, "input buffer too short");
Check.OutputLength(outBuf, outOff, 16, "output buffer too short");
long num = bytesToLong(inBuf, inOff);
long num2 = bytesToLong(inBuf, inOff + 8);
if (forEncryption)
{
for (int i = 0; i < 16; i++)
{
long num3 = num2;
num2 = num ^ F(wKey[2 * i], wKey[2 * i + 1], num2);
num = num3;
}
}
else
{
for (int num4 = 15; num4 >= 0; num4--)
{
long num5 = num2;
num2 = num ^ F(wKey[2 * num4], wKey[2 * num4 + 1], num2);
num = num5;
}
}
longToBytes(outBuf, outOff, num2);
longToBytes(outBuf, outOff + 8, num);
return 16;
}
public virtual void Reset()
{
}
private int[] createWorkingKey(byte[] inKey)
{
int[] array = new int[32];
long num = bytesToLong(inKey, 0);
long num2 = bytesToLong(inKey, 8);
int num3 = extractW0(num);
int num4 = extractW1(num);
int num5 = extractW0(num2);
int num6 = extractW1(num2);
for (int i = 0; i < 16; i++)
{
array[2 * i] = G(num3 + num5 - (int)KC[i]);
array[2 * i + 1] = G(num4 - num6 + (int)KC[i]);
if (i % 2 == 0)
{
num = rotateRight8(num);
num3 = extractW0(num);
num4 = extractW1(num);
}
else
{
num2 = rotateLeft8(num2);
num5 = extractW0(num2);
num6 = extractW1(num2);
}
}
return array;
}
private int extractW1(long lVal)
{
return (int)lVal;
}
private int extractW0(long lVal)
{
return (int)(lVal >> 32);
}
private long rotateLeft8(long x)
{
return (x << 8) | (x >>> 56);
}
private long rotateRight8(long x)
{
return (x >>> 8) | (x << 56);
}
private long bytesToLong(byte[] src, int srcOff)
{
long num = 0L;
for (int i = 0; i <= 7; i++)
{
num = (num << 8) + (src[i + srcOff] & 0xFF);
}
return num;
}
private void longToBytes(byte[] dest, int destOff, long value)
{
for (int i = 0; i < 8; i++)
{
dest[i + destOff] = (byte)(value >> (7 - i) * 8);
}
}
private int G(int x)
{
return (int)(SS0[x & 0xFF] ^ SS1[(x >> 8) & 0xFF] ^ SS2[(x >> 16) & 0xFF] ^ SS3[(x >> 24) & 0xFF]);
}
private long F(int ki0, int ki1, long r)
{
int r2 = (int)(r >> 32);
int r3 = (int)r;
int num = phaseCalc2(r2, ki0, r3, ki1);
int num2 = num + phaseCalc1(r2, ki0, r3, ki1);
return ((long)num2 << 32) | (num & 0xFFFFFFFFu);
}
private int phaseCalc1(int r0, int ki0, int r1, int ki1)
{
return G(G(r0 ^ ki0 ^ (r1 ^ ki1)) + (r0 ^ ki0));
}
private int phaseCalc2(int r0, int ki0, int r1, int ki1)
{
return G(phaseCalc1(r0, ki0, r1, ki1) + G(r0 ^ ki0 ^ (r1 ^ ki1)));
}
}

View File

@@ -0,0 +1,9 @@
namespace Org.BouncyCastle.Crypto.Engines;
public class SeedWrapEngine : Rfc3394WrapEngine
{
public SeedWrapEngine()
: base(new SeedEngine())
{
}
}

View File

@@ -0,0 +1,478 @@
using System;
using Org.BouncyCastle.Crypto.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public sealed class SerpentEngine : SerpentEngineBase
{
protected override int[] MakeWorkingKey(byte[] key)
{
int[] array = new int[16];
int num = 0;
int num2 = 0;
for (num = 0; num + 4 < key.Length; num += 4)
{
array[num2++] = (int)Pack.LE_To_UInt32(key, num);
}
if (num % 4 == 0)
{
array[num2++] = (int)Pack.LE_To_UInt32(key, num);
if (num2 < 8)
{
array[num2] = 1;
}
int num3 = 132;
int[] array2 = new int[num3];
for (int i = 8; i < 16; i++)
{
array[i] = SerpentEngineBase.RotateLeft(array[i - 8] ^ array[i - 5] ^ array[i - 3] ^ array[i - 1] ^ -1640531527 ^ (i - 8), 11);
}
Array.Copy(array, 8, array2, 0, 8);
for (int j = 8; j < num3; j++)
{
array2[j] = SerpentEngineBase.RotateLeft(array2[j - 8] ^ array2[j - 5] ^ array2[j - 3] ^ array2[j - 1] ^ -1640531527 ^ j, 11);
}
Sb3(array2[0], array2[1], array2[2], array2[3]);
array2[0] = X0;
array2[1] = X1;
array2[2] = X2;
array2[3] = X3;
Sb2(array2[4], array2[5], array2[6], array2[7]);
array2[4] = X0;
array2[5] = X1;
array2[6] = X2;
array2[7] = X3;
Sb1(array2[8], array2[9], array2[10], array2[11]);
array2[8] = X0;
array2[9] = X1;
array2[10] = X2;
array2[11] = X3;
Sb0(array2[12], array2[13], array2[14], array2[15]);
array2[12] = X0;
array2[13] = X1;
array2[14] = X2;
array2[15] = X3;
Sb7(array2[16], array2[17], array2[18], array2[19]);
array2[16] = X0;
array2[17] = X1;
array2[18] = X2;
array2[19] = X3;
Sb6(array2[20], array2[21], array2[22], array2[23]);
array2[20] = X0;
array2[21] = X1;
array2[22] = X2;
array2[23] = X3;
Sb5(array2[24], array2[25], array2[26], array2[27]);
array2[24] = X0;
array2[25] = X1;
array2[26] = X2;
array2[27] = X3;
Sb4(array2[28], array2[29], array2[30], array2[31]);
array2[28] = X0;
array2[29] = X1;
array2[30] = X2;
array2[31] = X3;
Sb3(array2[32], array2[33], array2[34], array2[35]);
array2[32] = X0;
array2[33] = X1;
array2[34] = X2;
array2[35] = X3;
Sb2(array2[36], array2[37], array2[38], array2[39]);
array2[36] = X0;
array2[37] = X1;
array2[38] = X2;
array2[39] = X3;
Sb1(array2[40], array2[41], array2[42], array2[43]);
array2[40] = X0;
array2[41] = X1;
array2[42] = X2;
array2[43] = X3;
Sb0(array2[44], array2[45], array2[46], array2[47]);
array2[44] = X0;
array2[45] = X1;
array2[46] = X2;
array2[47] = X3;
Sb7(array2[48], array2[49], array2[50], array2[51]);
array2[48] = X0;
array2[49] = X1;
array2[50] = X2;
array2[51] = X3;
Sb6(array2[52], array2[53], array2[54], array2[55]);
array2[52] = X0;
array2[53] = X1;
array2[54] = X2;
array2[55] = X3;
Sb5(array2[56], array2[57], array2[58], array2[59]);
array2[56] = X0;
array2[57] = X1;
array2[58] = X2;
array2[59] = X3;
Sb4(array2[60], array2[61], array2[62], array2[63]);
array2[60] = X0;
array2[61] = X1;
array2[62] = X2;
array2[63] = X3;
Sb3(array2[64], array2[65], array2[66], array2[67]);
array2[64] = X0;
array2[65] = X1;
array2[66] = X2;
array2[67] = X3;
Sb2(array2[68], array2[69], array2[70], array2[71]);
array2[68] = X0;
array2[69] = X1;
array2[70] = X2;
array2[71] = X3;
Sb1(array2[72], array2[73], array2[74], array2[75]);
array2[72] = X0;
array2[73] = X1;
array2[74] = X2;
array2[75] = X3;
Sb0(array2[76], array2[77], array2[78], array2[79]);
array2[76] = X0;
array2[77] = X1;
array2[78] = X2;
array2[79] = X3;
Sb7(array2[80], array2[81], array2[82], array2[83]);
array2[80] = X0;
array2[81] = X1;
array2[82] = X2;
array2[83] = X3;
Sb6(array2[84], array2[85], array2[86], array2[87]);
array2[84] = X0;
array2[85] = X1;
array2[86] = X2;
array2[87] = X3;
Sb5(array2[88], array2[89], array2[90], array2[91]);
array2[88] = X0;
array2[89] = X1;
array2[90] = X2;
array2[91] = X3;
Sb4(array2[92], array2[93], array2[94], array2[95]);
array2[92] = X0;
array2[93] = X1;
array2[94] = X2;
array2[95] = X3;
Sb3(array2[96], array2[97], array2[98], array2[99]);
array2[96] = X0;
array2[97] = X1;
array2[98] = X2;
array2[99] = X3;
Sb2(array2[100], array2[101], array2[102], array2[103]);
array2[100] = X0;
array2[101] = X1;
array2[102] = X2;
array2[103] = X3;
Sb1(array2[104], array2[105], array2[106], array2[107]);
array2[104] = X0;
array2[105] = X1;
array2[106] = X2;
array2[107] = X3;
Sb0(array2[108], array2[109], array2[110], array2[111]);
array2[108] = X0;
array2[109] = X1;
array2[110] = X2;
array2[111] = X3;
Sb7(array2[112], array2[113], array2[114], array2[115]);
array2[112] = X0;
array2[113] = X1;
array2[114] = X2;
array2[115] = X3;
Sb6(array2[116], array2[117], array2[118], array2[119]);
array2[116] = X0;
array2[117] = X1;
array2[118] = X2;
array2[119] = X3;
Sb5(array2[120], array2[121], array2[122], array2[123]);
array2[120] = X0;
array2[121] = X1;
array2[122] = X2;
array2[123] = X3;
Sb4(array2[124], array2[125], array2[126], array2[127]);
array2[124] = X0;
array2[125] = X1;
array2[126] = X2;
array2[127] = X3;
Sb3(array2[128], array2[129], array2[130], array2[131]);
array2[128] = X0;
array2[129] = X1;
array2[130] = X2;
array2[131] = X3;
return array2;
}
throw new ArgumentException("key must be a multiple of 4 bytes");
}
protected override void EncryptBlock(byte[] input, int inOff, byte[] output, int outOff)
{
X0 = (int)Pack.LE_To_UInt32(input, inOff);
X1 = (int)Pack.LE_To_UInt32(input, inOff + 4);
X2 = (int)Pack.LE_To_UInt32(input, inOff + 8);
X3 = (int)Pack.LE_To_UInt32(input, inOff + 12);
Sb0(wKey[0] ^ X0, wKey[1] ^ X1, wKey[2] ^ X2, wKey[3] ^ X3);
LT();
Sb1(wKey[4] ^ X0, wKey[5] ^ X1, wKey[6] ^ X2, wKey[7] ^ X3);
LT();
Sb2(wKey[8] ^ X0, wKey[9] ^ X1, wKey[10] ^ X2, wKey[11] ^ X3);
LT();
Sb3(wKey[12] ^ X0, wKey[13] ^ X1, wKey[14] ^ X2, wKey[15] ^ X3);
LT();
Sb4(wKey[16] ^ X0, wKey[17] ^ X1, wKey[18] ^ X2, wKey[19] ^ X3);
LT();
Sb5(wKey[20] ^ X0, wKey[21] ^ X1, wKey[22] ^ X2, wKey[23] ^ X3);
LT();
Sb6(wKey[24] ^ X0, wKey[25] ^ X1, wKey[26] ^ X2, wKey[27] ^ X3);
LT();
Sb7(wKey[28] ^ X0, wKey[29] ^ X1, wKey[30] ^ X2, wKey[31] ^ X3);
LT();
Sb0(wKey[32] ^ X0, wKey[33] ^ X1, wKey[34] ^ X2, wKey[35] ^ X3);
LT();
Sb1(wKey[36] ^ X0, wKey[37] ^ X1, wKey[38] ^ X2, wKey[39] ^ X3);
LT();
Sb2(wKey[40] ^ X0, wKey[41] ^ X1, wKey[42] ^ X2, wKey[43] ^ X3);
LT();
Sb3(wKey[44] ^ X0, wKey[45] ^ X1, wKey[46] ^ X2, wKey[47] ^ X3);
LT();
Sb4(wKey[48] ^ X0, wKey[49] ^ X1, wKey[50] ^ X2, wKey[51] ^ X3);
LT();
Sb5(wKey[52] ^ X0, wKey[53] ^ X1, wKey[54] ^ X2, wKey[55] ^ X3);
LT();
Sb6(wKey[56] ^ X0, wKey[57] ^ X1, wKey[58] ^ X2, wKey[59] ^ X3);
LT();
Sb7(wKey[60] ^ X0, wKey[61] ^ X1, wKey[62] ^ X2, wKey[63] ^ X3);
LT();
Sb0(wKey[64] ^ X0, wKey[65] ^ X1, wKey[66] ^ X2, wKey[67] ^ X3);
LT();
Sb1(wKey[68] ^ X0, wKey[69] ^ X1, wKey[70] ^ X2, wKey[71] ^ X3);
LT();
Sb2(wKey[72] ^ X0, wKey[73] ^ X1, wKey[74] ^ X2, wKey[75] ^ X3);
LT();
Sb3(wKey[76] ^ X0, wKey[77] ^ X1, wKey[78] ^ X2, wKey[79] ^ X3);
LT();
Sb4(wKey[80] ^ X0, wKey[81] ^ X1, wKey[82] ^ X2, wKey[83] ^ X3);
LT();
Sb5(wKey[84] ^ X0, wKey[85] ^ X1, wKey[86] ^ X2, wKey[87] ^ X3);
LT();
Sb6(wKey[88] ^ X0, wKey[89] ^ X1, wKey[90] ^ X2, wKey[91] ^ X3);
LT();
Sb7(wKey[92] ^ X0, wKey[93] ^ X1, wKey[94] ^ X2, wKey[95] ^ X3);
LT();
Sb0(wKey[96] ^ X0, wKey[97] ^ X1, wKey[98] ^ X2, wKey[99] ^ X3);
LT();
Sb1(wKey[100] ^ X0, wKey[101] ^ X1, wKey[102] ^ X2, wKey[103] ^ X3);
LT();
Sb2(wKey[104] ^ X0, wKey[105] ^ X1, wKey[106] ^ X2, wKey[107] ^ X3);
LT();
Sb3(wKey[108] ^ X0, wKey[109] ^ X1, wKey[110] ^ X2, wKey[111] ^ X3);
LT();
Sb4(wKey[112] ^ X0, wKey[113] ^ X1, wKey[114] ^ X2, wKey[115] ^ X3);
LT();
Sb5(wKey[116] ^ X0, wKey[117] ^ X1, wKey[118] ^ X2, wKey[119] ^ X3);
LT();
Sb6(wKey[120] ^ X0, wKey[121] ^ X1, wKey[122] ^ X2, wKey[123] ^ X3);
LT();
Sb7(wKey[124] ^ X0, wKey[125] ^ X1, wKey[126] ^ X2, wKey[127] ^ X3);
Pack.UInt32_To_LE((uint)(wKey[128] ^ X0), output, outOff);
Pack.UInt32_To_LE((uint)(wKey[129] ^ X1), output, outOff + 4);
Pack.UInt32_To_LE((uint)(wKey[130] ^ X2), output, outOff + 8);
Pack.UInt32_To_LE((uint)(wKey[131] ^ X3), output, outOff + 12);
}
protected override void DecryptBlock(byte[] input, int inOff, byte[] output, int outOff)
{
X0 = wKey[128] ^ (int)Pack.LE_To_UInt32(input, inOff);
X1 = wKey[129] ^ (int)Pack.LE_To_UInt32(input, inOff + 4);
X2 = wKey[130] ^ (int)Pack.LE_To_UInt32(input, inOff + 8);
X3 = wKey[131] ^ (int)Pack.LE_To_UInt32(input, inOff + 12);
Ib7(X0, X1, X2, X3);
X0 ^= wKey[124];
X1 ^= wKey[125];
X2 ^= wKey[126];
X3 ^= wKey[127];
InverseLT();
Ib6(X0, X1, X2, X3);
X0 ^= wKey[120];
X1 ^= wKey[121];
X2 ^= wKey[122];
X3 ^= wKey[123];
InverseLT();
Ib5(X0, X1, X2, X3);
X0 ^= wKey[116];
X1 ^= wKey[117];
X2 ^= wKey[118];
X3 ^= wKey[119];
InverseLT();
Ib4(X0, X1, X2, X3);
X0 ^= wKey[112];
X1 ^= wKey[113];
X2 ^= wKey[114];
X3 ^= wKey[115];
InverseLT();
Ib3(X0, X1, X2, X3);
X0 ^= wKey[108];
X1 ^= wKey[109];
X2 ^= wKey[110];
X3 ^= wKey[111];
InverseLT();
Ib2(X0, X1, X2, X3);
X0 ^= wKey[104];
X1 ^= wKey[105];
X2 ^= wKey[106];
X3 ^= wKey[107];
InverseLT();
Ib1(X0, X1, X2, X3);
X0 ^= wKey[100];
X1 ^= wKey[101];
X2 ^= wKey[102];
X3 ^= wKey[103];
InverseLT();
Ib0(X0, X1, X2, X3);
X0 ^= wKey[96];
X1 ^= wKey[97];
X2 ^= wKey[98];
X3 ^= wKey[99];
InverseLT();
Ib7(X0, X1, X2, X3);
X0 ^= wKey[92];
X1 ^= wKey[93];
X2 ^= wKey[94];
X3 ^= wKey[95];
InverseLT();
Ib6(X0, X1, X2, X3);
X0 ^= wKey[88];
X1 ^= wKey[89];
X2 ^= wKey[90];
X3 ^= wKey[91];
InverseLT();
Ib5(X0, X1, X2, X3);
X0 ^= wKey[84];
X1 ^= wKey[85];
X2 ^= wKey[86];
X3 ^= wKey[87];
InverseLT();
Ib4(X0, X1, X2, X3);
X0 ^= wKey[80];
X1 ^= wKey[81];
X2 ^= wKey[82];
X3 ^= wKey[83];
InverseLT();
Ib3(X0, X1, X2, X3);
X0 ^= wKey[76];
X1 ^= wKey[77];
X2 ^= wKey[78];
X3 ^= wKey[79];
InverseLT();
Ib2(X0, X1, X2, X3);
X0 ^= wKey[72];
X1 ^= wKey[73];
X2 ^= wKey[74];
X3 ^= wKey[75];
InverseLT();
Ib1(X0, X1, X2, X3);
X0 ^= wKey[68];
X1 ^= wKey[69];
X2 ^= wKey[70];
X3 ^= wKey[71];
InverseLT();
Ib0(X0, X1, X2, X3);
X0 ^= wKey[64];
X1 ^= wKey[65];
X2 ^= wKey[66];
X3 ^= wKey[67];
InverseLT();
Ib7(X0, X1, X2, X3);
X0 ^= wKey[60];
X1 ^= wKey[61];
X2 ^= wKey[62];
X3 ^= wKey[63];
InverseLT();
Ib6(X0, X1, X2, X3);
X0 ^= wKey[56];
X1 ^= wKey[57];
X2 ^= wKey[58];
X3 ^= wKey[59];
InverseLT();
Ib5(X0, X1, X2, X3);
X0 ^= wKey[52];
X1 ^= wKey[53];
X2 ^= wKey[54];
X3 ^= wKey[55];
InverseLT();
Ib4(X0, X1, X2, X3);
X0 ^= wKey[48];
X1 ^= wKey[49];
X2 ^= wKey[50];
X3 ^= wKey[51];
InverseLT();
Ib3(X0, X1, X2, X3);
X0 ^= wKey[44];
X1 ^= wKey[45];
X2 ^= wKey[46];
X3 ^= wKey[47];
InverseLT();
Ib2(X0, X1, X2, X3);
X0 ^= wKey[40];
X1 ^= wKey[41];
X2 ^= wKey[42];
X3 ^= wKey[43];
InverseLT();
Ib1(X0, X1, X2, X3);
X0 ^= wKey[36];
X1 ^= wKey[37];
X2 ^= wKey[38];
X3 ^= wKey[39];
InverseLT();
Ib0(X0, X1, X2, X3);
X0 ^= wKey[32];
X1 ^= wKey[33];
X2 ^= wKey[34];
X3 ^= wKey[35];
InverseLT();
Ib7(X0, X1, X2, X3);
X0 ^= wKey[28];
X1 ^= wKey[29];
X2 ^= wKey[30];
X3 ^= wKey[31];
InverseLT();
Ib6(X0, X1, X2, X3);
X0 ^= wKey[24];
X1 ^= wKey[25];
X2 ^= wKey[26];
X3 ^= wKey[27];
InverseLT();
Ib5(X0, X1, X2, X3);
X0 ^= wKey[20];
X1 ^= wKey[21];
X2 ^= wKey[22];
X3 ^= wKey[23];
InverseLT();
Ib4(X0, X1, X2, X3);
X0 ^= wKey[16];
X1 ^= wKey[17];
X2 ^= wKey[18];
X3 ^= wKey[19];
InverseLT();
Ib3(X0, X1, X2, X3);
X0 ^= wKey[12];
X1 ^= wKey[13];
X2 ^= wKey[14];
X3 ^= wKey[15];
InverseLT();
Ib2(X0, X1, X2, X3);
X0 ^= wKey[8];
X1 ^= wKey[9];
X2 ^= wKey[10];
X3 ^= wKey[11];
InverseLT();
Ib1(X0, X1, X2, X3);
X0 ^= wKey[4];
X1 ^= wKey[5];
X2 ^= wKey[6];
X3 ^= wKey[7];
InverseLT();
Ib0(X0, X1, X2, X3);
Pack.UInt32_To_LE((uint)(X0 ^ wKey[0]), output, outOff);
Pack.UInt32_To_LE((uint)(X1 ^ wKey[1]), output, outOff + 4);
Pack.UInt32_To_LE((uint)(X2 ^ wKey[2]), output, outOff + 8);
Pack.UInt32_To_LE((uint)(X3 ^ wKey[3]), output, outOff + 12);
}
}

View File

@@ -0,0 +1,364 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public abstract class SerpentEngineBase : IBlockCipher
{
internal const int ROUNDS = 32;
internal const int PHI = -1640531527;
protected static readonly int BlockSize = 16;
protected bool encrypting;
protected int[] wKey;
protected int X0;
protected int X1;
protected int X2;
protected int X3;
public virtual string AlgorithmName => "Serpent";
public virtual bool IsPartialBlockOkay => false;
public virtual void Init(bool encrypting, ICipherParameters parameters)
{
if (!(parameters is KeyParameter))
{
throw new ArgumentException("invalid parameter passed to " + AlgorithmName + " init - " + Platform.GetTypeName(parameters));
}
this.encrypting = encrypting;
wKey = MakeWorkingKey(((KeyParameter)parameters).GetKey());
}
public virtual int GetBlockSize()
{
return BlockSize;
}
public int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
{
if (wKey == null)
{
throw new InvalidOperationException(AlgorithmName + " not initialised");
}
Check.DataLength(input, inOff, BlockSize, "input buffer too short");
Check.OutputLength(output, outOff, BlockSize, "output buffer too short");
if (encrypting)
{
EncryptBlock(input, inOff, output, outOff);
}
else
{
DecryptBlock(input, inOff, output, outOff);
}
return BlockSize;
}
public virtual void Reset()
{
}
protected static int RotateLeft(int x, int bits)
{
return (x << bits) | (x >>> 32 - bits);
}
private static int RotateRight(int x, int bits)
{
return (x >>> bits) | (x << 32 - bits);
}
protected void Sb0(int a, int b, int c, int d)
{
int num = a ^ d;
int num2 = c ^ num;
int num3 = b ^ num2;
X3 = (a & d) ^ num3;
int num4 = a ^ (b & num);
X2 = num3 ^ (c | num4);
int num5 = X3 & (num2 ^ num4);
X1 = ~num2 ^ num5;
X0 = num5 ^ ~num4;
}
protected void Ib0(int a, int b, int c, int d)
{
int num = ~a;
int num2 = a ^ b;
int num3 = d ^ (num | num2);
int num4 = c ^ num3;
X2 = num2 ^ num4;
int num5 = num ^ (d & num2);
X1 = num3 ^ (X2 & num5);
X3 = (a & num3) ^ (num4 | X1);
X0 = X3 ^ (num4 ^ num5);
}
protected void Sb1(int a, int b, int c, int d)
{
int num = b ^ ~a;
int num2 = c ^ (a | num);
X2 = d ^ num2;
int num3 = b ^ (d | num);
int num4 = num ^ X2;
X3 = num4 ^ (num2 & num3);
int num5 = num2 ^ num3;
X1 = X3 ^ num5;
X0 = num2 ^ (num4 & num5);
}
protected void Ib1(int a, int b, int c, int d)
{
int num = b ^ d;
int num2 = a ^ (b & num);
int num3 = num ^ num2;
X3 = c ^ num3;
int num4 = b ^ (num & num2);
int num5 = X3 | num4;
X1 = num2 ^ num5;
int num6 = ~X1;
int num7 = X3 ^ num4;
X0 = num6 ^ num7;
X2 = num3 ^ (num6 | num7);
}
protected void Sb2(int a, int b, int c, int d)
{
int num = ~a;
int num2 = b ^ d;
int num3 = c & num;
X0 = num2 ^ num3;
int num4 = c ^ num;
int num5 = c ^ X0;
int num6 = b & num5;
X3 = num4 ^ num6;
X2 = a ^ ((d | num6) & (X0 | num4));
X1 = num2 ^ X3 ^ (X2 ^ (d | num));
}
protected void Ib2(int a, int b, int c, int d)
{
int num = b ^ d;
int num2 = ~num;
int num3 = a ^ c;
int num4 = c ^ num;
int num5 = b & num4;
X0 = num3 ^ num5;
int num6 = a | num2;
int num7 = d ^ num6;
int num8 = num3 | num7;
X3 = num ^ num8;
int num9 = ~num4;
int num10 = X0 | X3;
X1 = num9 ^ num10;
X2 = (d & num9) ^ (num3 ^ num10);
}
protected void Sb3(int a, int b, int c, int d)
{
int num = a ^ b;
int num2 = a & c;
int num3 = a | d;
int num4 = c ^ d;
int num5 = num & num3;
int num6 = num2 | num5;
X2 = num4 ^ num6;
int num7 = b ^ num3;
int num8 = num6 ^ num7;
int num9 = num4 & num8;
X0 = num ^ num9;
int num10 = X2 & X0;
X1 = num8 ^ num10;
X3 = (b | d) ^ (num4 ^ num10);
}
protected void Ib3(int a, int b, int c, int d)
{
int num = a | b;
int num2 = b ^ c;
int num3 = b & num2;
int num4 = a ^ num3;
int num5 = c ^ num4;
int num6 = d | num4;
X0 = num2 ^ num6;
int num7 = num2 | num6;
int num8 = d ^ num7;
X2 = num5 ^ num8;
int num9 = num ^ num8;
int num10 = X0 & num9;
X3 = num4 ^ num10;
X1 = X3 ^ (X0 ^ num9);
}
protected void Sb4(int a, int b, int c, int d)
{
int num = a ^ d;
int num2 = d & num;
int num3 = c ^ num2;
int num4 = b | num3;
X3 = num ^ num4;
int num5 = ~b;
int num6 = num | num5;
X0 = num3 ^ num6;
int num7 = a & X0;
int num8 = num ^ num5;
int num9 = num4 & num8;
X2 = num7 ^ num9;
X1 = a ^ num3 ^ (num8 & X2);
}
protected void Ib4(int a, int b, int c, int d)
{
int num = c | d;
int num2 = a & num;
int num3 = b ^ num2;
int num4 = a & num3;
int num5 = c ^ num4;
X1 = d ^ num5;
int num6 = ~a;
int num7 = num5 & X1;
X3 = num3 ^ num7;
int num8 = X1 | num6;
int num9 = d ^ num8;
X0 = X3 ^ num9;
X2 = (num3 & num9) ^ (X1 ^ num6);
}
protected void Sb5(int a, int b, int c, int d)
{
int num = ~a;
int num2 = a ^ b;
int num3 = a ^ d;
int num4 = c ^ num;
int num5 = num2 | num3;
X0 = num4 ^ num5;
int num6 = d & X0;
int num7 = num2 ^ X0;
X1 = num6 ^ num7;
int num8 = num | X0;
int num9 = num2 | num6;
int num10 = num3 ^ num8;
X2 = num9 ^ num10;
X3 = b ^ num6 ^ (X1 & num10);
}
protected void Ib5(int a, int b, int c, int d)
{
int num = ~c;
int num2 = b & num;
int num3 = d ^ num2;
int num4 = a & num3;
int num5 = b ^ num;
X3 = num4 ^ num5;
int num6 = b | X3;
int num7 = a & num6;
X1 = num3 ^ num7;
int num8 = a | d;
int num9 = num ^ num6;
X0 = num8 ^ num9;
X2 = (b & num8) ^ (num4 | (a ^ c));
}
protected void Sb6(int a, int b, int c, int d)
{
int num = ~a;
int num2 = a ^ d;
int num3 = b ^ num2;
int num4 = num | num2;
int num5 = c ^ num4;
X1 = b ^ num5;
int num6 = num2 | X1;
int num7 = d ^ num6;
int num8 = num5 & num7;
X2 = num3 ^ num8;
int num9 = num5 ^ num7;
X0 = X2 ^ num9;
X3 = ~num5 ^ (num3 & num9);
}
protected void Ib6(int a, int b, int c, int d)
{
int num = ~a;
int num2 = a ^ b;
int num3 = c ^ num2;
int num4 = c | num;
int num5 = d ^ num4;
X1 = num3 ^ num5;
int num6 = num3 & num5;
int num7 = num2 ^ num6;
int num8 = b | num7;
X3 = num5 ^ num8;
int num9 = b | X3;
X0 = num7 ^ num9;
X2 = (d & num) ^ (num3 ^ num9);
}
protected void Sb7(int a, int b, int c, int d)
{
int num = b ^ c;
int num2 = c & num;
int num3 = d ^ num2;
int num4 = a ^ num3;
int num5 = d | num;
int num6 = num4 & num5;
X1 = b ^ num6;
int num7 = num3 | X1;
int num8 = a & num4;
X3 = num ^ num8;
int num9 = num4 ^ num7;
int num10 = X3 & num9;
X2 = num3 ^ num10;
X0 = ~num9 ^ (X3 & X2);
}
protected void Ib7(int a, int b, int c, int d)
{
int num = c | (a & b);
int num2 = d & (a | b);
X3 = num ^ num2;
int num3 = ~d;
int num4 = b ^ num2;
int num5 = num4 | (X3 ^ num3);
X1 = a ^ num5;
X0 = c ^ num4 ^ (d | X1);
X2 = num ^ X1 ^ (X0 ^ (a & X3));
}
protected void LT()
{
int num = RotateLeft(X0, 13);
int num2 = RotateLeft(X2, 3);
int x = X1 ^ num ^ num2;
int x2 = X3 ^ num2 ^ (num << 3);
X1 = RotateLeft(x, 1);
X3 = RotateLeft(x2, 7);
X0 = RotateLeft(num ^ X1 ^ X3, 5);
X2 = RotateLeft(num2 ^ X3 ^ (X1 << 7), 22);
}
protected void InverseLT()
{
int num = RotateRight(X2, 22) ^ X3 ^ (X1 << 7);
int num2 = RotateRight(X0, 5) ^ X1 ^ X3;
int num3 = RotateRight(X3, 7);
int num4 = RotateRight(X1, 1);
X3 = num3 ^ num ^ (num2 << 3);
X1 = num4 ^ num2 ^ num;
X2 = RotateRight(num, 3);
X0 = RotateRight(num2, 13);
}
protected abstract int[] MakeWorkingKey(byte[] key);
protected abstract void EncryptBlock(byte[] input, int inOff, byte[] output, int outOff);
protected abstract void DecryptBlock(byte[] input, int inOff, byte[] output, int outOff);
}

View File

@@ -0,0 +1,203 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class SkipjackEngine : IBlockCipher
{
private const int BLOCK_SIZE = 8;
private static readonly short[] ftable = new short[256]
{
163, 215, 9, 131, 248, 72, 246, 244, 179, 33,
21, 120, 153, 177, 175, 249, 231, 45, 77, 138,
206, 76, 202, 46, 82, 149, 217, 30, 78, 56,
68, 40, 10, 223, 2, 160, 23, 241, 96, 104,
18, 183, 122, 195, 233, 250, 61, 83, 150, 132,
107, 186, 242, 99, 154, 25, 124, 174, 229, 245,
247, 22, 106, 162, 57, 182, 123, 15, 193, 147,
129, 27, 238, 180, 26, 234, 208, 145, 47, 184,
85, 185, 218, 133, 63, 65, 191, 224, 90, 88,
128, 95, 102, 11, 216, 144, 53, 213, 192, 167,
51, 6, 101, 105, 69, 0, 148, 86, 109, 152,
155, 118, 151, 252, 178, 194, 176, 254, 219, 32,
225, 235, 214, 228, 221, 71, 74, 29, 66, 237,
158, 110, 73, 60, 205, 67, 39, 210, 7, 212,
222, 199, 103, 24, 137, 203, 48, 31, 141, 198,
143, 170, 200, 116, 220, 201, 93, 92, 49, 164,
112, 136, 97, 44, 159, 13, 43, 135, 80, 130,
84, 100, 38, 125, 3, 64, 52, 75, 28, 115,
209, 196, 253, 59, 204, 251, 127, 171, 230, 62,
91, 165, 173, 4, 35, 156, 20, 81, 34, 240,
41, 121, 113, 126, 255, 140, 14, 226, 12, 239,
188, 114, 117, 111, 55, 161, 236, 211, 142, 98,
139, 134, 16, 232, 8, 119, 17, 190, 146, 79,
36, 197, 50, 54, 157, 207, 243, 166, 187, 172,
94, 108, 169, 19, 87, 37, 181, 227, 189, 168,
58, 1, 5, 89, 42, 70
};
private int[] key0;
private int[] key1;
private int[] key2;
private int[] key3;
private bool encrypting;
public virtual string AlgorithmName => "SKIPJACK";
public virtual bool IsPartialBlockOkay => false;
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
if (!(parameters is KeyParameter))
{
throw new ArgumentException("invalid parameter passed to SKIPJACK init - " + Platform.GetTypeName(parameters));
}
byte[] key = ((KeyParameter)parameters).GetKey();
encrypting = forEncryption;
key0 = new int[32];
key1 = new int[32];
key2 = new int[32];
key3 = new int[32];
for (int i = 0; i < 32; i++)
{
key0[i] = key[i * 4 % 10] & 0xFF;
key1[i] = key[(i * 4 + 1) % 10] & 0xFF;
key2[i] = key[(i * 4 + 2) % 10] & 0xFF;
key3[i] = key[(i * 4 + 3) % 10] & 0xFF;
}
}
public virtual int GetBlockSize()
{
return 8;
}
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
{
if (key1 == null)
{
throw new InvalidOperationException("SKIPJACK engine not initialised");
}
Check.DataLength(input, inOff, 8, "input buffer too short");
Check.OutputLength(output, outOff, 8, "output buffer too short");
if (encrypting)
{
EncryptBlock(input, inOff, output, outOff);
}
else
{
DecryptBlock(input, inOff, output, outOff);
}
return 8;
}
public virtual void Reset()
{
}
private int G(int k, int w)
{
int num = (w >> 8) & 0xFF;
int num2 = w & 0xFF;
int num3 = ftable[num2 ^ key0[k]] ^ num;
int num4 = ftable[num3 ^ key1[k]] ^ num2;
int num5 = ftable[num4 ^ key2[k]] ^ num3;
int num6 = ftable[num5 ^ key3[k]] ^ num4;
return (num5 << 8) + num6;
}
public virtual int EncryptBlock(byte[] input, int inOff, byte[] outBytes, int outOff)
{
int num = (input[inOff] << 8) + (input[inOff + 1] & 0xFF);
int num2 = (input[inOff + 2] << 8) + (input[inOff + 3] & 0xFF);
int num3 = (input[inOff + 4] << 8) + (input[inOff + 5] & 0xFF);
int num4 = (input[inOff + 6] << 8) + (input[inOff + 7] & 0xFF);
int num5 = 0;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 8; j++)
{
int num6 = num4;
num4 = num3;
num3 = num2;
num2 = G(num5, num);
num = num2 ^ num6 ^ (num5 + 1);
num5++;
}
for (int k = 0; k < 8; k++)
{
int num7 = num4;
num4 = num3;
num3 = num ^ num2 ^ (num5 + 1);
num2 = G(num5, num);
num = num7;
num5++;
}
}
outBytes[outOff] = (byte)(num >> 8);
outBytes[outOff + 1] = (byte)num;
outBytes[outOff + 2] = (byte)(num2 >> 8);
outBytes[outOff + 3] = (byte)num2;
outBytes[outOff + 4] = (byte)(num3 >> 8);
outBytes[outOff + 5] = (byte)num3;
outBytes[outOff + 6] = (byte)(num4 >> 8);
outBytes[outOff + 7] = (byte)num4;
return 8;
}
private int H(int k, int w)
{
int num = w & 0xFF;
int num2 = (w >> 8) & 0xFF;
int num3 = ftable[num2 ^ key3[k]] ^ num;
int num4 = ftable[num3 ^ key2[k]] ^ num2;
int num5 = ftable[num4 ^ key1[k]] ^ num3;
int num6 = ftable[num5 ^ key0[k]] ^ num4;
return (num6 << 8) + num5;
}
public virtual int DecryptBlock(byte[] input, int inOff, byte[] outBytes, int outOff)
{
int num = (input[inOff] << 8) + (input[inOff + 1] & 0xFF);
int num2 = (input[inOff + 2] << 8) + (input[inOff + 3] & 0xFF);
int num3 = (input[inOff + 4] << 8) + (input[inOff + 5] & 0xFF);
int num4 = (input[inOff + 6] << 8) + (input[inOff + 7] & 0xFF);
int num5 = 31;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 8; j++)
{
int num6 = num3;
num3 = num4;
num4 = num;
num = H(num5, num2);
num2 = num ^ num6 ^ (num5 + 1);
num5--;
}
for (int k = 0; k < 8; k++)
{
int num7 = num3;
num3 = num4;
num4 = num2 ^ num ^ (num5 + 1);
num = H(num5, num2);
num2 = num7;
num5--;
}
}
outBytes[outOff] = (byte)(num >> 8);
outBytes[outOff + 1] = (byte)num;
outBytes[outOff + 2] = (byte)(num2 >> 8);
outBytes[outOff + 3] = (byte)num2;
outBytes[outOff + 4] = (byte)(num3 >> 8);
outBytes[outOff + 5] = (byte)num3;
outBytes[outOff + 6] = (byte)(num4 >> 8);
outBytes[outOff + 7] = (byte)num4;
return 8;
}
}

View File

@@ -0,0 +1,114 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Utilities;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class TeaEngine : IBlockCipher
{
private const int rounds = 32;
private const int block_size = 8;
private const uint delta = 2654435769u;
private const uint d_sum = 3337565984u;
private uint _a;
private uint _b;
private uint _c;
private uint _d;
private bool _initialised;
private bool _forEncryption;
public virtual string AlgorithmName => "TEA";
public virtual bool IsPartialBlockOkay => false;
public TeaEngine()
{
_initialised = false;
}
public virtual int GetBlockSize()
{
return 8;
}
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
if (!(parameters is KeyParameter))
{
throw new ArgumentException("invalid parameter passed to TEA init - " + Platform.GetTypeName(parameters));
}
_forEncryption = forEncryption;
_initialised = true;
KeyParameter keyParameter = (KeyParameter)parameters;
setKey(keyParameter.GetKey());
}
public virtual int ProcessBlock(byte[] inBytes, int inOff, byte[] outBytes, int outOff)
{
if (!_initialised)
{
throw new InvalidOperationException(AlgorithmName + " not initialised");
}
Check.DataLength(inBytes, inOff, 8, "input buffer too short");
Check.OutputLength(outBytes, outOff, 8, "output buffer too short");
if (!_forEncryption)
{
return decryptBlock(inBytes, inOff, outBytes, outOff);
}
return encryptBlock(inBytes, inOff, outBytes, outOff);
}
public virtual void Reset()
{
}
private void setKey(byte[] key)
{
_a = Pack.BE_To_UInt32(key, 0);
_b = Pack.BE_To_UInt32(key, 4);
_c = Pack.BE_To_UInt32(key, 8);
_d = Pack.BE_To_UInt32(key, 12);
}
private int encryptBlock(byte[] inBytes, int inOff, byte[] outBytes, int outOff)
{
uint num = Pack.BE_To_UInt32(inBytes, inOff);
uint num2 = Pack.BE_To_UInt32(inBytes, inOff + 4);
uint num3 = 0u;
for (int i = 0; i != 32; i++)
{
num3 += 2654435769u;
num += ((num2 << 4) + _a) ^ (num2 + num3) ^ ((num2 >> 5) + _b);
num2 += ((num << 4) + _c) ^ (num + num3) ^ ((num >> 5) + _d);
}
Pack.UInt32_To_BE(num, outBytes, outOff);
Pack.UInt32_To_BE(num2, outBytes, outOff + 4);
return 8;
}
private int decryptBlock(byte[] inBytes, int inOff, byte[] outBytes, int outOff)
{
uint num = Pack.BE_To_UInt32(inBytes, inOff);
uint num2 = Pack.BE_To_UInt32(inBytes, inOff + 4);
uint num3 = 3337565984u;
for (int i = 0; i != 32; i++)
{
num2 -= ((num << 4) + _c) ^ (num + num3) ^ ((num >> 5) + _d);
num -= ((num2 << 4) + _a) ^ (num2 + num3) ^ ((num2 >> 5) + _b);
num3 -= 2654435769u;
}
Pack.UInt32_To_BE(num, outBytes, outOff);
Pack.UInt32_To_BE(num2, outBytes, outOff + 4);
return 8;
}
}

View File

@@ -0,0 +1,480 @@
using System;
using Org.BouncyCastle.Crypto.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public sealed class TnepresEngine : SerpentEngineBase
{
public override string AlgorithmName => "Tnepres";
protected override int[] MakeWorkingKey(byte[] key)
{
int[] array = new int[16];
int num = 0;
int num2 = 0;
for (num = key.Length - 4; num > 0; num -= 4)
{
array[num2++] = (int)Pack.BE_To_UInt32(key, num);
}
if (num == 0)
{
array[num2++] = (int)Pack.BE_To_UInt32(key, 0);
if (num2 < 8)
{
array[num2] = 1;
}
int num3 = 132;
int[] array2 = new int[num3];
for (int i = 8; i < 16; i++)
{
array[i] = SerpentEngineBase.RotateLeft(array[i - 8] ^ array[i - 5] ^ array[i - 3] ^ array[i - 1] ^ -1640531527 ^ (i - 8), 11);
}
Array.Copy(array, 8, array2, 0, 8);
for (int j = 8; j < num3; j++)
{
array2[j] = SerpentEngineBase.RotateLeft(array2[j - 8] ^ array2[j - 5] ^ array2[j - 3] ^ array2[j - 1] ^ -1640531527 ^ j, 11);
}
Sb3(array2[0], array2[1], array2[2], array2[3]);
array2[0] = X0;
array2[1] = X1;
array2[2] = X2;
array2[3] = X3;
Sb2(array2[4], array2[5], array2[6], array2[7]);
array2[4] = X0;
array2[5] = X1;
array2[6] = X2;
array2[7] = X3;
Sb1(array2[8], array2[9], array2[10], array2[11]);
array2[8] = X0;
array2[9] = X1;
array2[10] = X2;
array2[11] = X3;
Sb0(array2[12], array2[13], array2[14], array2[15]);
array2[12] = X0;
array2[13] = X1;
array2[14] = X2;
array2[15] = X3;
Sb7(array2[16], array2[17], array2[18], array2[19]);
array2[16] = X0;
array2[17] = X1;
array2[18] = X2;
array2[19] = X3;
Sb6(array2[20], array2[21], array2[22], array2[23]);
array2[20] = X0;
array2[21] = X1;
array2[22] = X2;
array2[23] = X3;
Sb5(array2[24], array2[25], array2[26], array2[27]);
array2[24] = X0;
array2[25] = X1;
array2[26] = X2;
array2[27] = X3;
Sb4(array2[28], array2[29], array2[30], array2[31]);
array2[28] = X0;
array2[29] = X1;
array2[30] = X2;
array2[31] = X3;
Sb3(array2[32], array2[33], array2[34], array2[35]);
array2[32] = X0;
array2[33] = X1;
array2[34] = X2;
array2[35] = X3;
Sb2(array2[36], array2[37], array2[38], array2[39]);
array2[36] = X0;
array2[37] = X1;
array2[38] = X2;
array2[39] = X3;
Sb1(array2[40], array2[41], array2[42], array2[43]);
array2[40] = X0;
array2[41] = X1;
array2[42] = X2;
array2[43] = X3;
Sb0(array2[44], array2[45], array2[46], array2[47]);
array2[44] = X0;
array2[45] = X1;
array2[46] = X2;
array2[47] = X3;
Sb7(array2[48], array2[49], array2[50], array2[51]);
array2[48] = X0;
array2[49] = X1;
array2[50] = X2;
array2[51] = X3;
Sb6(array2[52], array2[53], array2[54], array2[55]);
array2[52] = X0;
array2[53] = X1;
array2[54] = X2;
array2[55] = X3;
Sb5(array2[56], array2[57], array2[58], array2[59]);
array2[56] = X0;
array2[57] = X1;
array2[58] = X2;
array2[59] = X3;
Sb4(array2[60], array2[61], array2[62], array2[63]);
array2[60] = X0;
array2[61] = X1;
array2[62] = X2;
array2[63] = X3;
Sb3(array2[64], array2[65], array2[66], array2[67]);
array2[64] = X0;
array2[65] = X1;
array2[66] = X2;
array2[67] = X3;
Sb2(array2[68], array2[69], array2[70], array2[71]);
array2[68] = X0;
array2[69] = X1;
array2[70] = X2;
array2[71] = X3;
Sb1(array2[72], array2[73], array2[74], array2[75]);
array2[72] = X0;
array2[73] = X1;
array2[74] = X2;
array2[75] = X3;
Sb0(array2[76], array2[77], array2[78], array2[79]);
array2[76] = X0;
array2[77] = X1;
array2[78] = X2;
array2[79] = X3;
Sb7(array2[80], array2[81], array2[82], array2[83]);
array2[80] = X0;
array2[81] = X1;
array2[82] = X2;
array2[83] = X3;
Sb6(array2[84], array2[85], array2[86], array2[87]);
array2[84] = X0;
array2[85] = X1;
array2[86] = X2;
array2[87] = X3;
Sb5(array2[88], array2[89], array2[90], array2[91]);
array2[88] = X0;
array2[89] = X1;
array2[90] = X2;
array2[91] = X3;
Sb4(array2[92], array2[93], array2[94], array2[95]);
array2[92] = X0;
array2[93] = X1;
array2[94] = X2;
array2[95] = X3;
Sb3(array2[96], array2[97], array2[98], array2[99]);
array2[96] = X0;
array2[97] = X1;
array2[98] = X2;
array2[99] = X3;
Sb2(array2[100], array2[101], array2[102], array2[103]);
array2[100] = X0;
array2[101] = X1;
array2[102] = X2;
array2[103] = X3;
Sb1(array2[104], array2[105], array2[106], array2[107]);
array2[104] = X0;
array2[105] = X1;
array2[106] = X2;
array2[107] = X3;
Sb0(array2[108], array2[109], array2[110], array2[111]);
array2[108] = X0;
array2[109] = X1;
array2[110] = X2;
array2[111] = X3;
Sb7(array2[112], array2[113], array2[114], array2[115]);
array2[112] = X0;
array2[113] = X1;
array2[114] = X2;
array2[115] = X3;
Sb6(array2[116], array2[117], array2[118], array2[119]);
array2[116] = X0;
array2[117] = X1;
array2[118] = X2;
array2[119] = X3;
Sb5(array2[120], array2[121], array2[122], array2[123]);
array2[120] = X0;
array2[121] = X1;
array2[122] = X2;
array2[123] = X3;
Sb4(array2[124], array2[125], array2[126], array2[127]);
array2[124] = X0;
array2[125] = X1;
array2[126] = X2;
array2[127] = X3;
Sb3(array2[128], array2[129], array2[130], array2[131]);
array2[128] = X0;
array2[129] = X1;
array2[130] = X2;
array2[131] = X3;
return array2;
}
throw new ArgumentException("key must be a multiple of 4 bytes");
}
protected override void EncryptBlock(byte[] input, int inOff, byte[] output, int outOff)
{
X3 = (int)Pack.BE_To_UInt32(input, inOff);
X2 = (int)Pack.BE_To_UInt32(input, inOff + 4);
X1 = (int)Pack.BE_To_UInt32(input, inOff + 8);
X0 = (int)Pack.BE_To_UInt32(input, inOff + 12);
Sb0(wKey[0] ^ X0, wKey[1] ^ X1, wKey[2] ^ X2, wKey[3] ^ X3);
LT();
Sb1(wKey[4] ^ X0, wKey[5] ^ X1, wKey[6] ^ X2, wKey[7] ^ X3);
LT();
Sb2(wKey[8] ^ X0, wKey[9] ^ X1, wKey[10] ^ X2, wKey[11] ^ X3);
LT();
Sb3(wKey[12] ^ X0, wKey[13] ^ X1, wKey[14] ^ X2, wKey[15] ^ X3);
LT();
Sb4(wKey[16] ^ X0, wKey[17] ^ X1, wKey[18] ^ X2, wKey[19] ^ X3);
LT();
Sb5(wKey[20] ^ X0, wKey[21] ^ X1, wKey[22] ^ X2, wKey[23] ^ X3);
LT();
Sb6(wKey[24] ^ X0, wKey[25] ^ X1, wKey[26] ^ X2, wKey[27] ^ X3);
LT();
Sb7(wKey[28] ^ X0, wKey[29] ^ X1, wKey[30] ^ X2, wKey[31] ^ X3);
LT();
Sb0(wKey[32] ^ X0, wKey[33] ^ X1, wKey[34] ^ X2, wKey[35] ^ X3);
LT();
Sb1(wKey[36] ^ X0, wKey[37] ^ X1, wKey[38] ^ X2, wKey[39] ^ X3);
LT();
Sb2(wKey[40] ^ X0, wKey[41] ^ X1, wKey[42] ^ X2, wKey[43] ^ X3);
LT();
Sb3(wKey[44] ^ X0, wKey[45] ^ X1, wKey[46] ^ X2, wKey[47] ^ X3);
LT();
Sb4(wKey[48] ^ X0, wKey[49] ^ X1, wKey[50] ^ X2, wKey[51] ^ X3);
LT();
Sb5(wKey[52] ^ X0, wKey[53] ^ X1, wKey[54] ^ X2, wKey[55] ^ X3);
LT();
Sb6(wKey[56] ^ X0, wKey[57] ^ X1, wKey[58] ^ X2, wKey[59] ^ X3);
LT();
Sb7(wKey[60] ^ X0, wKey[61] ^ X1, wKey[62] ^ X2, wKey[63] ^ X3);
LT();
Sb0(wKey[64] ^ X0, wKey[65] ^ X1, wKey[66] ^ X2, wKey[67] ^ X3);
LT();
Sb1(wKey[68] ^ X0, wKey[69] ^ X1, wKey[70] ^ X2, wKey[71] ^ X3);
LT();
Sb2(wKey[72] ^ X0, wKey[73] ^ X1, wKey[74] ^ X2, wKey[75] ^ X3);
LT();
Sb3(wKey[76] ^ X0, wKey[77] ^ X1, wKey[78] ^ X2, wKey[79] ^ X3);
LT();
Sb4(wKey[80] ^ X0, wKey[81] ^ X1, wKey[82] ^ X2, wKey[83] ^ X3);
LT();
Sb5(wKey[84] ^ X0, wKey[85] ^ X1, wKey[86] ^ X2, wKey[87] ^ X3);
LT();
Sb6(wKey[88] ^ X0, wKey[89] ^ X1, wKey[90] ^ X2, wKey[91] ^ X3);
LT();
Sb7(wKey[92] ^ X0, wKey[93] ^ X1, wKey[94] ^ X2, wKey[95] ^ X3);
LT();
Sb0(wKey[96] ^ X0, wKey[97] ^ X1, wKey[98] ^ X2, wKey[99] ^ X3);
LT();
Sb1(wKey[100] ^ X0, wKey[101] ^ X1, wKey[102] ^ X2, wKey[103] ^ X3);
LT();
Sb2(wKey[104] ^ X0, wKey[105] ^ X1, wKey[106] ^ X2, wKey[107] ^ X3);
LT();
Sb3(wKey[108] ^ X0, wKey[109] ^ X1, wKey[110] ^ X2, wKey[111] ^ X3);
LT();
Sb4(wKey[112] ^ X0, wKey[113] ^ X1, wKey[114] ^ X2, wKey[115] ^ X3);
LT();
Sb5(wKey[116] ^ X0, wKey[117] ^ X1, wKey[118] ^ X2, wKey[119] ^ X3);
LT();
Sb6(wKey[120] ^ X0, wKey[121] ^ X1, wKey[122] ^ X2, wKey[123] ^ X3);
LT();
Sb7(wKey[124] ^ X0, wKey[125] ^ X1, wKey[126] ^ X2, wKey[127] ^ X3);
Pack.UInt32_To_BE((uint)(wKey[131] ^ X3), output, outOff);
Pack.UInt32_To_BE((uint)(wKey[130] ^ X2), output, outOff + 4);
Pack.UInt32_To_BE((uint)(wKey[129] ^ X1), output, outOff + 8);
Pack.UInt32_To_BE((uint)(wKey[128] ^ X0), output, outOff + 12);
}
protected override void DecryptBlock(byte[] input, int inOff, byte[] output, int outOff)
{
X3 = wKey[131] ^ (int)Pack.BE_To_UInt32(input, inOff);
X2 = wKey[130] ^ (int)Pack.BE_To_UInt32(input, inOff + 4);
X1 = wKey[129] ^ (int)Pack.BE_To_UInt32(input, inOff + 8);
X0 = wKey[128] ^ (int)Pack.BE_To_UInt32(input, inOff + 12);
Ib7(X0, X1, X2, X3);
X0 ^= wKey[124];
X1 ^= wKey[125];
X2 ^= wKey[126];
X3 ^= wKey[127];
InverseLT();
Ib6(X0, X1, X2, X3);
X0 ^= wKey[120];
X1 ^= wKey[121];
X2 ^= wKey[122];
X3 ^= wKey[123];
InverseLT();
Ib5(X0, X1, X2, X3);
X0 ^= wKey[116];
X1 ^= wKey[117];
X2 ^= wKey[118];
X3 ^= wKey[119];
InverseLT();
Ib4(X0, X1, X2, X3);
X0 ^= wKey[112];
X1 ^= wKey[113];
X2 ^= wKey[114];
X3 ^= wKey[115];
InverseLT();
Ib3(X0, X1, X2, X3);
X0 ^= wKey[108];
X1 ^= wKey[109];
X2 ^= wKey[110];
X3 ^= wKey[111];
InverseLT();
Ib2(X0, X1, X2, X3);
X0 ^= wKey[104];
X1 ^= wKey[105];
X2 ^= wKey[106];
X3 ^= wKey[107];
InverseLT();
Ib1(X0, X1, X2, X3);
X0 ^= wKey[100];
X1 ^= wKey[101];
X2 ^= wKey[102];
X3 ^= wKey[103];
InverseLT();
Ib0(X0, X1, X2, X3);
X0 ^= wKey[96];
X1 ^= wKey[97];
X2 ^= wKey[98];
X3 ^= wKey[99];
InverseLT();
Ib7(X0, X1, X2, X3);
X0 ^= wKey[92];
X1 ^= wKey[93];
X2 ^= wKey[94];
X3 ^= wKey[95];
InverseLT();
Ib6(X0, X1, X2, X3);
X0 ^= wKey[88];
X1 ^= wKey[89];
X2 ^= wKey[90];
X3 ^= wKey[91];
InverseLT();
Ib5(X0, X1, X2, X3);
X0 ^= wKey[84];
X1 ^= wKey[85];
X2 ^= wKey[86];
X3 ^= wKey[87];
InverseLT();
Ib4(X0, X1, X2, X3);
X0 ^= wKey[80];
X1 ^= wKey[81];
X2 ^= wKey[82];
X3 ^= wKey[83];
InverseLT();
Ib3(X0, X1, X2, X3);
X0 ^= wKey[76];
X1 ^= wKey[77];
X2 ^= wKey[78];
X3 ^= wKey[79];
InverseLT();
Ib2(X0, X1, X2, X3);
X0 ^= wKey[72];
X1 ^= wKey[73];
X2 ^= wKey[74];
X3 ^= wKey[75];
InverseLT();
Ib1(X0, X1, X2, X3);
X0 ^= wKey[68];
X1 ^= wKey[69];
X2 ^= wKey[70];
X3 ^= wKey[71];
InverseLT();
Ib0(X0, X1, X2, X3);
X0 ^= wKey[64];
X1 ^= wKey[65];
X2 ^= wKey[66];
X3 ^= wKey[67];
InverseLT();
Ib7(X0, X1, X2, X3);
X0 ^= wKey[60];
X1 ^= wKey[61];
X2 ^= wKey[62];
X3 ^= wKey[63];
InverseLT();
Ib6(X0, X1, X2, X3);
X0 ^= wKey[56];
X1 ^= wKey[57];
X2 ^= wKey[58];
X3 ^= wKey[59];
InverseLT();
Ib5(X0, X1, X2, X3);
X0 ^= wKey[52];
X1 ^= wKey[53];
X2 ^= wKey[54];
X3 ^= wKey[55];
InverseLT();
Ib4(X0, X1, X2, X3);
X0 ^= wKey[48];
X1 ^= wKey[49];
X2 ^= wKey[50];
X3 ^= wKey[51];
InverseLT();
Ib3(X0, X1, X2, X3);
X0 ^= wKey[44];
X1 ^= wKey[45];
X2 ^= wKey[46];
X3 ^= wKey[47];
InverseLT();
Ib2(X0, X1, X2, X3);
X0 ^= wKey[40];
X1 ^= wKey[41];
X2 ^= wKey[42];
X3 ^= wKey[43];
InverseLT();
Ib1(X0, X1, X2, X3);
X0 ^= wKey[36];
X1 ^= wKey[37];
X2 ^= wKey[38];
X3 ^= wKey[39];
InverseLT();
Ib0(X0, X1, X2, X3);
X0 ^= wKey[32];
X1 ^= wKey[33];
X2 ^= wKey[34];
X3 ^= wKey[35];
InverseLT();
Ib7(X0, X1, X2, X3);
X0 ^= wKey[28];
X1 ^= wKey[29];
X2 ^= wKey[30];
X3 ^= wKey[31];
InverseLT();
Ib6(X0, X1, X2, X3);
X0 ^= wKey[24];
X1 ^= wKey[25];
X2 ^= wKey[26];
X3 ^= wKey[27];
InverseLT();
Ib5(X0, X1, X2, X3);
X0 ^= wKey[20];
X1 ^= wKey[21];
X2 ^= wKey[22];
X3 ^= wKey[23];
InverseLT();
Ib4(X0, X1, X2, X3);
X0 ^= wKey[16];
X1 ^= wKey[17];
X2 ^= wKey[18];
X3 ^= wKey[19];
InverseLT();
Ib3(X0, X1, X2, X3);
X0 ^= wKey[12];
X1 ^= wKey[13];
X2 ^= wKey[14];
X3 ^= wKey[15];
InverseLT();
Ib2(X0, X1, X2, X3);
X0 ^= wKey[8];
X1 ^= wKey[9];
X2 ^= wKey[10];
X3 ^= wKey[11];
InverseLT();
Ib1(X0, X1, X2, X3);
X0 ^= wKey[4];
X1 ^= wKey[5];
X2 ^= wKey[6];
X3 ^= wKey[7];
InverseLT();
Ib0(X0, X1, X2, X3);
Pack.UInt32_To_BE((uint)(X3 ^ wKey[3]), output, outOff);
Pack.UInt32_To_BE((uint)(X2 ^ wKey[2]), output, outOff + 4);
Pack.UInt32_To_BE((uint)(X1 ^ wKey[1]), output, outOff + 8);
Pack.UInt32_To_BE((uint)(X0 ^ wKey[0]), output, outOff + 12);
}
}

View File

@@ -0,0 +1,474 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public sealed class TwofishEngine : IBlockCipher
{
private const int P_00 = 1;
private const int P_01 = 0;
private const int P_02 = 0;
private const int P_03 = 1;
private const int P_04 = 1;
private const int P_10 = 0;
private const int P_11 = 0;
private const int P_12 = 1;
private const int P_13 = 1;
private const int P_14 = 0;
private const int P_20 = 1;
private const int P_21 = 1;
private const int P_22 = 0;
private const int P_23 = 0;
private const int P_24 = 0;
private const int P_30 = 0;
private const int P_31 = 1;
private const int P_32 = 1;
private const int P_33 = 0;
private const int P_34 = 1;
private const int GF256_FDBK = 361;
private const int GF256_FDBK_2 = 180;
private const int GF256_FDBK_4 = 90;
private const int RS_GF_FDBK = 333;
private const int ROUNDS = 16;
private const int MAX_ROUNDS = 16;
private const int BLOCK_SIZE = 16;
private const int MAX_KEY_BITS = 256;
private const int INPUT_WHITEN = 0;
private const int OUTPUT_WHITEN = 4;
private const int ROUND_SUBKEYS = 8;
private const int TOTAL_SUBKEYS = 40;
private const int SK_STEP = 33686018;
private const int SK_BUMP = 16843009;
private const int SK_ROTL = 9;
private static readonly byte[,] P = new byte[2, 256]
{
{
169, 103, 179, 232, 4, 253, 163, 118, 154, 146,
128, 120, 228, 221, 209, 56, 13, 198, 53, 152,
24, 247, 236, 108, 67, 117, 55, 38, 250, 19,
148, 72, 242, 208, 139, 48, 132, 84, 223, 35,
25, 91, 61, 89, 243, 174, 162, 130, 99, 1,
131, 46, 217, 81, 155, 124, 166, 235, 165, 190,
22, 12, 227, 97, 192, 140, 58, 245, 115, 44,
37, 11, 187, 78, 137, 107, 83, 106, 180, 241,
225, 230, 189, 69, 226, 244, 182, 102, 204, 149,
3, 86, 212, 28, 30, 215, 251, 195, 142, 181,
233, 207, 191, 186, 234, 119, 57, 175, 51, 201,
98, 113, 129, 121, 9, 173, 36, 205, 249, 216,
229, 197, 185, 77, 68, 8, 134, 231, 161, 29,
170, 237, 6, 112, 178, 210, 65, 123, 160, 17,
49, 194, 39, 144, 32, 246, 96, 255, 150, 92,
177, 171, 158, 156, 82, 27, 95, 147, 10, 239,
145, 133, 73, 238, 45, 79, 143, 59, 71, 135,
109, 70, 214, 62, 105, 100, 42, 206, 203, 47,
252, 151, 5, 122, 172, 127, 213, 26, 75, 14,
167, 90, 40, 20, 63, 41, 136, 60, 76, 2,
184, 218, 176, 23, 85, 31, 138, 125, 87, 199,
141, 116, 183, 196, 159, 114, 126, 21, 34, 18,
88, 7, 153, 52, 110, 80, 222, 104, 101, 188,
219, 248, 200, 168, 43, 64, 220, 254, 50, 164,
202, 16, 33, 240, 211, 93, 15, 0, 111, 157,
54, 66, 74, 94, 193, 224
},
{
117, 243, 198, 244, 219, 123, 251, 200, 74, 211,
230, 107, 69, 125, 232, 75, 214, 50, 216, 253,
55, 113, 241, 225, 48, 15, 248, 27, 135, 250,
6, 63, 94, 186, 174, 91, 138, 0, 188, 157,
109, 193, 177, 14, 128, 93, 210, 213, 160, 132,
7, 20, 181, 144, 44, 163, 178, 115, 76, 84,
146, 116, 54, 81, 56, 176, 189, 90, 252, 96,
98, 150, 108, 66, 247, 16, 124, 40, 39, 140,
19, 149, 156, 199, 36, 70, 59, 112, 202, 227,
133, 203, 17, 208, 147, 184, 166, 131, 32, 255,
159, 119, 195, 204, 3, 111, 8, 191, 64, 231,
43, 226, 121, 12, 170, 130, 65, 58, 234, 185,
228, 154, 164, 151, 126, 218, 122, 23, 102, 148,
161, 29, 61, 240, 222, 179, 11, 114, 167, 28,
239, 209, 83, 62, 143, 51, 38, 95, 236, 118,
42, 73, 129, 136, 238, 33, 196, 26, 235, 217,
197, 57, 153, 205, 173, 49, 139, 1, 24, 35,
221, 31, 78, 45, 249, 72, 79, 242, 101, 142,
120, 92, 88, 25, 141, 229, 152, 87, 103, 127,
5, 100, 175, 99, 182, 254, 245, 183, 60, 165,
206, 233, 104, 68, 224, 77, 67, 105, 41, 46,
172, 21, 89, 168, 10, 158, 110, 71, 223, 52,
53, 106, 207, 220, 34, 201, 192, 155, 137, 212,
237, 171, 18, 162, 13, 82, 187, 2, 47, 169,
215, 97, 30, 180, 80, 4, 246, 194, 22, 37,
134, 86, 85, 9, 190, 145
}
};
private bool encrypting;
private int[] gMDS0 = new int[256];
private int[] gMDS1 = new int[256];
private int[] gMDS2 = new int[256];
private int[] gMDS3 = new int[256];
private int[] gSubKeys;
private int[] gSBox;
private int k64Cnt;
private byte[] workingKey;
public string AlgorithmName => "Twofish";
public bool IsPartialBlockOkay => false;
public TwofishEngine()
{
int[] array = new int[2];
int[] array2 = new int[2];
int[] array3 = new int[2];
for (int i = 0; i < 256; i++)
{
int x = (array[0] = P[0, i] & 0xFF);
array2[0] = Mx_X(x) & 0xFF;
array3[0] = Mx_Y(x) & 0xFF;
x = (array[1] = P[1, i] & 0xFF);
array2[1] = Mx_X(x) & 0xFF;
array3[1] = Mx_Y(x) & 0xFF;
gMDS0[i] = array[1] | (array2[1] << 8) | (array3[1] << 16) | (array3[1] << 24);
gMDS1[i] = array3[0] | (array3[0] << 8) | (array2[0] << 16) | (array[0] << 24);
gMDS2[i] = array2[1] | (array3[1] << 8) | (array[1] << 16) | (array3[1] << 24);
gMDS3[i] = array2[0] | (array[0] << 8) | (array3[0] << 16) | (array2[0] << 24);
}
}
public void Init(bool forEncryption, ICipherParameters parameters)
{
if (!(parameters is KeyParameter))
{
throw new ArgumentException("invalid parameter passed to Twofish init - " + Platform.GetTypeName(parameters));
}
encrypting = forEncryption;
workingKey = ((KeyParameter)parameters).GetKey();
k64Cnt = workingKey.Length / 8;
SetKey(workingKey);
}
public int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
{
if (workingKey == null)
{
throw new InvalidOperationException("Twofish not initialised");
}
Check.DataLength(input, inOff, 16, "input buffer too short");
Check.OutputLength(output, outOff, 16, "output buffer too short");
if (encrypting)
{
EncryptBlock(input, inOff, output, outOff);
}
else
{
DecryptBlock(input, inOff, output, outOff);
}
return 16;
}
public void Reset()
{
if (workingKey != null)
{
SetKey(workingKey);
}
}
public int GetBlockSize()
{
return 16;
}
private void SetKey(byte[] key)
{
int[] array = new int[4];
int[] array2 = new int[4];
int[] array3 = new int[4];
gSubKeys = new int[40];
if (k64Cnt < 1)
{
throw new ArgumentException("Key size less than 64 bits");
}
if (k64Cnt > 4)
{
throw new ArgumentException("Key size larger than 256 bits");
}
int i = 0;
int num = 0;
for (; i < k64Cnt; i++)
{
num = i * 8;
array[i] = BytesTo32Bits(key, num);
array2[i] = BytesTo32Bits(key, num + 4);
array3[k64Cnt - 1 - i] = RS_MDS_Encode(array[i], array2[i]);
}
for (int j = 0; j < 20; j++)
{
int num2 = j * 33686018;
int num3 = F32(num2, array);
int num4 = F32(num2 + 16843009, array2);
num4 = (num4 << 8) | (num4 >>> 24);
num3 += num4;
gSubKeys[j * 2] = num3;
num3 += num4;
gSubKeys[j * 2 + 1] = (num3 << 9) | (num3 >>> 23);
}
int x = array3[0];
int x2 = array3[1];
int x3 = array3[2];
int x4 = array3[3];
gSBox = new int[1024];
for (int k = 0; k < 256; k++)
{
int num6;
int num7;
int num8;
int num5 = (num6 = (num7 = (num8 = k)));
switch (k64Cnt & 3)
{
case 1:
gSBox[k * 2] = gMDS0[(P[0, num5] & 0xFF) ^ M_b0(x)];
gSBox[k * 2 + 1] = gMDS1[(P[0, num6] & 0xFF) ^ M_b1(x)];
gSBox[k * 2 + 512] = gMDS2[(P[1, num7] & 0xFF) ^ M_b2(x)];
gSBox[k * 2 + 513] = gMDS3[(P[1, num8] & 0xFF) ^ M_b3(x)];
continue;
case 0:
num5 = (P[1, num5] & 0xFF) ^ M_b0(x4);
num6 = (P[0, num6] & 0xFF) ^ M_b1(x4);
num7 = (P[0, num7] & 0xFF) ^ M_b2(x4);
num8 = (P[1, num8] & 0xFF) ^ M_b3(x4);
goto case 3;
case 3:
num5 = (P[1, num5] & 0xFF) ^ M_b0(x3);
num6 = (P[1, num6] & 0xFF) ^ M_b1(x3);
num7 = (P[0, num7] & 0xFF) ^ M_b2(x3);
num8 = (P[0, num8] & 0xFF) ^ M_b3(x3);
break;
case 2:
break;
default:
continue;
}
gSBox[k * 2] = gMDS0[(P[0, (P[0, num5] & 0xFF) ^ M_b0(x2)] & 0xFF) ^ M_b0(x)];
gSBox[k * 2 + 1] = gMDS1[(P[0, (P[1, num6] & 0xFF) ^ M_b1(x2)] & 0xFF) ^ M_b1(x)];
gSBox[k * 2 + 512] = gMDS2[(P[1, (P[0, num7] & 0xFF) ^ M_b2(x2)] & 0xFF) ^ M_b2(x)];
gSBox[k * 2 + 513] = gMDS3[(P[1, (P[1, num8] & 0xFF) ^ M_b3(x2)] & 0xFF) ^ M_b3(x)];
}
}
private void EncryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex)
{
int num = BytesTo32Bits(src, srcIndex) ^ gSubKeys[0];
int num2 = BytesTo32Bits(src, srcIndex + 4) ^ gSubKeys[1];
int num3 = BytesTo32Bits(src, srcIndex + 8) ^ gSubKeys[2];
int num4 = BytesTo32Bits(src, srcIndex + 12) ^ gSubKeys[3];
int num5 = 8;
for (int i = 0; i < 16; i += 2)
{
int num6 = Fe32_0(num);
int num7 = Fe32_3(num2);
num3 ^= num6 + num7 + gSubKeys[num5++];
num3 = (num3 >>> 1) | (num3 << 31);
num4 = ((num4 << 1) | (num4 >>> 31)) ^ (num6 + 2 * num7 + gSubKeys[num5++]);
num6 = Fe32_0(num3);
num7 = Fe32_3(num4);
num ^= num6 + num7 + gSubKeys[num5++];
num = (num >>> 1) | (num << 31);
num2 = ((num2 << 1) | (num2 >>> 31)) ^ (num6 + 2 * num7 + gSubKeys[num5++]);
}
Bits32ToBytes(num3 ^ gSubKeys[4], dst, dstIndex);
Bits32ToBytes(num4 ^ gSubKeys[5], dst, dstIndex + 4);
Bits32ToBytes(num ^ gSubKeys[6], dst, dstIndex + 8);
Bits32ToBytes(num2 ^ gSubKeys[7], dst, dstIndex + 12);
}
private void DecryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex)
{
int num = BytesTo32Bits(src, srcIndex) ^ gSubKeys[4];
int num2 = BytesTo32Bits(src, srcIndex + 4) ^ gSubKeys[5];
int num3 = BytesTo32Bits(src, srcIndex + 8) ^ gSubKeys[6];
int num4 = BytesTo32Bits(src, srcIndex + 12) ^ gSubKeys[7];
int num5 = 39;
for (int i = 0; i < 16; i += 2)
{
int num6 = Fe32_0(num);
int num7 = Fe32_3(num2);
num4 ^= num6 + 2 * num7 + gSubKeys[num5--];
num3 = ((num3 << 1) | (num3 >>> 31)) ^ (num6 + num7 + gSubKeys[num5--]);
num4 = (num4 >>> 1) | (num4 << 31);
num6 = Fe32_0(num3);
num7 = Fe32_3(num4);
num2 ^= num6 + 2 * num7 + gSubKeys[num5--];
num = ((num << 1) | (num >>> 31)) ^ (num6 + num7 + gSubKeys[num5--]);
num2 = (num2 >>> 1) | (num2 << 31);
}
Bits32ToBytes(num3 ^ gSubKeys[0], dst, dstIndex);
Bits32ToBytes(num4 ^ gSubKeys[1], dst, dstIndex + 4);
Bits32ToBytes(num ^ gSubKeys[2], dst, dstIndex + 8);
Bits32ToBytes(num2 ^ gSubKeys[3], dst, dstIndex + 12);
}
private int F32(int x, int[] k32)
{
int num = M_b0(x);
int num2 = M_b1(x);
int num3 = M_b2(x);
int num4 = M_b3(x);
int x2 = k32[0];
int x3 = k32[1];
int x4 = k32[2];
int x5 = k32[3];
int result = 0;
switch (k64Cnt & 3)
{
case 1:
result = gMDS0[(P[0, num] & 0xFF) ^ M_b0(x2)] ^ gMDS1[(P[0, num2] & 0xFF) ^ M_b1(x2)] ^ gMDS2[(P[1, num3] & 0xFF) ^ M_b2(x2)] ^ gMDS3[(P[1, num4] & 0xFF) ^ M_b3(x2)];
break;
case 0:
num = (P[1, num] & 0xFF) ^ M_b0(x5);
num2 = (P[0, num2] & 0xFF) ^ M_b1(x5);
num3 = (P[0, num3] & 0xFF) ^ M_b2(x5);
num4 = (P[1, num4] & 0xFF) ^ M_b3(x5);
goto case 3;
case 3:
num = (P[1, num] & 0xFF) ^ M_b0(x4);
num2 = (P[1, num2] & 0xFF) ^ M_b1(x4);
num3 = (P[0, num3] & 0xFF) ^ M_b2(x4);
num4 = (P[0, num4] & 0xFF) ^ M_b3(x4);
goto case 2;
case 2:
result = gMDS0[(P[0, (P[0, num] & 0xFF) ^ M_b0(x3)] & 0xFF) ^ M_b0(x2)] ^ gMDS1[(P[0, (P[1, num2] & 0xFF) ^ M_b1(x3)] & 0xFF) ^ M_b1(x2)] ^ gMDS2[(P[1, (P[0, num3] & 0xFF) ^ M_b2(x3)] & 0xFF) ^ M_b2(x2)] ^ gMDS3[(P[1, (P[1, num4] & 0xFF) ^ M_b3(x3)] & 0xFF) ^ M_b3(x2)];
break;
}
return result;
}
private int RS_MDS_Encode(int k0, int k1)
{
int num = k1;
for (int i = 0; i < 4; i++)
{
num = RS_rem(num);
}
num ^= k0;
for (int j = 0; j < 4; j++)
{
num = RS_rem(num);
}
return num;
}
private int RS_rem(int x)
{
int num = (x >>> 24) & 0xFF;
int num2 = ((num << 1) ^ (((num & 0x80) != 0) ? 333 : 0)) & 0xFF;
int num3 = (num >>> 1) ^ (((num & 1) != 0) ? 166 : 0) ^ num2;
return (x << 8) ^ (num3 << 24) ^ (num2 << 16) ^ (num3 << 8) ^ num;
}
private int LFSR1(int x)
{
return (x >> 1) ^ (((x & 1) != 0) ? 180 : 0);
}
private int LFSR2(int x)
{
return (x >> 2) ^ (((x & 2) != 0) ? 180 : 0) ^ (((x & 1) != 0) ? 90 : 0);
}
private int Mx_X(int x)
{
return x ^ LFSR2(x);
}
private int Mx_Y(int x)
{
return x ^ LFSR1(x) ^ LFSR2(x);
}
private int M_b0(int x)
{
return x & 0xFF;
}
private int M_b1(int x)
{
return (x >>> 8) & 0xFF;
}
private int M_b2(int x)
{
return (x >>> 16) & 0xFF;
}
private int M_b3(int x)
{
return (x >>> 24) & 0xFF;
}
private int Fe32_0(int x)
{
return gSBox[2 * (x & 0xFF)] ^ gSBox[1 + 2 * ((x >>> 8) & 0xFF)] ^ gSBox[512 + 2 * ((x >>> 16) & 0xFF)] ^ gSBox[513 + 2 * ((x >>> 24) & 0xFF)];
}
private int Fe32_3(int x)
{
return gSBox[2 * ((x >>> 24) & 0xFF)] ^ gSBox[1 + 2 * (x & 0xFF)] ^ gSBox[512 + 2 * ((x >>> 8) & 0xFF)] ^ gSBox[513 + 2 * ((x >>> 16) & 0xFF)];
}
private int BytesTo32Bits(byte[] b, int p)
{
return (b[p] & 0xFF) | ((b[p + 1] & 0xFF) << 8) | ((b[p + 2] & 0xFF) << 16) | ((b[p + 3] & 0xFF) << 24);
}
private void Bits32ToBytes(int inData, byte[] b, int offset)
{
b[offset] = (byte)inData;
b[offset + 1] = (byte)(inData >> 8);
b[offset + 2] = (byte)(inData >> 16);
b[offset + 3] = (byte)(inData >> 24);
}
}

View File

@@ -0,0 +1,97 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
namespace Org.BouncyCastle.Crypto.Engines;
public class VmpcEngine : IStreamCipher
{
protected byte n = 0;
protected byte[] P = null;
protected byte s = 0;
protected byte[] workingIV;
protected byte[] workingKey;
public virtual string AlgorithmName => "VMPC";
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
if (!(parameters is ParametersWithIV))
{
throw new ArgumentException("VMPC Init parameters must include an IV");
}
ParametersWithIV parametersWithIV = (ParametersWithIV)parameters;
if (!(parametersWithIV.Parameters is KeyParameter))
{
throw new ArgumentException("VMPC Init parameters must include a key");
}
KeyParameter keyParameter = (KeyParameter)parametersWithIV.Parameters;
workingIV = parametersWithIV.GetIV();
if (workingIV == null || workingIV.Length < 1 || workingIV.Length > 768)
{
throw new ArgumentException("VMPC requires 1 to 768 bytes of IV");
}
workingKey = keyParameter.GetKey();
InitKey(workingKey, workingIV);
}
protected virtual void InitKey(byte[] keyBytes, byte[] ivBytes)
{
s = 0;
P = new byte[256];
for (int i = 0; i < 256; i++)
{
P[i] = (byte)i;
}
for (int j = 0; j < 768; j++)
{
s = P[(s + P[j & 0xFF] + keyBytes[j % keyBytes.Length]) & 0xFF];
byte b = P[j & 0xFF];
P[j & 0xFF] = P[s & 0xFF];
P[s & 0xFF] = b;
}
for (int k = 0; k < 768; k++)
{
s = P[(s + P[k & 0xFF] + ivBytes[k % ivBytes.Length]) & 0xFF];
byte b2 = P[k & 0xFF];
P[k & 0xFF] = P[s & 0xFF];
P[s & 0xFF] = b2;
}
n = 0;
}
public virtual void ProcessBytes(byte[] input, int inOff, int len, byte[] output, int outOff)
{
Check.DataLength(input, inOff, len, "input buffer too short");
Check.OutputLength(output, outOff, len, "output buffer too short");
for (int i = 0; i < len; i++)
{
s = P[(s + P[n & 0xFF]) & 0xFF];
byte b = P[(P[P[s & 0xFF] & 0xFF] + 1) & 0xFF];
byte b2 = P[n & 0xFF];
P[n & 0xFF] = P[s & 0xFF];
P[s & 0xFF] = b2;
n = (byte)((n + 1) & 0xFF);
output[i + outOff] = (byte)(input[i + inOff] ^ b);
}
}
public virtual void Reset()
{
InitKey(workingKey, workingIV);
}
public virtual byte ReturnByte(byte input)
{
s = P[(s + P[n & 0xFF]) & 0xFF];
byte b = P[(P[P[s & 0xFF] & 0xFF] + 1) & 0xFF];
byte b2 = P[n & 0xFF];
P[n & 0xFF] = P[s & 0xFF];
P[s & 0xFF] = b2;
n = (byte)((n + 1) & 0xFF);
return (byte)(input ^ b);
}
}

View File

@@ -0,0 +1,38 @@
namespace Org.BouncyCastle.Crypto.Engines;
public class VmpcKsa3Engine : VmpcEngine
{
public override string AlgorithmName => "VMPC-KSA3";
protected override void InitKey(byte[] keyBytes, byte[] ivBytes)
{
s = 0;
P = new byte[256];
for (int i = 0; i < 256; i++)
{
P[i] = (byte)i;
}
for (int j = 0; j < 768; j++)
{
s = P[(s + P[j & 0xFF] + keyBytes[j % keyBytes.Length]) & 0xFF];
byte b = P[j & 0xFF];
P[j & 0xFF] = P[s & 0xFF];
P[s & 0xFF] = b;
}
for (int k = 0; k < 768; k++)
{
s = P[(s + P[k & 0xFF] + ivBytes[k % ivBytes.Length]) & 0xFF];
byte b2 = P[k & 0xFF];
P[k & 0xFF] = P[s & 0xFF];
P[s & 0xFF] = b2;
}
for (int l = 0; l < 768; l++)
{
s = P[(s + P[l & 0xFF] + keyBytes[l % keyBytes.Length]) & 0xFF];
byte b3 = P[l & 0xFF];
P[l & 0xFF] = P[s & 0xFF];
P[s & 0xFF] = b3;
}
n = 0;
}
}

View File

@@ -0,0 +1,36 @@
using System;
using Org.BouncyCastle.Crypto.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class XSalsa20Engine : Salsa20Engine
{
public override string AlgorithmName => "XSalsa20";
protected override int NonceSize => 24;
protected override void SetKey(byte[] keyBytes, byte[] ivBytes)
{
if (keyBytes == null)
{
throw new ArgumentException(AlgorithmName + " doesn't support re-init with null key");
}
if (keyBytes.Length != 32)
{
throw new ArgumentException(AlgorithmName + " requires a 256 bit key");
}
base.SetKey(keyBytes, ivBytes);
Pack.LE_To_UInt32(ivBytes, 8, engineState, 8, 2);
uint[] array = new uint[engineState.Length];
Salsa20Engine.SalsaCore(20, engineState, array);
engineState[1] = array[0] - engineState[0];
engineState[2] = array[5] - engineState[5];
engineState[3] = array[10] - engineState[10];
engineState[4] = array[15] - engineState[15];
engineState[11] = array[6] - engineState[6];
engineState[12] = array[7] - engineState[7];
engineState[13] = array[8] - engineState[8];
engineState[14] = array[9] - engineState[9];
Pack.LE_To_UInt32(ivBytes, 16, engineState, 6, 2);
}
}

View File

@@ -0,0 +1,116 @@
using System;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Utilities;
using Org.BouncyCastle.Utilities;
namespace Org.BouncyCastle.Crypto.Engines;
public class XteaEngine : IBlockCipher
{
private const int rounds = 32;
private const int block_size = 8;
private const int delta = -1640531527;
private uint[] _S = new uint[4];
private uint[] _sum0 = new uint[32];
private uint[] _sum1 = new uint[32];
private bool _initialised;
private bool _forEncryption;
public virtual string AlgorithmName => "XTEA";
public virtual bool IsPartialBlockOkay => false;
public XteaEngine()
{
_initialised = false;
}
public virtual int GetBlockSize()
{
return 8;
}
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
if (!(parameters is KeyParameter))
{
throw new ArgumentException("invalid parameter passed to TEA init - " + Platform.GetTypeName(parameters));
}
_forEncryption = forEncryption;
_initialised = true;
KeyParameter keyParameter = (KeyParameter)parameters;
setKey(keyParameter.GetKey());
}
public virtual int ProcessBlock(byte[] inBytes, int inOff, byte[] outBytes, int outOff)
{
if (!_initialised)
{
throw new InvalidOperationException(AlgorithmName + " not initialised");
}
Check.DataLength(inBytes, inOff, 8, "input buffer too short");
Check.OutputLength(outBytes, outOff, 8, "output buffer too short");
if (!_forEncryption)
{
return decryptBlock(inBytes, inOff, outBytes, outOff);
}
return encryptBlock(inBytes, inOff, outBytes, outOff);
}
public virtual void Reset()
{
}
private void setKey(byte[] key)
{
int num2;
int num = (num2 = 0);
while (num < 4)
{
_S[num] = Pack.BE_To_UInt32(key, num2);
num++;
num2 += 4;
}
for (num = (num2 = 0); num < 32; num++)
{
_sum0[num] = (uint)num2 + _S[num2 & 3];
num2 += -1640531527;
_sum1[num] = (uint)num2 + _S[(num2 >> 11) & 3];
}
}
private int encryptBlock(byte[] inBytes, int inOff, byte[] outBytes, int outOff)
{
uint num = Pack.BE_To_UInt32(inBytes, inOff);
uint num2 = Pack.BE_To_UInt32(inBytes, inOff + 4);
for (int i = 0; i < 32; i++)
{
num += (((num2 << 4) ^ (num2 >> 5)) + num2) ^ _sum0[i];
num2 += (((num << 4) ^ (num >> 5)) + num) ^ _sum1[i];
}
Pack.UInt32_To_BE(num, outBytes, outOff);
Pack.UInt32_To_BE(num2, outBytes, outOff + 4);
return 8;
}
private int decryptBlock(byte[] inBytes, int inOff, byte[] outBytes, int outOff)
{
uint num = Pack.BE_To_UInt32(inBytes, inOff);
uint num2 = Pack.BE_To_UInt32(inBytes, inOff + 4);
for (int num3 = 31; num3 >= 0; num3--)
{
num2 -= (((num << 4) ^ (num >> 5)) + num) ^ _sum1[num3];
num -= (((num2 << 4) ^ (num2 >> 5)) + num2) ^ _sum0[num3];
}
Pack.UInt32_To_BE(num, outBytes, outOff);
Pack.UInt32_To_BE(num2, outBytes, outOff + 4);
return 8;
}
}