Skip to content

Commit bcd852d

Browse files
authored
Merge pull request #1100 from pq-code-package/test-acvp_data_update_1_1_0_40
Update the ACVP tests to 1.1.0.40 (add {en,de}capsulationKeyCheck)
2 parents 68033c2 + a00cc0d commit bcd852d

16 files changed

+2707
-1966
lines changed

BIBLIOGRAPHY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ source code and documentation.
188188
- [mlkem/src/compress.h](mlkem/src/compress.h)
189189
- [mlkem/src/indcpa.c](mlkem/src/indcpa.c)
190190
- [mlkem/src/kem.c](mlkem/src/kem.c)
191+
- [mlkem/src/kem.h](mlkem/src/kem.h)
191192
- [mlkem/src/poly.c](mlkem/src/poly.c)
192193
- [mlkem/src/poly_k.c](mlkem/src/poly_k.c)
193194
- [mlkem/src/sampling.c](mlkem/src/sampling.c)

mlkem/mlkem_native.S

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,8 @@
191191
/* mlkem/src/kem.h */
192192
#undef MLK_CONFIG_API_NO_SUPERCOP
193193
#undef MLK_KEM_H
194+
#undef crypto_kem_check_pk
195+
#undef crypto_kem_check_sk
194196
#undef crypto_kem_dec
195197
#undef crypto_kem_enc
196198
#undef crypto_kem_enc_derand

mlkem/mlkem_native.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@
180180
/* mlkem/src/kem.h */
181181
#undef MLK_CONFIG_API_NO_SUPERCOP
182182
#undef MLK_KEM_H
183+
#undef crypto_kem_check_pk
184+
#undef crypto_kem_check_sk
183185
#undef crypto_kem_dec
184186
#undef crypto_kem_enc
185187
#undef crypto_kem_enc_derand

mlkem/src/kem.c

Lines changed: 6 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@
3636
* This is to facilitate building multiple instances
3737
* of mlkem-native (e.g. with varying security levels)
3838
* within a single compilation unit. */
39-
#define mlk_check_pk MLK_ADD_PARAM_SET(mlk_check_pk)
40-
#define mlk_check_sk MLK_ADD_PARAM_SET(mlk_check_sk)
4139
#define mlk_check_pct MLK_ADD_PARAM_SET(mlk_check_pct)
4240
/* End of parameter set namespacing */
4341

@@ -50,26 +48,11 @@ __contract__(
5048
);
5149
#endif /* CBMC */
5250

53-
/*************************************************
54-
* Name: mlk_check_pk
55-
*
56-
* Description: Implements modulus check mandated by FIPS 203,
57-
* i.e., ensures that coefficients are in [0,q-1].
58-
*
59-
* Arguments: - const uint8_t *pk: pointer to input public key
60-
* (an already allocated array of MLKEM_INDCCA_PUBLICKEYBYTES
61-
* bytes)
62-
*
63-
* Returns: - 0 on success
64-
* - -1 on failure
65-
*
66-
* Specification: Implements @[FIPS203, Section 7.2, 'modulus check']
67-
*
68-
**************************************************/
6951

7052
/* Reference: Not implemented in the reference implementation @[REF]. */
53+
MLK_INTERNAL_API
7154
MLK_MUST_CHECK_RETURN_VALUE
72-
static int mlk_check_pk(const uint8_t pk[MLKEM_INDCCA_PUBLICKEYBYTES])
55+
int crypto_kem_check_pk(const uint8_t pk[MLKEM_INDCCA_PUBLICKEYBYTES])
7356
{
7457
int res;
7558
mlk_polyvec p;
@@ -90,27 +73,11 @@ static int mlk_check_pk(const uint8_t pk[MLKEM_INDCCA_PUBLICKEYBYTES])
9073
return res;
9174
}
9275

93-
/*************************************************
94-
* Name: mlk_check_sk
95-
*
96-
* Description: Implements public key hash check mandated by FIPS 203,
97-
* i.e., ensures that
98-
* sk[768𝑘+32 ∶ 768𝑘+64] = H(pk)= H(sk[384𝑘 : 768𝑘+32])
99-
*
100-
* Arguments: - const uint8_t *sk: pointer to input private key
101-
* (an already allocated array of MLKEM_INDCCA_SECRETKEYBYTES
102-
* bytes)
103-
*
104-
* Returns: - 0 on success
105-
* - -1 on failure
106-
*
107-
* Specification: Implements @[FIPS203, Section 7.3, 'hash check']
108-
*
109-
**************************************************/
11076

