From bfbde585f4ba59f67c4c888c02a750f4d8194d81 Mon Sep 17 00:00:00 2001 From: Fredrik Dahlgren Date: Fri, 26 Jun 2026 16:28:42 +0200 Subject: [PATCH] Document signing secret-key validity precondition --- mldsa/mldsa_native.h | 31 ++++++++++++++++++++++------ mldsa/src/sign.h | 30 +++++++++++++++++++++------ test/wycheproof/wycheproof_client.py | 5 ++++- 3 files changed, 53 insertions(+), 13 deletions(-) diff --git a/mldsa/mldsa_native.h b/mldsa/mldsa_native.h index 4310f2aae..c84bebce8 100644 --- a/mldsa/mldsa_native.h +++ b/mldsa/mldsa_native.h @@ -315,7 +315,11 @@ int MLD_API_NAMESPACE(keypair)( * @param prelen Length of prefix string. Ignored when * externalmu != 0. * @param[in] rnd Random seed. - * @param[in] sk Bit-packed secret key. + * @param[in] sk Bit-packed valid secret key. Signing does not perform + * full serialized secret-key validation; callers + * importing serialized keys can use + * crypto_sign_pk_from_sk to validate them before + * signing. * @param externalmu 0: m/mlen is the raw message; mu = H(tr, pre, m) is * computed internally. * non-zero: m points to a precomputed mu of @@ -361,7 +365,10 @@ int MLD_API_NAMESPACE(signature_internal)( * @param mlen Length of message. * @param[in] ctx Pointer to context string. May be NULL if ctxlen == 0. * @param ctxlen Length of context string. Should be <= 255. - * @param[in] sk Bit-packed secret key. + * @param[in] sk Bit-packed valid secret key. Signing does not perform + * full serialized secret-key validation; callers importing + * serialized keys can use crypto_sign_pk_from_sk to + * validate them before signing. * @param context Application context. Only present when * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by * MLD_CONFIG_CONTEXT_PARAMETER_TYPE. @@ -400,7 +407,10 @@ int MLD_API_NAMESPACE(signature)( * @param[out] sig Output signature. * @param[out] siglen Pointer to output length of signature. * @param[in] mu Precomputed message representative. - * @param[in] sk Bit-packed secret key. + * @param[in] sk Bit-packed valid secret key. Signing does not perform + * full serialized secret-key validation; callers importing + * serialized keys can use crypto_sign_pk_from_sk to + * validate them before signing. * @param context Application context. Only present when * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by * MLD_CONFIG_CONTEXT_PARAMETER_TYPE. @@ -439,7 +449,10 @@ int MLD_API_NAMESPACE(signature_extmu)( * @param mlen Length of message. * @param[in] ctx Pointer to context string. * @param ctxlen Length of context string. - * @param[in] sk Bit-packed secret key. + * @param[in] sk Bit-packed valid secret key. Signing does not perform + * full serialized secret-key validation; callers importing + * serialized keys can use crypto_sign_pk_from_sk to + * validate them before signing. * @param context Application context. Only present when * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by * MLD_CONFIG_CONTEXT_PARAMETER_TYPE. @@ -648,7 +661,10 @@ int MLD_API_NAMESPACE(open)( * @param[in] ctx Pointer to context string. * @param ctxlen Length of context string. * @param[in] rnd Random seed. - * @param[in] sk Bit-packed secret key. + * @param[in] sk Bit-packed valid secret key. Signing does not perform + * full serialized secret-key validation; callers importing + * serialized keys can use crypto_sign_pk_from_sk to + * validate them before signing. * @param hashalg Hash algorithm constant (one of MLD_PREHASH_*). * @param context Application context. Only present when * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by @@ -739,7 +755,10 @@ int MLD_API_NAMESPACE(verify_pre_hash_internal)( * @param[in] ctx Pointer to context string. * @param ctxlen Length of context string. * @param[in] rnd Random seed. - * @param[in] sk Bit-packed secret key. + * @param[in] sk Bit-packed valid secret key. Signing does not perform + * full serialized secret-key validation; callers importing + * serialized keys can use crypto_sign_pk_from_sk to + * validate them before signing. * @param context Application context. Only present when * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by * MLD_CONFIG_CONTEXT_PARAMETER_TYPE. diff --git a/mldsa/src/sign.h b/mldsa/src/sign.h index cc2ddc6dc..527ecb7a2 100644 --- a/mldsa/src/sign.h +++ b/mldsa/src/sign.h @@ -194,7 +194,10 @@ __contract__( * @param prelen Length of prefix string. Ignored when * externalmu != 0. * @param[in] rnd Random seed. - * @param[in] sk Bit-packed secret key. + * @param[in] sk Bit-packed valid secret key. Signing does not perform + * full serialized secret-key validation; callers + * importing serialized keys can use mld_sign_pk_from_sk + * to validate them before signing. * @param externalmu 0: m/mlen is the raw message; mu = H(tr, pre, m) is * computed internally. * non-zero: m points to a precomputed mu of @@ -254,7 +257,10 @@ __contract__( * @param mlen Length of message. * @param[in] ctx Pointer to context string. May be NULL if ctxlen == 0. * @param ctxlen Length of context string. Should be <= 255. - * @param[in] sk Bit-packed secret key. + * @param[in] sk Bit-packed valid secret key. Signing does not perform + * full serialized secret-key validation; callers importing + * serialized keys can use mld_sign_pk_from_sk to validate + * them before signing. * @param context Application context. Only present when * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by * MLD_CONFIG_CONTEXT_PARAMETER_TYPE. @@ -303,7 +309,10 @@ __contract__( * @param[out] sig Output signature. * @param[out] siglen Pointer to output length of signature. * @param[in] mu Precomputed message representative. - * @param[in] sk Bit-packed secret key. + * @param[in] sk Bit-packed valid secret key. Signing does not perform + * full serialized secret-key validation; callers importing + * serialized keys can use mld_sign_pk_from_sk to validate + * them before signing. * @param context Application context. Only present when * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by * MLD_CONFIG_CONTEXT_PARAMETER_TYPE. @@ -345,7 +354,10 @@ __contract__( * @param mlen Length of message. * @param[in] ctx Pointer to context string. * @param ctxlen Length of context string. - * @param[in] sk Bit-packed secret key. + * @param[in] sk Bit-packed valid secret key. Signing does not perform + * full serialized secret-key validation; callers importing + * serialized keys can use mld_sign_pk_from_sk to validate + * them before signing. * @param context Application context. Only present when * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by * MLD_CONFIG_CONTEXT_PARAMETER_TYPE. @@ -569,7 +581,10 @@ __contract__( * @param[in] ctx Pointer to context string. * @param ctxlen Length of context string. * @param[in] rnd Random seed. - * @param[in] sk Bit-packed secret key. + * @param[in] sk Bit-packed valid secret key. Signing does not perform + * full serialized secret-key validation; callers importing + * serialized keys can use mld_sign_pk_from_sk to validate + * them before signing. * @param hashalg Hash algorithm constant (one of MLD_PREHASH_*). * @param context Application context. Only present when * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by @@ -674,7 +689,10 @@ __contract__( * @param[in] ctx Pointer to context string. * @param ctxlen Length of context string. * @param[in] rnd Random seed. - * @param[in] sk Bit-packed secret key. + * @param[in] sk Bit-packed valid secret key. Signing does not perform + * full serialized secret-key validation; callers importing + * serialized keys can use mld_sign_pk_from_sk to validate + * them before signing. * @param context Application context. Only present when * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by * MLD_CONFIG_CONTEXT_PARAMETER_TYPE. diff --git a/test/wycheproof/wycheproof_client.py b/test/wycheproof/wycheproof_client.py index 177f68f4a..7d10b56ec 100755 --- a/test/wycheproof/wycheproof_client.py +++ b/test/wycheproof/wycheproof_client.py @@ -126,7 +126,10 @@ class TestResult(Enum): def check_sign_result(tc, out): if tc["result"] == "invalid": flags = tc.get("flags", []) - # InvalidPrivateKey: signing does not validate sk; tested via pk_from_sk + # FIPS 204 does not require signing to validate serialized private keys. + # Checking only s1/s2 would be incomplete: full validation also checks + # t0 and tr and is exposed through pk_from_sk. These InvalidPrivateKey + # vectors are skipped for signing and still tested through pkFromSk. if "InvalidPrivateKey" in flags: return TestResult.SKIPPED # If new invalid-flag classes appear, fail loudly so we can handle them.