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

RC532Engine

public class RC532Engine : IBlockCipher
using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto.Utilities; using Org.BouncyCastle.Utilities; using System; namespace Org.BouncyCastle.Crypto.Engines { public class RC532Engine : IBlockCipher { private int _noRounds; private int[] _S; private static readonly int P32 = -1209970333; private static readonly int Q32 = -1640531527; private bool forEncryption; public virtual string AlgorithmName => "RC5-32"; public RC532Engine() { _noRounds = 12; } public virtual int GetBlockSize() { return 8; } public virtual void Init(bool forEncryption, ICipherParameters parameters) { RC5Parameters rC5Parameters = parameters as RC5Parameters; if (rC5Parameters != null) { _noRounds = rC5Parameters.Rounds; SetKey(rC5Parameters.GetKey()); } else { KeyParameter keyParameter = parameters as KeyParameter; if (keyParameter == null) throw new ArgumentException("invalid parameter passed to RC532 init - " + Platform.GetTypeName(parameters)); SetKey(keyParameter.GetKey()); } this.forEncryption = forEncryption; } public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff) { if (!forEncryption) return DecryptBlock(input, inOff, output, outOff); return EncryptBlock(input, inOff, output, outOff); } private void SetKey(byte[] key) { int[] array = new int[(key.Length + 3) / 4]; for (int i = 0; i != key.Length; i++) { array[i / 4] += (key[i] & 255) << 8 * (i % 4); } _S = new int[2 * (_noRounds + 1)]; _S[0] = P32; for (int j = 1; j < _S.Length; j++) { _S[j] = _S[j - 1] + Q32; } int num = (array.Length <= _S.Length) ? (3 * _S.Length) : (3 * array.Length); int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 0; for (int k = 0; k < num; k++) { num2 = (_S[num4] = Integers.RotateLeft(_S[num4] + num2 + num3, 3)); num3 = (array[num5] = Integers.RotateLeft(array[num5] + num2 + num3, num2 + num3)); num4 = (num4 + 1) % _S.Length; num5 = (num5 + 1) % array.Length; } } private int EncryptBlock(byte[] input, int inOff, byte[] outBytes, int outOff) { int num = (int)Pack.LE_To_UInt32(input, inOff) + _S[0]; int num2 = (int)Pack.LE_To_UInt32(input, inOff + 4) + _S[1]; for (int i = 1; i <= _noRounds; i++) { num = Integers.RotateLeft(num ^ num2, num2) + _S[2 * i]; num2 = Integers.RotateLeft(num2 ^ num, num) + _S[2 * i + 1]; } Pack.UInt32_To_LE((uint)num, outBytes, outOff); Pack.UInt32_To_LE((uint)num2, outBytes, outOff + 4); return 8; } private int DecryptBlock(byte[] input, int inOff, byte[] outBytes, int outOff) { int num = (int)Pack.LE_To_UInt32(input, inOff); int num2 = (int)Pack.LE_To_UInt32(input, inOff + 4); for (int num3 = _noRounds; num3 >= 1; num3--) { num2 = (Integers.RotateRight(num2 - _S[2 * num3 + 1], num) ^ num); num = (Integers.RotateRight(num - _S[2 * num3], num2) ^ num2); } Pack.UInt32_To_LE((uint)(num - _S[0]), outBytes, outOff); Pack.UInt32_To_LE((uint)(num2 - _S[1]), outBytes, outOff + 4); return 8; } } }