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

HarakaBase

public abstract class HarakaBase : IDigest
using Org.BouncyCastle.Utilities; using System; namespace Org.BouncyCastle.Crypto.Digests { public abstract class HarakaBase : IDigest { internal static readonly int DIGEST_SIZE = 32; internal static readonly byte[][] RC = new byte[40][] { new byte[16] { 157, 123, 129, 117, 240, 254, 197, 178, 10, 192, 32, 230, 76, 112, 132, 6 }, new byte[16] { 23, 247, 8, 47, 164, 107, 15, 100, 107, 160, 243, 136, 225, 180, 102, 139 }, new byte[16] { 20, 145, 2, 159, 96, 157, 2, 207, 152, 132, 242, 83, 45, 222, 2, 52 }, new byte[16] { 121, 79, 91, 253, 175, 188, 243, 187, 8, 79, 123, 46, 230, 234, 214, 14 }, new byte[16] { 68, 112, 57, 190, 28, 205, 238, 121, 139, 68, 114, 72, 203, 176, 207, 203 }, new byte[16] { 123, 5, 138, 43, 237, 53, 83, 141, 183, 50, 144, 110, 238, 205, 234, 126 }, new byte[16] { 27, 239, 79, 218, 97, 39, 65, 226, 208, 124, 46, 94, 67, 143, 194, 103 }, new byte[16] { 59, 11, 199, 31, 226, 253, 95, 103, 7, 204, 202, 175, 176, 217, 36, 41 }, new byte[16] { 238, 101, 212, 185, 202, 143, 219, 236, 233, 127, 134, 230, 241, 99, 77, 171 }, new byte[16] { 51, 126, 3, 173, 79, 64, 42, 91, 100, 205, 183, 212, 132, 191, 48, 28 }, new byte[16] { 0, 152, 246, 141, 46, 139, 2, 105, 191, 35, 23, 148, 185, 11, 204, 178 }, new byte[16] { 138, 45, 157, 92, 200, 158, 170, 74, 114, 85, 111, 222, 166, 120, 4, 250 }, new byte[16] { 212, 159, 18, 41, 46, 79, 250, 14, 18, 42, 119, 107, 43, 159, 180, 223 }, new byte[16] { 238, 18, 106, 187, 174, 17, 214, 50, 54, 162, 73, 244, 68, 3, 161, 30 }, new byte[16] { 166, 236, 168, 156, 201, 0, 150, 95, 132, 0, 5, 75, 136, 73, 4, 175 }, new byte[16] { 236, 147, 229, 39, 227, 199, 162, 120, 79, 156, 25, 157, 216, 94, 2, 33 }, new byte[16] { 115, 1, 212, 130, 205, 46, 40, 185, 183, 201, 89, 167, 248, 170, 58, 191 }, new byte[16] { 107, 125, 48, 16, 217, 239, 242, 55, 23, 176, 134, 97, 13, 112, 96, 98 }, new byte[16] { 198, 154, 252, 246, 83, 145, 194, 129, 67, 4, 48, 33, 194, 69, 202, 90 }, new byte[16] { 58, 148, 209, 54, 232, 146, 175, 44, 187, 104, 107, 34, 60, 151, 35, 146 }, new byte[16] { 180, 113, 16, 229, 88, 185, 186, 108, 235, 134, 88, 34, 56, 146, 191, 211 }, new byte[16] { 141, 18, 225, 36, 221, 253, 61, 147, 119, 198, 240, 174, 229, 60, 134, 219 }, new byte[16] { 177, 18, 34, 203, 227, 141, 228, 131, 156, 160, 235, byte.MaxValue, 104, 98, 96, 187 }, new byte[16] { 125, 247, 43, 199, 78, 26, 185, 45, 156, 209, 228, 226, 220, 211, 75, 115 }, new byte[16] { 78, 146, 179, 44, 196, 21, 20, 75, 67, 27, 48, 97, 195, 71, 187, 67 }, new byte[16] { 153, 104, 235, 22, 221, 49, 178, 3, 246, 239, 7, 231, 168, 117, 167, 219 }, new byte[16] { 44, 71, 202, 126, 2, 35, 94, 142, 119, 89, 117, 60, 75, 97, 243, 109 }, new byte[16] { 249, 23, 134, 184, 185, 229, 27, 109, 119, 125, 222, 214, 23, 90, 167, 205 }, new byte[16] { 93, 238, 70, 169, 157, 6, 108, 157, 170, 233, 168, 107, 240, 67, 107, 236 }, new byte[16] { 193, 39, 243, 59, 89, 17, 83, 162, 43, 51, 87, 249, 80, 105, 30, 203 }, new byte[16] { 217, 208, 14, 96, 83, 3, 237, 228, 156, 97, 218, 0, 117, 12, 238, 44 }, new byte[16] { 80, 163, 164, 99, 188, 186, 187, 128, 171, 12, 233, 150, 161, 165, 177, 240 }, new byte[16] { 57, 202, 141, 147, 48, 222, 13, 171, 136, 41, 150, 94, 2, 177, 61, 174 }, new byte[16] { 66, 180, 117, 46, 168, 243, 20, 136, 11, 164, 84, 213, 56, 143, 187, 23 }, new byte[16] { 246, 22, 10, 54, 121, 183, 182, 174, 215, 127, 66, 95, 91, 138, 187, 52 }, new byte[16] { 222, 175, 186, byte.MaxValue, 24, 89, 206, 67, 56, 84, 229, 203, 65, 82, 246, 38 }, new byte[16] { 120, 201, 158, 131, 247, 156, 202, 162, 106, 2, 243, 185, 84, 154, 233, 76 }, new byte[16] { 53, 18, 144, 34, 40, 110, 192, 64, 190, 247, 223, 27, 26, 165, 81, 174 }, new byte[16] { 207, 89, 166, 72, 15, 188, 115, 193, 43, 210, 126, 186, 60, 97, 193, 160 }, new byte[16] { 161, 157, 197, 233, 253, 189, 214, 74, 136, 130, 40, 2, 3, 204, 106, 117 } }; private static readonly byte[,] S = new byte[16, 16] { { 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, byte.MaxValue, 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 } }; public abstract string AlgorithmName { get; } private static byte SBox(byte x) { return S[(uint)x >> 4, x & 15]; } private static byte[] SubBytes(byte[] s) { byte[] array = new byte[s.Length]; for (int i = 0; i < 16; i++) { array[i] = SBox(s[i]); } return array; } private static byte[] ShiftRows(byte[] s) { return new byte[16] { s[0], s[5], s[10], s[15], s[4], s[9], s[14], s[3], s[8], s[13], s[2], s[7], s[12], s[1], s[6], s[11] }; } internal static byte[] AesEnc(byte[] s, byte[] rk) { s = SubBytes(s); s = ShiftRows(s); s = MixColumns(s); Bytes.XorTo(16, rk, s); return s; } private static byte MulX(byte p) { return (byte)(((p & 127) << 1) ^ (((uint)p >> 7) * 27)); } private static byte[] MixColumns(byte[] s) { byte[] array = new byte[s.Length]; int num = 0; for (int i = 0; i < 4; i++) { int num2 = i << 2; array[num++] = (byte)(MulX(s[num2]) ^ MulX(s[num2 + 1]) ^ s[num2 + 1] ^ s[num2 + 2] ^ s[num2 + 3]); array[num++] = (byte)(s[num2] ^ MulX(s[num2 + 1]) ^ MulX(s[num2 + 2]) ^ s[num2 + 2] ^ s[num2 + 3]); array[num++] = (byte)(s[num2] ^ s[num2 + 1] ^ MulX(s[num2 + 2]) ^ MulX(s[num2 + 3]) ^ s[num2 + 3]); array[num++] = (byte)(MulX(s[num2]) ^ s[num2] ^ s[num2 + 1] ^ s[num2 + 2] ^ MulX(s[num2 + 3])); } return array; } public int GetDigestSize() { return DIGEST_SIZE; } public abstract int GetByteLength(); public abstract void Update(byte input); public abstract void BlockUpdate(byte[] input, int inOff, int length); public abstract int DoFinal(byte[] output, int outOff); public abstract void Reset(); public abstract void BlockUpdate(ReadOnlySpan<byte> input); public abstract int DoFinal(Span<byte> output); } }