summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/mlkem/mlkem_internal.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/mlkem/mlkem_internal.h')
-rw-r--r--src/lib/libcrypto/mlkem/mlkem_internal.h460
1 files changed, 177 insertions, 283 deletions
diff --git a/src/lib/libcrypto/mlkem/mlkem_internal.h b/src/lib/libcrypto/mlkem/mlkem_internal.h
index 7e6c313aa9..2b3157256e 100644
--- a/src/lib/libcrypto/mlkem/mlkem_internal.h
+++ b/src/lib/libcrypto/mlkem/mlkem_internal.h
@@ -1,6 +1,7 @@
1/* $OpenBSD: mlkem_internal.h,v 1.9 2025/08/19 21:37:08 tb Exp $ */ 1/* $OpenBSD: mlkem_internal.h,v 1.10 2025/09/05 23:30:12 beck Exp $ */
2/* 2/*
3 * Copyright (c) 2023, Google Inc. 3 * Copyright (c) 2023, Google Inc.
4 * Copyright (c) 2025, Bob Beck <beck@obtuse.com>
4 * 5 *
5 * Permission to use, copy, modify, and/or distribute this software for any 6 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above 7 * purpose with or without fee is hereby granted, provided that the above
@@ -26,402 +27,295 @@ extern "C" {
26#endif 27#endif
27 28
28__BEGIN_HIDDEN_DECLS 29__BEGIN_HIDDEN_DECLS
29/*
30 * MLKEM_SEED_LENGTH is the number of bytes in an ML-KEM seed. An ML-KEM
31 * seed is normally used to represent a private key.
32 */
33#define MLKEM_SEED_LENGTH 64
34 30
35/* 31/* Public opaque ML-KEM key structures. */
36 * MLKEM_SHARED_SECRET_LENGTH is the number of bytes in an ML-KEM shared
37 * secret.
38 */
39#define MLKEM_SHARED_SECRET_LENGTH 32
40 32
41/* 33#define MLKEM_PUBLIC_KEY_UNINITIALIZED 1
42 * |MLKEM_encap_external_entropy| behaves exactly like the public |MLKEM_encap| 34#define MLKEM_PUBLIC_KEY_INITIALIZED 2
43 * with the entropy provided by the caller. It is directly called internally 35#define MLKEM_PRIVATE_KEY_UNINITIALIZED 3
44 * and by tests. 36#define MLKEM_PRIVATE_KEY_INITIALIZED 4
45 */
46int
47MLKEM_encap_external_entropy(const MLKEM_public_key *public_key,
48 const uint8_t *entropy, uint8_t **out_ciphertext,
49 size_t *out_ciphertext_len, uint8_t **out_shared_secret,
50 size_t *out_shared_secret_len);
51 37
52/* 38struct MLKEM_public_key_st {
53 * |MLKEM_generate_key_external_entropy| behaves exactly like the public 39 uint16_t rank;
54 * |MLKEM_generate_key| with the entropy provided by the caller. 40 int state;
55 * It is directly called internally and by tests. 41 struct MLKEM768_public_key *key_768;
56 */ 42 struct MLKEM1024_public_key *key_1024;
57int 43};
58MLKEM_generate_key_external_entropy(MLKEM_private_key *private_key, 44
59 uint8_t **out_encoded_public_key, size_t *out_encoded_public_key_len, 45struct MLKEM_private_key_st {
60 const uint8_t *entropy); 46 uint16_t rank;
47 int state;
48 struct MLKEM768_private_key *key_768;
49 struct MLKEM1024_private_key *key_1024;
50};
61 51
62/* 52/*
63 * ML-KEM-768 53 * ML-KEM-768 and ML-KEM-1024
64 * 54 *
65 * This implements the Module-Lattice-Based Key-Encapsulation Mechanism from 55 * This implements the Module-Lattice-Based Key-Encapsulation Mechanism from
66 * https://csrc.nist.gov/pubs/fips/204/final 56 * https://csrc.nist.gov/pubs/fips/204/final
57 *
58 * You should prefer ML-KEM-768 where possible. ML-KEM-1024 is larger and exists
59 * for people who are obsessed with more 'bits of crypto', and who are also
60 * lacking the knowledge to realize that anything that can count to 256 bits
61 * must likely use an equivalent amount of energy to that of an entire star to
62 * do so.
63 *
64 * ML-KEM-768 is adequate to protect against a future cryptographically relevant
65 * quantum computer, VIC 20, abacus, or carefully calibrated reference dog. I
66 * for one plan on welcoming our new Kardashev-II civilization overlords with
67 * open arms. In the meantime will not waste bytes on the wire by to adding
68 * the fear of the possible future existence of a cryptographically relevant
69 * Dyson sphere to the aforementioned list of fear-inducing future
70 * cryptographically relevant hypotheticals.
71 *
72 * If your carefully calibrated reference dog notices the sun starting to dim,
73 * you might need ML-KEM-1024, but you probably have bigger concerns than
74 * the decryption of your stored past TLS sessions at that point.
67 */ 75 */
68 76
69/* 77/*
70 * MLKEM768_PUBLIC_KEY_BYTES is the number of bytes in an encoded ML-KEM768 public 78 * MLKEM1024_public_key contains an ML-KEM-1024 public key. The contents of this
71 * key. 79 * object should never leave the address space since the format is unstable.
72 */ 80 */
73#define MLKEM768_PUBLIC_KEY_BYTES 1184 81struct MLKEM1024_public_key {
74 82 uint8_t bytes[512 * (4 + 16) + 32 + 32];
75/* MLKEM_SEED_BYTES is the number of bytes in an ML-KEM seed. */ 83 uint16_t alignment;
76#define MLKEM_SEED_BYTES 64 84};
77 85
78/* 86/*
79 * MLKEM_SHARED_SECRET_BYTES is the number of bytes in the ML-KEM768 shared 87 * MLKEM1024_private_key contains a ML-KEM-1024 private key. The contents of
80 * secret. Although the round-3 specification has a variable-length output, the 88 * this object should never leave the address space since the format is
81 * final ML-KEM construction is expected to use a fixed 32-byte output. To 89 * unstable.
82 * simplify the future transition, we apply the same restriction.
83 */ 90 */
84#define MLKEM_SHARED_SECRET_BYTES 32 91struct MLKEM1024_private_key {
92 uint8_t bytes[512 * (4 + 4 + 16) + 32 + 32 + 32];
93 uint16_t alignment;
94};
85 95
86/* 96/*
87 * MLKEM_generate_key generates a random public/private key pair, writes the 97 * MLKEM768_public_key contains a ML-KEM-768 public key. The contents of this
88 * encoded public key to |out_encoded_public_key| and sets |out_private_key| to 98 * object should never leave the address space since the format is unstable.
89 * the private key. If |optional_out_seed| is not NULL then the seed used to
90 * generate the private key is written to it.
91 */ 99 */
92int MLKEM768_generate_key( 100struct MLKEM768_public_key {
93 uint8_t out_encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES], 101 uint8_t bytes[512 * (3 + 9) + 32 + 32];
94 uint8_t optional_out_seed[MLKEM_SEED_BYTES], 102 uint16_t alignment;
95 MLKEM_private_key *out_private_key); 103};
96 104
97/* 105/*
98 * MLKEM768_private_key_from_seed derives a private key from a seed that was 106 * MLKEM768_private_key contains a ML-KEM-768 private key. The contents of this
99 * generated by |MLKEM768_generate_key|. It fails and returns 0 if |seed_len| is 107 * object should never leave the address space since the format is unstable.
100 * incorrect, otherwise it writes |*out_private_key| and returns 1.
101 */ 108 */
102int MLKEM768_private_key_from_seed(const uint8_t *seed, size_t seed_len, 109struct MLKEM768_private_key {
103 MLKEM_private_key *out_private_key); 110 uint8_t bytes[512 * (3 + 3 + 9) + 32 + 32 + 32];
111 uint16_t alignment;
112};
104 113
105/* 114/*
106 * MLKEM_public_from_private sets |*out_public_key| to the public key that 115 * MLKEM_SEED_LENGTH is the number of bytes in an ML-KEM seed. An ML-KEM
107 * corresponds to |private_key|. (This is faster than parsing the output of 116 * seed is normally used to represent a private key.
108 * |MLKEM_generate_key| if, for some reason, you need to encapsulate to a key
109 * that was just generated.)
110 */ 117 */
111void MLKEM768_public_from_private(const MLKEM_private_key *private_key, 118#define MLKEM_SEED_LENGTH 64
112 MLKEM_public_key *out_public_key);
113
114/* MLKEM768_CIPHERTEXT_BYTES is number of bytes in the ML-KEM768 ciphertext. */
115#define MLKEM768_CIPHERTEXT_BYTES 1088
116 119
117/* 120/*
118 * MLKEM768_encap encrypts a random shared secret for |public_key|, writes the 121 * MLKEM_SHARED_SECRET_LENGTH is the number of bytes in an ML-KEM shared
119 * ciphertext to |out_ciphertext|, and writes the random shared secret to 122 * secret.
120 * |out_shared_secret|.
121 */ 123 */
122void MLKEM768_encap(const MLKEM_public_key *public_key, 124#define MLKEM_SHARED_SECRET_LENGTH 32
123 uint8_t out_ciphertext[MLKEM768_CIPHERTEXT_BYTES],
124 uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES]);
125 125
126/* 126/*
127 * MLKEM768_decap decrypts a shared secret from |ciphertext| using |private_key| 127 * MLKEM_ENCAP_ENTROPY is the number of bytes of uniformly random entropy
128 * and writes it to |out_shared_secret|. If |ciphertext_len| is incorrect it 128 * necessary to encapsulate a secret. The entropy will be leaked to the
129 * returns 0, otherwise it rreturns 1. If |ciphertext| is invalid, 129 * decapsulating party.
130 * |out_shared_secret| is filled with a key that will always be the same for the
131 * same |ciphertext| and |private_key|, but which appears to be random unless
132 * one has access to |private_key|. These alternatives occur in constant time.
133 * Any subsequent symmetric encryption using |out_shared_secret| must use an
134 * authenticated encryption scheme in order to discover the decapsulation
135 * failure.
136 */ 130 */
137int MLKEM768_decap(const MLKEM_private_key *private_key, 131#define MLKEM_ENCAP_ENTROPY 32
138 const uint8_t *ciphertext, size_t ciphertext_len,
139 uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES]);
140 132
141/* Serialisation of keys. */ 133/* MLKEM1024_CIPHERTEXT_BYTES is number of bytes in the ML-KEM-1024 ciphertext. */
134#define MLKEM1024_CIPHERTEXT_BYTES 1568
135
136/* MLKEM768_CIPHERTEXT_BYTES is number of bytes in the ML-KEM768 ciphertext. */
137#define MLKEM768_CIPHERTEXT_BYTES 1088
142 138
143/* 139/*
144 * MLKEM768_marshal_public_key serializes |public_key| to |out| in the standard 140 * MLKEM768_PUBLIC_KEY_BYTES is the number of bytes in an encoded ML-KEM768 public
145 * format for ML-KEM public keys. It returns one on success or zero on allocation 141 * key.
146 * error.
147 */ 142 */
148int MLKEM768_marshal_public_key(const MLKEM_public_key *public_key, 143#define MLKEM768_PUBLIC_KEY_BYTES 1184
149 uint8_t **output, size_t *output_len);
150 144
151/* 145/*
152 * MLKEM768_parse_public_key parses a public key, in the format generated by 146 * MLKEM1024_PUBLIC_KEY_BYTES is the number of bytes in an encoded ML-KEM-1024
153 * |MLKEM_marshal_public_key|, from |in| and writes the result to 147 * public key.
154 * |out_public_key|. It returns one on success or zero on parse error or if
155 * there are trailing bytes in |in|.
156 */ 148 */
157int MLKEM768_parse_public_key(const uint8_t *input, size_t input_len, 149#define MLKEM1024_PUBLIC_KEY_BYTES 1568
158 MLKEM_public_key *out_public_key);
159 150
160/* 151/*
161 * MLKEM_parse_private_key parses a private key, in the format generated by 152 * MLKEM768_PRIVATE_KEY_BYTES is the length of the data produced by
162 * |MLKEM_marshal_private_key|, from |in| and writes the result to 153 * |marshal_private_key| for a RANK768 MLKEM_private_key.
163 * |out_private_key|. It returns one on success or zero on parse error or if
164 * there are trailing bytes in |in|. This formate is verbose and should be avoided.
165 * Private keys should be stored as seeds and parsed using |MLKEM768_private_key_from_seed|.
166 */ 154 */
167int MLKEM768_parse_private_key(const uint8_t *input, size_t input_len, 155#define MLKEM768_PRIVATE_KEY_BYTES 2400
168 MLKEM_private_key *out_private_key);
169 156
170/* 157/*
171 * ML-KEM-1024 158 * MLKEM1024_PRIVATE_KEY_BYTES is the length of the data produced by
172 * 159 * |marshal_private_key| for a RANK1024 MLKEM_private_key.
173 * ML-KEM-1024 also exists. You should prefer ML-KEM-768 where possible.
174 */ 160 */
161#define MLKEM1024_PRIVATE_KEY_BYTES 3168
175 162
176/* 163/*
177 * MLKEM1024_PUBLIC_KEY_BYTES is the number of bytes in an encoded ML-KEM-1024 164 * Internal MLKEM 768 and MLKEM 1024 functions come largely from BoringSSL, but
178 * public key. 165 * converted to C from templated C++. Due to this history, most internal
166 * functions do not allocate, and are expected to be handed memory allocated by
167 * the caller. The caller is generally expected to know what sizes to allocate
168 * based upon the rank of the key (either public or private) that they are
169 * starting with. This avoids the need to handle memory allocation failures
170 * (which boring in C++ just crashes by choice) deep in the implementation, as
171 * what is needed is allocated up front in the public facing functions, and
172 * failure is handled there.
179 */ 173 */
180#define MLKEM1024_PUBLIC_KEY_BYTES 1568 174
175/* Key generation. */
181 176
182/* 177/*
183 * MLKEM1024_generate_key generates a random public/private key pair, writes the 178 * mlkem_generate_key generates a random public/private key pair, writes the
184 * encoded public key to |out_encoded_public_key| and sets |out_private_key| to 179 * encoded public key to |out_encoded_public_key| and sets |out_private_key| to
185 * the private key. If |optional_out_seed| is not NULL then the seed used to 180 * the private key. If |optional_out_seed| is not NULL then the seed used to
186 * generate the private key is written to it. 181 * generate the private key is written to it. The caller is responsible for
182 * ensuring that |out_encoded_public_key| and |out_optonal_seed| point to
183 * enough memory to contain a key and seed for the rank of |out_private_key|.
187 */ 184 */
188int MLKEM1024_generate_key( 185int mlkem_generate_key(uint8_t *out_encoded_public_key,
189 uint8_t out_encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES], 186 uint8_t *optional_out_seed, MLKEM_private_key *out_private_key);
190 uint8_t optional_out_seed[MLKEM_SEED_BYTES],
191 MLKEM_private_key *out_private_key);
192 187
193/* 188/*
194 * MLKEM1024_private_key_from_seed derives a private key from a seed that was 189 * mlkem_private_key_from_seed modifies |out_private_key| to generate a key of
195 * generated by |MLKEM1024_generate_key|. It fails and returns 0 if |seed_len| 190 * the rank of |*out_private_key| from a seed that was generated by
196 * is incorrect, otherwise it writes |*out_private_key| and returns 1. 191 * |mlkem_generate_key|. It fails and returns 0 if |seed_len| is incorrect, or
192 * if |*out_private_key| has not been initialized. otherwise it writes to
193 * |*out_private_key| and returns 1.
197 */ 194 */
198int MLKEM1024_private_key_from_seed( 195int mlkem_private_key_from_seed(const uint8_t *seed, size_t seed_len,
199 MLKEM_private_key *out_private_key, const uint8_t *seed, 196 MLKEM_private_key *out_private_key);
200 size_t seed_len);
201 197
202/* 198/*
203 * MLKEM1024_public_from_private sets |*out_public_key| to the public key that 199 * mlkem_public_from_private sets |*out_public_key| to the public key that
204 * corresponds to |private_key|. (This is faster than parsing the output of 200 * corresponds to |*private_key|. (This is faster than parsing the output of
205 * |MLKEM1024_generate_key| if, for some reason, you need to encapsulate to a 201 * |MLKEM_generate_key| if, for some reason, you need to encapsulate to a key
206 * key that was just generated.) 202 * that was just generated.)
207 */ 203 */
208void MLKEM1024_public_from_private(const MLKEM_private_key *private_key, 204void mlkem_public_from_private(const MLKEM_private_key *private_key,
209 MLKEM_public_key *out_public_key); 205 MLKEM_public_key *out_public_key);
210 206
211/* MLKEM1024_CIPHERTEXT_BYTES is number of bytes in the ML-KEM-1024 ciphertext. */ 207
212#define MLKEM1024_CIPHERTEXT_BYTES 1568 208/* Encapsulation and decapsulation of secrets. */
213 209
214/* 210/*
215 * MLKEM1024_encap encrypts a random shared secret for |public_key|, writes the 211 * mlkem_encap encrypts a random shared secret for |public_key|, writes the
216 * ciphertext to |out_ciphertext|, and writes the random shared secret to 212 * ciphertext to |out_ciphertext|, and writes the random shared secret to
217 * |out_shared_secret|. 213 * |out_shared_secret|.
218 */ 214 */
219void MLKEM1024_encap(const MLKEM_public_key *public_key, 215void mlkem_encap(const MLKEM_public_key *public_key,
220 uint8_t out_ciphertext[MLKEM1024_CIPHERTEXT_BYTES], 216 uint8_t out_ciphertext[MLKEM768_CIPHERTEXT_BYTES],
221 uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES]); 217 uint8_t out_shared_secret[MLKEM_SHARED_SECRET_LENGTH]);
222
223 218
224/* 219/*
225 * MLKEM1024_decap decrypts a shared secret from |ciphertext| using 220 * mlkem_decap decrypts a shared secret from |ciphertext| using |private_key|
226 * |private_key| and writes it to |out_shared_secret|. If |ciphertext_len| is 221 * and writes it to |out_shared_secret|. If |ciphertext_len| is incorrect it
227 * incorrect it returns 0, otherwise it returns 1. If |ciphertext| is invalid 222 * returns 0, otherwise it returns 1. If |ciphertext| is invalid,
228 * (but of the correct length), |out_shared_secret| is filled with a key that 223 * |out_shared_secret| is filled with a key that will always be the same for the
229 * will always be the same for the same |ciphertext| and |private_key|, but 224 * same |ciphertext| and |private_key|, but which appears to be random unless
230 * which appears to be random unless one has access to |private_key|. These 225 * one has access to |private_key|. These alternatives occur in constant time.
231 * alternatives occur in constant time. Any subsequent symmetric encryption 226 * Any subsequent symmetric encryption using |out_shared_secret| must use an
232 * using |out_shared_secret| must use an authenticated encryption scheme in 227 * authenticated encryption scheme in order to discover the decapsulation
233 * order to discover the decapsulation failure. 228 * failure.
234 */ 229 */
235int MLKEM1024_decap(const MLKEM_private_key *private_key, 230int mlkem_decap(const MLKEM_private_key *private_key,
236 const uint8_t *ciphertext, size_t ciphertext_len, 231 const uint8_t *ciphertext, size_t ciphertext_len,
237 uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES]); 232 uint8_t out_shared_secret[MLKEM_SHARED_SECRET_LENGTH]);
233
234
235/* Serialisation of keys. */
238 236
239/* 237/*
240 * Serialisation of ML-KEM-1024 keys. 238 * mlkem_marshal_public_key serializes |public_key| to |output| in the standard
241 * MLKEM1024_marshal_public_key serializes |public_key| to |out| in the standard 239 * format for ML-KEM public keys. It returns one on success or zero on allocation
242 * format for ML-KEM-1024 public keys. It returns one on success or zero on 240 * error.
243 * allocation error.
244 */ 241 */
245int MLKEM1024_marshal_public_key(const MLKEM_public_key *public_key, 242int mlkem_marshal_public_key(const MLKEM_public_key *public_key,
246 uint8_t **output, size_t *output_len); 243 uint8_t **output, size_t *output_len);
247 244
248
249/* 245/*
250 * MLKEM1024_parse_public_key parses a public key, in the format generated by 246 * mlkem_parse_public_key parses a public key, in the format generated by
251 * |MLKEM1024_marshal_public_key|, from |in| and writes the result to 247 * |MLKEM_marshal_public_key|, from |input| and writes the result to
252 * |out_public_key|. It returns one on success or zero on parse error or if 248 * |out_public_key|. It returns one on success or zero on parse error or if
253 * there are trailing bytes in |in|. 249 * there are trailing bytes in |input|.
254 */ 250 */
255int MLKEM1024_parse_public_key(const uint8_t *input, size_t input_len, 251int mlkem_parse_public_key(const uint8_t *input, size_t input_len,
256 MLKEM_public_key *out_public_key); 252 MLKEM_public_key *out_public_key);
257 253
258
259/* 254/*
260 * MLKEM1024_parse_private_key parses a private key, in NIST's format for 255 * mlkem_parse_private_key parses a private key, in the format generated by
261 * private keys, from |in| and writes the result to |out_private_key|. It 256 * |MLKEM_marshal_private_key|, from |input| and writes the result to
262 * returns one on success or zero on parse error or if there are trailing bytes 257 * |out_private_key|. It returns one on success or zero on parse error or if
263 * in |in|. This format is verbose and should be avoided. Private keys should be 258 * there are trailing bytes in |input|. This formate is verbose and should be avoided.
264 * stored as seeds and parsed using |MLKEM1024_private_key_from_seed|. 259 * Private keys should be stored as seeds and parsed using |mlkem_private_key_from_seed|.
265 */ 260 */
266int MLKEM1024_parse_private_key(const uint8_t *input, size_t input_len, 261int mlkem_parse_private_key(const uint8_t *input, size_t input_len,
267 MLKEM_private_key *out_private_key); 262 MLKEM_private_key *out_private_key);
268
269
270/* XXXX Truly internal stuff below, also in need of de-duping */
271 263
272/*
273 * MLKEM_ENCAP_ENTROPY is the number of bytes of uniformly random entropy
274 * necessary to encapsulate a secret. The entropy will be leaked to the
275 * decapsulating party.
276 */
277#define MLKEM_ENCAP_ENTROPY 32
278 264
279/* 265/* Functions that are only used for test purposes. */
280 * MLKEM768_public_key contains a ML-KEM-768 public key. The contents of this
281 * object should never leave the address space since the format is unstable.
282 */
283struct MLKEM768_public_key {
284 union {
285 uint8_t bytes[512 * (3 + 9) + 32 + 32];
286 uint16_t alignment;
287 } opaque;
288};
289 266
290/* 267/*
291 * MLKEM768_private_key contains a ML-KEM-768 private key. The contents of this 268 * mlkem_generate_key_external_entropy is a deterministic function to create a
292 * object should never leave the address space since the format is unstable.
293 */
294struct MLKEM768_private_key {
295 union {
296 uint8_t bytes[512 * (3 + 3 + 9) + 32 + 32 + 32];
297 uint16_t alignment;
298 } opaque;
299};
300
301/* Public opaque ML-KEM key structures. */
302
303#define MLKEM_PUBLIC_KEY_UNINITIALIZED 1
304#define MLKEM_PUBLIC_KEY_INITIALIZED 2
305#define MLKEM_PRIVATE_KEY_UNINITIALIZED 3
306#define MLKEM_PRIVATE_KEY_INITIALIZED 4
307
308struct MLKEM_public_key_st {
309 uint16_t rank;
310 int state;
311 struct MLKEM768_public_key *key_768;
312 struct MLKEM1024_public_key *key_1024;
313};
314
315struct MLKEM_private_key_st {
316 uint16_t rank;
317 int state;
318 struct MLKEM768_private_key *key_768;
319 struct MLKEM1024_private_key *key_1024;
320};
321
322/*
323 * MLKEM768_generate_key_external_entropy is a deterministic function to create a
324 * pair of ML-KEM 768 keys, using the supplied entropy. The entropy needs to be 269 * pair of ML-KEM 768 keys, using the supplied entropy. The entropy needs to be
325 * uniformly random generated. This function is should only be used for tests, 270 * uniformly random generated. This function is should only be used for tests,
326 * regular callers should use the non-deterministic |MLKEM_generate_key| 271 * regular callers should use the non-deterministic |MLKEM_generate_key|
327 * directly. 272 * directly.
328 */ 273 */
329int MLKEM768_generate_key_external_entropy( 274int mlkem_generate_key_external_entropy(
330 uint8_t out_encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES], 275 uint8_t out_encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES],
331 MLKEM_private_key *out_private_key, 276 MLKEM_private_key *out_private_key,
332 const uint8_t entropy[MLKEM_SEED_BYTES]); 277 const uint8_t entropy[MLKEM_SEED_LENGTH]);
333
334/*
335 * MLKEM768_PRIVATE_KEY_BYTES is the length of the data produced by
336 * |MLKEM768_marshal_private_key|.
337 */
338#define MLKEM768_PRIVATE_KEY_BYTES 2400
339 278
340/* 279/*
341 * MLKEM768_marshal_private_key serializes |private_key| to |out| in the standard 280 * mlkem_marshal_private_key serializes |private_key| to |out_private_key| in the standard
342 * format for ML-KEM private keys. It returns one on success or zero on 281 * format for ML-KEM private keys. It returns one on success or zero on
343 * allocation error. 282 * allocation error.
344 */ 283 */
345int MLKEM768_marshal_private_key(const MLKEM_private_key *private_key, 284int mlkem_marshal_private_key(const MLKEM_private_key *private_key,
346 uint8_t **out_private_key, size_t *out_private_key_len); 285 uint8_t **out_private_key, size_t *out_private_key_len);
347 286
348/* 287/*
349 * MLKEM768_encap_external_entropy behaves like |MLKEM768_encap|, but uses 288 * mlkem_encap_external_entropy behaves like |mlkem_encap|, but uses
350 * |MLKEM_ENCAP_ENTROPY| bytes of |entropy| for randomization. The decapsulating 289 * |MLKEM_ENCAP_ENTROPY| bytes of |entropy| for randomization. The decapsulating
351 * side will be able to recover |entropy| in full. This function should only be 290 * side will be able to recover |entropy| in full. This function should only be
352 * used for tests, regular callers should use the non-deterministic 291 * used for tests, regular callers should use the non-deterministic
353 * |MLKEM_encap| directly. 292 * |MLKEM_encap| directly.
354 */ 293 */
355void MLKEM768_encap_external_entropy( 294void mlkem_encap_external_entropy(
356 uint8_t out_ciphertext[MLKEM768_CIPHERTEXT_BYTES], 295 uint8_t out_ciphertext[MLKEM768_CIPHERTEXT_BYTES],
357 uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], 296 uint8_t out_shared_secret[MLKEM_SHARED_SECRET_LENGTH],
358 const MLKEM_public_key *public_key, 297 const MLKEM_public_key *public_key,
359 const uint8_t entropy[MLKEM_ENCAP_ENTROPY]); 298 const uint8_t entropy[MLKEM_ENCAP_ENTROPY]);
360 299
361
362/* 300/*
363 * MLKEM1024_public_key contains an ML-KEM-1024 public key. The contents of this 301 * |MLKEM_encap_external_entropy| behaves exactly like the public |MLKEM_encap|
364 * object should never leave the address space since the format is unstable. 302 * with the entropy provided by the caller. It is directly called internally
365 */ 303 * and by tests.
366struct MLKEM1024_public_key {
367 union {
368 uint8_t bytes[512 * (4 + 16) + 32 + 32];
369 uint16_t alignment;
370 } opaque;
371};
372
373/*
374 * MLKEM1024_private_key contains a ML-KEM-1024 private key. The contents of
375 * this object should never leave the address space since the format is
376 * unstable.
377 */
378struct MLKEM1024_private_key {
379 union {
380 uint8_t bytes[512 * (4 + 4 + 16) + 32 + 32 + 32];
381 uint16_t alignment;
382 } opaque;
383};
384
385
386/*
387 * MLKEM1024_generate_key_external_entropy is a deterministic function to create a
388 * pair of ML-KEM 1024 keys, using the supplied entropy. The entropy needs to be
389 * uniformly random generated. This function is should only be used for tests,
390 * regular callers should use the non-deterministic |MLKEM_generate_key|
391 * directly.
392 */
393int MLKEM1024_generate_key_external_entropy(
394 uint8_t out_encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES],
395 MLKEM_private_key *out_private_key,
396 const uint8_t entropy[MLKEM_SEED_BYTES]);
397
398/*
399 * MLKEM1024_PRIVATE_KEY_BYTES is the length of the data produced by
400 * |MLKEM1024_marshal_private_key|.
401 */ 304 */
402#define MLKEM1024_PRIVATE_KEY_BYTES 3168 305int MLKEM_encap_external_entropy(const MLKEM_public_key *public_key,
306 const uint8_t *entropy, uint8_t **out_ciphertext,
307 size_t *out_ciphertext_len, uint8_t **out_shared_secret,
308 size_t *out_shared_secret_len);
403 309
404/* 310/*
405 * MLKEM1024_marshal_private_key serializes |private_key| to |out| in the 311 * |MLKEM_generate_key_external_entropy| behaves exactly like the public
406 * standard format for ML-KEM private keys. It returns one on success or zero on 312 * |MLKEM_generate_key| with the entropy provided by the caller.
407 * allocation error. 313 * It is directly called internally and by tests.
408 */ 314 */
409int MLKEM1024_marshal_private_key( 315int MLKEM_generate_key_external_entropy(MLKEM_private_key *private_key,
410 const MLKEM_private_key *private_key, uint8_t **out_private_key, 316 uint8_t **out_encoded_public_key, size_t *out_encoded_public_key_len,
411 size_t *out_private_key_len); 317 const uint8_t *entropy);
412 318
413/*
414 * MLKEM_encap_external_entropy behaves like |MLKEM_encap|, but uses
415 * |MLKEM_ENCAP_ENTROPY| bytes of |entropy| for randomization. The decapsulating
416 * side will be able to recover |entropy| in full. This function should only be
417 * used for tests, regular callers should use the non-deterministic
418 * |MLKEM_encap| directly.
419 */
420void MLKEM1024_encap_external_entropy(
421 uint8_t out_ciphertext[MLKEM1024_CIPHERTEXT_BYTES],
422 uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES],
423 const MLKEM_public_key *public_key,
424 const uint8_t entropy[MLKEM_ENCAP_ENTROPY]);
425 319
426__END_HIDDEN_DECLS 320__END_HIDDEN_DECLS
427 321