Compare commits

...

8 Commits

Author SHA1 Message Date
JacobBarthelmeh cb9885ba53
Merge pull request #143 from embhorn/zd22306
Fix ML-DSA example in docs
2026-08-10 10:25:58 -06:00
Eric Blankenhorn d4b8fbad0e Fix from review 2026-08-07 14:30:49 -05:00
Eric Blankenhorn 58520ace10 Fix ML-DSA example in docs 2026-08-07 14:11:45 -05:00
John Safranek e1bdcab5ea
Merge pull request #138 from MarkAtwood/fix/pin-setuptools-build-backend
build: declare the setuptools build backend floor (F-5426)
2026-08-02 21:38:30 -07:00
Mark Atwood ef980e4d09 build: declare the setuptools build backend floor (F-5426)
[build-system] declared bare `setuptools`, so isolated builds resolved
whatever version the index served at build time. This repo has no uv.lock,
so CI's `uv build --wheel` re-resolves the backend on every run.

Declare `setuptools>=77`. Nothing was broken before this: an unpinned
resolver always fetched a recent backend, so the build worked. The floor is
measured, not chosen. The PEP 639 `license` expression and `license-files`
key already in this file each require setuptools >= 77 independently (76 and
older reject either one alone, while the older `license = {file = ...}`
table form passes), so the project had an undeclared >= 77 requirement that
stayed invisible precisely because the version floated. Declaring it keeps a
build environment pinned below 77 from failing mid-build on an opaque
`project.license` config error with no hint that the fix is an upgrade.

No upper bound, matching the floor-only convention of every other bound in
this file (`cffi>=1.17`, `typing-extensions>=4.4.0`). A ceiling would not
address the reported risk anyway -- a malicious point release satisfies any
range, so only hash-pinned build requirements help there -- and setuptools
ships majors often enough (7 since 2025-03, with 81 and 82 two days apart)
that a stale ceiling silently excludes working versions instead of
protecting anything.

Verified: builds at 77.0.3 and 83.0.0, 76.1.0 refused at resolve time,
License-Expression intact in wheel METADATA, ruff clean, 196 passed.
2026-07-31 15:05:30 -07:00
philljj b297f8a00b
Merge pull request #141 from julek-wolfssl/fenrir-dilithium-ctxlen-fix
Use byte ctxLen in wc_dilithium_verify_ctx_msg cdef (F-4014)
2026-07-29 23:25:42 -05:00
Juliusz Sosinowicz 2fea30cd32 Validate ctx length in MlDsa.verify (F-4014)
MlDsa.sign/sign_with_seed reject a context longer than 255 bytes with
ValueError, but verify did not. With ctxLen now correctly declared as byte in
the cdef, an over-long ctx would surface as a low-level CFFI OverflowError
instead of the consistent ValueError callers get from the signing paths.

Reject len(ctx) > 255 with ValueError in verify, matching sign.
2026-07-16 13:44:55 +00:00
Juliusz Sosinowicz 8bb46362b7 Use byte ctxLen in wc_dilithium_verify_ctx_msg cdef (F-4014)
The CFFI cdef declared wc_dilithium_verify_ctx_msg with word32 ctxLen while the
sign variants use byte ctxLen. wolfSSL's real API (wc_MlDsaKey_VerifyCtx in
wolfcrypt/wc_mldsa.h, which the wc_dilithium_verify_ctx_msg macro forwards to)
takes byte ctxLen, matching FIPS 204's 255-byte context cap. The mismatched
cdef made CFFI marshal a 4-byte word32 into a 1-byte slot, silently truncating
any ctxLen > 255 to its low byte.

Declare ctxLen as byte to match the sign cdef and the underlying API.
2026-07-16 08:48:55 +00:00
4 changed files with 12 additions and 6 deletions

View File

@ -144,8 +144,8 @@ ML-DSA
>>>
>>> msg = b"This is an example message"
>>>
>>> sig = mldsa_priv.sign(msg)
>>> mldsa_pub.verify(sig, msg)
>>> sig = mldsa_priv.sign(msg, ctx=b"")
>>> mldsa_pub.verify(sig, msg, ctx=b"")
True
>>>
>>> ######## Export and Import Keys
@ -160,6 +160,6 @@ True
>>> mldsa_pub2 = MlDsaPublic(mldsa_type)
>>> mldsa_pub2.decode_key(exported_pub_key)
>>>
>>> sig2 = mldsa_priv2.sign(msg)
>>> mldsa_pub2.verify(sig2, msg)
>>> sig2 = mldsa_priv2.sign(msg, ctx=b"")
>>> mldsa_pub2.verify(sig2, msg, ctx=b"")
True

View File

@ -31,7 +31,9 @@ dependencies = [
Homepage = "https://github.com/wolfssl/wolfcrypt-py"
[build-system]
requires = ["setuptools", "cffi>=1.17"]
# setuptools >= 77 is required for the PEP 639 `license` expression and
# `license-files` above; 76 and older reject them.
requires = ["setuptools>=77", "cffi>=1.17"]
build-backend = "setuptools.build_meta:__legacy__"
[dependency-groups]

View File

@ -1350,7 +1350,7 @@ def build_ffi(local_wolfssl, features):
int wc_dilithium_import_public(const byte* in, word32 inLen, dilithium_key* key);
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_with_seed(const byte* ctx, byte ctxLen, const byte* msg, word32 msgLen, byte* sig, word32* sigLen, dilithium_key* key, const byte* seed);
int wc_dilithium_verify_ctx_msg(const byte* sig, word32 sigLen, const byte* ctx, word32 ctxLen, const byte* msg, word32 msgLen, int* res, dilithium_key* key);
int wc_dilithium_verify_ctx_msg(const byte* sig, word32 sigLen, const byte* ctx, byte ctxLen, const byte* msg, word32 msgLen, int* res, dilithium_key* key);
typedef dilithium_key MlDsaKey;
int wc_MlDsaKey_GetPrivLen(MlDsaKey* key, int* len);
int wc_MlDsaKey_GetPubLen(MlDsaKey* key, int* len);

View File

@ -2364,6 +2364,10 @@ if _lib.ML_DSA_ENABLED:
if ctx is not None:
ctx_bytestype = t2b(ctx)
if len(ctx_bytestype) > 255:
raise ValueError(
f"context length {len(ctx_bytestype)} too large: must be 255 or less"
)
ret = _lib.wc_dilithium_verify_ctx_msg(
sig_bytestype,
len(sig_bytestype),