init commit
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Engines;
|
||||
|
||||
public class RC564Engine : IBlockCipher
|
||||
{
|
||||
private static readonly int wordSize = 64;
|
||||
|
||||
private static readonly int bytesPerWord = wordSize / 8;
|
||||
|
||||
private int _noRounds;
|
||||
|
||||
private long[] _S;
|
||||
|
||||
private static readonly long P64 = -5196783011329398165L;
|
||||
|
||||
private static readonly long Q64 = -7046029254386353131L;
|
||||
|
||||
private bool forEncryption;
|
||||
|
||||
public virtual string AlgorithmName => "RC5-64";
|
||||
|
||||
public virtual bool IsPartialBlockOkay => false;
|
||||
|
||||
public RC564Engine()
|
||||
{
|
||||
_noRounds = 12;
|
||||
}
|
||||
|
||||
public virtual int GetBlockSize()
|
||||
{
|
||||
return 2 * bytesPerWord;
|
||||
}
|
||||
|
||||
public virtual void Init(bool forEncryption, ICipherParameters parameters)
|
||||
{
|
||||
if (!typeof(RC5Parameters).IsInstanceOfType(parameters))
|
||||
{
|
||||
throw new ArgumentException("invalid parameter passed to RC564 init - " + Platform.GetTypeName(parameters));
|
||||
}
|
||||
RC5Parameters rC5Parameters = (RC5Parameters)parameters;
|
||||
this.forEncryption = forEncryption;
|
||||
_noRounds = rC5Parameters.Rounds;
|
||||
SetKey(rC5Parameters.GetKey());
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
}
|
||||
|
||||
private void SetKey(byte[] key)
|
||||
{
|
||||
long[] array = new long[(key.Length + (bytesPerWord - 1)) / bytesPerWord];
|
||||
for (int i = 0; i != key.Length; i++)
|
||||
{
|
||||
long[] array3;
|
||||
long[] array2 = (array3 = array);
|
||||
int num = i / bytesPerWord;
|
||||
nint num2 = num;
|
||||
array2[num] = array3[num2] + ((long)(key[i] & 0xFF) << 8 * (i % bytesPerWord));
|
||||
}
|
||||
_S = new long[2 * (_noRounds + 1)];
|
||||
_S[0] = P64;
|
||||
for (int j = 1; j < _S.Length; j++)
|
||||
{
|
||||
_S[j] = _S[j - 1] + Q64;
|
||||
}
|
||||
int num3 = ((array.Length <= _S.Length) ? (3 * _S.Length) : (3 * array.Length));
|
||||
long num4 = 0L;
|
||||
long num5 = 0L;
|
||||
int num6 = 0;
|
||||
int num7 = 0;
|
||||
for (int k = 0; k < num3; k++)
|
||||
{
|
||||
num4 = (_S[num6] = RotateLeft(_S[num6] + num4 + num5, 3L));
|
||||
num5 = (array[num7] = RotateLeft(array[num7] + num4 + num5, num4 + num5));
|
||||
num6 = (num6 + 1) % _S.Length;
|
||||
num7 = (num7 + 1) % array.Length;
|
||||
}
|
||||
}
|
||||
|
||||
private int EncryptBlock(byte[] input, int inOff, byte[] outBytes, int outOff)
|
||||
{
|
||||
long num = BytesToWord(input, inOff) + _S[0];
|
||||
long num2 = BytesToWord(input, inOff + bytesPerWord) + _S[1];
|
||||
for (int i = 1; i <= _noRounds; i++)
|
||||
{
|
||||
num = RotateLeft(num ^ num2, num2) + _S[2 * i];
|
||||
num2 = RotateLeft(num2 ^ num, num) + _S[2 * i + 1];
|
||||
}
|
||||
WordToBytes(num, outBytes, outOff);
|
||||
WordToBytes(num2, outBytes, outOff + bytesPerWord);
|
||||
return 2 * bytesPerWord;
|
||||
}
|
||||
|
||||
private int DecryptBlock(byte[] input, int inOff, byte[] outBytes, int outOff)
|
||||
{
|
||||
long num = BytesToWord(input, inOff);
|
||||
long num2 = BytesToWord(input, inOff + bytesPerWord);
|
||||
for (int num3 = _noRounds; num3 >= 1; num3--)
|
||||
{
|
||||
num2 = RotateRight(num2 - _S[2 * num3 + 1], num) ^ num;
|
||||
num = RotateRight(num - _S[2 * num3], num2) ^ num2;
|
||||
}
|
||||
WordToBytes(num - _S[0], outBytes, outOff);
|
||||
WordToBytes(num2 - _S[1], outBytes, outOff + bytesPerWord);
|
||||
return 2 * bytesPerWord;
|
||||
}
|
||||
|
||||
private long RotateLeft(long x, long y)
|
||||
{
|
||||
return (x << (int)(y & (wordSize - 1))) | (x >>> (int)(wordSize - (y & (wordSize - 1))));
|
||||
}
|
||||
|
||||
private long RotateRight(long x, long y)
|
||||
{
|
||||
return (x >>> (int)(y & (wordSize - 1))) | (x << (int)(wordSize - (y & (wordSize - 1))));
|
||||
}
|
||||
|
||||
private long BytesToWord(byte[] src, int srcOff)
|
||||
{
|
||||
long num = 0L;
|
||||
for (int num2 = bytesPerWord - 1; num2 >= 0; num2--)
|
||||
{
|
||||
num = (num << 8) + (src[num2 + srcOff] & 0xFF);
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
private void WordToBytes(long word, byte[] dst, int dstOff)
|
||||
{
|
||||
for (int i = 0; i < bytesPerWord; i++)
|
||||
{
|
||||
dst[i + dstOff] = (byte)word;
|
||||
word >>>= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user