1package org.bouncycastle.crypto.params;
2
3import java.math.BigInteger;
4
5import org.bouncycastle.crypto.CipherParameters;
6
7public class DHParameters
8    implements CipherParameters
9{
10    private static final int DEFAULT_MINIMUM_LENGTH = 160;
11
12    // not final due to compiler bug in "simpler" JDKs
13    private BigInteger              g;
14    private BigInteger              p;
15    private BigInteger              q;
16    private BigInteger              j;
17    private int                     m;
18    private int                     l;
19    private DHValidationParameters  validation;
20
21    private static int getDefaultMParam(
22        int lParam)
23    {
24        if (lParam == 0)
25        {
26            return DEFAULT_MINIMUM_LENGTH;
27        }
28
29        return lParam < DEFAULT_MINIMUM_LENGTH ? lParam : DEFAULT_MINIMUM_LENGTH;
30    }
31
32    public DHParameters(
33        BigInteger  p,
34        BigInteger  g)
35    {
36        this(p, g, null, 0);
37    }
38
39    public DHParameters(
40        BigInteger  p,
41        BigInteger  g,
42        BigInteger  q)
43    {
44        this(p, g, q, 0);
45    }
46
47    public DHParameters(
48        BigInteger  p,
49        BigInteger  g,
50        BigInteger  q,
51        int         l)
52    {
53        this(p, g, q, getDefaultMParam(l), l, null, null);
54    }
55
56    public DHParameters(
57        BigInteger  p,
58        BigInteger  g,
59        BigInteger  q,
60        int         m,
61        int         l)
62    {
63        this(p, g, q, m, l, null, null);
64    }
65
66    public DHParameters(
67        BigInteger              p,
68        BigInteger              g,
69        BigInteger              q,
70        BigInteger              j,
71        DHValidationParameters  validation)
72    {
73        this(p, g, q, DEFAULT_MINIMUM_LENGTH, 0, j, validation);
74    }
75
76    public DHParameters(
77        BigInteger              p,
78        BigInteger              g,
79        BigInteger              q,
80        int                     m,
81        int                     l,
82        BigInteger              j,
83        DHValidationParameters  validation)
84    {
85        if (l != 0)
86        {
87            if (l > p.bitLength())
88            {
89                throw new IllegalArgumentException("when l value specified, it must satisfy 2^(l-1) <= p");
90            }
91            if (l < m)
92            {
93                throw new IllegalArgumentException("when l value specified, it may not be less than m value");
94            }
95        }
96
97        this.g = g;
98        this.p = p;
99        this.q = q;
100        this.m = m;
101        this.l = l;
102        this.j = j;
103        this.validation = validation;
104    }
105
106    public BigInteger getP()
107    {
108        return p;
109    }
110
111    public BigInteger getG()
112    {
113        return g;
114    }
115
116    public BigInteger getQ()
117    {
118        return q;
119    }
120
121    /**
122     * Return the subgroup factor J.
123     *
124     * @return subgroup factor
125     */
126    public BigInteger getJ()
127    {
128        return j;
129    }
130
131    /**
132     * Return the minimum length of the private value.
133     *
134     * @return the minimum length of the private value in bits.
135     */
136    public int getM()
137    {
138        return m;
139    }
140
141    /**
142     * Return the private value length in bits - if set, zero otherwise
143     *
144     * @return the private value length in bits, zero otherwise.
145     */
146    public int getL()
147    {
148        return l;
149    }
150
151    public DHValidationParameters getValidationParameters()
152    {
153        return validation;
154    }
155
156    public boolean equals(
157        Object  obj)
158    {
159        if (!(obj instanceof DHParameters))
160        {
161            return false;
162        }
163
164        DHParameters    pm = (DHParameters)obj;
165
166        if (this.getQ() != null)
167        {
168            if (!this.getQ().equals(pm.getQ()))
169            {
170                return false;
171            }
172        }
173        else
174        {
175            if (pm.getQ() != null)
176            {
177                return false;
178            }
179        }
180
181        return pm.getP().equals(p) && pm.getG().equals(g);
182    }
183
184    public int hashCode()
185    {
186        return getP().hashCode() ^ getG().hashCode() ^ (getQ() != null ? getQ().hashCode() : 0);
187    }
188}
189