Botan 3.12.0
Crypto and TLS for C&
dl_group.h
Go to the documentation of this file.
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
15namespace Botan {
16
19class DL_Group_Data;
20
26
27/**
28* The DL group encoding format variants.
29*/
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*/
46class BOTAN_PUBLIC_API(2, 0) DL_Group final {
47 public:
48 /**
49 * Determine the prime creation for DL groups.
50 */
51 enum PrimeType : uint8_t /* NOLINT(*-use-enum-class) */ { Strong, Prime_Subgroup, DSA_Kosherizer };
52
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 BOTAN_DEPRECATED("Use from_PEM") static DL_Group DL_Group_from_PEM(std::string_view pem) {
86 return DL_Group::from_PEM(pem);
87 }
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 DER-encoded DL group param
130 */
131 DL_Group(const uint8_t der[], size_t der_len, DL_Group_Format format) : DL_Group({der, der_len}, format) {}
132
133 /**
134 * Decode a DER-encoded DL group param
135 */
136 DL_Group(std::span<const uint8_t> der, DL_Group_Format format);
137
138 /**
139 * Get the prime p.
140 * @return prime p
141 */
142 const BigInt& get_p() const;
143
144 /**
145 * Get the prime q, returns zero if q is not used
146 * @return prime q
147 */
148 const BigInt& get_q() const;
149
150 /**
151 * Get the base g.
152 * @return base g
153 */
154 const BigInt& get_g() const;
155
156 /**
157 * Perform validity checks on the group.
158 * @param rng the rng to use
159 * @param strong whether to perform stronger by lengthier tests
160 * @return true if the object is consistent, false otherwise
161 */
162 bool verify_group(RandomNumberGenerator& rng, bool strong = true) const;
163
164 /**
165 * Verify a public element, ie check if y = g^x for some x.
166 *
167 * This is not a perfect test. It verifies that 1 < y < p and (if q is set)
168 * that y is in the subgroup of size q.
169 */
170 bool verify_public_element(const BigInt& y) const;
171
172 /**
173 * Verify a private element
174 *
175 * Specifically this checks that x is > 1 and < p, and additionally if
176 * q is set then x must be < q
177 */
178 bool verify_private_element(const BigInt& x) const;
179
180 /**
181 * Verify a pair of elements y = g^x
182 *
183 * This verifies that 1 < x,y < p and that y=g^x mod p
184 */
185 BOTAN_DEPRECATED("Deprecated no replacement") bool verify_element_pair(const BigInt& y, const BigInt& x) const;
186
187 /**
188 * Encode this group into a string using PEM encoding.
189 * @param format the encoding format
190 * @return string holding the PEM encoded group
191 */
192 std::string PEM_encode(DL_Group_Format format) const;
193
194 /**
195 * Encode this group into a string using DER encoding.
196 * @param format the encoding format
197 * @return string holding the DER encoded group
198 */
199 std::vector<uint8_t> DER_encode(DL_Group_Format format) const;
200
201 /**
202 * Reduce an integer modulo p
203 * @return x % p
204 */
205 BigInt mod_p(const BigInt& x) const;
206
207 /**
208 * Multiply and reduce an integer modulo p
209 * @return (x*y) % p
210 */
211 BigInt multiply_mod_p(const BigInt& x, const BigInt& y) const;
212
213 /**
214 * Return the inverse of x mod p
215 */
216 BigInt inverse_mod_p(const BigInt& x) const;
217
218 /**
219 * Reduce an integer modulo q
220 * Throws if q is unset on this DL_Group
221 * @return x % q
222 */
223 BigInt mod_q(const BigInt& x) const;
224
225 /**
226 * Multiply and reduce an integer modulo q
227 * Throws if q is unset on this DL_Group
228 * @return (x*y) % q
229 */
230 BigInt multiply_mod_q(const BigInt& x, const BigInt& y) const;
231
232 /**
233 * Multiply and reduce an integer modulo q
234 * Throws if q is unset on this DL_Group
235 * @return (x*y*z) % q
236 */
237 BigInt multiply_mod_q(const BigInt& x, const BigInt& y, const BigInt& z) const;
238
239 /**
240 * Square and reduce an integer modulo q
241 * Throws if q is unset on this DL_Group
242 * @return (x*x) % q
243 */
244 BigInt square_mod_q(const BigInt& x) const;
245
246 /**
247 * Return the inverse of x mod q
248 * Throws if q is unset on this DL_Group
249 */
250 BigInt inverse_mod_q(const BigInt& x) const;
251
252 /**
253 * Modular exponentiation
254 *
255 * @warning this function leaks the size of x via the number of
256 * loop iterations. Use the version taking the maximum size to
257 * avoid this.
258 *
259 * @return (g^x) % p
260 */
261 BOTAN_DEPRECATED("Use version taking bitlength upper bound") inline BigInt power_g_p(const BigInt& x) const {
262 return power_g_p(x, x.bits());
263 }
264
265 /**
266 * Modular exponentiation
267 * @param x the exponent
268 * @param max_x_bits x is assumed to be at most this many bits long.
269 *
270 * @return (g^x) % p
271 */
272 BigInt power_g_p(const BigInt& x, size_t max_x_bits) const;
273
274 /**
275 * Modular exponentiation
276 * @param b the base
277 * @param x the exponent
278 * @param max_x_bits x is assumed to be at most this many bits long.
279 *
280 * @return (b^x) % p
281 */
282 BigInt power_b_p(const BigInt& b, const BigInt& x, size_t max_x_bits) const;
283
284 /**
285 * Modular exponentiation
286 * @param b the base
287 * @param x the exponent
288 *
289 * @return (b^x) % p
290 */
291 BigInt power_b_p(const BigInt& b, const BigInt& x) const;
292
293 /**
294 * Multi-exponentiate
295 * Return (g^x * y^z) % p
296 *
297 * @warning this function is variable time and should not be used with secret inputs
298 */
299 BigInt multi_exponentiate(const BigInt& x, const BigInt& y, const BigInt& z) const;
300
301 /**
302 * Return the size of p in bits
303 * Same as get_p().bits()
304 */
305 size_t p_bits() const;
306
307 /**
308 * Return the size of p in bytes
309 * Same as get_p().bytes()
310 */
311 size_t p_bytes() const;
312
313 /**
314 * Return the size of q in bits
315 * Same as get_q().bits()
316 * Throws if q is unset
317 */
318 size_t q_bits() const;
319
320 /**
321 * Return the size of q in bytes
322 * Same as get_q().bytes()
323 * Throws if q is unset
324 */
325 size_t q_bytes() const;
326
327 /**
328 * Return if the q value is set
329 */
330 bool has_q() const;
331
332 /**
333 * Return size in bits of a secret exponent
334 *
335 * This attempts to balance between the attack costs of NFS
336 * (which depends on the size of the modulus) and Pollard's rho
337 * (which depends on the size of the exponent).
338 *
339 * It may vary over time for a particular group, if the attack
340 * costs change.
341 */
342 size_t exponent_bits() const;
343
344 /**
345 * Return an estimate of the strength of this group against
346 * discrete logarithm attacks (eg NFS). Warning: since this only
347 * takes into account known attacks it is by necessity an
348 * overestimate of the actual strength.
349 */
350 size_t estimated_strength() const;
351
352 /**
353 * Decode a DER encoded group into this instance.
354 * @param der a vector containing the DER encoded group
355 * @param format the format of the encoded group
356 *
357 * @warning avoid this. Instead use the DL_Group constructor
358 */
359 BOTAN_DEPRECATED("Use DL_Group constructor taking DER encoding")
360 void BER_decode(const std::vector<uint8_t>& der, DL_Group_Format format) {
361 *this = DL_Group(der, format);
362 }
363
364 DL_Group_Source source() const;
365
366 /*
367 * For internal use only
368 * TODO(Botan4) Underscore prefix this
369 */
370 static std::shared_ptr<DL_Group_Data> DL_group_info(std::string_view name);
371
372 /**
373 * Return parameters for Montgomery reduction/exponentiation mod p
374 *
375 * For internal use only
376 */
377 const Montgomery_Params& _monty_params_p() const;
378
379 /*
380 * For internal use only
381 */
382 const Barrett_Reduction& _reducer_mod_p() const;
383
384 private:
385 explicit DL_Group(std::shared_ptr<DL_Group_Data> data) : m_data(std::move(data)) {}
386
387 static std::shared_ptr<DL_Group_Data> load_DL_group_info(const char* p_str, const char* q_str, const char* g_str);
388
389 static std::shared_ptr<DL_Group_Data> load_DL_group_info(const char* p_str, const char* g_str);
390
391 static std::shared_ptr<DL_Group_Data> DER_decode_DL_group(std::span<const uint8_t> data,
392 DL_Group_Format format,
393 DL_Group_Source source);
394
395 const DL_Group_Data& data() const;
396 std::shared_ptr<DL_Group_Data> m_data;
397};
398
399} // namespace Botan
400
401#endif
#define BOTAN_PUBLIC_API(maj, min)
Definition api.h:21
#define BOTAN_DEPRECATED(msg)
Definition api.h:73
BigInt power_g_p(const BigInt &x) const
Definition dl_group.h:261
static DL_Group from_PEM(std::string_view pem)
Definition dl_group.cpp:273
DL_Group(const uint8_t der[], size_t der_len, DL_Group_Format format)
Definition dl_group.h:131
void BER_decode(const std::vector< uint8_t > &der, DL_Group_Format format)
Definition dl_group.h:360
static DL_Group DL_Group_from_PEM(std::string_view pem)
Definition dl_group.h:85
static DL_Group from_name(std::string_view name)
Definition dl_group.cpp:262
DL_Group_Format Format
Definition dl_group.h:53
DL_Group()=default
EC_Point multi_exponentiate(const EC_Point &p1, const BigInt &z1, const EC_Point &p2, const BigInt &z2)
Definition point_mul.cpp:36
DL_Group_Format
Definition dl_group.h:30
DL_Group_Source
Definition dl_group.h:21