Skip to content

Commit 3c76933

Browse files
mkannwischerhanno-becker
authored andcommitted
Doc: Document and test that message pointer may be NULL when mlen == 0
Note in the mldsa_native.h docs that m may be NULL when mlen == 0, and add a test exercising it: a sign/verify round-trip with m == NULL, mlen == 0 for both the pure and SHAKE256 pre-hash paths. Signed-off-by: Matthias J. Kannwischer <matthias@zerorisc.com>
1 parent 12a3cab commit 3c76933

2 files changed

Lines changed: 50 additions & 4 deletions

File tree

mldsa/mldsa_native.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,8 @@ int MLD_API_NAMESPACE(signature_internal)(
319319
*
320320
* @param[out] sig Pointer to buffer to hold the generated signature of
321321
* MLDSA_BYTES(MLD_CONFIG_PARAMETER_SET) bytes.
322-
* @param[in] m Pointer to message to be signed.
322+
* @param[in] m Pointer to message to be signed. May be NULL if
323+
* mlen == 0.
323324
* @param mlen Length of message.
324325
* @param[in] ctx Pointer to context string. May be NULL if ctxlen == 0.
325326
* @param ctxlen Length of context string. Should be <= 255.
@@ -446,7 +447,7 @@ int MLD_API_NAMESPACE(verify_internal)(
446447
*
447448
* @param[in] sig Pointer to input signature of
448449
* MLDSA_BYTES(MLD_CONFIG_PARAMETER_SET) bytes.
449-
* @param[in] m Pointer to message.
450+
* @param[in] m Pointer to message. May be NULL if mlen == 0.
450451
* @param mlen Length of message.
451452
* @param[in] ctx Pointer to context string. May be NULL if ctxlen == 0.
452453
* @param ctxlen Length of context string.
@@ -647,7 +648,8 @@ int MLD_API_NAMESPACE(verify_pre_hash_internal)(
647648
*
648649
* @param[out] sig Pointer to buffer to hold the generated signature of
649650
* MLDSA_BYTES(MLD_CONFIG_PARAMETER_SET) bytes.
650-
* @param[in] m Pointer to message to be hashed and signed.
651+
* @param[in] m Pointer to message to be hashed and signed. May be
652+
* NULL if mlen == 0.
651653
* @param mlen Length of message.
652654
* @param[in] ctx Pointer to context string.
653655
* @param ctxlen Length of context string.
@@ -692,7 +694,8 @@ int MLD_API_NAMESPACE(signature_pre_hash_shake256)(
692694
*
693695
* @param[in] sig Pointer to input signature of
694696
* MLDSA_BYTES(MLD_CONFIG_PARAMETER_SET) bytes.
695-
* @param[in] m Pointer to message to be hashed and verified.
697+
* @param[in] m Pointer to message to be hashed and verified. May be
698+
* NULL if mlen == 0.
696699
* @param mlen Length of message.
697700
* @param[in] ctx Pointer to context string.
698701
* @param ctxlen Length of context string.

test/src/test_mldsa.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,48 @@ static int test_sign_pre_hash(void)
150150

151151
return 0;
152152
}
153+
154+
/* Empty message with a NULL pointer: m may be NULL when mlen == 0.
155+
* Covers both the pure and SHAKE256 pre-hash paths, so the mlen == 0
156+
* behaviour is exercised for prehash as well, across all backends in CI. */
157+
static int test_sign_empty_message(void)
158+
{
159+
uint8_t pk[MLDSA_PK_BYTES];
160+
uint8_t sk[MLDSA_SK_BYTES];
161+
uint8_t sig[MLDSA_SIG_BYTES];
162+
uint8_t ctx[CTXLEN];
163+
uint8_t rnd[MLDSA_RNDBYTES];
164+
int rc;
165+
166+
CHECK(mld_sign_keypair(pk, sk) == 0);
167+
CHECK(randombytes(ctx, CTXLEN) == 0);
168+
MLD_CT_TESTING_SECRET(ctx, CTXLEN);
169+
170+
/* Pure ML-DSA */
171+
CHECK_SIGN_RC(mld_sign_signature(sig, NULL, 0, ctx, CTXLEN, sk));
172+
rc = mld_sign_verify(sig, NULL, 0, ctx, CTXLEN, pk);
173+
MLD_CT_TESTING_DECLASSIFY(rc, sizeof(int));
174+
if (rc)
175+
{
176+
printf("ERROR: empty_message: pure verify\n");
177+
return 1;
178+
}
179+
180+
/* HashML-DSA (SHAKE256 pre-hash) */
181+
CHECK(randombytes(rnd, MLDSA_RNDBYTES) == 0);
182+
MLD_CT_TESTING_SECRET(rnd, sizeof(rnd));
183+
CHECK_SIGN_RC(
184+
mld_sign_signature_pre_hash_shake256(sig, NULL, 0, ctx, CTXLEN, rnd, sk));
185+
rc = mld_sign_verify_pre_hash_shake256(sig, NULL, 0, ctx, CTXLEN, pk);
186+
MLD_CT_TESTING_DECLASSIFY(rc, sizeof(int));
187+
if (rc)
188+
{
189+
printf("ERROR: empty_message: pre-hash verify\n");
190+
return 1;
191+
}
192+
193+
return 0;
194+
}
153195
#endif /* !MLD_CONFIG_NO_KEYPAIR_API && !MLD_CONFIG_NO_SIGN_API && \
154196
!MLD_CONFIG_NO_VERIFY_API */
155197

@@ -444,6 +486,7 @@ int main(void)
444486
r |= test_wrong_ctx();
445487
r |= test_sign_extmu();
446488
r |= test_sign_pre_hash();
489+
r |= test_sign_empty_message();
447490
#endif /* !MLD_CONFIG_NO_KEYPAIR_API && !MLD_CONFIG_NO_SIGN_API && \
448491
!MLD_CONFIG_NO_VERIFY_API */
449492
#if !defined(MLD_CONFIG_NO_KEYPAIR_API)

0 commit comments

Comments
 (0)