Rename Dilithium implementation file/symbols to ML-DSA, add temporary backward-compat shims#17
Closed
Rename Dilithium implementation file/symbols to ML-DSA, add temporary backward-compat shims#17
Conversation
f3b4129 to
c88674a
Compare
Frauschi
commented
May 8, 2026
5d8f9bf to
a6d9f2e
Compare
Frauschi
commented
May 8, 2026
e45c9ff to
0fcf98a
Compare
…-compat shims
The post-quantum signature algorithm originally implemented as Dilithium
was standardized by NIST as ML-DSA in FIPS 204. This commit renames the
implementation file pair, the public API surface, and every internal
helper to the canonical ML-DSA names, mirroring the earlier Kyber ->
ML-KEM migration in wc_mlkem.{h,c}.
This commit deliberately scopes the change to the rename + compatibility
surface only. **No in-tree consumer call sites are converted.** Existing
in-tree consumers (TLS layer, ASN.1 / EVP / cryptocb wrappers, tests,
benchmark, examples, Rust wrapper) keep using the legacy spelling and
compile through the dilithium.h compatibility shim, which provides both
the legacy macro / inline name aliases and the bi-directional sub-config
build-gate translation in a single header. New consumer code can
include <wolfssl/wolfcrypt/wc_mldsa.h> directly and use the canonical
names. See doc/dilithium-to-mldsa-migration.md for the full migration
guide.
Rebased onto current master (7d1516f). The rebase pulls in three
upstream fixes:
- PR wolfSSL#10399 (commit 2833a4b, ~220 (sword32)/(byte)/(word32) casts in
dilithium.c plus three cast hunks in asn.c) -- inherited into the
new wc_mldsa.c via the file rename.
- PR wolfSSL#10400 (commit 4191d46, "Fix Dilithium signing when
WC_DILITHIUM_CACHE_MATRIX_A is enabled") -- backported into
wc_mldsa.c with canonical gate names; assigns to key->a (not local
a), adds (size_t) cast on params->aSz, and zero-initializes after
successful allocation in mldsa_sign_with_seed_mu.
- PR wolfSSL#10420 (commit 55d7ed8, "ML-DSA fixes: small vfy key object,
small SHA-3, fix test") -- the verify-only k[] gate was manually
backported from master's struct dilithium_key into our renamed
struct MlDsaKey in wc_mldsa.h (same #if !defined(WOLFSSL_MLDSA_VERIFY_ONLY)
structure for both INTEL_SPEEDUP and non-INTEL paths). The
test_mldsa.c WOLFSSL_NO_ML_DSA_44/65/87 test gates auto-merged
cleanly.
File layout
-----------
wolfcrypt/src/dilithium.c -> wolfcrypt/src/wc_mldsa.c
wolfssl/wolfcrypt/dilithium.h -> wolfssl/wolfcrypt/wc_mldsa.h
The legacy <wolfssl/wolfcrypt/dilithium.h> path is reborn as a thin
compatibility shim that #include's wc_mldsa.h and provides macro /
inline aliases for every legacy linkage symbol. The shim also hosts
the bi-directional sub-config build-gate translation block (the parent
gate HAVE_DILITHIUM <-> WOLFSSL_HAVE_MLDSA is mapped earlier in
settings.h, since some files read it before dilithium.h is included).
Build-gate rename
-----------------
HAVE_DILITHIUM -> WOLFSSL_HAVE_MLDSA
WOLFSSL_DILITHIUM_* -> WOLFSSL_MLDSA_* (~25 sub-config gates)
WC_DILITHIUM_CACHE_* -> WC_MLDSA_CACHE_*
WC_DILITHIUM_FIXED_ARRAY -> WC_MLDSA_FIXED_ARRAY
WC_DILITHIUMKEY_TYPE_DEFINED -> WC_MLDSAKEY_TYPE_DEFINED
Build-system options
--------------------
CMake:
WOLFSSL_MLDSA -- new canonical option.
WOLFSSL_DILITHIUM -- preserved as a legacy alias; either being set
enables -DWOLFSSL_HAVE_MLDSA.
BUILD_DILITHIUM (cmake/automake conditional) -> BUILD_MLDSA.
Autotools:
--enable-mldsa -- canonical configure switch.
--enable-dilithium -- preserved as a convenience alias.
Internal shell variables ENABLED_DILITHIUM* renamed to ENABLED_MLDSA*.
The configure summary echoes "ML-DSA: yes" rather than "DILITHIUM: yes".
Public API rename
-----------------
Type:
dilithium_key -> MlDsaKey
wc_dilithium_params -> MlDsaParams
Init / lifecycle (3-arg Init matching wc_MlKemKey_Init):
wc_dilithium_init -> wc_MlDsaKey_Init (was 1-arg, now 3-arg
with heap + devId; legacy 1-arg form is
supplied by the shim's static-inline
wrapper that defaults heap=NULL,
devId=INVALID_DEVID).
wc_dilithium_init_ex -> wc_MlDsaKey_Init (3-arg)
wc_dilithium_init_id -> wc_MlDsaKey_InitId
wc_dilithium_init_label -> wc_MlDsaKey_InitLabel
wc_dilithium_new -> wc_MlDsaKey_New
wc_dilithium_delete -> wc_MlDsaKey_Delete
wc_dilithium_free -> wc_MlDsaKey_Free
Parameters / sizing:
wc_dilithium_set_level -> wc_MlDsaKey_SetParams
wc_dilithium_get_level -> wc_MlDsaKey_GetParams
wc_dilithium_size -> wc_MlDsaKey_Size
wc_dilithium_priv_size -> wc_MlDsaKey_PrivSize
wc_dilithium_pub_size -> wc_MlDsaKey_PubSize
wc_dilithium_sig_size -> wc_MlDsaKey_SigSize
wc_dilithium_check_key -> wc_MlDsaKey_CheckKey
Key generation:
wc_dilithium_make_key -> wc_MlDsaKey_MakeKey
wc_dilithium_make_key_from_seed -> wc_MlDsaKey_MakeKeyFromSeed
Raw export (no argument reorder):
wc_dilithium_export_public -> wc_MlDsaKey_ExportPubRaw
wc_dilithium_export_private[_only] -> wc_MlDsaKey_ExportPrivRaw
wc_dilithium_export_key -> wc_MlDsaKey_ExportKey
Raw import / sign / verify / DER decode (FIPS 204 / ML-KEM
convention puts the key first; legacy form put it last):
wc_dilithium_import_public(in, inLen, key)
-> wc_MlDsaKey_ImportPubRaw(key, in, inLen)
wc_dilithium_import_private[_only](priv, privSz, key)
-> wc_MlDsaKey_ImportPrivRaw(key, priv, privSz)
wc_dilithium_import_key(priv, privSz, pub, pubSz, key)
-> wc_MlDsaKey_ImportKey(key, priv, privSz, pub, pubSz)
wc_dilithium_sign_msg / sign_ctx_msg / sign_ctx_hash / *_with_seed
-> wc_MlDsaKey_Sign / SignCtx / SignCtxHash / *WithSeed
wc_dilithium_verify_msg / verify_ctx_msg / verify_ctx_hash / verify_mu
-> wc_MlDsaKey_Verify / VerifyCtx / VerifyCtxHash / VerifyMu
wc_Dilithium_PrivateKeyDecode(in, idx, key, sz)
-> wc_MlDsaKey_PrivateKeyDecode(key, in, sz, idx)
wc_Dilithium_PublicKeyDecode(in, idx, key, sz)
-> wc_MlDsaKey_PublicKeyDecode(key, in, sz, idx)
ASN.1 encode (no reorder):
wc_Dilithium_PublicKeyToDer -> wc_MlDsaKey_PublicKeyToDer
wc_Dilithium_PrivateKeyToDer -> wc_MlDsaKey_PrivateKeyToDer
wc_Dilithium_KeyToDer -> wc_MlDsaKey_KeyToDer
Type forward declaration in wolfssl/wolfcrypt/asn_public.h:
typedef struct MlDsaKey MlDsaKey added (guarded by
WC_MLDSAKEY_TYPE_DEFINED). The legacy `typedef struct MlDsaKey
dilithium_key` typedef alias is also exposed from this header
(guarded by !WOLFSSL_NO_DILITHIUM_LEGACY_NAMES) so application
code that included only asn_public.h on master keeps compiling.
OpenSSL-compat enum (wolfssl/openssl/evp.h):
Unchanged in this PR -- WC_EVP_PKEY_DILITHIUM = 301 / EVP_PKEY_DILITHIUM
are kept as-is. Aligning the enum value with OpenSSL 3.5+'s actual
NID_ML_DSA_44/65/87 (1457/1458/1459) is planned for a follow-up PR.
Struct field in wolfssl/wolfcrypt/asn.h:
Unchanged in this PR -- SignatureCtx::dilithium remains a `struct
dilithium_key*`, and the surrounding gates remain on HAVE_DILITHIUM.
The legacy struct tag resolves to the canonical type via the shim
macro `#define dilithium_key MlDsaKey`.
Internal helper rename
----------------------
All ~80 lower-case static / file-scope helpers in wc_mldsa.{h,c} and
wc_mldsa_asm.S are renamed dilithium_* -> mldsa_* for consistency with
ML-KEM's mlkem_* convention. The two WOLFSSL_TEST_VIS encoders
wc_dilithium_encode_w1_88/32 become wc_mldsa_encode_w1_88/32. The
struct typedef wc_dilithium_params becomes MlDsaParams.
The FIPS 204 spec-derived constants (DILITHIUM_Q, DILITHIUM_N,
DILITHIUM_LEVEL{2,3,5}_*, DILITHIUM_ML_DSA_{44,65,87}_*) are kept under
their existing names; renaming those public macro constants is
out of scope for this PR.
Compatibility surface
---------------------
A single shim header at wolfssl/wolfcrypt/dilithium.h. It provides
two independent compatibility services, each suppressible via its
own opt-out:
- Macro / static-inline aliases for the legacy linkage names. Direct
one-to-one #defines for the no-reorder APIs and static-inline
function wrappers for the 16 arg-reorder APIs (so the legacy names
remain addressable, not just preprocessor expansions). Suppressed
by defining WOLFSSL_NO_DILITHIUM_LEGACY_NAMES.
- Bi-directional translation of all 31 sub-config build gates
(legacy WOLFSSL_DILITHIUM_* / WC_DILITHIUM_* <-> canonical
WOLFSSL_MLDSA_* / WC_MLDSA_*). The block runs before the shim's
#include of wc_mldsa.h so the canonical implementation reads its
conditional declarations correctly regardless of which spelling
user_settings.h or the build system used. Suppressed by defining
WOLFSSL_NO_DILITHIUM_LEGACY_GATES.
The parent gate HAVE_DILITHIUM <-> WOLFSSL_HAVE_MLDSA is mapped in
settings.h (forward arm unconditional, reverse arm honors the opt-out)
because some files (notably memory.h via types.h) need the parent gate
visible before they have a chance to include dilithium.h.
A small block of internal-helper aliases inside dilithium.h covers
WOLFSSL_LOCAL `dilithium_get_oid_sum` and the WOLFSSL_TEST_VIS
`wc_dilithium_encode_w1_*` encoders that this branch's unmigrated
in-tree consumers (src/ssl_load.c, tests/api/test_mldsa.c) still call.
Two wolfSSL-internal infrastructure files have their sub-gate
references migrated to canonical names because neither pulls in the
dilithium.h shim:
- wolfssl/wolfcrypt/memory.h reads 4 sub-gates for LARGEST_MEM_BUCKET
sizing. Reachable from <types.h> very early, before any TU has a
chance to include dilithium.h.
- wolfssl/certs_test.h is auto-generated from gencertbuf.pl and has
zero #include directives. Reachable from external TUs that include
only <wolfssl/ssl.h>, which does not transitively pull in
dilithium.h.
For both files, configure now emits canonical -DWOLFSSL_MLDSA_*
defines, so canonical sub-gate references are correct without
relying on the bidirectional shim. gencertbuf.pl was updated
accordingly so future regenerations stay on canonical.
Tests / verification
--------------------
A compile-time validation block at the bottom of wc_mldsa.c (under
!WOLFSSL_NO_DILITHIUM_LEGACY_NAMES suppression) exercises every legacy
macro / inline alias. A parallel block exercises every canonical
declaration in wc_mldsa.h. The bodies sit inside `if (0)` so the
compiler parses and type-checks the expansions without emitting any
runtime call. A missing or misordered alias produces an immediate
compile error.
Wconversion preservation: master's PR wolfSSL#10399 added 220 `(sword32)`
casts (and several `(byte)` / `(word32)` casts) inside dilithium.c.
After the file rename, the new wc_mldsa.c has all 220 `(sword32)`
casts intact (count verified equal between master's dilithium.c and
our new wc_mldsa.c).
Builds clean with --enable-mldsa, --enable-dilithium (legacy alias),
and --enable-mldsa with -DWOLFSSL_MLDSA_VERIFY_ONLY. make check
passes; testwolfcrypt DILITHIUM test passes.
https://claude.ai/code/session_01N9vLeZw4Gsfb11N4BU1Mbe
0fcf98a to
f877862
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Renames the post-quantum signature implementation from its
pre-standardization name Dilithium to its FIPS 204 standardized name
ML-DSA, mirroring the earlier Kyber → ML-KEM migration in
wc_mlkem.{h,c}.This PR ships only the provider-side rename. Existing in-tree
consumer call sites (TLS layer, ASN/EVP/cryptocb wrappers, tests,
benchmark, examples) keep using the legacy
wc_dilithium_*/dilithium_keyspelling and compile through two TEMPORARY shims.The shims will be removed in a future release; consumer migration is a
separate follow-up.
File / symbol rename
wolfcrypt/src/dilithium.cwolfcrypt/src/wc_mldsa.cwolfssl/wolfcrypt/dilithium.hwolfssl/wolfcrypt/wc_mldsa.hdilithium_keyMlDsaKeywc_dilithium_*/wc_Dilithium_*wc_MlDsaKey_*(key-first arg order for sign/verify/import/DER-decode)HAVE_DILITHIUMWOLFSSL_HAVE_MLDSAWOLFSSL_DILITHIUM_*/WC_DILITHIUM_*WOLFSSL_MLDSA_*/WC_MLDSA_*wc_dilithium_paramsMlDsaParamsdilithium_*lower-case helpersmldsa_*wc_MlDsaKey_Init(MlDsaKey*, void* heap, int devId)is 3-arg, matchingwc_MlKemKey_Initand master's existing canonical-name alias.Backward-compatibility (temporary)
<wolfssl/wolfcrypt/dilithium.h>is now a thin shim that#includeswc_mldsa.hand provides macro aliases for the legacysymbol names, including arg-reordering function-like macros for the
16 entry points whose new prototypes put the key first. Suppressible
via
WOLFSSL_NO_DILITHIUM_LEGACY_NAMES.<wolfssl/wolfcrypt/settings_legacy_mldsa.h>(auto-included fromsettings.himmediately afteruser_settings.h) is a bi-directionalshim that keeps the legacy and canonical build-gate names in sync, so
existing
user_settings.hfiles keep working unchanged. Suppressiblevia
WOLFSSL_NO_DILITHIUM_LEGACY_GATES.The
dilithium_keytypedef alias is also exposed from<wolfssl/wolfcrypt/asn_public.h>so application code that includedonly that header on master keeps compiling.
--enable-dilithiumis preserved as a convenience alias for--enable-mldsa.WC_EVP_PKEY_DILITHIUM/EVP_PKEY_DILITHIUMremain as numericaliases for the new
WC_EVP_PKEY_MLDSA/EVP_PKEY_MLDSAenumvalues.
Wconversion fixes inherited
The branch is rebased onto current master so the ML-DSA Wconversion
fixes from PR wolfSSL#10399 (commit
2833a4b1, ~220(sword32)/(byte)/(word32)casts) are inherited byte-for-byte into the newwc_mldsa.cvia the file rename.ABI note
The library's exported linkage symbols are renamed (the
.sonowexports
wc_MlDsaKey_*instead ofwc_dilithium_*). Applications thatlinked dynamically against the legacy symbol names need to either
recompile against the legacy header path (which provides macro aliases
that resolve to the new symbols) or switch their sources to the
canonical names.
Test plan
./configure --enable-mldsa --disable-shared && make && make check && ./wolfcrypt/test/testwolfcrypt(5 PASS, 0 FAIL)./configure --enable-dilithium --disable-shared && make && ./wolfcrypt/test/testwolfcrypt(DILITHIUM test passes through legacy alias)./configure --enable-mldsa --disable-shared CPPFLAGS="-DWOLFSSL_NO_MALLOC -DWOLFSSL_NO_DILITHIUM_LEGACY_NAMES -DWOLFSSL_NO_DILITHIUM_LEGACY_GATES" && make wolfcrypt/test/testwolfcrypt && ./wolfcrypt/test/testwolfcrypt(full opt-out matrix, builds clean and passes)(sword32)cast count inwc_mldsa.cmatches master'sdilithium.c(220).🤖 Generated with Claude Code
Generated by Claude Code