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

Symmetric

public abstract class Symmetric
using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Digests; using Org.BouncyCastle.Crypto.Modes; using Org.BouncyCastle.Crypto.Parameters; namespace Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium { public abstract class Symmetric { internal class AesSymmetric : Symmetric { private SicBlockCipher cipher; public AesSymmetric() : base(64, 64) { cipher = new SicBlockCipher(AesUtilities.CreateEngine()); } private void Aes128(byte[] output, int offset, int size) { byte[] input = new byte[size]; for (int i = 0; i < size; i += 16) { cipher.ProcessBlock(input, i + offset, output, i + offset); } } private void StreamInit(byte[] key, ushort nonce) { ParametersWithIV parameters = new ParametersWithIV(iv: new byte[12] { (byte)nonce, (byte)(nonce >> 8), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, parameters: new KeyParameter(key, 0, 32)); cipher.Init(true, parameters); } internal override void Stream128Init(byte[] seed, ushort nonce) { StreamInit(seed, nonce); } internal override void Stream256Init(byte[] seed, ushort nonce) { StreamInit(seed, nonce); } internal override void Stream128SqueezeBlocks(byte[] output, int offset, int size) { Aes128(output, offset, size); } internal override void Stream256SqueezeBlocks(byte[] output, int offset, int size) { Aes128(output, offset, size); } } internal class ShakeSymmetric : Symmetric { private ShakeDigest digest128; private ShakeDigest digest256; public ShakeSymmetric() : base(168, 136) { digest128 = new ShakeDigest(128); digest256 = new ShakeDigest(256); } private void StreamInit(ShakeDigest digest, byte[] seed, ushort nonce) { digest.Reset(); byte[] array = new byte[2] { (byte)nonce, (byte)(nonce >> 8) }; digest.BlockUpdate(seed, 0, seed.Length); digest.BlockUpdate(array, 0, array.Length); } internal override void Stream128Init(byte[] seed, ushort nonce) { StreamInit(digest128, seed, nonce); } internal override void Stream256Init(byte[] seed, ushort nonce) { StreamInit(digest256, seed, nonce); } internal override void Stream128SqueezeBlocks(byte[] output, int offset, int size) { digest128.Output(output, offset, size); } internal override void Stream256SqueezeBlocks(byte[] output, int offset, int size) { digest256.Output(output, offset, size); } } public int Stream128BlockBytes; public int Stream256BlockBytes; private Symmetric(int stream128, int stream256) { Stream128BlockBytes = stream128; Stream256BlockBytes = stream256; } internal abstract void Stream128Init(byte[] seed, ushort nonce); internal abstract void Stream256Init(byte[] seed, ushort nonce); internal abstract void Stream128SqueezeBlocks(byte[] output, int offset, int size); internal abstract void Stream256SqueezeBlocks(byte[] output, int offset, int size); } }