Skip to content

Commit 10cccc5

Browse files
authored
Merge pull request #769 from pq-code-package/pct
Add Pairwise Consistency Test (PCT) for FIPS-203 IG compliance
2 parents 9bb55fe + 953daba commit 10cccc5

File tree

26 files changed

+497
-382
lines changed

26 files changed

+497
-382
lines changed

.github/workflows/ci.yml

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ jobs:
329329
nix-cache: ${{ matrix.target.mode == 'native' && 'false' || 'true' }}
330330
gh_token: ${{ secrets.GITHUB_TOKEN }}
331331
compile_mode: ${{ matrix.target.mode }}
332+
cflags: "-DMLK_KEYGEN_PCT"
332333
# There is no native code on R-V or AArch64_be yet, so no point running opt tests
333334
opt: ${{ (matrix.target.arch != 'riscv64' && matrix.target.arch != 'aarch64_be') && 'all' || 'no_opt' }}
334335
- name: build + test (+debug+memsan+ubsan)
@@ -337,7 +338,7 @@ jobs:
337338
with:
338339
gh_token: ${{ secrets.GITHUB_TOKEN }}
339340
compile_mode: native
340-
cflags: "-DMLKEM_DEBUG -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all"
341+
cflags: "-DMLK_KEYGEN_PCT -DMLKEM_DEBUG -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all"
341342
compiler_tests:
342343
name: Compiler tests (${{ matrix.compiler.name }}, ${{ matrix.target.name }})
343344
needs: [quickcheck, quickcheck-windows, quickcheck-c90, quickcheck-lib, examples, lint, lint-markdown-link]
@@ -393,6 +394,7 @@ jobs:
393394
kat: false
394395
acvp: false
395396
nix-shell: ${{ matrix.compiler.shell }}
397+
cflags: "-DMLK_KEYGEN_PCT"
396398
- name: native build+functest (C90)
397399
if: ${{ matrix.compiler.darwin || matrix.target.runner != 'macos-latest' }}
398400
uses: ./.github/actions/multi-functest
@@ -404,7 +406,7 @@ jobs:
404406
kat: false
405407
acvp: false
406408
nix-shell: ${{ matrix.compiler.shell }}
407-
cflags: "-std=c90"
409+
cflags: "-std=c90 -DMLK_KEYGEN_PCT"
408410
- name: native build+functest (C99)
409411
if: ${{ matrix.compiler.darwin || matrix.target.runner != 'macos-latest' }}
410412
uses: ./.github/actions/multi-functest
@@ -428,7 +430,7 @@ jobs:
428430
kat: false
429431
acvp: false
430432
nix-shell: ${{ matrix.compiler.shell }}
431-
cflags: "-std=c11"
433+
cflags: "-std=c11 -DMLK_KEYGEN_PCT"
432434
- name: native build+functest (C17)
433435
if: ${{ (matrix.compiler.darwin || matrix.target.runner != 'macos-latest') &&
434436
matrix.compiler.c17 }}
@@ -441,7 +443,7 @@ jobs:
441443
kat: false
442444
acvp: false
443445
nix-shell: ${{ matrix.compiler.shell }}
444-
cflags: "-std=c17"
446+
cflags: "-std=c17 -DMLK_KEYGEN_PCT"
445447
config_variations:
446448
name: Non-standard configurations
447449
needs: [quickcheck, quickcheck-windows, quickcheck-c90, quickcheck-lib, examples, lint, lint-markdown-link]
@@ -605,6 +607,7 @@ jobs:
605607
acvptest: true
606608
lint: false
607609
verbose: true
610+
cflags: " -DMLK_KEYGEN_PCT"
608611
secrets: inherit
609612
compatibility_tests:
610613
strategy:
@@ -653,6 +656,7 @@ jobs:
653656
with:
654657
nix-shell: ""
655658
gh_token: ${{ secrets.AWS_GITHUB_TOKEN }}
659+
cflags: " -DMLK_KEYGEN_PCT"
656660
ec2_compatibilitytests:
657661
strategy:
658662
max-parallel: 8
@@ -699,7 +703,7 @@ jobs:
699703
acvptest: true
700704
lint: false
701705
verbose: true
702-
cflags: "-O0"
706+
cflags: "-O0 -DMLK_KEYGEN_PCT"
703707
secrets: inherit
704708
cbmc_k2:
705709
name: CBMC (ML-KEM-512)

