diff --git a/crypto/src/crypto/engines/VMPCEngine.cs b/crypto/src/crypto/engines/VMPCEngine.cs
index f34259248..897068e1a 100644
--- a/crypto/src/crypto/engines/VMPCEngine.cs
+++ b/crypto/src/crypto/engines/VMPCEngine.cs
@@ -7,10 +7,6 @@ namespace Org.BouncyCastle.Crypto.Engines
public class VmpcEngine
: IStreamCipher
{
- /*
- * variables to hold the state of the VMPC engine during encryption and
- * decryption
- */
protected byte n = 0;
protected byte[] P = null;
protected byte s = 0;
@@ -18,10 +14,7 @@ namespace Org.BouncyCastle.Crypto.Engines
protected byte[] workingIV;
protected byte[] workingKey;
- public virtual string AlgorithmName
- {
- get { return "VMPC"; }
- }
+ public virtual string AlgorithmName => "VMPC";
/**
* initialise a VMPC cipher.
@@ -33,64 +26,41 @@ namespace Org.BouncyCastle.Crypto.Engines
* @exception ArgumentException
* if the params argument is inappropriate.
*/
- public virtual void Init(
- bool forEncryption,
- ICipherParameters parameters)
+ public virtual void Init(bool forEncryption, ICipherParameters parameters)
{
- if (!(parameters is ParametersWithIV))
+ if (!(parameters is ParametersWithIV ivParams))
throw new ArgumentException("VMPC Init parameters must include an IV");
-
- ParametersWithIV ivParams = (ParametersWithIV) parameters;
-
- if (!(ivParams.Parameters is KeyParameter))
+ if (!(ivParams.Parameters is KeyParameter key))
throw new ArgumentException("VMPC Init parameters must include a key");
- KeyParameter key = (KeyParameter)ivParams.Parameters;
-
- this.workingIV = ivParams.GetIV();
+ int keyLength = key.KeyLength;
+ if (keyLength < 16 || keyLength > 64)
+ throw new ArgumentException("VMPC requires 16 to 64 bytes of key");
- if (workingIV == null || workingIV.Length < 1 || workingIV.Length > 768)
- throw new ArgumentException("VMPC requires 1 to 768 bytes of IV");
+ int ivLength = ivParams.IVLength;
+ if (ivLength < 16 || ivLength > 64)
+ throw new ArgumentException("VMPC requires 16 to 64 bytes of IV");
this.workingKey = key.GetKey();
+ this.workingIV = ivParams.GetIV();
InitKey(this.workingKey, this.workingIV);
}
- protected virtual void InitKey(
- byte[] keyBytes,
- byte[] ivBytes)
+ protected virtual void InitKey(byte[] keyBytes, byte[] ivBytes)
{
+ n = 0;
s = 0;
P = new byte[256];
for (int i = 0; i < 256; i++)
{
- P[i] = (byte) i;
+ P[i] = (byte)i;
}
-
- for (int m = 0; m < 768; m++)
- {
- s = P[(s + P[m & 0xff] + keyBytes[m % keyBytes.Length]) & 0xff];
- byte temp = P[m & 0xff];
- P[m & 0xff] = P[s & 0xff];
- P[s & 0xff] = temp;
- }
- for (int m = 0; m < 768; m++)
- {
- s = P[(s + P[m & 0xff] + ivBytes[m % ivBytes.Length]) & 0xff];
- byte temp = P[m & 0xff];
- P[m & 0xff] = P[s & 0xff];
- P[s & 0xff] = temp;
- }
- n = 0;
+ KsaRound(P, ref s, keyBytes);
+ KsaRound(P, ref s, ivBytes);
}
- public virtual void ProcessBytes(
- byte[] input,
- int inOff,
- int len,
- byte[] output,
- int outOff)
+ 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");
@@ -98,16 +68,12 @@ namespace Org.BouncyCastle.Crypto.Engines
for (int i = 0; i < len; i++)
{
byte pn = P[n];
- s = P[(s + pn) & 0xff];
+ s = P[(s + pn) & 0xFF];
byte ps = P[s];
- byte z = P[(P[ps] + 1) & 0xff];
- // encryption
+ output[outOff + i] = (byte)(input[inOff + i] ^ P[(P[ps] + 1) & 0xFF]);
P[n] = ps;
P[s] = pn;
n = (byte)(n + 1);
-
- // xor
- output[i + outOff] = (byte)(input[i + inOff] ^ z);
}
}
@@ -119,16 +85,12 @@ namespace Org.BouncyCastle.Crypto.Engines
for (int i = 0; i < input.Length; i++)
{
byte pn = P[n];
- s = P[(s + pn) & 0xff];
+ s = P[(s + pn) & 0xFF];
byte ps = P[s];
- byte z = P[(P[ps] + 1) & 0xff];
- // encryption
+ output[i] = (byte)(input[i] ^ P[(P[ps] + 1) & 0xFF]);
P[n] = ps;
P[s] = pn;
n = (byte)(n + 1);
-
- // xor
- output[i] = (byte)(input[i] ^ z);
}
}
#endif
@@ -138,19 +100,36 @@ namespace Org.BouncyCastle.Crypto.Engines
InitKey(this.workingKey, this.workingIV);
}
- public virtual byte ReturnByte(
- byte input)
+ public virtual byte ReturnByte(byte input)
{
- s = P[(s + P[n & 0xff]) & 0xff];
- byte z = P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff];
- // encryption
- byte temp = P[n & 0xff];
- P[n & 0xff] = P[s & 0xff];
- P[s & 0xff] = temp;
- n = (byte) ((n + 1) & 0xff);
-
- // xor
- return (byte) (input ^ z);
+ byte pn = P[n];
+ s = P[(s + pn) & 0xFF];
+ byte ps = P[s];
+ byte output = (byte)(input ^ P[(P[ps] + 1) & 0xFF]);
+ P[n] = ps;
+ P[s] = pn;
+ n = (byte)(n + 1);
+ return output;
+ }
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ internal static void KsaRound(byte[] P, ref byte S, ReadOnlySpan<byte> input)
+#else
+ internal static void KsaRound(byte[] P, ref byte S, byte[] input)
+#endif
+ {
+ byte s = S;
+ int modulus = input.Length, offset = 0;
+ for (int m = 0; m < 768; m++)
+ {
+ byte pm = P[m & 0xFF];
+ s = P[(s + pm + input[offset]) & 0xFF];
+ int t = offset + 1 - modulus;
+ offset = t + (modulus & (t >> 31));
+ P[m & 0xFF] = P[s];
+ P[s] = pm;
+ }
+ S = s;
}
}
}
diff --git a/crypto/src/crypto/engines/VMPCKSA3Engine.cs b/crypto/src/crypto/engines/VMPCKSA3Engine.cs
index 95b6813b7..d44c15b0b 100644
--- a/crypto/src/crypto/engines/VMPCKSA3Engine.cs
+++ b/crypto/src/crypto/engines/VMPCKSA3Engine.cs
@@ -5,47 +5,13 @@ namespace Org.BouncyCastle.Crypto.Engines
public class VmpcKsa3Engine
: VmpcEngine
{
- public override string AlgorithmName
- {
- get { return "VMPC-KSA3"; }
- }
+ public override string AlgorithmName => "VMPC-KSA3";
- protected override void InitKey(
- byte[] keyBytes,
- byte[] ivBytes)
+ protected override 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 m = 0; m < 768; m++)
- {
- s = P[(s + P[m & 0xff] + keyBytes[m % keyBytes.Length]) & 0xff];
- byte temp = P[m & 0xff];
- P[m & 0xff] = P[s & 0xff];
- P[s & 0xff] = temp;
- }
-
- for (int m = 0; m < 768; m++)
- {
- s = P[(s + P[m & 0xff] + ivBytes[m % ivBytes.Length]) & 0xff];
- byte temp = P[m & 0xff];
- P[m & 0xff] = P[s & 0xff];
- P[s & 0xff] = temp;
- }
-
- for (int m = 0; m < 768; m++)
- {
- s = P[(s + P[m & 0xff] + keyBytes[m % keyBytes.Length]) & 0xff];
- byte temp = P[m & 0xff];
- P[m & 0xff] = P[s & 0xff];
- P[s & 0xff] = temp;
- }
+ base.InitKey(keyBytes, ivBytes);
- n = 0;
+ KsaRound(P, ref s, keyBytes);
}
}
}
diff --git a/crypto/src/crypto/macs/VMPCMac.cs b/crypto/src/crypto/macs/VMPCMac.cs
index c2902179f..a64ce4ffc 100644
--- a/crypto/src/crypto/macs/VMPCMac.cs
+++ b/crypto/src/crypto/macs/VMPCMac.cs
@@ -1,5 +1,6 @@
using System;
+using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Parameters;
namespace Org.BouncyCastle.Crypto.Macs
@@ -13,7 +14,7 @@ namespace Org.BouncyCastle.Crypto.Macs
private byte[] P = null;
private byte s = 0;
- private byte[] T;
+ private readonly byte[] T = new byte[32];
private byte[] workingIV;
private byte[] workingKey;
@@ -28,43 +29,43 @@ namespace Org.BouncyCastle.Crypto.Macs
// Execute the Post-Processing Phase
for (int r = 1; r < 25; r++)
{
- s = P[(s + P[n & 0xff]) & 0xff];
-
- x4 = P[(x4 + x3 + r) & 0xff];
- x3 = P[(x3 + x2 + r) & 0xff];
- x2 = P[(x2 + x1 + r) & 0xff];
- x1 = P[(x1 + s + r) & 0xff];
- T[g & 0x1f] = (byte) (T[g & 0x1f] ^ x1);
- T[(g + 1) & 0x1f] = (byte) (T[(g + 1) & 0x1f] ^ x2);
- T[(g + 2) & 0x1f] = (byte) (T[(g + 2) & 0x1f] ^ x3);
- T[(g + 3) & 0x1f] = (byte) (T[(g + 3) & 0x1f] ^ x4);
- g = (byte) ((g + 4) & 0x1f);
-
- byte temp = P[n & 0xff];
- P[n & 0xff] = P[s & 0xff];
- P[s & 0xff] = temp;
- n = (byte) ((n + 1) & 0xff);
+ s = P[(s + P[n & 0xFF]) & 0xFF];
+
+ x4 = P[(x4 + x3 + r) & 0xFF];
+ x3 = P[(x3 + x2 + r) & 0xFF];
+ x2 = P[(x2 + x1 + r) & 0xFF];
+ x1 = P[(x1 + s + r) & 0xFF];
+ T[g & 0x1F] = (byte)(T[g & 0x1F] ^ x1);
+ T[(g + 1) & 0x1F] = (byte)(T[(g + 1) & 0x1F] ^ x2);
+ T[(g + 2) & 0x1F] = (byte)(T[(g + 2) & 0x1F] ^ x3);
+ T[(g + 3) & 0x1F] = (byte)(T[(g + 3) & 0x1F] ^ x4);
+ g = (byte)((g + 4) & 0x1F);
+
+ byte temp = P[n & 0xFF];
+ P[n & 0xFF] = P[s & 0xFF];
+ P[s & 0xFF] = temp;
+ n = (byte)((n + 1) & 0xFF);
}
// Input T to the IV-phase of the VMPC KSA
for (int m = 0; m < 768; m++)
{
- s = P[(s + P[m & 0xff] + T[m & 0x1f]) & 0xff];
- byte temp = P[m & 0xff];
- P[m & 0xff] = P[s & 0xff];
- P[s & 0xff] = temp;
+ s = P[(s + P[m & 0xFF] + T[m & 0x1F]) & 0xFF];
+ byte temp = P[m & 0xFF];
+ P[m & 0xFF] = P[s & 0xFF];
+ P[s & 0xFF] = temp;
}
// Store 20 new outputs of the VMPC Stream Cipher input table M
byte[] M = new byte[20];
for (int i = 0; i < 20; i++)
{
- s = P[(s + P[i & 0xff]) & 0xff];
- M[i] = P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff];
+ s = P[(s + P[i & 0xFF]) & 0xFF];
+ M[i] = P[(P[(P[s & 0xFF]) & 0xFF] + 1) & 0xFF];
- byte temp = P[i & 0xff];
- P[i & 0xff] = P[s & 0xff];
- P[s & 0xff] = temp;
+ byte temp = P[i & 0xFF];
+ P[i & 0xFF] = P[s & 0xFF];
+ P[s & 0xFF] = temp;
}
Array.Copy(M, 0, output, outOff, M.Length);
@@ -80,43 +81,43 @@ namespace Org.BouncyCastle.Crypto.Macs
// Execute the Post-Processing Phase
for (int r = 1; r < 25; r++)
{
- s = P[(s + P[n & 0xff]) & 0xff];
-
- x4 = P[(x4 + x3 + r) & 0xff];
- x3 = P[(x3 + x2 + r) & 0xff];
- x2 = P[(x2 + x1 + r) & 0xff];
- x1 = P[(x1 + s + r) & 0xff];
- T[g & 0x1f] = (byte)(T[g & 0x1f] ^ x1);
- T[(g + 1) & 0x1f] = (byte)(T[(g + 1) & 0x1f] ^ x2);
- T[(g + 2) & 0x1f] = (byte)(T[(g + 2) & 0x1f] ^ x3);
- T[(g + 3) & 0x1f] = (byte)(T[(g + 3) & 0x1f] ^ x4);
- g = (byte)((g + 4) & 0x1f);
-
- byte temp = P[n & 0xff];
- P[n & 0xff] = P[s & 0xff];
- P[s & 0xff] = temp;
- n = (byte)((n + 1) & 0xff);
+ s = P[(s + P[n & 0xFF]) & 0xFF];
+
+ x4 = P[(x4 + x3 + r) & 0xFF];
+ x3 = P[(x3 + x2 + r) & 0xFF];
+ x2 = P[(x2 + x1 + r) & 0xFF];
+ x1 = P[(x1 + s + r) & 0xFF];
+ T[g & 0x1F] = (byte)(T[g & 0x1F] ^ x1);
+ T[(g + 1) & 0x1F] = (byte)(T[(g + 1) & 0x1F] ^ x2);
+ T[(g + 2) & 0x1F] = (byte)(T[(g + 2) & 0x1F] ^ x3);
+ T[(g + 3) & 0x1F] = (byte)(T[(g + 3) & 0x1F] ^ x4);
+ g = (byte)((g + 4) & 0x1F);
+
+ byte temp = P[n & 0xFF];
+ P[n & 0xFF] = P[s & 0xFF];
+ P[s & 0xFF] = temp;
+ n = (byte)((n + 1) & 0xFF);
}
// Input T to the IV-phase of the VMPC KSA
for (int m = 0; m < 768; m++)
{
- s = P[(s + P[m & 0xff] + T[m & 0x1f]) & 0xff];
- byte temp = P[m & 0xff];
- P[m & 0xff] = P[s & 0xff];
- P[s & 0xff] = temp;
+ s = P[(s + P[m & 0xFF] + T[m & 0x1F]) & 0xFF];
+ byte temp = P[m & 0xFF];
+ P[m & 0xFF] = P[s & 0xFF];
+ P[s & 0xFF] = temp;
}
// Store 20 new outputs of the VMPC Stream Cipher input table M
byte[] M = new byte[20];
for (int i = 0; i < 20; i++)
{
- s = P[(s + P[i & 0xff]) & 0xff];
- M[i] = P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff];
+ s = P[(s + P[i & 0xFF]) & 0xFF];
+ M[i] = P[(P[(P[s & 0xFF]) & 0xFF] + 1) & 0xFF];
- byte temp = P[i & 0xff];
- P[i & 0xff] = P[s & 0xff];
- P[s & 0xff] = temp;
+ byte temp = P[i & 0xFF];
+ P[i & 0xFF] = P[s & 0xFF];
+ P[s & 0xFF] = temp;
}
M.CopyTo(output);
@@ -126,113 +127,129 @@ namespace Org.BouncyCastle.Crypto.Macs
}
#endif
- public virtual string AlgorithmName
- {
- get { return "VMPC-MAC"; }
- }
+ public virtual string AlgorithmName => "VMPC-MAC";
- public virtual int GetMacSize()
- {
- return 20;
- }
+ public virtual int GetMacSize() => 20;
public virtual void Init(ICipherParameters parameters)
{
- if (!(parameters is ParametersWithIV))
+ if (!(parameters is ParametersWithIV ivParams))
throw new ArgumentException("VMPC-MAC Init parameters must include an IV", "parameters");
-
- ParametersWithIV ivParams = (ParametersWithIV) parameters;
- KeyParameter key = (KeyParameter) ivParams.Parameters;
-
- if (!(ivParams.Parameters is KeyParameter))
+ if (!(ivParams.Parameters is KeyParameter key))
throw new ArgumentException("VMPC-MAC Init parameters must include a key", "parameters");
- this.workingIV = ivParams.GetIV();
+ int keyLength = key.KeyLength;
+ if (keyLength < 16 || keyLength > 64)
+ throw new ArgumentException("VMPC requires 16 to 64 bytes of key");
- if (workingIV == null || workingIV.Length < 1 || workingIV.Length > 768)
- throw new ArgumentException("VMPC-MAC requires 1 to 768 bytes of IV", "parameters");
+ int ivLength = ivParams.IVLength;
+ if (ivLength < 16 || ivLength > 64)
+ throw new ArgumentException("VMPC requires 16 to 64 bytes of IV");
- this.workingKey = key.GetKey();
+ this.workingKey = key.GetKey();
+ this.workingIV = ivParams.GetIV();
Reset();
-
}
- private void initKey(byte[] keyBytes, byte[] ivBytes)
+ private void InitKey(byte[] keyBytes, byte[] ivBytes)
{
- s = 0;
+ n = 0;
+ s = 0;
P = new byte[256];
for (int i = 0; i < 256; i++)
{
- P[i] = (byte) i;
- }
- for (int m = 0; m < 768; m++)
- {
- s = P[(s + P[m & 0xff] + keyBytes[m % keyBytes.Length]) & 0xff];
- byte temp = P[m & 0xff];
- P[m & 0xff] = P[s & 0xff];
- P[s & 0xff] = temp;
- }
- for (int m = 0; m < 768; m++)
- {
- s = P[(s + P[m & 0xff] + ivBytes[m % ivBytes.Length]) & 0xff];
- byte temp = P[m & 0xff];
- P[m & 0xff] = P[s & 0xff];
- P[s & 0xff] = temp;
+ P[i] = (byte)i;
}
- n = 0;
+ VmpcEngine.KsaRound(P, ref s, keyBytes);
+ VmpcEngine.KsaRound(P, ref s, ivBytes);
}
public virtual void Reset()
{
- initKey(this.workingKey, this.workingIV);
+ InitKey(this.workingKey, this.workingIV);
g = x1 = x2 = x3 = x4 = n = 0;
- T = new byte[32];
- for (int i = 0; i < 32; i++)
- {
- T[i] = 0;
- }
+ Array.Clear(T, 0, T.Length);
}
public virtual void Update(byte input)
{
- s = P[(s + P[n & 0xff]) & 0xff];
- byte c = (byte) (input ^ P[(P[(P[s & 0xff]) & 0xff] + 1) & 0xff]);
-
- x4 = P[(x4 + x3) & 0xff];
- x3 = P[(x3 + x2) & 0xff];
- x2 = P[(x2 + x1) & 0xff];
- x1 = P[(x1 + s + c) & 0xff];
- T[g & 0x1f] = (byte) (T[g & 0x1f] ^ x1);
- T[(g + 1) & 0x1f] = (byte) (T[(g + 1) & 0x1f] ^ x2);
- T[(g + 2) & 0x1f] = (byte) (T[(g + 2) & 0x1f] ^ x3);
- T[(g + 3) & 0x1f] = (byte) (T[(g + 3) & 0x1f] ^ x4);
- g = (byte) ((g + 4) & 0x1f);
-
- byte temp = P[n & 0xff];
- P[n & 0xff] = P[s & 0xff];
- P[s & 0xff] = temp;
- n = (byte) ((n + 1) & 0xff);
- }
-
- public virtual void BlockUpdate(byte[] input, int inOff, int inLen)
+ byte pn = P[n];
+ s = P[(s + pn) & 0xFF];
+ byte ps = P[s];
+ byte c = (byte)(input ^ P[(P[ps] + 1) & 0xFF]);
+
+ x4 = P[(x4 + x3) & 0xFF];
+ x3 = P[(x3 + x2) & 0xFF];
+ x2 = P[(x2 + x1) & 0xFF];
+ x1 = P[(x1 + s + c) & 0xFF];
+ T[g & 0x1F] = (byte)(T[g & 0x1F] ^ x1);
+ T[(g + 1) & 0x1F] = (byte)(T[(g + 1) & 0x1F] ^ x2);
+ T[(g + 2) & 0x1F] = (byte)(T[(g + 2) & 0x1F] ^ x3);
+ T[(g + 3) & 0x1F] = (byte)(T[(g + 3) & 0x1F] ^ x4);
+ g = (byte)((g + 4) & 0x1F);
+
+ P[n] = ps;
+ P[s] = pn;
+ n = (byte)(n + 1);
+ }
+
+ public virtual void BlockUpdate(byte[] input, int inOff, int inLen)
{
Check.DataLength(input, inOff, inLen, "input buffer too short");
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ BlockUpdate(input.AsSpan(inOff, inLen));
+#else
for (int i = 0; i < inLen; i++)
{
- Update(input[inOff + i]);
- }
- }
+ byte pn = P[n];
+ s = P[(s + pn) & 0xFF];
+ byte ps = P[s];
+ byte c = (byte)(input[inOff + i] ^ P[(P[ps] + 1) & 0xFF]);
+
+ x4 = P[(x4 + x3) & 0xFF];
+ x3 = P[(x3 + x2) & 0xFF];
+ x2 = P[(x2 + x1) & 0xFF];
+ x1 = P[(x1 + s + c) & 0xFF];
+ T[g & 0x1F] = (byte)(T[g & 0x1F] ^ x1);
+ T[(g + 1) & 0x1F] = (byte)(T[(g + 1) & 0x1F] ^ x2);
+ T[(g + 2) & 0x1F] = (byte)(T[(g + 2) & 0x1F] ^ x3);
+ T[(g + 3) & 0x1F] = (byte)(T[(g + 3) & 0x1F] ^ x4);
+ g = (byte)((g + 4) & 0x1F);
+
+ P[n] = ps;
+ P[s] = pn;
+ n = (byte)(n + 1);
+ }
+#endif
+ }
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
public virtual void BlockUpdate(ReadOnlySpan<byte> input)
{
for (int i = 0; i < input.Length; i++)
{
- Update(input[i]);
- }
- }
+ byte pn = P[n];
+ s = P[(s + pn) & 0xFF];
+ byte ps = P[s];
+ byte c = (byte)(input[i] ^ P[(P[ps] + 1) & 0xFF]);
+
+ x4 = P[(x4 + x3) & 0xFF];
+ x3 = P[(x3 + x2) & 0xFF];
+ x2 = P[(x2 + x1) & 0xFF];
+ x1 = P[(x1 + s + c) & 0xFF];
+ T[g & 0x1F] = (byte)(T[g & 0x1F] ^ x1);
+ T[(g + 1) & 0x1F] = (byte)(T[(g + 1) & 0x1F] ^ x2);
+ T[(g + 2) & 0x1F] = (byte)(T[(g + 2) & 0x1F] ^ x3);
+ T[(g + 3) & 0x1F] = (byte)(T[(g + 3) & 0x1F] ^ x4);
+ g = (byte)((g + 4) & 0x1F);
+
+ P[n] = ps;
+ P[s] = pn;
+ n = (byte)(n + 1);
+ }
+ }
#endif
- }
+ }
}
diff --git a/crypto/src/crypto/prng/VMPCRandomGenerator.cs b/crypto/src/crypto/prng/VMPCRandomGenerator.cs
index 92d163710..23f2d2ec1 100644
--- a/crypto/src/crypto/prng/VMPCRandomGenerator.cs
+++ b/crypto/src/crypto/prng/VMPCRandomGenerator.cs
@@ -56,6 +56,12 @@ namespace Org.BouncyCastle.Crypto.Prng
public void AddSeedMaterial(byte[] seed)
{
+ if (seed == null)
+ return;
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ AddSeedMaterial(seed.AsSpan());
+#else
for (int m = 0; m < seed.Length; m++)
{
byte pn = P[n];
@@ -64,6 +70,7 @@ namespace Org.BouncyCastle.Crypto.Prng
P[s] = pn;
n = (byte)(n + 1);
}
+#endif
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
|