Coverage Report

Created: 2020-08-01 06:18

/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_oid.h>
15
#include <memory>
16
#include <set>
17
18
namespace Botan {
19
20
/**
21
* This class represents elliptic curce domain parameters
22
*/
23
enum EC_Group_Encoding {
24
   EC_DOMPAR_ENC_EXPLICIT = 0,
25
   EC_DOMPAR_ENC_IMPLICITCA = 1,
26
   EC_DOMPAR_ENC_OID = 2
27
};
28
29
class CurveGFp;
30
31
class EC_Group_Data;
32
class EC_Group_Data_Map;
33
34
/**
35
* Class representing an elliptic curve
36
*
37
* The internal representation is stored in a shared_ptr, so copying an
38
* EC_Group is inexpensive.
39
*/
40
class BOTAN_PUBLIC_API(2,0) EC_Group final
41
   {
42
   public:
43
44
      /**
45
      * Construct Domain paramers from specified parameters
46
      * @param curve elliptic curve
47
      * @param base_point a base point
48
      * @param order the order of the base point
49
      * @param cofactor the cofactor
50
      */
51
      BOTAN_DEPRECATED("Use version taking all BigInts")
52
      EC_Group(const CurveGFp& curve,
53
               const PointGFp& base_point,
54
               const BigInt& order,
55
               const BigInt& cofactor) :
56
         EC_Group(curve.get_p(),
57
                  curve.get_a(),
58
                  curve.get_b(),
59
                  base_point.get_affine_x(),
60
                  base_point.get_affine_y(),
61
                  order,
62
0
                  cofactor) {}
63
64
      /**
65
      * Construct Domain paramers from specified parameters
66
      * @param p the elliptic curve p
67
      * @param a the elliptic curve a param
68
      * @param b the elliptic curve b param
69
      * @param base_x the x coordinate of the base point
70
      * @param base_y the y coordinate of the base point
71
      * @param order the order of the base point
72
      * @param cofactor the cofactor
73
      * @param oid an optional OID used to identify this curve
74
      */
75
      EC_Group(const BigInt& p,
76
               const BigInt& a,
77
               const BigInt& b,
78
               const BigInt& base_x,
79
               const BigInt& base_y,
80
               const BigInt& order,
81
               const BigInt& cofactor,
82
               const OID& oid = OID());
83
84
      /**
85
      * Decode a BER encoded ECC domain parameter set
86
      * @param ber_encoding the bytes of the BER encoding
87
      */
88
      explicit EC_Group(const std::vector<uint8_t>& ber_encoding);
89
90
      /**
91
      * Create an EC domain by OID (or throw if unknown)
92
      * @param oid the OID of the EC domain to create
93
      */
94
      explicit EC_Group(const OID& oid);
95
96
      /**
97
      * Create an EC domain from PEM encoding (as from PEM_encode), or
98
      * from an OID name (eg "secp256r1", or "1.2.840.10045.3.1.7")
99
      * @param pem_or_oid PEM-encoded data, or an OID
100
      */
101
      explicit EC_Group(const std::string& pem_or_oid);
102
103
      /**
104
      * Create an uninitialized EC_Group
105
      */
106
      EC_Group();
107
108
      ~EC_Group();
109
110
13.4k
      EC_Group(const EC_Group&) = default;
111
      EC_Group(EC_Group&&) = default;
112
113
18.4k
      EC_Group& operator=(const EC_Group&) = default;
114
1.28k
      EC_Group& operator=(EC_Group&&) = default;
115
116
      /**
117
      * Create the DER encoding of this domain
118
      * @param form of encoding to use
119
      * @returns bytes encododed as DER
120
      */
121
      std::vector<uint8_t> DER_encode(EC_Group_Encoding form) const;
122
123
      /**
124
      * Return the PEM encoding (always in explicit form)
125
      * @return string containing PEM data
126
      */
127
      std::string PEM_encode() const;
128
129
      /**
130
      * Return domain parameter curve
131
      * @result domain parameter curve
132
      */
133
      BOTAN_DEPRECATED("Avoid CurveGFp") const CurveGFp& get_curve() const;
134
135
      /**
136
      * Return if a == -3 mod p
137
      */
138
      bool a_is_minus_3() const;
139
140
      /**
141
      * Return if a == 0 mod p
142
      */
143
      bool a_is_zero() const;
144
145
      /**
146
      * Return the size of p in bits (same as get_p().bits())
147
      */
148
      size_t get_p_bits() const;
149
150
      /**
151
      * Return the size of p in bits (same as get_p().bytes())
152
      */
153
      size_t get_p_bytes() const;
154
155
      /**
156
      * Return the size of group order in bits (same as get_order().bits())
157
      */
158
      size_t get_order_bits() const;
159
160
      /**
161
      * Return the size of p in bytes (same as get_order().bytes())
162
      */
163
      size_t get_order_bytes() const;
164
165
      /**
166
      * Return the prime modulus of the field
167
      */
168
      const BigInt& get_p() const;
169
170
      /**
171
      * Return the a parameter of the elliptic curve equation
172
      */
173
      const BigInt& get_a() const;
174
175
      /**
176
      * Return the b parameter of the elliptic curve equation
177
      */
178
      const BigInt& get_b() const;
179
180
      /**
181
      * Return group base point
182
      * @result base point
183
      */
184
      const PointGFp& get_base_point() const;
185
186
      /**
187
      * Return the x coordinate of the base point
188
      */
189
      const BigInt& get_g_x() const;
190
191
      /**
192
      * Return the y coordinate of the base point
193
      */
194
      const BigInt& get_g_y() const;
195
196
      /**
197
      * Return the order of the base point
198
      * @result order of the base point
199
      */
200
      const BigInt& get_order() const;
201
202
      /*
203
      * Reduce x modulo the order
204
      */
205
      BigInt mod_order(const BigInt& x) const;
206
207
      /*
208
      * Return inverse of x modulo the order
209
      */
210
      BigInt inverse_mod_order(const BigInt& x) const;
211
212
      /*
213
      * Reduce (x*x) modulo the order
214
      */
215
      BigInt square_mod_order(const BigInt& x) const;
216
217
      /*
218
      * Reduce (x*y) modulo the order
219
      */
220
      BigInt multiply_mod_order(const BigInt& x, const BigInt& y) const;
221
222
      /*
223
      * Reduce (x*y*z) modulo the order
224
      */
225
      BigInt multiply_mod_order(const BigInt& x, const BigInt& y, const BigInt& z) const;
226
227
      /**
228
      * Return the cofactor
229
      * @result the cofactor
230
      */
231
      const BigInt& get_cofactor() const;
232
233
      /**
234
      * Check if y is a plausible point on the curve
235
      *
236
      * In particular, checks that it is a point on the curve, not infinity,
237
      * and that it has order matching the group.
238
      */
239
      bool verify_public_element(const PointGFp& y) const;
240
241
      /**
242
      * Return the OID of these domain parameters
243
      * @result the OID as a string
244
      */
245
0
      std::string BOTAN_DEPRECATED("Use get_curve_oid") get_oid() const { return get_curve_oid().to_string(); }
246
247
      /**
248
      * Return the OID of these domain parameters
249
      * @result the OID
250
      */
251
      const OID& get_curve_oid() const;
252
253
      /**
254
      * Return a point on this curve with the affine values x, y
255
      */
256
      PointGFp point(const BigInt& x, const BigInt& y) const;
257
258
      /**
259
      * Multi exponentiate. Not constant time.
260
      * @return base_point*x + pt*y
261
      */
262
      PointGFp point_multiply(const BigInt& x, const PointGFp& pt, const BigInt& y) const;
263
264
      /**
265
      * Blinded point multiplication, attempts resistance to side channels
266
      * @param k the scalar
267
      * @param rng a random number generator
268
      * @param ws a temp workspace
269
      * @return base_point*k
270
      */
271
      PointGFp blinded_base_point_multiply(const BigInt& k,
272
                                           RandomNumberGenerator& rng,
273
                                           std::vector<BigInt>& ws) const;
274
275
      /**
276
      * Blinded point multiplication, attempts resistance to side channels
277
      * Returns just the x coordinate of the point
278
      *
279
      * @param k the scalar
280
      * @param rng a random number generator
281
      * @param ws a temp workspace
282
      * @return x coordinate of base_point*k
283
      */
284
      BigInt blinded_base_point_multiply_x(const BigInt& k,
285
                                           RandomNumberGenerator& rng,
286
                                           std::vector<BigInt>& ws) const;
287
288
      /**
289
      * Blinded point multiplication, attempts resistance to side channels
290
      * @param point input point
291
      * @param k the scalar
292
      * @param rng a random number generator
293
      * @param ws a temp workspace
294
      * @return point*k
295
      */
296
      PointGFp blinded_var_point_multiply(const PointGFp& point,
297
                                          const BigInt& k,
298
                                          RandomNumberGenerator& rng,
299
                                          std::vector<BigInt>& ws) const;
300
301
      /**
302
      * Return a random scalar ie an integer in [1,order)
303
      */
304
      BigInt random_scalar(RandomNumberGenerator& rng) const;
305
306
      /**
307
      * Return the zero (or infinite) point on this curve
308
      */
309
      PointGFp zero_point() const;
310
311
      size_t point_size(PointGFp::Compression_Type format) const;
312
313
      PointGFp OS2ECP(const uint8_t bits[], size_t len) const;
314
315
      template<typename Alloc>
316
      PointGFp OS2ECP(const std::vector<uint8_t, Alloc>& vec) const
317
3.60k
         {
318
3.60k
         return this->OS2ECP(vec.data(), vec.size());
319
3.60k
         }
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
317
2.94k
         {
318
2.94k
         return this->OS2ECP(vec.data(), vec.size());
319
2.94k
         }
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
317
660
         {
318
660
         return this->OS2ECP(vec.data(), vec.size());
319
660
         }
320
321
0
      bool initialized() const { return (m_data != nullptr); }
322
323
      /**
324
       * Verify EC_Group domain
325
       * @returns true if group is valid. false otherwise
326
       */
327
      bool verify_group(RandomNumberGenerator& rng,
328
                        bool strong = false) const;
329
330
      bool operator==(const EC_Group& other) const;
331
332
      /**
333
      * Return PEM representation of named EC group
334
      * Deprecated: Use EC_Group(name).PEM_encode() if this is needed
335
      */
336
      static std::string BOTAN_DEPRECATED("See header comment") PEM_for_named_group(const std::string& name);
337
338
      /**
339
      * Return a set of known named EC groups
340
      */
341
      static const std::set<std::string>& known_named_groups();
342
343
      /*
344
      * For internal use only
345
      */
346
      static std::shared_ptr<EC_Group_Data> EC_group_info(const OID& oid);
347
348
      static size_t clear_registered_curve_data();
349
350
   private:
351
      static EC_Group_Data_Map& ec_group_data();
352
353
      static std::shared_ptr<EC_Group_Data> BER_decode_EC_group(const uint8_t bits[], size_t len);
354
355
      static std::shared_ptr<EC_Group_Data>
356
         load_EC_group_info(const char* p,
357
                            const char* a,
358
                            const char* b,
359
                            const char* g_x,
360
                            const char* g_y,
361
                            const char* order,
362
                            const OID& oid);
363
364
      // Member data
365
      const EC_Group_Data& data() const;
366
      std::shared_ptr<EC_Group_Data> m_data;
367
   };
368
369
inline bool operator!=(const EC_Group& lhs,
370
                       const EC_Group& rhs)
371
0
   {
372
0
   return !(lhs == rhs);
373
0
   }
374
375
// For compatibility with 1.8
376
typedef EC_Group EC_Domain_Params;
377
378
}
379
380
#endif