<PackageReference Include="BouncyCastle.Cryptography" Version="2.3.1" />

CamelliaEngine

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