Add external mu (message representative) support for ML-DSA#14979
Draft
reaperhulk wants to merge 5 commits into
Draft
Add external mu (message representative) support for ML-DSA#14979reaperhulk wants to merge 5 commits into
reaperhulk wants to merge 5 commits into
Conversation
Adds sign_mu()/verify_mu() to the ML-DSA private/public key classes for
signing and verifying a precomputed 64-byte external mu, as defined in
FIPS 204. mu already incorporates the public key and any context string,
so these methods take no context.
Per-backend mechanism:
- OpenSSL 3.5+: set the integer "mu" signature parameter
(OSSL_SIGNATURE_PARAM_MU) and pass mu through EVP_DigestSign.
- AWS-LC: EVP_PKEY_sign/EVP_PKEY_verify, which use the "ExternalMu"
format for ML-DSA keys.
- BoringSSL: the EVP layer has no external-mu support, so use the
low-level MLDSA*_{sign,verify}_message_representative functions.
Derive mu from the existing deterministic pure KAT vectors (whose signatures come from an independent reference implementation) and check that verify_mu accepts each reference signature for its derived mu and rejects it for a tampered mu, across ML-DSA-44/65/87. https://claude.ai/code/session_01MmjphxZ6ookRpjUhQouKjf
The Wycheproof ML-DSA sign vectors carry a precomputed mu ('External Mu')
for every case with a valid signature, including the mu-only 'Internal'
cases NIST provides without an accompanying message or context. The
signing tests skip those, so add external-mu tests that exercise
verify_mu against the vector mu/signature pairs, confirm a perturbed mu
fails, and (when msg/ctx are present) check the derived mu matches the
vector.
https://claude.ai/code/session_01MmjphxZ6ookRpjUhQouKjf
Point openssl and openssl-sys at the rust-openssl master branch via [patch.crates-io] so the BoringSSL build picks up the merged mldsa.h addition to the bindgen wrapper (rust-openssl/rust-openssl#2650), which the external-mu BoringSSL path needs for the MLDSA* low-level functions and the CBS public-key parser. Temporary until a release including it ships. https://claude.ai/code/session_01MmjphxZ6ookRpjUhQouKjf
Replace the allocating OSSL_PARAM_BLD in set_mu with a fixed two-element OSSL_PARAM array constructed via OSSL_PARAM_construct_uint. The provider reads the 'mu' flag back with OSSL_PARAM_get_int, which accepts an unsigned integer param. This removes the builder's allocation-failure branch, which was unreachable in practice and left uncovered. https://claude.ai/code/session_01MmjphxZ6ookRpjUhQouKjf
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.
This PR adds support for the "external mu" variant of ML-DSA signing and verification as defined in FIPS 204. This allows applications to precompute the message representative (mu) and sign/verify it directly, which is useful for protocols that need to work with the intermediate mu value.
Key Changes
MLDSA_MU_BYTES(64 bytes) defines the length of an ML-DSA external mu valuesign_mu(mu)on all three private key classes (MlDsa44, MlDsa65, MlDsa87) to sign a precomputed 64-byte muverify_mu(signature, mu)on all three public key classes to verify a signature over a precomputed muCRYPTOGRAPHY_OPENSSL_350_OR_GREATERto the conditional compilation flags for the new functionsValueErrorif notImplementation Details
The external mu interface is implemented with conditional compilation to support three different backends:
MLDSA*_sign_message_representativefunctionsset_mu()configures the signature context with the "mu" parameter before signing/verifyingThe external mu signatures are fully compatible with ordinary ML-DSA signatures—a signature produced via
sign_mu()can be verified with the standardverify()method if the message and context are provided, and vice versa.https://claude.ai/code/session_01MmjphxZ6ookRpjUhQouKjf