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

Dstu7624Mac

public class Dstu7624Mac : IMac
using Org.BouncyCastle.Crypto.Engines; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Utilities; using System; namespace Org.BouncyCastle.Crypto.Macs { public class Dstu7624Mac : IMac { private int macSize; private Dstu7624Engine engine; private int blockSize; private byte[] c; private byte[] cTemp; private byte[] kDelta; private byte[] buf; private int bufOff; public string AlgorithmName => "Dstu7624Mac"; public Dstu7624Mac(int blockSizeBits, int q) { engine = new Dstu7624Engine(blockSizeBits); blockSize = blockSizeBits / 8; macSize = q / 8; c = new byte[blockSize]; cTemp = new byte[blockSize]; kDelta = new byte[blockSize]; buf = new byte[blockSize]; } public void Init(ICipherParameters parameters) { if (parameters is KeyParameter) { engine.Init(true, (KeyParameter)parameters); engine.ProcessBlock(kDelta, 0, kDelta, 0); return; } throw new ArgumentException("invalid parameter passed to Dstu7624Mac init - " + Platform.GetTypeName(parameters)); } public int GetMacSize() { return macSize; } public void Update(byte input) { if (bufOff == buf.Length) { ProcessBlock(buf); bufOff = 0; } buf[bufOff++] = input; } public void BlockUpdate(byte[] input, int inOff, int len) { if (len < 0) throw new ArgumentException("Can't have a negative input length!"); BlockUpdate(input.AsSpan(inOff, len)); } public void BlockUpdate(ReadOnlySpan<byte> input) { int num = engine.GetBlockSize(); int num2 = num - bufOff; if (input.Length > num2) { input.Slice(0, num2).CopyTo(buf.AsSpan(bufOff)); ProcessBlock(buf); bufOff = 0; int num3 = num2; input = input.Slice(num3, input.Length - num3); while (input.Length > num) { ProcessBlock(input); num3 = num; input = input.Slice(num3, input.Length - num3); } } input.CopyTo(buf.AsSpan(bufOff)); bufOff += input.Length; } private void ProcessBlock(ReadOnlySpan<byte> input) { Xor(c, input, cTemp); engine.ProcessBlock(cTemp, c); } private void Xor(ReadOnlySpan<byte> c, ReadOnlySpan<byte> input, Span<byte> xorResult) { for (int i = 0; i < blockSize; i++) { xorResult[i] = (byte)(c[i] ^ input[i]); } } private void Xor(byte[] c, int cOff, byte[] input, int inOff, byte[] xorResult) { for (int i = 0; i < blockSize; i++) { xorResult[i] = (byte)(c[i + cOff] ^ input[i + inOff]); } } public int DoFinal(byte[] output, int outOff) { if (bufOff % buf.Length != 0) throw new DataLengthException("Input must be a multiple of blocksize"); Check.OutputLength(output, outOff, macSize, "output buffer too short"); Xor(c, 0, buf, 0, cTemp); Xor(cTemp, 0, kDelta, 0, c); engine.ProcessBlock(c, 0, c, 0); Array.Copy(c, 0, output, outOff, macSize); return macSize; } public int DoFinal(Span<byte> output) { if (bufOff % buf.Length != 0) throw new DataLengthException("Input must be a multiple of blocksize"); Check.OutputLength(output, macSize, "output buffer too short"); Xor(c, 0, buf, 0, cTemp); Xor(cTemp, 0, kDelta, 0, c); engine.ProcessBlock(c, c); c.AsSpan(0, macSize).CopyTo(output); return macSize; } public void Reset() { Arrays.Fill(c, 0); Arrays.Fill(cTemp, 0); Arrays.Fill(kDelta, 0); Arrays.Fill(buf, 0); engine.ProcessBlock(kDelta, 0, kDelta, 0); bufOff = 0; } } }