Super User's BSD Cross Reference: /OpenBSD/lib/libcrypto/mlkem/mlkem_internal.h

1 /* $OpenBSD: mlkem_internal.h,v 1.10 2025年09月05日 23:30:12 beck Exp $ */
2 /*
3 * Copyright (c) 2023, Google Inc.
4 * Copyright (c) 2025, Bob Beck <beck@obtuse.com>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#ifndef OPENSSL_HEADER_CRYPTO_MLKEM_INTERNAL_H
20#define OPENSSL_HEADER_CRYPTO_MLKEM_INTERNAL_H
21
22#include "bytestring.h"
23#include "mlkem.h"
24
25#if defined(__cplusplus)
26 extern "C" {
27#endif
28
29 __BEGIN_HIDDEN_DECLS
30
31 /* Public opaque ML-KEM key structures. */
32
33#define MLKEM_PUBLIC_KEY_UNINITIALIZED 1
34#define MLKEM_PUBLIC_KEY_INITIALIZED 2
35#define MLKEM_PRIVATE_KEY_UNINITIALIZED 3
36#define MLKEM_PRIVATE_KEY_INITIALIZED 4
37
38 struct MLKEM_public_key_st {
39 uint16_t rank;
40 int state;
41 struct MLKEM768_public_key *key_768;
42 struct MLKEM1024_public_key *key_1024;
43};
44
45 struct MLKEM_private_key_st {
46 uint16_t rank;
47 int state;
48 struct MLKEM768_private_key *key_768;
49 struct MLKEM1024_private_key *key_1024;
50};
51
52 /*
53 * ML-KEM-768 and ML-KEM-1024
54 *
55 * This implements the Module-Lattice-Based Key-Encapsulation Mechanism from
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.
75 */
76
77 /*
78 * MLKEM1024_public_key contains an ML-KEM-1024 public key. The contents of this
79 * object should never leave the address space since the format is unstable.
80 */
81 struct MLKEM1024_public_key {
82 uint8_t bytes[512 * (4 + 16) + 32 + 32];
83 uint16_t alignment;
84};
85
86 /*
87 * MLKEM1024_private_key contains a ML-KEM-1024 private key. The contents of
88 * this object should never leave the address space since the format is
89 * unstable.
90 */
91 struct MLKEM1024_private_key {
92 uint8_t bytes[512 * (4 + 4 + 16) + 32 + 32 + 32];
93 uint16_t alignment;
94};
95
96 /*
97 * MLKEM768_public_key contains a ML-KEM-768 public key. The contents of this
98 * object should never leave the address space since the format is unstable.
99 */
100 struct MLKEM768_public_key {
101 uint8_t bytes[512 * (3 + 9) + 32 + 32];
102 uint16_t alignment;
103};
104
105 /*
106 * MLKEM768_private_key contains a ML-KEM-768 private key. The contents of this
107 * object should never leave the address space since the format is unstable.
108 */
109 struct MLKEM768_private_key {
110 uint8_t bytes[512 * (3 + 3 + 9) + 32 + 32 + 32];
111 uint16_t alignment;
112};
113
114 /*
115 * MLKEM_SEED_LENGTH is the number of bytes in an ML-KEM seed. An ML-KEM
116 * seed is normally used to represent a private key.
117 */
118#define MLKEM_SEED_LENGTH 64
119
120 /*
121 * MLKEM_SHARED_SECRET_LENGTH is the number of bytes in an ML-KEM shared
122 * secret.
123 */
124#define MLKEM_SHARED_SECRET_LENGTH 32
125
126 /*
127 * MLKEM_ENCAP_ENTROPY is the number of bytes of uniformly random entropy
128 * necessary to encapsulate a secret. The entropy will be leaked to the
129 * decapsulating party.
130 */
131#define MLKEM_ENCAP_ENTROPY 32
132
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
138
139 /*
140 * MLKEM768_PUBLIC_KEY_BYTES is the number of bytes in an encoded ML-KEM768 public
141 * key.
142 */
143#define MLKEM768_PUBLIC_KEY_BYTES 1184
144
145 /*
146 * MLKEM1024_PUBLIC_KEY_BYTES is the number of bytes in an encoded ML-KEM-1024
147 * public key.
148 */
149#define MLKEM1024_PUBLIC_KEY_BYTES 1568
150
151 /*
152 * MLKEM768_PRIVATE_KEY_BYTES is the length of the data produced by
153 * |marshal_private_key| for a RANK768 MLKEM_private_key.
154 */
155#define MLKEM768_PRIVATE_KEY_BYTES 2400
156
157 /*
158 * MLKEM1024_PRIVATE_KEY_BYTES is the length of the data produced by
159 * |marshal_private_key| for a RANK1024 MLKEM_private_key.
160 */
161#define MLKEM1024_PRIVATE_KEY_BYTES 3168
162
163 /*
164 * Internal MLKEM 768 and MLKEM 1024 functions come largely from BoringSSL, but
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.
173 */
174
175 /* Key generation. */
176
177 /*
178 * mlkem_generate_key generates a random public/private key pair, writes the
179 * encoded public key to |out_encoded_public_key| and sets |out_private_key| to
180 * the private key. If |optional_out_seed| is not NULL then the seed used to
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|.
184 */
185 int mlkem_generate_key(uint8_t *out_encoded_public_key,
186 uint8_t *optional_out_seed, MLKEM_private_key *out_private_key);
187
188 /*
189 * mlkem_private_key_from_seed modifies |out_private_key| to generate a key of
190 * the rank of |*out_private_key| from a seed that was generated by
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.
194 */
195 int mlkem_private_key_from_seed(const uint8_t *seed, size_t seed_len,
196 MLKEM_private_key *out_private_key);
197
198 /*
199 * mlkem_public_from_private sets |*out_public_key| to the public key that
200 * corresponds to |*private_key|. (This is faster than parsing the output of
201 * |MLKEM_generate_key| if, for some reason, you need to encapsulate to a key
202 * that was just generated.)
203 */
204 void mlkem_public_from_private(const MLKEM_private_key *private_key,
205 MLKEM_public_key *out_public_key);
206
207
208 /* Encapsulation and decapsulation of secrets. */
209
210 /*
211 * mlkem_encap encrypts a random shared secret for |public_key|, writes the
212 * ciphertext to |out_ciphertext|, and writes the random shared secret to
213 * |out_shared_secret|.
214 */
215 void mlkem_encap(const MLKEM_public_key *public_key,
216 uint8_t out_ciphertext[MLKEM768_CIPHERTEXT_BYTES],
217 uint8_t out_shared_secret[MLKEM_SHARED_SECRET_LENGTH]);
218
219 /*
220 * mlkem_decap decrypts a shared secret from |ciphertext| using |private_key|
221 * and writes it to |out_shared_secret|. If |ciphertext_len| is incorrect it
222 * returns 0, otherwise it returns 1. If |ciphertext| is invalid,
223 * |out_shared_secret| is filled with a key that will always be the same for the
224 * same |ciphertext| and |private_key|, but which appears to be random unless
225 * one has access to |private_key|. These alternatives occur in constant time.
226 * Any subsequent symmetric encryption using |out_shared_secret| must use an
227 * authenticated encryption scheme in order to discover the decapsulation
228 * failure.
229 */
230 int mlkem_decap(const MLKEM_private_key *private_key,
231 const uint8_t *ciphertext, size_t ciphertext_len,
232 uint8_t out_shared_secret[MLKEM_SHARED_SECRET_LENGTH]);
233
234
235 /* Serialisation of keys. */
236
237 /*
238 * mlkem_marshal_public_key serializes |public_key| to |output| in the standard
239 * format for ML-KEM public keys. It returns one on success or zero on allocation
240 * error.
241 */
242 int mlkem_marshal_public_key(const MLKEM_public_key *public_key,
243 uint8_t **output, size_t *output_len);
244
245 /*
246 * mlkem_parse_public_key parses a public key, in the format generated by
247 * |MLKEM_marshal_public_key|, from |input| and writes the result to
248 * |out_public_key|. It returns one on success or zero on parse error or if
249 * there are trailing bytes in |input|.
250 */
251 int mlkem_parse_public_key(const uint8_t *input, size_t input_len,
252 MLKEM_public_key *out_public_key);
253
254 /*
255 * mlkem_parse_private_key parses a private key, in the format generated by
256 * |MLKEM_marshal_private_key|, from |input| and writes the result to
257 * |out_private_key|. It returns one on success or zero on parse error or if
258 * there are trailing bytes in |input|. This formate is verbose and should be avoided.
259 * Private keys should be stored as seeds and parsed using |mlkem_private_key_from_seed|.
260 */
261 int mlkem_parse_private_key(const uint8_t *input, size_t input_len,
262 MLKEM_private_key *out_private_key);
263
264
265 /* Functions that are only used for test purposes. */
266
267 /*
268 * mlkem_generate_key_external_entropy is a deterministic function to create a
269 * pair of ML-KEM 768 keys, using the supplied entropy. The entropy needs to be
270 * uniformly random generated. This function is should only be used for tests,
271 * regular callers should use the non-deterministic |MLKEM_generate_key|
272 * directly.
273 */
274 int mlkem_generate_key_external_entropy(
275 uint8_t out_encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES],
276 MLKEM_private_key *out_private_key,
277 const uint8_t entropy[MLKEM_SEED_LENGTH]);
278
279 /*
280 * mlkem_marshal_private_key serializes |private_key| to |out_private_key| in the standard
281 * format for ML-KEM private keys. It returns one on success or zero on
282 * allocation error.
283 */
284 int mlkem_marshal_private_key(const MLKEM_private_key *private_key,
285 uint8_t **out_private_key, size_t *out_private_key_len);
286
287 /*
288 * mlkem_encap_external_entropy behaves like |mlkem_encap|, but uses
289 * |MLKEM_ENCAP_ENTROPY| bytes of |entropy| for randomization. The decapsulating
290 * side will be able to recover |entropy| in full. This function should only be
291 * used for tests, regular callers should use the non-deterministic
292 * |MLKEM_encap| directly.
293 */
294 void mlkem_encap_external_entropy(
295 uint8_t out_ciphertext[MLKEM768_CIPHERTEXT_BYTES],
296 uint8_t out_shared_secret[MLKEM_SHARED_SECRET_LENGTH],
297 const MLKEM_public_key *public_key,
298 const uint8_t entropy[MLKEM_ENCAP_ENTROPY]);
299
300 /*
301 * |MLKEM_encap_external_entropy| behaves exactly like the public |MLKEM_encap|
302 * with the entropy provided by the caller. It is directly called internally
303 * and by tests.
304 */
305 int 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);
309
310 /*
311 * |MLKEM_generate_key_external_entropy| behaves exactly like the public
312 * |MLKEM_generate_key| with the entropy provided by the caller.
313 * It is directly called internally and by tests.
314 */
315 int MLKEM_generate_key_external_entropy(MLKEM_private_key *private_key,
316 uint8_t **out_encoded_public_key, size_t *out_encoded_public_key_len,
317 const uint8_t *entropy);
318
319
320 __END_HIDDEN_DECLS
321
322#if defined(__cplusplus)
323}
324#endif
325
326#endif /* OPENSSL_HEADER_CRYPTO_MLKEM_INTERNAL_H */
327 

AltStyle によって変換されたページ (->オリジナル) /