- Initial commit

This commit is contained in:
Timur Kozanov
2026-07-03 05:02:26 +03:00
commit 374ff1e689
4080 changed files with 388870 additions and 0 deletions

View File

@ -0,0 +1,723 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.Diagnostics;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/**
* an implementation of the AES (Rijndael), from FIPS-197.
* <p>
* For further details see: <a href="http://csrc.nist.gov/encryption/aes/">http://csrc.nist.gov/encryption/aes/</a>.
*
* This implementation is based on optimizations from Dr. Brian Gladman's paper and C code at
* <a href="http://fp.gladman.plus.com/cryptography_technology/rijndael/">http://fp.gladman.plus.com/cryptography_technology/rijndael/</a>
*
* There are three levels of tradeoff of speed vs memory
* Because java has no preprocessor, they are written as three separate classes from which to choose
*
* The fastest uses 8Kbytes of static tables to precompute round calculations, 4 256 word tables for encryption
* and 4 for decryption.
*
* The middle performance version uses only one 256 word table for each, for a total of 2Kbytes,
* adding 12 rotate operations per round to compute the values contained in the other tables from
* the contents of the first.
*
* The slowest version uses no static tables at all and computes the values in each round.
* </p>
* <p>
* This file contains the middle performance version with 2Kbytes of static tables for round precomputation.
* </p>
*/
public sealed class AesEngine
: IBlockCipher
{
// The S box
private static readonly byte[] S =
{
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,
};
// The inverse S-box
private static readonly byte[] Si =
{
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,
};
// vector used in calculating key schedule (powers of x in GF(256))
private static readonly byte[] rcon =
{
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91
};
// precomputation tables of calculations for rounds
private static readonly uint[] T0 =
{
0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0x0df2f2ff,
0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, 0x50303060, 0x03010102,
0xa96767ce, 0x7d2b2b56, 0x19fefee7, 0x62d7d7b5, 0xe6abab4d,
0x9a7676ec, 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa,
0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb, 0xecadad41,
0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453,
0x967272e4, 0x5bc0c09b, 0xc2b7b775, 0x1cfdfde1, 0xae93933d,
0x6a26264c, 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83,
0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9, 0x937171e2,
0x73d8d8ab, 0x53313162, 0x3f15152a, 0x0c040408, 0x52c7c795,
0x65232346, 0x5ec3c39d, 0x28181830, 0xa1969637, 0x0f05050a,
0xb59a9a2f, 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df,
0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, 0x1b090912,
0x9e83831d, 0x742c2c58, 0x2e1a1a34, 0x2d1b1b36, 0xb26e6edc,
0xee5a5ab4, 0xfba0a05b, 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7,
0xceb3b37d, 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413,
0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, 0x60202040,
0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, 0xbe6a6ad4, 0x46cbcb8d,
0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0,
0x4acfcf85, 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed,
0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, 0xcf45458a,
0x10f9f9e9, 0x06020204, 0x817f7ffe, 0xf05050a0, 0x443c3c78,
0xba9f9f25, 0xe3a8a84b, 0xf35151a2, 0xfea3a35d, 0xc0404080,
0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1,
0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 0x30101020,
0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf, 0x4ccdcd81, 0x140c0c18,
0x35131326, 0x2fececc3, 0xe15f5fbe, 0xa2979735, 0xcc444488,
0x3917172e, 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a,
0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, 0xa06060c0,
0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54,
0xab90903b, 0x8388880b, 0xca46468c, 0x29eeeec7, 0xd3b8b86b,
0x3c141428, 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad,
0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, 0xdb494992,
0x0a06060c, 0x6c242448, 0xe45c5cb8, 0x5dc2c29f, 0x6ed3d3bd,
0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531, 0x37e4e4d3,
0x8b7979f2, 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda,
0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, 0xb46c6cd8,
0xfa5656ac, 0x07f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4,
0xe9aeae47, 0x18080810, 0xd5baba6f, 0x887878f0, 0x6f25254a,
0x722e2e5c, 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697,
0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, 0xdd4b4b96,
0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, 0x907070e0, 0x423e3e7c,
0xc4b5b571, 0xaa6666cc, 0xd8484890, 0x05030306, 0x01f6f6f7,
0x120e0e1c, 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969,
0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, 0x38e1e1d9,
0x13f8f8eb, 0xb398982b, 0x33111122, 0xbb6969d2, 0x70d9d9a9,
0x898e8e07, 0xa7949433, 0xb69b9b2d, 0x221e1e3c, 0x92878715,
0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5,
0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65,
0x31e6e6d7, 0xc6424284, 0xb86868d0, 0xc3414182, 0xb0999929,
0x772d2d5a, 0x110f0f1e, 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d,
0x3a16162c
};
private static readonly uint[] Tinv0 =
{
0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, 0xcb6bab3b,
0xf1459d1f, 0xab58faac, 0x9303e34b, 0x55fa3020, 0xf66d76ad,
0x9176cc88, 0x254c02f5, 0xfcd7e54f, 0xd7cb2ac5, 0x80443526,
0x8fa362b5, 0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d,
0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b, 0xe75f8f03,
0x959c9215, 0xeb7a6dbf, 0xda595295, 0x2d83bed4, 0xd3217458,
0x2969e049, 0x44c8c98e, 0x6a89c275, 0x78798ef4, 0x6b3e5899,
0xdd71b927, 0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d,
0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362, 0xe07764b1,
0x84ae6bbb, 0x1ca081fe, 0x942b08f9, 0x58684870, 0x19fd458f,
0x876cde94, 0xb7f87b52, 0x23d373ab, 0xe2024b72, 0x578f1fe3,
0x2aab5566, 0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3,
0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed, 0x2b1ccf8a,
0x92b479a7, 0xf0f207f3, 0xa1e2694e, 0xcdf4da65, 0xd5be0506,
0x1f6234d1, 0x8afea6c4, 0x9d532e34, 0xa055f3a2, 0x32e18a05,
0x75ebf6a4, 0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd,
0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d, 0xb58d5491,
0x055dc471, 0x6fd40604, 0xff155060, 0x24fb9819, 0x97e9bdd6,
0xcc434089, 0x779ed967, 0xbd42e8b0, 0x888b8907, 0x385b19e7,
0xdbeec879, 0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000,
0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c, 0xfbff0efd,
0x5638850f, 0x1ed5ae3d, 0x27392d36, 0x64d90f0a, 0x21a65c68,
0xd1545b9b, 0x3a2e3624, 0xb1670a0c, 0x0fe75793, 0xd296eeb4,
0x9e919b1b, 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c,
0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12, 0x0b0d090e,
0xadc78bf2, 0xb9a8b62d, 0xc8a91e14, 0x8519f157, 0x4c0775af,
0xbbdd99ee, 0xfd607fa3, 0x9f2601f7, 0xbcf5725c, 0xc53b6644,
0x347efb5b, 0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8,
0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684, 0x7d244a85,
0xf83dbbd2, 0x1132f9ae, 0x6da129c7, 0x4b2f9e1d, 0xf330b2dc,
0xec52860d, 0xd0e3c177, 0x6c16b32b, 0x99b970a9, 0xfa489411,
0x2264e947, 0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322,
0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498, 0xcf81f5a6,
0x28de7aa5, 0x268eb7da, 0xa4bfad3f, 0xe49d3a2c, 0x0d927850,
0x9bcc5f6a, 0x62467e54, 0xc2138df6, 0xe8b8d890, 0x5ef7392e,
0xf5afc382, 0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf,
0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb, 0x097826cd,
0xf418596e, 0x01b79aec, 0xa89a4f83, 0x656e95e6, 0x7ee6ffaa,
0x08cfbc21, 0xe6e815ef, 0xd99be7ba, 0xce366f4a, 0xd4099fea,
0xd67cb029, 0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235,
0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733, 0x4a9804f1,
0xf7daec41, 0x0e50cd7f, 0x2ff69117, 0x8dd64d76, 0x4db0ef43,
0x544daacc, 0xdf0496e4, 0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1,
0x7f516546, 0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb,
0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d, 0x8c61d79a,
0x7a0ca137, 0x8e14f859, 0x893c13eb, 0xee27a9ce, 0x35c961b7,
0xede51ce1, 0x3cb1477a, 0x59dfd29c, 0x3f73f255, 0x79ce1418,
0xbf37c773, 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478,
0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, 0x72c31d16,
0x0c25e2bc, 0x8b493c28, 0x41950dff, 0x7101a839, 0xdeb30c08,
0x9ce4b4d8, 0x90c15664, 0x6184cb7b, 0x70b632d5, 0x745c6c48,
0x4257b8d0
};
private static uint Shift(uint r, int shift)
{
return (r >> shift) | (r << (32 - shift));
}
/* multiply four bytes in GF(2^8) by 'x' {02} in parallel */
private const uint m1 = 0x80808080;
private const uint m2 = 0x7f7f7f7f;
private const uint m3 = 0x0000001b;
private const uint m4 = 0xC0C0C0C0;
private const uint m5 = 0x3f3f3f3f;
private static uint FFmulX(uint x)
{
return ((x & m2) << 1) ^ (((x & m1) >> 7) * m3);
}
private static uint FFmulX2(uint x)
{
uint t0 = (x & m5) << 2;
uint t1 = (x & m4);
t1 ^= (t1 >> 1);
return t0 ^ (t1 >> 2) ^ (t1 >> 5);
}
/*
The following defines provide alternative definitions of FFmulX that might
give improved performance if a fast 32-bit multiply is not available.
private int FFmulX(int x) { int u = x & m1; u |= (u >> 1); return ((x & m2) << 1) ^ ((u >>> 3) | (u >>> 6)); }
private static final int m4 = 0x1b1b1b1b;
private int FFmulX(int x) { int u = x & m1; return ((x & m2) << 1) ^ ((u - (u >>> 7)) & m4); }
*/
private static uint Inv_Mcol(uint x)
{
uint t0, t1;
t0 = x;
t1 = t0 ^ Shift(t0, 8);
t0 ^= FFmulX(t1);
t1 ^= FFmulX2(t0);
t0 ^= t1 ^ Shift(t1, 16);
return t0;
}
private static uint SubWord(uint x)
{
return (uint)S[x&255]
| (((uint)S[(x>>8)&255]) << 8)
| (((uint)S[(x>>16)&255]) << 16)
| (((uint)S[(x>>24)&255]) << 24);
}
/**
* Calculate the necessary round keys
* The number of calculations depends on key size and block size
* AES specified a fixed block size of 128 bits and key sizes 128/192/256 bits
* This code is written assuming those are the only possible values
*/
private uint[][] GenerateWorkingKey(byte[] key, bool forEncryption)
{
int keyLen = key.Length;
if (keyLen < 16 || keyLen > 32 || (keyLen & 7) != 0)
throw new ArgumentException("Key length not 128/192/256 bits.");
int KC = keyLen >> 2;
this.ROUNDS = KC + 6; // This is not always true for the generalized Rijndael that allows larger block sizes
uint[][] W = new uint[ROUNDS + 1][]; // 4 words in a block
for (int i = 0; i <= ROUNDS; ++i)
{
W[i] = new uint[4];
}
switch (KC)
{
case 4:
{
uint t0 = Pack.LE_To_UInt32(key, 0); W[0][0] = t0;
uint t1 = Pack.LE_To_UInt32(key, 4); W[0][1] = t1;
uint t2 = Pack.LE_To_UInt32(key, 8); W[0][2] = t2;
uint t3 = Pack.LE_To_UInt32(key, 12); W[0][3] = t3;
for (int i = 1; i <= 10; ++i)
{
uint u = SubWord(Shift(t3, 8)) ^ rcon[i - 1];
t0 ^= u; W[i][0] = t0;
t1 ^= t0; W[i][1] = t1;
t2 ^= t1; W[i][2] = t2;
t3 ^= t2; W[i][3] = t3;
}
break;
}
case 6:
{
uint t0 = Pack.LE_To_UInt32(key, 0); W[0][0] = t0;
uint t1 = Pack.LE_To_UInt32(key, 4); W[0][1] = t1;
uint t2 = Pack.LE_To_UInt32(key, 8); W[0][2] = t2;
uint t3 = Pack.LE_To_UInt32(key, 12); W[0][3] = t3;
uint t4 = Pack.LE_To_UInt32(key, 16); W[1][0] = t4;
uint t5 = Pack.LE_To_UInt32(key, 20); W[1][1] = t5;
uint rcon = 1;
uint u = SubWord(Shift(t5, 8)) ^ rcon; rcon <<= 1;
t0 ^= u; W[1][2] = t0;
t1 ^= t0; W[1][3] = t1;
t2 ^= t1; W[2][0] = t2;
t3 ^= t2; W[2][1] = t3;
t4 ^= t3; W[2][2] = t4;
t5 ^= t4; W[2][3] = t5;
for (int i = 3; i < 12; i += 3)
{
u = SubWord(Shift(t5, 8)) ^ rcon; rcon <<= 1;
t0 ^= u; W[i ][0] = t0;
t1 ^= t0; W[i ][1] = t1;
t2 ^= t1; W[i ][2] = t2;
t3 ^= t2; W[i ][3] = t3;
t4 ^= t3; W[i + 1][0] = t4;
t5 ^= t4; W[i + 1][1] = t5;
u = SubWord(Shift(t5, 8)) ^ rcon; rcon <<= 1;
t0 ^= u; W[i + 1][2] = t0;
t1 ^= t0; W[i + 1][3] = t1;
t2 ^= t1; W[i + 2][0] = t2;
t3 ^= t2; W[i + 2][1] = t3;
t4 ^= t3; W[i + 2][2] = t4;
t5 ^= t4; W[i + 2][3] = t5;
}
u = SubWord(Shift(t5, 8)) ^ rcon;
t0 ^= u; W[12][0] = t0;
t1 ^= t0; W[12][1] = t1;
t2 ^= t1; W[12][2] = t2;
t3 ^= t2; W[12][3] = t3;
break;
}
case 8:
{
uint t0 = Pack.LE_To_UInt32(key, 0); W[0][0] = t0;
uint t1 = Pack.LE_To_UInt32(key, 4); W[0][1] = t1;
uint t2 = Pack.LE_To_UInt32(key, 8); W[0][2] = t2;
uint t3 = Pack.LE_To_UInt32(key, 12); W[0][3] = t3;
uint t4 = Pack.LE_To_UInt32(key, 16); W[1][0] = t4;
uint t5 = Pack.LE_To_UInt32(key, 20); W[1][1] = t5;
uint t6 = Pack.LE_To_UInt32(key, 24); W[1][2] = t6;
uint t7 = Pack.LE_To_UInt32(key, 28); W[1][3] = t7;
uint u, rcon = 1;
for (int i = 2; i < 14; i += 2)
{
u = SubWord(Shift(t7, 8)) ^ rcon; rcon <<= 1;
t0 ^= u; W[i ][0] = t0;
t1 ^= t0; W[i ][1] = t1;
t2 ^= t1; W[i ][2] = t2;
t3 ^= t2; W[i ][3] = t3;
u = SubWord(t3);
t4 ^= u; W[i + 1][0] = t4;
t5 ^= t4; W[i + 1][1] = t5;
t6 ^= t5; W[i + 1][2] = t6;
t7 ^= t6; W[i + 1][3] = t7;
}
u = SubWord(Shift(t7, 8)) ^ rcon;
t0 ^= u; W[14][0] = t0;
t1 ^= t0; W[14][1] = t1;
t2 ^= t1; W[14][2] = t2;
t3 ^= t2; W[14][3] = t3;
break;
}
default:
{
throw new InvalidOperationException("Should never get here");
}
}
if (!forEncryption)
{
for (int j = 1; j < ROUNDS; j++)
{
uint[] w = W[j];
for (int i = 0; i < 4; i++)
{
w[i] = Inv_Mcol(w[i]);
}
}
}
return W;
}
private int ROUNDS;
private uint[][] WorkingKey;
private bool forEncryption;
private byte[] s;
private const int BLOCK_SIZE = 16;
/**
* default constructor - 128 bit block size.
*/
public AesEngine()
{
}
/**
* initialise an AES cipher.
*
* @param forEncryption whether or not we are for encryption.
* @param parameters the parameters required to set up the cipher.
* @exception ArgumentException if the parameters argument is
* inappropriate.
*/
public void Init(bool forEncryption, ICipherParameters parameters)
{
if (!(parameters is KeyParameter keyParameter))
throw new ArgumentException("invalid parameter passed to AES init - "
+ Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters));
WorkingKey = GenerateWorkingKey(keyParameter.GetKey(), forEncryption);
this.forEncryption = forEncryption;
this.s = Arrays.Clone(forEncryption ? S : Si);
}
public string AlgorithmName
{
get { return "AES"; }
}
public int GetBlockSize()
{
return BLOCK_SIZE;
}
public 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");
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
if (forEncryption)
{
EncryptBlock(input.AsSpan(inOff), output.AsSpan(outOff), WorkingKey);
}
else
{
DecryptBlock(input.AsSpan(inOff), output.AsSpan(outOff), WorkingKey);
}
#else
if (forEncryption)
{
EncryptBlock(input, inOff, output, outOff, WorkingKey);
}
else
{
DecryptBlock(input, inOff, output, outOff, WorkingKey);
}
#endif
return BLOCK_SIZE;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public int ProcessBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
if (WorkingKey == null)
throw new InvalidOperationException("AES engine not initialised");
Check.DataLength(input, 16, "input buffer too short");
Check.OutputLength(output, 16, "output buffer too short");
if (forEncryption)
{
EncryptBlock(input, output, WorkingKey);
}
else
{
DecryptBlock(input, output, WorkingKey);
}
return BLOCK_SIZE;
}
#endif
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
private void EncryptBlock(ReadOnlySpan<byte> input, Span<byte> output, uint[][] KW)
{
uint C0 = Pack.LE_To_UInt32(input);
uint C1 = Pack.LE_To_UInt32(input[4..]);
uint C2 = Pack.LE_To_UInt32(input[8..]);
uint C3 = Pack.LE_To_UInt32(input[12..]);
uint[] kw = KW[0];
uint t0 = C0 ^ kw[0];
uint t1 = C1 ^ kw[1];
uint t2 = C2 ^ kw[2];
uint r0, r1, r2, r3 = C3 ^ kw[3];
int r = 1;
while (r < ROUNDS - 1)
{
kw = KW[r++];
r0 = T0[t0 & 255] ^ Shift(T0[(t1 >> 8) & 255], 24) ^ Shift(T0[(t2 >> 16) & 255], 16) ^ Shift(T0[(r3 >> 24) & 255], 8) ^ kw[0];
r1 = T0[t1 & 255] ^ Shift(T0[(t2 >> 8) & 255], 24) ^ Shift(T0[(r3 >> 16) & 255], 16) ^ Shift(T0[(t0 >> 24) & 255], 8) ^ kw[1];
r2 = T0[t2 & 255] ^ Shift(T0[(r3 >> 8) & 255], 24) ^ Shift(T0[(t0 >> 16) & 255], 16) ^ Shift(T0[(t1 >> 24) & 255], 8) ^ kw[2];
r3 = T0[r3 & 255] ^ Shift(T0[(t0 >> 8) & 255], 24) ^ Shift(T0[(t1 >> 16) & 255], 16) ^ Shift(T0[(t2 >> 24) & 255], 8) ^ kw[3];
kw = KW[r++];
t0 = T0[r0 & 255] ^ Shift(T0[(r1 >> 8) & 255], 24) ^ Shift(T0[(r2 >> 16) & 255], 16) ^ Shift(T0[(r3 >> 24) & 255], 8) ^ kw[0];
t1 = T0[r1 & 255] ^ Shift(T0[(r2 >> 8) & 255], 24) ^ Shift(T0[(r3 >> 16) & 255], 16) ^ Shift(T0[(r0 >> 24) & 255], 8) ^ kw[1];
t2 = T0[r2 & 255] ^ Shift(T0[(r3 >> 8) & 255], 24) ^ Shift(T0[(r0 >> 16) & 255], 16) ^ Shift(T0[(r1 >> 24) & 255], 8) ^ kw[2];
r3 = T0[r3 & 255] ^ Shift(T0[(r0 >> 8) & 255], 24) ^ Shift(T0[(r1 >> 16) & 255], 16) ^ Shift(T0[(r2 >> 24) & 255], 8) ^ kw[3];
}
kw = KW[r++];
r0 = T0[t0 & 255] ^ Shift(T0[(t1 >> 8) & 255], 24) ^ Shift(T0[(t2 >> 16) & 255], 16) ^ Shift(T0[(r3 >> 24) & 255], 8) ^ kw[0];
r1 = T0[t1 & 255] ^ Shift(T0[(t2 >> 8) & 255], 24) ^ Shift(T0[(r3 >> 16) & 255], 16) ^ Shift(T0[(t0 >> 24) & 255], 8) ^ kw[1];
r2 = T0[t2 & 255] ^ Shift(T0[(r3 >> 8) & 255], 24) ^ Shift(T0[(t0 >> 16) & 255], 16) ^ Shift(T0[(t1 >> 24) & 255], 8) ^ kw[2];
r3 = T0[r3 & 255] ^ Shift(T0[(t0 >> 8) & 255], 24) ^ Shift(T0[(t1 >> 16) & 255], 16) ^ Shift(T0[(t2 >> 24) & 255], 8) ^ kw[3];
// the final round's table is a simple function of S so we don't use a whole other four tables for it
kw = KW[r];
C0 = (uint)S[r0 & 255] ^ (((uint)S[(r1 >> 8) & 255]) << 8) ^ (((uint)s[(r2 >> 16) & 255]) << 16) ^ (((uint)s[(r3 >> 24) & 255]) << 24) ^ kw[0];
C1 = (uint)s[r1 & 255] ^ (((uint)S[(r2 >> 8) & 255]) << 8) ^ (((uint)S[(r3 >> 16) & 255]) << 16) ^ (((uint)s[(r0 >> 24) & 255]) << 24) ^ kw[1];
C2 = (uint)s[r2 & 255] ^ (((uint)S[(r3 >> 8) & 255]) << 8) ^ (((uint)S[(r0 >> 16) & 255]) << 16) ^ (((uint)S[(r1 >> 24) & 255]) << 24) ^ kw[2];
C3 = (uint)s[r3 & 255] ^ (((uint)s[(r0 >> 8) & 255]) << 8) ^ (((uint)s[(r1 >> 16) & 255]) << 16) ^ (((uint)S[(r2 >> 24) & 255]) << 24) ^ kw[3];
Pack.UInt32_To_LE(C0, output);
Pack.UInt32_To_LE(C1, output[4..]);
Pack.UInt32_To_LE(C2, output[8..]);
Pack.UInt32_To_LE(C3, output[12..]);
}
private void DecryptBlock(ReadOnlySpan<byte> input, Span<byte> output, uint[][] KW)
{
uint C0 = Pack.LE_To_UInt32(input);
uint C1 = Pack.LE_To_UInt32(input[4..]);
uint C2 = Pack.LE_To_UInt32(input[8..]);
uint C3 = Pack.LE_To_UInt32(input[12..]);
uint[] kw = KW[ROUNDS];
uint t0 = C0 ^ kw[0];
uint t1 = C1 ^ kw[1];
uint t2 = C2 ^ kw[2];
uint r0, r1, r2, r3 = C3 ^ kw[3];
int r = ROUNDS - 1;
while (r > 1)
{
kw = KW[r--];
r0 = Tinv0[t0 & 255] ^ Shift(Tinv0[(r3 >> 8) & 255], 24) ^ Shift(Tinv0[(t2 >> 16) & 255], 16) ^ Shift(Tinv0[(t1 >> 24) & 255], 8) ^ kw[0];
r1 = Tinv0[t1 & 255] ^ Shift(Tinv0[(t0 >> 8) & 255], 24) ^ Shift(Tinv0[(r3 >> 16) & 255], 16) ^ Shift(Tinv0[(t2 >> 24) & 255], 8) ^ kw[1];
r2 = Tinv0[t2 & 255] ^ Shift(Tinv0[(t1 >> 8) & 255], 24) ^ Shift(Tinv0[(t0 >> 16) & 255], 16) ^ Shift(Tinv0[(r3 >> 24) & 255], 8) ^ kw[2];
r3 = Tinv0[r3 & 255] ^ Shift(Tinv0[(t2 >> 8) & 255], 24) ^ Shift(Tinv0[(t1 >> 16) & 255], 16) ^ Shift(Tinv0[(t0 >> 24) & 255], 8) ^ kw[3];
kw = KW[r--];
t0 = Tinv0[r0 & 255] ^ Shift(Tinv0[(r3 >> 8) & 255], 24) ^ Shift(Tinv0[(r2 >> 16) & 255], 16) ^ Shift(Tinv0[(r1 >> 24) & 255], 8) ^ kw[0];
t1 = Tinv0[r1 & 255] ^ Shift(Tinv0[(r0 >> 8) & 255], 24) ^ Shift(Tinv0[(r3 >> 16) & 255], 16) ^ Shift(Tinv0[(r2 >> 24) & 255], 8) ^ kw[1];
t2 = Tinv0[r2 & 255] ^ Shift(Tinv0[(r1 >> 8) & 255], 24) ^ Shift(Tinv0[(r0 >> 16) & 255], 16) ^ Shift(Tinv0[(r3 >> 24) & 255], 8) ^ kw[2];
r3 = Tinv0[r3 & 255] ^ Shift(Tinv0[(r2 >> 8) & 255], 24) ^ Shift(Tinv0[(r1 >> 16) & 255], 16) ^ Shift(Tinv0[(r0 >> 24) & 255], 8) ^ kw[3];
}
kw = KW[1];
r0 = Tinv0[t0 & 255] ^ Shift(Tinv0[(r3 >> 8) & 255], 24) ^ Shift(Tinv0[(t2 >> 16) & 255], 16) ^ Shift(Tinv0[(t1 >> 24) & 255], 8) ^ kw[0];
r1 = Tinv0[t1 & 255] ^ Shift(Tinv0[(t0 >> 8) & 255], 24) ^ Shift(Tinv0[(r3 >> 16) & 255], 16) ^ Shift(Tinv0[(t2 >> 24) & 255], 8) ^ kw[1];
r2 = Tinv0[t2 & 255] ^ Shift(Tinv0[(t1 >> 8) & 255], 24) ^ Shift(Tinv0[(t0 >> 16) & 255], 16) ^ Shift(Tinv0[(r3 >> 24) & 255], 8) ^ kw[2];
r3 = Tinv0[r3 & 255] ^ Shift(Tinv0[(t2 >> 8) & 255], 24) ^ Shift(Tinv0[(t1 >> 16) & 255], 16) ^ Shift(Tinv0[(t0 >> 24) & 255], 8) ^ kw[3];
// the final round's table is a simple function of Si so we don't use a whole other four tables for it
kw = KW[0];
C0 = (uint)Si[r0 & 255] ^ (((uint)s[(r3 >> 8) & 255]) << 8) ^ (((uint)s[(r2 >> 16) & 255]) << 16) ^ (((uint)Si[(r1 >> 24) & 255]) << 24) ^ kw[0];
C1 = (uint)s[r1 & 255] ^ (((uint)s[(r0 >> 8) & 255]) << 8) ^ (((uint)Si[(r3 >> 16) & 255]) << 16) ^ (((uint)s[(r2 >> 24) & 255]) << 24) ^ kw[1];
C2 = (uint)s[r2 & 255] ^ (((uint)Si[(r1 >> 8) & 255]) << 8) ^ (((uint)Si[(r0 >> 16) & 255]) << 16) ^ (((uint)s[(r3 >> 24) & 255]) << 24) ^ kw[2];
C3 = (uint)Si[r3 & 255] ^ (((uint)s[(r2 >> 8) & 255]) << 8) ^ (((uint)s[(r1 >> 16) & 255]) << 16) ^ (((uint)s[(r0 >> 24) & 255]) << 24) ^ kw[3];
Pack.UInt32_To_LE(C0, output);
Pack.UInt32_To_LE(C1, output[4..]);
Pack.UInt32_To_LE(C2, output[8..]);
Pack.UInt32_To_LE(C3, output[12..]);
}
#else
private void EncryptBlock(byte[] input, int inOff, byte[] output, int outOff, uint[][] KW)
{
uint C0 = Pack.LE_To_UInt32(input, inOff + 0);
uint C1 = Pack.LE_To_UInt32(input, inOff + 4);
uint C2 = Pack.LE_To_UInt32(input, inOff + 8);
uint C3 = Pack.LE_To_UInt32(input, inOff + 12);
uint[] kw = KW[0];
uint t0 = C0 ^ kw[0];
uint t1 = C1 ^ kw[1];
uint t2 = C2 ^ kw[2];
uint r0, r1, r2, r3 = C3 ^ kw[3];
int r = 1;
while (r < ROUNDS - 1)
{
kw = KW[r++];
r0 = T0[t0 & 255] ^ Shift(T0[(t1 >> 8) & 255], 24) ^ Shift(T0[(t2 >> 16) & 255], 16) ^ Shift(T0[(r3 >> 24) & 255], 8) ^ kw[0];
r1 = T0[t1 & 255] ^ Shift(T0[(t2 >> 8) & 255], 24) ^ Shift(T0[(r3 >> 16) & 255], 16) ^ Shift(T0[(t0 >> 24) & 255], 8) ^ kw[1];
r2 = T0[t2 & 255] ^ Shift(T0[(r3 >> 8) & 255], 24) ^ Shift(T0[(t0 >> 16) & 255], 16) ^ Shift(T0[(t1 >> 24) & 255], 8) ^ kw[2];
r3 = T0[r3 & 255] ^ Shift(T0[(t0 >> 8) & 255], 24) ^ Shift(T0[(t1 >> 16) & 255], 16) ^ Shift(T0[(t2 >> 24) & 255], 8) ^ kw[3];
kw = KW[r++];
t0 = T0[r0 & 255] ^ Shift(T0[(r1 >> 8) & 255], 24) ^ Shift(T0[(r2 >> 16) & 255], 16) ^ Shift(T0[(r3 >> 24) & 255], 8) ^ kw[0];
t1 = T0[r1 & 255] ^ Shift(T0[(r2 >> 8) & 255], 24) ^ Shift(T0[(r3 >> 16) & 255], 16) ^ Shift(T0[(r0 >> 24) & 255], 8) ^ kw[1];
t2 = T0[r2 & 255] ^ Shift(T0[(r3 >> 8) & 255], 24) ^ Shift(T0[(r0 >> 16) & 255], 16) ^ Shift(T0[(r1 >> 24) & 255], 8) ^ kw[2];
r3 = T0[r3 & 255] ^ Shift(T0[(r0 >> 8) & 255], 24) ^ Shift(T0[(r1 >> 16) & 255], 16) ^ Shift(T0[(r2 >> 24) & 255], 8) ^ kw[3];
}
kw = KW[r++];
r0 = T0[t0 & 255] ^ Shift(T0[(t1 >> 8) & 255], 24) ^ Shift(T0[(t2 >> 16) & 255], 16) ^ Shift(T0[(r3 >> 24) & 255], 8) ^ kw[0];
r1 = T0[t1 & 255] ^ Shift(T0[(t2 >> 8) & 255], 24) ^ Shift(T0[(r3 >> 16) & 255], 16) ^ Shift(T0[(t0 >> 24) & 255], 8) ^ kw[1];
r2 = T0[t2 & 255] ^ Shift(T0[(r3 >> 8) & 255], 24) ^ Shift(T0[(t0 >> 16) & 255], 16) ^ Shift(T0[(t1 >> 24) & 255], 8) ^ kw[2];
r3 = T0[r3 & 255] ^ Shift(T0[(t0 >> 8) & 255], 24) ^ Shift(T0[(t1 >> 16) & 255], 16) ^ Shift(T0[(t2 >> 24) & 255], 8) ^ kw[3];
// the final round's table is a simple function of S so we don't use a whole other four tables for it
kw = KW[r];
C0 = (uint)S[r0 & 255] ^ (((uint)S[(r1 >> 8) & 255]) << 8) ^ (((uint)s[(r2 >> 16) & 255]) << 16) ^ (((uint)s[(r3 >> 24) & 255]) << 24) ^ kw[0];
C1 = (uint)s[r1 & 255] ^ (((uint)S[(r2 >> 8) & 255]) << 8) ^ (((uint)S[(r3 >> 16) & 255]) << 16) ^ (((uint)s[(r0 >> 24) & 255]) << 24) ^ kw[1];
C2 = (uint)s[r2 & 255] ^ (((uint)S[(r3 >> 8) & 255]) << 8) ^ (((uint)S[(r0 >> 16) & 255]) << 16) ^ (((uint)S[(r1 >> 24) & 255]) << 24) ^ kw[2];
C3 = (uint)s[r3 & 255] ^ (((uint)s[(r0 >> 8) & 255]) << 8) ^ (((uint)s[(r1 >> 16) & 255]) << 16) ^ (((uint)S[(r2 >> 24) & 255]) << 24) ^ kw[3];
Pack.UInt32_To_LE(C0, output, outOff + 0);
Pack.UInt32_To_LE(C1, output, outOff + 4);
Pack.UInt32_To_LE(C2, output, outOff + 8);
Pack.UInt32_To_LE(C3, output, outOff + 12);
}
private void DecryptBlock(byte[] input, int inOff, byte[] output, int outOff, uint[][] KW)
{
uint C0 = Pack.LE_To_UInt32(input, inOff + 0);
uint C1 = Pack.LE_To_UInt32(input, inOff + 4);
uint C2 = Pack.LE_To_UInt32(input, inOff + 8);
uint C3 = Pack.LE_To_UInt32(input, inOff + 12);
uint[] kw = KW[ROUNDS];
uint t0 = C0 ^ kw[0];
uint t1 = C1 ^ kw[1];
uint t2 = C2 ^ kw[2];
uint r0, r1, r2, r3 = C3 ^ kw[3];
int r = ROUNDS - 1;
while (r > 1)
{
kw = KW[r--];
r0 = Tinv0[t0 & 255] ^ Shift(Tinv0[(r3 >> 8) & 255], 24) ^ Shift(Tinv0[(t2 >> 16) & 255], 16) ^ Shift(Tinv0[(t1 >> 24) & 255], 8) ^ kw[0];
r1 = Tinv0[t1 & 255] ^ Shift(Tinv0[(t0 >> 8) & 255], 24) ^ Shift(Tinv0[(r3 >> 16) & 255], 16) ^ Shift(Tinv0[(t2 >> 24) & 255], 8) ^ kw[1];
r2 = Tinv0[t2 & 255] ^ Shift(Tinv0[(t1 >> 8) & 255], 24) ^ Shift(Tinv0[(t0 >> 16) & 255], 16) ^ Shift(Tinv0[(r3 >> 24) & 255], 8) ^ kw[2];
r3 = Tinv0[r3 & 255] ^ Shift(Tinv0[(t2 >> 8) & 255], 24) ^ Shift(Tinv0[(t1 >> 16) & 255], 16) ^ Shift(Tinv0[(t0 >> 24) & 255], 8) ^ kw[3];
kw = KW[r--];
t0 = Tinv0[r0 & 255] ^ Shift(Tinv0[(r3 >> 8) & 255], 24) ^ Shift(Tinv0[(r2 >> 16) & 255], 16) ^ Shift(Tinv0[(r1 >> 24) & 255], 8) ^ kw[0];
t1 = Tinv0[r1 & 255] ^ Shift(Tinv0[(r0 >> 8) & 255], 24) ^ Shift(Tinv0[(r3 >> 16) & 255], 16) ^ Shift(Tinv0[(r2 >> 24) & 255], 8) ^ kw[1];
t2 = Tinv0[r2 & 255] ^ Shift(Tinv0[(r1 >> 8) & 255], 24) ^ Shift(Tinv0[(r0 >> 16) & 255], 16) ^ Shift(Tinv0[(r3 >> 24) & 255], 8) ^ kw[2];
r3 = Tinv0[r3 & 255] ^ Shift(Tinv0[(r2 >> 8) & 255], 24) ^ Shift(Tinv0[(r1 >> 16) & 255], 16) ^ Shift(Tinv0[(r0 >> 24) & 255], 8) ^ kw[3];
}
kw = KW[1];
r0 = Tinv0[t0 & 255] ^ Shift(Tinv0[(r3 >> 8) & 255], 24) ^ Shift(Tinv0[(t2 >> 16) & 255], 16) ^ Shift(Tinv0[(t1 >> 24) & 255], 8) ^ kw[0];
r1 = Tinv0[t1 & 255] ^ Shift(Tinv0[(t0 >> 8) & 255], 24) ^ Shift(Tinv0[(r3 >> 16) & 255], 16) ^ Shift(Tinv0[(t2 >> 24) & 255], 8) ^ kw[1];
r2 = Tinv0[t2 & 255] ^ Shift(Tinv0[(t1 >> 8) & 255], 24) ^ Shift(Tinv0[(t0 >> 16) & 255], 16) ^ Shift(Tinv0[(r3 >> 24) & 255], 8) ^ kw[2];
r3 = Tinv0[r3 & 255] ^ Shift(Tinv0[(t2 >> 8) & 255], 24) ^ Shift(Tinv0[(t1 >> 16) & 255], 16) ^ Shift(Tinv0[(t0 >> 24) & 255], 8) ^ kw[3];
// the final round's table is a simple function of Si so we don't use a whole other four tables for it
kw = KW[0];
C0 = (uint)Si[r0 & 255] ^ (((uint)s[(r3 >> 8) & 255]) << 8) ^ (((uint)s[(r2 >> 16) & 255]) << 16) ^ (((uint)Si[(r1 >> 24) & 255]) << 24) ^ kw[0];
C1 = (uint)s[r1 & 255] ^ (((uint)s[(r0 >> 8) & 255]) << 8) ^ (((uint)Si[(r3 >> 16) & 255]) << 16) ^ (((uint)s[(r2 >> 24) & 255]) << 24) ^ kw[1];
C2 = (uint)s[r2 & 255] ^ (((uint)Si[(r1 >> 8) & 255]) << 8) ^ (((uint)Si[(r0 >> 16) & 255]) << 16) ^ (((uint)s[(r3 >> 24) & 255]) << 24) ^ kw[2];
C3 = (uint)Si[r3 & 255] ^ (((uint)s[(r2 >> 8) & 255]) << 8) ^ (((uint)s[(r1 >> 16) & 255]) << 16) ^ (((uint)s[(r0 >> 24) & 255]) << 24) ^ kw[3];
Pack.UInt32_To_LE(C0, output, outOff + 0);
Pack.UInt32_To_LE(C1, output, outOff + 4);
Pack.UInt32_To_LE(C2, output, outOff + 8);
Pack.UInt32_To_LE(C3, output, outOff + 12);
}
#endif
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: fafbe10fe323dff42b75958ef30fdacd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/AesEngine.cs
uploadId: 783279

View File

@ -0,0 +1,834 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
#if NETCOREAPP3_0_OR_GREATER
using System;
using System.Buffers.Binary;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
using Aes = System.Runtime.Intrinsics.X86.Aes;
using Sse2 = System.Runtime.Intrinsics.X86.Sse2;
public struct AesEngine_X86
: IBlockCipher
{
public static bool IsSupported => Aes.IsSupported;
private static Vector128<byte>[] CreateRoundKeys(byte[] key, bool forEncryption)
{
Vector128<byte>[] K;
switch (key.Length)
{
case 16:
{
ReadOnlySpan<byte> rcon = stackalloc byte[]{ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
K = new Vector128<byte>[11];
var s = Load128(key.AsSpan(0, 16));
K[0] = s;
for (int round = 0; round < 10;)
{
var t = Aes.KeygenAssist(s, rcon[round++]);
t = Sse2.Shuffle(t.AsInt32(), 0xFF).AsByte();
s = Sse2.Xor(s, Sse2.ShiftLeftLogical128BitLane(s, 8));
s = Sse2.Xor(s, Sse2.ShiftLeftLogical128BitLane(s, 4));
s = Sse2.Xor(s, t);
K[round] = s;
}
break;
}
case 24:
{
K = new Vector128<byte>[13];
var s1 = Load128(key.AsSpan(0, 16));
var s2 = Load64(key.AsSpan(16, 8)).ToVector128();
K[0] = s1;
byte rcon = 0x01;
for (int round = 0;;)
{
var t1 = Aes.KeygenAssist(s2, rcon); rcon <<= 1;
t1 = Sse2.Shuffle(t1.AsInt32(), 0x55).AsByte();
s1 = Sse2.Xor(s1, Sse2.ShiftLeftLogical128BitLane(s1, 8));
s1 = Sse2.Xor(s1, Sse2.ShiftLeftLogical128BitLane(s1, 4));
s1 = Sse2.Xor(s1, t1);
K[++round] = Sse2.Xor(s2, Sse2.ShiftLeftLogical128BitLane(s1, 8));
var s3 = Sse2.Xor(s2, Sse2.ShiftRightLogical128BitLane(s1, 12));
s3 = Sse2.Xor(s3, Sse2.ShiftLeftLogical128BitLane(s3, 4));
K[++round] = Sse2.Xor(
Sse2.ShiftRightLogical128BitLane(s1, 8),
Sse2.ShiftLeftLogical128BitLane(s3, 8));
var t2 = Aes.KeygenAssist(s3, rcon); rcon <<= 1;
t2 = Sse2.Shuffle(t2.AsInt32(), 0x55).AsByte();
s1 = Sse2.Xor(s1, Sse2.ShiftLeftLogical128BitLane(s1, 8));
s1 = Sse2.Xor(s1, Sse2.ShiftLeftLogical128BitLane(s1, 4));
s1 = Sse2.Xor(s1, t2);
K[++round] = s1;
if (round == 12)
break;
s2 = Sse2.Xor(s3, Sse2.ShiftRightLogical128BitLane(s1, 12));
s2 = Sse2.Xor(s2, Sse2.ShiftLeftLogical128BitLane(s2, 4));
s2 = s2.WithUpper(Vector64<byte>.Zero);
}
break;
}
case 32:
{
K = new Vector128<byte>[15];
var s1 = Load128(key.AsSpan(0, 16));
var s2 = Load128(key.AsSpan(16, 16));
K[0] = s1;
K[1] = s2;
byte rcon = 0x01;
for (int round = 1;;)
{
var t1 = Aes.KeygenAssist(s2, rcon); rcon <<= 1;
t1 = Sse2.Shuffle(t1.AsInt32(), 0xFF).AsByte();
s1 = Sse2.Xor(s1, Sse2.ShiftLeftLogical128BitLane(s1, 8));
s1 = Sse2.Xor(s1, Sse2.ShiftLeftLogical128BitLane(s1, 4));
s1 = Sse2.Xor(s1, t1);
K[++round] = s1;
if (round == 14)
break;
var t2 = Aes.KeygenAssist(s1, 0x00);
t2 = Sse2.Shuffle(t2.AsInt32(), 0xAA).AsByte();
s2 = Sse2.Xor(s2, Sse2.ShiftLeftLogical128BitLane(s2, 8));
s2 = Sse2.Xor(s2, Sse2.ShiftLeftLogical128BitLane(s2, 4));
s2 = Sse2.Xor(s2, t2);
K[++round] = s2;
}
break;
}
default:
throw new ArgumentException("Key length not 128/192/256 bits.");
}
if (!forEncryption)
{
for (int i = 1, last = K.Length - 1; i < last; ++i)
{
K[i] = Aes.InverseMixColumns(K[i]);
}
Array.Reverse(K);
}
return K;
}
private enum Mode { DEC_128, DEC_192, DEC_256, ENC_128, ENC_192, ENC_256, UNINITIALIZED };
private Vector128<byte>[] m_roundKeys = null;
private Mode m_mode = Mode.UNINITIALIZED;
public AesEngine_X86()
{
if (!IsSupported)
throw new PlatformNotSupportedException(nameof(AesEngine_X86));
}
public string AlgorithmName => "AES";
public int GetBlockSize() => 16;
public void Init(bool forEncryption, ICipherParameters parameters)
{
if (!(parameters is KeyParameter keyParameter))
{
ArgumentNullException.ThrowIfNull(parameters, nameof(parameters));
throw new ArgumentException("invalid type: " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters), nameof(parameters));
}
m_roundKeys = CreateRoundKeys(keyParameter.GetKey(), forEncryption);
if (m_roundKeys.Length == 11)
{
m_mode = forEncryption ? Mode.ENC_128 : Mode.DEC_128;
}
else if (m_roundKeys.Length == 13)
{
m_mode = forEncryption ? Mode.ENC_192 : Mode.DEC_192;
}
else
{
m_mode = forEncryption ? Mode.ENC_256 : Mode.DEC_256;
}
}
public int ProcessBlock(byte[] inBuf, int inOff, byte[] outBuf, int outOff)
{
Check.DataLength(inBuf, inOff, 16, "input buffer too short");
Check.OutputLength(outBuf, outOff, 16, "output buffer too short");
var state = Load128(inBuf.AsSpan(inOff, 16));
ImplRounds(ref state);
Store128(state, outBuf.AsSpan(outOff, 16));
return 16;
}
public int ProcessBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
Check.DataLength(input, 16, "input buffer too short");
Check.OutputLength(output, 16, "output buffer too short");
var state = Load128(input[..16]);
ImplRounds(ref state);
Store128(state, output[..16]);
return 16;
}
public int ProcessFourBlocks(ReadOnlySpan<byte> input, Span<byte> output)
{
Check.DataLength(input, 64, "input buffer too short");
Check.OutputLength(output, 64, "output buffer too short");
var s1 = Load128(input[..16]);
var s2 = Load128(input[16..32]);
var s3 = Load128(input[32..48]);
var s4 = Load128(input[48..64]);
ImplRounds(ref s1, ref s2, ref s3, ref s4);
Store128(s1, output[..16]);
Store128(s2, output[16..32]);
Store128(s3, output[32..48]);
Store128(s4, output[48..64]);
return 64;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ImplRounds(ref Vector128<byte> state)
{
switch (m_mode)
{
case Mode.DEC_128: Decrypt128(m_roundKeys, ref state); break;
case Mode.DEC_192: Decrypt192(m_roundKeys, ref state); break;
case Mode.DEC_256: Decrypt256(m_roundKeys, ref state); break;
case Mode.ENC_128: Encrypt128(m_roundKeys, ref state); break;
case Mode.ENC_192: Encrypt192(m_roundKeys, ref state); break;
case Mode.ENC_256: Encrypt256(m_roundKeys, ref state); break;
default: throw new InvalidOperationException(nameof(AesEngine_X86) + " not initialised");
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ImplRounds(
ref Vector128<byte> s1, ref Vector128<byte> s2, ref Vector128<byte> s3, ref Vector128<byte> s4)
{
switch (m_mode)
{
case Mode.DEC_128: DecryptFour128(m_roundKeys, ref s1, ref s2, ref s3, ref s4); break;
case Mode.DEC_192: DecryptFour192(m_roundKeys, ref s1, ref s2, ref s3, ref s4); break;
case Mode.DEC_256: DecryptFour256(m_roundKeys, ref s1, ref s2, ref s3, ref s4); break;
case Mode.ENC_128: EncryptFour128(m_roundKeys, ref s1, ref s2, ref s3, ref s4); break;
case Mode.ENC_192: EncryptFour192(m_roundKeys, ref s1, ref s2, ref s3, ref s4); break;
case Mode.ENC_256: EncryptFour256(m_roundKeys, ref s1, ref s2, ref s3, ref s4); break;
default: throw new InvalidOperationException(nameof(AesEngine_X86) + " not initialised");
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void Decrypt128(Vector128<byte>[] roundKeys, ref Vector128<byte> state)
{
state = Sse2.Xor(state, roundKeys[0]);
state = Aes.Decrypt(state, roundKeys[1]);
state = Aes.Decrypt(state, roundKeys[2]);
state = Aes.Decrypt(state, roundKeys[3]);
state = Aes.Decrypt(state, roundKeys[4]);
state = Aes.Decrypt(state, roundKeys[5]);
state = Aes.Decrypt(state, roundKeys[6]);
state = Aes.Decrypt(state, roundKeys[7]);
state = Aes.Decrypt(state, roundKeys[8]);
state = Aes.Decrypt(state, roundKeys[9]);
state = Aes.DecryptLast(state, roundKeys[10]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void Decrypt192(Vector128<byte>[] roundKeys, ref Vector128<byte> state)
{
state = Sse2.Xor(state, roundKeys[0]);
state = Aes.Decrypt(state, roundKeys[1]);
state = Aes.Decrypt(state, roundKeys[2]);
state = Aes.Decrypt(state, roundKeys[3]);
state = Aes.Decrypt(state, roundKeys[4]);
state = Aes.Decrypt(state, roundKeys[5]);
state = Aes.Decrypt(state, roundKeys[6]);
state = Aes.Decrypt(state, roundKeys[7]);
state = Aes.Decrypt(state, roundKeys[8]);
state = Aes.Decrypt(state, roundKeys[9]);
state = Aes.Decrypt(state, roundKeys[10]);
state = Aes.Decrypt(state, roundKeys[11]);
state = Aes.DecryptLast(state, roundKeys[12]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void Decrypt256(Vector128<byte>[] roundKeys, ref Vector128<byte> state)
{
state = Sse2.Xor(state, roundKeys[0]);
state = Aes.Decrypt(state, roundKeys[1]);
state = Aes.Decrypt(state, roundKeys[2]);
state = Aes.Decrypt(state, roundKeys[3]);
state = Aes.Decrypt(state, roundKeys[4]);
state = Aes.Decrypt(state, roundKeys[5]);
state = Aes.Decrypt(state, roundKeys[6]);
state = Aes.Decrypt(state, roundKeys[7]);
state = Aes.Decrypt(state, roundKeys[8]);
state = Aes.Decrypt(state, roundKeys[9]);
state = Aes.Decrypt(state, roundKeys[10]);
state = Aes.Decrypt(state, roundKeys[11]);
state = Aes.Decrypt(state, roundKeys[12]);
state = Aes.Decrypt(state, roundKeys[13]);
state = Aes.DecryptLast(state, roundKeys[14]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void DecryptFour128(Vector128<byte>[] rk,
ref Vector128<byte> s1, ref Vector128<byte> s2, ref Vector128<byte> s3, ref Vector128<byte> s4)
{
s1 = Sse2.Xor(s1, rk[0]);
s2 = Sse2.Xor(s2, rk[0]);
s3 = Sse2.Xor(s3, rk[0]);
s4 = Sse2.Xor(s4, rk[0]);
s1 = Aes.Decrypt(s1, rk[1]);
s2 = Aes.Decrypt(s2, rk[1]);
s3 = Aes.Decrypt(s3, rk[1]);
s4 = Aes.Decrypt(s4, rk[1]);
s1 = Aes.Decrypt(s1, rk[2]);
s2 = Aes.Decrypt(s2, rk[2]);
s3 = Aes.Decrypt(s3, rk[2]);
s4 = Aes.Decrypt(s4, rk[2]);
s1 = Aes.Decrypt(s1, rk[3]);
s2 = Aes.Decrypt(s2, rk[3]);
s3 = Aes.Decrypt(s3, rk[3]);
s4 = Aes.Decrypt(s4, rk[3]);
s1 = Aes.Decrypt(s1, rk[4]);
s2 = Aes.Decrypt(s2, rk[4]);
s3 = Aes.Decrypt(s3, rk[4]);
s4 = Aes.Decrypt(s4, rk[4]);
s1 = Aes.Decrypt(s1, rk[5]);
s2 = Aes.Decrypt(s2, rk[5]);
s3 = Aes.Decrypt(s3, rk[5]);
s4 = Aes.Decrypt(s4, rk[5]);
s1 = Aes.Decrypt(s1, rk[6]);
s2 = Aes.Decrypt(s2, rk[6]);
s3 = Aes.Decrypt(s3, rk[6]);
s4 = Aes.Decrypt(s4, rk[6]);
s1 = Aes.Decrypt(s1, rk[7]);
s2 = Aes.Decrypt(s2, rk[7]);
s3 = Aes.Decrypt(s3, rk[7]);
s4 = Aes.Decrypt(s4, rk[7]);
s1 = Aes.Decrypt(s1, rk[8]);
s2 = Aes.Decrypt(s2, rk[8]);
s3 = Aes.Decrypt(s3, rk[8]);
s4 = Aes.Decrypt(s4, rk[8]);
s1 = Aes.Decrypt(s1, rk[9]);
s2 = Aes.Decrypt(s2, rk[9]);
s3 = Aes.Decrypt(s3, rk[9]);
s4 = Aes.Decrypt(s4, rk[9]);
s1 = Aes.DecryptLast(s1, rk[10]);
s2 = Aes.DecryptLast(s2, rk[10]);
s3 = Aes.DecryptLast(s3, rk[10]);
s4 = Aes.DecryptLast(s4, rk[10]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void DecryptFour192(Vector128<byte>[] rk,
ref Vector128<byte> s1, ref Vector128<byte> s2, ref Vector128<byte> s3, ref Vector128<byte> s4)
{
s1 = Sse2.Xor(s1, rk[0]);
s2 = Sse2.Xor(s2, rk[0]);
s3 = Sse2.Xor(s3, rk[0]);
s4 = Sse2.Xor(s4, rk[0]);
s1 = Aes.Decrypt(s1, rk[1]);
s2 = Aes.Decrypt(s2, rk[1]);
s3 = Aes.Decrypt(s3, rk[1]);
s4 = Aes.Decrypt(s4, rk[1]);
s1 = Aes.Decrypt(s1, rk[2]);
s2 = Aes.Decrypt(s2, rk[2]);
s3 = Aes.Decrypt(s3, rk[2]);
s4 = Aes.Decrypt(s4, rk[2]);
s1 = Aes.Decrypt(s1, rk[3]);
s2 = Aes.Decrypt(s2, rk[3]);
s3 = Aes.Decrypt(s3, rk[3]);
s4 = Aes.Decrypt(s4, rk[3]);
s1 = Aes.Decrypt(s1, rk[4]);
s2 = Aes.Decrypt(s2, rk[4]);
s3 = Aes.Decrypt(s3, rk[4]);
s4 = Aes.Decrypt(s4, rk[4]);
s1 = Aes.Decrypt(s1, rk[5]);
s2 = Aes.Decrypt(s2, rk[5]);
s3 = Aes.Decrypt(s3, rk[5]);
s4 = Aes.Decrypt(s4, rk[5]);
s1 = Aes.Decrypt(s1, rk[6]);
s2 = Aes.Decrypt(s2, rk[6]);
s3 = Aes.Decrypt(s3, rk[6]);
s4 = Aes.Decrypt(s4, rk[6]);
s1 = Aes.Decrypt(s1, rk[7]);
s2 = Aes.Decrypt(s2, rk[7]);
s3 = Aes.Decrypt(s3, rk[7]);
s4 = Aes.Decrypt(s4, rk[7]);
s1 = Aes.Decrypt(s1, rk[8]);
s2 = Aes.Decrypt(s2, rk[8]);
s3 = Aes.Decrypt(s3, rk[8]);
s4 = Aes.Decrypt(s4, rk[8]);
s1 = Aes.Decrypt(s1, rk[9]);
s2 = Aes.Decrypt(s2, rk[9]);
s3 = Aes.Decrypt(s3, rk[9]);
s4 = Aes.Decrypt(s4, rk[9]);
s1 = Aes.Decrypt(s1, rk[10]);
s2 = Aes.Decrypt(s2, rk[10]);
s3 = Aes.Decrypt(s3, rk[10]);
s4 = Aes.Decrypt(s4, rk[10]);
s1 = Aes.Decrypt(s1, rk[11]);
s2 = Aes.Decrypt(s2, rk[11]);
s3 = Aes.Decrypt(s3, rk[11]);
s4 = Aes.Decrypt(s4, rk[11]);
s1 = Aes.DecryptLast(s1, rk[12]);
s2 = Aes.DecryptLast(s2, rk[12]);
s3 = Aes.DecryptLast(s3, rk[12]);
s4 = Aes.DecryptLast(s4, rk[12]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void DecryptFour256(Vector128<byte>[] rk,
ref Vector128<byte> s1, ref Vector128<byte> s2, ref Vector128<byte> s3, ref Vector128<byte> s4)
{
s1 = Sse2.Xor(s1, rk[0]);
s2 = Sse2.Xor(s2, rk[0]);
s3 = Sse2.Xor(s3, rk[0]);
s4 = Sse2.Xor(s4, rk[0]);
s1 = Aes.Decrypt(s1, rk[1]);
s2 = Aes.Decrypt(s2, rk[1]);
s3 = Aes.Decrypt(s3, rk[1]);
s4 = Aes.Decrypt(s4, rk[1]);
s1 = Aes.Decrypt(s1, rk[2]);
s2 = Aes.Decrypt(s2, rk[2]);
s3 = Aes.Decrypt(s3, rk[2]);
s4 = Aes.Decrypt(s4, rk[2]);
s1 = Aes.Decrypt(s1, rk[3]);
s2 = Aes.Decrypt(s2, rk[3]);
s3 = Aes.Decrypt(s3, rk[3]);
s4 = Aes.Decrypt(s4, rk[3]);
s1 = Aes.Decrypt(s1, rk[4]);
s2 = Aes.Decrypt(s2, rk[4]);
s3 = Aes.Decrypt(s3, rk[4]);
s4 = Aes.Decrypt(s4, rk[4]);
s1 = Aes.Decrypt(s1, rk[5]);
s2 = Aes.Decrypt(s2, rk[5]);
s3 = Aes.Decrypt(s3, rk[5]);
s4 = Aes.Decrypt(s4, rk[5]);
s1 = Aes.Decrypt(s1, rk[6]);
s2 = Aes.Decrypt(s2, rk[6]);
s3 = Aes.Decrypt(s3, rk[6]);
s4 = Aes.Decrypt(s4, rk[6]);
s1 = Aes.Decrypt(s1, rk[7]);
s2 = Aes.Decrypt(s2, rk[7]);
s3 = Aes.Decrypt(s3, rk[7]);
s4 = Aes.Decrypt(s4, rk[7]);
s1 = Aes.Decrypt(s1, rk[8]);
s2 = Aes.Decrypt(s2, rk[8]);
s3 = Aes.Decrypt(s3, rk[8]);
s4 = Aes.Decrypt(s4, rk[8]);
s1 = Aes.Decrypt(s1, rk[9]);
s2 = Aes.Decrypt(s2, rk[9]);
s3 = Aes.Decrypt(s3, rk[9]);
s4 = Aes.Decrypt(s4, rk[9]);
s1 = Aes.Decrypt(s1, rk[10]);
s2 = Aes.Decrypt(s2, rk[10]);
s3 = Aes.Decrypt(s3, rk[10]);
s4 = Aes.Decrypt(s4, rk[10]);
s1 = Aes.Decrypt(s1, rk[11]);
s2 = Aes.Decrypt(s2, rk[11]);
s3 = Aes.Decrypt(s3, rk[11]);
s4 = Aes.Decrypt(s4, rk[11]);
s1 = Aes.Decrypt(s1, rk[12]);
s2 = Aes.Decrypt(s2, rk[12]);
s3 = Aes.Decrypt(s3, rk[12]);
s4 = Aes.Decrypt(s4, rk[12]);
s1 = Aes.Decrypt(s1, rk[13]);
s2 = Aes.Decrypt(s2, rk[13]);
s3 = Aes.Decrypt(s3, rk[13]);
s4 = Aes.Decrypt(s4, rk[13]);
s1 = Aes.DecryptLast(s1, rk[14]);
s2 = Aes.DecryptLast(s2, rk[14]);
s3 = Aes.DecryptLast(s3, rk[14]);
s4 = Aes.DecryptLast(s4, rk[14]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void Encrypt128(Vector128<byte>[] roundKeys, ref Vector128<byte> state)
{
state = Sse2.Xor(state, roundKeys[0]);
state = Aes.Encrypt(state, roundKeys[1]);
state = Aes.Encrypt(state, roundKeys[2]);
state = Aes.Encrypt(state, roundKeys[3]);
state = Aes.Encrypt(state, roundKeys[4]);
state = Aes.Encrypt(state, roundKeys[5]);
state = Aes.Encrypt(state, roundKeys[6]);
state = Aes.Encrypt(state, roundKeys[7]);
state = Aes.Encrypt(state, roundKeys[8]);
state = Aes.Encrypt(state, roundKeys[9]);
state = Aes.EncryptLast(state, roundKeys[10]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void Encrypt192(Vector128<byte>[] roundKeys, ref Vector128<byte> state)
{
state = Sse2.Xor(state, roundKeys[0]);
state = Aes.Encrypt(state, roundKeys[1]);
state = Aes.Encrypt(state, roundKeys[2]);
state = Aes.Encrypt(state, roundKeys[3]);
state = Aes.Encrypt(state, roundKeys[4]);
state = Aes.Encrypt(state, roundKeys[5]);
state = Aes.Encrypt(state, roundKeys[6]);
state = Aes.Encrypt(state, roundKeys[7]);
state = Aes.Encrypt(state, roundKeys[8]);
state = Aes.Encrypt(state, roundKeys[9]);
state = Aes.Encrypt(state, roundKeys[10]);
state = Aes.Encrypt(state, roundKeys[11]);
state = Aes.EncryptLast(state, roundKeys[12]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void Encrypt256(Vector128<byte>[] roundKeys, ref Vector128<byte> state)
{
state = Sse2.Xor(state, roundKeys[0]);
state = Aes.Encrypt(state, roundKeys[1]);
state = Aes.Encrypt(state, roundKeys[2]);
state = Aes.Encrypt(state, roundKeys[3]);
state = Aes.Encrypt(state, roundKeys[4]);
state = Aes.Encrypt(state, roundKeys[5]);
state = Aes.Encrypt(state, roundKeys[6]);
state = Aes.Encrypt(state, roundKeys[7]);
state = Aes.Encrypt(state, roundKeys[8]);
state = Aes.Encrypt(state, roundKeys[9]);
state = Aes.Encrypt(state, roundKeys[10]);
state = Aes.Encrypt(state, roundKeys[11]);
state = Aes.Encrypt(state, roundKeys[12]);
state = Aes.Encrypt(state, roundKeys[13]);
state = Aes.EncryptLast(state, roundKeys[14]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void EncryptFour128(Vector128<byte>[] rk,
ref Vector128<byte> s1, ref Vector128<byte> s2, ref Vector128<byte> s3, ref Vector128<byte> s4)
{
s1 = Sse2.Xor(s1, rk[0]);
s2 = Sse2.Xor(s2, rk[0]);
s3 = Sse2.Xor(s3, rk[0]);
s4 = Sse2.Xor(s4, rk[0]);
s1 = Aes.Encrypt(s1, rk[1]);
s2 = Aes.Encrypt(s2, rk[1]);
s3 = Aes.Encrypt(s3, rk[1]);
s4 = Aes.Encrypt(s4, rk[1]);
s1 = Aes.Encrypt(s1, rk[2]);
s2 = Aes.Encrypt(s2, rk[2]);
s3 = Aes.Encrypt(s3, rk[2]);
s4 = Aes.Encrypt(s4, rk[2]);
s1 = Aes.Encrypt(s1, rk[3]);
s2 = Aes.Encrypt(s2, rk[3]);
s3 = Aes.Encrypt(s3, rk[3]);
s4 = Aes.Encrypt(s4, rk[3]);
s1 = Aes.Encrypt(s1, rk[4]);
s2 = Aes.Encrypt(s2, rk[4]);
s3 = Aes.Encrypt(s3, rk[4]);
s4 = Aes.Encrypt(s4, rk[4]);
s1 = Aes.Encrypt(s1, rk[5]);
s2 = Aes.Encrypt(s2, rk[5]);
s3 = Aes.Encrypt(s3, rk[5]);
s4 = Aes.Encrypt(s4, rk[5]);
s1 = Aes.Encrypt(s1, rk[6]);
s2 = Aes.Encrypt(s2, rk[6]);
s3 = Aes.Encrypt(s3, rk[6]);
s4 = Aes.Encrypt(s4, rk[6]);
s1 = Aes.Encrypt(s1, rk[7]);
s2 = Aes.Encrypt(s2, rk[7]);
s3 = Aes.Encrypt(s3, rk[7]);
s4 = Aes.Encrypt(s4, rk[7]);
s1 = Aes.Encrypt(s1, rk[8]);
s2 = Aes.Encrypt(s2, rk[8]);
s3 = Aes.Encrypt(s3, rk[8]);
s4 = Aes.Encrypt(s4, rk[8]);
s1 = Aes.Encrypt(s1, rk[9]);
s2 = Aes.Encrypt(s2, rk[9]);
s3 = Aes.Encrypt(s3, rk[9]);
s4 = Aes.Encrypt(s4, rk[9]);
s1 = Aes.EncryptLast(s1, rk[10]);
s2 = Aes.EncryptLast(s2, rk[10]);
s3 = Aes.EncryptLast(s3, rk[10]);
s4 = Aes.EncryptLast(s4, rk[10]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void EncryptFour192(Vector128<byte>[] rk,
ref Vector128<byte> s1, ref Vector128<byte> s2, ref Vector128<byte> s3, ref Vector128<byte> s4)
{
s1 = Sse2.Xor(s1, rk[0]);
s2 = Sse2.Xor(s2, rk[0]);
s3 = Sse2.Xor(s3, rk[0]);
s4 = Sse2.Xor(s4, rk[0]);
s1 = Aes.Encrypt(s1, rk[1]);
s2 = Aes.Encrypt(s2, rk[1]);
s3 = Aes.Encrypt(s3, rk[1]);
s4 = Aes.Encrypt(s4, rk[1]);
s1 = Aes.Encrypt(s1, rk[2]);
s2 = Aes.Encrypt(s2, rk[2]);
s3 = Aes.Encrypt(s3, rk[2]);
s4 = Aes.Encrypt(s4, rk[2]);
s1 = Aes.Encrypt(s1, rk[3]);
s2 = Aes.Encrypt(s2, rk[3]);
s3 = Aes.Encrypt(s3, rk[3]);
s4 = Aes.Encrypt(s4, rk[3]);
s1 = Aes.Encrypt(s1, rk[4]);
s2 = Aes.Encrypt(s2, rk[4]);
s3 = Aes.Encrypt(s3, rk[4]);
s4 = Aes.Encrypt(s4, rk[4]);
s1 = Aes.Encrypt(s1, rk[5]);
s2 = Aes.Encrypt(s2, rk[5]);
s3 = Aes.Encrypt(s3, rk[5]);
s4 = Aes.Encrypt(s4, rk[5]);
s1 = Aes.Encrypt(s1, rk[6]);
s2 = Aes.Encrypt(s2, rk[6]);
s3 = Aes.Encrypt(s3, rk[6]);
s4 = Aes.Encrypt(s4, rk[6]);
s1 = Aes.Encrypt(s1, rk[7]);
s2 = Aes.Encrypt(s2, rk[7]);
s3 = Aes.Encrypt(s3, rk[7]);
s4 = Aes.Encrypt(s4, rk[7]);
s1 = Aes.Encrypt(s1, rk[8]);
s2 = Aes.Encrypt(s2, rk[8]);
s3 = Aes.Encrypt(s3, rk[8]);
s4 = Aes.Encrypt(s4, rk[8]);
s1 = Aes.Encrypt(s1, rk[9]);
s2 = Aes.Encrypt(s2, rk[9]);
s3 = Aes.Encrypt(s3, rk[9]);
s4 = Aes.Encrypt(s4, rk[9]);
s1 = Aes.Encrypt(s1, rk[10]);
s2 = Aes.Encrypt(s2, rk[10]);
s3 = Aes.Encrypt(s3, rk[10]);
s4 = Aes.Encrypt(s4, rk[10]);
s1 = Aes.Encrypt(s1, rk[11]);
s2 = Aes.Encrypt(s2, rk[11]);
s3 = Aes.Encrypt(s3, rk[11]);
s4 = Aes.Encrypt(s4, rk[11]);
s1 = Aes.EncryptLast(s1, rk[12]);
s2 = Aes.EncryptLast(s2, rk[12]);
s3 = Aes.EncryptLast(s3, rk[12]);
s4 = Aes.EncryptLast(s4, rk[12]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void EncryptFour256(Vector128<byte>[] rk,
ref Vector128<byte> s1, ref Vector128<byte> s2, ref Vector128<byte> s3, ref Vector128<byte> s4)
{
s1 = Sse2.Xor(s1, rk[0]);
s2 = Sse2.Xor(s2, rk[0]);
s3 = Sse2.Xor(s3, rk[0]);
s4 = Sse2.Xor(s4, rk[0]);
s1 = Aes.Encrypt(s1, rk[1]);
s2 = Aes.Encrypt(s2, rk[1]);
s3 = Aes.Encrypt(s3, rk[1]);
s4 = Aes.Encrypt(s4, rk[1]);
s1 = Aes.Encrypt(s1, rk[2]);
s2 = Aes.Encrypt(s2, rk[2]);
s3 = Aes.Encrypt(s3, rk[2]);
s4 = Aes.Encrypt(s4, rk[2]);
s1 = Aes.Encrypt(s1, rk[3]);
s2 = Aes.Encrypt(s2, rk[3]);
s3 = Aes.Encrypt(s3, rk[3]);
s4 = Aes.Encrypt(s4, rk[3]);
s1 = Aes.Encrypt(s1, rk[4]);
s2 = Aes.Encrypt(s2, rk[4]);
s3 = Aes.Encrypt(s3, rk[4]);
s4 = Aes.Encrypt(s4, rk[4]);
s1 = Aes.Encrypt(s1, rk[5]);
s2 = Aes.Encrypt(s2, rk[5]);
s3 = Aes.Encrypt(s3, rk[5]);
s4 = Aes.Encrypt(s4, rk[5]);
s1 = Aes.Encrypt(s1, rk[6]);
s2 = Aes.Encrypt(s2, rk[6]);
s3 = Aes.Encrypt(s3, rk[6]);
s4 = Aes.Encrypt(s4, rk[6]);
s1 = Aes.Encrypt(s1, rk[7]);
s2 = Aes.Encrypt(s2, rk[7]);
s3 = Aes.Encrypt(s3, rk[7]);
s4 = Aes.Encrypt(s4, rk[7]);
s1 = Aes.Encrypt(s1, rk[8]);
s2 = Aes.Encrypt(s2, rk[8]);
s3 = Aes.Encrypt(s3, rk[8]);
s4 = Aes.Encrypt(s4, rk[8]);
s1 = Aes.Encrypt(s1, rk[9]);
s2 = Aes.Encrypt(s2, rk[9]);
s3 = Aes.Encrypt(s3, rk[9]);
s4 = Aes.Encrypt(s4, rk[9]);
s1 = Aes.Encrypt(s1, rk[10]);
s2 = Aes.Encrypt(s2, rk[10]);
s3 = Aes.Encrypt(s3, rk[10]);
s4 = Aes.Encrypt(s4, rk[10]);
s1 = Aes.Encrypt(s1, rk[11]);
s2 = Aes.Encrypt(s2, rk[11]);
s3 = Aes.Encrypt(s3, rk[11]);
s4 = Aes.Encrypt(s4, rk[11]);
s1 = Aes.Encrypt(s1, rk[12]);
s2 = Aes.Encrypt(s2, rk[12]);
s3 = Aes.Encrypt(s3, rk[12]);
s4 = Aes.Encrypt(s4, rk[12]);
s1 = Aes.Encrypt(s1, rk[13]);
s2 = Aes.Encrypt(s2, rk[13]);
s3 = Aes.Encrypt(s3, rk[13]);
s4 = Aes.Encrypt(s4, rk[13]);
s1 = Aes.EncryptLast(s1, rk[14]);
s2 = Aes.EncryptLast(s2, rk[14]);
s3 = Aes.EncryptLast(s3, rk[14]);
s4 = Aes.EncryptLast(s4, rk[14]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector128<byte> Load128(ReadOnlySpan<byte> t)
{
#if NET7_0_OR_GREATER
return Vector128.Create<byte>(t);
#else
if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector128<byte>>() == 16)
return MemoryMarshal.Read<Vector128<byte>>(t);
return Vector128.Create(
BinaryPrimitives.ReadUInt64LittleEndian(t[..8]),
BinaryPrimitives.ReadUInt64LittleEndian(t[8..])
).AsByte();
#endif
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector64<byte> Load64(ReadOnlySpan<byte> t)
{
#if NET7_0_OR_GREATER
return Vector64.Create<byte>(t);
#else
if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector64<byte>>() == 8)
return MemoryMarshal.Read<Vector64<byte>>(t);
return Vector64.Create(
BinaryPrimitives.ReadUInt64LittleEndian(t[..8])
).AsByte();
#endif
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void Store128(Vector128<byte> s, Span<byte> t)
{
#if NET7_0_OR_GREATER
Vector128.CopyTo(s, t);
#else
if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector128<byte>>() == 16)
{
MemoryMarshal.Write(t, ref s);
return;
}
var u = s.AsUInt64();
BinaryPrimitives.WriteUInt64LittleEndian(t[..8], u.GetElement(0));
BinaryPrimitives.WriteUInt64LittleEndian(t[8..], u.GetElement(1));
#endif
}
}
}
#endif
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: d9b6bab5c035f7c469bf54cb40312899
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/AesEngine_X86.cs
uploadId: 783279

View File

@ -0,0 +1,2 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: a7a304b68d3b9cd40953469c2a58b9b5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/AesFastEngine.cs
uploadId: 783279

View File

@ -0,0 +1,617 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.Diagnostics;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/**
* an implementation of the AES (Rijndael), from FIPS-197.
* <p>
* For further details see: <a href="http://csrc.nist.gov/encryption/aes/">http://csrc.nist.gov/encryption/aes/</a>.
*
* This implementation is based on optimizations from Dr. Brian Gladman's paper and C code at
* <a href="http://fp.gladman.plus.com/cryptography_technology/rijndael/">http://fp.gladman.plus.com/cryptography_technology/rijndael/</a>
*
* There are three levels of tradeoff of speed vs memory
* Because java has no preprocessor, they are written as three separate classes from which to choose
*
* The fastest uses 8Kbytes of static tables to precompute round calculations, 4 256 word tables for encryption
* and 4 for decryption.
*
* The middle performance version uses only one 256 word table for each, for a total of 2Kbytes,
* adding 12 rotate operations per round to compute the values contained in the other tables from
* the contents of the first
*
* The slowest version uses no static tables at all and computes the values
* in each round.
* </p>
* <p>
* This file contains the slowest performance version with no static tables
* for round precomputation, but it has the smallest foot print.
* </p>
*/
public sealed class AesLightEngine
: IBlockCipher
{
// The S box
private static readonly byte[] S =
{
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,
};
// The inverse S-box
private static readonly byte[] Si =
{
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,
};
// vector used in calculating key schedule (powers of x in GF(256))
private static readonly byte[] rcon =
{
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91
};
private static uint Shift(uint r, int shift)
{
return (r >> shift) | (r << (32 - shift));
}
/* multiply four bytes in GF(2^8) by 'x' {02} in parallel */
private const uint m1 = 0x80808080;
private const uint m2 = 0x7f7f7f7f;
private const uint m3 = 0x0000001b;
private const uint m4 = 0xC0C0C0C0;
private const uint m5 = 0x3f3f3f3f;
private static uint FFmulX(uint x)
{
return ((x & m2) << 1) ^ (((x & m1) >> 7) * m3);
}
private static uint FFmulX2(uint x)
{
uint t0 = (x & m5) << 2;
uint t1 = (x & m4);
t1 ^= (t1 >> 1);
return t0 ^ (t1 >> 2) ^ (t1 >> 5);
}
/*
The following defines provide alternative definitions of FFmulX that might
give improved performance if a fast 32-bit multiply is not available.
private int FFmulX(int x) { int u = x & m1; u |= (u >> 1); return ((x & m2) << 1) ^ ((u >>> 3) | (u >>> 6)); }
private static final int m4 = 0x1b1b1b1b;
private int FFmulX(int x) { int u = x & m1; return ((x & m2) << 1) ^ ((u - (u >>> 7)) & m4); }
*/
private static uint Mcol(uint x)
{
uint t0, t1;
t0 = Shift(x, 8);
t1 = x ^ t0;
return Shift(t1, 16) ^ t0 ^ FFmulX(t1);
}
private static uint Inv_Mcol(uint x)
{
uint t0, t1;
t0 = x;
t1 = t0 ^ Shift(t0, 8);
t0 ^= FFmulX(t1);
t1 ^= FFmulX2(t0);
t0 ^= t1 ^ Shift(t1, 16);
return t0;
}
private static uint SubWord(uint x)
{
return (uint)S[x&255]
| (((uint)S[(x>>8)&255]) << 8)
| (((uint)S[(x>>16)&255]) << 16)
| (((uint)S[(x>>24)&255]) << 24);
}
/**
* Calculate the necessary round keys
* The number of calculations depends on key size and block size
* AES specified a fixed block size of 128 bits and key sizes 128/192/256 bits
* This code is written assuming those are the only possible values
*/
private uint[][] GenerateWorkingKey(byte[] key, bool forEncryption)
{
int keyLen = key.Length;
if (keyLen < 16 || keyLen > 32 || (keyLen & 7) != 0)
throw new ArgumentException("Key length not 128/192/256 bits.");
int KC = keyLen >> 2;
this.ROUNDS = KC + 6; // This is not always true for the generalized Rijndael that allows larger block sizes
uint[][] W = new uint[ROUNDS + 1][]; // 4 words in a block
for (int i = 0; i <= ROUNDS; ++i)
{
W[i] = new uint[4];
}
switch (KC)
{
case 4:
{
uint t0 = Pack.LE_To_UInt32(key, 0); W[0][0] = t0;
uint t1 = Pack.LE_To_UInt32(key, 4); W[0][1] = t1;
uint t2 = Pack.LE_To_UInt32(key, 8); W[0][2] = t2;
uint t3 = Pack.LE_To_UInt32(key, 12); W[0][3] = t3;
for (int i = 1; i <= 10; ++i)
{
uint u = SubWord(Shift(t3, 8)) ^ rcon[i - 1];
t0 ^= u; W[i][0] = t0;
t1 ^= t0; W[i][1] = t1;
t2 ^= t1; W[i][2] = t2;
t3 ^= t2; W[i][3] = t3;
}
break;
}
case 6:
{
uint t0 = Pack.LE_To_UInt32(key, 0); W[0][0] = t0;
uint t1 = Pack.LE_To_UInt32(key, 4); W[0][1] = t1;
uint t2 = Pack.LE_To_UInt32(key, 8); W[0][2] = t2;
uint t3 = Pack.LE_To_UInt32(key, 12); W[0][3] = t3;
uint t4 = Pack.LE_To_UInt32(key, 16); W[1][0] = t4;
uint t5 = Pack.LE_To_UInt32(key, 20); W[1][1] = t5;
uint rcon = 1;
uint u = SubWord(Shift(t5, 8)) ^ rcon; rcon <<= 1;
t0 ^= u; W[1][2] = t0;
t1 ^= t0; W[1][3] = t1;
t2 ^= t1; W[2][0] = t2;
t3 ^= t2; W[2][1] = t3;
t4 ^= t3; W[2][2] = t4;
t5 ^= t4; W[2][3] = t5;
for (int i = 3; i < 12; i += 3)
{
u = SubWord(Shift(t5, 8)) ^ rcon; rcon <<= 1;
t0 ^= u; W[i ][0] = t0;
t1 ^= t0; W[i ][1] = t1;
t2 ^= t1; W[i ][2] = t2;
t3 ^= t2; W[i ][3] = t3;
t4 ^= t3; W[i + 1][0] = t4;
t5 ^= t4; W[i + 1][1] = t5;
u = SubWord(Shift(t5, 8)) ^ rcon; rcon <<= 1;
t0 ^= u; W[i + 1][2] = t0;
t1 ^= t0; W[i + 1][3] = t1;
t2 ^= t1; W[i + 2][0] = t2;
t3 ^= t2; W[i + 2][1] = t3;
t4 ^= t3; W[i + 2][2] = t4;
t5 ^= t4; W[i + 2][3] = t5;
}
u = SubWord(Shift(t5, 8)) ^ rcon;
t0 ^= u; W[12][0] = t0;
t1 ^= t0; W[12][1] = t1;
t2 ^= t1; W[12][2] = t2;
t3 ^= t2; W[12][3] = t3;
break;
}
case 8:
{
uint t0 = Pack.LE_To_UInt32(key, 0); W[0][0] = t0;
uint t1 = Pack.LE_To_UInt32(key, 4); W[0][1] = t1;
uint t2 = Pack.LE_To_UInt32(key, 8); W[0][2] = t2;
uint t3 = Pack.LE_To_UInt32(key, 12); W[0][3] = t3;
uint t4 = Pack.LE_To_UInt32(key, 16); W[1][0] = t4;
uint t5 = Pack.LE_To_UInt32(key, 20); W[1][1] = t5;
uint t6 = Pack.LE_To_UInt32(key, 24); W[1][2] = t6;
uint t7 = Pack.LE_To_UInt32(key, 28); W[1][3] = t7;
uint u, rcon = 1;
for (int i = 2; i < 14; i += 2)
{
u = SubWord(Shift(t7, 8)) ^ rcon; rcon <<= 1;
t0 ^= u; W[i ][0] = t0;
t1 ^= t0; W[i ][1] = t1;
t2 ^= t1; W[i ][2] = t2;
t3 ^= t2; W[i ][3] = t3;
u = SubWord(t3);
t4 ^= u; W[i + 1][0] = t4;
t5 ^= t4; W[i + 1][1] = t5;
t6 ^= t5; W[i + 1][2] = t6;
t7 ^= t6; W[i + 1][3] = t7;
}
u = SubWord(Shift(t7, 8)) ^ rcon;
t0 ^= u; W[14][0] = t0;
t1 ^= t0; W[14][1] = t1;
t2 ^= t1; W[14][2] = t2;
t3 ^= t2; W[14][3] = t3;
break;
}
default:
{
throw new InvalidOperationException("Should never get here");
}
}
if (!forEncryption)
{
for (int j = 1; j < ROUNDS; j++)
{
uint[] w = W[j];
for (int i = 0; i < 4; i++)
{
w[i] = Inv_Mcol(w[i]);
}
}
}
return W;
}
private int ROUNDS;
private uint[][] WorkingKey;
private bool forEncryption;
private const int BLOCK_SIZE = 16;
/**
* default constructor - 128 bit block size.
*/
public AesLightEngine()
{
}
/**
* initialise an AES cipher.
*
* @param forEncryption whether or not we are for encryption.
* @param parameters the parameters required to set up the cipher.
* @exception ArgumentException if the parameters argument is
* inappropriate.
*/
public void Init(bool forEncryption, ICipherParameters parameters)
{
if (!(parameters is KeyParameter keyParameter))
throw new ArgumentException("invalid parameter passed to AES init - "
+ Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters));
WorkingKey = GenerateWorkingKey(keyParameter.GetKey(), forEncryption);
this.forEncryption = forEncryption;
}
public string AlgorithmName
{
get { return "AES"; }
}
public int GetBlockSize()
{
return BLOCK_SIZE;
}
public 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");
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
if (forEncryption)
{
EncryptBlock(input.AsSpan(inOff), output.AsSpan(outOff), WorkingKey);
}
else
{
DecryptBlock(input.AsSpan(inOff), output.AsSpan(outOff), WorkingKey);
}
#else
if (forEncryption)
{
EncryptBlock(input, inOff, output, outOff, WorkingKey);
}
else
{
DecryptBlock(input, inOff, output, outOff, WorkingKey);
}
#endif
return BLOCK_SIZE;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public int ProcessBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
if (WorkingKey == null)
throw new InvalidOperationException("AES engine not initialised");
Check.DataLength(input, 16, "input buffer too short");
Check.OutputLength(output, 16, "output buffer too short");
if (forEncryption)
{
EncryptBlock(input, output, WorkingKey);
}
else
{
DecryptBlock(input, output, WorkingKey);
}
return BLOCK_SIZE;
}
#endif
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
private void EncryptBlock(ReadOnlySpan<byte> input, Span<byte> output, uint[][] KW)
{
uint C0 = Pack.LE_To_UInt32(input);
uint C1 = Pack.LE_To_UInt32(input[4..]);
uint C2 = Pack.LE_To_UInt32(input[8..]);
uint C3 = Pack.LE_To_UInt32(input[12..]);
uint[] kw = KW[0];
uint t0 = C0 ^ kw[0];
uint t1 = C1 ^ kw[1];
uint t2 = C2 ^ kw[2];
uint r0, r1, r2, r3 = C3 ^ kw[3];
int r = 1;
while (r < ROUNDS - 1)
{
kw = KW[r++];
r0 = Mcol((uint)S[t0 & 255] ^ (((uint)S[(t1 >> 8) & 255]) << 8) ^ (((uint)S[(t2 >> 16) & 255]) << 16) ^ (((uint)S[(r3 >> 24) & 255]) << 24)) ^ kw[0];
r1 = Mcol((uint)S[t1 & 255] ^ (((uint)S[(t2 >> 8) & 255]) << 8) ^ (((uint)S[(r3 >> 16) & 255]) << 16) ^ (((uint)S[(t0 >> 24) & 255]) << 24)) ^ kw[1];
r2 = Mcol((uint)S[t2 & 255] ^ (((uint)S[(r3 >> 8) & 255]) << 8) ^ (((uint)S[(t0 >> 16) & 255]) << 16) ^ (((uint)S[(t1 >> 24) & 255]) << 24)) ^ kw[2];
r3 = Mcol((uint)S[r3 & 255] ^ (((uint)S[(t0 >> 8) & 255]) << 8) ^ (((uint)S[(t1 >> 16) & 255]) << 16) ^ (((uint)S[(t2 >> 24) & 255]) << 24)) ^ kw[3];
kw = KW[r++];
t0 = Mcol((uint)S[r0 & 255] ^ (((uint)S[(r1 >> 8) & 255]) << 8) ^ (((uint)S[(r2 >> 16) & 255]) << 16) ^ (((uint)S[(r3 >> 24) & 255]) << 24)) ^ kw[0];
t1 = Mcol((uint)S[r1 & 255] ^ (((uint)S[(r2 >> 8) & 255]) << 8) ^ (((uint)S[(r3 >> 16) & 255]) << 16) ^ (((uint)S[(r0 >> 24) & 255]) << 24)) ^ kw[1];
t2 = Mcol((uint)S[r2 & 255] ^ (((uint)S[(r3 >> 8) & 255]) << 8) ^ (((uint)S[(r0 >> 16) & 255]) << 16) ^ (((uint)S[(r1 >> 24) & 255]) << 24)) ^ kw[2];
r3 = Mcol((uint)S[r3 & 255] ^ (((uint)S[(r0 >> 8) & 255]) << 8) ^ (((uint)S[(r1 >> 16) & 255]) << 16) ^ (((uint)S[(r2 >> 24) & 255]) << 24)) ^ kw[3];
}
kw = KW[r++];
r0 = Mcol((uint)S[t0 & 255] ^ (((uint)S[(t1 >> 8) & 255]) << 8) ^ (((uint)S[(t2 >> 16) & 255]) << 16) ^ (((uint)S[(r3 >> 24) & 255]) << 24)) ^ kw[0];
r1 = Mcol((uint)S[t1 & 255] ^ (((uint)S[(t2 >> 8) & 255]) << 8) ^ (((uint)S[(r3 >> 16) & 255]) << 16) ^ (((uint)S[(t0 >> 24) & 255]) << 24)) ^ kw[1];
r2 = Mcol((uint)S[t2 & 255] ^ (((uint)S[(r3 >> 8) & 255]) << 8) ^ (((uint)S[(t0 >> 16) & 255]) << 16) ^ (((uint)S[(t1 >> 24) & 255]) << 24)) ^ kw[2];
r3 = Mcol((uint)S[r3 & 255] ^ (((uint)S[(t0 >> 8) & 255]) << 8) ^ (((uint)S[(t1 >> 16) & 255]) << 16) ^ (((uint)S[(t2 >> 24) & 255]) << 24)) ^ kw[3];
// the final round is a simple function of S
kw = KW[r];
C0 = (uint)S[r0 & 255] ^ (((uint)S[(r1 >> 8) & 255]) << 8) ^ (((uint)S[(r2 >> 16) & 255]) << 16) ^ (((uint)S[(r3 >> 24) & 255]) << 24) ^ kw[0];
C1 = (uint)S[r1 & 255] ^ (((uint)S[(r2 >> 8) & 255]) << 8) ^ (((uint)S[(r3 >> 16) & 255]) << 16) ^ (((uint)S[(r0 >> 24) & 255]) << 24) ^ kw[1];
C2 = (uint)S[r2 & 255] ^ (((uint)S[(r3 >> 8) & 255]) << 8) ^ (((uint)S[(r0 >> 16) & 255]) << 16) ^ (((uint)S[(r1 >> 24) & 255]) << 24) ^ kw[2];
C3 = (uint)S[r3 & 255] ^ (((uint)S[(r0 >> 8) & 255]) << 8) ^ (((uint)S[(r1 >> 16) & 255]) << 16) ^ (((uint)S[(r2 >> 24) & 255]) << 24) ^ kw[3];
Pack.UInt32_To_LE(C0, output);
Pack.UInt32_To_LE(C1, output[4..]);
Pack.UInt32_To_LE(C2, output[8..]);
Pack.UInt32_To_LE(C3, output[12..]);
}
private void DecryptBlock(ReadOnlySpan<byte> input, Span<byte> output, uint[][] KW)
{
uint C0 = Pack.LE_To_UInt32(input);
uint C1 = Pack.LE_To_UInt32(input[4..]);
uint C2 = Pack.LE_To_UInt32(input[8..]);
uint C3 = Pack.LE_To_UInt32(input[12..]);
uint[] kw = KW[ROUNDS];
uint t0 = C0 ^ kw[0];
uint t1 = C1 ^ kw[1];
uint t2 = C2 ^ kw[2];
uint r0, r1, r2, r3 = C3 ^ kw[3];
int r = ROUNDS - 1;
while (r > 1)
{
kw = KW[r--];
r0 = Inv_Mcol((uint)Si[t0 & 255] ^ (((uint)Si[(r3 >> 8) & 255]) << 8) ^ (((uint)Si[(t2 >> 16) & 255]) << 16) ^ ((uint)Si[(t1 >> 24) & 255] << 24)) ^ kw[0];
r1 = Inv_Mcol((uint)Si[t1 & 255] ^ (((uint)Si[(t0 >> 8) & 255]) << 8) ^ (((uint)Si[(r3 >> 16) & 255]) << 16) ^ ((uint)Si[(t2 >> 24) & 255] << 24)) ^ kw[1];
r2 = Inv_Mcol((uint)Si[t2 & 255] ^ (((uint)Si[(t1 >> 8) & 255]) << 8) ^ (((uint)Si[(t0 >> 16) & 255]) << 16) ^ ((uint)Si[(r3 >> 24) & 255] << 24)) ^ kw[2];
r3 = Inv_Mcol((uint)Si[r3 & 255] ^ (((uint)Si[(t2 >> 8) & 255]) << 8) ^ (((uint)Si[(t1 >> 16) & 255]) << 16) ^ ((uint)Si[(t0 >> 24) & 255] << 24)) ^ kw[3];
kw = KW[r--];
t0 = Inv_Mcol((uint)Si[r0 & 255] ^ (((uint)Si[(r3 >> 8) & 255]) << 8) ^ (((uint)Si[(r2 >> 16) & 255]) << 16) ^ ((uint)Si[(r1 >> 24) & 255] << 24)) ^ kw[0];
t1 = Inv_Mcol((uint)Si[r1 & 255] ^ (((uint)Si[(r0 >> 8) & 255]) << 8) ^ (((uint)Si[(r3 >> 16) & 255]) << 16) ^ ((uint)Si[(r2 >> 24) & 255] << 24)) ^ kw[1];
t2 = Inv_Mcol((uint)Si[r2 & 255] ^ (((uint)Si[(r1 >> 8) & 255]) << 8) ^ (((uint)Si[(r0 >> 16) & 255]) << 16) ^ ((uint)Si[(r3 >> 24) & 255] << 24)) ^ kw[2];
r3 = Inv_Mcol((uint)Si[r3 & 255] ^ (((uint)Si[(r2 >> 8) & 255]) << 8) ^ (((uint)Si[(r1 >> 16) & 255]) << 16) ^ ((uint)Si[(r0 >> 24) & 255] << 24)) ^ kw[3];
}
kw = KW[1];
r0 = Inv_Mcol((uint)Si[t0 & 255] ^ (((uint)Si[(r3 >> 8) & 255]) << 8) ^ (((uint)Si[(t2 >> 16) & 255]) << 16) ^ ((uint)Si[(t1 >> 24) & 255] << 24)) ^ kw[0];
r1 = Inv_Mcol((uint)Si[t1 & 255] ^ (((uint)Si[(t0 >> 8) & 255]) << 8) ^ (((uint)Si[(r3 >> 16) & 255]) << 16) ^ ((uint)Si[(t2 >> 24) & 255] << 24)) ^ kw[1];
r2 = Inv_Mcol((uint)Si[t2 & 255] ^ (((uint)Si[(t1 >> 8) & 255]) << 8) ^ (((uint)Si[(t0 >> 16) & 255]) << 16) ^ ((uint)Si[(r3 >> 24) & 255] << 24)) ^ kw[2];
r3 = Inv_Mcol((uint)Si[r3 & 255] ^ (((uint)Si[(t2 >> 8) & 255]) << 8) ^ (((uint)Si[(t1 >> 16) & 255]) << 16) ^ ((uint)Si[(t0 >> 24) & 255] << 24)) ^ kw[3];
// the final round's table is a simple function of Si
kw = KW[0];
C0 = (uint)Si[r0 & 255] ^ (((uint)Si[(r3 >> 8) & 255]) << 8) ^ (((uint)Si[(r2 >> 16) & 255]) << 16) ^ (((uint)Si[(r1 >> 24) & 255]) << 24) ^ kw[0];
C1 = (uint)Si[r1 & 255] ^ (((uint)Si[(r0 >> 8) & 255]) << 8) ^ (((uint)Si[(r3 >> 16) & 255]) << 16) ^ (((uint)Si[(r2 >> 24) & 255]) << 24) ^ kw[1];
C2 = (uint)Si[r2 & 255] ^ (((uint)Si[(r1 >> 8) & 255]) << 8) ^ (((uint)Si[(r0 >> 16) & 255]) << 16) ^ (((uint)Si[(r3 >> 24) & 255]) << 24) ^ kw[2];
C3 = (uint)Si[r3 & 255] ^ (((uint)Si[(r2 >> 8) & 255]) << 8) ^ (((uint)Si[(r1 >> 16) & 255]) << 16) ^ (((uint)Si[(r0 >> 24) & 255]) << 24) ^ kw[3];
Pack.UInt32_To_LE(C0, output);
Pack.UInt32_To_LE(C1, output[4..]);
Pack.UInt32_To_LE(C2, output[8..]);
Pack.UInt32_To_LE(C3, output[12..]);
}
#else
private void EncryptBlock(byte[] input, int inOff, byte[] output, int outOff, uint[][] KW)
{
uint C0 = Pack.LE_To_UInt32(input, inOff + 0);
uint C1 = Pack.LE_To_UInt32(input, inOff + 4);
uint C2 = Pack.LE_To_UInt32(input, inOff + 8);
uint C3 = Pack.LE_To_UInt32(input, inOff + 12);
uint[] kw = KW[0];
uint t0 = C0 ^ kw[0];
uint t1 = C1 ^ kw[1];
uint t2 = C2 ^ kw[2];
uint r0, r1, r2, r3 = C3 ^ kw[3];
int r = 1;
while (r < ROUNDS - 1)
{
kw = KW[r++];
r0 = Mcol((uint)S[t0 & 255] ^ (((uint)S[(t1 >> 8) & 255]) << 8) ^ (((uint)S[(t2 >> 16) & 255]) << 16) ^ (((uint)S[(r3 >> 24) & 255]) << 24)) ^ kw[0];
r1 = Mcol((uint)S[t1 & 255] ^ (((uint)S[(t2 >> 8) & 255]) << 8) ^ (((uint)S[(r3 >> 16) & 255]) << 16) ^ (((uint)S[(t0 >> 24) & 255]) << 24)) ^ kw[1];
r2 = Mcol((uint)S[t2 & 255] ^ (((uint)S[(r3 >> 8) & 255]) << 8) ^ (((uint)S[(t0 >> 16) & 255]) << 16) ^ (((uint)S[(t1 >> 24) & 255]) << 24)) ^ kw[2];
r3 = Mcol((uint)S[r3 & 255] ^ (((uint)S[(t0 >> 8) & 255]) << 8) ^ (((uint)S[(t1 >> 16) & 255]) << 16) ^ (((uint)S[(t2 >> 24) & 255]) << 24)) ^ kw[3];
kw = KW[r++];
t0 = Mcol((uint)S[r0 & 255] ^ (((uint)S[(r1 >> 8) & 255]) << 8) ^ (((uint)S[(r2 >> 16) & 255]) << 16) ^ (((uint)S[(r3 >> 24) & 255]) << 24)) ^ kw[0];
t1 = Mcol((uint)S[r1 & 255] ^ (((uint)S[(r2 >> 8) & 255]) << 8) ^ (((uint)S[(r3 >> 16) & 255]) << 16) ^ (((uint)S[(r0 >> 24) & 255]) << 24)) ^ kw[1];
t2 = Mcol((uint)S[r2 & 255] ^ (((uint)S[(r3 >> 8) & 255]) << 8) ^ (((uint)S[(r0 >> 16) & 255]) << 16) ^ (((uint)S[(r1 >> 24) & 255]) << 24)) ^ kw[2];
r3 = Mcol((uint)S[r3 & 255] ^ (((uint)S[(r0 >> 8) & 255]) << 8) ^ (((uint)S[(r1 >> 16) & 255]) << 16) ^ (((uint)S[(r2 >> 24) & 255]) << 24)) ^ kw[3];
}
kw = KW[r++];
r0 = Mcol((uint)S[t0 & 255] ^ (((uint)S[(t1 >> 8) & 255]) << 8) ^ (((uint)S[(t2 >> 16) & 255]) << 16) ^ (((uint)S[(r3 >> 24) & 255]) << 24)) ^ kw[0];
r1 = Mcol((uint)S[t1 & 255] ^ (((uint)S[(t2 >> 8) & 255]) << 8) ^ (((uint)S[(r3 >> 16) & 255]) << 16) ^ (((uint)S[(t0 >> 24) & 255]) << 24)) ^ kw[1];
r2 = Mcol((uint)S[t2 & 255] ^ (((uint)S[(r3 >> 8) & 255]) << 8) ^ (((uint)S[(t0 >> 16) & 255]) << 16) ^ (((uint)S[(t1 >> 24) & 255]) << 24)) ^ kw[2];
r3 = Mcol((uint)S[r3 & 255] ^ (((uint)S[(t0 >> 8) & 255]) << 8) ^ (((uint)S[(t1 >> 16) & 255]) << 16) ^ (((uint)S[(t2 >> 24) & 255]) << 24)) ^ kw[3];
// the final round is a simple function of S
kw = KW[r];
C0 = (uint)S[r0 & 255] ^ (((uint)S[(r1 >> 8) & 255]) << 8) ^ (((uint)S[(r2 >> 16) & 255]) << 16) ^ (((uint)S[(r3 >> 24) & 255]) << 24) ^ kw[0];
C1 = (uint)S[r1 & 255] ^ (((uint)S[(r2 >> 8) & 255]) << 8) ^ (((uint)S[(r3 >> 16) & 255]) << 16) ^ (((uint)S[(r0 >> 24) & 255]) << 24) ^ kw[1];
C2 = (uint)S[r2 & 255] ^ (((uint)S[(r3 >> 8) & 255]) << 8) ^ (((uint)S[(r0 >> 16) & 255]) << 16) ^ (((uint)S[(r1 >> 24) & 255]) << 24) ^ kw[2];
C3 = (uint)S[r3 & 255] ^ (((uint)S[(r0 >> 8) & 255]) << 8) ^ (((uint)S[(r1 >> 16) & 255]) << 16) ^ (((uint)S[(r2 >> 24) & 255]) << 24) ^ kw[3];
Pack.UInt32_To_LE(C0, output, outOff + 0);
Pack.UInt32_To_LE(C1, output, outOff + 4);
Pack.UInt32_To_LE(C2, output, outOff + 8);
Pack.UInt32_To_LE(C3, output, outOff + 12);
}
private void DecryptBlock(byte[] input, int inOff, byte[] output, int outOff, uint[][] KW)
{
uint C0 = Pack.LE_To_UInt32(input, inOff + 0);
uint C1 = Pack.LE_To_UInt32(input, inOff + 4);
uint C2 = Pack.LE_To_UInt32(input, inOff + 8);
uint C3 = Pack.LE_To_UInt32(input, inOff + 12);
uint[] kw = KW[ROUNDS];
uint t0 = C0 ^ kw[0];
uint t1 = C1 ^ kw[1];
uint t2 = C2 ^ kw[2];
uint r0, r1, r2, r3 = C3 ^ kw[3];
int r = ROUNDS - 1;
while (r > 1)
{
kw = KW[r--];
r0 = Inv_Mcol((uint)Si[t0 & 255] ^ (((uint)Si[(r3 >> 8) & 255]) << 8) ^ (((uint)Si[(t2 >> 16) & 255]) << 16) ^ ((uint)Si[(t1 >> 24) & 255] << 24)) ^ kw[0];
r1 = Inv_Mcol((uint)Si[t1 & 255] ^ (((uint)Si[(t0 >> 8) & 255]) << 8) ^ (((uint)Si[(r3 >> 16) & 255]) << 16) ^ ((uint)Si[(t2 >> 24) & 255] << 24)) ^ kw[1];
r2 = Inv_Mcol((uint)Si[t2 & 255] ^ (((uint)Si[(t1 >> 8) & 255]) << 8) ^ (((uint)Si[(t0 >> 16) & 255]) << 16) ^ ((uint)Si[(r3 >> 24) & 255] << 24)) ^ kw[2];
r3 = Inv_Mcol((uint)Si[r3 & 255] ^ (((uint)Si[(t2 >> 8) & 255]) << 8) ^ (((uint)Si[(t1 >> 16) & 255]) << 16) ^ ((uint)Si[(t0 >> 24) & 255] << 24)) ^ kw[3];
kw = KW[r--];
t0 = Inv_Mcol((uint)Si[r0 & 255] ^ (((uint)Si[(r3 >> 8) & 255]) << 8) ^ (((uint)Si[(r2 >> 16) & 255]) << 16) ^ ((uint)Si[(r1 >> 24) & 255] << 24)) ^ kw[0];
t1 = Inv_Mcol((uint)Si[r1 & 255] ^ (((uint)Si[(r0 >> 8) & 255]) << 8) ^ (((uint)Si[(r3 >> 16) & 255]) << 16) ^ ((uint)Si[(r2 >> 24) & 255] << 24)) ^ kw[1];
t2 = Inv_Mcol((uint)Si[r2 & 255] ^ (((uint)Si[(r1 >> 8) & 255]) << 8) ^ (((uint)Si[(r0 >> 16) & 255]) << 16) ^ ((uint)Si[(r3 >> 24) & 255] << 24)) ^ kw[2];
r3 = Inv_Mcol((uint)Si[r3 & 255] ^ (((uint)Si[(r2 >> 8) & 255]) << 8) ^ (((uint)Si[(r1 >> 16) & 255]) << 16) ^ ((uint)Si[(r0 >> 24) & 255] << 24)) ^ kw[3];
}
kw = KW[1];
r0 = Inv_Mcol((uint)Si[t0 & 255] ^ (((uint)Si[(r3 >> 8) & 255]) << 8) ^ (((uint)Si[(t2 >> 16) & 255]) << 16) ^ ((uint)Si[(t1 >> 24) & 255] << 24)) ^ kw[0];
r1 = Inv_Mcol((uint)Si[t1 & 255] ^ (((uint)Si[(t0 >> 8) & 255]) << 8) ^ (((uint)Si[(r3 >> 16) & 255]) << 16) ^ ((uint)Si[(t2 >> 24) & 255] << 24)) ^ kw[1];
r2 = Inv_Mcol((uint)Si[t2 & 255] ^ (((uint)Si[(t1 >> 8) & 255]) << 8) ^ (((uint)Si[(t0 >> 16) & 255]) << 16) ^ ((uint)Si[(r3 >> 24) & 255] << 24)) ^ kw[2];
r3 = Inv_Mcol((uint)Si[r3 & 255] ^ (((uint)Si[(t2 >> 8) & 255]) << 8) ^ (((uint)Si[(t1 >> 16) & 255]) << 16) ^ ((uint)Si[(t0 >> 24) & 255] << 24)) ^ kw[3];
// the final round's table is a simple function of Si
kw = KW[0];
C0 = (uint)Si[r0 & 255] ^ (((uint)Si[(r3 >> 8) & 255]) << 8) ^ (((uint)Si[(r2 >> 16) & 255]) << 16) ^ (((uint)Si[(r1 >> 24) & 255]) << 24) ^ kw[0];
C1 = (uint)Si[r1 & 255] ^ (((uint)Si[(r0 >> 8) & 255]) << 8) ^ (((uint)Si[(r3 >> 16) & 255]) << 16) ^ (((uint)Si[(r2 >> 24) & 255]) << 24) ^ kw[1];
C2 = (uint)Si[r2 & 255] ^ (((uint)Si[(r1 >> 8) & 255]) << 8) ^ (((uint)Si[(r0 >> 16) & 255]) << 16) ^ (((uint)Si[(r3 >> 24) & 255]) << 24) ^ kw[2];
C3 = (uint)Si[r3 & 255] ^ (((uint)Si[(r2 >> 8) & 255]) << 8) ^ (((uint)Si[(r1 >> 16) & 255]) << 16) ^ (((uint)Si[(r0 >> 24) & 255]) << 24) ^ kw[3];
Pack.UInt32_To_LE(C0, output, outOff + 0);
Pack.UInt32_To_LE(C1, output, outOff + 4);
Pack.UInt32_To_LE(C2, output, outOff + 8);
Pack.UInt32_To_LE(C3, output, outOff + 12);
}
#endif
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 0646f3c6342a62b4e9d9e047072d0a33
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/AesLightEngine.cs
uploadId: 783279

View File

@ -0,0 +1,20 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/// <remarks>
/// An implementation of the AES Key Wrapper from the NIST Key Wrap Specification.
/// <p/>
/// For further details see: <a href="http://csrc.nist.gov/encryption/kms/key-wrap.pdf">http://csrc.nist.gov/encryption/kms/key-wrap.pdf</a>.
/// </remarks>
public class AesWrapEngine
: Rfc3394WrapEngine
{
public AesWrapEngine()
: base(AesUtilities.CreateEngine())
{
}
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: a090d0a62734c9046b5915956873d52e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/AesWrapEngine.cs
uploadId: 783279

View File

@ -0,0 +1,445 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/**
* RFC 5794.
*
* ARIA is a 128-bit block cipher with 128-, 192-, and 256-bit keys.
*/
public class AriaEngine
: IBlockCipher
{
private static readonly byte[][] C = { Hex.DecodeStrict("517cc1b727220a94fe13abe8fa9a6ee0"),
Hex.DecodeStrict("6db14acc9e21c820ff28b1d5ef5de2b0"), Hex.DecodeStrict("db92371d2126e9700324977504e8c90e") };
private static readonly byte[] SB1_sbox = { (byte)0x63, (byte)0x7c, (byte)0x77, (byte)0x7b, (byte)0xf2, (byte)0x6b,
(byte)0x6f, (byte)0xc5, (byte)0x30, (byte)0x01, (byte)0x67, (byte)0x2b, (byte)0xfe, (byte)0xd7, (byte)0xab,
(byte)0x76, (byte)0xca, (byte)0x82, (byte)0xc9, (byte)0x7d, (byte)0xfa, (byte)0x59, (byte)0x47, (byte)0xf0,
(byte)0xad, (byte)0xd4, (byte)0xa2, (byte)0xaf, (byte)0x9c, (byte)0xa4, (byte)0x72, (byte)0xc0, (byte)0xb7,
(byte)0xfd, (byte)0x93, (byte)0x26, (byte)0x36, (byte)0x3f, (byte)0xf7, (byte)0xcc, (byte)0x34, (byte)0xa5,
(byte)0xe5, (byte)0xf1, (byte)0x71, (byte)0xd8, (byte)0x31, (byte)0x15, (byte)0x04, (byte)0xc7, (byte)0x23,
(byte)0xc3, (byte)0x18, (byte)0x96, (byte)0x05, (byte)0x9a, (byte)0x07, (byte)0x12, (byte)0x80, (byte)0xe2,
(byte)0xeb, (byte)0x27, (byte)0xb2, (byte)0x75, (byte)0x09, (byte)0x83, (byte)0x2c, (byte)0x1a, (byte)0x1b,
(byte)0x6e, (byte)0x5a, (byte)0xa0, (byte)0x52, (byte)0x3b, (byte)0xd6, (byte)0xb3, (byte)0x29, (byte)0xe3,
(byte)0x2f, (byte)0x84, (byte)0x53, (byte)0xd1, (byte)0x00, (byte)0xed, (byte)0x20, (byte)0xfc, (byte)0xb1,
(byte)0x5b, (byte)0x6a, (byte)0xcb, (byte)0xbe, (byte)0x39, (byte)0x4a, (byte)0x4c, (byte)0x58, (byte)0xcf,
(byte)0xd0, (byte)0xef, (byte)0xaa, (byte)0xfb, (byte)0x43, (byte)0x4d, (byte)0x33, (byte)0x85, (byte)0x45,
(byte)0xf9, (byte)0x02, (byte)0x7f, (byte)0x50, (byte)0x3c, (byte)0x9f, (byte)0xa8, (byte)0x51, (byte)0xa3,
(byte)0x40, (byte)0x8f, (byte)0x92, (byte)0x9d, (byte)0x38, (byte)0xf5, (byte)0xbc, (byte)0xb6, (byte)0xda,
(byte)0x21, (byte)0x10, (byte)0xff, (byte)0xf3, (byte)0xd2, (byte)0xcd, (byte)0x0c, (byte)0x13, (byte)0xec,
(byte)0x5f, (byte)0x97, (byte)0x44, (byte)0x17, (byte)0xc4, (byte)0xa7, (byte)0x7e, (byte)0x3d, (byte)0x64,
(byte)0x5d, (byte)0x19, (byte)0x73, (byte)0x60, (byte)0x81, (byte)0x4f, (byte)0xdc, (byte)0x22, (byte)0x2a,
(byte)0x90, (byte)0x88, (byte)0x46, (byte)0xee, (byte)0xb8, (byte)0x14, (byte)0xde, (byte)0x5e, (byte)0x0b,
(byte)0xdb, (byte)0xe0, (byte)0x32, (byte)0x3a, (byte)0x0a, (byte)0x49, (byte)0x06, (byte)0x24, (byte)0x5c,
(byte)0xc2, (byte)0xd3, (byte)0xac, (byte)0x62, (byte)0x91, (byte)0x95, (byte)0xe4, (byte)0x79, (byte)0xe7,
(byte)0xc8, (byte)0x37, (byte)0x6d, (byte)0x8d, (byte)0xd5, (byte)0x4e, (byte)0xa9, (byte)0x6c, (byte)0x56,
(byte)0xf4, (byte)0xea, (byte)0x65, (byte)0x7a, (byte)0xae, (byte)0x08, (byte)0xba, (byte)0x78, (byte)0x25,
(byte)0x2e, (byte)0x1c, (byte)0xa6, (byte)0xb4, (byte)0xc6, (byte)0xe8, (byte)0xdd, (byte)0x74, (byte)0x1f,
(byte)0x4b, (byte)0xbd, (byte)0x8b, (byte)0x8a, (byte)0x70, (byte)0x3e, (byte)0xb5, (byte)0x66, (byte)0x48,
(byte)0x03, (byte)0xf6, (byte)0x0e, (byte)0x61, (byte)0x35, (byte)0x57, (byte)0xb9, (byte)0x86, (byte)0xc1,
(byte)0x1d, (byte)0x9e, (byte)0xe1, (byte)0xf8, (byte)0x98, (byte)0x11, (byte)0x69, (byte)0xd9, (byte)0x8e,
(byte)0x94, (byte)0x9b, (byte)0x1e, (byte)0x87, (byte)0xe9, (byte)0xce, (byte)0x55, (byte)0x28, (byte)0xdf,
(byte)0x8c, (byte)0xa1, (byte)0x89, (byte)0x0d, (byte)0xbf, (byte)0xe6, (byte)0x42, (byte)0x68, (byte)0x41,
(byte)0x99, (byte)0x2d, (byte)0x0f, (byte)0xb0, (byte)0x54, (byte)0xbb, (byte)0x16 };
private static readonly byte[] SB2_sbox = { (byte)0xe2, (byte)0x4e, (byte)0x54, (byte)0xfc, (byte)0x94, (byte)0xc2,
(byte)0x4a, (byte)0xcc, (byte)0x62, (byte)0x0d, (byte)0x6a, (byte)0x46, (byte)0x3c, (byte)0x4d, (byte)0x8b,
(byte)0xd1, (byte)0x5e, (byte)0xfa, (byte)0x64, (byte)0xcb, (byte)0xb4, (byte)0x97, (byte)0xbe, (byte)0x2b,
(byte)0xbc, (byte)0x77, (byte)0x2e, (byte)0x03, (byte)0xd3, (byte)0x19, (byte)0x59, (byte)0xc1, (byte)0x1d,
(byte)0x06, (byte)0x41, (byte)0x6b, (byte)0x55, (byte)0xf0, (byte)0x99, (byte)0x69, (byte)0xea, (byte)0x9c,
(byte)0x18, (byte)0xae, (byte)0x63, (byte)0xdf, (byte)0xe7, (byte)0xbb, (byte)0x00, (byte)0x73, (byte)0x66,
(byte)0xfb, (byte)0x96, (byte)0x4c, (byte)0x85, (byte)0xe4, (byte)0x3a, (byte)0x09, (byte)0x45, (byte)0xaa,
(byte)0x0f, (byte)0xee, (byte)0x10, (byte)0xeb, (byte)0x2d, (byte)0x7f, (byte)0xf4, (byte)0x29, (byte)0xac,
(byte)0xcf, (byte)0xad, (byte)0x91, (byte)0x8d, (byte)0x78, (byte)0xc8, (byte)0x95, (byte)0xf9, (byte)0x2f,
(byte)0xce, (byte)0xcd, (byte)0x08, (byte)0x7a, (byte)0x88, (byte)0x38, (byte)0x5c, (byte)0x83, (byte)0x2a,
(byte)0x28, (byte)0x47, (byte)0xdb, (byte)0xb8, (byte)0xc7, (byte)0x93, (byte)0xa4, (byte)0x12, (byte)0x53,
(byte)0xff, (byte)0x87, (byte)0x0e, (byte)0x31, (byte)0x36, (byte)0x21, (byte)0x58, (byte)0x48, (byte)0x01,
(byte)0x8e, (byte)0x37, (byte)0x74, (byte)0x32, (byte)0xca, (byte)0xe9, (byte)0xb1, (byte)0xb7, (byte)0xab,
(byte)0x0c, (byte)0xd7, (byte)0xc4, (byte)0x56, (byte)0x42, (byte)0x26, (byte)0x07, (byte)0x98, (byte)0x60,
(byte)0xd9, (byte)0xb6, (byte)0xb9, (byte)0x11, (byte)0x40, (byte)0xec, (byte)0x20, (byte)0x8c, (byte)0xbd,
(byte)0xa0, (byte)0xc9, (byte)0x84, (byte)0x04, (byte)0x49, (byte)0x23, (byte)0xf1, (byte)0x4f, (byte)0x50,
(byte)0x1f, (byte)0x13, (byte)0xdc, (byte)0xd8, (byte)0xc0, (byte)0x9e, (byte)0x57, (byte)0xe3, (byte)0xc3,
(byte)0x7b, (byte)0x65, (byte)0x3b, (byte)0x02, (byte)0x8f, (byte)0x3e, (byte)0xe8, (byte)0x25, (byte)0x92,
(byte)0xe5, (byte)0x15, (byte)0xdd, (byte)0xfd, (byte)0x17, (byte)0xa9, (byte)0xbf, (byte)0xd4, (byte)0x9a,
(byte)0x7e, (byte)0xc5, (byte)0x39, (byte)0x67, (byte)0xfe, (byte)0x76, (byte)0x9d, (byte)0x43, (byte)0xa7,
(byte)0xe1, (byte)0xd0, (byte)0xf5, (byte)0x68, (byte)0xf2, (byte)0x1b, (byte)0x34, (byte)0x70, (byte)0x05,
(byte)0xa3, (byte)0x8a, (byte)0xd5, (byte)0x79, (byte)0x86, (byte)0xa8, (byte)0x30, (byte)0xc6, (byte)0x51,
(byte)0x4b, (byte)0x1e, (byte)0xa6, (byte)0x27, (byte)0xf6, (byte)0x35, (byte)0xd2, (byte)0x6e, (byte)0x24,
(byte)0x16, (byte)0x82, (byte)0x5f, (byte)0xda, (byte)0xe6, (byte)0x75, (byte)0xa2, (byte)0xef, (byte)0x2c,
(byte)0xb2, (byte)0x1c, (byte)0x9f, (byte)0x5d, (byte)0x6f, (byte)0x80, (byte)0x0a, (byte)0x72, (byte)0x44,
(byte)0x9b, (byte)0x6c, (byte)0x90, (byte)0x0b, (byte)0x5b, (byte)0x33, (byte)0x7d, (byte)0x5a, (byte)0x52,
(byte)0xf3, (byte)0x61, (byte)0xa1, (byte)0xf7, (byte)0xb0, (byte)0xd6, (byte)0x3f, (byte)0x7c, (byte)0x6d,
(byte)0xed, (byte)0x14, (byte)0xe0, (byte)0xa5, (byte)0x3d, (byte)0x22, (byte)0xb3, (byte)0xf8, (byte)0x89,
(byte)0xde, (byte)0x71, (byte)0x1a, (byte)0xaf, (byte)0xba, (byte)0xb5, (byte)0x81 };
private static readonly byte[] SB3_sbox = { (byte)0x52, (byte)0x09, (byte)0x6a, (byte)0xd5, (byte)0x30, (byte)0x36,
(byte)0xa5, (byte)0x38, (byte)0xbf, (byte)0x40, (byte)0xa3, (byte)0x9e, (byte)0x81, (byte)0xf3, (byte)0xd7,
(byte)0xfb, (byte)0x7c, (byte)0xe3, (byte)0x39, (byte)0x82, (byte)0x9b, (byte)0x2f, (byte)0xff, (byte)0x87,
(byte)0x34, (byte)0x8e, (byte)0x43, (byte)0x44, (byte)0xc4, (byte)0xde, (byte)0xe9, (byte)0xcb, (byte)0x54,
(byte)0x7b, (byte)0x94, (byte)0x32, (byte)0xa6, (byte)0xc2, (byte)0x23, (byte)0x3d, (byte)0xee, (byte)0x4c,
(byte)0x95, (byte)0x0b, (byte)0x42, (byte)0xfa, (byte)0xc3, (byte)0x4e, (byte)0x08, (byte)0x2e, (byte)0xa1,
(byte)0x66, (byte)0x28, (byte)0xd9, (byte)0x24, (byte)0xb2, (byte)0x76, (byte)0x5b, (byte)0xa2, (byte)0x49,
(byte)0x6d, (byte)0x8b, (byte)0xd1, (byte)0x25, (byte)0x72, (byte)0xf8, (byte)0xf6, (byte)0x64, (byte)0x86,
(byte)0x68, (byte)0x98, (byte)0x16, (byte)0xd4, (byte)0xa4, (byte)0x5c, (byte)0xcc, (byte)0x5d, (byte)0x65,
(byte)0xb6, (byte)0x92, (byte)0x6c, (byte)0x70, (byte)0x48, (byte)0x50, (byte)0xfd, (byte)0xed, (byte)0xb9,
(byte)0xda, (byte)0x5e, (byte)0x15, (byte)0x46, (byte)0x57, (byte)0xa7, (byte)0x8d, (byte)0x9d, (byte)0x84,
(byte)0x90, (byte)0xd8, (byte)0xab, (byte)0x00, (byte)0x8c, (byte)0xbc, (byte)0xd3, (byte)0x0a, (byte)0xf7,
(byte)0xe4, (byte)0x58, (byte)0x05, (byte)0xb8, (byte)0xb3, (byte)0x45, (byte)0x06, (byte)0xd0, (byte)0x2c,
(byte)0x1e, (byte)0x8f, (byte)0xca, (byte)0x3f, (byte)0x0f, (byte)0x02, (byte)0xc1, (byte)0xaf, (byte)0xbd,
(byte)0x03, (byte)0x01, (byte)0x13, (byte)0x8a, (byte)0x6b, (byte)0x3a, (byte)0x91, (byte)0x11, (byte)0x41,
(byte)0x4f, (byte)0x67, (byte)0xdc, (byte)0xea, (byte)0x97, (byte)0xf2, (byte)0xcf, (byte)0xce, (byte)0xf0,
(byte)0xb4, (byte)0xe6, (byte)0x73, (byte)0x96, (byte)0xac, (byte)0x74, (byte)0x22, (byte)0xe7, (byte)0xad,
(byte)0x35, (byte)0x85, (byte)0xe2, (byte)0xf9, (byte)0x37, (byte)0xe8, (byte)0x1c, (byte)0x75, (byte)0xdf,
(byte)0x6e, (byte)0x47, (byte)0xf1, (byte)0x1a, (byte)0x71, (byte)0x1d, (byte)0x29, (byte)0xc5, (byte)0x89,
(byte)0x6f, (byte)0xb7, (byte)0x62, (byte)0x0e, (byte)0xaa, (byte)0x18, (byte)0xbe, (byte)0x1b, (byte)0xfc,
(byte)0x56, (byte)0x3e, (byte)0x4b, (byte)0xc6, (byte)0xd2, (byte)0x79, (byte)0x20, (byte)0x9a, (byte)0xdb,
(byte)0xc0, (byte)0xfe, (byte)0x78, (byte)0xcd, (byte)0x5a, (byte)0xf4, (byte)0x1f, (byte)0xdd, (byte)0xa8,
(byte)0x33, (byte)0x88, (byte)0x07, (byte)0xc7, (byte)0x31, (byte)0xb1, (byte)0x12, (byte)0x10, (byte)0x59,
(byte)0x27, (byte)0x80, (byte)0xec, (byte)0x5f, (byte)0x60, (byte)0x51, (byte)0x7f, (byte)0xa9, (byte)0x19,
(byte)0xb5, (byte)0x4a, (byte)0x0d, (byte)0x2d, (byte)0xe5, (byte)0x7a, (byte)0x9f, (byte)0x93, (byte)0xc9,
(byte)0x9c, (byte)0xef, (byte)0xa0, (byte)0xe0, (byte)0x3b, (byte)0x4d, (byte)0xae, (byte)0x2a, (byte)0xf5,
(byte)0xb0, (byte)0xc8, (byte)0xeb, (byte)0xbb, (byte)0x3c, (byte)0x83, (byte)0x53, (byte)0x99, (byte)0x61,
(byte)0x17, (byte)0x2b, (byte)0x04, (byte)0x7e, (byte)0xba, (byte)0x77, (byte)0xd6, (byte)0x26, (byte)0xe1,
(byte)0x69, (byte)0x14, (byte)0x63, (byte)0x55, (byte)0x21, (byte)0x0c, (byte)0x7d };
private static readonly byte[] SB4_sbox = { (byte)0x30, (byte)0x68, (byte)0x99, (byte)0x1b, (byte)0x87, (byte)0xb9,
(byte)0x21, (byte)0x78, (byte)0x50, (byte)0x39, (byte)0xdb, (byte)0xe1, (byte)0x72, (byte)0x9, (byte)0x62,
(byte)0x3c, (byte)0x3e, (byte)0x7e, (byte)0x5e, (byte)0x8e, (byte)0xf1, (byte)0xa0, (byte)0xcc, (byte)0xa3,
(byte)0x2a, (byte)0x1d, (byte)0xfb, (byte)0xb6, (byte)0xd6, (byte)0x20, (byte)0xc4, (byte)0x8d, (byte)0x81,
(byte)0x65, (byte)0xf5, (byte)0x89, (byte)0xcb, (byte)0x9d, (byte)0x77, (byte)0xc6, (byte)0x57, (byte)0x43,
(byte)0x56, (byte)0x17, (byte)0xd4, (byte)0x40, (byte)0x1a, (byte)0x4d, (byte)0xc0, (byte)0x63, (byte)0x6c,
(byte)0xe3, (byte)0xb7, (byte)0xc8, (byte)0x64, (byte)0x6a, (byte)0x53, (byte)0xaa, (byte)0x38, (byte)0x98,
(byte)0x0c, (byte)0xf4, (byte)0x9b, (byte)0xed, (byte)0x7f, (byte)0x22, (byte)0x76, (byte)0xaf, (byte)0xdd,
(byte)0x3a, (byte)0x0b, (byte)0x58, (byte)0x67, (byte)0x88, (byte)0x06, (byte)0xc3, (byte)0x35, (byte)0x0d,
(byte)0x01, (byte)0x8b, (byte)0x8c, (byte)0xc2, (byte)0xe6, (byte)0x5f, (byte)0x02, (byte)0x24, (byte)0x75,
(byte)0x93, (byte)0x66, (byte)0x1e, (byte)0xe5, (byte)0xe2, (byte)0x54, (byte)0xd8, (byte)0x10, (byte)0xce,
(byte)0x7a, (byte)0xe8, (byte)0x08, (byte)0x2c, (byte)0x12, (byte)0x97, (byte)0x32, (byte)0xab, (byte)0xb4,
(byte)0x27, (byte)0x0a, (byte)0x23, (byte)0xdf, (byte)0xef, (byte)0xca, (byte)0xd9, (byte)0xb8, (byte)0xfa,
(byte)0xdc, (byte)0x31, (byte)0x6b, (byte)0xd1, (byte)0xad, (byte)0x19, (byte)0x49, (byte)0xbd, (byte)0x51,
(byte)0x96, (byte)0xee, (byte)0xe4, (byte)0xa8, (byte)0x41, (byte)0xda, (byte)0xff, (byte)0xcd, (byte)0x55,
(byte)0x86, (byte)0x36, (byte)0xbe, (byte)0x61, (byte)0x52, (byte)0xf8, (byte)0xbb, (byte)0x0e, (byte)0x82,
(byte)0x48, (byte)0x69, (byte)0x9a, (byte)0xe0, (byte)0x47, (byte)0x9e, (byte)0x5c, (byte)0x04, (byte)0x4b,
(byte)0x34, (byte)0x15, (byte)0x79, (byte)0x26, (byte)0xa7, (byte)0xde, (byte)0x29, (byte)0xae, (byte)0x92,
(byte)0xd7, (byte)0x84, (byte)0xe9, (byte)0xd2, (byte)0xba, (byte)0x5d, (byte)0xf3, (byte)0xc5, (byte)0xb0,
(byte)0xbf, (byte)0xa4, (byte)0x3b, (byte)0x71, (byte)0x44, (byte)0x46, (byte)0x2b, (byte)0xfc, (byte)0xeb,
(byte)0x6f, (byte)0xd5, (byte)0xf6, (byte)0x14, (byte)0xfe, (byte)0x7c, (byte)0x70, (byte)0x5a, (byte)0x7d,
(byte)0xfd, (byte)0x2f, (byte)0x18, (byte)0x83, (byte)0x16, (byte)0xa5, (byte)0x91, (byte)0x1f, (byte)0x05,
(byte)0x95, (byte)0x74, (byte)0xa9, (byte)0xc1, (byte)0x5b, (byte)0x4a, (byte)0x85, (byte)0x6d, (byte)0x13,
(byte)0x07, (byte)0x4f, (byte)0x4e, (byte)0x45, (byte)0xb2, (byte)0x0f, (byte)0xc9, (byte)0x1c, (byte)0xa6,
(byte)0xbc, (byte)0xec, (byte)0x73, (byte)0x90, (byte)0x7b, (byte)0xcf, (byte)0x59, (byte)0x8f, (byte)0xa1,
(byte)0xf9, (byte)0x2d, (byte)0xf2, (byte)0xb1, (byte)0x00, (byte)0x94, (byte)0x37, (byte)0x9f, (byte)0xd0,
(byte)0x2e, (byte)0x9c, (byte)0x6e, (byte)0x28, (byte)0x3f, (byte)0x80, (byte)0xf0, (byte)0x3d, (byte)0xd3,
(byte)0x25, (byte)0x8a, (byte)0xb5, (byte)0xe7, (byte)0x42, (byte)0xb3, (byte)0xc7, (byte)0xea, (byte)0xf7,
(byte)0x4c, (byte)0x11, (byte)0x33, (byte)0x03, (byte)0xa2, (byte)0xac, (byte)0x60 };
protected const int BlockSize = 16;
private byte[][] m_roundKeys;
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
KeyParameter keyParameter = parameters as KeyParameter;
if (keyParameter == null)
throw new ArgumentException("invalid parameter passed to ARIA init - "
+ Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters));
this.m_roundKeys = KeySchedule(forEncryption, keyParameter.GetKey());
}
public virtual string AlgorithmName
{
get { return "ARIA"; }
}
public virtual int GetBlockSize()
{
return BlockSize;
}
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
{
if (m_roundKeys == null)
throw new InvalidOperationException("ARIA engine not initialised");
Check.DataLength(input, inOff, BlockSize, "input buffer too short");
Check.OutputLength(output, outOff, BlockSize, "output buffer too short");
byte[] z = new byte[BlockSize];
Array.Copy(input, inOff, z, 0, BlockSize);
int i = 0, rounds = m_roundKeys.Length - 3;
while (i < rounds)
{
FO(z, m_roundKeys[i++]);
FE(z, m_roundKeys[i++]);
}
FO(z, m_roundKeys[i++]);
Xor(z, m_roundKeys[i++]);
SL2(z);
Xor(z, m_roundKeys[i]);
Array.Copy(z, 0, output, outOff, BlockSize);
return BlockSize;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual int ProcessBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
if (m_roundKeys == null)
throw new InvalidOperationException("ARIA engine not initialised");
Check.DataLength(input, BlockSize, "input buffer too short");
Check.OutputLength(output, BlockSize, "output buffer too short");
byte[] z = new byte[BlockSize];
input[..BlockSize].CopyTo(z);
int i = 0, rounds = m_roundKeys.Length - 3;
while (i < rounds)
{
FO(z, m_roundKeys[i++]);
FE(z, m_roundKeys[i++]);
}
FO(z, m_roundKeys[i++]);
Xor(z, m_roundKeys[i++]);
SL2(z);
Xor(z, m_roundKeys[i]);
z.CopyTo(output);
return BlockSize;
}
#endif
protected static void A(byte[] z)
{
byte x0 = z[0], x1 = z[1], x2 = z[2], x3 = z[3], x4 = z[4], x5 = z[5], x6 = z[6], x7 = z[7], x8 = z[8],
x9 = z[9], x10 = z[10], x11 = z[11], x12 = z[12], x13 = z[13], x14 = z[14], x15 = z[15];
z[0] = (byte)(x3 ^ x4 ^ x6 ^ x8 ^ x9 ^ x13 ^ x14);
z[1] = (byte)(x2 ^ x5 ^ x7 ^ x8 ^ x9 ^ x12 ^ x15);
z[2] = (byte)(x1 ^ x4 ^ x6 ^ x10 ^ x11 ^ x12 ^ x15);
z[3] = (byte)(x0 ^ x5 ^ x7 ^ x10 ^ x11 ^ x13 ^ x14);
z[4] = (byte)(x0 ^ x2 ^ x5 ^ x8 ^ x11 ^ x14 ^ x15);
z[5] = (byte)(x1 ^ x3 ^ x4 ^ x9 ^ x10 ^ x14 ^ x15);
z[6] = (byte)(x0 ^ x2 ^ x7 ^ x9 ^ x10 ^ x12 ^ x13);
z[7] = (byte)(x1 ^ x3 ^ x6 ^ x8 ^ x11 ^ x12 ^ x13);
z[8] = (byte)(x0 ^ x1 ^ x4 ^ x7 ^ x10 ^ x13 ^ x15);
z[9] = (byte)(x0 ^ x1 ^ x5 ^ x6 ^ x11 ^ x12 ^ x14);
z[10] = (byte)(x2 ^ x3 ^ x5 ^ x6 ^ x8 ^ x13 ^ x15);
z[11] = (byte)(x2 ^ x3 ^ x4 ^ x7 ^ x9 ^ x12 ^ x14);
z[12] = (byte)(x1 ^ x2 ^ x6 ^ x7 ^ x9 ^ x11 ^ x12);
z[13] = (byte)(x0 ^ x3 ^ x6 ^ x7 ^ x8 ^ x10 ^ x13);
z[14] = (byte)(x0 ^ x3 ^ x4 ^ x5 ^ x9 ^ x11 ^ x14);
z[15] = (byte)(x1 ^ x2 ^ x4 ^ x5 ^ x8 ^ x10 ^ x15);
}
protected static void FE(byte[] D, byte[] RK)
{
Xor(D, RK);
SL2(D);
A(D);
}
protected static void FO(byte[] D, byte[] RK)
{
Xor(D, RK);
SL1(D);
A(D);
}
protected static byte[][] KeySchedule(bool forEncryption, byte[] K)
{
int keyLen = K.Length;
if (keyLen < 16 || keyLen > 32 || (keyLen & 7) != 0)
throw new ArgumentException("Key length not 128/192/256 bits.");
int keyLenIdx = (keyLen >> 3) - 2;
byte[] CK1 = C[keyLenIdx];
byte[] CK2 = C[(keyLenIdx + 1) % 3];
byte[] CK3 = C[(keyLenIdx + 2) % 3];
byte[] KL = new byte[16], KR = new byte[16];
Array.Copy(K, 0, KL, 0, 16);
Array.Copy(K, 16, KR, 0, keyLen - 16);
byte[] W0 = new byte[16];
byte[] W1 = new byte[16];
byte[] W2 = new byte[16];
byte[] W3 = new byte[16];
Array.Copy(KL, 0, W0, 0, 16);
Array.Copy(W0, 0, W1, 0, 16);
FO(W1, CK1);
Xor(W1, KR);
Array.Copy(W1, 0, W2, 0, 16);
FE(W2, CK2);
Xor(W2, W0);
Array.Copy(W2, 0, W3, 0, 16);
FO(W3, CK3);
Xor(W3, W1);
int numRounds = 12 + (keyLenIdx * 2);
byte[][] rks = new byte[numRounds + 1][];
rks[0] = KeyScheduleRound(W0, W1, 19);
rks[1] = KeyScheduleRound(W1, W2, 19);
rks[2] = KeyScheduleRound(W2, W3, 19);
rks[3] = KeyScheduleRound(W3, W0, 19);
rks[4] = KeyScheduleRound(W0, W1, 31);
rks[5] = KeyScheduleRound(W1, W2, 31);
rks[6] = KeyScheduleRound(W2, W3, 31);
rks[7] = KeyScheduleRound(W3, W0, 31);
rks[8] = KeyScheduleRound(W0, W1, 67);
rks[9] = KeyScheduleRound(W1, W2, 67);
rks[10] = KeyScheduleRound(W2, W3, 67);
rks[11] = KeyScheduleRound(W3, W0, 67);
rks[12] = KeyScheduleRound(W0, W1, 97);
if (numRounds > 12)
{
rks[13] = KeyScheduleRound(W1, W2, 97);
rks[14] = KeyScheduleRound(W2, W3, 97);
if (numRounds > 14)
{
rks[15] = KeyScheduleRound(W3, W0, 97);
rks[16] = KeyScheduleRound(W0, W1, 109);
}
}
if (!forEncryption)
{
ReverseKeys(rks);
for (int i = 1; i < numRounds; ++i)
{
A(rks[i]);
}
}
return rks;
}
protected static byte[] KeyScheduleRound(byte[] w, byte[] wr, int n)
{
byte[] rk = new byte[16];
int off = n >> 3, right = n & 7, left = 8 - right;
int hi = wr[15 - off] & 0xFF;
for (int to = 0; to < 16; ++to)
{
int lo = wr[(to - off) & 0xF] & 0xFF;
int b = (hi << left) | (lo >> right);
b ^= (w[to] & 0xFF);
rk[to] = (byte)b;
hi = lo;
}
return rk;
}
protected static void ReverseKeys(byte[][] keys)
{
int length = keys.Length, limit = length / 2, last = length - 1;
for (int i = 0; i < limit; ++i)
{
byte[] t = keys[i];
keys[i] = keys[last - i];
keys[last - i] = t;
}
}
protected static byte SB1(byte x)
{
return SB1_sbox[x & 0xFF];
}
protected static byte SB2(byte x)
{
return SB2_sbox[x & 0xFF];
}
protected static byte SB3(byte x)
{
return SB3_sbox[x & 0xFF];
}
protected static byte SB4(byte x)
{
return SB4_sbox[x & 0xFF];
}
protected static void SL1(byte[] z)
{
z[0] = SB1(z[0]);
z[1] = SB2(z[1]);
z[2] = SB3(z[2]);
z[3] = SB4(z[3]);
z[4] = SB1(z[4]);
z[5] = SB2(z[5]);
z[6] = SB3(z[6]);
z[7] = SB4(z[7]);
z[8] = SB1(z[8]);
z[9] = SB2(z[9]);
z[10] = SB3(z[10]);
z[11] = SB4(z[11]);
z[12] = SB1(z[12]);
z[13] = SB2(z[13]);
z[14] = SB3(z[14]);
z[15] = SB4(z[15]);
}
protected static void SL2(byte[] z)
{
z[0] = SB3(z[0]);
z[1] = SB4(z[1]);
z[2] = SB1(z[2]);
z[3] = SB2(z[3]);
z[4] = SB3(z[4]);
z[5] = SB4(z[5]);
z[6] = SB1(z[6]);
z[7] = SB2(z[7]);
z[8] = SB3(z[8]);
z[9] = SB4(z[9]);
z[10] = SB1(z[10]);
z[11] = SB2(z[11]);
z[12] = SB3(z[12]);
z[13] = SB4(z[13]);
z[14] = SB1(z[14]);
z[15] = SB2(z[15]);
}
protected static void Xor(byte[] z, byte[] x)
{
for (int i = 0; i < 16; ++i)
{
z[i] ^= x[i];
}
}
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: cc3e3f4d64c125641b940c8844cf06f2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/AriaEngine.cs
uploadId: 783279

View File

@ -0,0 +1,604 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/**
* A class that provides Blowfish key encryption operations,
* such as encoding data and generating keys.
* All the algorithms herein are from Applied Cryptography
* and implement a simplified cryptography interface.
*/
public sealed class BlowfishEngine
: IBlockCipher
{
private readonly static uint[] KP =
{
0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344,
0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89,
0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C,
0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917,
0x9216D5D9, 0x8979FB1B
},
KS0 =
{
0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7,
0xB8E1AFED, 0x6A267E96, 0xBA7C9045, 0xF12C7F99,
0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16,
0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E,
0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE,
0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013,
0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF,
0x8E79DCB0, 0x603A180E, 0x6C9E0E8B, 0xB01E8A3E,
0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60,
0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440,
0x55CA396A, 0x2AAB10B6, 0xB4CC5C34, 0x1141E8CE,
0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A,
0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E,
0xAFD6BA33, 0x6C24CF5C, 0x7A325381, 0x28958677,
0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193,
0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032,
0xEF845D5D, 0xE98575B1, 0xDC262302, 0xEB651B88,
0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239,
0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E,
0x21C66842, 0xF6E96C9A, 0x670C9C61, 0xABD388F0,
0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3,
0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98,
0xA1F1651D, 0x39AF0176, 0x66CA593E, 0x82430E88,
0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE,
0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6,
0x4ED3AA62, 0x363F7706, 0x1BFEDF72, 0x429B023D,
0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B,
0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7,
0xE3FE501A, 0xB6794C3B, 0x976CE0BD, 0x04C006BA,
0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463,
0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F,
0x6DFC511F, 0x9B30952C, 0xCC814544, 0xAF5EBD09,
0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3,
0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB,
0x5579C0BD, 0x1A60320A, 0xD6A100C6, 0x402C7279,
0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8,
0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB,
0x323DB5FA, 0xFD238760, 0x53317B48, 0x3E00DF82,
0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB,
0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573,
0x695B27B0, 0xBBCA58C8, 0xE1FFA35D, 0xB8F011A0,
0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B,
0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790,
0xE1DDF2DA, 0xA4CB7E33, 0x62FB1341, 0xCEE4C6E8,
0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4,
0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0,
0xD08ED1D0, 0xAFC725E0, 0x8E3C5B2F, 0x8E7594B7,
0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C,
0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD,
0x2F2F2218, 0xBE0E1777, 0xEA752DFE, 0x8B021FA1,
0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299,
0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9,
0x165FA266, 0x80957705, 0x93CC7314, 0x211A1477,
0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF,
0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49,
0x00250E2D, 0x2071B35E, 0x226800BB, 0x57B8E0AF,
0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA,
0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5,
0x83260376, 0x6295CFA9, 0x11C81968, 0x4E734A41,
0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915,
0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400,
0x08BA6FB5, 0x571BE91F, 0xF296EC6B, 0x2A0DD915,
0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664,
0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A
},
KS1 =
{
0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623,
0xAD6EA6B0, 0x49A7DF7D, 0x9CEE60B8, 0x8FEDB266,
0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1,
0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E,
0x3F54989A, 0x5B429D65, 0x6B8FE4D6, 0x99F73FD6,
0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1,
0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E,
0x09686B3F, 0x3EBAEFC9, 0x3C971814, 0x6B6A70A1,
0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737,
0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8,
0xB03ADA37, 0xF0500C0D, 0xF01C1F04, 0x0200B3FF,
0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD,
0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701,
0x3AE5E581, 0x37C2DADC, 0xC8B57634, 0x9AF3DDA7,
0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41,
0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331,
0x4E548B38, 0x4F6DB908, 0x6F420D03, 0xF60A04BF,
0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF,
0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E,
0x5512721F, 0x2E6B7124, 0x501ADDE6, 0x9F84CD87,
0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C,
0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2,
0xEF1C1847, 0x3215D908, 0xDD433B37, 0x24C2BA16,
0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD,
0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B,
0x043556F1, 0xD7A3C76B, 0x3C11183B, 0x5924A509,
0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E,
0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3,
0x771FE71C, 0x4E3D06FA, 0x2965DCB9, 0x99E71D0F,
0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A,
0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4,
0xF2F74EA7, 0x361D2B3D, 0x1939260F, 0x19C27960,
0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66,
0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28,
0xC332DDEF, 0xBE6C5AA5, 0x65582185, 0x68AB9802,
0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84,
0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510,
0x13CCA830, 0xEB61BD96, 0x0334FE1E, 0xAA0363CF,
0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14,
0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E,
0x648B1EAF, 0x19BDF0CA, 0xA02369B9, 0x655ABB50,
0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7,
0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8,
0xF837889A, 0x97E32D77, 0x11ED935F, 0x16681281,
0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99,
0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696,
0xCDB30AEB, 0x532E3054, 0x8FD948E4, 0x6DBC3128,
0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73,
0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0,
0x45EEE2B6, 0xA3AAABEA, 0xDB6C4F15, 0xFACB4FD0,
0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105,
0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250,
0xCF62A1F2, 0x5B8D2646, 0xFC8883A0, 0xC1C7B6A3,
0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285,
0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00,
0x58428D2A, 0x0C55F5EA, 0x1DADF43E, 0x233F7061,
0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB,
0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E,
0xA6078084, 0x19F8509E, 0xE8EFD855, 0x61D99735,
0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC,
0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9,
0xDB73DBD3, 0x105588CD, 0x675FDA79, 0xE3674340,
0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20,
0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7
},
KS2 =
{
0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934,
0x411520F7, 0x7602D4F7, 0xBCF46B2E, 0xD4A20068,
0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF,
0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840,
0x4D95FC1D, 0x96B591AF, 0x70F4DDD3, 0x66A02F45,
0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504,
0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A,
0x28507825, 0x530429F4, 0x0A2C86DA, 0xE9B66DFB,
0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE,
0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6,
0xAACE1E7C, 0xD3375FEC, 0xCE78A399, 0x406B2A42,
0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B,
0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2,
0x3A6EFA74, 0xDD5B4332, 0x6841E7F7, 0xCA7820FB,
0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527,
0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B,
0x55A867BC, 0xA1159A58, 0xCCA92963, 0x99E1DB33,
0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C,
0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3,
0x95C11548, 0xE4C66D22, 0x48C1133F, 0xC70F86DC,
0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17,
0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564,
0x257B7834, 0x602A9C60, 0xDFF8E8A3, 0x1F636C1B,
0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115,
0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922,
0x85B2A20E, 0xE6BA0D99, 0xDE720C8C, 0x2DA2F728,
0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0,
0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E,
0x0A476341, 0x992EFF74, 0x3A6F6EAB, 0xF4F8FD37,
0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D,
0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804,
0xF1290DC7, 0xCC00FFA3, 0xB5390F92, 0x690FED0B,
0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3,
0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB,
0x37392EB3, 0xCC115979, 0x8026E297, 0xF42E312D,
0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C,
0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350,
0x1A6B1018, 0x11CAEDFA, 0x3D25BDD8, 0xE2E1C3C9,
0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A,
0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE,
0x9DBC8057, 0xF0F7C086, 0x60787BF8, 0x6003604D,
0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC,
0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F,
0x77A057BE, 0xBDE8AE24, 0x55464299, 0xBF582E61,
0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2,
0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9,
0x7AEB2661, 0x8B1DDF84, 0x846A0E79, 0x915F95E2,
0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C,
0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E,
0xB77F19B6, 0xE0A9DC09, 0x662D09A1, 0xC4324633,
0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10,
0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169,
0xDCB7DA83, 0x573906FE, 0xA1E2CE9B, 0x4FCD7F52,
0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027,
0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5,
0xF0177A28, 0xC0F586E0, 0x006058AA, 0x30DC7D62,
0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634,
0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76,
0x6F05E409, 0x4B7C0188, 0x39720A3D, 0x7C927C24,
0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC,
0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4,
0x1E50EF5E, 0xB161E6F8, 0xA28514D9, 0x6C51133C,
0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837,
0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0
},
KS3 =
{
0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B,
0x5CB0679E, 0x4FA33742, 0xD3822740, 0x99BC9BBE,
0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B,
0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4,
0x5748AB2F, 0xBC946E79, 0xC6A376D2, 0x6549C2C8,
0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6,
0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304,
0xA1FAD5F0, 0x6A2D519A, 0x63EF8CE2, 0x9A86EE22,
0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4,
0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6,
0x2826A2F9, 0xA73A3AE1, 0x4BA99586, 0xEF5562E9,
0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59,
0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593,
0xE990FD5A, 0x9E34D797, 0x2CF0B7D9, 0x022B8B51,
0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28,
0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C,
0xE029AC71, 0xE019A5E6, 0x47B0ACFD, 0xED93FA9B,
0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28,
0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C,
0x15056DD4, 0x88F46DBA, 0x03A16125, 0x0564F0BD,
0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A,
0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319,
0x7533D928, 0xB155FDF5, 0x03563482, 0x8ABA3CBB,
0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F,
0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991,
0xEA7A90C2, 0xFB3E7BCE, 0x5121CE64, 0x774FBE32,
0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680,
0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166,
0xB39A460A, 0x6445C0DD, 0x586CDECF, 0x1C20C8AE,
0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB,
0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5,
0x72EACEA8, 0xFA6484BB, 0x8D6612AE, 0xBF3C6F47,
0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370,
0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D,
0x4040CB08, 0x4EB4E2CC, 0x34D2466A, 0x0115AF84,
0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048,
0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8,
0x611560B1, 0xE7933FDC, 0xBB3A792B, 0x344525BD,
0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9,
0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7,
0x1A908749, 0xD44FBD9A, 0xD0DADECB, 0xD50ADA38,
0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F,
0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C,
0xBF97222C, 0x15E6FC2A, 0x0F91FC71, 0x9B941525,
0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1,
0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442,
0xE0EC6E0E, 0x1698DB3B, 0x4C98A0BE, 0x3278E964,
0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E,
0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8,
0xDF359F8D, 0x9B992F2E, 0xE60B6F47, 0x0FE3F11D,
0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F,
0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299,
0xF523F357, 0xA6327623, 0x93A83531, 0x56CCCD02,
0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC,
0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614,
0xE6C6C7BD, 0x327A140A, 0x45E1D006, 0xC3F27B9A,
0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6,
0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B,
0x53113EC0, 0x1640E3D3, 0x38ABBD60, 0x2547ADF0,
0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060,
0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E,
0x1948C25C, 0x02FB8A8C, 0x01C36AE4, 0xD6EBE1F9,
0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F,
0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6
};
//====================================
// Useful constants
//====================================
private static readonly int ROUNDS = 16;
private const int BLOCK_SIZE = 8; // bytes = 64 bits
private static readonly int SBOX_SK = 256;
private static readonly int P_SZ = ROUNDS+2;
private readonly uint[] S0, S1, S2, S3; // the s-boxes
private readonly uint[] P; // the p-array
private bool encrypting;
private byte[] workingKey;
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];
}
/**
* initialise a Blowfish cipher.
*
* @param forEncryption whether or not we are for encryption.
* @param parameters the parameters required to set up the cipher.
* @exception ArgumentException if the parameters argument is
* inappropriate.
*/
public void Init(
bool forEncryption,
ICipherParameters parameters)
{
if (!(parameters is KeyParameter))
throw new ArgumentException("invalid parameter passed to Blowfish init - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters));
this.encrypting = forEncryption;
this.workingKey = ((KeyParameter)parameters).GetKey();
SetKey(this.workingKey);
}
public string AlgorithmName
{
get { return "Blowfish"; }
}
public int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
{
if (workingKey == null)
throw new InvalidOperationException("Blowfish not initialised");
Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short");
Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short");
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
if (encrypting)
{
EncryptBlock(input.AsSpan(inOff), output.AsSpan(outOff));
}
else
{
DecryptBlock(input.AsSpan(inOff), output.AsSpan(outOff));
}
#else
if (encrypting)
{
EncryptBlock(input, inOff, output, outOff);
}
else
{
DecryptBlock(input, inOff, output, outOff);
}
#endif
return BLOCK_SIZE;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public int ProcessBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
if (workingKey == null)
throw new InvalidOperationException("Blowfish not initialised");
Check.DataLength(input, BLOCK_SIZE, "input buffer too short");
Check.OutputLength(output, BLOCK_SIZE, "output buffer too short");
if (encrypting)
{
EncryptBlock(input, output);
}
else
{
DecryptBlock(input, output);
}
return BLOCK_SIZE;
}
#endif
public int GetBlockSize()
{
return BLOCK_SIZE;
}
//==================================
// Private Implementation
//==================================
private uint F(uint x)
{
return (((S0[x >> 24] + S1[(x >> 16) & 0xff]) ^ S2[(x >> 8) & 0xff]) + S3[x & 0xff]);
}
/**
* apply the encryption cycle to each value pair in the table.
*/
private void ProcessTable(
uint xl,
uint xr,
uint[] table)
{
int size = table.Length;
for (int s = 0; s < size; s += 2)
{
xl ^= P[0];
for (int i = 1; i < ROUNDS; i += 2)
{
xr ^= F(xl) ^ P[i];
xl ^= F(xr) ^ P[i + 1];
}
xr ^= P[ROUNDS + 1];
table[s] = xr;
table[s + 1] = xl;
xr = xl; // end of cycle swap
xl = table[s];
}
}
private void SetKey(byte[] key)
{
if (key.Length < 4 || key.Length > 56)
{
throw new ArgumentException("key length must be in range 32 to 448 bits");
}
/*
* - comments are from _Applied Crypto_, Schneier, p338
* please be careful comparing the two, AC numbers the
* arrays from 1, the enclosed code from 0.
*
* (1)
* Initialise the S-boxes and the P-array, with a fixed string
* This string contains the hexadecimal digits of pi (3.141...)
*/
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);
/*
* (2)
* Now, XOR P[0] with the first 32 bits of the key, XOR P[1] with the
* second 32-bits of the key, and so on for all bits of the key
* (up to P[17]). Repeatedly cycle through the key bits until the
* entire P-array has been XOR-ed with the key bits
*/
int keyLength = key.Length;
int keyIndex = 0;
for (int i=0; i < P_SZ; i++)
{
// Get the 32 bits of the key, in 4 * 8 bit chunks
uint data = 0x0000000;
for (int j=0; j < 4; j++)
{
// create a 32 bit block
data = (data << 8) | (uint)key[keyIndex++];
// wrap when we get to the end of the key
if (keyIndex >= keyLength)
{
keyIndex = 0;
}
}
// XOR the newly created 32 bit chunk onto the P-array
P[i] ^= data;
}
/*
* (3)
* Encrypt the all-zero string with the Blowfish algorithm, using
* the subkeys described in (1) and (2)
*
* (4)
* Replace P1 and P2 with the output of step (3)
*
* (5)
* Encrypt the output of step(3) using the Blowfish algorithm,
* with the modified subkeys.
*
* (6)
* Replace P3 and P4 with the output of step (5)
*
* (7)
* Continue the process, replacing all elements of the P-array
* and then all four S-boxes in order, with the output of the
* continuously changing Blowfish algorithm
*/
ProcessTable(0, 0, 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);
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
private void EncryptBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
uint xl = Pack.BE_To_UInt32(input);
uint xr = Pack.BE_To_UInt32(input[4..]);
xl ^= P[0];
for (int i = 1; i < ROUNDS; i += 2)
{
xr ^= F(xl) ^ P[i];
xl ^= F(xr) ^ P[i + 1];
}
xr ^= P[ROUNDS + 1];
Pack.UInt32_To_BE(xr, output);
Pack.UInt32_To_BE(xl, output[4..]);
}
private void DecryptBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
uint xl = Pack.BE_To_UInt32(input);
uint xr = Pack.BE_To_UInt32(input[4..]);
xl ^= P[ROUNDS + 1];
for (int i = ROUNDS; i > 0; i -= 2)
{
xr ^= F(xl) ^ P[i];
xl ^= F(xr) ^ P[i - 1];
}
xr ^= P[0];
Pack.UInt32_To_BE(xr, output);
Pack.UInt32_To_BE(xl, output[4..]);
}
#else
private void EncryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex)
{
uint xl = Pack.BE_To_UInt32(src, srcIndex);
uint xr = Pack.BE_To_UInt32(src, srcIndex+4);
xl ^= P[0];
for (int i = 1; i < ROUNDS; i += 2)
{
xr ^= F(xl) ^ P[i];
xl ^= F(xr) ^ P[i + 1];
}
xr ^= P[ROUNDS + 1];
Pack.UInt32_To_BE(xr, dst, dstIndex);
Pack.UInt32_To_BE(xl, dst, dstIndex + 4);
}
private void DecryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex)
{
uint xl = Pack.BE_To_UInt32(src, srcIndex);
uint xr = Pack.BE_To_UInt32(src, srcIndex + 4);
xl ^= P[ROUNDS + 1];
for (int i = ROUNDS; i > 0 ; i -= 2)
{
xr ^= F(xl) ^ P[i];
xl ^= F(xr) ^ P[i - 1];
}
xr ^= P[0];
Pack.UInt32_To_BE(xr, dst, dstIndex);
Pack.UInt32_To_BE(xl, dst, dstIndex + 4);
}
#endif
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: f08145dcbc1db324da79674306bd2b7f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/BlowfishEngine.cs
uploadId: 783279

View File

@ -0,0 +1,714 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/**
* Camellia - based on RFC 3713.
*/
public class CamelliaEngine
: IBlockCipher
{
private bool initialised = false;
private bool _keyIs128;
private const int BLOCK_SIZE = 16;
private uint[] subkey = new uint[24 * 4];
private uint[] kw = new uint[4 * 2]; // for whitening
private uint[] ke = new uint[6 * 2]; // for FL and FL^(-1)
private static readonly uint[] SIGMA = new uint[]{
0xa09e667f, 0x3bcc908b,
0xb67ae858, 0x4caa73b2,
0xc6ef372f, 0xe94f82be,
0x54ff53a5, 0xf1d36f1c,
0x10e527fa, 0xde682d1d,
0xb05688c2, 0xb3e6c1fd
};
/*
*
* S-box data
*
*/
private static readonly uint[] SBOX1_1110 = new uint[]{
0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00, 0xb3b3b300, 0x27272700,
0xc0c0c000, 0xe5e5e500, 0xe4e4e400, 0x85858500, 0x57575700, 0x35353500,
0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100, 0x23232300, 0xefefef00,
0x6b6b6b00, 0x93939300, 0x45454500, 0x19191900, 0xa5a5a500, 0x21212100,
0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00, 0x1d1d1d00, 0x65656500,
0x92929200, 0xbdbdbd00, 0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00,
0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00, 0x3e3e3e00, 0x30303000,
0xdcdcdc00, 0x5f5f5f00, 0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00,
0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00, 0xd5d5d500, 0x47474700,
0x5d5d5d00, 0x3d3d3d00, 0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600,
0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00, 0x8b8b8b00, 0x0d0d0d00,
0x9a9a9a00, 0x66666600, 0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00,
0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000, 0xf0f0f000, 0xb1b1b100,
0x84848400, 0x99999900, 0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200,
0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500, 0x6d6d6d00, 0xb7b7b700,
0xa9a9a900, 0x31313100, 0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700,
0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100, 0xdedede00, 0x1b1b1b00,
0x11111100, 0x1c1c1c00, 0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600,
0x53535300, 0x18181800, 0xf2f2f200, 0x22222200, 0xfefefe00, 0x44444400,
0xcfcfcf00, 0xb2b2b200, 0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100,
0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800, 0x60606000, 0xfcfcfc00,
0x69696900, 0x50505000, 0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00,
0xa1a1a100, 0x89898900, 0x62626200, 0x97979700, 0x54545400, 0x5b5b5b00,
0x1e1e1e00, 0x95959500, 0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200,
0x10101000, 0xc4c4c400, 0x00000000, 0x48484800, 0xa3a3a300, 0xf7f7f700,
0x75757500, 0xdbdbdb00, 0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00,
0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400, 0x87878700, 0x5c5c5c00,
0x83838300, 0x02020200, 0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300,
0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300, 0x9d9d9d00, 0x7f7f7f00,
0xbfbfbf00, 0xe2e2e200, 0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600,
0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00, 0x81818100, 0x96969600,
0x6f6f6f00, 0x4b4b4b00, 0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00,
0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00, 0x9f9f9f00, 0x6e6e6e00,
0xbcbcbc00, 0x8e8e8e00, 0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600,
0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900, 0x78787800, 0x98989800,
0x06060600, 0x6a6a6a00, 0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00,
0xd4d4d400, 0x25252500, 0xababab00, 0x42424200, 0x88888800, 0xa2a2a200,
0x8d8d8d00, 0xfafafa00, 0x72727200, 0x07070700, 0xb9b9b900, 0x55555500,
0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00, 0x36363600, 0x49494900,
0x2a2a2a00, 0x68686800, 0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400,
0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00, 0xbbbbbb00, 0xc9c9c900,
0x43434300, 0xc1c1c100, 0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400,
0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00
};
private static readonly uint[] SBOX4_4404 = new uint[]{
0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0, 0xe4e400e4, 0x57570057,
0xeaea00ea, 0xaeae00ae, 0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5,
0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092, 0x86860086, 0xafaf00af,
0x7c7c007c, 0x1f1f001f, 0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b,
0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d, 0xd9d900d9, 0x5a5a005a,
0x51510051, 0x6c6c006c, 0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0,
0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084, 0xdfdf00df, 0xcbcb00cb,
0x34340034, 0x76760076, 0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004,
0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011, 0x32320032, 0x9c9c009c,
0x53530053, 0xf2f200f2, 0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a,
0x24240024, 0xe8e800e8, 0x60600060, 0x69690069, 0xaaaa00aa, 0xa0a000a0,
0xa1a100a1, 0x62620062, 0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064,
0x10100010, 0x00000000, 0xa3a300a3, 0x75750075, 0x8a8a008a, 0xe6e600e6,
0x09090009, 0xdddd00dd, 0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090,
0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf, 0x52520052, 0xd8d800d8,
0xc8c800c8, 0xc6c600c6, 0x81810081, 0x6f6f006f, 0x13130013, 0x63630063,
0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc, 0x29290029, 0xf9f900f9,
0x2f2f002f, 0xb4b400b4, 0x78780078, 0x06060006, 0xe7e700e7, 0x71710071,
0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d, 0x72720072, 0xb9b900b9,
0xf8f800f8, 0xacac00ac, 0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1,
0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043, 0x15150015, 0xadad00ad,
0x77770077, 0x80800080, 0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5,
0x85850085, 0x35350035, 0x0c0c000c, 0x41410041, 0xefef00ef, 0x93930093,
0x19190019, 0x21210021, 0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd,
0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce, 0x30300030, 0x5f5f005f,
0xc5c500c5, 0x1a1a001a, 0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d,
0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d, 0x0d0d000d, 0x66660066,
0xcccc00cc, 0x2d2d002d, 0x12120012, 0x20200020, 0xb1b100b1, 0x99990099,
0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005, 0xb7b700b7, 0x31310031,
0x17170017, 0xd7d700d7, 0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c,
0x0f0f000f, 0x16160016, 0x18180018, 0x22220022, 0x44440044, 0xb2b200b2,
0xb5b500b5, 0x91910091, 0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050,
0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097, 0x5b5b005b, 0x95950095,
0xffff00ff, 0xd2d200d2, 0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db,
0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094, 0x5c5c005c, 0x02020002,
0x4a4a004a, 0x33330033, 0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2,
0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b, 0x96960096, 0x4b4b004b,
0xbebe00be, 0x2e2e002e, 0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e,
0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059, 0x98980098, 0x6a6a006a,
0x46460046, 0xbaba00ba, 0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa,
0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a, 0x49490049, 0x68680068,
0x38380038, 0xa4a400a4, 0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1,
0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e
};
private static readonly uint[] SBOX2_0222 = new uint[]{
0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9, 0x00676767, 0x004e4e4e,
0x00818181, 0x00cbcbcb, 0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a,
0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282, 0x00464646, 0x00dfdfdf,
0x00d6d6d6, 0x00272727, 0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242,
0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c, 0x003a3a3a, 0x00cacaca,
0x00252525, 0x007b7b7b, 0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f,
0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d, 0x007c7c7c, 0x00606060,
0x00b9b9b9, 0x00bebebe, 0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434,
0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595, 0x00ababab, 0x008e8e8e,
0x00bababa, 0x007a7a7a, 0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad,
0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a, 0x00171717, 0x001a1a1a,
0x00353535, 0x00cccccc, 0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a,
0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040, 0x00e1e1e1, 0x00636363,
0x00090909, 0x00333333, 0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585,
0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a, 0x00dadada, 0x006f6f6f,
0x00535353, 0x00626262, 0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf,
0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2, 0x00bdbdbd, 0x00363636,
0x00222222, 0x00383838, 0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c,
0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444, 0x00fdfdfd, 0x00888888,
0x009f9f9f, 0x00656565, 0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323,
0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151, 0x00c0c0c0, 0x00f9f9f9,
0x00d2d2d2, 0x00a0a0a0, 0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa,
0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f, 0x00a8a8a8, 0x00b6b6b6,
0x003c3c3c, 0x002b2b2b, 0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5,
0x00202020, 0x00898989, 0x00000000, 0x00909090, 0x00474747, 0x00efefef,
0x00eaeaea, 0x00b7b7b7, 0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5,
0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929, 0x000f0f0f, 0x00b8b8b8,
0x00070707, 0x00040404, 0x009b9b9b, 0x00949494, 0x00212121, 0x00666666,
0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7, 0x003b3b3b, 0x00fefefe,
0x007f7f7f, 0x00c5c5c5, 0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c,
0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676, 0x00030303, 0x002d2d2d,
0x00dedede, 0x00969696, 0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c,
0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919, 0x003f3f3f, 0x00dcdcdc,
0x00797979, 0x001d1d1d, 0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d,
0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2, 0x00f0f0f0, 0x00313131,
0x000c0c0c, 0x00d4d4d4, 0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575,
0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484, 0x00111111, 0x00454545,
0x001b1b1b, 0x00f5f5f5, 0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa,
0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414, 0x006c6c6c, 0x00929292,
0x00545454, 0x00d0d0d0, 0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949,
0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6, 0x00777777, 0x00939393,
0x00868686, 0x00838383, 0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9,
0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d
};
private static readonly uint[] SBOX3_3033 = new uint[]{
0x38003838, 0x41004141, 0x16001616, 0x76007676, 0xd900d9d9, 0x93009393,
0x60006060, 0xf200f2f2, 0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a,
0x75007575, 0x06000606, 0x57005757, 0xa000a0a0, 0x91009191, 0xf700f7f7,
0xb500b5b5, 0xc900c9c9, 0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090,
0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727, 0x8e008e8e, 0xb200b2b2,
0x49004949, 0xde00dede, 0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7,
0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767, 0x1f001f1f, 0x18001818,
0x6e006e6e, 0xaf00afaf, 0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d,
0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565, 0xea00eaea, 0xa300a3a3,
0xae00aeae, 0x9e009e9e, 0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b,
0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6, 0xc500c5c5, 0x86008686,
0x4d004d4d, 0x33003333, 0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696,
0x3a003a3a, 0x09000909, 0x95009595, 0x10001010, 0x78007878, 0xd800d8d8,
0x42004242, 0xcc00cccc, 0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161,
0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282, 0xb600b6b6, 0xdb00dbdb,
0xd400d4d4, 0x98009898, 0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb,
0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0, 0x6f006f6f, 0x8d008d8d,
0x88008888, 0x0e000e0e, 0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b,
0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111, 0x7f007f7f, 0x22002222,
0xe700e7e7, 0x59005959, 0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8,
0x12001212, 0x04000404, 0x74007474, 0x54005454, 0x30003030, 0x7e007e7e,
0xb400b4b4, 0x28002828, 0x55005555, 0x68006868, 0x50005050, 0xbe00bebe,
0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb, 0x2a002a2a, 0xad00adad,
0x0f000f0f, 0xca00caca, 0x70007070, 0xff00ffff, 0x32003232, 0x69006969,
0x08000808, 0x62006262, 0x00000000, 0x24002424, 0xd100d1d1, 0xfb00fbfb,
0xba00baba, 0xed00eded, 0x45004545, 0x81008181, 0x73007373, 0x6d006d6d,
0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a, 0xc300c3c3, 0x2e002e2e,
0xc100c1c1, 0x01000101, 0xe600e6e6, 0x25002525, 0x48004848, 0x99009999,
0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9, 0xce00cece, 0xbf00bfbf,
0xdf00dfdf, 0x71007171, 0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313,
0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d, 0xc000c0c0, 0x4b004b4b,
0xb700b7b7, 0xa500a5a5, 0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717,
0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646, 0xcf00cfcf, 0x37003737,
0x5e005e5e, 0x47004747, 0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b,
0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac, 0x3c003c3c, 0x4c004c4c,
0x03000303, 0x35003535, 0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d,
0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121, 0x44004444, 0x51005151,
0xc600c6c6, 0x7d007d7d, 0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa,
0x7c007c7c, 0x77007777, 0x56005656, 0x05000505, 0x1b001b1b, 0xa400a4a4,
0x15001515, 0x34003434, 0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252,
0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd, 0xdd00dddd, 0xe400e4e4,
0xa100a1a1, 0xe000e0e0, 0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a,
0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f
};
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[0 + ooff] = (ki[0 + 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[0 + ioff] >> (32 - rot));
ki[0 + ioff] = ko[0 + 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[0 + ioff] << rot) | (ki[1 + ioff] >> (32 - rot));
ko[3 + ooff] = (ki[1 + ioff] << rot) | (ki[2 + ioff] >> (32 - rot));
ko[0 + ooff] = (ki[2 + ioff] << rot) | (ki[3 + ioff] >> (32 - rot));
ko[1 + ooff] = (ki[3 + ioff] << rot) | (ki[0 + ioff] >> (32 - rot));
ki[0 + ioff] = ko[2 + ooff];
ki[1 + ioff] = ko[3 + ooff];
ki[2 + ioff] = ko[0 + ooff];
ki[3 + ioff] = ko[1 + ooff];
}
private static void roldqo32(int rot, uint[] ki, int ioff, uint[] ko, int ooff)
{
ko[0 + 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[0 + ioff] >> (64 - rot));
ko[3 + ooff] = (ki[0 + ioff] << (rot - 32)) | (ki[1 + ioff] >> (64 - rot));
ki[0 + ioff] = ko[0 + 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[0 + ooff] = (ki[3 + ioff] << (rot - 32)) | (ki[0 + ioff] >> (64 - rot));
ko[1 + ooff] = (ki[0 + ioff] << (rot - 32)) | (ki[1 + ioff] >> (64 - rot));
ki[0 + ioff] = ko[2 + ooff];
ki[1 + ioff] = ko[3 + ooff];
ki[2 + ioff] = ko[0 + ooff];
ki[3 + ioff] = ko[1 + ooff];
}
private static void camelliaF2(uint[] s, uint[] skey, int keyoff)
{
uint t1, t2, u, v;
t1 = s[0] ^ skey[0 + keyoff];
u = SBOX4_4404[(byte)t1];
u ^= SBOX3_3033[(byte)(t1 >> 8)];
u ^= SBOX2_0222[(byte)(t1 >> 16)];
u ^= SBOX1_1110[(byte)(t1 >> 24)];
t2 = s[1] ^ skey[1 + keyoff];
v = SBOX1_1110[(byte)t2];
v ^= SBOX4_4404[(byte)(t2 >> 8)];
v ^= SBOX3_3033[(byte)(t2 >> 16)];
v ^= SBOX2_0222[(byte)(t2 >> 24)];
s[2] ^= u ^ v;
s[3] ^= u ^ v ^ rightRotate(u, 8);
t1 = s[2] ^ skey[2 + keyoff];
u = SBOX4_4404[(byte)t1];
u ^= SBOX3_3033[(byte)(t1 >> 8)];
u ^= SBOX2_0222[(byte)(t1 >> 16)];
u ^= SBOX1_1110[(byte)(t1 >> 24)];
t2 = s[3] ^ skey[3 + keyoff];
v = SBOX1_1110[(byte)t2];
v ^= SBOX4_4404[(byte)(t2 >> 8)];
v ^= SBOX3_3033[(byte)(t2 >> 16)];
v ^= SBOX2_0222[(byte)(t2 >> 24)];
s[0] ^= u ^ v;
s[1] ^= u ^ v ^ rightRotate(u, 8);
}
private static void camelliaFLs(uint[] s, uint[] fkey, int keyoff)
{
s[1] ^= leftRotate(s[0] & fkey[0 + keyoff], 1);
s[0] ^= fkey[1 + keyoff] | s[1];
s[2] ^= fkey[3 + keyoff] | s[3];
s[3] ^= leftRotate(fkey[2 + keyoff] & s[2], 1);
}
private void setKey(bool forEncryption, byte[] key)
{
uint[] k = new uint[8];
uint[] ka = new uint[4];
uint[] kb = new uint[4];
uint[] t = new uint[4];
switch (key.Length)
{
case 16:
_keyIs128 = true;
Pack.BE_To_UInt32(key, 0, k, 0, 4);
k[4] = k[5] = k[6] = k[7] = 0;
break;
case 24:
Pack.BE_To_UInt32(key, 0, k, 0, 6);
k[6] = ~k[4];
k[7] = ~k[5];
_keyIs128 = false;
break;
case 32:
Pack.BE_To_UInt32(key, 0, k, 0, 8);
_keyIs128 = false;
break;
default:
throw new ArgumentException("key sizes are only 16/24/32 bytes.");
}
for (int i = 0; i < 4; i++)
{
ka[i] = k[i] ^ k[i + 4];
}
/* compute KA */
camelliaF2(ka, SIGMA, 0);
for (int i = 0; i < 4; i++)
{
ka[i] ^= k[i];
}
camelliaF2(ka, SIGMA, 4);
if (_keyIs128)
{
if (forEncryption)
{
/* KL dependant keys */
kw[0] = k[0];
kw[1] = k[1];
kw[2] = k[2];
kw[3] = k[3];
roldq(15, k, 0, subkey, 4);
roldq(30, k, 0, subkey, 12);
roldq(15, k, 0, t, 0);
subkey[18] = t[2];
subkey[19] = t[3];
roldq(17, k, 0, ke, 4);
roldq(17, k, 0, subkey, 24);
roldq(17, k, 0, subkey, 32);
/* KA dependant keys */
subkey[0] = ka[0];
subkey[1] = ka[1];
subkey[2] = ka[2];
subkey[3] = ka[3];
roldq(15, ka, 0, subkey, 8);
roldq(15, ka, 0, ke, 0);
roldq(15, ka, 0, t, 0);
subkey[16] = t[0];
subkey[17] = t[1];
roldq(15, ka, 0, subkey, 20);
roldqo32(34, ka, 0, subkey, 28);
roldq(17, ka, 0, kw, 4);
}
else
{ // decryption
/* KL dependant keys */
kw[4] = k[0];
kw[5] = k[1];
kw[6] = k[2];
kw[7] = k[3];
decroldq(15, k, 0, subkey, 28);
decroldq(30, k, 0, subkey, 20);
decroldq(15, k, 0, t, 0);
subkey[16] = t[0];
subkey[17] = t[1];
decroldq(17, k, 0, ke, 0);
decroldq(17, k, 0, subkey, 8);
decroldq(17, k, 0, subkey, 0);
/* KA dependant keys */
subkey[34] = ka[0];
subkey[35] = ka[1];
subkey[32] = ka[2];
subkey[33] = ka[3];
decroldq(15, ka, 0, subkey, 24);
decroldq(15, ka, 0, ke, 4);
decroldq(15, ka, 0, t, 0);
subkey[18] = t[2];
subkey[19] = t[3];
decroldq(15, ka, 0, subkey, 12);
decroldqo32(34, ka, 0, subkey, 4);
roldq(17, ka, 0, kw, 0);
}
}
else
{ // 192bit or 256bit
/* compute KB */
for (int i = 0; i < 4; i++)
{
kb[i] = ka[i] ^ k[i + 4];
}
camelliaF2(kb, SIGMA, 8);
if (forEncryption)
{
/* KL dependant keys */
kw[0] = k[0];
kw[1] = k[1];
kw[2] = k[2];
kw[3] = k[3];
roldqo32(45, k, 0, subkey, 16);
roldq(15, k, 0, ke, 4);
roldq(17, k, 0, subkey, 32);
roldqo32(34, k, 0, subkey, 44);
/* KR dependant keys */
roldq(15, k, 4, subkey, 4);
roldq(15, k, 4, ke, 0);
roldq(30, k, 4, subkey, 24);
roldqo32(34, k, 4, subkey, 36);
/* KA dependant keys */
roldq(15, ka, 0, subkey, 8);
roldq(30, ka, 0, subkey, 20);
/* 32bit rotation */
ke[8] = ka[1];
ke[9] = ka[2];
ke[10] = ka[3];
ke[11] = ka[0];
roldqo32(49, ka, 0, subkey, 40);
/* KB dependant keys */
subkey[0] = kb[0];
subkey[1] = kb[1];
subkey[2] = kb[2];
subkey[3] = kb[3];
roldq(30, kb, 0, subkey, 12);
roldq(30, kb, 0, subkey, 28);
roldqo32(51, kb, 0, kw, 4);
}
else
{ // decryption
/* KL dependant keys */
kw[4] = k[0];
kw[5] = k[1];
kw[6] = k[2];
kw[7] = k[3];
decroldqo32(45, k, 0, subkey, 28);
decroldq(15, k, 0, ke, 4);
decroldq(17, k, 0, subkey, 12);
decroldqo32(34, k, 0, subkey, 0);
/* KR dependant keys */
decroldq(15, k, 4, subkey, 40);
decroldq(15, k, 4, ke, 8);
decroldq(30, k, 4, subkey, 20);
decroldqo32(34, k, 4, subkey, 8);
/* KA dependant keys */
decroldq(15, ka, 0, subkey, 36);
decroldq(30, ka, 0, subkey, 24);
/* 32bit rotation */
ke[2] = ka[1];
ke[3] = ka[2];
ke[0] = ka[3];
ke[1] = ka[0];
decroldqo32(49, ka, 0, subkey, 4);
/* KB dependant keys */
subkey[46] = kb[0];
subkey[47] = kb[1];
subkey[44] = kb[2];
subkey[45] = kb[3];
decroldq(30, kb, 0, subkey, 32);
decroldq(30, kb, 0, subkey, 16);
roldqo32(51, kb, 0, kw, 0);
}
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
private int ProcessBlock128(ReadOnlySpan<byte> input, Span<byte> output)
{
uint[] state = new uint[4];
Pack.BE_To_UInt32(input, state);
state[0] ^= kw[0];
state[1] ^= kw[1];
state[2] ^= kw[2];
state[3] ^= kw[3];
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);
Pack.UInt32_To_BE(state[2] ^ kw[4], output);
Pack.UInt32_To_BE(state[3] ^ kw[5], output[4..]);
Pack.UInt32_To_BE(state[0] ^ kw[6], output[8..]);
Pack.UInt32_To_BE(state[1] ^ kw[7], output[12..]);
return BLOCK_SIZE;
}
private int ProcessBlock192or256(ReadOnlySpan<byte> input, Span<byte> output)
{
uint[] state = new uint[4];
Pack.BE_To_UInt32(input, state);
state[0] ^= kw[0];
state[1] ^= kw[1];
state[2] ^= kw[2];
state[3] ^= kw[3];
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);
Pack.UInt32_To_BE(state[2] ^ kw[4], output);
Pack.UInt32_To_BE(state[3] ^ kw[5], output[4..]);
Pack.UInt32_To_BE(state[0] ^ kw[6], output[8..]);
Pack.UInt32_To_BE(state[1] ^ kw[7], output[12..]);
return BLOCK_SIZE;
}
#else
private int ProcessBlock128(byte[] input, int inOff, byte[] output, int outOff)
{
uint[] state = new uint[4];
for (int i = 0; i < 4; i++)
{
state[i] = Pack.BE_To_UInt32(input, inOff + (i * 4)) ^ 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);
Pack.UInt32_To_BE(state[2] ^ kw[4], output, outOff);
Pack.UInt32_To_BE(state[3] ^ kw[5], output, outOff + 4);
Pack.UInt32_To_BE(state[0] ^ kw[6], output, outOff + 8);
Pack.UInt32_To_BE(state[1] ^ kw[7], output, outOff + 12);
return BLOCK_SIZE;
}
private int ProcessBlock192or256(byte[] input, int inOff, byte[] output, int outOff)
{
uint[] state = new uint[4];
for (int i = 0; i < 4; i++)
{
state[i] = Pack.BE_To_UInt32(input, inOff + (i * 4)) ^ 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);
Pack.UInt32_To_BE(state[2] ^ kw[4], output, outOff);
Pack.UInt32_To_BE(state[3] ^ kw[5], output, outOff + 4);
Pack.UInt32_To_BE(state[0] ^ kw[6], output, outOff + 8);
Pack.UInt32_To_BE(state[1] ^ kw[7], output, outOff + 12);
return BLOCK_SIZE;
}
#endif
public CamelliaEngine()
{
}
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 string AlgorithmName
{
get { return "Camellia"; }
}
public virtual int GetBlockSize()
{
return BLOCK_SIZE;
}
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, BLOCK_SIZE, "input buffer too short");
Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short");
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
if (_keyIs128)
{
return ProcessBlock128(input.AsSpan(inOff), output.AsSpan(outOff));
}
else
{
return ProcessBlock192or256(input.AsSpan(inOff), output.AsSpan(outOff));
}
#else
if (_keyIs128)
{
return ProcessBlock128(input, inOff, output, outOff);
}
else
{
return ProcessBlock192or256(input, inOff, output, outOff);
}
#endif
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual int ProcessBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
if (!initialised)
throw new InvalidOperationException("Camellia engine not initialised");
Check.DataLength(input, BLOCK_SIZE, "input buffer too short");
Check.OutputLength(output, BLOCK_SIZE, "output buffer too short");
if (_keyIs128)
{
return ProcessBlock128(input, output);
}
else
{
return ProcessBlock192or256(input, output);
}
}
#endif
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 10254e7acb687ff4e9e90bedbdc0ab6d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/CamelliaEngine.cs
uploadId: 783279

View File

@ -0,0 +1,627 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/**
* Camellia - based on RFC 3713, smaller implementation, about half the size of CamelliaEngine.
*/
public class CamelliaLightEngine
: IBlockCipher
{
private const int BLOCK_SIZE = 16;
// private const int MASK8 = 0xff;
private bool initialised;
private bool _keyis128;
private uint[] subkey = new uint[24 * 4];
private uint[] kw = new uint[4 * 2]; // for whitening
private uint[] ke = new uint[6 * 2]; // for FL and FL^(-1)
private static readonly uint[] SIGMA = {
0xa09e667f, 0x3bcc908b,
0xb67ae858, 0x4caa73b2,
0xc6ef372f, 0xe94f82be,
0x54ff53a5, 0xf1d36f1c,
0x10e527fa, 0xde682d1d,
0xb05688c2, 0xb3e6c1fd
};
/*
*
* S-box data
*
*/
private static readonly byte[] SBOX1 = {
(byte)112, (byte)130, (byte)44, (byte)236,
(byte)179, (byte)39, (byte)192, (byte)229,
(byte)228, (byte)133, (byte)87, (byte)53,
(byte)234, (byte)12, (byte)174, (byte)65,
(byte)35, (byte)239, (byte)107, (byte)147,
(byte)69, (byte)25, (byte)165, (byte)33,
(byte)237, (byte)14, (byte)79, (byte)78,
(byte)29, (byte)101, (byte)146, (byte)189,
(byte)134, (byte)184, (byte)175, (byte)143,
(byte)124, (byte)235, (byte)31, (byte)206,
(byte)62, (byte)48, (byte)220, (byte)95,
(byte)94, (byte)197, (byte)11, (byte)26,
(byte)166, (byte)225, (byte)57, (byte)202,
(byte)213, (byte)71, (byte)93, (byte)61,
(byte)217, (byte)1, (byte)90, (byte)214,
(byte)81, (byte)86, (byte)108, (byte)77,
(byte)139, (byte)13, (byte)154, (byte)102,
(byte)251, (byte)204, (byte)176, (byte)45,
(byte)116, (byte)18, (byte)43, (byte)32,
(byte)240, (byte)177, (byte)132, (byte)153,
(byte)223, (byte)76, (byte)203, (byte)194,
(byte)52, (byte)126, (byte)118, (byte)5,
(byte)109, (byte)183, (byte)169, (byte)49,
(byte)209, (byte)23, (byte)4, (byte)215,
(byte)20, (byte)88, (byte)58, (byte)97,
(byte)222, (byte)27, (byte)17, (byte)28,
(byte)50, (byte)15, (byte)156, (byte)22,
(byte)83, (byte)24, (byte)242, (byte)34,
(byte)254, (byte)68, (byte)207, (byte)178,
(byte)195, (byte)181, (byte)122, (byte)145,
(byte)36, (byte)8, (byte)232, (byte)168,
(byte)96, (byte)252, (byte)105, (byte)80,
(byte)170, (byte)208, (byte)160, (byte)125,
(byte)161, (byte)137, (byte)98, (byte)151,
(byte)84, (byte)91, (byte)30, (byte)149,
(byte)224, (byte)255, (byte)100, (byte)210,
(byte)16, (byte)196, (byte)0, (byte)72,
(byte)163, (byte)247, (byte)117, (byte)219,
(byte)138, (byte)3, (byte)230, (byte)218,
(byte)9, (byte)63, (byte)221, (byte)148,
(byte)135, (byte)92, (byte)131, (byte)2,
(byte)205, (byte)74, (byte)144, (byte)51,
(byte)115, (byte)103, (byte)246, (byte)243,
(byte)157, (byte)127, (byte)191, (byte)226,
(byte)82, (byte)155, (byte)216, (byte)38,
(byte)200, (byte)55, (byte)198, (byte)59,
(byte)129, (byte)150, (byte)111, (byte)75,
(byte)19, (byte)190, (byte)99, (byte)46,
(byte)233, (byte)121, (byte)167, (byte)140,
(byte)159, (byte)110, (byte)188, (byte)142,
(byte)41, (byte)245, (byte)249, (byte)182,
(byte)47, (byte)253, (byte)180, (byte)89,
(byte)120, (byte)152, (byte)6, (byte)106,
(byte)231, (byte)70, (byte)113, (byte)186,
(byte)212, (byte)37, (byte)171, (byte)66,
(byte)136, (byte)162, (byte)141, (byte)250,
(byte)114, (byte)7, (byte)185, (byte)85,
(byte)248, (byte)238, (byte)172, (byte)10,
(byte)54, (byte)73, (byte)42, (byte)104,
(byte)60, (byte)56, (byte)241, (byte)164,
(byte)64, (byte)40, (byte)211, (byte)123,
(byte)187, (byte)201, (byte)67, (byte)193,
(byte)21, (byte)227, (byte)173, (byte)244,
(byte)119, (byte)199, (byte)128, (byte)158
};
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[0 + ooff] = (ki[0 + 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[0 + ioff] >> (32 - rot));
ki[0 + ioff] = ko[0 + 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[0 + ioff] << rot) | (ki[1 + ioff] >> (32 - rot));
ko[3 + ooff] = (ki[1 + ioff] << rot) | (ki[2 + ioff] >> (32 - rot));
ko[0 + ooff] = (ki[2 + ioff] << rot) | (ki[3 + ioff] >> (32 - rot));
ko[1 + ooff] = (ki[3 + ioff] << rot) | (ki[0 + ioff] >> (32 - rot));
ki[0 + ioff] = ko[2 + ooff];
ki[1 + ioff] = ko[3 + ooff];
ki[2 + ioff] = ko[0 + ooff];
ki[3 + ioff] = ko[1 + ooff];
}
private static void roldqo32(int rot, uint[] ki, int ioff, uint[] ko, int ooff)
{
ko[0 + 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[0 + ioff] >> (64 - rot));
ko[3 + ooff] = (ki[0 + ioff] << (rot - 32)) | (ki[1 + ioff] >> (64 - rot));
ki[0 + ioff] = ko[0 + 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[0 + ooff] = (ki[3 + ioff] << (rot - 32)) | (ki[0 + ioff] >> (64 - rot));
ko[1 + ooff] = (ki[0 + ioff] << (rot - 32)) | (ki[1 + ioff] >> (64 - rot));
ki[0 + ioff] = ko[2 + ooff];
ki[1 + ioff] = ko[3 + ooff];
ki[2 + ioff] = ko[0 + ooff];
ki[3 + ioff] = ko[1 + ooff];
}
private byte lRot8(byte v, int rot)
{
return (byte)(((uint)v << rot) | ((uint)v >> (8 - rot)));
}
private uint sbox2(int x)
{
return (uint)lRot8(SBOX1[x], 1);
}
private uint sbox3(int x)
{
return (uint)lRot8(SBOX1[x], 7);
}
private uint sbox4(int x)
{
return (uint)SBOX1[lRot8((byte)x, 1)];
}
private void camelliaF2(uint[] s, uint[] skey, int keyoff)
{
uint t1, t2, u, v;
t1 = s[0] ^ skey[0 + keyoff];
u = sbox4((byte)t1);
u |= (sbox3((byte)(t1 >> 8)) << 8);
u |= (sbox2((byte)(t1 >> 16)) << 16);
u |= ((uint)(SBOX1[(byte)(t1 >> 24)]) << 24);
t2 = s[1] ^ skey[1 + keyoff];
v = (uint)SBOX1[(byte)t2];
v |= (sbox4((byte)(t2 >> 8)) << 8);
v |= (sbox3((byte)(t2 >> 16)) << 16);
v |= (sbox2((byte)(t2 >> 24)) << 24);
v = leftRotate(v, 8);
u ^= v;
v = leftRotate(v, 8) ^ u;
u = rightRotate(u, 8) ^ v;
s[2] ^= leftRotate(v, 16) ^ u;
s[3] ^= leftRotate(u, 8);
t1 = s[2] ^ skey[2 + keyoff];
u = sbox4((byte)t1);
u |= sbox3((byte)(t1 >> 8)) << 8;
u |= sbox2((byte)(t1 >> 16)) << 16;
u |= ((uint)SBOX1[(byte)(t1 >> 24)]) << 24;
t2 = s[3] ^ skey[3 + keyoff];
v = (uint)SBOX1[(byte)t2];
v |= sbox4((byte)(t2 >> 8)) << 8;
v |= sbox3((byte)(t2 >> 16)) << 16;
v |= sbox2((byte)(t2 >> 24)) << 24;
v = leftRotate(v, 8);
u ^= v;
v = leftRotate(v, 8) ^ u;
u = rightRotate(u, 8) ^ v;
s[0] ^= leftRotate(v, 16) ^ u;
s[1] ^= leftRotate(u, 8);
}
private void camelliaFLs(uint[] s, uint[] fkey, int keyoff)
{
s[1] ^= leftRotate(s[0] & fkey[0 + keyoff], 1);
s[0] ^= fkey[1 + keyoff] | s[1];
s[2] ^= fkey[3 + keyoff] | s[3];
s[3] ^= leftRotate(fkey[2 + keyoff] & s[2], 1);
}
private void setKey(bool forEncryption, byte[] key)
{
uint[] k = new uint[8];
uint[] ka = new uint[4];
uint[] kb = new uint[4];
uint[] t = new uint[4];
switch (key.Length)
{
case 16:
_keyis128 = true;
Pack.BE_To_UInt32(key, 0, k, 0, 4);
k[4] = k[5] = k[6] = k[7] = 0;
break;
case 24:
Pack.BE_To_UInt32(key, 0, k, 0, 6);
k[6] = ~k[4];
k[7] = ~k[5];
_keyis128 = false;
break;
case 32:
Pack.BE_To_UInt32(key, 0, k, 0, 8);
_keyis128 = false;
break;
default:
throw new ArgumentException("key sizes are only 16/24/32 bytes.");
}
for (int i = 0; i < 4; i++)
{
ka[i] = k[i] ^ k[i + 4];
}
/* compute KA */
camelliaF2(ka, SIGMA, 0);
for (int i = 0; i < 4; i++)
{
ka[i] ^= k[i];
}
camelliaF2(ka, SIGMA, 4);
if (_keyis128)
{
if (forEncryption)
{
/* KL dependant keys */
kw[0] = k[0];
kw[1] = k[1];
kw[2] = k[2];
kw[3] = k[3];
roldq(15, k, 0, subkey, 4);
roldq(30, k, 0, subkey, 12);
roldq(15, k, 0, t, 0);
subkey[18] = t[2];
subkey[19] = t[3];
roldq(17, k, 0, ke, 4);
roldq(17, k, 0, subkey, 24);
roldq(17, k, 0, subkey, 32);
/* KA dependant keys */
subkey[0] = ka[0];
subkey[1] = ka[1];
subkey[2] = ka[2];
subkey[3] = ka[3];
roldq(15, ka, 0, subkey, 8);
roldq(15, ka, 0, ke, 0);
roldq(15, ka, 0, t, 0);
subkey[16] = t[0];
subkey[17] = t[1];
roldq(15, ka, 0, subkey, 20);
roldqo32(34, ka, 0, subkey, 28);
roldq(17, ka, 0, kw, 4);
}
else
{ // decryption
/* KL dependant keys */
kw[4] = k[0];
kw[5] = k[1];
kw[6] = k[2];
kw[7] = k[3];
decroldq(15, k, 0, subkey, 28);
decroldq(30, k, 0, subkey, 20);
decroldq(15, k, 0, t, 0);
subkey[16] = t[0];
subkey[17] = t[1];
decroldq(17, k, 0, ke, 0);
decroldq(17, k, 0, subkey, 8);
decroldq(17, k, 0, subkey, 0);
/* KA dependant keys */
subkey[34] = ka[0];
subkey[35] = ka[1];
subkey[32] = ka[2];
subkey[33] = ka[3];
decroldq(15, ka, 0, subkey, 24);
decroldq(15, ka, 0, ke, 4);
decroldq(15, ka, 0, t, 0);
subkey[18] = t[2];
subkey[19] = t[3];
decroldq(15, ka, 0, subkey, 12);
decroldqo32(34, ka, 0, subkey, 4);
roldq(17, ka, 0, kw, 0);
}
}
else
{ // 192bit or 256bit
/* compute KB */
for (int i = 0; i < 4; i++)
{
kb[i] = ka[i] ^ k[i + 4];
}
camelliaF2(kb, SIGMA, 8);
if (forEncryption)
{
/* KL dependant keys */
kw[0] = k[0];
kw[1] = k[1];
kw[2] = k[2];
kw[3] = k[3];
roldqo32(45, k, 0, subkey, 16);
roldq(15, k, 0, ke, 4);
roldq(17, k, 0, subkey, 32);
roldqo32(34, k, 0, subkey, 44);
/* KR dependant keys */
roldq(15, k, 4, subkey, 4);
roldq(15, k, 4, ke, 0);
roldq(30, k, 4, subkey, 24);
roldqo32(34, k, 4, subkey, 36);
/* KA dependant keys */
roldq(15, ka, 0, subkey, 8);
roldq(30, ka, 0, subkey, 20);
/* 32bit rotation */
ke[8] = ka[1];
ke[9] = ka[2];
ke[10] = ka[3];
ke[11] = ka[0];
roldqo32(49, ka, 0, subkey, 40);
/* KB dependant keys */
subkey[0] = kb[0];
subkey[1] = kb[1];
subkey[2] = kb[2];
subkey[3] = kb[3];
roldq(30, kb, 0, subkey, 12);
roldq(30, kb, 0, subkey, 28);
roldqo32(51, kb, 0, kw, 4);
}
else
{ // decryption
/* KL dependant keys */
kw[4] = k[0];
kw[5] = k[1];
kw[6] = k[2];
kw[7] = k[3];
decroldqo32(45, k, 0, subkey, 28);
decroldq(15, k, 0, ke, 4);
decroldq(17, k, 0, subkey, 12);
decroldqo32(34, k, 0, subkey, 0);
/* KR dependant keys */
decroldq(15, k, 4, subkey, 40);
decroldq(15, k, 4, ke, 8);
decroldq(30, k, 4, subkey, 20);
decroldqo32(34, k, 4, subkey, 8);
/* KA dependant keys */
decroldq(15, ka, 0, subkey, 36);
decroldq(30, ka, 0, subkey, 24);
/* 32bit rotation */
ke[2] = ka[1];
ke[3] = ka[2];
ke[0] = ka[3];
ke[1] = ka[0];
decroldqo32(49, ka, 0, subkey, 4);
/* KB dependant keys */
subkey[46] = kb[0];
subkey[47] = kb[1];
subkey[44] = kb[2];
subkey[45] = kb[3];
decroldq(30, kb, 0, subkey, 32);
decroldq(30, kb, 0, subkey, 16);
roldqo32(51, kb, 0, kw, 0);
}
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
private int ProcessBlock128(ReadOnlySpan<byte> input, Span<byte> output)
{
uint[] state = new uint[4];
Pack.BE_To_UInt32(input, state);
state[0] ^= kw[0];
state[1] ^= kw[1];
state[2] ^= kw[2];
state[3] ^= kw[3];
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);
Pack.UInt32_To_BE(state[2] ^ kw[4], output);
Pack.UInt32_To_BE(state[3] ^ kw[5], output[4..]);
Pack.UInt32_To_BE(state[0] ^ kw[6], output[8..]);
Pack.UInt32_To_BE(state[1] ^ kw[7], output[12..]);
return BLOCK_SIZE;
}
private int ProcessBlock192or256(ReadOnlySpan<byte> input, Span<byte> output)
{
uint[] state = new uint[4];
Pack.BE_To_UInt32(input, state);
state[0] ^= kw[0];
state[1] ^= kw[1];
state[2] ^= kw[2];
state[3] ^= kw[3];
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);
Pack.UInt32_To_BE(state[2] ^ kw[4], output);
Pack.UInt32_To_BE(state[3] ^ kw[5], output[4..]);
Pack.UInt32_To_BE(state[0] ^ kw[6], output[8..]);
Pack.UInt32_To_BE(state[1] ^ kw[7], output[12..]);
return BLOCK_SIZE;
}
#else
private int ProcessBlock128(byte[] input, int inOff, byte[] output, int outOff)
{
uint[] state = new uint[4];
for (int i = 0; i < 4; i++)
{
state[i] = Pack.BE_To_UInt32(input, inOff + (i * 4)) ^ 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);
Pack.UInt32_To_BE(state[2] ^ kw[4], output, outOff);
Pack.UInt32_To_BE(state[3] ^ kw[5], output, outOff + 4);
Pack.UInt32_To_BE(state[0] ^ kw[6], output, outOff + 8);
Pack.UInt32_To_BE(state[1] ^ kw[7], output, outOff + 12);
return BLOCK_SIZE;
}
private int ProcessBlock192or256(byte[] input, int inOff, byte[] output, int outOff)
{
uint[] state = new uint[4];
for (int i = 0; i < 4; i++)
{
state[i] = Pack.BE_To_UInt32(input, inOff + (i * 4)) ^ 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);
Pack.UInt32_To_BE(state[2] ^ kw[4], output, outOff);
Pack.UInt32_To_BE(state[3] ^ kw[5], output, outOff + 4);
Pack.UInt32_To_BE(state[0] ^ kw[6], output, outOff + 8);
Pack.UInt32_To_BE(state[1] ^ kw[7], output, outOff + 12);
return BLOCK_SIZE;
}
#endif
public CamelliaLightEngine()
{
initialised = false;
}
public virtual string AlgorithmName
{
get { return "Camellia"; }
}
public virtual int GetBlockSize()
{
return BLOCK_SIZE;
}
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, BLOCK_SIZE, "input buffer too short");
Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short");
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
if (_keyis128)
{
return ProcessBlock128(input.AsSpan(inOff), output.AsSpan(outOff));
}
else
{
return ProcessBlock192or256(input.AsSpan(inOff), output.AsSpan(outOff));
}
#else
if (_keyis128)
{
return ProcessBlock128(input, inOff, output, outOff);
}
else
{
return ProcessBlock192or256(input, inOff, output, outOff);
}
#endif
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual int ProcessBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
if (!initialised)
throw new InvalidOperationException("Camellia engine not initialised");
Check.DataLength(input, BLOCK_SIZE, "input buffer too short");
Check.OutputLength(output, BLOCK_SIZE, "output buffer too short");
if (_keyis128)
{
return ProcessBlock128(input, output);
}
else
{
return ProcessBlock192or256(input, output);
}
}
#endif
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: c7e6ab2310226ea42b90e699623352e3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/CamelliaLightEngine.cs
uploadId: 783279

View File

@ -0,0 +1,20 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/// <remarks>
/// An implementation of the Camellia key wrapper based on RFC 3657/RFC 3394.
/// <p/>
/// For further details see: <a href="http://www.ietf.org/rfc/rfc3657.txt">http://www.ietf.org/rfc/rfc3657.txt</a>.
/// </remarks>
public class CamelliaWrapEngine
: Rfc3394WrapEngine
{
public CamelliaWrapEngine()
: base(new CamelliaEngine())
{
}
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: edbca90dd47c1584ebc76d023f7f1e37
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/CamelliaWrapEngine.cs
uploadId: 783279

View File

@ -0,0 +1,838 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/**
* A class that provides CAST key encryption operations,
* such as encoding data and generating keys.
*
* All the algorithms herein are from the Internet RFC's
*
* RFC2144 - Cast5 (64bit block, 40-128bit key)
* RFC2612 - CAST6 (128bit block, 128-256bit key)
*
* and implement a simplified cryptography interface.
*/
public class Cast5Engine
: IBlockCipher
{
private static readonly uint[] S1 =
{
0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949,
0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e,
0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0,
0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7,
0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935,
0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d,
0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50,
0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe,
0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3,
0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167,
0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291,
0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779,
0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2,
0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511,
0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d,
0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5,
0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324,
0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c,
0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc,
0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d,
0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96,
0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a,
0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d,
0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd,
0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6,
0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9,
0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872,
0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c,
0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e,
0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9,
0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf
},
S2 =
{
0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651,
0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3,
0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb,
0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806,
0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b,
0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359,
0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b,
0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c,
0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34,
0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb,
0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd,
0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860,
0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b,
0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304,
0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b,
0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf,
0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c,
0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13,
0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f,
0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6,
0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6,
0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58,
0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906,
0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d,
0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6,
0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4,
0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6,
0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f,
0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249,
0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9,
0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1
},
S3 =
{
0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90,
0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5,
0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e,
0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240,
0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5,
0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,
0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71,
0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04,
0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82,
0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15,
0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2,
0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176,
0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148,
0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc,
0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e,
0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51,
0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f,
0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a,
0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b,
0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,
0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5,
0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45,
0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536,
0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc,
0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0,
0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69,
0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2,
0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49,
0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d,
0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a,
0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783
},
S4 =
{
0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1,
0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf,
0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15,
0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121,
0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25,
0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,
0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb,
0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5,
0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d,
0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6,
0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23,
0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003,
0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6,
0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119,
0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a,
0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79,
0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df,
0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26,
0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab,
0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7,
0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417,
0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2,
0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2,
0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a,
0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919,
0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef,
0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876,
0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab,
0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04,
0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282,
0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2
},
S5 =
{
0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f,
0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a,
0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff,
0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02,
0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a,
0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7,
0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9,
0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981,
0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774,
0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655,
0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2,
0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910,
0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1,
0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da,
0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049,
0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f,
0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba,
0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be,
0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3,
0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840,
0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4,
0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2,
0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7,
0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5,
0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e,
0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e,
0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801,
0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad,
0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0,
0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20,
0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8,
0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4
},
S6 =
{
0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac,
0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138,
0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367,
0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98,
0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072,
0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3,
0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd,
0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8,
0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9,
0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54,
0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387,
0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc,
0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf,
0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf,
0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f,
0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289,
0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950,
0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f,
0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b,
0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be,
0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13,
0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976,
0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0,
0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891,
0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da,
0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc,
0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084,
0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25,
0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121,
0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5,
0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd,
0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f
},
S7 =
{
0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f,
0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de,
0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43,
0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19,
0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2,
0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516,
0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88,
0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816,
0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756,
0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a,
0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264,
0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688,
0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28,
0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3,
0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7,
0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06,
0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033,
0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a,
0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566,
0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509,
0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962,
0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e,
0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c,
0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c,
0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285,
0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301,
0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be,
0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767,
0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647,
0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914,
0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c,
0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3
},
S8 =
{
0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5,
0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc,
0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd,
0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d,
0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2,
0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862,
0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc,
0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c,
0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e,
0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039,
0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8,
0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42,
0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5,
0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472,
0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225,
0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c,
0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb,
0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054,
0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70,
0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc,
0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c,
0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3,
0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4,
0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101,
0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f,
0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e,
0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a,
0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c,
0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384,
0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c,
0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82,
0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e
};
//====================================
// Useful constants
//====================================
internal static readonly int MAX_ROUNDS = 16;
internal static readonly int RED_ROUNDS = 12;
private const int BLOCK_SIZE = 8; // bytes = 64 bits
private int[] _Kr = new int[17]; // the rotating round key
private uint[] _Km = new uint[17]; // the masking round key
private bool _encrypting;
private byte[] _workingKey;
private int _rounds = MAX_ROUNDS;
public Cast5Engine()
{
}
/**
* initialise a CAST cipher.
*
* @param forEncryption whether or not we are for encryption.
* @param parameters the parameters required to set up the cipher.
* @exception ArgumentException if the parameters argument is
* inappropriate.
*/
public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
if (!(parameters is KeyParameter))
throw new ArgumentException("Invalid parameter passed to "+ AlgorithmName +" init - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters));
_encrypting = forEncryption;
_workingKey = ((KeyParameter)parameters).GetKey();
SetKey(_workingKey);
}
public virtual string AlgorithmName
{
get { return "CAST5"; }
}
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
{
if (_workingKey == null)
throw new InvalidOperationException(AlgorithmName + " not initialised");
int blockSize = GetBlockSize();
Check.DataLength(input, inOff, blockSize, "input buffer too short");
Check.OutputLength(output, outOff, blockSize, "output buffer too short");
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
if (_encrypting)
{
return EncryptBlock(input.AsSpan(inOff), output.AsSpan(outOff));
}
else
{
return DecryptBlock(input.AsSpan(inOff), output.AsSpan(outOff));
}
#else
if (_encrypting)
{
return EncryptBlock(input, inOff, output, outOff);
}
else
{
return DecryptBlock(input, inOff, output, outOff);
}
#endif
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual int ProcessBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
if (_workingKey == null)
throw new InvalidOperationException(AlgorithmName + " not initialised");
int blockSize = GetBlockSize();
Check.DataLength(input, blockSize, "input buffer too short");
Check.OutputLength(output, blockSize, "output buffer too short");
if (_encrypting)
{
return EncryptBlock(input, output);
}
else
{
return DecryptBlock(input, output);
}
}
#endif
public virtual int GetBlockSize()
{
return BLOCK_SIZE;
}
//==================================
// Private Implementation
//==================================
/*
* Creates the subkeys using the same nomenclature
* as described in RFC2144.
*
* See section 2.4
*/
internal virtual void SetKey(byte[] key)
{
/*
* Determine the key size here, if required
*
* if keysize <= 80bits, use 12 rounds instead of 16
* if keysize < 128bits, pad with 0
*
* Typical key sizes => 40, 64, 80, 128
*/
if (key.Length < 11)
{
_rounds = RED_ROUNDS;
}
int [] z = new int[16];
int [] x = new int[16];
uint z03, z47, z8B, zCF;
uint x03, x47, x8B, xCF;
/* copy the key into x */
for (int i=0; i< key.Length; i++)
{
x[i] = (int)(key[i] & 0xff);
}
/*
* This will look different because the selection of
* bytes from the input key I've already chosen the
* correct int.
*/
x03 = IntsTo32bits(x, 0x0);
x47 = IntsTo32bits(x, 0x4);
x8B = IntsTo32bits(x, 0x8);
xCF = IntsTo32bits(x, 0xC);
z03 = x03 ^S5[x[0xD]] ^S6[x[0xF]] ^S7[x[0xC]] ^S8[x[0xE]] ^S7[x[0x8]];
Bits32ToInts(z03, z, 0x0);
z47 = x8B ^S5[z[0x0]] ^S6[z[0x2]] ^S7[z[0x1]] ^S8[z[0x3]] ^S8[x[0xA]];
Bits32ToInts(z47, z, 0x4);
z8B = xCF ^S5[z[0x7]] ^S6[z[0x6]] ^S7[z[0x5]] ^S8[z[0x4]] ^S5[x[0x9]];
Bits32ToInts(z8B, z, 0x8);
zCF = x47 ^S5[z[0xA]] ^S6[z[0x9]] ^S7[z[0xB]] ^S8[z[0x8]] ^S6[x[0xB]];
Bits32ToInts(zCF, z, 0xC);
_Km[ 1]= S5[z[0x8]] ^ S6[z[0x9]] ^ S7[z[0x7]] ^ S8[z[0x6]] ^ S5[z[0x2]];
_Km[ 2]= S5[z[0xA]] ^ S6[z[0xB]] ^ S7[z[0x5]] ^ S8[z[0x4]] ^ S6[z[0x6]];
_Km[ 3]= S5[z[0xC]] ^ S6[z[0xD]] ^ S7[z[0x3]] ^ S8[z[0x2]] ^ S7[z[0x9]];
_Km[ 4]= S5[z[0xE]] ^ S6[z[0xF]] ^ S7[z[0x1]] ^ S8[z[0x0]] ^ S8[z[0xC]];
z03 = IntsTo32bits(z, 0x0);
z47 = IntsTo32bits(z, 0x4);
z8B = IntsTo32bits(z, 0x8);
zCF = IntsTo32bits(z, 0xC);
x03 = z8B ^S5[z[0x5]] ^S6[z[0x7]] ^S7[z[0x4]] ^S8[z[0x6]] ^S7[z[0x0]];
Bits32ToInts(x03, x, 0x0);
x47 = z03 ^S5[x[0x0]] ^S6[x[0x2]] ^S7[x[0x1]] ^S8[x[0x3]] ^S8[z[0x2]];
Bits32ToInts(x47, x, 0x4);
x8B = z47 ^S5[x[0x7]] ^S6[x[0x6]] ^S7[x[0x5]] ^S8[x[0x4]] ^S5[z[0x1]];
Bits32ToInts(x8B, x, 0x8);
xCF = zCF ^S5[x[0xA]] ^S6[x[0x9]] ^S7[x[0xB]] ^S8[x[0x8]] ^S6[z[0x3]];
Bits32ToInts(xCF, x, 0xC);
_Km[ 5]= S5[x[0x3]] ^ S6[x[0x2]] ^ S7[x[0xC]] ^ S8[x[0xD]] ^ S5[x[0x8]];
_Km[ 6]= S5[x[0x1]] ^ S6[x[0x0]] ^ S7[x[0xE]] ^ S8[x[0xF]] ^ S6[x[0xD]];
_Km[ 7]= S5[x[0x7]] ^ S6[x[0x6]] ^ S7[x[0x8]] ^ S8[x[0x9]] ^ S7[x[0x3]];
_Km[ 8]= S5[x[0x5]] ^ S6[x[0x4]] ^ S7[x[0xA]] ^ S8[x[0xB]] ^ S8[x[0x7]];
x03 = IntsTo32bits(x, 0x0);
x47 = IntsTo32bits(x, 0x4);
x8B = IntsTo32bits(x, 0x8);
xCF = IntsTo32bits(x, 0xC);
z03 = x03 ^S5[x[0xD]] ^S6[x[0xF]] ^S7[x[0xC]] ^S8[x[0xE]] ^S7[x[0x8]];
Bits32ToInts(z03, z, 0x0);
z47 = x8B ^S5[z[0x0]] ^S6[z[0x2]] ^S7[z[0x1]] ^S8[z[0x3]] ^S8[x[0xA]];
Bits32ToInts(z47, z, 0x4);
z8B = xCF ^S5[z[0x7]] ^S6[z[0x6]] ^S7[z[0x5]] ^S8[z[0x4]] ^S5[x[0x9]];
Bits32ToInts(z8B, z, 0x8);
zCF = x47 ^S5[z[0xA]] ^S6[z[0x9]] ^S7[z[0xB]] ^S8[z[0x8]] ^S6[x[0xB]];
Bits32ToInts(zCF, z, 0xC);
_Km[ 9]= S5[z[0x3]] ^ S6[z[0x2]] ^ S7[z[0xC]] ^ S8[z[0xD]] ^ S5[z[0x9]];
_Km[10]= S5[z[0x1]] ^ S6[z[0x0]] ^ S7[z[0xE]] ^ S8[z[0xF]] ^ S6[z[0xc]];
_Km[11]= S5[z[0x7]] ^ S6[z[0x6]] ^ S7[z[0x8]] ^ S8[z[0x9]] ^ S7[z[0x2]];
_Km[12]= S5[z[0x5]] ^ S6[z[0x4]] ^ S7[z[0xA]] ^ S8[z[0xB]] ^ S8[z[0x6]];
z03 = IntsTo32bits(z, 0x0);
z47 = IntsTo32bits(z, 0x4);
z8B = IntsTo32bits(z, 0x8);
zCF = IntsTo32bits(z, 0xC);
x03 = z8B ^S5[z[0x5]] ^S6[z[0x7]] ^S7[z[0x4]] ^S8[z[0x6]] ^S7[z[0x0]];
Bits32ToInts(x03, x, 0x0);
x47 = z03 ^S5[x[0x0]] ^S6[x[0x2]] ^S7[x[0x1]] ^S8[x[0x3]] ^S8[z[0x2]];
Bits32ToInts(x47, x, 0x4);
x8B = z47 ^S5[x[0x7]] ^S6[x[0x6]] ^S7[x[0x5]] ^S8[x[0x4]] ^S5[z[0x1]];
Bits32ToInts(x8B, x, 0x8);
xCF = zCF ^S5[x[0xA]] ^S6[x[0x9]] ^S7[x[0xB]] ^S8[x[0x8]] ^S6[z[0x3]];
Bits32ToInts(xCF, x, 0xC);
_Km[13]= S5[x[0x8]] ^ S6[x[0x9]] ^ S7[x[0x7]] ^ S8[x[0x6]] ^ S5[x[0x3]];
_Km[14]= S5[x[0xA]] ^ S6[x[0xB]] ^ S7[x[0x5]] ^ S8[x[0x4]] ^ S6[x[0x7]];
_Km[15]= S5[x[0xC]] ^ S6[x[0xD]] ^ S7[x[0x3]] ^ S8[x[0x2]] ^ S7[x[0x8]];
_Km[16]= S5[x[0xE]] ^ S6[x[0xF]] ^ S7[x[0x1]] ^ S8[x[0x0]] ^ S8[x[0xD]];
x03 = IntsTo32bits(x, 0x0);
x47 = IntsTo32bits(x, 0x4);
x8B = IntsTo32bits(x, 0x8);
xCF = IntsTo32bits(x, 0xC);
z03 = x03 ^S5[x[0xD]] ^S6[x[0xF]] ^S7[x[0xC]] ^S8[x[0xE]] ^S7[x[0x8]];
Bits32ToInts(z03, z, 0x0);
z47 = x8B ^S5[z[0x0]] ^S6[z[0x2]] ^S7[z[0x1]] ^S8[z[0x3]] ^S8[x[0xA]];
Bits32ToInts(z47, z, 0x4);
z8B = xCF ^S5[z[0x7]] ^S6[z[0x6]] ^S7[z[0x5]] ^S8[z[0x4]] ^S5[x[0x9]];
Bits32ToInts(z8B, z, 0x8);
zCF = x47 ^S5[z[0xA]] ^S6[z[0x9]] ^S7[z[0xB]] ^S8[z[0x8]] ^S6[x[0xB]];
Bits32ToInts(zCF, z, 0xC);
_Kr[ 1]=(int)((S5[z[0x8]]^S6[z[0x9]]^S7[z[0x7]]^S8[z[0x6]] ^ S5[z[0x2]])&0x1f);
_Kr[ 2]=(int)((S5[z[0xA]]^S6[z[0xB]]^S7[z[0x5]]^S8[z[0x4]] ^ S6[z[0x6]])&0x1f);
_Kr[ 3]=(int)((S5[z[0xC]]^S6[z[0xD]]^S7[z[0x3]]^S8[z[0x2]] ^ S7[z[0x9]])&0x1f);
_Kr[ 4]=(int)((S5[z[0xE]]^S6[z[0xF]]^S7[z[0x1]]^S8[z[0x0]] ^ S8[z[0xC]])&0x1f);
z03 = IntsTo32bits(z, 0x0);
z47 = IntsTo32bits(z, 0x4);
z8B = IntsTo32bits(z, 0x8);
zCF = IntsTo32bits(z, 0xC);
x03 = z8B ^S5[z[0x5]] ^S6[z[0x7]] ^S7[z[0x4]] ^S8[z[0x6]] ^S7[z[0x0]];
Bits32ToInts(x03, x, 0x0);
x47 = z03 ^S5[x[0x0]] ^S6[x[0x2]] ^S7[x[0x1]] ^S8[x[0x3]] ^S8[z[0x2]];
Bits32ToInts(x47, x, 0x4);
x8B = z47 ^S5[x[0x7]] ^S6[x[0x6]] ^S7[x[0x5]] ^S8[x[0x4]] ^S5[z[0x1]];
Bits32ToInts(x8B, x, 0x8);
xCF = zCF ^S5[x[0xA]] ^S6[x[0x9]] ^S7[x[0xB]] ^S8[x[0x8]] ^S6[z[0x3]];
Bits32ToInts(xCF, x, 0xC);
_Kr[ 5]=(int)((S5[x[0x3]]^S6[x[0x2]]^S7[x[0xC]]^S8[x[0xD]]^S5[x[0x8]])&0x1f);
_Kr[ 6]=(int)((S5[x[0x1]]^S6[x[0x0]]^S7[x[0xE]]^S8[x[0xF]]^S6[x[0xD]])&0x1f);
_Kr[ 7]=(int)((S5[x[0x7]]^S6[x[0x6]]^S7[x[0x8]]^S8[x[0x9]]^S7[x[0x3]])&0x1f);
_Kr[ 8]=(int)((S5[x[0x5]]^S6[x[0x4]]^S7[x[0xA]]^S8[x[0xB]]^S8[x[0x7]])&0x1f);
x03 = IntsTo32bits(x, 0x0);
x47 = IntsTo32bits(x, 0x4);
x8B = IntsTo32bits(x, 0x8);
xCF = IntsTo32bits(x, 0xC);
z03 = x03 ^S5[x[0xD]] ^S6[x[0xF]] ^S7[x[0xC]] ^S8[x[0xE]] ^S7[x[0x8]];
Bits32ToInts(z03, z, 0x0);
z47 = x8B ^S5[z[0x0]] ^S6[z[0x2]] ^S7[z[0x1]] ^S8[z[0x3]] ^S8[x[0xA]];
Bits32ToInts(z47, z, 0x4);
z8B = xCF ^S5[z[0x7]] ^S6[z[0x6]] ^S7[z[0x5]] ^S8[z[0x4]] ^S5[x[0x9]];
Bits32ToInts(z8B, z, 0x8);
zCF = x47 ^S5[z[0xA]] ^S6[z[0x9]] ^S7[z[0xB]] ^S8[z[0x8]] ^S6[x[0xB]];
Bits32ToInts(zCF, z, 0xC);
_Kr[ 9]=(int)((S5[z[0x3]]^S6[z[0x2]]^S7[z[0xC]]^S8[z[0xD]]^S5[z[0x9]])&0x1f);
_Kr[10]=(int)((S5[z[0x1]]^S6[z[0x0]]^S7[z[0xE]]^S8[z[0xF]]^S6[z[0xc]])&0x1f);
_Kr[11]=(int)((S5[z[0x7]]^S6[z[0x6]]^S7[z[0x8]]^S8[z[0x9]]^S7[z[0x2]])&0x1f);
_Kr[12]=(int)((S5[z[0x5]]^S6[z[0x4]]^S7[z[0xA]]^S8[z[0xB]]^S8[z[0x6]])&0x1f);
z03 = IntsTo32bits(z, 0x0);
z47 = IntsTo32bits(z, 0x4);
z8B = IntsTo32bits(z, 0x8);
zCF = IntsTo32bits(z, 0xC);
x03 = z8B ^S5[z[0x5]] ^S6[z[0x7]] ^S7[z[0x4]] ^S8[z[0x6]] ^S7[z[0x0]];
Bits32ToInts(x03, x, 0x0);
x47 = z03 ^S5[x[0x0]] ^S6[x[0x2]] ^S7[x[0x1]] ^S8[x[0x3]] ^S8[z[0x2]];
Bits32ToInts(x47, x, 0x4);
x8B = z47 ^S5[x[0x7]] ^S6[x[0x6]] ^S7[x[0x5]] ^S8[x[0x4]] ^S5[z[0x1]];
Bits32ToInts(x8B, x, 0x8);
xCF = zCF ^S5[x[0xA]] ^S6[x[0x9]] ^S7[x[0xB]] ^S8[x[0x8]] ^S6[z[0x3]];
Bits32ToInts(xCF, x, 0xC);
_Kr[13]=(int)((S5[x[0x8]]^S6[x[0x9]]^S7[x[0x7]]^S8[x[0x6]]^S5[x[0x3]])&0x1f);
_Kr[14]=(int)((S5[x[0xA]]^S6[x[0xB]]^S7[x[0x5]]^S8[x[0x4]]^S6[x[0x7]])&0x1f);
_Kr[15]=(int)((S5[x[0xC]]^S6[x[0xD]]^S7[x[0x3]]^S8[x[0x2]]^S7[x[0x8]])&0x1f);
_Kr[16]=(int)((S5[x[0xE]]^S6[x[0xF]]^S7[x[0x1]]^S8[x[0x0]]^S8[x[0xD]])&0x1f);
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
internal virtual int EncryptBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
// process the input block
// batch the units up into a 32 bit chunk and go for it
// the array is in bytes, the increment is 8x8 bits = 64
uint L0 = Pack.BE_To_UInt32(input);
uint R0 = Pack.BE_To_UInt32(input[4..]);
uint[] result = new uint[2];
CAST_Encipher(L0, R0, result);
// now stuff them into the destination block
Pack.UInt32_To_BE(result[0], output);
Pack.UInt32_To_BE(result[1], output[4..]);
return BLOCK_SIZE;
}
internal virtual int DecryptBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
// process the input block
// batch the units up into a 32 bit chunk and go for it
// the array is in bytes, the increment is 8x8 bits = 64
uint L16 = Pack.BE_To_UInt32(input);
uint R16 = Pack.BE_To_UInt32(input[4..]);
uint[] result = new uint[2];
CAST_Decipher(L16, R16, result);
// now stuff them into the destination block
Pack.UInt32_To_BE(result[0], output);
Pack.UInt32_To_BE(result[1], output[4..]);
return BLOCK_SIZE;
}
#else
internal virtual int EncryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex)
{
// process the input block
// batch the units up into a 32 bit chunk and go for it
// the array is in bytes, the increment is 8x8 bits = 64
uint L0 = Pack.BE_To_UInt32(src, srcIndex);
uint R0 = Pack.BE_To_UInt32(src, srcIndex + 4);
uint[] result = new uint[2];
CAST_Encipher(L0, R0, result);
// now stuff them into the destination block
Pack.UInt32_To_BE(result[0], dst, dstIndex);
Pack.UInt32_To_BE(result[1], dst, dstIndex + 4);
return BLOCK_SIZE;
}
internal virtual int DecryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex)
{
// process the input block
// batch the units up into a 32 bit chunk and go for it
// the array is in bytes, the increment is 8x8 bits = 64
uint L16 = Pack.BE_To_UInt32(src, srcIndex);
uint R16 = Pack.BE_To_UInt32(src, srcIndex + 4);
uint[] result = new uint[2];
CAST_Decipher(L16, R16, result);
// now stuff them into the destination block
Pack.UInt32_To_BE(result[0], dst, dstIndex);
Pack.UInt32_To_BE(result[1], dst, dstIndex + 4);
return BLOCK_SIZE;
}
#endif
/**
* The first of the three processing functions for the
* encryption and decryption.
*
* @param D the input to be processed
* @param Kmi the mask to be used from Km[n]
* @param Kri the rotation value to be used
*
*/
internal static uint F1(uint D, uint Kmi, int Kri)
{
uint I = Kmi + D;
I = I << Kri | (I >> (32-Kri));
return ((S1[(I>>24)&0xff]^S2[(I>>16)&0xff])-S3[(I>>8)&0xff])+S4[I&0xff];
}
/**
* The second of the three processing functions for the
* encryption and decryption.
*
* @param D the input to be processed
* @param Kmi the mask to be used from Km[n]
* @param Kri the rotation value to be used
*
*/
internal static uint F2(uint D, uint Kmi, int Kri)
{
uint I = Kmi ^ D;
I = I << Kri | (I >> (32-Kri));
return ((S1[(I>>24)&0xff]-S2[(I>>16)&0xff])+S3[(I>>8)&0xff])^S4[I&0xff];
}
/**
* The third of the three processing functions for the
* encryption and decryption.
*
* @param D the input to be processed
* @param Kmi the mask to be used from Km[n]
* @param Kri the rotation value to be used
*
*/
internal static uint F3(uint D, uint Kmi, int Kri)
{
uint I = Kmi - D;
I = I << Kri | (I >> (32-Kri));
return ((S1[(I>>24)&0xff]+S2[(I>>16)&0xff])^S3[(I>>8)&0xff])-S4[I&0xff];
}
/**
* Does the 16 rounds to encrypt the block.
*
* @param L0 the LH-32bits of the plaintext block
* @param R0 the RH-32bits of the plaintext block
*/
internal void CAST_Encipher(uint L0, uint R0, uint[] result)
{
uint Lp = L0; // the previous value, equiv to L[i-1]
uint Rp = R0; // equivalent to R[i-1]
/*
* numbering consistent with paper to make
* checking and validating easier
*/
uint Li = L0, Ri = R0;
for (int i = 1; i<=_rounds ; i++)
{
Lp = Li;
Rp = Ri;
Li = Rp;
switch (i)
{
case 1:
case 4:
case 7:
case 10:
case 13:
case 16:
Ri = Lp ^ F1(Rp, _Km[i], _Kr[i]);
break;
case 2:
case 5:
case 8:
case 11:
case 14:
Ri = Lp ^ F2(Rp, _Km[i], _Kr[i]);
break;
case 3:
case 6:
case 9:
case 12:
case 15:
Ri = Lp ^ F3(Rp, _Km[i], _Kr[i]);
break;
}
}
result[0] = Ri;
result[1] = Li;
return;
}
internal void CAST_Decipher(uint L16, uint R16, uint[] result)
{
uint Lp = L16; // the previous value, equiv to L[i-1]
uint Rp = R16; // equivalent to R[i-1]
/*
* numbering consistent with paper to make
* checking and validating easier
*/
uint Li = L16, Ri = R16;
for (int i = _rounds; i > 0; i--)
{
Lp = Li;
Rp = Ri;
Li = Rp;
switch (i)
{
case 1:
case 4:
case 7:
case 10:
case 13:
case 16:
Ri = Lp ^ F1(Rp, _Km[i], _Kr[i]);
break;
case 2:
case 5:
case 8:
case 11:
case 14:
Ri = Lp ^ F2(Rp, _Km[i], _Kr[i]);
break;
case 3:
case 6:
case 9:
case 12:
case 15:
Ri = Lp ^ F3(Rp, _Km[i], _Kr[i]);
break;
}
}
result[0] = Ri;
result[1] = Li;
return;
}
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)));
}
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: d1d5ea93366634b49a08b076c20d3beb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/Cast5Engine.cs
uploadId: 783279

View File

@ -0,0 +1,291 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/**
* A class that provides CAST6 key encryption operations,
* such as encoding data and generating keys.
*
* All the algorithms herein are from the Internet RFC
*
* RFC2612 - CAST6 (128bit block, 128-256bit key)
*
* and implement a simplified cryptography interface.
*/
public sealed class Cast6Engine
: Cast5Engine
{
//====================================
// Useful constants
//====================================
private const int ROUNDS = 12;
private const int BLOCK_SIZE = 16; // bytes = 128 bits
/*
* Put the round and mask keys into an array.
* Kr0[i] => _Kr[i*4 + 0]
*/
private int []_Kr = new int[ROUNDS*4]; // the rotating round key(s)
private uint []_Km = new uint[ROUNDS*4]; // the masking round key(s)
/*
* Key setup
*/
private int []_Tr = new int[24 * 8];
private uint []_Tm = new uint[24 * 8];
private uint[] _workingKey = new uint[8];
public Cast6Engine()
{
}
public override string AlgorithmName
{
get { return "CAST6"; }
}
public override int GetBlockSize()
{
return BLOCK_SIZE;
}
//==================================
// Private Implementation
//==================================
/*
* Creates the subkeys using the same nomenclature
* as described in RFC2612.
*
* See section 2.4
*/
internal override void SetKey(
byte[] key)
{
uint Cm = 0x5a827999;
uint Mm = 0x6ed9eba1;
int Cr = 19;
int Mr = 17;
/*
* Determine the key size here, if required
*
* if keysize < 256 bytes, pad with 0
*
* Typical key sizes => 128, 160, 192, 224, 256
*/
for (int i=0; i< 24; i++)
{
for (int j=0; j< 8; j++)
{
_Tm[i*8 + j] = Cm;
Cm += Mm; //mod 2^32;
_Tr[i*8 + j] = Cr;
Cr = (Cr + Mr) & 0x1f; // mod 32
}
}
byte[] tmpKey = new byte[64];
key.CopyTo(tmpKey, 0);
// now create ABCDEFGH
for (int i = 0; i < 8; i++)
{
_workingKey[i] = Pack.BE_To_UInt32(tmpKey, i*4);
}
// Generate the key schedule
for (int i = 0; i < 12; i++)
{
// KAPPA <- W2i(KAPPA)
int i2 = i*2 *8;
_workingKey[6] ^= F1(_workingKey[7], _Tm[i2], _Tr[i2]);
_workingKey[5] ^= F2(_workingKey[6], _Tm[i2+1], _Tr[i2+1]);
_workingKey[4] ^= F3(_workingKey[5], _Tm[i2+2], _Tr[i2+2]);
_workingKey[3] ^= F1(_workingKey[4], _Tm[i2+3], _Tr[i2+3]);
_workingKey[2] ^= F2(_workingKey[3], _Tm[i2+4], _Tr[i2+4]);
_workingKey[1] ^= F3(_workingKey[2], _Tm[i2+5], _Tr[i2+5]);
_workingKey[0] ^= F1(_workingKey[1], _Tm[i2+6], _Tr[i2+6]);
_workingKey[7] ^= F2(_workingKey[0], _Tm[i2+7], _Tr[i2+7]);
// KAPPA <- W2i+1(KAPPA)
i2 = (i*2 + 1)*8;
_workingKey[6] ^= F1(_workingKey[7], _Tm[i2], _Tr[i2]);
_workingKey[5] ^= F2(_workingKey[6], _Tm[i2+1], _Tr[i2+1]);
_workingKey[4] ^= F3(_workingKey[5], _Tm[i2+2], _Tr[i2+2]);
_workingKey[3] ^= F1(_workingKey[4], _Tm[i2+3], _Tr[i2+3]);
_workingKey[2] ^= F2(_workingKey[3], _Tm[i2+4], _Tr[i2+4]);
_workingKey[1] ^= F3(_workingKey[2], _Tm[i2+5], _Tr[i2+5]);
_workingKey[0] ^= F1(_workingKey[1], _Tm[i2+6], _Tr[i2+6]);
_workingKey[7] ^= F2(_workingKey[0], _Tm[i2+7], _Tr[i2+7]);
// Kr_(i) <- KAPPA
_Kr[i*4] = (int)(_workingKey[0] & 0x1f);
_Kr[i*4 + 1] = (int)(_workingKey[2] & 0x1f);
_Kr[i*4 + 2] = (int)(_workingKey[4] & 0x1f);
_Kr[i*4 + 3] = (int)(_workingKey[6] & 0x1f);
// Km_(i) <- KAPPA
_Km[i*4] = _workingKey[7];
_Km[i*4 + 1] = _workingKey[5];
_Km[i*4 + 2] = _workingKey[3];
_Km[i*4 + 3] = _workingKey[1];
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
internal override int EncryptBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
// process the input block
// batch the units up into 4x32 bit chunks and go for it
uint A = Pack.BE_To_UInt32(input);
uint B = Pack.BE_To_UInt32(input[4..]);
uint C = Pack.BE_To_UInt32(input[8..]);
uint D = Pack.BE_To_UInt32(input[12..]);
uint[] result = new uint[4];
CAST_Encipher(A, B, C, D, result);
// now stuff them into the destination block
Pack.UInt32_To_BE(result[0], output);
Pack.UInt32_To_BE(result[1], output[4..]);
Pack.UInt32_To_BE(result[2], output[8..]);
Pack.UInt32_To_BE(result[3], output[12..]);
return BLOCK_SIZE;
}
internal override int DecryptBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
// process the input block
// batch the units up into 4x32 bit chunks and go for it
uint A = Pack.BE_To_UInt32(input);
uint B = Pack.BE_To_UInt32(input[4..]);
uint C = Pack.BE_To_UInt32(input[8..]);
uint D = Pack.BE_To_UInt32(input[12..]);
uint[] result = new uint[4];
CAST_Decipher(A, B, C, D, result);
// now stuff them into the destination block
Pack.UInt32_To_BE(result[0], output);
Pack.UInt32_To_BE(result[1], output[4..]);
Pack.UInt32_To_BE(result[2], output[8..]);
Pack.UInt32_To_BE(result[3], output[12..]);
return BLOCK_SIZE;
}
#else
internal override int EncryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex)
{
// process the input block
// batch the units up into 4x32 bit chunks and go for it
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[] result = new uint[4];
CAST_Encipher(A, B, C, D, result);
// now stuff them into the destination block
Pack.UInt32_To_BE(result[0], dst, dstIndex);
Pack.UInt32_To_BE(result[1], dst, dstIndex + 4);
Pack.UInt32_To_BE(result[2], dst, dstIndex + 8);
Pack.UInt32_To_BE(result[3], dst, dstIndex + 12);
return BLOCK_SIZE;
}
internal override int DecryptBlock(byte[] src, int srcIndex, byte[] dst, int dstIndex)
{
// process the input block
// batch the units up into 4x32 bit chunks and go for it
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[] result = new uint[4];
CAST_Decipher(A, B, C, D, result);
// now stuff them into the destination block
Pack.UInt32_To_BE(result[0], dst, dstIndex);
Pack.UInt32_To_BE(result[1], dst, dstIndex + 4);
Pack.UInt32_To_BE(result[2], dst, dstIndex + 8);
Pack.UInt32_To_BE(result[3], dst, dstIndex + 12);
return BLOCK_SIZE;
}
#endif
/**
* Does the 12 quad rounds rounds to encrypt the block.
*
* @param A the 00-31 bits of the plaintext block
* @param B the 32-63 bits of the plaintext block
* @param C the 64-95 bits of the plaintext block
* @param D the 96-127 bits of the plaintext block
* @param result the resulting ciphertext
*/
private void CAST_Encipher(
uint A,
uint B,
uint C,
uint D,
uint[] result)
{
for (int i = 0; i < 6; i++)
{
int x = i*4;
// BETA <- Qi(BETA)
C ^= F1(D, _Km[x], _Kr[x]);
B ^= F2(C, _Km[x + 1], _Kr[x + 1]);
A ^= F3(B, _Km[x + 2], _Kr[x + 2]);
D ^= F1(A, _Km[x + 3], _Kr[x + 3]);
}
for (int i = 6; i < 12; i++)
{
int x = i*4;
// BETA <- QBARi(BETA)
D ^= F1(A, _Km[x + 3], _Kr[x + 3]);
A ^= F3(B, _Km[x + 2], _Kr[x + 2]);
B ^= F2(C, _Km[x + 1], _Kr[x + 1]);
C ^= F1(D, _Km[x], _Kr[x]);
}
result[0] = A;
result[1] = B;
result[2] = C;
result[3] = D;
}
/**
* Does the 12 quad rounds rounds to decrypt the block.
*
* @param A the 00-31 bits of the ciphertext block
* @param B the 32-63 bits of the ciphertext block
* @param C the 64-95 bits of the ciphertext block
* @param D the 96-127 bits of the ciphertext block
* @param result the resulting plaintext
*/
private void CAST_Decipher(
uint A,
uint B,
uint C,
uint D,
uint[] result)
{
for (int i = 0; i < 6; i++)
{
int x = (11-i)*4;
// BETA <- Qi(BETA)
C ^= F1(D, _Km[x], _Kr[x]);
B ^= F2(C, _Km[x + 1], _Kr[x + 1]);
A ^= F3(B, _Km[x + 2], _Kr[x + 2]);
D ^= F1(A, _Km[x + 3], _Kr[x + 3]);
}
for (int i=6; i<12; i++)
{
int x = (11-i)*4;
// BETA <- QBARi(BETA)
D ^= F1(A, _Km[x + 3], _Kr[x + 3]);
A ^= F3(B, _Km[x + 2], _Kr[x + 2]);
B ^= F2(C, _Km[x + 1], _Kr[x + 1]);
C ^= F1(D, _Km[x], _Kr[x]);
}
result[0] = A;
result[1] = B;
result[2] = C;
result[3] = D;
}
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: dc43571249c7f30419bf2fe12ecc58ac
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/Cast6Engine.cs
uploadId: 783279

View File

@ -0,0 +1,525 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.Diagnostics;
#if NETSTANDARD1_0_OR_GREATER || NETCOREAPP1_0_OR_GREATER || UNITY_2021_2_OR_NEWER
using System.Runtime.CompilerServices;
#endif
#if NETCOREAPP3_0_OR_GREATER
using System.Buffers.Binary;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
#endif
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/// <summary>
/// Implementation of Daniel J. Bernstein's ChaCha stream cipher.
/// </summary>
public class ChaCha7539Engine
: Salsa20Engine
{
/// <summary>
/// Creates a 20 rounds ChaCha engine.
/// </summary>
public ChaCha7539Engine()
: base()
{
}
public override string AlgorithmName
{
get { return "ChaCha7539"; }
}
protected override int NonceSize
{
get { return 12; }
}
protected override void AdvanceCounter()
{
if (++engineState[12] == 0)
throw new InvalidOperationException("attempt to increase counter past 2^32.");
}
protected override void ResetCounter()
{
engineState[12] = 0;
}
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);
// Key
Pack.LE_To_UInt32(keyBytes, 0, engineState, 4, 8);
}
// IV
Pack.LE_To_UInt32(ivBytes, 0, engineState, 13, 3);
}
protected override void GenerateKeyStream(byte[] output)
{
ChaChaEngine.ChachaCore(rounds, engineState, output);
}
internal void DoFinal(byte[] inBuf, int inOff, int inLen, byte[] outBuf, int outOff)
{
if (!initialised)
throw new InvalidOperationException(AlgorithmName + " not initialised");
if (index != 0)
throw new InvalidOperationException(AlgorithmName + " not in block-aligned state");
Check.DataLength(inBuf, inOff, inLen, "input buffer too short");
Check.OutputLength(outBuf, outOff, inLen, "output buffer too short");
while (inLen >= 128)
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
ProcessBlocks2(inBuf.AsSpan(inOff), outBuf.AsSpan(outOff));
#else
ProcessBlocks2(inBuf, inOff, outBuf, outOff);
#endif
inOff += 128;
inLen -= 128;
outOff += 128;
}
if (inLen >= 64)
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
ImplProcessBlock(inBuf.AsSpan(inOff), outBuf.AsSpan(outOff));
#else
ImplProcessBlock(inBuf, inOff, outBuf, outOff);
#endif
inOff += 64;
inLen -= 64;
outOff += 64;
}
if (inLen > 0)
{
GenerateKeyStream(keyStream);
AdvanceCounter();
for (int i = 0; i < inLen; ++i)
{
outBuf[outOff + i] = (byte)(inBuf[i + inOff] ^ keyStream[i]);
}
}
engineState[12] = 0;
// TODO Prevent re-use if encrypting
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
internal void ProcessBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
if (!initialised)
throw new InvalidOperationException(AlgorithmName + " not initialised");
if (LimitExceeded(64U))
throw new MaxBytesExceededException("2^38 byte limit per IV would be exceeded; Change IV");
Debug.Assert(index == 0);
ImplProcessBlock(input, output);
}
internal void ProcessBlocks2(ReadOnlySpan<byte> input, Span<byte> output)
{
if (!initialised)
throw new InvalidOperationException(AlgorithmName + " not initialised");
if (LimitExceeded(128U))
throw new MaxBytesExceededException("2^38 byte limit per IV would be exceeded; Change IV");
Debug.Assert(index == 0);
#if NETCOREAPP3_0_OR_GREATER
if (Avx2.IsSupported)
{
ImplProcessBlocks2_X86_Avx2(rounds, engineState, input, output);
return;
}
if (Sse2.IsSupported)
{
ImplProcessBlocks2_X86_Sse2(rounds, engineState, input, output);
return;
}
#endif
{
ImplProcessBlock(input, output);
ImplProcessBlock(input[64..], output[64..]);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void ImplProcessBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
ChaChaEngine.ChachaCore(rounds, engineState, keyStream);
AdvanceCounter();
for (int i = 0; i < 64; ++i)
{
output[i] = (byte)(keyStream[i] ^ input[i]);
}
}
#else
internal void ProcessBlock(byte[] inBytes, int inOff, byte[] outBytes, int outOff)
{
if (!initialised)
throw new InvalidOperationException(AlgorithmName + " not initialised");
if (LimitExceeded(64U))
throw new MaxBytesExceededException("2^38 byte limit per IV would be exceeded; Change IV");
Debug.Assert(index == 0);
ImplProcessBlock(inBytes, inOff, outBytes, outOff);
}
internal void ProcessBlocks2(byte[] inBytes, int inOff, byte[] outBytes, int outOff)
{
if (!initialised)
throw new InvalidOperationException(AlgorithmName + " not initialised");
if (LimitExceeded(128U))
throw new MaxBytesExceededException("2^38 byte limit per IV would be exceeded; Change IV");
Debug.Assert(index == 0);
{
ImplProcessBlock(inBytes, inOff, outBytes, outOff);
ImplProcessBlock(inBytes, inOff + 64, outBytes, outOff + 64);
}
}
#if NETSTANDARD1_0_OR_GREATER || NETCOREAPP1_0_OR_GREATER || UNITY_2021_2_OR_NEWER
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
internal void ImplProcessBlock(byte[] inBuf, int inOff, byte[] outBuf, int outOff)
{
ChaChaEngine.ChachaCore(rounds, engineState, keyStream);
AdvanceCounter();
for (int i = 0; i < 64; ++i)
{
outBuf[outOff + i] = (byte)(keyStream[i] ^ inBuf[inOff + i]);
}
}
#endif
#if NETCOREAPP3_0_OR_GREATER
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void ImplProcessBlocks2_X86_Avx2(int rounds, uint[] state, ReadOnlySpan<byte> input,
Span<byte> output)
{
if (!Avx2.IsSupported)
throw new PlatformNotSupportedException();
Debug.Assert(rounds % 2 == 0);
Debug.Assert(state.Length >= 16);
Debug.Assert(input.Length >= 128);
Debug.Assert(output.Length >= 128);
var t0 = Load128_UInt32(state.AsSpan());
var t1 = Load128_UInt32(state.AsSpan(4));
var t2 = Load128_UInt32(state.AsSpan(8));
var t3 = Load128_UInt32(state.AsSpan(12));
++state[12];
var t4 = Load128_UInt32(state.AsSpan(12));
++state[12];
var x0 = Vector256.Create(t0, t0);
var x1 = Vector256.Create(t1, t1);
var x2 = Vector256.Create(t2, t2);
var x3 = Vector256.Create(t3, t4);
var v0 = x0;
var v1 = x1;
var v2 = x2;
var v3 = x3;
for (int i = rounds; i > 0; i -= 2)
{
v0 = Avx2.Add(v0, v1);
v3 = Avx2.Xor(v3, v0);
v3 = Avx2.Xor(Avx2.ShiftLeftLogical(v3, 16), Avx2.ShiftRightLogical(v3, 16));
v2 = Avx2.Add(v2, v3);
v1 = Avx2.Xor(v1, v2);
v1 = Avx2.Xor(Avx2.ShiftLeftLogical(v1, 12), Avx2.ShiftRightLogical(v1, 20));
v0 = Avx2.Add(v0, v1);
v3 = Avx2.Xor(v3, v0);
v3 = Avx2.Xor(Avx2.ShiftLeftLogical(v3, 8), Avx2.ShiftRightLogical(v3, 24));
v2 = Avx2.Add(v2, v3);
v1 = Avx2.Xor(v1, v2);
v1 = Avx2.Xor(Avx2.ShiftLeftLogical(v1, 7), Avx2.ShiftRightLogical(v1, 25));
v1 = Avx2.Shuffle(v1, 0x39);
v2 = Avx2.Shuffle(v2, 0x4E);
v3 = Avx2.Shuffle(v3, 0x93);
v0 = Avx2.Add(v0, v1);
v3 = Avx2.Xor(v3, v0);
v3 = Avx2.Xor(Avx2.ShiftLeftLogical(v3, 16), Avx2.ShiftRightLogical(v3, 16));
v2 = Avx2.Add(v2, v3);
v1 = Avx2.Xor(v1, v2);
v1 = Avx2.Xor(Avx2.ShiftLeftLogical(v1, 12), Avx2.ShiftRightLogical(v1, 20));
v0 = Avx2.Add(v0, v1);
v3 = Avx2.Xor(v3, v0);
v3 = Avx2.Xor(Avx2.ShiftLeftLogical(v3, 8), Avx2.ShiftRightLogical(v3, 24));
v2 = Avx2.Add(v2, v3);
v1 = Avx2.Xor(v1, v2);
v1 = Avx2.Xor(Avx2.ShiftLeftLogical(v1, 7), Avx2.ShiftRightLogical(v1, 25));
v1 = Avx2.Shuffle(v1, 0x93);
v2 = Avx2.Shuffle(v2, 0x4E);
v3 = Avx2.Shuffle(v3, 0x39);
}
v0 = Avx2.Add(v0, x0);
v1 = Avx2.Add(v1, x1);
v2 = Avx2.Add(v2, x2);
v3 = Avx2.Add(v3, x3);
var n0 = Avx2.Permute2x128(v0, v1, 0x20).AsByte();
var n1 = Avx2.Permute2x128(v2, v3, 0x20).AsByte();
var n2 = Avx2.Permute2x128(v0, v1, 0x31).AsByte();
var n3 = Avx2.Permute2x128(v2, v3, 0x31).AsByte();
n0 = Avx2.Xor(n0, Load256_Byte(input));
n1 = Avx2.Xor(n1, Load256_Byte(input[0x20..]));
n2 = Avx2.Xor(n2, Load256_Byte(input[0x40..]));
n3 = Avx2.Xor(n3, Load256_Byte(input[0x60..]));
Store256_Byte(n0, output);
Store256_Byte(n1, output[0x20..]);
Store256_Byte(n2, output[0x40..]);
Store256_Byte(n3, output[0x60..]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void ImplProcessBlocks2_X86_Sse2(int rounds, uint[] state, ReadOnlySpan<byte> input,
Span<byte> output)
{
if (!Sse2.IsSupported)
throw new PlatformNotSupportedException();
Debug.Assert(rounds % 2 == 0);
Debug.Assert(state.Length >= 16);
Debug.Assert(input.Length >= 128);
Debug.Assert(output.Length >= 128);
var x0 = Load128_UInt32(state.AsSpan());
var x1 = Load128_UInt32(state.AsSpan(4));
var x2 = Load128_UInt32(state.AsSpan(8));
var x3 = Load128_UInt32(state.AsSpan(12));
++state[12];
var v0 = x0;
var v1 = x1;
var v2 = x2;
var v3 = x3;
for (int i = rounds; i > 0; i -= 2)
{
v0 = Sse2.Add(v0, v1);
v3 = Sse2.Xor(v3, v0);
v3 = Sse2.Xor(Sse2.ShiftLeftLogical(v3, 16), Sse2.ShiftRightLogical(v3, 16));
v2 = Sse2.Add(v2, v3);
v1 = Sse2.Xor(v1, v2);
v1 = Sse2.Xor(Sse2.ShiftLeftLogical(v1, 12), Sse2.ShiftRightLogical(v1, 20));
v0 = Sse2.Add(v0, v1);
v3 = Sse2.Xor(v3, v0);
v3 = Sse2.Xor(Sse2.ShiftLeftLogical(v3, 8), Sse2.ShiftRightLogical(v3, 24));
v2 = Sse2.Add(v2, v3);
v1 = Sse2.Xor(v1, v2);
v1 = Sse2.Xor(Sse2.ShiftLeftLogical(v1, 7), Sse2.ShiftRightLogical(v1, 25));
v1 = Sse2.Shuffle(v1, 0x39);
v2 = Sse2.Shuffle(v2, 0x4E);
v3 = Sse2.Shuffle(v3, 0x93);
v0 = Sse2.Add(v0, v1);
v3 = Sse2.Xor(v3, v0);
v3 = Sse2.Xor(Sse2.ShiftLeftLogical(v3, 16), Sse2.ShiftRightLogical(v3, 16));
v2 = Sse2.Add(v2, v3);
v1 = Sse2.Xor(v1, v2);
v1 = Sse2.Xor(Sse2.ShiftLeftLogical(v1, 12), Sse2.ShiftRightLogical(v1, 20));
v0 = Sse2.Add(v0, v1);
v3 = Sse2.Xor(v3, v0);
v3 = Sse2.Xor(Sse2.ShiftLeftLogical(v3, 8), Sse2.ShiftRightLogical(v3, 24));
v2 = Sse2.Add(v2, v3);
v1 = Sse2.Xor(v1, v2);
v1 = Sse2.Xor(Sse2.ShiftLeftLogical(v1, 7), Sse2.ShiftRightLogical(v1, 25));
v1 = Sse2.Shuffle(v1, 0x93);
v2 = Sse2.Shuffle(v2, 0x4E);
v3 = Sse2.Shuffle(v3, 0x39);
}
v0 = Sse2.Add(v0, x0);
v1 = Sse2.Add(v1, x1);
v2 = Sse2.Add(v2, x2);
v3 = Sse2.Add(v3, x3);
var n0 = Load128_Byte(input);
var n1 = Load128_Byte(input[0x10..]);
var n2 = Load128_Byte(input[0x20..]);
var n3 = Load128_Byte(input[0x30..]);
n0 = Sse2.Xor(n0, v0.AsByte());
n1 = Sse2.Xor(n1, v1.AsByte());
n2 = Sse2.Xor(n2, v2.AsByte());
n3 = Sse2.Xor(n3, v3.AsByte());
Store128_Byte(n0, output);
Store128_Byte(n1, output[0x10..]);
Store128_Byte(n2, output[0x20..]);
Store128_Byte(n3, output[0x30..]);
x3 = Load128_UInt32(state.AsSpan(12));
++state[12];
v0 = x0;
v1 = x1;
v2 = x2;
v3 = x3;
for (int i = rounds; i > 0; i -= 2)
{
v0 = Sse2.Add(v0, v1);
v3 = Sse2.Xor(v3, v0);
v3 = Sse2.Xor(Sse2.ShiftLeftLogical(v3, 16), Sse2.ShiftRightLogical(v3, 16));
v2 = Sse2.Add(v2, v3);
v1 = Sse2.Xor(v1, v2);
v1 = Sse2.Xor(Sse2.ShiftLeftLogical(v1, 12), Sse2.ShiftRightLogical(v1, 20));
v0 = Sse2.Add(v0, v1);
v3 = Sse2.Xor(v3, v0);
v3 = Sse2.Xor(Sse2.ShiftLeftLogical(v3, 8), Sse2.ShiftRightLogical(v3, 24));
v2 = Sse2.Add(v2, v3);
v1 = Sse2.Xor(v1, v2);
v1 = Sse2.Xor(Sse2.ShiftLeftLogical(v1, 7), Sse2.ShiftRightLogical(v1, 25));
v1 = Sse2.Shuffle(v1, 0x39);
v2 = Sse2.Shuffle(v2, 0x4E);
v3 = Sse2.Shuffle(v3, 0x93);
v0 = Sse2.Add(v0, v1);
v3 = Sse2.Xor(v3, v0);
v3 = Sse2.Xor(Sse2.ShiftLeftLogical(v3, 16), Sse2.ShiftRightLogical(v3, 16));
v2 = Sse2.Add(v2, v3);
v1 = Sse2.Xor(v1, v2);
v1 = Sse2.Xor(Sse2.ShiftLeftLogical(v1, 12), Sse2.ShiftRightLogical(v1, 20));
v0 = Sse2.Add(v0, v1);
v3 = Sse2.Xor(v3, v0);
v3 = Sse2.Xor(Sse2.ShiftLeftLogical(v3, 8), Sse2.ShiftRightLogical(v3, 24));
v2 = Sse2.Add(v2, v3);
v1 = Sse2.Xor(v1, v2);
v1 = Sse2.Xor(Sse2.ShiftLeftLogical(v1, 7), Sse2.ShiftRightLogical(v1, 25));
v1 = Sse2.Shuffle(v1, 0x93);
v2 = Sse2.Shuffle(v2, 0x4E);
v3 = Sse2.Shuffle(v3, 0x39);
}
v0 = Sse2.Add(v0, x0);
v1 = Sse2.Add(v1, x1);
v2 = Sse2.Add(v2, x2);
v3 = Sse2.Add(v3, x3);
n0 = Load128_Byte(input[0x40..]);
n1 = Load128_Byte(input[0x50..]);
n2 = Load128_Byte(input[0x60..]);
n3 = Load128_Byte(input[0x70..]);
n0 = Sse2.Xor(n0, v0.AsByte());
n1 = Sse2.Xor(n1, v1.AsByte());
n2 = Sse2.Xor(n2, v2.AsByte());
n3 = Sse2.Xor(n3, v3.AsByte());
Store128_Byte(n0, output[0x40..]);
Store128_Byte(n1, output[0x50..]);
Store128_Byte(n2, output[0x60..]);
Store128_Byte(n3, output[0x70..]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector128<byte> Load128_Byte(ReadOnlySpan<byte> t)
{
if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector128<byte>>() == 16)
return MemoryMarshal.Read<Vector128<byte>>(t);
return Vector128.Create(
BinaryPrimitives.ReadUInt64LittleEndian(t[..8]),
BinaryPrimitives.ReadUInt64LittleEndian(t[8..])
).AsByte();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector128<uint> Load128_UInt32(ReadOnlySpan<uint> t)
{
if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector128<uint>>() == 16)
return MemoryMarshal.Read<Vector128<uint>>(MemoryMarshal.AsBytes(t));
return Vector128.Create(t[0], t[1], t[2], t[3]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector256<byte> Load256_Byte(ReadOnlySpan<byte> t)
{
if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector256<byte>>() == 32)
return MemoryMarshal.Read<Vector256<byte>>(t);
return Vector256.Create(
BinaryPrimitives.ReadUInt64LittleEndian(t[ 0.. 8]),
BinaryPrimitives.ReadUInt64LittleEndian(t[ 8..16]),
BinaryPrimitives.ReadUInt64LittleEndian(t[16..24]),
BinaryPrimitives.ReadUInt64LittleEndian(t[24..32])
).AsByte();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void Store128_Byte(Vector128<byte> s, Span<byte> t)
{
if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector128<byte>>() == 16)
{
MemoryMarshal.Write(t, ref s);
return;
}
var u = s.AsUInt64();
BinaryPrimitives.WriteUInt64LittleEndian(t[..8], u.GetElement(0));
BinaryPrimitives.WriteUInt64LittleEndian(t[8..], u.GetElement(1));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void Store256_Byte(Vector256<byte> s, Span<byte> t)
{
if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector256<byte>>() == 32)
{
MemoryMarshal.Write(t, ref s);
return;
}
var u = s.AsUInt64();
BinaryPrimitives.WriteUInt64LittleEndian(t[ 0.. 8], u.GetElement(0));
BinaryPrimitives.WriteUInt64LittleEndian(t[ 8..16], u.GetElement(1));
BinaryPrimitives.WriteUInt64LittleEndian(t[16..24], u.GetElement(2));
BinaryPrimitives.WriteUInt64LittleEndian(t[24..32], u.GetElement(3));
}
#endif
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 2965d47a019118b408c110cb6b9aa065
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/ChaCha7539Engine.cs
uploadId: 783279

View File

@ -0,0 +1,245 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.Diagnostics;
#if NETCOREAPP3_0_OR_GREATER
using System.Buffers.Binary;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
#endif
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/// <summary>
/// Implementation of Daniel J. Bernstein's ChaCha stream cipher.
/// </summary>
public class ChaChaEngine
: Salsa20Engine
{
/// <summary>
/// Creates a 20 rounds ChaCha engine.
/// </summary>
public ChaChaEngine()
{
}
/// <summary>
/// Creates a ChaCha engine with a specific number of rounds.
/// </summary>
/// <param name="rounds">the number of rounds (must be an even number).</param>
public ChaChaEngine(int rounds)
: base(rounds)
{
}
public override string AlgorithmName
{
get { return "ChaCha" + rounds; }
}
protected override void AdvanceCounter()
{
if (++engineState[12] == 0)
{
++engineState[13];
}
}
protected override void ResetCounter()
{
engineState[12] = engineState[13] = 0;
}
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);
// Key
Pack.LE_To_UInt32(keyBytes, 0, engineState, 4, 4);
Pack.LE_To_UInt32(keyBytes, keyBytes.Length - 16, engineState, 8, 4);
}
// IV
Pack.LE_To_UInt32(ivBytes, 0, engineState, 14, 2);
}
protected override void GenerateKeyStream(byte[] output)
{
ChachaCore(rounds, engineState, output);
}
internal static void ChachaCore(int rounds, uint[] input, byte[] output)
{
Debug.Assert(rounds % 2 == 0);
Debug.Assert(input.Length >= 16);
Debug.Assert(output.Length >= 64);
#if NETCOREAPP3_0_OR_GREATER
if (Sse2.IsSupported)
{
var x0 = Load128_UInt32(input.AsSpan());
var x1 = Load128_UInt32(input.AsSpan(4));
var x2 = Load128_UInt32(input.AsSpan(8));
var x3 = Load128_UInt32(input.AsSpan(12));
var v0 = x0;
var v1 = x1;
var v2 = x2;
var v3 = x3;
for (int i = rounds; i > 0; i -= 2)
{
v0 = Sse2.Add(v0, v1);
v3 = Sse2.Xor(v3, v0);
v3 = Sse2.Xor(Sse2.ShiftLeftLogical(v3, 16), Sse2.ShiftRightLogical(v3, 16));
v2 = Sse2.Add(v2, v3);
v1 = Sse2.Xor(v1, v2);
v1 = Sse2.Xor(Sse2.ShiftLeftLogical(v1, 12), Sse2.ShiftRightLogical(v1, 20));
v0 = Sse2.Add(v0, v1);
v3 = Sse2.Xor(v3, v0);
v3 = Sse2.Xor(Sse2.ShiftLeftLogical(v3, 8), Sse2.ShiftRightLogical(v3, 24));
v2 = Sse2.Add(v2, v3);
v1 = Sse2.Xor(v1, v2);
v1 = Sse2.Xor(Sse2.ShiftLeftLogical(v1, 7), Sse2.ShiftRightLogical(v1, 25));
v1 = Sse2.Shuffle(v1, 0x39);
v2 = Sse2.Shuffle(v2, 0x4E);
v3 = Sse2.Shuffle(v3, 0x93);
v0 = Sse2.Add(v0, v1);
v3 = Sse2.Xor(v3, v0);
v3 = Sse2.Xor(Sse2.ShiftLeftLogical(v3, 16), Sse2.ShiftRightLogical(v3, 16));
v2 = Sse2.Add(v2, v3);
v1 = Sse2.Xor(v1, v2);
v1 = Sse2.Xor(Sse2.ShiftLeftLogical(v1, 12), Sse2.ShiftRightLogical(v1, 20));
v0 = Sse2.Add(v0, v1);
v3 = Sse2.Xor(v3, v0);
v3 = Sse2.Xor(Sse2.ShiftLeftLogical(v3, 8), Sse2.ShiftRightLogical(v3, 24));
v2 = Sse2.Add(v2, v3);
v1 = Sse2.Xor(v1, v2);
v1 = Sse2.Xor(Sse2.ShiftLeftLogical(v1, 7), Sse2.ShiftRightLogical(v1, 25));
v1 = Sse2.Shuffle(v1, 0x93);
v2 = Sse2.Shuffle(v2, 0x4E);
v3 = Sse2.Shuffle(v3, 0x39);
}
v0 = Sse2.Add(v0, x0);
v1 = Sse2.Add(v1, x1);
v2 = Sse2.Add(v2, x2);
v3 = Sse2.Add(v3, x3);
Store128_UInt32(v0, output.AsSpan());
Store128_UInt32(v1, output.AsSpan(0x10));
Store128_UInt32(v2, output.AsSpan(0x20));
Store128_UInt32(v3, output.AsSpan(0x30));
return;
}
#endif
{
uint x00 = input[ 0], x01 = input[ 1], x02 = input[ 2], x03 = input[ 3];
uint x04 = input[ 4], x05 = input[ 5], x06 = input[ 6], x07 = input[ 7];
uint x08 = input[ 8], x09 = input[ 9], x10 = input[10], x11 = input[11];
uint x12 = input[12], x13 = input[13], x14 = input[14], x15 = input[15];
for (int i = rounds; i > 0; i -= 2)
{
x00 += x04; x12 = Integers.RotateLeft(x12 ^ x00, 16);
x01 += x05; x13 = Integers.RotateLeft(x13 ^ x01, 16);
x02 += x06; x14 = Integers.RotateLeft(x14 ^ x02, 16);
x03 += x07; x15 = Integers.RotateLeft(x15 ^ x03, 16);
x08 += x12; x04 = Integers.RotateLeft(x04 ^ x08, 12);
x09 += x13; x05 = Integers.RotateLeft(x05 ^ x09, 12);
x10 += x14; x06 = Integers.RotateLeft(x06 ^ x10, 12);
x11 += x15; x07 = Integers.RotateLeft(x07 ^ x11, 12);
x00 += x04; x12 = Integers.RotateLeft(x12 ^ x00, 8);
x01 += x05; x13 = Integers.RotateLeft(x13 ^ x01, 8);
x02 += x06; x14 = Integers.RotateLeft(x14 ^ x02, 8);
x03 += x07; x15 = Integers.RotateLeft(x15 ^ x03, 8);
x08 += x12; x04 = Integers.RotateLeft(x04 ^ x08, 7);
x09 += x13; x05 = Integers.RotateLeft(x05 ^ x09, 7);
x10 += x14; x06 = Integers.RotateLeft(x06 ^ x10, 7);
x11 += x15; x07 = Integers.RotateLeft(x07 ^ x11, 7);
x00 += x05; x15 = Integers.RotateLeft(x15 ^ x00, 16);
x01 += x06; x12 = Integers.RotateLeft(x12 ^ x01, 16);
x02 += x07; x13 = Integers.RotateLeft(x13 ^ x02, 16);
x03 += x04; x14 = Integers.RotateLeft(x14 ^ x03, 16);
x10 += x15; x05 = Integers.RotateLeft(x05 ^ x10, 12);
x11 += x12; x06 = Integers.RotateLeft(x06 ^ x11, 12);
x08 += x13; x07 = Integers.RotateLeft(x07 ^ x08, 12);
x09 += x14; x04 = Integers.RotateLeft(x04 ^ x09, 12);
x00 += x05; x15 = Integers.RotateLeft(x15 ^ x00, 8);
x01 += x06; x12 = Integers.RotateLeft(x12 ^ x01, 8);
x02 += x07; x13 = Integers.RotateLeft(x13 ^ x02, 8);
x03 += x04; x14 = Integers.RotateLeft(x14 ^ x03, 8);
x10 += x15; x05 = Integers.RotateLeft(x05 ^ x10, 7);
x11 += x12; x06 = Integers.RotateLeft(x06 ^ x11, 7);
x08 += x13; x07 = Integers.RotateLeft(x07 ^ x08, 7);
x09 += x14; x04 = Integers.RotateLeft(x04 ^ x09, 7);
}
Pack.UInt32_To_LE(x00 + input[ 0], output, 0);
Pack.UInt32_To_LE(x01 + input[ 1], output, 4);
Pack.UInt32_To_LE(x02 + input[ 2], output, 8);
Pack.UInt32_To_LE(x03 + input[ 3], output, 12);
Pack.UInt32_To_LE(x04 + input[ 4], output, 16);
Pack.UInt32_To_LE(x05 + input[ 5], output, 20);
Pack.UInt32_To_LE(x06 + input[ 6], output, 24);
Pack.UInt32_To_LE(x07 + input[ 7], output, 28);
Pack.UInt32_To_LE(x08 + input[ 8], output, 32);
Pack.UInt32_To_LE(x09 + input[ 9], output, 36);
Pack.UInt32_To_LE(x10 + input[10], output, 40);
Pack.UInt32_To_LE(x11 + input[11], output, 44);
Pack.UInt32_To_LE(x12 + input[12], output, 48);
Pack.UInt32_To_LE(x13 + input[13], output, 52);
Pack.UInt32_To_LE(x14 + input[14], output, 56);
Pack.UInt32_To_LE(x15 + input[15], output, 60);
}
}
#if NETCOREAPP3_0_OR_GREATER
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector128<uint> Load128_UInt32(ReadOnlySpan<uint> t)
{
if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector128<uint>>() == 16)
return MemoryMarshal.Read<Vector128<uint>>(MemoryMarshal.AsBytes(t));
return Vector128.Create(t[0], t[1], t[2], t[3]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void Store128_UInt32(Vector128<uint> s, Span<byte> t)
{
if (BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector128<uint>>() == 16)
{
MemoryMarshal.Write(t, ref s);
return;
}
var u = s.AsUInt64();
BinaryPrimitives.WriteUInt64LittleEndian(t[..8], u.GetElement(0));
BinaryPrimitives.WriteUInt64LittleEndian(t[8..], u.GetElement(1));
}
#endif
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 65e438836372ad84d85fe5ff83f21d8c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/ChaChaEngine.cs
uploadId: 783279

View File

@ -0,0 +1,133 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/// <remarks>A class that provides a basic DESede (or Triple DES) engine.</remarks>
public class DesEdeEngine
: DesEngine
{
private int[] workingKey1, workingKey2, workingKey3;
private bool forEncryption;
/**
* initialise a DESede cipher.
*
* @param forEncryption whether or not we are for encryption.
* @param parameters the parameters required to set up the cipher.
* @exception ArgumentException if the parameters argument is
* inappropriate.
*/
public override void Init(
bool forEncryption,
ICipherParameters parameters)
{
if (!(parameters is KeyParameter))
throw new ArgumentException("invalid parameter passed to DESede init - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters));
byte[] keyMaster = ((KeyParameter)parameters).GetKey();
if (keyMaster.Length != 24 && keyMaster.Length != 16)
throw new ArgumentException("key size must be 16 or 24 bytes.");
this.forEncryption = forEncryption;
byte[] key1 = new byte[8];
Array.Copy(keyMaster, 0, key1, 0, key1.Length);
workingKey1 = GenerateWorkingKey(forEncryption, key1);
byte[] key2 = new byte[8];
Array.Copy(keyMaster, 8, key2, 0, key2.Length);
workingKey2 = GenerateWorkingKey(!forEncryption, key2);
if (keyMaster.Length == 24)
{
byte[] key3 = new byte[8];
Array.Copy(keyMaster, 16, key3, 0, key3.Length);
workingKey3 = GenerateWorkingKey(forEncryption, key3);
}
else // 16 byte key
{
workingKey3 = workingKey1;
}
}
public override string AlgorithmName
{
get { return "DESede"; }
}
public override int GetBlockSize()
{
return BLOCK_SIZE;
}
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, BLOCK_SIZE, "input buffer too short");
Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short");
uint hi32 = Pack.BE_To_UInt32(input, inOff);
uint lo32 = Pack.BE_To_UInt32(input, inOff + 4);
if (forEncryption)
{
DesFunc(workingKey1, ref hi32, ref lo32);
DesFunc(workingKey2, ref hi32, ref lo32);
DesFunc(workingKey3, ref hi32, ref lo32);
}
else
{
DesFunc(workingKey3, ref hi32, ref lo32);
DesFunc(workingKey2, ref hi32, ref lo32);
DesFunc(workingKey1, ref hi32, ref lo32);
}
Pack.UInt32_To_BE(hi32, output, outOff);
Pack.UInt32_To_BE(lo32, output, outOff + 4);
return BLOCK_SIZE;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public override int ProcessBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
if (workingKey1 == null)
throw new InvalidOperationException("DESede engine not initialised");
Check.DataLength(input, BLOCK_SIZE, "input buffer too short");
Check.OutputLength(output, BLOCK_SIZE, "output buffer too short");
uint hi32 = Pack.BE_To_UInt32(input);
uint lo32 = Pack.BE_To_UInt32(input[4..]);
if (forEncryption)
{
DesFunc(workingKey1, ref hi32, ref lo32);
DesFunc(workingKey2, ref hi32, ref lo32);
DesFunc(workingKey3, ref hi32, ref lo32);
}
else
{
DesFunc(workingKey3, ref hi32, ref lo32);
DesFunc(workingKey2, ref hi32, ref lo32);
DesFunc(workingKey1, ref hi32, ref lo32);
}
Pack.UInt32_To_BE(hi32, output);
Pack.UInt32_To_BE(lo32, output[4..]);
return BLOCK_SIZE;
}
#endif
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: b9d0b996a0682ff4d94de11de922e1b3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/DesEdeEngine.cs
uploadId: 783279

View File

@ -0,0 +1,325 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Modes;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/**
* Wrap keys according to
* <a href="http://www.ietf.org/internet-drafts/draft-ietf-smime-key-wrap-01.txt">
* draft-ietf-smime-key-wrap-01.txt</a>.
* <p>
* Note:
* <ul>
* <li>this is based on a draft, and as such is subject to change - don't use this class for anything requiring long term storage.</li>
* <li>if you are using this to wrap triple-des keys you need to set the
* parity bits on the key and, if it's a two-key triple-des key, pad it
* yourself.</li>
* </ul>
* </p>
*/
public class DesEdeWrapEngine
: IWrapper
{
/** Field engine */
private CbcBlockCipher engine;
/** Field param */
private KeyParameter param;
/** Field paramPlusIV */
private ParametersWithIV paramPlusIV;
/** Field iv */
private byte[] iv;
/** Field forWrapping */
private bool forWrapping;
/** Field IV2 */
private static readonly byte[] IV2 = { (byte) 0x4a, (byte) 0xdd, (byte) 0xa2,
(byte) 0x2c, (byte) 0x79, (byte) 0xe8,
(byte) 0x21, (byte) 0x05 };
//
// checksum digest
//
private readonly IDigest sha1 = new Sha1Digest();
private readonly byte[] digest = new byte[20];
/**
* Method init
*
* @param forWrapping
* @param param
*/
public virtual void Init(
bool forWrapping,
ICipherParameters parameters)
{
this.forWrapping = forWrapping;
this.engine = new CbcBlockCipher(new DesEdeEngine());
SecureRandom sr;
if (parameters is ParametersWithRandom pr)
{
parameters = pr.Parameters;
sr = pr.Random;
}
else
{
sr = CryptoServicesRegistrar.GetSecureRandom();
}
if (parameters is KeyParameter)
{
this.param = (KeyParameter) parameters;
if (this.forWrapping)
{
// Hm, we have no IV but we want to wrap ?!?
// well, then we have to create our own IV.
this.iv = new byte[8];
sr.NextBytes(iv);
this.paramPlusIV = new ParametersWithIV(this.param, this.iv);
}
}
else if (parameters is ParametersWithIV)
{
if (!forWrapping)
throw new ArgumentException("You should not supply an IV for unwrapping");
this.paramPlusIV = (ParametersWithIV) parameters;
this.iv = this.paramPlusIV.GetIV();
this.param = (KeyParameter) this.paramPlusIV.Parameters;
if (this.iv.Length != 8)
throw new ArgumentException("IV is not 8 octets", "parameters");
}
}
/**
* Method GetAlgorithmName
*
* @return
*/
public virtual string AlgorithmName
{
get { return "DESede"; }
}
/**
* Method wrap
*
* @param in
* @param inOff
* @param inLen
* @return
*/
public virtual byte[] Wrap(
byte[] input,
int inOff,
int length)
{
if (!forWrapping)
{
throw new InvalidOperationException("Not initialized for wrapping");
}
byte[] keyToBeWrapped = new byte[length];
Array.Copy(input, inOff, keyToBeWrapped, 0, length);
// Compute the CMS Key Checksum, (section 5.6.1), call this CKS.
byte[] CKS = CalculateCmsKeyChecksum(keyToBeWrapped);
// Let WKCKS = WK || CKS where || is concatenation.
byte[] WKCKS = new byte[keyToBeWrapped.Length + CKS.Length];
Array.Copy(keyToBeWrapped, 0, WKCKS, 0, keyToBeWrapped.Length);
Array.Copy(CKS, 0, WKCKS, keyToBeWrapped.Length, CKS.Length);
// Encrypt WKCKS in CBC mode using KEK as the key and IV as the
// initialization vector. Call the results TEMP1.
int blockSize = engine.GetBlockSize();
if (WKCKS.Length % blockSize != 0)
throw new InvalidOperationException("Not multiple of block length");
engine.Init(true, paramPlusIV);
byte [] TEMP1 = new byte[WKCKS.Length];
for (int currentBytePos = 0; currentBytePos != WKCKS.Length; currentBytePos += blockSize)
{
engine.ProcessBlock(WKCKS, currentBytePos, TEMP1, currentBytePos);
}
// Let TEMP2 = IV || TEMP1.
byte[] TEMP2 = new byte[this.iv.Length + TEMP1.Length];
Array.Copy(this.iv, 0, TEMP2, 0, this.iv.Length);
Array.Copy(TEMP1, 0, TEMP2, this.iv.Length, TEMP1.Length);
// Reverse the order of the octets in TEMP2 and call the result TEMP3.
byte[] TEMP3 = reverse(TEMP2);
// Encrypt TEMP3 in CBC mode using the KEK and an initialization vector
// of 0x 4a dd a2 2c 79 e8 21 05. The resulting cipher text is the desired
// result. It is 40 octets long if a 168 bit key is being wrapped.
ParametersWithIV param2 = new ParametersWithIV(this.param, IV2);
this.engine.Init(true, param2);
for (int currentBytePos = 0; currentBytePos != TEMP3.Length; currentBytePos += blockSize)
{
engine.ProcessBlock(TEMP3, currentBytePos, TEMP3, currentBytePos);
}
return TEMP3;
}
/**
* Method unwrap
*
* @param in
* @param inOff
* @param inLen
* @return
* @throws InvalidCipherTextException
*/
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);
}
/*
// Check if the length of the cipher text is reasonable given the key
// type. It must be 40 bytes for a 168 bit key and either 32, 40, or
// 48 bytes for a 128, 192, or 256 bit key. If the length is not supported
// or inconsistent with the algorithm for which the key is intended,
// return error.
//
// we do not accept 168 bit keys. it has to be 192 bit.
int lengthA = (estimatedKeyLengthInBit / 8) + 16;
int lengthB = estimatedKeyLengthInBit % 8;
if ((lengthA != keyToBeUnwrapped.Length) || (lengthB != 0)) {
throw new XMLSecurityException("empty");
}
*/
// Decrypt the cipher text with TRIPLedeS in CBC mode using the KEK
// and an initialization vector (IV) of 0x4adda22c79e82105. Call the output TEMP3.
ParametersWithIV param2 = new ParametersWithIV(this.param, IV2);
this.engine.Init(false, param2);
byte [] TEMP3 = new byte[length];
for (int currentBytePos = 0; currentBytePos != TEMP3.Length; currentBytePos += blockSize)
{
engine.ProcessBlock(input, inOff + currentBytePos, TEMP3, currentBytePos);
}
// Reverse the order of the octets in TEMP3 and call the result TEMP2.
byte[] TEMP2 = reverse(TEMP3);
// Decompose TEMP2 into IV, the first 8 octets, and TEMP1, the remaining octets.
this.iv = new byte[8];
byte[] TEMP1 = new byte[TEMP2.Length - 8];
Array.Copy(TEMP2, 0, this.iv, 0, 8);
Array.Copy(TEMP2, 8, TEMP1, 0, TEMP2.Length - 8);
// Decrypt TEMP1 using TRIPLedeS in CBC mode using the KEK and the IV
// found in the previous step. Call the result WKCKS.
this.paramPlusIV = new ParametersWithIV(this.param, this.iv);
this.engine.Init(false, this.paramPlusIV);
byte[] WKCKS = new byte[TEMP1.Length];
for (int currentBytePos = 0; currentBytePos != WKCKS.Length; currentBytePos += blockSize)
{
engine.ProcessBlock(TEMP1, currentBytePos, WKCKS, currentBytePos);
}
// Decompose WKCKS. CKS is the last 8 octets and WK, the wrapped key, are
// those octets before the CKS.
byte[] result = new byte[WKCKS.Length - 8];
byte[] CKStoBeVerified = new byte[8];
Array.Copy(WKCKS, 0, result, 0, WKCKS.Length - 8);
Array.Copy(WKCKS, WKCKS.Length - 8, CKStoBeVerified, 0, 8);
// Calculate a CMS Key Checksum, (section 5.6.1), over the WK and compare
// with the CKS extracted in the above step. If they are not equal, return error.
if (!CheckCmsKeyChecksum(result, CKStoBeVerified)) {
throw new InvalidCipherTextException(
"Checksum inside ciphertext is corrupted");
}
// WK is the wrapped key, now extracted for use in data decryption.
return result;
}
/**
* Some key wrap algorithms make use of the Key Checksum defined
* in CMS [CMS-Algorithms]. This is used to provide an integrity
* check value for the key being wrapped. The algorithm is
*
* - Compute the 20 octet SHA-1 hash on the key being wrapped.
* - Use the first 8 octets of this hash as the checksum value.
*
* @param key
* @return
* @throws Exception
* @see http://www.w3.org/TR/xmlenc-core/#sec-CMSKeyChecksum
*/
private byte[] CalculateCmsKeyChecksum(
byte[] key)
{
sha1.BlockUpdate(key, 0, key.Length);
sha1.DoFinal(digest, 0);
byte[] result = new byte[8];
Array.Copy(digest, 0, result, 0, 8);
return result;
}
/**
* @param key
* @param checksum
* @return
* @see http://www.w3.org/TR/xmlenc-core/#sec-CMSKeyChecksum
*/
private bool CheckCmsKeyChecksum(
byte[] key,
byte[] checksum)
{
return Arrays.ConstantTimeAreEqual(CalculateCmsKeyChecksum(key), checksum);
}
private static byte[] reverse(byte[] bs)
{
byte[] result = new byte[bs.Length];
for (int i = 0; i < bs.Length; i++)
{
result[i] = bs[bs.Length - (i + 1)];
}
return result;
}
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: ac227cca8981f48429e77f4680486f17
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/DesEdeWrapEngine.cs
uploadId: 783279

View File

@ -0,0 +1,485 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/// <remarks>A class that provides a basic DES engine.</remarks>
public class DesEngine
: IBlockCipher
{
internal const int BLOCK_SIZE = 8;
private int[] workingKey;
public virtual int[] GetWorkingKey()
{
return workingKey;
}
/**
* initialise a DES cipher.
*
* @param forEncryption whether or not we are for encryption.
* @param parameters the parameters required to set up the cipher.
* @exception ArgumentException if the parameters argument is
* inappropriate.
*/
public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
if (!(parameters is KeyParameter keyParameter))
throw new ArgumentException("invalid parameter passed to DES init - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters));
workingKey = GenerateWorkingKey(forEncryption, keyParameter.GetKey());
}
public virtual string AlgorithmName
{
get { return "DES"; }
}
public virtual int GetBlockSize()
{
return BLOCK_SIZE;
}
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, BLOCK_SIZE, "input buffer too short");
Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short");
uint hi32 = Pack.BE_To_UInt32(input, inOff);
uint lo32 = Pack.BE_To_UInt32(input, inOff + 4);
DesFunc(workingKey, ref hi32, ref lo32);
Pack.UInt32_To_BE(hi32, output, outOff);
Pack.UInt32_To_BE(lo32, output, outOff + 4);
return BLOCK_SIZE;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual int ProcessBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
if (workingKey == null)
throw new InvalidOperationException("DES engine not initialised");
Check.DataLength(input, BLOCK_SIZE, "input buffer too short");
Check.OutputLength(output, BLOCK_SIZE, "output buffer too short");
uint hi32 = Pack.BE_To_UInt32(input);
uint lo32 = Pack.BE_To_UInt32(input[4..]);
DesFunc(workingKey, ref hi32, ref lo32);
Pack.UInt32_To_BE(hi32, output);
Pack.UInt32_To_BE(lo32, output[4..]);
return BLOCK_SIZE;
}
#endif
/**
* what follows is mainly taken from "Applied Cryptography", by
* Bruce Schneier, however it also bears great resemblance to Richard
* Outerbridge's D3DES...
*/
// private static readonly short[] Df_Key =
// {
// 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
// 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
// 0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67
// };
private static readonly short[] bytebit =
{
128, 64, 32, 16, 8, 4, 2, 1
};
private static readonly int[] bigbyte =
{
0x800000, 0x400000, 0x200000, 0x100000,
0x80000, 0x40000, 0x20000, 0x10000,
0x8000, 0x4000, 0x2000, 0x1000,
0x800, 0x400, 0x200, 0x100,
0x80, 0x40, 0x20, 0x10,
0x8, 0x4, 0x2, 0x1
};
/*
* Use the key schedule specified in the Standard (ANSI X3.92-1981).
*/
private static readonly byte[] pc1 =
{
56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3
};
private static readonly byte[] totrot =
{
1, 2, 4, 6, 8, 10, 12, 14,
15, 17, 19, 21, 23, 25, 27, 28
};
private static readonly byte[] pc2 =
{
13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31
};
private static readonly uint[] SP1 =
{
0x01010400, 0x00000000, 0x00010000, 0x01010404,
0x01010004, 0x00010404, 0x00000004, 0x00010000,
0x00000400, 0x01010400, 0x01010404, 0x00000400,
0x01000404, 0x01010004, 0x01000000, 0x00000004,
0x00000404, 0x01000400, 0x01000400, 0x00010400,
0x00010400, 0x01010000, 0x01010000, 0x01000404,
0x00010004, 0x01000004, 0x01000004, 0x00010004,
0x00000000, 0x00000404, 0x00010404, 0x01000000,
0x00010000, 0x01010404, 0x00000004, 0x01010000,
0x01010400, 0x01000000, 0x01000000, 0x00000400,
0x01010004, 0x00010000, 0x00010400, 0x01000004,
0x00000400, 0x00000004, 0x01000404, 0x00010404,
0x01010404, 0x00010004, 0x01010000, 0x01000404,
0x01000004, 0x00000404, 0x00010404, 0x01010400,
0x00000404, 0x01000400, 0x01000400, 0x00000000,
0x00010004, 0x00010400, 0x00000000, 0x01010004
};
private static readonly uint[] SP2 =
{
0x80108020, 0x80008000, 0x00008000, 0x00108020,
0x00100000, 0x00000020, 0x80100020, 0x80008020,
0x80000020, 0x80108020, 0x80108000, 0x80000000,
0x80008000, 0x00100000, 0x00000020, 0x80100020,
0x00108000, 0x00100020, 0x80008020, 0x00000000,
0x80000000, 0x00008000, 0x00108020, 0x80100000,
0x00100020, 0x80000020, 0x00000000, 0x00108000,
0x00008020, 0x80108000, 0x80100000, 0x00008020,
0x00000000, 0x00108020, 0x80100020, 0x00100000,
0x80008020, 0x80100000, 0x80108000, 0x00008000,
0x80100000, 0x80008000, 0x00000020, 0x80108020,
0x00108020, 0x00000020, 0x00008000, 0x80000000,
0x00008020, 0x80108000, 0x00100000, 0x80000020,
0x00100020, 0x80008020, 0x80000020, 0x00100020,
0x00108000, 0x00000000, 0x80008000, 0x00008020,
0x80000000, 0x80100020, 0x80108020, 0x00108000
};
private static readonly uint[] SP3 =
{
0x00000208, 0x08020200, 0x00000000, 0x08020008,
0x08000200, 0x00000000, 0x00020208, 0x08000200,
0x00020008, 0x08000008, 0x08000008, 0x00020000,
0x08020208, 0x00020008, 0x08020000, 0x00000208,
0x08000000, 0x00000008, 0x08020200, 0x00000200,
0x00020200, 0x08020000, 0x08020008, 0x00020208,
0x08000208, 0x00020200, 0x00020000, 0x08000208,
0x00000008, 0x08020208, 0x00000200, 0x08000000,
0x08020200, 0x08000000, 0x00020008, 0x00000208,
0x00020000, 0x08020200, 0x08000200, 0x00000000,
0x00000200, 0x00020008, 0x08020208, 0x08000200,
0x08000008, 0x00000200, 0x00000000, 0x08020008,
0x08000208, 0x00020000, 0x08000000, 0x08020208,
0x00000008, 0x00020208, 0x00020200, 0x08000008,
0x08020000, 0x08000208, 0x00000208, 0x08020000,
0x00020208, 0x00000008, 0x08020008, 0x00020200
};
private static readonly uint[] SP4 =
{
0x00802001, 0x00002081, 0x00002081, 0x00000080,
0x00802080, 0x00800081, 0x00800001, 0x00002001,
0x00000000, 0x00802000, 0x00802000, 0x00802081,
0x00000081, 0x00000000, 0x00800080, 0x00800001,
0x00000001, 0x00002000, 0x00800000, 0x00802001,
0x00000080, 0x00800000, 0x00002001, 0x00002080,
0x00800081, 0x00000001, 0x00002080, 0x00800080,
0x00002000, 0x00802080, 0x00802081, 0x00000081,
0x00800080, 0x00800001, 0x00802000, 0x00802081,
0x00000081, 0x00000000, 0x00000000, 0x00802000,
0x00002080, 0x00800080, 0x00800081, 0x00000001,
0x00802001, 0x00002081, 0x00002081, 0x00000080,
0x00802081, 0x00000081, 0x00000001, 0x00002000,
0x00800001, 0x00002001, 0x00802080, 0x00800081,
0x00002001, 0x00002080, 0x00800000, 0x00802001,
0x00000080, 0x00800000, 0x00002000, 0x00802080
};
private static readonly uint[] SP5 =
{
0x00000100, 0x02080100, 0x02080000, 0x42000100,
0x00080000, 0x00000100, 0x40000000, 0x02080000,
0x40080100, 0x00080000, 0x02000100, 0x40080100,
0x42000100, 0x42080000, 0x00080100, 0x40000000,
0x02000000, 0x40080000, 0x40080000, 0x00000000,
0x40000100, 0x42080100, 0x42080100, 0x02000100,
0x42080000, 0x40000100, 0x00000000, 0x42000000,
0x02080100, 0x02000000, 0x42000000, 0x00080100,
0x00080000, 0x42000100, 0x00000100, 0x02000000,
0x40000000, 0x02080000, 0x42000100, 0x40080100,
0x02000100, 0x40000000, 0x42080000, 0x02080100,
0x40080100, 0x00000100, 0x02000000, 0x42080000,
0x42080100, 0x00080100, 0x42000000, 0x42080100,
0x02080000, 0x00000000, 0x40080000, 0x42000000,
0x00080100, 0x02000100, 0x40000100, 0x00080000,
0x00000000, 0x40080000, 0x02080100, 0x40000100
};
private static readonly uint[] SP6 =
{
0x20000010, 0x20400000, 0x00004000, 0x20404010,
0x20400000, 0x00000010, 0x20404010, 0x00400000,
0x20004000, 0x00404010, 0x00400000, 0x20000010,
0x00400010, 0x20004000, 0x20000000, 0x00004010,
0x00000000, 0x00400010, 0x20004010, 0x00004000,
0x00404000, 0x20004010, 0x00000010, 0x20400010,
0x20400010, 0x00000000, 0x00404010, 0x20404000,
0x00004010, 0x00404000, 0x20404000, 0x20000000,
0x20004000, 0x00000010, 0x20400010, 0x00404000,
0x20404010, 0x00400000, 0x00004010, 0x20000010,
0x00400000, 0x20004000, 0x20000000, 0x00004010,
0x20000010, 0x20404010, 0x00404000, 0x20400000,
0x00404010, 0x20404000, 0x00000000, 0x20400010,
0x00000010, 0x00004000, 0x20400000, 0x00404010,
0x00004000, 0x00400010, 0x20004010, 0x00000000,
0x20404000, 0x20000000, 0x00400010, 0x20004010
};
private static readonly uint[] SP7 =
{
0x00200000, 0x04200002, 0x04000802, 0x00000000,
0x00000800, 0x04000802, 0x00200802, 0x04200800,
0x04200802, 0x00200000, 0x00000000, 0x04000002,
0x00000002, 0x04000000, 0x04200002, 0x00000802,
0x04000800, 0x00200802, 0x00200002, 0x04000800,
0x04000002, 0x04200000, 0x04200800, 0x00200002,
0x04200000, 0x00000800, 0x00000802, 0x04200802,
0x00200800, 0x00000002, 0x04000000, 0x00200800,
0x04000000, 0x00200800, 0x00200000, 0x04000802,
0x04000802, 0x04200002, 0x04200002, 0x00000002,
0x00200002, 0x04000000, 0x04000800, 0x00200000,
0x04200800, 0x00000802, 0x00200802, 0x04200800,
0x00000802, 0x04000002, 0x04200802, 0x04200000,
0x00200800, 0x00000000, 0x00000002, 0x04200802,
0x00000000, 0x00200802, 0x04200000, 0x00000800,
0x04000002, 0x04000800, 0x00000800, 0x00200002
};
private static readonly uint[] SP8 =
{
0x10001040, 0x00001000, 0x00040000, 0x10041040,
0x10000000, 0x10001040, 0x00000040, 0x10000000,
0x00040040, 0x10040000, 0x10041040, 0x00041000,
0x10041000, 0x00041040, 0x00001000, 0x00000040,
0x10040000, 0x10000040, 0x10001000, 0x00001040,
0x00041000, 0x00040040, 0x10040040, 0x10041000,
0x00001040, 0x00000000, 0x00000000, 0x10040040,
0x10000040, 0x10001000, 0x00041040, 0x00040000,
0x00041040, 0x00040000, 0x10041000, 0x00001000,
0x00000040, 0x10040040, 0x00001000, 0x00041040,
0x10001000, 0x00000040, 0x10000040, 0x10040000,
0x10040040, 0x10000000, 0x00040000, 0x10001040,
0x00000000, 0x10041040, 0x00040040, 0x10000040,
0x10040000, 0x10001000, 0x10001040, 0x00000000,
0x10041040, 0x00041000, 0x00041000, 0x00001040,
0x00001040, 0x00040040, 0x10000000, 0x10041000
};
/**
* Generate an integer based working key based on our secret key
* and what we processing we are planning to do.
*
* Acknowledgements for this routine go to James Gillogly and Phil Karn.
* (whoever, and wherever they are!).
*/
protected static int[] GenerateWorkingKey(
bool encrypting,
byte[] key)
{
int[] newKey = new int[32];
bool[] pc1m = new bool[56];
bool[] pcr = new bool[56];
for (int j = 0; j < 56; j++ )
{
int l = pc1[j];
pc1m[j] = ((key[(uint) l >> 3] & bytebit[l & 07]) != 0);
}
for (int i = 0; i < 16; i++)
{
int l, m, n;
if (encrypting)
{
m = i << 1;
}
else
{
m = (15 - i) << 1;
}
n = m + 1;
newKey[m] = newKey[n] = 0;
for (int j = 0; j < 28; j++)
{
l = j + totrot[i];
if ( l < 28 )
{
pcr[j] = pc1m[l];
}
else
{
pcr[j] = pc1m[l - 28];
}
}
for (int j = 28; j < 56; j++)
{
l = j + totrot[i];
if (l < 56 )
{
pcr[j] = pc1m[l];
}
else
{
pcr[j] = pc1m[l - 28];
}
}
for (int j = 0; j < 24; j++)
{
if (pcr[pc2[j]])
{
newKey[m] |= bigbyte[j];
}
if (pcr[pc2[j + 24]])
{
newKey[n] |= bigbyte[j];
}
}
}
//
// store the processed key
//
for (int i = 0; i != 32; i += 2)
{
int i1, i2;
i1 = newKey[i];
i2 = newKey[i + 1];
newKey[i] = (int) ( (uint) ((i1 & 0x00fc0000) << 6) |
(uint) ((i1 & 0x00000fc0) << 10) |
((uint) (i2 & 0x00fc0000) >> 10) |
((uint) (i2 & 0x00000fc0) >> 6));
newKey[i + 1] = (int) ( (uint) ((i1 & 0x0003f000) << 12) |
(uint) ((i1 & 0x0000003f) << 16) |
((uint) (i2 & 0x0003f000) >> 4) |
(uint) (i2 & 0x0000003f));
}
return newKey;
}
internal static void DesFunc(int[] wKey, ref uint hi32, ref uint lo32)
{
uint left = hi32;
uint right = lo32;
uint work;
work = ((left >> 4) ^ right) & 0x0f0f0f0f;
right ^= work;
left ^= (work << 4);
work = ((left >> 16) ^ right) & 0x0000ffff;
right ^= work;
left ^= (work << 16);
work = ((right >> 2) ^ left) & 0x33333333;
left ^= work;
right ^= (work << 2);
work = ((right >> 8) ^ left) & 0x00ff00ff;
left ^= work;
right ^= (work << 8);
right = (right << 1) | (right >> 31);
work = (left ^ right) & 0xaaaaaaaa;
left ^= work;
right ^= work;
left = (left << 1) | (left >> 31);
for (int round = 0; round < 8; round++)
{
uint fval;
work = (right << 28) | (right >> 4);
work ^= (uint)wKey[round * 4 + 0];
fval = SP7[work & 0x3f];
fval |= SP5[(work >> 8) & 0x3f];
fval |= SP3[(work >> 16) & 0x3f];
fval |= SP1[(work >> 24) & 0x3f];
work = right ^ (uint)wKey[round * 4 + 1];
fval |= SP8[ work & 0x3f];
fval |= SP6[(work >> 8) & 0x3f];
fval |= SP4[(work >> 16) & 0x3f];
fval |= SP2[(work >> 24) & 0x3f];
left ^= fval;
work = (left << 28) | (left >> 4);
work ^= (uint)wKey[round * 4 + 2];
fval = SP7[ work & 0x3f];
fval |= SP5[(work >> 8) & 0x3f];
fval |= SP3[(work >> 16) & 0x3f];
fval |= SP1[(work >> 24) & 0x3f];
work = left ^ (uint)wKey[round * 4 + 3];
fval |= SP8[ work & 0x3f];
fval |= SP6[(work >> 8) & 0x3f];
fval |= SP4[(work >> 16) & 0x3f];
fval |= SP2[(work >> 24) & 0x3f];
right ^= fval;
}
right = (right << 31) | (right >> 1);
work = (left ^ right) & 0xaaaaaaaa;
left ^= work;
right ^= work;
left = (left << 31) | (left >> 1);
work = ((left >> 8) ^ right) & 0x00ff00ff;
right ^= work;
left ^= (work << 8);
work = ((left >> 2) ^ right) & 0x33333333;
right ^= work;
left ^= (work << 2);
work = ((right >> 16) ^ left) & 0x0000ffff;
left ^= work;
right ^= (work << 16);
work = ((right >> 4) ^ left) & 0x0f0f0f0f;
left ^= work;
right ^= (work << 4);
hi32 = right;
lo32 = left;
}
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: f64e1c4494ede7341a55137f5ffa2423
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/DesEngine.cs
uploadId: 783279

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: a37d3ab8260c4ab4691df35eea1003e5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/Dstu7624Engine.cs
uploadId: 783279

View File

@ -0,0 +1,220 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.Collections.Generic;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
public class Dstu7624WrapEngine
: IWrapper
{
private KeyParameter param;
private Dstu7624Engine engine;
private bool forWrapping;
private int blockSize;
public Dstu7624WrapEngine(int blockSizeBits)
{
engine = new Dstu7624Engine(blockSizeBits);
param = null;
blockSize = blockSizeBits / 8;
}
public string AlgorithmName
{
get { return "Dstu7624WrapEngine"; }
}
public void Init(bool forWrapping, ICipherParameters parameters)
{
this.forWrapping = forWrapping;
if (parameters is KeyParameter)
{
this.param = (KeyParameter)parameters;
engine.Init(forWrapping, param);
}
else
{
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 n = 2 * (1 + length / blockSize);
int V = (n - 1) * 6;
byte[] buffer = new byte[length + blockSize];
Array.Copy(input, inOff, buffer, 0, length);
//Console.WriteLine(Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(buffer));
byte[] B = new byte[blockSize / 2];
Array.Copy(buffer, 0, B, 0, blockSize / 2);
//Console.WriteLine("B0: "+ Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(B));
var bTemp = new List<byte[]>();
int bHalfBlocksLen = buffer.Length - blockSize / 2;
int bufOff = blockSize / 2;
while (bHalfBlocksLen != 0)
{
byte[] temp = new byte[blockSize / 2];
Array.Copy(buffer, bufOff, temp, 0, blockSize / 2);
//Console.WriteLine(Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(buffer));
//Console.WriteLine(buffer.Length);
//Console.WriteLine("b: " + Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(temp));
bTemp.Add(temp);
bHalfBlocksLen -= blockSize / 2;
bufOff += blockSize / 2;
}
for (int j = 0; j < V; j++)
{
Array.Copy(B, 0, buffer, 0, blockSize / 2);
Array.Copy(bTemp[0], 0, buffer, blockSize / 2, blockSize / 2);
engine.ProcessBlock(buffer, 0, buffer, 0);
byte[] intArray = Pack.UInt32_To_LE((uint)(j + 1));
for (int byteNum = 0; byteNum < intArray.Length; byteNum++)
{
buffer[byteNum + blockSize / 2] ^= intArray[byteNum];
}
Array.Copy(buffer, blockSize / 2, B, 0, blockSize / 2);
for (int i = 2; i < n; i++)
{
Array.Copy(bTemp[i - 1], 0, bTemp[i - 2], 0, blockSize / 2);
}
Array.Copy(buffer, 0, bTemp[n - 2], 0, blockSize / 2);
//Console.WriteLine("B" + j.ToString() + ": " + Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(B));
//Console.WriteLine("b: " + Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(bTemp[0]));
//Console.WriteLine("b: " + Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(bTemp[1]));
//Console.WriteLine("b: " + Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(bTemp[2]));
//Console.WriteLine(Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(buffer));
}
Array.Copy(B, 0, buffer, 0, blockSize / 2);
bufOff = blockSize / 2;
for (int i = 0; i < n - 1; i++)
{
Array.Copy((byte[])bTemp[i], 0, buffer, bufOff, blockSize / 2);
bufOff += blockSize / 2;
}
return buffer;
}
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 n = 2 * length / blockSize;
int V = (n - 1) * 6;
byte[] buffer = new byte[length];
Array.Copy(input, inOff, buffer, 0, length);
byte[] B = new byte[blockSize / 2];
Array.Copy(buffer, 0, B, 0, blockSize / 2);
//Console.WriteLine("B18: " + Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(B));
var bTemp = new List<byte[]>();
int bHalfBlocksLen = buffer.Length - blockSize / 2;
int bufOff = blockSize / 2;
while (bHalfBlocksLen != 0)
{
byte[] temp = new byte[blockSize / 2];
Array.Copy(buffer, bufOff, temp, 0, blockSize / 2);
//Console.WriteLine(Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(buffer));
//Console.WriteLine(buffer.Length);
//Console.WriteLine("b: " + Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(temp));
bTemp.Add(temp);
bHalfBlocksLen -= blockSize / 2;
bufOff += blockSize / 2;
}
for (int j = 0; j < V; j++)
{
Array.Copy(bTemp[n - 2], 0, buffer, 0, blockSize / 2);
Array.Copy(B, 0, buffer, blockSize / 2, blockSize / 2);
byte[] intArray = Pack.UInt32_To_LE((uint)(V - j));
for (int byteNum = 0; byteNum < intArray.Length; byteNum++)
{
buffer[byteNum + blockSize / 2] ^= intArray[byteNum];
}
//Console.WriteLine(Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(buffer));
engine.ProcessBlock(buffer, 0, buffer, 0);
//Console.WriteLine(Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(buffer));
Array.Copy(buffer, 0, B, 0, blockSize / 2);
for (int i = 2; i < n; i++)
{
Array.Copy(bTemp[n - i - 1], 0, bTemp[n - i], 0, blockSize / 2);
}
Array.Copy(buffer, blockSize / 2, bTemp[0], 0, blockSize / 2);
//Console.WriteLine("B" + (V - j - 1).ToString() + ": " + Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(B));
//Console.WriteLine("b: " + Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(bTemp[0]));
//Console.WriteLine("b: " + Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(bTemp[1]));
//Console.WriteLine("b: " + Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(bTemp[2]));
//Console.WriteLine(Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(buffer));
}
Array.Copy(B, 0, buffer, 0, blockSize / 2);
bufOff = blockSize / 2;
for (int i = 0; i < n - 1; i++)
{
Array.Copy(bTemp[i], 0, buffer, bufOff, blockSize / 2);
bufOff += blockSize / 2;
}
byte diff = 0;
for (int i = buffer.Length - blockSize; i < buffer.Length; ++i)
{
diff |= buffer[i];
}
if (diff != 0)
throw new InvalidCipherTextException("checksum failed");
return Arrays.CopyOfRange(buffer, 0, buffer.Length - blockSize);
}
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 4c25d6f2f18628440944a37eeb445662
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/Dstu7624WrapEngine.cs
uploadId: 783279

View File

@ -0,0 +1,174 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/**
* this does your basic ElGamal algorithm.
*/
public class ElGamalEngine
: IAsymmetricBlockCipher
{
private ElGamalKeyParameters key;
private SecureRandom random;
private bool forEncryption;
private int bitSize;
public virtual string AlgorithmName
{
get { return "ElGamal"; }
}
/**
* initialise the ElGamal engine.
*
* @param forEncryption true if we are encrypting, false otherwise.
* @param param the necessary ElGamal key parameters.
*/
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
if (parameters is ParametersWithRandom withRandom)
{
this.key = (ElGamalKeyParameters)withRandom.Parameters;
this.random = withRandom.Random;
}
else
{
this.key = (ElGamalKeyParameters)parameters;
this.random = CryptoServicesRegistrar.GetSecureRandom();
}
this.forEncryption = forEncryption;
this.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.");
}
}
/**
* Return the maximum size for an input block to this engine.
* For ElGamal this is always one byte less than the size of P on
* encryption, and twice the length as the size of P on decryption.
*
* @return maximum size for an input block.
*/
public virtual int GetInputBlockSize()
{
if (forEncryption)
{
return (bitSize - 1) / 8;
}
return 2 * ((bitSize + 7) / 8);
}
/**
* Return the maximum size for an output block to this engine.
* For ElGamal this is always one byte less than the size of P on
* decryption, and twice the length as the size of P on encryption.
*
* @return maximum size for an output block.
*/
public virtual int GetOutputBlockSize()
{
if (forEncryption)
{
return 2 * ((bitSize + 7) / 8);
}
return (bitSize - 1) / 8;
}
/**
* Process a single block using the basic ElGamal algorithm.
*
* @param in the input array.
* @param inOff the offset into the input buffer where the data starts.
* @param length the length of the data to be processed.
* @return the result of the ElGamal process.
* @exception DataLengthException the input block is too large.
*/
public virtual byte[] ProcessBlock(
byte[] input,
int inOff,
int length)
{
if (key == null)
throw new InvalidOperationException("ElGamal engine not initialised");
int maxLength = forEncryption
? (bitSize - 1 + 7) / 8
: GetInputBlockSize();
if (length > maxLength)
throw new DataLengthException("input too large for ElGamal cipher.\n");
BigInteger p = key.Parameters.P;
byte[] output;
if (key is ElGamalPrivateKeyParameters) // decryption
{
int halfLength = length / 2;
BigInteger gamma = new BigInteger(1, input, inOff, halfLength);
BigInteger phi = new BigInteger(1, input, inOff + halfLength, halfLength);
ElGamalPrivateKeyParameters priv = (ElGamalPrivateKeyParameters) key;
// a shortcut, which generally relies on p being prime amongst other things.
// if a problem with this shows up, check the p and g values!
BigInteger m = gamma.ModPow(p.Subtract(BigInteger.One).Subtract(priv.X), p).Multiply(phi).Mod(p);
output = m.ToByteArrayUnsigned();
}
else // encryption
{
BigInteger tmp = new BigInteger(1, input, inOff, length);
if (tmp.BitLength >= p.BitLength)
throw new DataLengthException("input too large for ElGamal cipher.\n");
ElGamalPublicKeyParameters pub = (ElGamalPublicKeyParameters) key;
BigInteger pSub2 = p.Subtract(BigInteger.Two);
// TODO In theory, a series of 'k', 'g.ModPow(k, p)' and 'y.ModPow(k, p)' can be pre-calculated
BigInteger k;
do
{
k = new BigInteger(p.BitLength, random);
}
while (k.SignValue == 0 || k.CompareTo(pSub2) > 0);
BigInteger g = key.Parameters.G;
BigInteger gamma = g.ModPow(k, p);
BigInteger phi = tmp.Multiply(pub.Y.ModPow(k, p)).Mod(p);
output = new byte[this.GetOutputBlockSize()];
// TODO Add methods to allow writing BigInteger to existing byte array?
byte[] out1 = gamma.ToByteArrayUnsigned();
byte[] out2 = phi.ToByteArrayUnsigned();
out1.CopyTo(output, output.Length / 2 - out1.Length);
out2.CopyTo(output, output.Length - out2.Length);
}
return output;
}
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: b48ee2c2b53e0384582a6c21e3386d2f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/ElGamalEngine.cs
uploadId: 783279

View File

@ -0,0 +1,408 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.Collections.Generic;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/**
* implementation of GOST 28147-89
*/
public class Gost28147Engine
: IBlockCipher
{
private const int BlockSize = 8;
private int[] workingKey = null;
private bool forEncryption;
private byte[] S = Sbox_Default;
// these are the S-boxes given in Applied Cryptography 2nd Ed., p. 333
// This is default S-box!
private static readonly byte[] Sbox_Default = {
0x4,0xA,0x9,0x2,0xD,0x8,0x0,0xE,0x6,0xB,0x1,0xC,0x7,0xF,0x5,0x3,
0xE,0xB,0x4,0xC,0x6,0xD,0xF,0xA,0x2,0x3,0x8,0x1,0x0,0x7,0x5,0x9,
0x5,0x8,0x1,0xD,0xA,0x3,0x4,0x2,0xE,0xF,0xC,0x7,0x6,0x0,0x9,0xB,
0x7,0xD,0xA,0x1,0x0,0x8,0x9,0xF,0xE,0x4,0x6,0xC,0xB,0x2,0x5,0x3,
0x6,0xC,0x7,0x1,0x5,0xF,0xD,0x8,0x4,0xA,0x9,0xE,0x0,0x3,0xB,0x2,
0x4,0xB,0xA,0x0,0x7,0x2,0x1,0xD,0x3,0x6,0x8,0x5,0x9,0xC,0xF,0xE,
0xD,0xB,0x4,0x1,0x3,0xF,0x5,0x9,0x0,0xA,0xE,0x7,0x6,0x8,0x2,0xC,
0x1,0xF,0xD,0x0,0x5,0x7,0xA,0x4,0x9,0x2,0x3,0xE,0x6,0xB,0x8,0xC
};
/*
* class content S-box parameters for encrypting
* getting from, see: http://tools.ietf.org/id/draft-popov-cryptopro-cpalgs-01.txt
* http://tools.ietf.org/id/draft-popov-cryptopro-cpalgs-02.txt
*/
private static readonly byte[] ESbox_Test = {
0x4,0x2,0xF,0x5,0x9,0x1,0x0,0x8,0xE,0x3,0xB,0xC,0xD,0x7,0xA,0x6,
0xC,0x9,0xF,0xE,0x8,0x1,0x3,0xA,0x2,0x7,0x4,0xD,0x6,0x0,0xB,0x5,
0xD,0x8,0xE,0xC,0x7,0x3,0x9,0xA,0x1,0x5,0x2,0x4,0x6,0xF,0x0,0xB,
0xE,0x9,0xB,0x2,0x5,0xF,0x7,0x1,0x0,0xD,0xC,0x6,0xA,0x4,0x3,0x8,
0x3,0xE,0x5,0x9,0x6,0x8,0x0,0xD,0xA,0xB,0x7,0xC,0x2,0x1,0xF,0x4,
0x8,0xF,0x6,0xB,0x1,0x9,0xC,0x5,0xD,0x3,0x7,0xA,0x0,0xE,0x2,0x4,
0x9,0xB,0xC,0x0,0x3,0x6,0x7,0x5,0x4,0x8,0xE,0xF,0x1,0xA,0x2,0xD,
0xC,0x6,0x5,0x2,0xB,0x0,0x9,0xD,0x3,0xE,0x7,0xA,0xF,0x4,0x1,0x8
};
private static readonly byte[] ESbox_A = {
0x9,0x6,0x3,0x2,0x8,0xB,0x1,0x7,0xA,0x4,0xE,0xF,0xC,0x0,0xD,0x5,
0x3,0x7,0xE,0x9,0x8,0xA,0xF,0x0,0x5,0x2,0x6,0xC,0xB,0x4,0xD,0x1,
0xE,0x4,0x6,0x2,0xB,0x3,0xD,0x8,0xC,0xF,0x5,0xA,0x0,0x7,0x1,0x9,
0xE,0x7,0xA,0xC,0xD,0x1,0x3,0x9,0x0,0x2,0xB,0x4,0xF,0x8,0x5,0x6,
0xB,0x5,0x1,0x9,0x8,0xD,0xF,0x0,0xE,0x4,0x2,0x3,0xC,0x7,0xA,0x6,
0x3,0xA,0xD,0xC,0x1,0x2,0x0,0xB,0x7,0x5,0x9,0x4,0x8,0xF,0xE,0x6,
0x1,0xD,0x2,0x9,0x7,0xA,0x6,0x0,0x8,0xC,0x4,0x5,0xF,0x3,0xB,0xE,
0xB,0xA,0xF,0x5,0x0,0xC,0xE,0x8,0x6,0x2,0x3,0x9,0x1,0x7,0xD,0x4
};
private static readonly byte[] ESbox_B = {
0x8,0x4,0xB,0x1,0x3,0x5,0x0,0x9,0x2,0xE,0xA,0xC,0xD,0x6,0x7,0xF,
0x0,0x1,0x2,0xA,0x4,0xD,0x5,0xC,0x9,0x7,0x3,0xF,0xB,0x8,0x6,0xE,
0xE,0xC,0x0,0xA,0x9,0x2,0xD,0xB,0x7,0x5,0x8,0xF,0x3,0x6,0x1,0x4,
0x7,0x5,0x0,0xD,0xB,0x6,0x1,0x2,0x3,0xA,0xC,0xF,0x4,0xE,0x9,0x8,
0x2,0x7,0xC,0xF,0x9,0x5,0xA,0xB,0x1,0x4,0x0,0xD,0x6,0x8,0xE,0x3,
0x8,0x3,0x2,0x6,0x4,0xD,0xE,0xB,0xC,0x1,0x7,0xF,0xA,0x0,0x9,0x5,
0x5,0x2,0xA,0xB,0x9,0x1,0xC,0x3,0x7,0x4,0xD,0x0,0x6,0xF,0x8,0xE,
0x0,0x4,0xB,0xE,0x8,0x3,0x7,0x1,0xA,0x2,0x9,0x6,0xF,0xD,0x5,0xC
};
private static readonly byte[] ESbox_C = {
0x1,0xB,0xC,0x2,0x9,0xD,0x0,0xF,0x4,0x5,0x8,0xE,0xA,0x7,0x6,0x3,
0x0,0x1,0x7,0xD,0xB,0x4,0x5,0x2,0x8,0xE,0xF,0xC,0x9,0xA,0x6,0x3,
0x8,0x2,0x5,0x0,0x4,0x9,0xF,0xA,0x3,0x7,0xC,0xD,0x6,0xE,0x1,0xB,
0x3,0x6,0x0,0x1,0x5,0xD,0xA,0x8,0xB,0x2,0x9,0x7,0xE,0xF,0xC,0x4,
0x8,0xD,0xB,0x0,0x4,0x5,0x1,0x2,0x9,0x3,0xC,0xE,0x6,0xF,0xA,0x7,
0xC,0x9,0xB,0x1,0x8,0xE,0x2,0x4,0x7,0x3,0x6,0x5,0xA,0x0,0xF,0xD,
0xA,0x9,0x6,0x8,0xD,0xE,0x2,0x0,0xF,0x3,0x5,0xB,0x4,0x1,0xC,0x7,
0x7,0x4,0x0,0x5,0xA,0x2,0xF,0xE,0xC,0x6,0x1,0xB,0xD,0x9,0x3,0x8
};
private static readonly byte[] ESbox_D = {
0xF,0xC,0x2,0xA,0x6,0x4,0x5,0x0,0x7,0x9,0xE,0xD,0x1,0xB,0x8,0x3,
0xB,0x6,0x3,0x4,0xC,0xF,0xE,0x2,0x7,0xD,0x8,0x0,0x5,0xA,0x9,0x1,
0x1,0xC,0xB,0x0,0xF,0xE,0x6,0x5,0xA,0xD,0x4,0x8,0x9,0x3,0x7,0x2,
0x1,0x5,0xE,0xC,0xA,0x7,0x0,0xD,0x6,0x2,0xB,0x4,0x9,0x3,0xF,0x8,
0x0,0xC,0x8,0x9,0xD,0x2,0xA,0xB,0x7,0x3,0x6,0x5,0x4,0xE,0xF,0x1,
0x8,0x0,0xF,0x3,0x2,0x5,0xE,0xB,0x1,0xA,0x4,0x7,0xC,0x9,0xD,0x6,
0x3,0x0,0x6,0xF,0x1,0xE,0x9,0x2,0xD,0x8,0xC,0x4,0xB,0xA,0x5,0x7,
0x1,0xA,0x6,0x8,0xF,0xB,0x0,0x4,0xC,0x3,0x5,0x9,0x7,0xD,0x2,0xE
};
//S-box for digest
private static readonly byte[] DSbox_Test = {
0x4,0xA,0x9,0x2,0xD,0x8,0x0,0xE,0x6,0xB,0x1,0xC,0x7,0xF,0x5,0x3,
0xE,0xB,0x4,0xC,0x6,0xD,0xF,0xA,0x2,0x3,0x8,0x1,0x0,0x7,0x5,0x9,
0x5,0x8,0x1,0xD,0xA,0x3,0x4,0x2,0xE,0xF,0xC,0x7,0x6,0x0,0x9,0xB,
0x7,0xD,0xA,0x1,0x0,0x8,0x9,0xF,0xE,0x4,0x6,0xC,0xB,0x2,0x5,0x3,
0x6,0xC,0x7,0x1,0x5,0xF,0xD,0x8,0x4,0xA,0x9,0xE,0x0,0x3,0xB,0x2,
0x4,0xB,0xA,0x0,0x7,0x2,0x1,0xD,0x3,0x6,0x8,0x5,0x9,0xC,0xF,0xE,
0xD,0xB,0x4,0x1,0x3,0xF,0x5,0x9,0x0,0xA,0xE,0x7,0x6,0x8,0x2,0xC,
0x1,0xF,0xD,0x0,0x5,0x7,0xA,0x4,0x9,0x2,0x3,0xE,0x6,0xB,0x8,0xC
};
private static readonly byte[] DSbox_A = {
0xA,0x4,0x5,0x6,0x8,0x1,0x3,0x7,0xD,0xC,0xE,0x0,0x9,0x2,0xB,0xF,
0x5,0xF,0x4,0x0,0x2,0xD,0xB,0x9,0x1,0x7,0x6,0x3,0xC,0xE,0xA,0x8,
0x7,0xF,0xC,0xE,0x9,0x4,0x1,0x0,0x3,0xB,0x5,0x2,0x6,0xA,0x8,0xD,
0x4,0xA,0x7,0xC,0x0,0xF,0x2,0x8,0xE,0x1,0x6,0x5,0xD,0xB,0x9,0x3,
0x7,0x6,0x4,0xB,0x9,0xC,0x2,0xA,0x1,0x8,0x0,0xE,0xF,0xD,0x3,0x5,
0x7,0x6,0x2,0x4,0xD,0x9,0xF,0x0,0xA,0x1,0x5,0xB,0x8,0xE,0xC,0x3,
0xD,0xE,0x4,0x1,0x7,0x0,0x5,0xA,0x3,0xC,0x8,0xF,0x6,0x2,0x9,0xB,
0x1,0x3,0xA,0x9,0x5,0xB,0x4,0xF,0x8,0x6,0x7,0xE,0xD,0x0,0x2,0xC
};
//
// pre-defined sbox table
//
private static readonly Dictionary<string, byte[]> m_sBoxes =
new Dictionary<string, byte[]>(StringComparer.OrdinalIgnoreCase);
static Gost28147Engine()
{
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)
{
m_sBoxes.Add(sBoxName, sBox);
}
/**
* standard constructor.
*/
public Gost28147Engine()
{
}
/**
* initialise an Gost28147 cipher.
*
* @param forEncryption whether or not we are for encryption.
* @param parameters the parameters required to set up the cipher.
* @exception ArgumentException if the parameters argument is inappropriate.
*/
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
if (parameters is ParametersWithSBox param)
{
//
// Set the S-Box
//
byte[] sBox = param.GetSBox();
if (sBox.Length != Sbox_Default.Length)
throw new ArgumentException("invalid S-box passed to GOST28147 init");
this.S = Arrays.Clone(sBox);
//
// set key if there is one
//
if (param.Parameters != null)
{
workingKey = GenerateWorkingKey(forEncryption, ((KeyParameter)param.Parameters).GetKey());
}
}
else if (parameters is KeyParameter keyParameter)
{
workingKey = GenerateWorkingKey(forEncryption, keyParameter.GetKey());
}
else if (parameters != null)
{
throw new ArgumentException("invalid parameter passed to Gost28147 init - "
+ Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters));
}
}
public virtual string AlgorithmName
{
get { return "Gost28147"; }
}
public virtual int GetBlockSize()
{
return BlockSize;
}
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, BlockSize, "input buffer too short");
Check.OutputLength(output, outOff, BlockSize, "output buffer too short");
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
Gost28147Func(workingKey, input.AsSpan(inOff), output.AsSpan(outOff));
#else
Gost28147Func(workingKey, input, inOff, output, outOff);
#endif
return BlockSize;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual int ProcessBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
if (workingKey == null)
throw new InvalidOperationException("Gost28147 engine not initialised");
Check.DataLength(input, BlockSize, "input buffer too short");
Check.OutputLength(output, BlockSize, "output buffer too short");
Gost28147Func(workingKey, input, output);
return BlockSize;
}
#endif
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[] key = new int[8];
for(int i=0; i != 8; i++)
{
key[i] = (int)Pack.LE_To_UInt32(userKey, i * 4);
}
return key;
}
private int Gost28147_mainStep(int n1, int key)
{
int cm = (key + n1); // CM1
// S-box replacing
int om = S[ 0 + ((cm >> (0 * 4)) & 0xF)] << (0 * 4);
om += S[ 16 + ((cm >> (1 * 4)) & 0xF)] << (1 * 4);
om += S[ 32 + ((cm >> (2 * 4)) & 0xF)] << (2 * 4);
om += S[ 48 + ((cm >> (3 * 4)) & 0xF)] << (3 * 4);
om += S[ 64 + ((cm >> (4 * 4)) & 0xF)] << (4 * 4);
om += S[ 80 + ((cm >> (5 * 4)) & 0xF)] << (5 * 4);
om += S[ 96 + ((cm >> (6 * 4)) & 0xF)] << (6 * 4);
om += S[112 + ((cm >> (7 * 4)) & 0xF)] << (7 * 4);
// return om << 11 | om >>> (32-11); // 11-leftshift
int omLeft = om << 11;
int omRight = (int)(((uint) om) >> (32 - 11)); // Note: Casts required to get unsigned bit rotation
return omLeft | omRight;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
private void Gost28147Func(int[] workingKey, ReadOnlySpan<byte> input, Span<byte> output)
{
int N1 = (int)Pack.LE_To_UInt32(input);
int N2 = (int)Pack.LE_To_UInt32(input[4..]);
int tmp; //tmp -> for saving N1
if (this.forEncryption)
{
for(int k = 0; k < 3; k++) // 1-24 steps
{
for(int j = 0; j < 8; j++)
{
tmp = N1;
int step = Gost28147_mainStep(N1, workingKey[j]);
N1 = N2 ^ step; // CM2
N2 = tmp;
}
}
for(int j = 7; j > 0; j--) // 25-31 steps
{
tmp = N1;
N1 = N2 ^ Gost28147_mainStep(N1, workingKey[j]); // CM2
N2 = tmp;
}
}
else //decrypt
{
for(int j = 0; j < 8; j++) // 1-8 steps
{
tmp = N1;
N1 = N2 ^ Gost28147_mainStep(N1, workingKey[j]); // CM2
N2 = tmp;
}
for(int k = 0; k < 3; k++) //9-31 steps
{
for(int j = 7; j >= 0; j--)
{
if ((k == 2) && (j==0))
{
break; // break 32 step
}
tmp = N1;
N1 = N2 ^ Gost28147_mainStep(N1, workingKey[j]); // CM2
N2 = tmp;
}
}
}
N2 = N2 ^ Gost28147_mainStep(N1, workingKey[0]); // 32 step (N1=N1)
Pack.UInt32_To_LE((uint)N1, output);
Pack.UInt32_To_LE((uint)N2, output[4..]);
}
#else
private void Gost28147Func(int[] workingKey, byte[] inBytes, int inOff, byte[] outBytes, int outOff)
{
int N1 = (int)Pack.LE_To_UInt32(inBytes, inOff);
int N2 = (int)Pack.LE_To_UInt32(inBytes, inOff + 4);
int tmp; //tmp -> for saving N1
if (this.forEncryption)
{
for(int k = 0; k < 3; k++) // 1-24 steps
{
for(int j = 0; j < 8; j++)
{
tmp = N1;
int step = Gost28147_mainStep(N1, workingKey[j]);
N1 = N2 ^ step; // CM2
N2 = tmp;
}
}
for(int j = 7; j > 0; j--) // 25-31 steps
{
tmp = N1;
N1 = N2 ^ Gost28147_mainStep(N1, workingKey[j]); // CM2
N2 = tmp;
}
}
else //decrypt
{
for(int j = 0; j < 8; j++) // 1-8 steps
{
tmp = N1;
N1 = N2 ^ Gost28147_mainStep(N1, workingKey[j]); // CM2
N2 = tmp;
}
for(int k = 0; k < 3; k++) //9-31 steps
{
for(int j = 7; j >= 0; j--)
{
if ((k == 2) && (j==0))
{
break; // break 32 step
}
tmp = N1;
N1 = N2 ^ Gost28147_mainStep(N1, workingKey[j]); // CM2
N2 = tmp;
}
}
}
N2 = N2 ^ Gost28147_mainStep(N1, workingKey[0]); // 32 step (N1=N1)
Pack.UInt32_To_LE((uint)N1, outBytes, outOff);
Pack.UInt32_To_LE((uint)N2, outBytes, outOff + 4);
}
#endif
/**
* Return the S-Box associated with SBoxName
* @param sBoxName name of the S-Box
* @return byte array representing the S-Box
*/
public static byte[] GetSBox(string sBoxName)
{
if (!m_sBoxes.TryGetValue(sBoxName, out var sBox))
{
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(sBox);
}
public static string GetSBoxName(byte[] sBox)
{
foreach (var entry in m_sBoxes)
{
if (Arrays.AreEqual(entry.Value, sBox))
return entry.Key;
}
throw new ArgumentException("SBOX provided did not map to a known one");
}
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 6b53ae0fb8b5a1443ab7e30617094995
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/GOST28147Engine.cs
uploadId: 783279

View File

@ -0,0 +1,568 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.IO;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Modes;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
public sealed class Grain128AeadEngine
: IAeadCipher
{
/**
* Constants
*/
private static readonly int STATE_SIZE = 4;
/**
* Variables to hold the state of the engine during encryption and
* decryption
*/
private byte[] workingKey;
private byte[] workingIV;
private uint[] lfsr;
private uint[] nfsr;
private uint[] authAcc;
private uint[] authSr;
private bool initialised = false;
private bool aadFinished = false;
private MemoryStream aadData = new MemoryStream();
private byte[] mac;
public string AlgorithmName => "Grain-128AEAD";
/**
* Initialize a Grain-128AEAD cipher.
*
* @param forEncryption Whether or not we are for encryption.
* @param param The parameters required to set up the cipher.
* @throws ArgumentException If the params argument is inappropriate.
*/
public void Init(bool forEncryption, ICipherParameters param)
{
/*
* Grain encryption and decryption is completely symmetrical, so the
* 'forEncryption' is irrelevant.
*/
if (!(param is ParametersWithIV ivParams))
throw new ArgumentException("Grain-128AEAD Init parameters must include an IV");
byte[] iv = ivParams.GetIV();
if (iv == null || iv.Length != 12)
throw new ArgumentException("Grain-128AEAD requires exactly 12 bytes of IV");
if (!(ivParams.Parameters is KeyParameter key))
throw new ArgumentException("Grain-128AEAD Init parameters must include a key");
byte[] keyBytes = key.GetKey();
if (keyBytes.Length != 16)
throw new ArgumentException("Grain-128AEAD key must be 128 bits long");
/*
* Initialize variables.
*/
workingIV = new byte[keyBytes.Length];
workingKey = keyBytes;
lfsr = new uint[STATE_SIZE];
nfsr = new uint[STATE_SIZE];
authAcc = new uint[2];
authSr = new uint[2];
Array.Copy(iv, 0, workingIV, 0, iv.Length);
Reset();
}
/**
* 320 clocks initialization phase.
*/
private void InitGrain()
{
for (int i = 0; i < 320; ++i)
{
uint outputZ = GetOutput();
nfsr = Shift(nfsr, (GetOutputNFSR() ^ lfsr[0] ^ outputZ) & 1);
lfsr = Shift(lfsr, (GetOutputLFSR() ^ outputZ) & 1);
}
for (int quotient = 0; quotient < 8; ++quotient)
{
for (int remainder = 0; remainder < 8; ++remainder)
{
uint outputZ = GetOutput();
nfsr = Shift(nfsr, (GetOutputNFSR() ^ lfsr[0] ^ outputZ ^ (uint)((workingKey[quotient]) >> remainder)) & 1);
lfsr = Shift(lfsr, (GetOutputLFSR() ^ outputZ ^ (uint)((workingKey[quotient + 8]) >> remainder)) & 1);
}
}
for (int quotient = 0; quotient < 2; ++quotient)
{
for (int remainder = 0; remainder < 32; ++remainder)
{
uint outputZ = GetOutput();
nfsr = Shift(nfsr, (GetOutputNFSR() ^ lfsr[0]) & 1);
lfsr = Shift(lfsr, (GetOutputLFSR()) & 1);
authAcc[quotient] |= outputZ << remainder;
}
}
for (int quotient = 0; quotient < 2; ++quotient)
{
for (int remainder = 0; remainder < 32; ++remainder)
{
uint outputZ = GetOutput();
nfsr = Shift(nfsr, (GetOutputNFSR() ^ lfsr[0]) & 1);
lfsr = Shift(lfsr, (GetOutputLFSR()) & 1);
authSr[quotient] |= outputZ << remainder;
}
}
initialised = true;
}
/**
* Get output from non-linear function g(x).
*
* @return Output from NFSR.
*/
private uint GetOutputNFSR()
{
uint b0 = nfsr[0];
uint b3 = nfsr[0] >> 3;
uint b11 = nfsr[0] >> 11;
uint b13 = nfsr[0] >> 13;
uint b17 = nfsr[0] >> 17;
uint b18 = nfsr[0] >> 18;
uint b22 = nfsr[0] >> 22;
uint b24 = nfsr[0] >> 24;
uint b25 = nfsr[0] >> 25;
uint b26 = nfsr[0] >> 26;
uint b27 = nfsr[0] >> 27;
uint b40 = nfsr[1] >> 8;
uint b48 = nfsr[1] >> 16;
uint b56 = nfsr[1] >> 24;
uint b59 = nfsr[1] >> 27;
uint b61 = nfsr[1] >> 29;
uint b65 = nfsr[2] >> 1;
uint b67 = nfsr[2] >> 3;
uint b68 = nfsr[2] >> 4;
uint b70 = nfsr[2] >> 6;
uint b78 = nfsr[2] >> 14;
uint b82 = nfsr[2] >> 18;
uint b84 = nfsr[2] >> 20;
uint b88 = nfsr[2] >> 24;
uint b91 = nfsr[2] >> 27;
uint b92 = nfsr[2] >> 28;
uint b93 = nfsr[2] >> 29;
uint b95 = nfsr[2] >> 31;
uint b96 = nfsr[3];
return (b0 ^ b26 ^ b56 ^ b91 ^ b96 ^ b3 & b67 ^ b11 & b13 ^ b17 & b18
^ b27 & b59 ^ b40 & b48 ^ b61 & b65 ^ b68 & b84 ^ b22 & b24 & b25 ^ b70 & b78 & b82 ^ b88 & b92 & b93 & b95) & 1;
}
/**
* Get output from linear function f(x).
*
* @return Output from LFSR.
*/
private uint GetOutputLFSR()
{
uint s0 = lfsr[0];
uint s7 = lfsr[0] >> 7;
uint s38 = lfsr[1] >> 6;
uint s70 = lfsr[2] >> 6;
uint s81 = lfsr[2] >> 17;
uint s96 = lfsr[3];
return (s0 ^ s7 ^ s38 ^ s70 ^ s81 ^ s96) & 1;
}
/**
* Get output from output function h(x).
*
* @return y_t.
*/
private uint GetOutput()
{
uint b2 = nfsr[0] >> 2;
uint b12 = nfsr[0] >> 12;
uint b15 = nfsr[0] >> 15;
uint b36 = nfsr[1] >> 4;
uint b45 = nfsr[1] >> 13;
uint b64 = nfsr[2];
uint b73 = nfsr[2] >> 9;
uint b89 = nfsr[2] >> 25;
uint b95 = nfsr[2] >> 31;
uint s8 = lfsr[0] >> 8;
uint s13 = lfsr[0] >> 13;
uint s20 = lfsr[0] >> 20;
uint s42 = lfsr[1] >> 10;
uint s60 = lfsr[1] >> 28;
uint s79 = lfsr[2] >> 15;
uint s93 = lfsr[2] >> 29;
uint s94 = lfsr[2] >> 30;
return ((b12 & s8) ^ (s13 & s20) ^ (b95 & s42) ^ (s60 & s79) ^ (b12 & b95 & s94) ^ s93
^ b2 ^ b15 ^ b36 ^ b45 ^ b64 ^ b73 ^ b89) & 1;
}
/**
* Shift array 1 bit and add val to index.Length - 1.
*
* @param array The array to shift.
* @param val The value to shift in.
* @return The shifted array with val added to index.Length - 1.
*/
private uint[] Shift(uint[] array, uint val)
{
array[0] = (array[0] >> 1) | (array[1] << 31);
array[1] = (array[1] >> 1) | (array[2] << 31);
array[2] = (array[2] >> 1) | (array[3] << 31);
array[3] = (array[3] >> 1) | (val << 31);
return array;
}
/**
* Set keys, reset cipher.
*
* @param keyBytes The key.
* @param ivBytes The IV.
*/
private void SetKey(byte[] keyBytes, byte[] ivBytes)
{
ivBytes[12] = 0xFF;
ivBytes[13] = 0xFF;
ivBytes[14] = 0xFF;
ivBytes[15] = 0x7F;
workingKey = keyBytes;
workingIV = ivBytes;
/*
* Load NFSR and LFSR
*/
Pack.LE_To_UInt32(workingKey, 0, nfsr);
Pack.LE_To_UInt32(workingIV, 0, lfsr);
}
public int 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");
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
return ProcessBytes(input.AsSpan(inOff, len), output.AsSpan(outOff));
#else
if (!initialised)
throw new ArgumentException(AlgorithmName + " not initialised");
if (!aadFinished)
{
DoProcessAADBytes(aadData.GetBuffer(), 0, (int)aadData.Length);
aadFinished = true;
}
GetKeyStream(input, inOff, len, output, outOff);
return len;
#endif
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public int ProcessBytes(ReadOnlySpan<byte> input, Span<byte> output)
{
Check.OutputLength(output, input.Length, "output buffer too short");
if (!initialised)
throw new ArgumentException(AlgorithmName + " not initialised");
if (!aadFinished)
{
DoProcessAADBytes(aadData.GetBuffer(), 0, (int)aadData.Length);
aadFinished = true;
}
GetKeyStream(input, output);
return input.Length;
}
#endif
public void Reset()
{
Reset(true);
}
private void Reset(bool clearMac)
{
if (clearMac)
{
this.mac = null;
}
this.aadData.SetLength(0);
this.aadFinished = false;
SetKey(workingKey, workingIV);
InitGrain();
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
private void GetKeyStream(ReadOnlySpan<byte> input, Span<byte> output)
{
int len = input.Length;
for (int i = 0; i < len; ++i)
{
uint cc = 0, input_i = input[i];
for (int j = 0; j < 8; ++j)
{
uint outputZ = GetOutput();
nfsr = Shift(nfsr, (GetOutputNFSR() ^ lfsr[0]) & 1);
lfsr = Shift(lfsr, (GetOutputLFSR()) & 1);
uint input_i_j = (input_i >> j) & 1U;
cc |= (input_i_j ^ outputZ) << j;
//if (input_i_j != 0)
//{
// Accumulate();
//}
uint mask = 0U - input_i_j;
authAcc[0] ^= authSr[0] & mask;
authAcc[1] ^= authSr[1] & mask;
AuthShift(GetOutput());
nfsr = Shift(nfsr, (GetOutputNFSR() ^ lfsr[0]) & 1);
lfsr = Shift(lfsr, (GetOutputLFSR()) & 1);
}
output[i] = (byte)cc;
}
}
#else
private void GetKeyStream(byte[] input, int inOff, int len, byte[] ciphertext, int outOff)
{
for (int i = 0; i < len; ++i)
{
uint cc = 0, input_i = input[inOff + i];
for (int j = 0; j < 8; ++j)
{
uint outputZ = GetOutput();
nfsr = Shift(nfsr, (GetOutputNFSR() ^ lfsr[0]) & 1);
lfsr = Shift(lfsr, (GetOutputLFSR()) & 1);
uint input_i_j = (input_i >> j) & 1U;
cc |= (input_i_j ^ outputZ) << j;
//if (input_i_j != 0)
//{
// Accumulate();
//}
uint mask = 0U - input_i_j;
authAcc[0] ^= authSr[0] & mask;
authAcc[1] ^= authSr[1] & mask;
AuthShift(GetOutput());
nfsr = Shift(nfsr, (GetOutputNFSR() ^ lfsr[0]) & 1);
lfsr = Shift(lfsr, (GetOutputLFSR()) & 1);
}
ciphertext[outOff + i] = (byte)cc;
}
}
#endif
public byte ReturnByte(byte input)
{
if (!initialised)
throw new ArgumentException(AlgorithmName + " not initialised");
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
Span<byte> plaintext = stackalloc byte[1]{ input };
Span<byte> ciphertext = stackalloc byte[1];
GetKeyStream(plaintext, ciphertext);
return ciphertext[0];
#else
byte[] plaintext = new byte[1]{ input };
byte[] ciphertext = new byte[1];
GetKeyStream(plaintext, 0, 1, ciphertext, 0);
return ciphertext[0];
#endif
}
public void ProcessAadByte(byte input)
{
if (aadFinished)
throw new ArgumentException("associated data must be added before plaintext/ciphertext");
aadData.WriteByte(input);
}
public void ProcessAadBytes(byte[] input, int inOff, int len)
{
if (aadFinished)
throw new ArgumentException("associated data must be added before plaintext/ciphertext");
aadData.Write(input, inOff, len);
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public void ProcessAadBytes(ReadOnlySpan<byte> input)
{
if (aadFinished)
throw new ArgumentException("associated data must be added before plaintext/ciphertext");
aadData.Write(input);
}
#endif
private void Accumulate()
{
authAcc[0] ^= authSr[0];
authAcc[1] ^= authSr[1];
}
private void AuthShift(uint val)
{
authSr[0] = (authSr[0] >> 1) | (authSr[1] << 31);
authSr[1] = (authSr[1] >> 1) | (val << 31);
}
public int ProcessByte(byte input, byte[] output, int outOff)
{
return ProcessBytes(new byte[]{ input }, 0, 1, output, outOff);
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public int ProcessByte(byte input, Span<byte> output)
{
return ProcessBytes(stackalloc byte[1]{ input }, output);
}
#endif
private void DoProcessAADBytes(byte[] input, int inOff, int len)
{
byte[] ader;
int aderlen;
//encodeDer
if (len < 128)
{
ader = new byte[1 + len];
ader[0] = (byte)len;
aderlen = 0;
}
else
{
// aderlen is the highest bit position divided by 8
aderlen = LenLength(len);
ader = new byte[aderlen + 1 + len];
ader[0] = (byte)(0x80 | (uint)aderlen);
uint tmp = (uint)len;
for (int i = 0; i < aderlen; ++i)
{
ader[1 + i] = (byte)tmp;
tmp >>= 8;
}
}
for (int i = 0; i < len; ++i)
{
ader[1 + aderlen + i] = input[inOff + i];
}
for (int i = 0; i < ader.Length; ++i)
{
uint ader_i = ader[i];
for (int j = 0; j < 8; ++j)
{
nfsr = Shift(nfsr, (GetOutputNFSR() ^ lfsr[0]) & 1);
lfsr = Shift(lfsr, (GetOutputLFSR()) & 1);
uint ader_i_j = (ader_i >> j) & 1U;
//if (ader_i_j != 0)
//{
// Accumulate();
//}
uint mask = 0U - ader_i_j;
authAcc[0] ^= authSr[0] & mask;
authAcc[1] ^= authSr[1] & mask;
AuthShift(GetOutput());
nfsr = Shift(nfsr, (GetOutputNFSR() ^ lfsr[0]) & 1);
lfsr = Shift(lfsr, (GetOutputLFSR()) & 1);
}
}
}
public int DoFinal(byte[] output, int outOff)
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
return DoFinal(output.AsSpan(outOff));
#else
if (!aadFinished)
{
DoProcessAADBytes(aadData.GetBuffer(), 0, (int)aadData.Length);
aadFinished = true;
}
Accumulate();
this.mac = Pack.UInt32_To_LE(authAcc);
Array.Copy(mac, 0, output, outOff, mac.Length);
Reset(false);
return mac.Length;
#endif
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public int DoFinal(Span<byte> output)
{
if (!aadFinished)
{
DoProcessAADBytes(aadData.GetBuffer(), 0, (int)aadData.Length);
aadFinished = true;
}
Accumulate();
this.mac = Pack.UInt32_To_LE(authAcc);
mac.CopyTo(output);
Reset(false);
return mac.Length;
}
#endif
public byte[] GetMac()
{
return mac;
}
public int GetUpdateOutputSize(int len)
{
return len;
}
public int GetOutputSize(int len)
{
return len + 8;
}
private static int LenLength(int v)
{
if ((v & 0xff) == v)
return 1;
if ((v & 0xffff) == v)
return 2;
if ((v & 0xffffff) == v)
return 3;
return 4;
}
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: aa1295d600718c34fa3ae69a2816e467
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/Grain128AEADEngine.cs
uploadId: 783279

View File

@ -0,0 +1,254 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/**
* HC-128 is a software-efficient stream cipher created by Hongjun Wu. It
* generates keystream from a 128-bit secret key and a 128-bit initialization
* vector.
* <p>
* http://www.ecrypt.eu.org/stream/p3ciphers/hc/hc128_p3.pdf
* </p><p>
* It is a third phase candidate in the eStream contest, and is patent-free.
* No attacks are known as of today (April 2007). See
*
* http://www.ecrypt.eu.org/stream/hcp3.html
* </p>
*/
public class HC128Engine
: IStreamCipher
{
private uint[] p = new uint[512];
private uint[] q = new uint[512];
private uint cnt = 0;
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 j = Mod512(cnt);
uint ret;
if (cnt < 512)
{
p[j] += G1(p[Dim(j, 3)], p[Dim(j, 10)], p[Dim(j, 511)]);
ret = H1(p[Dim(j, 12)]) ^ p[j];
}
else
{
q[j] += G2(q[Dim(j, 3)], q[Dim(j, 10)], q[Dim(j, 511)]);
ret = H2(q[Dim(j, 12)]) ^ q[j];
}
cnt = Mod1024(cnt + 1);
return ret;
}
private byte[] key, iv;
private bool initialised;
private void Init()
{
if (key.Length != 16)
throw new ArgumentException("The key must be 128 bits long");
idx = 0;
cnt = 0;
uint[] w = new uint[1280];
for (int i = 0; i < 16; i++)
{
w[i >> 2] |= ((uint)key[i] << (8 * (i & 0x3)));
}
Array.Copy(w, 0, w, 4, 4);
for (int i = 0; i < iv.Length && i < 16; i++)
{
w[(i >> 2) + 8] |= ((uint)iv[i] << (8 * (i & 0x3)));
}
Array.Copy(w, 8, w, 12, 4);
for (uint i = 16; i < 1280; i++)
{
w[i] = F2(w[i - 2]) + w[i - 7] + F1(w[i - 15]) + w[i - 16] + i;
}
Array.Copy(w, 256, p, 0, 512);
Array.Copy(w, 768, q, 0, 512);
for (int i = 0; i < 512; i++)
{
p[i] = Step();
}
for (int i = 0; i < 512; i++)
{
q[i] = Step();
}
cnt = 0;
}
public virtual string AlgorithmName
{
get { return "HC-128"; }
}
/**
* Initialise a HC-128 cipher.
*
* @param forEncryption whether or not we are for encryption. Irrelevant, as
* encryption and decryption are the same.
* @param params the parameters required to set up the cipher.
* @throws ArgumentException if the params argument is
* inappropriate (ie. the key is not 128 bit long).
*/
public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
ICipherParameters keyParam = parameters;
if (parameters is ParametersWithIV)
{
iv = ((ParametersWithIV)parameters).GetIV();
keyParam = ((ParametersWithIV)parameters).Parameters;
}
else
{
iv = new byte[0];
}
if (keyParam is KeyParameter)
{
key = ((KeyParameter)keyParam).GetKey();
Init();
}
else
{
throw new ArgumentException(
"Invalid parameter passed to HC128 init - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters),
"parameters");
}
initialised = true;
}
private byte[] buf = new byte[4];
private int idx = 0;
private byte GetByte()
{
if (idx == 0)
{
Pack.UInt32_To_LE(Step(), buf);
}
byte ret = buf[idx];
idx = idx + 1 & 0x3;
return ret;
}
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());
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual void ProcessBytes(ReadOnlySpan<byte> input, Span<byte> output)
{
if (!initialised)
throw new InvalidOperationException(AlgorithmName + " not initialised");
Check.OutputLength(output, input.Length, "output buffer too short");
for (int i = 0; i < input.Length; i++)
{
output[i] = (byte)(input[i] ^ GetByte());
}
}
#endif
public virtual void Reset()
{
Init();
}
public virtual byte ReturnByte(byte input)
{
return (byte)(input ^ GetByte());
}
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 5f44bda56ad69a045bff41a813713e60
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/HC128Engine.cs
uploadId: 783279

View File

@ -0,0 +1,243 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/**
* HC-256 is a software-efficient stream cipher created by Hongjun Wu. It
* generates keystream from a 256-bit secret key and a 256-bit initialization
* vector.
* <p>
* http://www.ecrypt.eu.org/stream/p3ciphers/hc/hc256_p3.pdf
* </p><p>
* Its brother, HC-128, is a third phase candidate in the eStream contest.
* The algorithm is patent-free. No attacks are known as of today (April 2007).
* See
*
* http://www.ecrypt.eu.org/stream/hcp3.html
* </p>
*/
public class HC256Engine
: IStreamCipher
{
private uint[] p = new uint[1024];
private uint[] q = new uint[1024];
private uint cnt = 0;
private uint Step()
{
uint j = cnt & 0x3FF;
uint ret;
if (cnt < 1024)
{
uint x = p[(j - 3 & 0x3FF)];
uint y = p[(j - 1023 & 0x3FF)];
p[j] += p[(j - 10 & 0x3FF)]
+ (RotateRight(x, 10) ^ RotateRight(y, 23))
+ q[((x ^ y) & 0x3FF)];
x = p[(j - 12 & 0x3FF)];
ret = (q[x & 0xFF] + q[((x >> 8) & 0xFF) + 256]
+ q[((x >> 16) & 0xFF) + 512] + q[((x >> 24) & 0xFF) + 768])
^ p[j];
}
else
{
uint x = q[(j - 3 & 0x3FF)];
uint y = q[(j - 1023 & 0x3FF)];
q[j] += q[(j - 10 & 0x3FF)]
+ (RotateRight(x, 10) ^ RotateRight(y, 23))
+ p[((x ^ y) & 0x3FF)];
x = q[(j - 12 & 0x3FF)];
ret = (p[x & 0xFF] + p[((x >> 8) & 0xFF) + 256]
+ p[((x >> 16) & 0xFF) + 512] + p[((x >> 24) & 0xFF) + 768])
^ q[j];
}
cnt = cnt + 1 & 0x7FF;
return ret;
}
private byte[] key, iv;
private bool initialised;
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[] k = new byte[32];
Array.Copy(key, 0, k, 0, key.Length);
Array.Copy(key, 0, k, 16, key.Length);
key = k;
}
if (iv.Length < 32)
{
byte[] newIV = new byte[32];
Array.Copy(iv, 0, newIV, 0, iv.Length);
Array.Copy(iv, 0, newIV, iv.Length, newIV.Length - iv.Length);
iv = newIV;
}
idx = 0;
cnt = 0;
uint[] w = new uint[2560];
for (int i = 0; i < 32; i++)
{
w[i >> 2] |= ((uint)key[i] << (8 * (i & 0x3)));
}
for (int i = 0; i < 32; i++)
{
w[(i >> 2) + 8] |= ((uint)iv[i] << (8 * (i & 0x3)));
}
for (uint i = 16; i < 2560; i++)
{
uint x = w[i - 2];
uint y = w[i - 15];
w[i] = (RotateRight(x, 17) ^ RotateRight(x, 19) ^ (x >> 10))
+ w[i - 7]
+ (RotateRight(y, 7) ^ RotateRight(y, 18) ^ (y >> 3))
+ w[i - 16] + i;
}
Array.Copy(w, 512, p, 0, 1024);
Array.Copy(w, 1536, q, 0, 1024);
for (int i = 0; i < 4096; i++)
{
Step();
}
cnt = 0;
}
public virtual string AlgorithmName
{
get { return "HC-256"; }
}
/**
* Initialise a HC-256 cipher.
*
* @param forEncryption whether or not we are for encryption. Irrelevant, as
* encryption and decryption are the same.
* @param params the parameters required to set up the cipher.
* @throws ArgumentException if the params argument is
* inappropriate (ie. the key is not 256 bit long).
*/
public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
ICipherParameters keyParam = parameters;
if (parameters is ParametersWithIV)
{
iv = ((ParametersWithIV)parameters).GetIV();
keyParam = ((ParametersWithIV)parameters).Parameters;
}
else
{
iv = new byte[0];
}
if (keyParam is KeyParameter)
{
key = ((KeyParameter)keyParam).GetKey();
Init();
}
else
{
throw new ArgumentException(
"Invalid parameter passed to HC256 init - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters),
"parameters");
}
initialised = true;
}
private byte[] buf = new byte[4];
private int idx = 0;
private byte GetByte()
{
if (idx == 0)
{
Pack.UInt32_To_LE(Step(), buf);
}
byte ret = buf[idx];
idx = idx + 1 & 0x3;
return ret;
}
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());
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual void ProcessBytes(ReadOnlySpan<byte> input, Span<byte> output)
{
if (!initialised)
throw new InvalidOperationException(AlgorithmName + " not initialised");
Check.OutputLength(output, input.Length, "output buffer too short");
for (int i = 0; i < input.Length; i++)
{
output[i] = (byte)(input[i] ^ GetByte());
}
}
#endif
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);
}
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: df13794ef78e91b4893f4474bf7aa5c5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/HC256Engine.cs
uploadId: 783279

View File

@ -0,0 +1,237 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/**
* Implementation of Bob Jenkin's ISAAC (Indirection Shift Accumulate Add and Count).
* see: http://www.burtleburtle.net/bob/rand/isaacafa.html
*/
public class IsaacEngine
: IStreamCipher
{
// Constants
private static readonly int sizeL = 8,
stateArraySize = sizeL<<5; // 256
// Cipher's internal state
private uint[] engineState = null, // mm
results = null; // randrsl
private uint a = 0, b = 0, c = 0;
// Engine state
private int index = 0;
private byte[] keyStream = new byte[stateArraySize<<2], // results expanded into bytes
workingKey = null;
private bool initialised = false;
/**
* initialise an ISAAC cipher.
*
* @param forEncryption whether or not we are for encryption.
* @param params the parameters required to set up the cipher.
* @exception ArgumentException if the params argument is
* inappropriate.
*/
public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
if (!(parameters is KeyParameter))
throw new ArgumentException(
"invalid parameter passed to ISAAC Init - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters),
"parameters");
/*
* ISAAC encryption and decryption is completely
* symmetrical, so the 'forEncryption' is
* irrelevant.
*/
KeyParameter p = (KeyParameter) parameters;
setKey(p.GetKey());
}
public virtual byte ReturnByte(
byte input)
{
if (index == 0)
{
isaac();
keyStream = Pack.UInt32_To_BE(results);
}
byte output = (byte)(keyStream[index]^input);
index = (index + 1) & 1023;
return output;
}
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) & 1023;
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual void ProcessBytes(ReadOnlySpan<byte> input, Span<byte> output)
{
if (!initialised)
throw new InvalidOperationException(AlgorithmName + " not initialised");
Check.OutputLength(output, input.Length, "output buffer too short");
for (int i = 0; i < input.Length; i++)
{
if (index == 0)
{
isaac();
keyStream = Pack.UInt32_To_BE(results);
}
output[i] = (byte)(keyStream[index++] ^ input[i]);
index &= 1023;
}
}
#endif
public virtual string AlgorithmName
{
get { return "ISAAC"; }
}
public virtual void Reset()
{
setKey(workingKey);
}
// Private implementation
private void setKey(
byte[] keyBytes)
{
workingKey = keyBytes;
if (engineState == null)
{
engineState = new uint[stateArraySize];
}
if (results == null)
{
results = new uint[stateArraySize];
}
int i, j, k;
// Reset state
for (i = 0; i < stateArraySize; i++)
{
engineState[i] = results[i] = 0;
}
a = b = c = 0;
// Reset index counter for output
index = 0;
// Convert the key bytes to ints and put them into results[] for initialization
byte[] t = new byte[keyBytes.Length + (keyBytes.Length & 3)];
Array.Copy(keyBytes, 0, t, 0, keyBytes.Length);
for (i = 0; i < t.Length; i+=4)
{
results[i >> 2] = Pack.LE_To_UInt32(t, i);
}
// It has begun?
uint[] abcdefgh = new uint[sizeL];
for (i = 0; i < sizeL; i++)
{
abcdefgh[i] = 0x9e3779b9; // Phi (golden ratio)
}
for (i = 0; i < 4; i++)
{
mix(abcdefgh);
}
for (i = 0; i < 2; i++)
{
for (j = 0; j < stateArraySize; j+=sizeL)
{
for (k = 0; k < sizeL; k++)
{
abcdefgh[k] += (i<1) ? results[j+k] : engineState[j+k];
}
mix(abcdefgh);
for (k = 0; k < sizeL; k++)
{
engineState[j+k] = abcdefgh[k];
}
}
}
isaac();
initialised = true;
}
private void isaac()
{
uint x, y;
b += ++c;
for (int i = 0; i < stateArraySize; i++)
{
x = 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];
engineState[i] = y = engineState[(int)((uint)x >> 2) & 0xFF] + a + b;
results[i] = b = engineState[(int)((uint)y >> 10) & 0xFF] + x;
}
}
private void mix(uint[] x)
{
x[0]^=x[1]<< 11; x[3]+=x[0]; x[1]+=x[2];
x[1]^=x[2]>> 2; x[4]+=x[1]; x[2]+=x[3];
x[2]^=x[3]<< 8; x[5]+=x[2]; x[3]+=x[4];
x[3]^=x[4]>> 16; x[6]+=x[3]; x[4]+=x[5];
x[4]^=x[5]<< 10; x[7]+=x[4]; x[5]+=x[6];
x[5]^=x[6]>> 4; x[0]+=x[5]; x[6]+=x[7];
x[6]^=x[7]<< 8; x[1]+=x[6]; x[7]+=x[0];
x[7]^=x[0]>> 9; x[2]+=x[7]; x[0]+=x[1];
}
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 8b98839b43ea6fe4ca137cc72b6756ea
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/ISAACEngine.cs
uploadId: 783279

View File

@ -0,0 +1,381 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/**
* A class that provides a basic International Data Encryption Algorithm (IDEA) engine.
* <p>
* This implementation is based on the "HOWTO: INTERNATIONAL DATA ENCRYPTION ALGORITHM"
* implementation summary by Fauzan Mirza (F.U.Mirza@sheffield.ac.uk). (barring 1 typo at the
* end of the MulInv function!).
* </p>
* <p>
* It can be found at ftp://ftp.funet.fi/pub/crypt/cryptography/symmetric/idea/
* </p>
* <p>
* Note: This algorithm was patented in the USA, Japan and Europe. These patents expired in 2011/2012.
* </p>
*/
public class IdeaEngine
: IBlockCipher
{
private const int BLOCK_SIZE = 8;
private int[] workingKey;
/**
* standard constructor.
*/
public IdeaEngine()
{
}
/**
* initialise an IDEA cipher.
*
* @param forEncryption whether or not we are for encryption.
* @param parameters the parameters required to set up the cipher.
* @exception ArgumentException if the parameters argument is
* inappropriate.
*/
public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
if (!(parameters is KeyParameter))
throw new ArgumentException("invalid parameter passed to IDEA init - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters));
workingKey = GenerateWorkingKey(forEncryption,
((KeyParameter)parameters).GetKey());
}
public virtual string AlgorithmName
{
get { return "IDEA"; }
}
public virtual int GetBlockSize()
{
return BLOCK_SIZE;
}
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, BLOCK_SIZE, "input buffer too short");
Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short");
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
IdeaFunc(workingKey, input.AsSpan(inOff), output.AsSpan(outOff));
#else
IdeaFunc(workingKey, input, inOff, output, outOff);
#endif
return BLOCK_SIZE;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual int ProcessBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
if (workingKey == null)
throw new InvalidOperationException("IDEA engine not initialised");
Check.DataLength(input, BLOCK_SIZE, "input buffer too short");
Check.OutputLength(output, BLOCK_SIZE, "output buffer too short");
IdeaFunc(workingKey, input, output);
return BLOCK_SIZE;
}
#endif
private static readonly int MASK = 0xffff;
private static readonly int BASE = 0x10001;
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
private int BytesToWord(ReadOnlySpan<byte> input)
{
return ((input[0] << 8) & 0xff00) + (input[1] & 0xff);
}
private void WordToBytes(int word, Span<byte> output)
{
output[0] = (byte)((uint)word >> 8);
output[1] = (byte)word;
}
#else
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;
}
#endif
/**
* return x = x * y where the multiplication is done modulo
* 65537 (0x10001) (as defined in the IDEA specification) and
* a zero input is taken to be 65536 (0x10000).
*
* @param x the x value
* @param y the y value
* @return x = x * y
*/
private int Mul(
int x,
int y)
{
if (x == 0)
{
x = (BASE - y);
}
else if (y == 0)
{
x = (BASE - x);
}
else
{
int p = x * y;
y = p & MASK;
x = (int) ((uint) p >> 16);
x = y - x + ((y < x) ? 1 : 0);
}
return x & MASK;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
private void IdeaFunc(int[] workingKey, ReadOnlySpan<byte> input, Span<byte> output)
{
int x0 = BytesToWord(input);
int x1 = BytesToWord(input[2..]);
int x2 = BytesToWord(input[4..]);
int x3 = BytesToWord(input[6..]);
int keyOff = 0, t0, t1;
for (int round = 0; round < 8; round++)
{
x0 = Mul(x0, workingKey[keyOff++]);
x1 += workingKey[keyOff++];
x1 &= MASK;
x2 += workingKey[keyOff++];
x2 &= MASK;
x3 = Mul(x3, workingKey[keyOff++]);
t0 = x1;
t1 = x2;
x2 ^= x0;
x1 ^= x3;
x2 = Mul(x2, workingKey[keyOff++]);
x1 += x2;
x1 &= MASK;
x1 = Mul(x1, workingKey[keyOff++]);
x2 += x1;
x2 &= MASK;
x0 ^= x1;
x3 ^= x2;
x1 ^= t1;
x2 ^= t0;
}
WordToBytes(Mul(x0, workingKey[keyOff++]), output);
WordToBytes(x2 + workingKey[keyOff++], output[2..]); /* NB: Order */
WordToBytes(x1 + workingKey[keyOff++], output[4..]);
WordToBytes(Mul(x3, workingKey[keyOff]), output[6..]);
}
#else
private void IdeaFunc(int[] workingKey, byte[] input, int inOff, byte[] outBytes, int outOff)
{
int x0 = BytesToWord(input, inOff);
int x1 = BytesToWord(input, inOff + 2);
int x2 = BytesToWord(input, inOff + 4);
int x3 = BytesToWord(input, inOff + 6);
int keyOff = 0, t0, t1;
for (int round = 0; round < 8; round++)
{
x0 = Mul(x0, workingKey[keyOff++]);
x1 += workingKey[keyOff++];
x1 &= MASK;
x2 += workingKey[keyOff++];
x2 &= MASK;
x3 = Mul(x3, workingKey[keyOff++]);
t0 = x1;
t1 = x2;
x2 ^= x0;
x1 ^= x3;
x2 = Mul(x2, workingKey[keyOff++]);
x1 += x2;
x1 &= MASK;
x1 = Mul(x1, workingKey[keyOff++]);
x2 += x1;
x2 &= MASK;
x0 ^= x1;
x3 ^= x2;
x1 ^= t1;
x2 ^= t0;
}
WordToBytes(Mul(x0, workingKey[keyOff++]), outBytes, outOff);
WordToBytes(x2 + workingKey[keyOff++], outBytes, outOff + 2); /* NB: Order */
WordToBytes(x1 + workingKey[keyOff++], outBytes, outOff + 4);
WordToBytes(Mul(x3, workingKey[keyOff]), outBytes, outOff + 6);
}
#endif
/**
* The following function is used to expand the user key to the encryption
* subkey. The first 16 bytes are the user key, and the rest of the subkey
* is calculated by rotating the previous 16 bytes by 25 bits to the left,
* and so on until the subkey is completed.
*/
private int[] ExpandKey(byte[] uKey)
{
int[] key = new int[52];
if (uKey.Length < 16)
{
byte[] tmp = new byte[16];
Array.Copy(uKey, 0, tmp, tmp.Length - uKey.Length, uKey.Length);
uKey = tmp;
}
for (int i = 0; i < 8; i++)
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
key[i] = BytesToWord(uKey[(i * 2)..]);
#else
key[i] = BytesToWord(uKey, i * 2);
#endif
}
for (int i = 8; i < 52; i++)
{
if ((i & 7) < 6)
{
key[i] = ((key[i - 7] & 127) << 9 | key[i - 6] >> 7) & MASK;
}
else if ((i & 7) == 6)
{
key[i] = ((key[i - 7] & 127) << 9 | key[i - 14] >> 7) & MASK;
}
else
{
key[i] = ((key[i - 15] & 127) << 9 | key[i - 14] >> 7) & MASK;
}
}
return key;
}
/**
* This function computes multiplicative inverse using Euclid's Greatest
* Common Divisor algorithm. Zero and one are self inverse.
* <p>
* i.e. x * MulInv(x) == 1 (modulo BASE)
* </p>
*/
private int MulInv(
int x)
{
int t0, t1, q, y;
if (x < 2)
{
return x;
}
t0 = 1;
t1 = BASE / x;
y = BASE % x;
while (y != 1)
{
q = x / y;
x = x % y;
t0 = (t0 + (t1 * q)) & MASK;
if (x == 1)
{
return t0;
}
q = y / x;
y = y % x;
t1 = (t1 + (t0 * q)) & MASK;
}
return (1 - t1) & MASK;
}
/**
* Return the additive inverse of x.
* <p>
* i.e. x + AddInv(x) == 0
* </p>
*/
int AddInv(
int x)
{
return (0 - x) & MASK;
}
/**
* The function to invert the encryption subkey to the decryption subkey.
* It also involves the multiplicative inverse and the additive inverse functions.
*/
private int[] InvertKey(
int[] inKey)
{
int t1, t2, t3, t4;
int p = 52; /* We work backwards */
int[] key = new int[52];
int inOff = 0;
t1 = MulInv(inKey[inOff++]);
t2 = AddInv(inKey[inOff++]);
t3 = AddInv(inKey[inOff++]);
t4 = MulInv(inKey[inOff++]);
key[--p] = t4;
key[--p] = t3;
key[--p] = t2;
key[--p] = t1;
for (int round = 1; round < 8; round++)
{
t1 = inKey[inOff++];
t2 = inKey[inOff++];
key[--p] = t2;
key[--p] = t1;
t1 = MulInv(inKey[inOff++]);
t2 = AddInv(inKey[inOff++]);
t3 = AddInv(inKey[inOff++]);
t4 = MulInv(inKey[inOff++]);
key[--p] = t4;
key[--p] = t2; /* NB: Order */
key[--p] = t3;
key[--p] = t1;
}
t1 = inKey[inOff++];
t2 = inKey[inOff++];
key[--p] = t2;
key[--p] = t1;
t1 = MulInv(inKey[inOff++]);
t2 = AddInv(inKey[inOff++]);
t3 = AddInv(inKey[inOff++]);
t4 = MulInv(inKey[inOff]);
key[--p] = t4;
key[--p] = t3;
key[--p] = t2;
key[--p] = t1;
return key;
}
private int[] GenerateWorkingKey(
bool forEncryption,
byte[] userKey)
{
if (forEncryption)
{
return ExpandKey(userKey);
}
else
{
return InvertKey(ExpandKey(userKey));
}
}
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 4cd0d95613058e4489ba02ec1fc3e945
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/IdeaEngine.cs
uploadId: 783279

View File

@ -0,0 +1,247 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/**
* support class for constructing intergrated encryption ciphers
* for doing basic message exchanges on top of key agreement ciphers
*/
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, pubParam;
private IesParameters param;
/**
* set up for use with stream mode, where the key derivation function
* is used to provide a stream of bytes to xor with the message.
*
* @param agree the key agreement used as the basis for the encryption
* @param kdf the key derivation function used for byte generation
* @param mac the message authentication code generator for the message
*/
public IesEngine(
IBasicAgreement agree,
IDerivationFunction kdf,
IMac mac)
{
this.agree = agree;
this.kdf = kdf;
this.mac = mac;
this.macBuf = new byte[mac.GetMacSize()];
// this.cipher = null;
}
/**
* set up for use in conjunction with a block cipher to handle the
* message.
*
* @param agree the key agreement used as the basis for the encryption
* @param kdf the key derivation function used for byte generation
* @param mac the message authentication code generator for the message
* @param cipher the cipher to used for encrypting the message
*/
public IesEngine(
IBasicAgreement agree,
IDerivationFunction kdf,
IMac mac,
BufferedBlockCipher cipher)
{
this.agree = agree;
this.kdf = kdf;
this.mac = mac;
this.macBuf = new byte[mac.GetMacSize()];
this.cipher = cipher;
}
/**
* Initialise the encryptor.
*
* @param forEncryption whether or not this is encryption/decryption.
* @param privParam our private key parameters
* @param pubParam the recipient's/sender's public key parameters
* @param param encoding and derivation parameters.
*/
public virtual void Init(
bool forEncryption,
ICipherParameters privParameters,
ICipherParameters pubParameters,
ICipherParameters iesParameters)
{
this.forEncryption = forEncryption;
this.privParam = privParameters;
this.pubParam = pubParameters;
this.param = (IesParameters)iesParameters;
}
private byte[] DecryptBlock(
byte[] in_enc,
int inOff,
int inLen,
byte[] z)
{
byte[] M = null;
KeyParameter macKey = null;
KdfParameters kParam = new KdfParameters(z, param.GetDerivationV());
int macKeySize = param.MacKeySize;
kdf.Init(kParam);
// Ensure that the length of the input is greater than the MAC in bytes
if (inLen < mac.GetMacSize())
throw new InvalidCipherTextException("Length of input must be greater than the MAC");
inLen -= mac.GetMacSize();
if (cipher == null) // stream mode
{
byte[] Buffer = GenerateKdfBytes(kParam, inLen + (macKeySize / 8));
M = new byte[inLen];
for (int i = 0; i != inLen; i++)
{
M[i] = (byte)(in_enc[inOff + i] ^ Buffer[i]);
}
macKey = new KeyParameter(Buffer, inLen, (macKeySize / 8));
}
else
{
int cipherKeySize = ((IesWithCipherParameters)param).CipherKeySize;
byte[] Buffer = GenerateKdfBytes(kParam, (cipherKeySize / 8) + (macKeySize / 8));
cipher.Init(false, new KeyParameter(Buffer, 0, (cipherKeySize / 8)));
M = cipher.DoFinal(in_enc, inOff, inLen);
macKey = new KeyParameter(Buffer, (cipherKeySize / 8), (macKeySize / 8));
}
byte[] macIV = param.GetEncodingV();
mac.Init(macKey);
mac.BlockUpdate(in_enc, inOff, inLen);
mac.BlockUpdate(macIV, 0, macIV.Length);
mac.DoFinal(macBuf, 0);
inOff += inLen;
byte[] T1 = Arrays.CopyOfRange(in_enc, inOff, inOff + macBuf.Length);
if (!Arrays.ConstantTimeAreEqual(T1, macBuf))
throw (new InvalidCipherTextException("Invalid MAC."));
return M;
}
private byte[] EncryptBlock(
byte[] input,
int inOff,
int inLen,
byte[] z)
{
byte[] C = null;
KeyParameter macKey = null;
KdfParameters kParam = new KdfParameters(z, param.GetDerivationV());
int c_text_length = 0;
int macKeySize = param.MacKeySize;
if (cipher == null) // stream mode
{
byte[] Buffer = GenerateKdfBytes(kParam, inLen + (macKeySize / 8));
C = new byte[inLen + mac.GetMacSize()];
c_text_length = inLen;
for (int i = 0; i != inLen; i++)
{
C[i] = (byte)(input[inOff + i] ^ Buffer[i]);
}
macKey = new KeyParameter(Buffer, inLen, (macKeySize / 8));
}
else
{
int cipherKeySize = ((IesWithCipherParameters)param).CipherKeySize;
byte[] Buffer = GenerateKdfBytes(kParam, (cipherKeySize / 8) + (macKeySize / 8));
cipher.Init(true, new KeyParameter(Buffer, 0, (cipherKeySize / 8)));
c_text_length = cipher.GetOutputSize(inLen);
byte[] tmp = new byte[c_text_length];
int len = cipher.ProcessBytes(input, inOff, inLen, tmp, 0);
len += cipher.DoFinal(tmp, len);
C = new byte[len + mac.GetMacSize()];
c_text_length = len;
Array.Copy(tmp, 0, C, 0, len);
macKey = new KeyParameter(Buffer, (cipherKeySize / 8), (macKeySize / 8));
}
byte[] macIV = param.GetEncodingV();
mac.Init(macKey);
mac.BlockUpdate(C, 0, c_text_length);
mac.BlockUpdate(macIV, 0, macIV.Length);
//
// return the message and it's MAC
//
mac.DoFinal(C, c_text_length);
return C;
}
private byte[] GenerateKdfBytes(
KdfParameters kParam,
int length)
{
byte[] buf = new byte[length];
kdf.Init(kParam);
kdf.GenerateBytes(buf, 0, buf.Length);
return buf;
}
public virtual byte[] ProcessBlock(
byte[] input,
int inOff,
int inLen)
{
agree.Init(privParam);
BigInteger z = agree.CalculateAgreement(pubParam);
byte[] zBytes = BigIntegers.AsUnsignedByteArray(agree.GetFieldSize(), z);
try
{
return forEncryption
? EncryptBlock(input, inOff, inLen, zBytes)
: DecryptBlock(input, inOff, inLen, zBytes);
}
finally
{
Array.Clear(zBytes, 0, zBytes.Length);
}
}
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 2c6099a03c3ca89459f45b5a11447705
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/IesEngine.cs
uploadId: 783279

View File

@ -0,0 +1,352 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using System.Collections.Generic;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/**
* NaccacheStern Engine. For details on this cipher, please see
* http://www.gemplus.com/smart/rd/publications/pdf/NS98pkcs.pdf
*/
public class NaccacheSternEngine
: IAsymmetricBlockCipher
{
private bool forEncryption;
private NaccacheSternKeyParameters key;
private IList<BigInteger>[] lookup = null;
public string AlgorithmName
{
get { return "NaccacheStern"; }
}
/**
* Initializes this algorithm. Must be called before all other Functions.
*
* @see org.bouncycastle.crypto.AsymmetricBlockCipher#init(bool,
* org.bouncycastle.crypto.CipherParameters)
*/
public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
this.forEncryption = forEncryption;
if (parameters is ParametersWithRandom)
{
parameters = ((ParametersWithRandom) parameters).Parameters;
}
key = (NaccacheSternKeyParameters)parameters;
// construct lookup table for faster decryption if necessary
if (!this.forEncryption)
{
NaccacheSternPrivateKeyParameters priv = (NaccacheSternPrivateKeyParameters)key;
var primes = priv.SmallPrimesList;
lookup = new IList<BigInteger>[primes.Count];
for (int i = 0; i < primes.Count; i++)
{
BigInteger actualPrime = primes[i];
int actualPrimeValue = actualPrime.IntValue;
lookup[i] = new List<BigInteger>(actualPrimeValue);
lookup[i].Add(BigInteger.One);
BigInteger accJ = BigInteger.Zero;
for (int j = 1; j < actualPrimeValue; j++)
{
accJ = accJ.Add(priv.PhiN);
BigInteger comp = accJ.Divide(actualPrime);
lookup[i].Add(priv.G.ModPow(comp, priv.Modulus));
}
}
}
}
/**
* Returns the input block size of this algorithm.
*
* @see org.bouncycastle.crypto.AsymmetricBlockCipher#GetInputBlockSize()
*/
public virtual int GetInputBlockSize()
{
if (forEncryption)
{
// We can only encrypt values up to lowerSigmaBound
return (key.LowerSigmaBound + 7) / 8 - 1;
}
else
{
// We pad to modulus-size bytes for easier decryption.
// return key.Modulus.ToByteArray().Length;
return key.Modulus.BitLength / 8 + 1;
}
}
/**
* Returns the output block size of this algorithm.
*
* @see org.bouncycastle.crypto.AsymmetricBlockCipher#GetOutputBlockSize()
*/
public virtual int GetOutputBlockSize()
{
if (forEncryption)
{
// encrypted Data is always padded up to modulus size
// return key.Modulus.ToByteArray().Length;
return key.Modulus.BitLength / 8 + 1;
}
else
{
// decrypted Data has upper limit lowerSigmaBound
return (key.LowerSigmaBound + 7) / 8 - 1;
}
}
/**
* Process a single Block using the Naccache-Stern algorithm.
*
* @see org.bouncycastle.crypto.AsymmetricBlockCipher#ProcessBlock(byte[],
* int, int)
*/
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)
{
// At decryption make sure that we receive padded data blocks
if (length < GetInputBlockSize())
{
throw new InvalidCipherTextException("BlockLength does not match modulus for Naccache-Stern cipher.\n");
}
}
// transform input into BigInteger
BigInteger input = new BigInteger(1, inBytes, inOff, length);
byte[] output;
if (forEncryption)
{
output = Encrypt(input);
}
else
{
var plain = new List<BigInteger>();
NaccacheSternPrivateKeyParameters priv = (NaccacheSternPrivateKeyParameters)key;
var primes = priv.SmallPrimesList;
// Get Chinese Remainders of CipherText
for (int i = 0; i < primes.Count; i++)
{
BigInteger exp = input.ModPow(priv.PhiN.Divide((BigInteger)primes[i]), priv.Modulus);
var al = lookup[i];
if (lookup[i].Count != primes[i].IntValue)
{
throw new InvalidCipherTextException("Error in lookup Array for "
+ primes[i].IntValue
+ ": Size mismatch. Expected ArrayList with length "
+ primes[i].IntValue + " but found ArrayList of length "
+ lookup[i].Count);
}
int lookedup = al.IndexOf(exp);
if (lookedup == -1)
throw new InvalidCipherTextException("Lookup failed");
plain.Add(BigInteger.ValueOf(lookedup));
}
BigInteger test = ChineseRemainder(plain, primes);
// Should not be used as an oracle, so reencrypt output to see
// if it corresponds to input
// this breaks probabilisic encryption, so disable it. Anyway, we do
// use the first n primes for key generation, so it is pretty easy
// to guess them. But as stated in the paper, this is not a security
// breach. So we can just work with the correct sigma.
// if ((key.G.ModPow(test, key.Modulus)).Equals(input)) {
// output = test.ToByteArray();
// } else {
// output = null;
// }
output = test.ToByteArray();
}
return output;
}
/**
* Encrypts a BigInteger aka Plaintext with the public key.
*
* @param plain
* The BigInteger to encrypt
* @return The byte[] representation of the encrypted BigInteger (i.e.
* crypted.toByteArray())
*/
public virtual byte[] Encrypt(
BigInteger plain)
{
// Always return modulus size values 0-padded at the beginning
// 0-padding at the beginning is correctly parsed by BigInteger :)
// byte[] output = key.Modulus.ToByteArray();
// Array.Clear(output, 0, output.Length);
byte[] output = new byte[key.Modulus.BitLength / 8 + 1];
byte[] tmp = key.G.ModPow(plain, key.Modulus).ToByteArray();
Array.Copy(tmp, 0, output, output.Length - tmp.Length, tmp.Length);
return output;
}
/**
* Adds the contents of two encrypted blocks mod sigma
*
* @param block1
* the first encrypted block
* @param block2
* the second encrypted block
* @return encrypt((block1 + block2) mod sigma)
* @throws InvalidCipherTextException
*/
public virtual byte[] AddCryptedBlocks(
byte[] block1,
byte[] block2)
{
// check for correct blocksize
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");
}
}
// calculate resulting block
BigInteger m1Crypt = new BigInteger(1, block1);
BigInteger m2Crypt = new BigInteger(1, block2);
BigInteger m1m2Crypt = m1Crypt.Multiply(m2Crypt);
m1m2Crypt = m1m2Crypt.Mod(key.Modulus);
//byte[] output = key.Modulus.ToByteArray();
//Array.Clear(output, 0, output.Length);
byte[] output = new byte[key.Modulus.BitLength / 8 + 1];
byte[] m1m2CryptBytes = m1m2Crypt.ToByteArray();
Array.Copy(m1m2CryptBytes, 0, output,
output.Length - m1m2CryptBytes.Length, m1m2CryptBytes.Length);
return output;
}
/**
* Convenience Method for data exchange with the cipher.
*
* Determines blocksize and splits data to blocksize.
*
* @param data the data to be processed
* @return the data after it went through the NaccacheSternEngine.
* @throws InvalidCipherTextException
*/
public virtual byte[] ProcessData(
byte[] data)
{
if (data.Length > GetInputBlockSize())
{
int inBlocksize = GetInputBlockSize();
int outBlocksize = GetOutputBlockSize();
int datapos = 0;
int retpos = 0;
byte[] retval = new byte[(data.Length / inBlocksize + 1) * outBlocksize];
while (datapos < data.Length)
{
byte[] tmp;
if (datapos + inBlocksize < data.Length)
{
tmp = ProcessBlock(data, datapos, inBlocksize);
datapos += inBlocksize;
}
else
{
tmp = ProcessBlock(data, datapos, data.Length - datapos);
datapos += data.Length - datapos;
}
if (tmp != null)
{
tmp.CopyTo(retval, retpos);
retpos += tmp.Length;
}
else
{
throw new InvalidCipherTextException("cipher returned null");
}
}
byte[] ret = new byte[retpos];
Array.Copy(retval, 0, ret, 0, retpos);
return ret;
}
else
{
return ProcessBlock(data, 0, data.Length);
}
}
/**
* Computes the integer x that is expressed through the given primes and the
* congruences with the chinese remainder theorem (CRT).
*
* @param congruences
* the congruences c_i
* @param primes
* the primes p_i
* @return an integer x for that x % p_i == c_i
*/
private static BigInteger ChineseRemainder(IList<BigInteger> congruences, IList<BigInteger> primes)
{
BigInteger retval = BigInteger.Zero;
BigInteger all = BigInteger.One;
for (int i = 0; i < primes.Count; i++)
{
all = all.Multiply(primes[i]);
}
for (int i = 0; i < primes.Count; i++)
{
BigInteger a = primes[i];
BigInteger b = all.Divide(a);
BigInteger b2 = b.ModInverse(a);
BigInteger tmp = b.Multiply(b2);
tmp = tmp.Multiply(congruences[i]);
retval = retval.Add(tmp);
}
return retval.Mod(all);
}
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 4f4d7516337f74b46b83119aed1c7184
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/NaccacheSternEngine.cs
uploadId: 783279

View File

@ -0,0 +1,414 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/**
* A Noekeon engine, using direct-key mode.
*/
public class NoekeonEngine
: IBlockCipher
{
// Block and key size, as well as the amount of rounds.
private const int Size = 16;
private static readonly byte[] RoundConstants = { 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e,
0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4 };
private readonly uint[] k = new uint[4];
private bool _initialised, _forEncryption;
/**
* Create an instance of the Noekeon encryption algorithm
* and set some defaults
*/
public NoekeonEngine()
{
_initialised = false;
}
public virtual string AlgorithmName
{
get { return "Noekeon"; }
}
public virtual int GetBlockSize()
{
return Size;
}
/**
* initialise
*
* @param forEncryption whether or not we are for encryption.
* @param params the parameters required to set up the cipher.
* @exception ArgumentException if the params argument is
* inappropriate.
*/
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
if (!(parameters is KeyParameter))
throw new ArgumentException("Invalid parameters passed to Noekeon init - "
+ Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters), "parameters");
KeyParameter p = (KeyParameter) parameters;
byte[] key = p.GetKey();
if (key.Length != 16)
throw new ArgumentException("Key length not 128 bits.");
Pack.BE_To_UInt32(key, 0, k, 0, 4);
if (!forEncryption)
{
// theta(k, new uint[]{ 0x00, 0x00, 0x00, 0x00 });
{
uint a0 = k[0], a1 = k[1], a2 = k[2], a3 = k[3];
uint t02 = a0 ^ a2;
t02 ^= Integers.RotateLeft(t02, 8) ^ Integers.RotateLeft(t02, 24);
uint t13 = a1 ^ a3;
t13 ^= Integers.RotateLeft(t13, 8) ^ Integers.RotateLeft(t13, 24);
a0 ^= t13;
a1 ^= t02;
a2 ^= t13;
a3 ^= t02;
k[0] = a0; k[1] = a1; k[2] = a2; k[3] = a3;
}
}
this._forEncryption = forEncryption;
this._initialised = true;
}
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
{
if (!_initialised)
throw new InvalidOperationException(AlgorithmName + " not initialised");
Check.DataLength(input, inOff, Size, "input buffer too short");
Check.OutputLength(output, outOff, Size, "output buffer too short");
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
return _forEncryption
? EncryptBlock(input.AsSpan(inOff), output.AsSpan(outOff))
: DecryptBlock(input.AsSpan(inOff), output.AsSpan(outOff));
#else
return _forEncryption
? EncryptBlock(input, inOff, output, outOff)
: DecryptBlock(input, inOff, output, outOff);
#endif
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual int ProcessBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
if (!_initialised)
throw new InvalidOperationException(AlgorithmName + " not initialised");
Check.DataLength(input, Size, "input buffer too short");
Check.OutputLength(output, Size, "output buffer too short");
return _forEncryption
? EncryptBlock(input, output)
: DecryptBlock(input, output);
}
#endif
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
private int EncryptBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
uint a0 = Pack.BE_To_UInt32(input);
uint a1 = Pack.BE_To_UInt32(input[4..]);
uint a2 = Pack.BE_To_UInt32(input[8..]);
uint a3 = Pack.BE_To_UInt32(input[12..]);
uint k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];
int round = 0;
for (;;)
{
a0 ^= RoundConstants[round];
// theta(a, k);
{
uint t02 = a0 ^ a2;
t02 ^= Integers.RotateLeft(t02, 8) ^ Integers.RotateLeft(t02, 24);
a0 ^= k0;
a1 ^= k1;
a2 ^= k2;
a3 ^= k3;
uint t13 = a1 ^ a3;
t13 ^= Integers.RotateLeft(t13, 8) ^ Integers.RotateLeft(t13, 24);
a0 ^= t13;
a1 ^= t02;
a2 ^= t13;
a3 ^= t02;
}
if (++round > Size)
break;
// pi1(a);
{
a1 = Integers.RotateLeft(a1, 1);
a2 = Integers.RotateLeft(a2, 5);
a3 = Integers.RotateLeft(a3, 2);
}
// gamma(a);
{
uint t = a3;
a1 ^= a3 | a2;
a3 = a0 ^ (a2 & ~a1);
a2 = t ^ ~a1 ^ a2 ^ a3;
a1 ^= a3 | a2;
a0 = t ^ (a2 & a1);
}
// pi2(a);
{
a1 = Integers.RotateLeft(a1, 31);
a2 = Integers.RotateLeft(a2, 27);
a3 = Integers.RotateLeft(a3, 30);
}
}
Pack.UInt32_To_BE(a0, output);
Pack.UInt32_To_BE(a1, output[4..]);
Pack.UInt32_To_BE(a2, output[8..]);
Pack.UInt32_To_BE(a3, output[12..]);
return Size;
}
private int DecryptBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
uint a0 = Pack.BE_To_UInt32(input);
uint a1 = Pack.BE_To_UInt32(input[4..]);
uint a2 = Pack.BE_To_UInt32(input[8..]);
uint a3 = Pack.BE_To_UInt32(input[12..]);
uint k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];
int round = Size;
for (;;)
{
// theta(a, k);
{
uint t02 = a0 ^ a2;
t02 ^= Integers.RotateLeft(t02, 8) ^ Integers.RotateLeft(t02, 24);
a0 ^= k0;
a1 ^= k1;
a2 ^= k2;
a3 ^= k3;
uint t13 = a1 ^ a3;
t13 ^= Integers.RotateLeft(t13, 8) ^ Integers.RotateLeft(t13, 24);
a0 ^= t13;
a1 ^= t02;
a2 ^= t13;
a3 ^= t02;
}
a0 ^= RoundConstants[round];
if (--round < 0)
break;
// pi1(a);
{
a1 = Integers.RotateLeft(a1, 1);
a2 = Integers.RotateLeft(a2, 5);
a3 = Integers.RotateLeft(a3, 2);
}
// gamma(a);
{
uint t = a3;
a1 ^= a3 | a2;
a3 = a0 ^ (a2 & ~a1);
a2 = t ^ ~a1 ^ a2 ^ a3;
a1 ^= a3 | a2;
a0 = t ^ (a2 & a1);
}
// pi2(a);
{
a1 = Integers.RotateLeft(a1, 31);
a2 = Integers.RotateLeft(a2, 27);
a3 = Integers.RotateLeft(a3, 30);
}
}
Pack.UInt32_To_BE(a0, output);
Pack.UInt32_To_BE(a1, output[4..]);
Pack.UInt32_To_BE(a2, output[8..]);
Pack.UInt32_To_BE(a3, output[12..]);
return Size;
}
#else
private int EncryptBlock(byte[] input, int inOff, byte[] output, int outOff)
{
uint a0 = Pack.BE_To_UInt32(input, inOff);
uint a1 = Pack.BE_To_UInt32(input, inOff + 4);
uint a2 = Pack.BE_To_UInt32(input, inOff + 8);
uint a3 = Pack.BE_To_UInt32(input, inOff + 12);
uint k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];
int round = 0;
for (;;)
{
a0 ^= RoundConstants[round];
// theta(a, k);
{
uint t02 = a0 ^ a2;
t02 ^= Integers.RotateLeft(t02, 8) ^ Integers.RotateLeft(t02, 24);
a0 ^= k0;
a1 ^= k1;
a2 ^= k2;
a3 ^= k3;
uint t13 = a1 ^ a3;
t13 ^= Integers.RotateLeft(t13, 8) ^ Integers.RotateLeft(t13, 24);
a0 ^= t13;
a1 ^= t02;
a2 ^= t13;
a3 ^= t02;
}
if (++round > Size)
break;
// pi1(a);
{
a1 = Integers.RotateLeft(a1, 1);
a2 = Integers.RotateLeft(a2, 5);
a3 = Integers.RotateLeft(a3, 2);
}
// gamma(a);
{
uint t = a3;
a1 ^= a3 | a2;
a3 = a0 ^ (a2 & ~a1);
a2 = t ^ ~a1 ^ a2 ^ a3;
a1 ^= a3 | a2;
a0 = t ^ (a2 & a1);
}
// pi2(a);
{
a1 = Integers.RotateLeft(a1, 31);
a2 = Integers.RotateLeft(a2, 27);
a3 = Integers.RotateLeft(a3, 30);
}
}
Pack.UInt32_To_BE(a0, output, outOff);
Pack.UInt32_To_BE(a1, output, outOff + 4);
Pack.UInt32_To_BE(a2, output, outOff + 8);
Pack.UInt32_To_BE(a3, output, outOff + 12);
return Size;
}
private int DecryptBlock(byte[] input, int inOff, byte[] output, int outOff)
{
uint a0 = Pack.BE_To_UInt32(input, inOff);
uint a1 = Pack.BE_To_UInt32(input, inOff + 4);
uint a2 = Pack.BE_To_UInt32(input, inOff + 8);
uint a3 = Pack.BE_To_UInt32(input, inOff + 12);
uint k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3];
int round = Size;
for (;;)
{
// theta(a, k);
{
uint t02 = a0 ^ a2;
t02 ^= Integers.RotateLeft(t02, 8) ^ Integers.RotateLeft(t02, 24);
a0 ^= k0;
a1 ^= k1;
a2 ^= k2;
a3 ^= k3;
uint t13 = a1 ^ a3;
t13 ^= Integers.RotateLeft(t13, 8) ^ Integers.RotateLeft(t13, 24);
a0 ^= t13;
a1 ^= t02;
a2 ^= t13;
a3 ^= t02;
}
a0 ^= RoundConstants[round];
if (--round < 0)
break;
// pi1(a);
{
a1 = Integers.RotateLeft(a1, 1);
a2 = Integers.RotateLeft(a2, 5);
a3 = Integers.RotateLeft(a3, 2);
}
// gamma(a);
{
uint t = a3;
a1 ^= a3 | a2;
a3 = a0 ^ (a2 & ~a1);
a2 = t ^ ~a1 ^ a2 ^ a3;
a1 ^= a3 | a2;
a0 = t ^ (a2 & a1);
}
// pi2(a);
{
a1 = Integers.RotateLeft(a1, 31);
a2 = Integers.RotateLeft(a2, 27);
a3 = Integers.RotateLeft(a3, 30);
}
}
Pack.UInt32_To_BE(a0, output, outOff);
Pack.UInt32_To_BE(a1, output, outOff + 4);
Pack.UInt32_To_BE(a2, output, outOff + 8);
Pack.UInt32_To_BE(a3, output, outOff + 12);
return Size;
}
#endif
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 164c8b2d9ea43184a834ee4c7118963d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/NoekeonEngine.cs
uploadId: 783279

View File

@ -0,0 +1,2 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 5c0eb676404b00b4eb58a10223d7faf3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/NullEngine.cs
uploadId: 783279

View File

@ -0,0 +1,433 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/**
* an implementation of RC2 as described in RFC 2268
* "A Description of the RC2(r) Encryption Algorithm" R. Rivest.
*/
public class RC2Engine
: IBlockCipher
{
//
// the values we use for key expansion (based on the digits of PI)
//
private static readonly byte[] piTable =
{
(byte)0xd9, (byte)0x78, (byte)0xf9, (byte)0xc4, (byte)0x19, (byte)0xdd, (byte)0xb5, (byte)0xed,
(byte)0x28, (byte)0xe9, (byte)0xfd, (byte)0x79, (byte)0x4a, (byte)0xa0, (byte)0xd8, (byte)0x9d,
(byte)0xc6, (byte)0x7e, (byte)0x37, (byte)0x83, (byte)0x2b, (byte)0x76, (byte)0x53, (byte)0x8e,
(byte)0x62, (byte)0x4c, (byte)0x64, (byte)0x88, (byte)0x44, (byte)0x8b, (byte)0xfb, (byte)0xa2,
(byte)0x17, (byte)0x9a, (byte)0x59, (byte)0xf5, (byte)0x87, (byte)0xb3, (byte)0x4f, (byte)0x13,
(byte)0x61, (byte)0x45, (byte)0x6d, (byte)0x8d, (byte)0x9, (byte)0x81, (byte)0x7d, (byte)0x32,
(byte)0xbd, (byte)0x8f, (byte)0x40, (byte)0xeb, (byte)0x86, (byte)0xb7, (byte)0x7b, (byte)0xb,
(byte)0xf0, (byte)0x95, (byte)0x21, (byte)0x22, (byte)0x5c, (byte)0x6b, (byte)0x4e, (byte)0x82,
(byte)0x54, (byte)0xd6, (byte)0x65, (byte)0x93, (byte)0xce, (byte)0x60, (byte)0xb2, (byte)0x1c,
(byte)0x73, (byte)0x56, (byte)0xc0, (byte)0x14, (byte)0xa7, (byte)0x8c, (byte)0xf1, (byte)0xdc,
(byte)0x12, (byte)0x75, (byte)0xca, (byte)0x1f, (byte)0x3b, (byte)0xbe, (byte)0xe4, (byte)0xd1,
(byte)0x42, (byte)0x3d, (byte)0xd4, (byte)0x30, (byte)0xa3, (byte)0x3c, (byte)0xb6, (byte)0x26,
(byte)0x6f, (byte)0xbf, (byte)0xe, (byte)0xda, (byte)0x46, (byte)0x69, (byte)0x7, (byte)0x57,
(byte)0x27, (byte)0xf2, (byte)0x1d, (byte)0x9b, (byte)0xbc, (byte)0x94, (byte)0x43, (byte)0x3,
(byte)0xf8, (byte)0x11, (byte)0xc7, (byte)0xf6, (byte)0x90, (byte)0xef, (byte)0x3e, (byte)0xe7,
(byte)0x6, (byte)0xc3, (byte)0xd5, (byte)0x2f, (byte)0xc8, (byte)0x66, (byte)0x1e, (byte)0xd7,
(byte)0x8, (byte)0xe8, (byte)0xea, (byte)0xde, (byte)0x80, (byte)0x52, (byte)0xee, (byte)0xf7,
(byte)0x84, (byte)0xaa, (byte)0x72, (byte)0xac, (byte)0x35, (byte)0x4d, (byte)0x6a, (byte)0x2a,
(byte)0x96, (byte)0x1a, (byte)0xd2, (byte)0x71, (byte)0x5a, (byte)0x15, (byte)0x49, (byte)0x74,
(byte)0x4b, (byte)0x9f, (byte)0xd0, (byte)0x5e, (byte)0x4, (byte)0x18, (byte)0xa4, (byte)0xec,
(byte)0xc2, (byte)0xe0, (byte)0x41, (byte)0x6e, (byte)0xf, (byte)0x51, (byte)0xcb, (byte)0xcc,
(byte)0x24, (byte)0x91, (byte)0xaf, (byte)0x50, (byte)0xa1, (byte)0xf4, (byte)0x70, (byte)0x39,
(byte)0x99, (byte)0x7c, (byte)0x3a, (byte)0x85, (byte)0x23, (byte)0xb8, (byte)0xb4, (byte)0x7a,
(byte)0xfc, (byte)0x2, (byte)0x36, (byte)0x5b, (byte)0x25, (byte)0x55, (byte)0x97, (byte)0x31,
(byte)0x2d, (byte)0x5d, (byte)0xfa, (byte)0x98, (byte)0xe3, (byte)0x8a, (byte)0x92, (byte)0xae,
(byte)0x5, (byte)0xdf, (byte)0x29, (byte)0x10, (byte)0x67, (byte)0x6c, (byte)0xba, (byte)0xc9,
(byte)0xd3, (byte)0x0, (byte)0xe6, (byte)0xcf, (byte)0xe1, (byte)0x9e, (byte)0xa8, (byte)0x2c,
(byte)0x63, (byte)0x16, (byte)0x1, (byte)0x3f, (byte)0x58, (byte)0xe2, (byte)0x89, (byte)0xa9,
(byte)0xd, (byte)0x38, (byte)0x34, (byte)0x1b, (byte)0xab, (byte)0x33, (byte)0xff, (byte)0xb0,
(byte)0xbb, (byte)0x48, (byte)0xc, (byte)0x5f, (byte)0xb9, (byte)0xb1, (byte)0xcd, (byte)0x2e,
(byte)0xc5, (byte)0xf3, (byte)0xdb, (byte)0x47, (byte)0xe5, (byte)0xa5, (byte)0x9c, (byte)0x77,
(byte)0xa, (byte)0xa6, (byte)0x20, (byte)0x68, (byte)0xfe, (byte)0x7f, (byte)0xc1, (byte)0xad
};
private const int BLOCK_SIZE = 8;
private int[] workingKey;
private bool encrypting;
private int[] GenerateWorkingKey(
byte[] key,
int bits)
{
int x;
int[] xKey = new int[128];
for (int i = 0; i != key.Length; i++)
{
xKey[i] = key[i] & 0xff;
}
// Phase 1: Expand input key to 128 bytes
int len = key.Length;
if (len < 128)
{
int index = 0;
x = xKey[len - 1];
do
{
x = piTable[(x + xKey[index++]) & 255] & 0xff;
xKey[len++] = x;
}
while (len < 128);
}
// Phase 2 - reduce effective key size to "bits"
len = (bits + 7) >> 3;
x = piTable[xKey[128 - len] & (255 >> (7 & -bits))] & 0xff;
xKey[128 - len] = x;
for (int i = 128 - len - 1; i >= 0; i--)
{
x = piTable[x ^ xKey[i + len]] & 0xff;
xKey[i] = x;
}
// Phase 3 - copy to newKey in little-endian order
int[] newKey = new int[64];
for (int i = 0; i != newKey.Length; i++)
{
newKey[i] = (xKey[2 * i] + (xKey[2 * i + 1] << 8));
}
return newKey;
}
/**
* initialise a RC2 cipher.
*
* @param forEncryption whether or not we are for encryption.
* @param parameters the parameters required to set up the cipher.
* @exception ArgumentException if the parameters argument is
* inappropriate.
*/
public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
this.encrypting = forEncryption;
if (parameters is RC2Parameters)
{
RC2Parameters param = (RC2Parameters) parameters;
workingKey = GenerateWorkingKey(param.GetKey(), param.EffectiveKeyBits);
}
else if (parameters is KeyParameter)
{
KeyParameter param = (KeyParameter) parameters;
byte[] key = param.GetKey();
workingKey = GenerateWorkingKey(key, key.Length * 8);
}
else
{
throw new ArgumentException("invalid parameter passed to RC2 init - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters));
}
}
public virtual string AlgorithmName
{
get { return "RC2"; }
}
public virtual int GetBlockSize()
{
return BLOCK_SIZE;
}
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, BLOCK_SIZE, "input buffer too short");
Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short");
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
if (encrypting)
{
EncryptBlock(input.AsSpan(inOff), output.AsSpan(outOff));
}
else
{
DecryptBlock(input.AsSpan(inOff), output.AsSpan(outOff));
}
#else
if (encrypting)
{
EncryptBlock(input, inOff, output, outOff);
}
else
{
DecryptBlock(input, inOff, output, outOff);
}
#endif
return BLOCK_SIZE;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual int ProcessBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
if (workingKey == null)
throw new InvalidOperationException("RC2 engine not initialised");
Check.DataLength(input, BLOCK_SIZE, "input buffer too short");
Check.OutputLength(output, BLOCK_SIZE, "output buffer too short");
if (encrypting)
{
EncryptBlock(input, output);
}
else
{
DecryptBlock(input, output);
}
return BLOCK_SIZE;
}
#endif
/**
* return the result rotating the 16 bit number in x left by y
*/
private static int RotateWordLeft(int x, int y)
{
x &= 0xffff;
return (x << y) | (x >> (16 - y));
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
private void EncryptBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
int x76, x54, x32, x10;
x76 = ((input[7] & 0xff) << 8) + (input[6] & 0xff);
x54 = ((input[5] & 0xff) << 8) + (input[4] & 0xff);
x32 = ((input[3] & 0xff) << 8) + (input[2] & 0xff);
x10 = ((input[1] & 0xff) << 8) + (input[0] & 0xff);
for (int i = 0; i <= 16; i += 4)
{
x10 = RotateWordLeft(x10 + (x32 & ~x76) + (x54 & x76) + workingKey[i], 1);
x32 = RotateWordLeft(x32 + (x54 & ~x10) + (x76 & x10) + workingKey[i + 1], 2);
x54 = RotateWordLeft(x54 + (x76 & ~x32) + (x10 & x32) + workingKey[i + 2], 3);
x76 = RotateWordLeft(x76 + (x10 & ~x54) + (x32 & x54) + workingKey[i + 3], 5);
}
x10 += workingKey[x76 & 63];
x32 += workingKey[x10 & 63];
x54 += workingKey[x32 & 63];
x76 += workingKey[x54 & 63];
for (int i = 20; i <= 40; i += 4)
{
x10 = RotateWordLeft(x10 + (x32 & ~x76) + (x54 & x76) + workingKey[i], 1);
x32 = RotateWordLeft(x32 + (x54 & ~x10) + (x76 & x10) + workingKey[i + 1], 2);
x54 = RotateWordLeft(x54 + (x76 & ~x32) + (x10 & x32) + workingKey[i + 2], 3);
x76 = RotateWordLeft(x76 + (x10 & ~x54) + (x32 & x54) + workingKey[i + 3], 5);
}
x10 += workingKey[x76 & 63];
x32 += workingKey[x10 & 63];
x54 += workingKey[x32 & 63];
x76 += workingKey[x54 & 63];
for (int i = 44; i < 64; i += 4)
{
x10 = RotateWordLeft(x10 + (x32 & ~x76) + (x54 & x76) + workingKey[i], 1);
x32 = RotateWordLeft(x32 + (x54 & ~x10) + (x76 & x10) + workingKey[i + 1], 2);
x54 = RotateWordLeft(x54 + (x76 & ~x32) + (x10 & x32) + workingKey[i + 2], 3);
x76 = RotateWordLeft(x76 + (x10 & ~x54) + (x32 & x54) + workingKey[i + 3], 5);
}
output[0] = (byte)x10;
output[1] = (byte)(x10 >> 8);
output[2] = (byte)x32;
output[3] = (byte)(x32 >> 8);
output[4] = (byte)x54;
output[5] = (byte)(x54 >> 8);
output[6] = (byte)x76;
output[7] = (byte)(x76 >> 8);
}
private void DecryptBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
int x76, x54, x32, x10;
x76 = ((input[7] & 0xff) << 8) + (input[6] & 0xff);
x54 = ((input[5] & 0xff) << 8) + (input[4] & 0xff);
x32 = ((input[3] & 0xff) << 8) + (input[2] & 0xff);
x10 = ((input[1] & 0xff) << 8) + (input[0] & 0xff);
for (int i = 60; i >= 44; i -= 4)
{
x76 = RotateWordLeft(x76, 11) - ((x10 & ~x54) + (x32 & x54) + workingKey[i + 3]);
x54 = RotateWordLeft(x54, 13) - ((x76 & ~x32) + (x10 & x32) + workingKey[i + 2]);
x32 = RotateWordLeft(x32, 14) - ((x54 & ~x10) + (x76 & x10) + workingKey[i + 1]);
x10 = RotateWordLeft(x10, 15) - ((x32 & ~x76) + (x54 & x76) + workingKey[i]);
}
x76 -= workingKey[x54 & 63];
x54 -= workingKey[x32 & 63];
x32 -= workingKey[x10 & 63];
x10 -= workingKey[x76 & 63];
for (int i = 40; i >= 20; i -= 4)
{
x76 = RotateWordLeft(x76, 11) - ((x10 & ~x54) + (x32 & x54) + workingKey[i + 3]);
x54 = RotateWordLeft(x54, 13) - ((x76 & ~x32) + (x10 & x32) + workingKey[i + 2]);
x32 = RotateWordLeft(x32, 14) - ((x54 & ~x10) + (x76 & x10) + workingKey[i + 1]);
x10 = RotateWordLeft(x10, 15) - ((x32 & ~x76) + (x54 & x76) + workingKey[i]);
}
x76 -= workingKey[x54 & 63];
x54 -= workingKey[x32 & 63];
x32 -= workingKey[x10 & 63];
x10 -= workingKey[x76 & 63];
for (int i = 16; i >= 0; i -= 4)
{
x76 = RotateWordLeft(x76, 11) - ((x10 & ~x54) + (x32 & x54) + workingKey[i + 3]);
x54 = RotateWordLeft(x54, 13) - ((x76 & ~x32) + (x10 & x32) + workingKey[i + 2]);
x32 = RotateWordLeft(x32, 14) - ((x54 & ~x10) + (x76 & x10) + workingKey[i + 1]);
x10 = RotateWordLeft(x10, 15) - ((x32 & ~x76) + (x54 & x76) + workingKey[i]);
}
output[0] = (byte)x10;
output[1] = (byte)(x10 >> 8);
output[2] = (byte)x32;
output[3] = (byte)(x32 >> 8);
output[4] = (byte)x54;
output[5] = (byte)(x54 >> 8);
output[6] = (byte)x76;
output[7] = (byte)(x76 >> 8);
}
#else
private void EncryptBlock(byte[] input, int inOff, byte[] outBytes, int outOff)
{
int x76, x54, x32, x10;
x76 = ((input[inOff + 7] & 0xff) << 8) + (input[inOff + 6] & 0xff);
x54 = ((input[inOff + 5] & 0xff) << 8) + (input[inOff + 4] & 0xff);
x32 = ((input[inOff + 3] & 0xff) << 8) + (input[inOff + 2] & 0xff);
x10 = ((input[inOff + 1] & 0xff) << 8) + (input[inOff + 0] & 0xff);
for (int i = 0; i <= 16; i += 4)
{
x10 = RotateWordLeft(x10 + (x32 & ~x76) + (x54 & x76) + workingKey[i ], 1);
x32 = RotateWordLeft(x32 + (x54 & ~x10) + (x76 & x10) + workingKey[i+1], 2);
x54 = RotateWordLeft(x54 + (x76 & ~x32) + (x10 & x32) + workingKey[i+2], 3);
x76 = RotateWordLeft(x76 + (x10 & ~x54) + (x32 & x54) + workingKey[i+3], 5);
}
x10 += workingKey[x76 & 63];
x32 += workingKey[x10 & 63];
x54 += workingKey[x32 & 63];
x76 += workingKey[x54 & 63];
for (int i = 20; i <= 40; i += 4)
{
x10 = RotateWordLeft(x10 + (x32 & ~x76) + (x54 & x76) + workingKey[i ], 1);
x32 = RotateWordLeft(x32 + (x54 & ~x10) + (x76 & x10) + workingKey[i+1], 2);
x54 = RotateWordLeft(x54 + (x76 & ~x32) + (x10 & x32) + workingKey[i+2], 3);
x76 = RotateWordLeft(x76 + (x10 & ~x54) + (x32 & x54) + workingKey[i+3], 5);
}
x10 += workingKey[x76 & 63];
x32 += workingKey[x10 & 63];
x54 += workingKey[x32 & 63];
x76 += workingKey[x54 & 63];
for (int i = 44; i < 64; i += 4)
{
x10 = RotateWordLeft(x10 + (x32 & ~x76) + (x54 & x76) + workingKey[i ], 1);
x32 = RotateWordLeft(x32 + (x54 & ~x10) + (x76 & x10) + workingKey[i+1], 2);
x54 = RotateWordLeft(x54 + (x76 & ~x32) + (x10 & x32) + workingKey[i+2], 3);
x76 = RotateWordLeft(x76 + (x10 & ~x54) + (x32 & x54) + workingKey[i+3], 5);
}
outBytes[outOff + 0] = (byte)x10;
outBytes[outOff + 1] = (byte)(x10 >> 8);
outBytes[outOff + 2] = (byte)x32;
outBytes[outOff + 3] = (byte)(x32 >> 8);
outBytes[outOff + 4] = (byte)x54;
outBytes[outOff + 5] = (byte)(x54 >> 8);
outBytes[outOff + 6] = (byte)x76;
outBytes[outOff + 7] = (byte)(x76 >> 8);
}
private void DecryptBlock(byte[] input, int inOff, byte[] outBytes, int outOff)
{
int x76, x54, x32, x10;
x76 = ((input[inOff + 7] & 0xff) << 8) + (input[inOff + 6] & 0xff);
x54 = ((input[inOff + 5] & 0xff) << 8) + (input[inOff + 4] & 0xff);
x32 = ((input[inOff + 3] & 0xff) << 8) + (input[inOff + 2] & 0xff);
x10 = ((input[inOff + 1] & 0xff) << 8) + (input[inOff + 0] & 0xff);
for (int i = 60; i >= 44; i -= 4)
{
x76 = RotateWordLeft(x76, 11) - ((x10 & ~x54) + (x32 & x54) + workingKey[i+3]);
x54 = RotateWordLeft(x54, 13) - ((x76 & ~x32) + (x10 & x32) + workingKey[i+2]);
x32 = RotateWordLeft(x32, 14) - ((x54 & ~x10) + (x76 & x10) + workingKey[i+1]);
x10 = RotateWordLeft(x10, 15) - ((x32 & ~x76) + (x54 & x76) + workingKey[i ]);
}
x76 -= workingKey[x54 & 63];
x54 -= workingKey[x32 & 63];
x32 -= workingKey[x10 & 63];
x10 -= workingKey[x76 & 63];
for (int i = 40; i >= 20; i -= 4)
{
x76 = RotateWordLeft(x76, 11) - ((x10 & ~x54) + (x32 & x54) + workingKey[i+3]);
x54 = RotateWordLeft(x54, 13) - ((x76 & ~x32) + (x10 & x32) + workingKey[i+2]);
x32 = RotateWordLeft(x32, 14) - ((x54 & ~x10) + (x76 & x10) + workingKey[i+1]);
x10 = RotateWordLeft(x10, 15) - ((x32 & ~x76) + (x54 & x76) + workingKey[i ]);
}
x76 -= workingKey[x54 & 63];
x54 -= workingKey[x32 & 63];
x32 -= workingKey[x10 & 63];
x10 -= workingKey[x76 & 63];
for (int i = 16; i >= 0; i -= 4)
{
x76 = RotateWordLeft(x76, 11) - ((x10 & ~x54) + (x32 & x54) + workingKey[i+3]);
x54 = RotateWordLeft(x54, 13) - ((x76 & ~x32) + (x10 & x32) + workingKey[i+2]);
x32 = RotateWordLeft(x32, 14) - ((x54 & ~x10) + (x76 & x10) + workingKey[i+1]);
x10 = RotateWordLeft(x10, 15) - ((x32 & ~x76) + (x54 & x76) + workingKey[i ]);
}
outBytes[outOff + 0] = (byte)x10;
outBytes[outOff + 1] = (byte)(x10 >> 8);
outBytes[outOff + 2] = (byte)x32;
outBytes[outOff + 3] = (byte)(x32 >> 8);
outBytes[outOff + 4] = (byte)x54;
outBytes[outOff + 5] = (byte)(x54 >> 8);
outBytes[outOff + 6] = (byte)x76;
outBytes[outOff + 7] = (byte)(x76 >> 8);
}
#endif
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 673892226e64f09479c20f1cc717d293
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/RC2Engine.cs
uploadId: 783279

View File

@ -0,0 +1,371 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Modes;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/**
* Wrap keys according to RFC 3217 - RC2 mechanism
*/
public class RC2WrapEngine
: IWrapper
{
/** Field engine */
private CbcBlockCipher engine;
/** Field param */
private ICipherParameters parameters;
/** Field paramPlusIV */
private ParametersWithIV paramPlusIV;
/** Field iv */
private byte[] iv;
/** Field forWrapping */
private bool forWrapping;
private SecureRandom sr;
/** Field IV2 */
private static readonly byte[] IV2 =
{
(byte) 0x4a, (byte) 0xdd, (byte) 0xa2,
(byte) 0x2c, (byte) 0x79, (byte) 0xe8,
(byte) 0x21, (byte) 0x05
};
//
// checksum digest
//
private readonly IDigest sha1 = new Sha1Digest();
private readonly byte[] digest = new byte[20];
/**
* Method init
*
* @param forWrapping
* @param param
*/
public virtual void Init(bool forWrapping, ICipherParameters parameters)
{
this.forWrapping = forWrapping;
this.engine = new CbcBlockCipher(new RC2Engine());
if (parameters is ParametersWithRandom pWithR)
{
sr = pWithR.Random;
parameters = pWithR.Parameters;
}
else
{
sr = CryptoServicesRegistrar.GetSecureRandom();
}
if (parameters is ParametersWithIV)
{
if (!forWrapping)
throw new ArgumentException("You should not supply an IV for unwrapping");
this.paramPlusIV = (ParametersWithIV)parameters;
this.iv = this.paramPlusIV.GetIV();
this.parameters = this.paramPlusIV.Parameters;
if (this.iv.Length != 8)
throw new ArgumentException("IV is not 8 octets");
}
else
{
this.parameters = parameters;
if (this.forWrapping)
{
// Hm, we have no IV but we want to wrap ?!?
// well, then we have to create our own IV.
this.iv = new byte[8];
sr.NextBytes(iv);
this.paramPlusIV = new ParametersWithIV(this.parameters, this.iv);
}
}
}
/**
* Method GetAlgorithmName
*
* @return
*/
public virtual string AlgorithmName
{
get { return "RC2"; }
}
/**
* Method wrap
*
* @param in
* @param inOff
* @param inLen
* @return
*/
public virtual byte[] Wrap(
byte[] input,
int inOff,
int length)
{
if (!forWrapping)
{
throw new InvalidOperationException("Not initialized for wrapping");
}
int len = length + 1;
if ((len % 8) != 0)
{
len += 8 - (len % 8);
}
byte [] keyToBeWrapped = new byte[len];
keyToBeWrapped[0] = (byte)length;
Array.Copy(input, inOff, keyToBeWrapped, 1, length);
byte[] pad = new byte[keyToBeWrapped.Length - length - 1];
if (pad.Length > 0)
{
sr.NextBytes(pad);
Array.Copy(pad, 0, keyToBeWrapped, length + 1, pad.Length);
}
// Compute the CMS Key Checksum, (section 5.6.1), call this CKS.
byte[] CKS = CalculateCmsKeyChecksum(keyToBeWrapped);
// Let WKCKS = WK || CKS where || is concatenation.
byte[] WKCKS = new byte[keyToBeWrapped.Length + CKS.Length];
Array.Copy(keyToBeWrapped, 0, WKCKS, 0, keyToBeWrapped.Length);
Array.Copy(CKS, 0, WKCKS, keyToBeWrapped.Length, CKS.Length);
// Encrypt WKCKS in CBC mode using KEK as the key and IV as the
// initialization vector. Call the results TEMP1.
byte [] TEMP1 = new byte[WKCKS.Length];
Array.Copy(WKCKS, 0, TEMP1, 0, WKCKS.Length);
int noOfBlocks = WKCKS.Length / engine.GetBlockSize();
int extraBytes = WKCKS.Length % engine.GetBlockSize();
if (extraBytes != 0)
{
throw new InvalidOperationException("Not multiple of block length");
}
engine.Init(true, paramPlusIV);
for (int i = 0; i < noOfBlocks; i++)
{
int currentBytePos = i * engine.GetBlockSize();
engine.ProcessBlock(TEMP1, currentBytePos, TEMP1, currentBytePos);
}
// Left TEMP2 = IV || TEMP1.
byte[] TEMP2 = new byte[this.iv.Length + TEMP1.Length];
Array.Copy(this.iv, 0, TEMP2, 0, this.iv.Length);
Array.Copy(TEMP1, 0, TEMP2, this.iv.Length, TEMP1.Length);
// Reverse the order of the octets in TEMP2 and call the result TEMP3.
byte[] TEMP3 = new byte[TEMP2.Length];
for (int i = 0; i < TEMP2.Length; i++)
{
TEMP3[i] = TEMP2[TEMP2.Length - (i + 1)];
}
// Encrypt TEMP3 in CBC mode using the KEK and an initialization vector
// of 0x 4a dd a2 2c 79 e8 21 05. The resulting cipher text is the desired
// result. It is 40 octets long if a 168 bit key is being wrapped.
ParametersWithIV param2 = new ParametersWithIV(this.parameters, IV2);
this.engine.Init(true, param2);
for (int i = 0; i < noOfBlocks + 1; i++)
{
int currentBytePos = i * engine.GetBlockSize();
engine.ProcessBlock(TEMP3, currentBytePos, TEMP3, currentBytePos);
}
return TEMP3;
}
/**
* Method unwrap
*
* @param in
* @param inOff
* @param inLen
* @return
* @throws InvalidCipherTextException
*/
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());
}
/*
// Check if the length of the cipher text is reasonable given the key
// type. It must be 40 bytes for a 168 bit key and either 32, 40, or
// 48 bytes for a 128, 192, or 256 bit key. If the length is not supported
// or inconsistent with the algorithm for which the key is intended,
// return error.
//
// we do not accept 168 bit keys. it has to be 192 bit.
int lengthA = (estimatedKeyLengthInBit / 8) + 16;
int lengthB = estimatedKeyLengthInBit % 8;
if ((lengthA != keyToBeUnwrapped.Length) || (lengthB != 0)) {
throw new XMLSecurityException("empty");
}
*/
// Decrypt the cipher text with TRIPLedeS in CBC mode using the KEK
// and an initialization vector (IV) of 0x4adda22c79e82105. Call the output TEMP3.
ParametersWithIV param2 = new ParametersWithIV(this.parameters, IV2);
this.engine.Init(false, param2);
byte [] TEMP3 = new byte[length];
Array.Copy(input, inOff, TEMP3, 0, length);
for (int i = 0; i < (TEMP3.Length / engine.GetBlockSize()); i++)
{
int currentBytePos = i * engine.GetBlockSize();
engine.ProcessBlock(TEMP3, currentBytePos, TEMP3, currentBytePos);
}
// Reverse the order of the octets in TEMP3 and call the result TEMP2.
byte[] TEMP2 = new byte[TEMP3.Length];
for (int i = 0; i < TEMP3.Length; i++)
{
TEMP2[i] = TEMP3[TEMP3.Length - (i + 1)];
}
// Decompose TEMP2 into IV, the first 8 octets, and TEMP1, the remaining octets.
this.iv = new byte[8];
byte[] TEMP1 = new byte[TEMP2.Length - 8];
Array.Copy(TEMP2, 0, this.iv, 0, 8);
Array.Copy(TEMP2, 8, TEMP1, 0, TEMP2.Length - 8);
// Decrypt TEMP1 using TRIPLedeS in CBC mode using the KEK and the IV
// found in the previous step. Call the result WKCKS.
this.paramPlusIV = new ParametersWithIV(this.parameters, this.iv);
this.engine.Init(false, this.paramPlusIV);
byte[] LCEKPADICV = new byte[TEMP1.Length];
Array.Copy(TEMP1, 0, LCEKPADICV, 0, TEMP1.Length);
for (int i = 0; i < (LCEKPADICV.Length / engine.GetBlockSize()); i++)
{
int currentBytePos = i * engine.GetBlockSize();
engine.ProcessBlock(LCEKPADICV, currentBytePos, LCEKPADICV, currentBytePos);
}
// Decompose LCEKPADICV. CKS is the last 8 octets and WK, the wrapped key, are
// those octets before the CKS.
byte[] result = new byte[LCEKPADICV.Length - 8];
byte[] CKStoBeVerified = new byte[8];
Array.Copy(LCEKPADICV, 0, result, 0, LCEKPADICV.Length - 8);
Array.Copy(LCEKPADICV, LCEKPADICV.Length - 8, CKStoBeVerified, 0, 8);
// Calculate a CMS Key Checksum, (section 5.6.1), over the WK and compare
// with the CKS extracted in the above step. If they are not equal, return error.
if (!CheckCmsKeyChecksum(result, CKStoBeVerified))
{
throw new InvalidCipherTextException(
"Checksum inside ciphertext is corrupted");
}
if ((result.Length - ((result[0] & 0xff) + 1)) > 7)
{
throw new InvalidCipherTextException(
"too many pad bytes (" + (result.Length - ((result[0] & 0xff) + 1)) + ")");
}
// CEK is the wrapped key, now extracted for use in data decryption.
byte[] CEK = new byte[result[0]];
Array.Copy(result, 1, CEK, 0, CEK.Length);
return CEK;
}
/**
* Some key wrap algorithms make use of the Key Checksum defined
* in CMS [CMS-Algorithms]. This is used to provide an integrity
* check value for the key being wrapped. The algorithm is
*
* - Compute the 20 octet SHA-1 hash on the key being wrapped.
* - Use the first 8 octets of this hash as the checksum value.
*
* @param key
* @return
* @throws Exception
* @see http://www.w3.org/TR/xmlenc-core/#sec-CMSKeyChecksum
*/
private byte[] CalculateCmsKeyChecksum(
byte[] key)
{
sha1.BlockUpdate(key, 0, key.Length);
sha1.DoFinal(digest, 0);
byte[] result = new byte[8];
Array.Copy(digest, 0, result, 0, 8);
return result;
}
/**
* @param key
* @param checksum
* @return
* @see http://www.w3.org/TR/xmlenc-core/#sec-CMSKeyChecksum
*/
private bool CheckCmsKeyChecksum(
byte[] key,
byte[] checksum)
{
return Arrays.ConstantTimeAreEqual(CalculateCmsKeyChecksum(key), checksum);
}
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: acd004a5f8a034246acc6c2aae60aa0f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/RC2WrapEngine.cs
uploadId: 783279

View File

@ -0,0 +1,167 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
public class RC4Engine
: IStreamCipher
{
private readonly static int STATE_LENGTH = 256;
/*
* variables to hold the state of the RC4 engine
* during encryption and decryption
*/
private byte[] engineState;
private int x;
private int y;
private byte[] workingKey;
/**
* initialise a RC4 cipher.
*
* @param forEncryption whether or not we are for encryption.
* @param parameters the parameters required to set up the cipher.
* @exception ArgumentException if the parameters argument is
* inappropriate.
*/
public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
if (parameters is KeyParameter)
{
/*
* RC4 encryption and decryption is completely
* symmetrical, so the 'forEncryption' is
* irrelevant.
*/
workingKey = ((KeyParameter)parameters).GetKey();
SetKey(workingKey);
return;
}
throw new ArgumentException("invalid parameter passed to RC4 init - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters));
}
public virtual string AlgorithmName
{
get { return "RC4"; }
}
public virtual byte ReturnByte(
byte input)
{
x = (x + 1) & 0xff;
y = (engineState[x] + y) & 0xff;
// swap
byte tmp = engineState[x];
engineState[x] = engineState[y];
engineState[y] = tmp;
// xor
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 sx = engineState[x];
byte sy = engineState[y];
// swap
engineState[x] = sy;
engineState[y] = sx;
// xor
output[i+outOff] = (byte)(input[i + inOff] ^ engineState[(sx + sy) & 0xff]);
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual void ProcessBytes(ReadOnlySpan<byte> input, Span<byte> output)
{
Check.OutputLength(output, input.Length, "output buffer too short");
for (int i = 0; i < input.Length; i++)
{
x = (x + 1) & 0xff;
y = (engineState[x] + y) & 0xff;
byte sx = engineState[x];
byte sy = engineState[y];
// swap
engineState[x] = sy;
engineState[y] = sx;
// xor
output[i] = (byte)(input[i] ^ engineState[(sx + sy) & 0xff]);
}
}
#endif
public virtual void Reset()
{
SetKey(workingKey);
}
// Private implementation
private void SetKey(
byte[] keyBytes)
{
workingKey = keyBytes;
// System.out.println("the key length is ; "+ workingKey.Length);
x = 0;
y = 0;
if (engineState == null)
{
engineState = new byte[STATE_LENGTH];
}
// reset the state of the engine
for (int i=0; i < STATE_LENGTH; i++)
{
engineState[i] = (byte)i;
}
int i1 = 0;
int i2 = 0;
for (int i=0; i < STATE_LENGTH; i++)
{
i2 = ((keyBytes[i1] & 0xff) + engineState[i] + i2) & 0xff;
// do the byte-swap inline
byte tmp = engineState[i];
engineState[i] = engineState[i2];
engineState[i2] = tmp;
i1 = (i1+1) % keyBytes.Length;
}
}
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 457d3936f4e6c504fa7aa397f724ff68
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/RC4Engine.cs
uploadId: 783279

View File

@ -0,0 +1,254 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/**
* The specification for RC5 came from the <code>RC5 Encryption Algorithm</code>
* publication in RSA CryptoBytes, Spring of 1995.
* <em>http://www.rsasecurity.com/rsalabs/cryptobytes</em>.
* <p>
* This implementation has a word size of 32 bits.</p>
*/
public class RC532Engine
: IBlockCipher
{
/*
* the number of rounds to perform
*/
private int _noRounds;
/*
* the expanded key array of size 2*(rounds + 1)
*/
private int [] _S;
/*
* our "magic constants" for 32 32
*
* Pw = Odd((e-2) * 2^wordsize)
* Qw = Odd((o-2) * 2^wordsize)
*
* where e is the base of natural logarithms (2.718281828...)
* and o is the golden ratio (1.61803398...)
*/
private static readonly int P32 = unchecked((int) 0xb7e15163);
private static readonly int Q32 = unchecked((int) 0x9e3779b9);
private bool forEncryption;
/**
* Create an instance of the RC5 encryption algorithm
* and set some defaults
*/
public RC532Engine()
{
_noRounds = 12; // the default
}
public virtual string AlgorithmName
{
get { return "RC5-32"; }
}
public virtual int GetBlockSize()
{
return 2 * 4;
}
/**
* initialise a RC5-32 cipher.
*
* @param forEncryption whether or not we are for encryption.
* @param parameters the parameters required to set up the cipher.
* @exception ArgumentException if the parameters argument is
* inappropriate.
*/
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
if (parameters is RC5Parameters rc5Parameters)
{
_noRounds = rc5Parameters.Rounds;
SetKey(rc5Parameters.GetKey());
}
else if (parameters is KeyParameter keyParameter)
{
SetKey(keyParameter.GetKey());
}
else
{
throw new ArgumentException("invalid parameter passed to RC532 init - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters));
}
this.forEncryption = forEncryption;
}
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
return forEncryption
? EncryptBlock(input.AsSpan(inOff), output.AsSpan(outOff))
: DecryptBlock(input.AsSpan(inOff), output.AsSpan(outOff));
#else
return forEncryption
? EncryptBlock(input, inOff, output, outOff)
: DecryptBlock(input, inOff, output, outOff);
#endif
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual int ProcessBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
return forEncryption
? EncryptBlock(input, output)
: DecryptBlock(input, output);
}
#endif
/**
* Re-key the cipher.
*
* @param key the key to be used
*/
private void SetKey(byte[] key)
{
//
// KEY EXPANSION:
//
// There are 3 phases to the key expansion.
//
// Phase 1:
// Copy the secret key K[0...b-1] into an array L[0..c-1] of
// c = ceil(b/u), where u = 32/8 in little-endian order.
// In other words, we fill up L using u consecutive key bytes
// of K. Any unfilled byte positions in L are zeroed. In the
// case that b = c = 0, set c = 1 and L[0] = 0.
//
int[] L = new int[(key.Length + 3) / 4];
for (int i = 0; i != key.Length; i++)
{
L[i / 4] += (key[i] & 0xff) << (8 * (i % 4));
}
//
// Phase 2:
// Initialize S to a particular fixed pseudo-random bit pattern
// using an arithmetic progression modulo 2^wordsize determined
// by the magic numbers, Pw & Qw.
//
_S = new int[2*(_noRounds + 1)];
_S[0] = P32;
for (int i=1; i < _S.Length; i++)
{
_S[i] = (_S[i-1] + Q32);
}
//
// Phase 3:
// Mix in the user's secret key in 3 passes over the arrays S & L.
// The max of the arrays sizes is used as the loop control
//
int iter;
if (L.Length > _S.Length)
{
iter = 3 * L.Length;
}
else
{
iter = 3 * _S.Length;
}
int A = 0, B = 0;
int ii = 0, jj = 0;
for (int k = 0; k < iter; k++)
{
A = _S[ii] = Integers.RotateLeft(_S[ii] + A + B, 3);
B = L[jj] = Integers.RotateLeft(L[jj] + A + B, A + B);
ii = (ii+1) % _S.Length;
jj = (jj+1) % L.Length;
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
private int EncryptBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
int A = (int)Pack.LE_To_UInt32(input) + _S[0];
int B = (int)Pack.LE_To_UInt32(input[4..]) + _S[1];
for (int i = 1; i <= _noRounds; i++)
{
A = Integers.RotateLeft(A ^ B, B) + _S[2*i];
B = Integers.RotateLeft(B ^ A, A) + _S[2*i+1];
}
Pack.UInt32_To_LE((uint)A, output);
Pack.UInt32_To_LE((uint)B, output[4..]);
return 8;
}
private int DecryptBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
int A = (int)Pack.LE_To_UInt32(input);
int B = (int)Pack.LE_To_UInt32(input[4..]);
for (int i = _noRounds; i >= 1; i--)
{
B = Integers.RotateRight(B - _S[2*i+1], A) ^ A;
A = Integers.RotateRight(A - _S[2*i], B) ^ B;
}
Pack.UInt32_To_LE((uint)(A - _S[0]), output);
Pack.UInt32_To_LE((uint)(B - _S[1]), output[4..]);
return 8;
}
#else
private int EncryptBlock(byte[] input, int inOff, byte[] outBytes, int outOff)
{
int A = (int)Pack.LE_To_UInt32(input, inOff) + _S[0];
int B = (int)Pack.LE_To_UInt32(input, inOff + 4) + _S[1];
for (int i = 1; i <= _noRounds; i++)
{
A = Integers.RotateLeft(A ^ B, B) + _S[2*i];
B = Integers.RotateLeft(B ^ A, A) + _S[2*i+1];
}
Pack.UInt32_To_LE((uint)A, outBytes, outOff);
Pack.UInt32_To_LE((uint)B, outBytes, outOff + 4);
return 8;
}
private int DecryptBlock(byte[] input, int inOff, byte[] outBytes, int outOff)
{
int A = (int)Pack.LE_To_UInt32(input, inOff);
int B = (int)Pack.LE_To_UInt32(input, inOff + 4);
for (int i = _noRounds; i >= 1; i--)
{
B = Integers.RotateRight(B - _S[2*i+1], A) ^ A;
A = Integers.RotateRight(A - _S[2*i], B) ^ B;
}
Pack.UInt32_To_LE((uint)(A - _S[0]), outBytes, outOff);
Pack.UInt32_To_LE((uint)(B - _S[1]), outBytes, outOff + 4);
return 8;
}
#endif
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: e806268a1f1fb8c4d9773e88008196b3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/RC532Engine.cs
uploadId: 783279

View File

@ -0,0 +1,247 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/**
* The specification for RC5 came from the <code>RC5 Encryption Algorithm</code>
* publication in RSA CryptoBytes, Spring of 1995.
* <em>http://www.rsasecurity.com/rsalabs/cryptobytes</em>.
* <p>
* This implementation is set to work with a 64 bit word size.</p>
*/
public class RC564Engine
: IBlockCipher
{
/*
* the number of rounds to perform
*/
private int _noRounds;
/*
* the expanded key array of size 2*(rounds + 1)
*/
private long [] _S;
/*
* our "magic constants" for wordSize 62
*
* Pw = Odd((e-2) * 2^wordsize)
* Qw = Odd((o-2) * 2^wordsize)
*
* where e is the base of natural logarithms (2.718281828...)
* and o is the golden ratio (1.61803398...)
*/
private static readonly long P64 = unchecked( (long) 0xb7e151628aed2a6bL);
private static readonly long Q64 = unchecked( (long) 0x9e3779b97f4a7c15L);
private bool forEncryption;
/**
* Create an instance of the RC5 encryption algorithm
* and set some defaults
*/
public RC564Engine()
{
_noRounds = 12;
// _S = null;
}
public virtual string AlgorithmName
{
get { return "RC5-64"; }
}
public virtual int GetBlockSize()
{
return 16;
}
/**
* initialise a RC5-64 cipher.
*
* @param forEncryption whether or not we are for encryption.
* @param parameters the parameters required to set up the cipher.
* @exception ArgumentException if the parameters argument is
* inappropriate.
*/
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
if (!(parameters is RC5Parameters rc5Parameters))
throw new ArgumentException("invalid parameter passed to RC564 init - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters));
this.forEncryption = forEncryption;
_noRounds = rc5Parameters.Rounds;
SetKey(rc5Parameters.GetKey());
}
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
return forEncryption
? EncryptBlock(input.AsSpan(inOff), output.AsSpan(outOff))
: DecryptBlock(input.AsSpan(inOff), output.AsSpan(outOff));
#else
return forEncryption
? EncryptBlock(input, inOff, output, outOff)
: DecryptBlock(input, inOff, output, outOff);
#endif
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual int ProcessBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
return forEncryption
? EncryptBlock(input, output)
: DecryptBlock(input, output);
}
#endif
/**
* Re-key the cipher.
*
* @param key the key to be used
*/
private void SetKey(byte[] key)
{
//
// KEY EXPANSION:
//
// There are 3 phases to the key expansion.
//
// Phase 1:
// Copy the secret key K[0...b-1] into an array L[0..c-1] of
// c = ceil(b/u), where u = wordSize/8 in little-endian order.
// In other words, we fill up L using u consecutive key bytes
// of K. Any unfilled byte positions in L are zeroed. In the
// case that b = c = 0, set c = 1 and L[0] = 0.
//
long[] L = new long[(key.Length + 7) / 8];
for (int i = 0; i != key.Length; i++)
{
L[i / 8] += (long)(key[i] & 0xff) << (8 * (i % 8));
}
//
// Phase 2:
// Initialize S to a particular fixed pseudo-random bit pattern
// using an arithmetic progression modulo 2^wordsize determined
// by the magic numbers, Pw & Qw.
//
_S = new long[2*(_noRounds + 1)];
_S[0] = P64;
for (int i=1; i < _S.Length; i++)
{
_S[i] = (_S[i-1] + Q64);
}
//
// Phase 3:
// Mix in the user's secret key in 3 passes over the arrays S & L.
// The max of the arrays sizes is used as the loop control
//
int iter;
if (L.Length > _S.Length)
{
iter = 3 * L.Length;
}
else
{
iter = 3 * _S.Length;
}
long A = 0, B = 0;
int ii = 0, jj = 0;
for (int k = 0; k < iter; k++)
{
A = _S[ii] = Longs.RotateLeft(_S[ii] + A + B, 3);
B = L[jj] = Longs.RotateLeft(L[jj] + A + B, (int)(A + B));
ii = (ii+1) % _S.Length;
jj = (jj+1) % L.Length;
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
private int EncryptBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
long A = (long)Pack.LE_To_UInt64(input) + _S[0];
long B = (long)Pack.LE_To_UInt64(input[8..]) + _S[1];
for (int i = 1; i <= _noRounds; i++)
{
A = Longs.RotateLeft(A ^ B, (int)B) + _S[2*i];
B = Longs.RotateLeft(B ^ A, (int)A) + _S[2*i+1];
}
Pack.UInt64_To_LE((ulong)A, output);
Pack.UInt64_To_LE((ulong)B, output[8..]);
return 16;
}
private int DecryptBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
long A = (long)Pack.LE_To_UInt64(input);
long B = (long)Pack.LE_To_UInt64(input[8..]);
for (int i = _noRounds; i >= 1; i--)
{
B = Longs.RotateRight(B - _S[2*i+1], (int)A) ^ A;
A = Longs.RotateRight(A - _S[2*i], (int)B) ^ B;
}
Pack.UInt64_To_LE((ulong)(A - _S[0]), output);
Pack.UInt64_To_LE((ulong)(B - _S[1]), output[8..]);
return 16;
}
#else
private int EncryptBlock(byte[] input, int inOff, byte[] outBytes, int outOff)
{
long A = (long)Pack.LE_To_UInt64(input, inOff) + _S[0];
long B = (long)Pack.LE_To_UInt64(input, inOff + 8) + _S[1];
for (int i = 1; i <= _noRounds; i++)
{
A = Longs.RotateLeft(A ^ B, (int)B) + _S[2*i];
B = Longs.RotateLeft(B ^ A, (int)A) + _S[2*i+1];
}
Pack.UInt64_To_LE((ulong)A, outBytes, outOff);
Pack.UInt64_To_LE((ulong)B, outBytes, outOff + 8);
return 16;
}
private int DecryptBlock(byte[] input, int inOff, byte[] outBytes, int outOff)
{
long A = (long)Pack.LE_To_UInt64(input, inOff);
long B = (long)Pack.LE_To_UInt64(input, inOff + 8);
for (int i = _noRounds; i >= 1; i--)
{
B = Longs.RotateRight(B - _S[2*i+1], (int)A) ^ A;
A = Longs.RotateRight(A - _S[2*i], (int)B) ^ B;
}
Pack.UInt64_To_LE((ulong)(A - _S[0]), outBytes, outOff);
Pack.UInt64_To_LE((ulong)(B - _S[1]), outBytes, outOff + 8);
return 16;
}
#endif
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 46c641fb7b1444f409874a9c65ca7acb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/RC564Engine.cs
uploadId: 783279

View File

@ -0,0 +1,399 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/**
* An RC6 engine.
*/
public class RC6Engine
: IBlockCipher
{
/*
* the number of rounds to perform
*/
private static readonly int _noRounds = 20;
/*
* the expanded key array of size 2*(rounds + 1)
*/
private int [] _S;
/*
* our "magic constants" for wordSize 32
*
* Pw = Odd((e-2) * 2^wordsize)
* Qw = Odd((o-2) * 2^wordsize)
*
* where e is the base of natural logarithms (2.718281828...)
* and o is the golden ratio (1.61803398...)
*/
private static readonly int P32 = unchecked((int) 0xb7e15163);
private static readonly int Q32 = unchecked((int) 0x9e3779b9);
private static readonly int LGW = 5; // log2(32)
private bool forEncryption;
/**
* Create an instance of the RC6 encryption algorithm
* and set some defaults
*/
public RC6Engine()
{
}
public virtual string AlgorithmName
{
get { return "RC6"; }
}
public virtual int GetBlockSize()
{
return 16;
}
/**
* initialise a RC5-32 cipher.
*
* @param forEncryption whether or not we are for encryption.
* @param parameters the parameters required to set up the cipher.
* @exception ArgumentException if the parameters argument is
* inappropriate.
*/
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
if (!(parameters is KeyParameter keyParameter))
throw new ArgumentException("invalid parameter passed to RC6 init - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters));
this.forEncryption = forEncryption;
SetKey(keyParameter.GetKey());
}
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
{
if (_S == null)
throw new InvalidOperationException("RC6 engine not initialised");
int blockSize = GetBlockSize();
Check.DataLength(input, inOff, blockSize, "input buffer too short");
Check.OutputLength(output, outOff, blockSize, "output buffer too short");
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
return forEncryption
? EncryptBlock(input.AsSpan(inOff), output.AsSpan(outOff))
: DecryptBlock(input.AsSpan(inOff), output.AsSpan(outOff));
#else
return forEncryption
? EncryptBlock(input, inOff, output, outOff)
: DecryptBlock(input, inOff, output, outOff);
#endif
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual int ProcessBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
if (_S == null)
throw new InvalidOperationException("RC6 engine not initialised");
int blockSize = GetBlockSize();
Check.DataLength(input, blockSize, "input buffer too short");
Check.OutputLength(output, blockSize, "output buffer too short");
return forEncryption
? EncryptBlock(input, output)
: DecryptBlock(input, output);
}
#endif
/**
* Re-key the cipher.
*
* @param inKey the key to be used
*/
private void SetKey(
byte[] key)
{
//
// KEY EXPANSION:
//
// There are 3 phases to the key expansion.
//
// Phase 1:
// Copy the secret key K[0...b-1] into an array L[0..c-1] of
// c = ceil(b/u), where u = wordSize/8 in little-endian order.
// In other words, we fill up L using u consecutive key bytes
// of K. Any unfilled byte positions in L are zeroed. In the
// case that b = c = 0, set c = 1 and L[0] = 0.
//
// compute number of dwords
int c = (key.Length + 3) / 4;
if (c == 0)
{
c = 1;
}
int[] L = new int[(key.Length + 3) / 4];
// load all key bytes into array of key dwords
for (int i = key.Length - 1; i >= 0; i--)
{
L[i / 4] = (L[i / 4] << 8) + (key[i] & 0xff);
}
//
// Phase 2:
// Key schedule is placed in a array of 2+2*ROUNDS+2 = 44 dwords.
// Initialize S to a particular fixed pseudo-random bit pattern
// using an arithmetic progression modulo 2^wordsize determined
// by the magic numbers, Pw & Qw.
//
_S = new int[2+2*_noRounds+2];
_S[0] = P32;
for (int i=1; i < _S.Length; i++)
{
_S[i] = (_S[i-1] + Q32);
}
//
// Phase 3:
// Mix in the user's secret key in 3 passes over the arrays S & L.
// The max of the arrays sizes is used as the loop control
//
int iter;
if (L.Length > _S.Length)
{
iter = 3 * L.Length;
}
else
{
iter = 3 * _S.Length;
}
int A = 0;
int B = 0;
int ii = 0, jj = 0;
for (int k = 0; k < iter; k++)
{
A = _S[ii] = Integers.RotateLeft(_S[ii] + A + B, 3);
B = L[jj] = Integers.RotateLeft( L[jj] + A + B, A + B);
ii = (ii+1) % _S.Length;
jj = (jj+1) % L.Length;
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
private int EncryptBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
// load A,B,C and D registers from in.
int A = (int)Pack.LE_To_UInt32(input);
int B = (int)Pack.LE_To_UInt32(input[4..]);
int C = (int)Pack.LE_To_UInt32(input[8..]);
int D = (int)Pack.LE_To_UInt32(input[12..]);
// Do pseudo-round #0: pre-whitening of B and D
B += _S[0];
D += _S[1];
// perform round #1,#2 ... #ROUNDS of encryption
for (int i = 1; i <= _noRounds; i++)
{
int t = 0, u = 0;
t = B * (2 * B + 1);
t = Integers.RotateLeft(t, 5);
u = D * (2 * D + 1);
u = Integers.RotateLeft(u, 5);
A ^= t;
A = Integers.RotateLeft(A, u);
A += _S[2 * i];
C ^= u;
C = Integers.RotateLeft(C, t);
C += _S[2 * i + 1];
int temp = A;
A = B;
B = C;
C = D;
D = temp;
}
// do pseudo-round #(ROUNDS+1) : post-whitening of A and C
A += _S[2 * _noRounds + 2];
C += _S[2 * _noRounds + 3];
// store A, B, C and D registers to out
Pack.UInt32_To_LE((uint)A, output);
Pack.UInt32_To_LE((uint)B, output[4..]);
Pack.UInt32_To_LE((uint)C, output[8..]);
Pack.UInt32_To_LE((uint)D, output[12..]);
return 16;
}
private int DecryptBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
// load A,B,C and D registers from out.
int A = (int)Pack.LE_To_UInt32(input);
int B = (int)Pack.LE_To_UInt32(input[4..]);
int C = (int)Pack.LE_To_UInt32(input[8..]);
int D = (int)Pack.LE_To_UInt32(input[12..]);
// Undo pseudo-round #(ROUNDS+1) : post whitening of A and C
C -= _S[2 * _noRounds + 3];
A -= _S[2 * _noRounds + 2];
// Undo round #ROUNDS, .., #2,#1 of encryption
for (int i = _noRounds; i >= 1; i--)
{
int t = 0, u = 0;
int temp = D;
D = C;
C = B;
B = A;
A = temp;
t = B * (2 * B + 1);
t = Integers.RotateLeft(t, LGW);
u = D * (2 * D + 1);
u = Integers.RotateLeft(u, LGW);
C -= _S[2 * i + 1];
C = Integers.RotateRight(C, t);
C ^= u;
A -= _S[2 * i];
A = Integers.RotateRight(A, u);
A ^= t;
}
// Undo pseudo-round #0: pre-whitening of B and D
D -= _S[1];
B -= _S[0];
Pack.UInt32_To_LE((uint)A, output);
Pack.UInt32_To_LE((uint)B, output[4..]);
Pack.UInt32_To_LE((uint)C, output[8..]);
Pack.UInt32_To_LE((uint)D, output[12..]);
return 16;
}
#else
private int EncryptBlock(byte[] input, int inOff, byte[] outBytes, int outOff)
{
// load A,B,C and D registers from in.
int A = (int)Pack.LE_To_UInt32(input, inOff);
int B = (int)Pack.LE_To_UInt32(input, inOff + 4);
int C = (int)Pack.LE_To_UInt32(input, inOff + 8);
int D = (int)Pack.LE_To_UInt32(input, inOff + 12);
// Do pseudo-round #0: pre-whitening of B and D
B += _S[0];
D += _S[1];
// perform round #1,#2 ... #ROUNDS of encryption
for (int i = 1; i <= _noRounds; i++)
{
int t = 0,u = 0;
t = B*(2*B+1);
t = Integers.RotateLeft(t,5);
u = D*(2*D+1);
u = Integers.RotateLeft(u,5);
A ^= t;
A = Integers.RotateLeft(A,u);
A += _S[2*i];
C ^= u;
C = Integers.RotateLeft(C,t);
C += _S[2*i+1];
int temp = A;
A = B;
B = C;
C = D;
D = temp;
}
// do pseudo-round #(ROUNDS+1) : post-whitening of A and C
A += _S[2*_noRounds+2];
C += _S[2*_noRounds+3];
// store A, B, C and D registers to out
Pack.UInt32_To_LE((uint)A, outBytes, outOff);
Pack.UInt32_To_LE((uint)B, outBytes, outOff + 4);
Pack.UInt32_To_LE((uint)C, outBytes, outOff + 8);
Pack.UInt32_To_LE((uint)D, outBytes, outOff + 12);
return 16;
}
private int DecryptBlock(byte[] input, int inOff, byte[] outBytes, int outOff)
{
// load A,B,C and D registers from out.
int A = (int)Pack.LE_To_UInt32(input, inOff);
int B = (int)Pack.LE_To_UInt32(input, inOff + 4);
int C = (int)Pack.LE_To_UInt32(input, inOff + 8);
int D = (int)Pack.LE_To_UInt32(input, inOff + 12);
// Undo pseudo-round #(ROUNDS+1) : post whitening of A and C
C -= _S[2*_noRounds+3];
A -= _S[2*_noRounds+2];
// Undo round #ROUNDS, .., #2,#1 of encryption
for (int i = _noRounds; i >= 1; i--)
{
int t=0,u = 0;
int temp = D;
D = C;
C = B;
B = A;
A = temp;
t = B*(2*B+1);
t = Integers.RotateLeft(t, LGW);
u = D*(2*D+1);
u = Integers.RotateLeft(u, LGW);
C -= _S[2*i+1];
C = Integers.RotateRight(C,t);
C ^= u;
A -= _S[2*i];
A = Integers.RotateRight(A,u);
A ^= t;
}
// Undo pseudo-round #0: pre-whitening of B and D
D -= _S[1];
B -= _S[0];
Pack.UInt32_To_LE((uint)A, outBytes, outOff);
Pack.UInt32_To_LE((uint)B, outBytes, outOff + 4);
Pack.UInt32_To_LE((uint)C, outBytes, outOff + 8);
Pack.UInt32_To_LE((uint)D, outBytes, outOff + 12);
return 16;
}
#endif
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: edff8f9ff18060e418306e90e6f68992
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/RC6Engine.cs
uploadId: 783279

View File

@ -0,0 +1,179 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Modes;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/**
* an implementation of the RFC 3211 Key Wrap
* Specification.
*/
public class Rfc3211WrapEngine
: IWrapper
{
private CbcBlockCipher engine;
private ParametersWithIV param;
private bool forWrapping;
private SecureRandom rand;
public Rfc3211WrapEngine(
IBlockCipher engine)
{
this.engine = new CbcBlockCipher(engine);
}
public virtual void Init(bool forWrapping, ICipherParameters param)
{
this.forWrapping = forWrapping;
if (param is ParametersWithRandom withRandom)
{
this.rand = withRandom.Random;
this.param = withRandom.Parameters as ParametersWithIV;
}
else
{
if (forWrapping)
{
rand = CryptoServicesRegistrar.GetSecureRandom();
}
this.param = param as ParametersWithIV;
}
if (null == this.param)
throw new ArgumentException("RFC3211Wrap requires an IV", "param");
}
public virtual string AlgorithmName
{
get { return engine.UnderlyingCipher.AlgorithmName + "/RFC3211Wrap"; }
}
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(true, param);
int blockSize = engine.GetBlockSize();
byte[] cekBlock;
if (inLen + 4 < blockSize * 2)
{
cekBlock = new byte[blockSize * 2];
}
else
{
cekBlock = new byte[(inLen + 4) % blockSize == 0 ? inLen + 4 : ((inLen + 4) / blockSize + 1) * blockSize];
}
cekBlock[0] = (byte)inLen;
Array.Copy(inBytes, inOff, cekBlock, 4, inLen);
rand.NextBytes(cekBlock, inLen + 4, cekBlock.Length - inLen - 4);
cekBlock[1] = (byte)~cekBlock[4];
cekBlock[2] = (byte)~cekBlock[4 + 1];
cekBlock[3] = (byte)~cekBlock[4 + 2];
for (int i = 0; i < cekBlock.Length; i += blockSize)
{
engine.ProcessBlock(cekBlock, i, cekBlock, i);
}
for (int i = 0; i < cekBlock.Length; i += blockSize)
{
engine.ProcessBlock(cekBlock, i, cekBlock, i);
}
return cekBlock;
}
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[] cekBlock = new byte[inLen];
byte[] iv = new byte[blockSize];
Array.Copy(inBytes, inOff, cekBlock, 0, inLen);
Array.Copy(inBytes, inOff, iv, 0, iv.Length);
engine.Init(false, new ParametersWithIV(param.Parameters, iv));
for (int i = blockSize; i < cekBlock.Length; i += blockSize)
{
engine.ProcessBlock(cekBlock, i, cekBlock, i);
}
Array.Copy(cekBlock, cekBlock.Length - iv.Length, iv, 0, iv.Length);
engine.Init(false, new ParametersWithIV(param.Parameters, iv));
engine.ProcessBlock(cekBlock, 0, cekBlock, 0);
engine.Init(false, param);
for (int i = 0; i < cekBlock.Length; i += blockSize)
{
engine.ProcessBlock(cekBlock, i, cekBlock, i);
}
bool invalidLength = (int)cekBlock[0] > (cekBlock.Length - 4);
byte[] key;
if (invalidLength)
{
key = new byte[cekBlock.Length - 4];
}
else
{
key = new byte[cekBlock[0]];
}
Array.Copy(cekBlock, 4, key, 0, key.Length);
// Note: Using constant time comparison
int nonEqual = 0;
for (int i = 0; i != 3; i++)
{
byte check = (byte)~cekBlock[1 + i];
nonEqual |= (check ^ cekBlock[4 + i]);
}
Array.Clear(cekBlock, 0, cekBlock.Length);
if (nonEqual != 0 | invalidLength)
throw new InvalidCipherTextException("wrapped key corrupted");
return key;
}
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: eec9c01abe454c04aa79b2e2d01a488e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/RFC3211WrapEngine.cs
uploadId: 783279

View File

@ -0,0 +1,182 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/// <remarks>
/// An implementation of the AES Key Wrapper from the NIST Key Wrap
/// Specification as described in RFC 3394.
/// <p/>
/// For further details see: <a href="http://www.ietf.org/rfc/rfc3394.txt">http://www.ietf.org/rfc/rfc3394.txt</a>
/// and <a href="http://csrc.nist.gov/encryption/kms/key-wrap.pdf">http://csrc.nist.gov/encryption/kms/key-wrap.pdf</a>.
/// </remarks>
public class Rfc3394WrapEngine
: IWrapper
{
private readonly IBlockCipher engine;
private KeyParameter param;
private bool forWrapping;
private byte[] iv =
{
0xa6, 0xa6, 0xa6, 0xa6,
0xa6, 0xa6, 0xa6, 0xa6
};
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)
{
this.param = (KeyParameter) parameters;
}
else if (parameters is ParametersWithIV)
{
ParametersWithIV pIV = (ParametersWithIV) parameters;
byte[] iv = pIV.GetIV();
if (iv.Length != 8)
throw new ArgumentException("IV length not equal to 8", "parameters");
this.iv = iv;
this.param = (KeyParameter) pIV.Parameters;
}
else
{
// TODO Throw an exception for bad parameters?
}
}
public virtual string AlgorithmName
{
get { return engine.AlgorithmName; }
}
public virtual byte[] Wrap(
byte[] input,
int inOff,
int inLen)
{
if (!forWrapping)
{
throw new InvalidOperationException("not set for wrapping");
}
int n = inLen / 8;
if ((n * 8) != inLen)
{
throw new DataLengthException("wrap data must be a multiple of 8 bytes");
}
byte[] block = new byte[inLen + iv.Length];
byte[] buf = new byte[8 + iv.Length];
Array.Copy(iv, 0, block, 0, iv.Length);
Array.Copy(input, inOff, block, iv.Length, inLen);
engine.Init(true, param);
for (int j = 0; j != 6; j++)
{
for (int i = 1; i <= n; i++)
{
Array.Copy(block, 0, buf, 0, iv.Length);
Array.Copy(block, 8 * i, buf, iv.Length, 8);
engine.ProcessBlock(buf, 0, buf, 0);
int t = n * j + i;
for (int k = 1; t != 0; k++)
{
byte v = (byte)t;
buf[iv.Length - k] ^= v;
t = (int) ((uint)t >> 8);
}
Array.Copy(buf, 0, block, 0, 8);
Array.Copy(buf, 8, block, 8 * i, 8);
}
}
return block;
}
public virtual byte[] Unwrap(
byte[] input,
int inOff,
int inLen)
{
if (forWrapping)
{
throw new InvalidOperationException("not set for unwrapping");
}
int n = inLen / 8;
if ((n * 8) != inLen)
{
throw new InvalidCipherTextException("unwrap data must be a multiple of 8 bytes");
}
byte[] block = new byte[inLen - iv.Length];
byte[] a = new byte[iv.Length];
byte[] buf = new byte[8 + iv.Length];
Array.Copy(input, inOff, a, 0, iv.Length);
Array.Copy(input, inOff + iv.Length, block, 0, inLen - iv.Length);
engine.Init(false, param);
n = n - 1;
for (int j = 5; j >= 0; j--)
{
for (int i = n; i >= 1; i--)
{
Array.Copy(a, 0, buf, 0, iv.Length);
Array.Copy(block, 8 * (i - 1), buf, iv.Length, 8);
int t = n * j + i;
for (int k = 1; t != 0; k++)
{
byte v = (byte)t;
buf[iv.Length - k] ^= v;
t = (int) ((uint)t >> 8);
}
engine.ProcessBlock(buf, 0, buf, 0);
Array.Copy(buf, 0, a, 0, 8);
Array.Copy(buf, 8, block, 8 * (i - 1), 8);
}
}
if (!Arrays.ConstantTimeAreEqual(a, iv))
throw new InvalidCipherTextException("checksum failed");
return block;
}
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: e24f6e1da23022042bec9eded6c6a965
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/RFC3394WrapEngine.cs
uploadId: 783279

View File

@ -0,0 +1,155 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/**
* this does your basic RSA algorithm with blinding
*/
public class RsaBlindedEngine
: IAsymmetricBlockCipher
{
private readonly IRsa core;
private RsaKeyParameters key;
private SecureRandom random;
public RsaBlindedEngine()
: this(new RsaCoreEngine())
{
}
public RsaBlindedEngine(IRsa rsa)
{
this.core = rsa;
}
public virtual string AlgorithmName
{
get { return "RSA"; }
}
/**
* initialise the RSA engine.
*
* @param forEncryption true if we are encrypting, false otherwise.
* @param param the necessary RSA key parameters.
*/
public virtual void Init(bool forEncryption, ICipherParameters param)
{
core.Init(forEncryption, param);
if (param is ParametersWithRandom rParam)
{
this.key = (RsaKeyParameters)rParam.Parameters;
if (key is RsaPrivateCrtKeyParameters)
{
this.random = rParam.Random;
}
else
{
this.random = null;
}
}
else
{
this.key = (RsaKeyParameters)param;
if (key is RsaPrivateCrtKeyParameters)
{
this.random = CryptoServicesRegistrar.GetSecureRandom();
}
else
{
this.random = null;
}
}
}
/**
* Return the maximum size for an input block to this engine.
* For RSA this is always one byte less than the key size on
* encryption, and the same length as the key size on decryption.
*
* @return maximum size for an input block.
*/
public virtual int GetInputBlockSize()
{
return core.GetInputBlockSize();
}
/**
* Return the maximum size for an output block to this engine.
* For RSA this is always one byte less than the key size on
* decryption, and the same length as the key size on encryption.
*
* @return maximum size for an output block.
*/
public virtual int GetOutputBlockSize()
{
return core.GetOutputBlockSize();
}
/**
* Process a single block using the basic RSA algorithm.
*
* @param inBuf the input array.
* @param inOff the offset into the input buffer where the data starts.
* @param inLen the length of the data to be processed.
* @return the result of the RSA process.
* @exception DataLengthException the input block is too large.
*/
public virtual byte[] ProcessBlock(
byte[] inBuf,
int inOff,
int inLen)
{
if (key == null)
throw new InvalidOperationException("RSA engine not initialised");
BigInteger input = core.ConvertInput(inBuf, inOff, inLen);
BigInteger result;
if (key is RsaPrivateCrtKeyParameters)
{
RsaPrivateCrtKeyParameters k = (RsaPrivateCrtKeyParameters)key;
BigInteger e = k.PublicExponent;
if (e != null) // can't do blinding without a public exponent
{
BigInteger m = k.Modulus;
BigInteger r = BigIntegers.CreateRandomInRange(
BigInteger.One, m.Subtract(BigInteger.One), random);
BigInteger blindedInput = r.ModPow(e, m).Multiply(input).Mod(m);
BigInteger blindedResult = core.ProcessBlock(blindedInput);
BigInteger rInv = BigIntegers.ModOddInverse(m, r);
result = blindedResult.Multiply(rInv).Mod(m);
// defence against Arjen Lenstra<72>s CRT attack
if (!input.Equals(result.ModPow(e, m)))
throw new InvalidOperationException("RSA engine faulty decryption/signing detected");
}
else
{
result = core.ProcessBlock(input);
}
}
else
{
result = core.ProcessBlock(input);
}
return core.ConvertOutput(result);
}
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 1b80e1341d98fdb49851a4cd4a57eac2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/RSABlindedEngine.cs
uploadId: 783279

View File

@ -0,0 +1,154 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/**
* This does your basic RSA Chaum's blinding and unblinding as outlined in
* "Handbook of Applied Cryptography", page 475. You need to use this if you are
* trying to get another party to generate signatures without them being aware
* of the message they are signing.
*/
public class RsaBlindingEngine
: IAsymmetricBlockCipher
{
private readonly IRsa core;
private RsaKeyParameters key;
private BigInteger blindingFactor;
private bool forEncryption;
public RsaBlindingEngine()
: this(new RsaCoreEngine())
{
}
public RsaBlindingEngine(IRsa rsa)
{
this.core = rsa;
}
public virtual string AlgorithmName
{
get { return "RSA"; }
}
/**
* Initialise the blinding engine.
*
* @param forEncryption true if we are encrypting (blinding), false otherwise.
* @param param the necessary RSA key parameters.
*/
public virtual void Init(
bool forEncryption,
ICipherParameters param)
{
RsaBlindingParameters p;
if (param is ParametersWithRandom)
{
ParametersWithRandom rParam = (ParametersWithRandom)param;
p = (RsaBlindingParameters)rParam.Parameters;
}
else
{
p = (RsaBlindingParameters)param;
}
core.Init(forEncryption, p.PublicKey);
this.forEncryption = forEncryption;
this.key = p.PublicKey;
this.blindingFactor = p.BlindingFactor;
}
/**
* Return the maximum size for an input block to this engine.
* For RSA this is always one byte less than the key size on
* encryption, and the same length as the key size on decryption.
*
* @return maximum size for an input block.
*/
public virtual int GetInputBlockSize()
{
return core.GetInputBlockSize();
}
/**
* Return the maximum size for an output block to this engine.
* For RSA this is always one byte less than the key size on
* decryption, and the same length as the key size on encryption.
*
* @return maximum size for an output block.
*/
public virtual int GetOutputBlockSize()
{
return core.GetOutputBlockSize();
}
/**
* Process a single block using the RSA blinding algorithm.
*
* @param in the input array.
* @param inOff the offset into the input buffer where the data starts.
* @param inLen the length of the data to be processed.
* @return the result of the RSA process.
* @throws DataLengthException the input block is too large.
*/
public virtual byte[] ProcessBlock(
byte[] inBuf,
int inOff,
int inLen)
{
BigInteger msg = core.ConvertInput(inBuf, inOff, inLen);
if (forEncryption)
{
msg = BlindMessage(msg);
}
else
{
msg = UnblindMessage(msg);
}
return core.ConvertOutput(msg);
}
/*
* Blind message with the blind factor.
*/
private BigInteger BlindMessage(
BigInteger msg)
{
BigInteger blindMsg = blindingFactor;
blindMsg = msg.Multiply(blindMsg.ModPow(key.Exponent, key.Modulus));
blindMsg = blindMsg.Mod(key.Modulus);
return blindMsg;
}
/*
* Unblind the message blinded with the blind factor.
*/
private BigInteger UnblindMessage(
BigInteger blindedMsg)
{
BigInteger m = key.Modulus;
BigInteger msg = blindedMsg;
BigInteger blindFactorInverse = BigIntegers.ModOddInverse(m, blindingFactor);
msg = msg.Multiply(blindFactorInverse);
msg = msg.Mod(m);
return msg;
}
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: d90b524dee5e7c14f9cd372f30fefb58
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/RSABlindingEngine.cs
uploadId: 783279

View File

@ -0,0 +1,163 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/**
* this does your basic RSA algorithm.
*/
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");
}
/**
* initialise the RSA engine.
*
* @param forEncryption true if we are encrypting, false otherwise.
* @param param the necessary RSA key parameters.
*/
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");
this.key = (RsaKeyParameters) parameters;
this.forEncryption = forEncryption;
this.bitSize = key.Modulus.BitLength;
}
/**
* Return the maximum size for an input block to this engine.
* For RSA this is always one byte less than the key size on
* encryption, and the same length as the key size on decryption.
*
* @return maximum size for an input block.
*/
public virtual int GetInputBlockSize()
{
CheckInitialised();
if (forEncryption)
{
return (bitSize - 1) / 8;
}
return (bitSize + 7) / 8;
}
/**
* Return the maximum size for an output block to this engine.
* For RSA this is always one byte less than the key size on
* decryption, and the same length as the key size on encryption.
*
* @return maximum size for an output block.
*/
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 maxLength = (bitSize + 7) / 8;
if (inLen > maxLength)
throw new DataLengthException("input too large for RSA cipher.");
BigInteger input = new BigInteger(1, inBuf, inOff, inLen);
if (input.CompareTo(key.Modulus) >= 0)
throw new DataLengthException("input too large for RSA cipher.");
return input;
}
public virtual byte[] ConvertOutput(BigInteger result)
{
CheckInitialised();
return forEncryption
? BigIntegers.AsUnsignedByteArray(GetOutputBlockSize(), result)
: BigIntegers.AsUnsignedByteArray(result);
}
public virtual BigInteger ProcessBlock(
BigInteger input)
{
CheckInitialised();
if (key is RsaPrivateCrtKeyParameters)
{
//
// we have the extra factors, use the Chinese Remainder Theorem - the author
// wishes to express his thanks to Dirk Bonekaemper at rtsffm.com for
// advice regarding the expression of this.
//
RsaPrivateCrtKeyParameters crtKey = (RsaPrivateCrtKeyParameters)key;
BigInteger p = crtKey.P;
BigInteger q = crtKey.Q;
BigInteger dP = crtKey.DP;
BigInteger dQ = crtKey.DQ;
BigInteger qInv = crtKey.QInv;
BigInteger mP, mQ, h, m;
// mP = ((input Mod p) ^ dP)) Mod p
mP = (input.Remainder(p)).ModPow(dP, p);
// mQ = ((input Mod q) ^ dQ)) Mod q
mQ = (input.Remainder(q)).ModPow(dQ, q);
// h = qInv * (mP - mQ) Mod p
h = mP.Subtract(mQ);
h = h.Multiply(qInv);
h = h.Mod(p); // Mod (in Java) returns the positive residual
// m = h * q + mQ
m = h.Multiply(q);
m = m.Add(mQ);
return m;
}
return input.ModPow(key.Exponent, key.Modulus);
}
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 3069653cc00071b44a1ff3745ce8a215
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/RSACoreEngine.cs
uploadId: 783279

View File

@ -0,0 +1,795 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
#if UNITY_WSA && !UNITY_EDITOR && !ENABLE_IL2CPP
using System.TypeFix;
#endif
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/**
* an implementation of Rijndael, based on the documentation and reference implementation
* by Paulo Barreto, Vincent Rijmen, for v2.0 August '99.
* <p>
* Note: this implementation is based on information prior to readonly NIST publication.
* </p>
*/
public class RijndaelEngine
: IBlockCipher
{
private static readonly int MAXROUNDS = 14;
private static readonly int MAXKC = (256/4);
private static readonly byte[] Logtable =
{
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 =
{
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 =
{
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 =
{
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 =
{
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91
};
static readonly byte[][] shifts0 = new byte [][]
{
new byte[]{ 0, 8, 16, 24 },
new byte[]{ 0, 8, 16, 24 },
new byte[]{ 0, 8, 16, 24 },
new byte[]{ 0, 8, 16, 32 },
new byte[]{ 0, 8, 24, 32 }
};
static readonly byte[][] shifts1 =
{
new byte[]{ 0, 24, 16, 8 },
new byte[]{ 0, 32, 24, 16 },
new byte[]{ 0, 40, 32, 24 },
new byte[]{ 0, 48, 40, 24 },
new byte[]{ 0, 56, 40, 32 }
};
/**
* multiply two elements of GF(2^m)
* needed for MixColumn and InvMixColumn
*/
private byte Mul0x2(
int b)
{
if (b != 0)
{
return Alogtable[25 + (Logtable[b] & 0xff)];
}
else
{
return 0;
}
}
private byte Mul0x3(
int b)
{
if (b != 0)
{
return Alogtable[1 + (Logtable[b] & 0xff)];
}
else
{
return 0;
}
}
private byte Mul0x9(
int b)
{
if (b >= 0)
{
return Alogtable[199 + b];
}
else
{
return 0;
}
}
private byte Mul0xb(
int b)
{
if (b >= 0)
{
return Alogtable[104 + b];
}
else
{
return 0;
}
}
private byte Mul0xd(
int b)
{
if (b >= 0)
{
return Alogtable[238 + b];
}
else
{
return 0;
}
}
private byte Mul0xe(
int b)
{
if (b >= 0)
{
return Alogtable[223 + b];
}
else
{
return 0;
}
}
/**
* xor corresponding text input and round key input bytes
*/
private void KeyAddition(
long[] rk)
{
A0 ^= rk[0];
A1 ^= rk[1];
A2 ^= rk[2];
A3 ^= rk[3];
}
private long Shift(
long r,
int shift)
{
//return (((long)((ulong) r >> shift) | (r << (BC - shift)))) & BC_MASK;
ulong temp = (ulong) r >> shift;
// NB: This corrects for Mono Bug #79087 (fixed in 1.1.17)
if (shift > 31)
{
temp &= 0xFFFFFFFFUL;
}
return ((long) temp | (r << (BC - shift))) & BC_MASK;
}
/**
* Row 0 remains unchanged
* The other three rows are shifted a variable amount
*/
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 res = 0;
for (int j = 0; j < BC; j += 8)
{
res |= (long)(box[(int)((r >> j) & 0xff)] & 0xff) << j;
}
return res;
}
/**
* Replace every byte of the input by the byte at that place
* in the nonlinear S-box
*/
private void Substitution(
byte[] box)
{
A0 = ApplyS(A0, box);
A1 = ApplyS(A1, box);
A2 = ApplyS(A2, box);
A3 = ApplyS(A3, box);
}
/**
* Mix the bytes of every column in a linear way
*/
private void MixColumn()
{
long r0, r1, r2, r3;
r0 = r1 = r2 = r3 = 0;
for (int j = 0; j < BC; j += 8)
{
int a0 = (int)((A0 >> j) & 0xff);
int a1 = (int)((A1 >> j) & 0xff);
int a2 = (int)((A2 >> j) & 0xff);
int a3 = (int)((A3 >> j) & 0xff);
r0 |= (long)((Mul0x2(a0) ^ Mul0x3(a1) ^ a2 ^ a3) & 0xff) << j;
r1 |= (long)((Mul0x2(a1) ^ Mul0x3(a2) ^ a3 ^ a0) & 0xff) << j;
r2 |= (long)((Mul0x2(a2) ^ Mul0x3(a3) ^ a0 ^ a1) & 0xff) << j;
r3 |= (long)((Mul0x2(a3) ^ Mul0x3(a0) ^ a1 ^ a2) & 0xff) << j;
}
A0 = r0;
A1 = r1;
A2 = r2;
A3 = r3;
}
/**
* Mix the bytes of every column in a linear way
* This is the opposite operation of Mixcolumn
*/
private void InvMixColumn()
{
long r0, r1, r2, r3;
r0 = r1 = r2 = r3 = 0;
for (int j = 0; j < BC; j += 8)
{
int a0 = (int)((A0 >> j) & 0xff);
int a1 = (int)((A1 >> j) & 0xff);
int a2 = (int)((A2 >> j) & 0xff);
int a3 = (int)((A3 >> j) & 0xff);
//
// pre-lookup the log table
//
a0 = (a0 != 0) ? (Logtable[a0 & 0xff] & 0xff) : -1;
a1 = (a1 != 0) ? (Logtable[a1 & 0xff] & 0xff) : -1;
a2 = (a2 != 0) ? (Logtable[a2 & 0xff] & 0xff) : -1;
a3 = (a3 != 0) ? (Logtable[a3 & 0xff] & 0xff) : -1;
r0 |= (long)((Mul0xe(a0) ^ Mul0xb(a1) ^ Mul0xd(a2) ^ Mul0x9(a3)) & 0xff) << j;
r1 |= (long)((Mul0xe(a1) ^ Mul0xb(a2) ^ Mul0xd(a3) ^ Mul0x9(a0)) & 0xff) << j;
r2 |= (long)((Mul0xe(a2) ^ Mul0xb(a3) ^ Mul0xd(a0) ^ Mul0x9(a1)) & 0xff) << j;
r3 |= (long)((Mul0xe(a3) ^ Mul0xb(a0) ^ Mul0xd(a1) ^ Mul0x9(a2)) & 0xff) << j;
}
A0 = r0;
A1 = r1;
A2 = r2;
A3 = r3;
}
/**
* Calculate the necessary round keys
* The number of calculations depends on keyBits and blockBits
*/
private long[][] GenerateWorkingKey(
byte[] key)
{
int KC;
int t, rconpointer = 0;
int keyBits = key.Length * 8;
byte[,] tk = new byte[4,MAXKC];
//long[,] W = new long[MAXROUNDS+1,4];
long[][] W = new long[MAXROUNDS+1][];
for (int i = 0; i < MAXROUNDS+1; i++) W[i] = new long[4];
switch (keyBits)
{
case 128:
KC = 4;
break;
case 160:
KC = 5;
break;
case 192:
KC = 6;
break;
case 224:
KC = 7;
break;
case 256:
KC = 8;
break;
default :
throw new ArgumentException("Key length not 128/160/192/224/256 bits.");
}
if (keyBits >= blockBits)
{
ROUNDS = KC + 6;
}
else
{
ROUNDS = (BC / 8) + 6;
}
//
// copy the key into the processing area
//
int index = 0;
for (int i = 0; i < key.Length; i++)
{
tk[i % 4,i / 4] = key[index++];
}
t = 0;
//
// copy values into round key array
//
for (int j = 0; (j < KC) && (t < (ROUNDS+1)*(BC / 8)); j++, t++)
{
for (int i = 0; i < 4; i++)
{
W[t / (BC / 8)][i] |= (long)(tk[i,j] & 0xff) << ((t * 8) % BC);
}
}
//
// while not enough round key material calculated
// calculate new values
//
while (t < (ROUNDS+1)*(BC/8))
{
for (int i = 0; i < 4; i++)
{
tk[i,0] ^= S[tk[(i+1)%4,KC-1] & 0xff];
}
tk[0,0] ^= (byte) rcon[rconpointer++];
if (KC <= 6)
{
for (int j = 1; j < KC; j++)
{
for (int i = 0; i < 4; i++)
{
tk[i,j] ^= tk[i,j-1];
}
}
}
else
{
for (int j = 1; j < 4; j++)
{
for (int i = 0; i < 4; i++)
{
tk[i,j] ^= tk[i,j-1];
}
}
for (int i = 0; i < 4; i++)
{
tk[i,4] ^= S[tk[i,3] & 0xff];
}
for (int j = 5; j < KC; j++)
{
for (int i = 0; i < 4; i++)
{
tk[i,j] ^= tk[i,j-1];
}
}
}
//
// copy values into round key array
//
for (int j = 0; (j < KC) && (t < (ROUNDS+1)*(BC/8)); j++, t++)
{
for (int i = 0; i < 4; i++)
{
W[t / (BC/8)][i] |= (long)(tk[i,j] & 0xff) << ((t * 8) % (BC));
}
}
}
return W;
}
private int BC;
private long BC_MASK;
private int ROUNDS;
private int blockBits;
private long[][] workingKey;
private long A0, A1, A2, A3;
private bool forEncryption;
private byte[] shifts0SC;
private byte[] shifts1SC;
/**
* default constructor - 128 bit block size.
*/
public RijndaelEngine() : this(128) {}
/**
* basic constructor - set the cipher up for a given blocksize
*
* @param blocksize the blocksize in bits, must be 128, 192, or 256.
*/
public RijndaelEngine(
int blockBits)
{
switch (blockBits)
{
case 128:
BC = 32;
BC_MASK = 0xffffffffL;
shifts0SC = shifts0[0];
shifts1SC = shifts1[0];
break;
case 160:
BC = 40;
BC_MASK = 0xffffffffffL;
shifts0SC = shifts0[1];
shifts1SC = shifts1[1];
break;
case 192:
BC = 48;
BC_MASK = 0xffffffffffffL;
shifts0SC = shifts0[2];
shifts1SC = shifts1[2];
break;
case 224:
BC = 56;
BC_MASK = 0xffffffffffffffL;
shifts0SC = shifts0[3];
shifts1SC = shifts1[3];
break;
case 256:
BC = 64;
BC_MASK = unchecked( (long)0xffffffffffffffffL);
shifts0SC = shifts0[4];
shifts1SC = shifts1[4];
break;
default:
throw new ArgumentException("unknown blocksize to Rijndael");
}
this.blockBits = blockBits;
}
/**
* initialise a Rijndael cipher.
*
* @param forEncryption whether or not we are for encryption.
* @param parameters the parameters required to set up the cipher.
* @exception ArgumentException if the parameters argument is
* inappropriate.
*/
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 - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters));
}
public virtual string AlgorithmName
{
get { return "Rijndael"; }
}
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");
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
UnPackBlock(input.AsSpan(inOff));
#else
UnPackBlock(input, inOff);
#endif
if (forEncryption)
{
EncryptBlock(workingKey);
}
else
{
DecryptBlock(workingKey);
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
PackBlock(output.AsSpan(outOff));
#else
PackBlock(output, outOff);
#endif
return BC / 2;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual int ProcessBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
if (workingKey == null)
throw new InvalidOperationException("Rijndael engine not initialised");
Check.DataLength(input, (BC / 2), "input buffer too short");
Check.OutputLength(output, (BC / 2), "output buffer too short");
UnPackBlock(input);
if (forEncryption)
{
EncryptBlock(workingKey);
}
else
{
DecryptBlock(workingKey);
}
PackBlock(output);
return BC / 2;
}
#endif
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
private void UnPackBlock(ReadOnlySpan<byte> input)
{
int index = 0;
A0 = (long)(input[index++] & 0xff);
A1 = (long)(input[index++] & 0xff);
A2 = (long)(input[index++] & 0xff);
A3 = (long)(input[index++] & 0xff);
for (int j = 8; j != BC; j += 8)
{
A0 |= (long)(input[index++] & 0xff) << j;
A1 |= (long)(input[index++] & 0xff) << j;
A2 |= (long)(input[index++] & 0xff) << j;
A3 |= (long)(input[index++] & 0xff) << j;
}
}
private void PackBlock(Span<byte> output)
{
int index = 0;
for (int j = 0; j != BC; j += 8)
{
output[index++] = (byte)(A0 >> j);
output[index++] = (byte)(A1 >> j);
output[index++] = (byte)(A2 >> j);
output[index++] = (byte)(A3 >> j);
}
}
#else
private void UnPackBlock(byte[] bytes, int off)
{
int index = off;
A0 = (long)(bytes[index++] & 0xff);
A1 = (long)(bytes[index++] & 0xff);
A2 = (long)(bytes[index++] & 0xff);
A3 = (long)(bytes[index++] & 0xff);
for (int j = 8; j != BC; j += 8)
{
A0 |= (long)(bytes[index++] & 0xff) << j;
A1 |= (long)(bytes[index++] & 0xff) << j;
A2 |= (long)(bytes[index++] & 0xff) << j;
A3 |= (long)(bytes[index++] & 0xff) << j;
}
}
private void PackBlock(byte[] bytes, int off)
{
int index = off;
for (int j = 0; j != BC; j += 8)
{
bytes[index++] = (byte)(A0 >> j);
bytes[index++] = (byte)(A1 >> j);
bytes[index++] = (byte)(A2 >> j);
bytes[index++] = (byte)(A3 >> j);
}
}
#endif
private void EncryptBlock(
long[][] rk)
{
int r;
//
// begin with a key addition
//
KeyAddition(rk[0]);
//
// ROUNDS-1 ordinary rounds
//
for (r = 1; r < ROUNDS; r++)
{
Substitution(S);
ShiftRow(shifts0SC);
MixColumn();
KeyAddition(rk[r]);
}
//
// Last round is special: there is no MixColumn
//
Substitution(S);
ShiftRow(shifts0SC);
KeyAddition(rk[ROUNDS]);
}
private void DecryptBlock(
long[][] rk)
{
int r;
// To decrypt: apply the inverse operations of the encrypt routine,
// in opposite order
//
// (KeyAddition is an involution: it 's equal to its inverse)
// (the inverse of Substitution with table S is Substitution with the inverse table of S)
// (the inverse of Shiftrow is Shiftrow over a suitable distance)
//
// First the special round:
// without InvMixColumn
// with extra KeyAddition
//
KeyAddition(rk[ROUNDS]);
Substitution(Si);
ShiftRow(shifts1SC);
//
// ROUNDS-1 ordinary rounds
//
for (r = ROUNDS-1; r > 0; r--)
{
KeyAddition(rk[r]);
InvMixColumn();
Substitution(Si);
ShiftRow(shifts1SC);
}
//
// End with the extra key addition
//
KeyAddition(rk[0]);
}
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 4cf037396c2603a43a6a5470c1fb3798
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/RijndaelEngine.cs
uploadId: 783279

View File

@ -0,0 +1,90 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/**
* this does your basic RSA algorithm.
*/
public class RsaEngine
: IAsymmetricBlockCipher
{
private readonly IRsa core;
public RsaEngine()
: this(new RsaCoreEngine())
{
}
public RsaEngine(IRsa rsa)
{
this.core = rsa;
}
public virtual string AlgorithmName
{
get { return "RSA"; }
}
/**
* initialise the RSA engine.
*
* @param forEncryption true if we are encrypting, false otherwise.
* @param param the necessary RSA key parameters.
*/
public virtual void Init(
bool forEncryption,
ICipherParameters parameters)
{
core.Init(forEncryption, parameters);
}
/**
* Return the maximum size for an input block to this engine.
* For RSA this is always one byte less than the key size on
* encryption, and the same length as the key size on decryption.
*
* @return maximum size for an input block.
*/
public virtual int GetInputBlockSize()
{
return core.GetInputBlockSize();
}
/**
* Return the maximum size for an output block to this engine.
* For RSA this is always one byte less than the key size on
* decryption, and the same length as the key size on encryption.
*
* @return maximum size for an output block.
*/
public virtual int GetOutputBlockSize()
{
return core.GetOutputBlockSize();
}
/**
* Process a single block using the basic RSA algorithm.
*
* @param inBuf the input array.
* @param inOff the offset into the input buffer where the data starts.
* @param inLen the length of the data to be processed.
* @return the result of the RSA process.
* @exception DataLengthException the input block is too large.
*/
public virtual byte[] ProcessBlock(
byte[] inBuf,
int inOff,
int inLen)
{
BigInteger input = core.ConvertInput(inBuf, inOff, inLen);
BigInteger output = core.ProcessBlock(input);
return core.ConvertOutput(output);
}
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: b8545895894aa114287ea461626c8a83
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/RsaEngine.cs
uploadId: 783279

View File

@ -0,0 +1,368 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/**
* Implementation of the SEED algorithm as described in RFC 4009
*/
public class SeedEngine
: IBlockCipher
{
private const int BlockSize = 16;
private static readonly uint[] SS0 =
{
0x2989a1a8, 0x05858184, 0x16c6d2d4, 0x13c3d3d0, 0x14445054, 0x1d0d111c, 0x2c8ca0ac, 0x25052124,
0x1d4d515c, 0x03434340, 0x18081018, 0x1e0e121c, 0x11415150, 0x3cccf0fc, 0x0acac2c8, 0x23436360,
0x28082028, 0x04444044, 0x20002020, 0x1d8d919c, 0x20c0e0e0, 0x22c2e2e0, 0x08c8c0c8, 0x17071314,
0x2585a1a4, 0x0f8f838c, 0x03030300, 0x3b4b7378, 0x3b8bb3b8, 0x13031310, 0x12c2d2d0, 0x2ecee2ec,
0x30407070, 0x0c8c808c, 0x3f0f333c, 0x2888a0a8, 0x32023230, 0x1dcdd1dc, 0x36c6f2f4, 0x34447074,
0x2ccce0ec, 0x15859194, 0x0b0b0308, 0x17475354, 0x1c4c505c, 0x1b4b5358, 0x3d8db1bc, 0x01010100,
0x24042024, 0x1c0c101c, 0x33437370, 0x18889098, 0x10001010, 0x0cccc0cc, 0x32c2f2f0, 0x19c9d1d8,
0x2c0c202c, 0x27c7e3e4, 0x32427270, 0x03838380, 0x1b8b9398, 0x11c1d1d0, 0x06868284, 0x09c9c1c8,
0x20406060, 0x10405050, 0x2383a3a0, 0x2bcbe3e8, 0x0d0d010c, 0x3686b2b4, 0x1e8e929c, 0x0f4f434c,
0x3787b3b4, 0x1a4a5258, 0x06c6c2c4, 0x38487078, 0x2686a2a4, 0x12021210, 0x2f8fa3ac, 0x15c5d1d4,
0x21416160, 0x03c3c3c0, 0x3484b0b4, 0x01414140, 0x12425250, 0x3d4d717c, 0x0d8d818c, 0x08080008,
0x1f0f131c, 0x19899198, 0x00000000, 0x19091118, 0x04040004, 0x13435350, 0x37c7f3f4, 0x21c1e1e0,
0x3dcdf1fc, 0x36467274, 0x2f0f232c, 0x27072324, 0x3080b0b0, 0x0b8b8388, 0x0e0e020c, 0x2b8ba3a8,
0x2282a2a0, 0x2e4e626c, 0x13839390, 0x0d4d414c, 0x29496168, 0x3c4c707c, 0x09090108, 0x0a0a0208,
0x3f8fb3bc, 0x2fcfe3ec, 0x33c3f3f0, 0x05c5c1c4, 0x07878384, 0x14041014, 0x3ecef2fc, 0x24446064,
0x1eced2dc, 0x2e0e222c, 0x0b4b4348, 0x1a0a1218, 0x06060204, 0x21012120, 0x2b4b6368, 0x26466264,
0x02020200, 0x35c5f1f4, 0x12829290, 0x0a8a8288, 0x0c0c000c, 0x3383b3b0, 0x3e4e727c, 0x10c0d0d0,
0x3a4a7278, 0x07474344, 0x16869294, 0x25c5e1e4, 0x26062224, 0x00808080, 0x2d8da1ac, 0x1fcfd3dc,
0x2181a1a0, 0x30003030, 0x37073334, 0x2e8ea2ac, 0x36063234, 0x15051114, 0x22022220, 0x38083038,
0x34c4f0f4, 0x2787a3a4, 0x05454144, 0x0c4c404c, 0x01818180, 0x29c9e1e8, 0x04848084, 0x17879394,
0x35053134, 0x0bcbc3c8, 0x0ecec2cc, 0x3c0c303c, 0x31417170, 0x11011110, 0x07c7c3c4, 0x09898188,
0x35457174, 0x3bcbf3f8, 0x1acad2d8, 0x38c8f0f8, 0x14849094, 0x19495158, 0x02828280, 0x04c4c0c4,
0x3fcff3fc, 0x09494148, 0x39093138, 0x27476364, 0x00c0c0c0, 0x0fcfc3cc, 0x17c7d3d4, 0x3888b0b8,
0x0f0f030c, 0x0e8e828c, 0x02424240, 0x23032320, 0x11819190, 0x2c4c606c, 0x1bcbd3d8, 0x2484a0a4,
0x34043034, 0x31c1f1f0, 0x08484048, 0x02c2c2c0, 0x2f4f636c, 0x3d0d313c, 0x2d0d212c, 0x00404040,
0x3e8eb2bc, 0x3e0e323c, 0x3c8cb0bc, 0x01c1c1c0, 0x2a8aa2a8, 0x3a8ab2b8, 0x0e4e424c, 0x15455154,
0x3b0b3338, 0x1cccd0dc, 0x28486068, 0x3f4f737c, 0x1c8c909c, 0x18c8d0d8, 0x0a4a4248, 0x16465254,
0x37477374, 0x2080a0a0, 0x2dcde1ec, 0x06464244, 0x3585b1b4, 0x2b0b2328, 0x25456164, 0x3acaf2f8,
0x23c3e3e0, 0x3989b1b8, 0x3181b1b0, 0x1f8f939c, 0x1e4e525c, 0x39c9f1f8, 0x26c6e2e4, 0x3282b2b0,
0x31013130, 0x2acae2e8, 0x2d4d616c, 0x1f4f535c, 0x24c4e0e4, 0x30c0f0f0, 0x0dcdc1cc, 0x08888088,
0x16061214, 0x3a0a3238, 0x18485058, 0x14c4d0d4, 0x22426260, 0x29092128, 0x07070304, 0x33033330,
0x28c8e0e8, 0x1b0b1318, 0x05050104, 0x39497178, 0x10809090, 0x2a4a6268, 0x2a0a2228, 0x1a8a9298
};
private static readonly uint[] SS1 =
{
0x38380830, 0xe828c8e0, 0x2c2d0d21, 0xa42686a2, 0xcc0fcfc3, 0xdc1eced2, 0xb03383b3, 0xb83888b0,
0xac2f8fa3, 0x60204060, 0x54154551, 0xc407c7c3, 0x44044440, 0x6c2f4f63, 0x682b4b63, 0x581b4b53,
0xc003c3c3, 0x60224262, 0x30330333, 0xb43585b1, 0x28290921, 0xa02080a0, 0xe022c2e2, 0xa42787a3,
0xd013c3d3, 0x90118191, 0x10110111, 0x04060602, 0x1c1c0c10, 0xbc3c8cb0, 0x34360632, 0x480b4b43,
0xec2fcfe3, 0x88088880, 0x6c2c4c60, 0xa82888a0, 0x14170713, 0xc404c4c0, 0x14160612, 0xf434c4f0,
0xc002c2c2, 0x44054541, 0xe021c1e1, 0xd416c6d2, 0x3c3f0f33, 0x3c3d0d31, 0x8c0e8e82, 0x98188890,
0x28280820, 0x4c0e4e42, 0xf436c6f2, 0x3c3e0e32, 0xa42585a1, 0xf839c9f1, 0x0c0d0d01, 0xdc1fcfd3,
0xd818c8d0, 0x282b0b23, 0x64264662, 0x783a4a72, 0x24270723, 0x2c2f0f23, 0xf031c1f1, 0x70324272,
0x40024242, 0xd414c4d0, 0x40014141, 0xc000c0c0, 0x70334373, 0x64274763, 0xac2c8ca0, 0x880b8b83,
0xf437c7f3, 0xac2d8da1, 0x80008080, 0x1c1f0f13, 0xc80acac2, 0x2c2c0c20, 0xa82a8aa2, 0x34340430,
0xd012c2d2, 0x080b0b03, 0xec2ecee2, 0xe829c9e1, 0x5c1d4d51, 0x94148490, 0x18180810, 0xf838c8f0,
0x54174753, 0xac2e8ea2, 0x08080800, 0xc405c5c1, 0x10130313, 0xcc0dcdc1, 0x84068682, 0xb83989b1,
0xfc3fcff3, 0x7c3d4d71, 0xc001c1c1, 0x30310131, 0xf435c5f1, 0x880a8a82, 0x682a4a62, 0xb03181b1,
0xd011c1d1, 0x20200020, 0xd417c7d3, 0x00020202, 0x20220222, 0x04040400, 0x68284860, 0x70314171,
0x04070703, 0xd81bcbd3, 0x9c1d8d91, 0x98198991, 0x60214161, 0xbc3e8eb2, 0xe426c6e2, 0x58194951,
0xdc1dcdd1, 0x50114151, 0x90108090, 0xdc1cccd0, 0x981a8a92, 0xa02383a3, 0xa82b8ba3, 0xd010c0d0,
0x80018181, 0x0c0f0f03, 0x44074743, 0x181a0a12, 0xe023c3e3, 0xec2ccce0, 0x8c0d8d81, 0xbc3f8fb3,
0x94168692, 0x783b4b73, 0x5c1c4c50, 0xa02282a2, 0xa02181a1, 0x60234363, 0x20230323, 0x4c0d4d41,
0xc808c8c0, 0x9c1e8e92, 0x9c1c8c90, 0x383a0a32, 0x0c0c0c00, 0x2c2e0e22, 0xb83a8ab2, 0x6c2e4e62,
0x9c1f8f93, 0x581a4a52, 0xf032c2f2, 0x90128292, 0xf033c3f3, 0x48094941, 0x78384870, 0xcc0cccc0,
0x14150511, 0xf83bcbf3, 0x70304070, 0x74354571, 0x7c3f4f73, 0x34350531, 0x10100010, 0x00030303,
0x64244460, 0x6c2d4d61, 0xc406c6c2, 0x74344470, 0xd415c5d1, 0xb43484b0, 0xe82acae2, 0x08090901,
0x74364672, 0x18190911, 0xfc3ecef2, 0x40004040, 0x10120212, 0xe020c0e0, 0xbc3d8db1, 0x04050501,
0xf83acaf2, 0x00010101, 0xf030c0f0, 0x282a0a22, 0x5c1e4e52, 0xa82989a1, 0x54164652, 0x40034343,
0x84058581, 0x14140410, 0x88098981, 0x981b8b93, 0xb03080b0, 0xe425c5e1, 0x48084840, 0x78394971,
0x94178793, 0xfc3cccf0, 0x1c1e0e12, 0x80028282, 0x20210121, 0x8c0c8c80, 0x181b0b13, 0x5c1f4f53,
0x74374773, 0x54144450, 0xb03282b2, 0x1c1d0d11, 0x24250521, 0x4c0f4f43, 0x00000000, 0x44064642,
0xec2dcde1, 0x58184850, 0x50124252, 0xe82bcbe3, 0x7c3e4e72, 0xd81acad2, 0xc809c9c1, 0xfc3dcdf1,
0x30300030, 0x94158591, 0x64254561, 0x3c3c0c30, 0xb43686b2, 0xe424c4e0, 0xb83b8bb3, 0x7c3c4c70,
0x0c0e0e02, 0x50104050, 0x38390931, 0x24260622, 0x30320232, 0x84048480, 0x68294961, 0x90138393,
0x34370733, 0xe427c7e3, 0x24240420, 0xa42484a0, 0xc80bcbc3, 0x50134353, 0x080a0a02, 0x84078783,
0xd819c9d1, 0x4c0c4c40, 0x80038383, 0x8c0f8f83, 0xcc0ecec2, 0x383b0b33, 0x480a4a42, 0xb43787b3
};
private static readonly uint[] SS2 =
{
0xa1a82989, 0x81840585, 0xd2d416c6, 0xd3d013c3, 0x50541444, 0x111c1d0d, 0xa0ac2c8c, 0x21242505,
0x515c1d4d, 0x43400343, 0x10181808, 0x121c1e0e, 0x51501141, 0xf0fc3ccc, 0xc2c80aca, 0x63602343,
0x20282808, 0x40440444, 0x20202000, 0x919c1d8d, 0xe0e020c0, 0xe2e022c2, 0xc0c808c8, 0x13141707,
0xa1a42585, 0x838c0f8f, 0x03000303, 0x73783b4b, 0xb3b83b8b, 0x13101303, 0xd2d012c2, 0xe2ec2ece,
0x70703040, 0x808c0c8c, 0x333c3f0f, 0xa0a82888, 0x32303202, 0xd1dc1dcd, 0xf2f436c6, 0x70743444,
0xe0ec2ccc, 0x91941585, 0x03080b0b, 0x53541747, 0x505c1c4c, 0x53581b4b, 0xb1bc3d8d, 0x01000101,
0x20242404, 0x101c1c0c, 0x73703343, 0x90981888, 0x10101000, 0xc0cc0ccc, 0xf2f032c2, 0xd1d819c9,
0x202c2c0c, 0xe3e427c7, 0x72703242, 0x83800383, 0x93981b8b, 0xd1d011c1, 0x82840686, 0xc1c809c9,
0x60602040, 0x50501040, 0xa3a02383, 0xe3e82bcb, 0x010c0d0d, 0xb2b43686, 0x929c1e8e, 0x434c0f4f,
0xb3b43787, 0x52581a4a, 0xc2c406c6, 0x70783848, 0xa2a42686, 0x12101202, 0xa3ac2f8f, 0xd1d415c5,
0x61602141, 0xc3c003c3, 0xb0b43484, 0x41400141, 0x52501242, 0x717c3d4d, 0x818c0d8d, 0x00080808,
0x131c1f0f, 0x91981989, 0x00000000, 0x11181909, 0x00040404, 0x53501343, 0xf3f437c7, 0xe1e021c1,
0xf1fc3dcd, 0x72743646, 0x232c2f0f, 0x23242707, 0xb0b03080, 0x83880b8b, 0x020c0e0e, 0xa3a82b8b,
0xa2a02282, 0x626c2e4e, 0x93901383, 0x414c0d4d, 0x61682949, 0x707c3c4c, 0x01080909, 0x02080a0a,
0xb3bc3f8f, 0xe3ec2fcf, 0xf3f033c3, 0xc1c405c5, 0x83840787, 0x10141404, 0xf2fc3ece, 0x60642444,
0xd2dc1ece, 0x222c2e0e, 0x43480b4b, 0x12181a0a, 0x02040606, 0x21202101, 0x63682b4b, 0x62642646,
0x02000202, 0xf1f435c5, 0x92901282, 0x82880a8a, 0x000c0c0c, 0xb3b03383, 0x727c3e4e, 0xd0d010c0,
0x72783a4a, 0x43440747, 0x92941686, 0xe1e425c5, 0x22242606, 0x80800080, 0xa1ac2d8d, 0xd3dc1fcf,
0xa1a02181, 0x30303000, 0x33343707, 0xa2ac2e8e, 0x32343606, 0x11141505, 0x22202202, 0x30383808,
0xf0f434c4, 0xa3a42787, 0x41440545, 0x404c0c4c, 0x81800181, 0xe1e829c9, 0x80840484, 0x93941787,
0x31343505, 0xc3c80bcb, 0xc2cc0ece, 0x303c3c0c, 0x71703141, 0x11101101, 0xc3c407c7, 0x81880989,
0x71743545, 0xf3f83bcb, 0xd2d81aca, 0xf0f838c8, 0x90941484, 0x51581949, 0x82800282, 0xc0c404c4,
0xf3fc3fcf, 0x41480949, 0x31383909, 0x63642747, 0xc0c000c0, 0xc3cc0fcf, 0xd3d417c7, 0xb0b83888,
0x030c0f0f, 0x828c0e8e, 0x42400242, 0x23202303, 0x91901181, 0x606c2c4c, 0xd3d81bcb, 0xa0a42484,
0x30343404, 0xf1f031c1, 0x40480848, 0xc2c002c2, 0x636c2f4f, 0x313c3d0d, 0x212c2d0d, 0x40400040,
0xb2bc3e8e, 0x323c3e0e, 0xb0bc3c8c, 0xc1c001c1, 0xa2a82a8a, 0xb2b83a8a, 0x424c0e4e, 0x51541545,
0x33383b0b, 0xd0dc1ccc, 0x60682848, 0x737c3f4f, 0x909c1c8c, 0xd0d818c8, 0x42480a4a, 0x52541646,
0x73743747, 0xa0a02080, 0xe1ec2dcd, 0x42440646, 0xb1b43585, 0x23282b0b, 0x61642545, 0xf2f83aca,
0xe3e023c3, 0xb1b83989, 0xb1b03181, 0x939c1f8f, 0x525c1e4e, 0xf1f839c9, 0xe2e426c6, 0xb2b03282,
0x31303101, 0xe2e82aca, 0x616c2d4d, 0x535c1f4f, 0xe0e424c4, 0xf0f030c0, 0xc1cc0dcd, 0x80880888,
0x12141606, 0x32383a0a, 0x50581848, 0xd0d414c4, 0x62602242, 0x21282909, 0x03040707, 0x33303303,
0xe0e828c8, 0x13181b0b, 0x01040505, 0x71783949, 0x90901080, 0x62682a4a, 0x22282a0a, 0x92981a8a
};
private static readonly uint[] SS3 =
{
0x08303838, 0xc8e0e828, 0x0d212c2d, 0x86a2a426, 0xcfc3cc0f, 0xced2dc1e, 0x83b3b033, 0x88b0b838,
0x8fa3ac2f, 0x40606020, 0x45515415, 0xc7c3c407, 0x44404404, 0x4f636c2f, 0x4b63682b, 0x4b53581b,
0xc3c3c003, 0x42626022, 0x03333033, 0x85b1b435, 0x09212829, 0x80a0a020, 0xc2e2e022, 0x87a3a427,
0xc3d3d013, 0x81919011, 0x01111011, 0x06020406, 0x0c101c1c, 0x8cb0bc3c, 0x06323436, 0x4b43480b,
0xcfe3ec2f, 0x88808808, 0x4c606c2c, 0x88a0a828, 0x07131417, 0xc4c0c404, 0x06121416, 0xc4f0f434,
0xc2c2c002, 0x45414405, 0xc1e1e021, 0xc6d2d416, 0x0f333c3f, 0x0d313c3d, 0x8e828c0e, 0x88909818,
0x08202828, 0x4e424c0e, 0xc6f2f436, 0x0e323c3e, 0x85a1a425, 0xc9f1f839, 0x0d010c0d, 0xcfd3dc1f,
0xc8d0d818, 0x0b23282b, 0x46626426, 0x4a72783a, 0x07232427, 0x0f232c2f, 0xc1f1f031, 0x42727032,
0x42424002, 0xc4d0d414, 0x41414001, 0xc0c0c000, 0x43737033, 0x47636427, 0x8ca0ac2c, 0x8b83880b,
0xc7f3f437, 0x8da1ac2d, 0x80808000, 0x0f131c1f, 0xcac2c80a, 0x0c202c2c, 0x8aa2a82a, 0x04303434,
0xc2d2d012, 0x0b03080b, 0xcee2ec2e, 0xc9e1e829, 0x4d515c1d, 0x84909414, 0x08101818, 0xc8f0f838,
0x47535417, 0x8ea2ac2e, 0x08000808, 0xc5c1c405, 0x03131013, 0xcdc1cc0d, 0x86828406, 0x89b1b839,
0xcff3fc3f, 0x4d717c3d, 0xc1c1c001, 0x01313031, 0xc5f1f435, 0x8a82880a, 0x4a62682a, 0x81b1b031,
0xc1d1d011, 0x00202020, 0xc7d3d417, 0x02020002, 0x02222022, 0x04000404, 0x48606828, 0x41717031,
0x07030407, 0xcbd3d81b, 0x8d919c1d, 0x89919819, 0x41616021, 0x8eb2bc3e, 0xc6e2e426, 0x49515819,
0xcdd1dc1d, 0x41515011, 0x80909010, 0xccd0dc1c, 0x8a92981a, 0x83a3a023, 0x8ba3a82b, 0xc0d0d010,
0x81818001, 0x0f030c0f, 0x47434407, 0x0a12181a, 0xc3e3e023, 0xcce0ec2c, 0x8d818c0d, 0x8fb3bc3f,
0x86929416, 0x4b73783b, 0x4c505c1c, 0x82a2a022, 0x81a1a021, 0x43636023, 0x03232023, 0x4d414c0d,
0xc8c0c808, 0x8e929c1e, 0x8c909c1c, 0x0a32383a, 0x0c000c0c, 0x0e222c2e, 0x8ab2b83a, 0x4e626c2e,
0x8f939c1f, 0x4a52581a, 0xc2f2f032, 0x82929012, 0xc3f3f033, 0x49414809, 0x48707838, 0xccc0cc0c,
0x05111415, 0xcbf3f83b, 0x40707030, 0x45717435, 0x4f737c3f, 0x05313435, 0x00101010, 0x03030003,
0x44606424, 0x4d616c2d, 0xc6c2c406, 0x44707434, 0xc5d1d415, 0x84b0b434, 0xcae2e82a, 0x09010809,
0x46727436, 0x09111819, 0xcef2fc3e, 0x40404000, 0x02121012, 0xc0e0e020, 0x8db1bc3d, 0x05010405,
0xcaf2f83a, 0x01010001, 0xc0f0f030, 0x0a22282a, 0x4e525c1e, 0x89a1a829, 0x46525416, 0x43434003,
0x85818405, 0x04101414, 0x89818809, 0x8b93981b, 0x80b0b030, 0xc5e1e425, 0x48404808, 0x49717839,
0x87939417, 0xccf0fc3c, 0x0e121c1e, 0x82828002, 0x01212021, 0x8c808c0c, 0x0b13181b, 0x4f535c1f,
0x47737437, 0x44505414, 0x82b2b032, 0x0d111c1d, 0x05212425, 0x4f434c0f, 0x00000000, 0x46424406,
0xcde1ec2d, 0x48505818, 0x42525012, 0xcbe3e82b, 0x4e727c3e, 0xcad2d81a, 0xc9c1c809, 0xcdf1fc3d,
0x00303030, 0x85919415, 0x45616425, 0x0c303c3c, 0x86b2b436, 0xc4e0e424, 0x8bb3b83b, 0x4c707c3c,
0x0e020c0e, 0x40505010, 0x09313839, 0x06222426, 0x02323032, 0x84808404, 0x49616829, 0x83939013,
0x07333437, 0xc7e3e427, 0x04202424, 0x84a0a424, 0xcbc3c80b, 0x43535013, 0x0a02080a, 0x87838407,
0xc9d1d819, 0x4c404c0c, 0x83838003, 0x8f838c0f, 0xcec2cc0e, 0x0b33383b, 0x4a42480a, 0x87b3b437
};
private static readonly uint[] KC =
{
0x9e3779b9, 0x3c6ef373, 0x78dde6e6, 0xf1bbcdcc,
0xe3779b99, 0xc6ef3733, 0x8dde6e67, 0x1bbcdccf,
0x3779b99e, 0x6ef3733c, 0xdde6e678, 0xbbcdccf1,
0x779b99e3, 0xef3733c6, 0xde6e678d, 0xbcdccf1b
};
private int[] wKey;
private bool forEncryption;
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
this.forEncryption = forEncryption;
wKey = CreateWorkingKey(((KeyParameter)parameters).GetKey());
}
public virtual string AlgorithmName
{
get { return "SEED"; }
}
public virtual int GetBlockSize()
{
return BlockSize;
}
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, BlockSize, "input buffer too short");
Check.OutputLength(outBuf, outOff, BlockSize, "output buffer too short");
long l = (long)Pack.BE_To_UInt64(inBuf, inOff + 0);
long r = (long)Pack.BE_To_UInt64(inBuf, inOff + 8);
if (forEncryption)
{
for (int i = 0; i < 16; i++)
{
long nl = r;
r = l ^ F(wKey[2 * i], wKey[(2 * i) + 1], r);
l = nl;
}
}
else
{
for (int i = 15; i >= 0; i--)
{
long nl = r;
r = l ^ F(wKey[2 * i], wKey[(2 * i) + 1], r);
l = nl;
}
}
Pack.UInt64_To_BE((ulong)r, outBuf, outOff + 0);
Pack.UInt64_To_BE((ulong)l, outBuf, outOff + 8);
return BlockSize;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual int ProcessBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
if (wKey == null)
throw new InvalidOperationException("SEED engine not initialised");
Check.DataLength(input, BlockSize, "input buffer too short");
Check.OutputLength(output, BlockSize, "output buffer too short");
long l = (long)Pack.BE_To_UInt64(input);
long r = (long)Pack.BE_To_UInt64(input[8..]);
if (forEncryption)
{
for (int i = 0; i < 16; i++)
{
long nl = r;
r = l ^ F(wKey[2 * i], wKey[(2 * i) + 1], r);
l = nl;
}
}
else
{
for (int i = 15; i >= 0; i--)
{
long nl = r;
r = l ^ F(wKey[2 * i], wKey[(2 * i) + 1], r);
l = nl;
}
}
Pack.UInt64_To_BE((ulong)r, output);
Pack.UInt64_To_BE((ulong)l, output[8..]);
return BlockSize;
}
#endif
private int[] CreateWorkingKey(byte[] inKey)
{
if (inKey.Length != 16)
throw new ArgumentException("key size must be 128 bits");
int[] key = new int[32];
long lower = (long)Pack.BE_To_UInt64(inKey, 0);
long upper = (long)Pack.BE_To_UInt64(inKey, 8);
int key0 = extractW0(lower);
int key1 = extractW1(lower);
int key2 = extractW0(upper);
int key3 = extractW1(upper);
for (int i = 0; i < 16; i++)
{
key[2 * i] = G(key0 + key2 - (int)KC[i]);
key[2 * i + 1] = G(key1 - key3 + (int)KC[i]);
if (i % 2 == 0)
{
lower = rotateRight8(lower);
key0 = extractW0(lower);
key1 = extractW1(lower);
}
else
{
upper = rotateLeft8(upper);
key2 = extractW0(upper);
key3 = extractW1(upper);
}
}
return key;
}
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) | ((long)((ulong) x >> 56));
}
private long rotateRight8(
long x)
{
return ((long)((ulong) x >> 8)) | (x << 56);
}
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 r0 = (int)(r >> 32);
int r1 = (int)r;
int rd1 = phaseCalc2(r0, ki0, r1, ki1);
int rd0 = rd1 + phaseCalc1(r0, ki0, r1, ki1);
return ((long)rd0 << 32) | (rd1 & 0xffffffffL);
}
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)));
}
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: e755da8b639e8c84d86ad30a0d844389
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/SEEDEngine.cs
uploadId: 783279

View File

@ -0,0 +1,20 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/// <remarks>
/// An implementation of the SEED key wrapper based on RFC 4010/RFC 3394.
/// <p/>
/// For further details see: <a href="http://www.ietf.org/rfc/rfc4010.txt">http://www.ietf.org/rfc/rfc4010.txt</a>.
/// </remarks>
public class SeedWrapEngine
: Rfc3394WrapEngine
{
public SeedWrapEngine()
: base(new SeedEngine())
{
}
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 69ade6b85be88c64699697ac1b03a8be
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/SEEDWrapEngine.cs
uploadId: 783279

View File

@ -0,0 +1,456 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Digests;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math.EC;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Math.EC.Multiplier;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Security;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/// <summary>
/// SM2 public key encryption engine - based on https://tools.ietf.org/html/draft-shen-sm2-ecdsa-02.
/// </summary>
public class SM2Engine
{
public enum Mode
{
C1C2C3, C1C3C2
}
private readonly IDigest mDigest;
private readonly Mode mMode;
private bool mForEncryption;
private ECKeyParameters mECKey;
private ECDomainParameters mECParams;
private int mCurveLength;
private SecureRandom mRandom;
public SM2Engine()
: this(new SM3Digest())
{
}
public SM2Engine(Mode mode)
: this(new SM3Digest(), mode)
{
}
public SM2Engine(IDigest digest)
: this(digest, Mode.C1C2C3)
{
}
public SM2Engine(IDigest digest, Mode mode)
{
mDigest = digest;
mMode = mode;
}
public virtual void Init(bool forEncryption, ICipherParameters param)
{
this.mForEncryption = forEncryption;
if (forEncryption)
{
ParametersWithRandom rParam = (ParametersWithRandom)param;
mECKey = (ECKeyParameters)rParam.Parameters;
mECParams = mECKey.Parameters;
ECPoint s = ((ECPublicKeyParameters)mECKey).Q.Multiply(mECParams.H);
if (s.IsInfinity)
throw new ArgumentException("invalid key: [h]Q at infinity");
mRandom = rParam.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 ((inOff + inLen) > input.Length || inLen == 0)
throw new DataLengthException("input buffer too short");
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
return ProcessBlock(input.AsSpan(inOff, inLen));
#else
if (mForEncryption)
{
return Encrypt(input, inOff, inLen);
}
else
{
return Decrypt(input, inOff, inLen);
}
#endif
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual byte[] ProcessBlock(ReadOnlySpan<byte> input)
{
if (input.Length == 0)
throw new DataLengthException("input buffer too short");
if (mForEncryption)
{
return Encrypt(input);
}
else
{
return Decrypt(input);
}
}
#endif
protected virtual ECMultiplier CreateBasePointMultiplier()
{
return new FixedPointCombMultiplier();
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
private byte[] Encrypt(ReadOnlySpan<byte> input)
{
byte[] c2 = input.ToArray();
ECMultiplier multiplier = CreateBasePointMultiplier();
BigInteger k;
ECPoint kPB;
do
{
k = NextK();
kPB = ((ECPublicKeyParameters)mECKey).Q.Multiply(k).Normalize();
Kdf(mDigest, kPB, c2);
}
while (NotEncrypted(c2, input));
ECPoint c1P = multiplier.Multiply(mECParams.G, k).Normalize();
int c1PEncodedLength = c1P.GetEncodedLength(false);
Span<byte> c1 = c1PEncodedLength <= 512
? stackalloc byte[c1PEncodedLength]
: new byte[c1PEncodedLength];
c1P.EncodeTo(false, c1);
AddFieldElement(mDigest, kPB.AffineXCoord);
mDigest.BlockUpdate(input);
AddFieldElement(mDigest, kPB.AffineYCoord);
int digestSize = mDigest.GetDigestSize();
Span<byte> c3 = digestSize <= 128
? stackalloc byte[digestSize]
: new byte[digestSize];
mDigest.DoFinal(c3);
switch (mMode)
{
case Mode.C1C3C2:
return Arrays.Concatenate(c1, c3, c2);
default:
return Arrays.Concatenate(c1, c2, c3);
}
}
private byte[] Decrypt(ReadOnlySpan<byte> input)
{
int c1Length = mCurveLength * 2 + 1;
ECPoint c1P = mECParams.Curve.DecodePoint(input[..c1Length]);
ECPoint s = c1P.Multiply(mECParams.H);
if (s.IsInfinity)
throw new InvalidCipherTextException("[h]C1 at infinity");
c1P = c1P.Multiply(((ECPrivateKeyParameters)mECKey).D).Normalize();
int digestSize = mDigest.GetDigestSize();
int c2Length = input.Length - c1Length - digestSize;
byte[] c2 = new byte[c2Length];
if (mMode == Mode.C1C3C2)
{
input[(c1Length + digestSize)..].CopyTo(c2);
}
else
{
input[c1Length..(c1Length + c2Length)].CopyTo(c2);
}
Kdf(mDigest, c1P, c2);
AddFieldElement(mDigest, c1P.AffineXCoord);
mDigest.BlockUpdate(c2);
AddFieldElement(mDigest, c1P.AffineYCoord);
Span<byte> c3 = digestSize <= 128
? stackalloc byte[digestSize]
: new byte[digestSize];
mDigest.DoFinal(c3);
int check = 0;
if (mMode == Mode.C1C3C2)
{
for (int i = 0; i != c3.Length; i++)
{
check |= c3[i] ^ input[c1Length + i];
}
}
else
{
for (int i = 0; i != c3.Length; i++)
{
check |= c3[i] ^ input[c1Length + c2.Length + i];
}
}
c3.Fill(0);
if (check != 0)
{
Arrays.Fill(c2, 0);
throw new InvalidCipherTextException("invalid cipher text");
}
return c2;
}
private bool NotEncrypted(ReadOnlySpan<byte> encData, ReadOnlySpan<byte> input)
{
for (int i = 0; i != encData.Length; i++)
{
if (encData[i] != input[i])
return false;
}
return true;
}
#else
private byte[] Encrypt(byte[] input, int inOff, int inLen)
{
byte[] c2 = new byte[inLen];
Array.Copy(input, inOff, c2, 0, c2.Length);
ECMultiplier multiplier = CreateBasePointMultiplier();
BigInteger k;
ECPoint kPB;
do
{
k = NextK();
kPB = ((ECPublicKeyParameters)mECKey).Q.Multiply(k).Normalize();
Kdf(mDigest, kPB, c2);
}
while (NotEncrypted(c2, input, inOff));
ECPoint c1P = multiplier.Multiply(mECParams.G, k).Normalize();
byte[] c1 = c1P.GetEncoded(false);
AddFieldElement(mDigest, kPB.AffineXCoord);
mDigest.BlockUpdate(input, inOff, inLen);
AddFieldElement(mDigest, kPB.AffineYCoord);
byte[] c3 = DigestUtilities.DoFinal(mDigest);
switch (mMode)
{
case Mode.C1C3C2:
return Arrays.ConcatenateAll(c1, c3, c2);
default:
return Arrays.ConcatenateAll(c1, c2, c3);
}
}
private byte[] Decrypt(byte[] input, int inOff, int inLen)
{
byte[] c1 = new byte[mCurveLength * 2 + 1];
Array.Copy(input, inOff, c1, 0, c1.Length);
ECPoint c1P = mECParams.Curve.DecodePoint(c1);
ECPoint s = c1P.Multiply(mECParams.H);
if (s.IsInfinity)
throw new InvalidCipherTextException("[h]C1 at infinity");
c1P = c1P.Multiply(((ECPrivateKeyParameters)mECKey).D).Normalize();
int digestSize = mDigest.GetDigestSize();
byte[] c2 = new byte[inLen - c1.Length - digestSize];
if (mMode == Mode.C1C3C2)
{
Array.Copy(input, inOff + c1.Length + digestSize, c2, 0, c2.Length);
}
else
{
Array.Copy(input, inOff + c1.Length, c2, 0, c2.Length);
}
Kdf(mDigest, c1P, c2);
AddFieldElement(mDigest, c1P.AffineXCoord);
mDigest.BlockUpdate(c2, 0, c2.Length);
AddFieldElement(mDigest, c1P.AffineYCoord);
byte[] c3 = DigestUtilities.DoFinal(mDigest);
int check = 0;
if (mMode == Mode.C1C3C2)
{
for (int i = 0; i != c3.Length; i++)
{
check |= c3[i] ^ input[inOff + c1.Length + i];
}
}
else
{
for (int i = 0; i != c3.Length; i++)
{
check |= c3[i] ^ input[inOff + c1.Length + c2.Length + i];
}
}
Arrays.Fill(c1, 0);
Arrays.Fill(c3, 0);
if (check != 0)
{
Arrays.Fill(c2, 0);
throw new InvalidCipherTextException("invalid cipher text");
}
return c2;
}
private bool NotEncrypted(byte[] encData, byte[] input, int inOff)
{
for (int i = 0; i != encData.Length; i++)
{
if (encData[i] != input[inOff + i])
return false;
}
return true;
}
#endif
private void Kdf(IDigest digest, ECPoint c1, byte[] encData)
{
int digestSize = digest.GetDigestSize();
int bufSize = System.Math.Max(4, digestSize);
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
Span<byte> buf = bufSize <= 128
? stackalloc byte[bufSize]
: new byte[bufSize];
#else
byte[] buf = new byte[bufSize];
#endif
int off = 0;
IMemoable memo = digest as IMemoable;
IMemoable copy = null;
if (memo != null)
{
AddFieldElement(digest, c1.AffineXCoord);
AddFieldElement(digest, c1.AffineYCoord);
copy = memo.Copy();
}
uint ct = 0;
while (off < encData.Length)
{
if (memo != null)
{
memo.Reset(copy);
}
else
{
AddFieldElement(digest, c1.AffineXCoord);
AddFieldElement(digest, c1.AffineYCoord);
}
int xorLen = System.Math.Min(digestSize, encData.Length - off);
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
Pack.UInt32_To_BE(++ct, buf);
digest.BlockUpdate(buf[..4]);
digest.DoFinal(buf);
Xor(encData.AsSpan(off, xorLen), buf);
#else
Pack.UInt32_To_BE(++ct, buf, 0);
digest.BlockUpdate(buf, 0, 4);
digest.DoFinal(buf, 0);
Xor(encData, buf, off, xorLen);
#endif
off += xorLen;
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
private void Xor(Span<byte> data, ReadOnlySpan<byte> kdfOut)
{
for (int i = 0; i != data.Length; i++)
{
data[i] ^= kdfOut[i];
}
}
#else
private void Xor(byte[] data, byte[] kdfOut, int dOff, int dRemaining)
{
for (int i = 0; i != dRemaining; i++)
{
data[dOff + i] ^= kdfOut[i];
}
}
#endif
private BigInteger NextK()
{
int qBitLength = mECParams.N.BitLength;
BigInteger k;
do
{
k = new BigInteger(qBitLength, mRandom);
}
while (k.SignValue == 0 || k.CompareTo(mECParams.N) >= 0);
return k;
}
private void AddFieldElement(IDigest digest, ECFieldElement v)
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
int encodedLength = v.GetEncodedLength();
Span<byte> p = encodedLength <= 128
? stackalloc byte[encodedLength]
: new byte[encodedLength];
v.EncodeTo(p);
digest.BlockUpdate(p);
#else
byte[] p = v.GetEncoded();
digest.BlockUpdate(p, 0, p.Length);
#endif
}
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 9c18320ad9da1a74a9f2c28a40df4089
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/SM2Engine.cs
uploadId: 783279

View File

@ -0,0 +1,215 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/// <summary>SM4 Block Cipher - SM4 is a 128 bit block cipher with a 128 bit key.</summary>
/// <remarks>
/// The implementation here is based on the document <a href="http://eprint.iacr.org/2008/329.pdf">http://eprint.iacr.org/2008/329.pdf</a>
/// by Whitfield Diffie and George Ledin, which is a translation of Prof. LU Shu-wang's original standard.
/// </remarks>
public class SM4Engine
: IBlockCipher
{
private const int BlockSize = 16;
private static readonly byte[] Sbox =
{
0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62,
0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6,
0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8,
0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35,
0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87,
0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e,
0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1,
0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3,
0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f,
0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51,
0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8,
0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0,
0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84,
0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48
};
private static readonly uint[] CK =
{
0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279
};
private static readonly uint[] FK =
{
0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc
};
private uint[] rk;
// non-linear substitution tau.
private static uint tau(uint A)
{
uint b0 = Sbox[A >> 24];
uint b1 = Sbox[(A >> 16) & 0xFF];
uint b2 = Sbox[(A >> 8) & 0xFF];
uint b3 = Sbox[A & 0xFF];
return (b0 << 24) | (b1 << 16) | (b2 << 8) | b3;
}
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));
}
// Key expansion
private void ExpandKey(bool forEncryption, byte[] key)
{
uint K0 = Pack.BE_To_UInt32(key, 0) ^ FK[0];
uint K1 = Pack.BE_To_UInt32(key, 4) ^ FK[1];
uint K2 = Pack.BE_To_UInt32(key, 8) ^ FK[2];
uint K3 = Pack.BE_To_UInt32(key, 12) ^ FK[3];
if (forEncryption)
{
rk[0] = K0 ^ T_ap(K1 ^ K2 ^ K3 ^ CK[0]);
rk[1] = K1 ^ T_ap(K2 ^ K3 ^ rk[0] ^ CK[1]);
rk[2] = K2 ^ T_ap(K3 ^ rk[0] ^ rk[1] ^ CK[2]);
rk[3] = K3 ^ 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]);
}
}
else
{
rk[31] = K0 ^ T_ap(K1 ^ K2 ^ K3 ^ CK[0]);
rk[30] = K1 ^ T_ap(K2 ^ K3 ^ rk[31] ^ CK[1]);
rk[29] = K2 ^ T_ap(K3 ^ rk[31] ^ rk[30] ^ CK[2]);
rk[28] = K3 ^ T_ap(rk[31] ^ rk[30] ^ rk[29] ^ CK[3]);
for (int i = 27; i >= 0; --i)
{
rk[i] = rk[i + 4] ^ T_ap(rk[i + 3] ^ rk[i + 2] ^ rk[i + 1] ^ CK[31 - i]);
}
}
}
// Linear substitution L
private static uint L(uint B)
{
return B ^ Integers.RotateLeft(B, 2) ^ Integers.RotateLeft(B, 10) ^ Integers.RotateLeft(B, 18) ^ Integers.RotateLeft(B, 24);
}
// Mixer-substitution T
private static uint T(uint Z)
{
return L(tau(Z));
}
public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
KeyParameter keyParameter = parameters as KeyParameter;
if (null == keyParameter)
throw new ArgumentException("invalid parameter passed to SM4 init - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters), "parameters");
byte[] key = keyParameter.GetKey();
if (key.Length != 16)
throw new ArgumentException("SM4 requires a 128 bit key", "parameters");
if (null == rk)
{
rk = new uint[32];
}
ExpandKey(forEncryption, key);
}
public virtual string AlgorithmName
{
get { return "SM4"; }
}
public virtual int GetBlockSize()
{
return BlockSize;
}
public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff)
{
if (null == rk)
throw new InvalidOperationException("SM4 not initialised");
Check.DataLength(input, inOff, BlockSize, "input buffer too short");
Check.OutputLength(output, outOff, BlockSize, "output buffer too short");
uint X0 = Pack.BE_To_UInt32(input, inOff);
uint X1 = Pack.BE_To_UInt32(input, inOff + 4);
uint X2 = Pack.BE_To_UInt32(input, inOff + 8);
uint X3 = Pack.BE_To_UInt32(input, inOff + 12);
for (int i = 0; i < 32; i += 4)
{
X0 ^= T(X1 ^ X2 ^ X3 ^ rk[i ]); // F0
X1 ^= T(X2 ^ X3 ^ X0 ^ rk[i + 1]); // F1
X2 ^= T(X3 ^ X0 ^ X1 ^ rk[i + 2]); // F2
X3 ^= T(X0 ^ X1 ^ X2 ^ rk[i + 3]); // F3
}
Pack.UInt32_To_BE(X3, output, outOff);
Pack.UInt32_To_BE(X2, output, outOff + 4);
Pack.UInt32_To_BE(X1, output, outOff + 8);
Pack.UInt32_To_BE(X0, output, outOff + 12);
return BlockSize;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual int ProcessBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
if (null == rk)
throw new InvalidOperationException("SM4 not initialised");
Check.DataLength(input, BlockSize, "input buffer too short");
Check.OutputLength(output, BlockSize, "output buffer too short");
uint X0 = Pack.BE_To_UInt32(input);
uint X1 = Pack.BE_To_UInt32(input[4..]);
uint X2 = Pack.BE_To_UInt32(input[8..]);
uint X3 = Pack.BE_To_UInt32(input[12..]);
for (int i = 0; i < 32; i += 4)
{
X0 ^= T(X1 ^ X2 ^ X3 ^ rk[i ]); // F0
X1 ^= T(X2 ^ X3 ^ X0 ^ rk[i + 1]); // F1
X2 ^= T(X3 ^ X0 ^ X1 ^ rk[i + 2]); // F2
X3 ^= T(X0 ^ X1 ^ X2 ^ rk[i + 3]); // F3
}
Pack.UInt32_To_BE(X3, output);
Pack.UInt32_To_BE(X2, output[4..]);
Pack.UInt32_To_BE(X1, output[8..]);
Pack.UInt32_To_BE(X0, output[12..]);
return BlockSize;
}
#endif
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 48e0155581320e94d9f238d5f3a684f8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/SM4Engine.cs
uploadId: 783279

View File

@ -0,0 +1,512 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
#if NETSTANDARD1_0_OR_GREATER || NETCOREAPP1_0_OR_GREATER || UNITY_2021_2_OR_NEWER
using System.Runtime.CompilerServices;
#endif
#if NETCOREAPP3_0_OR_GREATER
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
#endif
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/// <summary>
/// Implementation of Daniel J. Bernstein's Salsa20 stream cipher, Snuffle 2005
/// </summary>
public class Salsa20Engine
: IStreamCipher
{
public static readonly int DEFAULT_ROUNDS = 20;
/** Constants */
private const int StateSize = 16; // 16, 32 bit ints = 64 bytes
private readonly static uint[] TAU_SIGMA = Pack.LE_To_UInt32(Strings.ToAsciiByteArray("expand 16-byte k" + "expand 32-byte k"), 0, 8);
internal void PackTauOrSigma(int keyLength, uint[] state, int stateOffset)
{
int tsOff = (keyLength - 16) / 4;
state[stateOffset] = TAU_SIGMA[tsOff];
state[stateOffset + 1] = TAU_SIGMA[tsOff + 1];
state[stateOffset + 2] = TAU_SIGMA[tsOff + 2];
state[stateOffset + 3] = TAU_SIGMA[tsOff + 3];
}
protected int rounds;
/*
* variables to hold the state of the engine
* during encryption and decryption
*/
internal int index = 0;
internal uint[] engineState = new uint[StateSize]; // state
internal uint[] x = new uint[StateSize]; // internal buffer
internal byte[] keyStream = new byte[StateSize * 4]; // expanded state, 64 bytes
internal bool initialised = false;
/*
* internal counter
*/
private uint cW0, cW1, cW2;
/// <summary>
/// Creates a 20 round Salsa20 engine.
/// </summary>
public Salsa20Engine()
: this(DEFAULT_ROUNDS)
{
}
/// <summary>
/// Creates a Salsa20 engine with a specific number of rounds.
/// </summary>
/// <param name="rounds">the number of rounds (must be an even number).</param>
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)
{
/*
* Salsa20 encryption and decryption is completely
* symmetrical, so the 'forEncryption' is
* irrelevant. (Like 90% of stream ciphers)
*/
ParametersWithIV ivParams = parameters as ParametersWithIV;
if (ivParams == null)
throw new ArgumentException(AlgorithmName + " Init requires an IV", "parameters");
byte[] iv = ivParams.GetIV();
if (iv == null || iv.Length != NonceSize)
throw new ArgumentException(AlgorithmName + " requires exactly " + NonceSize + " bytes of IV");
ICipherParameters keyParam = ivParams.Parameters;
if (keyParam == null)
{
if (!initialised)
throw new InvalidOperationException(AlgorithmName + " KeyParameter can not be null for first initialisation");
SetKey(null, iv);
}
else if (keyParam is KeyParameter)
{
SetKey(((KeyParameter)keyParam).GetKey(), iv);
}
else
{
throw new ArgumentException(AlgorithmName + " Init parameters must contain a KeyParameter (or null for re-init)");
}
Reset();
initialised = true;
}
protected virtual int NonceSize
{
get { return 8; }
}
public virtual string AlgorithmName
{
get
{
string name = "Salsa20";
if (rounds != DEFAULT_ROUNDS)
{
name += "/" + rounds;
}
return name;
}
}
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 output = (byte)(keyStream[index] ^ input);
index = (index + 1) & 63;
return output;
}
protected virtual void AdvanceCounter()
{
if (++engineState[8] == 0)
{
++engineState[9];
}
}
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) & 63;
}
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public virtual void ProcessBytes(ReadOnlySpan<byte> input, Span<byte> output)
{
if (!initialised)
throw new InvalidOperationException(AlgorithmName + " not initialised");
Check.OutputLength(output, input.Length, "output buffer too short");
if (LimitExceeded((uint)input.Length))
throw new MaxBytesExceededException("2^70 byte limit per IV would be exceeded; Change IV");
for (int i = 0; i < input.Length; i++)
{
if (index == 0)
{
GenerateKeyStream(keyStream);
AdvanceCounter();
}
output[i] = (byte)(keyStream[index++] ^ input[i]);
index &= 63;
}
}
#endif
public virtual void Reset()
{
index = 0;
ResetLimitCounter();
ResetCounter();
}
protected virtual void ResetCounter()
{
engineState[8] = engineState[9] = 0;
}
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 tsOff = (keyBytes.Length - 16) / 4;
engineState[0] = TAU_SIGMA[tsOff];
engineState[5] = TAU_SIGMA[tsOff + 1];
engineState[10] = TAU_SIGMA[tsOff + 2];
engineState[15] = TAU_SIGMA[tsOff + 3];
// Key
Pack.LE_To_UInt32(keyBytes, 0, engineState, 1, 4);
Pack.LE_To_UInt32(keyBytes, keyBytes.Length - 16, engineState, 11, 4);
}
// IV
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);
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
internal static void SalsaCore(int rounds, ReadOnlySpan<uint> input, Span<uint> output)
{
if (input.Length < 16)
throw new ArgumentException();
if (output.Length < 16)
throw new ArgumentException();
if (rounds % 2 != 0)
throw new ArgumentException("Number of rounds must be even");
#if NETCOREAPP3_0_OR_GREATER
if (Sse41.IsSupported && BitConverter.IsLittleEndian && Unsafe.SizeOf<Vector128<short>>() == 16)
{
Vector128<uint> b0, b1, b2, b3;
{
var I = MemoryMarshal.AsBytes(input[..16]);
var t0 = MemoryMarshal.Read<Vector128<short>>(I[0x00..0x10]);
var t1 = MemoryMarshal.Read<Vector128<short>>(I[0x10..0x20]);
var t2 = MemoryMarshal.Read<Vector128<short>>(I[0x20..0x30]);
var t3 = MemoryMarshal.Read<Vector128<short>>(I[0x30..0x40]);
var u0 = Sse41.Blend(t0, t2, 0xF0);
var u1 = Sse41.Blend(t1, t3, 0xC3);
var u2 = Sse41.Blend(t0, t2, 0x0F);
var u3 = Sse41.Blend(t1, t3, 0x3C);
b0 = Sse41.Blend(u0, u1, 0xCC).AsUInt32();
b1 = Sse41.Blend(u0, u1, 0x33).AsUInt32();
b2 = Sse41.Blend(u2, u3, 0xCC).AsUInt32();
b3 = Sse41.Blend(u2, u3, 0x33).AsUInt32();
}
var c0 = b0;
var c1 = b1;
var c2 = b2;
var c3 = b3;
for (int i = rounds; i > 0; i -= 2)
{
QuarterRound_Sse2(ref c0, ref c3, ref c2, ref c1);
QuarterRound_Sse2(ref c0, ref c1, ref c2, ref c3);
}
b0 = Sse2.Add(b0, c0);
b1 = Sse2.Add(b1, c1);
b2 = Sse2.Add(b2, c2);
b3 = Sse2.Add(b3, c3);
{
var t0 = b0.AsUInt16();
var t1 = b1.AsUInt16();
var t2 = b2.AsUInt16();
var t3 = b3.AsUInt16();
var u0 = Sse41.Blend(t0, t1, 0xCC);
var u1 = Sse41.Blend(t0, t1, 0x33);
var u2 = Sse41.Blend(t2, t3, 0xCC);
var u3 = Sse41.Blend(t2, t3, 0x33);
var v0 = Sse41.Blend(u0, u2, 0xF0);
var v1 = Sse41.Blend(u1, u3, 0xC3);
var v2 = Sse41.Blend(u0, u2, 0x0F);
var v3 = Sse41.Blend(u1, u3, 0x3C);
var X = MemoryMarshal.AsBytes(output[..16]);
MemoryMarshal.Write(X[0x00..0x10], ref v0);
MemoryMarshal.Write(X[0x10..0x20], ref v1);
MemoryMarshal.Write(X[0x20..0x30], ref v2);
MemoryMarshal.Write(X[0x30..0x40], ref v3);
}
return;
}
#endif
uint x00 = input[ 0];
uint x01 = input[ 1];
uint x02 = input[ 2];
uint x03 = input[ 3];
uint x04 = input[ 4];
uint x05 = input[ 5];
uint x06 = input[ 6];
uint x07 = input[ 7];
uint x08 = input[ 8];
uint x09 = input[ 9];
uint x10 = input[10];
uint x11 = input[11];
uint x12 = input[12];
uint x13 = input[13];
uint x14 = input[14];
uint x15 = input[15];
for (int i = rounds; i > 0; i -= 2)
{
QuarterRound(ref x00, ref x04, ref x08, ref x12);
QuarterRound(ref x05, ref x09, ref x13, ref x01);
QuarterRound(ref x10, ref x14, ref x02, ref x06);
QuarterRound(ref x15, ref x03, ref x07, ref x11);
QuarterRound(ref x00, ref x01, ref x02, ref x03);
QuarterRound(ref x05, ref x06, ref x07, ref x04);
QuarterRound(ref x10, ref x11, ref x08, ref x09);
QuarterRound(ref x15, ref x12, ref x13, ref x14);
}
output[ 0] = x00 + input[ 0];
output[ 1] = x01 + input[ 1];
output[ 2] = x02 + input[ 2];
output[ 3] = x03 + input[ 3];
output[ 4] = x04 + input[ 4];
output[ 5] = x05 + input[ 5];
output[ 6] = x06 + input[ 6];
output[ 7] = x07 + input[ 7];
output[ 8] = x08 + input[ 8];
output[ 9] = x09 + input[ 9];
output[10] = x10 + input[10];
output[11] = x11 + input[11];
output[12] = x12 + input[12];
output[13] = x13 + input[13];
output[14] = x14 + input[14];
output[15] = x15 + input[15];
}
#else
internal static void SalsaCore(int rounds, uint[] input, uint[] output)
{
if (input.Length < 16)
throw new ArgumentException();
if (output.Length < 16)
throw new ArgumentException();
if (rounds % 2 != 0)
throw new ArgumentException("Number of rounds must be even");
uint x00 = input[ 0];
uint x01 = input[ 1];
uint x02 = input[ 2];
uint x03 = input[ 3];
uint x04 = input[ 4];
uint x05 = input[ 5];
uint x06 = input[ 6];
uint x07 = input[ 7];
uint x08 = input[ 8];
uint x09 = input[ 9];
uint x10 = input[10];
uint x11 = input[11];
uint x12 = input[12];
uint x13 = input[13];
uint x14 = input[14];
uint x15 = input[15];
for (int i = rounds; i > 0; i -= 2)
{
QuarterRound(ref x00, ref x04, ref x08, ref x12);
QuarterRound(ref x05, ref x09, ref x13, ref x01);
QuarterRound(ref x10, ref x14, ref x02, ref x06);
QuarterRound(ref x15, ref x03, ref x07, ref x11);
QuarterRound(ref x00, ref x01, ref x02, ref x03);
QuarterRound(ref x05, ref x06, ref x07, ref x04);
QuarterRound(ref x10, ref x11, ref x08, ref x09);
QuarterRound(ref x15, ref x12, ref x13, ref x14);
}
output[ 0] = x00 + input[ 0];
output[ 1] = x01 + input[ 1];
output[ 2] = x02 + input[ 2];
output[ 3] = x03 + input[ 3];
output[ 4] = x04 + input[ 4];
output[ 5] = x05 + input[ 5];
output[ 6] = x06 + input[ 6];
output[ 7] = x07 + input[ 7];
output[ 8] = x08 + input[ 8];
output[ 9] = x09 + input[ 9];
output[10] = x10 + input[10];
output[11] = x11 + input[11];
output[12] = x12 + input[12];
output[13] = x13 + input[13];
output[14] = x14 + input[14];
output[15] = x15 + input[15];
}
#endif
internal void ResetLimitCounter()
{
cW0 = 0;
cW1 = 0;
cW2 = 0;
}
internal bool LimitExceeded()
{
if (++cW0 == 0)
{
if (++cW1 == 0)
{
return (++cW2 & 0x20) != 0; // 2^(32 + 32 + 6)
}
}
return false;
}
/*
* this relies on the fact len will always be positive.
*/
internal bool LimitExceeded(
uint len)
{
uint old = cW0;
cW0 += len;
if (cW0 < old)
{
if (++cW1 == 0)
{
return (++cW2 & 0x20) != 0; // 2^(32 + 32 + 6)
}
}
return false;
}
#if NETSTANDARD1_0_OR_GREATER || NETCOREAPP1_0_OR_GREATER || UNITY_2021_2_OR_NEWER
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
private static void QuarterRound(ref uint a, ref uint b, ref uint c, ref uint d)
{
b ^= Integers.RotateLeft(a + d, 7);
c ^= Integers.RotateLeft(b + a, 9);
d ^= Integers.RotateLeft(c + b, 13);
a ^= Integers.RotateLeft(d + c, 18);
}
#if NETCOREAPP3_0_OR_GREATER
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void QuarterRound_Sse2(ref Vector128<uint> a, ref Vector128<uint> b, ref Vector128<uint> c,
ref Vector128<uint> d)
{
b = Sse2.Xor(b, Rotate_Sse2(Sse2.Add(a, d), 7));
c = Sse2.Xor(c, Rotate_Sse2(Sse2.Add(b, a), 9));
d = Sse2.Xor(d, Rotate_Sse2(Sse2.Add(c, b), 13));
a = Sse2.Xor(a, Rotate_Sse2(Sse2.Add(d, c), 18));
b = Sse2.Shuffle(b, 0x93);
c = Sse2.Shuffle(c, 0x4E);
d = Sse2.Shuffle(d, 0x39);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector128<uint> Rotate_Sse2(Vector128<uint> x, byte sl)
{
byte sr = (byte)(32 - sl);
return Sse2.Xor(Sse2.ShiftLeftLogical(x, sl), Sse2.ShiftRightLogical(x, sr));
}
#endif
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 45a640781b0ce9e429cc6f2d8cbceadd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/Salsa20Engine.cs
uploadId: 783279

View File

@ -0,0 +1,405 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Utilities;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
/**
* Serpent is a 128-bit 32-round block cipher with variable key lengths,
* including 128, 192 and 256 bit keys conjectured to be at least as
* secure as three-key triple-DES.
* <p>
* Serpent was designed by Ross Anderson, Eli Biham and Lars Knudsen as a
* candidate algorithm for the NIST AES Quest.
* </p>
* <p>
* For full details see <a href="http://www.cl.cam.ac.uk/~rja14/serpent.html">The Serpent home page</a>
* </p>
*/
public sealed class SerpentEngine
: SerpentEngineBase
{
/**
* Expand a user-supplied key material into a session key.
*
* @param key The user-key bytes (multiples of 4) to use.
* @exception ArgumentException
*/
internal override int[] MakeWorkingKey(byte[] key)
{
//
// pad key to 256 bits
//
int[] kPad = new int[16];
int off = 0;
int length = 0;
for (off = 0; (off + 4) < key.Length; off += 4)
{
kPad[length++] = (int)Pack.LE_To_UInt32(key, off);
}
if (off % 4 == 0)
{
kPad[length++] = (int)Pack.LE_To_UInt32(key, off);
if (length < 8)
{
kPad[length] = 1;
}
}
else
{
throw new ArgumentException("key must be a multiple of 4 bytes");
}
//
// expand the padded key up to 33 x 128 bits of key material
//
int amount = (ROUNDS + 1) * 4;
int[] w = new int[amount];
//
// compute w0 to w7 from w-8 to w-1
//
for (int i = 8; i < 16; i++)
{
kPad[i] = Integers.RotateLeft(kPad[i - 8] ^ kPad[i - 5] ^ kPad[i - 3] ^ kPad[i - 1] ^ PHI ^ (i - 8), 11);
}
Array.Copy(kPad, 8, w, 0, 8);
//
// compute w8 to w136
//
for (int i = 8; i < amount; i++)
{
w[i] = Integers.RotateLeft(w[i - 8] ^ w[i - 5] ^ w[i - 3] ^ w[i - 1] ^ PHI ^ i, 11);
}
//
// create the working keys by processing w with the Sbox and IP
//
Sb3(w[0], w[1], w[2], w[3]);
w[0] = X0; w[1] = X1; w[2] = X2; w[3] = X3;
Sb2(w[4], w[5], w[6], w[7]);
w[4] = X0; w[5] = X1; w[6] = X2; w[7] = X3;
Sb1(w[8], w[9], w[10], w[11]);
w[8] = X0; w[9] = X1; w[10] = X2; w[11] = X3;
Sb0(w[12], w[13], w[14], w[15]);
w[12] = X0; w[13] = X1; w[14] = X2; w[15] = X3;
Sb7(w[16], w[17], w[18], w[19]);
w[16] = X0; w[17] = X1; w[18] = X2; w[19] = X3;
Sb6(w[20], w[21], w[22], w[23]);
w[20] = X0; w[21] = X1; w[22] = X2; w[23] = X3;
Sb5(w[24], w[25], w[26], w[27]);
w[24] = X0; w[25] = X1; w[26] = X2; w[27] = X3;
Sb4(w[28], w[29], w[30], w[31]);
w[28] = X0; w[29] = X1; w[30] = X2; w[31] = X3;
Sb3(w[32], w[33], w[34], w[35]);
w[32] = X0; w[33] = X1; w[34] = X2; w[35] = X3;
Sb2(w[36], w[37], w[38], w[39]);
w[36] = X0; w[37] = X1; w[38] = X2; w[39] = X3;
Sb1(w[40], w[41], w[42], w[43]);
w[40] = X0; w[41] = X1; w[42] = X2; w[43] = X3;
Sb0(w[44], w[45], w[46], w[47]);
w[44] = X0; w[45] = X1; w[46] = X2; w[47] = X3;
Sb7(w[48], w[49], w[50], w[51]);
w[48] = X0; w[49] = X1; w[50] = X2; w[51] = X3;
Sb6(w[52], w[53], w[54], w[55]);
w[52] = X0; w[53] = X1; w[54] = X2; w[55] = X3;
Sb5(w[56], w[57], w[58], w[59]);
w[56] = X0; w[57] = X1; w[58] = X2; w[59] = X3;
Sb4(w[60], w[61], w[62], w[63]);
w[60] = X0; w[61] = X1; w[62] = X2; w[63] = X3;
Sb3(w[64], w[65], w[66], w[67]);
w[64] = X0; w[65] = X1; w[66] = X2; w[67] = X3;
Sb2(w[68], w[69], w[70], w[71]);
w[68] = X0; w[69] = X1; w[70] = X2; w[71] = X3;
Sb1(w[72], w[73], w[74], w[75]);
w[72] = X0; w[73] = X1; w[74] = X2; w[75] = X3;
Sb0(w[76], w[77], w[78], w[79]);
w[76] = X0; w[77] = X1; w[78] = X2; w[79] = X3;
Sb7(w[80], w[81], w[82], w[83]);
w[80] = X0; w[81] = X1; w[82] = X2; w[83] = X3;
Sb6(w[84], w[85], w[86], w[87]);
w[84] = X0; w[85] = X1; w[86] = X2; w[87] = X3;
Sb5(w[88], w[89], w[90], w[91]);
w[88] = X0; w[89] = X1; w[90] = X2; w[91] = X3;
Sb4(w[92], w[93], w[94], w[95]);
w[92] = X0; w[93] = X1; w[94] = X2; w[95] = X3;
Sb3(w[96], w[97], w[98], w[99]);
w[96] = X0; w[97] = X1; w[98] = X2; w[99] = X3;
Sb2(w[100], w[101], w[102], w[103]);
w[100] = X0; w[101] = X1; w[102] = X2; w[103] = X3;
Sb1(w[104], w[105], w[106], w[107]);
w[104] = X0; w[105] = X1; w[106] = X2; w[107] = X3;
Sb0(w[108], w[109], w[110], w[111]);
w[108] = X0; w[109] = X1; w[110] = X2; w[111] = X3;
Sb7(w[112], w[113], w[114], w[115]);
w[112] = X0; w[113] = X1; w[114] = X2; w[115] = X3;
Sb6(w[116], w[117], w[118], w[119]);
w[116] = X0; w[117] = X1; w[118] = X2; w[119] = X3;
Sb5(w[120], w[121], w[122], w[123]);
w[120] = X0; w[121] = X1; w[122] = X2; w[123] = X3;
Sb4(w[124], w[125], w[126], w[127]);
w[124] = X0; w[125] = X1; w[126] = X2; w[127] = X3;
Sb3(w[128], w[129], w[130], w[131]);
w[128] = X0; w[129] = X1; w[130] = X2; w[131] = X3;
return w;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
internal override void EncryptBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
X0 = (int)Pack.LE_To_UInt32(input);
X1 = (int)Pack.LE_To_UInt32(input[4..]);
X2 = (int)Pack.LE_To_UInt32(input[8..]);
X3 = (int)Pack.LE_To_UInt32(input[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);
Pack.UInt32_To_LE((uint)(wKey[129] ^ X1), output[4..]);
Pack.UInt32_To_LE((uint)(wKey[130] ^ X2), output[8..]);
Pack.UInt32_To_LE((uint)(wKey[131] ^ X3), output[12..]);
}
internal override void DecryptBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
X0 = wKey[128] ^ (int)Pack.LE_To_UInt32(input);
X1 = wKey[129] ^ (int)Pack.LE_To_UInt32(input[4..]);
X2 = wKey[130] ^ (int)Pack.LE_To_UInt32(input[8..]);
X3 = wKey[131] ^ (int)Pack.LE_To_UInt32(input[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);
Pack.UInt32_To_LE((uint)(X1 ^ wKey[1]), output[4..]);
Pack.UInt32_To_LE((uint)(X2 ^ wKey[2]), output[8..]);
Pack.UInt32_To_LE((uint)(X3 ^ wKey[3]), output[12..]);
}
#else
internal 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);
}
internal 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);
}
#endif
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: ac17de8597ec6214f8cdd5d47aa35e13
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/SerpentEngine.cs
uploadId: 783279

View File

@ -0,0 +1,491 @@
#if !BESTHTTP_DISABLE_ALTERNATE_SSL && (!UNITY_WEBGL || UNITY_EDITOR)
#pragma warning disable
using System;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Parameters;
using Best.HTTP.SecureProtocol.Org.BouncyCastle.Utilities;
namespace Best.HTTP.SecureProtocol.Org.BouncyCastle.Crypto.Engines
{
public abstract class SerpentEngineBase
: IBlockCipher
{
protected static readonly int BlockSize = 16;
internal const int ROUNDS = 32;
internal const int PHI = unchecked((int)0x9E3779B9); // (sqrt(5) - 1) * 2**31
protected bool encrypting;
protected int[] wKey;
protected int X0, X1, X2, X3; // registers
internal SerpentEngineBase()
{
}
/**
* initialise a Serpent cipher.
*
* @param encrypting whether or not we are for encryption.
* @param params the parameters required to set up the cipher.
* @throws IllegalArgumentException if the params argument is
* inappropriate.
*/
public virtual void Init(bool encrypting, ICipherParameters parameters)
{
if (!(parameters is KeyParameter))
throw new ArgumentException("invalid parameter passed to " + AlgorithmName + " init - " + Org.BouncyCastle.Utilities.Platform.GetTypeName(parameters));
this.encrypting = encrypting;
this.wKey = MakeWorkingKey(((KeyParameter)parameters).GetKey());
}
public virtual string AlgorithmName
{
get { return "Serpent"; }
}
public virtual int GetBlockSize()
{
return BlockSize;
}
/**
* Process one block of input from the array in and write it to
* the out array.
*
* @param in the array containing the input data.
* @param inOff offset into the in array the data starts at.
* @param out the array the output data will be copied into.
* @param outOff the offset into the out array the output will start at.
* @return the number of bytes processed and produced.
* @throws DataLengthException if there isn't enough data in in, or
* space in out.
* @throws IllegalStateException if the cipher isn't initialised.
*/
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 NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
if (encrypting)
{
EncryptBlock(input.AsSpan(inOff), output.AsSpan(outOff));
}
else
{
DecryptBlock(input.AsSpan(inOff), output.AsSpan(outOff));
}
#else
if (encrypting)
{
EncryptBlock(input, inOff, output, outOff);
}
else
{
DecryptBlock(input, inOff, output, outOff);
}
#endif
return BlockSize;
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
public int ProcessBlock(ReadOnlySpan<byte> input, Span<byte> output)
{
if (wKey == null)
throw new InvalidOperationException(AlgorithmName + " not initialised");
Check.DataLength(input, BlockSize, "input buffer too short");
Check.OutputLength(output, BlockSize, "output buffer too short");
if (encrypting)
{
EncryptBlock(input, output);
}
else
{
DecryptBlock(input, output);
}
return BlockSize;
}
#endif
/*
* The sboxes below are based on the work of Brian Gladman and
* Sam Simpson, whose original notice appears below.
* <p>
* For further details see:
* http://fp.gladman.plus.com/cryptography_technology/serpent/
* </p>
*/
/* Partially optimised Serpent S Box boolean functions derived */
/* using a recursive descent analyser but without a full search */
/* of all subtrees. This set of S boxes is the result of work */
/* by Sam Simpson and Brian Gladman using the spare time on a */
/* cluster of high capacity servers to search for S boxes with */
/* this customised search engine. There are now an average of */
/* 15.375 terms per S box. */
/* */
/* Copyright: Dr B. R Gladman (gladman@seven77.demon.co.uk) */
/* and Sam Simpson (s.simpson@mia.co.uk) */
/* 17th December 1998 */
/* */
/* We hereby give permission for information in this file to be */
/* used freely subject only to acknowledgement of its origin. */
/*
* S0 - { 3, 8,15, 1,10, 6, 5,11,14,13, 4, 2, 7, 0, 9,12 } - 15 terms.
*/
protected void Sb0(int a, int b, int c, int d)
{
int t1 = a ^ d;
int t3 = c ^ t1;
int t4 = b ^ t3;
X3 = (a & d) ^ t4;
int t7 = a ^ (b & t1);
X2 = t4 ^ (c | t7);
int t12 = X3 & (t3 ^ t7);
X1 = (~t3) ^ t12;
X0 = t12 ^ (~t7);
}
/**
* InvSO - {13, 3,11, 0,10, 6, 5,12, 1,14, 4, 7,15, 9, 8, 2 } - 15 terms.
*/
protected void Ib0(int a, int b, int c, int d)
{
int t1 = ~a;
int t2 = a ^ b;
int t4 = d ^ (t1 | t2);
int t5 = c ^ t4;
X2 = t2 ^ t5;
int t8 = t1 ^ (d & t2);
X1 = t4 ^ (X2 & t8);
X3 = (a & t4) ^ (t5 | X1);
X0 = X3 ^ (t5 ^ t8);
}
/**
* S1 - {15,12, 2, 7, 9, 0, 5,10, 1,11,14, 8, 6,13, 3, 4 } - 14 terms.
*/
protected void Sb1(int a, int b, int c, int d)
{
int t2 = b ^ (~a);
int t5 = c ^ (a | t2);
X2 = d ^ t5;
int t7 = b ^ (d | t2);
int t8 = t2 ^ X2;
X3 = t8 ^ (t5 & t7);
int t11 = t5 ^ t7;
X1 = X3 ^ t11;
X0 = t5 ^ (t8 & t11);
}
/**
* InvS1 - { 5, 8, 2,14,15, 6,12, 3,11, 4, 7, 9, 1,13,10, 0 } - 14 steps.
*/
protected void Ib1(int a, int b, int c, int d)
{
int t1 = b ^ d;
int t3 = a ^ (b & t1);
int t4 = t1 ^ t3;
X3 = c ^ t4;
int t7 = b ^ (t1 & t3);
int t8 = X3 | t7;
X1 = t3 ^ t8;
int t10 = ~X1;
int t11 = X3 ^ t7;
X0 = t10 ^ t11;
X2 = t4 ^ (t10 | t11);
}
/**
* S2 - { 8, 6, 7, 9, 3,12,10,15,13, 1,14, 4, 0,11, 5, 2 } - 16 terms.
*/
protected void Sb2(int a, int b, int c, int d)
{
int t1 = ~a;
int t2 = b ^ d;
int t3 = c & t1;
X0 = t2 ^ t3;
int t5 = c ^ t1;
int t6 = c ^ X0;
int t7 = b & t6;
X3 = t5 ^ t7;
X2 = a ^ ((d | t7) & (X0 | t5));
X1 = (t2 ^ X3) ^ (X2 ^ (d | t1));
}
/**
* InvS2 - {12, 9,15, 4,11,14, 1, 2, 0, 3, 6,13, 5, 8,10, 7 } - 16 steps.
*/
protected void Ib2(int a, int b, int c, int d)
{
int t1 = b ^ d;
int t2 = ~t1;
int t3 = a ^ c;
int t4 = c ^ t1;
int t5 = b & t4;
X0 = t3 ^ t5;
int t7 = a | t2;
int t8 = d ^ t7;
int t9 = t3 | t8;
X3 = t1 ^ t9;
int t11 = ~t4;
int t12 = X0 | X3;
X1 = t11 ^ t12;
X2 = (d & t11) ^ (t3 ^ t12);
}
/**
* S3 - { 0,15,11, 8,12, 9, 6, 3,13, 1, 2, 4,10, 7, 5,14 } - 16 terms.
*/
protected void Sb3(int a, int b, int c, int d)
{
int t1 = a ^ b;
int t2 = a & c;
int t3 = a | d;
int t4 = c ^ d;
int t5 = t1 & t3;
int t6 = t2 | t5;
X2 = t4 ^ t6;
int t8 = b ^ t3;
int t9 = t6 ^ t8;
int t10 = t4 & t9;
X0 = t1 ^ t10;
int t12 = X2 & X0;
X1 = t9 ^ t12;
X3 = (b | d) ^ (t4 ^ t12);
}
/**
* InvS3 - { 0, 9,10, 7,11,14, 6,13, 3, 5,12, 2, 4, 8,15, 1 } - 15 terms
*/
protected void Ib3(int a, int b, int c, int d)
{
int t1 = a | b;
int t2 = b ^ c;
int t3 = b & t2;
int t4 = a ^ t3;
int t5 = c ^ t4;
int t6 = d | t4;
X0 = t2 ^ t6;
int t8 = t2 | t6;
int t9 = d ^ t8;
X2 = t5 ^ t9;
int t11 = t1 ^ t9;
int t12 = X0 & t11;
X3 = t4 ^ t12;
X1 = X3 ^ (X0 ^ t11);
}
/**
* S4 - { 1,15, 8, 3,12, 0,11, 6, 2, 5, 4,10, 9,14, 7,13 } - 15 terms.
*/
protected void Sb4(int a, int b, int c, int d)
{
int t1 = a ^ d;
int t2 = d & t1;
int t3 = c ^ t2;
int t4 = b | t3;
X3 = t1 ^ t4;
int t6 = ~b;
int t7 = t1 | t6;
X0 = t3 ^ t7;
int t9 = a & X0;
int t10 = t1 ^ t6;
int t11 = t4 & t10;
X2 = t9 ^ t11;
X1 = (a ^ t3) ^ (t10 & X2);
}
/**
* InvS4 - { 5, 0, 8, 3,10, 9, 7,14, 2,12,11, 6, 4,15,13, 1 } - 15 terms.
*/
protected void Ib4(int a, int b, int c, int d)
{
int t1 = c | d;
int t2 = a & t1;
int t3 = b ^ t2;
int t4 = a & t3;
int t5 = c ^ t4;
X1 = d ^ t5;
int t7 = ~a;
int t8 = t5 & X1;
X3 = t3 ^ t8;
int t10 = X1 | t7;
int t11 = d ^ t10;
X0 = X3 ^ t11;
X2 = (t3 & t11) ^ (X1 ^ t7);
}
/**
* S5 - {15, 5, 2,11, 4,10, 9,12, 0, 3,14, 8,13, 6, 7, 1 } - 16 terms.
*/
protected void Sb5(int a, int b, int c, int d)
{
int t1 = ~a;
int t2 = a ^ b;
int t3 = a ^ d;
int t4 = c ^ t1;
int t5 = t2 | t3;
X0 = t4 ^ t5;
int t7 = d & X0;
int t8 = t2 ^ X0;
X1 = t7 ^ t8;
int t10 = t1 | X0;
int t11 = t2 | t7;
int t12 = t3 ^ t10;
X2 = t11 ^ t12;
X3 = (b ^ t7) ^ (X1 & t12);
}
/**
* InvS5 - { 8,15, 2, 9, 4, 1,13,14,11, 6, 5, 3, 7,12,10, 0 } - 16 terms.
*/
protected void Ib5(int a, int b, int c, int d)
{
int t1 = ~c;
int t2 = b & t1;
int t3 = d ^ t2;
int t4 = a & t3;
int t5 = b ^ t1;
X3 = t4 ^ t5;
int t7 = b | X3;
int t8 = a & t7;
X1 = t3 ^ t8;
int t10 = a | d;
int t11 = t1 ^ t7;
X0 = t10 ^ t11;
X2 = (b & t10) ^ (t4 | (a ^ c));
}
/**
* S6 - { 7, 2,12, 5, 8, 4, 6,11,14, 9, 1,15,13, 3,10, 0 } - 15 terms.
*/
protected void Sb6(int a, int b, int c, int d)
{
int t1 = ~a;
int t2 = a ^ d;
int t3 = b ^ t2;
int t4 = t1 | t2;
int t5 = c ^ t4;
X1 = b ^ t5;
int t7 = t2 | X1;
int t8 = d ^ t7;
int t9 = t5 & t8;
X2 = t3 ^ t9;
int t11 = t5 ^ t8;
X0 = X2 ^ t11;
X3 = (~t5) ^ (t3 & t11);
}
/**
* InvS6 - {15,10, 1,13, 5, 3, 6, 0, 4, 9,14, 7, 2,12, 8,11 } - 15 terms.
*/
protected void Ib6(int a, int b, int c, int d)
{
int t1 = ~a;
int t2 = a ^ b;
int t3 = c ^ t2;
int t4 = c | t1;
int t5 = d ^ t4;
X1 = t3 ^ t5;
int t7 = t3 & t5;
int t8 = t2 ^ t7;
int t9 = b | t8;
X3 = t5 ^ t9;
int t11 = b | X3;
X0 = t8 ^ t11;
X2 = (d & t1) ^ (t3 ^ t11);
}
/**
* S7 - { 1,13,15, 0,14, 8, 2,11, 7, 4,12,10, 9, 3, 5, 6 } - 16 terms.
*/
protected void Sb7(int a, int b, int c, int d)
{
int t1 = b ^ c;
int t2 = c & t1;
int t3 = d ^ t2;
int t4 = a ^ t3;
int t5 = d | t1;
int t6 = t4 & t5;
X1 = b ^ t6;
int t8 = t3 | X1;
int t9 = a & t4;
X3 = t1 ^ t9;
int t11 = t4 ^ t8;
int t12 = X3 & t11;
X2 = t3 ^ t12;
X0 = (~t11) ^ (X3 & X2);
}
/**
* InvS7 - { 3, 0, 6,13, 9,14,15, 8, 5,12,11, 7,10, 1, 4, 2 } - 17 terms.
*/
protected void Ib7(int a, int b, int c, int d)
{
int t3 = c | (a & b);
int t4 = d & (a | b);
X3 = t3 ^ t4;
int t6 = ~d;
int t7 = b ^ t4;
int t9 = t7 | (X3 ^ t6);
X1 = a ^ t9;
X0 = (c ^ t7) ^ (d | X1);
X2 = (t3 ^ X1) ^ (X0 ^ (a & X3));
}
/**
* Apply the linear transformation to the register set.
*/
protected void LT()
{
int x0 = Integers.RotateLeft(X0, 13);
int x2 = Integers.RotateLeft(X2, 3);
int x1 = X1 ^ x0 ^ x2;
int x3 = X3 ^ x2 ^ x0 << 3;
X1 = Integers.RotateLeft(x1, 1);
X3 = Integers.RotateLeft(x3, 7);
X0 = Integers.RotateLeft(x0 ^ X1 ^ X3, 5);
X2 = Integers.RotateLeft(x2 ^ X3 ^ (X1 << 7), 22);
}
/**
* Apply the inverse of the linear transformation to the register set.
*/
protected void InverseLT()
{
int x2 = Integers.RotateRight(X2, 22) ^ X3 ^ (X1 << 7);
int x0 = Integers.RotateRight(X0, 5) ^ X1 ^ X3;
int x3 = Integers.RotateRight(X3, 7);
int x1 = Integers.RotateRight(X1, 1);
X3 = x3 ^ x2 ^ x0 << 3;
X1 = x1 ^ x0 ^ x2;
X2 = Integers.RotateRight(x2, 3);
X0 = Integers.RotateRight(x0, 13);
}
internal abstract int[] MakeWorkingKey(byte[] key);
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || UNITY_2021_2_OR_NEWER
internal abstract void EncryptBlock(ReadOnlySpan<byte> input, Span<byte> output);
internal abstract void DecryptBlock(ReadOnlySpan<byte> input, Span<byte> output);
#else
internal abstract void EncryptBlock(byte[] input, int inOff, byte[] output, int outOff);
internal abstract void DecryptBlock(byte[] input, int inOff, byte[] output, int outOff);
#endif
}
}
#pragma warning restore
#endif

View File

@ -0,0 +1,18 @@
fileFormatVersion: 2
guid: 9268488c378289645a98f18bb453e7f8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 267636
packageName: Best HTTP
packageVersion: 3.0.17
assetPath: Packages/com.tivadar.best.http/Runtime/3rdParty/BouncyCastle/crypto/engines/SerpentEngineBase.cs
uploadId: 783279

Some files were not shown because too many files have changed in this diff Show More