@@ -7763,6 +7763,179 @@ int test_mldsa_make_key_from_seed(void)
77637763 return EXPECT_RESULT();
77647764}
77657765
7766+ int test_mldsa_make_public_key(void)
7767+ {
7768+ EXPECT_DECLS;
7769+ #if defined(WOLFSSL_HAVE_MLDSA) && defined(WOLFSSL_MLDSA_PRIVATE_KEY) && \
7770+ !defined(WOLFSSL_MLDSA_ASSIGN_KEY) && !defined(WOLFSSL_MLDSA_NO_MAKE_KEY)
7771+ wc_MlDsaKey* key;
7772+
7773+ key = (wc_MlDsaKey*)XMALLOC(sizeof(*key), NULL, DYNAMIC_TYPE_TMP_BUFFER);
7774+ ExpectNotNull(key);
7775+ if (key != NULL) {
7776+ XMEMSET(key, 0, sizeof(*key));
7777+ }
7778+
7779+ /* NULL key. */
7780+ ExpectIntEQ(wc_MlDsaKey_MakePublicKey(NULL),
7781+ WC_NO_ERR_TRACE(BAD_FUNC_ARG));
7782+
7783+ #ifndef WOLFSSL_NO_ML_DSA_44
7784+ ExpectIntEQ(wc_MlDsaKey_Init(key, NULL, INVALID_DEVID), 0);
7785+ ExpectIntEQ(wc_MlDsaKey_SetParams(key, WC_ML_DSA_44), 0);
7786+
7787+ /* Private key not set yet. */
7788+ ExpectIntEQ(wc_MlDsaKey_MakePublicKey(key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
7789+
7790+ /* Import a known private-only key (no public key attached) and derive
7791+ * the public key from it. */
7792+ ExpectIntEQ(wc_MlDsaKey_ImportPrivRaw(key, bench_mldsa_44_key,
7793+ sizeof_bench_mldsa_44_key), 0);
7794+ ExpectIntEQ(key->pubKeySet, 0);
7795+
7796+ ExpectIntEQ(wc_MlDsaKey_MakePublicKey(key), 0);
7797+ ExpectIntEQ(key->pubKeySet, 1);
7798+ ExpectIntEQ(XMEMCMP(key->p, bench_mldsa_44_pubkey,
7799+ sizeof_bench_mldsa_44_pubkey), 0);
7800+
7801+ /* No-op when the public key is already set. */
7802+ ExpectIntEQ(wc_MlDsaKey_MakePublicKey(key), 0);
7803+
7804+ wc_MlDsaKey_Free(key);
7805+ #endif /* !WOLFSSL_NO_ML_DSA_44 */
7806+
7807+ #ifndef WOLFSSL_NO_ML_DSA_65
7808+ ExpectIntEQ(wc_MlDsaKey_Init(key, NULL, INVALID_DEVID), 0);
7809+ ExpectIntEQ(wc_MlDsaKey_SetParams(key, WC_ML_DSA_65), 0);
7810+
7811+ ExpectIntEQ(wc_MlDsaKey_ImportPrivRaw(key, bench_mldsa_65_key,
7812+ sizeof_bench_mldsa_65_key), 0);
7813+ ExpectIntEQ(key->pubKeySet, 0);
7814+
7815+ ExpectIntEQ(wc_MlDsaKey_MakePublicKey(key), 0);
7816+ ExpectIntEQ(key->pubKeySet, 1);
7817+ ExpectIntEQ(XMEMCMP(key->p, bench_mldsa_65_pubkey,
7818+ sizeof_bench_mldsa_65_pubkey), 0);
7819+
7820+ wc_MlDsaKey_Free(key);
7821+ #endif /* !WOLFSSL_NO_ML_DSA_65 */
7822+
7823+ #ifndef WOLFSSL_NO_ML_DSA_87
7824+ ExpectIntEQ(wc_MlDsaKey_Init(key, NULL, INVALID_DEVID), 0);
7825+ ExpectIntEQ(wc_MlDsaKey_SetParams(key, WC_ML_DSA_87), 0);
7826+
7827+ ExpectIntEQ(wc_MlDsaKey_ImportPrivRaw(key, bench_mldsa_87_key,
7828+ sizeof_bench_mldsa_87_key), 0);
7829+ ExpectIntEQ(key->pubKeySet, 0);
7830+
7831+ ExpectIntEQ(wc_MlDsaKey_MakePublicKey(key), 0);
7832+ ExpectIntEQ(key->pubKeySet, 1);
7833+ ExpectIntEQ(XMEMCMP(key->p, bench_mldsa_87_pubkey,
7834+ sizeof_bench_mldsa_87_pubkey), 0);
7835+
7836+ wc_MlDsaKey_Free(key);
7837+ #endif /* !WOLFSSL_NO_ML_DSA_87 */
7838+
7839+ XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7840+ #endif
7841+ return EXPECT_RESULT();
7842+ }
7843+
7844+ int test_mldsa_private_key_decode_derives_public_key(void)
7845+ {
7846+ EXPECT_DECLS;
7847+ #if defined(WOLFSSL_HAVE_MLDSA) && !defined(WOLFSSL_MLDSA_NO_ASN1) && \
7848+ !defined(WOLFSSL_MLDSA_ASSIGN_KEY) && !defined(WOLFSSL_MLDSA_NO_MAKE_KEY) && \
7849+ !defined(WOLFSSL_MLDSA_NO_SIGN) && !defined(WOLFSSL_MLDSA_NO_VERIFY) && \
7850+ defined(WOLFSSL_MLDSA_PUBLIC_KEY)
7851+ wc_MlDsaKey* privKey;
7852+ wc_MlDsaKey* pubKey;
7853+ word32 idx;
7854+
7855+ privKey = (wc_MlDsaKey*)XMALLOC(sizeof(*privKey), NULL,
7856+ DYNAMIC_TYPE_TMP_BUFFER);
7857+ ExpectNotNull(privKey);
7858+ pubKey = (wc_MlDsaKey*)XMALLOC(sizeof(*pubKey), NULL,
7859+ DYNAMIC_TYPE_TMP_BUFFER);
7860+ ExpectNotNull(pubKey);
7861+ if (privKey != NULL) {
7862+ XMEMSET(privKey, 0, sizeof(*privKey));
7863+ }
7864+ if (pubKey != NULL) {
7865+ XMEMSET(pubKey, 0, sizeof(*pubKey));
7866+ }
7867+
7868+ #ifndef WOLFSSL_NO_ML_DSA_44
7869+ ExpectIntEQ(wc_MlDsaKey_Init(privKey, NULL, INVALID_DEVID), 0);
7870+ ExpectIntEQ(wc_MlDsaKey_SetParams(privKey, WC_ML_DSA_44), 0);
7871+
7872+ /* mldsa44_priv_only holds a private-key-only DER (no embedded public
7873+ * point). wc_MlDsaKey_PrivateKeyDecode should derive and cache the
7874+ * public key as a best-effort side effect of decoding it. */
7875+ idx = 0;
7876+ ExpectIntEQ(wc_MlDsaKey_PrivateKeyDecode(privKey, mldsa44_priv_only,
7877+ sizeof_mldsa44_priv_only, &idx), 0);
7878+ ExpectIntEQ(privKey->pubKeySet, 1);
7879+
7880+ /* Confirm the derived public key matches the known public key for the
7881+ * same key pair. */
7882+ ExpectIntEQ(wc_MlDsaKey_Init(pubKey, NULL, INVALID_DEVID), 0);
7883+ ExpectIntEQ(wc_MlDsaKey_SetParams(pubKey, WC_ML_DSA_44), 0);
7884+ idx = 0;
7885+ ExpectIntEQ(wc_MlDsaKey_PublicKeyDecode(pubKey, mldsa44_pub_spki,
7886+ sizeof_mldsa44_pub_spki, &idx), 0);
7887+ ExpectIntEQ(XMEMCMP(privKey->p, pubKey->p, WC_MLDSA_44_PUB_KEY_SIZE), 0);
7888+
7889+ wc_MlDsaKey_Free(privKey);
7890+ wc_MlDsaKey_Free(pubKey);
7891+ #endif /* !WOLFSSL_NO_ML_DSA_44 */
7892+
7893+ #ifndef WOLFSSL_NO_ML_DSA_65
7894+ ExpectIntEQ(wc_MlDsaKey_Init(privKey, NULL, INVALID_DEVID), 0);
7895+ ExpectIntEQ(wc_MlDsaKey_SetParams(privKey, WC_ML_DSA_65), 0);
7896+
7897+ idx = 0;
7898+ ExpectIntEQ(wc_MlDsaKey_PrivateKeyDecode(privKey, mldsa65_priv_only,
7899+ sizeof_mldsa65_priv_only, &idx), 0);
7900+ ExpectIntEQ(privKey->pubKeySet, 1);
7901+
7902+ ExpectIntEQ(wc_MlDsaKey_Init(pubKey, NULL, INVALID_DEVID), 0);
7903+ ExpectIntEQ(wc_MlDsaKey_SetParams(pubKey, WC_ML_DSA_65), 0);
7904+ idx = 0;
7905+ ExpectIntEQ(wc_MlDsaKey_PublicKeyDecode(pubKey, mldsa65_pub_spki,
7906+ sizeof_mldsa65_pub_spki, &idx), 0);
7907+ ExpectIntEQ(XMEMCMP(privKey->p, pubKey->p, WC_MLDSA_65_PUB_KEY_SIZE), 0);
7908+
7909+ wc_MlDsaKey_Free(privKey);
7910+ wc_MlDsaKey_Free(pubKey);
7911+ #endif /* !WOLFSSL_NO_ML_DSA_65 */
7912+
7913+ #ifndef WOLFSSL_NO_ML_DSA_87
7914+ ExpectIntEQ(wc_MlDsaKey_Init(privKey, NULL, INVALID_DEVID), 0);
7915+ ExpectIntEQ(wc_MlDsaKey_SetParams(privKey, WC_ML_DSA_87), 0);
7916+
7917+ idx = 0;
7918+ ExpectIntEQ(wc_MlDsaKey_PrivateKeyDecode(privKey, mldsa87_priv_only,
7919+ sizeof_mldsa87_priv_only, &idx), 0);
7920+ ExpectIntEQ(privKey->pubKeySet, 1);
7921+
7922+ ExpectIntEQ(wc_MlDsaKey_Init(pubKey, NULL, INVALID_DEVID), 0);
7923+ ExpectIntEQ(wc_MlDsaKey_SetParams(pubKey, WC_ML_DSA_87), 0);
7924+ idx = 0;
7925+ ExpectIntEQ(wc_MlDsaKey_PublicKeyDecode(pubKey, mldsa87_pub_spki,
7926+ sizeof_mldsa87_pub_spki, &idx), 0);
7927+ ExpectIntEQ(XMEMCMP(privKey->p, pubKey->p, WC_MLDSA_87_PUB_KEY_SIZE), 0);
7928+
7929+ wc_MlDsaKey_Free(privKey);
7930+ wc_MlDsaKey_Free(pubKey);
7931+ #endif /* !WOLFSSL_NO_ML_DSA_87 */
7932+
7933+ XFREE(privKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7934+ XFREE(pubKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
7935+ #endif
7936+ return EXPECT_RESULT();
7937+ }
7938+
77667939int test_mldsa_sig_kats(void)
77677940{
77687941 EXPECT_DECLS;
0 commit comments