Initial Commit
This commit is contained in:
139
iTechSharp/srcbc/crypto/generators/RsaKeyPairGenerator.cs
Normal file
139
iTechSharp/srcbc/crypto/generators/RsaKeyPairGenerator.cs
Normal file
@@ -0,0 +1,139 @@
|
||||
using System;
|
||||
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Math;
|
||||
|
||||
namespace Org.BouncyCastle.Crypto.Generators
|
||||
{
|
||||
/**
|
||||
* an RSA key pair generator.
|
||||
*/
|
||||
public class RsaKeyPairGenerator
|
||||
: IAsymmetricCipherKeyPairGenerator
|
||||
{
|
||||
private static readonly BigInteger DefaultPublicExponent = BigInteger.ValueOf(0x10001);
|
||||
private const int DefaultTests = 12;
|
||||
|
||||
private RsaKeyGenerationParameters param;
|
||||
|
||||
public void Init(
|
||||
KeyGenerationParameters parameters)
|
||||
{
|
||||
if (parameters is RsaKeyGenerationParameters)
|
||||
{
|
||||
this.param = (RsaKeyGenerationParameters)parameters;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.param = new RsaKeyGenerationParameters(
|
||||
DefaultPublicExponent, parameters.Random, parameters.Strength, DefaultTests);
|
||||
}
|
||||
}
|
||||
|
||||
public AsymmetricCipherKeyPair GenerateKeyPair()
|
||||
{
|
||||
BigInteger p, q, n, d, e, pSub1, qSub1, phi;
|
||||
|
||||
//
|
||||
// p and q values should have a length of half the strength in bits
|
||||
//
|
||||
int strength = param.Strength;
|
||||
int pbitlength = (strength + 1) / 2;
|
||||
int qbitlength = (strength - pbitlength);
|
||||
int mindiffbits = strength / 3;
|
||||
|
||||
e = param.PublicExponent;
|
||||
|
||||
// TODO Consider generating safe primes for p, q (see DHParametersHelper.generateSafePrimes)
|
||||
// (then p-1 and q-1 will not consist of only small factors - see "Pollard's algorithm")
|
||||
|
||||
//
|
||||
// Generate p, prime and (p-1) relatively prime to e
|
||||
//
|
||||
for (;;)
|
||||
{
|
||||
p = new BigInteger(pbitlength, 1, param.Random);
|
||||
|
||||
if (p.Mod(e).Equals(BigInteger.One))
|
||||
continue;
|
||||
|
||||
if (!p.IsProbablePrime(param.Certainty))
|
||||
continue;
|
||||
|
||||
if (e.Gcd(p.Subtract(BigInteger.One)).Equals(BigInteger.One))
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// Generate a modulus of the required length
|
||||
//
|
||||
for (;;)
|
||||
{
|
||||
// Generate q, prime and (q-1) relatively prime to e,
|
||||
// and not equal to p
|
||||
//
|
||||
for (;;)
|
||||
{
|
||||
q = new BigInteger(qbitlength, 1, param.Random);
|
||||
|
||||
if (q.Subtract(p).Abs().BitLength < mindiffbits)
|
||||
continue;
|
||||
|
||||
if (q.Mod(e).Equals(BigInteger.One))
|
||||
continue;
|
||||
|
||||
if (!q.IsProbablePrime(param.Certainty))
|
||||
continue;
|
||||
|
||||
if (e.Gcd(q.Subtract(BigInteger.One)).Equals(BigInteger.One))
|
||||
break;
|
||||
}
|
||||
|
||||
//
|
||||
// calculate the modulus
|
||||
//
|
||||
n = p.Multiply(q);
|
||||
|
||||
if (n.BitLength == param.Strength)
|
||||
break;
|
||||
|
||||
//
|
||||
// if we Get here our primes aren't big enough, make the largest
|
||||
// of the two p and try again
|
||||
//
|
||||
p = p.Max(q);
|
||||
}
|
||||
|
||||
if (p.CompareTo(q) < 0)
|
||||
{
|
||||
phi = p;
|
||||
p = q;
|
||||
q = phi;
|
||||
}
|
||||
|
||||
pSub1 = p.Subtract(BigInteger.One);
|
||||
qSub1 = q.Subtract(BigInteger.One);
|
||||
phi = pSub1.Multiply(qSub1);
|
||||
|
||||
//
|
||||
// calculate the private exponent
|
||||
//
|
||||
d = e.ModInverse(phi);
|
||||
|
||||
//
|
||||
// calculate the CRT factors
|
||||
//
|
||||
BigInteger dP, dQ, qInv;
|
||||
|
||||
dP = d.Remainder(pSub1);
|
||||
dQ = d.Remainder(qSub1);
|
||||
qInv = q.ModInverse(p);
|
||||
|
||||
return new AsymmetricCipherKeyPair(
|
||||
new RsaKeyParameters(false, n, e),
|
||||
new RsaPrivateCrtKeyParameters(n, e, d, p, q, dP, dQ, qInv));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user