131 lines
3.1 KiB
C#
131 lines
3.1 KiB
C#
using System;
|
|
using System.Globalization;
|
|
|
|
using Org.BouncyCastle.Asn1;
|
|
using Org.BouncyCastle.Asn1.X9;
|
|
using Org.BouncyCastle.Crypto;
|
|
using Org.BouncyCastle.Crypto.Parameters;
|
|
using Org.BouncyCastle.Math;
|
|
using Org.BouncyCastle.Math.EC;
|
|
using Org.BouncyCastle.Security;
|
|
|
|
namespace Org.BouncyCastle.Crypto.Generators
|
|
{
|
|
public class ECKeyPairGenerator
|
|
: IAsymmetricCipherKeyPairGenerator
|
|
{
|
|
private readonly string algorithm;
|
|
|
|
private ECDomainParameters parameters;
|
|
private DerObjectIdentifier publicKeyParamSet;
|
|
private SecureRandom random;
|
|
|
|
public ECKeyPairGenerator()
|
|
: this("EC")
|
|
{
|
|
}
|
|
|
|
public ECKeyPairGenerator(
|
|
string algorithm)
|
|
{
|
|
if (algorithm == null)
|
|
throw new ArgumentNullException("algorithm");
|
|
|
|
this.algorithm = VerifyAlgorithmName(algorithm);
|
|
}
|
|
|
|
public void Init(
|
|
KeyGenerationParameters parameters)
|
|
{
|
|
if (parameters is ECKeyGenerationParameters)
|
|
{
|
|
ECKeyGenerationParameters ecP = (ECKeyGenerationParameters) parameters;
|
|
|
|
if (ecP.PublicKeyParamSet != null)
|
|
{
|
|
if (algorithm != "ECGOST3410")
|
|
throw new ArgumentException("parameters invalid for algorithm: " + algorithm, "parameters");
|
|
|
|
this.publicKeyParamSet = ecP.PublicKeyParamSet;
|
|
}
|
|
|
|
this.parameters = ecP.DomainParameters;
|
|
}
|
|
else
|
|
{
|
|
DerObjectIdentifier oid;
|
|
switch (parameters.Strength)
|
|
{
|
|
case 192:
|
|
oid = X9ObjectIdentifiers.Prime192v1;
|
|
break;
|
|
case 239:
|
|
oid = X9ObjectIdentifiers.Prime239v1;
|
|
break;
|
|
case 256:
|
|
oid = X9ObjectIdentifiers.Prime256v1;
|
|
break;
|
|
default:
|
|
throw new InvalidParameterException("unknown key size.");
|
|
}
|
|
|
|
X9ECParameters ecps = X962NamedCurves.GetByOid(oid);
|
|
|
|
this.parameters = new ECDomainParameters(
|
|
ecps.Curve, ecps.G, ecps.N, ecps.H, ecps.GetSeed());
|
|
}
|
|
|
|
this.random = parameters.Random;
|
|
}
|
|
|
|
/**
|
|
* Given the domain parameters this routine Generates an EC key
|
|
* pair in accordance with X9.62 section 5.2.1 pages 26, 27.
|
|
*/
|
|
public AsymmetricCipherKeyPair GenerateKeyPair()
|
|
{
|
|
BigInteger n = parameters.N;
|
|
BigInteger d;
|
|
|
|
do
|
|
{
|
|
d = new BigInteger(n.BitLength, random);
|
|
}
|
|
while (d.SignValue == 0 || (d.CompareTo(n) >= 0));
|
|
|
|
ECPoint q = parameters.G.Multiply(d);
|
|
|
|
if (publicKeyParamSet != null)
|
|
{
|
|
return new AsymmetricCipherKeyPair(
|
|
new ECPublicKeyParameters(q, publicKeyParamSet),
|
|
new ECPrivateKeyParameters(d, publicKeyParamSet));
|
|
}
|
|
|
|
return new AsymmetricCipherKeyPair(
|
|
new ECPublicKeyParameters(algorithm, q, parameters),
|
|
new ECPrivateKeyParameters(algorithm, d, parameters));
|
|
}
|
|
|
|
private string VerifyAlgorithmName(
|
|
string algorithm)
|
|
{
|
|
string upper = algorithm.ToUpper(CultureInfo.InvariantCulture);
|
|
|
|
switch (upper)
|
|
{
|
|
case "EC":
|
|
case "ECDSA":
|
|
case "ECGOST3410":
|
|
case "ECDH":
|
|
case "ECDHC":
|
|
break;
|
|
default:
|
|
throw new ArgumentException("unrecognised algorithm: " + algorithm, "algorithm");
|
|
}
|
|
|
|
return upper;
|
|
}
|
|
}
|
|
}
|