1 /**
2  * \file kem.h
3  * \brief Key encapsulation mechanisms
4  *
5  * The file `tests/example_kem.c` contains two examples on using the OQS_KEM API.
6  *
7  * The first example uses the individual scheme's algorithms directly and uses
8  * no dynamic memory allocation -- all buffers are allocated on the stack, with
9  * sizes indicated using preprocessor macros.  Since algorithms can be disabled at
10  * compile-time, the programmer should wrap the code in \#ifdefs.
11  *
12  * The second example uses an OQS_KEM object to use an algorithm specified at
13  * runtime.  Therefore it uses dynamic memory allocation -- all buffers must be
14  * malloc'ed by the programmer, with sizes indicated using the corresponding length
15  * member of the OQS_KEM object in question.  Since algorithms can be disabled at
16  * compile-time, the programmer should check that the OQS_KEM object is not `NULL`.
17  *
18  * SPDX-License-Identifier: MIT
19  */
20 
21 #ifndef OQS_KEM_H
22 #define OQS_KEM_H
23 
24 #include <stdbool.h>
25 #include <stddef.h>
26 #include <stdint.h>
27 
28 #include <oqs/oqs.h>
29 
30 #if defined(__cplusplus)
31 extern "C" {
32 #endif
33 
34 /** Algorithm identifier for BIKE-L1 KEM (Round-3). */
35 #define OQS_KEM_alg_bike_l1 "BIKE-L1"
36 /** Algorithm identifier for BIKE-L3 KEM (Round-3). */
37 #define OQS_KEM_alg_bike_l3 "BIKE-L3"
38 ///// OQS_COPY_FROM_UPSTREAM_FRAGMENT_ALG_IDENTIFIER_START
39 /** Algorithm identifier for Classic-McEliece-348864 KEM. */
40 #define OQS_KEM_alg_classic_mceliece_348864 "Classic-McEliece-348864"
41 /** Algorithm identifier for Classic-McEliece-348864f KEM. */
42 #define OQS_KEM_alg_classic_mceliece_348864f "Classic-McEliece-348864f"
43 /** Algorithm identifier for Classic-McEliece-460896 KEM. */
44 #define OQS_KEM_alg_classic_mceliece_460896 "Classic-McEliece-460896"
45 /** Algorithm identifier for Classic-McEliece-460896f KEM. */
46 #define OQS_KEM_alg_classic_mceliece_460896f "Classic-McEliece-460896f"
47 /** Algorithm identifier for Classic-McEliece-6688128 KEM. */
48 #define OQS_KEM_alg_classic_mceliece_6688128 "Classic-McEliece-6688128"
49 /** Algorithm identifier for Classic-McEliece-6688128f KEM. */
50 #define OQS_KEM_alg_classic_mceliece_6688128f "Classic-McEliece-6688128f"
51 /** Algorithm identifier for Classic-McEliece-6960119 KEM. */
52 #define OQS_KEM_alg_classic_mceliece_6960119 "Classic-McEliece-6960119"
53 /** Algorithm identifier for Classic-McEliece-6960119f KEM. */
54 #define OQS_KEM_alg_classic_mceliece_6960119f "Classic-McEliece-6960119f"
55 /** Algorithm identifier for Classic-McEliece-8192128 KEM. */
56 #define OQS_KEM_alg_classic_mceliece_8192128 "Classic-McEliece-8192128"
57 /** Algorithm identifier for Classic-McEliece-8192128f KEM. */
58 #define OQS_KEM_alg_classic_mceliece_8192128f "Classic-McEliece-8192128f"
59 /** Algorithm identifier for HQC-128 KEM. */
60 #define OQS_KEM_alg_hqc_128 "HQC-128"
61 /** Algorithm identifier for HQC-192 KEM. */
62 #define OQS_KEM_alg_hqc_192 "HQC-192"
63 /** Algorithm identifier for HQC-256 KEM. */
64 #define OQS_KEM_alg_hqc_256 "HQC-256"
65 /** Algorithm identifier for Kyber512 KEM. */
66 #define OQS_KEM_alg_kyber_512 "Kyber512"
67 /** Algorithm identifier for Kyber768 KEM. */
68 #define OQS_KEM_alg_kyber_768 "Kyber768"
69 /** Algorithm identifier for Kyber1024 KEM. */
70 #define OQS_KEM_alg_kyber_1024 "Kyber1024"
71 /** Algorithm identifier for Kyber512-90s KEM. */
72 #define OQS_KEM_alg_kyber_512_90s "Kyber512-90s"
73 /** Algorithm identifier for Kyber768-90s KEM. */
74 #define OQS_KEM_alg_kyber_768_90s "Kyber768-90s"
75 /** Algorithm identifier for Kyber1024-90s KEM. */
76 #define OQS_KEM_alg_kyber_1024_90s "Kyber1024-90s"
77 /** Algorithm identifier for NTRU-HPS-2048-509 KEM. */
78 #define OQS_KEM_alg_ntru_hps2048509 "NTRU-HPS-2048-509"
79 /** Algorithm identifier for NTRU-HPS-2048-677 KEM. */
80 #define OQS_KEM_alg_ntru_hps2048677 "NTRU-HPS-2048-677"
81 /** Algorithm identifier for NTRU-HPS-4096-821 KEM. */
82 #define OQS_KEM_alg_ntru_hps4096821 "NTRU-HPS-4096-821"
83 /** Algorithm identifier for NTRU-HRSS-701 KEM. */
84 #define OQS_KEM_alg_ntru_hrss701 "NTRU-HRSS-701"
85 /** Algorithm identifier for ntrulpr653 KEM. */
86 #define OQS_KEM_alg_ntruprime_ntrulpr653 "ntrulpr653"
87 /** Algorithm identifier for ntrulpr761 KEM. */
88 #define OQS_KEM_alg_ntruprime_ntrulpr761 "ntrulpr761"
89 /** Algorithm identifier for ntrulpr857 KEM. */
90 #define OQS_KEM_alg_ntruprime_ntrulpr857 "ntrulpr857"
91 /** Algorithm identifier for sntrup653 KEM. */
92 #define OQS_KEM_alg_ntruprime_sntrup653 "sntrup653"
93 /** Algorithm identifier for sntrup761 KEM. */
94 #define OQS_KEM_alg_ntruprime_sntrup761 "sntrup761"
95 /** Algorithm identifier for sntrup857 KEM. */
96 #define OQS_KEM_alg_ntruprime_sntrup857 "sntrup857"
97 /** Algorithm identifier for LightSaber-KEM KEM. */
98 #define OQS_KEM_alg_saber_lightsaber "LightSaber-KEM"
99 /** Algorithm identifier for Saber-KEM KEM. */
100 #define OQS_KEM_alg_saber_saber "Saber-KEM"
101 /** Algorithm identifier for FireSaber-KEM KEM. */
102 #define OQS_KEM_alg_saber_firesaber "FireSaber-KEM"
103 ///// OQS_COPY_FROM_UPSTREAM_FRAGMENT_ALG_IDENTIFIER_END
104 /** Algorithm identifier for FrodoKEM-640-AES KEM. */
105 #define OQS_KEM_alg_frodokem_640_aes "FrodoKEM-640-AES"
106 /** Algorithm identifier for FrodoKEM-640-SHAKE KEM. */
107 #define OQS_KEM_alg_frodokem_640_shake "FrodoKEM-640-SHAKE"
108 /** Algorithm identifier for FrodoKEM-976-AES KEM. */
109 #define OQS_KEM_alg_frodokem_976_aes "FrodoKEM-976-AES"
110 /** Algorithm identifier for FrodoKEM-976-SHAKE KEM. */
111 #define OQS_KEM_alg_frodokem_976_shake "FrodoKEM-976-SHAKE"
112 /** Algorithm identifier for FrodoKEM-1344-AES KEM. */
113 #define OQS_KEM_alg_frodokem_1344_aes "FrodoKEM-1344-AES"
114 /** Algorithm identifier for FrodoKEM-1344-SHAKE KEM. */
115 #define OQS_KEM_alg_frodokem_1344_shake "FrodoKEM-1344-SHAKE"
116 /** Algorithm identifier for SIDH p434 KEM. */
117 #define OQS_KEM_alg_sidh_p434 "SIDH-p434"
118 /** Algorithm identifier for SIDH p434 compressed KEM. */
119 #define OQS_KEM_alg_sidh_p434_compressed "SIDH-p434-compressed"
120 /** Algorithm identifier for SIDH p503 KEM. */
121 #define OQS_KEM_alg_sidh_p503 "SIDH-p503"
122 /** Algorithm identifier for SIDH p503 compressed KEM. */
123 #define OQS_KEM_alg_sidh_p503_compressed "SIDH-p503-compressed"
124 /** Algorithm identifier for SIDH p610 KEM. */
125 #define OQS_KEM_alg_sidh_p610 "SIDH-p610"
126 /** Algorithm identifier for SIDH p610 compressed KEM. */
127 #define OQS_KEM_alg_sidh_p610_compressed "SIDH-p610-compressed"
128 /** Algorithm identifier for SIDH p751 KEM. */
129 #define OQS_KEM_alg_sidh_p751 "SIDH-p751"
130 /** Algorithm identifier for SIDH p751 compressed KEM. */
131 #define OQS_KEM_alg_sidh_p751_compressed "SIDH-p751-compressed"
132 /** Algorithm identifier for SIKE p434 KEM. */
133 #define OQS_KEM_alg_sike_p434 "SIKE-p434"
134 /** Algorithm identifier for SIKE p434 compressed KEM. */
135 #define OQS_KEM_alg_sike_p434_compressed "SIKE-p434-compressed"
136 /** Algorithm identifier for SIKE p503 KEM. */
137 #define OQS_KEM_alg_sike_p503 "SIKE-p503"
138 /** Algorithm identifier for SIKE p503 compressed KEM. */
139 #define OQS_KEM_alg_sike_p503_compressed "SIKE-p503-compressed"
140 /** Algorithm identifier for SIKE p610 KEM. */
141 #define OQS_KEM_alg_sike_p610 "SIKE-p610"
142 /** Algorithm identifier for SIKE p610 compressed KEM. */
143 #define OQS_KEM_alg_sike_p610_compressed "SIKE-p610-compressed"
144 /** Algorithm identifier for SIKE p751 KEM. */
145 #define OQS_KEM_alg_sike_p751 "SIKE-p751"
146 /** Algorithm identifier for SIKE p751 compressed KEM. */
147 #define OQS_KEM_alg_sike_p751_compressed "SIKE-p751-compressed"
148 // EDIT-WHEN-ADDING-KEM
149 ///// OQS_COPY_FROM_UPSTREAM_FRAGMENT_ALGS_LENGTH_START
150 /** Number of algorithm identifiers above. */
151 #define OQS_KEM_algs_length 56
152 ///// OQS_COPY_FROM_UPSTREAM_FRAGMENT_ALGS_LENGTH_END
153 
154 /**
155  * Returns identifiers for available key encapsulation mechanisms in liboqs.  Used with OQS_KEM_new.
156  *
157  * Note that algorithm identifiers are present in this list even when the algorithm is disabled
158  * at compile time.
159  *
160  * @param[in] i Index of the algorithm identifier to return, 0 <= i < OQS_KEM_algs_length
161  * @return Algorithm identifier as a string, or NULL.
162  */
163 OQS_API const char *OQS_KEM_alg_identifier(size_t i);
164 
165 /**
166  * Returns the number of key encapsulation mechanisms in liboqs.  They can be enumerated with
167  * OQS_KEM_alg_identifier.
168  *
169  * Note that some mechanisms may be disabled at compile time.
170  *
171  * @return The number of key encapsulation mechanisms.
172  */
173 OQS_API int OQS_KEM_alg_count(void);
174 
175 /**
176  * Indicates whether the specified algorithm was enabled at compile-time or not.
177  *
178  * @param[in] method_name Name of the desired algorithm; one of the names in `OQS_KEM_algs`.
179  * @return 1 if enabled, 0 if disabled or not found
180  */
181 OQS_API int OQS_KEM_alg_is_enabled(const char *method_name);
182 
183 /**
184  * Key encapsulation mechanism object
185  */
186 typedef struct OQS_KEM {
187 
188 	/** Printable string representing the name of the key encapsulation mechanism. */
189 	const char *method_name;
190 
191 	/**
192 	 * Printable string representing the version of the cryptographic algorithm.
193 	 *
194 	 * Implementations with the same method_name and same alg_version will be interoperable.
195 	 * See README.md for information about algorithm compatibility.
196 	 */
197 	const char *alg_version;
198 
199 	/** The NIST security level (1, 2, 3, 4, 5) claimed in this algorithm's original NIST submission. */
200 	uint8_t claimed_nist_level;
201 
202 	/** Whether the KEM offers IND-CCA security (TRUE) or IND-CPA security (FALSE). */
203 	bool ind_cca;
204 
205 	/** The (maximum) length, in bytes, of public keys for this KEM. */
206 	size_t length_public_key;
207 	/** The (maximum) length, in bytes, of secret keys for this KEM. */
208 	size_t length_secret_key;
209 	/** The (maximum) length, in bytes, of ciphertexts for this KEM. */
210 	size_t length_ciphertext;
211 	/** The (maximum) length, in bytes, of shared secrets for this KEM. */
212 	size_t length_shared_secret;
213 
214 	/**
215 	 * Keypair generation algorithm.
216 	 *
217 	 * Caller is responsible for allocating sufficient memory for `public_key` and
218 	 * `secret_key`, based on the `length_*` members in this object or the per-scheme
219 	 * compile-time macros `OQS_KEM_*_length_*`.
220 	 *
221 	 * @param[out] public_key The public key represented as a byte string.
222 	 * @param[out] secret_key The secret key represented as a byte string.
223 	 * @return OQS_SUCCESS or OQS_ERROR
224 	 */
225 	OQS_STATUS (*keypair)(uint8_t *public_key, uint8_t *secret_key);
226 
227 	/**
228 	 * Encapsulation algorithm.
229 	 *
230 	 * Caller is responsible for allocating sufficient memory for `ciphertext` and
231 	 * `shared_secret`, based on the `length_*` members in this object or the per-scheme
232 	 * compile-time macros `OQS_KEM_*_length_*`.
233 	 *
234 	 * @param[out] ciphertext The ciphertext (encapsulation) represented as a byte string.
235 	 * @param[out] shared_secret The shared secret represented as a byte string.
236 	 * @param[in] public_key The public key represented as a byte string.
237 	 * @return OQS_SUCCESS or OQS_ERROR
238 	 */
239 	OQS_STATUS (*encaps)(uint8_t *ciphertext, uint8_t *shared_secret, const uint8_t *public_key);
240 
241 	/**
242 	 * Decapsulation algorithm.
243 	 *
244 	 * Caller is responsible for allocating sufficient memory for `shared_secret`, based
245 	 * on the `length_*` members in this object or the per-scheme compile-time macros
246 	 * `OQS_KEM_*_length_*`.
247 	 *
248 	 * @param[out] shared_secret The shared secret represented as a byte string.
249 	 * @param[in] ciphertext The ciphertext (encapsulation) represented as a byte string.
250 	 * @param[in] secret_key The secret key represented as a byte string.
251 	 * @return OQS_SUCCESS or OQS_ERROR
252 	 */
253 	OQS_STATUS (*decaps)(uint8_t *shared_secret, const uint8_t *ciphertext, const uint8_t *secret_key);
254 
255 } OQS_KEM;
256 
257 /**
258  * Constructs an OQS_KEM object for a particular algorithm.
259  *
260  * Callers should always check whether the return value is `NULL`, which indicates either than an
261  * invalid algorithm name was provided, or that the requested algorithm was disabled at compile-time.
262  *
263  * @param[in] method_name Name of the desired algorithm; one of the names in `OQS_KEM_algs`.
264  * @return An OQS_KEM for the particular algorithm, or `NULL` if the algorithm has been disabled at compile-time.
265  */
266 OQS_API OQS_KEM *OQS_KEM_new(const char *method_name);
267 
268 /**
269  * Keypair generation algorithm.
270  *
271  * Caller is responsible for allocating sufficient memory for `public_key` and
272  * `secret_key`, based on the `length_*` members in this object or the per-scheme
273  * compile-time macros `OQS_KEM_*_length_*`.
274  *
275  * @param[in] kem The OQS_KEM object representing the KEM.
276  * @param[out] public_key The public key represented as a byte string.
277  * @param[out] secret_key The secret key represented as a byte string.
278  * @return OQS_SUCCESS or OQS_ERROR
279  */
280 OQS_API OQS_STATUS OQS_KEM_keypair(const OQS_KEM *kem, uint8_t *public_key, uint8_t *secret_key);
281 
282 /**
283  * Encapsulation algorithm.
284  *
285  * Caller is responsible for allocating sufficient memory for `ciphertext` and
286  * `shared_secret`, based on the `length_*` members in this object or the per-scheme
287  * compile-time macros `OQS_KEM_*_length_*`.
288  *
289  * @param[in] kem The OQS_KEM object representing the KEM.
290  * @param[out] ciphertext The ciphertext (encapsulation) represented as a byte string.
291  * @param[out] shared_secret The shared secret represented as a byte string.
292  * @param[in] public_key The public key represented as a byte string.
293  * @return OQS_SUCCESS or OQS_ERROR
294  */
295 OQS_API OQS_STATUS OQS_KEM_encaps(const OQS_KEM *kem, uint8_t *ciphertext, uint8_t *shared_secret, const uint8_t *public_key);
296 
297 /**
298  * Decapsulation algorithm.
299  *
300  * Caller is responsible for allocating sufficient memory for `shared_secret`, based
301  * on the `length_*` members in this object or the per-scheme compile-time macros
302  * `OQS_KEM_*_length_*`.
303  *
304  * @param[in] kem The OQS_KEM object representing the KEM.
305  * @param[out] shared_secret The shared secret represented as a byte string.
306  * @param[in] ciphertext The ciphertext (encapsulation) represented as a byte string.
307  * @param[in] secret_key The secret key represented as a byte string.
308  * @return OQS_SUCCESS or OQS_ERROR
309  */
310 OQS_API OQS_STATUS OQS_KEM_decaps(const OQS_KEM *kem, uint8_t *shared_secret, const uint8_t *ciphertext, const uint8_t *secret_key);
311 
312 /**
313  * Frees an OQS_KEM object that was constructed by OQS_KEM_new.
314  *
315  * @param[in] kem The OQS_KEM object to free.
316  */
317 OQS_API void OQS_KEM_free(OQS_KEM *kem);
318 
319 #ifdef OQS_ENABLE_KEM_BIKE
320 #include <oqs/kem_bike.h>
321 #endif /* OQS_ENABLE_KEM_BIKE */
322 ///// OQS_COPY_FROM_UPSTREAM_FRAGMENT_INCLUDE_START
323 #ifdef OQS_ENABLE_KEM_CLASSIC_MCELIECE
324 #include <oqs/kem_classic_mceliece.h>
325 #endif /* OQS_ENABLE_KEM_CLASSIC_MCELIECE */
326 #ifdef OQS_ENABLE_KEM_HQC
327 #include <oqs/kem_hqc.h>
328 #endif /* OQS_ENABLE_KEM_HQC */
329 #ifdef OQS_ENABLE_KEM_KYBER
330 #include <oqs/kem_kyber.h>
331 #endif /* OQS_ENABLE_KEM_KYBER */
332 #ifdef OQS_ENABLE_KEM_NTRU
333 #include <oqs/kem_ntru.h>
334 #endif /* OQS_ENABLE_KEM_NTRU */
335 #ifdef OQS_ENABLE_KEM_NTRUPRIME
336 #include <oqs/kem_ntruprime.h>
337 #endif /* OQS_ENABLE_KEM_NTRUPRIME */
338 #ifdef OQS_ENABLE_KEM_SABER
339 #include <oqs/kem_saber.h>
340 #endif /* OQS_ENABLE_KEM_SABER */
341 ///// OQS_COPY_FROM_UPSTREAM_FRAGMENT_INCLUDE_END
342 #ifdef OQS_ENABLE_KEM_FRODOKEM
343 #include <oqs/kem_frodokem.h>
344 #endif /* OQS_ENABLE_KEM_FRODOKEM */
345 #ifdef OQS_ENABLE_KEM_SIKE
346 #include <oqs/kem_sike.h>
347 #endif /* OQS_ENABLE_KEM_SIKE */
348 #ifdef OQS_ENABLE_KEM_SIDH
349 #include <oqs/kem_sike.h>
350 #endif /* OQS_ENABLE_KEM_SIDH */
351 // EDIT-WHEN-ADDING-KEM
352 
353 #if defined(__cplusplus)
354 } // extern "C"
355 #endif
356 
357 #endif // OQS_KEM_H
358