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

GF12

struct GF12 : GF
using Org.BouncyCastle.Math.Raw; using System.Runtime.InteropServices; namespace Org.BouncyCastle.Pqc.Crypto.Cmce { [StructLayout(LayoutKind.Sequential, Size = 1)] internal struct GF12 : GF { public void GFMulPoly(int length, int[] poly, ushort[] output, ushort[] left, ushort[] right, uint[] temp) { temp[0] = GFMulExt(left[0], right[0]); for (int i = 1; i < length; i++) { temp[i + i - 1] = 0; ushort num = left[i]; ushort num2 = right[i]; for (int j = 0; j < i; j++) { temp[i + j] ^= GFMulExtPar(num, right[j], left[j], num2); } temp[i + i] = GFMulExt(num, num2); } for (int num3 = (length - 1) * 2; num3 >= length; num3--) { uint num4 = temp[num3]; for (int k = 0; k < poly.Length - 1; k++) { temp[num3 - length + poly[k]] ^= num4; } temp[num3 - length] ^= num4 << 1; } for (int l = 0; l < length; l++) { output[l] = GFReduce(temp[l]); } } public void GFSqrPoly(int length, int[] poly, ushort[] output, ushort[] input, uint[] temp) { temp[0] = GFSqExt(input[0]); for (int i = 1; i < length; i++) { temp[i + i - 1] = 0; temp[i + i] = GFSqExt(input[i]); } for (int num = (length - 1) * 2; num >= length; num--) { uint num2 = temp[num]; for (int j = 0; j < poly.Length - 1; j++) { temp[num - length + poly[j]] ^= num2; } temp[num - length] ^= num2 << 1; } for (int k = 0; k < length; k++) { output[k] = GFReduce(temp[k]); } } public ushort GFFrac(ushort den, ushort num) { return GFMul(GFInv(den), num); } public ushort GFInv(ushort input) { ushort input2 = input; input2 = GFSq(input2); ushort num = GFMul(input2, input); input2 = GFSq(num); input2 = GFSq(input2); ushort num2 = GFMul(input2, num); input2 = GFSq(num2); input2 = GFSq(input2); input2 = GFSq(input2); input2 = GFSq(input2); input2 = GFMul(input2, num2); input2 = GFSq(input2); input2 = GFSq(input2); input2 = GFMul(input2, num); input2 = GFSq(input2); input2 = GFMul(input2, input); return GFSq(input2); } public ushort GFIsZero(ushort a) { return (ushort)(a - 1 >> 31); } public ushort GFMul(ushort left, ushort right) { int num = left * (right & 1); for (int i = 1; i < 12; i++) { num ^= left * (right & (1 << i)); } return GFReduce((uint)num); } public uint GFMulExt(ushort left, ushort right) { int num = left * (right & 1); for (int i = 1; i < 12; i++) { num ^= left * (right & (1 << i)); } return (uint)num; } private uint GFMulExtPar(ushort left0, ushort right0, ushort left1, ushort right1) { int num = left0 * (right0 & 1); int num2 = left1 * (right1 & 1); for (int i = 1; i < 12; i++) { num ^= left0 * (right0 & (1 << i)); num2 ^= left1 * (right1 & (1 << i)); } return (uint)(num ^ num2); } public ushort GFReduce(uint x) { uint num = x & 4095; uint num2 = x >> 12; uint num3 = (x & 2093056) >> 9; uint num4 = (x & 14680064) >> 18; uint num5 = x >> 21; return (ushort)(num ^ num2 ^ num3 ^ num4 ^ num5); } public ushort GFSq(ushort input) { uint x = Interleave.Expand16to32(input); return GFReduce(x); } public uint GFSqExt(ushort input) { return Interleave.Expand16to32(input); } } }