init commit
This commit is contained in:
@@ -0,0 +1,204 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Math;
|
||||
using Org.BouncyCastle.Utilities;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Engines;
|
||||
|
||||
public class NaccacheSternEngine : IAsymmetricBlockCipher
|
||||
{
|
||||
private bool forEncryption;
|
||||
|
||||
private NaccacheSternKeyParameters key;
|
||||
|
||||
private IList[] lookup = null;
|
||||
|
||||
public string AlgorithmName => "NaccacheStern";
|
||||
|
||||
[Obsolete("Remove: no longer used")]
|
||||
public virtual bool Debug
|
||||
{
|
||||
set
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Init(bool forEncryption, ICipherParameters parameters)
|
||||
{
|
||||
this.forEncryption = forEncryption;
|
||||
if (parameters is ParametersWithRandom)
|
||||
{
|
||||
parameters = ((ParametersWithRandom)parameters).Parameters;
|
||||
}
|
||||
key = (NaccacheSternKeyParameters)parameters;
|
||||
if (this.forEncryption)
|
||||
{
|
||||
return;
|
||||
}
|
||||
NaccacheSternPrivateKeyParameters naccacheSternPrivateKeyParameters = (NaccacheSternPrivateKeyParameters)key;
|
||||
IList smallPrimesList = naccacheSternPrivateKeyParameters.SmallPrimesList;
|
||||
lookup = new IList[smallPrimesList.Count];
|
||||
for (int i = 0; i < smallPrimesList.Count; i++)
|
||||
{
|
||||
BigInteger bigInteger = (BigInteger)smallPrimesList[i];
|
||||
int intValue = bigInteger.IntValue;
|
||||
lookup[i] = Platform.CreateArrayList(intValue);
|
||||
lookup[i].Add(BigInteger.One);
|
||||
BigInteger bigInteger2 = BigInteger.Zero;
|
||||
for (int j = 1; j < intValue; j++)
|
||||
{
|
||||
bigInteger2 = bigInteger2.Add(naccacheSternPrivateKeyParameters.PhiN);
|
||||
BigInteger e = bigInteger2.Divide(bigInteger);
|
||||
lookup[i].Add(naccacheSternPrivateKeyParameters.G.ModPow(e, naccacheSternPrivateKeyParameters.Modulus));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual int GetInputBlockSize()
|
||||
{
|
||||
if (forEncryption)
|
||||
{
|
||||
return (key.LowerSigmaBound + 7) / 8 - 1;
|
||||
}
|
||||
return key.Modulus.BitLength / 8 + 1;
|
||||
}
|
||||
|
||||
public virtual int GetOutputBlockSize()
|
||||
{
|
||||
if (forEncryption)
|
||||
{
|
||||
return key.Modulus.BitLength / 8 + 1;
|
||||
}
|
||||
return (key.LowerSigmaBound + 7) / 8 - 1;
|
||||
}
|
||||
|
||||
public virtual byte[] ProcessBlock(byte[] inBytes, int inOff, int length)
|
||||
{
|
||||
if (key == null)
|
||||
{
|
||||
throw new InvalidOperationException("NaccacheStern engine not initialised");
|
||||
}
|
||||
if (length > GetInputBlockSize() + 1)
|
||||
{
|
||||
throw new DataLengthException("input too large for Naccache-Stern cipher.\n");
|
||||
}
|
||||
if (!forEncryption && length < GetInputBlockSize())
|
||||
{
|
||||
throw new InvalidCipherTextException("BlockLength does not match modulus for Naccache-Stern cipher.\n");
|
||||
}
|
||||
BigInteger bigInteger = new BigInteger(1, inBytes, inOff, length);
|
||||
if (forEncryption)
|
||||
{
|
||||
return Encrypt(bigInteger);
|
||||
}
|
||||
IList list = Platform.CreateArrayList();
|
||||
NaccacheSternPrivateKeyParameters naccacheSternPrivateKeyParameters = (NaccacheSternPrivateKeyParameters)key;
|
||||
IList smallPrimesList = naccacheSternPrivateKeyParameters.SmallPrimesList;
|
||||
for (int i = 0; i < smallPrimesList.Count; i++)
|
||||
{
|
||||
BigInteger value = bigInteger.ModPow(naccacheSternPrivateKeyParameters.PhiN.Divide((BigInteger)smallPrimesList[i]), naccacheSternPrivateKeyParameters.Modulus);
|
||||
IList list2 = lookup[i];
|
||||
if (lookup[i].Count != ((BigInteger)smallPrimesList[i]).IntValue)
|
||||
{
|
||||
throw new InvalidCipherTextException("Error in lookup Array for " + ((BigInteger)smallPrimesList[i]).IntValue + ": Size mismatch. Expected ArrayList with length " + ((BigInteger)smallPrimesList[i]).IntValue + " but found ArrayList of length " + lookup[i].Count);
|
||||
}
|
||||
int num = list2.IndexOf(value);
|
||||
if (num == -1)
|
||||
{
|
||||
throw new InvalidCipherTextException("Lookup failed");
|
||||
}
|
||||
list.Add(BigInteger.ValueOf(num));
|
||||
}
|
||||
BigInteger bigInteger2 = chineseRemainder(list, smallPrimesList);
|
||||
return bigInteger2.ToByteArray();
|
||||
}
|
||||
|
||||
public virtual byte[] Encrypt(BigInteger plain)
|
||||
{
|
||||
byte[] array = new byte[key.Modulus.BitLength / 8 + 1];
|
||||
byte[] array2 = key.G.ModPow(plain, key.Modulus).ToByteArray();
|
||||
Array.Copy(array2, 0, array, array.Length - array2.Length, array2.Length);
|
||||
return array;
|
||||
}
|
||||
|
||||
public virtual byte[] AddCryptedBlocks(byte[] block1, byte[] block2)
|
||||
{
|
||||
if (forEncryption)
|
||||
{
|
||||
if (block1.Length > GetOutputBlockSize() || block2.Length > GetOutputBlockSize())
|
||||
{
|
||||
throw new InvalidCipherTextException("BlockLength too large for simple addition.\n");
|
||||
}
|
||||
}
|
||||
else if (block1.Length > GetInputBlockSize() || block2.Length > GetInputBlockSize())
|
||||
{
|
||||
throw new InvalidCipherTextException("BlockLength too large for simple addition.\n");
|
||||
}
|
||||
BigInteger bigInteger = new BigInteger(1, block1);
|
||||
BigInteger val = new BigInteger(1, block2);
|
||||
BigInteger bigInteger2 = bigInteger.Multiply(val);
|
||||
bigInteger2 = bigInteger2.Mod(key.Modulus);
|
||||
byte[] array = new byte[key.Modulus.BitLength / 8 + 1];
|
||||
byte[] array2 = bigInteger2.ToByteArray();
|
||||
Array.Copy(array2, 0, array, array.Length - array2.Length, array2.Length);
|
||||
return array;
|
||||
}
|
||||
|
||||
public virtual byte[] ProcessData(byte[] data)
|
||||
{
|
||||
if (data.Length > GetInputBlockSize())
|
||||
{
|
||||
int inputBlockSize = GetInputBlockSize();
|
||||
int outputBlockSize = GetOutputBlockSize();
|
||||
int num = 0;
|
||||
int num2 = 0;
|
||||
byte[] array = new byte[(data.Length / inputBlockSize + 1) * outputBlockSize];
|
||||
while (num < data.Length)
|
||||
{
|
||||
byte[] array2;
|
||||
if (num + inputBlockSize < data.Length)
|
||||
{
|
||||
array2 = ProcessBlock(data, num, inputBlockSize);
|
||||
num += inputBlockSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
array2 = ProcessBlock(data, num, data.Length - num);
|
||||
num += data.Length - num;
|
||||
}
|
||||
if (array2 != null)
|
||||
{
|
||||
array2.CopyTo(array, num2);
|
||||
num2 += array2.Length;
|
||||
continue;
|
||||
}
|
||||
throw new InvalidCipherTextException("cipher returned null");
|
||||
}
|
||||
byte[] array3 = new byte[num2];
|
||||
Array.Copy(array, 0, array3, 0, num2);
|
||||
return array3;
|
||||
}
|
||||
return ProcessBlock(data, 0, data.Length);
|
||||
}
|
||||
|
||||
private static BigInteger chineseRemainder(IList congruences, IList primes)
|
||||
{
|
||||
BigInteger bigInteger = BigInteger.Zero;
|
||||
BigInteger bigInteger2 = BigInteger.One;
|
||||
for (int i = 0; i < primes.Count; i++)
|
||||
{
|
||||
bigInteger2 = bigInteger2.Multiply((BigInteger)primes[i]);
|
||||
}
|
||||
for (int j = 0; j < primes.Count; j++)
|
||||
{
|
||||
BigInteger bigInteger3 = (BigInteger)primes[j];
|
||||
BigInteger bigInteger4 = bigInteger2.Divide(bigInteger3);
|
||||
BigInteger val = bigInteger4.ModInverse(bigInteger3);
|
||||
BigInteger bigInteger5 = bigInteger4.Multiply(val);
|
||||
bigInteger5 = bigInteger5.Multiply((BigInteger)congruences[j]);
|
||||
bigInteger = bigInteger.Add(bigInteger5);
|
||||
}
|
||||
return bigInteger.Mod(bigInteger2);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user