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