NaccacheSternKeyPairGenerator
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
using System.Collections.Generic;
namespace Org.BouncyCastle.Crypto.Generators
{
public class NaccacheSternKeyPairGenerator : IAsymmetricCipherKeyPairGenerator
{
private static readonly int[] smallPrimes = new int[101] {
3,
5,
7,
11,
13,
17,
19,
23,
29,
31,
37,
41,
43,
47,
53,
59,
61,
67,
71,
73,
79,
83,
89,
97,
101,
103,
107,
109,
113,
127,
131,
137,
139,
149,
151,
157,
163,
167,
173,
179,
181,
191,
193,
197,
199,
211,
223,
227,
229,
233,
239,
241,
251,
257,
263,
269,
271,
277,
281,
283,
293,
307,
311,
313,
317,
331,
337,
347,
349,
353,
359,
367,
373,
379,
383,
389,
397,
401,
409,
419,
421,
431,
433,
439,
443,
449,
457,
461,
463,
467,
479,
487,
491,
499,
503,
509,
521,
523,
541,
547,
557
};
private NaccacheSternKeyGenerationParameters param;
public void Init(KeyGenerationParameters parameters)
{
param = (NaccacheSternKeyGenerationParameters)parameters;
}
public AsymmetricCipherKeyPair GenerateKeyPair()
{
int strength = param.Strength;
SecureRandom random = param.Random;
int certainty = param.Certainty;
IList<BigInteger> arr = FindFirstPrimes(param.CountSmallPrimes);
arr = PermuteList(arr, random);
BigInteger bigInteger = BigInteger.One;
BigInteger bigInteger2 = BigInteger.One;
for (int i = 0; i < arr.Count / 2; i++) {
bigInteger = bigInteger.Multiply(arr[i]);
}
for (int j = arr.Count / 2; j < arr.Count; j++) {
bigInteger2 = bigInteger2.Multiply(arr[j]);
}
BigInteger bigInteger3 = bigInteger.Multiply(bigInteger2);
int num = strength - bigInteger3.BitLength - 48;
BigInteger bigInteger4 = GeneratePrime(num / 2 + 1, certainty, random);
BigInteger bigInteger5 = GeneratePrime(num / 2 + 1, certainty, random);
long num2 = 0;
BigInteger val = bigInteger4.Multiply(bigInteger).ShiftLeft(1);
BigInteger val2 = bigInteger5.Multiply(bigInteger2).ShiftLeft(1);
BigInteger bigInteger6;
BigInteger bigInteger7;
BigInteger bigInteger8;
BigInteger bigInteger9;
BigInteger bigInteger10;
while (true) {
num2++;
bigInteger6 = GeneratePrime(24, certainty, random);
bigInteger7 = bigInteger6.Multiply(val).Add(BigInteger.One);
if (bigInteger7.IsProbablePrime(certainty, true)) {
while (true) {
bigInteger8 = GeneratePrime(24, certainty, random);
if (!bigInteger6.Equals(bigInteger8)) {
bigInteger9 = bigInteger8.Multiply(val2).Add(BigInteger.One);
if (bigInteger9.IsProbablePrime(certainty, true))
break;
}
}
if (BigIntegers.ModOddIsCoprime(bigInteger6.Multiply(bigInteger8), bigInteger3)) {
bigInteger10 = bigInteger7.Multiply(bigInteger9);
if (bigInteger10.BitLength >= strength)
break;
}
}
}
BigInteger bigInteger11 = bigInteger7.Subtract(BigInteger.One).Multiply(bigInteger9.Subtract(BigInteger.One));
num2 = 0;
BigInteger bigInteger12;
bool flag;
do {
List<BigInteger> list = new List<BigInteger>();
for (int k = 0; k != arr.Count; k++) {
BigInteger val3 = arr[k];
BigInteger e = bigInteger11.Divide(val3);
do {
num2++;
bigInteger12 = GeneratePrime(strength, certainty, random);
} while (bigInteger12.ModPow(e, bigInteger10).Equals(BigInteger.One));
list.Add(bigInteger12);
}
bigInteger12 = BigInteger.One;
for (int l = 0; l < arr.Count; l++) {
BigInteger bigInteger13 = list[l];
BigInteger val4 = arr[l];
bigInteger12 = bigInteger12.Multiply(bigInteger13.ModPow(bigInteger3.Divide(val4), bigInteger10)).Mod(bigInteger10);
}
flag = false;
for (int m = 0; m < arr.Count; m++) {
if (bigInteger12.ModPow(bigInteger11.Divide(arr[m]), bigInteger10).Equals(BigInteger.One)) {
flag = true;
break;
}
}
} while (flag || bigInteger12.ModPow(bigInteger11.ShiftRight(2), bigInteger10).Equals(BigInteger.One) || bigInteger12.ModPow(bigInteger11.Divide(bigInteger6), bigInteger10).Equals(BigInteger.One) || bigInteger12.ModPow(bigInteger11.Divide(bigInteger8), bigInteger10).Equals(BigInteger.One) || bigInteger12.ModPow(bigInteger11.Divide(bigInteger4), bigInteger10).Equals(BigInteger.One) || bigInteger12.ModPow(bigInteger11.Divide(bigInteger5), bigInteger10).Equals(BigInteger.One));
return new AsymmetricCipherKeyPair(new NaccacheSternKeyParameters(false, bigInteger12, bigInteger10, bigInteger3.BitLength), new NaccacheSternPrivateKeyParameters(bigInteger12, bigInteger10, bigInteger3.BitLength, arr, bigInteger11));
}
private static BigInteger GeneratePrime(int bitLength, int certainty, SecureRandom rand)
{
return new BigInteger(bitLength, certainty, rand);
}
private static IList<T> PermuteList<T>(IList<T> arr, SecureRandom rand)
{
List<T> list = new List<T>(((ICollection<T>)arr).Count);
foreach (T item in (IEnumerable<T>)arr) {
int index = rand.Next(list.Count + 1);
list.Insert(index, item);
}
return list;
}
private static IList<BigInteger> FindFirstPrimes(int count)
{
List<BigInteger> list = new List<BigInteger>(count);
for (int i = 0; i != count; i++) {
list.Add(BigInteger.ValueOf(smallPrimes[i]));
}
return list;
}
}
}