examples/bring_your_own_fips202/main.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,18 @@
99
#include <mlkem_native.h>
1010
#include "test_only_rng/notrandombytes.h"
1111

12+
#define CHECK(x) \
13+
do \
14+
{ \
15+
int rc; \
16+
rc = (x); \
17+
if (!rc) \
18+
{ \
19+
fprintf(stderr, "ERROR (%s,%d)\n", __FILE__, __LINE__); \
20+
return 1; \
21+
} \
22+
} while (0)
23+
1224
int main(void)
1325
{
1426
uint8_t pk[CRYPTO_PUBLICKEYBYTES];
@@ -41,19 +53,19 @@ int main(void)
4153
printf("Generating keypair ... ");
4254

4355
/* Alice generates a public key */
44-
crypto_kem_keypair(pk, sk);
56+
CHECK(crypto_kem_keypair(pk, sk) == 0);
4557

4658
printf("DONE\n");
4759
printf("Encaps... ");
4860

4961
/* Bob derives a secret key and creates a response */
50-
crypto_kem_enc(ct, key_b, pk);
62+
CHECK(crypto_kem_enc(ct, key_b, pk) == 0);
5163

5264
printf("DONE\n");
5365
printf("Decaps... ");
5466

5567
/* Alice uses Bobs response to get her shared key */
56-
crypto_kem_dec(key_a, ct, sk);
68+
CHECK(crypto_kem_dec(key_a, ct, sk) == 0);
5769

5870
printf("DONE\n");
5971
printf("Compare... ");
@@ -74,11 +86,7 @@ int main(void)
7486

7587
/* Check against hardcoded result to make sure that
7688
* we integrated custom FIPS202 correctly */
77-
if (memcmp(key_a, expected_key, CRYPTO_BYTES) != 0)
78-
{
79-
printf("ERROR: Unexpected result\n");
80-
return 1;
81-
}
89+
CHECK(memcmp(key_a, expected_key, CRYPTO_BYTES) == 0);
8290

8391
printf("OK\n");
8492

examples/custom_backend/main.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,18 @@
99
#include <mlkem_native.h>
1010
#include "test_only_rng/notrandombytes.h"
1111

12+
#define CHECK(x) \
13+
do \
14+
{ \
15+
int rc; \
16+
rc = (x); \
17+
if (!rc) \
18+
{ \
19+
fprintf(stderr, "ERROR (%s,%d)\n", __FILE__, __LINE__); \
20+
return 1; \
21+
} \
22+
} while (0)
23+
1224
int main(void)
1325
{
1426
uint8_t pk[CRYPTO_PUBLICKEYBYTES];
@@ -41,19 +53,19 @@ int main(void)
4153
printf("Generating keypair ... ");
4254

4355
/* Alice generates a public key */
44-
crypto_kem_keypair(pk, sk);
56+
CHECK(crypto_kem_keypair(pk, sk) == 0);
4557

4658
printf("DONE\n");
4759
printf("Encaps... ");
4860

4961
/* Bob derives a secret key and creates a response */
50-
crypto_kem_enc(ct, key_b, pk);
62+
CHECK(crypto_kem_enc(ct, key_b, pk) == 0);
5163

5264
printf("DONE\n");
5365
printf("Decaps... ");
5466

5567
/* Alice uses Bobs response to get her shared key */
56-
crypto_kem_dec(key_a, ct, sk);
68+
CHECK(crypto_kem_dec(key_a, ct, sk) == 0);
5769

5870
printf("DONE\n");
5971
printf("Compare... ");
@@ -74,11 +86,7 @@ int main(void)
7486

7587
/* Check against hardcoded result to make sure that
7688
* we integrated custom FIPS202 correctly */
77-
if (memcmp(key_a, expected_key, CRYPTO_BYTES) != 0)
78-
{
79-
printf("ERROR: Unexpected result\n");
80-
return 1;
81-
}
89+
CHECK(memcmp(key_a, expected_key, CRYPTO_BYTES) == 0);
8290

8391
printf("OK\n");
8492

examples/mlkem_native_as_code_package/main.c

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,18 @@
99
#include "mlkem_native/mlkem/mlkem_native.h"
1010
#include "test_only_rng/notrandombytes.h"
1111

12+
#define CHECK(x) \
13+
do \
14+
{ \
15+
int rc; \
16+
rc = (x); \
17+
if (!rc) \
18+
{ \
19+
fprintf(stderr, "ERROR (%s,%d)\n", __FILE__, __LINE__); \
20+
return 1; \
21+
} \
22+
} while (0)
23+
1224
int main(void)
1325
{
1426
uint8_t pk[CRYPTO_PUBLICKEYBYTES];
@@ -41,28 +53,24 @@ int main(void)
4153
printf("Generating keypair ... ");
4254

4355
/* Alice generates a public key */
44-
crypto_kem_keypair(pk, sk);
56+
CHECK(crypto_kem_keypair(pk, sk) == 0);
4557

4658
printf("DONE\n");
4759
printf("Encaps... ");
4860

4961
/* Bob derives a secret key and creates a response */
50-
crypto_kem_enc(ct, key_b, pk);
62+
CHECK(crypto_kem_enc(ct, key_b, pk) == 0);
5163

5264
printf("DONE\n");
5365
printf("Decaps... ");
5466

5567
/* Alice uses Bobs response to get her shared key */
56-
crypto_kem_dec(key_a, ct, sk);
68+
CHECK(crypto_kem_dec(key_a, ct, sk) == 0);
5769

5870
printf("DONE\n");
5971
printf("Compare... ");
6072

61-
if (memcmp(key_a, key_b, CRYPTO_BYTES))
62-
{
63-
printf("ERROR\n");
64-
return 1;
65-
}
73+
CHECK(memcmp(key_a, key_b, CRYPTO_BYTES) == 0);
6674

6775
printf("Shared secret: ");
6876
{
@@ -72,12 +80,7 @@ int main(void)
7280
}
7381
printf("\n");
7482

75-
if (memcmp(key_a, expected_key, sizeof(key_a)) != 0)
76-
{
77-
printf("ERROR: Unexpected result\n");
78-
return 1;
79-
}
80-
83+
CHECK(memcmp(key_a, expected_key, sizeof(key_a)) == 0);
8184
printf("OK\n");
8285
return 0;
8386
}

examples/monolithic_build/main.c

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,18 @@
1010
#include "mlkem_native.h"
1111
#include "test_only_rng/notrandombytes.h"
1212

13+
#define CHECK(x) \
14+
do \
15+
{ \
16+
int rc; \
17+
rc = (x); \
18+
if (!rc) \
19+
{ \
20+
fprintf(stderr, "ERROR (%s,%d)\n", __FILE__, __LINE__); \
21+
return 1; \
22+
} \
23+
} while (0)
24+
1325
static int test_keys_mlkem(void)
1426
{
1527
#if MLKEM_K == 2
@@ -39,19 +51,15 @@ static int test_keys_mlkem(void)
3951
randombytes_reset();
4052

4153
/* Alice generates a public key */
42-
mlkem_keypair(pk, sk);
54+
CHECK(mlkem_keypair(pk, sk) == 0);
4355

4456
/* Bob derives a secret key and creates a response */
45-
mlkem_enc(ct, key_b, pk);
57+
CHECK(mlkem_enc(ct, key_b, pk) == 0);
4658

4759
/* Alice uses Bobs response to get her shared key */
48-
mlkem_dec(key_a, ct, sk);
60+
CHECK(mlkem_dec(key_a, ct, sk) == 0);
4961

50-
if (memcmp(key_a, key_b, MLKEM_BYTES))
51-
{
52-
printf("[MLKEM] ERROR keys\n");
53-
return 1;
54-
}
62+
CHECK(memcmp(key_a, key_b, MLKEM_BYTES) == 0);
5563

5664
printf("Shared secret: ");
5765
{
@@ -61,11 +69,7 @@ static int test_keys_mlkem(void)
6169
}
6270
printf("\n");
6371

64-
if (memcmp(key_a, expected_key, sizeof(key_a)) != 0)
65-
{
66-
printf("ERROR: Unexpected result\n");
67-
return 1;
68-
}
72+
CHECK(memcmp(key_a, expected_key, sizeof(key_a)) == 0);
6973

7074
printf("[MLKEM-%d] OK\n", MLK_BUILD_INFO_LVL);
7175
return 0;

examples/monolithic_build/mlkem_native_monobuild.c

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@
140140
#undef MLK_BUILD_INFO_LVL
141141
#undef MLK_BUILD_INFO_NAMESPACE
142142
#undef MLK_H
143+
#undef MLK_MUST_CHECK_RETURN_VALUE
143144
#undef crypto_kem_dec
144145
#undef crypto_kem_enc
145146
#undef crypto_kem_enc_derand
@@ -197,6 +198,25 @@
197198
#undef polyvec_reduce
198199
#undef polyvec_tobytes
199200
#undef polyvec_tomont
201+
/* mlkem/sys.h */
202+
#undef MLK_ALIGN
203+
#undef MLK_ALWAYS_INLINE
204+
#undef MLK_CET_ENDBR
205+
#undef MLK_CT_TESTING_DECLASSIFY
206+
#undef MLK_CT_TESTING_SECRET
207+
#undef MLK_DEFAULT_ALIGN
208+
#undef MLK_HAVE_INLINE_ASM
209+
#undef MLK_INLINE
210+
#undef MLK_MUST_CHECK_RETURN_VALUE
211+
#undef MLK_RESTRICT
212+
#undef MLK_SYS_AARCH64
213+
#undef MLK_SYS_AARCH64_EB
214+
#undef MLK_SYS_BIG_ENDIAN
215+
#undef MLK_SYS_H
216+
#undef MLK_SYS_LITTLE_ENDIAN
217+
#undef MLK_SYS_WINDOWS
218+
#undef MLK_SYS_X86_64
219+
#undef MLK_SYS_X86_64_AVX2
200220

201221
#if !defined(MLK_MONOBUILD_KEEP_SHARED_HEADERS)
202222
/*
@@ -280,24 +300,6 @@
280300
#undef xof_x4_init
281301
#undef xof_x4_release
282302
#undef xof_x4_squeezeblocks
283-
/* mlkem/sys.h */
284-
#undef MLK_ALIGN
285-
#undef MLK_ALWAYS_INLINE
286-
#undef MLK_CET_ENDBR
287-
#undef MLK_CT_TESTING_DECLASSIFY
288-
#undef MLK_CT_TESTING_SECRET
289-
#undef MLK_DEFAULT_ALIGN
290-
#undef MLK_HAVE_INLINE_ASM
291-
#undef MLK_INLINE
292-
#undef MLK_RESTRICT
293-
#undef MLK_SYS_AARCH64
294-
#undef MLK_SYS_AARCH64_EB
295-
#undef MLK_SYS_BIG_ENDIAN
296-
#undef MLK_SYS_H
297-
#undef MLK_SYS_LITTLE_ENDIAN
298-
#undef MLK_SYS_WINDOWS
299-
#undef MLK_SYS_X86_64
300-
#undef MLK_SYS_X86_64_AVX2
301303
/* mlkem/verify.h */
302304
#undef MLK_USE_ASM_VALUE_BARRIER
303305
#undef MLK_VERIFY_H

0 commit comments

Comments
 (0)