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