init commit
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
using System;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Engines;
|
||||
|
||||
public class VmpcEngine : IStreamCipher
|
||||
{
|
||||
protected byte n = 0;
|
||||
|
||||
protected byte[] P = null;
|
||||
|
||||
protected byte s = 0;
|
||||
|
||||
protected byte[] workingIV;
|
||||
|
||||
protected byte[] workingKey;
|
||||
|
||||
public virtual string AlgorithmName => "VMPC";
|
||||
|
||||
public virtual void Init(bool forEncryption, ICipherParameters parameters)
|
||||
{
|
||||
if (!(parameters is ParametersWithIV))
|
||||
{
|
||||
throw new ArgumentException("VMPC Init parameters must include an IV");
|
||||
}
|
||||
ParametersWithIV parametersWithIV = (ParametersWithIV)parameters;
|
||||
if (!(parametersWithIV.Parameters is KeyParameter))
|
||||
{
|
||||
throw new ArgumentException("VMPC Init parameters must include a key");
|
||||
}
|
||||
KeyParameter keyParameter = (KeyParameter)parametersWithIV.Parameters;
|
||||
workingIV = parametersWithIV.GetIV();
|
||||
if (workingIV == null || workingIV.Length < 1 || workingIV.Length > 768)
|
||||
{
|
||||
throw new ArgumentException("VMPC requires 1 to 768 bytes of IV");
|
||||
}
|
||||
workingKey = keyParameter.GetKey();
|
||||
InitKey(workingKey, workingIV);
|
||||
}
|
||||
|
||||
protected virtual void InitKey(byte[] keyBytes, byte[] ivBytes)
|
||||
{
|
||||
s = 0;
|
||||
P = new byte[256];
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
P[i] = (byte)i;
|
||||
}
|
||||
for (int j = 0; j < 768; j++)
|
||||
{
|
||||
s = P[(s + P[j & 0xFF] + keyBytes[j % keyBytes.Length]) & 0xFF];
|
||||
byte b = P[j & 0xFF];
|
||||
P[j & 0xFF] = P[s & 0xFF];
|
||||
P[s & 0xFF] = b;
|
||||
}
|
||||
for (int k = 0; k < 768; k++)
|
||||
{
|
||||
s = P[(s + P[k & 0xFF] + ivBytes[k % ivBytes.Length]) & 0xFF];
|
||||
byte b2 = P[k & 0xFF];
|
||||
P[k & 0xFF] = P[s & 0xFF];
|
||||
P[s & 0xFF] = b2;
|
||||
}
|
||||
n = 0;
|
||||
}
|
||||
|
||||
public virtual void ProcessBytes(byte[] input, int inOff, int len, byte[] output, int outOff)
|
||||
{
|
||||
Check.DataLength(input, inOff, len, "input buffer too short");
|
||||
Check.OutputLength(output, outOff, len, "output buffer too short");
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
s = P[(s + P[n & 0xFF]) & 0xFF];
|
||||
byte b = P[(P[P[s & 0xFF] & 0xFF] + 1) & 0xFF];
|
||||
byte b2 = P[n & 0xFF];
|
||||
P[n & 0xFF] = P[s & 0xFF];
|
||||
P[s & 0xFF] = b2;
|
||||
n = (byte)((n + 1) & 0xFF);
|
||||
output[i + outOff] = (byte)(input[i + inOff] ^ b);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
InitKey(workingKey, workingIV);
|
||||
}
|
||||
|
||||
public virtual byte ReturnByte(byte input)
|
||||
{
|
||||
s = P[(s + P[n & 0xFF]) & 0xFF];
|
||||
byte b = P[(P[P[s & 0xFF] & 0xFF] + 1) & 0xFF];
|
||||
byte b2 = P[n & 0xFF];
|
||||
P[n & 0xFF] = P[s & 0xFF];
|
||||
P[s & 0xFF] = b2;
|
||||
n = (byte)((n + 1) & 0xFF);
|
||||
return (byte)(input ^ b);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user