summary refs log tree commit diff
path: root/Crypto/src/crypto/generators/DsaKeyPairGenerator.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Crypto/src/crypto/generators/DsaKeyPairGenerator.cs')
-rw-r--r--Crypto/src/crypto/generators/DsaKeyPairGenerator.cs61
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);
+		}
+	}
+}