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

SerpentEngineBase

public abstract class SerpentEngineBase : IBlockCipher
using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Utilities; using System; namespace Org.BouncyCastle.Crypto.Engines { public abstract class SerpentEngineBase : IBlockCipher { protected static readonly int BlockSize = 16; internal const int ROUNDS = 32; internal const int PHI = -1640531527; protected bool encrypting; protected int[] wKey; protected int X0; protected int X1; protected int X2; protected int X3; public virtual string AlgorithmName => "Serpent"; internal SerpentEngineBase() { } public virtual void Init(bool encrypting, ICipherParameters parameters) { if (!(parameters is KeyParameter)) throw new ArgumentException("invalid parameter passed to " + AlgorithmName + " init - " + Platform.GetTypeName(parameters)); this.encrypting = encrypting; wKey = MakeWorkingKey(((KeyParameter)parameters).GetKey()); } public virtual int GetBlockSize() { return BlockSize; } public int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff) { if (wKey == null) throw new InvalidOperationException(AlgorithmName + " not initialised"); Check.DataLength(input, inOff, BlockSize, "input buffer too short"); Check.OutputLength(output, outOff, BlockSize, "output buffer too short"); if (encrypting) EncryptBlock(input.AsSpan(inOff), output.AsSpan(outOff)); else DecryptBlock(input.AsSpan(inOff), output.AsSpan(outOff)); return BlockSize; } public int ProcessBlock(ReadOnlySpan<byte> input, Span<byte> output) { if (wKey == null) throw new InvalidOperationException(AlgorithmName + " not initialised"); Check.DataLength(input, BlockSize, "input buffer too short"); Check.OutputLength(output, BlockSize, "output buffer too short"); if (encrypting) EncryptBlock(input, output); else DecryptBlock(input, output); return BlockSize; } protected void Sb0(int a, int b, int c, int d) { int num = a ^ d; int num2 = c ^ num; int num3 = b ^ num2; X3 = ((a & d) ^ num3); int num4 = a ^ (b & num); X2 = (num3 ^ (c | num4)); int num5 = X3 & (num2 ^ num4); X1 = (~num2 ^ num5); X0 = (num5 ^ ~num4); } protected void Ib0(int a, int b, int c, int d) { int num = ~a; int num2 = a ^ b; int num3 = d ^ (num | num2); int num4 = c ^ num3; X2 = (num2 ^ num4); int num5 = num ^ (d & num2); X1 = (num3 ^ (X2 & num5)); X3 = ((a & num3) ^ (num4 | X1)); X0 = (X3 ^ (num4 ^ num5)); } protected void Sb1(int a, int b, int c, int d) { int num = b ^ ~a; int num2 = c ^ (a | num); X2 = (d ^ num2); int num3 = b ^ (d | num); int num4 = num ^ X2; X3 = (num4 ^ (num2 & num3)); int num5 = num2 ^ num3; X1 = (X3 ^ num5); X0 = (num2 ^ (num4 & num5)); } protected void Ib1(int a, int b, int c, int d) { int num = b ^ d; int num2 = a ^ (b & num); int num3 = num ^ num2; X3 = (c ^ num3); int num4 = b ^ (num & num2); int num5 = X3 | num4; X1 = (num2 ^ num5); int num6 = ~X1; int num7 = X3 ^ num4; X0 = (num6 ^ num7); X2 = (num3 ^ (num6 | num7)); } protected void Sb2(int a, int b, int c, int d) { int num = ~a; int num2 = b ^ d; int num3 = c & num; X0 = (num2 ^ num3); int num4 = c ^ num; int num5 = c ^ X0; int num6 = b & num5; X3 = (num4 ^ num6); X2 = (a ^ ((d | num6) & (X0 | num4))); X1 = (num2 ^ X3 ^ (X2 ^ (d | num))); } protected void Ib2(int a, int b, int c, int d) { int num = b ^ d; int num2 = ~num; int num3 = a ^ c; int num4 = c ^ num; int num5 = b & num4; X0 = (num3 ^ num5); int num6 = a | num2; int num7 = d ^ num6; int num8 = num3 | num7; X3 = (num ^ num8); int num9 = ~num4; int num10 = X0 | X3; X1 = (num9 ^ num10); X2 = ((d & num9) ^ (num3 ^ num10)); } protected void Sb3(int a, int b, int c, int d) { int num = a ^ b; int num2 = a & c; int num3 = a | d; int num4 = c ^ d; int num5 = num & num3; int num6 = num2 | num5; X2 = (num4 ^ num6); int num7 = b ^ num3; int num8 = num6 ^ num7; int num9 = num4 & num8; X0 = (num ^ num9); int num10 = X2 & X0; X1 = (num8 ^ num10); X3 = ((b | d) ^ (num4 ^ num10)); } protected void Ib3(int a, int b, int c, int d) { int num = a | b; int num2 = b ^ c; int num3 = b & num2; int num4 = a ^ num3; int num5 = c ^ num4; int num6 = d | num4; X0 = (num2 ^ num6); int num7 = num2 | num6; int num8 = d ^ num7; X2 = (num5 ^ num8); int num9 = num ^ num8; int num10 = X0 & num9; X3 = (num4 ^ num10); X1 = (X3 ^ (X0 ^ num9)); } protected void Sb4(int a, int b, int c, int d) { int num = a ^ d; int num2 = d & num; int num3 = c ^ num2; int num4 = b | num3; X3 = (num ^ num4); int num5 = ~b; int num6 = num | num5; X0 = (num3 ^ num6); int num7 = a & X0; int num8 = num ^ num5; int num9 = num4 & num8; X2 = (num7 ^ num9); X1 = (a ^ num3 ^ (num8 & X2)); } protected void Ib4(int a, int b, int c, int d) { int num = c | d; int num2 = a & num; int num3 = b ^ num2; int num4 = a & num3; int num5 = c ^ num4; X1 = (d ^ num5); int num6 = ~a; int num7 = num5 & X1; X3 = (num3 ^ num7); int num8 = X1 | num6; int num9 = d ^ num8; X0 = (X3 ^ num9); X2 = ((num3 & num9) ^ (X1 ^ num6)); } protected void Sb5(int a, int b, int c, int d) { int num = ~a; int num2 = a ^ b; int num3 = a ^ d; int num4 = c ^ num; int num5 = num2 | num3; X0 = (num4 ^ num5); int num6 = d & X0; int num7 = num2 ^ X0; X1 = (num6 ^ num7); int num8 = num | X0; int num9 = num2 | num6; int num10 = num3 ^ num8; X2 = (num9 ^ num10); X3 = (b ^ num6 ^ (X1 & num10)); } protected void Ib5(int a, int b, int c, int d) { int num = ~c; int num2 = b & num; int num3 = d ^ num2; int num4 = a & num3; int num5 = b ^ num; X3 = (num4 ^ num5); int num6 = b | X3; int num7 = a & num6; X1 = (num3 ^ num7); int num8 = a | d; int num9 = num ^ num6; X0 = (num8 ^ num9); X2 = ((b & num8) ^ (num4 | (a ^ c))); } protected void Sb6(int a, int b, int c, int d) { int num = ~a; int num2 = a ^ d; int num3 = b ^ num2; int num4 = num | num2; int num5 = c ^ num4; X1 = (b ^ num5); int num6 = num2 | X1; int num7 = d ^ num6; int num8 = num5 & num7; X2 = (num3 ^ num8); int num9 = num5 ^ num7; X0 = (X2 ^ num9); X3 = (~num5 ^ (num3 & num9)); } protected void Ib6(int a, int b, int c, int d) { int num = ~a; int num2 = a ^ b; int num3 = c ^ num2; int num4 = c | num; int num5 = d ^ num4; X1 = (num3 ^ num5); int num6 = num3 & num5; int num7 = num2 ^ num6; int num8 = b | num7; X3 = (num5 ^ num8); int num9 = b | X3; X0 = (num7 ^ num9); X2 = ((d & num) ^ (num3 ^ num9)); } protected void Sb7(int a, int b, int c, int d) { int num = b ^ c; int num2 = c & num; int num3 = d ^ num2; int num4 = a ^ num3; int num5 = d | num; int num6 = num4 & num5; X1 = (b ^ num6); int num7 = num3 | X1; int num8 = a & num4; X3 = (num ^ num8); int num9 = num4 ^ num7; int num10 = X3 & num9; X2 = (num3 ^ num10); X0 = (~num9 ^ (X3 & X2)); } protected void Ib7(int a, int b, int c, int d) { int num = c | (a & b); int num2 = d & (a | b); X3 = (num ^ num2); int num3 = ~d; int num4 = b ^ num2; int num5 = num4 | (X3 ^ num3); X1 = (a ^ num5); X0 = (c ^ num4 ^ (d | X1)); X2 = (num ^ X1 ^ (X0 ^ (a & X3))); } protected void LT() { int num = Integers.RotateLeft(X0, 13); int num2 = Integers.RotateLeft(X2, 3); int i = X1 ^ num ^ num2; int i2 = X3 ^ num2 ^ (num << 3); X1 = Integers.RotateLeft(i, 1); X3 = Integers.RotateLeft(i2, 7); X0 = Integers.RotateLeft(num ^ X1 ^ X3, 5); X2 = Integers.RotateLeft(num2 ^ X3 ^ (X1 << 7), 22); } protected void InverseLT() { int num = Integers.RotateRight(X2, 22) ^ X3 ^ (X1 << 7); int num2 = Integers.RotateRight(X0, 5) ^ X1 ^ X3; int num3 = Integers.RotateRight(X3, 7); int num4 = Integers.RotateRight(X1, 1); X3 = (num3 ^ num ^ (num2 << 3)); X1 = (num4 ^ num2 ^ num); X2 = Integers.RotateRight(num, 3); X0 = Integers.RotateRight(num2, 13); } internal abstract int[] MakeWorkingKey(byte[] key); internal abstract void EncryptBlock(ReadOnlySpan<byte> input, Span<byte> output); internal abstract void DecryptBlock(ReadOnlySpan<byte> input, Span<byte> output); } }