/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 |