SerpentEngineBase
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);
}
}