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            BigInteger bigL = BigInteger.valueOf(2L ^ (l - 1));
88            if (bigL.compareTo(p) == 1)
89            {
90                throw new IllegalArgumentException("when l value specified, it must satisfy 2^(l-1) <= p");
91            }
92            if (l < m)
93            {
94                throw new IllegalArgumentException("when l value specified, it may not be less than m value");
95            }
96        }
97
98        this.g = g;
99        this.p = p;
100        this.q = q;
101        this.m = m;
102        this.l = l;
103        this.j = j;
104        this.validation = validation;
105    }
106
107    public BigInteger getP()
108    {
109        return p;
110    }
111
112    public BigInteger getG()
113    {
114        return g;
115    }
116
117    public BigInteger getQ()
118    {
119        return q;
120    }
121
122    /**
123     * Return the subgroup factor J.
124     *
125     * @return subgroup factor
126     */
127    public BigInteger getJ()
128    {
129        return j;
130    }
131
132    /**
133     * Return the minimum length of the private value.
134     *
135     * @return the minimum length of the private value in bits.
136     */
137    public int getM()
138    {
139        return m;
140    }
141
142    /**
143     * Return the private value length in bits - if set, zero otherwise
144     *
145     * @return the private value length in bits, zero otherwise.
146     */
147    public int getL()
148    {
149        return l;
150    }
151
152    public DHValidationParameters getValidationParameters()
153    {
154        return validation;
155    }
156
157    public boolean equals(
158        Object  obj)
159    {
160        if (!(obj instanceof DHParameters))
161        {
162            return false;
163        }
164
165        DHParameters    pm = (DHParameters)obj;
166
167        if (this.getQ() != null)
168        {
169            if (!this.getQ().equals(pm.getQ()))
170            {
171                return false;
172            }
173        }
174        else
175        {
176            if (pm.getQ() != null)
177            {
178                return false;
179            }
180        }
181
182        return pm.getP().equals(p) && pm.getG().equals(g);
183    }
184
185    public int hashCode()
186    {
187        return getP().hashCode() ^ getG().hashCode() ^ (getQ() != null ? getQ().hashCode() : 0);
188    }
189}
190