Botan 3.11.0
Crypto and TLS for C&
hybrid_kem_ops.h
Go to the documentation of this file.
1/**
2* Abstraction for a combined KEM encryptors and decryptors.
3*
4* (C) 2024 Jack Lloyd
5* 2024 Fabian Albert, René Meusel - Rohde & Schwarz Cybersecurity
6*
7* Botan is released under the Simplified BSD License (see license.txt)
8*/
9
10#ifndef BOTAN_HYBRID_KEM_OPS_H_
11#define BOTAN_HYBRID_KEM_OPS_H_
12
13#include <botan/pk_algs.h>
14#include <botan/pubkey.h>
15#include <botan/internal/pk_ops_impl.h>
16
17#include <memory>
18#include <vector>
19
20namespace Botan {
21
22/**
23 * @brief Abstract interface for a KEM encryption operation for KEM combiners.
24 *
25 * Multiple public keys are used to encapsulate shared secrets. These shared
26 * secrets (and maybe the ciphertexts and public keys) are combined using the
27 * KEM combiner to derive the final shared secret.
28 *
29 */
31 public:
32 KEM_Encryption_with_Combiner(const std::vector<std::unique_ptr<Public_Key>>& public_keys,
33 std::string_view provider);
34
35 void kem_encrypt(std::span<uint8_t> out_encapsulated_key,
36 std::span<uint8_t> out_shared_key,
38 size_t desired_shared_key_len,
39 std::span<const uint8_t> salt) final;
40
41 /// The default implementation returns the sum of the encapsulated key lengths of the underlying KEMs.
42 size_t encapsulated_key_length() const override { return m_encapsulated_key_length; }
43
44 protected:
45 /**
46 * @brief Defines how multiple ciphertexts are combined into a single ciphertext.
47 *
48 * The default implementation concatenates the ciphertexts.
49 *
50 * @param out_ciphertext The output buffer for the combined ciphertext
51 * @param ciphertexts The ciphertexts to combine
52 * @param salt The salt. In this default implementation the salt must be empty.
53 */
54 virtual void combine_ciphertexts(std::span<uint8_t> out_ciphertext,
55 const std::vector<std::vector<uint8_t>>& ciphertexts,
56 std::span<const uint8_t> salt);
57
58 /**
59 * @brief Describes how the shared secrets are combined to derive the final shared secret.
60 *
61 * @param out_shared_secret the output buffer for the shared secret
62 * @param shared_secrets a list of shared secrets corresponding to the public keys
63 * @param ciphertexts a list of encapsulated shared secrets
64 * @param desired_shared_key_len the desired shared key length
65 * @param salt the salt (input of kem_encrypt)
66 */
67 virtual void combine_shared_secrets(std::span<uint8_t> out_shared_secret,
68 const std::vector<secure_vector<uint8_t>>& shared_secrets,
69 const std::vector<std::vector<uint8_t>>& ciphertexts,
70 size_t desired_shared_key_len,
71 std::span<const uint8_t> salt) = 0;
72
73 std::vector<PK_KEM_Encryptor>& encryptors() { return m_encryptors; }
74
75 const std::vector<PK_KEM_Encryptor>& encryptors() const { return m_encryptors; }
76
77 private:
78 std::vector<PK_KEM_Encryptor> m_encryptors;
79 size_t m_encapsulated_key_length;
80};
81
82/**
83 * @brief Abstract interface for a KEM decryption operation for KEM combiners.
84 *
85 * Multiple private keys are used to decapsulate shared secrets from a combined
86 * ciphertext (concatenated in most cases). These shared
87 * secrets (and maybe the ciphertexts and public keys) are combined using the
88 * KEM combiner to derive the final shared secret.
89 */
91 public:
92 KEM_Decryption_with_Combiner(const std::vector<std::unique_ptr<Private_Key>>& private_keys,
94 std::string_view provider);
95
96 void kem_decrypt(std::span<uint8_t> out_shared_key,
97 std::span<const uint8_t> encapsulated_key,
98 size_t desired_shared_key_len,
99 std::span<const uint8_t> salt) final;
100
101 /// The default implementation returns the sum of the encapsulated key lengths of the underlying KEMs.
102 size_t encapsulated_key_length() const override { return m_encapsulated_key_length; }
103
104 protected:
105 /**
106 * @brief Defines how the individual ciphertexts are extracted from the combined ciphertext.
107 *
108 * The default implementation splits concatenated ciphertexts.
109 * @param concat_ciphertext The combined ciphertext
110 * @returns The individual ciphertexts
111 */
112 virtual std::vector<std::vector<uint8_t>> split_ciphertexts(std::span<const uint8_t> concat_ciphertext);
113
114 /**
115 * @brief Describes how the shared secrets are combined to derive the final shared secret.
116 *
117 * @param out_shared_secret the output buffer for the shared secret
118 * @param shared_secrets a list of shared secrets corresponding to the public keys
119 * @param ciphertexts the list of encapsulated shared secrets
120 * @param desired_shared_key_len the desired shared key length
121 * @param salt the salt (input of kem_decrypt)
122 */
123 virtual void combine_shared_secrets(std::span<uint8_t> out_shared_secret,
124 const std::vector<secure_vector<uint8_t>>& shared_secrets,
125 const std::vector<std::vector<uint8_t>>& ciphertexts,
126 size_t desired_shared_key_len,
127 std::span<const uint8_t> salt) = 0;
128
129 std::vector<PK_KEM_Decryptor>& decryptors() { return m_decryptors; }
130
131 const std::vector<PK_KEM_Decryptor>& decryptors() const { return m_decryptors; }
132
133 private:
134 std::vector<PK_KEM_Decryptor> m_decryptors;
135 size_t m_encapsulated_key_length;
136};
137
138} // namespace Botan
139
140#endif // BOTAN_HYBRID_KEM_OPS_H_
std::vector< PK_KEM_Decryptor > & decryptors()
const std::vector< PK_KEM_Decryptor > & decryptors() const
void kem_decrypt(std::span< uint8_t > out_shared_key, std::span< const uint8_t > encapsulated_key, size_t desired_shared_key_len, std::span< const uint8_t > salt) final
KEM_Decryption_with_Combiner(const std::vector< std::unique_ptr< Private_Key > > &private_keys, RandomNumberGenerator &rng, std::string_view provider)
size_t encapsulated_key_length() const override
The default implementation returns the sum of the encapsulated key lengths of the underlying KEMs.
virtual void combine_shared_secrets(std::span< uint8_t > out_shared_secret, const std::vector< secure_vector< uint8_t > > &shared_secrets, const std::vector< std::vector< uint8_t > > &ciphertexts, size_t desired_shared_key_len, std::span< const uint8_t > salt)=0
Describes how the shared secrets are combined to derive the final shared secret.
virtual std::vector< std::vector< uint8_t > > split_ciphertexts(std::span< const uint8_t > concat_ciphertext)
Defines how the individual ciphertexts are extracted from the combined ciphertext.
KEM_Encryption_with_Combiner(const std::vector< std::unique_ptr< Public_Key > > &public_keys, std::string_view provider)
std::vector< PK_KEM_Encryptor > & encryptors()
virtual void combine_ciphertexts(std::span< uint8_t > out_ciphertext, const std::vector< std::vector< uint8_t > > &ciphertexts, std::span< const uint8_t > salt)
Defines how multiple ciphertexts are combined into a single ciphertext.
void kem_encrypt(std::span< uint8_t > out_encapsulated_key, std::span< uint8_t > out_shared_key, RandomNumberGenerator &rng, size_t desired_shared_key_len, std::span< const uint8_t > salt) final
const std::vector< PK_KEM_Encryptor > & encryptors() const
size_t encapsulated_key_length() const override
The default implementation returns the sum of the encapsulated key lengths of the underlying KEMs.
virtual void combine_shared_secrets(std::span< uint8_t > out_shared_secret, const std::vector< secure_vector< uint8_t > > &shared_secrets, const std::vector< std::vector< uint8_t > > &ciphertexts, size_t desired_shared_key_len, std::span< const uint8_t > salt)=0
Describes how the shared secrets are combined to derive the final shared secret.
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:68