Skip to content

ML-DSA: Add optional context to signing and verification#90

Open
mjdemilliano wants to merge 1 commit intowolfSSL:masterfrom
mjdemilliano:ml-dsa-sign-with-context
Open

ML-DSA: Add optional context to signing and verification#90
mjdemilliano wants to merge 1 commit intowolfSSL:masterfrom
mjdemilliano:ml-dsa-sign-with-context

Conversation

@mjdemilliano
Copy link
Copy Markdown
Contributor

No description provided.

@embhorn
Copy link
Copy Markdown
Member

embhorn commented Apr 7, 2026

@mjdemilliano is an approved contributor

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds optional “context” (ctx) support to ML-DSA (Dilithium) signing and verification, enabling domain separation when using the wolfSSL context-aware APIs.

Changes:

  • Extend MlDsaPrivate.sign() and _MlDsaBase.verify() with an optional ctx argument and route to *_ctx_msg wolfCrypt APIs when provided.
  • Add tests covering sign/verify behavior with correct/incorrect context.
  • Extend the CFFI bindings to include wc_dilithium_sign_ctx_msg and wc_dilithium_verify_ctx_msg.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
wolfcrypt/ciphers.py Adds ctx parameter and switches between ctx/non-ctx wolfCrypt functions.
tests/test_mldsa.py Adds coverage for context-aware signing and verification.
scripts/build_ffi.py Declares the new ctx-aware wolfCrypt APIs in the FFI cdef.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +2281 to +2286
if ctx is not None:
ctx_bytestype = t2b(ctx)
ret = _lib.wc_dilithium_sign_ctx_msg(
_ffi.from_buffer(ctx_bytestype),
len(ctx_bytestype),
_ffi.from_buffer(msg_bytestype),
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wc_dilithium_sign_ctx_msg() takes ctxLen as a C "byte" in the FFI definition, but this wrapper passes len(ctx_bytestype) without bounds checking. For ctx lengths > 255, cffi will truncate the value and only a prefix of ctx will be used, which is very surprising and can break domain separation; please validate ctx length (or adjust the FFI signature if ctxLen is actually wider).

Copilot uses AI. Check for mistakes.
Comment on lines 2303 to 2304
if ret < 0: # pragma: no cover
raise WolfCryptError("wc_dilithium_sign_msg() error (%d)" % ret)
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When ctx is provided, failures will raise an exception that still references wc_dilithium_sign_msg(), even though wc_dilithium_sign_ctx_msg() was called. Please update the error string to match the actual call path (or include ctx/no-ctx in the message).

Copilot uses AI. Check for mistakes.
int wc_dilithium_export_public(dilithium_key* key, byte* out, word32* outLen);
int wc_dilithium_import_public(const byte* in, word32 inLen, dilithium_key* key);
int wc_dilithium_sign_msg(const byte* msg, word32 msgLen, byte* sig, word32* sigLen, dilithium_key* key, WC_RNG* rng);
int wc_dilithium_sign_ctx_msg(const byte* ctx, byte ctxLen, const byte* msg, word32 msgLen, byte* sig, word32* sigLen, dilithium_key* key, WC_RNG* rng);
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new FFI declarations use different types for ctxLen: wc_dilithium_sign_ctx_msg declares ctxLen as byte, but wc_dilithium_verify_ctx_msg declares ctxLen as word32. Please confirm the correct signature in the wolfSSL headers and make these consistent; if ctxLen is actually word32, the current byte declaration will truncate lengths >255 at the ABI boundary.

Suggested change
int wc_dilithium_sign_ctx_msg(const byte* ctx, byte ctxLen, const byte* msg, word32 msgLen, byte* sig, word32* sigLen, dilithium_key* key, WC_RNG* rng);
int wc_dilithium_sign_ctx_msg(const byte* ctx, word32 ctxLen, const byte* msg, word32 msgLen, byte* sig, word32* sigLen, dilithium_key* key, WC_RNG* rng);

Copilot uses AI. Check for mistakes.
wrong_message = b"This is a wrong message for ML-DSA signature"
assert not mldsa_pub.verify(signature, wrong_message)

# Verify with ctx for signature generated without
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor test comment clarity: "Verify with ctx for signature generated without" reads incomplete; consider updating to something like "...generated without context" so the intent is unambiguous.

Suggested change
# Verify with ctx for signature generated without
# Verify with ctx for signature generated without context

Copilot uses AI. Check for mistakes.
@danielinux danielinux assigned danielinux and unassigned wolfSSL-Bot Apr 8, 2026
Copy link
Copy Markdown
Member

@danielinux danielinux left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please address copilot's commends

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants