74 lines
1.8 KiB
C#
74 lines
1.8 KiB
C#
using System;
|
|
|
|
using Org.BouncyCastle.Asn1.CryptoPro;
|
|
using Org.BouncyCastle.Crypto.Parameters;
|
|
using Org.BouncyCastle.Math;
|
|
using Org.BouncyCastle.Security;
|
|
|
|
namespace Org.BouncyCastle.Crypto.Generators
|
|
{
|
|
/**
|
|
* a GOST3410 key pair generator.
|
|
* This generates GOST3410 keys in line with the method described
|
|
* in GOST R 34.10-94.
|
|
*/
|
|
public class Gost3410KeyPairGenerator
|
|
: IAsymmetricCipherKeyPairGenerator
|
|
{
|
|
private Gost3410KeyGenerationParameters param;
|
|
|
|
public void Init(
|
|
KeyGenerationParameters parameters)
|
|
{
|
|
if (parameters is Gost3410KeyGenerationParameters)
|
|
{
|
|
this.param = (Gost3410KeyGenerationParameters) parameters;
|
|
}
|
|
else
|
|
{
|
|
Gost3410KeyGenerationParameters kgp = new Gost3410KeyGenerationParameters(
|
|
parameters.Random,
|
|
CryptoProObjectIdentifiers.GostR3410x94CryptoProA);
|
|
|
|
if (parameters.Strength != kgp.Parameters.P.BitLength - 1)
|
|
{
|
|
// TODO Should we complain?
|
|
}
|
|
|
|
this.param = kgp;
|
|
}
|
|
}
|
|
|
|
public AsymmetricCipherKeyPair GenerateKeyPair()
|
|
{
|
|
SecureRandom random = param.Random;
|
|
Gost3410Parameters gost3410Params = param.Parameters;
|
|
|
|
BigInteger q = gost3410Params.Q;
|
|
BigInteger x;
|
|
do
|
|
{
|
|
x = new BigInteger(256, random);
|
|
}
|
|
while (x.SignValue < 1 || x.CompareTo(q) >= 0);
|
|
|
|
BigInteger p = gost3410Params.P;
|
|
BigInteger a = gost3410Params.A;
|
|
|
|
// calculate the public key.
|
|
BigInteger y = a.ModPow(x, p);
|
|
|
|
if (param.PublicKeyParamSet != null)
|
|
{
|
|
return new AsymmetricCipherKeyPair(
|
|
new Gost3410PublicKeyParameters(y, param.PublicKeyParamSet),
|
|
new Gost3410PrivateKeyParameters(x, param.PublicKeyParamSet));
|
|
}
|
|
|
|
return new AsymmetricCipherKeyPair(
|
|
new Gost3410PublicKeyParameters(y, gost3410Params),
|
|
new Gost3410PrivateKeyParameters(x, gost3410Params));
|
|
}
|
|
}
|
|
}
|