/src/botan/build/include/botan/dl_group.h
Line | Count | Source |
1 | | /* |
2 | | * Discrete Logarithm Group |
3 | | * (C) 1999-2008,2018 Jack Lloyd |
4 | | * |
5 | | * Botan is released under the Simplified BSD License (see license.txt) |
6 | | */ |
7 | | |
8 | | #ifndef BOTAN_DL_PARAM_H_ |
9 | | #define BOTAN_DL_PARAM_H_ |
10 | | |
11 | | #include <botan/bigint.h> |
12 | | |
13 | | namespace Botan { |
14 | | |
15 | | class Montgomery_Params; |
16 | | class DL_Group_Data; |
17 | | |
18 | | /** |
19 | | * This class represents discrete logarithm groups. It holds a prime |
20 | | * modulus p, a generator g, and (optionally) a prime q which is a |
21 | | * factor of (p-1). In most cases g generates the order-q subgroup. |
22 | | */ |
23 | | class BOTAN_PUBLIC_API(2,0) DL_Group final |
24 | | { |
25 | | public: |
26 | | /** |
27 | | * Determine the prime creation for DL groups. |
28 | | */ |
29 | | enum PrimeType { Strong, Prime_Subgroup, DSA_Kosherizer }; |
30 | | |
31 | | /** |
32 | | * The DL group encoding format variants. |
33 | | */ |
34 | | enum Format { |
35 | | ANSI_X9_42, |
36 | | ANSI_X9_57, |
37 | | PKCS_3, |
38 | | |
39 | | DSA_PARAMETERS = ANSI_X9_57, |
40 | | DH_PARAMETERS = ANSI_X9_42, |
41 | | ANSI_X9_42_DH_PARAMETERS = ANSI_X9_42, |
42 | | PKCS3_DH_PARAMETERS = PKCS_3 |
43 | | }; |
44 | | |
45 | | /** |
46 | | * Construct a DL group with uninitialized internal value. |
47 | | * Use this constructor is you wish to set the groups values |
48 | | * from a DER or PEM encoded group. |
49 | | */ |
50 | 2.10k | DL_Group() = default; |
51 | | |
52 | | /** |
53 | | * Construct a DL group that is registered in the configuration. |
54 | | * @param name the name that is configured in the global configuration |
55 | | * for the desired group. If no configuration file is specified, |
56 | | * the default values from the file policy.cpp will be used. For instance, |
57 | | * use "modp/ietf/3072". |
58 | | */ |
59 | | explicit DL_Group(const std::string& name); |
60 | | |
61 | | /** |
62 | | * Create a new group randomly. |
63 | | * @param rng the random number generator to use |
64 | | * @param type specifies how the creation of primes p and q shall |
65 | | * be performed. If type=Strong, then p will be determined as a |
66 | | * safe prime, and q will be chosen as (p-1)/2. If |
67 | | * type=Prime_Subgroup and qbits = 0, then the size of q will be |
68 | | * determined according to the estimated difficulty of the DL |
69 | | * problem. If type=DSA_Kosherizer, DSA primes will be created. |
70 | | * @param pbits the number of bits of p |
71 | | * @param qbits the number of bits of q. Leave it as 0 to have |
72 | | * the value determined according to pbits. |
73 | | */ |
74 | | DL_Group(RandomNumberGenerator& rng, PrimeType type, |
75 | | size_t pbits, size_t qbits = 0); |
76 | | |
77 | | /** |
78 | | * Create a DSA group with a given seed. |
79 | | * @param rng the random number generator to use |
80 | | * @param seed the seed to use to create the random primes |
81 | | * @param pbits the desired bit size of the prime p |
82 | | * @param qbits the desired bit size of the prime q. |
83 | | */ |
84 | | DL_Group(RandomNumberGenerator& rng, |
85 | | const std::vector<uint8_t>& seed, |
86 | | size_t pbits = 1024, size_t qbits = 0); |
87 | | |
88 | | /** |
89 | | * Create a DL group. |
90 | | * @param p the prime p |
91 | | * @param g the base g |
92 | | */ |
93 | | DL_Group(const BigInt& p, const BigInt& g); |
94 | | |
95 | | /** |
96 | | * Create a DL group. |
97 | | * @param p the prime p |
98 | | * @param q the prime q |
99 | | * @param g the base g |
100 | | */ |
101 | | DL_Group(const BigInt& p, const BigInt& q, const BigInt& g); |
102 | | |
103 | | /** |
104 | | * Decode a BER-encoded DL group param |
105 | | */ |
106 | | DL_Group(const uint8_t ber[], size_t ber_len, Format format); |
107 | | |
108 | | /** |
109 | | * Decode a BER-encoded DL group param |
110 | | */ |
111 | | template<typename Alloc> |
112 | | DL_Group(const std::vector<uint8_t, Alloc>& ber, Format format) : |
113 | 307 | DL_Group(ber.data(), ber.size(), format) {} |
114 | | |
115 | | /** |
116 | | * Get the prime p. |
117 | | * @return prime p |
118 | | */ |
119 | | const BigInt& get_p() const; |
120 | | |
121 | | /** |
122 | | * Get the prime q, returns zero if q is not used |
123 | | * @return prime q |
124 | | */ |
125 | | const BigInt& get_q() const; |
126 | | |
127 | | /** |
128 | | * Get the base g. |
129 | | * @return base g |
130 | | */ |
131 | | const BigInt& get_g() const; |
132 | | |
133 | | /** |
134 | | * Perform validity checks on the group. |
135 | | * @param rng the rng to use |
136 | | * @param strong whether to perform stronger by lengthier tests |
137 | | * @return true if the object is consistent, false otherwise |
138 | | */ |
139 | | bool verify_group(RandomNumberGenerator& rng, bool strong = true) const; |
140 | | |
141 | | /** |
142 | | * Verify a public element, ie check if y = g^x for some x. |
143 | | * |
144 | | * This is not a perfect test. It verifies that 1 < y < p and (if q is set) |
145 | | * that y is in the subgroup of size q. |
146 | | */ |
147 | | bool verify_public_element(const BigInt& y) const; |
148 | | |
149 | | /** |
150 | | * Verify a pair of elements y = g^x |
151 | | * |
152 | | * This verifies that 1 < x,y < p and that y=g^x mod p |
153 | | */ |
154 | | bool verify_element_pair(const BigInt& y, const BigInt& x) const; |
155 | | |
156 | | /** |
157 | | * Encode this group into a string using PEM encoding. |
158 | | * @param format the encoding format |
159 | | * @return string holding the PEM encoded group |
160 | | */ |
161 | | std::string PEM_encode(Format format) const; |
162 | | |
163 | | /** |
164 | | * Encode this group into a string using DER encoding. |
165 | | * @param format the encoding format |
166 | | * @return string holding the DER encoded group |
167 | | */ |
168 | | std::vector<uint8_t> DER_encode(Format format) const; |
169 | | |
170 | | /** |
171 | | * Reduce an integer modulo p |
172 | | * @return x % p |
173 | | */ |
174 | | BigInt mod_p(const BigInt& x) const; |
175 | | |
176 | | /** |
177 | | * Multiply and reduce an integer modulo p |
178 | | * @return (x*y) % p |
179 | | */ |
180 | | BigInt multiply_mod_p(const BigInt& x, const BigInt& y) const; |
181 | | |
182 | | /** |
183 | | * Return the inverse of x mod p |
184 | | */ |
185 | | BigInt inverse_mod_p(const BigInt& x) const; |
186 | | |
187 | | /** |
188 | | * Reduce an integer modulo q |
189 | | * Throws if q is unset on this DL_Group |
190 | | * @return x % q |
191 | | */ |
192 | | BigInt mod_q(const BigInt& x) const; |
193 | | |
194 | | /** |
195 | | * Multiply and reduce an integer modulo q |
196 | | * Throws if q is unset on this DL_Group |
197 | | * @return (x*y) % q |
198 | | */ |
199 | | BigInt multiply_mod_q(const BigInt& x, const BigInt& y) const; |
200 | | |
201 | | /** |
202 | | * Multiply and reduce an integer modulo q |
203 | | * Throws if q is unset on this DL_Group |
204 | | * @return (x*y*z) % q |
205 | | */ |
206 | | BigInt multiply_mod_q(const BigInt& x, const BigInt& y, const BigInt& z) const; |
207 | | |
208 | | /** |
209 | | * Square and reduce an integer modulo q |
210 | | * Throws if q is unset on this DL_Group |
211 | | * @return (x*x) % q |
212 | | */ |
213 | | BigInt square_mod_q(const BigInt& x) const; |
214 | | |
215 | | /** |
216 | | * Return the inverse of x mod q |
217 | | * Throws if q is unset on this DL_Group |
218 | | */ |
219 | | BigInt inverse_mod_q(const BigInt& x) const; |
220 | | |
221 | | /** |
222 | | * Modular exponentiation |
223 | | * |
224 | | * @warning this function leaks the size of x via the number of |
225 | | * loop iterations. Use the version taking the maximum size to |
226 | | * avoid this. |
227 | | * |
228 | | * @return (g^x) % p |
229 | | */ |
230 | | BigInt power_g_p(const BigInt& x) const; |
231 | | |
232 | | /** |
233 | | * Modular exponentiation |
234 | | * @param x the exponent |
235 | | * @param max_x_bits x is assumed to be at most this many bits long. |
236 | | * |
237 | | * @return (g^x) % p |
238 | | */ |
239 | | BigInt power_g_p(const BigInt& x, size_t max_x_bits) const; |
240 | | |
241 | | /** |
242 | | * Multi-exponentiate |
243 | | * Return (g^x * y^z) % p |
244 | | */ |
245 | | BigInt multi_exponentiate(const BigInt& x, const BigInt& y, const BigInt& z) const; |
246 | | |
247 | | /** |
248 | | * Return parameters for Montgomery reduction/exponentiation mod p |
249 | | */ |
250 | | std::shared_ptr<const Montgomery_Params> monty_params_p() const; |
251 | | |
252 | | /** |
253 | | * Return the size of p in bits |
254 | | * Same as get_p().bits() |
255 | | */ |
256 | | size_t p_bits() const; |
257 | | |
258 | | /** |
259 | | * Return the size of p in bytes |
260 | | * Same as get_p().bytes() |
261 | | */ |
262 | | size_t p_bytes() const; |
263 | | |
264 | | /** |
265 | | * Return the size of q in bits |
266 | | * Same as get_q().bits() |
267 | | * Throws if q is unset |
268 | | */ |
269 | | size_t q_bits() const; |
270 | | |
271 | | /** |
272 | | * Return the size of q in bytes |
273 | | * Same as get_q().bytes() |
274 | | * Throws if q is unset |
275 | | */ |
276 | | size_t q_bytes() const; |
277 | | |
278 | | /** |
279 | | * Return size in bits of a secret exponent |
280 | | * |
281 | | * This attempts to balance between the attack costs of NFS |
282 | | * (which depends on the size of the modulus) and Pollard's rho |
283 | | * (which depends on the size of the exponent). |
284 | | * |
285 | | * It may vary over time for a particular group, if the attack |
286 | | * costs change. |
287 | | */ |
288 | | size_t exponent_bits() const; |
289 | | |
290 | | /** |
291 | | * Return an estimate of the strength of this group against |
292 | | * discrete logarithm attacks (eg NFS). Warning: since this only |
293 | | * takes into account known attacks it is by necessity an |
294 | | * overestimate of the actual strength. |
295 | | */ |
296 | | size_t estimated_strength() const; |
297 | | |
298 | | /** |
299 | | * Decode a DER/BER encoded group into this instance. |
300 | | * @param ber a vector containing the DER/BER encoded group |
301 | | * @param format the format of the encoded group |
302 | | */ |
303 | | void BER_decode(const std::vector<uint8_t>& ber, Format format); |
304 | | |
305 | | /** |
306 | | * Decode a PEM encoded group into this instance. |
307 | | * @param pem the PEM encoding of the group |
308 | | */ |
309 | | void PEM_decode(const std::string& pem); |
310 | | |
311 | | /** |
312 | | * Return PEM representation of named DL group |
313 | | */ |
314 | | static std::string BOTAN_DEPRECATED("Use DL_Group(name).PEM_encode()") |
315 | | PEM_for_named_group(const std::string& name); |
316 | | |
317 | | /* |
318 | | * For internal use only |
319 | | */ |
320 | | static std::shared_ptr<DL_Group_Data> DL_group_info(const std::string& name); |
321 | | |
322 | | private: |
323 | | static std::shared_ptr<DL_Group_Data> load_DL_group_info(const char* p_str, |
324 | | const char* q_str, |
325 | | const char* g_str); |
326 | | |
327 | | static std::shared_ptr<DL_Group_Data> load_DL_group_info(const char* p_str, |
328 | | const char* g_str); |
329 | | |
330 | | static std::shared_ptr<DL_Group_Data> |
331 | | BER_decode_DL_group(const uint8_t data[], size_t data_len, DL_Group::Format format); |
332 | | |
333 | | const DL_Group_Data& data() const; |
334 | | std::shared_ptr<DL_Group_Data> m_data; |
335 | | }; |
336 | | |
337 | | } |
338 | | |
339 | | #endif |