summaryrefslogtreecommitdiff
path: root/lib/liboqs/include/oqs/kem.h
blob: 2b28851f9a35e99ef88dff46abaa10402722cce4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
/**
 * \file kem.h
 * \brief Key encapsulation mechanisms
 *
 * The file `tests/example_kem.c` contains two examples on using the OQS_KEM API.
 *
 * The first example uses the individual scheme's algorithms directly and uses
 * no dynamic memory allocation -- all buffers are allocated on the stack, with
 * sizes indicated using preprocessor macros.  Since algorithms can be disabled at
 * compile-time, the programmer should wrap the code in \#ifdefs.
 *
 * The second example uses an OQS_KEM object to use an algorithm specified at
 * runtime.  Therefore it uses dynamic memory allocation -- all buffers must be
 * malloc'ed by the programmer, with sizes indicated using the corresponding length
 * member of the OQS_KEM object in question.  Since algorithms can be disabled at
 * compile-time, the programmer should check that the OQS_KEM object is not `NULL`.
 *
 * SPDX-License-Identifier: MIT
 */

#ifndef OQS_KEM_H
#define OQS_KEM_H

#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

#include <oqs/oqs.h>

#if defined(__cplusplus)
extern "C" {
#endif

/** Algorithm identifier for BIKE-L1 KEM (Round-4). */
#define OQS_KEM_alg_bike_l1 "BIKE-L1"
/** Algorithm identifier for BIKE-L3 KEM (Round-4). */
#define OQS_KEM_alg_bike_l3 "BIKE-L3"
/** Algorithm identifier for BIKE-L5 KEM (Round-4). */
#define OQS_KEM_alg_bike_l5 "BIKE-L5"
///// OQS_COPY_FROM_UPSTREAM_FRAGMENT_ALG_IDENTIFIER_START
/** Algorithm identifier for Classic-McEliece-348864 KEM. */
#define OQS_KEM_alg_classic_mceliece_348864 "Classic-McEliece-348864"
/** Algorithm identifier for Classic-McEliece-348864f KEM. */
#define OQS_KEM_alg_classic_mceliece_348864f "Classic-McEliece-348864f"
/** Algorithm identifier for Classic-McEliece-460896 KEM. */
#define OQS_KEM_alg_classic_mceliece_460896 "Classic-McEliece-460896"
/** Algorithm identifier for Classic-McEliece-460896f KEM. */
#define OQS_KEM_alg_classic_mceliece_460896f "Classic-McEliece-460896f"
/** Algorithm identifier for Classic-McEliece-6688128 KEM. */
#define OQS_KEM_alg_classic_mceliece_6688128 "Classic-McEliece-6688128"
/** Algorithm identifier for Classic-McEliece-6688128f KEM. */
#define OQS_KEM_alg_classic_mceliece_6688128f "Classic-McEliece-6688128f"
/** Algorithm identifier for Classic-McEliece-6960119 KEM. */
#define OQS_KEM_alg_classic_mceliece_6960119 "Classic-McEliece-6960119"
/** Algorithm identifier for Classic-McEliece-6960119f KEM. */
#define OQS_KEM_alg_classic_mceliece_6960119f "Classic-McEliece-6960119f"
/** Algorithm identifier for Classic-McEliece-8192128 KEM. */
#define OQS_KEM_alg_classic_mceliece_8192128 "Classic-McEliece-8192128"
/** Algorithm identifier for Classic-McEliece-8192128f KEM. */
#define OQS_KEM_alg_classic_mceliece_8192128f "Classic-McEliece-8192128f"
/** Algorithm identifier for HQC-128 KEM. */
#define OQS_KEM_alg_hqc_128 "HQC-128"
/** Algorithm identifier for HQC-192 KEM. */
#define OQS_KEM_alg_hqc_192 "HQC-192"
/** Algorithm identifier for HQC-256 KEM. */
#define OQS_KEM_alg_hqc_256 "HQC-256"
/** Algorithm identifier for Kyber512 KEM. */
#define OQS_KEM_alg_kyber_512 "Kyber512"
/** Algorithm identifier for Kyber768 KEM. */
#define OQS_KEM_alg_kyber_768 "Kyber768"
/** Algorithm identifier for Kyber1024 KEM. */
#define OQS_KEM_alg_kyber_1024 "Kyber1024"
/** Algorithm identifier for Kyber512-90s KEM. */
#define OQS_KEM_alg_kyber_512_90s "Kyber512-90s"
/** Algorithm identifier for Kyber768-90s KEM. */
#define OQS_KEM_alg_kyber_768_90s "Kyber768-90s"
/** Algorithm identifier for Kyber1024-90s KEM. */
#define OQS_KEM_alg_kyber_1024_90s "Kyber1024-90s"
///// OQS_COPY_FROM_UPSTREAM_FRAGMENT_ALG_IDENTIFIER_END
/** Algorithm identifier for sntrup761 KEM. */
#define OQS_KEM_alg_ntruprime_sntrup761 "sntrup761"
/** Algorithm identifier for FrodoKEM-640-AES KEM. */
#define OQS_KEM_alg_frodokem_640_aes "FrodoKEM-640-AES"
/** Algorithm identifier for FrodoKEM-640-SHAKE KEM. */
#define OQS_KEM_alg_frodokem_640_shake "FrodoKEM-640-SHAKE"
/** Algorithm identifier for FrodoKEM-976-AES KEM. */
#define OQS_KEM_alg_frodokem_976_aes "FrodoKEM-976-AES"
/** Algorithm identifier for FrodoKEM-976-SHAKE KEM. */
#define OQS_KEM_alg_frodokem_976_shake "FrodoKEM-976-SHAKE"
/** Algorithm identifier for FrodoKEM-1344-AES KEM. */
#define OQS_KEM_alg_frodokem_1344_aes "FrodoKEM-1344-AES"
/** Algorithm identifier for FrodoKEM-1344-SHAKE KEM. */
#define OQS_KEM_alg_frodokem_1344_shake "FrodoKEM-1344-SHAKE"
// EDIT-WHEN-ADDING-KEM
///// OQS_COPY_FROM_UPSTREAM_FRAGMENT_ALGS_LENGTH_START
/** Number of algorithm identifiers above. */
#define OQS_KEM_algs_length 29
///// OQS_COPY_FROM_UPSTREAM_FRAGMENT_ALGS_LENGTH_END

/**
 * Returns identifiers for available key encapsulation mechanisms in liboqs.  Used with OQS_KEM_new.
 *
 * Note that algorithm identifiers are present in this list even when the algorithm is disabled
 * at compile time.
 *
 * @param[in] i Index of the algorithm identifier to return, 0 <= i < OQS_KEM_algs_length
 * @return Algorithm identifier as a string, or NULL.
 */
OQS_API const char *OQS_KEM_alg_identifier(size_t i);

/**
 * Returns the number of key encapsulation mechanisms in liboqs.  They can be enumerated with
 * OQS_KEM_alg_identifier.
 *
 * Note that some mechanisms may be disabled at compile time.
 *
 * @return The number of key encapsulation mechanisms.
 */
OQS_API int OQS_KEM_alg_count(void);

/**
 * Indicates whether the specified algorithm was enabled at compile-time or not.
 *
 * @param[in] method_name Name of the desired algorithm; one of the names in `OQS_KEM_algs`.
 * @return 1 if enabled, 0 if disabled or not found
 */
OQS_API int OQS_KEM_alg_is_enabled(const char *method_name);

/**
 * Key encapsulation mechanism object
 */
typedef struct OQS_KEM {

	/** Printable string representing the name of the key encapsulation mechanism. */
	const char *method_name;

	/**
	 * Printable string representing the version of the cryptographic algorithm.
	 *
	 * Implementations with the same method_name and same alg_version will be interoperable.
	 * See README.md for information about algorithm compatibility.
	 */
	const char *alg_version;

	/** The NIST security level (1, 2, 3, 4, 5) claimed in this algorithm's original NIST submission. */
	uint8_t claimed_nist_level;

	/** Whether the KEM offers IND-CCA security (TRUE) or IND-CPA security (FALSE). */
	bool ind_cca;

	/** The (maximum) length, in bytes, of public keys for this KEM. */
	size_t length_public_key;
	/** The (maximum) length, in bytes, of secret keys for this KEM. */
	size_t length_secret_key;
	/** The (maximum) length, in bytes, of ciphertexts for this KEM. */
	size_t length_ciphertext;
	/** The (maximum) length, in bytes, of shared secrets for this KEM. */
	size_t length_shared_secret;

	/**
	 * Keypair generation algorithm.
	 *
	 * Caller is responsible for allocating sufficient memory for `public_key` and
	 * `secret_key`, based on the `length_*` members in this object or the per-scheme
	 * compile-time macros `OQS_KEM_*_length_*`.
	 *
	 * @param[out] public_key The public key represented as a byte string.
	 * @param[out] secret_key The secret key represented as a byte string.
	 * @return OQS_SUCCESS or OQS_ERROR
	 */
	OQS_STATUS (*keypair)(uint8_t *public_key, uint8_t *secret_key);

	/**
	 * Encapsulation algorithm.
	 *
	 * Caller is responsible for allocating sufficient memory for `ciphertext` and
	 * `shared_secret`, based on the `length_*` members in this object or the per-scheme
	 * compile-time macros `OQS_KEM_*_length_*`.
	 *
	 * @param[out] ciphertext The ciphertext (encapsulation) represented as a byte string.
	 * @param[out] shared_secret The shared secret represented as a byte string.
	 * @param[in] public_key The public key represented as a byte string.
	 * @return OQS_SUCCESS or OQS_ERROR
	 */
	OQS_STATUS (*encaps)(uint8_t *ciphertext, uint8_t *shared_secret, const uint8_t *public_key);

	/**
	 * Decapsulation algorithm.
	 *
	 * Caller is responsible for allocating sufficient memory for `shared_secret`, based
	 * on the `length_*` members in this object or the per-scheme compile-time macros
	 * `OQS_KEM_*_length_*`.
	 *
	 * @param[out] shared_secret The shared secret represented as a byte string.
	 * @param[in] ciphertext The ciphertext (encapsulation) represented as a byte string.
	 * @param[in] secret_key The secret key represented as a byte string.
	 * @return OQS_SUCCESS or OQS_ERROR
	 */
	OQS_STATUS (*decaps)(uint8_t *shared_secret, const uint8_t *ciphertext, const uint8_t *secret_key);

} OQS_KEM;

/**
 * Constructs an OQS_KEM object for a particular algorithm.
 *
 * Callers should always check whether the return value is `NULL`, which indicates either than an
 * invalid algorithm name was provided, or that the requested algorithm was disabled at compile-time.
 *
 * @param[in] method_name Name of the desired algorithm; one of the names in `OQS_KEM_algs`.
 * @return An OQS_KEM for the particular algorithm, or `NULL` if the algorithm has been disabled at compile-time.
 */
OQS_API OQS_KEM *OQS_KEM_new(const char *method_name);

/**
 * Keypair generation algorithm.
 *
 * Caller is responsible for allocating sufficient memory for `public_key` and
 * `secret_key`, based on the `length_*` members in this object or the per-scheme
 * compile-time macros `OQS_KEM_*_length_*`.
 *
 * @param[in] kem The OQS_KEM object representing the KEM.
 * @param[out] public_key The public key represented as a byte string.
 * @param[out] secret_key The secret key represented as a byte string.
 * @return OQS_SUCCESS or OQS_ERROR
 */
OQS_API OQS_STATUS OQS_KEM_keypair(const OQS_KEM *kem, uint8_t *public_key, uint8_t *secret_key);

/**
 * Encapsulation algorithm.
 *
 * Caller is responsible for allocating sufficient memory for `ciphertext` and
 * `shared_secret`, based on the `length_*` members in this object or the per-scheme
 * compile-time macros `OQS_KEM_*_length_*`.
 *
 * @param[in] kem The OQS_KEM object representing the KEM.
 * @param[out] ciphertext The ciphertext (encapsulation) represented as a byte string.
 * @param[out] shared_secret The shared secret represented as a byte string.
 * @param[in] public_key The public key represented as a byte string.
 * @return OQS_SUCCESS or OQS_ERROR
 */
OQS_API OQS_STATUS OQS_KEM_encaps(const OQS_KEM *kem, uint8_t *ciphertext, uint8_t *shared_secret, const uint8_t *public_key);

/**
 * Decapsulation algorithm.
 *
 * Caller is responsible for allocating sufficient memory for `shared_secret`, based
 * on the `length_*` members in this object or the per-scheme compile-time macros
 * `OQS_KEM_*_length_*`.
 *
 * @param[in] kem The OQS_KEM object representing the KEM.
 * @param[out] shared_secret The shared secret represented as a byte string.
 * @param[in] ciphertext The ciphertext (encapsulation) represented as a byte string.
 * @param[in] secret_key The secret key represented as a byte string.
 * @return OQS_SUCCESS or OQS_ERROR
 */
OQS_API OQS_STATUS OQS_KEM_decaps(const OQS_KEM *kem, uint8_t *shared_secret, const uint8_t *ciphertext, const uint8_t *secret_key);

/**
 * Frees an OQS_KEM object that was constructed by OQS_KEM_new.
 *
 * @param[in] kem The OQS_KEM object to free.
 */
OQS_API void OQS_KEM_free(OQS_KEM *kem);

#ifdef OQS_ENABLE_KEM_BIKE
#include <oqs/kem_bike.h>
#endif /* OQS_ENABLE_KEM_BIKE */
///// OQS_COPY_FROM_UPSTREAM_FRAGMENT_INCLUDE_START
#ifdef OQS_ENABLE_KEM_CLASSIC_MCELIECE
#include <oqs/kem_classic_mceliece.h>
#endif /* OQS_ENABLE_KEM_CLASSIC_MCELIECE */
#ifdef OQS_ENABLE_KEM_HQC
#include <oqs/kem_hqc.h>
#endif /* OQS_ENABLE_KEM_HQC */
#ifdef OQS_ENABLE_KEM_KYBER
#include <oqs/kem_kyber.h>
#endif /* OQS_ENABLE_KEM_KYBER */
///// OQS_COPY_FROM_UPSTREAM_FRAGMENT_INCLUDE_END
#ifdef OQS_ENABLE_KEM_NTRUPRIME
#include <oqs/kem_ntruprime.h>
#endif /* OQS_ENABLE_KEM_NTRUPRIME */
#ifdef OQS_ENABLE_KEM_FRODOKEM
#include <oqs/kem_frodokem.h>
#endif /* OQS_ENABLE_KEM_FRODOKEM */
// EDIT-WHEN-ADDING-KEM

#if defined(__cplusplus)
} // extern "C"
#endif

#endif // OQS_KEM_H