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

SicBlockCipher

using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Utilities; using System; namespace Org.BouncyCastle.Crypto.Modes { public class SicBlockCipher : IBlockCipherMode, IBlockCipher { private readonly IBlockCipher cipher; private readonly int blockSize; private readonly byte[] counter; private readonly byte[] counterOut; private byte[] IV; public IBlockCipher UnderlyingCipher => cipher; public virtual string AlgorithmName => cipher.AlgorithmName + "/SIC"; public virtual bool IsPartialBlockOkay => true; public SicBlockCipher(IBlockCipher cipher) { this.cipher = cipher; blockSize = cipher.GetBlockSize(); counter = new byte[blockSize]; counterOut = new byte[blockSize]; IV = new byte[blockSize]; } public virtual void Init(bool forEncryption, ICipherParameters parameters) { ParametersWithIV parametersWithIV = parameters as ParametersWithIV; if (parametersWithIV == null) throw new ArgumentException("CTR/SIC mode requires ParametersWithIV", "parameters"); IV = Arrays.Clone(parametersWithIV.GetIV()); int num; if (blockSize < IV.Length) { num = blockSize; throw new ArgumentException("CTR/SIC mode requires IV no greater than: " + num.ToString() + " bytes."); } int num2 = System.Math.Min(8, blockSize / 2); if (blockSize - IV.Length > num2) { num = blockSize - num2; throw new ArgumentException("CTR/SIC mode requires IV of at least: " + num.ToString() + " bytes."); } Reset(); if (parametersWithIV.Parameters != null) cipher.Init(true, parametersWithIV.Parameters); } public virtual int GetBlockSize() { return cipher.GetBlockSize(); } public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff) { cipher.ProcessBlock(counter, 0, counterOut, 0); for (int i = 0; i < counterOut.Length; i++) { output[outOff + i] = (byte)(counterOut[i] ^ input[inOff + i]); } int num = counter.Length; while (--num >= 0 && ++counter[num] == 0) { } return counter.Length; } public virtual void Reset() { Arrays.Fill(counter, 0); Array.Copy(IV, 0, counter, 0, IV.Length); } } }