You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
172 lines
5.6 KiB
172 lines
5.6 KiB
using System;
|
|
|
|
using Org.BouncyCastle.Asn1;
|
|
using Org.BouncyCastle.Asn1.Nist;
|
|
using Org.BouncyCastle.Asn1.Sec;
|
|
using Org.BouncyCastle.Asn1.TeleTrust;
|
|
using Org.BouncyCastle.Asn1.X9;
|
|
using Org.BouncyCastle.Crypto;
|
|
using Org.BouncyCastle.Crypto.EC;
|
|
using Org.BouncyCastle.Crypto.Parameters;
|
|
using Org.BouncyCastle.Math;
|
|
using Org.BouncyCastle.Math.EC;
|
|
using Org.BouncyCastle.Math.EC.Multiplier;
|
|
using Org.BouncyCastle.Security;
|
|
using Org.BouncyCastle.Utilities;
|
|
|
|
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 = ECKeyParameters.VerifyAlgorithmName(algorithm);
|
|
}
|
|
|
|
public void Init(
|
|
KeyGenerationParameters parameters)
|
|
{
|
|
if (parameters is ECKeyGenerationParameters)
|
|
{
|
|
ECKeyGenerationParameters ecP = (ECKeyGenerationParameters) parameters;
|
|
|
|
this.publicKeyParamSet = ecP.PublicKeyParamSet;
|
|
this.parameters = ecP.DomainParameters;
|
|
}
|
|
else
|
|
{
|
|
DerObjectIdentifier oid;
|
|
switch (parameters.Strength)
|
|
{
|
|
case 192:
|
|
oid = X9ObjectIdentifiers.Prime192v1;
|
|
break;
|
|
case 224:
|
|
oid = SecObjectIdentifiers.SecP224r1;
|
|
break;
|
|
case 239:
|
|
oid = X9ObjectIdentifiers.Prime239v1;
|
|
break;
|
|
case 256:
|
|
oid = X9ObjectIdentifiers.Prime256v1;
|
|
break;
|
|
case 384:
|
|
oid = SecObjectIdentifiers.SecP384r1;
|
|
break;
|
|
case 521:
|
|
oid = SecObjectIdentifiers.SecP521r1;
|
|
break;
|
|
default:
|
|
throw new InvalidParameterException("unknown key size.");
|
|
}
|
|
|
|
X9ECParameters ecps = FindECCurveByOid(oid);
|
|
|
|
this.publicKeyParamSet = oid;
|
|
#pragma warning disable CS0612 // ���ͻ���Ա�ѹ�ʱ
|
|
this.parameters = new ECDomainParameters(
|
|
ecps.Curve, ecps.G, ecps.N, ecps.H, ecps.GetSeed());
|
|
#pragma warning restore CS0612 // ���ͻ���Ա�ѹ�ʱ
|
|
}
|
|
|
|
this.random = parameters.Random;
|
|
|
|
if (this.random == null)
|
|
{
|
|
this.random = new SecureRandom();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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;
|
|
int minWeight = n.BitLength >> 2;
|
|
|
|
for (;;)
|
|
{
|
|
d = new BigInteger(n.BitLength, random);
|
|
|
|
if (d.CompareTo(BigInteger.One) < 0 || d.CompareTo(n) >= 0)
|
|
continue;
|
|
|
|
if (WNafUtilities.GetNafWeight(d) < minWeight)
|
|
continue;
|
|
|
|
break;
|
|
}
|
|
|
|
ECPoint q = CreateBasePointMultiplier().Multiply(parameters.G, d);
|
|
|
|
if (publicKeyParamSet != null)
|
|
{
|
|
return new AsymmetricCipherKeyPair(
|
|
#pragma warning disable CS0612 // ���ͻ���Ա�ѹ�ʱ
|
|
new ECPublicKeyParameters(algorithm, q, publicKeyParamSet),
|
|
#pragma warning restore CS0612 // ���ͻ���Ա�ѹ�ʱ
|
|
new ECPrivateKeyParameters(algorithm, d, publicKeyParamSet));
|
|
}
|
|
|
|
return new AsymmetricCipherKeyPair(
|
|
#pragma warning disable CS0612 // ���ͻ���Ա�ѹ�ʱ
|
|
new ECPublicKeyParameters(algorithm, q, parameters),
|
|
#pragma warning restore CS0612 // ���ͻ���Ա�ѹ�ʱ
|
|
new ECPrivateKeyParameters(algorithm, d, parameters));
|
|
}
|
|
|
|
protected virtual ECMultiplier CreateBasePointMultiplier()
|
|
{
|
|
return new FixedPointCombMultiplier();
|
|
}
|
|
|
|
internal static X9ECParameters FindECCurveByOid(DerObjectIdentifier oid)
|
|
{
|
|
// TODO ECGost3410NamedCurves support (returns ECDomainParameters though)
|
|
|
|
X9ECParameters ecP = CustomNamedCurves.GetByOid(oid);
|
|
if (ecP == null)
|
|
{
|
|
ecP = ECNamedCurveTable.GetByOid(oid);
|
|
}
|
|
return ecP;
|
|
}
|
|
|
|
internal static ECPublicKeyParameters GetCorrespondingPublicKey(
|
|
ECPrivateKeyParameters privKey)
|
|
{
|
|
ECDomainParameters ec = privKey.Parameters;
|
|
ECPoint q = new FixedPointCombMultiplier().Multiply(ec.G, privKey.D);
|
|
|
|
if (privKey.PublicKeyParamSet != null)
|
|
{
|
|
#pragma warning disable CS0612 // ���ͻ���Ա�ѹ�ʱ
|
|
return new ECPublicKeyParameters(privKey.AlgorithmName, q, privKey.PublicKeyParamSet);
|
|
#pragma warning restore CS0612 // ���ͻ���Ա�ѹ�ʱ
|
|
}
|
|
|
|
#pragma warning disable CS0612 // ���ͻ���Ա�ѹ�ʱ
|
|
return new ECPublicKeyParameters(privKey.AlgorithmName, q, ec);
|
|
#pragma warning restore CS0612 // ���ͻ���Ա�ѹ�ʱ
|
|
}
|
|
}
|
|
}
|
|
|