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

FrodoMatrixGenerator

public abstract class FrodoMatrixGenerator
using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Digests; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto.Utilities; using System; namespace Org.BouncyCastle.Pqc.Crypto.Frodo { public abstract class FrodoMatrixGenerator { internal class Shake128MatrixGenerator : FrodoMatrixGenerator { public Shake128MatrixGenerator(int n, int q) : base(n, q) { } internal override short[] GenMatrix(byte[] seedA) { short[] array = new short[n * n]; byte[] array2 = new byte[16 * n / 8]; byte[] array3 = new byte[2 + seedA.Length]; Array.Copy(seedA, 0, array3, 2, seedA.Length); uint num = (uint)((q - 1 << 16) | (ushort)(q - 1)); IXof xof = new ShakeDigest(128); for (ushort num2 = 0; num2 < n; num2 = (ushort)(num2 + 1)) { Pack.UInt16_To_LE(num2, array3); xof.BlockUpdate(array3, 0, array3.Length); xof.OutputFinal(array2, 0, array2.Length); for (ushort num3 = 0; num3 < n; num3 = (ushort)(num3 + 8)) { uint num4 = Pack.LE_To_UInt32(array2, 2 * num3) & num; uint num5 = Pack.LE_To_UInt32(array2, 2 * num3 + 4) & num; uint num6 = Pack.LE_To_UInt32(array2, 2 * num3 + 8) & num; uint num7 = Pack.LE_To_UInt32(array2, 2 * num3 + 12) & num; array[num2 * n + num3] = (short)num4; array[num2 * n + num3 + 1] = (short)(num4 >> 16); array[num2 * n + num3 + 2] = (short)num5; array[num2 * n + num3 + 3] = (short)(num5 >> 16); array[num2 * n + num3 + 4] = (short)num6; array[num2 * n + num3 + 5] = (short)(num6 >> 16); array[num2 * n + num3 + 6] = (short)num7; array[num2 * n + num3 + 7] = (short)(num7 >> 16); } } return array; } } internal class Aes128MatrixGenerator : FrodoMatrixGenerator { public Aes128MatrixGenerator(int n, int q) : base(n, q) { } internal override short[] GenMatrix(byte[] seedA) { short[] array = new short[n * n]; byte[] array2 = new byte[16]; byte[] array3 = new byte[16]; uint num = (uint)((q - 1 << 16) | (ushort)(q - 1)); IBlockCipher blockCipher = AesUtilities.CreateEngine(); blockCipher.Init(true, new KeyParameter(seedA)); for (int i = 0; i < n; i++) { Pack.UInt16_To_LE((ushort)i, array2, 0); for (int j = 0; j < n; j += 8) { Pack.UInt16_To_LE((ushort)j, array2, 2); blockCipher.ProcessBlock(array2, 0, array3, 0); uint num2 = Pack.LE_To_UInt32(array3, 0) & num; uint num3 = Pack.LE_To_UInt32(array3, 4) & num; uint num4 = Pack.LE_To_UInt32(array3, 8) & num; uint num5 = Pack.LE_To_UInt32(array3, 12) & num; array[i * n + j] = (short)num2; array[i * n + j + 1] = (short)(num2 >> 16); array[i * n + j + 2] = (short)num3; array[i * n + j + 3] = (short)(num3 >> 16); array[i * n + j + 4] = (short)num4; array[i * n + j + 5] = (short)(num4 >> 16); array[i * n + j + 6] = (short)num5; array[i * n + j + 7] = (short)(num5 >> 16); } } return array; } } private int n; private int q; public FrodoMatrixGenerator(int n, int q) { this.n = n; this.q = q; } internal abstract short[] GenMatrix(byte[] seedA); } }