diff options
Diffstat (limited to 'Crypto/src/crypto/generators/DsaKeyPairGenerator.cs')
-rw-r--r-- | Crypto/src/crypto/generators/DsaKeyPairGenerator.cs | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/Crypto/src/crypto/generators/DsaKeyPairGenerator.cs b/Crypto/src/crypto/generators/DsaKeyPairGenerator.cs new file mode 100644 index 000000000..bb8ec591b --- /dev/null +++ b/Crypto/src/crypto/generators/DsaKeyPairGenerator.cs @@ -0,0 +1,61 @@ +using System; +using Org.BouncyCastle.Math; +using Org.BouncyCastle.Security; +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Parameters; +using Org.BouncyCastle.Utilities; + +namespace Org.BouncyCastle.Crypto.Generators +{ + /** + * a DSA key pair generator. + * + * This Generates DSA keys in line with the method described + * in <i>FIPS 186-3 B.1 FFC Key Pair Generation</i>. + */ + public class DsaKeyPairGenerator + : IAsymmetricCipherKeyPairGenerator + { + private DsaKeyGenerationParameters param; + + public void Init( + KeyGenerationParameters parameters) + { + if (parameters == null) + throw new ArgumentNullException("parameters"); + + // Note: If we start accepting instances of KeyGenerationParameters, + // must apply constraint checking on strength (see DsaParametersGenerator.Init) + + this.param = (DsaKeyGenerationParameters) parameters; + } + + public AsymmetricCipherKeyPair GenerateKeyPair() + { + DsaParameters dsaParams = param.Parameters; + + BigInteger x = GeneratePrivateKey(dsaParams.Q, param.Random); + BigInteger y = CalculatePublicKey(dsaParams.P, dsaParams.G, x); + + return new AsymmetricCipherKeyPair( + new DsaPublicKeyParameters(y, dsaParams), + new DsaPrivateKeyParameters(x, dsaParams)); + } + + private static BigInteger GeneratePrivateKey(BigInteger q, SecureRandom random) + { + // TODO Prefer this method? (change test cases that used fixed random) + // B.1.1 Key Pair Generation Using Extra Random Bits +// BigInteger c = new BigInteger(q.BitLength + 64, random); +// return c.Mod(q.Subtract(BigInteger.One)).Add(BigInteger.One); + + // B.1.2 Key Pair Generation by Testing Candidates + return BigIntegers.CreateRandomInRange(BigInteger.One, q.Subtract(BigInteger.One), random); + } + + private static BigInteger CalculatePublicKey(BigInteger p, BigInteger g, BigInteger x) + { + return g.ModPow(x, p); + } + } +} |