summaryrefslogtreecommitdiff
path: root/src/regress/lib/libcrypto/mlkem/mlkem_tests.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/regress/lib/libcrypto/mlkem/mlkem_tests.c')
-rw-r--r--src/regress/lib/libcrypto/mlkem/mlkem_tests.c728
1 files changed, 728 insertions, 0 deletions
diff --git a/src/regress/lib/libcrypto/mlkem/mlkem_tests.c b/src/regress/lib/libcrypto/mlkem/mlkem_tests.c
new file mode 100644
index 0000000000..716f38d144
--- /dev/null
+++ b/src/regress/lib/libcrypto/mlkem/mlkem_tests.c
@@ -0,0 +1,728 @@
1/* $OpenBSD: mlkem_tests.c,v 1.1 2024/12/26 00:04:24 tb Exp $ */
2/*
3 * Copyright (c) 2024 Google Inc.
4 * Copyright (c) 2024 Theo Buehler <tb@openbsd.org>
5 * Copyright (c) 2024 Bob Beck <beck@obtuse.com>
6 *
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
14 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
16 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
17 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include <err.h>
21#include <stdint.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25
26#include "bytestring.h"
27#include "mlkem.h"
28
29#include "mlkem_internal.h"
30
31#include "mlkem_tests_util.h"
32#include "parse_test_file.h"
33
34enum test_type {
35 TEST_TYPE_NORMAL,
36 TEST_TYPE_NIST,
37};
38
39struct decap_ctx {
40 struct parse *parse_ctx;
41
42 void *private_key;
43 size_t private_key_len;
44
45 mlkem_parse_private_key_fn parse_private_key;
46 mlkem_decap_fn decap;
47};
48
49enum decap_states {
50 DECAP_PRIVATE_KEY,
51 DECAP_CIPHERTEXT,
52 DECAP_RESULT,
53 DECAP_SHARED_SECRET,
54 N_DECAP_STATES,
55};
56
57static const struct line_spec decap_state_machine[] = {
58 [DECAP_PRIVATE_KEY] = {
59 .state = DECAP_PRIVATE_KEY,
60 .type = LINE_HEX,
61 .name = "private key",
62 .label = "private_key",
63 },
64 [DECAP_CIPHERTEXT] = {
65 .state = DECAP_CIPHERTEXT,
66 .type = LINE_HEX,
67 .name = "cipher text",
68 .label = "ciphertext",
69 },
70 [DECAP_RESULT] = {
71 .state = DECAP_RESULT,
72 .type = LINE_STRING_MATCH,
73 .name = "result",
74 .label = "result",
75 .match = "fail",
76 },
77 [DECAP_SHARED_SECRET] = {
78 .state = DECAP_SHARED_SECRET,
79 .type = LINE_HEX,
80 .name = "shared secret",
81 .label = "shared_secret",
82 },
83};
84
85static int
86decap_init(void *ctx, void *parse_ctx)
87{
88 struct decap_ctx *decap = ctx;
89
90 decap->parse_ctx = parse_ctx;
91
92 return 1;
93}
94
95static void
96decap_finish(void *ctx)
97{
98 (void)ctx;
99}
100
101static int
102MlkemDecapFileTest(struct decap_ctx *decap)
103{
104 struct parse *p = decap->parse_ctx;
105 uint8_t shared_secret_buf[MLKEM_SHARED_SECRET_BYTES];
106 CBS ciphertext, shared_secret, private_key;
107 int should_fail;
108 int failed = 1;
109
110 parse_get_cbs(p, DECAP_CIPHERTEXT, &ciphertext);
111 parse_get_cbs(p, DECAP_SHARED_SECRET, &shared_secret);
112 parse_get_cbs(p, DECAP_PRIVATE_KEY, &private_key);
113 parse_get_int(p, DECAP_RESULT, &should_fail);
114
115 if (!decap->parse_private_key(decap->private_key, &private_key)) {
116 if ((failed = !should_fail))
117 parse_info(p, "parse private key");
118 goto err;
119 }
120 if (!decap->decap(shared_secret_buf,
121 CBS_data(&ciphertext), CBS_len(&ciphertext), decap->private_key)) {
122 if ((failed = !should_fail))
123 parse_info(p, decap");
124 goto err;
125 }
126
127 failed = !parse_data_equal(p, "shared_secret", &shared_secret,
128 shared_secret_buf, sizeof(shared_secret_buf));
129
130 if (should_fail != failed) {
131 parse_info(p, "FAIL: should_fail %d, failed %d",
132 should_fail, failed);
133 failed = 1;
134 }
135
136 err:
137 return failed;
138}
139
140static int
141decap_run_test_case(void *ctx)
142{
143 return MlkemDecapFileTest(ctx);
144}
145
146static const struct test_parse decap_parse = {
147 .states = decap_state_machine,
148 .num_states = N_DECAP_STATES,
149
150 .init = decap_init,
151 .finish = decap_finish,
152
153 .run_test_case = decap_run_test_case,
154};
155
156enum nist_decap_instructions {
157 NIST_DECAP_DK,
158 N_NIST_DECAP_INSTRUCTIONS,
159};
160
161static const struct line_spec nist_decap_instruction_state_machine[] = {
162 [NIST_DECAP_DK] = {
163 .state = NIST_DECAP_DK,
164 .type = LINE_HEX,
165 .name = "private key (instruction [dk])",
166 .label = "dk",
167 },
168};
169
170enum nist_decap_states {
171 NIST_DECAP_C,
172 NIST_DECAP_K,
173 N_NIST_DECAP_STATES,
174};
175
176static const struct line_spec nist_decap_state_machine[] = {
177 [NIST_DECAP_C] = {
178 .state = NIST_DECAP_C,
179 .type = LINE_HEX,
180 .name = "ciphertext (c)",
181 .label = "c",
182 },
183 [NIST_DECAP_K] = {
184 .state = NIST_DECAP_K,
185 .type = LINE_HEX,
186 .name = "shared secret (k)",
187 .label = "k",
188 },
189};
190
191static int
192MlkemNistDecapFileTest(struct decap_ctx *decap)
193{
194 struct parse *p = decap->parse_ctx;
195 uint8_t shared_secret[MLKEM_SHARED_SECRET_BYTES];
196 CBS dk, c, k;
197 int failed = 1;
198
199 parse_instruction_get_cbs(p, NIST_DECAP_DK, &dk);
200 parse_get_cbs(p, NIST_DECAP_C, &c);
201 parse_get_cbs(p, NIST_DECAP_K, &k);
202
203 if (!parse_length_equal(p, "private key",
204 decap->private_key_len, CBS_len(&dk)))
205 goto err;
206 if (!parse_length_equal(p, "shared secret",
207 MLKEM_SHARED_SECRET_BYTES, CBS_len(&k)))
208 goto err;
209
210 if (!decap->parse_private_key(decap->private_key, &dk)) {
211 parse_info(p, "parse private key");
212 goto err;
213 }
214 if (!decap->decap(shared_secret, CBS_data(&c), CBS_len(&c),
215 decap->private_key)) {
216 parse_info(p, "decap");
217 goto err;
218 }
219
220 failed = !parse_data_equal(p, "shared secret", &k,
221 shared_secret, MLKEM_SHARED_SECRET_BYTES);
222
223 err:
224 return failed;
225}
226
227static int
228nist_decap_run_test_case(void *ctx)
229{
230 return MlkemNistDecapFileTest(ctx);
231}
232
233static const struct test_parse nist_decap_parse = {
234 .instructions = nist_decap_instruction_state_machine,
235 .num_instructions = N_NIST_DECAP_INSTRUCTIONS,
236
237 .states = nist_decap_state_machine,
238 .num_states = N_NIST_DECAP_STATES,
239
240 .init = decap_init,
241 .finish = decap_finish,
242
243 .run_test_case = nist_decap_run_test_case,
244};
245
246static int
247mlkem_decap_tests(const char *fn, size_t size, enum test_type test_type)
248{
249 struct MLKEM768_private_key private_key768;
250 struct decap_ctx decap768 = {
251 .private_key = &private_key768,
252 .private_key_len = MLKEM768_PRIVATE_KEY_BYTES,
253
254 .parse_private_key = mlkem768_parse_private_key,
255 .decap = mlkem768_decap,
256 };
257 struct MLKEM1024_private_key private_key1024;
258 struct decap_ctx decap1024 = {
259 .private_key = &private_key1024,
260 .private_key_len = MLKEM1024_PRIVATE_KEY_BYTES,
261
262 .parse_private_key = mlkem1024_parse_private_key,
263 .decap = mlkem1024_decap,
264 };
265
266 if (size == 768 && test_type == TEST_TYPE_NORMAL)
267 return parse_test_file(fn, &decap_parse, &decap768);
268 if (size == 768 && test_type == TEST_TYPE_NIST)
269 return parse_test_file(fn, &nist_decap_parse, &decap768);
270 if (size == 1024 && test_type == TEST_TYPE_NORMAL)
271 return parse_test_file(fn, &decap_parse, &decap1024);
272 if (size == 1024 && test_type == TEST_TYPE_NIST)
273 return parse_test_file(fn, &nist_decap_parse, &decap1024);
274
275 errx(1, "unknown decap test: size %zu, type %d", size, test_type);
276}
277
278struct encap_ctx {
279 struct parse *parse_ctx;
280
281 void *public_key;
282 uint8_t *ciphertext;
283 size_t ciphertext_len;
284
285 mlkem_parse_public_key_fn parse_public_key;
286 mlkem_encap_external_entropy_fn encap_external_entropy;
287};
288
289enum encap_states {
290 ENCAP_ENTROPY,
291 ENCAP_PUBLIC_KEY,
292 ENCAP_RESULT,
293 ENCAP_CIPHERTEXT,
294 ENCAP_SHARED_SECRET,
295 N_ENCAP_STATES,
296};
297
298static const struct line_spec encap_state_machine[] = {
299 [ENCAP_ENTROPY] = {
300 .state = ENCAP_ENTROPY,
301 .type = LINE_HEX,
302 .name = "entropy",
303 .label = "entropy",
304 },
305 [ENCAP_PUBLIC_KEY] = {
306 .state = ENCAP_PUBLIC_KEY,
307 .type = LINE_HEX,
308 .name = "public key",
309 .label = "public_key",
310 },
311 [ENCAP_RESULT] = {
312 .state = ENCAP_RESULT,
313 .type = LINE_STRING_MATCH,
314 .name = "result",
315 .label = "result",
316 .match = "fail",
317 },
318 [ENCAP_CIPHERTEXT] = {
319 .state = ENCAP_CIPHERTEXT,
320 .type = LINE_HEX,
321 .name = "ciphertext",
322 .label = "ciphertext",
323 },
324 [ENCAP_SHARED_SECRET] = {
325 .state = ENCAP_SHARED_SECRET,
326 .type = LINE_HEX,
327 .name = "shared secret",
328 .label = "shared_secret",
329 },
330};
331
332static int
333encap_init(void *ctx, void *parse_ctx)
334{
335 struct encap_ctx *encap = ctx;
336
337 encap->parse_ctx = parse_ctx;
338
339 return 1;
340}
341
342static void
343encap_finish(void *ctx)
344{
345 (void)ctx;
346}
347
348static int
349MlkemEncapFileTest(struct encap_ctx *encap)
350{
351 struct parse *p = encap->parse_ctx;
352 uint8_t shared_secret_buf[MLKEM_SHARED_SECRET_BYTES];
353 CBS entropy, public_key, ciphertext, shared_secret;
354 int should_fail;
355 int failed = 1;
356
357 parse_get_cbs(p, ENCAP_ENTROPY, &entropy);
358 parse_get_cbs(p, ENCAP_PUBLIC_KEY, &public_key);
359 parse_get_cbs(p, ENCAP_CIPHERTEXT, &ciphertext);
360 parse_get_cbs(p, ENCAP_SHARED_SECRET, &shared_secret);
361 parse_get_int(p, ENCAP_RESULT, &should_fail);
362
363 if (!encap->parse_public_key(encap->public_key, &public_key)) {
364 if ((failed = !should_fail))
365 parse_info(p, "parse public key");
366 goto err;
367 }
368 encap->encap_external_entropy(encap->ciphertext, shared_secret_buf,
369 encap->public_key, CBS_data(&entropy));
370
371 failed = !parse_data_equal(p, "shared_secret", &shared_secret,
372 shared_secret_buf, sizeof(shared_secret_buf));
373 failed |= !parse_data_equal(p, "ciphertext", &ciphertext,
374 encap->ciphertext, encap->ciphertext_len);
375
376 if (should_fail != failed) {
377 parse_info(p, "FAIL: should_fail %d, failed %d",
378 should_fail, failed);
379 failed = 1;
380 }
381
382 err:
383 return failed;
384}
385
386static int
387encap_run_test_case(void *ctx)
388{
389 return MlkemEncapFileTest(ctx);
390}
391
392static const struct test_parse encap_parse = {
393 .states = encap_state_machine,
394 .num_states = N_ENCAP_STATES,
395
396 .init = encap_init,
397 .finish = encap_finish,
398
399 .run_test_case = encap_run_test_case,
400};
401
402static int
403mlkem_encap_tests(const char *fn, size_t size)
404{
405 struct MLKEM768_public_key public_key768;
406 uint8_t ciphertext768[MLKEM768_CIPHERTEXT_BYTES];
407 struct encap_ctx encap768 = {
408 .public_key = &public_key768,
409 .ciphertext = ciphertext768,
410 .ciphertext_len = sizeof(ciphertext768),
411
412 .parse_public_key = mlkem768_parse_public_key,
413 .encap_external_entropy = mlkem768_encap_external_entropy,
414 };
415 struct MLKEM1024_public_key public_key1024;
416 uint8_t ciphertext1024[MLKEM1024_CIPHERTEXT_BYTES];
417 struct encap_ctx encap1024 = {
418 .public_key = &public_key1024,
419 .ciphertext = ciphertext1024,
420 .ciphertext_len = sizeof(ciphertext1024),
421
422 .parse_public_key = mlkem1024_parse_public_key,
423 .encap_external_entropy = mlkem1024_encap_external_entropy,
424 };
425
426 if (size == 768)
427 return parse_test_file(fn, &encap_parse, &encap768);
428 if (size == 1024)
429 return parse_test_file(fn, &encap_parse, &encap1024);
430
431 errx(1, "unknown encap test: size %zu", size);
432}
433
434struct keygen_ctx {
435 struct parse *parse_ctx;
436
437 void *private_key;
438 void *encoded_public_key;
439 size_t encoded_public_key_len;
440 size_t private_key_len;
441 size_t public_key_len;
442
443 mlkem_generate_key_external_entropy_fn generate_key_external_entropy;
444 mlkem_encode_private_key_fn encode_private_key;
445};
446
447enum keygen_states {
448 KEYGEN_SEED,
449 KEYGEN_PUBLIC_KEY,
450 KEYGEN_PRIVATE_KEY,
451 N_KEYGEN_STATES,
452};
453
454static const struct line_spec keygen_state_machine[] = {
455 [KEYGEN_SEED] = {
456 .state = KEYGEN_SEED,
457 .type = LINE_HEX,
458 .name = "seed",
459 .label = "seed",
460 },
461 [KEYGEN_PUBLIC_KEY] = {
462 .state = KEYGEN_PUBLIC_KEY,
463 .type = LINE_HEX,
464 .name = "public key",
465 .label = "public_key",
466 },
467 [KEYGEN_PRIVATE_KEY] = {
468 .state = KEYGEN_PRIVATE_KEY,
469 .type = LINE_HEX,
470 .name = "private key",
471 .label = "private_key",
472 },
473};
474
475static int
476keygen_init(void *ctx, void *parse_ctx)
477{
478 struct keygen_ctx *keygen = ctx;
479
480 keygen->parse_ctx = parse_ctx;
481
482 return 1;
483}
484
485static void
486keygen_finish(void *ctx)
487{
488 (void)ctx;
489}
490
491static int
492MlkemKeygenFileTest(struct keygen_ctx *keygen)
493{
494 struct parse *p = keygen->parse_ctx;
495 CBS seed, public_key, private_key;
496 uint8_t *encoded_private_key = NULL;
497 size_t encoded_private_key_len = 0;
498 int failed = 1;
499
500 parse_get_cbs(p, KEYGEN_SEED, &seed);
501 parse_get_cbs(p, KEYGEN_PUBLIC_KEY, &public_key);
502 parse_get_cbs(p, KEYGEN_PRIVATE_KEY, &private_key);
503
504 if (!parse_length_equal(p, "seed", MLKEM_SEED_BYTES, CBS_len(&seed)))
505 goto err;
506 if (!parse_length_equal(p, "public key",
507 keygen->public_key_len, CBS_len(&public_key)))
508 goto err;
509 if (!parse_length_equal(p, "private key",
510 keygen->private_key_len, CBS_len(&private_key)))
511 goto err;
512
513 keygen->generate_key_external_entropy(keygen->encoded_public_key,
514 keygen->private_key, CBS_data(&seed));
515 if (!keygen->encode_private_key(keygen->private_key,
516 &encoded_private_key, &encoded_private_key_len)) {
517 parse_info(p, "encode private key");
518 goto err;
519 }
520
521 failed = !parse_data_equal(p, "private key", &private_key,
522 encoded_private_key, encoded_private_key_len);
523 failed |= !parse_data_equal(p, "public key", &public_key,
524 keygen->encoded_public_key, keygen->encoded_public_key_len);
525
526 err:
527 freezero(encoded_private_key, encoded_private_key_len);
528
529 return failed;
530}
531
532static int
533keygen_run_test_case(void *ctx)
534{
535 return MlkemKeygenFileTest(ctx);
536}
537
538static const struct test_parse keygen_parse = {
539 .states = keygen_state_machine,
540 .num_states = N_KEYGEN_STATES,
541
542 .init = keygen_init,
543 .finish = keygen_finish,
544
545 .run_test_case = keygen_run_test_case,
546};
547
548enum nist_keygen_states {
549 NIST_KEYGEN_Z,
550 NIST_KEYGEN_D,
551 NIST_KEYGEN_EK,
552 NIST_KEYGEN_DK,
553 N_NIST_KEYGEN_STATES,
554};
555
556static const struct line_spec nist_keygen_state_machine[] = {
557 [NIST_KEYGEN_Z] = {
558 .state = NIST_KEYGEN_Z,
559 .type = LINE_HEX,
560 .name = "seed (z)",
561 .label = "z",
562 },
563 [NIST_KEYGEN_D] = {
564 .state = NIST_KEYGEN_D,
565 .type = LINE_HEX,
566 .name = "seed (d)",
567 .label = "d",
568 },
569 [NIST_KEYGEN_EK] = {
570 .state = NIST_KEYGEN_EK,
571 .type = LINE_HEX,
572 .name = "public key (ek)",
573 .label = "ek",
574 },
575 [NIST_KEYGEN_DK] = {
576 .state = NIST_KEYGEN_DK,
577 .type = LINE_HEX,
578 .name = "private key (dk)",
579 .label = "dk",
580 },
581};
582
583static int
584MlkemNistKeygenFileTest(struct keygen_ctx *keygen)
585{
586 struct parse *p = keygen->parse_ctx;
587 CBB seed_cbb;
588 CBS z, d, ek, dk;
589 uint8_t seed[MLKEM_SEED_BYTES];
590 size_t seed_len;
591 uint8_t *encoded_private_key = NULL;
592 size_t encoded_private_key_len = 0;
593 int failed = 1;
594
595 parse_get_cbs(p, NIST_KEYGEN_Z, &z);
596 parse_get_cbs(p, NIST_KEYGEN_D, &d);
597 parse_get_cbs(p, NIST_KEYGEN_EK, &ek);
598 parse_get_cbs(p, NIST_KEYGEN_DK, &dk);
599
600 if (!CBB_init_fixed(&seed_cbb, seed, sizeof(seed)))
601 parse_errx(p, "CBB_init_fixed");
602 if (!CBB_add_bytes(&seed_cbb, CBS_data(&d), CBS_len(&d)))
603 parse_errx(p, "CBB_add_bytes");
604 if (!CBB_add_bytes(&seed_cbb, CBS_data(&z), CBS_len(&z)))
605 parse_errx(p, "CBB_add_bytes");
606 if (!CBB_finish(&seed_cbb, NULL, &seed_len))
607 parse_errx(p, "CBB_finish");
608
609 if (!parse_length_equal(p, "bogus z or d", MLKEM_SEED_BYTES, seed_len))
610 goto err;
611
612 keygen->generate_key_external_entropy(keygen->encoded_public_key,
613 keygen->private_key, seed);
614 if (!keygen->encode_private_key(keygen->private_key,
615 &encoded_private_key, &encoded_private_key_len)) {
616 parse_info(p, "encode private key");
617 goto err;
618 }
619
620 failed = !parse_data_equal(p, "public key", &ek,
621 keygen->encoded_public_key, keygen->encoded_public_key_len);
622 failed |= !parse_data_equal(p, "private key", &dk,
623 encoded_private_key, encoded_private_key_len);
624
625 err:
626 freezero(encoded_private_key, encoded_private_key_len);
627
628 return failed;
629}
630
631static int
632nist_keygen_run_test_case(void *ctx)
633{
634 return MlkemNistKeygenFileTest(ctx);
635}
636
637static const struct test_parse nist_keygen_parse = {
638 .states = nist_keygen_state_machine,
639 .num_states = N_NIST_KEYGEN_STATES,
640
641 .init = keygen_init,
642 .finish = keygen_finish,
643
644 .run_test_case = nist_keygen_run_test_case,
645};
646
647static int
648mlkem_keygen_tests(const char *fn, size_t size, enum test_type test_type)
649{
650 struct MLKEM768_private_key private_key768;
651 uint8_t encoded_public_key768[MLKEM768_PUBLIC_KEY_BYTES];
652 struct keygen_ctx keygen768 = {
653 .private_key = &private_key768,
654 .encoded_public_key = encoded_public_key768,
655 .encoded_public_key_len = sizeof(encoded_public_key768),
656 .private_key_len = MLKEM768_PRIVATE_KEY_BYTES,
657 .public_key_len = MLKEM768_PUBLIC_KEY_BYTES,
658 .generate_key_external_entropy =
659 mlkem768_generate_key_external_entropy,
660 .encode_private_key =
661 mlkem768_encode_private_key,
662 };
663 struct MLKEM1024_private_key private_key1024;
664 uint8_t encoded_public_key1024[MLKEM1024_PUBLIC_KEY_BYTES];
665 struct keygen_ctx keygen1024 = {
666 .private_key = &private_key1024,
667 .encoded_public_key = encoded_public_key1024,
668 .encoded_public_key_len = sizeof(encoded_public_key1024),
669 .private_key_len = MLKEM1024_PRIVATE_KEY_BYTES,
670 .public_key_len = MLKEM1024_PUBLIC_KEY_BYTES,
671
672 .generate_key_external_entropy =
673 mlkem1024_generate_key_external_entropy,
674 .encode_private_key =
675 mlkem1024_encode_private_key,
676 };
677
678 if (size == 768 && test_type == TEST_TYPE_NORMAL)
679 return parse_test_file(fn, &keygen_parse, &keygen768);
680 if (size == 768 && test_type == TEST_TYPE_NIST)
681 return parse_test_file(fn, &nist_keygen_parse, &keygen768);
682 if (size == 1024 && test_type == TEST_TYPE_NORMAL)
683 return parse_test_file(fn, &keygen_parse, &keygen1024);
684 if (size == 1024 && test_type == TEST_TYPE_NIST)
685 return parse_test_file(fn, &nist_keygen_parse, &keygen1024);
686
687 errx(1, "unknown keygen test: size %zu, type %d", size, test_type);
688}
689
690static int
691run_mlkem_test(const char *test, const char *fn)
692{
693 if (strcmp(test, "mlkem768_decap_tests") == 0)
694 return mlkem_decap_tests(fn, 768, TEST_TYPE_NORMAL);
695 if (strcmp(test, "mlkem768_nist_decap_tests") == 0)
696 return mlkem_decap_tests(fn, 768, TEST_TYPE_NIST);
697 if (strcmp(test, "mlkem1024_decap_tests") == 0)
698 return mlkem_decap_tests(fn, 1024, TEST_TYPE_NORMAL);
699 if (strcmp(test, "mlkem1024_nist_decap_tests") == 0)
700 return mlkem_decap_tests(fn, 1024, TEST_TYPE_NIST);
701
702 if (strcmp(test, "mlkem768_encap_tests") == 0)
703 return mlkem_encap_tests(fn, 768);
704 if (strcmp(test, "mlkem1024_encap_tests") == 0)
705 return mlkem_encap_tests(fn, 1024);
706
707 if (strcmp(test, "mlkem768_keygen_tests") == 0)
708 return mlkem_keygen_tests(fn, 768, TEST_TYPE_NORMAL);
709 if (strcmp(test, "mlkem768_nist_keygen_tests") == 0)
710 return mlkem_keygen_tests(fn, 768, TEST_TYPE_NIST);
711 if (strcmp(test, "mlkem1024_keygen_tests") == 0)
712 return mlkem_keygen_tests(fn, 1024, TEST_TYPE_NORMAL);
713 if (strcmp(test, "mlkem1024_nist_keygen_tests") == 0)
714 return mlkem_keygen_tests(fn, 1024, TEST_TYPE_NIST);
715
716 errx(1, "unknown test %s (test file %s)", test, fn);
717}
718
719int
720main(int argc, const char *argv[])
721{
722 if (argc != 3) {
723 fprintf(stderr, "usage: mlkem_test test testfile.txt\n");
724 exit(1);
725 }
726
727 return run_mlkem_test(argv[1], argv[2]);
728}