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