Skip to content

Commit fd8be9c

Browse files
committed
pk_from_sk: Add validation of s1 and s2
Altenative to #807 This commit adds validation of the s1 and s2 components of the secret key to the pk_from_sk function. It checks if coefficients are within the valid bound [-MLDSA_ETA, MLDSA_ETA] by using the chknorm function that is already present in the code. Documentation and CBMC proofs are adjusted accordingly. Signed-off-by: Matthias J. Kannwischer <[email protected]>
1 parent 606e8dd commit fd8be9c

File tree

4 files changed

+30
-8
lines changed

4 files changed

+30
-8
lines changed

mldsa/mldsa_native.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -735,8 +735,16 @@ size_t MLD_API_NAMESPACE(prepare_domain_separation_prefix)(
735735
/*************************************************
736736
* Name: crypto_sign_pk_from_sk
737737
*
738-
* Description: Derives public key from secret key with validation.
739-
* Checks that t0 and tr stored in sk match recomputed values.
738+
* Description: Performs basic validity checks on secret key, and derives
739+
* public key.
740+
*
741+
* Referring to the decoding of the secret key
742+
* `sk=(rho, K, tr, s1, s2, t0)`
743+
* (cf. [@FIPS204, Algorithm 25 skDecode]),
744+
* the following checks are performed:
745+
* - Check that s1 and s2 have coefficients in
746+
* [-MLDSA_ETA, MLDSA_ETA]
747+
* - Check that t0 and tr stored in sk match recomputed values.
740748
*
741749
* Arguments: - uint8_t pk[CRYPTO_PUBLICKEYBYTES]: output public key
742750
* - const uint8_t sk[CRYPTO_SECRETKEYBYTES]: input secret key

mldsa/src/sign.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1297,7 +1297,7 @@ MLD_EXTERNAL_API
12971297
int crypto_sign_pk_from_sk(uint8_t pk[MLDSA_CRYPTO_PUBLICKEYBYTES],
12981298
const uint8_t sk[MLDSA_CRYPTO_SECRETKEYBYTES])
12991299
{
1300-
uint8_t cmp, cmp0, cmp1;
1300+
uint8_t check, cmp0, cmp1, chk1, chk2;
13011301
int ret;
13021302
MLD_ALLOC(rho, uint8_t, MLDSA_SEEDBYTES);
13031303
MLD_ALLOC(tr, uint8_t, MLDSA_TRBYTES);
@@ -1320,6 +1320,10 @@ int crypto_sign_pk_from_sk(uint8_t pk[MLDSA_CRYPTO_PUBLICKEYBYTES],
13201320
/* Unpack secret key */
13211321
mld_unpack_sk(rho, tr, key, t0, s1, s2, sk);
13221322

1323+
/* Validate s1 and s2 coefficients are within [-MLDSA_ETA, MLDSA_ETA] */
1324+
chk1 = mld_polyvecl_chknorm(s1, MLDSA_ETA + 1) & 0xFF;
1325+
chk2 = mld_polyveck_chknorm(s2, MLDSA_ETA + 1) & 0xFF;
1326+
13231327
/* Recompute t0, t1, tr, and pk from rho, s1, s2 */
13241328
ret = mld_compute_t0_t1_tr_from_sk_components(t0_computed, t1, tr_computed,
13251329
pk, rho, s1, s2);
@@ -1333,11 +1337,11 @@ int crypto_sign_pk_from_sk(uint8_t pk[MLDSA_CRYPTO_PUBLICKEYBYTES],
13331337
sizeof(mld_polyveck));
13341338
cmp1 = mld_ct_memcmp((const uint8_t *)tr, (const uint8_t *)tr_computed,
13351339
MLDSA_TRBYTES);
1336-
cmp = mld_value_barrier_u8(cmp0 | cmp1);
1340+
check = mld_value_barrier_u8(cmp0 | cmp1 | chk1 | chk2);
13371341

13381342
/* Declassify the final result of the validity check. */
1339-
MLD_CT_TESTING_DECLASSIFY(&cmp, sizeof(cmp));
1340-
ret = (cmp != 0) ? MLD_ERR_FAIL : 0;
1343+
MLD_CT_TESTING_DECLASSIFY(&check, sizeof(check));
1344+
ret = (check != 0) ? MLD_ERR_FAIL : 0;
13411345

13421346
cleanup:
13431347

mldsa/src/sign.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -745,8 +745,16 @@ __contract__(
745745
/*************************************************
746746
* Name: crypto_sign_pk_from_sk
747747
*
748-
* Description: Derives public key from secret key with validation.
749-
* Checks that t0 and tr stored in sk match recomputed values.
748+
* Description: Performs basic validity checks on secret key, and derives
749+
* public key.
750+
*
751+
* Referring to the decoding of the secret key
752+
* `sk=(rho, K, tr, s1, s2, t0)`
753+
* (cf. [@FIPS204, Algorithm 25 skDecode]),
754+
* the following checks are performed:
755+
* - Check that s1 and s2 have coefficients in
756+
* [-MLDSA_ETA, MLDSA_ETA]
757+
* - Check that t0 and tr stored in sk match recomputed values.
750758
*
751759
* Arguments: - uint8_t pk[MLDSA_CRYPTO_PUBLICKEYBYTES]: output public key
752760
* - const uint8_t sk[MLDSA_CRYPTO_SECRETKEYBYTES]: input secret

proofs/cbmc/crypto_sign_pk_from_sk/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ PROJECT_SOURCES += $(SRCDIR)/mldsa/src/sign.c
2222
CHECK_FUNCTION_CONTRACTS=$(MLD_NAMESPACE)pk_from_sk
2323
USE_FUNCTION_CONTRACTS=$(MLD_NAMESPACE)unpack_sk
2424
USE_FUNCTION_CONTRACTS+=$(MLD_NAMESPACE)pack_pk
25+
USE_FUNCTION_CONTRACTS+=$(MLD_NAMESPACE)polyvecl_chknorm
26+
USE_FUNCTION_CONTRACTS+=$(MLD_NAMESPACE)polyveck_chknorm
2527
USE_FUNCTION_CONTRACTS+=mld_compute_t0_t1_tr_from_sk_components
2628
USE_FUNCTION_CONTRACTS+=mld_value_barrier_u8
2729
USE_FUNCTION_CONTRACTS+=mld_ct_memcmp

0 commit comments

Comments
 (0)