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)); } } }