Botan 3.13.0
Crypto and TLS for C&
ecies.h
Go to the documentation of this file.
1/*
2* ECIES
3* (C) 2016 Philipp Weber
4* 2025 Jack Lloyd
5*
6* Botan is released under the Simplified BSD License (see license.txt)
7*/
8
9#ifndef BOTAN_ECIES_H_
10#define BOTAN_ECIES_H_
11
12#include <botan/cipher_mode.h>
13#include <botan/ec_apoint.h>
14#include <botan/ec_group.h>
15#include <botan/mac.h>
16#include <botan/pubkey.h>
17#include <botan/secmem.h>
18#include <botan/symkey.h>
19#include <memory>
20#include <optional>
21#include <string>
22#include <string_view>
23#include <vector>
24
25#if defined(BOTAN_HAS_LEGACY_EC_POINT)
26 #include <botan/ec_point.h>
27#endif
28
29namespace Botan {
30
32
33/**
34* Flags controlling ECIES operation
35*
36* Two of the flags are related to how cofactors are handled.
37* Support for cofactors is deprecated and will be removed in Botan4.
38*
39* The CheckMode flag is completely ignored; we always check that the point is
40* valid.
41*
42* TODO(Botan4) remove this enum
43*/
44enum class ECIES_Flags : uint8_t {
45 None = 0,
46 /// if set: do NOT prefix the input of the (ecdh) key agreement with the encoded (ephemeral) public key
48 /// (decryption only) if set: use cofactor multiplication during (ecdh) key agreement
49 /// This only matters if the curve has a cofactor
51 /// if set: use ecdhc instead of ecdh.
52 /// This only matters if the curve has a cofactor
54 /// (decryption only) if set: test if the (ephemeral) public key is on the curve
55 /// Note that we actually ignore this flag and always check the key
57
58 NONE BOTAN_DEPRECATED("Use None") = None,
63};
64
66 // NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
67 return static_cast<ECIES_Flags>(static_cast<uint32_t>(a) | static_cast<uint32_t>(b));
68}
69
71 return static_cast<ECIES_Flags>(static_cast<uint32_t>(a) & static_cast<uint32_t>(b));
72}
73
74/**
75* Parameters for ECIES secret derivation
76*/
78 public:
79 /**
80 * @param group ec domain parameters of the involved ec keys
81 * @param kdf_spec name of the key derivation function
82 * @param length length of the secret to be derived
83 * @param point_format format of encoded keys (the ephemeral public key encoding
84 * only affects the secret derivation when single_hash_mode is false)
85 * @param single_hash_mode if false, prefix the KDF input with the encoded
86 * ephemeral public key; if true (recommended, and the default), the
87 * KDF input is just the ECDH shared secret
88 */
90 std::string_view kdf_spec,
91 size_t length,
93 bool single_hash_mode = true);
94
95 /**
96 * @param group ec domain parameters of the involved ec keys
97 * @param kdf_spec name of the key derivation function
98 * @param length length of the secret to be derived
99 * @param point_format format of encoded keys (the ephemeral public key encoding
100 * only affects the secret derivation when ECIES_Flags::SingleHashMode is not set)
101 * @param flags options, see documentation of ECIES_Flags
102 *
103 * This constructor makes sense only if you are using the CofactorMode or
104 * OldCofactorMode flags. Support for cofactors in EC_Group is deprecated
105 * and will be removed in Botan4.
106 *
107 * TODO(Botan4) remove this constructor when cofactor support is removed
108 */
109 BOTAN_DEPRECATED("Prefer other constructor, see header comment")
111 std::string_view kdf_spec,
112 size_t length,
114 ECIES_Flags flags);
115
120
121 virtual ~ECIES_KA_Params() = default;
122
123 const EC_Group& group() const { return m_group; }
124
125 size_t secret_length() const { return m_length; }
126
127 bool single_hash_mode() const { return m_single_hash_mode; }
128
129 // TODO(Botan4) remove this when cofactor support is removed
130 bool cofactor_mode() const { return m_cofactor_mode; }
131
132 // TODO(Botan4) remove this when cofactor support is removed
133 bool old_cofactor_mode() const { return m_old_cofactor_mode; }
134
135 // TODO(Botan4) remove this when cofactor support is removed
136 bool check_mode() const { return m_check_mode; }
137
138 EC_Point_Format point_format() const { return m_point_format; }
139
140 const std::string& kdf() const { return m_kdf; }
141
142 BOTAN_DEPRECATED("Use kdf") const std::string& kdf_spec() const { return kdf(); }
143
144 BOTAN_DEPRECATED("Use group") const EC_Group& domain() const { return group(); }
145
146 BOTAN_DEPRECATED("Use point_format") EC_Point_Format compression_type() const { return point_format(); }
147
148 private:
149 const EC_Group m_group;
150 const std::string m_kdf;
151 const size_t m_length;
152 const EC_Point_Format m_point_format;
153 const bool m_single_hash_mode;
154 const bool m_check_mode; // TODO(Botan4) remove this field
155 const bool m_cofactor_mode; // TODO(Botan4) remove this field
156 const bool m_old_cofactor_mode; // TODO(Botan4) remove this field
157};
158
160 public:
161 /**
162 * @param group ec domain parameters of the involved ec keys
163 * @param kdf_spec name of the key derivation function
164 * @param dem_algo_spec name of the data encryption method
165 * @param dem_key_len length of the key used for the data encryption method
166 * @param mac_spec name of the message authentication code
167 * @param mac_key_len length of the key used for the message authentication code
168 * @param point_format format of encoded keys (the ephemeral public key encoding
169 * only affects the secret derivation when single_hash_mode is false)
170 * @param single_hash_mode if false, prefix the KDF input with the encoded
171 * ephemeral public key; if true, the KDF input is just the ECDH shared secret
172 *
173 * TODO(Botan4) split this constructor into two, one taking the point format (requesting
174 * !single_hash_mode) and the other with no extra params (for single_hash_mode)
175 */
177 std::string_view kdf_spec,
178 std::string_view dem_algo_spec,
179 size_t dem_key_len,
180 std::string_view mac_spec,
181 size_t mac_key_len,
183 bool single_hash_mode = false);
184
185 /**
186 * @param group ec domain parameters of the involved ec keys
187 * @param kdf_spec name of the key derivation function
188 * @param dem_algo_spec name of the data encryption method
189 * @param dem_key_len length of the key used for the data encryption method
190 * @param mac_spec name of the message authentication code
191 * @param mac_key_len length of the key used for the message authentication code
192 * @param point_format format of encoded keys (the ephemeral public key encoding
193 * only affects the secret derivation when ECIES_Flags::SingleHashMode is not set)
194 * @param flags options, see documentation of ECIES_Flags
195 *
196 * This constructor makes sense only if you are using the CofactorMode or
197 * OldCofactorMode flags. Support for cofactors in EC_Group is deprecated
198 * and will be removed in Botan4.
199 *
200 * TODO(Botan4) remove this constructor when cofactor support is removed
201 */
202 BOTAN_DEPRECATED("Prefer other constructor, see header comment")
204 std::string_view kdf_spec,
205 std::string_view dem_algo_spec,
206 size_t dem_key_len,
207 std::string_view mac_spec,
208 size_t mac_key_len,
210 ECIES_Flags flags);
211
216 ~ECIES_System_Params() override = default;
217
218 /// creates an instance of the message authentication code
219 std::unique_ptr<MessageAuthenticationCode> create_mac() const;
220
221 /// creates an instance of the data encryption method
222 std::unique_ptr<Cipher_Mode> create_cipher(Cipher_Dir direction) const;
223
224 /// returns the length of the key used by the data encryption method
225 size_t dem_keylen() const { return m_dem_keylen; }
226
227 /// returns the length of the key used by the message authentication code
228 size_t mac_keylen() const { return m_mac_keylen; }
229
230 private:
231 const std::string m_dem_spec;
232 const size_t m_dem_keylen;
233 const std::string m_mac_spec;
234 const size_t m_mac_keylen;
235};
236
237/**
238* ECIES secret derivation according to ISO 18033-2
239*/
241 public:
242 /**
243 * @param private_key the (ephemeral) private key which is used to derive the secret
244 * @param ecies_params settings for ecies
245 * @param for_encryption disable cofactor mode if the secret will be used for encryption
246 * (according to ISO 18033 cofactor mode is only used during decryption)
247 * @param rng the RNG to use
248 */
249 ECIES_KA_Operation(const PK_Key_Agreement_Key& private_key,
250 const ECIES_KA_Params& ecies_params,
251 bool for_encryption,
253
254#if defined(BOTAN_HAS_LEGACY_EC_POINT)
255 /**
256 * Performs a key agreement with the provided keys and derives the secret from the result
257 * @param eph_public_key_bin the encoded (ephemeral) public key which belongs to the used (ephemeral) private key
258 * @param other_public_key_point public key point of the other party
259 */
260 SymmetricKey derive_secret(const std::vector<uint8_t>& eph_public_key_bin,
261 const EC_Point& other_public_key_point) const;
262#endif
263
264 /**
265 * Performs a key agreement with the provided keys and derives the secret from the result
266 * @param eph_public_key_bin the encoded (ephemeral) public key which belongs to the used (ephemeral) private key
267 * @param other_public_key_point public key point of the other party
268 */
269 SymmetricKey derive_secret(std::span<const uint8_t> eph_public_key_bin,
270 const EC_AffinePoint& other_public_key_point) const;
271
272 private:
273 const PK_Key_Agreement m_ka;
274 const ECIES_KA_Params m_params;
275};
276
277/**
278* ECIES Encryption according to ISO 18033-2
279*
280* TODO(Botan4) remove derivation on PK_Encryptor and provide a direct API
281* for encryption taking all relevant params, avoiding setters/implicit state
282*/
284 public:
285 /**
286 * @param private_key the (ephemeral) private key which is used for the key agreement
287 * @param ecies_params settings for ecies
288 * @param rng random generator to use
289 */
290 ECIES_Encryptor(const PK_Key_Agreement_Key& private_key,
291 const ECIES_System_Params& ecies_params,
293
294 /**
295 * Creates an ephemeral private key which is used for the key agreement
296 * @param rng random generator used during private key generation
297 * @param ecies_params settings for ecies
298 */
300
301#if defined(BOTAN_HAS_LEGACY_EC_POINT)
302 /// Set the public key of the other party
303 void set_other_key(const EC_Point& public_point) {
304 m_other_point = EC_AffinePoint(m_params.group(), public_point);
305 }
306#endif
307
308 /// Set the public key of the other party
309 void set_other_key(const EC_AffinePoint& pt) { m_other_point = pt; }
310
311 /// Set the initialization vector for the data encryption method
312 ///
313 /// A new IV must be provided for each message; it is not included
314 /// in the serialized ciphertext and must be conveyed separately
315 void set_initialization_vector(const InitializationVector& iv) { m_iv = iv; }
316
317 /// Set the label which is appended to the input for the message authentication code
318 void set_label(std::string_view label) { m_label.assign(label.begin(), label.end()); }
319
320 private:
321 std::vector<uint8_t> enc(const uint8_t data[], size_t length, RandomNumberGenerator& rng) const override;
322
323 size_t maximum_input_size() const override;
324
325 size_t ciphertext_length(size_t ptext_len) const override;
326
327 const ECIES_KA_Operation m_ka;
328 const ECIES_System_Params m_params;
329 std::unique_ptr<MessageAuthenticationCode> m_mac;
330 std::unique_ptr<Cipher_Mode> m_cipher;
331 std::vector<uint8_t> m_eph_public_key_bin;
332 mutable std::optional<InitializationVector> m_iv;
333 std::optional<EC_AffinePoint> m_other_point;
334 std::vector<uint8_t> m_label;
335};
336
337/**
338* ECIES Decryption according to ISO 18033-2
339*
340* TODO(Botan4) remove derivation on PK_Decryptor and provide a direct API
341* for decryption taking all relevant params, avoiding setters/implicit state
342*/
344 public:
345 /**
346 * @param private_key the private key which is used for the key agreement
347 * @param ecies_params settings for ecies
348 * @param rng the random generator to use
349 */
350 ECIES_Decryptor(const PK_Key_Agreement_Key& private_key,
351 const ECIES_System_Params& ecies_params,
353
354 /// Set the initialization vector for the data encryption method
355 ///
356 /// A new IV must be provided for each message; it is not included
357 /// in the serialized ciphertext and must be conveyed separately
358 void set_initialization_vector(const InitializationVector& iv) { m_iv = iv; }
359
360 /// Set the label which is appended to the input for the message authentication code
361 void set_label(std::string_view label) { m_label = std::vector<uint8_t>(label.begin(), label.end()); }
362
363 private:
364 secure_vector<uint8_t> do_decrypt(uint8_t& valid_mask, const uint8_t in[], size_t in_len) const override;
365
366 size_t plaintext_length(size_t ctext_len) const override;
367
368 size_t ciphertext_length(size_t ptext_len) const override;
369
370 const ECIES_KA_Operation m_ka;
371 const ECIES_System_Params m_params;
372 std::unique_ptr<MessageAuthenticationCode> m_mac;
373 std::unique_ptr<Cipher_Mode> m_cipher;
374 mutable std::optional<InitializationVector> m_iv;
375 std::vector<uint8_t> m_label;
376};
377
378} // namespace Botan
379
380#endif
#define BOTAN_PUBLIC_API(maj, min)
Definition api.h:21
#define BOTAN_DEPRECATED(msg)
Definition api.h:73
void set_label(std::string_view label)
Set the label which is appended to the input for the message authentication code.
Definition ecies.h:361
void set_initialization_vector(const InitializationVector &iv)
Definition ecies.h:358
ECIES_Decryptor(const PK_Key_Agreement_Key &private_key, const ECIES_System_Params &ecies_params, RandomNumberGenerator &rng)
Definition ecies.cpp:358
void set_other_key(const EC_AffinePoint &pt)
Set the public key of the other party.
Definition ecies.h:309
ECIES_Encryptor(const PK_Key_Agreement_Key &private_key, const ECIES_System_Params &ecies_params, RandomNumberGenerator &rng)
Definition ecies.cpp:282
void set_initialization_vector(const InitializationVector &iv)
Definition ecies.h:315
void set_label(std::string_view label)
Set the label which is appended to the input for the message authentication code.
Definition ecies.h:318
ECIES_KA_Operation(const PK_Key_Agreement_Key &private_key, const ECIES_KA_Params &ecies_params, bool for_encryption, RandomNumberGenerator &rng)
Definition ecies.cpp:130
SymmetricKey derive_secret(std::span< const uint8_t > eph_public_key_bin, const EC_AffinePoint &other_public_key_point) const
Definition ecies.cpp:179
ECIES_KA_Params(const ECIES_KA_Params &)=default
bool check_mode() const
Definition ecies.h:136
size_t secret_length() const
Definition ecies.h:125
bool old_cofactor_mode() const
Definition ecies.h:133
ECIES_KA_Params(const EC_Group &group, std::string_view kdf_spec, size_t length, EC_Point_Format point_format=EC_Point_Format::Uncompressed, bool single_hash_mode=true)
Definition ecies.cpp:227
EC_Point_Format compression_type() const
Definition ecies.h:146
bool cofactor_mode() const
Definition ecies.h:130
virtual ~ECIES_KA_Params()=default
bool single_hash_mode() const
Definition ecies.h:127
const std::string & kdf_spec() const
Definition ecies.h:142
const EC_Group & group() const
Definition ecies.h:123
const std::string & kdf() const
Definition ecies.h:140
ECIES_KA_Params & operator=(ECIES_KA_Params &&)=delete
const EC_Group & domain() const
Definition ecies.h:144
EC_Point_Format point_format() const
Definition ecies.h:138
ECIES_KA_Params & operator=(const ECIES_KA_Params &)=delete
ECIES_KA_Params(ECIES_KA_Params &&)=default
ECIES_System_Params(ECIES_System_Params &&)=default
ECIES_System_Params(const ECIES_System_Params &)=default
~ECIES_System_Params() override=default
size_t dem_keylen() const
returns the length of the key used by the data encryption method
Definition ecies.h:225
ECIES_System_Params & operator=(ECIES_System_Params &&)=delete
size_t mac_keylen() const
returns the length of the key used by the message authentication code
Definition ecies.h:228
std::unique_ptr< Cipher_Mode > create_cipher(Cipher_Dir direction) const
creates an instance of the data encryption method
Definition ecies.cpp:275
std::unique_ptr< MessageAuthenticationCode > create_mac() const
creates an instance of the message authentication code
Definition ecies.cpp:271
ECIES_System_Params & operator=(const ECIES_System_Params &)=delete
ECIES_System_Params(const EC_Group &group, std::string_view kdf_spec, std::string_view dem_algo_spec, size_t dem_key_len, std::string_view mac_spec, size_t mac_key_len, EC_Point_Format point_format=EC_Point_Format::Uncompressed, bool single_hash_mode=false)
Definition ecies.cpp:257
PK_Decryptor()=default
PK_Encryptor()=default
ASN1_Type operator|(ASN1_Type x, ASN1_Type y)
Definition asn1_obj.h:84
OctetString SymmetricKey
Definition symkey.h:153
@ NONE
Definition filter.h:193
ECIES_Flags
Definition ecies.h:44
@ SingleHashMode
if set: do NOT prefix the input of the (ecdh) key agreement with the encoded (ephemeral) public key
Definition ecies.h:47
OctetString InitializationVector
Definition symkey.h:158
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:128
ECIES_Flags operator&(ECIES_Flags a, ECIES_Flags b)
Definition ecies.h:70