11177
/* Reference: Not implemented in the reference implementation @[REF]. */
78+
MLK_INTERNAL_API
11279
MLK_MUST_CHECK_RETURN_VALUE
113-
static int mlk_check_sk(const uint8_t sk[MLKEM_INDCCA_SECRETKEYBYTES])
80+
int crypto_kem_check_sk(const uint8_t sk[MLKEM_INDCCA_SECRETKEYBYTES])
11481
{
11582
int res;
11683
MLK_ALIGN uint8_t test[MLKEM_SYMBYTES];
@@ -267,7 +234,7 @@ int crypto_kem_enc_derand(uint8_t ct[MLKEM_INDCCA_CIPHERTEXTBYTES],
267234
MLK_ALIGN uint8_t kr[2 * MLKEM_SYMBYTES];
268235

269236
/* Specification: Implements @[FIPS203, Section 7.2, Modulus check] */
270-
if (mlk_check_pk(pk))
237+
if (crypto_kem_check_pk(pk))
271238
{
272239
return -1;
273240
}
@@ -329,7 +296,7 @@ int crypto_kem_dec(uint8_t ss[MLKEM_SSBYTES],
329296
const uint8_t *pk = sk + MLKEM_INDCPA_SECRETKEYBYTES;
330297

331298
/* Specification: Implements @[FIPS203, Section 7.3, Hash check] */
332-
if (mlk_check_sk(sk))
299+
if (crypto_kem_check_sk(sk))
333300
{
334301
return -1;
335302
}
@@ -367,6 +334,4 @@ int crypto_kem_dec(uint8_t ss[MLKEM_SSBYTES],
367334

368335
/* To facilitate single-compilation-unit (SCU) builds, undefine all macros.
369336
* Don't modify by hand -- this is auto-generated by scripts/autogen. */
370-
#undef mlk_check_pk
371-
#undef mlk_check_sk
372337
#undef mlk_check_pct

mlkem/src/kem.h

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@
1010
* FIPS 203 Module-Lattice-Based Key-Encapsulation Mechanism Standard
1111
* National Institute of Standards and Technology
1212
* https://csrc.nist.gov/pubs/fips/203/final
13+
*
14+
* - [REF]
15+
* CRYSTALS-Kyber C reference implementation
16+
* Bos, Ducas, Kiltz, Lepoint, Lyubashevsky, Schanck, Schwabe, Seiler, Stehlé
17+
* https://github.com/pq-crystals/kyber/tree/main/ref
1318
*/
1419

1520
#ifndef MLK_KEM_H
@@ -49,6 +54,56 @@
4954
#define crypto_kem_enc_derand MLK_NAMESPACE_K(enc_derand)
5055
#define crypto_kem_enc MLK_NAMESPACE_K(enc)
5156
#define crypto_kem_dec MLK_NAMESPACE_K(dec)
57+
#define crypto_kem_check_pk MLK_NAMESPACE_K(check_pk)
58+
#define crypto_kem_check_sk MLK_NAMESPACE_K(check_sk)
59+
60+
61+
62+
/*************************************************
63+
* Name: crypto_kem_check_pk
64+
*
65+
* Description: Implements modulus check mandated by FIPS 203,
66+
* i.e., ensures that coefficients are in [0,q-1].
67+
*
68+
* Arguments: - const uint8_t *pk: pointer to input public key
69+
* (an already allocated array of MLKEM_INDCCA_PUBLICKEYBYTES
70+
* bytes)
71+
*
72+
* Returns: - 0 on success
73+
* - -1 on failure
74+
*
75+
* Specification: Implements @[FIPS203, Section 7.2, 'modulus check']
76+
*
77+
**************************************************/
78+
79+
/* Reference: Not implemented in the reference implementation @[REF]. */
80+
MLK_INTERNAL_API
81+
MLK_MUST_CHECK_RETURN_VALUE
82+
int crypto_kem_check_pk(const uint8_t pk[MLKEM_INDCCA_PUBLICKEYBYTES]);
83+
84+
85+
/*************************************************
86+
* Name: crypto_kem_check_sk
87+
*
88+
* Description: Implements public key hash check mandated by FIPS 203,
89+
* i.e., ensures that
90+
* sk[768𝑘+32 ∶ 768𝑘+64] = H(pk)= H(sk[384𝑘 : 768𝑘+32])
91+
*
92+
* Arguments: - const uint8_t *sk: pointer to input private key
93+
* (an already allocated array of MLKEM_INDCCA_SECRETKEYBYTES
94+
* bytes)
95+
*
96+
* Returns: - 0 on success
97+
* - -1 on failure
98+
*
99+
* Specification: Implements @[FIPS203, Section 7.3, 'hash check']
100+
*
101+
**************************************************/
102+
103+
/* Reference: Not implemented in the reference implementation @[REF]. */
104+
MLK_INTERNAL_API
105+
MLK_MUST_CHECK_RETURN_VALUE
106+
int crypto_kem_check_sk(const uint8_t sk[MLKEM_INDCCA_SECRETKEYBYTES]);
52107

53108
/*************************************************
54109
* Name: crypto_kem_keypair_derand

test/acvp_client.py

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,6 @@
2121

2222
acvp_dir = "test/acvp_data"
2323
acvp_jsons = [
24-
(
25-
f"{acvp_dir}/acvp_v1.1.0.36_keyGen_prompt.json",
26-
f"{acvp_dir}/acvp_v1.1.0.36_keyGen_expectedResults.json",
27-
),
2824
(
2925
f"{acvp_dir}/acvp_v1.1.0.38_keyGen_prompt.json",
3026
f"{acvp_dir}/acvp_v1.1.0.38_keyGen_expectedResults.json",
@@ -34,8 +30,8 @@
3430
f"{acvp_dir}/acvp_v1.1.0.39_keyGen_expectedResults.json",
3531
),
3632
(
37-
f"{acvp_dir}/acvp_v1.1.0.36_encapDecap_prompt.json",
38-
f"{acvp_dir}/acvp_v1.1.0.36_encapDecap_expectedResults.json",
33+
f"{acvp_dir}/acvp_v1.1.0.40_keyGen_prompt.json",
34+
f"{acvp_dir}/acvp_v1.1.0.40_keyGen_expectedResults.json",
3935
),
4036
(
4137
f"{acvp_dir}/acvp_v1.1.0.38_encapDecap_prompt.json",
@@ -45,6 +41,10 @@
4541
f"{acvp_dir}/acvp_v1.1.0.39_encapDecap_prompt.json",
4642
f"{acvp_dir}/acvp_v1.1.0.39_encapDecap_expectedResults.json",
4743
),
44+
(
45+
f"{acvp_dir}/acvp_v1.1.0.40_encapDecap_prompt.json",
46+
f"{acvp_dir}/acvp_v1.1.0.40_encapDecap_expectedResults.json",
47+
),
4848
]
4949

5050

@@ -113,12 +113,15 @@ def run_encapDecap_test(tg, tc):
113113
results[k] = v
114114
elif tg["function"] == "decapsulation":
115115
acvp_bin = get_acvp_binary(tg)
116+
# TODO: Remove this fallback workaround. v.1.1.0.40 moved the dk from the
117+
# tg to the tc. This can be removed when v1.1.0.39 is removed.
118+
dk_value = tc.get("dk", tg.get("dk"))
116119
acvp_call = exec_prefix + [
117120
acvp_bin,
118121
"encapDecap",
119122
"VAL",
120123
"decapsulation",
121-
f"dk={tg['dk']}",
124+
f"dk={dk_value}",
122125
f"c={tc['c']}",
123126
]
124127
result = subprocess.run(acvp_call, encoding="utf-8", capture_output=True)
@@ -131,6 +134,45 @@ def run_encapDecap_test(tg, tc):
131134
for l in result.stdout.splitlines():
132135
(k, v) = l.split("=")
133136
results[k] = v
137+
elif tg["function"] == "encapsulationKeyCheck":
138+
acvp_bin = get_acvp_binary(tg)
139+
acvp_call = exec_prefix + [
140+
acvp_bin,
141+
"encapDecap",
142+
"VAL",
143+
"encapsulationKeyCheck",
144+
f"ek={tc['ek']}",
145+
]
146+
result = subprocess.run(acvp_call, encoding="utf-8", capture_output=True)
147+
if result.returncode != 0:
148+
err("FAIL!")
149+
err(f"{acvp_call} failed with error code {result.returncode}")
150+
err(result.stderr)
151+
exit(1)
152+
# Extract results
153+
for l in result.stdout.splitlines():
154+
(k, v) = l.split("=")
155+
results[k] = v == "1"
156+
157+
elif tg["function"] == "decapsulationKeyCheck":
158+
acvp_bin = get_acvp_binary(tg)
159+
acvp_call = exec_prefix + [
160+
acvp_bin,
161+
"encapDecap",
162+
"VAL",
163+
"decapsulationKeyCheck",
164+
f"dk={tc['dk']}",
165+
]
166+
result = subprocess.run(acvp_call, encoding="utf-8", capture_output=True)
167+
if result.returncode != 0:
168+
err("FAIL!")
169+
err(f"{acvp_call} failed with error code {result.returncode}")
170+
err(result.stderr)
171+
exit(1)
172+
# Extract results
173+
for l in result.stdout.splitlines():
174+
(k, v) = l.split("=")
175+
results[k] = v == "1"
134176
info("done")
135177
return results
136178

test/acvp_data/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[//]: # (SPDX-License-Identifier: CC-BY-4.0)
22

3-
This directory contains the ACVP test vectors from [^ACVP_Server], versions v1.1.0.36, v1.1.0.38, and v1.1.0.39. See [^ACVP_Spec] for the
3+
This directory contains the ACVP test vectors from [^ACVP_Server], versions v1.1.0.38, v1.1.0.39, and v1.1.0.40. See [^ACVP_Spec] for the
44
specification of the ACVP tests.
55

66
<!--- bibliography --->

0 commit comments

Comments
 (0)