Coverage Report

Created: 2022-06-23 06:44

/src/botan/build/include/botan/ec_group.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
* ECC Domain Parameters
3
*
4
* (C) 2007 Falko Strenzke, FlexSecure GmbH
5
*     2008-2010 Jack Lloyd
6
*
7
* Botan is released under the Simplified BSD License (see license.txt)
8
*/
9
10
#ifndef BOTAN_ECC_DOMAIN_PARAMETERS_H_
11
#define BOTAN_ECC_DOMAIN_PARAMETERS_H_
12
13
#include <botan/point_gfp.h>
14
#include <botan/asn1_obj.h>
15
#include <memory>
16
#include <set>
17
18
namespace Botan {
19
20
/**
21
* This class represents elliptic curce domain parameters
22
*/
23
enum class EC_Group_Encoding {
24
   Explicit,
25
   ImplicitCA,
26
   NamedCurve,
27
28
   EC_DOMPAR_ENC_EXPLICIT = Explicit,
29
   EC_DOMPAR_ENC_IMPLICITCA = ImplicitCA,
30
   EC_DOMPAR_ENC_OID = NamedCurve
31
};
32
33
enum class EC_Group_Source {
34
   Builtin,
35
   ExternalSource,
36
};
37
38
class CurveGFp;
39
40
class EC_Group_Data;
41
class EC_Group_Data_Map;
42
43
/**
44
* Class representing an elliptic curve
45
*
46
* The internal representation is stored in a shared_ptr, so copying an
47
* EC_Group is inexpensive.
48
*/
49
class BOTAN_PUBLIC_API(2,0) EC_Group final
50
   {
51
   public:
52
53
      /**
54
      * Construct Domain paramers from specified parameters
55
      * @param p the elliptic curve p
56
      * @param a the elliptic curve a param
57
      * @param b the elliptic curve b param
58
      * @param base_x the x coordinate of the base point
59
      * @param base_y the y coordinate of the base point
60
      * @param order the order of the base point
61
      * @param cofactor the cofactor
62
      * @param oid an optional OID used to identify this curve
63
      */
64
      EC_Group(const BigInt& p,
65
               const BigInt& a,
66
               const BigInt& b,
67
               const BigInt& base_x,
68
               const BigInt& base_y,
69
               const BigInt& order,
70
               const BigInt& cofactor,
71
               const OID& oid = OID());
72
73
      /**
74
      * Decode a BER encoded ECC domain parameter set
75
      * @param ber the bytes of the BER encoding
76
      * @param ber_len the length of ber
77
      */
78
      explicit EC_Group(const uint8_t ber[], size_t ber_len);
79
80
      template<typename Alloc>
81
         EC_Group(const std::vector<uint8_t, Alloc>& ber) :
82
4.06k
         EC_Group(ber.data(), ber.size()) {}
83
84
      /**
85
      * Create an EC domain by OID (or throw if unknown)
86
      * @param oid the OID of the EC domain to create
87
      */
88
      explicit EC_Group(const OID& oid);
89
90
      /**
91
      * Create an EC domain from PEM encoding (as from PEM_encode), or
92
      * from an OID name (eg "secp256r1", or "1.2.840.10045.3.1.7")
93
      * @param pem_or_oid PEM-encoded data, or an OID
94
95
      * @warning Support for PEM in this function is deprecated. Use
96
      * EC_Group_from_PEM
97
      */
98
      explicit EC_Group(const std::string& pem_or_oid);
99
100
      static EC_Group EC_Group_from_PEM(const std::string& pem);
101
102
      /**
103
      * Create an uninitialized EC_Group
104
      */
105
      EC_Group();
106
107
      ~EC_Group();
108
109
14.0k
      EC_Group(const EC_Group&) = default;
110
      EC_Group(EC_Group&&) = default;
111
112
18.2k
      EC_Group& operator=(const EC_Group&) = default;
113
2.09k
      EC_Group& operator=(EC_Group&&) = default;
114
115
      /**
116
      * Create the DER encoding of this domain
117
      * @param form of encoding to use
118
      * @returns bytes encododed as DER
119
      */
120
      std::vector<uint8_t> DER_encode(EC_Group_Encoding form) const;
121
122
      /**
123
      * Return the PEM encoding (always in explicit form)
124
      * @return string containing PEM data
125
      */
126
      std::string PEM_encode() const;
127
128
      /**
129
      * Return if a == -3 mod p
130
      */
131
      bool a_is_minus_3() const;
132
133
      /**
134
      * Return if a == 0 mod p
135
      */
136
      bool a_is_zero() const;
137
138
      /**
139
      * Return the size of p in bits (same as get_p().bits())
140
      */
141
      size_t get_p_bits() const;
142
143
      /**
144
      * Return the size of p in bits (same as get_p().bytes())
145
      */
146
      size_t get_p_bytes() const;
147
148
      /**
149
      * Return the size of group order in bits (same as get_order().bits())
150
      */
151
      size_t get_order_bits() const;
152
153
      /**
154
      * Return the size of p in bytes (same as get_order().bytes())
155
      */
156
      size_t get_order_bytes() const;
157
158
      /**
159
      * Return the prime modulus of the field
160
      */
161
      const BigInt& get_p() const;
162
163
      /**
164
      * Return the a parameter of the elliptic curve equation
165
      */
166
      const BigInt& get_a() const;
167
168
      /**
169
      * Return the b parameter of the elliptic curve equation
170
      */
171
      const BigInt& get_b() const;
172
173
      /**
174
      * Return group base point
175
      * @result base point
176
      */
177
      const PointGFp& get_base_point() const;
178
179
      /**
180
      * Return the x coordinate of the base point
181
      */
182
      const BigInt& get_g_x() const;
183
184
      /**
185
      * Return the y coordinate of the base point
186
      */
187
      const BigInt& get_g_y() const;
188
189
      /**
190
      * Return the order of the base point
191
      * @result order of the base point
192
      */
193
      const BigInt& get_order() const;
194
195
      /**
196
      * Return the cofactor
197
      * @result the cofactor
198
      */
199
      const BigInt& get_cofactor() const;
200
201
      /*
202
      * Reduce x modulo the order
203
      */
204
      BigInt mod_order(const BigInt& x) const;
205
206
      /*
207
      * Return inverse of x modulo the order
208
      */
209
      BigInt inverse_mod_order(const BigInt& x) const;
210
211
      /*
212
      * Reduce (x*x) modulo the order
213
      */
214
      BigInt square_mod_order(const BigInt& x) const;
215
216
      /*
217
      * Reduce (x*y) modulo the order
218
      */
219
      BigInt multiply_mod_order(const BigInt& x, const BigInt& y) const;
220
221
      /*
222
      * Reduce (x*y*z) modulo the order
223
      */
224
      BigInt multiply_mod_order(const BigInt& x, const BigInt& y, const BigInt& z) const;
225
226
      /*
227
      * Return x^3 modulo the order
228
      */
229
      inline BigInt cube_mod_order(const BigInt& x) const
230
0
         {
231
0
         return multiply_mod_order(x, square_mod_order(x));
232
0
         }
233
234
      /**
235
      * Check if y is a plausible point on the curve
236
      *
237
      * In particular, checks that it is a point on the curve, not infinity,
238
      * and that it has order matching the group.
239
      */
240
      bool verify_public_element(const PointGFp& y) const;
241
242
      /**
243
      * Return the OID of these domain parameters
244
      * @result the OID
245
      */
246
      const OID& get_curve_oid() const;
247
248
      /**
249
      * Return a point on this curve with the affine values x, y
250
      */
251
      PointGFp point(const BigInt& x, const BigInt& y) const;
252
253
      /**
254
      * Multi exponentiate. Not constant time.
255
      * @return base_point*x + pt*y
256
      */
257
      PointGFp point_multiply(const BigInt& x, const PointGFp& pt, const BigInt& y) const;
258
259
      /**
260
      * Blinded point multiplication, attempts resistance to side channels
261
      * @param k the scalar
262
      * @param rng a random number generator
263
      * @param ws a temp workspace
264
      * @return base_point*k
265
      */
266
      PointGFp blinded_base_point_multiply(const BigInt& k,
267
                                           RandomNumberGenerator& rng,
268
                                           std::vector<BigInt>& ws) const;
269
270
      /**
271
      * Blinded point multiplication, attempts resistance to side channels
272
      * Returns just the x coordinate of the point
273
      *
274
      * @param k the scalar
275
      * @param rng a random number generator
276
      * @param ws a temp workspace
277
      * @return x coordinate of base_point*k
278
      */
279
      BigInt blinded_base_point_multiply_x(const BigInt& k,
280
                                           RandomNumberGenerator& rng,
281
                                           std::vector<BigInt>& ws) const;
282
283
      /**
284
      * Blinded point multiplication, attempts resistance to side channels
285
      * @param point input point
286
      * @param k the scalar
287
      * @param rng a random number generator
288
      * @param ws a temp workspace
289
      * @return point*k
290
      */
291
      PointGFp blinded_var_point_multiply(const PointGFp& point,
292
                                          const BigInt& k,
293
                                          RandomNumberGenerator& rng,
294
                                          std::vector<BigInt>& ws) const;
295
296
      /**
297
      * Return a random scalar ie an integer in [1,order)
298
      */
299
      BigInt random_scalar(RandomNumberGenerator& rng) const;
300
301
      /**
302
      * Hash onto the curve.
303
      * For some curve types no mapping is currently available, in this
304
      * case this function will throw an exception.
305
      *
306
      * @param hash_fn the hash function to use (typically "SHA-256" or "SHA-512")
307
      * @param input the input to hash
308
      * @param input_len length of input in bytes
309
      * @param domain_sep a domain seperator
310
      * @param domain_sep_len length of domain_sep in bytes
311
      * @param random_oracle if the mapped point must be uniform (use
312
               "true" here unless you know what you are doing)
313
      */
314
      PointGFp hash_to_curve(const std::string& hash_fn,
315
                             const uint8_t input[],
316
                             size_t input_len,
317
                             const uint8_t domain_sep[],
318
                             size_t domain_sep_len,
319
                             bool random_oracle = true) const;
320
321
      /**
322
      * Hash onto the curve.
323
      * For some curve types no mapping is currently available, in this
324
      * case this function will throw an exception.
325
      *
326
      * @param hash_fn the hash function to use (typically "SHA-256" or "SHA-512")
327
      * @param input the input to hash
328
      * @param input_len length of input in bytes
329
      * @param domain_sep a domain seperator
330
      * @param random_oracle if the mapped point must be uniform (use
331
               "true" here unless you know what you are doing)
332
      */
333
      PointGFp hash_to_curve(const std::string& hash_fn,
334
                             const uint8_t input[],
335
                             size_t input_len,
336
                             const std::string& domain_sep,
337
                             bool random_oracle = true) const;
338
339
      /**
340
      * Return the zero (or infinite) point on this curve
341
      */
342
      PointGFp zero_point() const;
343
344
      size_t point_size(PointGFp::Compression_Type format) const;
345
346
      PointGFp OS2ECP(const uint8_t bits[], size_t len) const;
347
348
      template<typename Alloc>
349
      PointGFp OS2ECP(const std::vector<uint8_t, Alloc>& vec) const
350
2.47k
         {
351
2.47k
         return this->OS2ECP(vec.data(), vec.size());
352
2.47k
         }
Botan::PointGFp Botan::EC_Group::OS2ECP<std::__1::allocator<unsigned char> >(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&) const
Line
Count
Source
350
1.29k
         {
351
1.29k
         return this->OS2ECP(vec.data(), vec.size());
352
1.29k
         }
Botan::PointGFp Botan::EC_Group::OS2ECP<Botan::secure_allocator<unsigned char> >(std::__1::vector<unsigned char, Botan::secure_allocator<unsigned char> > const&) const
Line
Count
Source
350
1.18k
         {
351
1.18k
         return this->OS2ECP(vec.data(), vec.size());
352
1.18k
         }
353
354
0
      bool initialized() const { return (m_data != nullptr); }
355
356
      /**
357
       * Verify EC_Group domain
358
       * @returns true if group is valid. false otherwise
359
       */
360
      bool verify_group(RandomNumberGenerator& rng,
361
                        bool strong = false) const;
362
363
      bool operator==(const EC_Group& other) const;
364
365
      EC_Group_Source source() const;
366
367
      /**
368
      * Return a set of known named EC groups
369
      */
370
      static const std::set<std::string>& known_named_groups();
371
372
      /*
373
      * For internal use only
374
      */
375
      static std::shared_ptr<EC_Group_Data> EC_group_info(const OID& oid);
376
377
      /*
378
      * For internal use only
379
      */
380
      static size_t clear_registered_curve_data();
381
382
      /*
383
      * For internal use only
384
      */
385
      static OID EC_group_identity_from_order(const BigInt& order);
386
387
   private:
388
      static EC_Group_Data_Map& ec_group_data();
389
390
      static std::shared_ptr<EC_Group_Data> BER_decode_EC_group(const uint8_t bits[], size_t len,
391
                                                                EC_Group_Source source);
392
393
      static std::shared_ptr<EC_Group_Data>
394
         load_EC_group_info(const char* p,
395
                            const char* a,
396
                            const char* b,
397
                            const char* g_x,
398
                            const char* g_y,
399
                            const char* order,
400
                            const OID& oid);
401
402
      // Member data
403
      const EC_Group_Data& data() const;
404
      std::shared_ptr<EC_Group_Data> m_data;
405
   };
406
407
inline bool operator!=(const EC_Group& lhs,
408
                       const EC_Group& rhs)
409
0
   {
410
0
   return !(lhs == rhs);
411
0
   }
412
413
// For compatibility with 1.8
414
typedef EC_Group EC_Domain_Params;
415
416
}
417
418
#endif