1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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);
}
}
}
|