1 /* $OpenBSD: mlkem_tests.c,v 1.2 2024/12/26 00:10:19 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 34 enum test_type { 35 TEST_TYPE_NORMAL, 36 TEST_TYPE_NIST, 37 }; 38 39 struct 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 49 enum decap_states { 50 DECAP_PRIVATE_KEY, 51 DECAP_CIPHERTEXT, 52 DECAP_RESULT, 53 DECAP_SHARED_SECRET, 54 N_DECAP_STATES, 55 }; 56 57 static 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 85 static int 86 decap_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 95 static void 96 decap_finish(void *ctx) 97 { 98 (void)ctx; 99 } 100 101 static int 102 MlkemDecapFileTest(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 140 static int 141 decap_run_test_case(void *ctx) 142 { 143 return MlkemDecapFileTest(ctx); 144 } 145 146 static 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 156 enum nist_decap_instructions { 157 NIST_DECAP_DK, 158 N_NIST_DECAP_INSTRUCTIONS, 159 }; 160 161 static 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 170 enum nist_decap_states { 171 NIST_DECAP_C, 172 NIST_DECAP_K, 173 N_NIST_DECAP_STATES, 174 }; 175 176 static 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 191 static int 192 MlkemNistDecapFileTest(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 227 static int 228 nist_decap_run_test_case(void *ctx) 229 { 230 return MlkemNistDecapFileTest(ctx); 231 } 232 233 static 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 246 static int 247 mlkem_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 278 struct 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 289 enum 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 298 static 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 332 static int 333 encap_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 342 static void 343 encap_finish(void *ctx) 344 { 345 (void)ctx; 346 } 347 348 static int 349 MlkemEncapFileTest(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 386 static int 387 encap_run_test_case(void *ctx) 388 { 389 return MlkemEncapFileTest(ctx); 390 } 391 392 static 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 402 static int 403 mlkem_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 434 struct 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 447 enum keygen_states { 448 KEYGEN_SEED, 449 KEYGEN_PUBLIC_KEY, 450 KEYGEN_PRIVATE_KEY, 451 N_KEYGEN_STATES, 452 }; 453 454 static 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 475 static int 476 keygen_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 485 static void 486 keygen_finish(void *ctx) 487 { 488 (void)ctx; 489 } 490 491 static int 492 MlkemKeygenFileTest(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 532 static int 533 keygen_run_test_case(void *ctx) 534 { 535 return MlkemKeygenFileTest(ctx); 536 } 537 538 static 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 548 enum 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 556 static 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 583 static int 584 MlkemNistKeygenFileTest(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 631 static int 632 nist_keygen_run_test_case(void *ctx) 633 { 634 return MlkemNistKeygenFileTest(ctx); 635 } 636 637 static 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 647 static int 648 mlkem_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 690 static int 691 run_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 719 int 720 main(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 } 729