diff options
author | beck <> | 2024-12-13 00:17:18 +0000 |
---|---|---|
committer | beck <> | 2024-12-13 00:17:18 +0000 |
commit | d9dfb4af218b8d9fe842f363b39f2dc52cc54fc3 (patch) | |
tree | 96342312b2f330ea5c3d02d4c28c8c50ece4ee37 /src/lib/libcrypto/mlkem/mlkem.h | |
parent | c1d2232367daaf8b4eb64a789c2280bf931a6b99 (diff) | |
download | openbsd-d9dfb4af218b8d9fe842f363b39f2dc52cc54fc3.tar.gz openbsd-d9dfb4af218b8d9fe842f363b39f2dc52cc54fc3.tar.bz2 openbsd-d9dfb4af218b8d9fe842f363b39f2dc52cc54fc3.zip |
Add ML-KEM 1024 from BoringSSL
Changes include conversion from C++, basic KNF, then adaptation to
use our sha3 functions for sha3 and shake instead of the BorinSSL
version. This Adds units tests to run against BoringSSL and NIST test
vectors.
The future public API is the same as Boring's - but is not yet exposed
pending making bytestring.h public (which will happen separately) and
a minor bump
Currently this will just ensure we build and run regress.
ok tb@ to get it into the tree and massage from there.
Diffstat (limited to 'src/lib/libcrypto/mlkem/mlkem.h')
-rw-r--r-- | src/lib/libcrypto/mlkem/mlkem.h | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/src/lib/libcrypto/mlkem/mlkem.h b/src/lib/libcrypto/mlkem/mlkem.h index 8040f4844b..1033b89a60 100644 --- a/src/lib/libcrypto/mlkem/mlkem.h +++ b/src/lib/libcrypto/mlkem/mlkem.h | |||
@@ -161,6 +161,125 @@ int MLKEM768_parse_public_key(struct MLKEM768_public_key *out_public_key, | |||
161 | int MLKEM768_parse_private_key(struct MLKEM768_private_key *out_private_key, | 161 | int MLKEM768_parse_private_key(struct MLKEM768_private_key *out_private_key, |
162 | struct cbs_st *in); | 162 | struct cbs_st *in); |
163 | 163 | ||
164 | /* | ||
165 | * ML-KEM-1024 | ||
166 | * | ||
167 | * ML-KEM-1024 also exists. You should prefer ML-KEM-768 where possible. | ||
168 | */ | ||
169 | |||
170 | /* | ||
171 | * MLKEM1024_public_key contains an ML-KEM-1024 public key. The contents of this | ||
172 | * object should never leave the address space since the format is unstable. | ||
173 | */ | ||
174 | struct MLKEM1024_public_key { | ||
175 | union { | ||
176 | uint8_t bytes[512 * (4 + 16) + 32 + 32]; | ||
177 | uint16_t alignment; | ||
178 | } opaque; | ||
179 | }; | ||
180 | |||
181 | /* | ||
182 | * MLKEM1024_private_key contains a ML-KEM-1024 private key. The contents of | ||
183 | * this object should never leave the address space since the format is | ||
184 | * unstable. | ||
185 | */ | ||
186 | struct MLKEM1024_private_key { | ||
187 | union { | ||
188 | uint8_t bytes[512 * (4 + 4 + 16) + 32 + 32 + 32]; | ||
189 | uint16_t alignment; | ||
190 | } opaque; | ||
191 | }; | ||
192 | |||
193 | /* | ||
194 | * MLKEM1024_PUBLIC_KEY_BYTES is the number of bytes in an encoded ML-KEM-1024 | ||
195 | * public key. | ||
196 | */ | ||
197 | #define MLKEM1024_PUBLIC_KEY_BYTES 1568 | ||
198 | |||
199 | /* | ||
200 | * MLKEM1024_generate_key generates a random public/private key pair, writes the | ||
201 | * encoded public key to |out_encoded_public_key| and sets |out_private_key| to | ||
202 | * the private key. If |optional_out_seed| is not NULL then the seed used to | ||
203 | * generate the private key is written to it. | ||
204 | */ | ||
205 | void MLKEM1024_generate_key( | ||
206 | uint8_t out_encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES], | ||
207 | uint8_t optional_out_seed[MLKEM_SEED_BYTES], | ||
208 | struct MLKEM1024_private_key *out_private_key); | ||
209 | |||
210 | /* | ||
211 | * MLKEM1024_private_key_from_seed derives a private key from a seed that was | ||
212 | * generated by |MLKEM1024_generate_key|. It fails and returns 0 if |seed_len| | ||
213 | * is incorrect, otherwise it writes |*out_private_key| and returns 1. | ||
214 | */ | ||
215 | int MLKEM1024_private_key_from_seed( | ||
216 | struct MLKEM1024_private_key *out_private_key, const uint8_t *seed, | ||
217 | size_t seed_len); | ||
218 | |||
219 | /* | ||
220 | * MLKEM1024_public_from_private sets |*out_public_key| to the public key that | ||
221 | * corresponds to |private_key|. (This is faster than parsing the output of | ||
222 | * |MLKEM1024_generate_key| if, for some reason, you need to encapsulate to a | ||
223 | * key that was just generated.) | ||
224 | */ | ||
225 | void MLKEM1024_public_from_private(struct MLKEM1024_public_key *out_public_key, | ||
226 | const struct MLKEM1024_private_key *private_key); | ||
227 | |||
228 | /* MLKEM1024_CIPHERTEXT_BYTES is number of bytes in the ML-KEM-1024 ciphertext. */ | ||
229 | #define MLKEM1024_CIPHERTEXT_BYTES 1568 | ||
230 | |||
231 | /* | ||
232 | * MLKEM1024_encap encrypts a random shared secret for |public_key|, writes the | ||
233 | * ciphertext to |out_ciphertext|, and writes the random shared secret to | ||
234 | * |out_shared_secret|. | ||
235 | */ | ||
236 | void MLKEM1024_encap(uint8_t out_ciphertext[MLKEM1024_CIPHERTEXT_BYTES], | ||
237 | uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], | ||
238 | const struct MLKEM1024_public_key *public_key); | ||
239 | |||
240 | /* | ||
241 | * MLKEM1024_decap decrypts a shared secret from |ciphertext| using | ||
242 | * |private_key| and writes it to |out_shared_secret|. If |ciphertext_len| is | ||
243 | * incorrect it returns 0, otherwise it returns 1. If |ciphertext| is invalid | ||
244 | * (but of the correct length), |out_shared_secret| is filled with a key that | ||
245 | * will always be the same for the same |ciphertext| and |private_key|, but | ||
246 | * which appears to be random unless one has access to |private_key|. These | ||
247 | * alternatives occur in constant time. Any subsequent symmetric encryption | ||
248 | * using |out_shared_secret| must use an authenticated encryption scheme in | ||
249 | * order to discover the decapsulation failure. | ||
250 | */ | ||
251 | int MLKEM1024_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], | ||
252 | const uint8_t *ciphertext, size_t ciphertext_len, | ||
253 | const struct MLKEM1024_private_key *private_key); | ||
254 | |||
255 | /* | ||
256 | * Serialisation of ML-KEM-1024 keys. | ||
257 | * MLKEM1024_marshal_public_key serializes |public_key| to |out| in the standard | ||
258 | * format for ML-KEM-1024 public keys. It returns one on success or zero on | ||
259 | * allocation error. | ||
260 | */ | ||
261 | int MLKEM1024_marshal_public_key(struct cbb_st *out, | ||
262 | const struct MLKEM1024_public_key *public_key); | ||
263 | |||
264 | /* | ||
265 | * MLKEM1024_parse_public_key parses a public key, in the format generated by | ||
266 | * |MLKEM1024_marshal_public_key|, from |in| and writes the result to | ||
267 | * |out_public_key|. It returns one on success or zero on parse error or if | ||
268 | * there are trailing bytes in |in|. | ||
269 | */ | ||
270 | int MLKEM1024_parse_public_key(struct MLKEM1024_public_key *out_public_key, | ||
271 | struct cbs_st *in); | ||
272 | |||
273 | /* | ||
274 | * MLKEM1024_parse_private_key parses a private key, in NIST's format for | ||
275 | * private keys, from |in| and writes the result to |out_private_key|. It | ||
276 | * returns one on success or zero on parse error or if there are trailing bytes | ||
277 | * in |in|. This format is verbose and should be avoided. Private keys should be | ||
278 | * stored as seeds and parsed using |MLKEM1024_private_key_from_seed|. | ||
279 | */ | ||
280 | int MLKEM1024_parse_private_key(struct MLKEM1024_private_key *out_private_key, | ||
281 | struct cbs_st *in); | ||
282 | |||
164 | #if defined(__cplusplus) | 283 | #if defined(__cplusplus) |
165 | } | 284 | } |
166 | #endif | 285 | #endif |