Skip to content

Commit ac6eee4

Browse files
mjdemillianodanielinux
authored andcommitted
Process Copilot comments
- Use constant from ciphers.py - Raise ValueError or TypeError in sign_with_seed instead of assert - Add missing test case
1 parent e36859c commit ac6eee4

2 files changed

Lines changed: 45 additions & 14 deletions

File tree

tests/test_mldsa.py

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,9 @@
2525
if _lib.ML_DSA_ENABLED:
2626
import pytest
2727

28-
from wolfcrypt.ciphers import MlDsaPrivate, MlDsaPublic, MlDsaType
28+
from wolfcrypt.ciphers import MlDsaPrivate, MlDsaPublic, MlDsaType, ML_DSA_SIGNATURE_SEED_LENGTH
2929
from wolfcrypt.random import Random
3030

31-
ML_DSA_SIGNATURE_SEED_LENGTH = 32
32-
3331
@pytest.fixture
3432
def rng():
3533
return Random()
@@ -159,8 +157,27 @@ def test_sign_with_seed(mldsa_type, rng):
159157
assert signature == signature_from_same_seed
160158

161159
# test that the seed size is checked:
162-
with pytest.raises(AssertionError):
160+
with pytest.raises(ValueError):
163161
_ = mldsa_priv.sign_with_seed(message, signature_seed[:-1])
164162

165-
with pytest.raises(AssertionError):
163+
# test that the seed type is checked (should be bytes-like, not string)
164+
with pytest.raises(TypeError):
166165
_ = mldsa_priv.sign_with_seed(message, "")
166+
167+
def test_sign_with_seed_and_context(mldsa_type, rng):
168+
signature_seed = rng.bytes(ML_DSA_SIGNATURE_SEED_LENGTH)
169+
mldsa_priv = MlDsaPrivate.make_key(mldsa_type, rng)
170+
pub_key = mldsa_priv.encode_pub_key()
171+
172+
# Import public key
173+
mldsa_pub = MlDsaPublic(mldsa_type)
174+
mldsa_pub.decode_key(pub_key)
175+
176+
# Sign a message
177+
message = b"This is a test message for ML-DSA signature"
178+
context = b"Some context for the signature"
179+
signature = mldsa_priv.sign_with_seed(message, signature_seed, ctx=context)
180+
assert len(signature) == mldsa_priv.sig_size
181+
# test that the context length is checked (more than 255 bytes is invalid):
182+
with pytest.raises(ValueError):
183+
_ = mldsa_priv.sign_with_seed(message, signature_seed[:-1], ctx=bytes(1000))

wolfcrypt/ciphers.py

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2028,6 +2028,9 @@ def decapsulate(self, ct):
20282028

20292029

20302030
if _lib.ML_DSA_ENABLED:
2031+
ML_DSA_SIGNATURE_SEED_LENGTH = 32
2032+
"""The length of a signature generation seed."""
2033+
20312034
class MlDsaType(IntEnum):
20322035
"""
20332036
`MlDsaType` specifies supported ML-DSA types.
@@ -2149,9 +2152,7 @@ def verify(self, signature, message):
21492152
return res[0] == 1
21502153

21512154
class MlDsaPrivate(_MlDsaBase):
2152-
_SIGNATURE_SEED_LENGTH = 32
2153-
"""The length of a signature generation seed."""
2154-
2155+
21552156
@classmethod
21562157
def make_key(cls, mldsa_type, rng=Random()):
21572158
"""
@@ -2286,7 +2287,7 @@ def sign_with_seed(self, message, seed, ctx=None):
22862287
:type message: bytes or str
22872288
:param seed: 32-byte seed for deterministic signature generation.
22882289
:type seed: bytes
2289-
:param ctx: context (optional)
2290+
:param ctx: context (optional, maximum 255 bytes)
22902291
:type ctx: None for no context, str or bytes otherwise
22912292
:return: signature
22922293
:rtype: bytes
@@ -2297,20 +2298,33 @@ def sign_with_seed(self, message, seed, ctx=None):
22972298
out_size = _ffi.new("word32 *")
22982299
out_size[0] = in_size
22992300

2300-
assert isinstance(seed, bytes) and len(seed) == MlDsaPrivate._SIGNATURE_SEED_LENGTH, \
2301-
f"Seed for generating a signature must be {MlDsaPrivate._SIGNATURE_SEED_LENGTH} bytes."
2301+
try:
2302+
seed_view = memoryview(seed)
2303+
except TypeError as exception:
2304+
raise TypeError(
2305+
"seed must support the buffer protocol, such as `bytes` or `bytearray`"
2306+
) from exception
2307+
if len(seed_view) != ML_DSA_SIGNATURE_SEED_LENGTH:
2308+
raise ValueError(
2309+
f"Seed for generating a signature must be {ML_DSA_SIGNATURE_SEED_LENGTH}"
2310+
"bytes."
2311+
)
23022312

23032313
if ctx is not None:
23042314
ctx_bytestype = t2b(ctx)
2315+
if len(ctx_bytestype) > 255:
2316+
raise ValueError(
2317+
f"context length {len(ctx_bytestype)} too large: must be 255 or less"
2318+
)
23052319
ret = _lib.wc_dilithium_sign_ctx_msg_with_seed(
23062320
_ffi.from_buffer(ctx_bytestype),
2307-
len(ctx_bytestype),
2321+
len(ctx_bytestype), # length must be < 256 bytes
23082322
_ffi.from_buffer(msg_bytestype),
23092323
len(msg_bytestype),
23102324
signature,
23112325
out_size,
23122326
self.native_object,
2313-
_ffi.from_buffer(seed),
2327+
_ffi.from_buffer(seed_view),
23142328
)
23152329
if ret < 0: # pragma: no cover
23162330
raise WolfCryptError("wc_dilithium_sign_ctx_msg_with_seed() error (%d)" % ret)
@@ -2321,7 +2335,7 @@ def sign_with_seed(self, message, seed, ctx=None):
23212335
signature,
23222336
out_size,
23232337
self.native_object,
2324-
_ffi.from_buffer(seed),
2338+
_ffi.from_buffer(seed_view),
23252339
)
23262340
if ret < 0: # pragma: no cover
23272341
raise WolfCryptError("wc_dilithium_sign_msg_with_seed() error (%d)" % ret)

0 commit comments

Comments
 (0)