Coverage Report

Created: 2021-02-21 07:20

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